private void AnalyzeCompilation(CompilationAnalysisContext context) { Trace.WriteLine("AnalyzeCompilation"); try { INamedTypeSymbol dbContextTypeSymbol; IEnumerable<INamedTypeSymbol> entityTypeSymbols = SymbolHelper.GetAllEntityTypesFromDbContext(context.Compilation, out dbContextTypeSymbol); if (!entityTypeSymbols.Any()) { return; } var allTypeSymbols = context.Compilation.GetSymbolsWithName(s => !s.EndsWith("DbContext"), SymbolFilter.Type).Cast<INamedTypeSymbol>(); var allMemberSymbols = allTypeSymbols.SelectMany(t => t.GetMembers().Where(m => m.Kind == SymbolKind.Property)); Trace.WriteLine("Class count: " + allTypeSymbols.Count()); Trace.WriteLine("Property count: " + allMemberSymbols.Count()); var efRoslynTheorem = new EFRoslynTheorem(); var result = efRoslynTheorem.Solve(entityTypeSymbols); if (result.Status == Status.Unsatisfiable) { var classAssumptions = efRoslynTheorem.ClassAssumptions.ToList(); var propertyAssumptions = efRoslynTheorem.PropertyAssumptions.OrderBy(pa => pa.Rank).ToList(); do { result = TryToRemoveWrongAssumption(efRoslynTheorem, result, classAssumptions, propertyAssumptions); } while (result != null && result.Status != Status.Satisfiable); if (result == null || result.Status != Status.Satisfiable) { var diagnostic2 = Diagnostic.Create(UnsatisfiableRule, dbContextTypeSymbol.Locations[0], dbContextTypeSymbol.Name); Trace.WriteLine("ReportDiagnostic " + diagnostic2.Descriptor.Id); context.ReportDiagnostic(diagnostic2); return; } var cacheId = EFRoslynTheoremCache.Add(context.Compilation, efRoslynTheorem, result); var props = ImmutableDictionary.Create<string, string>(); props = props.Add("CacheId", cacheId); var diagnostic = Diagnostic.Create(SatisfiableRule, dbContextTypeSymbol.Locations[0], props, dbContextTypeSymbol.Name); Trace.WriteLine("ReportDiagnostic " + diagnostic.Descriptor.Id); context.ReportDiagnostic(diagnostic); } } catch (Exception ex) { Trace.WriteLine(ex.ToString()); throw; } }
public Item(Compilation compilation, EFRoslynTheorem efRoslynTheorem, ObjectTheoremResult objectTheoremResult) { Compilation = compilation; EFRoslynTheorem = efRoslynTheorem; ObjectTheoremResult = objectTheoremResult; }
public static string Add(Compilation compilation, EFRoslynTheorem efRoslynTheorem, ObjectTheoremResult objectTheoremResult) { var cacheId = compilation.AssemblyName; _cache[cacheId] = new Item(compilation, efRoslynTheorem, objectTheoremResult); return cacheId; }
private ObjectTheoremResult TryToRemoveWrongAssumption(EFRoslynTheorem efRoslynTheorem, ObjectTheoremResult result, List<IClassAssumption> classAssumptions, List<IPropertyAssumption> propertyAssumptions) { foreach (var assumes in classAssumptions) { if (result.IsAssumptionWrong(assumes.Assumption)) { classAssumptions.Remove(assumes); efRoslynTheorem.RemoveAssumption(assumes.Assumption); return efRoslynTheorem.ReSolve(); } } foreach (var assumes in propertyAssumptions) { if (result.IsAssumptionWrong(assumes.Assumption)) { propertyAssumptions.Remove(assumes); efRoslynTheorem.RemoveAssumption(assumes.Assumption); return efRoslynTheorem.ReSolve(); } } return null; }