Esempio n. 1
0
        // ----------------------------------------------------------------------
        // Entry point from AssemblyCompiler
        // ----------------------------------------------------------------------

        public void Emit(Seq <JST.Statement> body)
        {
            if (Env.BreakOnBreak &&
                Env.AttributeHelper.TypeHasAttribute(TyconEnv.Assembly, TyconEnv.Type, Env.AttributeHelper.BreakAttributeRef, false, false))
            {
                System.Diagnostics.Debugger.Break();
            }

            CollectMembers();

            var typeName = CST.CSTWriter.WithAppend
                               (Env.Global, CST.WriterStyle.Uniform, TyconEnv.Type.EffectiveName(Env.Global).Append);
            var slotName = Env.GlobalMapping.ResolveTypeDefToSlot(TyconEnv.Assembly, TyconEnv.Type);

            if (TypeTrace != null && TypeTrace.IncludeType && TypeTrace.Parent.Parent.Flavor == TraceFlavor.Remainder)
            {
                // Self-loader fragment
                var assmName = CST.CSTWriter.WithAppend
                                   (Env.Global, CST.WriterStyle.Uniform, TyconEnv.Assembly.Name.Append);
                var funcBody = new Seq <JST.Statement>();
                BuildTypeStructure(funcBody);
                var func = new JST.FunctionExpression
                               (new Seq <JST.Identifier> {
                    RootId, AssemblyId, TypeDefinitionId
                }, new JST.Statements(funcBody));
                var loaderBody = new Seq <JST.Statement>();
                if (Env.DebugMode)
                {
                    loaderBody.Add(new JST.CommentStatement(TyconEnv.ToString()));
                }
                loaderBody.Add
                    (JST.Statement.DotCall
                        (new JST.Identifier(Env.Root).ToE(),
                        Constants.RootBindType,
                        new JST.StringLiteral(assmName),
                        new JST.StringLiteral(slotName),
                        new JST.StringLiteral(typeName),
                        func));
                var program  = new JST.Program(new JST.Statements(loaderBody));
                var typePath = Path.Combine
                                   (Path.Combine(Env.OutputDirectory, JST.Lexemes.StringToFileName(assmName)), slotName);
                var fileName = Path.Combine(typePath, Constants.TypeFileName);
                program.ToFile(fileName, Env.PrettyPrint);
                Env.Log(new GeneratedJavaScriptFile("type '" + TyconEnv.TypeConstructorRef + "'", fileName));

                CompileMethods(null, NameSupply);
            }
            else if (TypeTrace != null && !TypeTrace.IncludeType && TypeTrace.Parent.Parent.Flavor == TraceFlavor.Remainder)
            {
                // Just passisng through
                CompileMethods(body, NameSupply);
            }
            else if (TypeTrace != null && !TypeTrace.IncludeType)
            {
                // Type defined elsewhere, include some/all methods only
                body.Add
                    (JST.Statement.Var
                        (TypeDefinitionId,
                        JST.Expression.DotCall
                            (AssemblyId.ToE(),
                            new JST.Identifier(Constants.AssemblyTypeBuilderSlot(slotName)),
                            Env.JSTHelpers.PhaseExpression(TypePhase.Slots))));
                CompileMethods(body, NameSupply);
            }
            else
            {
                // Inline type definition and some/all methods
                if (Env.DebugMode)
                {
                    body.Add(new JST.CommentStatement(TyconEnv.ToString()));
                }
                // We must construct the type explicity to phase 1 rather than using type compiler environment
                // since it thinks the type is already at phase 2.
                body.Add
                    (JST.Statement.Var
                        (TypeDefinitionId,
                        JST.Expression.DotCall
                            (AssemblyId.ToE(),
                            new JST.Identifier(Constants.AssemblyTypeBuilderSlot(slotName)),
                            Env.JSTHelpers.PhaseExpression(TypePhase.Id))));
                BuildTypeStructure(body);
                CompileMethods(body, NameSupply);
            }
        }