private void EmitConstructor(DeclarationEmitContext dgc, IEnumerable<string> autoprops)
        {
            var ltype = dgc.LType;
            var rtype = ltype.RType;
            var typename = ltype.CodeName;

            var declctx = (IDeclarationContext)ltype;

            // method context for constructor
            var context = ModuleFactory.CreateMethodContext(declctx);

            // rewriter
            var rewriter = CreateRewriter(dgc, context);

            // writer receiving constructor and related code.
            JScriptWriter jsw = new JScriptWriter();

            // initialize the prototype
            string basename = null;
            if (null != ltype.BaseType)
            {
                if (null != ltype.BaseType.RType)
                {
                    basename = ltype.BaseType.CodeName;
                    jsw.WriteLine(typename + ".prototype = new " + basename + "();");
                    jsw.WriteLine(typename + ".prototype.constructor = " + typename + ";");
                }
            }

            // static
            EmitStaticInitializer(dgc, jsw);

            // analyze constructors ...
            var cls = dgc.Source.ClassDeclaration;
            var constructors = cls.Members.OfType<ConstructorDeclarationSyntax>();
            if (constructors.Count() > 1)
            {
                throw new Exception("multiple constructors are not supported [" + typename + "].");
            }

            var constructor = constructors.FirstOrDefault();
            var ps = string.Empty;
            if (null != constructor)
            {
                var parameters = constructor.ParameterList.ChildNodes().OfType<ParameterSyntax>();
                rewriter.AddMethodParameters(parameters);
                ps = TranslateMethodParameters(parameters);
            }


            // constructor method
            jsw.WriteLine("function " + typename + "(" + ps + ")");
            jsw.EnterBlock();

            // call base constructor
            if (null != basename)
            {
                jsw.WriteLine(basename + ".prototype.constructor.call(this);");
            }

            // type identifier
            jsw.WriteLine("this.$type = '" + typename + "';");

            // initialize our 'this' replacement.
            var cthis = CreateLambdaThis();
            jsw.Write(cthis.ToString());

            foreach (var ap in autoprops)
            {
                jsw.Write(Settings.OuterThis + "." + DeriveAutomaticName(ap) + " = null;");
            }

            foreach (var dp in dgc.DependencyPropertyInitializations)
            {
                // TODO: constant management required.
                //var dvalue = dp.DefaultMetadata.DefaultValue;
                object dvalue = null;
                if (null == dvalue)
                {
                    jsw.Write(Settings.OuterThis + ".InitValue(\"" + dp.Name + "\");");
                }
                else
                {
                    jsw.Write(Settings.OuterThis + ".InitValue(\"" + dp.Name + "\", " + dvalue + ");");
                }
            }

            // field initializers and constructor body ...
            EmitConstructorFields(dgc, rewriter, jsw);

            jsw.LeaveBlock();

            // commit to class output
            dgc.Writer.Write(jsw);
        }
        private void EmitDependencyPropertyDefinitions(JScriptWriter jsw, List<DependencyProperty> dplist)
        {
            foreach (var dp in dplist)
            {
                var dptype = dp.PropertyType;
                var ldptype = _context.TranslateRType(dptype, TranslateOptions.MustExist);
                var convert = ldptype.GetConvertMethod();

                jsw.Write(dp.Name + "Property:");
                jsw.EnterBlock();

                jsw.WriteLine("Type: \"" + ldptype.ID + "\",");

                if (null != convert)
                {
                    jsw.WriteLine("Convert: function(p) { return " + convert.ID + "(p); },");
                }

                jsw.LeaveBlock();
                jsw.WriteLine(",");
            }
        }
        private void EmitStaticInitializer(DeclarationEmitContext dgc, JScriptWriter staticinit)
        {
            var cls = dgc.Source.ClassDeclaration;
            var ltype = dgc.LType;
            var typename = ltype.CodeName;
            var rtype = ltype.RType;

            staticinit.WriteLine(typename + ".prototype.$static = ");
            staticinit.EnterBlock();

            if (null != ltype.BaseType)
            {
                staticinit.WriteLine("BaseClass: \"" + ltype.BaseType.CodeName + "\",");
            }

            var dplist = new List<DependencyProperty>();

            // emit static variables
            foreach (var fielddecl in cls.ChildNodes().OfType<FieldDeclarationSyntax>())
            {
                foreach (var declarator in fielddecl.DescendantNodes().OfType<VariableDeclaratorSyntax>())
                {
                    var id = declarator.Identifier.ToString();
                    var field = rtype.GetField(id, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

                    if (null != field && field.IsStatic)
                    {
                        if (field.FieldType == typeof(DependencyProperty))
                        {
                            var dp = field.GetValue(null) as DependencyProperty;
                            if (null == dp) continue;
                            dplist.Add(dp);
                        }
                    }
                }
            }

            EmitDependencyPropertyDefinitions(staticinit, dplist);

            staticinit.LeaveBlock();
            staticinit.WriteLine(";");

        }
Пример #4
0
        private void EmitScript(XmlWriter writer)
        {
            EmitScriptIncludesBefore(writer);

            var code = new JScriptWriter();
            code.WriteLine();
            code.WriteLine("// generated");
            code.Write(_scriptincludes);
            code.Write(Declarations);

            // consumed, more to come ...

            // resize handler function (unused currently)
            code.WriteLine("function docResized() ");
            code.EnterBlock();
            code.WriteLine("ResizeManager_Initialize();");
            code.Write(_resizebuilder);
            code.LeaveBlock();

            // bindings initialization
            code.WriteLine();
            code.WriteLine("function Bindings_Initialize() ");
            code.EnterBlock();
            code.WriteLine("if(window['BindingObject'] !== undefined)");
            code.EnterBlock();
            code.Write(CodeBuilder);
            code.LeaveBlock();
            code.LeaveBlock();

            // primary document ready handler
            code.WriteLine();
            code.WriteLine("docReady(function() ");
            code.EnterBlock();
            code.WriteLine("DataContext_Initialize(function() { Bindings_Initialize(); });");
            code.WriteLine("docResized();");
            code.WriteLine("DragDrop_Initialize();");
            code.LeaveBlock();
            code.WriteLine(");");


            // TraceTarget.Trace("jscript code in HTML:\n{0}\n\n", code.Text);

            writer.WriteStartElement("script");

            if (!IsOptimized)
            {

                writer.WriteRaw(code.Text);
            }
            else
            {
                Information("generating optimized code ...");
                var builder = new JScriptBuilder();
                builder.SuppressedGlobalFunctions.Add("trace");
                builder.RewriteProgram(code);
                writer.WriteRaw(builder.Text);
            }

            writer.WriteEndElement();

            // application specific initializer scripts ...
            _scriptincludes = new JScriptBuilder();
            EmitScriptIncludesAfter(writer);

            if (_scriptincludes.Text.Length > 0)
            {
                writer.WriteStartElement("script");
                writer.WriteRaw(_scriptincludes.Text);
                writer.WriteEndElement();
            }
        }