예제 #1
0
        /// <summary>
        /// Compiles the provided C# and then translates it into JavaScript.
        /// On success, returns the JS. On failure, throws.
        /// </summary>
        public static CompiledSnippet Compile(string csharp, bool deleteTempFiles)
        {
            var result = new CompiledSnippet {
                OriginalSource = csharp
            };

            int tempDirId = Interlocked.Increment(ref NextTempDirId);
            var tempPath  = Path.Combine(Path.GetTempPath(), "JSIL.Try", tempDirId.ToString());

            if (!Directory.Exists(tempPath))
            {
                Directory.CreateDirectory(tempPath);
            }

            try {
                string resultPath, entryPointName, compilerOutput, resultFullName;

                long compileStarted = DateTime.UtcNow.Ticks;

                CompileAssembly(
                    tempPath, csharp,
                    out compilerOutput, out resultPath,
                    out resultFullName, out entryPointName
                    );

                result.CompileElapsed = TimeSpan.FromTicks(DateTime.UtcNow.Ticks - compileStarted).TotalSeconds;

                if ((resultPath == null) || !File.Exists(resultPath))
                {
                    if (String.IsNullOrWhiteSpace(compilerOutput))
                    {
                        throw new Exception("Compile failed with unknown error.");
                    }
                    else
                    {
                        throw new Exception(compilerOutput);
                    }
                }

                var translatorConfiguration = new Configuration {
                    ApplyDefaults = false,
                    Assemblies    =
                    {
                        Stubbed =
                        {
                            "mscorlib,",
                            "System.*",
                            "Microsoft.*"
                        },
                        Ignored =
                        {
                            "Microsoft.VisualC,",
                            "Accessibility,",
                            "SMDiagnostics,",
                            "System.EnterpriseServices,",
                            "JSIL.Meta,"
                        }
                    },
                    FrameworkVersion = 4.0,
                    GenerateSkeletonsForStubbedAssemblies = false,
                    GenerateContentManifest = false,
                    IncludeDependencies     = false,
                    UseSymbols = true,
                    UseThreads = false
                };

                var translatorOutput = new StringBuilder();

                var typeInfo = CachedTypeInfo.Value;

                // Don't use a cached type provider if this snippet contains a proxy.
                bool disableCaching = csharp.Contains("JSProxy");

                using (var translator = new AssemblyTranslator(
                           translatorConfiguration,
                           // Reuse the cached type info provider, if one exists.
                           disableCaching ? null : typeInfo,
                           // Can't reuse a manifest meaningfully here.
                           null,
                           // Reuse the assembly cache so that mscorlib doesn't get loaded every time.
                           AssemblyCache
                           )) {
                    translator.CouldNotDecompileMethod += (s, exception) => {
                        lock (translatorOutput)
                            translatorOutput.AppendFormat(
                                "Could not decompile method '{0}': {1}{2}",
                                s, exception.Message, Environment.NewLine
                                );
                    };

                    translator.CouldNotResolveAssembly += (s, exception) => {
                        lock (translatorOutput)
                            translatorOutput.AppendFormat(
                                "Could not resolve assembly '{0}': {1}{2}",
                                s, exception.Message, Environment.NewLine
                                );
                    };

                    translator.Warning += (s) => {
                        lock (translatorOutput)
                            translatorOutput.AppendLine(s);
                    };

                    var translateStarted  = DateTime.UtcNow.Ticks;
                    var translationResult = translator.Translate(resultPath, true);

                    AssemblyTranslator.GenerateManifest(
                        translator.Manifest, Path.GetDirectoryName(resultPath), translationResult
                        );

                    result.EntryPoint = String.Format(
                        "{0}.{1}",
                        translator.Manifest.GetPrivateToken(resultFullName).IDString,
                        entryPointName
                        );

                    result.Warnings         = translatorOutput.ToString().Trim();
                    result.TranslateElapsed = TimeSpan.FromTicks(DateTime.UtcNow.Ticks - translateStarted).TotalSeconds;
                    result.JavaScript       = translationResult.WriteToString();

                    if (typeInfo != null)
                    {
                        // Remove the temporary assembly from the type info provider.
                        typeInfo.Remove(translationResult.Assemblies.ToArray());
                    }
                    else if (!disableCaching)
                    {
                        // We didn't have a type info provider to reuse, so store the translator's.
                        CachedTypeInfo.Value = typeInfo = translator.GetTypeInfoProvider();
                    }

                    /*
                     * result.Warnings += String.Format(
                     *  "{1} assemblies loaded{0}",
                     *  Environment.NewLine, AppDomain.CurrentDomain.GetAssemblies().Length
                     * );
                     */

                    /*
                     * result.Warnings += String.Format(
                     *  "TypeInfo.Count = {1}{0}AssemblyCache.Count = {2}{0}",
                     *  Environment.NewLine, TypeInfo.Count, AssemblyCache.Count
                     * );
                     */
                }

                /*
                 *
                 * GC.Collect();
                 *
                 * result.Warnings += String.Format(
                 *  "{1} byte(s) GC heap {0}",
                 *  Environment.NewLine, GC.GetTotalMemory(true)
                 * );
                 */

                return(result);
            } finally {
                try {
                    if (deleteTempFiles)
                    {
                        Directory.Delete(tempPath, true);
                    }
                } catch (Exception exc) {
                    Console.WriteLine("Failed to empty temporary directory: {0}", exc.Message);
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Compiles the provided C# and then translates it into JavaScript.
        /// On success, returns the JS. On failure, throws.
        /// </summary>
        public static CompiledSnippet Compile(string csharp, bool deleteTempFiles)
        {
            var result = new CompiledSnippet {
                OriginalSource = csharp
            };

            int tempDirId = Interlocked.Increment(ref NextTempDirId);
            var tempPath = Path.Combine(Path.GetTempPath(), "JSIL.Try", tempDirId.ToString());

            if (!Directory.Exists(tempPath))
                Directory.CreateDirectory(tempPath);

            try {
                string resultPath, entryPointName, compilerOutput, resultFullName;

                long compileStarted = DateTime.UtcNow.Ticks;

                CompileAssembly(
                    tempPath, csharp,
                    out compilerOutput, out resultPath,
                    out resultFullName, out entryPointName
                );

                result.CompileElapsed = TimeSpan.FromTicks(DateTime.UtcNow.Ticks - compileStarted).TotalSeconds;

                if ((resultPath == null) || !File.Exists(resultPath)) {
                    if (String.IsNullOrWhiteSpace(compilerOutput))
                        throw new Exception("Compile failed with unknown error.");
                    else
                        throw new Exception(compilerOutput);
                }

                var translatorConfiguration = new Configuration {
                    ApplyDefaults = false,
                    Assemblies = {
                        Stubbed = {
                            "mscorlib,",
                            "System.*",
                            "Microsoft.*"
                        },
                        Ignored = {
                            "Microsoft.VisualC,",
                            "Accessibility,",
                            "SMDiagnostics,",
                            "System.EnterpriseServices,",
                            "JSIL.Meta,"
                        }
                    },
                    FrameworkVersion = 4.0,
                    GenerateSkeletonsForStubbedAssemblies = false,
                    GenerateContentManifest = false,
                    IncludeDependencies = false,
                    UseSymbols = true,
                    UseThreads = false
                };

                var translatorOutput = new StringBuilder();

                var typeInfo = CachedTypeInfo.Value;

                // Don't use a cached type provider if this snippet contains a proxy.
                bool disableCaching = csharp.Contains("JSProxy");

                using (var translator = new AssemblyTranslator(
                    translatorConfiguration,
                    // Reuse the cached type info provider, if one exists.
                    disableCaching ? null : typeInfo,
                    // Can't reuse a manifest meaningfully here.
                    null,
                    // Reuse the assembly cache so that mscorlib doesn't get loaded every time.
                    AssemblyCache
                )) {
                    translator.CouldNotDecompileMethod += (s, exception) => {
                        lock (translatorOutput)
                            translatorOutput.AppendFormat(
                                "Could not decompile method '{0}': {1}{2}",
                                s, exception.Message, Environment.NewLine
                            );
                    };

                    translator.CouldNotResolveAssembly += (s, exception) => {
                        lock (translatorOutput)
                            translatorOutput.AppendFormat(
                                "Could not resolve assembly '{0}': {1}{2}",
                                s, exception.Message, Environment.NewLine
                            );
                    };

                    translator.Warning += (s) => {
                        lock (translatorOutput)
                            translatorOutput.AppendLine(s);
                    };

                    var translateStarted = DateTime.UtcNow.Ticks;
                    var translationResult = translator.Translate(resultPath, true);

                    AssemblyTranslator.GenerateManifest(
                        translator.Manifest, Path.GetDirectoryName(resultPath), translationResult
                    );

                    result.EntryPoint = String.Format(
                        "{0}.{1}",
                        translator.Manifest.GetPrivateToken(resultFullName).IDString,
                        entryPointName
                    );

                    result.Warnings = translatorOutput.ToString().Trim();
                    result.TranslateElapsed = TimeSpan.FromTicks(DateTime.UtcNow.Ticks - translateStarted).TotalSeconds;
                    result.JavaScript = translationResult.WriteToString();

                    if (typeInfo != null) {
                        // Remove the temporary assembly from the type info provider.
                        typeInfo.Remove(translationResult.Assemblies.ToArray());
                    } else if (!disableCaching) {
                        // We didn't have a type info provider to reuse, so store the translator's.
                        CachedTypeInfo.Value = typeInfo = translator.GetTypeInfoProvider();
                    }

                    /*
                    result.Warnings += String.Format(
                        "{1} assemblies loaded{0}",
                        Environment.NewLine, AppDomain.CurrentDomain.GetAssemblies().Length
                    );
                     */

                    /*
                    result.Warnings += String.Format(
                        "TypeInfo.Count = {1}{0}AssemblyCache.Count = {2}{0}",
                        Environment.NewLine, TypeInfo.Count, AssemblyCache.Count
                    );
                        */
                }

                /*

                GC.Collect();

                result.Warnings += String.Format(
                    "{1} byte(s) GC heap {0}",
                    Environment.NewLine, GC.GetTotalMemory(true)
                );
                 */

                return result;
            } finally {

                try {
                    if (deleteTempFiles)
                        Directory.Delete(tempPath, true);
                } catch (Exception exc) {
                    Console.WriteLine("Failed to empty temporary directory: {0}", exc.Message);
                }
            }
        }