AddStepAfter() public method

public AddStepAfter ( IStep target, IStep step ) : void
target IStep
step IStep
return void
Beispiel #1
0
        protected static void AddCustomStep(Pipeline pipeline, string arg)
        {
            int pos = arg.IndexOf(":");

            if (pos == -1)
            {
                pipeline.AppendStep(ResolveStep(arg));
                return;
            }

            string [] parts = arg.Split(':');
            if (parts.Length != 2)
            {
                Usage("Step is specified as TYPE:STEP");
            }

            if (parts [0].IndexOf(",") > -1)
            {
                pipeline.AddStepBefore(FindStep(pipeline, parts [1]), ResolveStep(parts [0]));
            }
            else if (parts [1].IndexOf(",") > -1)
            {
                pipeline.AddStepAfter(FindStep(pipeline, parts [0]), ResolveStep(parts [1]));
            }
            else
            {
                Usage("No comma separator in TYPE or STEP");
            }
        }
Beispiel #2
0
        protected static bool AddCustomStep(Pipeline pipeline, string arg)
        {
            int pos = arg.IndexOf(":");

            if (pos == -1)
            {
                var step = ResolveStep(arg);
                if (step == null)
                {
                    return(false);
                }

                pipeline.AppendStep(step);
                return(true);
            }

            string[] parts = arg.Split(':');
            if (parts.Length != 2)
            {
                Console.WriteLine($"Invalid value '{arg}' specified for '--custom-step' option");
                return(false);
            }

            if (!parts[0].StartsWith("-") && !parts [0].StartsWith("+"))
            {
                Console.WriteLine($"Expected '+' or '-' to control new step insertion");
                return(false);
            }

            bool   before = parts [0][0] == '-';
            string name   = parts [0].Substring(1);

            IStep target = FindStep(pipeline, name);

            if (target == null)
            {
                Console.WriteLine($"Pipeline step '{name}' could not be found");
                return(false);
            }

            IStep newStep = ResolveStep(parts [1]);

            if (newStep == null)
            {
                return(false);
            }

            if (before)
            {
                pipeline.AddStepBefore(target, newStep);
            }
            else
            {
                pipeline.AddStepAfter(target, newStep);
            }

            return(true);
        }
Beispiel #3
0
        void Run()
        {
            Pipeline       p            = GetStandardPipeline();
            LinkContext    context      = GetDefaultContext(p);
            I18nAssemblies assemblies   = I18nAssemblies.All;
            var            custom_steps = new List <string> ();

            bool resolver = false;

            while (HaveMoreTokens())
            {
                string token = GetParam();
                if (token.Length < 2)
                {
                    Usage("Option is too short");
                }

                if (!(token [0] == '-' || token [1] == '/'))
                {
                    Usage("Expecting an option, got instead: " + token);
                }

                if (token [0] == '-' && token [1] == '-')
                {
                    if (token.Length < 3)
                    {
                        Usage("Option is too short");
                    }

                    switch (token [2])
                    {
                    case 'v':
                        Version();
                        break;

                    case 'a':
                        About();
                        break;

                    default:
                        Usage(null);
                        break;
                    }
                }

                switch (token [1])
                {
                case 'd': {
                    DirectoryInfo info = new DirectoryInfo(GetParam());
                    context.Resolver.AddSearchDirectory(info.FullName);
                    break;
                }

                case 'o':
                    context.OutputDirectory = GetParam();
                    break;

                case 'c':
                    context.CoreAction = ParseAssemblyAction(GetParam());
                    break;

                case 'p':
                    AssemblyAction action = ParseAssemblyAction(GetParam());
                    context.Actions [GetParam()] = action;
                    break;

                case 's':
                    custom_steps.Add(GetParam());
                    break;

                case 't':
                    context.KeepTypeForwarderOnlyAssemblies = true;
                    break;

                case 'x':
                    foreach (string file in GetFiles(GetParam()))
                    {
                        p.PrependStep(new ResolveFromXmlStep(new XPathDocument(file)));
                    }
                    resolver = true;
                    break;

                case 'r':
                case 'a':
                    var rootVisibility = (token[1] == 'r')
                                                        ? ResolveFromAssemblyStep.RootVisibility.PublicAndFamily
                                                        : ResolveFromAssemblyStep.RootVisibility.Any;
                    foreach (string file in GetFiles(GetParam()))
                    {
                        p.PrependStep(new ResolveFromAssemblyStep(file, rootVisibility));
                    }
                    resolver = true;
                    break;

                case 'i':
                    foreach (string file in GetFiles(GetParam()))
                    {
                        p.PrependStep(new ResolveFromXApiStep(new XPathDocument(file)));
                    }
                    resolver = true;
                    break;

                case 'l':
                    assemblies = ParseI18n(GetParam());
                    break;

                case 'm':
                    context.SetParameter(GetParam(), GetParam());
                    break;

                case 'b':
                    context.LinkSymbols = bool.Parse(GetParam());
                    break;

                case 'g':
                    if (!bool.Parse(GetParam()))
                    {
                        p.RemoveStep(typeof(RegenerateGuidStep));
                    }
                    break;

                case 'v':
                    context.KeepMembersForDebuggerAttributes = bool.Parse(GetParam());
                    break;

                default:
                    Usage("Unknown option: `" + token [1] + "'");
                    break;
                }
            }

            if (!resolver)
            {
                Usage("No resolver was created (use -x, -a or -i)");
            }

            foreach (string custom_step in custom_steps)
            {
                AddCustomStep(p, custom_step);
            }

            p.AddStepAfter(typeof(LoadReferencesStep), new LoadI18nAssemblies(assemblies));

            p.Process(context);
        }
        public void Run(ILogger customLogger = null)
        {
            Pipeline p = GetStandardPipeline();

            using (LinkContext context = GetDefaultContext(p)) {
                if (customLogger != null)
                {
                    context.Logger = customLogger;
                }

                I18nAssemblies assemblies             = I18nAssemblies.All;
                var            custom_steps           = new List <string> ();
                var            excluded_features      = new HashSet <string> (StringComparer.Ordinal);
                var            disabled_optimizations = new HashSet <string> (StringComparer.Ordinal);
                bool           dumpDependencies       = false;
                bool           ignoreDescriptors      = false;
                bool           removeCAS = true;

                bool resolver = false;
                while (HaveMoreTokens())
                {
                    string token = GetParam();
                    if (token.Length < 2)
                    {
                        Usage("Option is too short");
                    }

                    if (!(token [0] == '-' || token [1] == '/'))
                    {
                        Usage("Expecting an option, got instead: " + token);
                    }

                    if (token [0] == '-' && token [1] == '-')
                    {
                        if (token.Length < 3)
                        {
                            Usage("Option is too short");
                        }

                        switch (token)
                        {
                        case "--skip-unresolved":
                            bool ignoreUnresolved = bool.Parse(GetParam());
                            context.IgnoreUnresolved          = ignoreUnresolved;
                            context.Resolver.IgnoreUnresolved = ignoreUnresolved;
                            continue;

                        case "--verbose":
                            context.LogMessages = true;
                            continue;

                        case "--dependencies-file":
                            context.Tracer.DependenciesFileName = GetParam();
                            continue;

                        case "--dump-dependencies":
                            dumpDependencies = true;
                            continue;

                        case "--reduced-tracing":
                            context.EnableReducedTracing = bool.Parse(GetParam());
                            continue;

                        case "--used-attrs-only":
                            context.KeepUsedAttributeTypesOnly = bool.Parse(GetParam());
                            continue;

                        case "--strip-security":
                            removeCAS = bool.Parse(GetParam());
                            continue;

                        case "--strip-resources":
                            context.StripResources = bool.Parse(GetParam());
                            continue;

                        case "--exclude-feature":
                            var name = GetParam();
                            foreach (var feature in name.Split(','))
                            {
                                if (!excluded_features.Contains(feature))
                                {
                                    excluded_features.Add(feature);
                                }
                            }
                            continue;

                        case "--custom-step":
                            custom_steps.Add(GetParam());
                            continue;

                        case "--keep-facades":
                            context.KeepTypeForwarderOnlyAssemblies = bool.Parse(GetParam());
                            continue;

                        case "--ignore-descriptors":
                            ignoreDescriptors = bool.Parse(GetParam());
                            continue;

                        case "--disable-opt":
                            var opt = GetParam().ToLower();
                            if (!disabled_optimizations.Contains(opt))
                            {
                                disabled_optimizations.Add(opt);
                            }

                            continue;
                        }

                        switch (token [2])
                        {
                        case 'v':
                            Version();
                            break;

                        case 'a':
                            About();
                            break;

                        default:
                            Usage(null);
                            break;
                        }
                    }

                    switch (token [1])
                    {
                    case 'd':
                        DirectoryInfo info = new DirectoryInfo(GetParam());
                        context.Resolver.AddSearchDirectory(info.FullName);
                        break;

                    case 'o':
                        context.OutputDirectory = GetParam();
                        break;

                    case 'c':
                        context.CoreAction = ParseAssemblyAction(GetParam());
                        break;

                    case 'u':
                        context.UserAction = ParseAssemblyAction(GetParam());
                        break;

                    case 'p':
                        AssemblyAction action = ParseAssemblyAction(GetParam());
                        context.Actions [GetParam()] = action;
                        break;

                    case 't':
                        context.KeepTypeForwarderOnlyAssemblies = true;
                        break;

                    case 'x':
                        foreach (string file in GetFiles(GetParam()))
                        {
                            p.PrependStep(new ResolveFromXmlStep(new XPathDocument(file)));
                        }
                        resolver = true;
                        break;

                    case 'r':
                    case 'a':
                        var rootVisibility = (token [1] == 'r')
                                                        ? ResolveFromAssemblyStep.RootVisibility.PublicAndFamily
                                                        : ResolveFromAssemblyStep.RootVisibility.Any;
                        foreach (string file in GetFiles(GetParam()))
                        {
                            p.PrependStep(new ResolveFromAssemblyStep(file, rootVisibility));
                        }
                        resolver = true;
                        break;

                    case 'i':
                        foreach (string file in GetFiles(GetParam()))
                        {
                            p.PrependStep(new ResolveFromXApiStep(new XPathDocument(file)));
                        }
                        resolver = true;
                        break;

                    case 'l':
                        assemblies = ParseI18n(GetParam());
                        break;

                    case 'm':
                        context.SetParameter(GetParam(), GetParam());
                        break;

                    case 'b':
                        context.LinkSymbols = bool.Parse(GetParam());
                        break;

                    case 'g':
                        if (!bool.Parse(GetParam()))
                        {
                            p.RemoveStep(typeof(RegenerateGuidStep));
                        }
                        break;

                    case 'z':
                        ignoreDescriptors = !bool.Parse(GetParam());
                        break;

                    case 'v':
                        context.KeepMembersForDebugger = bool.Parse(GetParam());
                        break;

                    default:
                        Usage("Unknown option: `" + token [1] + "'");
                        break;
                    }
                }

                if (!resolver)
                {
                    Usage("No resolver was created (use -x, -a or -i)");
                }

                if (ignoreDescriptors)
                {
                    p.RemoveStep(typeof(BlacklistStep));
                }

                if (dumpDependencies)
                {
                    context.Tracer.Start();
                }

                foreach (string custom_step in custom_steps)
                {
                    AddCustomStep(p, custom_step);
                }

                p.AddStepAfter(typeof(LoadReferencesStep), new LoadI18nAssemblies(assemblies));

                if (_needAddBypassNGenStep)
                {
                    p.AddStepAfter(typeof(SweepStep), new AddBypassNGenStep());
                }

                if (assemblies != I18nAssemblies.None)
                {
                    p.AddStepAfter(typeof(PreserveDependencyLookupStep), new PreserveCalendarsStep(assemblies));
                }

                if (removeCAS)
                {
                    p.AddStepBefore(typeof(MarkStep), new RemoveSecurityStep());
                }

                if (excluded_features.Count > 0)
                {
                    p.AddStepBefore(typeof(MarkStep), new RemoveFeaturesStep()
                    {
                        FeatureCOM           = excluded_features.Contains("com"),
                        FeatureETW           = excluded_features.Contains("etw"),
                        FeatureGlobalization = excluded_features.Contains("globalization")
                    });

                    var excluded = new string [excluded_features.Count];
                    excluded_features.CopyTo(excluded);
                    context.ExcludedFeatures = excluded;
                }

                if (disabled_optimizations.Count > 0)
                {
                    foreach (var item in disabled_optimizations)
                    {
                        switch (item)
                        {
                        case "beforefieldinit":
                            context.DisabledOptimizations |= CodeOptimizations.BeforeFieldInit;
                            break;

                        case "overrideremoval":
                            context.DisabledOptimizations |= CodeOptimizations.OverrideRemoval;
                            break;
                        }
                    }
                }

                PreProcessPipeline(p);

                try {
                    p.Process(context);
                }
                finally {
                    if (dumpDependencies)
                    {
                        context.Tracer.Finish();
                    }
                }
            }
        }
Beispiel #5
0
        public bool Run(ILogger customLogger = null)
        {
            Pipeline p = GetStandardPipeline();

            using (LinkContext context = GetDefaultContext(p)) {
                if (customLogger != null)
                {
                    context.Logger = customLogger;
                }

#if !FEATURE_ILLINK
                I18nAssemblies assemblies = I18nAssemblies.All;
#endif
                var    custom_steps           = new List <string> ();
                var    excluded_features      = new HashSet <string> (StringComparer.Ordinal);
                var    disabled_optimizations = new HashSet <string> (StringComparer.Ordinal);
                var    enabled_optimizations  = new HashSet <string> (StringComparer.Ordinal);
                bool   dumpDependencies       = false;
                string dependenciesFileName   = null;
                bool   ignoreDescriptors      = false;
                bool   removeCAS          = true;
                bool   new_mvid_used      = false;
                bool   deterministic_used = false;

                bool resolver = false;
                while (arguments.Count > 0)
                {
                    string token = arguments.Dequeue();
                    if (token.Length < 2)
                    {
                        ErrorUnrecognizedOption(token);
                        return(false);
                    }

                    //
                    // Handling of --value like options
                    //
                    if (token [0] == '-' && token [1] == '-')
                    {
                        switch (token)
                        {
                        case "--skip-unresolved":
                            if (!GetBoolParam(token, l => context.IgnoreUnresolved = context.Resolver.IgnoreUnresolved = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--verbose":
                            context.LogMessages = true;
                            continue;

                        case "--dependencies-file":
                            if (!GetStringParam(token, l => dependenciesFileName = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--dump-dependencies":
                            dumpDependencies = true;
                            continue;

                        case "--reduced-tracing":
                            if (!GetBoolParam(token, l => context.EnableReducedTracing = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--used-attrs-only":
                            if (!GetBoolParam(token, l => context.KeepUsedAttributeTypesOnly = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--strip-security":
                            if (!GetBoolParam(token, l => removeCAS = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--strip-resources":
                            if (!GetBoolParam(token, l => context.StripResources = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--substitutions":
                            if (arguments.Count < 1)
                            {
                                ErrorMissingArgument(token);
                                return(false);
                            }

                            if (!GetStringParam(token, l => context.AddSubstitutionFile(l)))
                            {
                                return(false);
                            }

                            continue;

                        case "--exclude-feature":
                            if (arguments.Count < 1)
                            {
                                ErrorMissingArgument(token);
                                return(false);
                            }

                            if (!GetStringParam(token, l => {
                                foreach (var feature in l.Split(','))
                                {
                                    if (!excluded_features.Contains(feature))
                                    {
                                        excluded_features.Add(feature);
                                    }
                                }
                            }))
                            {
                                return(false);
                            }

                            continue;

                        case "--explicit-reflection":
                            if (!GetBoolParam(token, l => context.AddReflectionAnnotations = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--custom-step":
                            if (!GetStringParam(token, l => custom_steps.Add(l)))
                            {
                                return(false);
                            }

                            continue;

                        case "--keep-facades":
                            if (!GetBoolParam(token, l => context.KeepTypeForwarderOnlyAssemblies = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--keep-dep-attributes":
                            if (!GetBoolParam(token, l => context.KeepDependencyAttributes = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--ignore-descriptors":
                            if (!GetBoolParam(token, l => ignoreDescriptors = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--disable-opt":
                            if (!GetStringParam(token, l => {
                                var opt = l.ToLowerInvariant();
                                if (!disabled_optimizations.Contains(opt))
                                {
                                    disabled_optimizations.Add(opt);
                                }
                            }))
                            {
                                return(false);
                            }

                            continue;

                        case "--enable-opt":
                            if (!GetStringParam(token, l => {
                                var opt = l.ToLowerInvariant();
                                if (!enabled_optimizations.Contains(opt))
                                {
                                    enabled_optimizations.Add(opt);
                                }
                            }))
                            {
                                return(false);
                            }

                            continue;

                        case "--new-mvid":
                            //
                            // This is not same as --deterministic which calculates MVID
                            // from stable assembly content. This option creates a new random
                            // mvid or uses mvid of the source assembly.
                            //
                            if (!GetBoolParam(token, l => {
                                if (!l)
                                {
                                    p.RemoveStep(typeof(RegenerateGuidStep));
                                }
                            }))
                            {
                                return(false);
                            }

                            new_mvid_used = true;
                            continue;

                        case "--deterministic":
                            if (!GetBoolParam(token, l => context.DeterministicOutput = l))
                            {
                                return(false);
                            }

                            deterministic_used = true;
                            continue;

                        case "--output-assemblylist":
                            if (!GetStringParam(token, l => context.AssemblyListFile = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--version":
                            Version();
                            return(true);

                        case "--about":
                            About();
                            return(true);
                        }
                    }

                    if (token [0] == '-' || token [1] == '/')
                    {
                        switch (token.Substring(1))
                        {
                        case "d":
                            if (!GetStringParam(token, l => {
                                DirectoryInfo info = new DirectoryInfo(l);
                                context.Resolver.AddSearchDirectory(info.FullName);
                            }))
                            {
                                return(false);
                            }

                            continue;

                        case "o":
                        case "out":
                            if (!GetStringParam(token, l => context.OutputDirectory = l))
                            {
                                return(false);
                            }

                            continue;

                        case "c":
                            if (!GetStringParam(token, l => context.CoreAction = ParseAssemblyAction(l)))
                            {
                                return(false);
                            }

                            continue;

                        case "u":
                            if (!GetStringParam(token, l => context.UserAction = ParseAssemblyAction(l)))
                            {
                                return(false);
                            }

                            continue;

                        case "p":
                            if (arguments.Count < 2)
                            {
                                ErrorMissingArgument(token);
                                return(false);
                            }

                            AssemblyAction action = ParseAssemblyAction(arguments.Dequeue());
                            context.Actions [arguments.Dequeue()] = action;
                            continue;

                        case "t":
                            context.KeepTypeForwarderOnlyAssemblies = true;
                            continue;

                        case "x":
                            if (!GetStringParam(token, l => {
                                foreach (string file in GetFiles(l))
                                {
                                    p.PrependStep(new ResolveFromXmlStep(new XPathDocument(file)));
                                }
                            }))
                            {
                                return(false);
                            }

                            resolver = true;
                            continue;

                        case "r":
                        case "a":
                            if (!GetStringParam(token, l => {
                                var rootVisibility = (token [1] == 'r')
                                                                        ? ResolveFromAssemblyStep.RootVisibility.PublicAndFamily
                                                                        : ResolveFromAssemblyStep.RootVisibility.Any;
                                foreach (string file in GetFiles(l))
                                {
                                    p.PrependStep(new ResolveFromAssemblyStep(file, rootVisibility));
                                }
                            }))
                            {
                                return(false);
                            }

                            resolver = true;
                            continue;

#if !FEATURE_ILLINK
                        case "i":
                            if (!GetStringParam(token, l => {
                                foreach (string file in GetFiles(l))
                                {
                                    p.PrependStep(new ResolveFromXApiStep(new XPathDocument(file)));
                                }
                            }))
                            {
                                return(false);
                            }

                            resolver = true;
                            continue;

                        case "l":
                            if (!GetStringParam(token, l => assemblies = ParseI18n(l)))
                            {
                                return(false);
                            }

                            continue;
#endif
                        case "m":
                            if (arguments.Count < 2)
                            {
                                ErrorMissingArgument(token);
                                return(false);
                            }

                            context.SetParameter(arguments.Dequeue(), arguments.Dequeue());
                            continue;

                        case "b":
                            if (!GetBoolParam(token, l => context.LinkSymbols = l))
                            {
                                return(false);
                            }

                            continue;

                        case "g":
                            if (!GetBoolParam(token, l => context.DeterministicOutput = !l))
                            {
                                return(false);
                            }

                            continue;

                        case "z":
                            if (!GetBoolParam(token, l => ignoreDescriptors = !l))
                            {
                                return(false);
                            }

                            continue;

                        case "v":
                            if (!GetBoolParam(token, l => context.KeepMembersForDebugger = l))
                            {
                                return(false);
                            }

                            continue;

                        case "?":
                        case "help":
                            Usage();
                            return(true);

                        case "reference":
                            if (!GetStringParam(token, l => context.Resolver.AddReferenceAssembly(l)))
                            {
                                return(false);
                            }

                            continue;
                        }
                    }

                    ErrorUnrecognizedOption(token);
                    return(false);
                }

                if (!resolver)
                {
                    Console.WriteLine($"No files to link were specified. Use one of '{resolvers}' options");
                    return(false);
                }

                if (new_mvid_used && deterministic_used)
                {
                    Console.WriteLine($"Options '--new-mvid' and '--deterministic' cannot be used at the same time");
                    return(false);
                }

                if (dumpDependencies)
                {
                    context.Tracer.AddRecorder(new XmlDependencyRecorder(context, dependenciesFileName));
                }

                if (disabled_optimizations.Count > 0)
                {
                    foreach (var item in disabled_optimizations)
                    {
                        switch (item)
                        {
                        case "beforefieldinit":
                            context.DisabledOptimizations |= CodeOptimizations.BeforeFieldInit;
                            break;

                        case "overrideremoval":
                            context.DisabledOptimizations |= CodeOptimizations.OverrideRemoval;
                            break;

                        case "unreachablebodies":
                            context.DisabledOptimizations |= CodeOptimizations.UnreachableBodies;
                            break;

                        case "unusedinterfaces":
                            context.DisabledOptimizations |= CodeOptimizations.UnusedInterfaces;
                            break;

                        case "ipconstprop":
                            context.DisabledOptimizations |= CodeOptimizations.IPConstantPropagation;
                            break;
                        }
                    }
                }

                if (enabled_optimizations.Count > 0)
                {
                    foreach (var item in enabled_optimizations)
                    {
                        switch (item)
                        {
                        case "unreachablebodies":
                            context.DisabledOptimizations &= ~CodeOptimizations.UnreachableBodies;
                            break;

                        case "clearinitlocals":
                            context.DisabledOptimizations &= ~CodeOptimizations.ClearInitLocals;
                            break;

                        case "ipconstprop":
                            context.DisabledOptimizations &= ~CodeOptimizations.IPConstantPropagation;
                            break;
                        }
                    }
                }

                //
                // Modify the default pipeline
                //
                if (ignoreDescriptors)
                {
                    p.RemoveStep(typeof(BlacklistStep));
                }

                if (context.DeterministicOutput)
                {
                    p.RemoveStep(typeof(RegenerateGuidStep));
                }

                if (context.AddReflectionAnnotations)
                {
                    p.AddStepAfter(typeof(MarkStep), new ReflectionBlockedStep());
                }

#if !FEATURE_ILLINK
                p.AddStepAfter(typeof(LoadReferencesStep), new LoadI18nAssemblies(assemblies));

                if (assemblies != I18nAssemblies.None)
                {
                    p.AddStepAfter(typeof(PreserveDependencyLookupStep), new PreserveCalendarsStep(assemblies));
                }
#endif

                if (_needAddBypassNGenStep)
                {
                    p.AddStepAfter(typeof(SweepStep), new AddBypassNGenStep());
                }

                p.AddStepBefore(typeof(MarkStep), new BodySubstituterStep());

                if (removeCAS)
                {
                    p.AddStepBefore(typeof(MarkStep), new RemoveSecurityStep());
                }

                if (excluded_features.Count > 0)
                {
                    p.AddStepBefore(typeof(MarkStep), new RemoveFeaturesStep()
                    {
                        FeatureCOM           = excluded_features.Contains("com"),
                        FeatureETW           = excluded_features.Contains("etw"),
                        FeatureSRE           = excluded_features.Contains("sre"),
                        FeatureGlobalization = excluded_features.Contains("globalization")
                    });

                    var excluded = new string [excluded_features.Count];
                    excluded_features.CopyTo(excluded);
                    context.ExcludedFeatures = excluded;
                }

                p.AddStepBefore(typeof(MarkStep), new RemoveUnreachableBlocksStep());

                if (context.IsOptimizationEnabled(CodeOptimizations.ClearInitLocals))
                {
                    p.AddStepBefore(typeof(OutputStep), new ClearInitLocalsStep());
                }


                //
                // Pipeline setup with all steps enabled
                //
                // LoadReferencesStep
                // BlacklistStep [optional]
                // PreserveDependencyLookupStep
                // TypeMapStep
                // BodySubstituterStep [optional]
                // RemoveSecurityStep [optional]
                // RemoveFeaturesStep [optional]
                // RemoveUnreachableBlocksStep [optional]
                // MarkStep
                // ReflectionBlockedStep [optional]
                // SweepStep
                // AddBypassNGenStep [optional]
                // CodeRewriterStep
                // CleanStep
                // RegenerateGuidStep [optional]
                // ClearInitLocalsStep [optional]
                // OutputStep
                //

                foreach (string custom_step in custom_steps)
                {
                    if (!AddCustomStep(p, custom_step))
                    {
                        return(false);
                    }
                }

                PreProcessPipeline(p);

                try {
                    p.Process(context);
                } finally {
                    context.Tracer.Finish();
                }

                return(true);
            }
        }
Beispiel #6
0
        // Perform setup of the LinkContext and parse the arguments.
        // Return values:
        // 0 => successfully set up context with all arguments
        // 1 => argument processing stopped early without errors
        // -1 => error setting up context
        protected int SetupContext(ILogger customLogger = null)
        {
            Pipeline p = GetStandardPipeline();

            context = GetDefaultContext(p);

            if (customLogger != null)
            {
                context.Logger = customLogger;
            }

#if !FEATURE_ILLINK
            I18nAssemblies assemblies              = I18nAssemblies.All;
            var            excluded_features       = new HashSet <string> (StringComparer.Ordinal);
            var            resolve_from_xapi_steps = new Stack <string> ();
#endif
            var    resolve_from_assembly_steps = new Stack <(string, ResolveFromAssemblyStep.RootVisibility)> ();
            var    resolve_from_xml_steps      = new Stack <string> ();
            var    body_substituter_steps      = new Stack <string> ();
            var    custom_steps         = new Stack <string> ();
            var    set_optimizations    = new List <(CodeOptimizations, string, bool)> ();
            bool   dumpDependencies     = false;
            string dependenciesFileName = null;
            bool   removeCAS            = true;
            bool   new_mvid_used        = false;
            bool   deterministic_used   = false;

            bool resolver = false;
            while (arguments.Count > 0)
            {
                string token = arguments.Dequeue();
                if (token.Length < 2)
                {
                    ErrorUnrecognizedOption(token);
                    return(-1);
                }

                //
                // Handling of --value like options
                //
                if (token[0] == '-' && token[1] == '-')
                {
                    switch (token)
                    {
                    case "--skip-unresolved":
                        if (!GetBoolParam(token, l => context.IgnoreUnresolved = context.Resolver.IgnoreUnresolved = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--verbose":
                        context.LogMessages = true;
                        continue;

                    case "--dependencies-file":
                        if (!GetStringParam(token, l => dependenciesFileName = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--dump-dependencies":
                        dumpDependencies = true;
                        continue;

                    case "--reduced-tracing":
                        if (!GetBoolParam(token, l => context.EnableReducedTracing = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--used-attrs-only":
                        if (!GetBoolParam(token, l => context.KeepUsedAttributeTypesOnly = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--strip-security":
                        if (!GetBoolParam(token, l => removeCAS = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--strip-descriptors":
                        if (!GetBoolParam(token, l => context.StripDescriptors = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--strip-substitutions":
                        if (!GetBoolParam(token, l => context.StripSubstitutions = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--substitutions":
                        if (arguments.Count < 1)
                        {
                            ErrorMissingArgument(token);
                            return(-1);
                        }

                        if (!GetStringParam(token, l => body_substituter_steps.Push(l)))
                        {
                            return(-1);
                        }

                        continue;

#if !FEATURE_ILLINK
                    case "--exclude-feature":
                        if (arguments.Count < 1)
                        {
                            ErrorMissingArgument(token);
                            return(-1);
                        }

                        if (!GetStringParam(token, l => {
                            foreach (var feature in l.Split(','))
                            {
                                if (!excluded_features.Contains(feature))
                                {
                                    excluded_features.Add(feature);
                                }
                            }
                        }))
                        {
                            return(-1);
                        }

                        continue;
#endif
                    case "--explicit-reflection":
                        if (!GetBoolParam(token, l => context.AddReflectionAnnotations = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--custom-step":
                        if (!GetStringParam(token, l => custom_steps.Push(l)))
                        {
                            return(-1);
                        }

                        continue;

                    case "--custom-data":
                        if (arguments.Count < 1)
                        {
                            ErrorMissingArgument(token);
                            return(-1);
                        }

                        var      arg    = arguments.Dequeue();
                        string[] values = arg.Split('=');
                        if (values?.Length != 2)
                        {
                            Console.WriteLine($"Value used with '--custom-data' has to be in the KEY=VALUE format");
                            return(-1);
                        }

                        context.SetCustomData(values[0], values[1]);
                        continue;

                    case "--keep-facades":
                        if (!GetBoolParam(token, l => context.KeepTypeForwarderOnlyAssemblies = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--keep-dep-attributes":
                        if (!GetBoolParam(token, l => context.KeepDependencyAttributes = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--ignore-descriptors":
                        if (!GetBoolParam(token, l => context.IgnoreDescriptors = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--ignore-substitutions":
                        if (!GetBoolParam(token, l => context.IgnoreSubstitutions = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--disable-opt": {
                        string optName = null;
                        if (!GetStringParam(token, l => optName = l))
                        {
                            return(-1);
                        }

                        if (!GetOptimizationName(optName, out var opt))
                        {
                            return(-1);
                        }

                        string assemblyName = GetNextStringValue();
                        set_optimizations.Add((opt, assemblyName, false));

                        continue;
                    }

                    case "--enable-opt": {
                        string optName = null;
                        if (!GetStringParam(token, l => optName = l))
                        {
                            return(-1);
                        }

                        if (!GetOptimizationName(optName, out var opt))
                        {
                            return(-1);
                        }

                        string assemblyName = GetNextStringValue();
                        set_optimizations.Add((opt, assemblyName, true));

                        continue;
                    }

                    case "--feature": {
                        string featureName = null;
                        if (!GetStringParam(token, l => featureName = l))
                        {
                            return(-1);
                        }

                        if (!GetBoolParam(token, value => {
                                context.SetFeatureValue(featureName, value);
                            }))
                        {
                            return(-1);
                        }

                        continue;
                    }

                    case "--new-mvid":
                        //
                        // This is not same as --deterministic which calculates MVID
                        // from stable assembly content. This option creates a new random
                        // mvid or uses mvid of the source assembly.
                        //
                        if (!GetBoolParam(token, l => {
                            if (!l)
                            {
                                p.RemoveStep(typeof(RegenerateGuidStep));
                            }
                        }))
                        {
                            return(-1);
                        }

                        new_mvid_used = true;
                        continue;

                    case "--deterministic":
                        if (!GetBoolParam(token, l => context.DeterministicOutput = l))
                        {
                            return(-1);
                        }

                        deterministic_used = true;
                        continue;

                    case "--output-assemblylist":
                        if (!GetStringParam(token, l => context.AssemblyListFile = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--output-pinvokes":
                        if (!GetStringParam(token, l => context.PInvokesListFile = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--attribute-defs":
                        if (arguments.Count < 1)
                        {
                            ErrorMissingArgument(token);
                            return(-1);
                        }

                        if (!GetStringParam(token, l => context.AddAttributeDefinitionFile(l)))
                        {
                            return(-1);
                        }

                        continue;

                    case "--version":
                        Version();
                        return(1);

                    case "--about":
                        About();
                        return(1);
                    }
                }

                if (token[0] == '-' || token[1] == '/')
                {
                    switch (token.Substring(1))
                    {
                    case "d":
                        if (!GetStringParam(token, l => {
                            DirectoryInfo info = new DirectoryInfo(l);
                            context.Resolver.AddSearchDirectory(info.FullName);
                        }))
                        {
                            return(-1);
                        }

                        continue;

                    case "o":
                    case "out":
                        if (!GetStringParam(token, l => context.OutputDirectory = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "c":
                        if (!GetStringParam(token, l => context.CoreAction = ParseAssemblyAction(l)))
                        {
                            return(-1);
                        }

                        continue;

                    case "u":
                        if (!GetStringParam(token, l => context.UserAction = ParseAssemblyAction(l)))
                        {
                            return(-1);
                        }

                        continue;

                    case "p":
                        if (arguments.Count < 2)
                        {
                            ErrorMissingArgument(token);
                            return(-1);
                        }

                        AssemblyAction action = ParseAssemblyAction(arguments.Dequeue());
                        context.Actions[arguments.Dequeue()] = action;
                        continue;

                    case "t":
                        context.KeepTypeForwarderOnlyAssemblies = true;
                        continue;

                    case "x":
                        if (!GetStringParam(token, l => {
                            foreach (string file in GetFiles(l))
                            {
                                resolve_from_xml_steps.Push(file);
                            }
                        }))
                        {
                            return(-1);
                        }

                        resolver = true;
                        continue;

                    case "r":
                    case "a":
                        if (!GetStringParam(token, l => {
                            var rootVisibility = (token[1] == 'r')
                                                                ? ResolveFromAssemblyStep.RootVisibility.PublicAndFamily
                                                                : ResolveFromAssemblyStep.RootVisibility.Any;
                            foreach (string file in GetFiles(l))
                            {
                                resolve_from_assembly_steps.Push((file, rootVisibility));
                            }
                        }))
                        {
                            return(-1);
                        }

                        resolver = true;
                        continue;

#if !FEATURE_ILLINK
                    case "i":
                        if (!GetStringParam(token, l => {
                            foreach (string file in GetFiles(l))
                            {
                                resolve_from_xapi_steps.Push(file);
                            }
                        }))
                        {
                            return(-1);
                        }

                        resolver = true;
                        continue;

                    case "l":
                        if (!GetStringParam(token, l => assemblies = ParseI18n(l)))
                        {
                            return(-1);
                        }

                        continue;
#endif
                    case "b":
                        if (!GetBoolParam(token, l => context.LinkSymbols = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "g":
                        if (!GetBoolParam(token, l => context.DeterministicOutput = !l))
                        {
                            return(-1);
                        }

                        continue;

                    case "z":
                        if (!GetBoolParam(token, l => context.IgnoreDescriptors = !l))
                        {
                            return(-1);
                        }

                        continue;

                    case "v":
                        if (!GetBoolParam(token, l => context.KeepMembersForDebugger = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "?":
                    case "help":
                        Usage();
                        return(1);

                    case "reference":
                        if (!GetStringParam(token, l => context.Resolver.AddReferenceAssembly(l)))
                        {
                            return(-1);
                        }

                        continue;
                    }
                }

                ErrorUnrecognizedOption(token);
                return(-1);
            }

            if (!resolver)
            {
                Console.WriteLine($"No files to link were specified. Use one of '{resolvers}' options");
                return(-1);
            }

            if (new_mvid_used && deterministic_used)
            {
                Console.WriteLine($"Options '--new-mvid' and '--deterministic' cannot be used at the same time");
                return(-1);
            }

            if (dumpDependencies)
            {
                AddXmlDependencyRecorder(context, dependenciesFileName);
            }

            if (set_optimizations.Count > 0)
            {
                foreach (var(opt, assemblyName, enable) in set_optimizations)
                {
                    if (enable)
                    {
                        context.Optimizations.Enable(opt, assemblyName);
                    }
                    else
                    {
                        context.Optimizations.Disable(opt, assemblyName);
                    }
                }
            }

            //
            // Modify the default pipeline
            //

#if !FEATURE_ILLINK
            foreach (var file in resolve_from_xapi_steps)
            {
                p.PrependStep(new ResolveFromXApiStep(new XPathDocument(file)));
            }
#endif

            foreach (var file in resolve_from_xml_steps)
            {
                AddResolveFromXmlStep(p, file);
            }

            foreach (var(file, rootVisibility) in resolve_from_assembly_steps)
            {
                p.PrependStep(new ResolveFromAssemblyStep(file, rootVisibility));
            }

            foreach (var file in body_substituter_steps)
            {
                AddBodySubstituterStep(p, file);
            }

            if (context.DeterministicOutput)
            {
                p.RemoveStep(typeof(RegenerateGuidStep));
            }

            if (context.AddReflectionAnnotations)
            {
                p.AddStepAfter(typeof(MarkStep), new ReflectionBlockedStep());
            }

#if !FEATURE_ILLINK
            p.AddStepAfter(typeof(LoadReferencesStep), new LoadI18nAssemblies(assemblies));

            if (assemblies != I18nAssemblies.None)
            {
                p.AddStepAfter(typeof(PreserveDependencyLookupStep), new PreserveCalendarsStep(assemblies));
            }
#endif

            if (_needAddBypassNGenStep)
            {
                p.AddStepAfter(typeof(SweepStep), new AddBypassNGenStep());
            }

            if (removeCAS)
            {
                p.AddStepBefore(typeof(MarkStep), new RemoveSecurityStep());
            }

#if !FEATURE_ILLINK
            if (excluded_features.Count > 0)
            {
                p.AddStepBefore(typeof(MarkStep), new RemoveFeaturesStep()
                {
                    FeatureCOM           = excluded_features.Contains("com"),
                    FeatureETW           = excluded_features.Contains("etw"),
                    FeatureSRE           = excluded_features.Contains("sre"),
                    FeatureGlobalization = excluded_features.Contains("globalization")
                });

                var excluded = new string[excluded_features.Count];
                excluded_features.CopyTo(excluded);
                context.ExcludedFeatures = excluded;
            }
#endif

            p.AddStepBefore(typeof(MarkStep), new RemoveUnreachableBlocksStep());
            p.AddStepBefore(typeof(OutputStep), new ClearInitLocalsStep());
            p.AddStepBefore(typeof(OutputStep), new SealerStep());

            //
            // Pipeline setup with all steps enabled
            //
            // ResolveFromAssemblyStep [optional, possibly many]
            // ResolveFromXmlStep [optional, possibly many]
            // [mono only] ResolveFromXApiStep [optional, possibly many]
            // LoadReferencesStep
            // [mono only] LoadI18nAssemblies
            // BlacklistStep
            //   dynamically adds steps:
            //     ResolveFromXmlStep [optional, possibly many]
            //     BodySubstituterStep [optional, possibly many]
            // PreserveDependencyLookupStep
            // [mono only] PreselveCalendarsStep [optional]
            // TypeMapStep
            // BodySubstituterStep [optional]
            // RemoveSecurityStep [optional]
            // [mono only] RemoveFeaturesStep [optional]
            // RemoveUnreachableBlocksStep [optional]
            // MarkStep
            // ReflectionBlockedStep [optional]
            // SweepStep
            // AddBypassNGenStep [optional]
            // CodeRewriterStep
            // CleanStep
            // RegenerateGuidStep [optional]
            // ClearInitLocalsStep
            // SealerStep
            // OutputStep
            //

            foreach (string custom_step in custom_steps)
            {
                if (!AddCustomStep(p, custom_step))
                {
                    return(-1);
                }
            }

            return(0);
        }
Beispiel #7
0
        public void Run(ILogger customLogger = null)
        {
            Pipeline p = GetStandardPipeline();

            using (LinkContext context = GetDefaultContext(p)) {
                if (customLogger != null)
                {
                    context.Logger = customLogger;
                }

                I18nAssemblies assemblies       = I18nAssemblies.All;
                var            custom_steps     = new List <string> ();
                bool           dumpDependencies = false;

                bool resolver = false;
                while (HaveMoreTokens())
                {
                    string token = GetParam();
                    if (token.Length < 2)
                    {
                        Usage("Option is too short");
                    }

                    if (!(token [0] == '-' || token [1] == '/'))
                    {
                        Usage("Expecting an option, got instead: " + token);
                    }

                    if (token [0] == '-' && token [1] == '-')
                    {
                        if (token.Length < 3)
                        {
                            Usage("Option is too short");
                        }

                        if (token == "--skip-unresolved")
                        {
                            bool ignoreUnresolved = bool.Parse(GetParam());
                            context.IgnoreUnresolved          = ignoreUnresolved;
                            context.Resolver.IgnoreUnresolved = ignoreUnresolved;
                            continue;
                        }

                        if (token == "--verbose")
                        {
                            context.LogMessages = true;
                            continue;
                        }

                        if (token == "--dependencies-file")
                        {
                            context.Tracer.DependenciesFileName = GetParam();
                            continue;
                        }

                        if (token == "--dump-dependencies")
                        {
                            dumpDependencies = true;
                            continue;
                        }

                        if (token == "--reduced-tracing")
                        {
                            context.EnableReducedTracing = bool.Parse(GetParam());
                            continue;
                        }

                        if (token == "--used-attrs-only")
                        {
                            context.KeepUsedAttributeTypesOnly = bool.Parse(GetParam());
                            continue;
                        }

                        if (token == "--strip-security")
                        {
                            if (bool.Parse(GetParam()))
                            {
                                p.AddStepBefore(typeof(MarkStep), new RemoveSecurityStep());
                            }
                            continue;
                        }

                        if (token == "--strip-resources")
                        {
                            context.StripResources = bool.Parse(GetParam());
                            continue;
                        }

                        switch (token [2])
                        {
                        case 'v':
                            Version();
                            break;

                        case 'a':
                            About();
                            break;

                        default:
                            Usage(null);
                            break;
                        }
                    }

                    switch (token [1])
                    {
                    case 'd': {
                        DirectoryInfo info = new DirectoryInfo(GetParam());
                        context.Resolver.AddSearchDirectory(info.FullName);
                        break;
                    }

                    case 'o':
                        context.OutputDirectory = GetParam();
                        break;

                    case 'c':
                        context.CoreAction = ParseAssemblyAction(GetParam());
                        break;

                    case 'u':
                        context.UserAction = ParseAssemblyAction(GetParam());
                        break;

                    case 'p':
                        AssemblyAction action = ParseAssemblyAction(GetParam());
                        context.Actions [GetParam()] = action;
                        break;

                    case 's':
                        custom_steps.Add(GetParam());
                        break;

                    case 't':
                        context.KeepTypeForwarderOnlyAssemblies = true;
                        break;

                    case 'x':
                        foreach (string file in GetFiles(GetParam()))
                        {
                            p.PrependStep(new ResolveFromXmlStep(new XPathDocument(file)));
                        }
                        resolver = true;
                        break;

                    case 'r':
                    case 'a':
                        var rootVisibility = (token [1] == 'r')
                                                        ? ResolveFromAssemblyStep.RootVisibility.PublicAndFamily
                                                        : ResolveFromAssemblyStep.RootVisibility.Any;
                        foreach (string file in GetFiles(GetParam()))
                        {
                            p.PrependStep(new ResolveFromAssemblyStep(file, rootVisibility));
                        }
                        resolver = true;
                        break;

                    case 'i':
                        foreach (string file in GetFiles(GetParam()))
                        {
                            p.PrependStep(new ResolveFromXApiStep(new XPathDocument(file)));
                        }
                        resolver = true;
                        break;

                    case 'l':
                        assemblies = ParseI18n(GetParam());
                        break;

                    case 'm':
                        context.SetParameter(GetParam(), GetParam());
                        break;

                    case 'b':
                        context.LinkSymbols = bool.Parse(GetParam());
                        break;

                    case 'g':
                        if (!bool.Parse(GetParam()))
                        {
                            p.RemoveStep(typeof(RegenerateGuidStep));
                        }
                        break;

                    case 'z':
                        if (!bool.Parse(GetParam()))
                        {
                            p.RemoveStep(typeof(BlacklistStep));
                        }
                        break;

                    case 'v':
                        context.KeepMembersForDebuggerAttributes = bool.Parse(GetParam());
                        break;

                    default:
                        Usage("Unknown option: `" + token [1] + "'");
                        break;
                    }
                }

                if (!resolver)
                {
                    Usage("No resolver was created (use -x, -a or -i)");
                }

                if (dumpDependencies)
                {
                    context.Tracer.Start();
                }

                foreach (string custom_step in custom_steps)
                {
                    AddCustomStep(p, custom_step);
                }

                p.AddStepAfter(typeof(LoadReferencesStep), new LoadI18nAssemblies(assemblies));

                if (_needAddBypassNGenStep)
                {
                    p.AddStepAfter(typeof(SweepStep), new AddBypassNGenStep());
                }

                p.Process(context);
            }
        }
Beispiel #8
0
		static void AddCustomStep (Pipeline pipeline, string arg)
		{
			int pos = arg.IndexOf (":");
			if (pos == -1) {
				pipeline.AppendStep (ResolveStep (arg));
				return;
			}

			string [] parts = arg.Split (':');
			if (parts.Length != 2)
				Usage ("Step is specified as TYPE:STEP");

			if (parts [0].IndexOf (",") > -1)
				pipeline.AddStepBefore (FindStep (pipeline, parts [1]), ResolveStep (parts [0]));
			else if (parts [1].IndexOf (",") > -1)
				pipeline.AddStepAfter (FindStep (pipeline, parts [0]), ResolveStep (parts [1]));
			else
				Usage ("No comma separator in TYPE or STEP");
		}