public void MarkAllMethodsAsNotValid(Match match, AssemblyReport instrumentationReport) { // Did not match so marking all methods as false - can be changed by later validation attempts foreach (var exactMethodMatcher in match.ExactMethodMatchers) { instrumentationReport.AddMethodValidation(match, exactMethodMatcher, false); } }
internal TreeShakingRewriter(IMetadataHost host, AssemblyReport analysisReport, bool dryRun, bool removeMethods, bool debugStubs, StubMethodBodyEmitter stubEmitter) : base(host) { this.analysisReport = analysisReport; this.removeMethodsWhenPossible = removeMethods; this.fullDebugStubs = debugStubs; this.dryRun = dryRun; this.stubMethodBodyEmitter = stubEmitter; }
private static void OutputPerAssemblyReports(RapidTypeAnalysis rta, string reportingDirectory) { foreach (IAssembly assembly in rta.WholeProgram().AllAssemblies()) { AssemblyReport report = AssemblyReport.CreateAssemblyReportFromRTA(assembly, rta); string assemblyName = assembly.Name.Value; int reachableMethodsCount = report.ReachableMethods.Count; report.WriteReportToDirectory(reportingDirectory); } }
public void ValidateClass(AssemblyModel assemblyModel, Match match, AssemblyReport instrumentationReport) { // check if class exists in ClassModels and get ClassModel back if (assemblyModel.ClassModels.TryGetValue(match.ClassName, out var classModel)) { CheckExactMethodMatchers(instrumentationReport, match, classModel); return; } // class did not match so marking all methods as false - can be changed by later validation attempts //MarkAllMethodsAsNotValid(match, instrumentationReport); }
public bool ValidateAssembly(AssemblyModel assemblyModel, Match match, AssemblyReport instrumentationReport) { // okay to move on to checking classes if (match.AssemblyName == assemblyModel.AssemblyName) { return(true); } // assembly did not match so marking all methods as false - can be changed by later validation attempts // TODO: don't want invalid on methods that aren't in the instrumented assembly, right? //MarkAllMethodsAsNotValid(match, instrumentationReport); return(false); }
private static void RewriteBinary( Assembly copy, AssemblyReport assemblyReport, MetadataReaderHost host, string outputPath, MethodRemoval methodRemoval, StubMethodBodyEmitter stubEmitter) { /* This is an attempt to decouple the MethodRemoval commandline options * from the tree shaker, but it doesn't really seem to be working. * Might be better to just pass the method removal directly to * the rewriter. */ bool removeMethods = (methodRemoval == MethodRemoval.Remove); bool fullDebugStubs = (methodRemoval == MethodRemoval.Debug); bool dryRun = (methodRemoval == MethodRemoval.None); PdbReader /*?*/ pdbReader = null; string pdbFile = Path.ChangeExtension(copy.Location, "pdb"); if (File.Exists(pdbFile)) { using (var pdbStream = File.OpenRead(pdbFile)) { pdbReader = new PdbReader(pdbStream, host); } } else { Console.WriteLine("Could not load the PDB file for '" + copy.Name.Value + "' . Proceeding anyway."); } using (pdbReader) { var localScopeProvider = pdbReader == null ? null : new ILGenerator.LocalScopeProvider(pdbReader); var pdbPath = Path.ChangeExtension(outputPath, ".pdb"); var outputFileName = Path.GetFileNameWithoutExtension(outputPath); using (var peStream = File.Create(outputPath)) { using (var pdbWriter = new PdbWriter(pdbPath, pdbReader)) { var rewriter = new TreeShakingRewriter(host, assemblyReport, dryRun, removeMethods, fullDebugStubs, stubEmitter); IAssembly rewrittenCopy = rewriter.Rewrite(copy); PeWriter.WritePeToStream(rewrittenCopy, host, peStream, pdbReader, localScopeProvider, pdbWriter); } } } }
public IEnumerable <AssemblyReport> LogBreakingChangeReport(CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); var generator = new BreakingChangeReportGenerator(); IEnumerable <Assembly> functionContextAssemblies = AppDomain.CurrentDomain.GetAssemblies() .Where(a => AssemblyLoadContext.GetLoadContext(a) == FunctionAssemblyLoadContext.Shared); var reports = new List <AssemblyReport>(); foreach (var assembly in functionContextAssemblies) { cancellationToken.ThrowIfCancellationRequested(); AssemblyReport report = generator.ProduceReport(new Uri(assembly.CodeBase).LocalPath); _logger.LogDebug(JsonConvert.SerializeObject(report)); reports.Add(report); } return(reports); }
private static void TransformProgram(WholeProgram wholeProgram, string transformedBinariesPath, string reportsPath, MethodRemoval methodRemoval, TargetProfile profile) { System.IO.Directory.CreateDirectory(transformedBinariesPath); StubMethodBodyEmitter stubEmitter = GetStubMethodBodyEmitterForProfile(profile, wholeProgram); foreach (IAssembly assembly in wholeProgram.AllAssemblies()) { if (AssemblyShouldBeRewritten(assembly)) { if (assembly.PublicKeyToken.Count() > 0) { Console.WriteLine("Warning: rewriting assembly with a public key token. {0}", assembly); } string outputBinary = transformedBinariesPath + @"\" + Path.GetFileName(assembly.Location); var copy = new MetadataDeepCopier(wholeProgram.Host()).Copy(assembly); DocumentationCommentDefinitionIdStringMap idMap = new DocumentationCommentDefinitionIdStringMap(new IAssembly[] { copy }); AssemblyReport assemblyReport = AssemblyReport.CreateAssemblyReportFromPath(copy, reportsPath, idMap); stopwatch.Start(); RewriteBinary(copy, assemblyReport, wholeProgram.Host(), outputBinary, methodRemoval, stubEmitter); stopwatch.Start(); } else { //Console.WriteLine("Skipping rewrite of of assembly {0}", assembly.Name.Value); } } }
public void CheckExactMethodMatchers(AssemblyReport instrumentationReport, Match match, ClassModel classModel) { foreach (var exactMethodMatcher in match.ExactMethodMatchers) { // check if method exists in MethodModels and get MethodModel back if (classModel.MethodModels.TryGetValue(exactMethodMatcher.MethodName, out var methodModel)) { // Check if exactMethodMatcher.Parameters is empty or popluated if (string.IsNullOrWhiteSpace(exactMethodMatcher.Parameters)) { // exactMethodMatcher has NO params, checking of MethodModel has an empty ParameterSets value //if (methodModel.ParameterSets.Contains(string.Empty)) //{ // instrumentationReport.AddMethodValidation(match, exactMethodMatcher, true); // continue; //} instrumentationReport.AddMethodValidation(match, exactMethodMatcher, true); continue; } // exactMethodMatcher HAS params to check if (methodModel.ParameterSets.Contains(exactMethodMatcher.Parameters)) { instrumentationReport.AddMethodValidation(match, exactMethodMatcher, true); continue; } // param was not found instrumentationReport.AddMethodValidation(match, exactMethodMatcher, false); continue; } else { // Did not find method in classmodel, amrking method as false instrumentationReport.AddMethodValidation(match, exactMethodMatcher, false); } } }
public InstrumentationReport CheckInstrumentation(InstrumentationModel instrumentationModel, string instrumentationSetName, string targetFramework, string packageVersion, string packageName) { var instrumentationReport = new InstrumentationReport() { InstrumentationSetName = instrumentationSetName, TargetFramework = targetFramework, PackageVersion = packageVersion, PackageName = packageName }; // Check each AssemblyModel against all instrumentation var assemblyReport = new AssemblyReport(); assemblyReport.AssemblyName = _assemblyAnalysis.AssemblyModel.AssemblyName; CheckMatch(_assemblyAnalysis.AssemblyModel, instrumentationModel, assemblyReport); instrumentationReport.AssemblyReports.Add(assemblyReport); return(instrumentationReport); }
private static AssemblyReport CreateAssemblyReport(IGrouping <string, Info> groupByAssembly) { var reports = new List <TestReport>(); foreach (var info in groupByAssembly) { var report = new TestReport { ClassName = info.ClassName, Name = info.MethodName }; if (info is TestResultInfo) { var result = info as TestResultInfo; report.Status = result.IsPassed ? TestStatus.Passed : TestStatus.Failed; report.Time = result.Time; report.Message = result.FailedMessage; } else { var result = info as IgnoredTestInfo; report.Status = TestStatus.Ignored; report.Message = result.Message; } reports.Add(report); } var assemblyReport = new AssemblyReport { Name = groupByAssembly.Key, TestReports = reports, NumberOfPassed = reports.Where(r => r.Status == TestStatus.Passed).Count(), NumberOfFailed = reports.Where(r => r.Status == TestStatus.Failed).Count(), NumberOfIgnored = reports.Where(r => r.Status == TestStatus.Ignored).Count(), }; return(assemblyReport); }
public InstrumentationReport CheckInstrumentation(InstrumentationModel instrumentationModel, string instrumentationSetName) { var instrumentationReport = new InstrumentationReport() { InstrumentationSetName = instrumentationSetName }; // Check each AssemblyModel against all instrumentation // InstrumentationReport will show aggregated results from all assemblies foreach (var assemblyModel in _assemblyAnalysis.AssemblyModels.Values) { var assemblyReport = new AssemblyReport(); assemblyReport.AssemblyName = assemblyModel.AssemblyName; assemblyReport.AssemblyVersion = assemblyModel.AssemblyVersion; CheckMatch(assemblyModel, instrumentationModel, assemblyReport); instrumentationReport.AssemblyReports.Add(assemblyReport); } return(instrumentationReport); }
private static void RewriteBinary( Assembly copy, AssemblyReport assemblyReport, MetadataReaderHost host, string outputPath, MethodRemoval methodRemoval, StubMethodBodyEmitter stubEmitter) { /* This is an attempt to decouple the MethodRemoval commandline options * from the tree shaker, but it doesn't really seem to be working. * Might be better to just pass the method removal directly to * the rewriter. */ bool removeMethods = (methodRemoval == MethodRemoval.Remove); bool fullDebugStubs = (methodRemoval == MethodRemoval.Debug); bool dryRun = (methodRemoval == MethodRemoval.None); PdbReader/*?*/ pdbReader = null; string pdbFile = Path.ChangeExtension(copy.Location, "pdb"); if (File.Exists(pdbFile)) { using (var pdbStream = File.OpenRead(pdbFile)) { pdbReader = new PdbReader(pdbStream, host); } } else { Console.WriteLine("Could not load the PDB file for '" + copy.Name.Value + "' . Proceeding anyway."); } using (pdbReader) { var localScopeProvider = pdbReader == null ? null : new ILGenerator.LocalScopeProvider(pdbReader); var outputFileName = Path.GetFileNameWithoutExtension(outputPath); using (var peStream = File.Create(outputPath)) { using (var pdbWriter = new PdbWriter(outputFileName + ".pdb", pdbReader)) { var rewriter = new TreeShakingRewriter(host, assemblyReport, dryRun, removeMethods, fullDebugStubs, stubEmitter); IAssembly rewrittenCopy = rewriter.Rewrite(copy); PeWriter.WritePeToStream(rewrittenCopy, host, peStream, pdbReader, localScopeProvider, pdbWriter); } } } }
internal TreeShakingRewriter(IMetadataHost host, AssemblyReport analysisReport, bool dryRun, bool removeMethods, bool debugStubs, StubMethodBodyEmitter stubEmitter) : base(host) { this.analysisReport = analysisReport; this.removeMethodsWhenPossible = removeMethods; this.fullDebugStubs = debugStubs; this.dryRun = dryRun; this.stubMethodBodyEmitter = stubEmitter; }
public void CheckMatch(AssemblyModel assemblyModel, InstrumentationModel instrumentationModel, AssemblyReport instrumentationReport) { foreach (var match in instrumentationModel.Matches) { if (!ValidateAssembly(assemblyModel, match, instrumentationReport)) { continue; } // assembly match checking classes and methods ValidateClass(assemblyModel, match, instrumentationReport); } }