示例#1
0
        public static Bpl.Program /*?*/ TranslateAssembly(List <string> assemblyNames, HeapFactory heapFactory, Options options, List <Regex> exemptionList, bool whiteList)
        {
            Contract.Requires(assemblyNames != null);
            Contract.Requires(heapFactory != null);

            var       libPaths       = options.libpaths;
            var       wholeProgram   = options.wholeProgram;
            var /*?*/ stubAssemblies = options.stub;

            var host = new CodeContractAwareHostEnvironment(libPaths != null ? libPaths : Enumerable <string> .Empty, true, true);

            Host = host;

            Bpl.CommandLineOptions.Install(new Bpl.CommandLineOptions());

            #region Assemlies to translate (via cmd line)
            modules = new List <IModule>();
            var contractExtractors = new Dictionary <IUnit, IContractProvider>();
            var pdbReaders         = new Dictionary <IUnit, PdbReader>();
            #region Load *all* of the assemblies before doing anything else so that they can all vote on unification matters
            foreach (var a in assemblyNames)
            {
                var module = host.LoadUnitFrom(a) as IModule;
                if (module == null || module == Dummy.Module || module == Dummy.Assembly)
                {
                    Console.WriteLine(a + " is not a PE file containing a CLR module or assembly, or an error occurred when loading it.");
                    Console.WriteLine("Skipping it, continuing with other input assemblies");
                    continue;
                }
                modules.Add(module);
            }
            #endregion
            #region Decompile all of the assemblies
            var decompiledModules = new List <IModule>();
            foreach (var m in modules)
            {
                PdbReader /*?*/ pdbReader = null;
                string          pdbFile   = Path.ChangeExtension(m.Location, "pdb");
                if (File.Exists(pdbFile))
                {
                    Stream pdbStream = File.OpenRead(pdbFile);
                    pdbReader = new PdbReader(pdbStream, host);
                }
                var m2 = Decompiler.GetCodeModelFromMetadataModel(host, m, pdbReader, DecompilerOptions.Unstack) as IModule;
                // The decompiler does not turn calls to Assert/Assume into Code Model nodes
                m2 = new Microsoft.Cci.MutableContracts.ContractExtractor.AssertAssumeExtractor(host, pdbReader).Rewrite(m2);
                decompiledModules.Add(m2);
                host.RegisterAsLatest(m2);
                contractExtractors.Add(m2, host.GetContractExtractor(m2.UnitIdentity));
                pdbReaders.Add(m2, pdbReader);
            }
            modules = decompiledModules;
            #endregion
            #endregion

            #region Assemblies to translate (stubs)
            if (stubAssemblies != null)
            {
                foreach (var s in stubAssemblies)
                {
                    var module = host.LoadUnitFrom(s) as IModule;
                    if (module == null || module == Dummy.Module || module == Dummy.Assembly)
                    {
                        Console.WriteLine(s + " is not a PE file containing a CLR module or assembly, or an error occurred when loading it.");
                        Console.WriteLine("Skipping it, continuing with other input assemblies");
                    }
                    PdbReader /*?*/ pdbReader = null;
                    string          pdbFile   = Path.ChangeExtension(module.Location, "pdb");
                    if (File.Exists(pdbFile))
                    {
                        Stream pdbStream = File.OpenRead(pdbFile);
                        pdbReader = new PdbReader(pdbStream, host);
                    }
                    module = Decompiler.GetCodeModelFromMetadataModel(host, module, pdbReader, DecompilerOptions.Unstack) as IModule;

                    var copier        = new CodeDeepCopier(host);
                    var mutableModule = copier.Copy(module);

                    var mscorlib = TypeHelper.GetDefiningUnit(host.PlatformType.SystemObject.ResolvedType);

                    //var mutator = new ReparentModule(host, mscorlib, mutableModule);
                    //module = mutator.Rewrite(mutableModule);
                    //modules.Add(Tuple.Create(module, pdbReader));

                    RewriteUnitReferences renamer = new RewriteUnitReferences(host, mutableModule);
                    var mscorlibAssembly          = (IAssembly)mscorlib;
                    renamer.targetAssembly           = mscorlibAssembly;
                    renamer.originalAssemblyIdentity = mscorlibAssembly.AssemblyIdentity;
                    renamer.RewriteChildren(mutableModule);
                    modules.Add((IModule)mutableModule);
                    contractExtractors.Add(module, host.GetContractExtractor(module.UnitIdentity));
                    pdbReaders.Add(module, pdbReader);
                }
            }
            #endregion

            if (modules.Count == 0)
            {
                throw new TranslationException("No input assemblies to translate.");
            }

            //var primaryModule = modules[0];
            Sink sink = new Sink(host, heapFactory, options, exemptionList, whiteList);
            TranslationHelper.tmpVarCounter = 0;

            // TODO move away, get all plugin and translators from a config file or alike
            #region Plugged translators
            List <Translator>  translatorsPlugged = new List <Translator>();
            ITranslationPlugin bctPlugin          = new BytecodeTranslatorPlugin(wholeProgram);
            Translator         bcTranslator       = bctPlugin.getTranslator(sink, contractExtractors, pdbReaders);
            translatorsPlugged.Add(bcTranslator);

            #endregion
            sink.TranslationPlugins = translatorsPlugged;

            // TODO replace the whole translation by a translator initialization and an orchestrator calling back for each element
            // TODO for the current BC translator it will possibly just implement onMetadataElement(IModule)
            // TODO refactor this away, handle priorities between plugged translators
            IOrderedEnumerable <Translator> prioritizedTranslators = translatorsPlugged.OrderBy(t => t.getPriority());
            foreach (Translator t in prioritizedTranslators)
            {
                t.initialize();
                if (t.isOneShot())
                {
                    t.TranslateAssemblies(modules);
                }
            }

            foreach (var pair in sink.delegateTypeToDelegates.Values)
            {
                CreateDispatchMethod(sink, pair.Item1, pair.Item2);
                CreateDelegateCreateMethod(sink, pair.Item1, pair.Item2);
                CreateDelegateAddMethod(sink, pair.Item1, pair.Item2);
                CreateDelegateRemoveMethod(sink, pair.Item1, pair.Item2);
            }

            // Subtyping for extern types
            if (sink.Options.typeInfo > 0)
            {
                sink.DeclareExternTypeSubtyping();
            }

            //sink.CreateIdentifierCorrespondenceTable(primaryModule.Name.Value);

            //var rc = new Bpl.ResolutionContext((Bpl.IErrorSink)null);
            //foreach (var decl in sink.TranslatedProgram.TopLevelDeclarations) {
            //  decl.Register(rc);
            //}
            //sink.TranslatedProgram.Resolve(rc);
            //var goodDecls = new List<Bpl.Declaration>();
            //var tc = new Bpl.TypecheckingContext(null);
            //foreach (var decl in sink.TranslatedProgram.TopLevelDeclarations) {
            //  var impl = decl as Bpl.Implementation;
            //  if (impl == null) {
            //    goodDecls.Add(decl);
            //    continue;
            //  }
            //  try {
            //    //var tc = new Bpl.TypecheckingContext(null);
            //    impl.Typecheck(tc);
            //    goodDecls.Add(impl);
            //  } catch {
            //    Console.WriteLine("Deleting implementation for: " + impl.Name);
            //    // nothing to do, just continue
            //  }
            //}
            //sink.TranslatedProgram.TopLevelDeclarations = goodDecls;
            return(sink.TranslatedProgram);
        }
示例#2
0
        static int RealMain(string[] args)
        {
            int errorReturnValue = -1;

            #region Check options

            ILMerge.options = new ILMergeOptions();
            options.Parse(args);

            if (options.HelpRequested)
            {
                options.PrintOptions("");
                return(errorReturnValue);
            }
            if (options.HasErrors)
            {
                options.PrintErrorsAndExit(Console.Out);
            }

            if (options.breakIntoDebugger)
            {
                System.Diagnostics.Debugger.Break();
            }
            #endregion

            Version version = null;
            if (options.version != null)
            {
                TryGetVersionNumber(options.version, out version);
            }

            using (var host = new ILMergeHost(options.libpaths)) {
                if (options.libpaths != null)
                {
                    foreach (var libpath in options.libpaths)
                    {
                        host.AddLibPath(libpath);
                    }
                }

                Assembly /*?*/ primaryAssembly = null;
                var            modules         = new List <Module>();
                var            unit2SourceLocationProviderMap = new Dictionary <IUnit, ISourceLocationProvider>();
                var            unit2LocalScopeProviderMap     = new Dictionary <IUnit, ILocalScopeProvider>();
                try {
                    for (int i = 0; i < options.GeneralArguments.Count; i++)
                    {
                        var unitName = options.GeneralArguments[i];
                        var u        = host.LoadUnitFrom(unitName) as IModule;
                        if (i == 0)
                        {
                            IAssembly /*?*/ assembly = u as IAssembly;
                            if (assembly == null || assembly is Dummy)
                            {
                                Console.WriteLine(unitName + " is not a PE file containing a CLR assembly, or an error occurred when loading it.");
                                return(errorReturnValue);
                            }
                            // Use (the copy of) the first input assembly as the merged assembly!
                            primaryAssembly = new MetadataDeepCopier(host).Copy(assembly);
                        }
                        else
                        {
                            var copier        = new MetadataDeepCopier(host, primaryAssembly);
                            var mutableModule = copier.Copy(u);
                            modules.Add(mutableModule);
                        }
                        PdbReader /*?*/ pdbReader = null;
                        string          pdbFile   = Path.ChangeExtension(u.Location, "pdb");
                        if (File.Exists(pdbFile))
                        {
                            using (var pdbStream = File.OpenRead(pdbFile)) {
                                pdbReader = new PdbReader(pdbStream, host);
                            }
                            unit2SourceLocationProviderMap.Add(u, pdbReader);
                            unit2LocalScopeProviderMap.Add(u, pdbReader);
                        }
                        else
                        {
                            Console.WriteLine("Could not load the PDB file for the unit '" + u.Name.Value + "' . Proceeding anyway.");
                            unit2SourceLocationProviderMap.Add(u, null);
                        }
                    }

                    //PdbWriter/*?*/ pdbWriter = null;

                    RewriteUnitReferences renamer = new RewriteUnitReferences(host, modules, options);
                    renamer.targetAssembly           = primaryAssembly;
                    renamer.originalAssemblyIdentity = primaryAssembly.AssemblyIdentity;

                    int totalNumberOfTypes = primaryAssembly.AllTypes.Count;

                    #region Pass 1: Mutate each input module (including the primary assembly) so everything is re-parented to the merged assembly
                    renamer.RewriteChildren(primaryAssembly);
                    for (int i = 0, n = modules.Count; i < n; i++)
                    {
                        var mutableModule = modules[i];
                        // call Rewrite and not RewriteChildren so dynamic dispatch can call the right rewriter method
                        // otherwise, it just rewrites it as a module, not whatever subtype it is.
                        renamer.Rewrite(mutableModule);
                        // However, the rewriter does *not* rewrite parents. So need to re-parent the root unit namespace
                        // of the mutable assembly so it points to the merged assembly. Otherwise, interning (among other
                        // things) will not work correctly.
                        var rootUnitNs = (RootUnitNamespace)mutableModule.UnitNamespaceRoot;
                        rootUnitNs.Unit     = primaryAssembly;
                        totalNumberOfTypes += mutableModule.AllTypes.Count;
                    }
                    #endregion

                    #region Pass 2: Collect all of the types into the merged assembly

                    var mergedTypes = new List <INamedTypeDefinition>(totalNumberOfTypes);

                    #region Merge together all of the <Module> classes from the input assemblies
                    // TODO: Merge all of the <Module> classes, i.e., type 0 from each of the input assemblies
                    mergedTypes.Add(primaryAssembly.AllTypes[0]);
                    #endregion

                    var internedKeys = new HashSet <string>(); // keep track of all namespace type definitions

                    #region Types from the primary assembly
                    for (int i = 1, n = primaryAssembly.AllTypes.Count; i < n; i++)
                    {
                        var t = primaryAssembly.AllTypes[i];
                        mergedTypes.Add(t);
                        if (t is INamespaceTypeDefinition) // don't care about nested types
                        {
                            var key = TypeHelper.GetTypeName(t, NameFormattingOptions.None);
                            internedKeys.Add(key);
                        }
                    }
                    #endregion

                    #region Types from the other input assemblies, taking care of duplicates

                    for (int i = 0, n = modules.Count; i < n; i++)
                    {
                        var module   = modules[i];
                        var unitName = module.Name.Value;
                        for (int j = 1, m = module.AllTypes.Count; j < m; j++)
                        {
                            var t = module.AllTypes[j];
                            var namespaceTypeDefinition = t as NamespaceTypeDefinition;
                            // duplicates can be only at the top-level: namespace type definitions
                            // if a namespace type definition is unique, then so are all of its nested types
                            if (namespaceTypeDefinition != null)
                            {
                                var typeName = TypeHelper.GetTypeName(namespaceTypeDefinition, NameFormattingOptions.UseGenericTypeNameSuffix);
                                if (internedKeys.Contains(typeName)) // error: duplicate!
                                {
                                    if (!namespaceTypeDefinition.IsPublic || options.allowDup)
                                    {
                                        var newName = String.Format("{0}_from_{1}", namespaceTypeDefinition.Name.Value, unitName);
                                        namespaceTypeDefinition.Name = host.NameTable.GetNameFor(newName);
                                        var newTypeName = TypeHelper.GetTypeName(namespaceTypeDefinition, NameFormattingOptions.UseGenericTypeNameSuffix);
                                        Console.WriteLine("Adding '{0}' as '{1}'", typeName, newTypeName);
                                        internedKeys.Add(typeName);
                                        t = namespaceTypeDefinition;
                                    }
                                    else
                                    {
                                        Console.WriteLine("Error: Duplicate type '{0}'", typeName);
                                        continue; //TODO: set a flag somewhere to force a failure.
                                    }
                                }
                                else
                                {
                                    //Console.WriteLine("Adding '{0}'", typeName);
                                    internedKeys.Add(typeName);
                                }
                            }
                            mergedTypes.Add(t);
                        }
                    }
                    #endregion

                    primaryAssembly.AllTypes = mergedTypes;

                    #endregion

                    CopyResourcesToPrimaryAssembly(primaryAssembly, modules);

                    if (version != null)
                    {
                        primaryAssembly.Version = version;
                    }

                    string outputPath;
                    if (options.output != null)
                    {
                        outputPath = options.output;
                    }
                    else
                    {
                        outputPath = primaryAssembly.Name.Value + Path.GetExtension(options.GeneralArguments[0]) + ".meta";
                    }

                    using (var aggregateSourceLocationProvider = new AggregatingSourceLocationProvider(unit2SourceLocationProviderMap)) {
                        using (var aggregateLocalScopeProvider = new AggregatingLocalScopeProvider(unit2LocalScopeProviderMap)) {
                            using (var peStream = File.Create(outputPath)) {
                                using (var pdbWriter = new PdbWriter(Path.ChangeExtension(outputPath, "pdb"), aggregateSourceLocationProvider)) {
                                    PeWriter.WritePeToStream(primaryAssembly, host, peStream, aggregateSourceLocationProvider, aggregateLocalScopeProvider, pdbWriter);
                                }
                            }
                        }
                    }
                } finally {
                }

                return(0); // success
            }
        }
示例#3
0
    public static Bpl.Program/*?*/ TranslateAssembly(List<string> assemblyNames, HeapFactory heapFactory, Options options, List<Regex> exemptionList, bool whiteList) {
      Contract.Requires(assemblyNames != null);
      Contract.Requires(heapFactory != null);

      var libPaths = options.libpaths;
      var wholeProgram = options.wholeProgram;
      var/*?*/ stubAssemblies = options.stub;
      var phoneControlsConfigFile = options.phoneControls;
      var doPhoneNav = options.phoneNavigationCode;
      var doPhoneFeedback = options.phoneFeedbackCode;

      var host = new CodeContractAwareHostEnvironment(libPaths != null ? libPaths : Enumerable<string>.Empty, true, true);
      Host = host;

      Bpl.CommandLineOptions.Install(new Bpl.CommandLineOptions());

      #region Assemlies to translate (via cmd line)
      modules = new List<IModule>();
      var contractExtractors = new Dictionary<IUnit, IContractProvider>();
      var pdbReaders = new Dictionary<IUnit, PdbReader>();
      #region Load *all* of the assemblies before doing anything else so that they can all vote on unification matters
      foreach (var a in assemblyNames) {
        var module = host.LoadUnitFrom(a) as IModule;
        if (module == null || module == Dummy.Module || module == Dummy.Assembly) {
          Console.WriteLine(a + " is not a PE file containing a CLR module or assembly, or an error occurred when loading it.");
          Console.WriteLine("Skipping it, continuing with other input assemblies");
          continue;
        }
        modules.Add(module);
      }
      #endregion
      #region Decompile all of the assemblies
      var decompiledModules = new List<IModule>();
      foreach (var m in modules) {
        PdbReader/*?*/ pdbReader = null;
        string pdbFile = Path.ChangeExtension(m.Location, "pdb");
        if (File.Exists(pdbFile)) {
          Stream pdbStream = File.OpenRead(pdbFile);
          pdbReader = new PdbReader(pdbStream, host);
        }
        var m2 = Decompiler.GetCodeModelFromMetadataModel(host, m, pdbReader, DecompilerOptions.Unstack) as IModule;
        // The decompiler does not turn calls to Assert/Assume into Code Model nodes
        m2 = new Microsoft.Cci.MutableContracts.ContractExtractor.AssertAssumeExtractor(host, pdbReader).Rewrite(m2);
        decompiledModules.Add(m2);
        host.RegisterAsLatest(m2);
        contractExtractors.Add(m2, host.GetContractExtractor(m2.UnitIdentity));
        pdbReaders.Add(m2, pdbReader);
      }
      modules = decompiledModules;
      #endregion
      #endregion

      #region Assemblies to translate (stubs)
      if (stubAssemblies != null) {
        foreach (var s in stubAssemblies) {
          var module = host.LoadUnitFrom(s) as IModule;
          if (module == null || module == Dummy.Module || module == Dummy.Assembly) {
            Console.WriteLine(s + " is not a PE file containing a CLR module or assembly, or an error occurred when loading it.");
            Console.WriteLine("Skipping it, continuing with other input assemblies");
          }
          PdbReader/*?*/ pdbReader = null;
          string pdbFile = Path.ChangeExtension(module.Location, "pdb");
          if (File.Exists(pdbFile)) {
            Stream pdbStream = File.OpenRead(pdbFile);
            pdbReader = new PdbReader(pdbStream, host);
          }
          module = Decompiler.GetCodeModelFromMetadataModel(host, module, pdbReader, DecompilerOptions.Unstack) as IModule;

          var copier = new CodeDeepCopier(host);
          var mutableModule = copier.Copy(module);

          var mscorlib = TypeHelper.GetDefiningUnit(host.PlatformType.SystemObject.ResolvedType);

          //var mutator = new ReparentModule(host, mscorlib, mutableModule);
          //module = mutator.Rewrite(mutableModule);
          //modules.Add(Tuple.Create(module, pdbReader));

          RewriteUnitReferences renamer = new RewriteUnitReferences(host, mutableModule);
          var mscorlibAssembly = (IAssembly)mscorlib;
          renamer.targetAssembly = mscorlibAssembly;
          renamer.originalAssemblyIdentity = mscorlibAssembly.AssemblyIdentity;
          renamer.RewriteChildren(mutableModule);
          modules.Add((IModule)mutableModule);
          contractExtractors.Add(module, host.GetContractExtractor(module.UnitIdentity));
          pdbReaders.Add(module, pdbReader);
        }
      }
      #endregion

      if (modules.Count == 0) {
        throw new TranslationException("No input assemblies to translate.");
      }

      var primaryModule = modules[0];
      Sink sink= new Sink(host, heapFactory, options, exemptionList, whiteList);
      TranslationHelper.tmpVarCounter = 0;

      // TODO move away, get all plugin and translators from a config file or alike
      #region Plugged translators
      List<Translator> translatorsPlugged = new List<Translator>();
      ITranslationPlugin bctPlugin= new BytecodeTranslatorPlugin(wholeProgram);
      Translator bcTranslator = bctPlugin.getTranslator(sink, contractExtractors, pdbReaders);
      translatorsPlugged.Add(bcTranslator);

      if (phoneControlsConfigFile != null && phoneControlsConfigFile != "") {
        // TODO this should be part of the translator initialziation
        PhoneCodeHelper.initialize(host);
        PhoneCodeHelper.instance().PhonePlugin = new PhoneControlsPlugin(phoneControlsConfigFile);

        if (doPhoneNav) {
          // TODO this should be part of the translator initialziation
          PhoneCodeHelper.instance().PhoneNavigationToggled = true;

          ITranslationPlugin phoneInitPlugin = new PhoneInitializationPlugin();
          ITranslationPlugin phoneNavPlugin = new PhoneNavigationPlugin();
          Translator phInitTranslator = phoneInitPlugin.getTranslator(sink, contractExtractors, pdbReaders);
          Translator phNavTranslator = phoneNavPlugin.getTranslator(sink, contractExtractors, pdbReaders);
          translatorsPlugged.Add(phInitTranslator);
          translatorsPlugged.Add(phNavTranslator);
        }

        if (doPhoneFeedback) {
          // TODO this should be part of the translator initialziation
          PhoneCodeHelper.instance().PhoneFeedbackToggled = true;

          ITranslationPlugin phoneFeedbackPlugin = new PhoneFeedbackPlugin();
          Translator phFeedbackTranslator = phoneFeedbackPlugin.getTranslator(sink, contractExtractors, pdbReaders);
          translatorsPlugged.Add(phFeedbackTranslator);
        }
      }
      #endregion
      sink.TranslationPlugins = translatorsPlugged;

      /*
      if (phoneControlsConfigFile != null && phoneControlsConfigFile != "") {
        // TODO send this all way to initialization of phone plugin translator
        PhoneCodeHelper.initialize(host);
        PhoneCodeHelper.instance().PhonePlugin = new PhoneControlsPlugin(phoneControlsConfigFile);
        
        // TODO these parameters will eventually form part of plugin configuration
        if (doPhoneNav) {
          PhoneCodeHelper.instance().PhoneNavigationToggled = true;
          PhoneInitializationMetadataTraverser initTr = new PhoneInitializationMetadataTraverser(host);
          initTr.InjectPhoneCodeAssemblies(modules);
          PhoneNavigationMetadataTraverser navTr = new PhoneNavigationMetadataTraverser(host);
          navTr.InjectPhoneCodeAssemblies(modules);
        }

        if (doPhoneFeedback) {
          PhoneCodeHelper.instance().PhoneFeedbackToggled = true;
          PhoneControlFeedbackMetadataTraverser fbMetaDataTraverser= new PhoneControlFeedbackMetadataTraverser(host);
          fbMetaDataTraverser.Visit(modules);
        }
      }
      */

      // TODO replace the whole translation by a translator initialization and an orchestrator calling back for each element
      // TODO for the current BC translator it will possibly just implement onMetadataElement(IModule)
      // TODO refactor this away, handle priorities between plugged translators
      IOrderedEnumerable<Translator> prioritizedTranslators = translatorsPlugged.OrderBy(t => t.getPriority());
      foreach (Translator t in prioritizedTranslators) {
        t.initialize();
        if (t.isOneShot())
          t.TranslateAssemblies(modules);
      }

      foreach (var pair in sink.delegateTypeToDelegates.Values) {
        CreateDispatchMethod(sink, pair.Item1, pair.Item2);
        CreateDelegateCreateMethod(sink, pair.Item1, pair.Item2);
        CreateDelegateAddMethod(sink, pair.Item1, pair.Item2);
        CreateDelegateRemoveMethod(sink, pair.Item1, pair.Item2);
      }

      // Subtyping for extern types
      if(sink.Options.typeInfo > 0) sink.DeclareExternTypeSubtyping();

      string outputFileName = primaryModule.Name + ".bpl";
      callPostTranslationTraversers(modules, sink, phoneControlsConfigFile, outputFileName);
      if (PhoneCodeHelper.instance().PhoneNavigationToggled) {
        finalizeNavigationAnalysisAndBoogieCode(phoneControlsConfigFile, sink, outputFileName);
      }

      //sink.CreateIdentifierCorrespondenceTable(primaryModule.Name.Value);

      //var rc = new Bpl.ResolutionContext((Bpl.IErrorSink)null);
      //foreach (var decl in sink.TranslatedProgram.TopLevelDeclarations) {
      //  decl.Register(rc);
      //}
      //sink.TranslatedProgram.Resolve(rc);
      //var goodDecls = new List<Bpl.Declaration>();
      //var tc = new Bpl.TypecheckingContext(null);
      //foreach (var decl in sink.TranslatedProgram.TopLevelDeclarations) {
      //  var impl = decl as Bpl.Implementation;
      //  if (impl == null) {
      //    goodDecls.Add(decl);
      //    continue;
      //  }
      //  try {
      //    //var tc = new Bpl.TypecheckingContext(null);
      //    impl.Typecheck(tc);
      //    goodDecls.Add(impl);
      //  } catch {
      //    Console.WriteLine("Deleting implementation for: " + impl.Name);
      //    // nothing to do, just continue
      //  }
      //}
      //sink.TranslatedProgram.TopLevelDeclarations = goodDecls;
      return sink.TranslatedProgram;
    }