Skip to content

Commit

Permalink
Annotate SyntaxNode
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredpar committed Jan 3, 2020
1 parent 3ddf1c5 commit 8eaf6a9
Show file tree
Hide file tree
Showing 22 changed files with 386 additions and 157 deletions.
1 change: 1 addition & 0 deletions .vscode/tasks.json
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"args": [ "args": [
"msbuild", "msbuild",
"-p:UseRoslynAnalyzers=false", "-p:UseRoslynAnalyzers=false",
"-p:GenerateFullPaths=true",
"src/Compilers/CSharp/csc/csc.csproj" "src/Compilers/CSharp/csc/csc.csproj"
], ],
"problemMatcher": "$msCompile", "problemMatcher": "$msCompile",
Expand Down
180 changes: 180 additions & 0 deletions src/Compilers/CSharp/Portable/CSharpExtensions.cs

Large diffs are not rendered by default.

Original file line number Original file line Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ internal static void ReportTupleNamesMismatchesIfAny(TypeSymbol destination, Bou


if (sourceName != null && !wasInferred && (allMissing || string.CompareOrdinal(destinationNames[i], sourceName) != 0)) if (sourceName != null && !wasInferred && (allMissing || string.CompareOrdinal(destinationNames[i], sourceName) != 0))
{ {
diagnostics.Add(ErrorCode.WRN_TupleLiteralNameMismatch, literal.Arguments[i].Syntax.Parent.Location, sourceName, destination); diagnostics.Add(ErrorCode.WRN_TupleLiteralNameMismatch, literal.Arguments[i].Syntax.Parent!.Location, sourceName, destination);
} }
} }
} }
Expand Down
106 changes: 54 additions & 52 deletions src/Compilers/Core/Portable/Syntax/SyntaxNode.cs

Large diffs are not rendered by default.

Original file line number Original file line Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ static bool ContainsNamespaceDeclaration(SyntaxNode node)
.OfType<NamespaceDeclarationSyntax>().Any(); .OfType<NamespaceDeclarationSyntax>().Any();
} }


private static string? GetAliasQualifier(SyntaxNode name) private static string? GetAliasQualifier(SyntaxNode? name)
{ {
while (true) while (true)
{ {
Expand Down

Large diffs are not rendered by default.

Original file line number Original file line Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ internal StatementSyntaxComparer(SyntaxNode oldRootChild, SyntaxNode newRootChil


#region Tree Traversal #region Tree Traversal


protected internal override bool TryGetParent(SyntaxNode node, out SyntaxNode parent) #pragma warning disable 8610 // Making the out parameter nullable
protected internal override bool TryGetParent(SyntaxNode node, [NotNullWhen(true)] out SyntaxNode? parent)
{ {
parent = node.Parent; parent = node.Parent;
while (parent != null && !HasLabel(parent)) while (parent != null && !HasLabel(parent))
Expand All @@ -45,6 +46,7 @@ protected internal override bool TryGetParent(SyntaxNode node, out SyntaxNode pa


return parent != null; return parent != null;
} }
#pragma warning restore 8610


protected internal override IEnumerable<SyntaxNode>? GetChildren(SyntaxNode node) protected internal override IEnumerable<SyntaxNode>? GetChildren(SyntaxNode node)
{ {
Expand Down Expand Up @@ -830,10 +832,10 @@ private bool TryComputeWeightedDistance(BlockSyntax leftBlock, BlockSyntax right
if (leftCatch.Declaration == null && leftCatch.Filter == null && if (leftCatch.Declaration == null && leftCatch.Filter == null &&
rightCatch.Declaration == null && rightCatch.Filter == null) rightCatch.Declaration == null && rightCatch.Filter == null)
{ {
var leftTry = (TryStatementSyntax)leftCatch.Parent; var leftTry = (TryStatementSyntax?)leftCatch.Parent;
var rightTry = (TryStatementSyntax)rightCatch.Parent; var rightTry = (TryStatementSyntax?)rightCatch.Parent;


distance = 0.5 * ComputeValueDistance(leftTry.Block, rightTry.Block) + distance = 0.5 * ComputeValueDistance(leftTry?.Block, rightTry?.Block) +
0.5 * ComputeValueDistance(leftBlock, rightBlock); 0.5 * ComputeValueDistance(leftBlock, rightBlock);
} }
else else
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public sealed override double GetDistance(SyntaxNode oldNode, SyntaxNode newNode
return ComputeValueDistance(oldNode, newNode); return ComputeValueDistance(oldNode, newNode);
} }


internal static double ComputeValueDistance(SyntaxNode oldNode, SyntaxNode newNode) internal static double ComputeValueDistance(SyntaxNode? oldNode, SyntaxNode? newNode)
{ {
if (SyntaxFactory.AreEquivalent(oldNode, newNode)) if (SyntaxFactory.AreEquivalent(oldNode, newNode))
{ {
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ public override bool ContainingScopeHasAsyncKeyword()
{ {
// regular case. always use ConvertedType to get implicit conversion right. // regular case. always use ConvertedType to get implicit conversion right.
var expression = node.GetUnparenthesizedExpression(); var expression = node.GetUnparenthesizedExpression();
RoslynDebug.Assert(expression is object);


var info = semanticModel.GetTypeInfo(expression); var info = semanticModel.GetTypeInfo(expression);
var conv = semanticModel.GetConversion(expression); var conv = semanticModel.GetConversion(expression);
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContex


private static (SyntaxNode?, ExplicitInterfaceSpecifierSyntax?, SyntaxToken) GetContainer(SyntaxToken token) private static (SyntaxNode?, ExplicitInterfaceSpecifierSyntax?, SyntaxToken) GetContainer(SyntaxToken token)
{ {
for (var node = token.Parent; node != null; node = node.Parent) for (SyntaxNode? node = token.Parent; node != null; node = node.Parent)
{ {
var result = node switch var result = node switch
{ {
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using Microsoft.CodeAnalysis.LanguageServices; using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Operations; using Microsoft.CodeAnalysis.Operations;
using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Extensions;
using Roslyn.Utilities;


namespace Microsoft.CodeAnalysis.CSharp.ImplementInterface namespace Microsoft.CodeAnalysis.CSharp.ImplementInterface
{ {
Expand Down Expand Up @@ -90,9 +91,11 @@ private void UpdateLocation(
? identifierName.Parent ? identifierName.Parent
: identifierName; : identifierName;


RoslynDebug.Assert(node is object);
if (syntaxFacts.IsInvocationExpression(node.Parent)) if (syntaxFacts.IsInvocationExpression(node.Parent))
node = node.Parent; node = node.Parent;


RoslynDebug.Assert(node is object);
var operation = semanticModel.GetOperation(node); var operation = semanticModel.GetOperation(node);
var instance = operation switch var instance = operation switch
{ {
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -27,11 +27,15 @@ public static bool IsStaticLocalFunctionSupported(SyntaxTree tree)
public static bool TryGetCaputuredSymbols(LocalFunctionStatementSyntax localFunction, SemanticModel semanticModel, out ImmutableArray<ISymbol> captures) public static bool TryGetCaputuredSymbols(LocalFunctionStatementSyntax localFunction, SemanticModel semanticModel, out ImmutableArray<ISymbol> captures)
{ {
var dataFlow = semanticModel.AnalyzeDataFlow(localFunction); var dataFlow = semanticModel.AnalyzeDataFlow(localFunction);
<<<<<<< HEAD
if (dataFlow is null) if (dataFlow is null)
{ {
captures = default; captures = default;
return false; return false;
} }
=======
captures = dataFlow!.CapturedInside;
>>>>>>> Annotate SyntaxNode


captures = dataFlow.CapturedInside; captures = dataFlow.CapturedInside;
return dataFlow.Succeeded; return dataFlow.Succeeded;
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ private void AddNodesForTokenToLeft<TSyntaxNode>(ISyntaxFactsService syntaxFacts
// there could be multiple (n) tokens to the left if first n-1 are Empty -> iterate over all of them // there could be multiple (n) tokens to the left if first n-1 are Empty -> iterate over all of them
while (tokenToLeft != default) while (tokenToLeft != default)
{ {
var leftNode = tokenToLeft.Parent; SyntaxNode? leftNode = tokenToLeft.Parent;
do do
{ {
// Consider either a Node that is: // Consider either a Node that is:
Expand All @@ -236,7 +236,7 @@ private void AddNodesForTokenToRightOrIn<TSyntaxNode>(ISyntaxFactsService syntax
{ {
if (tokenToRightOrIn != default) if (tokenToRightOrIn != default)
{ {
var rightNode = tokenToRightOrIn.Parent; SyntaxNode? rightNode = tokenToRightOrIn.Parent;
do do
{ {
// Consider either a Node that is: // Consider either a Node that is:
Expand Down Expand Up @@ -272,7 +272,7 @@ private void AddNodesForTokenToRightOrIn<TSyntaxNode>(ISyntaxFactsService syntax


private void AddRelevantNodesForSelection<TSyntaxNode>(ISyntaxFactsService syntaxFacts, SyntaxNode root, TextSpan selectionTrimmed, ArrayBuilder<TSyntaxNode> relevantNodesBuilder, CancellationToken cancellationToken) where TSyntaxNode : SyntaxNode private void AddRelevantNodesForSelection<TSyntaxNode>(ISyntaxFactsService syntaxFacts, SyntaxNode root, TextSpan selectionTrimmed, ArrayBuilder<TSyntaxNode> relevantNodesBuilder, CancellationToken cancellationToken) where TSyntaxNode : SyntaxNode
{ {
var selectionNode = root.FindNode(selectionTrimmed, getInnermostNodeForTie: true); SyntaxNode? selectionNode = root.FindNode(selectionTrimmed, getInnermostNodeForTie: true);
var prevNode = selectionNode; var prevNode = selectionNode;
do do
{ {
Expand Down Expand Up @@ -462,7 +462,7 @@ protected virtual async Task AddNodesDeepIn<TSyntaxNode>(
var token = root.FindTokenOnRightOfPosition(position, true); var token = root.FindTokenOnRightOfPosition(position, true);


// traverse upwards and add all parents if of correct type // traverse upwards and add all parents if of correct type
var ancestor = token.Parent; SyntaxNode? ancestor = token.Parent;
while (ancestor != null) while (ancestor != null)
{ {
if (ancestor is TSyntaxNode correctTypeNode) if (ancestor is TSyntaxNode correctTypeNode)
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ private SyntaxNode FindStatement(SyntaxNode declarationBody, TextSpan span, out
/// or null if the node isn't contained in a lambda. If a node is returned it must uniquely represent the lambda, /// or null if the node isn't contained in a lambda. If a node is returned it must uniquely represent the lambda,
/// i.e. be no two distinct nodes may represent the same lambda. /// i.e. be no two distinct nodes may represent the same lambda.
/// </summary> /// </summary>
protected abstract SyntaxNode? FindEnclosingLambdaBody(SyntaxNode? container, SyntaxNode node); protected abstract SyntaxNode? FindEnclosingLambdaBody(SyntaxNode? container, SyntaxNode? node);


/// <summary> /// <summary>
/// Given a node that represents a lambda body returns all nodes of the body in a syntax list. /// Given a node that represents a lambda body returns all nodes of the body in a syntax list.
Expand Down Expand Up @@ -238,21 +238,21 @@ internal TextSpan GetDiagnosticSpan(SyntaxNode node, EditKind editKind)


protected virtual TextSpan GetBodyDiagnosticSpan(SyntaxNode node, EditKind editKind) protected virtual TextSpan GetBodyDiagnosticSpan(SyntaxNode node, EditKind editKind)
{ {
var initialNode = node; var current = node.Parent;

while (true) while (true)
{ {
node = node.Parent; if (current == null)
if (node == null)
{ {
return initialNode.Span; return node.Span;
} }


var span = TryGetDiagnosticSpan(node, editKind); var span = TryGetDiagnosticSpan(current, editKind);
if (span != null) if (span != null)
{ {
return span.Value; return span.Value;
} }

current = current.Parent;
} }
} }


Expand All @@ -267,20 +267,21 @@ internal string GetDisplayName(SyntaxNode node, EditKind editKind = EditKind.Upd
/// </summary> /// </summary>
protected virtual string GetBodyDisplayName(SyntaxNode node, EditKind editKind = EditKind.Update) protected virtual string GetBodyDisplayName(SyntaxNode node, EditKind editKind = EditKind.Update)
{ {
var initialNode = node; var current = node.Parent;
while (true) while (true)
{ {
node = node.Parent; if (current == null)
if (node == null)
{ {
throw ExceptionUtilities.UnexpectedValue(initialNode.GetType().Name); throw ExceptionUtilities.UnexpectedValue(node.GetType().Name);
} }


var displayName = TryGetDisplayName(node, editKind); var displayName = TryGetDisplayName(current, editKind);
if (displayName != null) if (displayName != null)
{ {
return displayName; return displayName;
} }

current = current.Parent;
} }
} }


Expand Down Expand Up @@ -314,7 +315,7 @@ protected virtual string GetSuspensionPointDisplayName(SyntaxNode node, EditKind
internal abstract bool ContainsLambda(SyntaxNode declaration); internal abstract bool ContainsLambda(SyntaxNode declaration);
internal abstract SyntaxNode GetLambda(SyntaxNode lambdaBody); internal abstract SyntaxNode GetLambda(SyntaxNode lambdaBody);
internal abstract IMethodSymbol GetLambdaExpressionSymbol(SemanticModel model, SyntaxNode lambdaExpression, CancellationToken cancellationToken); internal abstract IMethodSymbol GetLambdaExpressionSymbol(SemanticModel model, SyntaxNode lambdaExpression, CancellationToken cancellationToken);
internal abstract SyntaxNode GetContainingQueryExpression(SyntaxNode node); internal abstract SyntaxNode? GetContainingQueryExpression(SyntaxNode node);
internal abstract bool QueryClauseLambdasTypeEquivalent(SemanticModel oldModel, SyntaxNode oldNode, SemanticModel newModel, SyntaxNode newNode, CancellationToken cancellationToken); internal abstract bool QueryClauseLambdasTypeEquivalent(SemanticModel oldModel, SyntaxNode oldNode, SemanticModel newModel, SyntaxNode newNode, CancellationToken cancellationToken);


/// <summary> /// <summary>
Expand Down Expand Up @@ -1680,7 +1681,7 @@ internal TextSpan GetDeletedNodeDiagnosticSpan(IReadOnlyDictionary<SyntaxNode, S
/// <summary> /// <summary>
/// Finds the inner-most ancestor of the specified node that has a matching node in the new tree. /// Finds the inner-most ancestor of the specified node that has a matching node in the new tree.
/// </summary> /// </summary>
private static bool TryGetMatchingAncestor(IReadOnlyDictionary<SyntaxNode, SyntaxNode> forwardMap, SyntaxNode oldNode, [NotNullWhen(true)]out SyntaxNode? newAncestor) private static bool TryGetMatchingAncestor(IReadOnlyDictionary<SyntaxNode, SyntaxNode> forwardMap, SyntaxNode? oldNode, [NotNullWhen(true)]out SyntaxNode? newAncestor)
{ {
while (oldNode != null) while (oldNode != null)
{ {
Expand Down Expand Up @@ -1753,9 +1754,12 @@ protected static bool HasParentEdit(Dictionary<SyntaxNode, EditKind> editMap, Ed
return HasEdit(editMap, node.Parent, edit.Kind); return HasEdit(editMap, node.Parent, edit.Kind);
} }


protected static bool HasEdit(Dictionary<SyntaxNode, EditKind> editMap, SyntaxNode node, EditKind editKind) protected static bool HasEdit(Dictionary<SyntaxNode, EditKind> editMap, SyntaxNode? node, EditKind editKind)
{ {
return editMap.TryGetValue(node, out var parentEdit) && parentEdit == editKind; return
node is object &&
editMap.TryGetValue(node, out var parentEdit) &&
parentEdit == editKind;
} }


#endregion #endregion
Expand Down Expand Up @@ -1951,11 +1955,11 @@ private static int IndexOfEquivalent<TSyntaxNode>(SyntaxNode newNode, List<Synta
return -1; return -1;
} }


private static List<SyntaxNode?>? GetAncestors(SyntaxNode? root, SyntaxNode node, Func<SyntaxNode, bool> nodeSelector) private static List<SyntaxNode?>? GetAncestors(SyntaxNode? root, SyntaxNode? node, Func<SyntaxNode, bool> nodeSelector)
{ {
List<SyntaxNode?>? list = null; List<SyntaxNode?>? list = null;


while (node != root) while (node is object && node != root)
{ {
if (nodeSelector(node)) if (nodeSelector(node))
{ {
Expand Down Expand Up @@ -3812,9 +3816,10 @@ private SyntaxNode GetCapturedVariableScope(ISymbol localOrParameter, SyntaxNode
return memberBody; return memberBody;
} }


var node = GetSymbolSyntax(localOrParameter, cancellationToken); SyntaxNode? node = GetSymbolSyntax(localOrParameter, cancellationToken);
while (true) while (true)
{ {
RoslynDebug.Assert(node is object);
if (IsClosureScope(node)) if (IsClosureScope(node))
{ {
return node; return node;
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -249,7 +249,8 @@ private static bool IsVerbatimStringToken(SyntaxToken token)
// Handle nested Tuple deconstruction // Handle nested Tuple deconstruction
while (parent.IsKind(SyntaxKind.ParenthesizedVariableDesignation)) while (parent.IsKind(SyntaxKind.ParenthesizedVariableDesignation))
{ {
parent = parent.Parent; // https://github.com/dotnet/roslyn/issues/40509
parent = parent!.Parent;
} }


// Checking for DeclarationExpression covers the following cases: // Checking for DeclarationExpression covers the following cases:
Expand Down Expand Up @@ -315,7 +316,7 @@ private static bool IsNamespaceName(IdentifierNameSyntax identifierSyntax)


public static bool IsStaticallyDeclared(SyntaxToken token) public static bool IsStaticallyDeclared(SyntaxToken token)
{ {
var parentNode = token.Parent; SyntaxNode? parentNode = token.Parent;


if (parentNode.IsKind(SyntaxKind.EnumMemberDeclaration)) if (parentNode.IsKind(SyntaxKind.EnumMemberDeclaration))
{ {
Expand All @@ -328,7 +329,7 @@ public static bool IsStaticallyDeclared(SyntaxToken token)
{ {
// The parent of a VariableDeclarator is a VariableDeclarationSyntax node. // The parent of a VariableDeclarator is a VariableDeclarationSyntax node.
// It's parent will be the declaration syntax node. // It's parent will be the declaration syntax node.
parentNode = parentNode.Parent.Parent; parentNode = parentNode!.Parent!.Parent;


// Check if this is a field constant declaration // Check if this is a field constant declaration
if (parentNode.GetModifiers().Any(SyntaxKind.ConstKeyword)) if (parentNode.GetModifiers().Any(SyntaxKind.ConstKeyword))
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public static bool CanSafelyMoveLocalToBlock(this ILocalSymbol localSymbol, Synt


return true; return true;


bool HasTypeParameterWithName(SyntaxNode node, string name) bool HasTypeParameterWithName(SyntaxNode? node, string name)
{ {
SeparatedSyntaxList<TypeParameterSyntax>? typeParameters; SeparatedSyntaxList<TypeParameterSyntax>? typeParameters;
switch (node) switch (node)
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -156,10 +156,12 @@ public bool IsAttributeName(SyntaxNode node)
return SyntaxFacts.IsAttributeName(node); return SyntaxFacts.IsAttributeName(node);
} }


public bool IsInvocationExpression(SyntaxNode node) #nullable enable
public bool IsInvocationExpression(SyntaxNode? node)
{ {
return node is InvocationExpressionSyntax; return node is InvocationExpressionSyntax;
} }
#nullable restore


public bool IsAnonymousFunction(SyntaxNode node) public bool IsAnonymousFunction(SyntaxNode node)
{ {
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ private void GetContainers(SyntaxNode root, SyntaxNode contextLocation, out Synt
var usingDirective = contextNode.GetAncestor<TUsingOrAliasSyntax>(); var usingDirective = contextNode.GetAncestor<TUsingOrAliasSyntax>();
if (usingDirective != null) if (usingDirective != null)
{ {
contextNode = usingDirective.Parent; contextNode = usingDirective.Parent!;
} }


return contextNode.GetAncestor<TNamespaceDeclarationSyntax>() ?? return contextNode.GetAncestor<TNamespaceDeclarationSyntax>() ??
Expand Down
3 changes: 2 additions & 1 deletion src/Workspaces/Core/Portable/Differencing/TreeComparer.cs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@


using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.Text;


#nullable enable #nullable enable
Expand Down Expand Up @@ -95,7 +96,7 @@ public Match<TNode> ComputeMatch(TNode oldRoot, TNode newRoot, IEnumerable<KeyVa
/// <summary> /// <summary>
/// Returns a parent for the specified node. /// Returns a parent for the specified node.
/// </summary> /// </summary>
protected internal abstract bool TryGetParent(TNode node, out TNode parent); protected internal abstract bool TryGetParent(TNode node, [NotNullWhen(true)][AllowNull] out TNode parent);


internal TNode GetParent(TNode node) internal TNode GetParent(TNode node)
{ {
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
Expand Down Expand Up @@ -607,7 +608,9 @@ public bool IsUsingStatement(SyntaxNode node)
public bool IsReturnStatement(SyntaxNode node) public bool IsReturnStatement(SyntaxNode node)
=> node?.RawKind == SyntaxKinds.ReturnStatement; => node?.RawKind == SyntaxKinds.ReturnStatement;


public bool IsExpressionStatement(SyntaxNode node) #nullable enable
public bool IsExpressionStatement([NotNullWhen(true)] SyntaxNode? node)
=> node?.RawKind == SyntaxKinds.ExpressionStatement; => node?.RawKind == SyntaxKinds.ExpressionStatement;
#nullable restore
} }
} }
Loading

0 comments on commit 8eaf6a9

Please sign in to comment.