Пример #1
0
        public bool RestoreWriter(IWriterInfo writer)
        {
            if (this.Emitter.Output != writer.Output)
            {
                this.Emitter.Output    = writer.Output;
                this.Emitter.IsNewLine = writer.IsNewLine;
                this.Emitter.ResetLevel(writer.Level);
                this.Emitter.Comma = writer.Comma;

                return(true);
            }

            return(false);
        }
Пример #2
0
        protected void EmitGeneratorBlock()
        {
            this.BeginBlock();
            var args = this.Parameters;

            if (!IsEnumeratorReturn)
            {
                this.WriteReturn(true);
                this.Write("new ");

                if (this.ReturnType.IsParameterized)
                {
                    this.Write("(Bridge.GeneratorEnumerable$1(" + BridgeTypes.ToJsName(this.ReturnType.TypeArguments[0], this.Emitter) + "))");
                }
                else
                {
                    this.Write("Bridge.GeneratorEnumerable");
                }

                this.WriteOpenParentheses();

                this.Write(JS.Funcs.BRIDGE_BIND + "(this, ");
                this.WriteFunction();
                if (args.Count > 0)
                {
                    this.WriteOpenParentheses();

                    for (int i = 0; i < args.Count; i++)
                    {
                        this.Write(args[i]);

                        if (i < args.Count - 1)
                        {
                            this.Write(", ");
                        }
                    }

                    this.WriteCloseParentheses();
                }
                else
                {
                    this.WriteOpenCloseParentheses(true);
                }

                this.WriteSpace();

                this.BeginBlock();
            }

            this.WriteVar(true);
            this.Write(JS.Vars.ASYNC_STEP + " = 0");
            this.Emitter.Comma = true;
            this.Indent();

            // This is required to add async variables into Emitter.AsyncVariables and emit them prior to body
            IWriterInfo   writerInfo = this.SaveWriter();
            StringBuilder body       = this.NewWriter();

            Emitter.ResetLevel(writerInfo.Level - 1);
            this.EmitGeneratorBody();
            this.RestoreWriter(writerInfo);

            foreach (var localVar in this.Emitter.AsyncVariables)
            {
                this.EnsureComma(true);
                this.Write(localVar);
                this.Emitter.Comma = true;
            }

            this.Emitter.Comma = false;
            this.WriteSemiColon();
            this.Outdent();
            this.WriteNewLine();
            this.WriteNewLine();

            this.WriteVar(true);
            this.Write(JS.Vars.ENUMERATOR + " = new ");

            if (this.ReturnType.IsParameterized)
            {
                this.Write("(" + JS.Types.Bridge.Generator.NAME_GENERIC + "(" + BridgeTypes.ToJsName(this.ReturnType.TypeArguments[0], this.Emitter) + "))");
            }
            else
            {
                this.Write(JS.Types.Bridge.Generator.NAME);
            }

            this.WriteOpenParentheses();
            this.Write(JS.Funcs.BRIDGE_BIND + "(this, ");
            this.WriteFunction();
            this.WriteOpenCloseParentheses(true);

            this.Write(body);

            this.WriteCloseParentheses();
            this.EmitFinallyHandler();
            this.WriteCloseParentheses();
            this.WriteSemiColon();
            this.WriteNewLine();

            this.WriteReturn(true);
            this.Write(JS.Vars.ENUMERATOR);
            this.WriteSemiColon();
            this.WriteNewLine();

            if (!IsEnumeratorReturn)
            {
                this.EndBlock();
                if (args.Count > 0)
                {
                    this.Write(", arguments");
                }
                this.WriteCloseParentheses();
                this.WriteCloseParentheses();
                this.WriteSemiColon();
                this.WriteNewLine();
            }

            this.EndBlock();
        }
Пример #3
0
        protected virtual void WrapBody(IWriterInfo oldWriter, string[] ctorWrappers, string ctorParams)
        {
            var body = this.Emitter.Output.ToString();

            this.RestoreWriter(oldWriter);

            List <string> endParts = new List <string>();
            StringBuilder sb       = new StringBuilder();

            for (int i = 0; i < ctorWrappers.Length; i++)
            {
                var isLast      = i == (ctorWrappers.Length - 1);
                var ctorWrapper = ctorWrappers[i];
                var parts       = ctorWrapper.Split(new[] { CS.Wrappers.Params.BODY }, StringSplitOptions.RemoveEmptyEntries);
                endParts.Add(parts[1]);

                sb.Append(parts[0]);
                sb.Append("function ");
                sb.Append(ctorParams);
                sb.Append(" {");

                if (!isLast)
                {
                    sb.Append(Bridge.Translator.Emitter.NEW_LINE);
                }

                Indent();

                for (var j = 0; j < this.Emitter.Level; j++)
                {
                    sb.Append(Bridge.Translator.Emitter.INDENT);
                }

                if (isLast)
                {
                    sb.Append(this.WriteIndentToString(body));
                }
            }

            endParts.Reverse();

            var newLine = false;

            foreach (var endPart in endParts)
            {
                Outdent();

                if (newLine)
                {
                    sb.Append(Bridge.Translator.Emitter.NEW_LINE);
                    for (var j = 0; j < this.Emitter.Level; j++)
                    {
                        sb.Append(Bridge.Translator.Emitter.INDENT);
                    }
                }
                else if (sb.ToString().Substring(sb.Length - 4) == Bridge.Translator.Emitter.INDENT)
                {
                    sb.Length -= 4;
                }
                newLine = true;

                sb.Append("}");
                sb.Append(endPart);
            }

            this.Write(sb.ToString());
            this.WriteNewLine();
        }
Пример #4
0
        protected virtual void EmitCtorForInstantiableClass()
        {
            var baseType        = this.Emitter.GetBaseTypeDefinition();
            var typeDef         = this.Emitter.GetTypeDefinition();
            var isObjectLiteral = this.Emitter.Validator.IsObjectLiteral(typeDef);
            var isPlainMode     = this.Emitter.Validator.GetObjectCreateMode(typeDef) == 0;

            var ctorWrappers = isObjectLiteral ? new string[0] : this.EmitInitMembers().ToArray();

            if (!this.TypeInfo.HasRealInstantiable(this.Emitter) && ctorWrappers.Length == 0 || isObjectLiteral && isPlainMode)
            {
                if (this.ctorHeader)
                {
                    this.WriteNewLine();
                    this.EndBlock();
                }
                return;
            }

            bool forceDefCtor = isObjectLiteral && this.Emitter.Validator.GetObjectCreateMode(typeDef) == 1 && this.TypeInfo.Ctors.Count == 0;

            if (typeDef.IsValueType || forceDefCtor || (this.TypeInfo.Ctors.Count == 0 && ctorWrappers.Length > 0))
            {
                this.TypeInfo.Ctors.Add(new ConstructorDeclaration
                {
                    Modifiers = Modifiers.Public,
                    Body      = new BlockStatement()
                });
            }

            if (!this.ctorHeader && this.TypeInfo.Ctors.Count > 0)
            {
                this.EnsureComma();
                this.ctorHeader = true;
                this.Write(JS.Fields.CTORS);
                this.WriteColon();
                this.BeginBlock();
            }

            this.Emitter.InConstructor = true;
            foreach (var ctor in this.TypeInfo.Ctors)
            {
                this.EnsureComma();
                this.ResetLocals();
                var prevMap      = this.BuildLocalsMap();
                var prevNamesMap = this.BuildLocalsNamesMap();
                this.AddLocals(ctor.Parameters, ctor.Body);

                var ctorName = JS.Funcs.CONSTRUCTOR;

                if (this.TypeInfo.Ctors.Count > 1 && ctor.Parameters.Count > 0)
                {
                    var overloads = OverloadsCollection.Create(this.Emitter, ctor);
                    ctorName = overloads.GetOverloadName();
                }

                XmlToJsDoc.EmitComment(this, ctor);
                this.Write(ctorName);

                this.WriteColon();
                this.WriteFunction();

                int pos = this.Emitter.Output.Length;
                this.EmitMethodParameters(ctor.Parameters, null, ctor);
                var ctorParams = this.Emitter.Output.ToString().Substring(pos);

                this.WriteSpace();
                this.BeginBlock();
                var len            = this.Emitter.Output.Length;
                var requireNewLine = false;

                var         noThisInvocation = ctor.Initializer == null || ctor.Initializer.IsNull || ctor.Initializer.ConstructorInitializerType == ConstructorInitializerType.Base;
                IWriterInfo oldWriter        = null;
                if (ctorWrappers.Length > 0 && noThisInvocation)
                {
                    oldWriter = this.SaveWriter();
                    this.NewWriter();
                }

                this.ConvertParamsToReferences(ctor.Parameters);

                if (len != this.Emitter.Output.Length)
                {
                    requireNewLine = true;
                }

                if (isObjectLiteral)
                {
                    if (requireNewLine)
                    {
                        this.WriteNewLine();
                    }

                    this.Write("var " + JS.Vars.D_THIS + " = ");

                    var isBaseObjectLiteral = baseType != null && this.Emitter.Validator.IsObjectLiteral(baseType);
                    if (isBaseObjectLiteral && baseType != null && (!this.Emitter.Validator.IsExternalType(baseType) || this.Emitter.Validator.IsBridgeClass(baseType)) ||
                        (ctor.Initializer != null && ctor.Initializer.ConstructorInitializerType == ConstructorInitializerType.This))
                    {
                        this.EmitBaseConstructor(ctor, ctorName, true);
                    }
                    else if (isBaseObjectLiteral && baseType != null && ctor.Initializer != null &&
                             ctor.Initializer.ConstructorInitializerType == ConstructorInitializerType.Base)
                    {
                        this.EmitExternalBaseCtor(ctor, ref requireNewLine);
                    }
                    else
                    {
                        this.Write("{};");
                    }

                    this.WriteNewLine();

                    string name = this.Emitter.Validator.GetCustomTypeName(typeDef, this.Emitter, false);
                    if (name.IsEmpty())
                    {
                        name = BridgeTypes.DefinitionToJsName(this.TypeInfo.Type, this.Emitter);
                    }

                    this.Write(JS.Vars.D_THIS + "." + JS.Funcs.GET_TYPE + " = function () { return " + name + "; };");

                    this.WriteNewLine();
                    this.Write("(function ()");
                    this.BeginBlock();
                    requireNewLine = false;
                }

                if (noThisInvocation)
                {
                    if (requireNewLine)
                    {
                        this.WriteNewLine();
                    }

                    if (isObjectLiteral)
                    {
                        var fieldBlock = new FieldBlock(this.Emitter, this.TypeInfo, false, false, true);
                        fieldBlock.Emit();

                        var properties = this.TypeInfo.InstanceProperties;

                        var names = new List <string>(properties.Keys);

                        foreach (var name in names)
                        {
                            var props = properties[name];

                            foreach (var prop in props)
                            {
                                var p = prop as PropertyDeclaration;
                                if (p != null)
                                {
                                    if (p.Getter.Body.IsNull && p.Setter.Body.IsNull)
                                    {
                                        continue;
                                    }

                                    this.Write(JS.Types.Object.DEFINEPROPERTY);
                                    this.WriteOpenParentheses();
                                    this.Write("this, ");
                                    this.WriteScript(OverloadsCollection.Create(this.Emitter, p).GetOverloadName());
                                    this.WriteComma();
                                    this.Emitter.Comma = false;
                                    this.BeginBlock();
                                    var memberResult = this.Emitter.Resolver.ResolveNode(p, this.Emitter) as MemberResolveResult;
                                    var block        = new VisitorPropertyBlock(this.Emitter, p);
                                    block.EmitPropertyMethod(p, p.Getter, ((IProperty)memberResult.Member).Getter, false, true);
                                    block.EmitPropertyMethod(p, p.Setter, ((IProperty)memberResult.Member).Setter, true, true);
                                    this.EnsureComma(true);
                                    this.Write(JS.Fields.ENUMERABLE + ": true");
                                    this.WriteNewLine();
                                    this.EndBlock();
                                    this.WriteCloseParentheses();
                                    this.Write(";");
                                    this.WriteNewLine();
                                }
                            }
                        }
                    }
                    else
                    {
                        this.Write("this." + JS.Funcs.INITIALIZE + "();");
                        requireNewLine = true;
                    }
                }

                if (!isObjectLiteral)
                {
                    if (baseType != null && (!this.Emitter.Validator.IsExternalType(baseType) || this.Emitter.Validator.IsBridgeClass(baseType)) ||
                        (ctor.Initializer != null && ctor.Initializer.ConstructorInitializerType == ConstructorInitializerType.This))
                    {
                        if (requireNewLine)
                        {
                            this.WriteNewLine();
                            requireNewLine = false;
                        }
                        this.EmitBaseConstructor(ctor, ctorName, false);
                    }
                    else if (baseType != null && ctor.Initializer != null &&
                             ctor.Initializer.ConstructorInitializerType == ConstructorInitializerType.Base)
                    {
                        this.EmitExternalBaseCtor(ctor, ref requireNewLine);
                    }
                }

                var script = this.Emitter.GetScript(ctor);

                if (script == null)
                {
                    if (ctor.Body.HasChildren)
                    {
                        var beginPosition = this.Emitter.Output.Length;
                        if (requireNewLine)
                        {
                            this.WriteNewLine();
                        }

                        ctor.Body.AcceptChildren(this.Emitter);

                        if (!this.Emitter.IsAsync)
                        {
                            this.EmitTempVars(beginPosition, true);
                        }
                    }
                    else if (requireNewLine)
                    {
                        this.WriteNewLine();
                    }
                }
                else
                {
                    if (requireNewLine)
                    {
                        this.WriteNewLine();
                    }

                    this.WriteLines(script);
                }

                if (oldWriter != null)
                {
                    this.WrapBody(oldWriter, ctorWrappers, ctorParams);
                }

                if (isObjectLiteral)
                {
                    if (requireNewLine)
                    {
                        this.WriteNewLine();
                    }
                    this.EndBlock();
                    this.Write(")." + JS.Funcs.CALL + "(" + JS.Vars.D_THIS + ");");
                    this.WriteNewLine();
                    this.Write("return " + JS.Vars.D_THIS + ";");
                    this.WriteNewLine();
                }

                this.EndBlock();
                this.Emitter.Comma = true;
                this.ClearLocalsMap(prevMap);
                this.ClearLocalsNamesMap(prevNamesMap);
            }

            this.Emitter.InConstructor = false;

            if (this.ctorHeader)
            {
                this.WriteNewLine();
                this.EndBlock();
            }
        }
Пример #5
0
        protected virtual bool WriteObject(string objectName, List <TypeConfigItem> members, string format, string interfaceFormat)
        {
            bool        hasProperties = this.HasProperties(objectName, members);
            int         pos           = 0;
            IWriterInfo writer        = null;
            bool        beginBlock    = false;

            if (hasProperties && objectName != null && !this.IsObjectLiteral)
            {
                beginBlock = true;
                pos        = this.Emitter.Output.Length;
                writer     = this.SaveWriter();
                this.EnsureComma();
                this.Write(objectName);

                this.WriteColon();
                this.BeginBlock();
            }

            bool isProperty = JS.Fields.PROPERTIES == objectName;
            bool isField    = JS.Fields.FIELDS == objectName;
            int  count      = 0;

            foreach (var member in members)
            {
                object constValue    = null;
                bool   isPrimitive   = false;
                var    primitiveExpr = member.Initializer as PrimitiveExpression;
                bool   write         = false;
                bool   writeScript   = false;

                if (primitiveExpr != null)
                {
                    //isPrimitive = true;
                    constValue = primitiveExpr.Value;

                    ResolveResult rr = null;
                    if (member.VarInitializer != null)
                    {
                        rr = this.Emitter.Resolver.ResolveNode(member.VarInitializer, this.Emitter);
                    }
                    else
                    {
                        rr = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter);
                    }

                    if (rr != null && rr.Type.Kind == TypeKind.Enum)
                    {
                        constValue  = Helpers.GetEnumValue(this.Emitter, rr.Type, constValue);
                        writeScript = true;
                    }
                }

                if (constValue is RawValue)
                {
                    constValue  = constValue.ToString();
                    write       = true;
                    writeScript = false;
                }

                var isNull = member.Initializer.IsNull || member.Initializer is NullReferenceExpression || member.Initializer.Parent == null;

                if (!isNull && !isPrimitive)
                {
                    var constrr = this.Emitter.Resolver.ResolveNode(member.Initializer, this.Emitter);
                    if (constrr != null && constrr.IsCompileTimeConstant)
                    {
                        //isPrimitive = true;
                        constValue = constrr.ConstantValue;

                        var expectedType = this.Emitter.Resolver.Resolver.GetExpectedType(member.Initializer);
                        if (!expectedType.Equals(constrr.Type) && expectedType.Kind != TypeKind.Dynamic)
                        {
                            try
                            {
                                constValue = Convert.ChangeType(constValue, ReflectionHelper.GetTypeCode(expectedType));
                            }
                            catch (Exception)
                            {
                                this.Emitter.Log.Warn($"FieldBlock: Convert.ChangeType is failed. Value type: {constrr.Type.FullName}, Target type: {expectedType.FullName}");
                            }
                        }

                        if (constrr.Type.Kind == TypeKind.Enum)
                        {
                            constValue = Helpers.GetEnumValue(this.Emitter, constrr.Type, constrr.ConstantValue);
                        }

                        writeScript = true;
                    }
                }

                var isNullable = false;

                if (isPrimitive && constValue is AstType)
                {
                    var itype = this.Emitter.Resolver.ResolveNode((AstType)constValue, this.Emitter);

                    if (NullableType.IsNullable(itype.Type))
                    {
                        isNullable = true;
                    }
                }

                string              tpl            = null;
                IMember             templateMember = null;
                MemberResolveResult init_rr        = null;
                if (isField && member.VarInitializer != null)
                {
                    init_rr = this.Emitter.Resolver.ResolveNode(member.VarInitializer, this.Emitter) as MemberResolveResult;
                    tpl     = init_rr != null?this.Emitter.GetInline(init_rr.Member) : null;

                    if (tpl != null)
                    {
                        templateMember = init_rr.Member;
                    }
                }

                bool isAutoProperty = false;

                if (isProperty)
                {
                    var member_rr = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter) as MemberResolveResult;
                    var property  = (IProperty)member_rr.Member;
                    isAutoProperty = Helpers.IsAutoProperty(property);
                }

                bool written = false;
                if (!isNull && (!isPrimitive || constValue is AstType || tpl != null) && !(isProperty && !IsObjectLiteral && !isAutoProperty))
                {
                    string value        = null;
                    bool   needContinue = false;
                    string defValue     = "";
                    if (!isPrimitive)
                    {
                        var oldWriter = this.SaveWriter();
                        this.NewWriter();
                        member.Initializer.AcceptVisitor(this.Emitter);
                        value = this.Emitter.Output.ToString();
                        this.RestoreWriter(oldWriter);

                        ResolveResult rr      = null;
                        AstType       astType = null;
                        if (member.VarInitializer != null)
                        {
                            rr = this.Emitter.Resolver.ResolveNode(member.VarInitializer, this.Emitter);
                        }
                        else
                        {
                            astType = member.Entity.ReturnType;
                            rr      = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter);
                        }

                        constValue = Inspector.GetDefaultFieldValue(rr.Type, astType);
                        if (rr.Type.Kind == TypeKind.Enum)
                        {
                            constValue = Helpers.GetEnumValue(this.Emitter, rr.Type, constValue);
                        }
                        isNullable   = NullableType.IsNullable(rr.Type);
                        needContinue = constValue is IType;
                        writeScript  = true;

                        /*if (needContinue && !(member.Initializer is ObjectCreateExpression))
                         * {
                         *  defValue = " || " + Inspector.GetStructDefaultValue((IType)constValue, this.Emitter);
                         * }*/
                    }
                    else if (constValue is AstType)
                    {
                        value = isNullable
                            ? "null"
                            : Inspector.GetStructDefaultValue((AstType)constValue, this.Emitter);
                        constValue   = value;
                        write        = true;
                        needContinue = !isProperty && !isNullable;
                    }

                    var name = member.GetName(this.Emitter);

                    bool isValidIdentifier = Helpers.IsValidIdentifier(name);

                    if (isProperty && isPrimitive)
                    {
                        constValue = "null";

                        if (this.IsObjectLiteral)
                        {
                            written = true;
                            if (isValidIdentifier)
                            {
                                this.Write(string.Format("this.{0} = {1};", name, value));
                            }
                            else
                            {
                                this.Write(string.Format("this[{0}] = {1};", AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value));
                            }

                            this.WriteNewLine();
                        }
                        else
                        {
                            this.Injectors.Add(string.Format(name.StartsWith("\"") || !isValidIdentifier ? "this[{0}] = {1};" : "this.{0} = {1};", isValidIdentifier ? name : AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value));
                        }
                    }
                    else
                    {
                        if (this.IsObjectLiteral)
                        {
                            written = true;
                            if (isValidIdentifier)
                            {
                                this.Write(string.Format("this.{0} = {1};", name, value + defValue));
                            }
                            else
                            {
                                this.Write(string.Format("this[{0}] = {1};", AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value + defValue));
                            }
                            this.WriteNewLine();
                        }
                        else if (tpl != null)
                        {
                            if (!tpl.Contains("{0}"))
                            {
                                tpl = tpl + " = {0};";
                            }

                            string v = null;
                            if (!isNull && (!isPrimitive || constValue is AstType))
                            {
                                v = value + defValue;
                            }
                            else
                            {
                                if (write)
                                {
                                    v = constValue != null?constValue.ToString() : "";
                                }
                                else if (writeScript)
                                {
                                    v = AbstractEmitterBlock.ToJavaScript(constValue, this.Emitter);
                                }
                                else
                                {
                                    var oldWriter = this.SaveWriter();
                                    this.NewWriter();
                                    member.Initializer.AcceptVisitor(this.Emitter);
                                    v = this.Emitter.Output.ToString();
                                    this.RestoreWriter(oldWriter);
                                }
                            }

                            tpl = Helpers.ConvertTokens(this.Emitter, tpl, templateMember);
                            tpl = tpl.Replace("{this}", "this").Replace("{0}", v);

                            if (!tpl.EndsWith(";"))
                            {
                                tpl += ";";
                            }
                            this.Injectors.Add(tpl);
                        }
                        else
                        {
                            var  rr = this.Emitter.Resolver.ResolveNode(member.Initializer, this.Emitter) as CSharpInvocationResolveResult;
                            bool isDefaultInstance = rr != null &&
                                                     rr.Member.SymbolKind == SymbolKind.Constructor &&
                                                     rr.Arguments.Count == 0 &&
                                                     rr.InitializerStatements.Count == 0 &&
                                                     rr.Type.Kind == TypeKind.Struct;

                            if (!isDefaultInstance)
                            {
                                if (isField && !isValidIdentifier)
                                {
                                    this.Injectors.Add(string.Format("this[{0}] = {1};", name.StartsWith("\"") ? name : AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value + defValue));
                                }
                                else
                                {
                                    this.Injectors.Add(string.Format(name.StartsWith("\"") ? interfaceFormat : format, name, value + defValue));
                                }
                            }
                        }
                    }
                }

                count++;

                if (written)
                {
                    continue;
                }
                bool withoutTypeParams   = true;
                MemberResolveResult m_rr = null;
                if (member.Entity != null)
                {
                    m_rr = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter) as MemberResolveResult;
                    if (m_rr != null)
                    {
                        withoutTypeParams = OverloadsCollection.ExcludeTypeParameterForDefinition(m_rr);
                    }
                }

                var mname = member.GetName(this.Emitter, withoutTypeParams);

                if (this.TypeInfo.IsEnum && m_rr != null)
                {
                    mname = this.Emitter.GetEntityName(m_rr.Member);
                }

                bool isValid = Helpers.IsValidIdentifier(mname);
                if (!isValid)
                {
                    if (this.IsObjectLiteral)
                    {
                        mname = "[" + AbstractEmitterBlock.ToJavaScript(mname, this.Emitter) + "]";
                    }
                    else
                    {
                        mname = AbstractEmitterBlock.ToJavaScript(mname, this.Emitter);
                    }
                }

                if (this.IsObjectLiteral)
                {
                    this.WriteThis();
                    if (isValid)
                    {
                        this.WriteDot();
                    }
                    this.Write(mname);
                    this.Write(" = ");
                }
                else
                {
                    this.EnsureComma();
                    XmlToJsDoc.EmitComment(this, member.Entity, null, member.Entity is FieldDeclaration ? member.VarInitializer : null);
                    this.Write(mname);
                    this.WriteColon();
                }

                bool close = false;
                if (isProperty && !IsObjectLiteral && !isAutoProperty)
                {
                    var oldTempVars = this.Emitter.TempVariables;
                    this.BeginBlock();
                    new VisitorPropertyBlock(this.Emitter, (PropertyDeclaration)member.Entity).Emit();
                    this.WriteNewLine();
                    this.EndBlock();
                    this.Emitter.Comma         = true;
                    this.Emitter.TempVariables = oldTempVars;
                    continue;
                }

                if (constValue is AstType || constValue is IType)
                {
                    this.Write("null");

                    if (!isNullable)
                    {
                        var  name = member.GetName(this.Emitter);
                        bool isValidIdentifier = Helpers.IsValidIdentifier(name);
                        var  value             = constValue is AstType?Inspector.GetStructDefaultValue((AstType)constValue, this.Emitter) : Inspector.GetStructDefaultValue((IType)constValue, this.Emitter);

                        if (!isValidIdentifier)
                        {
                            this.Injectors.Insert(BeginCounter++, string.Format("this[{0}] = {1};", name.StartsWith("\"") ? name : AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value));
                        }
                        else
                        {
                            this.Injectors.Insert(BeginCounter++, string.Format(name.StartsWith("\"") ? interfaceFormat : format, name, value));
                        }
                    }
                }
                else if (write)
                {
                    this.Write(constValue);
                }
                else if (writeScript)
                {
                    this.WriteScript(constValue);
                }
                else
                {
                    member.Initializer.AcceptVisitor(this.Emitter);
                }

                if (close)
                {
                    this.Write(" }");
                }

                if (this.IsObjectLiteral)
                {
                    this.WriteSemiColon(true);
                }

                this.Emitter.Comma = true;
            }

            if (count > 0 && objectName != null && !IsObjectLiteral)
            {
                this.WriteNewLine();
                this.EndBlock();
            }
            else if (beginBlock)
            {
                this.Emitter.IsNewLine = writer.IsNewLine;
                this.Emitter.ResetLevel(writer.Level);
                this.Emitter.Comma = writer.Comma;

                this.Emitter.Output.Length = pos;
            }

            return(count > 0);
        }
Пример #6
0
        public bool RestoreWriter(IWriterInfo writer)
        {
            if (this.Emitter.Output != writer.Output)
            {
                this.Emitter.Output = writer.Output;
                this.Emitter.IsNewLine = writer.IsNewLine;
                this.Emitter.Level = writer.Level;
                this.Emitter.Comma = writer.Comma;

                return true;
            }

            return false;
        }
Пример #7
0
        protected virtual void EmitCtorForInstantiableClass()
        {
            var ctorWrappers = this.EmitInitMembers().ToArray();

            if (!this.TypeInfo.HasInstantiable && ctorWrappers.Length == 0)
            {
                return;
            }

            var baseType = this.Emitter.GetBaseTypeDefinition();
            var typeDef  = this.Emitter.GetTypeDefinition();

            if (typeDef.IsValueType || (this.TypeInfo.Ctors.Count == 0 && ctorWrappers.Length > 0))
            {
                this.TypeInfo.Ctors.Add(new ConstructorDeclaration
                {
                    Modifiers = Modifiers.Public,
                    Body      = new BlockStatement()
                });
            }

            foreach (var ctor in this.TypeInfo.Ctors)
            {
                this.EnsureComma();
                this.ResetLocals();
                var prevMap      = this.BuildLocalsMap();
                var prevNamesMap = this.BuildLocalsNamesMap();
                this.AddLocals(ctor.Parameters, ctor.Body);

                var ctorName = JS.Funcs.CONSTRUCTOR;

                if (this.TypeInfo.Ctors.Count > 1 && ctor.Parameters.Count > 0)
                {
                    var overloads = OverloadsCollection.Create(this.Emitter, ctor);
                    ctorName = overloads.GetOverloadName();
                }

                XmlToJsDoc.EmitComment(this, ctor);
                this.Write(ctorName);

                this.WriteColon();
                this.WriteFunction();

                int pos = this.Emitter.Output.Length;
                this.EmitMethodParameters(ctor.Parameters, null, ctor);
                var ctorParams = this.Emitter.Output.ToString().Substring(pos);

                this.WriteSpace();
                this.BeginBlock();
                var len            = this.Emitter.Output.Length;
                var requireNewLine = false;

                var         noThisInvocation = ctor.Initializer == null || ctor.Initializer.IsNull || ctor.Initializer.ConstructorInitializerType == ConstructorInitializerType.Base;
                IWriterInfo oldWriter        = null;
                if (ctorWrappers.Length > 0 && noThisInvocation)
                {
                    oldWriter = this.SaveWriter();
                    this.NewWriter();
                }

                this.ConvertParamsToReferences(ctor.Parameters);

                if (len != this.Emitter.Output.Length)
                {
                    requireNewLine = true;
                }

                if (noThisInvocation)
                {
                    if (requireNewLine)
                    {
                        this.WriteNewLine();
                    }
                    this.Write("this." + JS.Funcs.INITIALIZE + "();");
                    requireNewLine = true;
                }

                if (baseType != null && (!this.Emitter.Validator.IsIgnoreType(baseType) || this.Emitter.Validator.IsBridgeClass(baseType)) ||
                    (ctor.Initializer != null && ctor.Initializer.ConstructorInitializerType == ConstructorInitializerType.This))
                {
                    if (requireNewLine)
                    {
                        this.WriteNewLine();
                        requireNewLine = false;
                    }
                    this.EmitBaseConstructor(ctor, ctorName);
                }
                else if (baseType != null && ctor.Initializer != null &&
                         ctor.Initializer.ConstructorInitializerType == ConstructorInitializerType.Base)
                {
                    this.CheckBaseCtorTemplate(ctor, ref requireNewLine);
                }

                var script = this.Emitter.GetScript(ctor);

                if (script == null)
                {
                    if (ctor.Body.HasChildren)
                    {
                        var beginPosition = this.Emitter.Output.Length;
                        if (requireNewLine)
                        {
                            this.WriteNewLine();
                        }

                        ctor.Body.AcceptChildren(this.Emitter);

                        if (!this.Emitter.IsAsync)
                        {
                            this.EmitTempVars(beginPosition, true);
                        }
                    }
                    else if (requireNewLine)
                    {
                        this.WriteNewLine();
                    }
                }
                else
                {
                    if (requireNewLine)
                    {
                        this.WriteNewLine();
                    }

                    this.WriteLines(script);
                }

                if (oldWriter != null)
                {
                    this.WrapBody(oldWriter, ctorWrappers, ctorParams);
                }

                this.EndBlock();
                this.Emitter.Comma = true;
                this.ClearLocalsMap(prevMap);
                this.ClearLocalsNamesMap(prevNamesMap);
            }
        }