public static void AppendTextBetween(SyntaxToken token1, SyntaxToken token2, StringBuilder builder) { Contract.ThrowIfTrue(token1.RawKind == 0 && token2.RawKind == 0); Contract.ThrowIfTrue(token1.Equals(token2)); if (token1.RawKind == 0) { AppendLeadingTriviaText(token2, builder); return; } if (token2.RawKind == 0) { AppendTrailingTriviaText(token1, builder); return; } var token1PartOftoken2LeadingTrivia = token1.FullSpan.Start > token2.FullSpan.Start; if (token1.FullSpan.End == token2.FullSpan.Start) { AppendTextBetweenTwoAdjacentTokens(token1, token2, builder); return; } AppendTrailingTriviaText(token1, builder); for (var token = token1.GetNextToken(includeZeroWidth: true); token.FullSpan.End <= token2.FullSpan.Start; token = token.GetNextToken(includeZeroWidth: true)) { builder.Append(token.ToFullString()); } AppendPartialLeadingTriviaText(token2, builder, token1.TrailingTrivia.FullSpan.End); }
protected override SyntaxToken VisitVariable(VariableSyntaxToken token) { if (SyntaxToken.Equals(this.Variable, token)) { return(SyntaxToken.Constant(1)); } return(SyntaxToken.Constant(0)); }
protected override SyntaxToken VisitNamedConstant(NamedConstantSyntaxToken token) { if (SyntaxToken.Equals(token, SyntaxToken.E)) { return(token); } return(this.VisitConstant(token)); }
public override bool Equals(object obj) { return(obj is TriviaMapping other && SourceLine == other.SourceLine && TargetLine == other.TargetLine && SourceTrivia.Equals(other.SourceTrivia) && TargetToken.Equals(other.TargetToken) && IsLeading == other.IsLeading); }
private static TextSpan GetSpanFromTokens(TextSpan span, SyntaxToken token1, SyntaxToken token2) { var tree = token1.SyntaxTree; // adjust span to include all whitespace before and after the given span. var start = token1.Span.End; // current token is inside of the given span, get previous token's end position if (span.Start <= token1.Span.Start) { token1 = token1.GetPreviousToken(); start = token1.Span.End; // If token1, that was passed, is the first visible token of the tree then we want to // the beginning of the span to start from the beginning of the tree if (token1.RawKind == 0) { start = 0; } } var end = token2.Span.Start; // current token is inside of the given span, get next token's start position. if (token2.Span.End <= span.End) { token2 = token2.GetNextToken(); end = token2.Span.Start; // If token2, that was passed, was the last visible token of the tree then we want the // span to expand till the end of the tree if (token2.RawKind == 0) { end = tree.Length; } } if (token1.Equals(token2) && end < start) { // This can happen if `token1.Span` is larger than `span` on each end (due to trivia) and occurs when // only a single token is projected into a buffer and the projection is sandwiched between two other // projections into the same backing buffer. An example of this is during broken code scenarios when // typing certain Razor `@` directives. var temp = end; end = start; start = temp; } return(TextSpan.FromBounds(start, end)); }
public static bool IsInvalidTokenRange(this SyntaxNode root, SyntaxToken startToken, SyntaxToken endToken) { // given token must be token exist excluding EndOfFile token. if (startToken.RawKind == 0 || endToken.RawKind == 0) { return(true); } if (startToken.Equals(endToken)) { return(false); } // regular case. // start token can't be end of file token and start token must be before end token if it's not the same token. return(root.FullSpan.End == startToken.SpanStart || startToken.FullSpan.End > endToken.FullSpan.Start); }
protected override SyntaxToken VisitFunction(FunctionSyntaxToken token) { if (token.Type == FunctionType.Ln) { if (!SyntaxToken.Equals(token.Arguments[0], SyntaxToken.E) && token.Arguments[0].TokenType == SyntaxTokenType.Constant) { return(token); } } else if (token.Type == FunctionType.Log) { if (!SyntaxToken.Equals(token.Arguments[0], token.Arguments[1])) { return(token); } } return(base.VisitFunction(token)); }
private static void AnalyzeText(SyntaxTreeAnalysisContext context) { var tree = context.Tree; var root = tree.GetRoot(); List <int> linesWas = new List <int>(); foreach (var node in root.DescendantNodesAndSelf()) { var tokens = node.DescendantTokens(); SyntaxToken prevToken = default(SyntaxToken); foreach (var token in tokens) { if (prevToken.Equals(default(SyntaxToken))) { prevToken = token; } var trivias = token.LeadingTrivia; foreach (var trivia in trivias) { if (token.IsKind(SyntaxKind.CloseBraceToken) || (prevToken.IsKind(SyntaxKind.OpenBraceToken) && !token.IsKind(SyntaxKind.OpenBraceToken) && !token.IsKind(SyntaxKind.CloseBraceToken))) { if (trivia.Kind().Equals(SyntaxKind.EndOfLineTrivia)) { var location = trivia.GetLocation(); var line = location.GetLineSpan().StartLinePosition.Line + 1; if (!linesWas.Contains(line)) { linesWas.Add(line); var diagnostic = Diagnostic.Create(Rule, location); context.ReportDiagnostic(diagnostic); } } } } prevToken = token; } } }
private async Task <Document> RemoveWhiteLine(CodeFixContext context) { var root = await context.Document.GetSyntaxRootAsync(); List <SyntaxTrivia> triviasForRemove = new List <SyntaxTrivia>(); foreach (var node in root.DescendantNodesAndSelf()) { var tokens = node.DescendantTokens(); SyntaxToken prevToken = default(SyntaxToken); foreach (var token in tokens) { if (prevToken.Equals(default(SyntaxToken))) { prevToken = token; } var trivias = token.LeadingTrivia; foreach (var trivia in trivias) { if (token.IsKind(SyntaxKind.CloseBraceToken) || (prevToken.IsKind(SyntaxKind.OpenBraceToken) && !token.IsKind(SyntaxKind.OpenBraceToken) && !token.IsKind(SyntaxKind.CloseBraceToken))) { if (trivia.Kind().Equals(SyntaxKind.EndOfLineTrivia)) { triviasForRemove.Add(trivia); } } } prevToken = token; } } SyntaxNode newRoot = root.ReplaceTrivia(triviasForRemove, (x, y) => default(SyntaxTrivia)); return(context.Document.WithSyntaxRoot(newRoot)); }
private static void AnalyzeAccessorList(SyntaxNodeAnalysisContext context) { var accessorList = (AccessorListSyntax)context.Node; SyntaxList <AccessorDeclarationSyntax> accessors = accessorList.Accessors; if (accessors.Any(f => f.BodyOrExpressionBody() != null)) { if (DiagnosticDescriptors.AddNewLineBeforeAccessorOfFullProperty.IsEffective(context)) { SyntaxToken token = accessorList.OpenBraceToken; foreach (AccessorDeclarationSyntax accessor in accessors) { if (accessor.BodyOrExpressionBody() != null && accessor.SyntaxTree.IsSingleLineSpan(TextSpan.FromBounds(token.Span.End, accessor.SpanStart))) { DiagnosticHelpers.ReportDiagnostic( context, DiagnosticDescriptors.AddNewLineBeforeAccessorOfFullProperty, Location.Create(accessor.SyntaxTree, new TextSpan(accessor.SpanStart, 0))); break; } token = accessor.Body?.CloseBraceToken ?? accessor.SemicolonToken; if (!token.Equals(accessor.GetLastToken())) { break; } } } if (DiagnosticDescriptors.RemoveNewLinesFromAccessorWithSingleLineExpression.IsEffective(context) && !accessorList.IsSingleLine(includeExteriorTrivia: false)) { foreach (AccessorDeclarationSyntax accessor in accessors) { if (CanRemoveNewLinesFromAccessor(accessor)) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.RemoveNewLinesFromAccessorWithSingleLineExpression, accessor); } } } } else if (DiagnosticDescriptors.RemoveNewLinesFromAccessorListOfAutoProperty.IsEffective(context)) { SyntaxNode parent = accessorList.Parent; switch (parent?.Kind()) { case SyntaxKind.PropertyDeclaration: { if (accessors.All(f => !f.AttributeLists.Any()) && !accessorList.IsSingleLine(includeExteriorTrivia: false)) { var propertyDeclaration = (PropertyDeclarationSyntax)parent; SyntaxToken identifier = propertyDeclaration.Identifier; if (!identifier.IsMissing) { SyntaxToken closeBrace = accessorList.CloseBraceToken; if (!closeBrace.IsMissing) { TextSpan span = TextSpan.FromBounds(identifier.Span.End, closeBrace.SpanStart); if (propertyDeclaration .DescendantTrivia(span) .All(f => f.IsWhitespaceOrEndOfLineTrivia())) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.RemoveNewLinesFromAccessorListOfAutoProperty, accessorList); } } } } break; } case SyntaxKind.IndexerDeclaration: { if (accessors.All(f => !f.AttributeLists.Any()) && !accessorList.IsSingleLine(includeExteriorTrivia: false)) { var indexerDeclaration = (IndexerDeclarationSyntax)parent; BracketedParameterListSyntax parameterList = indexerDeclaration.ParameterList; if (parameterList != null) { SyntaxToken closeBracket = parameterList.CloseBracketToken; if (!closeBracket.IsMissing) { SyntaxToken closeBrace = accessorList.CloseBraceToken; if (!closeBrace.IsMissing) { TextSpan span = TextSpan.FromBounds(closeBracket.Span.End, closeBrace.SpanStart); if (indexerDeclaration .DescendantTrivia(span) .All(f => f.IsWhitespaceOrEndOfLineTrivia())) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.RemoveNewLinesFromAccessorListOfAutoProperty, accessorList); } } } } } break; } } } }
private static TextSpan GetSpanFromTokens(TextSpan span, SyntaxToken token1, SyntaxToken token2) { var tree = token1.SyntaxTree; // adjust span to include all whitespace before and after the given span. var start = token1.Span.End; // current token is inside of the given span, get previous token's end position if (span.Start <= token1.Span.Start) { token1 = token1.GetPreviousToken(); start = token1.Span.End; // If token1, that was passed, is the first visible token of the tree then we want to // the beginning of the span to start from the beginning of the tree if (token1.RawKind == 0) { start = 0; } } var end = token2.Span.Start; // current token is inside of the given span, get next token's start position. if (token2.Span.End <= span.End) { token2 = token2.GetNextToken(); end = token2.Span.Start; // If token2, that was passed, was the last visible token of the tree then we want the // span to expand till the end of the tree if (token2.RawKind == 0) { end = tree.Length; } } if (token1.Equals(token2) && end < start) { // This can happen if `token1.Span` is larger than `span` on each end (due to trivia) and occurs when // only a single token is projected into a buffer and the projection is sandwiched between two other // projections into the same backing buffer. An example of this is during broken code scenarios when // typing certain Razor `@` directives. var temp = end; end = start; start = temp; } return TextSpan.FromBounds(start, end); }
protected override SyntaxToken VisitBinary(BinarySyntaxToken token) { SyntaxToken left = this.Visit(token.Left); SyntaxToken right = this.Visit(token.Right); BinaryOperationType type = token.Type; if (left.TokenType == SyntaxTokenType.Constant && right.TokenType == SyntaxTokenType.Constant) { return this.EvalBinary((ConstantSyntaxToken)left, (ConstantSyntaxToken)right, type); } // swap constant to the right if ((type == BinaryOperationType.Add || type == BinaryOperationType.Multiply) && (left.TokenType == SyntaxTokenType.Constant)) { SyntaxToken temp = right; right = left; left = temp; } // add if (type == BinaryOperationType.Add) { if (right.HasValue(0)) { return left; } } // subtract else if (type == BinaryOperationType.Subtract) { if (right.HasValue(0)) { return left; } if (SyntaxToken.Equals(left, right)) { return SyntaxToken.Constant(0); } } // multiply else if (type == BinaryOperationType.Multiply) { if (right.HasValue(0)) { return SyntaxToken.Constant(0); } if (right.HasValue(1)) { return left; } if (left.TokenType == SyntaxTokenType.Binary && right.TokenType == SyntaxTokenType.Binary) { BinarySyntaxToken bl = (BinarySyntaxToken)left; BinarySyntaxToken br = (BinarySyntaxToken)right; if (bl.Type == BinaryOperationType.Power && br.Type == BinaryOperationType.Power && SyntaxToken.Equals(bl.Left, br.Left)) { return this.Visit(SyntaxToken.Pow(bl.Left, SyntaxToken.Add(bl.Right, br.Right))); } } } // divide else if (type == BinaryOperationType.Divide) { if (left.HasValue(0)) { return SyntaxToken.Constant(0); } if (SyntaxToken.Equals(left, right)) { return SyntaxToken.Constant(1); } } // modulus else if (type == BinaryOperationType.Modulus) { if (left.HasValue(0)) { return SyntaxToken.Constant(0); } if (SyntaxToken.Equals(left, right)) { return SyntaxToken.Constant(0); } } // pow else if (type == BinaryOperationType.Power) { if (right.HasValue(0)) { return SyntaxToken.Constant(1); } if (right.HasValue(1)) { return left; } if (left.HasValue(0)) { return SyntaxToken.Constant(1); } if (left.TokenType == SyntaxTokenType.Binary) { BinarySyntaxToken bl = (BinarySyntaxToken)left; if (bl.Type == BinaryOperationType.Power) { return this.Visit(SyntaxToken.Pow(bl.Left, SyntaxToken.Multiply(bl.Right, right))); } } } return SyntaxToken.Binary(left, right, type); }