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;
 }
Beispiel #2
0
 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;
 }
Beispiel #3
0
        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);
        }
Beispiel #4
0
 /// <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));
 }
 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;
 }
Beispiel #6
0
 /// <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);
        }
Beispiel #10
0
 /// <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);
Beispiel #11
0
 /// <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);
        }
Beispiel #13
0
 /// <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;
        }
Beispiel #15
0
 /// <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;
 }
Beispiel #16
0
 /// <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);
 }
Beispiel #17
0
        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);
        }
Beispiel #18
0
 /// <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);
 }
Beispiel #19
0
 /// <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));
 }
Beispiel #20
0
 /// <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);
Beispiel #21
0
 /// <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);
Beispiel #22
0
 /// <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));
 }
Beispiel #23
0
 /// <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));
 }
Beispiel #24
0
 /// <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);
 }
Beispiel #25
0
 internal abstract bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, TypeSyntax type, SpeculativeBindingOption bindingOption, out SemanticModel speculativeModel);
Beispiel #26
0
        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;
        }
Beispiel #27
0
        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;
        }
Beispiel #28
0
        /// <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;
        }
Beispiel #30
0
 /// <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);
        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);
        }
Beispiel #32
0
 /// <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);
Beispiel #33
0
 protected sealed override TypeInfo GetSpeculativeTypeInfoCore(int position, SyntaxNode expression, SpeculativeBindingOption bindingOption)
 {
     return expression is ExpressionSyntax
         ? GetSpeculativeTypeInfo(position, (ExpressionSyntax)expression, bindingOption)
         : default(TypeInfo);
 }
Beispiel #34
0
 /// <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);
 }
Beispiel #35
0
 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());
            }
        }
Beispiel #37
0
        /// <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;
        }
Beispiel #38
0
 /// <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);
 }
Beispiel #40
0
        /// <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;
        }
Beispiel #41
0
 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);
     }
 }