Beispiel #1
0
 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);
     }
 }
Beispiel #2
0
        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;
        }
Beispiel #3
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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);
                    }
                }
            }
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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);
                }
            }
        }
Beispiel #9
0
        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);
                }
            }
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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;
    }
Beispiel #15
0
        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);
            }
        }