private void AnalyzeLoop(BlockSyntax blockSyntax) { var context = new AnalyzeContext(_efAnalyzer.Project, _efAnalyzer.Document); _efAnalyzer.AnalyzedContexts.Add(context); var methodInvocations = blockSyntax.DescendantNodes() .Where(q => q.Kind() == SyntaxKind.InvocationExpression) .OfType <InvocationExpressionSyntax>() .ToArray(); foreach (var methodInvocation in methodInvocations) { var detectAddRemoveInsideLoopAnalyzer = new DetectAddRemoveInsideLoopAnalyzer(_efAnalyzer.DocumentSemanticModel); context.RuleViolations.AddRange(detectAddRemoveInsideLoopAnalyzer.AnalyzeSyntaxNode(methodInvocation)); var detectSaveInsideLoopAnalyzer = new DetectSaveInsideLoopAnalyzer(_efAnalyzer.DocumentSemanticModel); context.RuleViolations.AddRange(detectSaveInsideLoopAnalyzer.AnalyzeSyntaxNode(methodInvocation)); } var objectCreations = blockSyntax.DescendantNodes() .Where(q => q.Kind() == SyntaxKind.ObjectCreationExpression) .OfType <ObjectCreationExpressionSyntax>() .ToArray(); foreach (var objectCreation in objectCreations) { var detectDbContextCreationInsideLoopAnalyzer = new DetectDbContextCreationInsideLoopAnalyzer(_efAnalyzer.DocumentSemanticModel); context.RuleViolations.AddRange(detectDbContextCreationInsideLoopAnalyzer.AnalyzeSyntaxNode(objectCreation)); } }
public static IReadOnlyList <ExpressionSyntax> GetAllThrowExpressions(this BlockSyntax codeBlock) { var expressionFromThrowStatements = codeBlock.DescendantNodes().OfType <ThrowStatementSyntax>().Select(x => x.Expression); var expressionFromThrowExpressions = codeBlock.DescendantNodes().OfType <ThrowExpressionSyntax>().Select(x => x.Expression); return(expressionFromThrowStatements.Concat(expressionFromThrowExpressions).ToList()); }
private static void GetLabelSymbols( BlockSyntax body, SemanticModel model, List <ISymbol> list ) { var labels = body.DescendantNodes().OfType <LabeledStatementSyntax>(); foreach (var n in labels) { // Label: -> 'Label' is token var sym = model.GetDeclaredSymbol(n); list.Add(sym); } var swlabels = body.DescendantNodes().OfType <SwitchLabelSyntax>(); foreach (var n in swlabels) { // label value has NO symbol, Type is expr's type // e.g. case "A": -> string type // var info1 = model.GetTypeInfo(n.Value); // var info2 = model.GetSymbolInfo(n.Value); var sym = model.GetDeclaredSymbol(n); list.Add(sym); } }
private static IReadOnlyList <ExpressionSyntax> GetAllThrowExpressions(BlockSyntax codeBlock) { IEnumerable <ExpressionSyntax> expressionFromThrowStatements = codeBlock.DescendantNodes() .OfType <ThrowStatementSyntax>() .Select(x => x.Expression) .RemoveNulls(); IEnumerable <ExpressionSyntax> expressionFromThrowExpressions = codeBlock.DescendantNodes() .OfType <ThrowExpressionSyntax>() .Select(x => x.Expression); return(expressionFromThrowStatements.Concat(expressionFromThrowExpressions) .ToArray()); }
private static void ComputeRefactoring( RefactoringContext context, SyntaxNode node, BlockSyntax body, SemanticModel semanticModel) { if (body? .DescendantNodes(body.Span, f => !f.IsNestedMethod()) .Any(f => f.IsKind(SyntaxKind.YieldReturnStatement)) == true) { var symbol = (IMethodSymbol)semanticModel.GetDeclaredSymbol(node, context.CancellationToken); if (symbol?.IsErrorType() == false) { ITypeSymbol type = GetElementType(symbol.ReturnType, semanticModel); if (type?.IsErrorType() == false) { context.RegisterRefactoring( "Use List<T> instead of yield", cancellationToken => RefactorAsync(context.Document, type, body, body.Statements, cancellationToken)); } } } }
public void CreateNthPrimeOperation_ShouldUseALambdaExpression() { BlockSyntax body = GetMethodBody(nameof(MathOperationFactory.CreateNthPrimeOperation)); var lambdaSyntax = body.DescendantNodes().OfType <LambdaExpressionSyntax>().FirstOrDefault(); Assert.That(lambdaSyntax, Is.Not.Null); }
private static bool ContainsOtherAwaitOrReturnWithoutAwait(BlockSyntax body, HashSet <AwaitExpressionSyntax> awaitExpressions) { foreach (SyntaxNode descendant in body.DescendantNodes(body.Span, f => !f.IsNestedMethod() && !f.IsKind(SyntaxKind.ReturnStatement))) { switch (descendant.Kind()) { case SyntaxKind.ReturnStatement: { ExpressionSyntax expression = ((ReturnStatementSyntax)descendant).Expression; if (expression?.IsKind(SyntaxKind.AwaitExpression) == true) { if (!awaitExpressions.Contains((AwaitExpressionSyntax)expression)) { return(true); } } else { return(true); } break; } case SyntaxKind.AwaitExpression: { return(true); } } } return(false); }
/// <summary> /// Checks whether a block has an assignment of a syntax token with a given name. /// </summary> /// <param name="blockSyntax">The block syntax.</param> /// <param name="checkIdentifierName">The syntax token.</param> /// <param name="memberName">Name of the assignment.</param> /// <param name="assignmentExpression">The assignment expression.</param> /// <returns></returns> public static bool AssignsMemberWithName(this BlockSyntax blockSyntax, SyntaxToken checkIdentifierName, string memberName, out AssignmentExpressionSyntax assignmentExpression) { assignmentExpression = default(AssignmentExpressionSyntax); var s = blockSyntax?.DescendantNodes().OfType <AssignmentExpressionSyntax>().ToList(); if (s == null || !s.Any()) { return(false); } foreach (var assignment in s) { if (assignment.Left is MemberAccessExpressionSyntax memberAccess) { if (memberAccess.Expression is IdentifierNameSyntax identifierName) { if (identifierName.Identifier.Value == checkIdentifierName.Value) { if (memberAccess.Name.Identifier.Value.Equals(memberName)) { assignmentExpression = assignment; return(true); } } } } } return(false); }
private bool IsWrittenAfter( SemanticModel semanticModel, ISymbol local, BlockSyntax block, AnonymousFunctionExpressionSyntax anonymousFunction, CancellationToken cancellationToken) { var anonymousFunctionStart = anonymousFunction.SpanStart; foreach (var descendentNode in block.DescendantNodes()) { var descendentStart = descendentNode.Span.Start; if (descendentStart <= anonymousFunctionStart) { // This node is before the local declaration. Can ignore it entirely as it could // not be an access to the local. continue; } if (descendentNode.IsKind(SyntaxKind.IdentifierName)) { var identifierName = (IdentifierNameSyntax)descendentNode; if (identifierName.Identifier.ValueText == local.Name && identifierName.IsWrittenTo() && local.Equals(semanticModel.GetSymbolInfo(identifierName, cancellationToken).GetAnySymbol())) { return(true); } } } return(false); }
private static BlockSyntax UpdateStatementsForAsyncMethod(BlockSyntax body, SemanticModel semanticModel, bool hasResultValue, bool returnTypeChanged, CancellationToken cancellationToken) { var fixedUpBlock = body.ReplaceNodes( body.DescendantNodes().OfType <ReturnStatementSyntax>(), (f, n) => { if (hasResultValue) { return(returnTypeChanged ? n : n.WithExpression(SyntaxFactory.AwaitExpression(n.Expression).TrySimplify(f.Expression, semanticModel, cancellationToken))); } if (body.Statements.Last() == f) { // If it is the last statement in the method, we can remove it since a return is implied. return(null); } return(n .WithExpression(null) // don't return any value .WithReturnKeyword(n.ReturnKeyword.WithTrailingTrivia(SyntaxFactory.TriviaList()))); // remove the trailing space after the keyword }); return(fixedUpBlock); }
static bool HasReturnContract(BlockSyntax bodyStatement, string parameterName) { var workspace = new AdhocWorkspace(); foreach (var expression in bodyStatement.DescendantNodes().OfType <ExpressionStatementSyntax>()) { var formatted = Formatter.Format(expression, workspace).ToString(); if (formatted == $"Contract.Requires(string.IsNullOrEmpty({parameterName}) == false);") { return(true); } if (formatted == $"Contract.Requires(false == string.IsNullOrEmpty({parameterName}));") { return(true); } if (formatted == $"Contract.Requires(!string.IsNullOrEmpty({parameterName}));") { return(true); } } return(false); }
/// <summary> /// Declares any "discard"ed variables - i.e. MyFunc(out _) - for this block and all nested blocks. /// </summary> private string DeclareDiscardedVariables(BlockSyntax block) { StringBuilder sb = new StringBuilder(); SemanticModel semanticModel = GetModel(block); IEnumerable <ISymbol> discardedVariables = block .DescendantNodes() .Where(x => x.IsKind(SyntaxKind.IdentifierName)) .Select(x => semanticModel.GetSymbolInfo(x).Symbol) .Where(x => x.Kind == SymbolKind.Discard) .Cast <IDiscardSymbol>(); List <ISymbol> alreadyWrittenTypes = new List <ISymbol>(); foreach (IDiscardSymbol discardedVariable in discardedVariables) { if (alreadyWrittenTypes.Contains(discardedVariable.Type)) { continue; } sb.Append(" "); sb.Append(GetDiscardedVariableType(discardedVariable)); sb.Append(' '); sb.Append(GetDiscardedVariableName(discardedVariable)); sb.AppendLine(";"); alreadyWrittenTypes.Add(discardedVariable.Type); } return(sb.ToString()); }
public int RecurseBlockUsageCount(BlockSyntax block, SyntaxToken methodID, int initialCount) { int usages = initialCount; foreach (var statement in block.Statements) { foreach (var token in statement.DescendantTokens()) { try { if (token.Value.Equals(methodID.Value)) { usages += 1; } } catch (NullReferenceException) // raised when parsing the 'null' C# token { // 'null' token parse, ignore it } } } foreach (var childBlock in block.DescendantNodes().OfType <BlockSyntax>().ToList()) { usages += RecurseBlockUsageCount(childBlock, methodID, 0); } return(usages); }
private IEnumerable <String> GetNameLocalVaraibleExpectedCreatedClass(SemanticModel semanticModel, BlockSyntax blockSyntax) { foreach (var node in blockSyntax.DescendantNodes()) { var localDeclarationStatement = node as LocalDeclarationStatementSyntax; if (localDeclarationStatement == null) { continue; } if (localDeclarationStatement.Declaration == null) { continue; } var variableDeclaration = localDeclarationStatement.Declaration as VariableDeclarationSyntax; if (variableDeclaration == null || !variableDeclaration.Variables.Any()) { continue; } var declarator = variableDeclaration.Variables.First(); var objectCreation = declarator.DescendantNodes().FirstOrDefault(n => n is ObjectCreationExpressionSyntax) as ObjectCreationExpressionSyntax; if (objectCreation == null) { continue; } var typeInfo = semanticModel.GetTypeInfo(objectCreation); if (TypeIsExist(typeInfo)) { continue; } yield return(declarator.GetFirstToken().Text); } }
private ArgumentSyntax FindThreadArgument(string variableName, BlockSyntax block) { var creationNodes = block.DescendantNodes().OfType <ObjectCreationExpressionSyntax>(); foreach (var creation in creationNodes) { if (creation.AncestorsAndSelf().OfType <VariableDeclaratorSyntax>().Any()) { if (creation.AncestorsAndSelf().OfType <VariableDeclaratorSyntax>().First().Identifier.ToString() == variableName) { return(creation.DescendantNodes().OfType <ArgumentSyntax>().First()); } } else if (creation.AncestorsAndSelf().OfType <AssignmentExpressionSyntax>().Any()) { if (creation.AncestorsAndSelf().OfType <AssignmentExpressionSyntax>().First().Left.ToString() == variableName) { return(creation.DescendantNodes().OfType <ArgumentSyntax>().First()); } } } return(null); }
private static IEnumerable <ReturnStatementSyntax> GetReturnNullStatements(BlockSyntax methodBlock) { return(methodBlock.DescendantNodes() .OfType <ReturnStatementSyntax>() .Where(returnStatement => returnStatement.Expression.IsKind(SyntaxKind.NullLiteralExpression) && returnStatement.FirstAncestorOrSelf <ParenthesizedLambdaExpressionSyntax>() == null)); }
private static bool ContainsOtherYieldStatement(BlockSyntax block, StatementSyntax statement) { TextSpan span = TextSpan.FromBounds(block.SpanStart, statement.FullSpan.Start); return(block .DescendantNodes(span, f => !f.IsNestedMethod()) .Any(f => f.IsKind(SyntaxKind.YieldBreakStatement, SyntaxKind.YieldReturnStatement))); }
private void GetAnonymousTypeOrFuncSymbols(BlockSyntax body, SemanticModel model, List <ISymbol> list) { IEnumerable <ExpressionSyntax> exprs = body.DescendantNodes().OfType <SimpleLambdaExpressionSyntax>(); IEnumerable <ExpressionSyntax> tmp = body.DescendantNodes().OfType <ParenthesizedLambdaExpressionSyntax>(); exprs = exprs.Concat(tmp); tmp = body.DescendantNodes().OfType <AnonymousMethodExpressionSyntax>(); exprs = exprs.Concat(tmp); tmp = body.DescendantNodes().OfType <AnonymousObjectCreationExpressionSyntax>(); exprs = exprs.Concat(tmp); foreach (var expr in exprs) { GetAnonymousExprSymbols(expr, model, list); } }
private static bool IsThreadDeclaredInBlock(BlockSyntax block, ExpressionSyntax identifier) { return (block .DescendantNodes() .OfType <VariableDeclaratorSyntax>() .Any(v => v.Identifier.ToString() == identifier.ToString())); }
private static bool IsAccessed( SemanticModel semanticModel, ISymbol outSymbol, BlockSyntax enclosingBlockOfLocalStatement, LocalDeclarationStatementSyntax localStatement, ArgumentSyntax argumentNode, CancellationToken cancellationToken ) { var localStatementStart = localStatement.Span.Start; var argumentNodeStart = argumentNode.Span.Start; var variableName = outSymbol.Name; // Walk the block that the local is declared in looking for accesses. // We can ignore anything prior to the actual local declaration point, // and we only need to check up until we reach the out-argument. foreach (var descendentNode in enclosingBlockOfLocalStatement.DescendantNodes()) { var descendentStart = descendentNode.Span.Start; if (descendentStart <= localStatementStart) { // This node is before the local declaration. Can ignore it entirely as it could // not be an access to the local. continue; } if (descendentStart >= argumentNodeStart) { // We reached the out-var. We can stop searching entirely. break; } if ( descendentNode.IsKind( SyntaxKind.IdentifierName, out IdentifierNameSyntax identifierName ) ) { // See if this looks like an accessor to the local variable syntactically. if (identifierName.Identifier.ValueText == variableName) { // Confirm that it is a access of the local. var symbol = semanticModel.GetSymbolInfo(identifierName, cancellationToken).Symbol; if (outSymbol.Equals(symbol)) { // We definitely accessed the local before the out-argument. We // can't inline this local. return(true); } } } } // No accesses detected return(false); }
private static ExpressionStatementSyntax ReinitializeTargetArrayy(BlockSyntax currentBlock, List <LiteralExpressionSyntax> initializationExpressions) { var declarator = currentBlock.DescendantNodes().OfType <VariableDeclaratorSyntax>() .FirstOrDefault(); var init = declarator.Initializer; var initializationExpression = currentBlock.DescendantNodes() .OfType <ImplicitArrayCreationExpressionSyntax>().FirstOrDefault(); initializationExpression = initializationExpression.AddInitializerExpressions(initializationExpressions.ToArray()); var variableIdentifier = SyntaxFactory.IdentifierName("target"); var assignment = SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, variableIdentifier, initializationExpression); var assignmentStatement = SyntaxFactory.ExpressionStatement(assignment); return(assignmentStatement); }
private static IEnumerable <ReturnStatementSyntax> GetReturnNullStatements(BlockSyntax methodBlock) { return(methodBlock.DescendantNodes(n => !n.IsAnyKind(SyntaxKindEx.LocalFunctionStatement, SyntaxKind.SimpleLambdaExpression, SyntaxKind.ParenthesizedLambdaExpression)) .OfType <ReturnStatementSyntax>() .Where(returnStatement => returnStatement.Expression.RemoveParentheses().IsNullLiteral())); }
public static void AnalyzeCatchClause(SyntaxNodeAnalysisContext context) { var catchClause = (CatchClauseSyntax)context.Node; BlockSyntax block = catchClause.Block; if (block == null) { return; } CatchDeclarationSyntax declaration = catchClause.Declaration; if (declaration == null) { return; } SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; ILocalSymbol symbol = semanticModel.GetDeclaredSymbol(declaration, cancellationToken); if (symbol?.IsErrorType() != false) { return; } //TODO: SyntaxWalker foreach (SyntaxNode node in block.DescendantNodes(descendIntoChildren: f => f.Kind() != SyntaxKind.CatchClause)) { if (node.Kind() != SyntaxKind.ThrowStatement) { continue; } var throwStatement = (ThrowStatementSyntax)node; ExpressionSyntax expression = throwStatement.Expression; if (expression == null) { continue; } ISymbol expressionSymbol = semanticModel.GetSymbol(expression, cancellationToken); if (!symbol.Equals(expressionSymbol)) { continue; } context.ReportDiagnostic( DiagnosticDescriptors.RemoveOriginalExceptionFromThrowStatement, expression); } }
public int RecurseBlockStatementCount(BlockSyntax block) { int statements = block.Statements.Count; foreach (var childBlock in block.DescendantNodes().OfType <BlockSyntax>().ToList()) { statements += RecurseBlockStatementCount(childBlock); } return(statements); }
public static LocalDeclarationStatementSyntax GetDelarationOfVariable(BlockSyntax bodyBlock, string variableName) { var declarator = bodyBlock.DescendantNodes() .OfType <VariableDeclaratorSyntax>() .Where(x => x.Identifier.ToString() == variableName) .Single(); var declaration = declarator.Ancestors().OfType <LocalDeclarationStatementSyntax>().First(); return(declaration); }
private static ExpressionSyntax GetVariableAssignmentExpression( BlockSyntax block, string variableName) { var field = from assignmentExpression in block.DescendantNodes().OfType <AssignmentExpressionSyntax>() where (assignmentExpression.Left as IdentifierNameSyntax) != null && ((IdentifierNameSyntax)assignmentExpression.Left).Identifier.ValueText == variableName select assignmentExpression.Right; return(field.First()); }
static bool HasReturnContract(BlockSyntax bodyStatement, string returnType) { var rhsEnsures = SyntaxFactory.ParseStatement($"Contract.Ensures(Contract.Result<{returnType}>() != null);"); var lhsEnsures = SyntaxFactory.ParseStatement($"Contract.Ensures(null != Contract.Result<{returnType}>());"); foreach (var expression in bodyStatement.DescendantNodes().OfType <ExpressionStatementSyntax>()) { var ies = expression.Expression as InvocationExpressionSyntax; if (ies == null) { continue; } var access = ies.Expression as MemberAccessExpressionSyntax; if (access == null) { continue; } if (!ValidateContractAccess(access, "Ensures", null)) { continue; } if (ies.ArgumentList.Arguments.Count != 1) { continue; } var arg = ies.ArgumentList.Arguments[0].Expression as BinaryExpressionSyntax; if (arg == null || !arg.OperatorToken.IsKind(SyntaxKind.ExclamationEqualsToken)) { continue; } if (arg.Left.IsKind(SyntaxKind.NullLiteralExpression)) { ies = arg.Right as InvocationExpressionSyntax; } else if (arg.Right.IsKind(SyntaxKind.NullLiteralExpression)) { ies = arg.Left as InvocationExpressionSyntax; } access = ies?.Expression as MemberAccessExpressionSyntax; if (!ValidateContractAccess(access, "Result", returnType)) { continue; } return(true); } return(false); }
private static HashSet <AwaitExpressionSyntax> CollectAwaitExpressions(BlockSyntax body, TextSpan span) { HashSet <AwaitExpressionSyntax> awaitExpressions = null; foreach (SyntaxNode node in body.DescendantNodes(span, f => !f.IsNestedMethod())) { if (node.IsKind(SyntaxKind.AwaitExpression)) { (awaitExpressions ?? (awaitExpressions = new HashSet <AwaitExpressionSyntax>())).Add((AwaitExpressionSyntax)node); } } return(awaitExpressions); }
private static void Analyze( SyntaxNodeAnalysisContext context, BlockSyntax body, SyntaxToken asyncKeyword, HashSet <AwaitExpressionSyntax> awaitExpressions) { if (awaitExpressions != null && !body .DescendantNodes(body.Span, f => !f.IsNestedMethod()) .Any(f => f.IsKind(SyntaxKind.AwaitExpression) && !awaitExpressions.Contains((AwaitExpressionSyntax)f))) { ReportDiagnostic(context, asyncKeyword, awaitExpressions); } }
private static bool ContainsOtherAwait(BlockSyntax body, SyntaxList <StatementSyntax> statements, StatementSyntax statement) { int index = statements.IndexOf(statement); if (index > 0) { TextSpan span = TextSpan.FromBounds(body.SpanStart, statements[index - 1].Span.End); return(body .DescendantNodes(span, f => !f.IsNestedMethod()) .Any(f => f.IsKind(SyntaxKind.AwaitExpression))); } return(false); }
static bool HasReturnContract(BlockSyntax bodyStatement, string returnType) { var workspace = new AdhocWorkspace(); foreach (var expression in bodyStatement.DescendantNodes().OfType<ExpressionStatementSyntax>()) { var formatted = Formatter.Format(expression, workspace).ToString(); if (formatted == $"Contract.Ensures(Contract.Result<{returnType}>() != null);") return true; if (formatted == $"Contract.Ensures(null != Contract.Result<{returnType}>());") return true; } return false; }
private BlockSyntax UpdateMethodBody(BlockSyntax blockSyntax, TypeSyntax returnTypeSyntax, ParameterListSyntax parameterListSyntax) { if (blockSyntax != null) { //var specialType = _typeTranslation.FirstOrDefault(tt => ExtractRoslynSymbol(tt.ActualType).ToDisplayString() == returnTypeSyntax.ToFullString().Replace("global::", "")); var specialType = _typeTranslation.FirstOrDefault(tt => PrettyTypeName(tt.ActualType) == returnTypeSyntax.ToFullString().Replace("global::", "")); if (specialType != null) { blockSyntax = SyntaxFactory.Block( blockSyntax.Statements.Select(s => s.IsKind(SyntaxKind.ReturnStatement) ? WrapReturnStatement(s as ReturnStatementSyntax, specialType) : s ).ToArray()); } var parameterIdentifierNodes = blockSyntax.DescendantNodes() .OfType<IdentifierNameSyntax>() .Where(i => parameterListSyntax.Parameters .Any(p => p.Identifier.ToFullString() == i.ToFullString())); blockSyntax = blockSyntax.ReplaceNodes(parameterIdentifierNodes, (originalNode, rewrittenNode) => WrapForwardedIdentifier(rewrittenNode, parameterListSyntax)); } return blockSyntax; }
private bool IsAccessed( SemanticModel semanticModel, ISymbol outSymbol, BlockSyntax enclosingBlockOfLocalStatement, LocalDeclarationStatementSyntax localStatement, ArgumentSyntax argumentNode, CancellationToken cancellationToken) { var localStatementStart = localStatement.Span.Start; var argumentNodeStart = argumentNode.Span.Start; var variableName = outSymbol.Name; // Walk the block that the local is declared in looking for accesses. // We can ignore anything prior to the actual local declaration point, // and we only need to check up until we reach the out-argument. foreach (var descendentNode in enclosingBlockOfLocalStatement.DescendantNodes()) { var descendentStart = descendentNode.Span.Start; if (descendentStart <= localStatementStart) { // This node is before the local declaration. Can ignore it entirely as it could // not be an access to the local. continue; } if (descendentStart >= argumentNodeStart) { // We reached the out-var. We can stop searching entirely. break; } if (descendentNode.IsKind(SyntaxKind.IdentifierName)) { // See if this looks like an accessor to the local variable syntactically. var identifierName = (IdentifierNameSyntax)descendentNode; if (identifierName.Identifier.ValueText == variableName) { // Confirm that it is a access of the local. var symbol = semanticModel.GetSymbolInfo(identifierName, cancellationToken).Symbol; if (outSymbol.Equals(symbol)) { // We definitely accessed the local before the out-argument. We // can't inline this local. return true; } } } } // No accesses detected return false; }
private static bool IsIterationVariableWritten(SemanticModel semanticModel, BlockSyntax forBlock, List<ILocalSymbol> iterableSymbols) { var forDescendants = forBlock.DescendantNodes(); var assignments = (from assignmentExpression in forDescendants.OfType<AssignmentExpressionSyntax>() let assignmentLeftSymbol = semanticModel.GetSymbolInfo(assignmentExpression.Left).Symbol where iterableSymbols.Any(i => i.Equals(assignmentLeftSymbol)) select assignmentExpression).ToList(); if (assignments.Any()) return true; var refs = (from argument in forDescendants.OfType<ArgumentSyntax>() where argument.RefOrOutKeyword != null let argumentExpressionSymbol = semanticModel.GetSymbolInfo(argument.Expression).Symbol where iterableSymbols.Any(i => i.Equals(argumentExpressionSymbol)) select argument).ToList(); if (refs.Any()) return true; var postfixUnaries = (from postfixUnaryExpression in forDescendants.OfType<PostfixUnaryExpressionSyntax>() let operandSymbol = semanticModel.GetSymbolInfo(postfixUnaryExpression.Operand).Symbol where iterableSymbols.Any(i => i.Equals(operandSymbol)) select postfixUnaryExpression).ToList(); if (postfixUnaries.Any()) return true; var prefixUnaries = (from postfixUnaryExpression in forDescendants.OfType<PrefixUnaryExpressionSyntax>() let operandSymbol = semanticModel.GetSymbolInfo(postfixUnaryExpression.Operand).Symbol where iterableSymbols.Any(i => i.Equals(operandSymbol)) select postfixUnaryExpression).ToList(); if (prefixUnaries.Any()) return true; return false; }
private static InvocationExpressionSyntax TryFindEndAPMCallSyntaxNode(BlockSyntax lambdaBlock, string methodNameBase) { // TODO: Check for correct signature, etc. // This can be done much smarter by e.g. using the BeginXxx method symbol, looking up the corresponding EndXxx symobl, and filtering on that. try { // TODO: Also considier IdentifierName EndXxx instances. var endXxxExpression = lambdaBlock.DescendantNodes() .OfType<MemberAccessExpressionSyntax>() .Where(node => NodeIsNotContainedInLambdaExpression(node, lambdaBlock)) .First(stmt => stmt.Name.ToString().Equals("End" + methodNameBase)); return (InvocationExpressionSyntax)endXxxExpression.Parent; } catch (InvalidOperationException) { return null; } }
static bool HasNotNullContract(SemanticModel semanticModel, IParameterSymbol parameterSymbol, BlockSyntax bodyStatement) { foreach (var expressions in bodyStatement.DescendantNodes().OfType<ExpressionStatementSyntax>()) { var identifiers = expressions.DescendantNodes().OfType<IdentifierNameSyntax>(); if (Enumerable.SequenceEqual(identifiers.Select(i => i.Identifier.Text), new List<string>() { "Contract", "Requires", parameterSymbol.Name })) { return true; } } return false; }
private void GetAnonymousTypeOrFuncSymbols(BlockSyntax body, SemanticModel model, List<ISymbol> list) { IEnumerable<ExpressionSyntax> exprs = body.DescendantNodes().OfType<SimpleLambdaExpressionSyntax>(); IEnumerable<ExpressionSyntax> tmp = body.DescendantNodes().OfType<ParenthesizedLambdaExpressionSyntax>(); exprs = exprs.Concat(tmp); tmp = body.DescendantNodes().OfType<AnonymousMethodExpressionSyntax>(); exprs = exprs.Concat(tmp); tmp = body.DescendantNodes().OfType<AnonymousObjectCreationExpressionSyntax>(); exprs = exprs.Concat(tmp); foreach (var expr in exprs) { GetAnonymousExprSymbols(expr, model, list); } }
private void GetLabelSymbols(BlockSyntax body, SemanticModel model, List<ISymbol> list) { var labels = body.DescendantNodes().OfType<LabeledStatementSyntax>(); foreach (var n in labels) { // Label: -> 'Label' is token var sym = model.GetDeclaredSymbol(n); list.Add(sym); } var swlabels = body.DescendantNodes().OfType<SwitchLabelSyntax>(); foreach (var n in swlabels) { // label value has NO symbol, Type is expr's type // e.g. case "A": -> string type // var info1 = model.GetTypeInfo(n.Value); // var info2 = model.GetSymbolInfo(n.Value); var sym = model.GetDeclaredSymbol(n); list.Add(sym); } }