Beispiel #1
0
        public Config(string[] args)
        {
            _syntaxResult = ArgumentSyntax.Parse(args, syntax =>
            {
                syntax.DefineOption("b|base", ref _baseExe, "The base compiler exe.");
                syntax.DefineOption("d|diff", ref _diffExe, "The diff compiler exe.");
                syntax.DefineOption("o|output", ref _rootPath, "The output path.");
                syntax.DefineOption("t|tag", ref _tag, "Name of root in output directory.  Allows for many sets of output.");
                syntax.DefineOption("f|file", ref _fileName, "Name of file to take list of assemblies from. Both a file and assembly list can be used.");
                syntax.DefineOption("gcinfo", ref _dumpGCInfo, "Add GC info to the disasm output.");
                syntax.DefineOption("v|verbose", ref _verbose, "Enable verbose output.");
                var waitArg = syntax.DefineOption("w|wait", ref _wait, "Wait for debugger to attach.");
                waitArg.IsHidden = true;

                syntax.DefineOption("r|recursive", ref _recursive, "Scan directories recursively.");
                syntax.DefineOptionList("p|platform", ref _platformPaths, "Path to platform assemblies");
                var methodsArg = syntax.DefineOptionList("m|methods", ref _methods,
                    "List of methods to disasm.");
                methodsArg.IsHidden = true;

                // Warning!! - Parameters must occur after options to preserve parsing semantics.

                syntax.DefineParameterList("assembly", ref _assemblyList, "The list of assemblies or directories to scan for assemblies.");
            });

            // Run validation code on parsed input to ensure we have a sensible scenario.

            validate();
        }
Beispiel #2
0
 protected override void ParseOptions(ArgumentSyntax syntax)
 {
     syntax.DefineOption("u|update-packages", ref _configOptions.UpdatePackages, "Check the NuGet server for more recent versions of each package and update them if applicable.");
     syntax.DefineOption("use-local-packages", ref _configOptions.UseLocalPackages, "Toggles the use of a local NuGet packages folder.");
     syntax.DefineOption("use-global-sources", ref _configOptions.UseGlobalSources, "Toggles the use of the global NuGet sources (default is false).");
     syntax.DefineOption("packages-path", ref _configOptions.PackagesPath, DirectoryPath.FromString, "The packages path to use (only if use-local is true).");
 }
        public static CommonCompilerOptions Parse(ArgumentSyntax syntax)
        {
            IReadOnlyList<string> defines = null;
            string languageVersion = null;
            string platform = null;
            bool? allowUnsafe = null;
            bool? warningsAsErrors = null;
            bool? optimize = null;
            string keyFile = null;
            bool? delaySign = null;
            bool? strongName = null;
            bool? emitEntryPoint = null;

            Func<string, bool?> nullableBoolConverter = v => bool.Parse(v);

            syntax.DefineOptionList(s_definesTemplate.LongName, ref defines, "Preprocessor definitions");

            syntax.DefineOption(s_languageVersionTemplate.LongName, ref languageVersion,
                    "The version of the language used to compile");

            syntax.DefineOption(s_platformTemplate.LongName, ref platform,
                    "The target platform");

            syntax.DefineOption(s_allowUnsafeTemplate.LongName, ref allowUnsafe,
                    nullableBoolConverter, "Allow unsafe code");

            syntax.DefineOption(s_warningsAsErrorsTemplate.LongName, ref warningsAsErrors,
                    nullableBoolConverter, "Turn all warnings into errors");

            syntax.DefineOption(s_optimizeTemplate.LongName, ref optimize,
                    nullableBoolConverter, "Enable compiler optimizations");

            syntax.DefineOption(s_keyFileTemplate.LongName, ref keyFile,
                    "Path to file containing the key to strong-name sign the output assembly");

            syntax.DefineOption(s_delaySignTemplate.LongName, ref delaySign,
                    nullableBoolConverter, "Delay-sign the output assembly");

            syntax.DefineOption(s_ossSignTemplate.LongName, ref strongName,
                    nullableBoolConverter, "OSS sign the output assembly");

            syntax.DefineOption(s_emitEntryPointTemplate.LongName, ref emitEntryPoint,
                    nullableBoolConverter, "Output an executable console program");

            return new CommonCompilerOptions
            {
                Defines = defines,
                LanguageVersion = languageVersion,
                Platform = platform,
                AllowUnsafe = allowUnsafe,
                WarningsAsErrors = warningsAsErrors,
                Optimize = optimize,
                KeyFile = keyFile,
                DelaySign = delaySign,
                UseOssSigning = strongName,
                EmitEntryPoint = emitEntryPoint
            };
        }
Beispiel #4
0
 private bool DefineSquirrelOption(ArgumentSyntax syntax, string name, CommandEnum command, bool hasVersion)
 {
     Argument<string> option = syntax.DefineOption(name, ref SquirrelVersion, hasVersion, string.Empty);
     option.IsHidden = true;
     if (option.IsSpecified)
     {
         Command = command;
         return true;
     }
     return false;
 }
Beispiel #5
0
        public void Parse(ArgumentSyntax syntax, Preprocessor preprocessor)
        {
            // Global options
            if(GlobalArguments)
            {
                syntax.DefineOption("v|verbose", ref _verbose, "Turns on verbose output showing additional trace message useful for debugging.");
                syntax.DefineOption("attach", ref _attach, "Pause execution at the start of the program until a debugger is attached.");
            }

            // Command options
            ParseOptions(syntax);

            // Directives
            if (SupportedDirectives != null)
            {
                foreach (IDirective directive in preprocessor.Directives
                    .Where(x => SupportedDirectives.Contains(x.Name, StringComparer.OrdinalIgnoreCase)))
                {
                    // Get the option name and help text
                    string optionName = (string.IsNullOrEmpty(directive.ShortName) ? string.Empty : directive.ShortName + "|") + directive.Name;
                    string optionHelp = $"{directive.Description}{(string.IsNullOrEmpty(directive.GetHelpText()) ? string.Empty : " See below for syntax details.")}";

                    // Single or multiple?
                    if (directive.SupportsMultiple)
                    {
                        // Multiple
                        IReadOnlyList<string> directiveValues = null;
                        syntax.DefineOptionList(optionName, ref directiveValues, optionHelp);
                        if (directiveValues != null)
                        {
                            foreach (string directiveValue in directiveValues)
                            {
                                preprocessor.AddValue(new DirectiveValue(directive.Name, directiveValue));
                            }
                        }
                    }
                    else
                    {
                        // Single
                        string directiveValue = null;
                        syntax.DefineOption(optionName, ref directiveValue, optionHelp);
                        if (directiveValue != null)
                        {
                            preprocessor.AddValue(new DirectiveValue(directive.Name, directiveValue));
                        }
                    }
                }
            }

            // Command parameters
            ParseParameters(syntax);
        }
        public static string Generate(ArgumentSyntax argumentSyntax, int maxWidth)
        {
            var forCommandList = argumentSyntax.ActiveCommand == null &&
                                 argumentSyntax.Commands.Any();

            var page = forCommandList
                ? GetCommandListHelp(argumentSyntax)
                : GetCommandHelp(argumentSyntax, argumentSyntax.ActiveCommand);

            var sb = new StringBuilder();
            sb.WriteHelpPage(page, maxWidth);
            return sb.ToString();
        }
Beispiel #7
0
        protected override void ParseOptions(ArgumentSyntax syntax)
        {
            syntax.DefineOption("w|watch", ref _watch, "Watches the input folder for any changes.");
            _preview = syntax.DefineOption("p|preview", ref _previewPort, false, "Start the preview web server on the specified port (default is " + _previewPort + ").").IsSpecified;
            if (syntax.DefineOption("force-ext", ref _previewForceExtension, "Force the use of extensions in the preview web server (by default, extensionless URLs may be used).").IsSpecified && !_preview)
            {
                syntax.ReportError("force-ext can only be specified if the preview server is running.");
            }
            if (syntax.DefineOption("preview-root", ref _previewRoot, DirectoryPath.FromString, "The path to the root of the preview server, if not the output folder.").IsSpecified && !_preview)
            {
                syntax.ReportError("preview-root can only be specified if the preview server is running.");
            }
            syntax.DefineOptionList("i|input", ref _configOptions.InputPaths, DirectoryPath.FromString, "The path(s) of input files, can be absolute or relative to the current folder.");
            syntax.DefineOption("o|output", ref _configOptions.OutputPath, DirectoryPath.FromString, "The path to output files, can be absolute or relative to the current folder.");
            syntax.DefineOption("c|config", ref _configOptions.ConfigFilePath, FilePath.FromString, "Configuration file (by default, config.wyam is used).");
            syntax.DefineOption("u|update-packages", ref _configOptions.UpdatePackages, "Check the NuGet server for more recent versions of each package and update them if applicable.");
            syntax.DefineOption("use-local-packages", ref _configOptions.UseLocalPackages, "Toggles the use of a local NuGet packages folder.");
            syntax.DefineOption("use-global-sources", ref _configOptions.UseGlobalSources, "Toggles the use of the global NuGet sources (default is false).");
            syntax.DefineOption("packages-path", ref _configOptions.PackagesPath, DirectoryPath.FromString, "The packages path to use (only if use-local is true).");
            syntax.DefineOption("output-script", ref _configOptions.OutputScript, "Outputs the config script after it's been processed for further debugging.");
            syntax.DefineOption("verify-config", ref _verifyConfig, false, "Compile the configuration but do not execute.");
            syntax.DefineOption("noclean", ref _configOptions.NoClean, "Prevents cleaning of the output path on each execution.");
            syntax.DefineOption("nocache", ref _configOptions.NoCache, "Prevents caching information during execution (less memory usage but slower execution).");

            _logFilePath = $"wyam-{DateTime.Now:yyyyMMddHHmmssfff}.txt";
            if (!syntax.DefineOption("l|log", ref _logFilePath, FilePath.FromString, false, "Log all trace messages to the specified log file (by default, wyam-[datetime].txt).").IsSpecified)
            {
                _logFilePath = null;
            }

            // Metadata
            IReadOnlyList<string> globalMetadata = null;
            if (syntax.DefineOptionList("g|global", ref globalMetadata, "Specifies global metadata as a sequence of key=value pairs.").IsSpecified)
            {
                _configOptions.GlobalMetadata = MetadataParser.Parse(globalMetadata);
            }
            IReadOnlyList<string> initialMetadata = null;
            if (syntax.DefineOptionList("initial", ref initialMetadata, "Specifies initial document metadata as a sequence of key=value pairs.").IsSpecified)
            {
                _configOptions.InitialMetadata = MetadataParser.Parse(initialMetadata);
            }
        }
Beispiel #8
0
        public static AssemblyInfoOptions Parse(ArgumentSyntax syntax)
        {
            string version = null;
            string informationalVersion = null;
            string fileVersion = null;
            string title = null;
            string description = null;
            string copyright = null;
            string culture = null;
            string neutralCulture = null;
            string targetFramework = null;

            syntax.DefineOption(AssemblyVersionOptionName, ref version, UnescapeNewlines, "Assembly version");

            syntax.DefineOption(TitleOptionName, ref title, UnescapeNewlines, "Assembly title");

            syntax.DefineOption(DescriptionOptionName, ref description, UnescapeNewlines, "Assembly description");

            syntax.DefineOption(CopyrightOptionName, ref copyright, UnescapeNewlines, "Assembly copyright");

            syntax.DefineOption(NeutralCultureOptionName, ref neutralCulture, UnescapeNewlines, "Assembly neutral culture");

            syntax.DefineOption(CultureOptionName, ref culture, UnescapeNewlines, "Assembly culture");

            syntax.DefineOption(InformationalVersionOptionName, ref informationalVersion, UnescapeNewlines, "Assembly informational version");

            syntax.DefineOption(AssemblyFileVersionOptionName, ref fileVersion, UnescapeNewlines, "Assembly title");

            syntax.DefineOption(TargetFrameworkOptionName, ref targetFramework, UnescapeNewlines, "Assembly target framework");

            return new AssemblyInfoOptions()
            {
                AssemblyFileVersion = fileVersion,
                AssemblyVersion = version,
                Copyright = copyright,
                NeutralLanguage = neutralCulture,
                Description = description,
                InformationalVersion = informationalVersion,
                Title = title,
                TargetFramework = targetFramework
            };
        }
Beispiel #9
0
 protected override void ParseParameters(ArgumentSyntax syntax)
 {
     // Root
     if (syntax.DefineParameter("root", ref _configOptions.RootPath, DirectoryPath.FromString, "The folder (or config file) to use.").IsSpecified)
     {
         // If a root folder was defined, but it actually points to a file, set the root folder to the directory
         // and use the specified file as the config file (if a config file was already specified, it's an error)
         FilePath rootDirectoryPathAsConfigFile = new DirectoryPath(Environment.CurrentDirectory).CombineFile(_configOptions.RootPath.FullPath);
         if (File.Exists(rootDirectoryPathAsConfigFile.FullPath))
         {
             // The specified root actually points to a file...
             if (_configOptions.ConfigFilePath != null)
             {
                 syntax.ReportError("A config file was both explicitly specified and specified in the root folder.");
             }
             else
             {
                 _configOptions.ConfigFilePath = rootDirectoryPathAsConfigFile.FileName;
                 _configOptions.RootPath = rootDirectoryPathAsConfigFile.Directory;
             }
         }
     }
 }
        private object GetDetails(ArgumentSyntax argument)
        {
            var identifier = argument.ChildNodes().OfType<IdentifierNameSyntax>().FirstOrDefault();
            if (identifier == null)
            {
                // this is really quite crap
                var child = argument.ChildNodes().OfType<IdentifierNameSyntax>().FirstOrDefault() ??
                                   (SyntaxNode)argument.ChildNodes().OfType<InvocationExpressionSyntax>().FirstOrDefault();

                if (child != null)
                {
                    identifier = child.ChildNodes().OfType<IdentifierNameSyntax>().First();
                }
            }

            if (identifier != null)
            {
                return identifier.Identifier.ValueText;
            }

            var lamda = argument.ChildNodes().OfType<SimpleLambdaExpressionSyntax>().FirstOrDefault();

            return lamda;
        }
Beispiel #11
0
 protected override void ParseOptions(ArgumentSyntax syntax)
 {
     syntax.DefineOption("directives", ref _directives, "Displays help for all preprocessor directives.");
 }
Beispiel #12
0
 public static ArgumentListSyntax ArgumentList(ArgumentSyntax argument)
 {
     return(SyntaxFactory.ArgumentList(SingletonSeparatedList(argument)));
 }
        public async Task <List <CompilationErrorDetails> > GetCompilationErrorDetails(Document document, SyntaxNode bodyOpt, CancellationToken cancellationToken)
        {
            try
            {
                var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

                var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                ImmutableArray <Diagnostic> diagnostics;

                // If we have the SyntaxNode bodyOpt,
                // then we can use its fullSpan property to process a subset of the document.
                if (bodyOpt == null)
                {
                    diagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken);
                }
                else
                {
                    diagnostics = semanticModel.GetDiagnostics(bodyOpt.FullSpan, cancellationToken: cancellationToken);
                }

                if (diagnostics.Length == 0)
                {
                    return(null);
                }

                var syntaxFacts = document.Project.LanguageServices.GetService <ISyntaxFactsService>();

                List <CompilationErrorDetails> ret = new List <CompilationErrorDetails>();

                foreach (var diagnostic in diagnostics)
                {
                    if (diagnostic.Severity != DiagnosticSeverity.Error || diagnostic.IsWarningAsError)
                    {
                        continue;
                    }

                    if (!IsTrackedCompilationError(diagnostic))
                    {
                        continue;
                    }

                    string   errorDetailsFilename                     = diagnostic.Location.GetLineSpan().Path;
                    string   errorDetailsUnresolvedMemberName         = null;
                    string   errorDetailsMethodName                   = null;
                    string   errorDetailsLeftExpressionDocId          = null;
                    string[] errorDetailsGenericArguments             = null;
                    string[] errorDetailsArgumentTypes                = null;
                    string[] errorDetailsLeftExpressionBaseTypeDocIds = null;

                    TextSpan span = diagnostic.Location.SourceSpan;

                    var node = root.FindNode(span);
                    if (node == null)
                    {
                        continue;
                    }

                    // If the expression binds, this could just be an extension method so we will continue and not
                    // log, as it's not actually an error.
                    if (ExpressionBinds(node, semanticModel, cancellationToken, checkForExtensionMethods: true))
                    {
                        continue;
                    }

                    // This is used to get unresolved member names.  It will not alway find a member name, but has been tested to do so
                    // in the cases where the error code needs it.
                    string name;
                    int    arity;
                    syntaxFacts.GetNameAndArityOfSimpleName(node, out name, out arity);
                    errorDetailsUnresolvedMemberName = name;

                    // Here we reuse the unresolved member name field for attribute classes that can't be resolved as
                    // actually being attributes.  Could factor this into a separate field for readability later.
                    AttributeSyntax attributeSyntax = node as AttributeSyntax;
                    if (attributeSyntax != null)
                    {
                        errorDetailsUnresolvedMemberName = semanticModel.GetTypeInfo(attributeSyntax, cancellationToken).Type.GetDocumentationCommentId();
                    }

                    GenericNameSyntax genericNameSyntax = node as GenericNameSyntax;
                    if (genericNameSyntax != null)
                    {
                        List <string> genericArgumentDocIds = new List <string>();
                        foreach (var genericArgument in genericNameSyntax.TypeArgumentList.Arguments)
                        {
                            var semanticInfo = semanticModel.GetTypeInfo(genericArgument, cancellationToken);
                            if (semanticInfo.Type != null)
                            {
                                genericArgumentDocIds.Add(GetDocId(semanticInfo.Type));
                            }
                            else
                            {
                                genericArgumentDocIds.Add(UnknownGenericArgumentTypeName);
                            }
                        }

                        errorDetailsGenericArguments = genericArgumentDocIds.ToArray();
                    }

                    ArgumentSyntax argumentSyntax = node as ArgumentSyntax;
                    if (argumentSyntax != null)
                    {
                        var argumentListSyntax   = argumentSyntax.GetAncestor <BaseArgumentListSyntax>().Arguments;
                        var invocationExpression = argumentSyntax.GetAncestor <InvocationExpressionSyntax>();

                        errorDetailsArgumentTypes = (from argument in argumentListSyntax
                                                     select GetDocId(semanticModel.GetTypeInfo(argument.Expression, cancellationToken).Type)).ToArray();

                        if (invocationExpression != null)
                        {
                            var memberAccessExpression = invocationExpression.Expression as ExpressionSyntax;
                            var symbolInfo             = semanticModel.GetSymbolInfo(memberAccessExpression, cancellationToken);

                            if (symbolInfo.CandidateSymbols.Length > 0)
                            {
                                // In this case, there is argument mismatch of some sort.
                                // Here we are getting the method name of any candidate symbols, then
                                // getting the docid of the type where the argument mismatch happened and storing this in LeftExpressionDocId.

                                errorDetailsMethodName          = symbolInfo.CandidateSymbols.First().Name;
                                errorDetailsLeftExpressionDocId = GetDocId(symbolInfo.CandidateSymbols.First().ContainingType);
                            }
                        }
                    }

                    if (syntaxFacts.IsSimpleMemberAccessExpression(node.Parent))
                    {
                        var expression = node.Parent;

                        var leftExpression = syntaxFacts.GetExpressionOfMemberAccessExpression(expression);
                        if (leftExpression != null)
                        {
                            var semanticInfo = semanticModel.GetTypeInfo(leftExpression, cancellationToken);

                            var leftExpressionType = semanticInfo.Type;
                            if (leftExpressionType != null)
                            {
                                errorDetailsLeftExpressionDocId = GetDocId(leftExpressionType);

                                IEnumerable <string> baseTypeDocids = leftExpressionType.GetBaseTypes().Select(t => GetDocId(t));
                                errorDetailsLeftExpressionBaseTypeDocIds = baseTypeDocids.ToArray();
                            }
                        }
                    }

                    ret.Add(new CompilationErrorDetails(diagnostic.Id, errorDetailsFilename, errorDetailsMethodName, errorDetailsUnresolvedMemberName,
                                                        errorDetailsLeftExpressionDocId, errorDetailsLeftExpressionBaseTypeDocIds, errorDetailsGenericArguments, errorDetailsArgumentTypes));
                }

                return(ret);
            }
            catch (Exception e)
            {
                List <CompilationErrorDetails> ret = new List <CompilationErrorDetails>();
                ret.Add(new CompilationErrorDetails("EXCEPTION", e.Message, e.StackTrace, null, null, null, null, null));
                return(ret);
            }
        }
 public static SyntaxToken RefKindKeyword(this ArgumentSyntax syntax)
 {
     return(RefKindKeywordAccessor(syntax));
 }
Beispiel #15
0
 internal static bool TryGetRegisteredName(ArgumentSyntax callback, SemanticModel semanticModel, CancellationToken cancellationToken, out string registeredName)
 {
     return(Callback.TryGetRegisteredName(callback, semanticModel, cancellationToken, out registeredName));
 }
Beispiel #16
0
 protected Symbol GetSymbol(ArgumentSyntax  syntax, Dictionary<SyntaxTree, SemanticModel> models)
 {
     return syntax == null ? null : GetModel(syntax, models).GetSymbolInfo(syntax.Expression).Symbol;
 }
Beispiel #17
0
        private int Run(string[] args)
        {
            InitializeDefaultOptions();

            ArgumentSyntax syntax = ParseCommandLine(args);

            if (_help)
            {
                Help(syntax.GetHelpText());
                return(1);
            }

            if (_outputFilePath == null)
            {
                throw new CommandLineException("Output filename must be specified (/out <file>)");
            }

            //
            // Set target Architecture and OS
            //
            if (_targetArchitectureStr != null)
            {
                if (_targetArchitectureStr.Equals("x86", StringComparison.OrdinalIgnoreCase))
                {
                    _targetArchitecture = TargetArchitecture.X86;
                }
                else if (_targetArchitectureStr.Equals("x64", StringComparison.OrdinalIgnoreCase))
                {
                    _targetArchitecture = TargetArchitecture.X64;
                }
                else if (_targetArchitectureStr.Equals("arm", StringComparison.OrdinalIgnoreCase))
                {
                    _targetArchitecture = TargetArchitecture.ARM;
                }
                else if (_targetArchitectureStr.Equals("armel", StringComparison.OrdinalIgnoreCase))
                {
                    _targetArchitecture = TargetArchitecture.ARM;
                }
                else if (_targetArchitectureStr.Equals("arm64", StringComparison.OrdinalIgnoreCase))
                {
                    _targetArchitecture = TargetArchitecture.ARM64;
                }
                else
                {
                    throw new CommandLineException("Target architecture is not supported");
                }
            }
            if (_targetOSStr != null)
            {
                if (_targetOSStr.Equals("windows", StringComparison.OrdinalIgnoreCase))
                {
                    _targetOS = TargetOS.Windows;
                }
                else if (_targetOSStr.Equals("linux", StringComparison.OrdinalIgnoreCase))
                {
                    _targetOS = TargetOS.Linux;
                }
                else if (_targetOSStr.Equals("osx", StringComparison.OrdinalIgnoreCase))
                {
                    _targetOS = TargetOS.OSX;
                }
                else
                {
                    throw new CommandLineException("Target OS is not supported");
                }
            }

            //
            // Initialize type system context
            //

            SharedGenericsMode genericsMode = SharedGenericsMode.CanonicalReferenceTypes;

            var targetDetails = new TargetDetails(_targetArchitecture, _targetOS, TargetAbi.CoreRT, SimdVectorLength.None);
            CompilerTypeSystemContext typeSystemContext = new ReadyToRunCompilerContext(targetDetails, genericsMode);

            //
            // TODO: To support our pre-compiled test tree, allow input files that aren't managed assemblies since
            // some tests contain a mixture of both managed and native binaries.
            //
            // See: https://github.com/dotnet/corert/issues/2785
            //
            // When we undo this this hack, replace this foreach with
            //  typeSystemContext.InputFilePaths = _inputFilePaths;
            //
            Dictionary <string, string> inputFilePaths = new Dictionary <string, string>();

            foreach (var inputFile in _inputFilePaths)
            {
                try
                {
                    var module = typeSystemContext.GetModuleFromPath(inputFile.Value);
                    inputFilePaths.Add(inputFile.Key, inputFile.Value);
                }
                catch (TypeSystemException.BadImageFormatException)
                {
                    // Keep calm and carry on.
                }
            }

            typeSystemContext.InputFilePaths     = inputFilePaths;
            typeSystemContext.ReferenceFilePaths = _referenceFilePaths;

            typeSystemContext.SetSystemModule(typeSystemContext.GetModuleForSimpleName(_systemModuleName));

            if (typeSystemContext.InputFilePaths.Count == 0)
            {
                throw new CommandLineException("No input files specified");
            }

            //
            // Initialize compilation group and compilation roots
            //

            // Single method mode?
            MethodDesc singleMethod = CheckAndParseSingleMethodModeArguments(typeSystemContext);

            var logger = new Logger(Console.Out, _isVerbose);
            ProfileDataManager profileDataManager = new ProfileDataManager(logger);

            CompilationModuleGroup          compilationGroup;
            List <ICompilationRootProvider> compilationRoots = new List <ICompilationRootProvider>();

            if (singleMethod != null)
            {
                // Compiling just a single method
                compilationGroup = new SingleMethodCompilationModuleGroup(singleMethod);
                compilationRoots.Add(new SingleMethodRootProvider(singleMethod));
            }
            else
            {
                // Either single file, or multifile library, or multifile consumption.
                EcmaModule entrypointModule = null;
                foreach (var inputFile in typeSystemContext.InputFilePaths)
                {
                    EcmaModule module = typeSystemContext.GetModuleFromPath(inputFile.Value);

                    if (module.PEReader.PEHeaders.IsExe)
                    {
                        if (entrypointModule != null)
                        {
                            throw new Exception("Multiple EXE modules");
                        }
                        entrypointModule = module;
                    }
                }

                List <EcmaModule> inputModules = new List <EcmaModule>();

                foreach (var inputFile in typeSystemContext.InputFilePaths)
                {
                    EcmaModule module = typeSystemContext.GetModuleFromPath(inputFile.Value);
                    compilationRoots.Add(new ReadyToRunRootProvider(module, profileDataManager));
                    inputModules.Add(module);

                    if (!_isInputVersionBubble)
                    {
                        break;
                    }
                }


                List <ModuleDesc> versionBubbleModules = new List <ModuleDesc>();
                if (_isInputVersionBubble)
                {
                    // In large version bubble mode add reference paths to the compilation group
                    foreach (string referenceFile in _referenceFilePaths.Values)
                    {
                        try
                        {
                            // Currently SimpleTest.targets has no easy way to filter out non-managed assemblies
                            // from the reference list.
                            EcmaModule module = typeSystemContext.GetModuleFromPath(referenceFile);
                            versionBubbleModules.Add(module);
                        }
                        catch (TypeSystemException.BadImageFormatException ex)
                        {
                            Console.WriteLine("Warning: cannot open reference assembly '{0}': {1}", referenceFile, ex.Message);
                        }
                    }
                }

                compilationGroup = new ReadyToRunSingleAssemblyCompilationModuleGroup(
                    typeSystemContext, inputModules, versionBubbleModules, _includeGenericsFromVersionBubble);
            }

            //
            // Compile
            //

            string inputFilePath = "";

            foreach (var input in typeSystemContext.InputFilePaths)
            {
                inputFilePath = input.Value;
                break;
            }
            CompilationBuilder builder = new ReadyToRunCodegenCompilationBuilder(typeSystemContext, compilationGroup, inputFilePath, _tuning);

            string compilationUnitPrefix = "";

            builder.UseCompilationUnitPrefix(compilationUnitPrefix);

            ILProvider ilProvider = new ReadyToRunILProvider();


            DependencyTrackingLevel trackingLevel = _dgmlLogFileName == null ?
                                                    DependencyTrackingLevel.None : (_generateFullDgmlLog ? DependencyTrackingLevel.All : DependencyTrackingLevel.First);

            builder
            .UseILProvider(ilProvider)
            .UseBackendOptions(_codegenOptions)
            .UseLogger(logger)
            .UseDependencyTracking(trackingLevel)
            .UseCompilationRoots(compilationRoots)
            .UseOptimizationMode(_optimizationMode);

            ICompilation compilation = builder.ToCompilation();

            compilation.Compile(_outputFilePath);

            return(0);
        }
Beispiel #18
0
        protected override void ParseOptions(ArgumentSyntax syntax)
        {
            syntax.DefineOption("w|watch", ref _watch, "Watches the input folder for any changes.");
            _preview = syntax.DefineOption("p|preview", ref _previewPort, false, "Start the preview web server on the specified port (default is " + _previewPort + ").").IsSpecified;
            if (syntax.DefineOption("force-ext", ref _previewForceExtension, "Force the use of extensions in the preview web server (by default, extensionless URLs may be used).").IsSpecified&& !_preview)
            {
                syntax.ReportError("force-ext can only be specified if the preview server is running.");
            }
            if (syntax.DefineOption("virtual-dir", ref _previewVirtualDirectory, DirectoryPathFromArg, "Serve files in the preview web server under the specified virtual directory.").IsSpecified&& !_preview)
            {
                syntax.ReportError("virtual-dir can only be specified if the preview server is running.");
            }
            if (syntax.DefineOption("preview-root", ref _previewRoot, DirectoryPathFromArg, "The path to the root of the preview server, if not the output folder.").IsSpecified&& !_preview)
            {
                syntax.ReportError("preview-root can only be specified if the preview server is running.");
            }
            if (syntax.DefineOption("noreload", ref _noReload, "Turns off LiveReload support in the preview server.").IsSpecified&& (!_preview || !_watch))
            {
                syntax.ReportError("noreload can only be specified if both the preview server is running and watching is enabled.");
            }
            syntax.DefineOptionList("i|input", ref _configOptions.InputPaths, DirectoryPathFromArg, "The path(s) of input files, can be absolute or relative to the current folder.");
            syntax.DefineOption("o|output", ref _configOptions.OutputPath, DirectoryPathFromArg, "The path to output files, can be absolute or relative to the current folder.");
            syntax.DefineOption("c|config", ref _configOptions.ConfigFilePath, FilePath.FromString, "Configuration file (by default, config.wyam is used).");
            syntax.DefineOption("u|update-packages", ref _configOptions.UpdatePackages, "Check the NuGet server for more recent versions of each package and update them if applicable.");
            syntax.DefineOption("use-local-packages", ref _configOptions.UseLocalPackages, "Toggles the use of a local NuGet packages folder.");
            syntax.DefineOption("use-global-sources", ref _configOptions.UseGlobalSources, "Toggles the use of the global NuGet sources (default is false).");
            syntax.DefineOption("packages-path", ref _configOptions.PackagesPath, DirectoryPathFromArg, "The packages path to use (only if use-local is true).");
            syntax.DefineOption("output-script", ref _configOptions.OutputScript, "Outputs the config script after it's been processed for further debugging.");
            syntax.DefineOption("verify-config", ref _verifyConfig, false, "Compile the configuration but do not execute.");
            syntax.DefineOption("noclean", ref _configOptions.NoClean, "Prevents cleaning of the output path on each execution.");
            syntax.DefineOption("nocache", ref _configOptions.NoCache, "Prevents caching information during execution (less memory usage but slower execution).");

            _logFilePath = $"wyam-{DateTime.Now:yyyyMMddHHmmssfff}.txt";
            if (!syntax.DefineOption("l|log", ref _logFilePath, FilePath.FromString, false, "Log all trace messages to the specified log file (by default, wyam-[datetime].txt).").IsSpecified)
            {
                _logFilePath = null;
            }

            // Metadata
            // TODO: Remove this dictionary and initial/global options
            Dictionary <string, object> settingsDictionary = new Dictionary <string, object>();
            IReadOnlyList <string>      globalMetadata     = null;

            if (syntax.DefineOptionList("g|global", ref globalMetadata, "Deprecated, do not use.").IsSpecified)
            {
                Trace.Warning("-g/--global is deprecated and will be removed in a future version. Please use -s/--setting instead.");
                AddSettings(settingsDictionary, globalMetadata);
            }
            IReadOnlyList <string> initialMetadata = null;

            if (syntax.DefineOptionList("initial", ref initialMetadata, "Deprecated, do not use.").IsSpecified)
            {
                Trace.Warning("--initial is deprecated and will be removed in a future version. Please use -s/--setting instead.");
                AddSettings(settingsDictionary, initialMetadata);
            }
            IReadOnlyList <string> settings = null;

            if (syntax.DefineOptionList("s|setting", ref settings, "Specifies a setting as a key=value pair. Use the syntax [x,y] to specify an array value.").IsSpecified)
            {
                // _configOptions.Settings = MetadataParser.Parse(settings); TODO: Use this when AddSettings() is removed

                AddSettings(settingsDictionary, settings);
            }
            if (settingsDictionary.Count > 0)
            {
                _configOptions.Settings = settingsDictionary;
            }
        }
Beispiel #19
0
        public static void Run(string[] args)
        {
            IReadOnlyList <string> input             = Array.Empty <string>();
            IReadOnlyList <string> resources         = null;
            IReadOnlyList <string> additionalFormats = null;
            string output   = null;
            string manifest = null;

            // Preview options
            bool   autosize      = false;
            double imgWidth      = 640;
            double imgHeight     = 480;
            string configuration = null;

            bool recursive = false;
            bool silent    = false;
            bool verbose   = false;

            var cliOptions = ArgumentSyntax.Parse(args, options =>
            {
                options.ApplicationName = "cdcli component";

                options.DefineOption("o|output", ref output,
                                     "Output file (the format will be inferred from the extension). Cannot be used for directory inputs or in combination with specific output format options.");
                var manifestOption = options.DefineOption("manifest", ref manifest, false, "Writes a manifest file listing the compiled components.");
                if (manifestOption.IsSpecified && manifest == null)
                {
                    manifest = "manifest.xml";
                }
                options.DefineOption("autosize", ref autosize, "Automatically sizes the output image to fit the rendered preview.");
                options.DefineOption("w|width", ref imgWidth, double.Parse, "Width of output images to generate (default=640).");
                options.DefineOption("h|height", ref imgHeight, double.Parse, "Height of output images to generate (default=480).");
                options.DefineOption("r|recursive", ref recursive, "Recursively searches sub-directories of the input directory.");
                options.DefineOption("s|silent", ref silent, "Does not output anything to the console on successful operation.");
                options.DefineOption("v|verbose", ref verbose, "Outputs extra information to the console.");
                options.DefineOption("c|configuration", ref configuration, "Name of component configuration to use.");
                options.DefineOptionList("resources", ref resources, "Resources to use in generating the output. Either a directory, or a space-separated list of [key] [filename] pairs.");
                options.DefineOptionList("format", ref additionalFormats, "Output formats to write.");
                options.DefineParameterList("input", ref input, "Components to compile.");
            });

            var loggerFactory = new LoggerFactory();

            if (!silent)
            {
                loggerFactory.AddProvider(new BasicConsoleLogger(LogLevel.Information));
            }

            var logger = loggerFactory.CreateLogger(typeof(ComponentApp));

            if (!input.Any())
            {
                logger.LogError("At least one input file must be specified.");
                Environment.Exit(1);
            }

            var  generators        = new Dictionary <IOutputGenerator, string>();
            var  outputGenerators  = new OutputGeneratorRepository();
            bool outputIsDirectory = Directory.Exists(output);

            if (output != null && !outputIsDirectory)
            {
                if (outputGenerators.TryGetGeneratorByFileExtension(Path.GetExtension(output), out var generator))
                {
                    // Use the generator implied by the file extension
                    generators.Add(generator, output);
                }
                else if (additionalFormats?.Any() != true)
                {
                    logger.LogError("Unable to infer format from output file extension." + Environment.NewLine +
                                    "Specify a known file extension or specify explicitly using --format");
                    Environment.Exit(1);
                }
                else
                {
                    logger.LogInformation("Unable to infer format from output file extension. Using formats only.");
                }
            }

            if (additionalFormats?.Any() == true)
            {
                foreach (var format in additionalFormats)
                {
                    if (outputGenerators.TryGetGeneratorByFormat(format, out var generator))
                    {
                        generators.Add(generator, outputIsDirectory ? output : null);
                    }
                    else
                    {
                        logger.LogError($"Unknown format: {format}");
                        Environment.Exit(1);
                    }
                }
            }

            var previewOptions = new PreviewGenerationOptions
            {
                Center        = true,
                Crop          = autosize,
                Width         = imgWidth,
                Height        = imgHeight,
                Configuration = configuration,
            };

            var resourceProvider = ResourceProviderFactory.Create(loggerFactory.CreateLogger(typeof(ResourceProviderFactory)), resources);
            var compileRunner    = new CompileRunner(loggerFactory.CreateLogger <CompileRunner>(), resourceProvider);
            var results          = new List <CompileResult>();

            foreach (var i in input)
            {
                if (File.Exists(i))
                {
                    var result = compileRunner.CompileOne(i, previewOptions, generators);
                    results.Add(result);
                }
                else if (Directory.Exists(i))
                {
                    foreach (var generator in generators)
                    {
                        if (generator.Value != null && !Directory.Exists(generator.Value))
                        {
                            logger.LogError("Outputs must be directories when the input is a directory.");
                            Environment.Exit(1);
                        }
                    }

                    foreach (var file in Directory.GetFiles(i, "*.xml",
                                                            recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly))
                    {
                        var result = compileRunner.CompileOne(file, previewOptions, generators);
                        results.Add(result);
                    }
                }
                else
                {
                    logger.LogError($"Input is not a valid file or directory: {i}");
                    Environment.Exit(1);
                }
            }

            if (manifest != null)
            {
                using (var manifestFs = File.Open(manifest, FileMode.Create))
                {
                    logger.LogInformation($"Writing manifest to {manifest}");
                    ManifestGenerator.WriteManifest(results, manifestFs);
                }
            }
        }
Beispiel #20
0
        public static int Main(string[] args)
        {
            string referenceItemsResponsePath = null;
            string compileItemsResponsePath   = null;
            string outputPath      = null;
            string genListFilePath = null;
            bool   listAllFiles    = false;
            string processorPath   = null;
            string processorArgs   = null;

            for (int i = 0; i < args.Length; i++)
            {
                args[i] = args[i].Replace("\\\\", "\\");
            }

            ArgumentSyntax.Parse(args, syntax =>
            {
                syntax.DefineOption("ref", ref referenceItemsResponsePath, true, "The semicolon-separated list of references to compile against.");
                syntax.DefineOption("src", ref compileItemsResponsePath, true, "The semicolon-separated list of source files to compile.");
                syntax.DefineOption("out", ref outputPath, true, "The output path for the generated shaders.");
                syntax.DefineOption("genlist", ref genListFilePath, true, "The output file to store the list of generated files.");
                syntax.DefineOption("listall", ref listAllFiles, false, "Forces all generated files to be listed in the list file. By default, only bytecode files will be listed and not the original shader code.");
                syntax.DefineOption("processor", ref processorPath, false, "The path of an assembly containing IShaderSetProcessor types to be used to post-process GeneratedShaderSet objects.");
                syntax.DefineOption("processorargs", ref processorArgs, false, "Custom information passed to IShaderSetProcessor.");
            });

            if (!File.Exists(referenceItemsResponsePath))
            {
                Console.Error.WriteLine("Reference items response file does not exist: " + referenceItemsResponsePath);
                return(-1);
            }
            if (!File.Exists(compileItemsResponsePath))
            {
                Console.Error.WriteLine("Compile items response file does not exist: " + compileItemsResponsePath);
                return(-1);
            }
            if (!Directory.Exists(outputPath))
            {
                try
                {
                    Directory.CreateDirectory(outputPath);
                }
                catch
                {
                    Console.Error.WriteLine("Unable to create the output directory.");
                    return(-1);
                }
            }

            string[] referenceItems = File.ReadAllLines(referenceItemsResponsePath);
            string[] compileItems   = File.ReadAllLines(compileItemsResponsePath);

            List <MetadataReference> references = new List <MetadataReference>();

            foreach (string referencePath in referenceItems)
            {
                if (!File.Exists(referencePath))
                {
                    Console.Error.WriteLine("Error: reference does not exist: " + referencePath);
                    return(1);
                }

                using (FileStream fs = File.OpenRead(referencePath))
                {
                    references.Add(MetadataReference.CreateFromStream(fs, filePath: referencePath));
                }
            }

            List <SyntaxTree> syntaxTrees = new List <SyntaxTree>();

            foreach (string sourcePath in compileItems)
            {
                string fullSourcePath = Path.Combine(Environment.CurrentDirectory, sourcePath);
                if (!File.Exists(fullSourcePath))
                {
                    Console.Error.WriteLine("Error: source file does not exist: " + fullSourcePath);
                    return(1);
                }

                using (FileStream fs = File.OpenRead(fullSourcePath))
                {
                    SourceText text = SourceText.From(fs);
                    syntaxTrees.Add(CSharpSyntaxTree.ParseText(text, path: fullSourcePath));
                }
            }

            Compilation compilation = CSharpCompilation.Create(
                "ShaderGen.App.GenerateShaders",
                syntaxTrees,
                references,
                options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            HlslBackend    hlsl    = new HlslBackend(compilation);
            Glsl330Backend glsl330 = new Glsl330Backend(compilation);
            Glsl450Backend glsl450 = new Glsl450Backend(compilation);

            LanguageBackend[] languages = new LanguageBackend[]
            {
                hlsl,
                glsl330,
                glsl450
            };

            List <IShaderSetProcessor> processors = new List <IShaderSetProcessor>();

            if (processorPath != null)
            {
                try
                {
                    Assembly           assm           = Assembly.LoadFrom(processorPath);
                    IEnumerable <Type> processorTypes = assm.GetTypes().Where(
                        t => t.GetInterface(nameof(ShaderGen) + "." + nameof(IShaderSetProcessor)) != null);
                    foreach (Type type in processorTypes)
                    {
                        IShaderSetProcessor processor = (IShaderSetProcessor)Activator.CreateInstance(type);
                        processor.UserArgs = processorArgs;
                        processors.Add(processor);
                    }
                }
                catch (ReflectionTypeLoadException rtle)
                {
                    string msg = string.Join(Environment.NewLine, rtle.LoaderExceptions.Select(e => e.ToString()));
                    Console.WriteLine("FAIL: " + msg);
                    throw new Exception(msg);
                }
            }

            ShaderGenerator        sg = new ShaderGenerator(compilation, languages, processors.ToArray());
            ShaderGenerationResult shaderGenResult;

            try
            {
                shaderGenResult = sg.GenerateShaders();
            }
            catch (Exception e) when(!Debugger.IsAttached)
            {
                StringBuilder sb = new StringBuilder();

                sb.AppendLine("An error was encountered while generating shader code:");
                sb.AppendLine(e.ToString());
                Console.Error.WriteLine(sb.ToString());
                return(-1);
            }

            Encoding      outputEncoding     = new UTF8Encoding(false);
            List <string> generatedFilePaths = new List <string>();

            foreach (LanguageBackend lang in languages)
            {
                string extension = BackendExtension(lang);
                IReadOnlyList <GeneratedShaderSet> sets = shaderGenResult.GetOutput(lang);
                foreach (GeneratedShaderSet set in sets)
                {
                    string name = set.Name;
                    if (set.VertexShaderCode != null)
                    {
                        string vsOutName = name + "-vertex." + extension;
                        string vsOutPath = Path.Combine(outputPath, vsOutName);
                        File.WriteAllText(vsOutPath, set.VertexShaderCode, outputEncoding);
                        bool succeeded = CompileCode(lang, vsOutPath, set.VertexFunction.Name, true, out string genPath);
                        if (succeeded)
                        {
                            generatedFilePaths.Add(genPath);
                        }
                        if (!succeeded || listAllFiles)
                        {
                            generatedFilePaths.Add(vsOutPath);
                        }
                    }
                    if (set.FragmentShaderCode != null)
                    {
                        string fsOutName = name + "-fragment." + extension;
                        string fsOutPath = Path.Combine(outputPath, fsOutName);
                        File.WriteAllText(fsOutPath, set.FragmentShaderCode, outputEncoding);
                        bool succeeded = CompileCode(lang, fsOutPath, set.FragmentFunction.Name, false, out string genPath);
                        if (succeeded)
                        {
                            generatedFilePaths.Add(genPath);
                        }
                        if (!succeeded || listAllFiles)
                        {
                            generatedFilePaths.Add(fsOutPath);
                        }
                    }
                }
            }

            File.WriteAllLines(genListFilePath, generatedFilePaths);

            return(0);
        }
Beispiel #21
0
 protected override void ParseParameters(ArgumentSyntax syntax)
 {
     ParseRootPathParameter(syntax, _configOptions);
 }
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out ArgumentSyntax argument))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.ArgumentMustBePassedWithRefOrOutKeyword:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddOutModifierToArgument))
                    {
                        return;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    IParameterSymbol parameter = semanticModel.DetermineParameter(argument, allowCandidate: true, cancellationToken: context.CancellationToken);

                    if (parameter == null)
                    {
                        return;
                    }

                    SyntaxToken refOrOutKeyword = default;

                    if (parameter.RefKind == RefKind.Out)
                    {
                        refOrOutKeyword = Token(SyntaxKind.OutKeyword);
                    }
                    else if (parameter.RefKind == RefKind.Ref)
                    {
                        refOrOutKeyword = Token(SyntaxKind.RefKeyword);
                    }
                    else
                    {
                        return;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        $"Add '{SyntaxFacts.GetText(refOrOutKeyword.Kind())}' modifier",
                        cancellationToken =>
                        {
                            ArgumentSyntax newArgument = argument
                                                         .WithRefOrOutKeyword(refOrOutKeyword)
                                                         .WithFormatterAnnotation();

                            return(context.Document.ReplaceNodeAsync(argument, newArgument, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case CompilerDiagnosticIdentifiers.ArgumentShouldNotBePassedWithRefOrOutKeyword:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveRefModifier))
                    {
                        return;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Remove 'ref' modifier",
                        cancellationToken =>
                        {
                            ArgumentSyntax newArgument = argument
                                                         .WithRefOrOutKeyword(default(SyntaxToken))
                                                         .PrependToLeadingTrivia(argument.RefOrOutKeyword.GetAllTrivia())
                                                         .WithFormatterAnnotation();

                            return(context.Document.ReplaceNodeAsync(argument, newArgument, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case CompilerDiagnosticIdentifiers.CannotConvertArgumentType:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue))
                    {
                        ExpressionSyntax expression = argument.Expression;

                        if (expression.Kind() == SyntaxKind.NullLiteralExpression &&
                            argument.Parent is ArgumentListSyntax argumentList)
                        {
                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            ImmutableArray <IParameterSymbol> parameterSymbols = FindParameters(argumentList, semanticModel, context.CancellationToken);

                            if (!parameterSymbols.IsDefault)
                            {
                                int index = argumentList.Arguments.IndexOf(argument);

                                IParameterSymbol parameterSymbol = parameterSymbols[index];

                                ITypeSymbol typeSymbol = parameterSymbol.Type;

                                if (typeSymbol.IsValueType)
                                {
                                    CodeFixRegistrator.ReplaceNullWithDefaultValue(
                                        context,
                                        diagnostic,
                                        expression,
                                        typeSymbol,
                                        CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue);
                                }
                            }
                        }
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddArgumentList))
                    {
                        ExpressionSyntax expression = argument.Expression;

                        if (expression.IsKind(
                                SyntaxKind.IdentifierName,
                                SyntaxKind.GenericName,
                                SyntaxKind.SimpleMemberAccessExpression))
                        {
                            InvocationExpressionSyntax invocationExpression = InvocationExpression(
                                expression.WithoutTrailingTrivia(),
                                ArgumentList().WithTrailingTrivia(expression.GetTrailingTrivia()));

                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            if (semanticModel.GetSpeculativeMethodSymbol(expression.SpanStart, invocationExpression) != null)
                            {
                                CodeAction codeAction = CodeAction.Create(
                                    "Add argument list",
                                    cancellationToken =>
                                    {
                                        ArgumentSyntax newNode = argument.WithExpression(invocationExpression);

                                        return(context.Document.ReplaceNodeAsync(argument, newNode, cancellationToken));
                                    },
                                    GetEquivalenceKey(diagnostic, CodeFixIdentifiers.AddArgumentList));

                                context.RegisterCodeFix(codeAction, diagnostic);
                                break;
                            }
                        }
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.CreateSingletonArray))
                    {
                        ExpressionSyntax expression = argument.Expression;

                        if (expression?.IsMissing == false)
                        {
                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(expression);

                            if (typeSymbol?.IsErrorType() == false)
                            {
                                foreach (ITypeSymbol typeSymbol2 in DetermineParameterTypeHelper.DetermineParameterTypes(argument, semanticModel, context.CancellationToken))
                                {
                                    if (!SymbolEqualityComparer.Default.Equals(typeSymbol, typeSymbol2) &&
                                        typeSymbol2 is IArrayTypeSymbol arrayType &&
                                        semanticModel.IsImplicitConversion(expression, arrayType.ElementType))
                                    {
                                        CodeAction codeAction = CodeAction.Create(
                                            "Create singleton array",
                                            cancellationToken => CreateSingletonArrayRefactoring.RefactorAsync(context.Document, expression, arrayType.ElementType, semanticModel, cancellationToken),
                                            GetEquivalenceKey(diagnostic, CodeFixIdentifiers.CreateSingletonArray));

                                        context.RegisterCodeFix(codeAction, diagnostic);
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.ReadOnlyFieldCannotBePassedAsRefOrOutValue:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.MakeFieldWritable))
                    {
                        return;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    SymbolInfo symbolInfo = semanticModel.GetSymbolInfo(argument.Expression, context.CancellationToken);

                    if (symbolInfo.CandidateReason != CandidateReason.NotAVariable)
                    {
                        return;
                    }

                    if (!(symbolInfo.CandidateSymbols.SingleOrDefault(shouldThrow: false) is IFieldSymbol fieldSymbol))
                    {
                        return;
                    }

                    if (fieldSymbol.DeclaredAccessibility != Accessibility.Private)
                    {
                        return;
                    }

                    if (!(fieldSymbol.GetSyntax().Parent.Parent is FieldDeclarationSyntax fieldDeclaration))
                    {
                        return;
                    }

                    TypeDeclarationSyntax containingTypeDeclaration = fieldDeclaration.FirstAncestor <TypeDeclarationSyntax>();

                    if (!argument.Ancestors().Any(f => f == containingTypeDeclaration))
                    {
                        return;
                    }

                    ModifiersCodeFixRegistrator.RemoveModifier(
                        context,
                        diagnostic,
                        fieldDeclaration,
                        SyntaxKind.ReadOnlyKeyword,
                        title: $"Make '{fieldSymbol.Name}' writable",
                        additionalKey: CodeFixIdentifiers.MakeFieldWritable);

                    break;
                }
                }
            }
        }
Beispiel #23
0
 public MemberInvocationExpressionWithSingleParameter(ExpressionSyntax expression, SimpleNameSyntax name, ArgumentSyntax argument)
 {
     Expression = expression;
     Name       = name;
     Argument   = argument;
 }
Beispiel #24
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            if (!Settings.IsAnyCodeFixEnabled(
                    CodeFixIdentifiers.AddOutModifierToArgument,
                    CodeFixIdentifiers.RemoveRefModifier,
                    CodeFixIdentifiers.CreateSingletonArray))
            {
                return;
            }

            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out ArgumentSyntax argument))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.ArgumentMustBePassedWithOutKeyword:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddOutModifierToArgument))
                    {
                        return;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Add 'out' modifier",
                        cancellationToken =>
                        {
                            ArgumentSyntax newArgument = argument
                                                         .WithRefOrOutKeyword(CSharpFactory.OutKeyword())
                                                         .WithFormatterAnnotation();

                            return(context.Document.ReplaceNodeAsync(argument, newArgument, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);

                    break;
                }

                case CompilerDiagnosticIdentifiers.ArgumentMayNotBePassedWithRefKeyword:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveRefModifier))
                    {
                        return;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Remove 'ref' modifier",
                        cancellationToken =>
                        {
                            ArgumentSyntax newArgument = argument
                                                         .WithRefOrOutKeyword(default(SyntaxToken))
                                                         .PrependToLeadingTrivia(argument.RefOrOutKeyword.GetLeadingAndTrailingTrivia())
                                                         .WithFormatterAnnotation();

                            return(context.Document.ReplaceNodeAsync(argument, newArgument, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case CompilerDiagnosticIdentifiers.CannotConvertArgumentType:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddOutModifierToArgument))
                    {
                        return;
                    }

                    ExpressionSyntax expression = argument.Expression;

                    if (expression?.IsMissing == false)
                    {
                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                        ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(expression);

                        if (typeSymbol?.IsErrorType() == false)
                        {
                            foreach (ITypeSymbol typeSymbol2 in DetermineParameterTypeHelper.DetermineParameterTypes(argument, semanticModel, context.CancellationToken))
                            {
                                if (!typeSymbol.Equals(typeSymbol2) &&
                                    typeSymbol2.IsArrayType())
                                {
                                    var arrayType = (IArrayTypeSymbol)typeSymbol2;

                                    if (semanticModel.IsImplicitConversion(expression, arrayType.ElementType))
                                    {
                                        CodeAction codeAction = CodeAction.Create(
                                            "Create singleton array",
                                            cancellationToken => CreateSingletonArrayRefactoring.RefactorAsync(context.Document, expression, arrayType.ElementType, semanticModel, cancellationToken),
                                            GetEquivalenceKey(diagnostic));

                                        context.RegisterCodeFix(codeAction, diagnostic);
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    break;
                }
                }
            }
        }
Beispiel #25
0
        private static void ConvertInitializers(SeparatedSyntaxList <ExpressionSyntax> initializers, string instance, List <StatementSyntax> statements, List <InitializerInfo> infos)
        {
            var idx = 0;

            foreach (var init in initializers)
            {
                var info  = infos[idx++];
                var mInfo = info != null && info.method != null ? info.method : null;
                if (mInfo != null)
                {
                    if (mInfo.IsStatic)
                    {
                        var ie = SyntaxHelper.GenerateStaticMethodCall(mInfo.Name,
                                                                       mInfo.ContainingType.FullyQualifiedName(),
                                                                       new[]
                        {
                            SyntaxFactory.Argument(SyntaxFactory.IdentifierName(instance)),
                            SyntaxFactory.Argument(init.WithoutTrivia())
                        }, mInfo.TypeArguments.ToArray());
                        statements.Add(ie);
                    }
                    else
                    {
                        ArgumentSyntax[] arguments = null;
                        if (init.Kind() == SyntaxKind.ComplexElementInitializerExpression)
                        {
                            var complexInit = (InitializerExpressionSyntax)init;

                            arguments = new ArgumentSyntax[complexInit.Expressions.Count];
                            for (int i = 0; i < complexInit.Expressions.Count; i++)
                            {
                                arguments[i] = SyntaxFactory.Argument(complexInit.Expressions[i].WithoutTrivia());
                            }
                        }
                        else
                        {
                            arguments = new[]
                            {
                                SyntaxFactory.Argument(init.WithoutTrivia())
                            };
                        }

                        var ie = SyntaxHelper.GenerateMethodCall(mInfo.Name, instance, arguments, mInfo.TypeArguments.ToArray());
                        statements.Add(ie);
                    }
                }
                else
                {
                    var be = (AssignmentExpressionSyntax)init;

                    if (be.Right is InitializerExpressionSyntax)
                    {
                        string name = null;
                        if (be.Left is IdentifierNameSyntax)
                        {
                            var identifier = (IdentifierNameSyntax)be.Left;
                            name = instance + "." + identifier.Identifier.ValueText;
                        }
                        else if (be.Left is ImplicitElementAccessSyntax)
                        {
                            name = SyntaxFactory.ElementAccessExpression(SyntaxFactory.IdentifierName(instance),
                                                                         ((ImplicitElementAccessSyntax)be.Left).ArgumentList.WithoutTrivia()).ToString();
                        }
                        else
                        {
                            name = instance;
                        }

                        SharpSixRewriter.ConvertInitializers(((InitializerExpressionSyntax)be.Right).Expressions, name, statements, info.nested);
                    }
                    else
                    {
                        var indexerKeys = be.Left as ImplicitElementAccessSyntax;

                        if (indexerKeys != null)
                        {
                            be = be.WithLeft(SyntaxFactory.ElementAccessExpression(SyntaxFactory.IdentifierName(instance),
                                                                                   indexerKeys.ArgumentList.WithoutTrivia()));
                        }
                        else
                        {
                            var identifier = (IdentifierNameSyntax)be.Left;
                            be =
                                be.WithLeft(SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                                 SyntaxFactory.IdentifierName(instance),
                                                                                 SyntaxFactory.IdentifierName(identifier.Identifier.ValueText)));
                        }

                        be = be.WithRight(be.Right.WithoutTrivia());
                        be = be.WithoutTrivia();

                        statements.Add(SyntaxFactory.ExpressionStatement(be, SyntaxFactory.Token(SyntaxKind.SemicolonToken)));
                    }
                }
            }
        }
Beispiel #26
0
        public static int Run(string[] args)
        {
            DebugHelper.HandleDebugSwitch(ref args);

            CommonCompilerOptions commonOptions       = null;
            AssemblyInfoOptions   assemblyInfoOptions = null;
            string tempOutDir = null;
            IReadOnlyList <string> references = Array.Empty <string>();
            IReadOnlyList <string> resources  = Array.Empty <string>();
            IReadOnlyList <string> sources    = Array.Empty <string>();
            string outputName = null;
            var    help       = false;
            var    returnCode = 0;
            string helpText   = null;

            try
            {
                ArgumentSyntax.Parse(args, syntax =>
                {
                    syntax.HandleHelp   = false;
                    syntax.HandleErrors = false;

                    commonOptions = CommonCompilerOptionsExtensions.Parse(syntax);

                    assemblyInfoOptions = AssemblyInfoOptions.Parse(syntax);

                    syntax.DefineOption("temp-output", ref tempOutDir, "Compilation temporary directory");

                    syntax.DefineOption("out", ref outputName, "Name of the output assembly");

                    syntax.DefineOptionList("reference", ref references, "Path to a compiler metadata reference");

                    syntax.DefineOptionList("resource", ref resources, "Resources to embed");

                    syntax.DefineOption("h|help", ref help, "Help for compile native.");

                    syntax.DefineParameterList("source-files", ref sources, "Compilation sources");

                    helpText = syntax.GetHelpText();

                    if (tempOutDir == null)
                    {
                        syntax.ReportError("Option '--temp-output' is required");
                    }
                });
            }
            catch (ArgumentSyntaxException exception)
            {
                Console.Error.WriteLine(exception.Message);
                help       = true;
                returnCode = ExitFailed;
            }

            if (help)
            {
                Console.WriteLine(helpText);

                return(returnCode);
            }

            var translated = TranslateCommonOptions(commonOptions, outputName);

            var allArgs = new List <string>(translated);

            allArgs.AddRange(GetDefaultOptions());

            // Generate assembly info
            var assemblyInfo = Path.Combine(tempOutDir, $"dotnet-compile.assemblyinfo.fs");

            File.WriteAllText(assemblyInfo, AssemblyInfoFileGenerator.GenerateFSharp(assemblyInfoOptions));
            allArgs.Add($"{assemblyInfo}");

            bool targetNetCore = commonOptions.Defines.Contains("DNXCORE50");

            //HACK fsc raise error FS0208 if target exe doesnt have extension .exe
            bool   hackFS0208         = targetNetCore && commonOptions.EmitEntryPoint == true;
            string originalOutputName = outputName;

            if (outputName != null)
            {
                if (hackFS0208)
                {
                    outputName = Path.ChangeExtension(outputName, ".exe");
                }

                allArgs.Add($"--out:{outputName}");
            }

            //set target framework
            if (targetNetCore)
            {
                allArgs.Add("--targetprofile:netcore");
            }

            allArgs.AddRange(references.Select(r => $"-r:{r}"));
            allArgs.AddRange(resources.Select(resource => $"--resource:{resource}"));
            allArgs.AddRange(sources.Select(s => $"{s}"));

            var rsp = Path.Combine(tempOutDir, "dotnet-compile-fsc.rsp");

            File.WriteAllLines(rsp, allArgs, Encoding.UTF8);

            // Execute FSC!
            var result = RunFsc(allArgs)
                         .ForwardStdErr()
                         .ForwardStdOut()
                         .Execute();

            bool successFsc = result.ExitCode == 0;

            if (hackFS0208 && File.Exists(outputName))
            {
                if (File.Exists(originalOutputName))
                {
                    File.Delete(originalOutputName);
                }
                File.Move(outputName, originalOutputName);
            }

            //HACK dotnet build require a pdb (crash without), fsc atm cant generate a portable pdb, so an empty pdb is created
            string pdbPath = Path.ChangeExtension(outputName, ".pdb");

            if (successFsc && !File.Exists(pdbPath))
            {
                File.WriteAllBytes(pdbPath, Array.Empty <byte>());
            }

            return(result.ExitCode);
        }
 private static IEnumerable<HelpRow> GetCommandRows(ArgumentSyntax argumentSyntax)
 {
     return argumentSyntax.Commands
                       .Where(c => !c.IsHidden)
                       .Select(c => new HelpRow { Header = c.Name, Text = c.Help });
 }
Beispiel #28
0
        static void Main(string[] args)
        {
            IReadOnlyList <string> input             = Array.Empty <string>();
            IReadOnlyList <string> resources         = null;
            IReadOnlyList <string> additionalFormats = null;
            string output   = null;
            string cdcom    = null;
            string svg      = null;
            string png      = null;
            string manifest = null;

            // Preview options
            bool   autosize  = false;
            double imgWidth  = 640;
            double imgHeight = 480;

            bool recursive = false;
            bool silent    = false;
            bool verbose   = false;
            bool version   = false;

#if NET461
            bool listGenerators = false;
#endif

            var cliOptions = ArgumentSyntax.Parse(args, options =>
            {
                options.ApplicationName = "cdcompile";

                options.DefineOption("o|output", ref output,
                                     "Output file (the format will be inferred from the extension). Cannot be used for directory inputs or in combination with specific output format options.");

                var cdcomOption = options.DefineOption("cdcom", ref cdcom, false, "Output a compiled binary component.");
                if (cdcomOption.IsSpecified && cdcom == null)
                {
                    cdcom = string.Empty;
                }

                var svgOption = options.DefineOption("svg", ref svg, false, "Render preview in SVG format.");
                if (svgOption.IsSpecified && svg == null)
                {
                    svg = string.Empty;
                }

                var pngOption = options.DefineOption("png", ref png, false, "Render preview in PNG format (experimental).");
                if (pngOption.IsSpecified && png == null)
                {
                    png = string.Empty;
                }

                var manifestOption = options.DefineOption("manifest", ref manifest, false, "Writes a manifest file listing the compiled components.");
                if (manifestOption.IsSpecified && manifest == null)
                {
                    manifest = "manifest.xml";
                }

                options.DefineOption("autosize", ref autosize, "Automatically sizes the output image to fit the rendered preview.");
                options.DefineOption("w|width", ref imgWidth, double.Parse, "Width of output images to generate (default=640).");
                options.DefineOption("h|height", ref imgHeight, double.Parse, "Height of output images to generate (default=480).");

                options.DefineOption("r|recursive", ref recursive, "Recursively searches sub-directories of the input directory.");
                options.DefineOption("s|silent", ref silent, "Does not output anything to the console on successful operation.");
                options.DefineOption("v|verbose", ref verbose, "Outputs extra information to the console.");

                options.DefineOption("version", ref version, "Prints the version of this application.");

#if NET461
                options.DefineOption("list-generators", ref listGenerators, "List the available output generators.");
#endif

                options.DefineOptionList("resources", ref resources, "Resources to use in generating the output. Either a directory, or a space-separated list of [key] [filename] pairs.");

                options.DefineOptionList("format", ref additionalFormats, "Output formats to write.");

                options.DefineParameterList("input", ref input, "Components to compile.");
            });

            if (version)
            {
                var assemblyName = typeof(Program).GetTypeInfo().Assembly.GetName();
                Console.WriteLine($"cdcompile {assemblyName.Version} ({assemblyName.ProcessorArchitecture})");
                return;
            }

            if (!silent)
            {
                LogManager.LoggerFactory.AddProvider(new BasicConsoleLogger(verbose ? LogLevel.Debug : LogLevel.Information));
            }

#if NET461
            if (listGenerators)
            {
                foreach (var generator in new OutputGeneratorRepository().AllGenerators)
                {
                    Console.WriteLine($"{generator.Format}: {generator.FileExtension}");
                }
                return;
            }
#endif

            if (!input.Any())
            {
                cliOptions.ReportError("At least one input file must be specified.");
            }

            if (output != null && (svg != null || png != null))
            {
                cliOptions.ReportError("Supplying both --output and a specific format is not supported.");
            }

            IResourceProvider resourceProvider = null;
            if (resources != null && resources.Count == 1)
            {
                string directory = resources.Single();
                if (!Directory.Exists(directory))
                {
                    cliOptions.ReportError($"Directory '{directory}' used for --resources does not exist.");
                }

                Log.LogDebug($"Using directory '{directory}' as resource provider.");
                resourceProvider = new DirectoryResourceProvider(resources.Single());
            }
            else if (resources != null && resources.Count % 2 == 0)
            {
                Log.LogDebug("Mapping resources as key-file pairs.");
                resourceProvider = new FileMapResourceProvider();
                for (int i = 0; i + 1 < resources.Count; i += 2)
                {
                    ((FileMapResourceProvider)resourceProvider).Mappings.Add(resources[i], resources[i + 1]);
                }
            }
            else if (resources != null)
            {
                cliOptions.ReportError("--resources must either be a directory or a space-separated list of [key] [filename] pairs.");
            }
            else
            {
                Log.LogDebug("Not supplying resources.");
                resourceProvider = new FileMapResourceProvider();
            }

            var  formats           = new Dictionary <IOutputGenerator, string>();
            var  outputGenerators  = new OutputGeneratorRepository();
            bool outputIsDirectory = Directory.Exists(output);
            if (output != null && !outputIsDirectory)
            {
                if (outputGenerators.TryGetGeneratorByFileExtension(Path.GetExtension(output), out var generator))
                {
                    // Use the generator implied by the file extension
                    formats.Add(generator, output);
                }
                else
                {
                    Log.LogError("Unable to infer format from output file extension.");
                    Environment.Exit(1);
                }
            }
            if (cdcom != null)
            {
                formats.Add(new BinaryComponentGenerator(), NullIfEmpty(cdcom));
            }
            if (svg != null)
            {
                formats.Add(new SvgPreviewRenderer(), NullIfEmpty(svg));
            }
            if (png != null)
            {
                formats.Add(new PngPreviewRenderer(), NullIfEmpty(png));
            }
            if (additionalFormats != null)
            {
                foreach (var format in additionalFormats)
                {
                    IOutputGenerator generator;
                    if (outputGenerators.TryGetGeneratorByFormat(format, out generator))
                    {
                        formats.Add(generator, outputIsDirectory ? output : null);
                    }
                    else
                    {
                        Log.LogError($"Unknown format: {format}");
                        Environment.Exit(1);
                    }
                }
            }

            var previewOptions = new PreviewGenerationOptions
            {
                Center = true,
                Crop   = autosize,
                Width  = imgWidth,
                Height = imgHeight
            };

            var results = new List <CompileResult>();

            foreach (var i in input)
            {
                if (File.Exists(i))
                {
                    var result = Run(i, resourceProvider, previewOptions, formats);
                    results.Add(result);
                }
                else if (Directory.Exists(i))
                {
                    foreach (var generator in formats)
                    {
                        if (generator.Value != null && !Directory.Exists(generator.Value))
                        {
                            cliOptions.ReportError("Outputs must be directories when the input is a directory.");
                        }
                    }

                    foreach (var file in Directory.GetFiles(i, "*.xml",
                                                            recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly))
                    {
                        var result = Run(file, resourceProvider, previewOptions, formats);
                        results.Add(result);
                    }
                }
                else
                {
                    Log.LogError($"Input is not a valid file or directory: {i}");
                    Environment.Exit(1);
                }
            }

            if (manifest != null)
            {
                using (var manifestFs = File.Open(manifest, FileMode.Create))
                {
                    Log.LogInformation($"Writing manifest to {manifest}");
                    ManifestGenerator.WriteManifest(results, manifestFs);
                }
            }
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="argumentSyntax">Node of ArgumentSyntax type</param>
 /// <returns>Trimed and without special character ToString representation.</returns>
 public static string ToCleanString(this ArgumentSyntax argumentSyntax)
 {
     return(argumentSyntax.ToString().Replace("\"", "").Trim());
 }
Beispiel #30
0
        private ArgumentSyntax ParseCommandLine(string[] args)
        {
            IReadOnlyList <string> inputFiles     = Array.Empty <string>();
            IReadOnlyList <string> referenceFiles = Array.Empty <string>();

            bool optimize = false;

            bool           waitForDebugger = false;
            AssemblyName   name            = typeof(Program).GetTypeInfo().Assembly.GetName();
            ArgumentSyntax argSyntax       = ArgumentSyntax.Parse(args, syntax =>
            {
                syntax.ApplicationName = name.Name.ToString();

                // HandleHelp writes to error, fails fast with crash dialog and lacks custom formatting.
                syntax.HandleHelp   = false;
                syntax.HandleErrors = true;

                syntax.DefineOption("h|help", ref _help, "Help message for ILC");
                syntax.DefineOptionList("r|reference", ref referenceFiles, "Reference file(s) for compilation");
                syntax.DefineOption("o|out", ref _outputFilePath, "Output file path");
                syntax.DefineOption("O", ref optimize, "Enable optimizations");
                syntax.DefineOption("g", ref _enableDebugInfo, "Emit debugging information");
                syntax.DefineOption("cpp", ref _isCppCodegen, "Compile for C++ code-generation");
                syntax.DefineOption("wasm", ref _isWasmCodegen, "Compile for WebAssembly code-generation");
                syntax.DefineOption("nativelib", ref _nativeLib, "Compile as static or shared library");
                syntax.DefineOption("exportsfile", ref _exportsFile, "File to write exported method definitions");
                syntax.DefineOption("dgmllog", ref _dgmlLogFileName, "Save result of dependency analysis as DGML");
                syntax.DefineOption("fulllog", ref _generateFullDgmlLog, "Save detailed log of dependency analysis");
                syntax.DefineOption("scandgmllog", ref _scanDgmlLogFileName, "Save result of scanner dependency analysis as DGML");
                syntax.DefineOption("scanfulllog", ref _generateFullScanDgmlLog, "Save detailed log of scanner dependency analysis");
                syntax.DefineOption("verbose", ref _isVerbose, "Enable verbose logging");
                syntax.DefineOption("systemmodule", ref _systemModuleName, "System module name (default: System.Private.CoreLib)");
                syntax.DefineOption("multifile", ref _multiFile, "Compile only input files (do not compile referenced assemblies)");
                syntax.DefineOption("waitfordebugger", ref waitForDebugger, "Pause to give opportunity to attach debugger");
                syntax.DefineOption("usesharedgenerics", ref _useSharedGenerics, "Enable shared generics");
                syntax.DefineOptionList("codegenopt", ref _codegenOptions, "Define a codegen option");
                syntax.DefineOptionList("rdxml", ref _rdXmlFilePaths, "RD.XML file(s) for compilation");
                syntax.DefineOption("map", ref _mapFileName, "Generate a map file");
                syntax.DefineOption("metadatalog", ref _metadataLogFileName, "Generate a metadata log file");
                syntax.DefineOption("nometadatablocking", ref _noMetadataBlocking, "Ignore metadata blocking for internal implementation details");
                syntax.DefineOption("scan", ref _useScanner, "Use IL scanner to generate optimized code (implied by -O)");
                syntax.DefineOption("noscan", ref _noScanner, "Do not use IL scanner to generate optimized code");
                syntax.DefineOption("ildump", ref _ilDump, "Dump IL assembly listing for compiler-generated IL");
                syntax.DefineOption("stacktracedata", ref _emitStackTraceData, "Emit data to support generating stack trace strings at runtime");
                syntax.DefineOptionList("initassembly", ref _initAssemblies, "Assembly(ies) with a library initializer");
                syntax.DefineOptionList("appcontextswitch", ref _appContextSwitches, "System.AppContext switches to set");

                syntax.DefineOption("targetarch", ref _targetArchitectureStr, "Target architecture for cross compilation");
                syntax.DefineOption("targetos", ref _targetOSStr, "Target OS for cross compilation");

                syntax.DefineOption("singlemethodtypename", ref _singleMethodTypeName, "Single method compilation: name of the owning type");
                syntax.DefineOption("singlemethodname", ref _singleMethodName, "Single method compilation: name of the method");
                syntax.DefineOptionList("singlemethodgenericarg", ref _singleMethodGenericArgs, "Single method compilation: generic arguments to the method");

                syntax.DefineParameterList("in", ref inputFiles, "Input file(s) to compile");
            });

            if (waitForDebugger)
            {
                Console.WriteLine("Waiting for debugger to attach. Press ENTER to continue");
                Console.ReadLine();
            }

            _optimizationMode = optimize ? OptimizationMode.Blended : OptimizationMode.None;

            foreach (var input in inputFiles)
            {
                Helpers.AppendExpandedPaths(_inputFilePaths, input, true);
            }

            foreach (var reference in referenceFiles)
            {
                Helpers.AppendExpandedPaths(_referenceFilePaths, reference, false);
            }

            return(argSyntax);
        }
Beispiel #31
0
        private ArgumentSyntax ParseCommandLine(string[] args)
        {
            IReadOnlyList <string> inputFiles      = Array.Empty <string>();
            IReadOnlyList <string> referenceFiles  = Array.Empty <string>();
            IReadOnlyList <string> includePatterns = Array.Empty <string>();
            IReadOnlyList <string> excludePatterns = Array.Empty <string>();
            string includeFile = string.Empty;
            string excludeFile = string.Empty;

            AssemblyName   name      = typeof(Program).GetTypeInfo().Assembly.GetName();
            ArgumentSyntax argSyntax = ArgumentSyntax.Parse(args, syntax =>
            {
                syntax.ApplicationName = name.Name.ToString();

                // HandleHelp writes to error, fails fast with crash dialog and lacks custom formatting.
                syntax.HandleHelp   = false;
                syntax.HandleErrors = true;

                syntax.DefineOption("h|help", ref _help, "Display this usage message");
                syntax.DefineOption("s|system-module", ref _systemModule, s => new AssemblyName(s), "System module name (default: mscorlib)");
                syntax.DefineOptionList("r|reference", ref referenceFiles, "Reference metadata from the specified assembly");
                syntax.DefineOptionList("i|include", ref includePatterns, "Use only methods/types/namespaces, which match the given regular expression(s)");
                syntax.DefineOption("include-file", ref includeFile, "Same as --include, but the regular expression(s) are declared line by line in the specified file.");
                syntax.DefineOptionList("e|exclude", ref excludePatterns, "Skip methods/types/namespaces, which match the given regular expression(s)");
                syntax.DefineOption("exclude-file", ref excludeFile, "Same as --exclude, but the regular expression(s) are declared line by line in the specified file.");
                syntax.DefineOption("statistics", ref _printStatistics, "Print verification statistics");
                syntax.DefineOption("v|verbose", ref _verbose, "Verbose output");

                syntax.DefineParameterList("in", ref inputFiles, "Input file(s)");
            });

            foreach (var input in inputFiles)
            {
                Helpers.AppendExpandedPaths(_inputFilePaths, input, true);
            }

            foreach (var reference in referenceFiles)
            {
                Helpers.AppendExpandedPaths(_referenceFilePaths, reference, false);
            }

            if (!string.IsNullOrEmpty(includeFile))
            {
                if (includePatterns.Count > 0)
                {
                    WriteLine("[Warning] --include-file takes precedence over --include");
                }
                includePatterns = File.ReadAllLines(includeFile);
            }
            _includePatterns = StringPatternsToRegexList(includePatterns);

            if (!string.IsNullOrEmpty(excludeFile))
            {
                if (excludePatterns.Count > 0)
                {
                    WriteLine("[Warning] --exclude-file takes precedence over --exclude");
                }
                excludePatterns = File.ReadAllLines(excludeFile);
            }
            _excludePatterns = StringPatternsToRegexList(excludePatterns);

            if (_verbose)
            {
                WriteLine();
                foreach (var path in _inputFilePaths)
                {
                    WriteLine($"Using input file '{path.Value}'");
                }

                WriteLine();
                foreach (var path in _referenceFilePaths)
                {
                    WriteLine($"Using reference file '{path.Value}'");
                }

                WriteLine();
                foreach (var pattern in _includePatterns)
                {
                    WriteLine($"Using include pattern '{pattern}'");
                }

                WriteLine();
                foreach (var pattern in _excludePatterns)
                {
                    WriteLine($"Using exclude pattern '{pattern}'");
                }
            }

            return(argSyntax);
        }
Beispiel #32
0
        private int Run(string[] args)
        {
            InitializeDefaultOptions();

            ArgumentSyntax syntax = ParseCommandLine(args);

            if (_help)
            {
                Help(syntax.GetHelpText());
                return(1);
            }

            if (_outputFilePath == null)
            {
                throw new CommandLineException("Output filename must be specified (/out <file>)");
            }

            //
            // Set target Architecture and OS
            //
            if (_targetArchitectureStr != null)
            {
                if (_targetArchitectureStr.Equals("x86", StringComparison.OrdinalIgnoreCase))
                {
                    _targetArchitecture = TargetArchitecture.X86;
                }
                else if (_targetArchitectureStr.Equals("x64", StringComparison.OrdinalIgnoreCase))
                {
                    _targetArchitecture = TargetArchitecture.X64;
                }
                else if (_targetArchitectureStr.Equals("arm", StringComparison.OrdinalIgnoreCase))
                {
                    _targetArchitecture = TargetArchitecture.ARM;
                }
                else if (_targetArchitectureStr.Equals("armel", StringComparison.OrdinalIgnoreCase))
                {
                    _targetArchitecture = TargetArchitecture.ARMEL;
                }
                else if (_targetArchitectureStr.Equals("arm64", StringComparison.OrdinalIgnoreCase))
                {
                    _targetArchitecture = TargetArchitecture.ARM64;
                }
                else if (_targetArchitectureStr.Equals("wasm", StringComparison.OrdinalIgnoreCase))
                {
                    _targetArchitecture = TargetArchitecture.Wasm32;
                    _isWasmCodegen      = true;
                }
                else
                {
                    throw new CommandLineException("Target architecture is not supported");
                }
            }
            if (_targetOSStr != null)
            {
                if (_targetOSStr.Equals("windows", StringComparison.OrdinalIgnoreCase))
                {
                    _targetOS = TargetOS.Windows;
                }
                else if (_targetOSStr.Equals("linux", StringComparison.OrdinalIgnoreCase))
                {
                    _targetOS = TargetOS.Linux;
                }
                else if (_targetOSStr.Equals("osx", StringComparison.OrdinalIgnoreCase))
                {
                    _targetOS = TargetOS.OSX;
                }
                else
                {
                    throw new CommandLineException("Target OS is not supported");
                }
            }

            if (_isWasmCodegen)
            {
                _targetArchitecture = TargetArchitecture.Wasm32;
            }
            else if (_isCppCodegen)
            {
                _targetArchitecture = TargetArchitecture.Cpp64;
            }

            //
            // Initialize type system context
            //

            SharedGenericsMode genericsMode = _useSharedGenerics || (!_isCppCodegen && !_isWasmCodegen) ?
                                              SharedGenericsMode.CanonicalReferenceTypes : SharedGenericsMode.Disabled;

            // TODO: compiler switch for SIMD support?
            var simdVectorLength  = (_isCppCodegen || _isWasmCodegen) ? SimdVectorLength.None : SimdVectorLength.Vector128Bit;
            var targetDetails     = new TargetDetails(_targetArchitecture, _targetOS, TargetAbi.CoreRT, simdVectorLength);
            var typeSystemContext = new CompilerTypeSystemContext(targetDetails, genericsMode);

            //
            // TODO: To support our pre-compiled test tree, allow input files that aren't managed assemblies since
            // some tests contain a mixture of both managed and native binaries.
            //
            // See: https://github.com/dotnet/corert/issues/2785
            //
            // When we undo this this hack, replace this foreach with
            //  typeSystemContext.InputFilePaths = _inputFilePaths;
            //
            Dictionary <string, string> inputFilePaths = new Dictionary <string, string>();

            foreach (var inputFile in _inputFilePaths)
            {
                try
                {
                    var module = typeSystemContext.GetModuleFromPath(inputFile.Value);
                    inputFilePaths.Add(inputFile.Key, inputFile.Value);
                }
                catch (TypeSystemException.BadImageFormatException)
                {
                    // Keep calm and carry on.
                }
            }

            typeSystemContext.InputFilePaths     = inputFilePaths;
            typeSystemContext.ReferenceFilePaths = _referenceFilePaths;

            typeSystemContext.SetSystemModule(typeSystemContext.GetModuleForSimpleName(_systemModuleName));

            if (typeSystemContext.InputFilePaths.Count == 0)
            {
                throw new CommandLineException("No input files specified");
            }

            //
            // Initialize compilation group and compilation roots
            //

            // Single method mode?
            MethodDesc singleMethod = CheckAndParseSingleMethodModeArguments(typeSystemContext);

            CompilationModuleGroup          compilationGroup;
            List <ICompilationRootProvider> compilationRoots = new List <ICompilationRootProvider>();

            if (singleMethod != null)
            {
                // Compiling just a single method
                compilationGroup = new SingleMethodCompilationModuleGroup(singleMethod);
                compilationRoots.Add(new SingleMethodRootProvider(singleMethod));
            }
            else
            {
                // Either single file, or multifile library, or multifile consumption.
                EcmaModule entrypointModule = null;
                foreach (var inputFile in typeSystemContext.InputFilePaths)
                {
                    EcmaModule module = typeSystemContext.GetModuleFromPath(inputFile.Value);

                    if (module.PEReader.PEHeaders.IsExe)
                    {
                        if (entrypointModule != null)
                        {
                            throw new Exception("Multiple EXE modules");
                        }
                        entrypointModule = module;
                    }

                    compilationRoots.Add(new ExportedMethodsRootProvider(module));
                }

                if (entrypointModule != null)
                {
                    compilationRoots.Add(new MainMethodRootProvider(entrypointModule, CreateInitializerList(typeSystemContext)));
                }

                if (_multiFile)
                {
                    List <EcmaModule> inputModules = new List <EcmaModule>();

                    foreach (var inputFile in typeSystemContext.InputFilePaths)
                    {
                        EcmaModule module = typeSystemContext.GetModuleFromPath(inputFile.Value);

                        if (entrypointModule == null)
                        {
                            // This is a multifile production build - we need to root all methods
                            compilationRoots.Add(new LibraryRootProvider(module));
                        }
                        inputModules.Add(module);
                    }

                    compilationGroup = new MultiFileSharedCompilationModuleGroup(typeSystemContext, inputModules);
                }
                else
                {
                    if (entrypointModule == null && !_nativeLib)
                    {
                        throw new Exception("No entrypoint module");
                    }

                    compilationRoots.Add(new ExportedMethodsRootProvider((EcmaModule)typeSystemContext.SystemModule));
                    compilationGroup = new SingleFileCompilationModuleGroup();
                }

                if (_nativeLib)
                {
                    // Set owning module of generated native library startup method to compiler generated module,
                    // to ensure the startup method is included in the object file during multimodule mode build
                    compilationRoots.Add(new NativeLibraryInitializerRootProvider(typeSystemContext.GeneratedAssembly, CreateInitializerList(typeSystemContext)));
                }

                if (_rdXmlFilePaths.Count > 0)
                {
                    Console.WriteLine("Warning: RD.XML processing will change before release (https://github.com/dotnet/corert/issues/5001)");
                }
                foreach (var rdXmlFilePath in _rdXmlFilePaths)
                {
                    compilationRoots.Add(new RdXmlRootProvider(typeSystemContext, rdXmlFilePath));
                }
            }

            //
            // Compile
            //

            CompilationBuilder builder;

            if (_isWasmCodegen)
            {
                builder = new WebAssemblyCodegenCompilationBuilder(typeSystemContext, compilationGroup);
            }
            else if (_isCppCodegen)
            {
                builder = new CppCodegenCompilationBuilder(typeSystemContext, compilationGroup);
            }
            else
            {
                builder = new RyuJitCompilationBuilder(typeSystemContext, compilationGroup);
            }

            var stackTracePolicy = _emitStackTraceData ?
                                   (StackTraceEmissionPolicy) new EcmaMethodStackTraceEmissionPolicy() : new NoStackTraceEmissionPolicy();

            MetadataBlockingPolicy mdBlockingPolicy = _noMetadataBlocking ?
                                                      (MetadataBlockingPolicy) new NoBlockingPolicy() : new BlockedInternalsBlockingPolicy();

            UsageBasedMetadataManager metadataManager = new UsageBasedMetadataManager(
                compilationGroup,
                typeSystemContext,
                mdBlockingPolicy,
                _metadataLogFileName,
                stackTracePolicy);

            // Unless explicitly opted in at the command line, we enable scanner for retail builds by default.
            // We don't do this for CppCodegen and Wasm, because those codegens are behind.
            // We also don't do this for multifile because scanner doesn't simulate inlining (this would be
            // fixable by using a CompilationGroup for the scanner that has a bigger worldview, but
            // let's cross that bridge when we get there).
            bool useScanner = _useScanner ||
                              (_optimizationMode != OptimizationMode.None && !_isCppCodegen && !_isWasmCodegen && !_multiFile);

            useScanner &= !_noScanner;

            bool supportsReflection = !_isWasmCodegen && !_isCppCodegen && _systemModuleName == DefaultSystemModule;

            MetadataManager compilationMetadataManager = supportsReflection ? metadataManager : (MetadataManager) new EmptyMetadataManager(typeSystemContext);
            ILScanResults   scanResults = null;

            if (useScanner)
            {
                ILScannerBuilder scannerBuilder = builder.GetILScannerBuilder()
                                                  .UseCompilationRoots(compilationRoots)
                                                  .UseMetadataManager(metadataManager);

                if (_scanDgmlLogFileName != null)
                {
                    scannerBuilder.UseDependencyTracking(_generateFullScanDgmlLog ? DependencyTrackingLevel.All : DependencyTrackingLevel.First);
                }

                IILScanner scanner = scannerBuilder.ToILScanner();

                scanResults = scanner.Scan();

                compilationMetadataManager = metadataManager.ToAnalysisBasedMetadataManager();
            }

            var logger = new Logger(Console.Out, _isVerbose);

            DebugInformationProvider debugInfoProvider = _enableDebugInfo ?
                                                         (_ilDump == null ? new DebugInformationProvider() : new ILAssemblyGeneratingMethodDebugInfoProvider(_ilDump, new EcmaOnlyDebugInformationProvider())) :
                                                         new NullDebugInformationProvider();

            DependencyTrackingLevel trackingLevel = _dgmlLogFileName == null ?
                                                    DependencyTrackingLevel.None : (_generateFullDgmlLog ? DependencyTrackingLevel.All : DependencyTrackingLevel.First);

            compilationRoots.Add(compilationMetadataManager);

            builder
            .UseBackendOptions(_codegenOptions)
            .UseMetadataManager(compilationMetadataManager)
            .UseLogger(logger)
            .UseDependencyTracking(trackingLevel)
            .UseCompilationRoots(compilationRoots)
            .UseOptimizationMode(_optimizationMode)
            .UseDebugInfoProvider(debugInfoProvider);

            if (scanResults != null)
            {
                // If we have a scanner, feed the vtable analysis results to the compilation.
                // This could be a command line switch if we really wanted to.
                builder.UseVTableSliceProvider(scanResults.GetVTableLayoutInfo());

                // If we have a scanner, feed the generic dictionary results to the compilation.
                // This could be a command line switch if we really wanted to.
                builder.UseGenericDictionaryLayoutProvider(scanResults.GetDictionaryLayoutInfo());

                // If we feed any outputs of the scanner into the compilation, it's essential
                // we use scanner's devirtualization manager. It prevents optimizing codegens
                // from accidentally devirtualizing cases that can never happen at runtime
                // (e.g. devirtualizing a method on a type that never gets allocated).
                builder.UseDevirtualizationManager(scanResults.GetDevirtualizationManager());
            }

            ICompilation compilation = builder.ToCompilation();

            ObjectDumper dumper = _mapFileName != null ? new ObjectDumper(_mapFileName) : null;

            CompilationResults compilationResults = compilation.Compile(_outputFilePath, dumper);

            if (_exportsFile != null)
            {
                ExportsFileWriter defFileWriter = new ExportsFileWriter(typeSystemContext, _exportsFile);
                foreach (var compilationRoot in compilationRoots)
                {
                    if (compilationRoot is ExportedMethodsRootProvider provider)
                    {
                        defFileWriter.AddExportedMethods(provider.ExportedMethods);
                    }
                }

                defFileWriter.EmitExportedMethods();
            }

            if (_dgmlLogFileName != null)
            {
                compilationResults.WriteDependencyLog(_dgmlLogFileName);
            }

            if (scanResults != null)
            {
                SimdHelper simdHelper = new SimdHelper();

                if (_scanDgmlLogFileName != null)
                {
                    scanResults.WriteDependencyLog(_scanDgmlLogFileName);
                }

                // If the scanner and compiler don't agree on what to compile, the outputs of the scanner might not actually be usable.
                // We are going to check this two ways:
                // 1. The methods and types generated during compilation are a subset of method and types scanned
                // 2. The methods and types scanned are a subset of methods and types compiled (this has a chance to hold for unoptimized builds only).

                // Check that methods and types generated during compilation are a subset of method and types scanned
                bool scanningFail = false;
                DiffCompilationResults(ref scanningFail, compilationResults.CompiledMethodBodies, scanResults.CompiledMethodBodies,
                                       "Methods", "compiled", "scanned", method => !(method.GetTypicalMethodDefinition() is EcmaMethod));
                DiffCompilationResults(ref scanningFail, compilationResults.ConstructedEETypes, scanResults.ConstructedEETypes,
                                       "EETypes", "compiled", "scanned", type => !(type.GetTypeDefinition() is EcmaType));

                // If optimizations are enabled, the results will for sure not match in the other direction due to inlining, etc.
                // But there's at least some value in checking the scanner doesn't expand the universe too much in debug.
                if (_optimizationMode == OptimizationMode.None)
                {
                    // Check that methods and types scanned are a subset of methods and types compiled

                    // If we find diffs here, they're not critical, but still might be causing a Size on Disk regression.
                    bool dummy = false;

                    // We additionally skip methods in SIMD module because there's just too many intrisics to handle and IL scanner
                    // doesn't expand them. They would show up as noisy diffs.
                    DiffCompilationResults(ref dummy, scanResults.CompiledMethodBodies, compilationResults.CompiledMethodBodies,
                                           "Methods", "scanned", "compiled", method => !(method.GetTypicalMethodDefinition() is EcmaMethod) || simdHelper.IsSimdType(method.OwningType));
                    DiffCompilationResults(ref dummy, scanResults.ConstructedEETypes, compilationResults.ConstructedEETypes,
                                           "EETypes", "scanned", "compiled", type => !(type.GetTypeDefinition() is EcmaType));
                }

                if (scanningFail)
                {
                    throw new Exception("Scanning failure");
                }
            }

            if (debugInfoProvider is IDisposable)
            {
                ((IDisposable)debugInfoProvider).Dispose();
            }

            return(0);
        }
 public static ArgumentSyntax WithRefKindKeyword(this ArgumentSyntax syntax, SyntaxToken refKindKeyword)
 {
     return(WithRefKindKeywordAccessor(syntax, refKindKeyword));
 }
Beispiel #34
0
        public static void Main(string[] args)
        {
            string username          = null;
            string password          = null;
            string tokenEndPoint     = null;
            string heartBeatEndPoint = null;
            string device            = null;
            string configFile        = null;

            ArgumentSyntax.Parse(args, t =>
            {
                t.DefineOption("un|username", ref username, "Login Username");
                t.DefineOption("pw|password", ref password, "Login Password");
                t.DefineOption("turl|tokenEndPoint", ref tokenEndPoint, "Token EndPoint");
                t.DefineOption("hurl|heartBeatEndPoint", ref heartBeatEndPoint, "HeartBeat EndPoint");
                t.DefineOption("dev|device", ref device, "DeviceName");
                t.DefineOption("c|config", ref configFile,
                               "Config File. The option in file will overwrite options provided by args.");

                if (string.IsNullOrEmpty(configFile))
                {
                    if (string.IsNullOrEmpty(username))
                    {
                        t.ReportError("username is required");
                    }
                    if (string.IsNullOrEmpty(password))
                    {
                        t.ReportError("password is required");
                    }
                    if (string.IsNullOrEmpty(device))
                    {
                        t.ReportError("device is required");
                    }
                    if (string.IsNullOrEmpty(tokenEndPoint))
                    {
                        t.ReportError("tokenEndPoint is required");
                    }
                    if (string.IsNullOrEmpty(heartBeatEndPoint))
                    {
                        t.ReportError("heartBeatEndPoint is required");
                    }
                }
            });

            if (!string.IsNullOrEmpty(configFile))
            {
                using (var jsonText = File.OpenText(configFile))
                {
                    var json = JObject.Parse(jsonText.ReadToEnd());
                    username          = json["username"].ToString();
                    password          = json["password"].ToString();
                    device            = json["device"].ToString();
                    tokenEndPoint     = json["token_end_point"].ToString();
                    heartBeatEndPoint = json["heart_beat_end_point"].ToString();
                }
            }

            var token = new Token(tokenEndPoint, username, password);

            var httpClient = new HttpClient();

            httpClient.DefaultRequestHeaders.Authorization =
                new AuthenticationHeaderValue("Bearer", token.GetAccessToken().Result);

            while (true)
            {
                try
                {
                    var response = httpClient.PostAsync(heartBeatEndPoint,
                                                        new StringContent("{\"device\":\"" + device + "\"}", Encoding.UTF8, "application/json")).Result;
                    if (response.StatusCode == HttpStatusCode.Unauthorized)
                    {
                        httpClient.DefaultRequestHeaders.Authorization =
                            new AuthenticationHeaderValue("Bearer", token.GetAccessToken().Result);
                    }
                    else
                    {
                        response.EnsureSuccessStatusCode();
                    }
                    Task.Delay(10 * 1000).Wait();
                }
                catch (Exception e)
                {
                    Console.Error.WriteLine(e.ToString());
                }
            }
        }
Beispiel #35
0
        internal static bool TryGetValidateValueCallback(InvocationExpressionSyntax registerCall, SemanticModel semanticModel, CancellationToken cancellationToken, out ArgumentSyntax callback)
        {
            callback = null;
            var methodSymbol = semanticModel.SemanticModelFor(registerCall)
                               .GetSymbolInfo(registerCall, cancellationToken)
                               .Symbol as IMethodSymbol;

            if (methodSymbol == null ||
                methodSymbol.ContainingType != KnownSymbol.DependencyProperty)
            {
                return(false);
            }

            if (!methodSymbol.Name.StartsWith("Register", StringComparison.Ordinal))
            {
                return(false);
            }

            for (int i = 0; i < methodSymbol.Parameters.Length; i++)
            {
                var parameter = methodSymbol.Parameters[i];
                if (parameter.Type == KnownSymbol.ValidateValueCallback)
                {
                    return(registerCall.TryGetArgumentAtIndex(i, out callback));
                }
            }

            return(false);
        }
Beispiel #36
0
        private int Run(string[] args)
        {
            InitializeDefaultOptions();

            ArgumentSyntax syntax = ParseCommandLine(args);

            if (_help)
            {
                Help(syntax.GetHelpText());
                return(1);
            }

            if (_inputFilePaths.Count == 0)
            {
                throw new CommandLineException("No input files specified");
            }

            if (_outputFilePath == null)
            {
                throw new CommandLineException("Output filename must be specified (/out <file>)");
            }

            //
            // Initialize type system context
            //

            SharedGenericsMode genericsMode = _useSharedGenerics ?
                                              SharedGenericsMode.CanonicalReferenceTypes : SharedGenericsMode.Disabled;

            var typeSystemContext = new CompilerTypeSystemContext(new TargetDetails(_targetArchitecture, _targetOS), genericsMode);

            typeSystemContext.InputFilePaths     = _inputFilePaths;
            typeSystemContext.ReferenceFilePaths = _referenceFilePaths;

            typeSystemContext.SetSystemModule(typeSystemContext.GetModuleForSimpleName(_systemModuleName));

            //
            // Initialize compilation group and compilation roots
            //

            // Single method mode?
            MethodDesc singleMethod = CheckAndParseSingleMethodModeArguments(typeSystemContext);

            CompilationModuleGroup          compilationGroup;
            List <ICompilationRootProvider> compilationRoots = new List <ICompilationRootProvider>();

            if (singleMethod != null)
            {
                // Compiling just a single method
                compilationGroup = new SingleMethodCompilationModuleGroup(singleMethod);
                compilationRoots.Add(new SingleMethodRootProvider(singleMethod));
            }
            else
            {
                // Either single file, or multifile library, or multifile consumption.
                EcmaModule entrypointModule = null;
                foreach (var inputFile in typeSystemContext.InputFilePaths)
                {
                    EcmaModule module = typeSystemContext.GetModuleFromPath(inputFile.Value);

                    if (module.PEReader.PEHeaders.IsExe)
                    {
                        if (entrypointModule != null)
                        {
                            throw new Exception("Multiple EXE modules");
                        }
                        entrypointModule = module;
                    }

                    compilationRoots.Add(new ExportedMethodsRootProvider(module));
                }

                if (entrypointModule != null)
                {
                    LibraryInitializers libraryInitializers =
                        new LibraryInitializers(typeSystemContext, _isCppCodegen);
                    compilationRoots.Add(new MainMethodRootProvider(entrypointModule, libraryInitializers.LibraryInitializerMethods));
                }

                if (_multiFile)
                {
                    List <EcmaModule> inputModules = new List <EcmaModule>();

                    foreach (var inputFile in typeSystemContext.InputFilePaths)
                    {
                        EcmaModule module = typeSystemContext.GetModuleFromPath(inputFile.Value);

                        if (entrypointModule == null)
                        {
                            // This is a multifile production build - we need to root all methods
                            compilationRoots.Add(new LibraryRootProvider(module));
                        }
                        inputModules.Add(module);
                    }

                    if (entrypointModule == null)
                    {
                        compilationGroup = new MultiFileSharedCompilationModuleGroup(typeSystemContext, inputModules);
                    }
                    else
                    {
                        compilationGroup = new MultiFileLeafCompilationModuleGroup(typeSystemContext, inputModules);
                    }
                }
                else
                {
                    if (entrypointModule == null)
                    {
                        throw new Exception("No entrypoint module");
                    }

                    compilationRoots.Add(new ExportedMethodsRootProvider((EcmaModule)typeSystemContext.SystemModule));

                    compilationGroup = new SingleFileCompilationModuleGroup(typeSystemContext);
                }

                foreach (var rdXmlFilePath in _rdXmlFilePaths)
                {
                    compilationRoots.Add(new RdXmlRootProvider(typeSystemContext, rdXmlFilePath));
                }
            }

            //
            // Compile
            //

            CompilationBuilder builder;

            if (_isCppCodegen)
            {
                builder = new CppCodegenCompilationBuilder(typeSystemContext, compilationGroup);
            }
            else
            {
                builder = new RyuJitCompilationBuilder(typeSystemContext, compilationGroup);
            }

            var logger = _isVerbose ? new Logger(Console.Out, true) : Logger.Null;

            DependencyTrackingLevel trackingLevel = _dgmlLogFileName == null ?
                                                    DependencyTrackingLevel.None : (_generateFullDgmlLog ? DependencyTrackingLevel.All : DependencyTrackingLevel.First);

            ICompilation compilation = builder
                                       .UseBackendOptions(_codegenOptions)
                                       .UseLogger(logger)
                                       .UseDependencyTracking(trackingLevel)
                                       .UseCompilationRoots(compilationRoots)
                                       .UseOptimizationMode(_optimizationMode)
                                       .UseDebugInfo(_enableDebugInfo)
                                       .ToCompilation();

            compilation.Compile(_outputFilePath);

            if (_dgmlLogFileName != null)
            {
                compilation.WriteDependencyLog(_dgmlLogFileName);
            }

            return(0);
        }
Beispiel #37
0
 protected override SyntaxNode GetArgumentExpression(ArgumentSyntax argument)
 {
     return(argument.Expression);
 }
 private static HelpPage GetCommandListHelp(ArgumentSyntax argumentSyntax)
 {
     return new HelpPage
     {
         ApplicationName = argumentSyntax.ApplicationName,
         SyntaxElements = GetGlobalSyntax(),
         Rows = GetCommandRows(argumentSyntax).ToArray()
     };
 }
        public void VisitArgument(ArgumentSyntax node)
        {
            if (node == null)
                throw new ArgumentNullException("node");

            node.Validate();

            if (node.NameColon != null)
                node.NameColon.Accept(this);

            switch (node.Modifier)
            {
                case ParameterModifier.Ref:
                    _writer.WriteKeyword(PrinterKeyword.Ref);
                    _writer.WriteSpace();
                    break;

                case ParameterModifier.Out:
                    _writer.WriteKeyword(PrinterKeyword.Out);
                    _writer.WriteSpace();
                    break;
            }

            node.Expression.Accept(this);
        }
 private static HelpPage GetCommandHelp(ArgumentSyntax argumentSyntax, ArgumentCommand command)
 {
     return new HelpPage
     {
         ApplicationName = argumentSyntax.ApplicationName,
         SyntaxElements = GetCommandSyntax(argumentSyntax, command),
         Rows = GetArgumentRows(argumentSyntax, command).ToArray()
     };
 }
Beispiel #41
0
            public Config(string[] args)
            {
                _syntaxResult = ArgumentSyntax.Parse(args, syntax =>
                {
                    // NOTE!!! - Commands and their options are ordered.  Moving an option out of line
                    // could move it to another command.  Take a careful look at how they're organized
                    // before changing.
                    syntax.DefineCommand("list", ref _command, Command.List, 
                        "List jobs on dotnet-ci.cloudapp.net for dotnet_coreclr.");
                    syntax.DefineOption("j|job", ref _jobName, "Name of the job.");
                    syntax.DefineOption("b|branch", ref _coreclrBranchName, 
                        "Name of the branch (dotnet/coreclr, def. is master).");
                    syntax.DefineOption("m|match", ref _matchPattern, 
                        "Regex pattern used to select jobs output.");
                    syntax.DefineOption("n|number", ref _number, "Job number.");
                    syntax.DefineOption("l|last_successful", ref _lastSuccessful, 
                        "List last successful build.");
                    syntax.DefineOption("a|artifacts", ref _artifacts, "List job artifacts on server.");

                    syntax.DefineCommand("copy", ref _command, Command.Copy, 
                        "Copies job artifacts from dotnet-ci.cloudapp.net. " 
                        + "Currently hardcoded to dotnet_coreclr, this command " 
                        + "copies a zip of the artifacts under the Product sub-directory "
                        + "that is the result of a build.");
                    syntax.DefineOption("j|job", ref _jobName, "Name of the job.");
                    syntax.DefineOption("n|number", ref _number, "Job number.");
                    syntax.DefineOption("l|last_successful", ref _lastSuccessful, 
                        "Copy last successful build.");
                    syntax.DefineOption("b|branch", ref _coreclrBranchName, 
                        "Name of branch  (dotnet_coreclr, def. is master)..");
                    syntax.DefineOption("o|output", ref _outputPath, "Output path.");
                    syntax.DefineOption("u|unzip", ref _unzip, "Unzip copied artifacts");
                });

                // Run validation code on parsed input to ensure we have a sensible scenario.
                validate();
            }
Beispiel #42
0
        public override SyntaxNode VisitArgument(ArgumentSyntax node)
        {
            var ti = this.semanticModel.GetTypeInfo(node.Expression);

            ITypeSymbol      type      = null;
            IMethodSymbol    method    = null;
            IParameterSymbol parameter = null;

            if (ti.Type != null && ti.Type.TypeKind == TypeKind.Delegate)
            {
                type = ti.Type;
            }
            else if (ti.ConvertedType != null && ti.ConvertedType.TypeKind == TypeKind.Delegate)
            {
                type = ti.ConvertedType;
            }

            if (type != null)
            {
                var list       = node.Parent as ArgumentListSyntax;
                var invocation = node.Parent.Parent as InvocationExpressionSyntax;

                if (list != null && invocation != null)
                {
                    method = this.semanticModel.GetSymbolInfo(invocation).Symbol as IMethodSymbol;

                    if (method != null)
                    {
                        if (node.NameColon != null)
                        {
                            if (node.NameColon.Name != null)
                            {
                                var nameText = node.NameColon.Name.Identifier.ValueText;
                                if (nameText != null)
                                {
                                    foreach (var p in method.Parameters)
                                    {
                                        if (string.Equals(p.Name, nameText, StringComparison.Ordinal))
                                        {
                                            parameter = p;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            var index = list.Arguments.IndexOf(node);
                            if (index >= 0)
                            {
                                if (index < method.Parameters.Length)
                                {
                                    parameter = method.Parameters[index];
                                }
                                else if (index >= method.Parameters.Length && method.Parameters[method.Parameters.Length - 1].IsParams)
                                {
                                    parameter = method.Parameters[method.Parameters.Length - 1];
                                }
                            }
                        }
                    }
                }
            }
            var isParam = parameter != null && !SyntaxHelper.IsAnonymous(parameter.Type);
            var parent  = isParam && parameter.IsParams ? (InvocationExpressionSyntax)node.Parent.Parent : null;

            node = (ArgumentSyntax)base.VisitArgument(node);

            if (isParam)
            {
                var pType = parameter.Type;
                if (parameter.IsParams && SharpSixRewriter.IsExpandedForm(this.semanticModel, parent, method))
                {
                    pType = ((IArrayTypeSymbol)parameter.Type).ElementType;
                }

                if (node.Expression is CastExpressionSyntax && type.Equals(pType) || parameter.RefKind != RefKind.None)
                {
                    return(node);
                }

                if (pType.TypeKind == TypeKind.Delegate || parameter.IsParams && ((IArrayTypeSymbol)parameter.Type).ElementType.TypeKind == TypeKind.Delegate)
                {
                    var name = SyntaxFactory.IdentifierName(pType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)).WithoutTrivia();
                    var expr = node.Expression;

                    if (expr is LambdaExpressionSyntax || expr is AnonymousMethodExpressionSyntax)
                    {
                        expr = SyntaxFactory.ParenthesizedExpression(expr);
                    }

                    var cast = SyntaxFactory.CastExpression(name, expr);
                    node = node.WithExpression(cast);
                }
            }

            return(node);
        }
 protected Symbol GetSymbol(ArgumentSyntax syntax)
 {
     return GetSymbol(syntax, models);
 }
        private static int? GetConstantArgumentValue(ArgumentSyntax argument, SemanticModel semanticModel)
        {
            var bound = semanticModel.GetConstantValue(argument.GetExpression());
            if (!bound.HasValue)
            {
                return null;
            }

            var boundValue = bound.Value as int?;
            return boundValue;
        }
        private static IEnumerable<string> GetCommandSyntax(ArgumentSyntax argumentSyntax, ArgumentCommand command)
        {
            if (command != null)
                yield return command.Name;

            foreach (var option in argumentSyntax.GetOptions(command).Where(o => !o.IsHidden))
                yield return GetOptionSyntax(option);

            if (argumentSyntax.GetParameters(command).All(p => p.IsHidden))
                yield break;

            if (argumentSyntax.GetOptions(command).Any(o => !o.IsHidden))
                yield return @"[--]";

            foreach (var parameter in argumentSyntax.GetParameters(command).Where(o => !o.IsHidden))
                yield return GetParameterSyntax(parameter);
        }
Beispiel #46
0
 protected virtual void ParseParameters(ArgumentSyntax syntax)
 {
 }
 private static IEnumerable<HelpRow> GetArgumentRows(ArgumentSyntax argumentSyntax, ArgumentCommand command)
 {
     return argumentSyntax.GetArguments(command)
                       .Where(a => !a.IsHidden)
                       .Select(a => new HelpRow { Header = GetArgumentRowHeader(a), Text = a.Help });
 }
Beispiel #48
0
 protected override void ParseParameters(ArgumentSyntax syntax)
 {
     syntax.DefineParameter("path", ref _path, DirectoryPath.FromString, "The path that the server should preview (defaults to \"output\").");
 }
        private static bool IsParamsArgument(InvocationExpressionSyntax invocationExpression, ArgumentSyntax argumentOpt, IMethodSymbol methodSymbol)
        {
            if (argumentOpt == null)
            {
                return(false);
            }

            if (invocationExpression.ArgumentList.Arguments.Any(o => o.NameColon != null))
            {
                return(false);                //params cannot be used with named arguments
            }
            int i = invocationExpression.ArgumentList.Arguments.IndexOf(argumentOpt);

            return(methodSymbol.Parameters.ElementAt(i).IsParams);
        }
Beispiel #50
0
 protected override void ParseParameters(ArgumentSyntax syntax)
 {
     syntax.DefineParameter("path", ref _path, DirectoryPath.FromString, "The path to generate the scaffold in.");
 }
 private static ArgumentSyntax CreateSyntax(IEnumerable<string> arguments, Action<ArgumentSyntax> defineAction)
 {
     var syntax = new ArgumentSyntax(arguments);
     syntax.ApplicationName = "tool";
     defineAction(syntax);
     return syntax;
 }
Beispiel #52
0
        internal static bool TryFindDisposeBoolCall(BaseMethodDeclarationSyntax disposeMethod, SemanticModel semanticModel, CancellationToken cancellationToken, out InvocationExpressionSyntax suppressCall, out ArgumentSyntax argument)
        {
            using (var invocations = InvocationWalker.Borrow(disposeMethod))
            {
                foreach (var candidate in invocations)
                {
                    if (candidate.ArgumentList is ArgumentListSyntax argumentList &&
                        argumentList.Arguments.TrySingle(out argument) &&
                        argument.Expression is ExpressionSyntax expression &&
                        expression.IsEither(SyntaxKind.TrueLiteralExpression, SyntaxKind.FalseLiteralExpression) &&
                        candidate.TryGetMethodName(out var name) &&
                        name == "Dispose")
                    {
                        suppressCall = candidate;
                        return(true);
                    }
                }
            }

            suppressCall = null;
            argument     = null;
            return(false);
        }
Beispiel #53
0
 public static ArgumentSyntax WithRef(this ArgumentSyntax syntax, bool isRef)
 => syntax.WithRefOrOutKeyword(isRef
Beispiel #54
0
        private static int MainInner(string[] args)
        {
            var commandText                       = string.Empty;
            var projectPath                       = string.Empty;
            var versionJsonRoot                   = string.Empty;
            var version                           = string.Empty;
            IReadOnlyList <string> sources        = Array.Empty <string>();
            IReadOnlyList <string> cloudVariables = Array.Empty <string>();
            var    format                         = string.Empty;
            string singleVariable                 = null;
            bool   quiet                          = false;
            var    cisystem                       = string.Empty;
            bool   cloudBuildCommonVars           = false;
            bool   cloudBuildAllVars              = false;
            string releasePreReleaseTag           = null;
            string releaseNextVersion             = null;
            string releaseVersionIncrement        = null;

            ArgumentCommand <string> install        = null;
            ArgumentCommand <string> getVersion     = null;
            ArgumentCommand <string> setVersion     = null;
            ArgumentCommand <string> tag            = null;
            ArgumentCommand <string> getCommits     = null;
            ArgumentCommand <string> cloud          = null;
            ArgumentCommand <string> prepareRelease = null;

            ArgumentSyntax.Parse(args, syntax =>
            {
                install = syntax.DefineCommand("install", ref commandText, "Prepares a project to have version stamps applied using Nerdbank.GitVersioning.");
                syntax.DefineOption("p|path", ref versionJsonRoot, "The path to the directory that should contain the version.json file. The default is the root of the git repo.");
                syntax.DefineOption("v|version", ref version, $"The initial version to set. The default is {DefaultVersionSpec}.");
                syntax.DefineOptionList("s|source", ref sources, $"The URI(s) of the NuGet package source(s) used to determine the latest stable version of the {PackageId} package. This setting overrides all of the sources specified in the NuGet.Config files.");

                getVersion = syntax.DefineCommand("get-version", ref commandText, "Gets the version information for a project.");
                syntax.DefineOption("p|project", ref projectPath, "The path to the project or project directory. The default is the current directory.");
                syntax.DefineOption("f|format", ref format, $"The format to write the version information. Allowed values are: text, json. The default is {DefaultOutputFormat}.");
                syntax.DefineOption("v|variable", ref singleVariable, "The name of just one version property to print to stdout. When specified, the output is always in raw text. Useful in scripts.");
                syntax.DefineParameter("commit-ish", ref version, $"The commit/ref to get the version information for. The default is {DefaultRef}.");

                setVersion = syntax.DefineCommand("set-version", ref commandText, "Updates the version stamp that is applied to a project.");
                syntax.DefineOption("p|project", ref projectPath, "The path to the project or project directory. The default is the root directory of the repo that spans the current directory, or an existing version.json file, if applicable.");
                syntax.DefineParameter("version", ref version, "The version to set.");

                tag = syntax.DefineCommand("tag", ref commandText, "Creates a git tag to mark a version.");
                syntax.DefineOption("p|project", ref projectPath, "The path to the project or project directory. The default is the root directory of the repo that spans the current directory, or an existing version.json file, if applicable.");
                syntax.DefineParameter("versionOrRef", ref version, $"The a.b.c[.d] version or git ref to be tagged. If not specified, {DefaultRef} is used.");

                getCommits = syntax.DefineCommand("get-commits", ref commandText, "Gets the commit(s) that match a given version.");
                syntax.DefineOption("p|project", ref projectPath, "The path to the project or project directory. The default is the root directory of the repo that spans the current directory, or an existing version.json file, if applicable.");
                syntax.DefineOption("q|quiet", ref quiet, "Use minimal output.");
                syntax.DefineParameter("version", ref version, "The a.b.c[.d] version to find.");

                cloud = syntax.DefineCommand("cloud", ref commandText, "Communicates with the ambient cloud build to set the build number and/or other cloud build variables.");
                syntax.DefineOption("p|project", ref projectPath, "The path to the project or project directory used to calculate the version. The default is the current directory. Ignored if the -v option is specified.");
                syntax.DefineOption("v|version", ref version, "The string to use for the cloud build number. If not specified, the computed version will be used.");
                syntax.DefineOption("s|ci-system", ref cisystem, "Force activation for a particular CI system. If not specified, auto-detection will be used. Supported values are: " + string.Join(", ", CloudProviderNames));
                syntax.DefineOption("a|all-vars", ref cloudBuildAllVars, false, "Defines ALL version variables as cloud build variables, with a \"NBGV_\" prefix.");
                syntax.DefineOption("c|common-vars", ref cloudBuildCommonVars, false, "Defines a few common version variables as cloud build variables, with a \"Git\" prefix (e.g. GitBuildVersion, GitBuildVersionSimple, GitAssemblyInformationalVersion).");
                syntax.DefineOptionList("d|define", ref cloudVariables, "Additional cloud build variables to define. Each should be in the NAME=VALUE syntax.");

                prepareRelease = syntax.DefineCommand("prepare-release", ref commandText, "Prepares a release by creating a release branch for the current version and adjusting the version on the current branch.");
                syntax.DefineOption("p|project", ref projectPath, "The path to the project or project directory. The default is the current directory.");
                syntax.DefineOption("nextVersion", ref releaseNextVersion, "The version to set for the current branch. If omitted, the next version is determined automatically by incrementing the current version.");
                syntax.DefineOption("versionIncrement", ref releaseVersionIncrement, "Overrides the 'versionIncrement' setting set in version.json for determining the next version of the current branch.");
                syntax.DefineOption("f|format", ref format, $"The format to write information about the release. Allowed values are: text, json. The default is {DefaultOutputFormat}.");
                syntax.DefineParameter("tag", ref releasePreReleaseTag, "The prerelease tag to apply on the release branch (if any). If not specified, any existing prerelease tag will be removed. The preceding hyphen may be omitted.");

                if (syntax.ActiveCommand == null)
                {
                    Console.WriteLine("nbgv v{0}", ThisAssembly.AssemblyInformationalVersion);
                    Console.WriteLine("Use -h, --help, or -? for usage help. Use after a command to get more help about a particular command.");
                }
            });

            if (install.IsActive)
            {
                exitCode = OnInstallCommand(versionJsonRoot, version, sources);
            }
            else if (getVersion.IsActive)
            {
                exitCode = OnGetVersionCommand(projectPath, format, singleVariable, version);
            }
            else if (setVersion.IsActive)
            {
                exitCode = OnSetVersionCommand(projectPath, version);
            }
            else if (tag.IsActive)
            {
                exitCode = OnTagCommand(projectPath, version);
            }
            else if (getCommits.IsActive)
            {
                exitCode = OnGetCommitsCommand(projectPath, version, quiet);
            }
            else if (cloud.IsActive)
            {
                exitCode = OnCloudCommand(projectPath, version, cisystem, cloudBuildAllVars, cloudBuildCommonVars, cloudVariables);
            }
            else if (prepareRelease.IsActive)
            {
                exitCode = OnPrepareReleaseCommand(projectPath, releasePreReleaseTag, releaseNextVersion, releaseVersionIncrement, format);
            }

            return((int)exitCode);
        }
Beispiel #55
0
 protected virtual void ParseOptions(ArgumentSyntax syntax)
 {
 }
Beispiel #56
0
        private ArgumentSyntax ParseCommandLine(string[] args)
        {
            IReadOnlyList <string> inputFiles     = Array.Empty <string>();
            IReadOnlyList <string> referenceFiles = Array.Empty <string>();

            bool optimize      = false;
            bool optimizeSpace = false;
            bool optimizeTime  = false;

            bool           waitForDebugger = false;
            AssemblyName   name            = typeof(Program).GetTypeInfo().Assembly.GetName();
            ArgumentSyntax argSyntax       = ArgumentSyntax.Parse(args, syntax =>
            {
                syntax.ApplicationName = name.Name.ToString();

                // HandleHelp writes to error, fails fast with crash dialog and lacks custom formatting.
                syntax.HandleHelp   = false;
                syntax.HandleErrors = true;

                syntax.DefineOption("h|help", ref _help, "Help message for ILC");
                syntax.DefineOptionList("r|reference", ref referenceFiles, "Reference file(s) for compilation");
                syntax.DefineOption("o|out", ref _outputFilePath, "Output file path");
                syntax.DefineOption("O", ref optimize, "Enable optimizations");
                syntax.DefineOption("Os", ref optimizeSpace, "Enable optimizations, favor code space");
                syntax.DefineOption("Ot", ref optimizeTime, "Enable optimizations, favor code speed");
                syntax.DefineOption("inputbubble", ref _isInputVersionBubble, "True when the entire input forms a version bubble (default = per-assembly bubble)");
                syntax.DefineOption("tuning", ref _tuning, "Generate IBC tuning image");
                syntax.DefineOption("compilebubblegenerics", ref _includeGenericsFromVersionBubble, "Compile instantiations from reference modules used in the current module");
                syntax.DefineOption("dgmllog", ref _dgmlLogFileName, "Save result of dependency analysis as DGML");
                syntax.DefineOption("fulllog", ref _generateFullDgmlLog, "Save detailed log of dependency analysis");
                syntax.DefineOption("verbose", ref _isVerbose, "Enable verbose logging");
                syntax.DefineOption("systemmodule", ref _systemModuleName, "System module name (default: System.Private.CoreLib)");
                syntax.DefineOption("waitfordebugger", ref waitForDebugger, "Pause to give opportunity to attach debugger");
                syntax.DefineOptionList("codegenopt", ref _codegenOptions, "Define a codegen option");

                syntax.DefineOption("targetarch", ref _targetArchitectureStr, "Target architecture for cross compilation");
                syntax.DefineOption("targetos", ref _targetOSStr, "Target OS for cross compilation");

                syntax.DefineOption("singlemethodtypename", ref _singleMethodTypeName, "Single method compilation: name of the owning type");
                syntax.DefineOption("singlemethodname", ref _singleMethodName, "Single method compilation: name of the method");
                syntax.DefineOptionList("singlemethodgenericarg", ref _singleMethodGenericArgs, "Single method compilation: generic arguments to the method");

                syntax.DefineParameterList("in", ref inputFiles, "Input file(s) to compile");
            });

            if (waitForDebugger)
            {
                Console.WriteLine("Waiting for debugger to attach. Press ENTER to continue");
                Console.ReadLine();
            }

            if (_includeGenericsFromVersionBubble)
            {
                if (!_isInputVersionBubble)
                {
                    Console.WriteLine("Warning: ignoring --compilebubblegenerics because --inputbubble was not specified");
                    _includeGenericsFromVersionBubble = false;
                }
            }

            _optimizationMode = OptimizationMode.None;
            if (optimizeSpace)
            {
                if (optimizeTime)
                {
                    Console.WriteLine("Warning: overriding -Ot with -Os");
                }
                _optimizationMode = OptimizationMode.PreferSize;
            }
            else if (optimizeTime)
            {
                _optimizationMode = OptimizationMode.PreferSpeed;
            }
            else if (optimize)
            {
                _optimizationMode = OptimizationMode.Blended;
            }

            foreach (var input in inputFiles)
            {
                Helpers.AppendExpandedPaths(_inputFilePaths, input, true);
            }

            foreach (var reference in referenceFiles)
            {
                Helpers.AppendExpandedPaths(_referenceFilePaths, reference, false);
            }

            return(argSyntax);
        }
        public static CommonCompilerOptions Parse(ArgumentSyntax syntax)
        {
            IReadOnlyList<string> defines = null;
            IReadOnlyList<string> suppressWarnings = null;
            string languageVersion = null;
            string platform = null;
            string debugType = null;
            bool? allowUnsafe = null;
            bool? warningsAsErrors = null;
            bool? optimize = null;
            string keyFile = null;
            bool? delaySign = null;
            bool? publicSign = null;
            bool? emitEntryPoint = null;
            bool? generateXmlDocumentation = null;
            string outputName = null;
            IReadOnlyList<string> additionalArguments = null;

            Func<string, bool?> nullableBoolConverter = v => bool.Parse(v);

            syntax.DefineOptionList(s_definesTemplate.LongName, ref defines, "Preprocessor definitions");

            syntax.DefineOptionList(s_suppressWarningTemplate.LongName, ref suppressWarnings, "Suppresses the specified warning");

            syntax.DefineOptionList(s_additionalArgumentsTemplate.LongName, ref additionalArguments, "Pass the additional argument directly to the compiler");

            syntax.DefineOption(s_debugTypeTemplate.LongName, ref debugType, "The type of PDB to emit: portable or full");

            syntax.DefineOption(s_languageVersionTemplate.LongName, ref languageVersion,
                    "The version of the language used to compile");

            syntax.DefineOption(s_platformTemplate.LongName, ref platform,
                    "The target platform");

            syntax.DefineOption(s_allowUnsafeTemplate.LongName, ref allowUnsafe,
                    nullableBoolConverter, "Allow unsafe code");

            syntax.DefineOption(s_warningsAsErrorsTemplate.LongName, ref warningsAsErrors,
                    nullableBoolConverter, "Turn all warnings into errors");

            syntax.DefineOption(s_optimizeTemplate.LongName, ref optimize,
                    nullableBoolConverter, "Enable compiler optimizations");

            syntax.DefineOption(s_keyFileTemplate.LongName, ref keyFile,
                    "Path to file containing the key to strong-name sign the output assembly");

            syntax.DefineOption(s_delaySignTemplate.LongName, ref delaySign,
                    nullableBoolConverter, "Delay-sign the output assembly");

            syntax.DefineOption(s_publicSignTemplate.LongName, ref publicSign,
                    nullableBoolConverter, "Public-sign the output assembly");

            syntax.DefineOption(s_emitEntryPointTemplate.LongName, ref emitEntryPoint,
                    nullableBoolConverter, "Output an executable console program");

            syntax.DefineOption(s_generateXmlDocumentation.LongName, ref generateXmlDocumentation,
                    nullableBoolConverter, "Generate XML documentation file");

            syntax.DefineOption(s_outputNameTemplate.LongName, ref outputName, "Output assembly name");

            return new CommonCompilerOptions
            {
                Defines = defines,
                SuppressWarnings = suppressWarnings,
                LanguageVersion = languageVersion,
                Platform = platform,
                AllowUnsafe = allowUnsafe,
                WarningsAsErrors = warningsAsErrors,
                Optimize = optimize,
                KeyFile = keyFile,
                DelaySign = delaySign,
                PublicSign = publicSign,
                DebugType = debugType,
                EmitEntryPoint = emitEntryPoint,
                GenerateXmlDocumentation = generateXmlDocumentation,
                OutputName = outputName,
                AdditionalArguments = additionalArguments
            };
        }
Beispiel #58
0
 protected override void ParseOptions(ArgumentSyntax syntax)
 {
     syntax.DefineOption("p|port", ref _port, "Start the preview web server on the specified port (default is " + _port + ").");
     syntax.DefineOption("force-ext", ref _forceExtension, "Force the use of extensions in the preview web server (by default, extensionless URLs may be used).");
 }