private SyntaxToken AnnotationResolver( SyntaxNode node, TriviaLocation location, SyntaxAnnotation annotation, SyntaxNode callsite, MethodDeclarationSyntax method) { var token = node.GetAnnotatedNodesAndTokens(annotation).FirstOrDefault().AsToken(); if (token.RawKind != 0) { return token; } switch (location) { case TriviaLocation.BeforeBeginningOfSpan: return callsite.GetFirstToken(includeZeroWidth: true).GetPreviousToken(includeZeroWidth: true); case TriviaLocation.AfterEndOfSpan: return callsite.GetLastToken(includeZeroWidth: true).GetNextToken(includeZeroWidth: true); case TriviaLocation.AfterBeginningOfSpan: return method.Body.OpenBraceToken.GetNextToken(includeZeroWidth: true); case TriviaLocation.BeforeEndOfSpan: return method.Body.CloseBraceToken.GetPreviousToken(includeZeroWidth: true); } return Contract.FailWithReturn<SyntaxToken>("can't happen"); }
private SyntaxToken AnnotationResolver( SyntaxNode node, TriviaLocation location, SyntaxAnnotation annotation, SyntaxNode callsite, MethodDeclarationSyntax method) { var token = node.GetAnnotatedNodesAndTokens(annotation).FirstOrDefault().AsToken(); if (token.RawKind != 0) { return(token); } return(location switch { TriviaLocation.BeforeBeginningOfSpan => callsite.GetFirstToken(includeZeroWidth: true).GetPreviousToken(includeZeroWidth: true), TriviaLocation.AfterEndOfSpan => callsite.GetLastToken(includeZeroWidth: true).GetNextToken(includeZeroWidth: true), TriviaLocation.AfterBeginningOfSpan => method.Body != null ? method.Body.OpenBraceToken.GetNextToken(includeZeroWidth : true) : method.ExpressionBody.ArrowToken.GetNextToken(includeZeroWidth: true), TriviaLocation.BeforeEndOfSpan => method.Body != null ? method.Body.CloseBraceToken.GetPreviousToken(includeZeroWidth : true) : method.SemicolonToken, _ => Contract.FailWithReturn <SyntaxToken>("can't happen"), });
private static SyntaxToken AnnotationResolver( SyntaxNode node, TriviaLocation location, SyntaxAnnotation annotation, SyntaxNode callsite, SyntaxNode method) { var token = node.GetAnnotatedNodesAndTokens(annotation).FirstOrDefault().AsToken(); if (token.RawKind != 0) { return(token); } var(body, expressionBody, semicolonToken) = GetResolverElements(method); return(location switch { TriviaLocation.BeforeBeginningOfSpan => callsite.GetFirstToken(includeZeroWidth: true).GetPreviousToken(includeZeroWidth: true), TriviaLocation.AfterEndOfSpan => callsite.GetLastToken(includeZeroWidth: true).GetNextToken(includeZeroWidth: true), TriviaLocation.AfterBeginningOfSpan => body != null ? body.OpenBraceToken.GetNextToken(includeZeroWidth : true) : expressionBody.ArrowToken.GetNextToken(includeZeroWidth: true), TriviaLocation.BeforeEndOfSpan => body != null ? body.CloseBraceToken.GetPreviousToken(includeZeroWidth : true) : semicolonToken, _ => throw ExceptionUtilities.UnexpectedValue(location) });
private static SyntaxToken ResolveAnnotation( SyntaxNode root, TriviaLocation location, SyntaxAnnotation annotation) { return(root.GetAnnotatedNodesAndTokens(annotation).FirstOrDefault().AsToken()); }
private static IEnumerable <SyntaxTrivia> ResolveTrivia( TriviaLocation location, PreviousNextTokenPair tokenPair, Dictionary <SyntaxToken, LeadingTrailingTriviaPair> triviaMap ) { var previousTriviaPair = triviaMap.ContainsKey(tokenPair.PreviousToken) ? triviaMap[tokenPair.PreviousToken] : default; var nextTriviaPair = triviaMap.ContainsKey(tokenPair.NextToken) ? triviaMap[tokenPair.NextToken] : default; var trailingTrivia = previousTriviaPair.TrailingTrivia ?? SpecializedCollections.EmptyEnumerable <SyntaxTrivia>(); var leadingTrivia = nextTriviaPair.LeadingTrivia ?? SpecializedCollections.EmptyEnumerable <SyntaxTrivia>(); return(tokenPair.PreviousToken.TrailingTrivia .Concat(trailingTrivia) .Concat(leadingTrivia) .Concat(tokenPair.NextToken.LeadingTrivia)); }
private SyntaxToken AnnotationResolver( SyntaxNode node, TriviaLocation location, SyntaxAnnotation annotation, SyntaxNode callsite, MethodDeclarationSyntax method) { var token = node.GetAnnotatedNodesAndTokens(annotation).FirstOrDefault().AsToken(); if (token.RawKind != 0) { return(token); } switch (location) { case TriviaLocation.BeforeBeginningOfSpan: return(callsite.GetFirstToken(includeZeroWidth: true).GetPreviousToken(includeZeroWidth: true)); case TriviaLocation.AfterEndOfSpan: return(callsite.GetLastToken(includeZeroWidth: true).GetNextToken(includeZeroWidth: true)); case TriviaLocation.AfterBeginningOfSpan: return(method.Body.OpenBraceToken.GetNextToken(includeZeroWidth: true)); case TriviaLocation.BeforeEndOfSpan: return(method.Body.CloseBraceToken.GetPreviousToken(includeZeroWidth: true)); } return(Contract.FailWithReturn <SyntaxToken>("can't happen")); }
private IEnumerable <SyntaxTrivia> TriviaResolver( TriviaLocation location, PreviousNextTokenPair tokenPair, Dictionary <SyntaxToken, LeadingTrailingTriviaPair> triviaMap, MethodDeclarationSyntax method) { // Resolve trivia at the edge of the selection. simple case is easy to deal with, but complex cases where // elastic trivia and user trivia are mixed (hybrid case) and we want to preserve some part of user coding style // but not others can be dealt with here. // method has no statement in them. so basically two trivia list now pointing to same thing. "{" and "}" if (method.Body != null) { if (tokenPair.PreviousToken == method.Body.OpenBraceToken && tokenPair.NextToken == method.Body.CloseBraceToken) { return((location == TriviaLocation.AfterBeginningOfSpan) ? SpecializedCollections.SingletonEnumerable(SyntaxFactory.ElasticMarker) : SpecializedCollections.EmptyEnumerable <SyntaxTrivia>()); } } else { if (tokenPair.PreviousToken == method.ExpressionBody.ArrowToken && tokenPair.NextToken.GetPreviousToken() == method.EosToken) { return((location == TriviaLocation.AfterBeginningOfSpan) ? SpecializedCollections.SingletonEnumerable(SyntaxFactory.ElasticMarker) : SpecializedCollections.EmptyEnumerable <SyntaxTrivia>()); } } var previousTriviaPair = triviaMap.ContainsKey(tokenPair.PreviousToken) ? triviaMap[tokenPair.PreviousToken] : default; var nextTriviaPair = triviaMap.ContainsKey(tokenPair.NextToken) ? triviaMap[tokenPair.NextToken] : default; var trailingTrivia = previousTriviaPair.TrailingTrivia ?? SpecializedCollections.EmptyEnumerable <SyntaxTrivia>(); var leadingTrivia = nextTriviaPair.LeadingTrivia ?? SpecializedCollections.EmptyEnumerable <SyntaxTrivia>(); var list = trailingTrivia.Concat(leadingTrivia); switch (location) { case TriviaLocation.BeforeBeginningOfSpan: return(FilterBeforeBeginningOfSpan(tokenPair, list)); case TriviaLocation.AfterEndOfSpan: return(FilterTriviaList(list.Concat(tokenPair.NextToken.LeadingTrivia))); case TriviaLocation.AfterBeginningOfSpan: return(FilterTriviaList(AppendTrailingTrivia(tokenPair).Concat(list).Concat(tokenPair.NextToken.LeadingTrivia))); case TriviaLocation.BeforeEndOfSpan: return(FilterTriviaList(tokenPair.PreviousToken.TrailingTrivia.Concat(list).Concat(tokenPair.NextToken.LeadingTrivia))); } return(Contract.FailWithReturn <IEnumerable <SyntaxTrivia> >("Shouldn't reach here")); }
protected override VList<LNode> AttachTriviaTo(ref LNode node, IListSource<Token> trivia, TriviaLocation loc, LNode parent, int indexInParent) { int nli; if (loc == TriviaLocation.Trailing && indexInParent == 1 && parent != null && parent.Calls(CodeSymbols.If, 3) && (nli = trivia.LastIndexWhere(t => t.Type() == TokenType.Newline)) != -1) { // The 'else' keyword is invisible here, but it often appears on a line by // itself; remove a newline to avoid creating a blank line when printing. var triviaSans = new DList<Token>(trivia); triviaSans.RemoveAt(nli); trivia = triviaSans; } return base.AttachTriviaTo(ref node, trivia, loc, parent, indexInParent); }
private LNode AttachTriviaTo(LNode node, IListSource <Trivia> trivia, TriviaLocation loc, LNode parent, int indexInParent) { var newAttrs = GetTriviaToAttach(node, trivia, loc, parent, indexInParent); if (loc == TriviaLocation.Leading) { return(node.PlusAttrsBefore(newAttrs)); } else { return(node.PlusTrailingTrivia(newAttrs)); } }
private LeadingTrailingTriviaPair GetTrailingAndLeadingTrivia(TriviaLocation locationKind, PreviousNextTokenPair tokenPair, IEnumerable <SyntaxTrivia> trivia) { var list = trivia.ToList(); // there are some noisy trivia var index = GetFirstEndOfLineIndex(list); return(new LeadingTrailingTriviaPair { TrailingTrivia = CreateTriviaListFromTo(list, 0, index), LeadingTrivia = CreateTriviaListFromTo(list, index + 1, list.Count - 1) }); }
private LeadingTrailingTriviaPair GetTrailingAndLeadingTrivia(TriviaLocation locationKind, PreviousNextTokenPair tokenPair, IEnumerable<SyntaxTrivia> trivia) { var list = trivia.ToList(); // there are some noisy trivia var index = GetFirstEndOfLineIndex(list); return new LeadingTrailingTriviaPair { TrailingTrivia = CreateTriviaListFromTo(list, 0, index), LeadingTrivia = CreateTriviaListFromTo(list, index + 1, list.Count - 1) }; }
private LeadingTrailingTriviaPair CreateTriviaPairs( TriviaLocation locationKind, PreviousNextTokenPair tokenPair, IEnumerable <SyntaxTrivia> trivia) { // beginning of the tree if (tokenPair.PreviousToken.RawKind == 0) { return(new LeadingTrailingTriviaPair { TrailingTrivia = SpecializedCollections.EmptyEnumerable <SyntaxTrivia>(), LeadingTrivia = trivia }); } return(GetTrailingAndLeadingTrivia(locationKind, tokenPair, trivia)); }
private IEnumerable<SyntaxTrivia> TriviaResolver( TriviaLocation location, PreviousNextTokenPair tokenPair, Dictionary<SyntaxToken, LeadingTrailingTriviaPair> triviaMap, MethodDeclarationSyntax method) { // Resolve trivia at the edge of the selection. simple case is easy to deal with, but complex cases where // elastic trivia and user trivia are mixed (hybrid case) and we want to preserve some part of user coding style // but not others can be dealt with here. // method has no statement in them. so basically two trivia list now pointing to same thing. "{" and "}" if (tokenPair.PreviousToken == method.Body.OpenBraceToken && tokenPair.NextToken == method.Body.CloseBraceToken) { return (location == TriviaLocation.AfterBeginningOfSpan) ? SpecializedCollections.SingletonEnumerable<SyntaxTrivia>(SyntaxFactory.ElasticMarker) : SpecializedCollections.EmptyEnumerable<SyntaxTrivia>(); } var previousTriviaPair = triviaMap.ContainsKey(tokenPair.PreviousToken) ? triviaMap[tokenPair.PreviousToken] : default(LeadingTrailingTriviaPair); var nextTriviaPair = triviaMap.ContainsKey(tokenPair.NextToken) ? triviaMap[tokenPair.NextToken] : default(LeadingTrailingTriviaPair); var trailingTrivia = previousTriviaPair.TrailingTrivia ?? SpecializedCollections.EmptyEnumerable<SyntaxTrivia>(); var leadingTrivia = nextTriviaPair.LeadingTrivia ?? SpecializedCollections.EmptyEnumerable<SyntaxTrivia>(); var list = trailingTrivia.Concat(leadingTrivia); switch (location) { case TriviaLocation.BeforeBeginningOfSpan: return FilterBeforeBeginningOfSpan(tokenPair, list); case TriviaLocation.AfterEndOfSpan: return FilterTriviaList(list.Concat(tokenPair.NextToken.LeadingTrivia)); case TriviaLocation.AfterBeginningOfSpan: return FilterTriviaList(AppendTrailingTrivia(tokenPair).Concat(list).Concat(tokenPair.NextToken.LeadingTrivia)); case TriviaLocation.BeforeEndOfSpan: return FilterTriviaList(tokenPair.PreviousToken.TrailingTrivia.Concat(list).Concat(tokenPair.NextToken.LeadingTrivia)); } return Contract.FailWithReturn<IEnumerable<SyntaxTrivia>>("Shouldn't reach here"); }
private bool TryAttachTriviaTo(ref LNode prev, ref InternalList <Trivia> triviaList, TriviaLocation loc, LNode parent, int prevIndexInParent) { var prev2 = AttachTriviaTo(prev, triviaList, loc, parent, prevIndexInParent); if (prev2 != null) { prev = prev2; triviaList.Clear(); return(true); } return(false); }
private static IEnumerable<SyntaxTrivia> ResolveTrivia( TriviaLocation location, PreviousNextTokenPair tokenPair, Dictionary<SyntaxToken, LeadingTrailingTriviaPair> triviaMap) { var previousTriviaPair = triviaMap.ContainsKey(tokenPair.PreviousToken) ? triviaMap[tokenPair.PreviousToken] : default(LeadingTrailingTriviaPair); var nextTriviaPair = triviaMap.ContainsKey(tokenPair.NextToken) ? triviaMap[tokenPair.NextToken] : default(LeadingTrailingTriviaPair); var trailingTrivia = previousTriviaPair.TrailingTrivia ?? SpecializedCollections.EmptyEnumerable<SyntaxTrivia>(); var leadingTrivia = nextTriviaPair.LeadingTrivia ?? SpecializedCollections.EmptyEnumerable<SyntaxTrivia>(); return tokenPair.PreviousToken.TrailingTrivia.Concat(trailingTrivia).Concat(leadingTrivia).Concat(tokenPair.NextToken.LeadingTrivia); }
private LeadingTrailingTriviaPair CreateTriviaPairs( TriviaLocation locationKind, PreviousNextTokenPair tokenPair, IEnumerable<SyntaxTrivia> trivia) { // beginning of the tree if (tokenPair.PreviousToken.RawKind == 0) { return new LeadingTrailingTriviaPair { TrailingTrivia = SpecializedCollections.EmptyEnumerable<SyntaxTrivia>(), LeadingTrivia = trivia }; } return GetTrailingAndLeadingTrivia(locationKind, tokenPair, trivia); }
private static SyntaxToken ResolveAnnotation( SyntaxNode root, TriviaLocation location, SyntaxAnnotation annotation) { return root.GetAnnotatedNodesAndTokens(annotation).FirstOrDefault().AsToken(); }
protected override VList <LNode> AttachTriviaTo(ref LNode node, IListSource <Token> trivia, TriviaLocation loc, LNode parent, int indexInParent) { VList <LNode> newAttrs = VList <LNode> .Empty; int i = 0; if (loc == TriviaLocation.Leading) { // leading trivia if (parent == null ? indexInParent > 0 : HasImplicitLeadingNewline(node, parent, indexInParent)) { // ignore expected leading newline if (trivia.Count > 0 && trivia[0].TypeInt == NewlineTypeInt) { i++; } else { newAttrs.Add(_trivia_appendStatement); } } } bool justAddedSLComment = false; LNode attr = null; for (; i < trivia.Count; i++) { var t = trivia[i]; // ignore first newline after single-line comment if (t.TypeInt == NewlineTypeInt && justAddedSLComment) { justAddedSLComment = false; continue; } if ((attr = MakeTriviaAttribute(t)) != null) { justAddedSLComment = attr.Calls(S.TriviaSLComment); newAttrs.Add(attr); } } // Suppress newline before closing brace or at EOF if (loc == TriviaLocation.TrailingExtra && newAttrs.Count > 0 && newAttrs.Last == _trivia_newline) { if (parent == null || parent.Calls(S.Braces)) { newAttrs.Pop(); // Printers add a newline here anyway } } return(newAttrs); }
protected override VList <LNode> AttachTriviaTo(ref LNode node, IListSource <Token> trivia, TriviaLocation loc, LNode parent, int indexInParent) { int nli; if (loc == TriviaLocation.Trailing && indexInParent == 1 && parent != null && parent.Calls(CodeSymbols.If, 3) && (nli = trivia.LastIndexWhere(t => t.Type() == TokenType.Newline)) != -1) { // The 'else' keyword is invisible here, but it often appears on a line by // itself; remove a newline to avoid creating a blank line when printing. var triviaSans = new DList <Token>(trivia); triviaSans.RemoveAt(nli); trivia = triviaSans; } return(base.AttachTriviaTo(ref node, trivia, loc, parent, indexInParent)); }
/// <summary>Derived class should associate the given list of trivia with the /// specified node. Leading trivia will be attached to a given node before /// trailing trivia.</summary> /// <param name="node">The node.</param> /// <param name="trivia">Trivia to be associated with <c>node</c>.</param> /// <param name="loc">Location of the trivia. For a given node, the base class /// calls this method at most once for each value of <see cref="TriviaLocation"/>. /// </param> /// <param name="parent">(Original version of) parent of <c>node</c>.</param> /// <param name="indexInParent">Index of <c>node</c> within <c>parent</c>.</param> /// <returns>The same node with trivia attributes added. If loc indicates trailing /// trivia, the derived class can say "I don't want trivia to be associated with /// this node" by returning null; the base class will, if possible, associate it /// with the next node instead, but this doesn't work for the last child in a /// sequence; in that case this method is called again with the same trivia and /// loc is set to TriviaLocation.TrailingExtra.</returns> /// <remarks>This method may STILL called for a given node when there is no trivia /// associated with that node, IF the node is at the top level or its sibling /// nodes in the same parent have associated trivia.</remarks> protected abstract VList <LNode> AttachTriviaTo(ref LNode node, IListSource <Trivia> trivia, TriviaLocation loc, LNode parent, int indexInParent);
protected override LNodeList GetTriviaToAttach(LNode node, IListSource <Token> trivia, TriviaLocation loc, LNode parent, int indexInParent) { int?nli; // In an 'if' statement, the 'else' keyword is invisible to the trivia // injector, but it often appears on a line by itself; remove one of // the two newline trivia to avoid creating a blank line when printing. if (loc == TriviaLocation.Leading && indexInParent == 2 && parent != null && parent.Calls(CodeSymbols.If, 3) && trivia.Count(t => t.Type() == TokenType.Newline) >= 2 && (nli = trivia.FirstIndexWhere(t => t.Type() == TokenType.Newline)) != null) { trivia = new VList <Token>(trivia).RemoveAt(nli.Value); } return(base.GetTriviaToAttach(node, trivia, loc, parent, indexInParent)); }
/// <summary>Derived class translates a list of trivia (tokens) into appropriate /// trivia attributes. This will be called for leading trivia before trailing /// trivia.</summary> /// <param name="node">The node.</param> /// <param name="trivia">Trivia to be associated with <c>node</c>.</param> /// <param name="loc">Location of the trivia. For a given node, the base class /// calls this method at most once for each value of <see cref="TriviaLocation"/>. /// </param> /// <param name="parent">(Original version of) parent of <c>node</c>.</param> /// <param name="indexInParent">Index of <c>node</c> within <c>parent</c>.</param> /// <returns>A list of trivia attributes that should be attached to the node.</returns> /// <remarks>This method will be called for a node when there is no trivia /// associated with that node; the derived class may, for example, want to add /// `%appendStatement` in certain cases.</remarks> protected abstract LNodeList GetTriviaToAttach(LNode node, IListSource <Trivia> trivia, TriviaLocation loc, LNode parent, int indexInParent);