public SuspiciousAttributeVisitor(IEnumerable <Type> adaptationTypes) : base(true) { SuspiciousAttributeSyntaxes = new SuspiciousAttributeSyntaxes(); _associationMap = adaptationTypes.CreateAssociationMap(); IsChanged = new ManualResetEvent(false); }
private List <AdaptationUsage> AnalyzeSemanticForAdaptationUsages(SuspiciousAttributeSyntaxes suspiciousAttributeSyntaxes, CSharpCompilation compilation, ILogger logger) { logger.Debug("------------"); logger.Info("Analyzing semantic"); var suspiciousSyntaxTrees = suspiciousAttributeSyntaxes.ToLookup(pair => pair.Syntax.SyntaxTree, pair => pair); var usages = new List <AdaptationUsage>(); foreach (var group in suspiciousSyntaxTrees) { var semanticModel = compilation.GetSemanticModel(group.Key, true); foreach (var syntax in group) { try { var attributeInfo = semanticModel.GetSymbolInfo(syntax.Syntax); var symbol = attributeInfo.Symbol ?? attributeInfo.CandidateSymbols.FirstOrDefault(); if (symbol == null) { continue; } var resolvedType = syntax.PossibleTypes.FirstOrDefault(t => symbol.ResolveType() == t); var attributeData = syntax.Syntax.ResolveAttributeData(semanticModel); if (resolvedType == null) { throw new InvalidDataException($"Could not resolve '{syntax.Syntax}' type"); } if (attributeData?.Item2 == null) { throw new InvalidDataException("Could not resolve attribute semantic"); } if (attributeData.Item1 == AttributeTargets.All) { throw new InvalidOperationException("Unexpected AttributeTargets in resolved attribute data"); } usages.Add(new AdaptationUsage(semanticModel, group.Key, syntax.Syntax.Parent.Parent, attributeData.Item2, attributeData.Item1, resolvedType, syntax.Escaped)); } catch (NotSupportedException e) { logger.Debug($"Not supported feature. Details: {e.GetBaseException().Message}"); } catch (Exception e) { logger.Warn($"Unexpected internal error. Details: {e.GetBaseException().Message}"); } } } logger.Info($"Found {usages.Count} adaptation attribute usages"); foreach (var usage in usages) { logger.Debug($"+ Usage: {usage}"); } return(usages); }