Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speculative semantic model - create child member models for attributes and parameter default values. #64634

Merged
merged 5 commits into from
Oct 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1863,13 +1863,6 @@ private bool TryBindNameofOperator(InvocationExpressionSyntax node, BindingDiagn
if (node.MayBeNameofOperator())
{
var binder = this.GetBinder(node);
if (binder is null)
{
// This could happen during speculation due to a bug
// Tracked by https://github.com/dotnet/roslyn/issues/60801
result = null;
return false;
}
if (binder.EnclosingNameofArgument == node.ArgumentList.Arguments[0].Expression)
{
result = binder.BindNameofOperatorInternal(node, diagnostics);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,15 @@ internal sealed class AttributeSemanticModel : MemberSemanticModel
private readonly AliasSymbol _aliasOpt;
private readonly Symbol? _attributeTarget;

private AttributeSemanticModel(
internal AttributeSemanticModel(
AttributeSyntax syntax,
NamedTypeSymbol attributeType,
Symbol? attributeTarget,
AliasSymbol aliasOpt,
Binder rootBinder,
SyntaxTreeSemanticModel? containingSemanticModelOpt = null,
SyntaxTreeSemanticModel? parentSemanticModelOpt = null,
ImmutableDictionary<Symbol, Symbol>? parentRemappedSymbolsOpt = null,
int speculatedPosition = 0)
: base(syntax, attributeType, new ExecutableCodeBinder(syntax, rootBinder.ContainingMember(), rootBinder), containingSemanticModelOpt, parentSemanticModelOpt, snapshotManagerOpt: null, parentRemappedSymbolsOpt: parentRemappedSymbolsOpt, speculatedPosition)
PublicSemanticModel containingPublicSemanticModel,
ImmutableDictionary<Symbol, Symbol>? parentRemappedSymbolsOpt = null)
: base(syntax, attributeType, new ExecutableCodeBinder(syntax, rootBinder.ContainingMember(), rootBinder), containingPublicSemanticModel, parentRemappedSymbolsOpt)
{
Debug.Assert(syntax != null);
_aliasOpt = aliasOpt;
Expand All @@ -38,7 +36,7 @@ private AttributeSemanticModel(
/// <summary>
/// Creates an AttributeSemanticModel that allows asking semantic questions about an attribute node.
/// </summary>
public static AttributeSemanticModel Create(SyntaxTreeSemanticModel containingSemanticModel, AttributeSyntax syntax, NamedTypeSymbol attributeType, AliasSymbol aliasOpt, Symbol? attributeTarget, Binder rootBinder, ImmutableDictionary<Symbol, Symbol> parentRemappedSymbolsOpt)
public static AttributeSemanticModel Create(PublicSemanticModel containingSemanticModel, AttributeSyntax syntax, NamedTypeSymbol attributeType, AliasSymbol aliasOpt, Symbol? attributeTarget, Binder rootBinder, ImmutableDictionary<Symbol, Symbol>? parentRemappedSymbolsOpt)
{
rootBinder = attributeTarget is null ? rootBinder : new ContextualAttributeBinder(rootBinder, attributeTarget);
return new AttributeSemanticModel(syntax, attributeType, attributeTarget, aliasOpt, rootBinder, containingSemanticModel, parentRemappedSymbolsOpt: parentRemappedSymbolsOpt);
Expand All @@ -47,27 +45,9 @@ public static AttributeSemanticModel Create(SyntaxTreeSemanticModel containingSe
/// <summary>
/// Creates a speculative AttributeSemanticModel that allows asking semantic questions about an attribute node that did not appear in the original source code.
/// </summary>
public static AttributeSemanticModel CreateSpeculative(SyntaxTreeSemanticModel parentSemanticModel, AttributeSyntax syntax, NamedTypeSymbol attributeType, AliasSymbol aliasOpt, Binder rootBinder, ImmutableDictionary<Symbol, Symbol> parentRemappedSymbolsOpt, int position)
public static SpeculativeSemanticModelWithMemberModel CreateSpeculative(SyntaxTreeSemanticModel parentSemanticModel, AttributeSyntax syntax, NamedTypeSymbol attributeType, AliasSymbol aliasOpt, Binder rootBinder, ImmutableDictionary<Symbol, Symbol> parentRemappedSymbolsOpt, int position)
{
Debug.Assert(parentSemanticModel != null);
Debug.Assert(rootBinder != null);
Debug.Assert(rootBinder.IsSemanticModelBinder);

var attributeTarget = GetAttributeTargetFromPosition(position, parentSemanticModel);
return new AttributeSemanticModel(syntax, attributeType, attributeTarget, aliasOpt, rootBinder, parentSemanticModelOpt: parentSemanticModel, parentRemappedSymbolsOpt: parentRemappedSymbolsOpt, speculatedPosition: position);
}

private static Symbol? GetAttributeTargetFromPosition(int position, SemanticModel model)
{
var attributedNode = model.SyntaxTree.GetRoot().FindToken(position).Parent;
attributedNode = attributedNode?.FirstAncestorOrSelf<AttributeListSyntax>()?.Parent;

if (attributedNode is not null)
{
return model.GetDeclaredSymbolForNode(attributedNode).GetSymbol();
}

return null;
return new SpeculativeSemanticModelWithMemberModel(parentSemanticModel, position, syntax, attributeType, aliasOpt, rootBinder, parentRemappedSymbolsOpt);
}

private NamedTypeSymbol AttributeType
Expand Down Expand Up @@ -145,43 +125,43 @@ internal static bool IsNullableAnalysisEnabledIn(CSharpCompilation compilation,
return compilation.IsNullableAnalysisEnabledIn(syntax);
}

internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, ConstructorInitializerSyntax constructorInitializer, out SemanticModel? speculativeModel)
internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, ConstructorInitializerSyntax constructorInitializer, out PublicSemanticModel? speculativeModel)
{
speculativeModel = null;
return false;
}

internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, PrimaryConstructorBaseTypeSyntax constructorInitializer, out SemanticModel? speculativeModel)
internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, PrimaryConstructorBaseTypeSyntax constructorInitializer, out PublicSemanticModel? speculativeModel)
{
speculativeModel = null;
return false;
}

internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, EqualsValueClauseSyntax initializer, out SemanticModel? speculativeModel)
internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, EqualsValueClauseSyntax initializer, out PublicSemanticModel? speculativeModel)
{
speculativeModel = null;
return false;
}

internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, ArrowExpressionClauseSyntax expressionBody, out SemanticModel? speculativeModel)
internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, ArrowExpressionClauseSyntax expressionBody, out PublicSemanticModel? speculativeModel)
{
speculativeModel = null;
return false;
}

internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, StatementSyntax statement, out SemanticModel? speculativeModel)
internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, StatementSyntax statement, out PublicSemanticModel? speculativeModel)
{
speculativeModel = null;
return false;
}

internal override bool TryGetSpeculativeSemanticModelForMethodBodyCore(SyntaxTreeSemanticModel parentModel, int position, BaseMethodDeclarationSyntax method, out SemanticModel? speculativeModel)
internal override bool TryGetSpeculativeSemanticModelForMethodBodyCore(SyntaxTreeSemanticModel parentModel, int position, BaseMethodDeclarationSyntax method, out PublicSemanticModel? speculativeModel)
{
speculativeModel = null;
return false;
}

internal override bool TryGetSpeculativeSemanticModelForMethodBodyCore(SyntaxTreeSemanticModel parentModel, int position, AccessorDeclarationSyntax accessor, out SemanticModel? speculativeModel)
internal override bool TryGetSpeculativeSemanticModelForMethodBodyCore(SyntaxTreeSemanticModel parentModel, int position, AccessorDeclarationSyntax accessor, out PublicSemanticModel? speculativeModel)
{
speculativeModel = null;
return false;
Expand Down
54 changes: 36 additions & 18 deletions src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2505,10 +2505,12 @@ public virtual DataFlowAnalysis AnalyzeDataFlow(StatementSyntax statement)
public bool TryGetSpeculativeSemanticModelForMethodBody(int position, BaseMethodDeclarationSyntax method, out SemanticModel speculativeModel)
{
CheckModelAndSyntaxNodeToSpeculate(method);
return TryGetSpeculativeSemanticModelForMethodBodyCore((SyntaxTreeSemanticModel)this, position, method, out speculativeModel);
var result = TryGetSpeculativeSemanticModelForMethodBodyCore((SyntaxTreeSemanticModel)this, position, method, out PublicSemanticModel speculativeSyntaxTreeModel);
speculativeModel = speculativeSyntaxTreeModel;
return result;
}

internal abstract bool TryGetSpeculativeSemanticModelForMethodBodyCore(SyntaxTreeSemanticModel parentModel, int position, BaseMethodDeclarationSyntax method, out SemanticModel speculativeModel);
internal abstract bool TryGetSpeculativeSemanticModelForMethodBodyCore(SyntaxTreeSemanticModel parentModel, int position, BaseMethodDeclarationSyntax method, out PublicSemanticModel speculativeModel);

/// <summary>
/// Get a SemanticModel object that is associated with a method body that did not appear in this source code.
Expand All @@ -2530,10 +2532,12 @@ public bool TryGetSpeculativeSemanticModelForMethodBody(int position, BaseMethod
public bool TryGetSpeculativeSemanticModelForMethodBody(int position, AccessorDeclarationSyntax accessor, out SemanticModel speculativeModel)
{
CheckModelAndSyntaxNodeToSpeculate(accessor);
return TryGetSpeculativeSemanticModelForMethodBodyCore((SyntaxTreeSemanticModel)this, position, accessor, out speculativeModel);
var result = TryGetSpeculativeSemanticModelForMethodBodyCore((SyntaxTreeSemanticModel)this, position, accessor, out PublicSemanticModel speculativeSyntaxTreeModel);
speculativeModel = speculativeSyntaxTreeModel;
return result;
}

internal abstract bool TryGetSpeculativeSemanticModelForMethodBodyCore(SyntaxTreeSemanticModel parentModel, int position, AccessorDeclarationSyntax accessor, out SemanticModel speculativeModel);
internal abstract bool TryGetSpeculativeSemanticModelForMethodBodyCore(SyntaxTreeSemanticModel parentModel, int position, AccessorDeclarationSyntax accessor, out PublicSemanticModel speculativeModel);

/// <summary>
/// Get a SemanticModel object that is associated with a type syntax node that did not appear in
Expand All @@ -2557,10 +2561,12 @@ public bool TryGetSpeculativeSemanticModelForMethodBody(int position, AccessorDe
public bool TryGetSpeculativeSemanticModel(int position, TypeSyntax type, out SemanticModel speculativeModel, SpeculativeBindingOption bindingOption = SpeculativeBindingOption.BindAsExpression)
{
CheckModelAndSyntaxNodeToSpeculate(type);
return TryGetSpeculativeSemanticModelCore((SyntaxTreeSemanticModel)this, position, type, bindingOption, out speculativeModel);
var result = TryGetSpeculativeSemanticModelCore((SyntaxTreeSemanticModel)this, position, type, bindingOption, out PublicSemanticModel speculativeSyntaxTreeModel);
speculativeModel = speculativeSyntaxTreeModel;
return result;
}

internal abstract bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, TypeSyntax type, SpeculativeBindingOption bindingOption, out SemanticModel speculativeModel);
internal abstract bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, TypeSyntax type, SpeculativeBindingOption bindingOption, out PublicSemanticModel speculativeModel);

/// <summary>
/// Get a SemanticModel object that is associated with a statement that did not appear in
Expand All @@ -2581,10 +2587,12 @@ public bool TryGetSpeculativeSemanticModel(int position, TypeSyntax type, out Se
public bool TryGetSpeculativeSemanticModel(int position, StatementSyntax statement, out SemanticModel speculativeModel)
{
CheckModelAndSyntaxNodeToSpeculate(statement);
return TryGetSpeculativeSemanticModelCore((SyntaxTreeSemanticModel)this, position, statement, out speculativeModel);
var result = TryGetSpeculativeSemanticModelCore((SyntaxTreeSemanticModel)this, position, statement, out PublicSemanticModel speculativeSyntaxTreeModel);
speculativeModel = speculativeSyntaxTreeModel;
return result;
}

internal abstract bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, StatementSyntax statement, out SemanticModel speculativeModel);
internal abstract bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, StatementSyntax statement, out PublicSemanticModel speculativeModel);

/// <summary>
/// Get a SemanticModel object that is associated with an initializer that did not appear in
Expand All @@ -2606,10 +2614,12 @@ public bool TryGetSpeculativeSemanticModel(int position, StatementSyntax stateme
public bool TryGetSpeculativeSemanticModel(int position, EqualsValueClauseSyntax initializer, out SemanticModel speculativeModel)
{
CheckModelAndSyntaxNodeToSpeculate(initializer);
return TryGetSpeculativeSemanticModelCore((SyntaxTreeSemanticModel)this, position, initializer, out speculativeModel);
var result = TryGetSpeculativeSemanticModelCore((SyntaxTreeSemanticModel)this, position, initializer, out PublicSemanticModel speculativeSyntaxTreeModel);
speculativeModel = speculativeSyntaxTreeModel;
return result;
}

internal abstract bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, EqualsValueClauseSyntax initializer, out SemanticModel speculativeModel);
internal abstract bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, EqualsValueClauseSyntax initializer, out PublicSemanticModel speculativeModel);

/// <summary>
/// Get a SemanticModel object that is associated with an expression body that did not appear in
Expand All @@ -2631,10 +2641,12 @@ public bool TryGetSpeculativeSemanticModel(int position, EqualsValueClauseSyntax
public bool TryGetSpeculativeSemanticModel(int position, ArrowExpressionClauseSyntax expressionBody, out SemanticModel speculativeModel)
{
CheckModelAndSyntaxNodeToSpeculate(expressionBody);
return TryGetSpeculativeSemanticModelCore((SyntaxTreeSemanticModel)this, position, expressionBody, out speculativeModel);
var result = TryGetSpeculativeSemanticModelCore((SyntaxTreeSemanticModel)this, position, expressionBody, out PublicSemanticModel speculativeSyntaxTreeModel);
speculativeModel = speculativeSyntaxTreeModel;
return result;
}

internal abstract bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, ArrowExpressionClauseSyntax expressionBody, out SemanticModel speculativeModel);
internal abstract bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, ArrowExpressionClauseSyntax expressionBody, out PublicSemanticModel speculativeModel);

/// <summary>
/// Get a SemanticModel object that is associated with a constructor initializer that did not appear in
Expand All @@ -2659,10 +2671,12 @@ public bool TryGetSpeculativeSemanticModel(int position, ArrowExpressionClauseSy
public bool TryGetSpeculativeSemanticModel(int position, ConstructorInitializerSyntax constructorInitializer, out SemanticModel speculativeModel)
{
CheckModelAndSyntaxNodeToSpeculate(constructorInitializer);
return TryGetSpeculativeSemanticModelCore((SyntaxTreeSemanticModel)this, position, constructorInitializer, out speculativeModel);
var result = TryGetSpeculativeSemanticModelCore((SyntaxTreeSemanticModel)this, position, constructorInitializer, out PublicSemanticModel speculativeSyntaxTreeModel);
speculativeModel = speculativeSyntaxTreeModel;
return result;
}

internal abstract bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, ConstructorInitializerSyntax constructorInitializer, out SemanticModel speculativeModel);
internal abstract bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, ConstructorInitializerSyntax constructorInitializer, out PublicSemanticModel speculativeModel);

/// <summary>
/// Get a SemanticModel object that is associated with a constructor initializer that did not appear in
Expand All @@ -2686,10 +2700,12 @@ public bool TryGetSpeculativeSemanticModel(int position, ConstructorInitializerS
public bool TryGetSpeculativeSemanticModel(int position, PrimaryConstructorBaseTypeSyntax constructorInitializer, out SemanticModel speculativeModel)
{
CheckModelAndSyntaxNodeToSpeculate(constructorInitializer);
return TryGetSpeculativeSemanticModelCore((SyntaxTreeSemanticModel)this, position, constructorInitializer, out speculativeModel);
var result = TryGetSpeculativeSemanticModelCore((SyntaxTreeSemanticModel)this, position, constructorInitializer, out PublicSemanticModel speculativeSyntaxTreeModel);
speculativeModel = speculativeSyntaxTreeModel;
return result;
}

internal abstract bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, PrimaryConstructorBaseTypeSyntax constructorInitializer, out SemanticModel speculativeModel);
internal abstract bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, PrimaryConstructorBaseTypeSyntax constructorInitializer, out PublicSemanticModel speculativeModel);

/// <summary>
/// Get a SemanticModel object that is associated with a cref that did not appear in
Expand All @@ -2714,10 +2730,12 @@ public bool TryGetSpeculativeSemanticModel(int position, PrimaryConstructorBaseT
public bool TryGetSpeculativeSemanticModel(int position, CrefSyntax crefSyntax, out SemanticModel speculativeModel)
{
CheckModelAndSyntaxNodeToSpeculate(crefSyntax);
return TryGetSpeculativeSemanticModelCore((SyntaxTreeSemanticModel)this, position, crefSyntax, out speculativeModel);
var result = TryGetSpeculativeSemanticModelCore((SyntaxTreeSemanticModel)this, position, crefSyntax, out PublicSemanticModel speculativeSyntaxTreeModel);
speculativeModel = speculativeSyntaxTreeModel;
return result;
}

internal abstract bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, CrefSyntax crefSyntax, out SemanticModel speculativeModel);
internal abstract bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, CrefSyntax crefSyntax, out PublicSemanticModel speculativeModel);

/// <summary>
/// Get a SemanticModel object that is associated with an attribute that did not appear in
Expand Down
Loading