Example #1
0
        public static SyntaxNode LocateOwner(this SyntaxNode node, SourceChange change)
        {
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }

            if (change.Span.AbsoluteIndex < node.Position)
            {
                // Early escape for cases where changes overlap multiple spans
                // In those cases, the span will return false, and we don't want to search the whole tree
                // So if the current span starts after the change, we know we've searched as far as we need to
                return(null);
            }

            if (IsSpanKind(node))
            {
                var editHandler = node.GetSpanContext()?.EditHandler ?? SpanEditHandler.CreateDefault();
                return(editHandler.OwnsChange(node, change) ? node : null);
            }

            SyntaxNode owner = null;
            IEnumerable <SyntaxNode> children;

            if (node is MarkupStartTagSyntax startTag)
            {
                children = startTag.Children;
            }
            else if (node is MarkupEndTagSyntax endTag)
            {
                children = endTag.Children;
            }
            else if (node is MarkupTagHelperStartTagSyntax startTagHelper)
            {
                children = startTagHelper.Children;
            }
            else if (node is MarkupTagHelperEndTagSyntax endTagHelper)
            {
                children = endTagHelper.Children;
            }
            else
            {
                children = node.ChildNodes();
            }

            foreach (var child in children)
            {
                owner = LocateOwner(child, change);
                if (owner != null)
                {
                    break;
                }
            }

            return(owner);
        }
Example #2
0
 public SpanConstructor(SpanKindInternal kind, SourceLocation location, IEnumerable <IToken> tokens)
 {
     Builder             = new SpanBuilder(location);
     Builder.Kind        = kind;
     Builder.EditHandler = SpanEditHandler.CreateDefault((content) => SpanConstructor.TestTokenizer(content));
     foreach (IToken sym in tokens)
     {
         Builder.Accept(sym);
     }
 }
Example #3
0
        public void Reset()
        {
            // Need to potentially allocate a new list because Span.ReplaceWith takes ownership
            // of the original list.
            _symbols = null;
            _symbols = new List <ISymbol>();

            EditHandler    = SpanEditHandler.CreateDefault((content) => Enumerable.Empty <ISymbol>());
            ChunkGenerator = SpanChunkGenerator.Null;
            Start          = SourceLocation.Undefined;
        }
Example #4
0
        protected override SyntaxTreeNode RewriteBlock(BlockBuilder parent, Block block)
        {
            // Collect the content of this node
            var builder = new StringBuilder();

            for (var i = 0; i < block.Children.Count; i++)
            {
                var childSpan = (Span)block.Children[i];
                builder.Append(childSpan.Content);
            }

            // Create a new span containing this content
            var span = new SpanBuilder(block.Children[0].Start);

            span.EditHandler = SpanEditHandler.CreateDefault(HtmlLanguageCharacteristics.Instance.TokenizeString);
            Debug.Assert(block.Children.Count > 0);
            var start = ((Span)block.Children[0]).Start;

            FillSpan(span, start, builder.ToString());
            return(span.Build());
        }
 private void CommentSpanConfig(SpanBuilder span)
 {
     span.ChunkGenerator = SpanChunkGenerator.Null;
     span.EditHandler    = SpanEditHandler.CreateDefault(Language.TokenizeString);
 }
Example #6
0
            public override SyntaxNode VisitCSharpExplicitExpression(CSharpExplicitExpressionSyntax node)
            {
                CSharpTransitionSyntax transition = null;
                var builder = SyntaxListBuilder <RazorSyntaxNode> .Create();

                if (_rewriteAsMarkup)
                {
                    // Convert transition.
                    // Change to a MarkupChunkGenerator so that the '@' \ parenthesis is generated as part of the output.
                    var context    = node.GetSpanContext();
                    var newContext = new SpanContext(new MarkupChunkGenerator(), context?.EditHandler ?? SpanEditHandler.CreateDefault((content) => Enumerable.Empty <Syntax.InternalSyntax.SyntaxToken>()));

                    var expression = SyntaxFactory.CSharpExpressionLiteral(new SyntaxList <SyntaxToken>(node.Transition.Transition)).WithSpanContext(newContext);
                    expression = (CSharpExpressionLiteralSyntax)VisitCSharpExpressionLiteral(expression);
                    builder.Add(expression);

                    // Since the original transition is part of the body, we need something to take it's place.
                    transition = SyntaxFactory.CSharpTransition(SyntaxFactory.MissingToken(SyntaxKind.Transition));

                    var body = (CSharpExplicitExpressionBodySyntax)node.Body;
                    var rewrittenOpenParen  = (RazorSyntaxNode)VisitRazorMetaCode(body.OpenParen);
                    var rewrittenBody       = (CSharpCodeBlockSyntax)VisitCSharpCodeBlock(body.CSharpCode);
                    var rewrittenCloseParen = (RazorSyntaxNode)VisitRazorMetaCode(body.CloseParen);
                    builder.Add(rewrittenOpenParen);
                    builder.AddRange(rewrittenBody.Children);
                    builder.Add(rewrittenCloseParen);
                }
                else
                {
                    // This is the first expression of a non-string attribute like attr=@(a + b)
                    // Below code converts this to an implicit expression to make the parens
                    // part of the expression so that it is rendered.
                    transition = (CSharpTransitionSyntax)Visit(node.Transition);
                    var body = (CSharpExplicitExpressionBodySyntax)node.Body;
                    var rewrittenOpenParen  = (RazorSyntaxNode)VisitRazorMetaCode(body.OpenParen);
                    var rewrittenBody       = (CSharpCodeBlockSyntax)VisitCSharpCodeBlock(body.CSharpCode);
                    var rewrittenCloseParen = (RazorSyntaxNode)VisitRazorMetaCode(body.CloseParen);
                    builder.Add(rewrittenOpenParen);
                    builder.AddRange(rewrittenBody.Children);
                    builder.Add(rewrittenCloseParen);
                }

                var rewrittenCodeBlock = SyntaxFactory.CSharpCodeBlock(builder.ToList());

                return(SyntaxFactory.CSharpImplicitExpression(transition, SyntaxFactory.CSharpImplicitExpressionBody(rewrittenCodeBlock)));
            }
Example #7
0
            public override SyntaxNode VisitCSharpImplicitExpression(CSharpImplicitExpressionSyntax node)
            {
                if (_rewriteAsMarkup)
                {
                    var builder = SyntaxListBuilder <RazorSyntaxNode> .Create();

                    // Convert transition.
                    // Change to a MarkupChunkGenerator so that the '@' \ parenthesis is generated as part of the output.
                    var context    = node.GetSpanContext();
                    var newContext = new SpanContext(new MarkupChunkGenerator(), context?.EditHandler ?? SpanEditHandler.CreateDefault((content) => Enumerable.Empty <Syntax.InternalSyntax.SyntaxToken>()));

                    var expression = SyntaxFactory.CSharpExpressionLiteral(new SyntaxList <SyntaxToken>(node.Transition.Transition)).WithSpanContext(newContext);
                    expression = (CSharpExpressionLiteralSyntax)VisitCSharpExpressionLiteral(expression);
                    builder.Add(expression);

                    var rewrittenBody = (CSharpCodeBlockSyntax)VisitCSharpCodeBlock(((CSharpImplicitExpressionBodySyntax)node.Body).CSharpCode);
                    builder.AddRange(rewrittenBody.Children);

                    // Since the original transition is part of the body, we need something to take it's place.
                    var transition = SyntaxFactory.CSharpTransition(SyntaxFactory.MissingToken(SyntaxKind.Transition));

                    var rewrittenCodeBlock = SyntaxFactory.CSharpCodeBlock(builder.ToList());
                    return(SyntaxFactory.CSharpImplicitExpression(transition, SyntaxFactory.CSharpImplicitExpressionBody(rewrittenCodeBlock)));
                }

                return(base.VisitCSharpImplicitExpression(node));
            }
Example #8
0
 public SpanConstructor With(SpanEditHandler handler)
 {
     Builder.EditHandler = handler;
     return(this);
 }
Example #9
0
 public void Reset()
 {
     EditHandler    = SpanEditHandler.CreateDefault((content) => Enumerable.Empty <SyntaxToken>());
     ChunkGenerator = SpanChunkGenerator.Null;
 }
Example #10
0
 public SpanContext(ISpanChunkGenerator chunkGenerator, SpanEditHandler editHandler)
 {
     ChunkGenerator = chunkGenerator;
     EditHandler    = editHandler;
 }