// Trace mode entry point
        public TypeDefinitionCompiler(AssemblyCompiler parent, TypeTrace typeTrace)
        {
            Env = parent.Env;
            Parent = parent;
            TyconEnv = parent.AssmEnv.AddType(typeTrace.Type);
            this.TypeTrace = typeTrace;

            if (typeTrace.IncludeType && typeTrace.Parent.Parent.Flavor == TraceFlavor.Remainder)
            {
                // Create a self-loader fragment file
                NameSupply = new JST.NameSupply(Constants.Globals);
                // Will be bound by function passed to root's BindType
                RootId = NameSupply.GenSym();
                AssemblyId = NameSupply.GenSym();
                TypeDefinitionId = NameSupply.GenSym();
            }
            else {
                // Possibly inline type definition and/or method definitions into trace
                NameSupply = parent.NameSupply;
                // Already bound by parent
                RootId = parent.RootId;
                AssemblyId = parent.AssemblyId;
                // Will be bound locally
                TypeDefinitionId = NameSupply.GenSym();
            }
        }
Example #2
0
 public void Emit()
 {
     if (Trace.Flavor == TraceFlavor.Remainder)
     {
         foreach (var kv in Trace.AssemblyMap)
         {
             var compiler = new AssemblyCompiler(this, kv.Value);
             compiler.Emit(null);
         }
     }
     else
     {
         var rootEnv = Env.Global.Environment();
         var body = new Seq<JST.Statement>();
         body.Add(JST.Statement.Var(RootId, new JST.Identifier(Env.Root).ToE()));
         foreach (var nm in rootEnv.AllLoadedAssembliesInLoadOrder().Where(Trace.AssemblyMap.ContainsKey))
         {
             var compiler = new AssemblyCompiler(this, Trace.AssemblyMap[nm]);
             compiler.Emit(body);
         }
         var program = new JST.Program
             (new JST.Statements
                  (new JST.ExpressionStatement
                       (new JST.StatementsPseudoExpression(new JST.Statements(body), null))));
         var fileName = Path.Combine(Env.OutputDirectory, Trace.Name + ".js");
         program.ToFile(fileName, Env.PrettyPrint);
         Env.Log(new GeneratedJavaScriptFile("trace '" + Trace.Name + "'", fileName));
     }
 }
Example #3
0
 public void Emit()
 {
     if (Trace.Flavor == TraceFlavor.Remainder)
     {
         foreach (var kv in Trace.AssemblyMap)
         {
             var compiler = new AssemblyCompiler(this, kv.Value);
             compiler.Emit(null);
         }
     }
     else
     {
         var rootEnv = Env.Global.Environment();
         var body    = new Seq <JST.Statement>();
         body.Add(JST.Statement.Var(RootId, new JST.Identifier(Env.Root).ToE()));
         foreach (var nm in rootEnv.AllLoadedAssembliesInLoadOrder().Where(Trace.AssemblyMap.ContainsKey))
         {
             var compiler = new AssemblyCompiler(this, Trace.AssemblyMap[nm]);
             compiler.Emit(body);
         }
         var program = new JST.Program
                           (new JST.Statements
                               (new JST.ExpressionStatement
                                   (new JST.StatementsPseudoExpression(new JST.Statements(body), null))));
         var fileName = Path.Combine(Env.OutputDirectory, Trace.Name + ".js");
         program.ToFile(fileName, Env.PrettyPrint);
         Env.Log(new GeneratedJavaScriptFile("trace '" + Trace.Name + "'", fileName));
     }
 }
Example #4
0
        // Trace mode entry point
        public TypeDefinitionCompiler(AssemblyCompiler parent, TypeTrace typeTrace)
        {
            Env            = parent.Env;
            Parent         = parent;
            TyconEnv       = parent.AssmEnv.AddType(typeTrace.Type);
            this.TypeTrace = typeTrace;

            if (typeTrace.IncludeType && typeTrace.Parent.Parent.Flavor == TraceFlavor.Remainder)
            {
                // Create a self-loader fragment file
                NameSupply = new JST.NameSupply(Constants.Globals);
                // Will be bound by function passed to root's BindType
                RootId           = NameSupply.GenSym();
                AssemblyId       = NameSupply.GenSym();
                TypeDefinitionId = NameSupply.GenSym();
            }
            else
            {
                // Possibly inline type definition and/or method definitions into trace
                NameSupply = parent.NameSupply;
                // Already bound by parent
                RootId     = parent.RootId;
                AssemblyId = parent.AssemblyId;
                // Will be bound locally
                TypeDefinitionId = NameSupply.GenSym();
            }
        }
 // Collecting mode entry point
 public TypeDefinitionCompiler(AssemblyCompiler parent, CST.TypeDef typeDef)
 {
     Env = parent.Env;
     Parent = parent;
     TyconEnv = parent.AssmEnv.AddType(typeDef);
     TypeTrace = null;
     // Inline type definition and method definitions into overall assembly
     NameSupply = parent.NameSupply;
     // Already bound by parent
     RootId = parent.RootId;
     AssemblyId = parent.AssemblyId;
     // Will be bound locally
     TypeDefinitionId = NameSupply.GenSym();
 }
Example #6
0
 // Collecting mode entry point
 public TypeDefinitionCompiler(AssemblyCompiler parent, CST.TypeDef typeDef)
 {
     Env       = parent.Env;
     Parent    = parent;
     TyconEnv  = parent.AssmEnv.AddType(typeDef);
     TypeTrace = null;
     // Inline type definition and method definitions into overall assembly
     NameSupply = parent.NameSupply;
     // Already bound by parent
     RootId     = parent.RootId;
     AssemblyId = parent.AssemblyId;
     // Will be bound locally
     TypeDefinitionId = NameSupply.GenSym();
 }
Example #7
0
        private static bool IsUpToDate(CompilerEnvironment env, CST.AssemblyDef assembly, bool complain)
        {
            var annot = assembly.Annotations.OfType <CST.AssemblyFileAnnotation>().FirstOrDefault();

            if (annot == null)
            {
                throw new InvalidOperationException("assembly is missing file annotation");
            }
            var fn           = default(string);
            var lastCompTime = AssemblyCompiler.LastCompilationTime(env, assembly.Name, out fn);

            if (lastCompTime.HasValue)
            {
                if (annot.LastWriteTime <= lastCompTime.Value)
                {
                    return(true);
                }
                else
                {
                    if (complain)
                    {
                        env.Log
                            (new OutOfDateAssemblyMessage(assembly.Name, annot.CanonicalFileName, fn));
                    }
                    return(false);
                }
            }
            else
            {
                if (complain)
                {
                    env.Log(new AssemblyNotCompiledMessage(assembly.Name, fn));
                }
                return(false);
            }
        }
Example #8
0
        public static int Main(string[] args)
        {
            var env = new CompilerEnvironment();

            try
            {
                // Collect command line args
                var cl = new CompilerCommandLine(env.Log, env);
                cl.MergeFromArgs(args);

                if (env.CompilationMode == CompilationMode.Traced && env.TraceFileNames.Count == 0 && string.IsNullOrEmpty(env.FinalTraceName))
                {
                    env.Log(new UsageMessage("'-mode traced' must be accompanied by at least on of '-trace' or '-finalTraceName' options."));
                    throw new ExitException();
                }

                env.SetupPrimTracer();

                // ----------------------------------------
                // Load the assemblies
                // ----------------------------------------

                // Renames
                var subst = new CST.AssemblyNameSubstitution(env.Log, env.PrimTracer, env.AssemblyNameResolution);
                foreach (var r in env.RenameRules)
                {
                    subst.Add(r);
                }

                // Augmentations
                var augmentations = new CST.AugmentationDatabase(subst);
                foreach (var fn in env.AugmentationFileNames)
                {
                    augmentations.AddFile(Path.Combine(env.InputDirectory, fn));
                }
                foreach (var sn in env.OriginalStrongNames)
                {
                    augmentations.AddOriginal(sn);
                }

                // Final references
                var loadedAssemblies = new CST.LoadedAssemblyDatabase(augmentations);
                foreach (var fileName in env.ReferenceFileNames)
                {
                    loadedAssemblies.Add(fileName, false);
                }
                foreach (var fileName in env.CompileFileNames)
                {
                    loadedAssemblies.Add(fileName, true);
                }

                var loader = new CST.PELoader(loadedAssemblies);
                var global = loader.Load();

                // Done with the loader
                loader = null;

                env.SetupMetadata(global);

                try
                {
                    env.Validity.Check();

                    foreach (var assmInfo in loadedAssemblies)
                    {
                        env.Log(new CST.LoadedAssemblyMessage(assmInfo.TargetAssemblyName));
                    }

                    if (env.Tracer != null)
                    {
                        env.Tracer.Trace
                            ("Loaded assemblies",
                            w =>
                        {
                            foreach (var assemblyDef in global.Assemblies)
                            {
                                assemblyDef.Append(w);
                                w.EndLine();
                            }
                        });
                    }

                    // ----------------------------------------
                    // Setup Interop
                    // ----------------------------------------
                    env.InteropManager.Setup();

                    // ----------------------------------------
                    // Collect assemblies
                    // ----------------------------------------

                    var allAssemblies        = new Set <CST.AssemblyDef>();
                    var compilingAssemblies  = new Set <CST.AssemblyDef>();
                    var referencedAssemblies = new Set <CST.AssemblyDef>();
                    var ok = true;
                    foreach (var assmInfo in loadedAssemblies)
                    {
                        var assembly = assmInfo.AssemblyDef;
                        allAssemblies.Add(assembly);
                        if (assmInfo.ForCompilation)
                        {
                            if (string.IsNullOrEmpty(env.OutputDirectory))
                            {
                                env.Log
                                    (new SkippingJavaScriptComplilation
                                        (assembly.Name, "No output directory was given"));
                                referencedAssemblies.Add(assembly);
                            }
                            else if (env.SkipUpToDate && IsUpToDate(env, assembly, false))
                            {
                                env.Log
                                    (new SkippingJavaScriptComplilation
                                        (assembly.Name, "Previously generated JavaScript is up to date"));
                                referencedAssemblies.Add(assembly);
                            }
                            else
                            {
                                compilingAssemblies.Add(assembly);
                            }
                        }
                        else
                        {
                            if (IsUpToDate(env, assembly, true))
                            {
                                referencedAssemblies.Add(assembly);
                            }
                            else
                            {
                                ok = false;
                            }
                        }
                    }

                    // Done with compilations
                    loadedAssemblies = null;

                    if (!ok)
                    {
                        throw new ExitException();
                    }

                    if (compilingAssemblies.Count > 0)
                    {
                        // ----------------------------------------
                        // Compile
                        // ----------------------------------------

                        switch (env.CompilationMode)
                        {
                        case CompilationMode.Plain:
                        case CompilationMode.Collecting:
                            // Compile all assemblies
                            foreach (var assemblyDef in compilingAssemblies)
                            {
                                var ac = new AssemblyCompiler(env, assemblyDef);
                                ac.Emit(null);
                            }
                            break;

                        case CompilationMode.Traced:
                            // Collect the trace file info
                            if (!string.IsNullOrEmpty(env.InitialTraceFileName))
                            {
                                env.Traces.Add(env.InitialTraceFileName, true);
                            }
                            foreach (var fn in env.TraceFileNames)
                            {
                                env.Traces.Add(fn, false);
                            }
                            env.Traces.AddFinalOrRemainder(env.FinalTraceName);
                            // Compile all traces and all remaining definitions
                            foreach (var kv in env.Traces.TraceMap)
                            {
                                var compiler = new TraceCompiler(env, kv.Value);
                                compiler.Emit();
                            }
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }

                        // ----------------------------------------
                        // Runtime
                        // ----------------------------------------

                        if (env.Global.Assemblies.Any(a => a.EntryPoint != null))
                        {
                            // Emit the runtime itself
                            var compiler = new RuntimeCompiler(env);
                            compiler.Emit();
                        }
                    }
                }
                finally
                {
                    env.Teardown();
                }
            }
            catch (ExitException)
            {
                // No-op
            }
            catch (Exception e)
            {
                Console.WriteLine("Internal error: {0}", e.Message);
                Console.WriteLine("Please report this error to the developers");
                env.NumErrors++;
            }
            finally
            {
                Console.WriteLine("{0} errors, {1} warnings", env.NumErrors, env.NumWarnings);
            }
            return(env.NumErrors == 0 ? 0 : 1);
        }
Example #9
0
        public static int Main(string[] args)
        {
            var env = new CompilerEnvironment();
            try
            {
                // Collect command line args
                var cl = new CompilerCommandLine(env.Log, env);
                cl.MergeFromArgs(args);

                if (env.CompilationMode == CompilationMode.Traced && env.TraceFileNames.Count == 0 && string.IsNullOrEmpty(env.FinalTraceName))
                {
                    env.Log(new UsageMessage("'-mode traced' must be accompanied by at least on of '-trace' or '-finalTraceName' options."));
                    throw new ExitException();
                }

                env.SetupPrimTracer();

                // ----------------------------------------
                // Load the assemblies
                // ----------------------------------------

                // Renames
                var subst = new CST.AssemblyNameSubstitution(env.Log, env.PrimTracer, env.AssemblyNameResolution);
                foreach (var r in env.RenameRules)
                    subst.Add(r);

                // Augmentations
                var augmentations = new CST.AugmentationDatabase(subst);
                foreach (var fn in env.AugmentationFileNames)
                    augmentations.AddFile(Path.Combine(env.InputDirectory, fn));
                foreach (var sn in env.OriginalStrongNames)
                    augmentations.AddOriginal(sn);

                // Final references
                var loadedAssemblies = new CST.LoadedAssemblyDatabase(augmentations);
                foreach (var fileName in env.ReferenceFileNames)
                    loadedAssemblies.Add(fileName, false);
                foreach (var fileName in env.CompileFileNames)
                    loadedAssemblies.Add(fileName, true);

                var loader = new CST.PELoader(loadedAssemblies);
                var global = loader.Load();

                // Done with the loader
                loader = null;

                env.SetupMetadata(global);

                try
                {
                    env.Validity.Check();

                    foreach (var assmInfo in loadedAssemblies)
                        env.Log(new CST.LoadedAssemblyMessage(assmInfo.TargetAssemblyName));

                    if (env.Tracer != null)
                        env.Tracer.Trace
                            ("Loaded assemblies",
                             w =>
                                 {
                                     foreach (var assemblyDef in global.Assemblies)
                                     {
                                         assemblyDef.Append(w);
                                         w.EndLine();
                                     }
                                 });

                    // ----------------------------------------
                    // Setup Interop
                    // ----------------------------------------
                    env.InteropManager.Setup();

                    // ----------------------------------------
                    // Collect assemblies
                    // ----------------------------------------

                    var allAssemblies = new Set<CST.AssemblyDef>();
                    var compilingAssemblies = new Set<CST.AssemblyDef>();
                    var referencedAssemblies = new Set<CST.AssemblyDef>();
                    var ok = true;
                    foreach (var assmInfo in loadedAssemblies)
                    {
                        var assembly = assmInfo.AssemblyDef;
                        allAssemblies.Add(assembly);
                        if (assmInfo.ForCompilation)
                        {
                            if (string.IsNullOrEmpty(env.OutputDirectory))
                            {
                                env.Log
                                    (new SkippingJavaScriptComplilation
                                         (assembly.Name, "No output directory was given"));
                                referencedAssemblies.Add(assembly);
                            }
                            else if (env.SkipUpToDate && IsUpToDate(env, assembly, false))
                            {
                                env.Log
                                    (new SkippingJavaScriptComplilation
                                         (assembly.Name, "Previously generated JavaScript is up to date"));
                                referencedAssemblies.Add(assembly);
                            }
                            else
                                compilingAssemblies.Add(assembly);
                        }
                        else
                        {
                            if (IsUpToDate(env, assembly, true))
                                referencedAssemblies.Add(assembly);
                            else
                                ok = false;
                        }
                    }

                    // Done with compilations
                    loadedAssemblies = null;                    

                    if (!ok)
                        throw new ExitException();

                    if (compilingAssemblies.Count > 0)
                    {
                        // ----------------------------------------
                        // Compile
                        // ----------------------------------------

                        switch (env.CompilationMode)
                        {
                        case CompilationMode.Plain:
                        case CompilationMode.Collecting:
                            // Compile all assemblies
                            foreach (var assemblyDef in compilingAssemblies)
                            {
                                var ac = new AssemblyCompiler(env, assemblyDef);
                                ac.Emit(null);
                            }
                            break;
                        case CompilationMode.Traced:
                            // Collect the trace file info
                            if (!string.IsNullOrEmpty(env.InitialTraceFileName))
                                env.Traces.Add(env.InitialTraceFileName, true);
                            foreach (var fn in env.TraceFileNames)
                                env.Traces.Add(fn, false);
                            env.Traces.AddFinalOrRemainder(env.FinalTraceName);
                            // Compile all traces and all remaining definitions
                            foreach (var kv in env.Traces.TraceMap)
                            {
                                var compiler = new TraceCompiler(env, kv.Value);
                                compiler.Emit();
                            }
                            break;
                        default:
                            throw new ArgumentOutOfRangeException();
                        }

                        // ----------------------------------------
                        // Runtime
                        // ----------------------------------------

                        if (env.Global.Assemblies.Any(a => a.EntryPoint != null))
                        {
                            // Emit the runtime itself
                            var compiler = new RuntimeCompiler(env);
                            compiler.Emit();
                        }
                    }
                }
                finally
                {
                    env.Teardown();
                }
            }
            catch (ExitException)
            {
                // No-op
            }
            catch (Exception e)
            {
                Console.WriteLine("Internal error: {0}", e.Message);
                Console.WriteLine("Please report this error to the developers");
                env.NumErrors++;
            }
            finally
            {
                Console.WriteLine("{0} errors, {1} warnings", env.NumErrors, env.NumWarnings);
            }
            return env.NumErrors == 0 ? 0 : 1;
        }