/// <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 TypeInfo GetSpeculativeTypeInfo( this SemanticModel semanticModel, int position, SyntaxNode expression, SpeculativeBindingOption bindingOption ) { return(semanticModel.GetSpeculativeTypeInfo(position, expression, bindingOption)); }
protected override ITypeSymbol GetTypeSymbolFromPartialName(string partialName, SemanticModel semanticModel, int position) { var parsedTypeName = SyntaxFactory.ParseTypeName(partialName); return semanticModel.GetSpeculativeTypeInfo(position, parsedTypeName, SpeculativeBindingOption.BindAsTypeOrNamespace).Type; }
static Tuple<ITypeSymbol, Location> GetInitializedType (Document document, SemanticModel semanticModel, int position, CancellationToken cancellationToken) { var tree = semanticModel.SyntaxTree; if (tree.IsInNonUserCode (position, cancellationToken)) { return null; } var token = tree.FindTokenOnLeftOfPosition (position, cancellationToken); token = token.GetPreviousTokenIfTouchingWord (position); if (token.Kind () != SyntaxKind.CommaToken && token.Kind () != SyntaxKind.OpenBraceToken) { return null; } if (token.Parent == null || token.Parent.Parent == null) { return null; } // If we got a comma, we can syntactically find out if we're in an ObjectInitializerExpression if (token.Kind () == SyntaxKind.CommaToken && token.Parent.Kind () != SyntaxKind.ObjectInitializerExpression) { return null; } // new Foo { bar = $$ if (token.Parent.Parent.IsKind (SyntaxKind.ObjectCreationExpression)) { var objectCreation = token.Parent.Parent as ObjectCreationExpressionSyntax; if (objectCreation == null) { return null; } var ctor = semanticModel.GetSymbolInfo (objectCreation, cancellationToken).Symbol; var type = ctor != null ? ctor.ContainingType : null; if (type == null) { type = semanticModel.GetSpeculativeTypeInfo (objectCreation.SpanStart, objectCreation.Type, SpeculativeBindingOption.BindAsTypeOrNamespace).Type as INamedTypeSymbol; } return Tuple.Create<ITypeSymbol, Location> (type, token.GetLocation ()); } // Nested: new Foo { bar = { $$ if (token.Parent.Parent.IsKind (SyntaxKind.SimpleAssignmentExpression)) { // Use the type inferrer to get the type being initialzied. var typeInferenceService = TypeGuessing.typeInferenceService; var parentInitializer = token.GetAncestor<InitializerExpressionSyntax> (); var expectedType = typeInferenceService.InferType (semanticModel, parentInitializer, objectAsDefault: false, cancellationToken: cancellationToken); return Tuple.Create (expectedType, token.GetLocation ()); } return null; }
protected override ITypeSymbol GetRangeVariableType(SemanticModel model, IRangeVariableSymbol symbol) { var info = model.GetSpeculativeTypeInfo(this.SelectionResult.FinalSpan.Start, SyntaxFactory.ParseName(symbol.Name), SpeculativeBindingOption.BindAsExpression); if (info.Type.IsErrorType()) { return null; } return info.Type == null || info.Type.SpecialType == Microsoft.CodeAnalysis.SpecialType.System_Object ? info.Type : info.ConvertedType; }
private SyntaxNode linkArray(ExcessContext ctx, SyntaxNode linkNode, SyntaxNode newNode, SemanticModel model) { ArrayCreationExpressionSyntax ace = newNode as ArrayCreationExpressionSyntax; ArgumentSyntax arg = null; bool asParam = newNode is ArgumentSyntax; if (asParam) { arg = (ArgumentSyntax)newNode; ace = (ArrayCreationExpressionSyntax)arg.Expression; } ITypeSymbol arrayType = null; foreach (var expr in ace.Initializer.Expressions) { ITypeSymbol type = model.GetSpeculativeTypeInfo(expr.SpanStart, expr, SpeculativeBindingOption.BindAsExpression).Type; if (arrayType == null) arrayType = type; else if (type != arrayType) { if (isSuperClass(type, arrayType)) arrayType = type; //downcast else if (!isSuperClass(arrayType, type)) { //td: error return newNode; //unable to refine } } } if (arrayType == null) return newNode; ace = ace.WithType(SyntaxFactory.ArrayType(SyntaxFactory.IdentifierName(arrayType.Name + "[]"))); if (asParam) return arg.WithExpression(ace); return ace; }
private IEnumerable<IMethodSymbol> GetMethods(SemanticModel semanticModel, ITypeSymbol symbol, string name, MethodDeclarationSyntax method, MethodDeclarationSyntax originalMethod) { var parameters = method.ParameterList.Parameters; var retval = this .GetAllMembers(symbol) .Where(c => c.Name == name) .OfType<IMethodSymbol>() .Where(c => c.Parameters.Select(d => this.GetParameterTypeComparisonKey(d.Type)).SequenceEqual(parameters.Select(d => this.GetParameterTypeComparisonKey(semanticModel.GetSpeculativeTypeInfo(originalMethod.ParameterList.SpanStart, d.Type, SpeculativeBindingOption.BindAsExpression).Type, method, d.Type)))); return retval; }