Skip to content

Commit

Permalink
Handle possible null symbols in getAttributeTarget (#62137)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcouv authored Jun 30, 2022
1 parent 67d572d commit 58d8ea0
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1289,14 +1289,14 @@ Symbol getAttributeTarget(SyntaxNode targetSyntax)
{
return targetSyntax switch
{
BaseMethodDeclarationSyntax methodDeclaration => GetDeclaredMemberSymbol(methodDeclaration),
LocalFunctionStatementSyntax localFunction => GetMemberModel(localFunction)?.GetDeclaredLocalFunction(localFunction),
ParameterSyntax parameterSyntax => ((Symbols.PublicModel.ParameterSymbol)GetDeclaredSymbol(parameterSyntax)).UnderlyingSymbol,
TypeParameterSyntax typeParameterSyntax => ((Symbols.PublicModel.TypeParameterSymbol)GetDeclaredSymbol(typeParameterSyntax)).UnderlyingSymbol,
IndexerDeclarationSyntax indexerSyntax => ((Symbols.PublicModel.PropertySymbol)GetDeclaredSymbol(indexerSyntax)).UnderlyingSymbol,
AccessorDeclarationSyntax accessorSyntax => ((Symbols.PublicModel.MethodSymbol)GetDeclaredSymbol(accessorSyntax)).UnderlyingSymbol,
AnonymousFunctionExpressionSyntax anonymousFunction => ((Symbols.PublicModel.Symbol)GetSymbolInfo(anonymousFunction).Symbol).UnderlyingSymbol,
DelegateDeclarationSyntax delegateSyntax => ((Symbols.PublicModel.NamedTypeSymbol)GetDeclaredSymbol(delegateSyntax)).UnderlyingSymbol,
BaseMethodDeclarationSyntax or
LocalFunctionStatementSyntax or
ParameterSyntax or
TypeParameterSyntax or
IndexerDeclarationSyntax or
AccessorDeclarationSyntax or
DelegateDeclarationSyntax => GetDeclaredSymbolForNode(targetSyntax).GetSymbol(),
AnonymousFunctionExpressionSyntax anonymousFunction => GetSymbolInfo(anonymousFunction).Symbol.GetSymbol(),
_ => null
};
}
Expand Down
61 changes: 61 additions & 0 deletions src/Compilers/CSharp/Test/Semantic/Semantics/LocalFunctionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9748,6 +9748,40 @@ public MyAttribute(string name1) { }
);
}

[Fact, WorkItem(1556927, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1556927")]
public void ParameterScope_ValueLocalNotInPropertyOrAccessorAttributeNameOf_UnknownAccessor()
{
var source = @"
class C
{
int Property4 { [My(nameof(value))] unknown => throw null; }
}
public class MyAttribute : System.Attribute
{
public MyAttribute(string name) { }
}
";
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition });
comp.VerifyDiagnostics(
// (4,9): error CS0548: 'C.Property4': property or indexer must have at least one accessor
// int Property4 { [My(nameof(value))] unknown => throw null; }
Diagnostic(ErrorCode.ERR_PropertyWithNoAccessors, "Property4").WithArguments("C.Property4").WithLocation(4, 9),
// (4,41): error CS1014: A get or set accessor expected
// int Property4 { [My(nameof(value))] unknown => throw null; }
Diagnostic(ErrorCode.ERR_GetOrSetExpected, "unknown").WithLocation(4, 41)
);

var tree = comp.SyntaxTrees.First();
var model = comp.GetSemanticModel(tree);
var node = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>()
.Where(i => i.Identifier.ValueText == "value")
.Where(i => i.Ancestors().Any(a => a.IsKind(SyntaxKind.Attribute)))
.Single();

Assert.Null(model.GetSymbolInfo(node).Symbol);
}

[Fact]
public void ParameterScope_InParameterAttributeNameOf_Constructor()
{
Expand Down Expand Up @@ -10429,5 +10463,32 @@ public MyAttribute(string name1) { }
");
comp.VerifyDiagnostics();
}

[Fact, WorkItem(1556927, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1556927")]
public void LambdaOutsideMemberModel()
{
var text = @"
public class MyAttribute : System.Attribute
{
public MyAttribute(string name1) { }
}
int P
{
badAccessorName
{
M([My(nameof(P))] env => env);
";
var comp = CreateCompilation(text);

var tree = comp.SyntaxTrees.First();
var model = comp.GetSemanticModel(tree);
var node = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>()
.Where(i => i.Identifier.ValueText == "P")
.Where(i => i.Ancestors().Any(a => a.IsKind(SyntaxKind.Attribute)))
.Single();

Assert.Null(model.GetSymbolInfo(node).Symbol);
}
}
}

0 comments on commit 58d8ea0

Please sign in to comment.