IEnumerable <ISymbol> HandleCustomAttribute(ITypeDefinition attributeType, AnalyzerScope scope, CancellationToken ct) { var genericContext = new Decompiler.TypeSystem.GenericContext(); // type arguments do not matter for this analyzer. foreach (var module in scope.GetModulesInScope(ct)) { var ts = scope.ConstructTypeSystem(module); ct.ThrowIfCancellationRequested(); var decoder = new FindTypeDecoder(ts.MainModule, attributeType); var referencedParameters = new HashSet <ParameterHandle>(); foreach (var h in module.Metadata.CustomAttributes) { var customAttribute = module.Metadata.GetCustomAttribute(h); if (IsCustomAttributeOfType(customAttribute.Constructor, module.Metadata, decoder)) { if (customAttribute.Parent.Kind == HandleKind.Parameter) { referencedParameters.Add((ParameterHandle)customAttribute.Parent); } else { var parent = AnalyzerHelpers.GetParentEntity(ts, customAttribute); if (parent != null) { yield return(parent); } } } } if (referencedParameters.Count > 0) { foreach (var h in module.Metadata.MethodDefinitions) { var md = module.Metadata.GetMethodDefinition(h); foreach (var p in md.GetParameters()) { if (referencedParameters.Contains(p)) { var method = ts.MainModule.ResolveMethod(h, genericContext); if (method != null) { if (method.IsAccessor) { yield return(method.AccessorOwner); } else { yield return(method); } } break; } } } } } }
private static bool IsLazyInstantiated(InvocationExpressionSyntax invocation) { var creationExpression = AnalyzerHelpers.TryFindParentOfType <ObjectCreationExpressionSyntax>(invocation); if (creationExpression != null) { var typeName = creationExpression.Type.ToString(); if (typeName.ToLower().Contains("lazy")) { return(true); } } return(false); }
private static void ConstructorCallsCheck(SyntaxNodeAnalysisContext context) { var node = context.Node as ConstructorDeclarationSyntax; if (node != null) { var usingStatements = AnalyzerHelpers.FindChildrenOfType <UsingStatementSyntax>(node.Body); DetectScopeCalls(context, usingStatements); foreach (var invocation in AnalyzerHelpers.FindChildrenOfType <InvocationExpressionSyntax>(node)) { if (IsLazyInstantiated(invocation)) { continue; } var memberAccess = AnalyzerHelpers.FindChildrenOfType <MemberAccessExpressionSyntax>(invocation).FirstOrDefault(); if (memberAccess != null) { var symbol = context.SemanticModel.GetSymbolInfo(memberAccess); if (symbol.Symbol != null && symbol.Symbol.Locations.Length > 0) { var location = symbol.Symbol.Locations[0]; if (location.SourceTree != null) { var root = location.SourceTree.GetRoot(); foreach (var method in AnalyzerHelpers.FindChildrenOfType <MethodDeclarationSyntax>(root)) { if (method.Identifier.ValueText == symbol.Symbol.Name) { usingStatements = AnalyzerHelpers.FindChildrenOfType <UsingStatementSyntax>(method); DetectScopeCalls(context, usingStatements, memberAccess); break; } } } } } } } }
private static void DetectScopeCalls(SyntaxNodeAnalysisContext context, IEnumerable <UsingStatementSyntax> nodes, SyntaxNode parent = null) { foreach (var node in nodes) { if (node.Declaration != null && node.Declaration.ToString().Contains("DalScope.Begin")) { var scopeVariableName = node.Declaration.Variables[0].Identifier.ValueText; foreach (var invocation in AnalyzerHelpers.FindChildrenOfType <InvocationExpressionSyntax>(node)) { var str = invocation.ToString(); if (str.Contains(scopeVariableName) && (str.Contains(".Fetch") || str.Contains(".TryFetch") || str.Contains(".Exists"))) { var location = parent != null?parent.GetLocation() : node.GetLocation(); var diagnostic = Diagnostic.Create(Rule, location); context.ReportDiagnostic(diagnostic); } } } } }
private static void CommitCheck(SyntaxNodeAnalysisContext context) { var node = context.Node as UsingStatementSyntax; if (node != null) { if (node.Declaration != null && node.Declaration.ToString().Contains("DalScope.Begin")) { var scopeVariableName = node.Declaration.Variables[0].Identifier.ValueText; var block = node.Statement as BlockSyntax; if (block != null) { bool isUpdateBlock = false; bool hasScopeCommit = false; foreach (var invocation in AnalyzerHelpers.FindChildrenOfType <InvocationExpressionSyntax>(block)) { var str = invocation.ToString(); if (str.Contains(".Update(") || str.Contains(".Insert(") || str.Contains(".Delete(")) { isUpdateBlock = true; } if (str.Contains(scopeVariableName) && str.Contains(".Commit(")) { hasScopeCommit = true; } } if (isUpdateBlock && !hasScopeCommit) { var diagnostic = Diagnostic.Create(Rule, node.GetLocation()); context.ReportDiagnostic(diagnostic); } } } } }
static IEnumerable <ISymbol> FindUsesInAttributes(DecompilerTypeSystem typeSystem, MetadataReader metadata, FindTypeDecoder decoder, ITypeDefinition analyzedType) { var attrDecoder = new FindTypeInAttributeDecoder(typeSystem.MainModule, analyzedType); var referencedParameters = new HashSet <ParameterHandle>(); foreach (var h in metadata.CustomAttributes) { var customAttribute = metadata.GetCustomAttribute(h); CustomAttributeValue <TokenSearchResult> value; try { value = customAttribute.DecodeValue(attrDecoder); } catch (EnumUnderlyingTypeResolveException) { continue; } if (AttributeAppliedToAnalyzer.IsCustomAttributeOfType(customAttribute.Constructor, metadata, decoder) || AnalyzeCustomAttributeValue(value)) { if (customAttribute.Parent.Kind == HandleKind.Parameter) { referencedParameters.Add((ParameterHandle)customAttribute.Parent); } else { var parent = AnalyzerHelpers.GetParentEntity(typeSystem, customAttribute); if (parent != null) { yield return(parent); } } } } if (referencedParameters.Count > 0) { foreach (var h in metadata.MethodDefinitions) { var md = metadata.GetMethodDefinition(h); foreach (var p in md.GetParameters()) { if (referencedParameters.Contains(p)) { var method = typeSystem.MainModule.ResolveMethod(h, default); if (method != null) { if (method.IsAccessor) { yield return(method.AccessorOwner); } else { yield return(method); } } break; } } } } }