public SuspiciousAttributeVisitor(IEnumerable <Type> adaptationTypes) : base(true)
 {
     SuspiciousAttributeSyntaxes = new SuspiciousAttributeSyntaxes();
     _associationMap             = adaptationTypes.CreateAssociationMap();
     IsChanged = new ManualResetEvent(false);
 }
예제 #2
0
        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);
        }