示例#1
0
 internal override void BuildResult(Scanner s, out MatchResult result, Match m)
 {
     this.NewMatchResult(out result);
     this.m_pattern.BuildMatchResult(m, s.Reader.PosCurrent, s.PosWindowStart, ref result);
     SetPositionsInResult(ref result);
     return;
 }
示例#2
0
        private void DoRegionEndOffsets(int idxResult, ref MatchResult match)
        {
            switch (this.OffSetType)
            {
            case OffsetType.MatchEnd:
                match.PosAfterMatch = idxResult;

                if (Whence.Start == this.Whence)
                {
                    match.PosAfterMatch++;
                }

                return;

            case OffsetType.HighlightEnd:
                match.PosAfterHighlight = idxResult;
                return;

            case OffsetType.RegionEnd:
                match.PosAfterRegion = idxResult;

                return;
            }
        }
示例#3
0
        private static void SetPositionsInResult(ref MatchResult result)
        {
            if (result.Success) {
                if (0 == result.PosHighlightStart) {
                    result.PosHighlightStart = result.PosMatchStart;
                }

                if (0 == result.PosAfterHighlight) {
                    result.PosAfterHighlight = result.PosAfterMatch;
                }
            }
        }
示例#4
0
 internal abstract void StartScopeForSuccesfulMatch(Scanner s, MatchResult match);
示例#5
0
        private void DoScan(SlidingWindowReader reader, ICodeFormatter formatter, bool writeAsynchronously)
        {
            ArgumentValidator.ThrowIfNull(formatter, "formatter");
            this.Reader = reader;

            if (this.m_isFirstRun) {
                this.m_scopeStack = new List<Scope>(8);
                this.m_modes = new List<KeyValuePair<int, HighlightMode>>(64);
                this.m_possibleKeyword = new StringBuilder(this.m_syntaxDefinition.MaxKeywordLength + 1);
                this.m_isFirstRun = false;
            } else {
                this.m_scopeStack.Clear();
                this.m_modes.Clear();
                this.m_possibleKeyword.Length = 0;
            }

            this.m_pendingMatch = new MatchResult();
            this.m_pendingMatch.PosMatchStart = int.MaxValue;
            this.m_posDontMatchUntil = -1;
            this.m_posAfterKeepend = int.MaxValue;

            this.m_scopeStack.Add(Scope.BuildBackgroundScope(this.m_syntaxDefinition.MainContext.TopItems));
            this.BuildHighlightModes();

            this.m_outputWriter = new HighlightedOutputWriter(formatter, writeAsynchronously);
            this.LoadInputWindow(this.Reader.CurrentWindow);
            this.Vrooom();
        }
示例#6
0
 private void NewMatchResult(out MatchResult result)
 {
     result               = new MatchResult();
     result.MatchType     = MatchType.Match;
     result.ContainerItem = this;
 }
示例#7
0
        internal void Match(Scanner s, int idxPosition, string[] externalCaptures, ref MatchResult result)
        {
            if (null == externalCaptures || externalCaptures.Length == 0) {
                this.Match(s, idxPosition, this.CachedRegex, ref result);
                return;
            }

            StringBuilder regexBuilder = new StringBuilder(this.RawRegex);
            int idxLastUsableCapture = Math.Min(externalCaptures.Length, this.LastExternalMatch);

            for (int i = 1; i <= idxLastUsableCapture; i++) {
                regexBuilder.Replace(StringExtensions.Fi("\\z{0}", i), externalCaptures[i - 1]);
            }

            Regex r = this.InstantiateRegex(regexBuilder.ToString(), false);

            this.Match(s, idxPosition, r, ref result);
        }
示例#8
0
        internal void BuildMatchResult(Match m, int posMatchedAt, int posWindowStart, ref MatchResult result)
        {
            result.Success = true;

            int posMatchStart = posMatchedAt + this.LeadingContext;
            int posAfterMatch = posMatchedAt + m.Length;

            if (this.HasMatchStartGroup) {
                for (int i = 0; i < m.Groups["zs"].Captures.Count; i++) {
                    posMatchStart = Math.Max(posMatchStart, m.Groups["zs"].Captures[i].Index + posWindowStart);
                }
            }

            if (this.HasMatchEndGroup) {
                posAfterMatch = 0;

                for (int i = 0; i < m.Groups["ze"].Captures.Count; i++) {
                    posAfterMatch = Math.Max(posAfterMatch, m.Groups["ze"].Captures[i].Index + posWindowStart);
                }
            }

            result.PosMatchedAt = posMatchedAt;
            result.PosMatchStart = posMatchStart;
            result.PosAfterMatch = posAfterMatch;

            for (int i = 0; i < this.m_offsets.Count; i++) {
                this.m_offsets[i].Apply(ref result, posMatchedAt, posAfterMatch);
            }

            if (this.CntExternalGroups > 0) {
                result.ExternalCaptures = new string[this.CntExternalGroups];

                for (int i = 1; i <= this.CntExternalGroups; i++) {
                    string capture = m.Groups["z" + i].Value;

                    if (StringExtensions.HasMagicRegexChars(capture)) {
                        capture = Regex.Escape(capture);
                    }

                    result.ExternalCaptures[i - 1] = capture;
                }
            }

            return;
        }
示例#9
0
文件: Region.cs 项目: svermeulen/iris
 private void NewMatchResult(out MatchResult result)
 {
     result = new MatchResult();
     result.MatchType = MatchType.RegionStart;
     result.ContainerItem = this;
 }
示例#10
0
 private void DoMatchOffsets(int posResult, ref MatchResult match)
 {
     switch (this.OffSetType) {
         case OffsetType.MatchStart:
             match.PosMatchStart = posResult;
             return;
         case OffsetType.MatchEnd:
             match.PosAfterMatch = posResult;
             return;
         case OffsetType.HighlightStart:
             match.PosHighlightStart = posResult;
             return;
         case OffsetType.HighlightEnd:
             match.PosAfterHighlight = posResult;
             return;
     }
 }
示例#11
0
 internal abstract void BuildResult(Scanner s, out MatchResult result, Match m);
示例#12
0
 internal abstract void StartScopeForSuccesfulMatch(Scanner s, MatchResult match);
示例#13
0
        internal override void StartScopeForSuccesfulMatch(Scanner s, MatchResult match)
        {
            Scope newScope = this.BuildNewScope(match, s.TopScope);
            s.PushScope(newScope);

            return;
        }
示例#14
0
        private Scope BuildNewScope(MatchResult result, Scope currentTopScope)
        {
            Scope scope = new Scope();

            scope.PosMatchedAt = result.PosMatchedAt;
            scope.PosStart = result.PosMatchStart;
            scope.PosAfter = result.PosAfterMatch;

            scope.PosHighlightStart = result.PosHighlightStart;
            scope.PosAfterHighlight = result.PosAfterHighlight;

            scope.SyntaxItem = this;
            scope.Extend = this.Extend;
            scope.EatNewLineInRegion = this.Pattern.EatNewLine;

            scope.ActiveSyntaxItems = this.GetMatchableItems(currentTopScope);

            return scope;
        }
示例#15
0
文件: Region.cs 项目: svermeulen/iris
        internal bool TryEnding(Scanner s, Scope scope)
        {
            int posMatchAt = s.Reader.PosCurrent;

            if (posMatchAt <= scope.PosEndSkippedUntil || scope.PosAfter != int.MaxValue) {
                return false;
            }

            if (this.TrySkips(s, scope, posMatchAt)) {
                return false;
            }

            MatchResult result = new MatchResult();
            result.MatchType = MatchType.RegionEnd;

            for (int i = 0; i < this.m_endPatterns.Count; i++) {
                this.m_endPatterns[i].Match(s, posMatchAt, scope.ExternalCaptures, ref result);

                if (result.Success) {
                    scope.PosAfter = result.PosAfterMatch;

                    bool hasHighlightMode = this.m_endPatterns[i].HasHighlightMode;

                    if (0 == result.PosAfterRegion && hasHighlightMode) {
                        result.PosAfterRegion = result.PosMatchStart;
                    }

                    if (0 == result.PosAfterHighlight) {
                        result.PosAfterHighlight = result.PosAfterMatch;
                    }

                    if (hasHighlightMode && result.PosAfterRegion < result.PosAfterHighlight) {
                        s.SendMode(this.m_endPatterns[i].HighlightMode, result.PosAfterRegion);
                    }

                    if (result.PosAfterHighlight < result.PosAfterMatch) {
                        s.BuildHighlightModes(result.PosAfterHighlight);
                    }

                    return true;
                }
            }

            return false;
        }
示例#16
0
文件: Region.cs 项目: svermeulen/iris
        internal bool TrySkips(Scanner s, Scope scope, int posMatchAt)
        {
            if (posMatchAt <= scope.PosEndSkippedUntil || scope.PosAfter != int.MaxValue) {
                return false;
            }

            MatchResult result = new MatchResult();
            result.MatchType = MatchType.RegionSkip;

            for (int i = 0; i < this.m_skipPatterns.Count; i++) {
                this.m_skipPatterns[i].Match(s, posMatchAt, scope.ExternalCaptures, ref result);

                if (result.Success) {
                    if (result.PosAfterMatch <= s.PosWindowEnd) {
                        if ('\n' == s[result.PosAfterMatch]) {
                            result.PosAfterMatch++;
                        }
                    }

                    scope.PosEndSkippedUntil = result.PosAfterMatch - 1;
                    return true;
                }
            }

            return false;
        }
示例#17
0
        private void DoRegionEndOffsets(int idxResult, ref MatchResult match)
        {
            switch (this.OffSetType) {
                case OffsetType.MatchEnd:
                    match.PosAfterMatch = idxResult;

                    if (Whence.Start == this.Whence) {
                        match.PosAfterMatch++;
                    }

                    return;
                case OffsetType.HighlightEnd:
                    match.PosAfterHighlight = idxResult;
                    return;
                case OffsetType.RegionEnd:
                    match.PosAfterRegion = idxResult;

                    return;
            }
        }
示例#18
0
文件: Region.cs 项目: svermeulen/iris
        private bool TryFindEndWithinLine(Scanner s, int posStartAt, string[] externalCaptures)
        {
            MatchResult result = new MatchResult();
            int position = posStartAt;

            while (position <= s.PosWindowEnd) {
                result.MatchType = MatchType.RegionSkip;
                for (int i = 0; i < this.m_skipPatterns.Count; i++) {
                    this.m_skipPatterns[i].Match(s, position, externalCaptures, ref result);

                    if (result.Success) {
                        while (position < result.PosAfterMatch) {
                            position++;

                            if ('\n' == s.InputWindow[position]) {
                                return false;
                            }
                        }
                        break;
                    }
                }

                for (int i = 0; i < this.m_endPatterns.Count; i++) {
                    this.m_endPatterns[i].Match(s, position, externalCaptures, ref result);

                    if (result.Success) {
                        return true;
                    }
                }

                if ('\n' == s.InputWindow[position]) {
                    return false;
                }

                position++;
            }

            return false;
        }
示例#19
0
 private void DoRegionSkipOffsets(int idxResult, ref MatchResult match)
 {
     switch (this.OffSetType) {
         case OffsetType.MatchEnd:
             match.PosAfterMatch = idxResult;
             return;
     }
 }
示例#20
0
        internal void Match(Scanner s, int idxPosition, ref MatchResult result)
        {
            if (0 < this.LastExternalMatch) {
                string msg = StringExtensions.Fi("Invalid call to Match(): no external captures were passed, but Pattern '{0}' expects them", this);
                throw new InvalidOperationException(msg);
            }

            this.Match(s, idxPosition, this.CachedRegex, ref result);
        }
示例#21
0
 private void DoRegionStartOffsets(int idxResult, ref MatchResult match)
 {
     switch (this.OffSetType) {
         case OffsetType.MatchStart:
             match.PosMatchStart = idxResult;
             return;
         case OffsetType.HighlightStart:
             match.PosHighlightStart = idxResult;
             return;
         case OffsetType.RegionStart:
             match.PosRegionStart = idxResult;
             return;
     }
 }
示例#22
0
        private void Match(Scanner s, int idxPosition, Regex r, ref MatchResult result)
        {
            int idxMatchAt = idxPosition;

            if (this.LeadingContext > 0) {
                idxMatchAt -= this.LeadingContext;

                // SHOULD: idxMatchAt = Math.Min(idxMatchAt, s.GetIdxLineStartFor(s.m_idxMatchHead));
                idxMatchAt = Math.Max(0, idxMatchAt);
            }

            Match m = r.Match(s.InputWindow.Window, idxMatchAt - s.PosWindowStart);

            if (m.Success) {
                this.BuildMatchResult(m, idxMatchAt, s.PosWindowStart, ref result);
            } else {
                result.Success = false;
            }
        }
示例#23
0
        /// <summary>
        /// 
        /// </summary>
        /// <devdoc>
        /// Vim patterns are pretty quirky and inconsistent. See the file 'OffsetExperiments.vim' - it contains
        /// some experiments that show the behavior of offsets in Vim.
        /// </devdoc>
        internal void Apply(ref MatchResult match, int posOriginalStart, int posOriginalAfter)
        {
            int posWhence = (Whence.Start == this.Whence) ? posOriginalStart : posOriginalAfter;
            int posResult = posWhence + this.Offset;

            if ((this.OffSetType == OffsetType.MatchStart) || (this.OffSetType == OffsetType.HighlightStart)) {
                if (Whence.End == this.Whence) {
                    posResult--;
                }
            }

            if (OffsetType.MatchStart == this.OffSetType) {
                if (posResult < posOriginalStart) {
                    // Vim allows one to specify a negative offset for the match start, which should in theory make your match
                    // happen earlier than it was actually found. No syntax files use this so we don't support it
                    string msg = StringExtensions.Fi("Error applying offset to pattern - Iris does not support changing the start of a match " +
                        "to a position BEFORE the unaltered start. Offset was '{0}', unaltered start was '{1}'", this, posOriginalStart);

                    throw new AssertionViolationException(msg);
                }
            }

            switch (match.MatchType) {
                case MatchType.Match:
                    this.DoMatchOffsets(posResult, ref match);
                    break;
                case MatchType.RegionStart:
                    this.DoRegionStartOffsets(posResult, ref match);
                    break;
                case MatchType.RegionSkip:
                    this.DoRegionSkipOffsets(posResult, ref match);
                    break;
                case MatchType.RegionEnd:
                    this.DoRegionEndOffsets(posResult, ref match);
                    break;
                default:
                    string msg = StringExtensions.Fi("Unhandled MatchType: '{0}'", match.MatchType);
                    throw new AssertionViolationException(msg);
            }
        }
示例#24
0
        internal void BuildMatchResult(Match m, int posMatchedAt, int posWindowStart, ref MatchResult result)
        {
            result.Success = true;

            int posMatchStart = posMatchedAt + this.LeadingContext;
            int posAfterMatch = posMatchedAt + m.Length;

            if (this.HasMatchStartGroup)
            {
                for (int i = 0; i < m.Groups["zs"].Captures.Count; i++)
                {
                    posMatchStart = Math.Max(posMatchStart, m.Groups["zs"].Captures[i].Index + posWindowStart);
                }
            }

            if (this.HasMatchEndGroup)
            {
                posAfterMatch = 0;

                for (int i = 0; i < m.Groups["ze"].Captures.Count; i++)
                {
                    posAfterMatch = Math.Max(posAfterMatch, m.Groups["ze"].Captures[i].Index + posWindowStart);
                }
            }

            result.PosMatchedAt  = posMatchedAt;
            result.PosMatchStart = posMatchStart;
            result.PosAfterMatch = posAfterMatch;

            for (int i = 0; i < this.m_offsets.Count; i++)
            {
                this.m_offsets[i].Apply(ref result, posMatchedAt, posAfterMatch);
            }

            if (this.CntExternalGroups > 0)
            {
                result.ExternalCaptures = new string[this.CntExternalGroups];

                for (int i = 1; i <= this.CntExternalGroups; i++)
                {
                    string capture = m.Groups["z" + i].Value;

                    if (StringExtensions.HasMagicRegexChars(capture))
                    {
                        capture = Regex.Escape(capture);
                    }

                    result.ExternalCaptures[i - 1] = capture;
                }
            }

            return;
        }
示例#25
0
文件: Region.cs 项目: svermeulen/iris
        internal override void BuildResult(Scanner s, out MatchResult result, Match m)
        {
            if (this.IsOneLine) {
                result = this.TryMatch(s);
                return;
            }

            this.NewMatchResult(out result);

            for (int i = 0; i < this.m_startPatterns.Count; i++) {
                if (m.Groups["s" + i].Success) {
                    result.Pattern = this.m_startPatterns[i];
                    this.m_startPatterns[i].BuildMatchResult(m, s.Reader.PosCurrent, s.PosWindowStart, ref result);
                    return;
                }
            }

            string msg = StringExtensions.Fi("Unable to find pattern that matched for region '{0}'", this);
            throw new AssertionViolationException(msg);
        }
示例#26
0
        private bool TryVimMatchesAndRegions(ref int posAdvanceTo)
        {
            int posMatchAt = this.Reader.PosCurrent;

            if (this.m_pendingMatch.PosMatchStart < posMatchAt) {
                this.m_pendingMatch.PosMatchStart = int.MaxValue;
            }

            if (this.m_posDontMatchUntil < posMatchAt && this.TopScope.ActiveSyntaxItems.HasMatchesOrRegions) {
                int idxMatchedItem;

                MatchResult result = this.TopScope.ActiveSyntaxItems.TryMatchOrRegionStart(this, out idxMatchedItem);

                for (int i = idxMatchedItem; i < this.TopScope.ActiveSyntaxItems.Items.Length; i++) {
                    bool firstIteration = idxMatchedItem == i;

                    if (!firstIteration) {
                        result = ((ContainerItem) this.TopScope.ActiveSyntaxItems.Items[i]).TryMatch(this);
                    }

                    ContainerItem matchCandidate = result.ContainerItem;

                    // the check below prevents infinite recursion when an item contains itself. It's still possible
                    // to get infinite recursion using two items that contain each other.
                    if ((matchCandidate == this.ItemInScope) && (posMatchAt == this.TopScope.PosMatchedAt)) {
                        continue;
                    }

                    if (result.Success) {
                        if (result.ContainerItem is VimMatch && result.PosAfterMatch == posMatchAt) {
                            continue;
                        }

                        if (result.PosMatchStart < this.m_pendingMatch.PosMatchStart
                            || (result.PosMatchStart == this.m_pendingMatch.PosMatchStart && this.m_pendingMatch.PositionInSyntaxFile < matchCandidate.PositionInSyntaxDefinition)
                            ) {
                            this.m_pendingMatch = result;
                            this.m_pendingMatch.PositionInSyntaxFile = matchCandidate.PositionInSyntaxDefinition;

                            // if the match starts at the match head, we'll call it the best possible match. In _theory_, we could find a match with
                            // a negative start offset, but this would always force us to try every match, which would kill performance. Vim behaves like
                            // we do. I imagine it's for the same reason.
                            if (result.PosMatchStart <= posMatchAt) {
                                break;
                            }
                        }
                    }
                }
            }

            if (this.m_pendingMatch.PosMatchStart <= posMatchAt) {
                ContainerItem matchedItem = this.m_pendingMatch.ContainerItem;
                matchedItem.StartScopeForSuccesfulMatch(this, this.m_pendingMatch);
                this.ClearPendingMatch();

                posAdvanceTo = this.TopScope.PosStart;
                return true;
            }

            return false;
        }
示例#27
0
文件: Region.cs 项目: svermeulen/iris
        internal override void StartScopeForSuccesfulMatch(Scanner s, MatchResult match)
        {
            Scope newScope = this.BuildNewScope(s.TopScope);
            newScope.PosMatchedAt = match.PosMatchedAt;
            newScope.ExternalCaptures = match.ExternalCaptures;

            bool hasHighlightMode = match.Pattern.HasHighlightMode;

            if (0 == match.PosRegionStart) {
                match.PosRegionStart = hasHighlightMode ? match.PosAfterMatch : match.PosMatchStart;
            }

            if (0 == match.PosHighlightStart) {
                match.PosHighlightStart = match.PosMatchStart;
            }

            if (hasHighlightMode && match.PosHighlightStart < match.PosRegionStart) {
                s.SendMode(match.Pattern.HighlightMode, match.PosHighlightStart);
            }

            newScope.PosStart = hasHighlightMode ? match.PosRegionStart : match.PosMatchStart;
            newScope.PosHighlightStart = hasHighlightMode ? match.PosRegionStart : match.PosHighlightStart;
            newScope.PosEndSkippedUntil = hasHighlightMode ? match.PosRegionStart - 1 : match.PosAfterMatch - 1;
            newScope.EatNewLineInRegion = match.Pattern.EatNewLine;

            s.PushScope(newScope);
        }
示例#28
0
 internal abstract void BuildResult(Scanner s, out MatchResult result, Match m);
示例#29
0
        private bool TryVimMatchesAndRegions(ref int posAdvanceTo)
        {
            int posMatchAt = this.Reader.PosCurrent;

            if (this.m_pendingMatch.PosMatchStart < posMatchAt)
            {
                this.m_pendingMatch.PosMatchStart = int.MaxValue;
            }

            if (this.m_posDontMatchUntil < posMatchAt && this.TopScope.ActiveSyntaxItems.HasMatchesOrRegions)
            {
                int idxMatchedItem;

                MatchResult result = this.TopScope.ActiveSyntaxItems.TryMatchOrRegionStart(this, out idxMatchedItem);

                for (int i = idxMatchedItem; i < this.TopScope.ActiveSyntaxItems.Items.Length; i++)
                {
                    bool firstIteration = idxMatchedItem == i;

                    if (!firstIteration)
                    {
                        result = ((ContainerItem)this.TopScope.ActiveSyntaxItems.Items[i]).TryMatch(this);
                    }

                    ContainerItem matchCandidate = result.ContainerItem;

                    // the check below prevents infinite recursion when an item contains itself. It's still possible
                    // to get infinite recursion using two items that contain each other.
                    if ((matchCandidate == this.ItemInScope) && (posMatchAt == this.TopScope.PosMatchedAt))
                    {
                        continue;
                    }


                    if (result.Success)
                    {
                        if (result.ContainerItem is VimMatch && result.PosAfterMatch == posMatchAt)
                        {
                            continue;
                        }

                        if (result.PosMatchStart < this.m_pendingMatch.PosMatchStart ||
                            (result.PosMatchStart == this.m_pendingMatch.PosMatchStart && this.m_pendingMatch.PositionInSyntaxFile < matchCandidate.PositionInSyntaxDefinition)
                            )
                        {
                            this.m_pendingMatch = result;
                            this.m_pendingMatch.PositionInSyntaxFile = matchCandidate.PositionInSyntaxDefinition;

                            // if the match starts at the match head, we'll call it the best possible match. In _theory_, we could find a match with
                            // a negative start offset, but this would always force us to try every match, which would kill performance. Vim behaves like
                            // we do. I imagine it's for the same reason.
                            if (result.PosMatchStart <= posMatchAt)
                            {
                                break;
                            }
                        }
                    }
                }
            }

            if (this.m_pendingMatch.PosMatchStart <= posMatchAt)
            {
                ContainerItem matchedItem = this.m_pendingMatch.ContainerItem;
                matchedItem.StartScopeForSuccesfulMatch(this, this.m_pendingMatch);
                this.ClearPendingMatch();

                posAdvanceTo = this.TopScope.PosStart;
                return(true);
            }

            return(false);
        }