Exemple #1
0
            private bool TryTakeOldNodeOrToken(
                bool asToken,
                out BlendedNode blendedNode)
            {
                // If we're asking for tokens, then first move down to our first token.  (if we're
                // already at a token, then this won't do anything).
                if (asToken)
                {
                    _oldTreeCursor = _oldTreeCursor.MoveToFirstToken();
                }

                // See if we're actually able to reuse this node or token.  If not, our caller will
                // move the cursor to the next appropriate position and will try again.
                var currentNodeOrToken = _oldTreeCursor.CurrentNodeOrToken;

                if (!CanReuse(currentNodeOrToken))
                {
                    blendedNode = default(BlendedNode);
                    return(false);
                }

                // We can reuse this node or token.  Move us forward in the new text, and move to the
                // next sibling.
                _newPosition  += currentNodeOrToken.FullWidth;
                _oldTreeCursor = _oldTreeCursor.MoveToNextSibling();

                _newDirectives = currentNodeOrToken.ApplyDirectives(_newDirectives);
                _oldDirectives = currentNodeOrToken.ApplyDirectives(_oldDirectives);

                blendedNode = CreateBlendedNode(
                    node: (Stark.CSharpSyntaxNode)currentNodeOrToken.AsNode(),
                    token: (InternalSyntax.SyntaxToken)currentNodeOrToken.AsToken().Node);
                return(true);
            }
Exemple #2
0
        private static DirectiveStack ApplyDirectivesToTrivia(GreenNode triviaList, DirectiveStack stack)
        {
            if (triviaList != null && triviaList.ContainsDirectives)
            {
                return(ApplyDirectivesToListOrNode(triviaList, stack));
            }

            return(stack);
        }
Exemple #3
0
        internal override DirectiveStack ApplyDirectives(DirectiveStack stack)
        {
            if (this.ContainsDirectives)
            {
                stack = ApplyDirectivesToTrivia(this.GetLeadingTrivia(), stack);
                stack = ApplyDirectivesToTrivia(this.GetTrailingTrivia(), stack);
            }

            return(stack);
        }
Exemple #4
0
 public Reader(Blender blender)
 {
     _lexer              = blender._lexer;
     _oldTreeCursor      = blender._oldTreeCursor;
     _changes            = blender._changes;
     _newPosition        = blender._newPosition;
     _changeDelta        = blender._changeDelta;
     _newDirectives      = blender._newDirectives;
     _oldDirectives      = blender._oldDirectives;
     _newLexerDrivenMode = blender._newLexerDrivenMode;
 }
Exemple #5
0
        private bool IsPreprocessorSymbolDefined(InternalSyntax.DirectiveStack directives, string symbolName)
        {
            switch (directives.IsDefined(symbolName))
            {
            case InternalSyntax.DefineState.Defined:
                return(true);

            case InternalSyntax.DefineState.Undefined:
                return(false);

            default:
                return(this.Options.PreprocessorSymbols.Contains(symbolName));
            }
        }
Exemple #6
0
        internal static DirectiveStack ApplyDirectives(GreenNode node, DirectiveStack stack)
        {
            if (node.ContainsDirectives)
            {
                for (int i = 0, n = node.SlotCount; i < n; i++)
                {
                    var child = node.GetSlot(i);
                    if (child != null)
                    {
                        stack = ApplyDirectivesToListOrNode(child, stack);
                    }
                }
            }

            return(stack);
        }
Exemple #7
0
        public Blender(Lexer lexer, Stark.CSharpSyntaxNode oldTree, IEnumerable <TextChangeRange> changes)
        {
            Debug.Assert(lexer != null);
            _lexer   = lexer;
            _changes = ImmutableStack.Create <TextChangeRange>();

            if (changes != null)
            {
                // TODO: Consider implementing NormalizedChangeCollection for TextSpan. the real
                // reason why we are collapsing is because we want to extend change ranges and
                // cannot allow them to overlap. This does not seem to be a big deal since multiple
                // changes are infrequent and typically close to each other. However if we have
                // NormalizedChangeCollection for TextSpan we can have both - we can extend ranges
                // and not require collapsing them. NormalizedChangeCollection would also ensure
                // that changes are always normalized.

                // TODO: this is a temporary measure to prevent individual change spans from
                // overlapping after they are widened to effective width (+1 token at the start).
                // once we have normalized collection for TextSpan we will not need to collapse all
                // the change spans.

                var collapsed = TextChangeRange.Collapse(changes);

                // extend the change to its affected range. This will make it easier
                // to filter out affected nodes since we will be able simply check
                // if node intersects with a change.
                var affectedRange = ExtendToAffectedRange(oldTree, collapsed);
                _changes = _changes.Push(affectedRange);
            }

            if (oldTree == null)
            {
                // start at lexer current position if no nodes specified
                _oldTreeCursor = new Cursor();
                _newPosition   = lexer.TextWindow.Position;
            }
            else
            {
                _oldTreeCursor = Cursor.FromRoot(oldTree).MoveToFirstChild();
                _newPosition   = 0;
            }

            _changeDelta        = 0;
            _newDirectives      = default(DirectiveStack);
            _oldDirectives      = default(DirectiveStack);
            _newLexerDrivenMode = 0;
        }
Exemple #8
0
            private SyntaxToken LexNewToken(LexerMode mode)
            {
                if (_lexer.TextWindow.Position != _newPosition)
                {
                    _lexer.Reset(_newPosition, _newDirectives);
                }

                if (mode >= LexerMode.XmlDocComment)
                {
                    mode |= _newLexerDrivenMode;
                }

                var token = _lexer.Lex(ref mode);

                _newDirectives      = _lexer.Directives;
                _newLexerDrivenMode = mode & (LexerMode.MaskXmlDocCommentLocation | LexerMode.MaskXmlDocCommentStyle);
                return(token);
            }
Exemple #9
0
            private void SkipOldToken()
            {
                Debug.Assert(!_oldTreeCursor.IsFinished);

                // First, move down so that we're actually pointing at a token.  If we're already
                // pointing at a token, then we'll just stay there.
                _oldTreeCursor = _oldTreeCursor.MoveToFirstToken();
                var node = _oldTreeCursor.CurrentNodeOrToken;

                // Now, skip past it.
                _changeDelta  += node.FullWidth;
                _oldDirectives = node.ApplyDirectives(_oldDirectives);
                _oldTreeCursor = _oldTreeCursor.MoveToNextSibling();

                // If our cursor is now after any changes, then just skip past them while upping
                // the changeDelta length.  This will let us know that we need to read tokens
                // from the new text to try to sync up.
                this.SkipPastChanges();
            }
Exemple #10
0
        public bool IncrementallyEquivalent(DirectiveStack other)
        {
            var  mine         = SkipInsignificantDirectives(_directives);
            var  theirs       = SkipInsignificantDirectives(other._directives);
            bool mineHasAny   = mine != null && mine.Any();
            bool theirsHasAny = theirs != null && theirs.Any();

            while (mineHasAny && theirsHasAny)
            {
                if (!mine.Head.IncrementallyEquivalent(theirs.Head))
                {
                    return(false);
                }

                mine         = SkipInsignificantDirectives(mine.Tail);
                theirs       = SkipInsignificantDirectives(theirs.Tail);
                mineHasAny   = mine != null && mine.Any();
                theirsHasAny = theirs != null && theirs.Any();
            }

            return(mineHasAny == theirsHasAny);
        }
Exemple #11
0
 private Blender(
     Lexer lexer,
     Cursor oldTreeCursor,
     ImmutableStack <TextChangeRange> changes,
     int newPosition,
     int changeDelta,
     DirectiveStack newDirectives,
     DirectiveStack oldDirectives,
     LexerMode newLexerDrivenMode)
 {
     Debug.Assert(lexer != null);
     Debug.Assert(changes != null);
     Debug.Assert(newPosition >= 0);
     _lexer              = lexer;
     _oldTreeCursor      = oldTreeCursor;
     _changes            = changes;
     _newPosition        = newPosition;
     _changeDelta        = changeDelta;
     _newDirectives      = newDirectives;
     _oldDirectives      = oldDirectives;
     _newLexerDrivenMode = newLexerDrivenMode & (LexerMode.MaskXmlDocCommentLocation | LexerMode.MaskXmlDocCommentStyle);
 }
Exemple #12
0
 internal virtual DirectiveStack ApplyDirectives(DirectiveStack stack)
 {
     return(ApplyDirectives(this, stack));
 }
Exemple #13
0
 internal static DirectiveStack ApplyDirectivesToListOrNode(GreenNode listOrNode, DirectiveStack stack)
 {
     // If we have a list of trivia, then that node is not actually a CSharpSyntaxNode.
     // Just defer to our standard ApplyDirectives helper as it will do the appropriate
     // walking of this list to ApplyDirectives to the children.
     if (listOrNode.RawKind == GreenNode.ListKind)
     {
         return(ApplyDirectives(listOrNode, stack));
     }
     else
     {
         // Otherwise, we must have an actual piece of C# trivia.  Just apply the stack
         // to that node directly.
         return(((CSharpSyntaxNode)listOrNode).ApplyDirectives(stack));
     }
 }
Exemple #14
0
 internal void SetDirectiveStack(InternalSyntax.DirectiveStack directives)
 {
     _directives    = directives;
     _hasDirectives = true;
 }
 internal override DirectiveStack ApplyDirectives(DirectiveStack stack)
 {
     return(stack.Add(new Directive(this)));
 }
Exemple #16
0
        private void BuildPreprocessorStateChangeMap()
        {
            InternalSyntax.DirectiveStack currentState = InternalSyntax.DirectiveStack.Empty;
            var positions = ArrayBuilder <int> .GetInstance();

            var states = ArrayBuilder <InternalSyntax.DirectiveStack> .GetInstance();

            foreach (DirectiveTriviaSyntax directive in this.GetRoot().GetDirectives(d =>
            {
                switch (d.Kind())
                {
                case SyntaxKind.IfDirectiveTrivia:
                case SyntaxKind.ElifDirectiveTrivia:
                case SyntaxKind.ElseDirectiveTrivia:
                case SyntaxKind.EndIfDirectiveTrivia:
                case SyntaxKind.DefineDirectiveTrivia:
                case SyntaxKind.UndefDirectiveTrivia:
                    return(true);

                default:
                    return(false);
                }
            }))
            {
                currentState = directive.ApplyDirectives(currentState);

                switch (directive.Kind())
                {
                case SyntaxKind.IfDirectiveTrivia:
                    // #if directive doesn't affect the set of defined/undefined symbols
                    break;

                case SyntaxKind.ElifDirectiveTrivia:
                    states.Add(currentState);
                    positions.Add(((ElifDirectiveTriviaSyntax)directive).ElifKeyword.SpanStart);
                    break;

                case SyntaxKind.ElseDirectiveTrivia:
                    states.Add(currentState);
                    positions.Add(((ElseDirectiveTriviaSyntax)directive).ElseKeyword.SpanStart);
                    break;

                case SyntaxKind.EndIfDirectiveTrivia:
                    states.Add(currentState);
                    positions.Add(((EndIfDirectiveTriviaSyntax)directive).EndIfKeyword.SpanStart);
                    break;

                case SyntaxKind.DefineDirectiveTrivia:
                    states.Add(currentState);
                    positions.Add(((DefineDirectiveTriviaSyntax)directive).Name.SpanStart);
                    break;

                case SyntaxKind.UndefDirectiveTrivia:
                    states.Add(currentState);
                    positions.Add(((UndefDirectiveTriviaSyntax)directive).Name.SpanStart);
                    break;

                default:
                    throw ExceptionUtilities.UnexpectedValue(directive.Kind());
                }
            }

#if DEBUG
            int currentPos = -1;
            foreach (int pos in positions)
            {
                Debug.Assert(currentPos < pos);
                currentPos = pos;
            }
#endif

            ImmutableInterlocked.InterlockedInitialize(ref _preprocessorStates, states.ToImmutableAndFree());
            ImmutableInterlocked.InterlockedInitialize(ref _preprocessorStateChangePositions, positions.ToImmutableAndFree());
        }
Exemple #17
0
 internal DirectiveParser(Lexer lexer, DirectiveStack context)
     : base(lexer, LexerMode.Directive, null, null, false)
 {
     _context = context;
 }
Exemple #18
0
            internal ParsedSyntaxTree(SourceText textOpt, Encoding encodingOpt, SourceHashAlgorithm checksumAlgorithm, string path, CSharpParseOptions options, CSharpSyntaxNode root, Syntax.InternalSyntax.DirectiveStack directives, bool cloneRoot = true)
            {
                Debug.Assert(root != null);
                Debug.Assert(options != null);
                Debug.Assert(textOpt == null || textOpt.Encoding == encodingOpt && textOpt.ChecksumAlgorithm == checksumAlgorithm);

                _lazyText          = textOpt;
                _encodingOpt       = encodingOpt ?? textOpt?.Encoding;
                _checksumAlgorithm = checksumAlgorithm;
                _options           = options;
                _path = path ?? string.Empty;
                _root = cloneRoot ? this.CloneNodeAsRoot(root) : root;
                _hasCompilationUnitRoot = root.Kind() == SyntaxKind.CompilationUnit;
                this.SetDirectiveStack(directives);
            }