The Labs \ Source Viewer \ SSCLI \ Microsoft.JScript \ VsaSite

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. namespace Microsoft.JScript
  16. {
  17.    
  18.     using System;
  19.     using System.CodeDom;
  20.     using System.CodeDom.Compiler;
  21.     using System.Collections;
  22.     using System.Collections.Specialized;
  23.     using System.Globalization;
  24.     using System.IO;
  25.     using System.Reflection;
  26.     using System.Reflection.Emit;
  27.     using System.Text;
  28.     using System.Text.RegularExpressions;
  29.     using Microsoft.JScript.Vsa;
  30.     using Microsoft.Vsa;
  31.    
  32.     internal class JSInProcCompiler
  33.     {
  34.         private int codeItemCounter = 0;
  35.         private string debugCommandLine = null;
  36.        
  37.         private void AddAssemblyReference(IVsaEngine engine, string filename)
  38.         {
  39.             IVsaReferenceItem item;
  40.             item = (IVsaReferenceItem)engine.Items.CreateItem(filename, VsaItemType.Reference, VsaItemFlag.None);
  41.             item.AssemblyName = filename;
  42.         }
  43.        
  44.         private void AddDefinition(string def, Hashtable definitions, VsaEngine engine)
  45.         {
  46.             int equalsIndex = def.IndexOf("=");
  47.             string key;
  48.             string strValue;
  49.             object value = null;
  50.             if (equalsIndex == -1) {
  51.                 key = def.Trim();
  52.                 value = true;
  53.             }
  54.             else {
  55.                 key = def.Substring(0, equalsIndex).Trim();
  56.                 strValue = def.Substring(equalsIndex + 1).Trim();
  57.                 if (String.Compare(strValue, "true", StringComparison.OrdinalIgnoreCase) == 0)
  58.                     value = true;
  59.                 else if (String.Compare(strValue, "false", StringComparison.OrdinalIgnoreCase) == 0)
  60.                     value = false;
  61.                 else {
  62.                     try {
  63.                         value = Int32.Parse(strValue, CultureInfo.InvariantCulture);
  64.                     }
  65.                     catch {
  66.                         throw new CmdLineException(CmdLineError.InvalidDefinition, key, engine.ErrorCultureInfo);
  67.                     }
  68.                 }
  69.             }
  70.             if (key.Length == 0)
  71.                 throw new CmdLineException(CmdLineError.MissingDefineArgument, engine.ErrorCultureInfo);
  72.             definitions[key] = value;
  73.         }
  74.        
  75.         private void AddResourceFile(ResInfo resinfo, Hashtable resources, Hashtable resourceFiles, VsaEngine engine)
  76.         {
  77.             if (!File.Exists(resinfo.fullpath))
  78.                 throw new CmdLineException(CmdLineError.ManagedResourceNotFound, resinfo.filename, engine.ErrorCultureInfo);
  79.             // duplicate resource references are an error - either linking and embedding the same
  80.             // file, naming two resources the same, or linking or embedding a file more than once
  81.             if (resourceFiles[resinfo.fullpath] != null)
  82.                 throw new CmdLineException(CmdLineError.DuplicateResourceFile, resinfo.filename, engine.ErrorCultureInfo);
  83.             if (resources[resinfo.name] != null)
  84.                 throw new CmdLineException(CmdLineError.DuplicateResourceName, resinfo.name, engine.ErrorCultureInfo);
  85.             resources[resinfo.name] = resinfo;
  86.             resourceFiles[resinfo.fullpath] = resinfo;
  87.         }
  88.        
  89.         private void AddSourceFile(VsaEngine engine, string filename)
  90.         {
  91.             IVsaCodeItem item;
  92.             string name = "$SourceFile_" + this.codeItemCounter++;
  93.             item = (IVsaCodeItem)engine.Items.CreateItem(name, VsaItemType.Code, VsaItemFlag.None);
  94.             item.SetOption("codebase", filename);
  95.             item.SourceText = this.ReadFile(filename, engine);
  96.         }
  97.        
  98.         internal int Compile(CompilerParameters options, string partialCmdLine, string[] sourceFiles, string outputFile)
  99.         {
  100.             // write compiler output to a stream with outputFile as the name
  101.             StreamWriter output = null;
  102.             int nativeReturnValue = 0;
  103.             try {
  104.                 // Compiler output must be UTF-8 encoded
  105.                 output = new StreamWriter(outputFile);
  106.                 output.AutoFlush = true;
  107.                 if (options.IncludeDebugInformation) {
  108.                     Debug.Assert(partialCmdLine != null);
  109.                     this.PrintOptions(output, options);
  110.                     this.debugCommandLine = partialCmdLine;
  111.                 }
  112.                 VsaEngine engine = null;
  113.                 try {
  114.                     engine = this.CreateAndInitEngine(options, sourceFiles, outputFile, output);
  115.                 }
  116.                 catch (CmdLineException e) {
  117.                     output.WriteLine(e.Message);
  118.                     nativeReturnValue = 10;
  119.                 }
  120.                 catch (Exception e) {
  121.                     output.WriteLine("fatal error JS2999: " + e);
  122.                     nativeReturnValue = 10;
  123.                 }
  124.                 catch {
  125.                     output.WriteLine("fatal error JS2999");
  126.                     nativeReturnValue = 10;
  127.                 }
  128.                 if (engine == null)
  129.                     return nativeReturnValue;
  130.                 if (options.IncludeDebugInformation) {
  131.                     // this.debugCommandLine was completed during CreateAndInitEngine (except for filenames)
  132.                     StringBuilder fullCmdLine = new StringBuilder(this.debugCommandLine);
  133.                     foreach (string sourceFile in sourceFiles) {
  134.                         fullCmdLine.Append(" \"");
  135.                         fullCmdLine.Append(sourceFile);
  136.                         fullCmdLine.Append("\"");
  137.                     }
  138.                     this.debugCommandLine = fullCmdLine.ToString();
  139.                     // write the full command line to a response file for debugging
  140.                     string responseFileName = options.TempFiles.AddExtension("cmdline");
  141.                     StreamWriter responseFile = null;
  142.                     try {
  143.                         responseFile = new StreamWriter(responseFileName);
  144.                         responseFile.WriteLine(this.debugCommandLine);
  145.                         responseFile.Flush();
  146.                     }
  147.                     finally {
  148.                         if (responseFile != null)
  149.                             responseFile.Close();
  150.                     }
  151.                     // show full debug command line in compiler output
  152.                     StringBuilder sb = new StringBuilder();
  153.                     sb.Append(Environment.NewLine);
  154.                     sb.Append(JScriptException.Localize("CmdLine helper", CultureInfo.CurrentUICulture));
  155.                     sb.Append(":");
  156.                     sb.Append(Environment.NewLine);
  157.                     sb.Append(" ");
  158.                     sb.Append(options.TempFiles.TempDir);
  159.                     sb.Append("> jsc.exe @\"");
  160.                     sb.Append(responseFileName);
  161.                     sb.Append("\"");
  162.                     sb.Append(Environment.NewLine);
  163.                     output.WriteLine(sb.ToString());
  164.                     this.PrintBanner(engine, output);
  165.                 }
  166.                 try {
  167.                     if (!engine.Compile())
  168.                         nativeReturnValue = 10;
  169.                     else
  170.                         nativeReturnValue = 0;
  171.                 }
  172.                 catch (VsaException e) {
  173.                     // check for expected errors
  174.                     if (e.ErrorCode == VsaError.AssemblyExpected) {
  175.                         if (e.InnerException != null && e.InnerException is System.BadImageFormatException) {
  176.                             // the reference was not for an assembly
  177.                             CmdLineException cmdLineError = new CmdLineException(CmdLineError.InvalidAssembly, e.Message, engine.ErrorCultureInfo);
  178.                             output.WriteLine(cmdLineError.Message);
  179.                         }
  180.                         else if (e.InnerException != null && e.InnerException is System.IO.FileNotFoundException) {
  181.                             // the referenced file not valid
  182.                             CmdLineException cmdLineError = new CmdLineException(CmdLineError.AssemblyNotFound, e.Message, engine.ErrorCultureInfo);
  183.                             output.WriteLine(cmdLineError.Message);
  184.                         }
  185.                         else {
  186.                             CmdLineException cmdLineError = new CmdLineException(CmdLineError.InvalidAssembly, engine.ErrorCultureInfo);
  187.                             output.WriteLine(cmdLineError.Message);
  188.                         }
  189.                     }
  190.                     else if (e.ErrorCode == VsaError.SaveCompiledStateFailed) {
  191.                         CmdLineException cmdLineError = new CmdLineException(CmdLineError.ErrorSavingCompiledState, e.Message, engine.ErrorCultureInfo);
  192.                         output.WriteLine(cmdLineError.Message);
  193.                     }
  194.                     else {
  195.                         output.WriteLine(JScriptException.Localize("INTERNAL COMPILER ERROR", engine.ErrorCultureInfo));
  196.                         output.WriteLine(e);
  197.                     }
  198.                     nativeReturnValue = 10;
  199.                 }
  200.                 catch (Exception e) {
  201.                     output.WriteLine(JScriptException.Localize("INTERNAL COMPILER ERROR", engine.ErrorCultureInfo));
  202.                     output.WriteLine(e);
  203.                     nativeReturnValue = 10;
  204.                 }
  205.                 catch {
  206.                     output.WriteLine(JScriptException.Localize("INTERNAL COMPILER ERROR", engine.ErrorCultureInfo));
  207.                     nativeReturnValue = 10;
  208.                 }
  209.             }
  210.             finally {
  211.                 if (output != null)
  212.                     output.Close();
  213.             }
  214.             return nativeReturnValue;
  215.         }
  216.        
  217.         private VsaEngine CreateAndInitEngine(CompilerParameters options, string[] sourceFiles, string outputFile, TextWriter output)
  218.         {
  219.             VsaEngine engine = new VsaEngine(true);
  220.             VsaSite site = new VsaSite(output);
  221.             engine.InitVsaEngine("JSCodeGenerator://Microsoft.JScript.Vsa.VsaEngine", site);
  222.            
  223.             // Ensure that all options are valid; throw a CmdLineException otherwise
  224.             this.ValidateOptions(options, engine);
  225.            
  226.             // Set options on the engine (equivalent of cmdline args in out-of-proc scenario)
  227.             engine.GenerateDebugInfo = options.IncludeDebugInformation;
  228.             engine.SetOption("referenceLoaderAPI", "LoadFile");
  229.             engine.SetOption("fast", true);
  230.             engine.SetOption("print", false);
  231.             engine.SetOption("VersionSafe", false);
  232.             engine.SetOption("output", options.OutputAssembly);
  233.             if (options.GenerateExecutable)
  234.                 engine.SetOption("PEFileKind", PEFileKinds.ConsoleApplication);
  235.             else
  236.                 engine.SetOption("PEFileKind", PEFileKinds.Dll);
  237.             site.treatWarningsAsErrors = options.TreatWarningsAsErrors;
  238.             engine.SetOption("warnaserror", options.TreatWarningsAsErrors);
  239.             site.warningLevel = options.WarningLevel;
  240.             engine.SetOption("WarningLevel", options.WarningLevel);
  241.             bool stdLibAdded = false;
  242.             foreach (string assemblyName in options.ReferencedAssemblies) {
  243.                 if (String.Compare(Path.GetFileName(assemblyName), "mscorlib.dll", StringComparison.OrdinalIgnoreCase) == 0)
  244.                     stdLibAdded = true;
  245.                 this.AddAssemblyReference(engine, assemblyName);
  246.             }
  247.             if (!stdLibAdded)
  248.                 this.AddAssemblyReference(engine, "mscorlib.dll");
  249.            
  250.             // Parse any additional compiler options
  251.             StringCollection compilerOptions = this.SplitCmdLineArguments(options.CompilerOptions);
  252.             this.ParseCompilerOptions(engine, compilerOptions, output, options.GenerateExecutable);
  253.            
  254.             // Add the source files to the engine (as IVsaCodeItems)
  255.             for (int j = 0; j < sourceFiles.Length; j++)
  256.                 this.AddSourceFile(engine, sourceFiles[j]);
  257.            
  258.             return engine;
  259.         }
  260.        
  261.         private void GetAllDefines(string definitionList, Hashtable defines, VsaEngine engine)
  262.         {
  263.             int startIndex = 0;
  264.             int nextIndex;
  265.             string definition;
  266.             do {
  267.                 nextIndex = this.GetArgumentSeparatorIndex(definitionList, startIndex);
  268.                 if (nextIndex == -1)
  269.                     definition = definitionList.Substring(startIndex);
  270.                 else
  271.                     definition = definitionList.Substring(startIndex, nextIndex - startIndex);
  272.                 this.AddDefinition(definition, defines, engine);
  273.                 startIndex = nextIndex + 1;
  274.             }
  275.             while (nextIndex > -1);
  276.         }
  277.        
  278.         private int GetArgumentSeparatorIndex(string argList, int startIndex)
  279.         {
  280.             int commaIndex = argList.IndexOf(",", startIndex);
  281.             int semicolonIndex = argList.IndexOf(";", startIndex);
  282.             if (commaIndex == -1)
  283.                 return semicolonIndex;
  284.             if (semicolonIndex == -1)
  285.                 return commaIndex;
  286.             if (commaIndex < semicolonIndex)
  287.                 return commaIndex;
  288.             return semicolonIndex;
  289.         }
  290.        
  291.         private void ParseCompilerOptions(VsaEngine engine, StringCollection args, TextWriter output, bool generateExe)
  292.         {
  293.             // Process compiler options and return command line fragment to complete the partial debug command line
  294.             // that was formed by examining the CompilerParameters structure only.
  295.             string libpath = System.Environment.GetEnvironmentVariable("LIB");
  296.             bool generateWinExe = false;
  297.             Hashtable defines = new Hashtable(10);
  298.             Hashtable resources = new Hashtable(10);
  299.             Hashtable resourceFiles = new Hashtable(10);
  300.             bool targetSpecified = false;
  301.            
  302.             StringBuilder fullCmdLine = null;
  303.             if (this.debugCommandLine != null)
  304.                 fullCmdLine = new StringBuilder(this.debugCommandLine);
  305.            
  306.             // if '/' separates dir, use '-' as switch
  307.             string cmdLineSwitch = Path.DirectorySeparatorChar == '/' ? "-" : "/";
  308.            
  309.             for (int i = 0int n = args.Count; i < n; i++) {
  310.                 object argument;
  311.                 string option;
  312.                
  313.                 string arg = args[i];
  314.                 if (arg == null || arg.Length == 0)
  315.                     continue;
  316.                
  317.                 if (arg[0] == '@')
  318.                     throw new CmdLineException(CmdLineError.InvalidForCompilerOptions, "@<filename>", engine.ErrorCultureInfo);
  319.                
  320.                 // slash ('/') character is a valid filename character on UNIX, so we can't use it as a switch
  321.                 if ('-' != arg[0] && ('/' != arg[0] || Path.DirectorySeparatorChar == '/'))
  322.                     break;
  323.                
  324.                 option = arg.Substring(1);
  325.                
  326.                 if (option.Length > 0) {
  327.                     switch (option[0]) {
  328.                         case '?':
  329.                             throw new CmdLineException(CmdLineError.InvalidForCompilerOptions, "/?", engine.ErrorCultureInfo);
  330.                             break;
  331.                         case 'a':
  332.                         case 'A':
  333.                             argument = CmdLineOptionParser.IsBooleanOption(option, "autoref");
  334.                             if (argument != null) {
  335.                                 engine.SetOption("autoref", argument);
  336.                                 if (fullCmdLine != null) {
  337.                                     fullCmdLine.Append(arg);
  338.                                     fullCmdLine.Append(" ");
  339.                                 }
  340.                                 continue;
  341.                             }
  342.                             break;
  343.                         case 'c':
  344.                         case 'C':
  345.                             argument = CmdLineOptionParser.IsArgumentOption(option, "codepage");
  346.                             if (argument != null)
  347.                                 throw new CmdLineException(CmdLineError.InvalidForCompilerOptions, "/codepage:<id>", engine.ErrorCultureInfo);
  348.                             break;
  349.                         case 'd':
  350.                         case 'D':
  351.                             argument = CmdLineOptionParser.IsBooleanOption(option, "debug");
  352.                             if (argument != null) {
  353.                                 engine.GenerateDebugInfo = (bool)argument;
  354.                                 if (fullCmdLine != null) {
  355.                                     fullCmdLine.Append(arg);
  356.                                     fullCmdLine.Append(" ");
  357.                                 }
  358.                                 continue;
  359.                             }
  360.                             argument = CmdLineOptionParser.IsArgumentOption(option, "d", "define");
  361.                             if (argument != null) {
  362.                                 this.GetAllDefines((string)argument, defines, engine);
  363.                                 if (fullCmdLine != null) {
  364.                                     fullCmdLine.Append(cmdLineSwitch + "d:\"");
  365.                                     fullCmdLine.Append((string)argument);
  366.                                     fullCmdLine.Append("\" ");
  367.                                 }
  368.                                 continue;
  369.                             }
  370.                             break;
  371.                         case 'f':
  372.                         case 'F':
  373.                             argument = CmdLineOptionParser.IsBooleanOption(option, "fast");
  374.                             if (argument != null) {
  375.                                 engine.SetOption("fast", argument);
  376.                                 if (fullCmdLine != null) {
  377.                                     fullCmdLine.Append(arg);
  378.                                     fullCmdLine.Append(" ");
  379.                                 }
  380.                                 continue;
  381.                             }
  382.                             break;
  383.                         case 'l':
  384.                         case 'L':
  385.                             argument = CmdLineOptionParser.IsArgumentOption(option, "lcid");
  386.                             if (argument != null) {
  387.                                 if (((string)argument).Length == 0)
  388.                                     throw new CmdLineException(CmdLineError.NoLocaleID, arg, engine.ErrorCultureInfo);
  389.                                 try {
  390.                                     engine.LCID = Int32.Parse((string)argument, CultureInfo.InvariantCulture);
  391.                                 }
  392.                                 catch {
  393.                                     throw new CmdLineException(CmdLineError.InvalidLocaleID, (string)argument, engine.ErrorCultureInfo);
  394.                                 }
  395.                                 continue;
  396.                             }
  397.                             argument = CmdLineOptionParser.IsArgumentOption(option, "lib");
  398.                             if (argument != null) {
  399.                                 string newPaths = (string)argument;
  400.                                 if (newPaths.Length == 0)
  401.                                     throw new CmdLineException(CmdLineError.MissingLibArgument, engine.ErrorCultureInfo);
  402.                                 newPaths = newPaths.Replace(',', Path.PathSeparator);
  403.                                 libpath = newPaths + Path.PathSeparator + libpath;
  404.                                 if (fullCmdLine != null) {
  405.                                     fullCmdLine.Append(cmdLineSwitch + "lib:\"");
  406.                                     fullCmdLine.Append((string)argument);
  407.                                     fullCmdLine.Append("\" ");
  408.                                 }
  409.                                 continue;
  410.                             }
  411.                             argument = CmdLineOptionParser.IsArgumentOption(option, "linkres", "linkresource");
  412.                             if (argument != null) {
  413.                                 try {
  414.                                         /* isLinked */                                    ResInfo resinfo = new ResInfo((string)argument, true);
  415.                                     this.AddResourceFile(resinfo, resources, resourceFiles, engine);
  416.                                 }
  417.                                 catch (CmdLineException) {
  418.                                     throw;
  419.                                 }
  420.                                 catch {
  421.                                     throw new CmdLineException(CmdLineError.ManagedResourceNotFound, engine.ErrorCultureInfo);
  422.                                 }
  423.                                 continue;
  424.                             }
  425.                             break;
  426.                         case 'n':
  427.                         case 'N':
  428.                             argument = CmdLineOptionParser.IsBooleanOption(option, "nologo");
  429.                             if (argument != null)
  430.                                 throw new CmdLineException(CmdLineError.InvalidForCompilerOptions, "/nologo[+|-]", engine.ErrorCultureInfo);
  431.                             argument = CmdLineOptionParser.IsBooleanOption(option, "nostdlib");
  432.                             if (argument != null)
  433.                                 throw new CmdLineException(CmdLineError.InvalidForCompilerOptions, "/nostdlib[+|-]", engine.ErrorCultureInfo);
  434.                             break;
  435.                         case 'o':
  436.                         case 'O':
  437.                             argument = CmdLineOptionParser.IsArgumentOption(option, "out");
  438.                             if (argument != null)
  439.                                 throw new CmdLineException(CmdLineError.InvalidForCompilerOptions, "/out:<filename>", engine.ErrorCultureInfo);
  440.                             break;
  441.                         case 'p':
  442.                         case 'P':
  443.                             argument = CmdLineOptionParser.IsBooleanOption(option, "print");
  444.                             if (argument != null) {
  445.                                 engine.SetOption("print", argument);
  446.                                 if (fullCmdLine != null) {
  447.                                     fullCmdLine.Append(arg);
  448.                                     fullCmdLine.Append(" ");
  449.                                 }
  450.                                 continue;
  451.                             }
  452.                             argument = CmdLineOptionParser.IsArgumentOption(option, "platform");
  453.                             if (argument != null) {
  454.                                 string platform = (string)argument;
  455.                                 PortableExecutableKinds PEKindFlags;
  456.                                 ImageFileMachine PEMachineArchitecture;
  457.                                 if (String.Compare(platform, "x86", StringComparison.OrdinalIgnoreCase) == 0) {
  458.                                     PEKindFlags = PortableExecutableKinds.ILOnly | PortableExecutableKinds.Required32Bit;
  459.                                     PEMachineArchitecture = ImageFileMachine.I386;
  460.                                 }
  461.                                 else if (String.Compare(platform, "Itanium", StringComparison.OrdinalIgnoreCase) == 0) {
  462.                                     PEKindFlags = PortableExecutableKinds.ILOnly | PortableExecutableKinds.PE32Plus;
  463.                                     PEMachineArchitecture = ImageFileMachine.IA64;
  464.                                 }
  465.                                 else if (String.Compare(platform, "x64", StringComparison.OrdinalIgnoreCase) == 0) {
  466.                                     PEKindFlags = PortableExecutableKinds.ILOnly | PortableExecutableKinds.PE32Plus;
  467.                                     PEMachineArchitecture = ImageFileMachine.AMD64;
  468.                                 }
  469.                                 else if (String.Compare(platform, "anycpu", StringComparison.OrdinalIgnoreCase) == 0) {
  470.                                     PEKindFlags = PortableExecutableKinds.ILOnly;
  471.                                     PEMachineArchitecture = ImageFileMachine.I386;
  472.                                 }
  473.                                 else
  474.                                     throw new CmdLineException(CmdLineError.InvalidPlatform, (string)argument, engine.ErrorCultureInfo);
  475.                                 engine.SetOption("PortableExecutableKind", PEKindFlags);
  476.                                 engine.SetOption("ImageFileMachine", PEMachineArchitecture);
  477.                                 if (fullCmdLine != null) {
  478.                                     fullCmdLine.Append(arg);
  479.                                     fullCmdLine.Append(" ");
  480.                                 }
  481.                                 continue;
  482.                             }
  483.                             break;
  484.                         case 'r':
  485.                         case 'R':
  486.                             argument = CmdLineOptionParser.IsArgumentOption(option, "r", "reference");
  487.                             if (argument != null)
  488.                                 throw new CmdLineException(CmdLineError.InvalidForCompilerOptions, "/r[eference]:<file list>", engine.ErrorCultureInfo);
  489.                             argument = CmdLineOptionParser.IsArgumentOption(option, "res", "resource");
  490.                             if (argument != null) {
  491.                                 try {
  492.                                         /* isLinked */                                    ResInfo resinfo = new ResInfo((string)argument, false);
  493.                                     this.AddResourceFile(resinfo, resources, resourceFiles, engine);
  494.                                 }
  495.                                 catch (CmdLineException) {
  496.                                     throw;
  497.                                 }
  498.                                 catch {
  499.                                     throw new CmdLineException(CmdLineError.ManagedResourceNotFound, engine.ErrorCultureInfo);
  500.                                 }
  501.                                 continue;
  502.                             }
  503.                             break;
  504.                         case 't':
  505.                         case 'T':
  506.                             argument = CmdLineOptionParser.IsArgumentOption(option, "t", "target");
  507.                             if (argument != null) {
  508.                                 if (String.Compare((string)argument, "exe", StringComparison.OrdinalIgnoreCase) == 0) {
  509.                                     if (!generateExe)
  510.                                         throw new CmdLineException(CmdLineError.IncompatibleTargets, arg, engine.ErrorCultureInfo);
  511.                                     if (targetSpecified)
  512.                                         throw new CmdLineException(CmdLineError.MultipleTargets, engine.ErrorCultureInfo);
  513.                                     // no change -- /t:exe is the default when GenerateExecutable is true
  514.                                     targetSpecified = true;
  515.                                     continue;
  516.                                 }
  517.                                 if (String.Compare((string)argument, "winexe", StringComparison.OrdinalIgnoreCase) == 0) {
  518.                                     if (!generateExe)
  519.                                         throw new CmdLineException(CmdLineError.IncompatibleTargets, arg, engine.ErrorCultureInfo);
  520.                                     if (targetSpecified)
  521.                                         throw new CmdLineException(CmdLineError.MultipleTargets, engine.ErrorCultureInfo);
  522.                                     engine.SetOption("PEFileKind", PEFileKinds.WindowApplication);
  523.                                     generateWinExe = true;
  524.                                     targetSpecified = true;
  525.                                     continue;
  526.                                 }
  527.                                 if (String.Compare((string)argument, "library", StringComparison.OrdinalIgnoreCase) == 0) {
  528.                                     if (generateExe)
  529.                                         throw new CmdLineException(CmdLineError.IncompatibleTargets, engine.ErrorCultureInfo);
  530.                                     if (targetSpecified)
  531.                                         throw new CmdLineException(CmdLineError.MultipleTargets, engine.ErrorCultureInfo);
  532.                                     // no change -- /t:library is the default when GenerateExecutable is false
  533.                                     targetSpecified = true;
  534.                                     continue;
  535.                                 }
  536.                                 throw new CmdLineException(CmdLineError.InvalidTarget, (string)argument, engine.ErrorCultureInfo);
  537.                             }
  538.                             break;
  539.                         case 'u':
  540.                         case 'U':
  541.                             argument = CmdLineOptionParser.IsArgumentOption(option, "utf8output");
  542.                             if (argument != null)
  543.                                 throw new CmdLineException(CmdLineError.InvalidForCompilerOptions, "/utf8output[+|-]", engine.ErrorCultureInfo);
  544.                             break;
  545.                         case 'v':
  546.                         case 'V':
  547.                             argument = CmdLineOptionParser.IsBooleanOption(option, "VersionSafe");
  548.                             if (argument != null) {
  549.                                 engine.SetOption("VersionSafe", argument);
  550.                                 if (fullCmdLine != null) {
  551.                                     fullCmdLine.Append(arg);
  552.                                     fullCmdLine.Append(" ");
  553.                                 }
  554.                                 continue;
  555.                             }
  556.                             break;
  557.                         case 'w':
  558.                         case 'W':
  559.                             argument = CmdLineOptionParser.IsArgumentOption(option, "w", "warn");
  560.                             if (argument != null) {
  561.                                 if (((string)argument).Length == 0) {
  562.                                     throw new CmdLineException(CmdLineError.NoWarningLevel, arg, engine.ErrorCultureInfo);
  563.                                 }
  564.                                 if (((string)argument).Length == 1) {
  565.                                     if (fullCmdLine != null) {
  566.                                         fullCmdLine.Append(arg);
  567.                                         fullCmdLine.Append(" ");
  568.                                     }
  569.                                     switch (((string)argument)[0]) {
  570.                                         case '0':
  571.                                             engine.SetOption("WarningLevel", (object)0);
  572.                                             continue;
  573.                                         case '1':
  574.                                             engine.SetOption("WarningLevel", (object)1);
  575.                                             continue;
  576.                                         case '2':
  577.                                             engine.SetOption("WarningLevel", (object)2);
  578.                                             continue;
  579.                                         case '3':
  580.                                             engine.SetOption("WarningLevel", (object)3);
  581.                                             continue;
  582.                                         case '4':
  583.                                             engine.SetOption("WarningLevel", (object)4);
  584.                                             continue;
  585.                                     }
  586.                                 }
  587.                                 throw new CmdLineException(CmdLineError.InvalidWarningLevel, arg, engine.ErrorCultureInfo);
  588.                             }
  589.                             argument = CmdLineOptionParser.IsBooleanOption(option, "warnaserror");
  590.                             if (argument != null) {
  591.                                 engine.SetOption("warnaserror", argument);
  592.                                 if (fullCmdLine != null) {
  593.                                     fullCmdLine.Append(arg);
  594.                                     fullCmdLine.Append(" ");
  595.                                 }
  596.                                 continue;
  597.                             }
  598.                             break;
  599.                         default:
  600.                             break;
  601.                     }
  602.                 }
  603.                 throw new CmdLineException(CmdLineError.UnknownOption, arg, engine.ErrorCultureInfo);
  604.             }
  605.             if (fullCmdLine != null) {
  606.                 // append target type to debug command line
  607.                 if (generateExe) {
  608.                     if (generateWinExe)
  609.                         fullCmdLine.Append(cmdLineSwitch + "t:winexe ");
  610.                     else
  611.                         fullCmdLine.Append(cmdLineSwitch + "t:exe ");
  612.                 }
  613.                 else {
  614.                     fullCmdLine.Append(cmdLineSwitch + "t:library ");
  615.                 }
  616.                 this.debugCommandLine = fullCmdLine.ToString();
  617.             }
  618.             // set options on engine that were possibly built from multiple arguments
  619.             engine.SetOption("libpath", libpath);
  620.             engine.SetOption("defines", defines);
  621.         }
  622.        
  623.         internal void PrintBanner(VsaEngine engine, TextWriter output)
  624.         {
  625.             string jsVersion = BuildVersionInfo.MajorVersion.ToString(CultureInfo.InvariantCulture) + "." + BuildVersionInfo.MinorVersion.ToString(CultureInfo.InvariantCulture).PadLeft(2, '0') + "." + BuildVersionInfo.Build.ToString(CultureInfo.InvariantCulture).PadLeft(4, '0');
  626.             Version version = System.Environment.Version;
  627.             string runtimeVersion = version.Major.ToString(CultureInfo.InvariantCulture) + "." + version.Minor.ToString(CultureInfo.InvariantCulture) + "." + version.Build.ToString(CultureInfo.InvariantCulture).PadLeft(4, '0');
  628.             output.WriteLine(String.Format(engine.ErrorCultureInfo, JScriptException.Localize("Banner line 1", engine.ErrorCultureInfo), jsVersion));
  629.             output.WriteLine(String.Format(engine.ErrorCultureInfo, JScriptException.Localize("Banner line 2", engine.ErrorCultureInfo), runtimeVersion));
  630.             output.WriteLine(JScriptException.Localize("Banner line 3", engine.ErrorCultureInfo) + Environment.NewLine);
  631.         }
  632.        
  633.         private void PrintOptions(TextWriter output, CompilerParameters options)
  634.         {
  635.             StringBuilder sb = new StringBuilder();
  636.             sb.Append("CompilerParameters.CompilerOptions : \"");
  637.             sb.Append(options.CompilerOptions);
  638.             sb.Append("\"");
  639.             sb.Append(Environment.NewLine);
  640.             sb.Append("CompilerParameters.GenerateExecutable : ");
  641.             sb.Append(options.GenerateExecutable.ToString(CultureInfo.InvariantCulture));
  642.             sb.Append(Environment.NewLine);
  643.             sb.Append("CompilerParameters.GenerateInMemory : ");
  644.             sb.Append(options.GenerateInMemory.ToString(CultureInfo.InvariantCulture));
  645.             sb.Append(Environment.NewLine);
  646.             sb.Append("CompilerParameters.IncludeDebugInformation: ");
  647.             sb.Append(options.IncludeDebugInformation.ToString(CultureInfo.InvariantCulture));
  648.             sb.Append(Environment.NewLine);
  649.             sb.Append("CompilerParameters.MainClass : \"");
  650.             sb.Append(options.MainClass);
  651.             sb.Append("\"");
  652.             sb.Append(Environment.NewLine);
  653.             sb.Append("CompilerParameters.OutputAssembly : \"");
  654.             sb.Append(options.OutputAssembly);
  655.             sb.Append("\"");
  656.             sb.Append(Environment.NewLine);
  657.             sb.Append("CompilerParameters.ReferencedAssemblies : ");
  658.             foreach (string reference in options.ReferencedAssemblies) {
  659.                 sb.Append(Environment.NewLine);
  660.                 sb.Append(" \"");
  661.                 sb.Append(reference);
  662.                 sb.Append("\"");
  663.             }
  664.             sb.Append(Environment.NewLine);
  665.             sb.Append("CompilerParameters.TreatWarningsAsErrors : ");
  666.             sb.Append(options.TreatWarningsAsErrors.ToString(CultureInfo.InvariantCulture));
  667.             sb.Append(Environment.NewLine);
  668.             sb.Append("CompilerParameters.WarningLevel : ");
  669.             sb.Append(options.WarningLevel.ToString(CultureInfo.InvariantCulture));
  670.             sb.Append(Environment.NewLine);
  671.             output.WriteLine(sb.ToString());
  672.         }
  673.        
  674.         protected string ReadFile(string fileName, VsaEngine engine)
  675.         {
  676.             string s = "";
  677.             FileStream inputStream = null;
  678.             try {
  679.                 inputStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
  680.             }
  681.             catch (System.ArgumentException) {
  682.                 throw new CmdLineException(CmdLineError.InvalidCharacters, fileName, engine.ErrorCultureInfo);
  683.             }
  684.             catch (System.IO.FileNotFoundException) {
  685.                 throw new CmdLineException(CmdLineError.SourceNotFound, fileName, engine.ErrorCultureInfo);
  686.             }
  687.             try {
  688.                 if (inputStream.Length != 0) {
  689.                         /*detectEncodingFromByteOrderMarks*/                    StreamReader reader = new StreamReader(inputStream, true);
  690.                     try {
  691.                         s = reader.ReadToEnd();
  692.                     }
  693.                     finally {
  694.                         reader.Close();
  695.                     }
  696.                 }
  697.             }
  698.             finally {
  699.                 inputStream.Close();
  700.             }
  701.             return s;
  702.         }
  703.        
  704.         private StringCollection SplitCmdLineArguments(string argumentString)
  705.         {
  706.             StringCollection args = new StringCollection();
  707.             if (argumentString == null || argumentString.Length == 0)
  708.                 return args;
  709.            
  710.             // This regular expression is: blank*(nonblanks|stringLiteral)+
  711.             string strReArgs = "\\s*([^\\s\\\"]|(\\\"[^\\\"\\n]*\\\"))+";
  712.             Regex re = new Regex(strReArgs);
  713.            
  714.             MatchCollection matches = re.Matches(argumentString);
  715.             if (matches != null && matches.Count != 0) {
  716.                 foreach (Match match in matches) {
  717.                     string arg = match.ToString().Trim();
  718.                     int quotes = 0;
  719.                     while ((quotes = arg.IndexOf("\"", quotes)) != -1) {
  720.                         if (quotes == 0)
  721.                             arg = arg.Substring(1);
  722.                         else if (arg[quotes - 1] == '\\')
  723.                             quotes += 1;
  724.                         else
  725.                             arg = arg.Remove(quotes, 1);
  726.                     }
  727.                     args.Add(arg);
  728.                 }
  729.             }
  730.             return args;
  731.         }
  732.        
  733.         private void ValidateOptions(CompilerParameters options, VsaEngine engine)
  734.         {
  735.             // make sure we have an output filename with an extension
  736.             string outputName = options.OutputAssembly;
  737.             try {
  738.                 if (Path.GetFileName(outputName).Length == 0)
  739.                     throw new CmdLineException(CmdLineError.NoFileName, outputName, engine.ErrorCultureInfo);
  740.             }
  741.             catch (System.ArgumentException) {
  742.                 throw new CmdLineException(CmdLineError.NoFileName, engine.ErrorCultureInfo);
  743.             }
  744.             if (Path.GetExtension(outputName).Length == 0)
  745.                 throw new CmdLineException(CmdLineError.MissingExtension, outputName, engine.ErrorCultureInfo);
  746.             // make sure warninglevel is valid (0-4)
  747.             // Note: ASP+ has -1 as the default value if the warning level is not specified in a page. We set
  748.             // any -1 warning level to 4, the JSC default.
  749.             if (options.WarningLevel == -1)
  750.                 options.WarningLevel = 4;
  751.             if ((options.WarningLevel < 0) || (options.WarningLevel > 4))
  752.                 throw new CmdLineException(CmdLineError.InvalidWarningLevel, options.WarningLevel.ToString(CultureInfo.InvariantCulture), engine.ErrorCultureInfo);
  753.         }
  754.     }
  755.    
  756.     internal class VsaSite : BaseVsaSite
  757.     {
  758.         public int warningLevel = 4;
  759.         public bool treatWarningsAsErrors = false;
  760.         public TextWriter output = Console.Out;
  761.        
  762.         public VsaSite(TextWriter redirectedOutput)
  763.         {
  764.             this.output = redirectedOutput;
  765.         }
  766.        
  767.         public override bool OnCompilerError(IVsaError error)
  768.         {
  769.             // Errors have severity 0, warnings have severities 1-4. Setting
  770.             // this.warningLevel to 0 results in all warnings being masked.
  771.             int severity = error.Severity;
  772.             if (severity > this.warningLevel)
  773.                 return true;
  774.             bool isWarning = (0 != severity) && !this.treatWarningsAsErrors;
  775.             this.PrintError(error.SourceMoniker, error.Line, error.StartColumn, isWarning, error.Number, error.Description);
  776.             // Report as many errors as possible (never return false)
  777.             return true;
  778.         }
  779.        
  780.         private void PrintError(string sourceFile, int line, int column, bool fIsWarning, int number, string message)
  781.         {
  782.             string errorNumber = (10000 + (number & 65535)).ToString(CultureInfo.InvariantCulture).Substring(1);
  783.             if (String.Compare(sourceFile, "no source", StringComparison.Ordinal) != 0)
  784.                 output.Write(sourceFile + "(" + line.ToString(CultureInfo.InvariantCulture) + "," + column.ToString(CultureInfo.InvariantCulture) + ") : ");
  785.             output.WriteLine((fIsWarning ? "warning JS" : "error JS") + errorNumber + ": " + message);
  786.         }
  787.     }
  788. }

Developer Fusion