protected override bool TryInitializeState( Document document, SemanticModel model, SyntaxNode node, CancellationToken cancellationToken, out INamedTypeSymbol classType, out INamedTypeSymbol abstractClassType) { var baseClassNode = node as TypeSyntax; if (baseClassNode != null && baseClassNode.Parent is BaseTypeSyntax && baseClassNode.Parent.IsParentKind(SyntaxKind.BaseList) && ((BaseTypeSyntax)baseClassNode.Parent).Type == baseClassNode) { if (baseClassNode.Parent.Parent.IsParentKind(SyntaxKind.ClassDeclaration)) { abstractClassType = model.GetTypeInfo(baseClassNode, cancellationToken).Type as INamedTypeSymbol; cancellationToken.ThrowIfCancellationRequested(); if (abstractClassType.IsAbstractClass()) { var classDecl = baseClassNode.Parent.Parent.Parent as ClassDeclarationSyntax; classType = model.GetDeclaredSymbol(classDecl, cancellationToken) as INamedTypeSymbol; return classType != null && abstractClassType != null; } } } classType = null; abstractClassType = null; return false; }
private static bool IsMainMethodEntryPoint(MethodDeclarationSyntax methodTarget, SemanticModel semanticModel) { if (!methodTarget.Identifier.Text.Equals("Main", StringComparison.Ordinal)) return false; if (!methodTarget.Modifiers.Any(SyntaxKind.StaticKeyword)) return false; var returnType = semanticModel.GetTypeInfo(methodTarget.ReturnType).Type; if (returnType == null) return false; if (!returnType.Name.Equals("Void", StringComparison.OrdinalIgnoreCase) && !returnType.Name.Equals("Int32", StringComparison.OrdinalIgnoreCase)) return false; var parameters = methodTarget.ParameterList.Parameters; if (parameters.Count > 1) return false; if (parameters.Count == 0) return true; var parameterType = semanticModel.GetTypeInfo(parameters.First().Type).Type; if (!parameterType.OriginalDefinition.ToString().Equals("String[]", StringComparison.OrdinalIgnoreCase)) return false; return true; }
private static void AnalyzeBinaryExpression(BinaryExpressionSyntax node, SemanticModel model, Action<Diagnostic> addDiagnostic) { var leftType = model.GetTypeInfo(node.Left).Type; var rightType = model.GetTypeInfo(node.Right).Type; if (leftType != null && rightType != null && leftType.SpecialType == SpecialType.System_String && rightType.SpecialType == SpecialType.System_String) { addDiagnostic(node.OperatorToken.GetLocation().CreateDiagnostic(Rule)); } }
private bool IsReportable(VariableDeclarationSyntax variableDeclaration, SemanticModel semanticModel) { bool result; TypeSyntax variableTypeName = variableDeclaration.Type; if (variableTypeName.IsVar) { // Implicitly-typed variables cannot have multiple declarators. Short circuit if it does. bool hasMultipleVariables = variableDeclaration.Variables.Skip(1).Any(); if(hasMultipleVariables == false) { // Special case: Ensure that 'var' isn't actually an alias to another type. (e.g. using var = System.String). IAliasSymbol aliasInfo = semanticModel.GetAliasInfo(variableTypeName); if (aliasInfo == null) { // Retrieve the type inferred for var. ITypeSymbol type = semanticModel.GetTypeInfo(variableTypeName).ConvertedType; // Special case: Ensure that 'var' isn't actually a type named 'var'. if (type.Name.Equals("var", StringComparison.Ordinal) == false) { // Special case: Ensure that the type is not an anonymous type. if (type.IsAnonymousType == false) { // Special case: Ensure that it's not a 'new' expression. if (variableDeclaration.Variables.First().Initializer.Value.IsKind(SyntaxKind.ObjectCreationExpression)) { result = false; } else { result = true; } } else { result = false; } } else { result = false; } } else { result = false; } } else { result = false; } } else { result = false; } return result; }
/// <summary> /// Determines whether the specified TypeSyntax is actually 'var'. /// </summary> public static bool IsTypeInferred(this TypeSyntax typeSyntax, SemanticModel semanticModel) { if (!typeSyntax.IsVar) { return false; } if (semanticModel.GetAliasInfo(typeSyntax) != null) { return false; } var type = semanticModel.GetTypeInfo(typeSyntax).Type; if (type == null) { return false; } if (type.Name == "var") { return false; } return true; }
static bool IsDeclarationConstFriendly(LocalDeclarationStatementSyntax declaration, SemanticModel semanticModel) { // all variables could be const? foreach (var variable in declaration.Declaration.Variables) { if (variable.Initializer == null) return false; if (variable.Initializer.Value is InterpolatedStringExpressionSyntax) return false; // is constant var constantValue = semanticModel.GetConstantValue(variable.Initializer.Value); var valueIsConstant = constantValue.HasValue; if (!valueIsConstant) return false; // if reference type, value is null? var variableTypeName = declaration.Declaration.Type; var variableType = semanticModel.GetTypeInfo(variableTypeName).ConvertedType; if (variableType.IsReferenceType && variableType.SpecialType != SpecialType.System_String && constantValue.Value != null) return false; // nullable? if (variableType.OriginalDefinition?.SpecialType == SpecialType.System_Nullable_T) return false; // value can be converted to variable type? var conversion = semanticModel.ClassifyConversion(variable.Initializer.Value, variableType); if (!conversion.Exists || conversion.IsUserDefined) return false; } return true; }
static bool CanBeNull(SemanticModel semanticModel, ExpressionSyntax expression, CancellationToken cancellationToken) { var info = semanticModel.GetTypeInfo(expression, cancellationToken); if (info.ConvertedType.IsReferenceType || info.ConvertedType.IsNullableType()) return true; return false; }
internal static bool CheckExceptionType(SemanticModel model, ObjectCreationExpressionSyntax objectCreateExpression, out ExpressionSyntax paramNode) { paramNode = null; var type = model.GetTypeInfo(objectCreateExpression).Type; if (type == null) return false; if (type.Name == typeof(ArgumentException).Name) { if (objectCreateExpression.ArgumentList.Arguments.Count >= 2) { paramNode = objectCreateExpression.ArgumentList.Arguments[1].Expression; } return paramNode != null; } if (type.Name == typeof(ArgumentNullException).Name || type.Name == typeof(ArgumentOutOfRangeException).Name || type.Name == "DuplicateWaitObjectException") { if (objectCreateExpression.ArgumentList.Arguments.Count >= 1) { paramNode = objectCreateExpression.ArgumentList.Arguments[0].Expression; } return paramNode != null; } return false; }
//--- Class Methods --- public static IEnumerable<ISymbol> GetMissingEnumMembers(SwitchStatementSyntax switchNode, SemanticModel semanticModel, out IdentifierNameSyntax switchVariable) { // TODO (2016-02-25, steveb): what if the swich calls a function instead? switchVariable = switchNode.Expression as IdentifierNameSyntax; if(switchVariable == null) { return Enumerable.Empty<ISymbol>(); } var switchVariableTypeInfo = semanticModel.GetTypeInfo(switchVariable); // check if we are switching over an enum if((switchVariableTypeInfo.Type != null) && (switchVariableTypeInfo.Type.TypeKind == TypeKind.Enum)) { // get all the enum values var enumMembers = switchVariableTypeInfo.Type.GetMembers().Where(x => x.Kind == SymbolKind.Field).ToImmutableArray(); // get all case statements var caseSwitchLabels = switchNode.Sections .SelectMany(section => section.Labels) .Select(label => label.DescendantNodes().OfType<MemberAccessExpressionSyntax>().FirstOrDefault()) .Where(memberAccess => memberAccess != null) .Select(memberAccess => semanticModel.GetSymbolInfo(memberAccess).Symbol) .ToImmutableHashSet(); // make sure we have all cases covered return enumMembers.Where(x => !caseSwitchLabels.Contains(x)).ToImmutableArray(); } return Enumerable.Empty<ISymbol>(); }
private static bool AnyArgumentIsValueType(ArgumentListSyntax argumentList, SemanticModel semanticModel) { return argumentList.Arguments.Any(argument => { var type = semanticModel.GetTypeInfo(argument.Expression).Type; return type != null && type.IsValueType; }); }
protected void GetDiagnosticsForNode(SyntaxNode node, SemanticModel model, Action<Diagnostic> addDiagnostic) { var type = model.GetTypeInfo(node).Type; if (type != null && TypeHasWeakIdentity(type, model)) { addDiagnostic(node.CreateDiagnostic(Rule, type.ToDisplayString())); } }
internal static bool IsCast(SemanticModel model, SyntaxNode n, ITypeSymbol type) { var expr = n as ExpressionSyntax; if (expr == null) return false; expr = expr.SkipParens(); var castExpr = expr as CastExpressionSyntax; if (castExpr != null) { return model.GetTypeInfo(castExpr.Type).Type == type; } var binExpr = expr as BinaryExpressionSyntax; if (binExpr != null) { return binExpr.IsKind(SyntaxKind.AsExpression) && model.GetTypeInfo(binExpr.Right).Type == type; } return false; }
internal static bool RequireReturnStatement(SemanticModel model, SyntaxNode lambda) { var typeInfo = model.GetTypeInfo(lambda); var type = typeInfo.ConvertedType ?? typeInfo.Type; if (type == null || !type.IsDelegateType()) return false; var returnType = type.GetDelegateInvokeMethod().GetReturnType(); return returnType != null && returnType.SpecialType != SpecialType.System_Void; }
internal static ExpressionSyntax UnpackNullableValueAccess(SemanticModel semanticModel, ExpressionSyntax expression, CancellationToken cancellationToken) { var expr = expression.SkipParens(); if (!expr.IsKind(SyntaxKind.SimpleMemberAccessExpression)) return expression; var info = semanticModel.GetTypeInfo(((MemberAccessExpressionSyntax)expr).Expression, cancellationToken); if (!info.ConvertedType.IsNullableType()) return expression; return ((MemberAccessExpressionSyntax)expr).Expression; }
internal static bool ShouldReportOnCollectionNode(SemanticModel semanticModel, SyntaxNode argument) { const bool returnIfUnknown = false; // if the variable is an invocation syntax we can assume that it was returned materialized, if it's not an extension method switch(argument.Kind()) { case SyntaxKind.InvocationExpression: var methodCallInfo = semanticModel.GetSymbolInfo(argument); if((methodCallInfo.Symbol != null) && (methodCallInfo.Symbol.Kind == SymbolKind.Method)) { var mSymbol = (IMethodSymbol)methodCallInfo.Symbol; var typeInfo = semanticModel.GetTypeInfo(argument); // If the method is not an extension method, we assume it returned a materialized collection return IsAbstractCollectionType(typeInfo) && mSymbol.IsExtensionMethod && mSymbol.ContainingNamespace.ToDisplayString().Equals("System.Linq"); } break; case SyntaxKind.IdentifierName: var identifierInfo = semanticModel.GetSymbolInfo(argument); // if this identifier came straight from a parameter, assume it is materialized if(identifierInfo.Symbol != null && identifierInfo.Symbol.Kind == SymbolKind.Parameter) { //TODO(2016-02-24, yurig): if parameter is modified locally, we should warn return false; } // if this is a local identifier, look at where it is defined if(identifierInfo.Symbol != null && identifierInfo.Symbol.Kind == SymbolKind.Local) { var declaration = identifierInfo.Symbol.DeclaringSyntaxReferences.FirstOrDefault(); // if the declaration is an equals expression, dive into it. var equalsExpression = declaration?.GetSyntax() .ChildNodes() .FirstOrDefault(x => x.Kind() == SyntaxKind.EqualsValueClause); var firstChild = equalsExpression?.ChildNodes().FirstOrDefault(); if(firstChild != null) { return ShouldReportOnCollectionNode(semanticModel, firstChild); } // if the variable was assigned somewhere else, find it var containingClass = declaration?.GetSyntax().FirstAncestorOrSelf<MethodDeclarationSyntax>(); var localAssignment = containingClass?.DescendantNodes().OfType<AssignmentExpressionSyntax>() .Where(x => x.Left.IsKind(SyntaxKind.IdentifierName)) .LastOrDefault(x => (x.Left as IdentifierNameSyntax).Identifier.Text.Equals(((IdentifierNameSyntax)argument).Identifier.Text)); if(localAssignment != null) { return ShouldReportOnCollectionNode(semanticModel, localAssignment.Right); } } break; case SyntaxKind.SimpleMemberAccessExpression: // Assume that member accesses are returned materialized return false; } return returnIfUnknown; }
public Statement GetStatement() { var typeInfo = semanticModel.GetTypeInfo(literalExpressionSyntax); var constantStatement = new ConstantStatement(literalExpressionSyntax.Token.Value); if (literalExpressionSyntax.Token.Value != null) { constantStatement.Type = typeInfo.GetClassType(); } return(constantStatement); }
public ITypeSymbol GetThrownExceptionTypeSymbol(SemanticModel semanticModel, ThrowStatementSyntax throwStatementSyntax) { SemanticModel = semanticModel; ThrowStatementSyntax = throwStatementSyntax; SyntaxNode syntaxNodeToGetTypeOf = ThrowStatementSyntax.Expression; if (syntaxNodeToGetTypeOf == null) syntaxNodeToGetTypeOf = GetCatchClaue(); if (syntaxNodeToGetTypeOf == null) return null; //Not sure this is possible.... return semanticModel.GetTypeInfo(syntaxNodeToGetTypeOf).Type; }
public static IEnumerable<SyntaxNode> CreateFixedYieldReturn(this YieldStatementSyntax yieldStatement, SemanticModel semanticModel) { var typeInfo = semanticModel.GetTypeInfo(yieldStatement.Expression); var type = typeInfo.Type as INamedTypeSymbol; var task = SyntaxFactory.IdentifierName(TaskName); yield return CreateLocalVariableDeclaration(TaskName, yieldStatement.Expression); yield return CreateYieldReturnIfNotCompleted(task); yield return CreateThrowIfException(task); if (type.TypeArguments.Count() == 1) { var exp = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, task, SyntaxFactory.IdentifierName("Result")); yield return CreateLocalVariableDeclaration("_result", exp); } }
private static SyntaxToken GetNewLiteral(LiteralExpressionSyntax literal, SemanticModel semanticModel) { var type = semanticModel.GetTypeInfo(literal).Type; var text = literal.Token.Text; var reversedText = text.Reverse(); var reversedTextEnding = new string(reversedText.TakeWhile(char.IsLetter).ToArray()); var reversedTextBeginning = new string(reversedText.SkipWhile(char.IsLetter).ToArray()); var newText = new string((reversedTextEnding.ToUpperInvariant() + reversedTextBeginning).Reverse().ToArray()); switch (type.SpecialType) { case SpecialType.System_Int32: return SyntaxFactory.Literal( newText, (int)literal.Token.Value); case SpecialType.System_Char: return SyntaxFactory.Literal( newText, (char)literal.Token.Value); case SpecialType.System_UInt32: return SyntaxFactory.Literal( newText, (uint)literal.Token.Value); case SpecialType.System_Int64: return SyntaxFactory.Literal( newText, (long)literal.Token.Value); case SpecialType.System_UInt64: return SyntaxFactory.Literal( newText, (ulong)literal.Token.Value); case SpecialType.System_Decimal: return SyntaxFactory.Literal( newText, (decimal)literal.Token.Value); case SpecialType.System_Single: return SyntaxFactory.Literal( newText, (float)literal.Token.Value); case SpecialType.System_Double: return SyntaxFactory.Literal( newText, (double)literal.Token.Value); default: return SyntaxFactory.Token(SyntaxKind.None); } }
public Statement GetStatement() { var lamdaStatement = new LamdaStatement(); var parameters = anonymousMethodExpressionSyntax.ParameterList?.Parameters .Select(x => statementInterpreterHandler.GetStatement(x)); lamdaStatement.Parameters = parameters?.Cast <Parameter>()?.ToArray() ?? new Parameter[0]; lamdaStatement.Body = statementInterpreterHandler.GetStatement(anonymousMethodExpressionSyntax.Body); var typeInfo = semanticModel.GetTypeInfo(anonymousMethodExpressionSyntax); lamdaStatement.Type = typeInfo.ConvertedType.GetClassType(); return(lamdaStatement); }
private static void CheckParam(InvocationExpressionSyntax invocationExpression, IMethodSymbol methodInfo, SemanticModel semanticModel, Action<Diagnostic> reportDiagnostic, string filePath, CancellationToken cancellationToken) { var arguments = invocationExpression.ArgumentList.Arguments; if (arguments.Count != methodInfo.Parameters.Length) { reportDiagnostic(Diagnostic.Create(ParamsParameterRule, invocationExpression.GetLocation(), EmptyMessageArgs)); HeapAllocationAnalyzerEventSource.Logger.ParamsAllocation(filePath); } else { var lastIndex = arguments.Count - 1; var lastArgumentTypeInfo = semanticModel.GetTypeInfo(arguments[lastIndex].Expression, cancellationToken); if (lastArgumentTypeInfo.Type != null && !lastArgumentTypeInfo.Type.Equals(methodInfo.Parameters[lastIndex].Type)) { reportDiagnostic(Diagnostic.Create(ParamsParameterRule, invocationExpression.GetLocation(), EmptyMessageArgs)); HeapAllocationAnalyzerEventSource.Logger.ParamsAllocation(filePath); } } }
public Statement GetStatement() { var lamdaStatement = new LamdaStatement(); var parameters = parenthesizedLambdaExpressionSyntax.ParameterList.Parameters .Select(x => statementInterpreterHandler.GetStatement(x)); lamdaStatement.Parameters = parameters.Cast <Parameter>().ToArray(); lamdaStatement.Body = statementInterpreterHandler.GetStatement(parenthesizedLambdaExpressionSyntax.Body); var typeInfo = semanticModel.GetTypeInfo(parenthesizedLambdaExpressionSyntax); lamdaStatement.Type = typeInfo.ConvertedType.GetClassType(); lamdaStatement.IsAsync = parenthesizedLambdaExpressionSyntax.AsyncKeyword.IsKind(Microsoft.CodeAnalysis.CSharp.SyntaxKind.AsyncKeyword); return(lamdaStatement); }
private static bool IsTask(ExpressionSyntax expression, SemanticModel semanticModel) { var type = semanticModel.GetTypeInfo(expression).Type as INamedTypeSymbol; if (type == null) { return false; } INamedTypeSymbol taskType; if (type.IsGenericType) { type = type.ConstructedFrom; taskType = semanticModel.Compilation.GetTypeByMetadataName(typeof(Task<>).FullName); } else { taskType = semanticModel.Compilation.GetTypeByMetadataName(typeof(Task).FullName); } return type.Equals(taskType); }
public Statement GetStatement() { var parameterType = semanticModel.GetTypeInfo(forEachStatementSyntax.Type).GetClassType(); var parameter = new LocalVariableDeclaration { Type = parameterType, Name = forEachStatementSyntax.Identifier.ValueText }; var collection = statementInterpreterHandler.GetStatement(forEachStatementSyntax.Expression); var body = statementInterpreterHandler.GetStatement(forEachStatementSyntax.Statement); return(new ForEachStatement { Variable = parameter, Collection = collection, Body = body }); }
public AttributeInspector(AttributeSyntax attributeSyntax, SemanticModel semanticModel) { _attributeName = attributeSyntax.Name.ToString(); TypeInfo typeInfo = semanticModel.GetTypeInfo(attributeSyntax); ITypeSymbol typeSymbol = typeInfo.Type; _attributeQualifiedName = typeSymbol.ToString(); var unamedArguments = new List<string>(); var namedArguments = new Dictionary<string, string>(); if (attributeSyntax.ArgumentList != null) { foreach (AttributeArgumentSyntax attributeArgumentSyntax in attributeSyntax.ArgumentList.Arguments) { String argValue = attributeArgumentSyntax.Expression.ToString(); if (attributeArgumentSyntax.NameEquals != null) { string argName = attributeArgumentSyntax.NameEquals.Name.Identifier.Text; namedArguments.Add(argName, argValue); } else { // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression if (argValue.StartsWith("@")) { argValue = argValue.Remove(0, 1).Replace("\"\"", "\""); } else { argValue = Regex.Unescape(argValue); } argValue = argValue.Trim('"'); unamedArguments.Add(argValue); } } } _unamedArguments = unamedArguments.AsReadOnly(); _namedArguments = new ReadOnlyDictionary<string, string>(namedArguments); }
internal static ExpressionSyntax GetSwitchExpression(SemanticModel context, ExpressionSyntax expr) { var binaryOp = expr as BinaryExpressionSyntax; if (binaryOp == null) return null; if (binaryOp.OperatorToken.IsKind(SyntaxKind.LogicalOrExpression)) return GetSwitchExpression(context, binaryOp.Left); if (binaryOp.OperatorToken.IsKind(SyntaxKind.EqualsEqualsToken)) { ExpressionSyntax switchExpr = null; if (IsConstantExpression(context, binaryOp.Right)) switchExpr = binaryOp.Left; if (IsConstantExpression(context, binaryOp.Left)) switchExpr = binaryOp.Right; if (switchExpr != null && IsValidSwitchType(context.GetTypeInfo(switchExpr).Type)) return switchExpr; } return null; }
public static bool TryGetAttribute(this SyntaxList<AttributeListSyntax> attributeLists, KnownType attributeKnownType, SemanticModel semanticModel, out AttributeSyntax searchedAttribute) { searchedAttribute = null; if (!attributeLists.Any()) { return false; } foreach (var attribute in attributeLists.SelectMany(attributeList => attributeList.Attributes)) { var attributeType = semanticModel.GetTypeInfo(attribute).Type; if (attributeType.Is(attributeKnownType)) { searchedAttribute = attribute; return true; } } return false; }
public Statement GetStatement() { var catchStatement = new CatchStatement(); catchStatement.Block = statementInterpreterHandler.GetStatement(catchClauseSyntax.Block); catchStatement.Filter = catchClauseSyntax.Filter == null ? null : statementInterpreterHandler.GetStatement(catchClauseSyntax.Filter.FilterExpression); if (catchClauseSyntax.Declaration != null) { catchStatement.Type = semanticModel.GetTypeInfo(catchClauseSyntax.Declaration.Type).GetClassType(); if (!catchClauseSyntax.Declaration.Identifier.IsKind(Microsoft.CodeAnalysis.CSharp.SyntaxKind.None)) { catchStatement.Variable = new LocalVariableDeclaration { Type = catchStatement.Type, Name = catchClauseSyntax.Declaration.Identifier.ValueText }; } } return(catchStatement); }
//--- Class Methods --- public static IEnumerable<ISymbol> GetMissingEnumMembers(SyntaxNode switchNode, SemanticModel semanticModel, out IdentifierNameSyntax switchVariable) { switchVariable = switchNode.DescendantNodes().OfType<IdentifierNameSyntax>().First(); var switchVariableTypeInfo = semanticModel.GetTypeInfo(switchVariable); // check if we are switching over an enum if(switchVariableTypeInfo.Type.TypeKind == TypeKind.Enum) { // get all the enum values var enumMembers = switchVariableTypeInfo.Type.GetMembers().Where(x => x.Kind == SymbolKind.Field).ToImmutableArray(); // get all case statements var caseSwitchLabels = switchNode .DescendantNodes().OfType<CaseSwitchLabelSyntax>() .Select(x => x.DescendantNodes().OfType<MemberAccessExpressionSyntax>().FirstOrDefault()) .Where(x => x != null) .Select(x => semanticModel.GetSymbolInfo(x).Symbol) .ToImmutableHashSet(); // make sure we have all cases covered return enumMembers.Where(x => !caseSwitchLabels.Contains(x)).ToImmutableArray(); } return Enumerable.Empty<ISymbol>(); }
internal static bool CheckExceptionType(SemanticModel model, ObjectCreationExpressionSyntax objectCreateExpression, out ExpressionSyntax paramNode, out ExpressionSyntax altParam, out bool canAddParameterName) { paramNode = null; altParam = null; canAddParameterName = false; var type = model.GetTypeInfo(objectCreateExpression).Type; if (type == null) return false; if (type.Name == typeof(ArgumentException).Name) { if (objectCreateExpression.ArgumentList.Arguments.Count >= 2) { altParam = objectCreateExpression.ArgumentList.Arguments[0].Expression; paramNode = objectCreateExpression.ArgumentList.Arguments[1].Expression; } return paramNode != null; } if (type.Name == typeof(ArgumentNullException).Name || type.Name == typeof(ArgumentOutOfRangeException).Name || type.Name == "DuplicateWaitObjectException") { canAddParameterName = objectCreateExpression.ArgumentList.Arguments.Count == 1; if (objectCreateExpression.ArgumentList.Arguments.Count >= 1) { paramNode = objectCreateExpression.ArgumentList.Arguments[0].Expression; if (objectCreateExpression.ArgumentList.Arguments.Count == 2) { altParam = objectCreateExpression.ArgumentList.Arguments[1].Expression; if (model.GetTypeInfo(altParam).Type?.SpecialType != SpecialType.System_String) paramNode = null; } if (objectCreateExpression.ArgumentList.Arguments.Count == 3) altParam = objectCreateExpression.ArgumentList.Arguments[2].Expression; } return paramNode != null; } return false; }
// static IEnumerable<ITypeSymbol> GetAllValidTypesFromObjectCreation(SemanticModel resolver, ObjectCreateExpressionSyntax invoke, SyntaxNode parameter) // { // int index = GetArgumentIndex(invoke.Arguments, parameter); // if (index < 0) // yield break; // // var targetResult = resolver.Resolve(invoke.Type); // if (targetResult is TypeResolveResult) { // var type = ((TypeResolveResult)targetResult).Type; // if (type.Kind == TypeKind.Delegate && index == 0) { // yield return type; // yield break; // } // foreach (var constructor in type.GetConstructors ()) { // if (index < constructor.Parameters.Count) // yield return constructor.Parameters [index].Type; // } // } // } // // public static ITypeSymbol GetElementType(SemanticModel resolver, ITypeSymbol type) // { // // TODO: A better get element type method. // if (type.Kind == TypeKind.Array || type.Kind == TypeKind.Dynamic) { // if (type.Kind == TypeKind.Array) // return ((ArrayType)type).ElementType; // return resolver.Compilation.FindType(KnownTypeCode.Object); // } // // // foreach (var method in type.GetMethods (m => m.Name == "GetEnumerator")) { // ITypeSymbol returnType = null; // foreach (var prop in method.ReturnType.GetProperties(p => p.Name == "Current")) { // if (returnType != null && prop.ReturnType.IsKnownType (KnownTypeCode.Object)) // continue; // returnType = prop.ReturnType; // } // if (returnType != null) // return returnType; // } // // return resolver.Compilation.FindType(KnownTypeCode.Object); // } // // static IEnumerable<ITypeSymbol> GuessFromConstructorInitializer(SemanticModel resolver, SyntaxNode expr) // { // var init = expr.Parent as ConstructorInitializer; // var rr = resolver.Resolve(expr.Parent); // int index = GetArgumentIndex(init.Arguments, expr); // if (index >= 0) { // foreach (var constructor in rr.Type.GetConstructors()) { // if (index < constructor.Parameters.Count) { // yield return constructor.Parameters[index].Type; // } // } // } // } public static IEnumerable<ITypeSymbol> GetValidTypes(SemanticModel model, SyntaxNode expr, CancellationToken cancellationToken = default(CancellationToken)) { // if (expr.Role == Roles.Condition) { // return new [] { model.Compilation.FindType (KnownTypeCode.Boolean) }; // } // var mref = expr.Parent as MemberAccessExpressionSyntax; if (mref != null && mref.Name != expr) { mref = null; } if (mref != null) { // case: guess enum when trying to access not existent enum member var rr = model.GetTypeInfo(mref.Expression); if (rr.Type != null && rr.Type.TypeKind == TypeKind.Enum) return new[] { rr.Type }; } // if (expr.Parent is ParenthesizedExpressionSyntax || expr.Parent is NamedArgumentExpressionSyntax) { // return GetValidTypes(model, expr.Parent); // } // if (expr.Parent is DirectionExpressionSyntax) { // var parent = expr.Parent.Parent; // if (parent is InvocationExpressionSyntax) { // var invoke = (InvocationExpressionSyntax)parent; // return GetAllValidTypesFromInvocation(model, invoke, expr.Parent); // } // } // // if (expr.Parent is ArrayInitializerExpressionSyntax) { // if (expr is NamedExpressionSyntax) // return new [] { model.Resolve(((NamedExpressionSyntax)expr).ExpressionSyntax).Type }; // // var aex = expr.Parent as ArrayInitializerExpressionSyntax; // if (aex.IsSingleElement) // aex = aex.Parent as ArrayInitializerExpressionSyntax; // var type = GetElementType(model, model.Resolve(aex.Parent).Type); // if (type.Kind != TypeKind.Unknown) // return new [] { type }; // } // // if (expr.Parent is ObjectCreateExpressionSyntax) { // var invoke = (ObjectCreateExpressionSyntax)expr.Parent; // return GetAllValidTypesFromObjectCreation(model, invoke, expr); // } // // if (expr.Parent is ArrayCreateExpressionSyntax) { // var ace = (ArrayCreateExpressionSyntax)expr.Parent; // if (!ace.Type.IsNull) { // return new [] { model.Resolve(ace.Type).Type }; // } // } // // if (expr.Parent is VariableInitializer) { // var initializer = (VariableInitializer)expr.Parent; // var field = initializer.GetParent<FieldDeclaration>(); // if (field != null) { // var rr = model.Resolve(field.ReturnType); // if (!rr.IsError) // return new [] { rr.Type }; // } // var varStmt = initializer.GetParent<VariableDeclarationStatement>(); // if (varStmt != null) { // var rr = model.Resolve(varStmt.Type); // if (!rr.IsError) // return new [] { rr.Type }; // } // return new [] { model.Resolve(initializer).Type }; // } // // if (expr.Parent is CastExpressionSyntax) { // var cast = (CastExpressionSyntax)expr.Parent; // return new [] { model.Resolve(cast.Type).Type }; // } // // if (expr.Parent is AsExpressionSyntax) { // var cast = (AsExpressionSyntax)expr.Parent; // return new [] { model.Resolve(cast.Type).Type }; // } if (expr.Parent is AssignmentExpressionSyntax || mref != null && mref.Parent is AssignmentExpressionSyntax) { var assign = expr.Parent as AssignmentExpressionSyntax ?? mref.Parent as AssignmentExpressionSyntax; var other = assign.Left == expr || assign.Left == mref ? assign.Right : assign.Left; return new[] { model.GetTypeInfo(other).Type }; } // if (expr.Parent is BinaryOperatorExpressionSyntax) { // var assign = (BinaryOperatorExpressionSyntax)expr.Parent; // var other = assign.Left == expr ? assign.Right : assign.Left; // return new [] { model.Resolve(other).Type }; // } // // if (expr.Parent is ReturnStatement) { // var parent = expr.Ancestors.FirstOrDefault(n => n is EntityDeclaration || n is AnonymousMethodExpressionSyntax|| n is LambdaExpressionSyntax); // if (parent != null) { // var rr = model.Resolve(parent); // if (!rr.IsError) // return new [] { rr.Type }; // } // var e = parent as EntityDeclaration; // if (e != null) { // var rt = model.Resolve(e.ReturnType); // if (!rt.IsError) // return new [] { rt.Type }; // } // } // // if (expr.Parent is YieldReturnStatement) { // var state = model.GetResolverStateBefore(expr); // if (state != null && (state.CurrentMember.ReturnType is ParameterizedType)) { // var pt = (ParameterizedType)state.CurrentMember.ReturnType; // if (pt.FullName == "System.Collections.Generic.IEnumerable") { // return new [] { pt.TypeArguments.First() }; // } // } // } // // if (expr.Parent is UnaryOperatorExpressionSyntax) { // var uop = (UnaryOperatorExpressionSyntax)expr.Parent; // switch (uop.Operator) { // case UnaryOperatorType.Not: // return new [] { model.Compilation.FindType(KnownTypeCode.Boolean) }; // case UnaryOperatorType.Minus: // case UnaryOperatorType.Plus: // case UnaryOperatorType.Increment: // case UnaryOperatorType.Decrement: // case UnaryOperatorType.PostIncrement: // case UnaryOperatorType.PostDecrement: // return new [] { model.Compilation.FindType(KnownTypeCode.Int32) }; // } // } // // if (expr.Parent is ConstructorInitializer) // return GuessFromConstructorInitializer(model, expr); // // if (expr.Parent is NamedExpressionSyntax) { // var rr = model.Resolve(expr.Parent); // if (!rr.IsError) { // return new [] { rr.Type }; // } // } if (expr.IsKind(SyntaxKind.Argument)) { var parent = expr.Parent.Parent; var invocationParent = parent as InvocationExpressionSyntax; if (invocationParent != null) { return GetAllValidTypesFromInvocation(model, invocationParent, expr); } } var types = typeInferenceService.InferTypes(model, expr, cancellationToken).ToList(); return types; }
public override SyntaxNode RemoveImplementedInterface(SyntaxNode node, ITypeSymbol typeSymbol, SemanticModel semanticModel) { if (!node.IsKind(SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration)) { throw Exceptions.ThrowEFail(); } var typeDeclaration = (TypeDeclarationSyntax)node; if (typeDeclaration.BaseList == null || typeDeclaration.BaseList.Types.Count == 0) { throw Exceptions.ThrowEInvalidArg(); } BaseTypeSyntax baseType = null; foreach (var type in typeDeclaration.BaseList.Types) { var typeInfo = semanticModel.GetTypeInfo(type.Type, CancellationToken.None); if (typeInfo.Type != null && typeInfo.Type.Equals(typeSymbol)) { baseType = type; break; } } if (baseType == null) { throw Exceptions.ThrowEInvalidArg(); } var newTypes = typeDeclaration.BaseList.Types.Remove(baseType); var newBaseList = typeDeclaration.BaseList.WithTypes(newTypes); if (newBaseList.Types.Count == 0) { newBaseList = null; } return typeDeclaration.WithBaseList(newBaseList); }
private static bool IsEventHandlerLike(MethodDeclarationSyntax method, SemanticModel semanticModel) { if (method.ParameterList.Parameters.Count != 2 || method.ReturnType.ToString() != "void") return false; var senderType = semanticModel.GetTypeInfo(method.ParameterList.Parameters[0].Type).Type; if (senderType.SpecialType != SpecialType.System_Object) return false; var eventArgsType = semanticModel.GetTypeInfo(method.ParameterList.Parameters[1].Type).Type as INamedTypeSymbol; if (eventArgsType == null) return false; return eventArgsType.AllBaseTypesAndSelf().Any(type => type.ToString() == "System.EventArgs"); }
private static bool IsSerializationConstructor(ConstructorDeclarationSyntax constructor, SemanticModel semanticModel) { if (constructor.ParameterList.Parameters.Count != 2) return false; var constructorSymbol = semanticModel.GetDeclaredSymbol(constructor); var typeSymbol = constructorSymbol?.ContainingType; if (!typeSymbol?.AllInterfaces.Any(i => i.ToString() == "System.Runtime.Serialization.ISerializable") ?? true) return false; if (!typeSymbol.GetAttributes().Any(a => a.AttributeClass.ToString() == "System.SerializableAttribute")) return false; var serializationInfoType = semanticModel.GetTypeInfo(constructor.ParameterList.Parameters[0].Type).Type as INamedTypeSymbol; if (serializationInfoType == null) return false; if (!serializationInfoType.AllBaseTypesAndSelf().Any(type => type.ToString() == "System.Runtime.Serialization.SerializationInfo")) return false; var streamingContextType = semanticModel.GetTypeInfo(constructor.ParameterList.Parameters[1].Type).Type as INamedTypeSymbol; if (streamingContextType == null) return false; return streamingContextType.AllBaseTypesAndSelf().Any(type => type.ToString() == "System.Runtime.Serialization.StreamingContext"); }
public override string GetFullName(SyntaxNode node, SemanticModel semanticModel) { if (node.Kind() == SyntaxKind.UsingDirective) { throw Exceptions.ThrowEFail(); } var symbol = node is AttributeSyntax ? semanticModel.GetTypeInfo(node).Type : semanticModel.GetDeclaredSymbol(node); return GetExternalSymbolFullName(symbol); }