private static bool HasCheckForNullThatReturns(InvocationExpressionSyntax invocation, SemanticModel semanticModel, ISymbol symbol) { var method = invocation.FirstAncestorOfKind(SyntaxKind.MethodDeclaration) as MethodDeclarationSyntax; if (method != null && method.Body != null) { var ifs = method.Body.Statements.OfKind(SyntaxKind.IfStatement); foreach (IfStatementSyntax @if in ifs) { if ([email protected]?.IsKind(SyntaxKind.EqualsExpression) ?? true) continue; var equals = (BinaryExpressionSyntax)@if.Condition; if (equals.Left == null || equals.Right == null) continue; if (@if.GetLocation().SourceSpan.Start > invocation.GetLocation().SourceSpan.Start) return false; ISymbol identifierSymbol; if (equals.Right.IsKind(SyntaxKind.NullLiteralExpression) && equals.Left.IsKind(SyntaxKind.IdentifierName)) identifierSymbol = semanticModel.GetSymbolInfo(equals.Left).Symbol; else if (equals.Left.IsKind(SyntaxKind.NullLiteralExpression) && equals.Right.IsKind(SyntaxKind.IdentifierName)) identifierSymbol = semanticModel.GetSymbolInfo(equals.Right).Symbol; else continue; if (!symbol.Equals(identifierSymbol)) continue; if (@if.Statement == null) continue; if (@if.Statement.IsKind(SyntaxKind.Block)) { var ifBlock = (BlockSyntax)@if.Statement; if (ifBlock.Statements.OfKind(SyntaxKind.ThrowStatement, SyntaxKind.ReturnStatement).Any()) return true; } else { if (@if.Statement.IsAnyKind(SyntaxKind.ThrowStatement, SyntaxKind.ReturnStatement)) return true; } } } return false; }
private void AnalyzeInvocationExpression(InvocationExpressionSyntax node, SemanticModel model, Action<Diagnostic> reportDiagnostic) { if (node.Expression.Kind() == SyntaxKind.SimpleMemberAccessExpression) { var memberAccess = (MemberAccessExpressionSyntax)node.Expression; if (memberAccess.Name != null && IsEqualsOrCompare(memberAccess.Name.Identifier.ValueText)) { var methodSymbol = model.GetSymbolInfo(memberAccess.Name).Symbol as IMethodSymbol; if (methodSymbol != null && methodSymbol.ContainingType.SpecialType == SpecialType.System_String) { Debug.Assert(IsEqualsOrCompare(methodSymbol.Name)); if (!IsAcceptableOverload(methodSymbol, model)) { // wrong overload reportDiagnostic(memberAccess.Name.GetLocation().CreateDiagnostic(Rule)); } else { var lastArgument = node.ArgumentList.Arguments.Last(); var lastArgSymbol = model.GetSymbolInfo(lastArgument.Expression).Symbol; if (lastArgSymbol != null && lastArgSymbol.ContainingType != null && lastArgSymbol.ContainingType.Equals(StringComparisonType) && !IsOrdinalOrOrdinalIgnoreCase(lastArgument, model)) { // right overload, wrong value reportDiagnostic(lastArgument.GetLocation().CreateDiagnostic(Rule)); } } } } } }
public Statement GetStatement() { if (binaryExpressionSyntax.Kind() == SyntaxKind.IsExpression) { var statement = statementInterpreterHandler.GetStatement(binaryExpressionSyntax.Left); var typeSymbol = (INamedTypeSymbol)semanticModel.GetSymbolInfo(binaryExpressionSyntax.Right).Symbol; return(new IsTypeStatement { Statement = statement, Type = typeSymbol.GetClassType() }); } else if (binaryExpressionSyntax.Kind() == SyntaxKind.AsExpression) { var statement = statementInterpreterHandler.GetStatement(binaryExpressionSyntax.Left); var typeSymbol = (INamedTypeSymbol)semanticModel.GetSymbolInfo(binaryExpressionSyntax.Right).Symbol; return(new AsStatement { Statement = statement, Type = typeSymbol.GetClassType() }); } var binaryStatement = new BinaryStatement(); binaryStatement.Left = statementInterpreterHandler.GetStatement(binaryExpressionSyntax.Left); binaryStatement.Right = statementInterpreterHandler.GetStatement(binaryExpressionSyntax.Right); binaryStatement.Operand = GetOperand(binaryExpressionSyntax.Kind()); return(binaryStatement); }
/// <summary> /// Retourne les assignations dans une listes d'expressions. /// </summary> /// <param name="expressions">Liste d'expressions.</param> /// <param name="modèleSémantique">Modèle sémantique.</param> /// <returns>La liste d'assignations.</returns> public static IEnumerable<StatementSyntax> TrouverAssignations(SyntaxList<StatementSyntax> expressions, SemanticModel modèleSémantique) => expressions.Where(e => { var expression = (e as ExpressionStatementSyntax)?.Expression as AssignmentExpressionSyntax; return expression?.Kind() == SyntaxKind.SimpleAssignmentExpression && modèleSémantique.GetSymbolInfo(expression.Left).Symbol?.Kind == SymbolKind.Field && modèleSémantique.GetSymbolInfo(expression.Right).Symbol?.Kind == SymbolKind.Parameter; });
/// <summary> /// Analyzes the ownership of the given-up symbol /// in the assignment expression. /// </summary> /// <param name="givenUpSymbol">GivenUpOwnershipSymbol</param> /// <param name="assignment">AssignmentExpressionSyntax</param> /// <param name="statement">Statement</param> /// <param name="machine">StateMachine</param> /// <param name="model">SemanticModel</param> /// <param name="trace">TraceInfo</param> protected override void AnalyzeOwnershipInAssignment(GivenUpOwnershipSymbol givenUpSymbol, AssignmentExpressionSyntax assignment, Statement statement, StateMachine machine, SemanticModel model, TraceInfo trace) { var leftIdentifier = base.AnalysisContext.GetRootIdentifier(assignment.Left); ISymbol leftSymbol = model.GetSymbolInfo(leftIdentifier).Symbol; if (assignment.Right is IdentifierNameSyntax) { var rightIdentifier = base.AnalysisContext.GetRootIdentifier(assignment.Right); ISymbol rightSymbol = model.GetSymbolInfo(rightIdentifier).Symbol; if (statement.Summary.DataFlowAnalysis.FlowsIntoSymbol(rightSymbol, givenUpSymbol.ContainingSymbol, statement, givenUpSymbol.Statement)) { var type = model.GetTypeInfo(assignment.Right).Type; if (leftSymbol != null && leftSymbol.Kind == SymbolKind.Field && base.IsFieldAccessedInSuccessor(leftSymbol as IFieldSymbol, statement.Summary, machine) && !base.AnalysisContext.IsTypePassedByValueOrImmutable(type)) { TraceInfo newTrace = new TraceInfo(); newTrace.Merge(trace); newTrace.AddErrorTrace(statement.SyntaxNode); AnalysisErrorReporter.ReportGivenUpOwnershipFieldAssignment(newTrace, leftSymbol); } return; } } else if (assignment.Right is MemberAccessExpressionSyntax) { this.AnalyzeOwnershipInExpression(givenUpSymbol, assignment.Right, statement, machine, model, trace); } else if (assignment.Right is InvocationExpressionSyntax || assignment.Right is ObjectCreationExpressionSyntax) { trace.InsertCall(statement.Summary.Method, assignment.Right); base.AnalyzeOwnershipInCall(givenUpSymbol, assignment.Right, statement, machine, model, trace); } if (assignment.Left is MemberAccessExpressionSyntax) { ISymbol outerLeftMemberSymbol = model.GetSymbolInfo(assignment.Left).Symbol; if (!outerLeftMemberSymbol.Equals(leftSymbol) && statement.Summary.DataFlowAnalysis.FlowsIntoSymbol(givenUpSymbol.ContainingSymbol, leftSymbol, givenUpSymbol.Statement, statement)) { TraceInfo newTrace = new TraceInfo(); newTrace.Merge(trace); newTrace.AddErrorTrace(statement.SyntaxNode); AnalysisErrorReporter.ReportGivenUpOwnershipAccess(newTrace); } } }
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; }
/// <summary> /// Retourne les conditions sur les paramètres dans une listes d'expressions. /// </summary> /// <param name="expressions">Liste d'expressions.</param> /// <param name="paramètres">Les paramètres du constructeur.</param> /// <param name="modèleSémantique">Modèle sémantique.</param> /// <returns>La liste d'assignations.</returns> public static IEnumerable<IfStatementSyntax> TrouveConditionsParametres(SyntaxList<StatementSyntax> expressions, ParameterListSyntax paramètres, SemanticModel modèleSémantique) => expressions .OfType<IfStatementSyntax>() .Where(e => (e.Condition ?.DescendantNodes()?.OfType<IdentifierNameSyntax>() ?.Any(identifiant => modèleSémantique.GetSymbolInfo(identifiant).Symbol?.Kind == SymbolKind.Parameter) ?? false) && (e.Statement ?.DescendantNodes()?.OfType<IdentifierNameSyntax>() ?.All(identifiant => modèleSémantique.GetSymbolInfo(identifiant).Symbol?.Kind != SymbolKind.Field) ?? false));
public IEnumerable<CodeAction> GetActions(Document document, SemanticModel model, SyntaxNode root, TextSpan span) { var token = root.FindToken(span.Start); var lambdaExpression = token.GetAncestor<LambdaExpressionSyntax>(); if ((lambdaExpression != null) && (lambdaExpression.ArrowToken.FullSpan.Contains(span))) { if (ContainsLocalReferences(model, lambdaExpression, lambdaExpression.Body)) yield break; var lambdaSymbol = model.GetSymbolInfo(lambdaExpression).Symbol as IMethodSymbol; if (lambdaSymbol == null) yield break; bool noReturn = false; BlockSyntax body; if (lambdaExpression.Body is BlockSyntax) { body = SyntaxFactory.Block(((BlockSyntax)lambdaExpression.Body).Statements); } else { if (!(lambdaExpression.Body is ExpressionSyntax)) yield break; body = SyntaxFactory.Block(); if ((lambdaSymbol.ReturnType == null) || lambdaSymbol.ReturnsVoid) { body = body.AddStatements(SyntaxFactory.ExpressionStatement((ExpressionSyntax)lambdaExpression.Body)); } else { body = body.AddStatements(SyntaxFactory.ReturnStatement((ExpressionSyntax)lambdaExpression.Body)); } } var method = GetMethod(model, span, lambdaSymbol, body); yield return GetAction(document, model, root, lambdaExpression, method); } // anonymous method var anonymousMethod = token.GetAncestor<AnonymousMethodExpressionSyntax>(); if ((anonymousMethod != null) && anonymousMethod.DelegateKeyword.FullSpan.Contains(span)) { if (ContainsLocalReferences(model, anonymousMethod, anonymousMethod.Body)) yield break; var lambdaSymbol = model.GetSymbolInfo(anonymousMethod).Symbol as IMethodSymbol; if (lambdaSymbol == null) yield break; var method = GetMethod(model, span, lambdaSymbol, SyntaxFactory.Block(((BlockSyntax)anonymousMethod.Body).Statements)); yield return GetAction(document, model, root, anonymousMethod, method); } }
private ClassType GetClassType() { var symbolInfo = semanticModel.GetSymbolInfo(elementAccessExpressionSyntax.Expression); switch (symbolInfo.Symbol) { case IFieldSymbol fs: return(fs.Type.GetClassType()); case IPropertySymbol ps: return(ps.Type.GetClassType()); case ILocalSymbol ls: return(ls.Type.GetClassType()); case IParameterSymbol paraS: return(paraS.Type.GetClassType()); case INamedTypeSymbol nts: return(nts.GetClassType()); default: throw new NotSupportedException($"{symbolInfo.Symbol.GetType()} is not supported yet."); } }
//--- 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 SyntaxNode ComputeReplacement(SemanticModel semanticModel, SyntaxNode node, CancellationToken cancellationToken) { var memberAccess = node.Parent as MemberAccessExpressionSyntax; if (memberAccess != null) { if (node == memberAccess.Name) { node = memberAccess; } } var type = semanticModel.GetSymbolInfo(node, cancellationToken).Symbol as INamedTypeSymbol; PredefinedTypeSyntax typeSyntax; if (!PredefinedSpecialTypes.TryGetValue(type.SpecialType, out typeSyntax)) { return node; } SyntaxNode newNode; if (node is CrefSyntax) { newNode = SyntaxFactory.TypeCref(typeSyntax); } else { newNode = typeSyntax; } return newNode.WithTriviaFrom(node).WithoutFormatting(); }
public static SyntaxNode CreateUsing(SyntaxNode root, ObjectCreationExpressionSyntax objectCreation, SemanticModel semanticModel) { SyntaxNode newRoot; if (objectCreation.Parent.IsKind(SyntaxKind.SimpleAssignmentExpression)) { var assignmentExpression = (AssignmentExpressionSyntax)objectCreation.Parent; var statement = assignmentExpression.Parent as ExpressionStatementSyntax; var identitySymbol = (ILocalSymbol)semanticModel.GetSymbolInfo(assignmentExpression.Left).Symbol; newRoot = UsedOutsideParentBlock(semanticModel, statement, identitySymbol) ? CreateRootAddingDisposeToEndOfMethod(root, statement, identitySymbol) : CreateRootWithUsing(root, statement, u => u.WithExpression(assignmentExpression)); } else if (objectCreation.Parent.IsKind(SyntaxKind.EqualsValueClause) && objectCreation.Parent.Parent.IsKind(SyntaxKind.VariableDeclarator)) { var variableDeclarator = (VariableDeclaratorSyntax)objectCreation.Parent.Parent; var variableDeclaration = (VariableDeclarationSyntax)variableDeclarator.Parent; var statement = (LocalDeclarationStatementSyntax)variableDeclaration.Parent; newRoot = CreateRootWithUsing(root, statement, u => u.WithDeclaration(variableDeclaration)); } else { newRoot = CreateRootWithUsing(root, (ExpressionStatementSyntax)objectCreation.Parent, u => u.WithExpression(objectCreation)); } return newRoot; }
protected bool TryGetTypes( SyntaxNode expression, SemanticModel semanticModel, out INamedTypeSymbol source, out INamedTypeSymbol destination) { source = null; destination = null; var info = semanticModel.GetSymbolInfo(expression); var methodSymbol = info.Symbol as IMethodSymbol; if (methodSymbol == null) { return false; } var compilation = semanticModel.Compilation; var taskType = compilation.GetTypeByMetadataName("System.Threading.Tasks.Task"); if (taskType == null) { return false; } var returnType = methodSymbol.ReturnType as INamedTypeSymbol; if (returnType == null) { return false; } source = taskType; destination = returnType; return true; }
private ClassType GetTypeSyntax(SyntaxNode syntaxNode) { if (syntaxNode.Parent == null) { return(null); } while (!(syntaxNode.Parent is VariableDeclarationSyntax || syntaxNode.Parent is ArrayCreationExpressionSyntax)) { return(GetTypeSyntax(syntaxNode.Parent)); } var arrayCreationSyntax = syntaxNode.Parent as ArrayCreationExpressionSyntax; if (arrayCreationSyntax != null) { return(arrayCreationSyntax.Type.ElementType.GetClassType(semanticModel)); } var typeSyntax = ((VariableDeclarationSyntax)syntaxNode.Parent).Type; var typeSymbolInfo = semanticModel.GetSymbolInfo(typeSyntax); var arrayTypeSymbol = (IArrayTypeSymbol)typeSymbolInfo.Symbol; return(arrayTypeSymbol.ElementType.GetClassType()); }
internal static SyntaxList<UsingDirectiveSyntax> GenerateUsingDirectives( this SyntaxNode @this, SemanticModel model) { var namespacesForType = new SortedSet<string>(); foreach (var childNode in @this.DescendantNodes(_ => true)) { var symbol = model.GetSymbolInfo(childNode).Symbol; if (symbol != null && symbol.Kind != SymbolKind.Namespace && symbol.ContainingNamespace != null) { if ((symbol as ITypeSymbol)?.SpecialType == SpecialType.System_Void) { continue; } var containingNamespace = symbol.GetContainingNamespace(); if (!string.IsNullOrWhiteSpace(containingNamespace)) { namespacesForType.Add(containingNamespace); } } } return SyntaxFactory.List( namespacesForType.Select(_ => SyntaxFactory.UsingDirective( SyntaxFactory.IdentifierName(_)))); }
private static MemberAccessExpressionSyntax GetMemberAccessExpressionFromAssignment(SemanticModel semanticModel, AssignmentExpressionSyntax assignmentExpression, AssignmentExpressionSyntax nullLiteralAssignment) { if (assignmentExpression == null || nullLiteralAssignment == null || !assignmentExpression.IsKind(SyntaxKind.SimpleAssignmentExpression) || !assignmentExpression.IsKind(SyntaxKind.SimpleAssignmentExpression)) return null; if (!nullLiteralAssignment.Right.IsKind(SyntaxKind.NullLiteralExpression)) return null; if (!nullLiteralAssignment.Left.IsKind(SyntaxKind.IdentifierName)) return null; if (!assignmentExpression.Left.IsKind(SyntaxKind.IdentifierName)) return null; var assignmentIdentifier = semanticModel.GetSymbolInfo(assignmentExpression.Left); var nullLiteralAssignmentIdentifier = semanticModel.GetSymbolInfo(nullLiteralAssignment.Left); if ((assignmentIdentifier.Symbol ?? nullLiteralAssignmentIdentifier.Symbol) == null) return null; if (!assignmentIdentifier.Equals(nullLiteralAssignmentIdentifier)) return null; var memberAccessExpression = assignmentExpression.Right as MemberAccessExpressionSyntax; return memberAccessExpression; }
public static bool Applicable(SemanticModel semanticModel, ArgumentSyntax argument, IEnumerable<ParameterSyntax> parameters) { var symbolInfo = semanticModel.GetSymbolInfo(argument.Expression); var symbol = symbolInfo.Symbol; if (symbol == null) { return true; } if (symbol.Kind != SymbolKind.Field && symbol.Kind != SymbolKind.Parameter && symbol.Kind != SymbolKind.Local) { return false; } var field = symbol as IFieldSymbol; if (field != null) { return !field.IsReadOnly; } return true; }
static bool IsDelegate(SemanticModel semanticModel, SyntaxNode node) { var info = semanticModel.GetSymbolInfo(node); if (info.Symbol == null || info.Symbol.IsKind(SymbolKind.Event)) return false; var type = info.Symbol.GetReturnType(); return type != null && type.TypeKind == TypeKind.Delegate; }
public static bool TryGetFormattingParameters( SemanticModel semanticModel, InvocationExpressionSyntax invocationExpression, out ExpressionSyntax formatArgument, out IList<ExpressionSyntax> arguments, Func<IParameterSymbol, ExpressionSyntax, bool> argumentFilter, CancellationToken cancellationToken = default (CancellationToken)) { if (semanticModel == null) throw new ArgumentNullException(nameof(semanticModel)); if (invocationExpression == null) throw new ArgumentNullException(nameof(invocationExpression)); var symbolInfo = semanticModel.GetSymbolInfo(invocationExpression.Expression, cancellationToken); if (argumentFilter == null) argumentFilter = (p, e) => true; var symbol = symbolInfo.Symbol; formatArgument = null; arguments = new List<ExpressionSyntax>(); var method = symbol as IMethodSymbol; if (method == null || method.Kind != SymbolKind.Method) return false; // Serach for method of type: void Name(string format, params object[] args); IList<IMethodSymbol> methods = method.ContainingType.GetMembers (method.Name).OfType<IMethodSymbol>().ToList(); if (!methods.Any(m => m.Parameters.Length == 2 && m.Parameters[0].Type.SpecialType == SpecialType.System_String && parameterNames.Contains(m.Parameters[0].Name) && m.Parameters[1].IsParams)) return false; // TODO: Handle argument -> parameter mapping. //var argumentToParameterMap = invocationResolveResult.GetArgumentToParameterMap(); //var resolvedParameters = invocationResolveResult.Member.Parameters; var allArguments = invocationExpression.ArgumentList.Arguments.ToArray(); for (int i = 0; i < allArguments.Length; i++) { var parameterIndex = i; //argumentToParameterMap[i]; if (parameterIndex < 0 || parameterIndex >= method.Parameters.Length) { // No valid mapping for this argument, skip it continue; } var parameter = method.Parameters[parameterIndex]; var argument = allArguments[i]; if (i == 0 && parameter.Type.SpecialType == SpecialType.System_String && parameterNames.Contains(parameter.Name)) { formatArgument = argument.Expression; } else if (formatArgument != null && parameter.IsParams /*&& !invocationResolveResult.IsExpandedForm*/) { var ace = argument.Expression as ArrayCreationExpressionSyntax; if (ace == null || ace.Initializer == null) return false; foreach (var element in ace.Initializer.Expressions) { if (argumentFilter(parameter, element)) arguments.Add(argument.Expression); } } else if (formatArgument != null && argumentFilter(parameter, argument.Expression)) { arguments.Add(argument.Expression); } } return formatArgument != null; }
public static IEnumerable<Fields> GetInvokedMethodsOfMock(ExpressionSyntax memberAccessExpresion, SemanticModel testSemanticModel, IEnumerable<SutInfo> suts) { var isLeftSideOfAssignExpression = memberAccessExpresion.IsLeftSideOfAssignExpression(); var symbol = testSemanticModel.GetSymbolInfo(memberAccessExpresion).Symbol; if(symbol == null) return new Fields[0]; var refType = symbol.ContainingType; var suitableSut = refType.GetSuitableSut(suts); if (suitableSut == null) return new Fields[0]; var sutSubstitutionsByInterface = TestSemanticHelper.GetSubstitutions(refType); var sutSubstitutionsByConcreteType = TestSemanticHelper.GetSubstitutions(suitableSut.SymbolInfo.Symbol); var symbolSubstitutions = TestSemanticHelper.GetSubstitutions(symbol); var sutSubstitutions = sutSubstitutionsByInterface.Concat(sutSubstitutionsByConcreteType) .Concat(symbolSubstitutions) .DistinctBy(x => x.Key) .ToDictionary(x => x.Key, x => x.Value); if (suitableSut.SemanticModel == null) return new Fields[0]; var suitableSutSymbol = suitableSut.GetSuitableSutSymbol(symbol); var sutFirstLocation = suitableSutSymbol.Locations.First(); var node = sutFirstLocation.GetMemberNode(); var allNodes = node.DescendantNodesAndSelf().Where(x => !x.Span.IsEmpty).ToList(); var allSyntax = new List<ExpressionSyntax>(); var count = int.MaxValue; while (count != allSyntax.Count ) { count = allSyntax.Count; var methods = TestSemanticHelper.GetMethodsToConfigureMocks(allNodes).ToArray(); var properties = TestSemanticHelper.GetPropertiesToConfigureMocks(allNodes, methods, isLeftSideOfAssignExpression).ToArray(); allSyntax.AddRange(methods.Concat(properties).Distinct()); allSyntax = allSyntax.Distinct().ToList(); allNodes = allSyntax.SelectMany(syn => syn.DescendantNodesAndSelf().Where(x => !x.Span.IsEmpty)) .SelectMany(x => GetReferencedNodes(x, suitableSut)) .ToList(); } var invokedMethodsOfMocks = GetInvokedMethodsOfMocks(allSyntax, suitableSut.SemanticModel, suitableSut, testSemanticModel, sutSubstitutions); invokedMethodsOfMocks = invokedMethodsOfMocks.Where(DontHaveSetups(suitableSut)); return invokedMethodsOfMocks; }
public static IEnumerable<AttributeSyntaxSymbolMapping> GetAttributesForParameter(ParameterSyntax parameter, SemanticModel semanticModel) { return parameter.AttributeLists .SelectMany(al => al.Attributes) .Select(attr => new AttributeSyntaxSymbolMapping(attr, semanticModel.GetSymbolInfo(attr).Symbol as IMethodSymbol)) .Where(attr => attr.Symbol != null); }
public static ISymbol GetDeclaredOrReferencedSymbol(this SyntaxNode node, SemanticModel model) { if (node == null) { return null; } return model.GetDeclaredSymbol(node) ?? model.GetSymbolInfo(node).Symbol; }
private static IMethodSymbol GetCallerMethodSymbol(SemanticModel semanticModel, SimpleNameSyntax name, int argumentsCount) { var symbolInfo = semanticModel.GetSymbolInfo(name); return symbolInfo.Symbol as IMethodSymbol ?? symbolInfo .CandidateSymbols .OfType<IMethodSymbol>() .FirstOrDefault(s => s.Parameters.Length == argumentsCount + 1); }
public static SyntaxNode CreateUsing(SyntaxNode root, ObjectCreationExpressionSyntax objectCreation, SemanticModel semanticModel) { SyntaxNode newRoot; if (objectCreation.Parent.IsKind(SyntaxKind.SimpleAssignmentExpression)) { var assignmentExpression = (AssignmentExpressionSyntax)objectCreation.Parent; var statement = assignmentExpression.Parent as ExpressionStatementSyntax; var identitySymbol = (ILocalSymbol)semanticModel.GetSymbolInfo(assignmentExpression.Left).Symbol; newRoot = UsedOutsideParentBlock(semanticModel, statement, identitySymbol) ? CreateRootAddingDisposeToEndOfMethod(root, statement, identitySymbol) : CreateRootWithUsing(root, statement, u => u.WithExpression(assignmentExpression)); } else if (objectCreation.Parent.IsKind(SyntaxKind.EqualsValueClause) && objectCreation.Parent.Parent.IsKind(SyntaxKind.VariableDeclarator)) { var variableDeclarator = (VariableDeclaratorSyntax)objectCreation.Parent.Parent; var variableDeclaration = (VariableDeclarationSyntax)variableDeclarator.Parent; var statement = (LocalDeclarationStatementSyntax)variableDeclaration.Parent; newRoot = CreateRootWithUsing(root, statement, u => u.WithDeclaration(variableDeclaration.WithoutLeadingTrivia())); } else if (objectCreation.Parent.IsKind(SyntaxKind.Argument)) { var identifierName = GetIdentifierName(objectCreation, semanticModel); var variableDeclaration = SyntaxFactory.VariableDeclaration(SyntaxFactory.IdentifierName(@"var")) .WithVariables(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.VariableDeclarator(SyntaxFactory.Identifier(identifierName)) .WithInitializer(SyntaxFactory.EqualsValueClause(SyntaxFactory.Token(SyntaxKind.EqualsToken), objectCreation)))); var arg = objectCreation.Parent as ArgumentSyntax; var args = objectCreation.Parent.Parent as ArgumentListSyntax; var newArgs = args.ReplaceNode(arg, arg.WithExpression(SyntaxFactory.IdentifierName(identifierName))); StatementSyntax statement = objectCreation.FirstAncestorOfType<ExpressionStatementSyntax>(); if (statement != null) { var exprStatement = statement.ReplaceNode(args, newArgs); var newUsingStatment = CreateUsingStatement(exprStatement, SyntaxFactory.Block(exprStatement)) .WithDeclaration(variableDeclaration); return root.ReplaceNode(statement, newUsingStatment); } statement = (StatementSyntax)objectCreation.Ancestors().First(node => node is StatementSyntax); var newStatement = statement.ReplaceNode(args, newArgs); var statementsForUsing = new[] { newStatement }.Concat(GetChildStatementsAfter(statement)); var usingBlock = SyntaxFactory.Block(statementsForUsing); var usingStatement = CreateUsingStatement(newStatement, usingBlock) .WithDeclaration(variableDeclaration); var statementsToReplace = new List<StatementSyntax> { statement }; statementsToReplace.AddRange(statementsForUsing.Skip(1)); newRoot = root.ReplaceNodes(statementsToReplace, (node, _) => node.Equals(statement) ? usingStatement : null); } else { newRoot = CreateRootWithUsing(root, (ExpressionStatementSyntax)objectCreation.Parent, u => u.WithExpression(objectCreation)); } return newRoot; }
private static bool IsOrdinalOrOrdinalIgnoreCase(ArgumentSyntax argumentSyntax, SemanticModel model) { var argumentSymbol = model.GetSymbolInfo(argumentSyntax.Expression).Symbol; if (argumentSymbol != null) { return IsOrdinalOrOrdinalIgnoreCase(argumentSymbol.Name); } return false; }
private static bool IsThrowArgumentExceptionStatement(StatementSyntax statement, SemanticModel semanticModel) { var throwStatement = statement as ThrowStatementSyntax; var objectCreation = throwStatement?.Expression as ObjectCreationExpressionSyntax; if (objectCreation == null) return false; var symbol = semanticModel.GetSymbolInfo(objectCreation.Type).Symbol; return symbol.IsArgumentExceptionType(semanticModel); }
public static glsl.VariableDeclarationSyntax Translate(this cs.VariableDeclarationSyntax node) { return(new glsl.VariableDeclarationSyntax() { Type = new glsl.TypeSyntax() { Name = model.GetSymbolInfo(node.Type).Symbol.Name }, Variables = node.Variables.Select(v => v.Translate()).ToList() }); }
private static DiagnosticDescriptor GetCorrespondingDiagnostic(SemanticModel semanticModel, InvocationExpressionSyntax invocation) { var methodName = (invocation?.Expression as MemberAccessExpressionSyntax)?.Name?.ToString(); var nameToCheck = methodName == "Any" ? allName : methodName == "All" ? anyName : null; if (nameToCheck == null) return null; var methodSymbol = semanticModel.GetSymbolInfo(invocation.Expression).Symbol as IMethodSymbol; if (methodSymbol?.Parameters.Length != 1) return null; if (!IsLambdaWithoutBody(invocation)) return null; if (!OtherMethodExists(invocation, nameToCheck, semanticModel)) return null; return methodName == "Any" ? RuleAny : RuleAll; }
private bool IsPrivateField(MemberAccessExpressionSyntax memberSyntax, SemanticModel model, CancellationToken token) { var symbolInfo = model.GetSymbolInfo(memberSyntax, token); if (symbolInfo.Symbol != null && symbolInfo.Symbol.Kind == SymbolKind.Field) { var field = (IFieldSymbol)symbolInfo.Symbol; return field.DeclaredAccessibility == Accessibility.Private; } return false; }
private bool IsInternal(SyntaxNode invocation, SemanticModel model, out string nameSpace) { var containingType = _documentWalker.GetContainingNodeOfType<TypeDeclarationSyntax>(invocation); var typeSymbol = model.GetDeclaredSymbol(containingType) as INamedTypeSymbol; if (typeSymbol == null) throw new NoNamedTypeException(containingType.ToString()); nameSpace = typeSymbol.ContainingNamespace.Name; var invocationSymbol = model.GetSymbolInfo(invocation).Symbol; if (invocationSymbol == null) return true; // No Symbol -> Anonymous Method -> is Internal var members = containingType.Members; return _documentWalker.IsSymbolInvocationOfNodes(members, invocationSymbol, model); }
/// <summary> /// Analyzes the ownership of the given-up symbol /// in the assignment expression. /// </summary> /// <param name="givenUpSymbol">GivenUpOwnershipSymbol</param> /// <param name="assignment">AssignmentExpressionSyntax</param> /// <param name="statement">Statement</param> /// <param name="machine">StateMachine</param> /// <param name="model">SemanticModel</param> /// <param name="trace">TraceInfo</param> protected override void AnalyzeOwnershipInAssignment(GivenUpOwnershipSymbol givenUpSymbol, AssignmentExpressionSyntax assignment, Statement statement, StateMachine machine, SemanticModel model, TraceInfo trace) { IdentifierNameSyntax leftIdentifier = base.AnalysisContext.GetRootIdentifier(assignment.Left); ISymbol leftSymbol = model.GetSymbolInfo(leftIdentifier).Symbol; this.AnalyzeGivingUpFieldOwnership(givenUpSymbol, leftSymbol, statement, machine, trace); this.AnalyzeOwnershipInExpression(givenUpSymbol, assignment.Right, statement, machine, model, trace); }
/// <summary> /// Returns true if the given expression is the expected one. /// </summary> /// <param name="expression">ExpressionSyntax</param> /// <param name="expectedName">Text</param> /// <param name="model">SemanticModel</param> /// <returns>Boolean</returns> protected bool IsExpectedExpression(ExpressionSyntax expression, string expectedName, SemanticModel model) { var symbol = model.GetSymbolInfo(expression).Symbol; if (this.IsExpectedSymbol(symbol, expectedName)) { return true; } var candidateSymbols = model.GetSymbolInfo(expression).CandidateSymbols; foreach (var candidate in candidateSymbols) { if (this.IsExpectedSymbol(candidate, expectedName)) { return true; } } return false; }
public static IFieldSymbol ScanGetter(this AccessorBlockSyntax getter, SemanticModel model) { if (getter == null || getter.Statements.Count != 1) return null; var retStatement = getter.Statements.First() as ReturnStatementSyntax; if (retStatement == null) return null; if (!IsPossibleExpression(retStatement.Expression)) return null; var retSymbol = model.GetSymbolInfo(retStatement.Expression).Symbol; return ((IFieldSymbol)retSymbol); }
private static bool IsAssignmentOutsideConstructor(AssignmentExpressionSyntax assignment, ISymbol fieldSymbol, SemanticModel model) { var assignedSymbol = model.GetSymbolInfo(assignment.Left); if (assignedSymbol.Symbol != fieldSymbol) { return false; } // Method (or whatever) enclosing the assignment var enclosingSymbol = model.GetEnclosingSymbol(assignment.SpanStart) as IMethodSymbol; var isCtor = enclosingSymbol?.MethodKind == MethodKind.Constructor; return !isCtor; }
public static SymbolInfo GetSymbolInfo(this SemanticModel semanticModel, SyntaxNode node, CancellationToken cancellationToken = default(CancellationToken)) { return(semanticModel.GetSymbolInfo(node, cancellationToken)); }
/// <summary> /// Returns the semantic symbol of the provided syntax node, or the declared symbol if the previous cast was invalid /// </summary> /// <param name="syntaxNode"></param> /// <param name="semanticModel"></param> /// <returns>The symbol or declared symbol of the provided syntax node</returns> public static ISymbol GetSymbolOrDeclared(this SyntaxNode syntaxNode, SemanticModel semanticModel) { return(semanticModel.GetSymbolInfo(syntaxNode).Symbol ?? semanticModel.GetDeclaredSymbol(syntaxNode)); }
public override void VisitMemberAccessExpression(MemberAccessExpressionSyntax node) { var expressionSymbol = _semanticModel.GetSymbolInfo(node.Expression).Symbol; if (expressionSymbol is ITypeSymbol) { return; } var parameterSymbol = expressionSymbol as IParameterSymbol; PropertyDependence variableProperties; var propertySymbol = _semanticModel.GetSymbolInfo(node).Symbol as PropertySymbol; if (propertySymbol == null) { return; } bool systemProperty = propertySymbol.ContainingType.ContainingNamespace != null && propertySymbol.ContainingType.ContainingNamespace.ToString().StartsWith("System"); if (systemProperty) { switch (propertySymbol.ContainingType.ConstructedFrom.ToString()) { case "System.Collections.Generic.KeyValuePair<TKey, TValue>": _properties.Error = true; _properties.Last.Error = true; _proceed = true; return; } } Action applyOnParameter = () => { bool knownVariable = _variables.TryGetValue(parameterSymbol.Name, out variableProperties); if (knownVariable && variableProperties != null) { PropertyDependence newLast; if (variableProperties.PropertiesDependences.TryGetValue(propertySymbol.Name, out newLast)) { _properties.Last = newLast.Last; _properties = newLast; _proceed = true; return; } } if (systemProperty) { _proceed = true; return; } if (knownVariable) { if (variableProperties == null || variableProperties.Last.Dependences.Count == 0) { AddProperty(new List <PropertySymbolInfo>() { PropertySymbolInfo.Get(propertySymbol) }); } else { foreach (var dp in variableProperties.Last.Dependences) { AddProperty(new List <PropertySymbolInfo>(dp) { PropertySymbolInfo.Get(propertySymbol) }); } } _proceed = true; } }; if (parameterSymbol != null) { applyOnParameter(); if (_proceed) { return; } } { var membersVisitor = new GetMembersVisitor(this); membersVisitor.Visit(node.Expression); if ((parameterSymbol = membersVisitor._properties.ParameterSymbol) != null) { applyOnParameter(); if (_proceed) { return; } } AddProperties(membersVisitor._properties, _properties); PropertyDependence newLast; if (membersVisitor._properties.Last.PropertiesDependences.TryGetValue(propertySymbol.Name, out newLast)) { AddProperties(newLast); _properties.Last = newLast.Last; _proceed = true; return; } if (systemProperty) { _proceed = true; return; } if (membersVisitor._properties.Dependences.Count != 0 || membersVisitor._properties.PropertiesDependences.Count != 0) { var dependencesList = new List <List <PropertySymbolInfo> >(); foreach (var pd in membersVisitor._properties.Last.Dependences) { var dependences = new List <PropertySymbolInfo>(pd); dependences.Add(PropertySymbolInfo.Get(propertySymbol)); AddProperty(dependences); dependencesList.Add(dependences); } _properties.Last = new PropertyDependence { Dependences = dependencesList }; _proceed = true; } } }
/// <summary> /// Returns the semantic symbol of the provided syntax node /// </summary> /// <param name="syntaxNode">The syntax node</param> /// <param name="model">The syntax semantic model</param> /// <returns>The symbol of the provided syntax node</returns> public static TSymbolType GetSymbolAs <TSymbolType>(this SyntaxNode syntaxNode, SemanticModel model) where TSymbolType : class, ISymbol { return(model.GetSymbolInfo(syntaxNode).Symbol as TSymbolType); }
/// <summary> /// Returns the semantic symbol of the provided syntax node /// </summary> /// <param name="syntaxNode">The syntax node</param> /// <param name="model">The syntax semantic model</param> /// <returns>The symbol of the provided syntax node</returns> public static ISymbol GetSymbol(this SyntaxNode syntaxNode, SemanticModel model) { return(model.GetSymbolInfo(syntaxNode).Symbol); }