/// <summary>
        ///
        /// </summary>
        /// <param name="sourceFile"></param>
        /// <param name="profile"></param>
        /// <param name="entryPoint"></param>
        /// <param name="defines"></param>
        /// <returns></returns>
        byte[] RunFxc(Parameters param, string sourceFile, string profile, string entryPoint, string defines, string output, string listing)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("/Cc" + " ");
            sb.Append("/T" + profile + " ");
            sb.Append("/E" + entryPoint + " ");
            sb.Append("/Fo\"" + output + "\" ");
            sb.Append("/Fc\"" + listing + "\" ");
            sb.Append("/nologo" + " ");
            sb.Append("/O" + OptimizationLevel.ToString() + " ");

            if (DisableOptimization)
            {
                sb.Append("/Od ");
            }
            if (PreferFlowControl)
            {
                sb.Append("/Gfp ");
            }
            if (AvoidFlowControl)
            {
                sb.Append("/Gfa ");
            }

            if (MatrixPacking == ShaderMatrixPacking.ColumnMajor)
            {
                sb.Append("/Zpc ");
            }
            if (MatrixPacking == ShaderMatrixPacking.RowMajor)
            {
                sb.Append("/Zpr ");
            }

            foreach (var def in defines.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries))
            {
                sb.AppendFormat("/D{0}=1 ", def);
            }

            sb.Append("\"" + buildContext.Resolve(sourceFile) + "\"");

            try {
                buildContext.RunTool("fxc_1.exe", sb.ToString());
            } catch (ToolException tx) {
                ///	entry point not fount - that is ok.
                if (tx.Message.Contains("error X3501"))
                {
                    Log.Debug("No entry point '{0}'. That is ok.", entryPoint);
                    return(new byte[0]);
                }

                throw;
            }

            return(File.ReadAllBytes(output));
        }
Example #2
0
        private static async Task <MirrorSharpTestDriver> NewTestDriverAsync(TestData data, OptimizationLevel optimizationLevel = OptimizationLevel.Release)
        {
            var driver = MirrorSharpTestDriver.New(MirrorSharpOptions);
            await driver.SendSetOptionsAsync(new Dictionary <string, string> {
                { "language", data.SourceLanguageName },
                { "optimize", optimizationLevel.ToString().ToLowerInvariant() },
                { "x-target", data.TargetLanguageName }
            });

            driver.SetText(data.Original);
            return(driver);
        }
Example #3
0
        /// <summary>
        /// Converts a optimization level enum value to JSON
        /// </summary>
        /// <param name="optimizationLevel">Optimization level enum value</param>
        /// <param name="level1OptimizationOptions">Level 1 optimization options</param>
        /// <param name="level2OptimizationOptions">Level 2 optimization options</param>
        /// <returns>Optimization level in JSON format</returns>
        internal static JToken ConvertOptimizationLevelEnumValueToJson(OptimizationLevel optimizationLevel,
                                                                       Level1OptimizationOptions level1OptimizationOptions, Level2OptimizationOptions level2OptimizationOptions)
        {
            JToken optimizationLevelJson;

            if (optimizationLevel == OptimizationLevel.Zero)
            {
                optimizationLevelJson = new JValue("0");
            }
            else if (optimizationLevel == OptimizationLevel.One || optimizationLevel == OptimizationLevel.Two)
            {
                var jObj = new JObject();
                jObj.Add("1", new JObject(
                             new JProperty("cleanupCharsets", level1OptimizationOptions.CleanupCharsets),
                             new JProperty("normalizeUrls", level1OptimizationOptions.NormalizeUrls),
                             new JProperty("optimizeBackground", level1OptimizationOptions.OptimizeBackground),
                             new JProperty("optimizeBorderRadius", level1OptimizationOptions.OptimizeBorderRadius),
                             new JProperty("optimizeFilter", level1OptimizationOptions.OptimizeFilter),
                             new JProperty("optimizeFont", level1OptimizationOptions.OptimizeFont),
                             new JProperty("optimizeFontWeight", level1OptimizationOptions.OptimizeFontWeight),
                             new JProperty("optimizeOutline", level1OptimizationOptions.OptimizeOutline),
                             new JProperty("removeEmpty", level1OptimizationOptions.RemoveEmpty),
                             new JProperty("removeNegativePaddings", level1OptimizationOptions.RemoveNegativePaddings),
                             new JProperty("removeQuotes", level1OptimizationOptions.RemoveQuotes),
                             new JProperty("removeWhitespace", level1OptimizationOptions.RemoveWhitespace),
                             new JProperty("replaceMultipleZeros", level1OptimizationOptions.ReplaceMultipleZeros),
                             new JProperty("replaceTimeUnits", level1OptimizationOptions.ReplaceTimeUnits),
                             new JProperty("replaceZeroUnits", level1OptimizationOptions.ReplaceZeroUnits),
                             new JProperty("roundingPrecision",
                                           ParseRoundingPrecision(level1OptimizationOptions.RoundingPrecision)),
                             new JProperty("selectorsSortingMethod", ConvertSelectorsSortingMethodEnumValueToCode(
                                               level1OptimizationOptions.SelectorsSortingMethod)),
                             new JProperty("specialComments", level1OptimizationOptions.SpecialComments),
                             new JProperty("tidyAtRules", level1OptimizationOptions.TidyAtRules),
                             new JProperty("tidyBlockScopes", level1OptimizationOptions.TidyBlockScopes),
                             new JProperty("tidySelectors", level1OptimizationOptions.TidySelectors)
                             ));

                if (optimizationLevel == OptimizationLevel.Two)
                {
                    jObj.Add("2", new JObject(
                                 new JProperty("mergeAdjacentRules", level2OptimizationOptions.MergeAdjacentRules),
                                 new JProperty("mergeIntoShorthands", level2OptimizationOptions.MergeIntoShorthands),
                                 new JProperty("mergeMedia", level2OptimizationOptions.MergeMedia),
                                 new JProperty("mergeNonAdjacentRules", level2OptimizationOptions.MergeNonAdjacentRules),
                                 new JProperty("mergeSemantically", level2OptimizationOptions.MergeSemantically),
                                 new JProperty("overrideProperties", level2OptimizationOptions.OverrideProperties),
                                 new JProperty("removeEmpty", level2OptimizationOptions.RemoveEmpty),
                                 new JProperty("reduceNonAdjacentRules", level2OptimizationOptions.ReduceNonAdjacentRules),
                                 new JProperty("removeDuplicateFontRules", level2OptimizationOptions.RemoveDuplicateFontRules),
                                 new JProperty("removeDuplicateMediaBlocks", level2OptimizationOptions.RemoveDuplicateMediaBlocks),
                                 new JProperty("removeDuplicateRules", level2OptimizationOptions.RemoveDuplicateRules),
                                 new JProperty("removeUnusedAtRules", level2OptimizationOptions.RemoveUnusedAtRules),
                                 new JProperty("restructureRules", level2OptimizationOptions.RestructureRules),
                                 new JProperty("skipProperties", ParseSkippingProperties(level2OptimizationOptions.SkipProperties))
                                 ));
                }

                optimizationLevelJson = jObj;
            }
            else
            {
                throw new InvalidCastException(string.Format(CoreStrings.Common_EnumValueToCodeConversionFailed,
                                                             optimizationLevel.ToString(), typeof(OptimizationLevel)));
            }

            return(optimizationLevelJson);
        }
Example #4
0
        internal override void ValidateOptions(ArrayBuilder <Diagnostic> builder)
        {
            ValidateOptions(builder, MessageProvider.Instance);

            //  /main & /target:{library|netmodule|winmdobj}
            if (this.MainTypeName != null)
            {
                if (this.OutputKind.IsValid() && !this.OutputKind.IsApplication())
                {
                    builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_NoMainOnDLL));
                }

                if (!MainTypeName.IsValidClrTypeName())
                {
                    builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(MainTypeName), MainTypeName));
                }
            }

            if (!Platform.IsValid())
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadPlatformType, Platform.ToString()));
            }

            if (ModuleName != null)
            {
                MetadataHelpers.CheckAssemblyOrModuleName(ModuleName, MessageProvider.Instance, (int)ErrorCode.ERR_BadModuleName, builder);
            }

            if (!OutputKind.IsValid())
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(OutputKind), OutputKind.ToString()));
            }

            if (!OptimizationLevel.IsValid())
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(OptimizationLevel), OptimizationLevel.ToString()));
            }

            if (ScriptClassName == null || !ScriptClassName.IsValidClrTypeName())
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(ScriptClassName), ScriptClassName ?? "null"));
            }

            if (WarningLevel < 0 || WarningLevel > 4)
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(WarningLevel), WarningLevel));
            }

            if (Usings != null && Usings.Any(u => !u.IsValidClrNamespaceName()))
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(Usings), Usings.Where(u => !u.IsValidClrNamespaceName()).First() ?? "null"));
            }

            if (Platform == Platform.AnyCpu32BitPreferred && OutputKind.IsValid() && !(OutputKind == OutputKind.ConsoleApplication || OutputKind == OutputKind.WindowsApplication || OutputKind == OutputKind.WindowsRuntimeApplication))
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadPrefer32OnLib));
            }

            if (!MetadataImportOptions.IsValid())
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(MetadataImportOptions), MetadataImportOptions.ToString()));
            }

            // TODO: add check for
            //          (kind == 'arm' || kind == 'appcontainer' || kind == 'winmdobj') &&
            //          (version >= "6.2")
        }
Example #5
0
        private bool ExecuteInner()
        {
            StringBuilder sb = new StringBuilder();

            if (ConfigFlags.Length > 0)
            {
                sb.AppendFormat(" --cfg {0}", String.Join(",", ConfigFlags));
            }
            if (AdditionalLibPaths.Length > 0)
            {
                sb.AppendFormat(" -L {0}", String.Join(",", AdditionalLibPaths));
            }
            if (CrateType.Length > 0)
            {
                sb.AppendFormat(" --crate-type {0}", String.Join(",", CrateType));
            }
            if (Emit.Length > 0)
            {
                sb.AppendFormat(" --emit {0}", String.Join(",", Emit));
            }
            if (!String.IsNullOrWhiteSpace(CrateName))
            {
                sb.AppendFormat(" --crate-name {0}", CrateName);
            }
            if (DebugInfo)
            {
                sb.AppendFormat(" -g");
            }
            if (OutputFile != null)
            {
                sb.AppendFormat(" -o {0}", OutputFile);
            }
            if (optimizationLevel.HasValue)
            {
                sb.AppendFormat(" -C opt-level={0}", Shared.OptimizationLevelExtension.Parse(OptimizationLevel.ToString()).ToBuildString());
            }
            if (OutputDirectory != null)
            {
                sb.AppendFormat(" --out-dir {0}", OutputDirectory);
            }
            if (test.HasValue && test.Value)
            {
                sb.Append(" --test");
            }
            if (TargetTriple != null && !String.Equals(TargetTriple, Shared.Environment.DefaultTarget, StringComparison.OrdinalIgnoreCase))
            {
                sb.AppendFormat(" --target {0}", TargetTriple);
            }
            if (LintsAsWarnings.Length > 0)
            {
                sb.AppendFormat(" -W {0}", String.Join(",", LintsAsWarnings));
            }
            if (LintsAsAllowed.Length > 0)
            {
                sb.AppendFormat(" -A {0}", String.Join(",", LintsAsAllowed));
            }
            if (LintsAsDenied.Length > 0)
            {
                sb.AppendFormat(" -D {0}", String.Join(",", LintsAsDenied));
            }
            if (LintsAsForbidden.Length > 0)
            {
                sb.AppendFormat(" -F {0}", String.Join(",", LintsAsForbidden));
            }
            if (lto.HasValue && lto.Value)
            {
                sb.AppendFormat(" -C lto");
            }
            if (CodegenOptions != null)
            {
                sb.AppendFormat(" -C {0}", CodegenOptions);
            }
            sb.AppendFormat(" {0}", Input);
            string target      = TargetTriple ?? Shared.Environment.DefaultTarget;
            string installPath = Shared.Environment.FindInstallPath(target);

            if (installPath == null)
            {
                if (String.Equals(target, Shared.Environment.DefaultTarget, StringComparison.OrdinalIgnoreCase))
                {
                    Log.LogError("No Rust installation detected. You can download official Rust installer from https://www.rust-lang.org/downloads.html");
                }
                else
                {
                    Log.LogError("Could not find a Rust installation that can compile target {0}.", target);
                }
                return(false);
            }
            var psi = new ProcessStartInfo()
            {
                CreateNoWindow        = true,
                FileName              = Path.Combine(installPath, "rustc.exe"),
                UseShellExecute       = false,
                WorkingDirectory      = WorkingDirectory,
                Arguments             = sb.ToString(),
                RedirectStandardError = true
            };

            Log.LogCommandLine(String.Join(" ", psi.FileName, psi.Arguments));
            try
            {
                Process process = new Process();
                process.StartInfo = psi;
                StringBuilder error = new StringBuilder();

                using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false))
                {
                    process.ErrorDataReceived += (sender, e) =>
                    {
                        if (e.Data == null)
                        {
                            errorWaitHandle.Set();
                        }
                        else
                        {
                            error.AppendLine(e.Data);
                        }
                    };

                    process.Start();
                    process.BeginErrorReadLine();
                    process.WaitForExit();
                    errorWaitHandle.WaitOne();
                }

                string errorOutput = error.ToString();
                // We found some warning or errors in the output, print them out
                IEnumerable <RustcParsedMessage> messages = ParseOutput(errorOutput);
                // We found some warning or errors in the output, print them out
                foreach (RustcParsedMessage msg in messages)
                {
                    LogRustcMessage(msg);
                }
                // rustc failed but we couldn't sniff anything from stderr
                // this could be an internal compiler error or a missing main() function (there are probably more errors without spans)
                if (process.ExitCode != 0 && !messages.Any())
                {
                    // FIXME: This automatically sets the file to VisualRust.Rust.targets. Is there a way to set no file instead?
                    this.Log.LogError(errorOutput);
                    return(false);
                }
                return(process.ExitCode == 0);
            }
            catch (Exception ex)
            {
                Log.LogErrorFromException(ex, true);
                return(false);
            }
        }
Example #6
0
        /// <summary>
        /// Inspects the project.assets.json file in a .NET Core project and attempts to determine
        /// which .dll files are referenced in its compilation
        /// </summary>
        public static string[] FindReferencedAssemblies(string copyFromProjectRoot, OptimizationLevel optimizationLevel)
        {
            var assetsJsonPath = Path.Combine(copyFromProjectRoot, "obj", "project.assets.json");

            if (!File.Exists(assetsJsonPath))
            {
                throw new FileNotFoundException($"Cannot local project assets file. Maybe the referenced project hasn't been restored yet. Searched for: {assetsJsonPath}");
            }

            var assetsInfo     = (JsonDict)Json.Deserialize(File.ReadAllText(assetsJsonPath));
            var packageFolders = ((JsonDict)assetsInfo["packageFolders"]).Keys.ToList();

            if (!packageFolders.Any())
            {
                throw new InvalidDataException($"Expected to find package folders, but found none.");
            }

            var targets = ((JsonDict)assetsInfo["targets"]);

            if (targets.Count != 1)
            {
                throw new InvalidDataException($"Expected to find exactly 1 target, but found {targets.Count}.");
            }
            var target = (Dictionary <string, object>)targets.Values.Single();

            var project    = (JsonDict)assetsInfo["project"];
            var frameworks = ((JsonDict)project["frameworks"]);

            if (frameworks.Count != 1)
            {
                throw new InvalidDataException($"Expected to find exactly 1 frameworks, but found {frameworks.Count}.");
            }
            var framework = frameworks.Single();
            var binDir    = Path.Combine(copyFromProjectRoot, "bin", optimizationLevel.ToString(), framework.Key);

            var referenceAssemblies = target.SelectMany(referenceKvp =>
            {
                var reference = (JsonDict)referenceKvp.Value;
                if (reference.TryGetValue("compile", out var compileInfo))
                {
                    var compileItems  = ((JsonDict)compileInfo).Keys.Where(item => item.EndsWith(".dll"));
                    var referenceType = (string)reference["type"];
                    if (referenceType == "package")
                    {
                        var packageNameAndVersion = referenceKvp.Key;

                        return(compileItems.Select(item =>
                        {
                            var partialPath = Path.Combine(packageNameAndVersion, item);
                            foreach (var packageFolder in packageFolders)
                            {
                                var candidateFilename = Path.Combine(packageFolder, partialPath);
                                if (File.Exists(candidateFilename))
                                {
                                    return candidateFilename;
                                }
                            }

                            throw new InvalidDataException($"Could not find {partialPath} in any of the package folders:\n{string.Join('\n', packageFolders)}");
                        }));
                    }
                    else if (referenceType == "project")
                    {
                        return(compileItems.Select(item => item.Replace("bin/placeholder", binDir)));
                    }
                }

                return(Enumerable.Empty <string>());
            });

            return(referenceAssemblies
                   .Select(path => path.Replace('/', Path.DirectorySeparatorChar))
                   .Distinct(new FilenameComparer()) // TODO: Make sure you pick the most recent version of each assembly, not just an arbitrary one
                   .ToArray());
        }
Example #7
0
        private bool ExecuteInner()
        {
            var useJsonErrorFormat = rustcVersion.Major >= 1 && rustcVersion.Minor >= 12;

            StringBuilder sb = new StringBuilder();

            if (ConfigFlags.Length > 0)
            {
                sb.AppendFormat(" --cfg {0}", String.Join(",", ConfigFlags));
            }
            if (AdditionalLibPaths.Length > 0)
            {
                sb.AppendFormat(" -L {0}", String.Join(",", AdditionalLibPaths));
            }
            if (CrateType.Length > 0)
            {
                sb.AppendFormat(" --crate-type {0}", String.Join(",", CrateType));
            }
            if (Emit.Length > 0)
            {
                sb.AppendFormat(" --emit {0}", String.Join(",", Emit));
            }
            if (!String.IsNullOrWhiteSpace(CrateName))
            {
                sb.AppendFormat(" --crate-name {0}", CrateName);
            }
            if (DebugInfo)
            {
                sb.AppendFormat(" -g");
            }
            if (OutputFile != null)
            {
                sb.AppendFormat(" -o {0}", OutputFile);
            }
            if (optimizationLevel.HasValue)
            {
                sb.AppendFormat(" -C opt-level={0}", Shared.OptimizationLevelExtension.Parse(OptimizationLevel.ToString()).ToBuildString());
            }
            if (OutputDirectory != null)
            {
                sb.AppendFormat(" --out-dir {0}", OutputDirectory);
            }
            if (test.HasValue && test.Value)
            {
                sb.Append(" --test");
            }
            if (TargetTriple != null && !String.Equals(TargetTriple, Shared.Environment.DefaultTarget, StringComparison.OrdinalIgnoreCase))
            {
                sb.AppendFormat(" --target {0}", TargetTriple);
            }
            if (LintsAsWarnings.Length > 0)
            {
                sb.AppendFormat(" -W {0}", String.Join(",", LintsAsWarnings));
            }
            if (LintsAsAllowed.Length > 0)
            {
                sb.AppendFormat(" -A {0}", String.Join(",", LintsAsAllowed));
            }
            if (LintsAsDenied.Length > 0)
            {
                sb.AppendFormat(" -D {0}", String.Join(",", LintsAsDenied));
            }
            if (LintsAsForbidden.Length > 0)
            {
                sb.AppendFormat(" -F {0}", String.Join(",", LintsAsForbidden));
            }
            if (lto.HasValue && lto.Value)
            {
                sb.AppendFormat(" -C lto");
            }
            if (CodegenOptions != null)
            {
                sb.AppendFormat(" -C {0}", CodegenOptions);
            }
            if (useJsonErrorFormat)
            {
                sb.Append(" --error-format=json");
            }
            sb.AppendFormat(" {0}", Input);

            var process = CreateProcess(sb.ToString());

            Log.LogCommandLine(String.Join(" ", process.StartInfo.FileName, process.StartInfo.Arguments));
            try
            {
                StringBuilder error = new StringBuilder();

                using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false))
                {
                    process.ErrorDataReceived += (sender, e) =>
                    {
                        if (e.Data == null)
                        {
                            errorWaitHandle.Set();
                        }
                        else
                        {
                            error.AppendLine(e.Data);
                        }
                    };

                    process.Start();
                    process.BeginErrorReadLine();
                    process.WaitForExit();
                    errorWaitHandle.WaitOne();
                }

                string errorOutput = error.ToString();
                // We found some warning or errors in the output, print them out
                IEnumerable <RustcMessageHuman> messagesHuman = null;
                IEnumerable <RustcMessageJson>  messageJson   = null;
                bool haveAnyMessages = false;

                if (useJsonErrorFormat)
                {
                    messageJson = RustcMessageJsonParser.Parse(errorOutput);
                    foreach (var msg in messageJson)
                    {
                        LogRustcMessage(msg, WorkingDirectory, Log);
                        haveAnyMessages = true;
                    }
                }
                else
                {
                    messagesHuman = RustcMessageHumanParser.Parse(errorOutput);
                    foreach (var msg in messagesHuman)
                    {
                        LogRustcMessage(msg);
                        haveAnyMessages = true;
                    }
                }

                // rustc failed but we couldn't sniff anything from stderr
                // this could be an internal compiler error or a missing main() function (there are probably more errors without spans)
                if (process.ExitCode != 0 && !haveAnyMessages)
                {
                    // FIXME: This automatically sets the file to VisualRust.Rust.targets. Is there a way to set no file instead?
                    this.Log.LogError(errorOutput);
                    return(false);
                }
                return(process.ExitCode == 0);
            }
            catch (Exception ex)
            {
                Log.LogErrorFromException(ex, true);
                return(false);
            }
        }
Example #8
0
        internal override void ValidateOptions(ArrayBuilder <Diagnostic> builder)
        {
            ValidateOptions(builder, MessageProvider.Instance);

            //  /main & /target:{library|netmodule|winmdobj}
            if (this.MainTypeName != null)
            {
                if (this.OutputKind.IsValid() && !this.OutputKind.IsApplication())
                {
                    builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_NoMainOnDLL));
                }

                if (!MainTypeName.IsValidClrTypeName())
                {
                    builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(MainTypeName), MainTypeName));
                }
            }

            if (!Platform.IsValid())
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadPlatformType, Platform.ToString()));
            }

            if (ModuleName != null)
            {
                MetadataHelpers.CheckAssemblyOrModuleName(ModuleName, MessageProvider.Instance, (int)ErrorCode.ERR_BadModuleName, builder);
            }

            if (!OutputKind.IsValid())
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(OutputKind), OutputKind.ToString()));
            }

            if (!OptimizationLevel.IsValid())
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(OptimizationLevel), OptimizationLevel.ToString()));
            }

            if (ScriptClassName == null || !ScriptClassName.IsValidClrTypeName())
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(ScriptClassName), ScriptClassName ?? "null"));
            }

            if (WarningLevel < 0)
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(WarningLevel), WarningLevel));
            }

            if (Usings != null && Usings.Any(static u => !u.IsValidClrNamespaceName()))
        internal override void ValidateOptions(ArrayBuilder <Diagnostic> builder)
        {
            //  /main & /target:{library|netmodule|winmdobj}
            if (this.MainTypeName != null)
            {
                if (this.OutputKind.IsValid() && !this.OutputKind.IsApplication())
                {
                    builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_NoMainOnDLL));
                }

                if (!MainTypeName.IsValidClrTypeName())
                {
                    builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, "MainTypeName", MainTypeName));
                }
            }

            if (FileAlignment != 0 && !IsValidFileAlignment(FileAlignment))
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadFileAlignment, FileAlignment));
            }

            if (!Platform.IsValid())
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadPlatformType, Platform.ToString()));
            }

            if (ModuleName != null)
            {
                Exception e = MetadataHelpers.CheckAssemblyOrModuleName(ModuleName, "ModuleName");
                if (e != null)
                {
                    builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOption, e.Message));
                }
            }

            if (!OutputKind.IsValid())
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, "OutputKind", OutputKind.ToString()));
            }

            if (!OptimizationLevel.IsValid())
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, "OptimizationLevel", OptimizationLevel.ToString()));
            }

            if (!SubsystemVersion.Equals(SubsystemVersion.None) && !SubsystemVersion.IsValid)
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadSubsystemVersion, SubsystemVersion.ToString()));
            }

            if (ScriptClassName == null || !ScriptClassName.IsValidClrTypeName())
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, "ScriptClassName", ScriptClassName ?? "null"));
            }

            if (WarningLevel < 0 || WarningLevel > 4)
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, "WarningLevel", WarningLevel));
            }

            if (Usings != null && Usings.Any(u => !u.IsValidClrNamespaceName()))
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, "Usings", Usings.Where(u => !u.IsValidClrNamespaceName()).First() ?? "null"));
            }

            if (Platform == Platform.AnyCpu32BitPreferred && OutputKind.IsValid() && !(OutputKind == OutputKind.ConsoleApplication || OutputKind == OutputKind.WindowsApplication || OutputKind == OutputKind.WindowsRuntimeApplication))
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadPrefer32OnLib));
            }

            // TODO: add check for
            //          (kind == 'arm' || kind == 'appcontainer' || kind == 'winmdobj') &&
            //          (version >= "6.2")
        }