static bool AreVariablesOnlyWrittenInsideDeclaration(LocalDeclarationStatementSyntax declaration, SemanticModel semanticModel) { var dfa = semanticModel.AnalyzeDataFlow(declaration); var symbols = from variable in declaration.Declaration.Variables select semanticModel.GetDeclaredSymbol(variable); var result = !symbols.Any(s => dfa.WrittenOutside.Contains(s)); return result; }
private static bool MethodShouldBeStatic(MethodDeclarationSyntax method, SemanticModel semanticModel) { if (method.Body == null) return false; var dataFlow = semanticModel.AnalyzeDataFlow(method.Body); var variablesDeclared = dataFlow.VariablesDeclared.ToList(); var variablesRead = dataFlow.ReadInside.Union(dataFlow.ReadOutside).ToList(); if (variablesDeclared.Any(c => c.Name == "this")) { return false; } if (variablesRead.Any(c => c.Name == "this")) { return false; } return true;
protected override ImmutableArray<ISymbol> GetCapturedVariables(SemanticModel model, SyntaxNode memberBody) { Debug.Assert(memberBody.IsKind(SyntaxKind.Block) || memberBody is ExpressionSyntax); return model.AnalyzeDataFlow(memberBody).Captured; }
private static bool UsedOutsideParentBlock(SemanticModel semanticModel, StatementSyntax expressionStatement, ISymbol identitySymbol) { var block = expressionStatement.FirstAncestorOrSelf<BlockSyntax>(); var method = expressionStatement.FirstAncestorOrSelf<MethodDeclarationSyntax>(); var methodBlock = method.Body; if (methodBlock.Equals(block)) return false; var collectionOfStatementsAfter = GetStatementsInBlocksAfter(block); foreach (var allStatementsAfterBlock in collectionOfStatementsAfter) { if (!allStatementsAfterBlock.Any()) continue; var dataFlowAnalysis = semanticModel.AnalyzeDataFlow(allStatementsAfterBlock.First(), allStatementsAfterBlock.Last()); if (!dataFlowAnalysis.Succeeded) continue; var isUsed = dataFlowAnalysis.ReadInside.Contains(identitySymbol) || dataFlowAnalysis.WrittenInside.Contains(identitySymbol); if (isUsed) return true; } return false; }
private static IEnumerable<ISymbol> GetReadSymbolsCondition(ForStatementSyntax forNode, SemanticModel semanticModel) { if (forNode.Condition == null) { return new ISymbol[0]; } var dataFlowAnalysis = semanticModel.AnalyzeDataFlow(forNode.Condition); return dataFlowAnalysis.Succeeded ? dataFlowAnalysis.ReadInside.Distinct() : new ISymbol[0]; }
private static bool CanBeMadeConst(LocalDeclarationStatementSyntax localDeclaration, SemanticModel semanticModel) { // already const? if (localDeclaration.Modifiers.Any(SyntaxKind.ConstKeyword)) { return false; } // Ensure that all variables in the local declaration have initializers that // are assigned with constant values. foreach (var variable in localDeclaration.Declaration.Variables) { var initializer = variable.Initializer; if (initializer == null) { return false; } var constantValue = semanticModel.GetConstantValue(initializer.Value); if (!constantValue.HasValue) { return false; } var variableTypeName = localDeclaration.Declaration.Type; var variableType = semanticModel.GetTypeInfo(variableTypeName).ConvertedType; // Ensure that the initializer value can be converted to the type of the // local declaration without a user-defined conversion. var conversion = semanticModel.ClassifyConversion(initializer.Value, variableType); if (!conversion.Exists || conversion.IsUserDefined) { return false; } // Special cases: // * If the constant value is a string, the type of the local declaration // must be System.String. // * If the constant value is null, the type of the local declaration must // be a reference type. if (constantValue.Value is string) { if (variableType.SpecialType != SpecialType.System_String) { return false; } } else if (variableType.IsReferenceType && constantValue.Value != null) { return false; } } // Perform data flow analysis on the local declaration. var dataFlowAnalysis = semanticModel.AnalyzeDataFlow(localDeclaration); // Retrieve the local symbol for each variable in the local declaration // and ensure that it is not written outside of the data flow analysis region. foreach (var variable in localDeclaration.Declaration.Variables) { var variableSymbol = semanticModel.GetDeclaredSymbol(variable); if (dataFlowAnalysis.WrittenOutside.Contains(variableSymbol)) { return false; } } return true; }
public static DataFlowAnalysis AnalyzeDataFlow(this SemanticModel semanticModel, SyntaxNode statementOrExpression) { return(semanticModel.AnalyzeDataFlow(statementOrExpression)); }
public static DataFlowAnalysis AnalyzeDataFlow(this SemanticModel semanticModel, SyntaxNode firstStatement, SyntaxNode lastStatement) { return(semanticModel.AnalyzeDataFlow(firstStatement, lastStatement)); }
static bool ContainsLocalReferences(SemanticModel context, SyntaxNode expr, SyntaxNode body) { var dataFlowAnalysis = context.AnalyzeDataFlow(expr); return dataFlowAnalysis.Captured.Any(); }