private SpeculativeSyntaxTreeSemanticModel(CSharpSemanticModel parentSemanticModel, CSharpSyntaxNode root, Binder rootBinder, int position, SpeculativeBindingOption bindingOption) : base(parentSemanticModel.Compilation, parentSemanticModel.SyntaxTree, root.SyntaxTree) { this.parentSemanticModel = parentSemanticModel; this.root = root; this.rootBinder = rootBinder; this.position = position; this.bindingOption = bindingOption; }
private SpeculativeSyntaxTreeSemanticModel(SyntaxTreeSemanticModel parentSemanticModel, LanguageSyntaxNode root, Binder rootBinder, int position, SpeculativeBindingOption bindingOption) : base(parentSemanticModel.Compilation, (LanguageSyntaxTree)parentSemanticModel.SyntaxTree, (LanguageSyntaxTree)root.SyntaxTree) { _parentSemanticModel = parentSemanticModel; _root = root; _rootBinder = rootBinder; _position = position; _bindingOption = bindingOption; }
public static SemanticInfoSummary GetSpeculativeSemanticInfoSummary( this SemanticModel semanticModel, int position, SyntaxNode node, SpeculativeBindingOption bindingOption ) { SemanticInfoSummary summary = new SemanticInfoSummary(); // The information that is available varies by the type of the syntax node. SymbolInfo symbolInfo = new SymbolInfo(); if (node is ExpressionSyntax) { ExpressionSyntax expr = (ExpressionSyntax)node; symbolInfo = semanticModel.GetSpeculativeSymbolInfo(position, expr, bindingOption); //summary.ConstantValue = semanticModel.GetSpeculativeConstantValue(expr); var typeInfo = semanticModel.GetSpeculativeTypeInfo(position, expr, bindingOption); summary.Type = typeInfo.Type; summary.ConvertedType = typeInfo.ConvertedType; summary.Nullability = typeInfo.Nullability; summary.ConvertedNullability = typeInfo.ConvertedNullability; summary.ImplicitConversion = semanticModel.GetSpeculativeConversion( position, expr, bindingOption ); //summary.MethodGroup = semanticModel.GetSpeculativeMethodGroup(expr); } else if (node is ConstructorInitializerSyntax) { var initializer = (ConstructorInitializerSyntax)node; symbolInfo = semanticModel.GetSpeculativeSymbolInfo(position, initializer); } else { throw new NotSupportedException( "Type of syntax node is not supported by GetSemanticInfoSummary" ); } summary.Symbol = symbolInfo.Symbol; summary.CandidateReason = symbolInfo.CandidateReason; summary.CandidateSymbols = symbolInfo.CandidateSymbols; if (node is IdentifierNameSyntax) { summary.Alias = semanticModel.GetSpeculativeAliasInfo( position, (IdentifierNameSyntax)node, bindingOption ); } return(summary); }
/// <summary> /// Binds the node in the context of the specified location and get semantic information /// such as type, symbols and diagnostics. This method is used to get semantic information /// about an expression that did not actually appear in the source code. /// </summary> /// <param name="semanticModel"></param> /// <param name="position">A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// </param> /// <param name="expression">A syntax node that represents a parsed expression. This syntax /// node need not and typically does not appear in the source code referred to SemanticModel /// instance.</param> /// <param name="bindingOption">Indicates whether to binding the expression as a full expressions, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax.</param> /// <returns>The semantic information for the topmost node of the expression.</returns> /// <remarks>The passed in expression is interpreted as a stand-alone expression, as if it /// appeared by itself somewhere within the scope that encloses "position".</remarks> public static SymbolInfo GetSpeculativeSymbolInfo( this SemanticModel semanticModel, int position, SyntaxNode expression, SpeculativeBindingOption bindingOption ) { return(semanticModel.GetSpeculativeSymbolInfo(position, expression, bindingOption)); }
/// <summary> /// Binds the name in the context of the specified location and sees if it resolves to an /// alias name. If it does, return the AliasSymbol corresponding to it. Otherwise, return null. /// </summary> /// <param name="semanticModel"></param> /// <param name="position">A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// </param> /// <param name="nameSyntax">A syntax node that represents a name. This syntax /// node need not and typically does not appear in the source code referred to by the /// SemanticModel instance.</param> /// <param name="bindingOption">Indicates whether to binding the name as a full expression, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax.</param> /// <remarks>The passed in name is interpreted as a stand-alone name, as if it /// appeared by itself somewhere within the scope that encloses "position".</remarks> public static IAliasSymbol?GetSpeculativeAliasInfo( this SemanticModel semanticModel, int position, SyntaxNode nameSyntax, SpeculativeBindingOption bindingOption ) { return(semanticModel.GetSpeculativeAliasInfo(position, nameSyntax, bindingOption)); }
public static SpeculativeSyntaxTreeSemanticModel Create( SyntaxTreeSemanticModel parentSemanticModel, TypeSyntax root, Binder rootBinder, int position, SpeculativeBindingOption bindingOption ) { return(CreateCore(parentSemanticModel, root, rootBinder, position, bindingOption)); }
private static SpeculativeSyntaxTreeSemanticModel CreateCore(CSharpSemanticModel parentSemanticModel, CSharpSyntaxNode root, Binder rootBinder, int position, SpeculativeBindingOption bindingOption) { Debug.Assert(parentSemanticModel is SyntaxTreeSemanticModel); Debug.Assert(root != null); Debug.Assert(root is TypeSyntax || root is CrefSyntax); Debug.Assert(rootBinder != null); Debug.Assert(rootBinder.IsSemanticModelBinder); var speculativeModel = new SpeculativeSyntaxTreeSemanticModel(parentSemanticModel, root, rootBinder, position, bindingOption); return speculativeModel; }
private static SpeculativeSyntaxTreeSemanticModel CreateCore( SyntaxTreeSemanticModel parentSemanticModel, CSharpSyntaxNode root, Binder rootBinder, int position, SpeculativeBindingOption bindingOption ) { Debug.Assert(parentSemanticModel is SyntaxTreeSemanticModel); Debug.Assert(root != null); Debug.Assert(root is TypeSyntax || root is CrefSyntax); Debug.Assert(rootBinder != null); Debug.Assert(rootBinder.IsSemanticModelBinder); var speculativeModel = new SpeculativeSyntaxTreeSemanticModel( parentSemanticModel, root, rootBinder, position, bindingOption ); return(speculativeModel); }
/// <summary> /// Binds the node in the context of the specified location and get semantic information /// such as type, symbols and diagnostics. This method is used to get semantic information /// about an expression that did not actually appear in the source code. /// </summary> /// <param name="position">A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// </param> /// <param name="expression">A syntax node that represents a parsed expression. This syntax /// node need not and typically does not appear in the source code referred to SemanticModel /// instance.</param> /// <param name="bindingOption">Indicates whether to binding the expression as a full expressions, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax.</param> /// <returns>The semantic information for the topmost node of the expression.</returns> /// <remarks>The passed in expression is interpreted as a stand-alone expression, as if it /// appeared by itself somewhere within the scope that encloses "position".</remarks> protected abstract SymbolInfo GetSpeculativeSymbolInfoCore(int position, GreenNode expression, SpeculativeBindingOption bindingOption);
/// <summary> /// Binds the name in the context of the specified location and sees if it resolves to an /// alias name. If it does, return the AliasSymbol corresponding to it. Otherwise, return null. /// </summary> /// <param name="semanticModel"></param> /// <param name="position">A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// </param> /// <param name="nameSyntax">A syntax node that represents a name. This syntax /// node need not and typically does not appear in the source code referred to by the /// SemanticModel instance.</param> /// <param name="bindingOption">Indicates whether to binding the name as a full expression, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax.</param> /// <remarks>The passed in name is interpreted as a stand-alone name, as if it /// appeared by itself somewhere within the scope that encloses "position".</remarks> public static IAliasSymbol GetSpeculativeAliasInfo(this SemanticModel semanticModel, int position, SyntaxNode nameSyntax, SpeculativeBindingOption bindingOption) { return semanticModel.GetSpeculativeAliasInfo(position, nameSyntax, bindingOption); }
internal sealed override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, LanguageSyntaxNode type, SpeculativeBindingOption bindingOption, out SemanticModel speculativeModel) { var expression = SyntaxFactory.GetStandaloneNode(type); var binder = this.GetSpeculativeBinder(position, expression, bindingOption); if (binder != null) { speculativeModel = new SpeculativeMemberSemanticModel(parentModel, _memberSymbol, type, binder, position); return(true); } speculativeModel = null; return(false); }
/// <summary> /// Binds the name in the context of the specified location and sees if it resolves to an /// alias name. If it does, return the AliasSymbol corresponding to it. Otherwise, return null. /// </summary> /// <param name="position">A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// </param> /// <param name="nameSyntax">A syntax node that represents a name. This syntax /// node need not and typically does not appear in the source code referred to by the /// SemanticModel instance.</param> /// <param name="bindingOption">Indicates whether to binding the name as a full expression, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax.</param> /// <remarks>The passed in name is interpreted as a stand-alone name, as if it /// appeared by itself somewhere within the scope that encloses "position".</remarks> internal IAliasSymbol GetSpeculativeAliasInfo(int position, SyntaxNode nameSyntax, SpeculativeBindingOption bindingOption) { return GetSpeculativeAliasInfoCore(position, nameSyntax, bindingOption); }
internal sealed override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, TypeSyntax type, SpeculativeBindingOption bindingOption, out SemanticModel speculativeModel) { var expression = SyntaxFactory.GetStandaloneExpression(type); var binder = this.GetSpeculativeBinder(position, expression, bindingOption); if (binder != null) { speculativeModel = new SpeculativeMemberSemanticModel(parentModel, _memberSymbol, type, binder, position); return true; } speculativeModel = null; return false; }
/// <summary> /// Gets the conversion that occurred between the expression's type and type implied by the expression's context. /// </summary> public Conversion GetSpeculativeConversion(int position, ExpressionSyntax expression, SpeculativeBindingOption bindingOption) { var info = this.GetSpeculativeTypeInfoWorker(position, expression, bindingOption); return info.ImplicitConversion; }
/// <summary> /// Binds the node in the context of the specified location and get semantic information /// such as type, symbols and diagnostics. This method is used to get semantic information /// about an expression that did not actually appear in the source code. /// </summary> /// <param name="position">A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// </param> /// <param name="expression">A syntax node that represents a parsed expression. This syntax /// node need not and typically does not appear in the source code referred to SemanticModel /// instance.</param> /// <param name="bindingOption">Indicates whether to binding the expression as a full expressions, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax.</param> /// <returns>The semantic information for the topmost node of the expression.</returns> /// <remarks>The passed in expression is interpreted as a stand-alone expression, as if it /// appeared by itself somewhere within the scope that encloses "position".</remarks> internal TypeInfo GetSpeculativeTypeInfo(int position, SyntaxNode expression, SpeculativeBindingOption bindingOption) { return GetSpeculativeTypeInfoCore(position, expression, bindingOption); }
internal Binder GetSpeculativeBinder(int position, ExpressionSyntax expression, SpeculativeBindingOption bindingOption) { Debug.Assert(expression != null); position = CheckAndAdjustPosition(position); if (bindingOption == SpeculativeBindingOption.BindAsTypeOrNamespace) { if (!(expression is TypeSyntax)) { return null; } } Binder binder = this.GetEnclosingBinder(position); if (binder == null) { return null; } if (bindingOption == SpeculativeBindingOption.BindAsTypeOrNamespace && IsInTypeofExpression(position)) { // If position is within a typeof expression, GetEnclosingBinder may return a // TypeofBinder. However, this TypeofBinder will have been constructed with the // actual syntax of the typeof argument and we want to use the given syntax. // Wrap the binder in another TypeofBinder to overrule its description of where // unbound generic types are allowed. //Debug.Assert(binder is TypeofBinder); // Expectation, not requirement. binder = new TypeofBinder(expression, binder); } // May be binding an expression in a context that doesn't have a LocalScopeBinder in the chain. return new LocalScopeBinder(binder); }
/// <summary> /// Get a SemanticModel object that is associated with a type syntax node that did not appear in /// this source code. This can be used to get detailed semantic information about sub-parts /// of a type syntax that did not appear in source code. /// </summary> /// <param name="position">A character position used to identify a declaration scope and accessibility. This /// character position must be within the FullSpan of the Root syntax node in this SemanticModel. /// </param> /// <param name="type">A syntax node that represents a parsed expression. This expression should not be /// present in the syntax tree associated with this object.</param> /// <param name="bindingOption">Indicates whether to bind the expression as a full expression, /// or as a type or namespace.</param> /// <param name="speculativeModel">A SemanticModel object that can be used to inquire about the semantic /// information associated with syntax nodes within <paramref name="type"/>.</param> /// <returns>Flag indicating whether a speculative semantic model was created.</returns> /// <exception cref="ArgumentException">Throws this exception if the <paramref name="type"/> node is contained any SyntaxTree in the current Compilation</exception> /// <exception cref="ArgumentNullException">Throws this exception if <paramref name="type"/> is null.</exception> /// <exception cref="InvalidOperationException">Throws this exception if this model is a speculative semantic model, i.e. <see cref="SemanticModel.IsSpeculativeSemanticModel"/> is true. /// Chaining of speculative semantic model is not supported.</exception> 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); }
/// <summary> /// Binds the name in the context of the specified location and sees if it resolves to an /// alias name. If it does, return the AliasSymbol corresponding to it. Otherwise, return null. /// </summary> /// <param name="position">A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// </param> /// <param name="nameSyntax">A syntax node that represents a name. This syntax /// node need not and typically does not appear in the source code referred to by the /// SemanticModel instance.</param> /// <param name="bindingOption">Indicates whether to binding the name as a full expression, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax.</param> /// <remarks>The passed in name is interpreted as a stand-alone name, as if it /// appeared by itself somewhere within the scope that encloses "position".</remarks> internal IAliasSymbol GetSpeculativeAliasInfo(int position, SyntaxNode nameSyntax, SpeculativeBindingOption bindingOption) { return(GetSpeculativeAliasInfoCore(position, nameSyntax, bindingOption)); }
/// <summary> /// Binds the name in the context of the specified location and sees if it resolves to an /// alias name. If it does, return the AliasSymbol corresponding to it. Otherwise, return null. /// </summary> /// <param name="position">A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// </param> /// <param name="nameSyntax">A syntax node that represents a name. This syntax /// node need not and typically does not appear in the source code referred to by the /// SemanticModel instance.</param> /// <param name="bindingOption">Indicates whether to binding the name as a full expression, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax.</param> /// <remarks>The passed in name is interpreted as a stand-alone name, as if it /// appeared by itself somewhere within the scope that encloses "position".</remarks> protected abstract IAliasSymbol GetSpeculativeAliasInfoCore(int position, SyntaxNode nameSyntax, SpeculativeBindingOption bindingOption);
/// <summary> /// Binds the node in the context of the specified location and get semantic information /// such as type, symbols and diagnostics. This method is used to get semantic information /// about an expression that did not actually appear in the source code. /// </summary> /// <param name="position">A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// </param> /// <param name="expression">A syntax node that represents a parsed expression. This syntax /// node need not and typically does not appear in the source code referred to SemanticModel /// instance.</param> /// <param name="bindingOption">Indicates whether to binding the expression as a full expressions, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax.</param> /// <returns>The semantic information for the topmost node of the expression.</returns> /// <remarks>The passed in expression is interpreted as a stand-alone expression, as if it /// appeared by itself somewhere within the scope that encloses "position".</remarks> protected abstract TypeInfo GetSpeculativeTypeInfoCore(int position, SyntaxNode expression, SpeculativeBindingOption bindingOption);
/// <summary> /// Binds the node in the context of the specified location and get semantic information /// such as type, symbols and diagnostics. This method is used to get semantic information /// about an expression that did not actually appear in the source code. /// </summary> /// <param name="position">A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// </param> /// <param name="expression">A syntax node that represents a parsed expression. This syntax /// node need not and typically does not appear in the source code referred to SemanticModel /// instance.</param> /// <param name="bindingOption">Indicates whether to binding the expression as a full expressions, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax.</param> /// <returns>The semantic information for the topmost node of the expression.</returns> /// <remarks>The passed in expression is interpreted as a stand-alone expression, as if it /// appeared by itself somewhere within the scope that encloses "position".</remarks> internal TypeInfo GetSpeculativeTypeInfo(int position, SyntaxNode expression, SpeculativeBindingOption bindingOption) { return(GetSpeculativeTypeInfoCore(position, expression, bindingOption)); }
/// <summary> /// Binds the node in the context of the specified location and get semantic information /// such as type, symbols and diagnostics. This method is used to get semantic information /// about an expression that did not actually appear in the source code. /// </summary> /// <param name="position">A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// </param> /// <param name="expression">A syntax node that represents a parsed expression. This syntax /// node need not and typically does not appear in the source code referred to SemanticModel /// instance.</param> /// <param name="bindingOption">Indicates whether to binding the expression as a full expressions, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax.</param> /// <returns>The semantic information for the topmost node of the expression.</returns> /// <remarks>The passed in expression is interpreted as a stand-alone expression, as if it /// appeared by itself somewhere within the scope that encloses "position".</remarks> public TypeInfo GetSpeculativeTypeInfo(int position, GreenNode expression, SpeculativeBindingOption bindingOption) { return(GetSpeculativeTypeInfoCore(position, expression, bindingOption)); }
/// <summary> /// Binds the expression in the context of the specified location and gets type information. /// This method is used to get type information about an expression that did not actually /// appear in the source code. /// </summary> /// <param name="position">A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// </param> /// <param name="expression">A syntax node that represents a parsed expression. This syntax /// node need not and typically does not appear in the source code referred to by the /// SemanticModel instance.</param> /// <param name="bindingOption">Indicates whether to binding the expression as a full expressions, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax.</param> /// <returns>The type information for the topmost node of the expression.</returns> /// <remarks>The passed in expression is interpreted as a stand-alone expression, as if it /// appeared by itself somewhere within the scope that encloses "position".</remarks> public TypeInfo GetSpeculativeTypeInfo(int position, ExpressionSyntax expression, SpeculativeBindingOption bindingOption) { return GetSpeculativeTypeInfoWorker(position, expression, bindingOption); }
internal abstract bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, TypeSyntax type, SpeculativeBindingOption bindingOption, out SemanticModel speculativeModel);
internal CSharpTypeInfo GetSpeculativeTypeInfoWorker(int position, ExpressionSyntax expression, SpeculativeBindingOption bindingOption) { if (!CanGetSemanticInfo(expression, isSpeculative: true)) { return CSharpTypeInfo.None; } Binder binder; ImmutableArray<Symbol> crefSymbols; BoundNode boundNode = GetSpeculativelyBoundExpression(position, expression, bindingOption, out binder, out crefSymbols); //calls CheckAndAdjustPosition Debug.Assert(boundNode == null || crefSymbols.IsDefault); if (boundNode == null) { return !crefSymbols.IsDefault && crefSymbols.Length == 1 ? GetTypeInfoForSymbol(crefSymbols[0]) : CSharpTypeInfo.None; } var typeInfo = GetTypeInfoForNode(boundNode, boundNode, boundNodeForSyntacticParent: null); return typeInfo; }
private static BoundExpression GetSpeculativelyBoundExpressionHelper(Binder binder, ExpressionSyntax expression, SpeculativeBindingOption bindingOption, DiagnosticBag diagnostics) { Debug.Assert(binder != null); Debug.Assert(binder.IsSemanticModelBinder); Debug.Assert(expression != null); Debug.Assert(bindingOption != SpeculativeBindingOption.BindAsTypeOrNamespace || expression is TypeSyntax); BoundExpression boundNode; if (bindingOption == SpeculativeBindingOption.BindAsTypeOrNamespace || binder.Flags.Includes(BinderFlags.CrefParameterOrReturnType)) { boundNode = binder.BindNamespaceOrType(expression, diagnostics); } else { Debug.Assert(bindingOption == SpeculativeBindingOption.BindAsExpression); boundNode = binder.BindExpression(expression, diagnostics); } return boundNode; }
/// <summary> /// Binds the name in the context of the specified location and sees if it resolves to an /// alias name. If it does, return the AliasSymbol corresponding to it. Otherwise, return null. /// </summary> /// <param name="position">A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// </param> /// <param name="nameSyntax">A syntax node that represents a name. This syntax /// node need not and typically does not appear in the source code referred to by the /// SemanticModel instance.</param> /// <param name="bindingOption">Indicates whether to binding the name as a full expression, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax.</param> /// <remarks>The passed in name is interpreted as a stand-alone name, as if it /// appeared by itself somewhere within the scope that encloses "position".</remarks> public IAliasSymbol GetSpeculativeAliasInfo(int position, IdentifierNameSyntax nameSyntax, SpeculativeBindingOption bindingOption) { Binder binder; ImmutableArray<Symbol> crefSymbols; BoundNode boundNode = GetSpeculativelyBoundExpression(position, nameSyntax, bindingOption, out binder, out crefSymbols); //calls CheckAndAdjustPosition Debug.Assert(boundNode == null || crefSymbols.IsDefault); if (boundNode == null) { return !crefSymbols.IsDefault && crefSymbols.Length == 1 ? crefSymbols[0] as AliasSymbol : null; } var symbolInfo = this.GetSymbolInfoForNode(SymbolInfoOptions.PreferTypeToConstructors | SymbolInfoOptions.PreserveAliases, boundNode, boundNode, boundNodeForSyntacticParent: null, binderOpt: binder); return symbolInfo.Symbol as AliasSymbol; }
internal sealed override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, TypeSyntax type, SpeculativeBindingOption bindingOption, out SemanticModel speculativeModel) { position = CheckAndAdjustPosition(position); var model = this.GetMemberModel(position); if (model != null) { return model.TryGetSpeculativeSemanticModelCore(parentModel, position, type, bindingOption, out speculativeModel); } Binder binder = GetSpeculativeBinder(position, type, bindingOption); if (binder != null) { speculativeModel = SpeculativeSyntaxTreeSemanticModel.Create(parentModel, type, binder, position, bindingOption); return true; } speculativeModel = null; return false; }
internal sealed override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, LanguageSyntaxNode node, SpeculativeBindingOption bindingOption, out SemanticModel speculativeModel) { position = CheckAndAdjustPosition(position); var model = this.GetMemberModel(position); if (model != null) { return(model.TryGetSpeculativeSemanticModelCore(parentModel, position, node, bindingOption, out speculativeModel)); } Binder binder = GetSpeculativeBinder(position, node, bindingOption); if (binder != null) { speculativeModel = SpeculativeSyntaxTreeSemanticModel.Create(parentModel, node, binder, position, bindingOption); return(true); } speculativeModel = null; return(false); }
protected sealed override TypeInfo GetSpeculativeTypeInfoCore(int position, SyntaxNode expression, SpeculativeBindingOption bindingOption) { return expression is ExpressionSyntax ? GetSpeculativeTypeInfo(position, (ExpressionSyntax)expression, bindingOption) : default(TypeInfo); }
/// <summary> /// Binds the node in the context of the specified location and get semantic information /// such as type, symbols and diagnostics. This method is used to get semantic information /// about an expression that did not actually appear in the source code. /// </summary> /// <param name="semanticModel"></param> /// <param name="position">A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// </param> /// <param name="expression">A syntax node that represents a parsed expression. This syntax /// node need not and typically does not appear in the source code referred to SemanticModel /// instance.</param> /// <param name="bindingOption">Indicates whether to binding the expression as a full expressions, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax.</param> /// <returns>The semantic information for the topmost node of the expression.</returns> /// <remarks>The passed in expression is interpreted as a stand-alone expression, as if it /// appeared by itself somewhere within the scope that encloses "position".</remarks> public static SymbolInfo GetSpeculativeSymbolInfo(this SemanticModel semanticModel, int position, SyntaxNode expression, SpeculativeBindingOption bindingOption) { return semanticModel.GetSpeculativeSymbolInfo(position, expression, bindingOption); }
protected sealed override IAliasSymbol GetSpeculativeAliasInfoCore(int position, SyntaxNode nameSyntax, SpeculativeBindingOption bindingOption) { return (nameSyntax is IdentifierNameSyntax) ? GetSpeculativeAliasInfo(position, (IdentifierNameSyntax)nameSyntax, bindingOption) : null; }
private static void TestGetSpeculativeSemanticModelForTypeSyntax_Common( SemanticModel model, int position, TypeSyntax speculatedTypeSyntax, SpeculativeBindingOption bindingOption, SymbolKind expectedSymbolKind, string expectedTypeDislayString) { Assert.False(model.IsSpeculativeSemanticModel); Assert.Null(model.ParentModel); Assert.Equal(0, model.OriginalPositionForSpeculation); SemanticModel speculativeModel; var success = model.TryGetSpeculativeSemanticModel(position, speculatedTypeSyntax, out speculativeModel, bindingOption); Assert.True(success); Assert.NotNull(speculativeModel); Assert.True(speculativeModel.IsSpeculativeSemanticModel); Assert.Equal(model, speculativeModel.ParentModel); Assert.NotNull(speculativeModel); Assert.Equal(position, speculativeModel.OriginalPositionForSpeculation); var symbol = speculativeModel.GetSymbolInfo(speculatedTypeSyntax).Symbol; Assert.NotNull(symbol); Assert.Equal(expectedSymbolKind, symbol.Kind); Assert.Equal(expectedTypeDislayString, symbol.ToDisplayString()); var typeSymbol = speculativeModel.GetTypeInfo(speculatedTypeSyntax).Type; Assert.NotNull(symbol); Assert.Equal(expectedSymbolKind, symbol.Kind); Assert.Equal(expectedTypeDislayString, symbol.ToDisplayString()); if (speculatedTypeSyntax.Kind == SyntaxKind.QualifiedName) { var right = ((QualifiedNameSyntax)speculatedTypeSyntax).Right; symbol = speculativeModel.GetSymbolInfo(right).Symbol; Assert.NotNull(symbol); Assert.Equal(expectedSymbolKind, symbol.Kind); Assert.Equal(expectedTypeDislayString, symbol.ToDisplayString()); typeSymbol = speculativeModel.GetTypeInfo(right).Type; Assert.NotNull(symbol); Assert.Equal(expectedSymbolKind, symbol.Kind); Assert.Equal(expectedTypeDislayString, symbol.ToDisplayString()); } }
/// <summary> /// Binds the expression in the context of the specified location and gets symbol information. /// This method is used to get symbol information about an expression that did not actually /// appear in the source code. /// </summary> /// <param name="position">A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// </param> /// <param name="expression">A syntax node that represents a parsed expression. This syntax /// node need not and typically does not appear in the source code referred to by the /// SemanticModel instance.</param> /// <param name="bindingOption">Indicates whether to binding the expression as a full expressions, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax.</param> /// <returns>The symbol information for the topmost node of the expression.</returns> /// <remarks> /// The passed in expression is interpreted as a stand-alone expression, as if it /// appeared by itself somewhere within the scope that encloses "position". /// /// <paramref name="bindingOption"/> is ignored if <paramref name="position"/> is within a documentation /// comment cref attribute value. /// </remarks> public SymbolInfo GetSpeculativeSymbolInfo(int position, ExpressionSyntax expression, SpeculativeBindingOption bindingOption) { if (!CanGetSemanticInfo(expression, isSpeculative: true)) return SymbolInfo.None; Binder binder; ImmutableArray<Symbol> crefSymbols; BoundNode boundNode = GetSpeculativelyBoundExpression(position, expression, bindingOption, out binder, out crefSymbols); //calls CheckAndAdjustPosition Debug.Assert(boundNode == null || crefSymbols.IsDefault); if (boundNode == null) { return crefSymbols.IsDefault ? SymbolInfo.None : GetCrefSymbolInfo(crefSymbols, SymbolInfoOptions.DefaultOptions, hasParameterList: false); } var symbolInfo = this.GetSymbolInfoForNode(SymbolInfoOptions.DefaultOptions, boundNode, boundNode, boundNodeForSyntacticParent: null, binderOpt: binder); return symbolInfo; }
/// <summary> /// Binds the node in the context of the specified location and get semantic information /// such as type, symbols and diagnostics. This method is used to get semantic information /// about an expression that did not actually appear in the source code. /// </summary> /// <param name="position">A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// </param> /// <param name="expression">A syntax node that represents a parsed expression. This syntax /// node need not and typically does not appear in the source code referred to SemanticModel /// instance.</param> /// <param name="bindingOption">Indicates whether to binding the expression as a full expressions, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax.</param> /// <returns>The semantic information for the topmost node of the expression.</returns> /// <remarks>The passed in expression is interpreted as a stand-alone expression, as if it /// appeared by itself somewhere within the scope that encloses "position".</remarks> internal SymbolInfo GetSpeculativeSymbolInfo(int position, SyntaxNode expression, SpeculativeBindingOption bindingOption) { return GetSpeculativeSymbolInfoCore(position, expression, bindingOption); }
public static SpeculativeSyntaxTreeSemanticModel Create(CSharpSemanticModel parentSemanticModel, TypeSyntax root, Binder rootBinder, int position, SpeculativeBindingOption bindingOption) { return CreateCore(parentSemanticModel, root, rootBinder, position, bindingOption); }
/// <summary> /// Bind the given expression speculatively at the given position, and return back /// the resulting bound node. May return null in some error cases. /// </summary> /// <remarks> /// Keep in sync with Binder.BindCrefParameterOrReturnType. /// </remarks> private BoundExpression GetSpeculativelyBoundExpression(int position, ExpressionSyntax expression, SpeculativeBindingOption bindingOption, out Binder binder, out ImmutableArray<Symbol> crefSymbols) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } crefSymbols = default(ImmutableArray<Symbol>); expression = SyntaxFactory.GetStandaloneExpression(expression); binder = this.GetSpeculativeBinder(position, expression, bindingOption); if (binder == null) { return null; } if (binder.Flags.Includes(BinderFlags.CrefParameterOrReturnType)) { var unusedDiagnostics = DiagnosticBag.GetInstance(); crefSymbols = ImmutableArray.Create<Symbol>(binder.BindType(expression, unusedDiagnostics)); unusedDiagnostics.Free(); return null; } else if (binder.InCref) { if (expression.IsKind(SyntaxKind.QualifiedName)) { var qualified = (QualifiedNameSyntax)expression; var crefWrapper = SyntaxFactory.QualifiedCref(qualified.Left, SyntaxFactory.NameMemberCref(qualified.Right)); crefSymbols = BindCref(crefWrapper, binder); } else { var typeSyntax = expression as TypeSyntax; if (typeSyntax != null) { var crefWrapper = typeSyntax is PredefinedTypeSyntax ? (CrefSyntax)SyntaxFactory.TypeCref(typeSyntax) : SyntaxFactory.NameMemberCref(typeSyntax); crefSymbols = BindCref(crefWrapper, binder); } } return null; } var diagnostics = DiagnosticBag.GetInstance(); var boundNode = GetSpeculativelyBoundExpressionHelper(binder, expression, bindingOption, diagnostics); diagnostics.Free(); return boundNode; }
protected sealed override SymbolInfo GetSpeculativeSymbolInfoCore(int position, SyntaxNode expression, SpeculativeBindingOption bindingOption) { if (expression is ExpressionSyntax) { return GetSpeculativeSymbolInfo(position, (ExpressionSyntax)expression, bindingOption); } else if (expression is ConstructorInitializerSyntax) { return GetSpeculativeSymbolInfo(position, (ConstructorInitializerSyntax)expression); } else if (expression is AttributeSyntax) { return GetSpeculativeSymbolInfo(position, (AttributeSyntax)expression); } else if (expression is CrefSyntax) { return GetSpeculativeSymbolInfo(position, (CrefSyntax)expression); } else { return default(SymbolInfo); } }