Beispiel #1
0
        protected virtual List <string> WriteObjectInitializer(IList <KeyValuePair <IMember, ResolveResult> > expressions, TypeDefinition type, IAttribute attr)
        {
            bool          needComma  = false;
            List <string> names      = new List <string>();
            List <string> inlineInit = new List <string>();

            if (expressions != null)
            {
                foreach (KeyValuePair <IMember, ResolveResult> item in expressions)
                {
                    var member = item.Key;
                    var name   = Emitter.GetEntityName(member);

                    var inlineCode = GetInlineInit(item, this);

                    if (inlineCode != null)
                    {
                        inlineInit.Add(inlineCode);
                    }
                    else
                    {
                        if (member is IProperty)
                        {
                            name = Helpers.GetPropertyRef(member, Emitter, true);
                        }
                        else if (member is IEvent)
                        {
                            name = Helpers.GetEventRef(member, Emitter, false);
                        }

                        if (needComma)
                        {
                            WriteComma();
                        }

                        needComma = true;

                        Write(name, ": ");

                        WriteResolveResult(item.Value, this);

                        names.Add(name);
                    }
                }
            }

            if (Emitter.Validator.IsObjectLiteral(type))
            {
                var key   = H5Types.GetTypeDefinitionKey(type);
                var tinfo = Emitter.Types.FirstOrDefault(t => t.Key == key);

                if (tinfo == null)
                {
                    return(inlineInit);
                }

                var mode = 0;
                if (attr.Constructor != null)
                {
                    if (tinfo.Type is ITypeDefinition itype)
                    {
                        var oattr = Emitter.Validator.GetAttribute(itype.Attributes, Translator.H5_ASSEMBLY + ".ObjectLiteralAttribute");
                        if (oattr.PositionalArguments.Count > 0)
                        {
                            var value = oattr.PositionalArguments.First().ConstantValue;

                            if (value is int)
                            {
                                mode = (int)value;
                            }
                        }
                    }
                }

                if (mode != 0)
                {
                    var members = tinfo.InstanceConfig.Fields.Concat(tinfo.InstanceConfig.Properties);

                    if (members.Any())
                    {
                        foreach (var member in members)
                        {
                            if (mode == 1 && (member.VarInitializer == null || member.VarInitializer.Initializer.IsNull))
                            {
                                continue;
                            }

                            var name = member.GetName(Emitter);

                            if (names.Contains(name))
                            {
                                continue;
                            }

                            if (needComma)
                            {
                                WriteComma();
                            }

                            needComma = true;

                            Write(name, ": ");


                            if (member.Initializer is PrimitiveExpression primitiveExpr && primitiveExpr.Value is AstType)
                            {
                                Write(Inspector.GetStructDefaultValue((AstType)primitiveExpr.Value, Emitter));
                            }
                            else
                            {
                                member.Initializer.AcceptVisitor(Emitter);
                            }
                        }
                    }
                }
Beispiel #2
0
        protected virtual bool WriteObject(string objectName, List <TypeConfigItem> members, string format, string interfaceFormat)
        {
            bool        hasProperties = HasProperties(objectName, members);
            int         pos           = 0;
            IWriterInfo writer        = null;
            bool        beginBlock    = false;

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

                WriteColon();
                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;
                bool   write       = false;
                bool   writeScript = false;

                if (member.Initializer is PrimitiveExpression primitiveExpr)
                {
                    //isPrimitive = true;
                    constValue = primitiveExpr.Value;

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

                    if (rr != null && rr.Type.Kind == TypeKind.Enum)
                    {
                        constValue  = Helpers.GetEnumValue(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 = Emitter.Resolver.ResolveNode(member.Initializer);
                    if (constrr != null && constrr.IsCompileTimeConstant)
                    {
                        //isPrimitive = true;
                        constValue = constrr.ConstantValue;

                        var expectedType = 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)
                            {
                                Logger.ZLogWarning("FieldBlock: Convert.ChangeType is failed. Value type: {0}, Target type: {1}", constrr.Type.FullName, expectedType.FullName);
                            }
                        }

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

                        writeScript = true;
                    }
                }

                var isNullable = false;

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

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

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

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

                bool isAutoProperty = false;

                if (isProperty)
                {
                    var member_rr = Emitter.Resolver.ResolveNode(member.Entity) 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 = SaveWriter();
                        NewWriter();
                        member.Initializer.AcceptVisitor(Emitter);
                        value = Emitter.Output.ToString();
                        RestoreWriter(oldWriter);

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

                        constValue = Inspector.GetDefaultFieldValue(rr.Type, astType);
                        if (rr.Type.Kind == TypeKind.Enum)
                        {
                            constValue = Helpers.GetEnumValue(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, Emitter);
                        constValue   = value;
                        write        = true;
                        needContinue = !isProperty && !isNullable;
                    }

                    var name = member.GetName(Emitter);

                    bool isValidIdentifier = Helpers.IsValidIdentifier(name);

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

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

                            WriteNewLine();
                        }
                        else
                        {
                            Injectors.Add(string.Format(name.StartsWith("\"") || !isValidIdentifier ? "this[{0}] = {1};" : "this.{0} = {1};", isValidIdentifier ? name : ToJavaScript(name, Emitter), value));
                        }
                    }
                    else
                    {
                        if (IsObjectLiteral)
                        {
                            written = true;
                            if (isValidIdentifier)
                            {
                                Write(string.Format("this.{0} = {1};", name, value + defValue));
                            }
                            else
                            {
                                Write(string.Format("this[{0}] = {1};", ToJavaScript(name, Emitter), value + defValue));
                            }
                            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 = ToJavaScript(constValue, Emitter);
                                }
                                else
                                {
                                    var oldWriter = SaveWriter();
                                    NewWriter();
                                    member.Initializer.AcceptVisitor(Emitter);
                                    v = Emitter.Output.ToString();
                                    RestoreWriter(oldWriter);
                                }
                            }

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

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

                            if (!isDefaultInstance)
                            {
                                if (isField && !isValidIdentifier)
                                {
                                    Injectors.Add(string.Format("this[{0}] = {1};", name.StartsWith("\"") ? name : ToJavaScript(name, Emitter), value + defValue));
                                }
                                else
                                {
                                    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 = Emitter.Resolver.ResolveNode(member.Entity) as MemberResolveResult;
                    if (m_rr != null)
                    {
                        withoutTypeParams = OverloadsCollection.ExcludeTypeParameterForDefinition(m_rr);
                    }
                }

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

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

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

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

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

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

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

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

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

                if (IsObjectLiteral)
                {
                    WriteSemiColon(true);
                }

                Emitter.Comma = true;
            }

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

                Emitter.Output.Length = pos;
            }

            return(count > 0);
        }
        public virtual void ConvertParamsToReferences(IEnumerable <ParameterDeclaration> declarations)
        {
            if (declarations.Any())
            {
                var p = declarations.First().Parent;
                if (p != null)
                {
                    if (Emitter.Resolver.ResolveNode(p) is MemberResolveResult rr)
                    {
                        if (rr.Member is DefaultResolvedMethod method)
                        {
                            var expandParams = method.Attributes.Any(a => a.AttributeType.FullName == "H5.ExpandParamsAttribute");
                            foreach (var prm in method.Parameters)
                            {
                                if (prm.IsOptional)
                                {
                                    var name = prm.Name;
                                    if (Helpers.IsReservedWord(Emitter, name))
                                    {
                                        name = Helpers.ChangeReservedWord(name);
                                    }

                                    Write(string.Format("if ({0} === void 0) {{ {0} = ", name));
                                    if (prm.ConstantValue == null && prm.Type.Kind == TypeKind.Struct && !prm.Type.IsKnownType(KnownTypeCode.NullableOfT))
                                    {
                                        Write(Inspector.GetStructDefaultValue(prm.Type, Emitter));
                                    }
                                    else if (prm.ConstantValue == null && prm.Type.Kind == TypeKind.TypeParameter)
                                    {
                                        Write(JS.Funcs.H5_GETDEFAULTVALUE + "(" + H5Types.ToJsName(prm.Type, Emitter) + ")");
                                    }
                                    else if (prm.Type.Kind == TypeKind.Enum)
                                    {
                                        var enumMode = Helpers.EnumEmitMode(prm.Type);

                                        if (enumMode >= 3 && enumMode < 7)
                                        {
                                            var members = prm.Type.GetMembers(options: GetMemberOptions.IgnoreInheritedMembers);
                                            var member  = members.FirstOrDefault(m => m is IField field && field.ConstantValue == prm.ConstantValue);

                                            if (member != null)
                                            {
                                                string enumStringName = Emitter.GetEntityName(member);
                                                WriteScript(enumStringName);
                                            }
                                            else
                                            {
                                                WriteScript(prm.ConstantValue);
                                            }
                                        }
                                        else
                                        {
                                            WriteScript(prm.ConstantValue);
                                        }
                                    }
                                    else
                                    {
                                        WriteScript(prm.ConstantValue);
                                    }

                                    Write("; }");
                                    WriteNewLine();
                                }
                                else if (prm.IsParams)
                                {
                                    var name = prm.Name;
                                    if (Helpers.IsReservedWord(Emitter, name))
                                    {
                                        name = Helpers.ChangeReservedWord(name);
                                    }

                                    if (expandParams)
                                    {
                                        Write(string.Format("{0} = " + JS.Types.ARRAY + "." + JS.Fields.PROTOTYPE + "." + JS.Funcs.SLICE + "." + JS.Funcs.CALL + "(" + JS.Vars.ARGUMENTS + ", {1});", name, method.Parameters.IndexOf(prm) + method.TypeParameters.Count));
                                    }
                                    else
                                    {
                                        Write(string.Format("if ({0} === void 0) {{ {0} = []; }}", name));
                                    }

                                    WriteNewLine();
                                }
                            }
                        }
                    }
                }
            }

            declarations.ToList().ForEach(item =>
            {
                var lrr = item.Parent != null ? (LocalResolveResult)Emitter.Resolver.ResolveNode(item) : null;
                var isReferenceLocal = lrr != null && Emitter.LocalsMap.ContainsKey(lrr.Variable) && Emitter.LocalsMap[lrr.Variable].EndsWith(".v");

                if (item.Parent == null && item.Name == "value")
                {
                    var p = Emitter.LocalsMap.FirstOrDefault(pair => pair.Key.Name == "value");
                    if (p.Value != null && p.Value.EndsWith(".v"))
                    {
                        isReferenceLocal = true;
                    }
                }

                if (isReferenceLocal && !(item.ParameterModifier == ParameterModifier.Out || item.ParameterModifier == ParameterModifier.Ref))
                {
                    Write(string.Format("{0} = {{v:{0}}};", Emitter.LocalsNamesMap[item.Name]));
                    WriteNewLine();
                }
            });
        }
Beispiel #4
0
        protected override void DoEmit()
        {
            var elements = ArrayInitializerExpression.Elements;
            var first    = elements.Count > 0 ? elements.First() : null;

            var isObjectInitializer = first is NamedExpression || first is NamedArgumentExpression;
            var rr     = Emitter.Resolver.ResolveNode(ArrayInitializerExpression) as ArrayCreateResolveResult;
            var at     = rr != null ? (ArrayType)rr.Type : null;
            var create = at != null && at.Dimensions > 1;

            if (rr != null)
            {
            }
            if (!isObjectInitializer || ArrayInitializerExpression.IsSingleElement)
            {
                if (at != null)
                {
                    Write(create ? JS.Types.System.Array.CREATE : JS.Types.System.Array.INIT);
                    WriteOpenParentheses();
                }

                if (create)
                {
                    var defaultInitializer = new PrimitiveExpression(Inspector.GetDefaultFieldValue(at.ElementType, AstType.Null), "?");

                    if (defaultInitializer.Value is IType)
                    {
                        Write(Inspector.GetStructDefaultValue((IType)defaultInitializer.Value, Emitter));
                    }
                    else if (defaultInitializer.Value is RawValue)
                    {
                        Write(defaultInitializer.Value.ToString());
                    }
                    else
                    {
                        defaultInitializer.AcceptVisitor(Emitter);
                    }

                    WriteComma();
                }

                Write("[");
            }
            else
            {
                BeginBlock();
            }

            new ExpressionListBlock(Emitter, elements, null, null, 0, elements.Count > 2).Emit();

            if (!isObjectInitializer || ArrayInitializerExpression.IsSingleElement)
            {
                Write("]");
                if (at != null)
                {
                    Write(", ");
                    Write(H5Types.ToJsName(at.ElementType, Emitter));

                    if (create)
                    {
                        Emitter.Comma = true;

                        for (int i = 0; i < rr.SizeArguments.Count; i++)
                        {
                            var a = rr.SizeArguments[i];
                            EnsureComma(false);

                            if (a.IsCompileTimeConstant)
                            {
                                Write(a.ConstantValue);
                            }
                            else
                            {
                                AttributeCreateBlock.WriteResolveResult(rr.SizeArguments[i], this);
                            }
                            Emitter.Comma = true;
                        }
                    }

                    Write(")");
                }
            }
            else
            {
                WriteNewLine();
                EndBlock();
            }
        }
Beispiel #5
0
        protected void VisitArrayCreateExpression()
        {
            ArrayCreateExpression arrayCreateExpression = ArrayCreateExpression;
            var rr   = ArrayCreateResolveResult ?? (Emitter.Resolver.ResolveNode(arrayCreateExpression) as ArrayCreateResolveResult);
            var at   = (ArrayType)rr.Type;
            var rank = arrayCreateExpression.Arguments.Count;

            if (arrayCreateExpression.Initializer.IsNull && rank == 1)
            {
                string typedArrayName = null;
                if (Emitter.AssemblyInfo.UseTypedArrays && (typedArrayName = Helpers.GetTypedArrayName(at.ElementType)) != null)
                {
                    Write(JS.Types.System.Array.INIT);
                    WriteOpenParentheses();

                    Write("new ", typedArrayName, "(");
                    if (ArrayCreateResolveResult != null)
                    {
                        AttributeCreateBlock.WriteResolveResult(ArrayCreateResolveResult.SizeArguments.First(), this);
                    }
                    else
                    {
                        arrayCreateExpression.Arguments.First().AcceptVisitor(Emitter);
                    }
                    Write(")");
                    Write(", ");
                    Write(H5Types.ToJsName(at.ElementType, Emitter));
                    Write(")");
                }
                else
                {
                    Write(JS.Types.System.Array.INIT);
                    WriteOpenParentheses();

                    if (ArrayCreateResolveResult != null)
                    {
                        AttributeCreateBlock.WriteResolveResult(ArrayCreateResolveResult.SizeArguments.First(), this);
                    }
                    else
                    {
                        arrayCreateExpression.Arguments.First().AcceptVisitor(Emitter);
                    }
                    WriteComma();

                    var def = Inspector.GetDefaultFieldValue(at.ElementType, arrayCreateExpression.Type);
                    if (def == at.ElementType || def is RawValue)
                    {
                        WriteFunction();
                        WriteOpenCloseParentheses();
                        BeginBlock();
                        WriteReturn(true);
                        if (def is RawValue)
                        {
                            Write(def.ToString());
                        }
                        else
                        {
                            Write(Inspector.GetStructDefaultValue(at.ElementType, Emitter));
                        }

                        WriteSemiColon();
                        WriteNewLine();
                        EndBlock();
                    }
                    else
                    {
                        WriteScript(def);
                    }

                    Write(", ");
                    Write(H5Types.ToJsName(at.ElementType, Emitter));

                    Write(")");
                }
                return;
            }

            if (at.Dimensions > 1)
            {
                Write(JS.Types.System.Array.CREATE);
                WriteOpenParentheses();

                var def = Inspector.GetDefaultFieldValue(at.ElementType, arrayCreateExpression.Type);
                var defaultInitializer = new PrimitiveExpression(def, "?");

                if (def == at.ElementType || def is RawValue)
                {
                    WriteFunction();
                    WriteOpenCloseParentheses();
                    BeginBlock();
                    WriteReturn(true);
                    if (def is RawValue)
                    {
                        Write(def.ToString());
                    }
                    else
                    {
                        Write(Inspector.GetStructDefaultValue(at.ElementType, Emitter));
                    }

                    WriteSemiColon();
                    WriteNewLine();
                    EndBlock();
                }
                else if (defaultInitializer.Value is IType)
                {
                    Write(Inspector.GetStructDefaultValue((IType)defaultInitializer.Value, Emitter));
                }
                else if (defaultInitializer.Value is RawValue)
                {
                    Write(defaultInitializer.Value.ToString());
                }
                else
                {
                    defaultInitializer.AcceptVisitor(Emitter);
                }

                WriteComma();
            }
            else
            {
                Write(JS.Types.System.Array.INIT);
                WriteOpenParentheses();
            }

            if (rr.InitializerElements != null && rr.InitializerElements.Count > 0)
            {
                string typedArrayName = null;
                bool   isTyped        = Emitter.AssemblyInfo.UseTypedArrays && (typedArrayName = Helpers.GetTypedArrayName(at.ElementType)) != null;
                if (isTyped)
                {
                    Write("new ", typedArrayName, "(");
                }

                WriteOpenBracket();

                if (ArrayCreateResolveResult != null)
                {
                    bool needComma = false;
                    foreach (ResolveResult item in ArrayCreateResolveResult.InitializerElements)
                    {
                        if (needComma)
                        {
                            WriteComma();
                        }

                        needComma = true;

                        AttributeCreateBlock.WriteResolveResult(item, this);
                    }
                }
                else
                {
                    var elements = arrayCreateExpression.Initializer.Elements;
                    new ExpressionListBlock(Emitter, elements, null, null, 0).Emit();
                }

                WriteCloseBracket();

                if (isTyped)
                {
                    Write(")");
                }
            }
            else if (at.Dimensions > 1)
            {
                Write("null");
            }
            else
            {
                Write("[]");
            }

            Write(", ");
            Write(H5Types.ToJsName(at.ElementType, Emitter));

            if (at.Dimensions > 1)
            {
                Emitter.Comma = true;

                for (int i = 0; i < rr.SizeArguments.Count; i++)
                {
                    var a = rr.SizeArguments[i];
                    EnsureComma(false);

                    if (a.IsCompileTimeConstant)
                    {
                        this.Write(a.ConstantValue);
                    }
                    else if (ArrayCreateResolveResult != null)
                    {
                        AttributeCreateBlock.WriteResolveResult(ArrayCreateResolveResult.SizeArguments[i], this);
                    }
                    else if (arrayCreateExpression.Arguments.Count > i)
                    {
                        var arg = arrayCreateExpression.Arguments.ElementAt(i);

                        if (arg != null)
                        {
                            arg.AcceptVisitor(Emitter);
                        }
                    }
                    Emitter.Comma = true;
                }
            }

            Write(")");
            Emitter.Comma = false;
        }
Beispiel #6
0
        protected virtual void WriteObjectInitializer(IEnumerable <Expression> expressions, TypeDefinition type, InvocationResolveResult rr, bool withCtor)
        {
            bool          needComma       = false;
            List <string> names           = new List <string>();
            var           isObjectLiteral = Emitter.Validator.IsObjectLiteral(type);

            if (!withCtor && rr != null && ObjectCreateExpression.Arguments.Count > 0)
            {
                var args      = ObjectCreateExpression.Arguments.ToList();
                var arrIsOpen = false;
                for (int i = 0; i < args.Count; i++)
                {
                    Expression expression = args[i];
                    var        p          = rr.Member.Parameters[i < rr.Member.Parameters.Count ? i : (rr.Member.Parameters.Count - 1)];
                    var        name       = p.Name;

                    if (p.Type.FullName == "H5.ObjectInitializationMode" ||
                        p.Type.FullName == "H5.ObjectCreateMode")
                    {
                        continue;
                    }

                    if (needComma)
                    {
                        WriteComma();
                    }

                    needComma = true;

                    if (p.IsParams && !arrIsOpen)
                    {
                        arrIsOpen = true;
                        Write("[");
                    }

                    Write(name, ": ");
                    expression.AcceptVisitor(Emitter);

                    names.Add(name);
                }

                if (arrIsOpen)
                {
                    Write("]");
                }
            }

            if (expressions != null)
            {
                foreach (Expression item in expressions)
                {
                    NamedExpression         namedExression          = item as NamedExpression;
                    NamedArgumentExpression namedArgumentExpression = item as NamedArgumentExpression;
                    string name = namedExression != null ? namedExression.Name : namedArgumentExpression.Name;

                    if (Emitter.Resolver.ResolveNode(item) is MemberResolveResult itemrr)
                    {
                        var  oc = OverloadsCollection.Create(Emitter, itemrr.Member);
                        bool forceObjectLiteral = itemrr.Member is IProperty && !itemrr.Member.Attributes.Any(attr => attr.AttributeType.FullName == "H5.NameAttribute") && !Emitter.Validator.IsObjectLiteral(itemrr.Member.DeclaringTypeDefinition);

                        name = oc.GetOverloadName(isObjectLiteral: forceObjectLiteral);
                    }

                    if (needComma)
                    {
                        WriteComma();
                    }

                    needComma = true;

                    Expression expression = namedExression != null ? namedExression.Expression : namedArgumentExpression.Expression;

                    WriteIdentifier(name, true, true);
                    Write(": ");
                    expression.AcceptVisitor(Emitter);

                    names.Add(name);
                }
            }

            if (isObjectLiteral)
            {
                var key   = H5Types.GetTypeDefinitionKey(type);
                var tinfo = Emitter.Types.FirstOrDefault(t => t.Key == key);

                var mode = 0;
                if (rr != null)
                {
                    if (rr.Member.Parameters.Count > 0)
                    {
                        var prm = rr.Member.Parameters.FirstOrDefault(p => p.Type.FullName == "H5.ObjectInitializationMode");

                        if (prm != null)
                        {
                            var prmIndex = rr.Member.Parameters.IndexOf(prm);
                            var arg      = rr.Arguments.FirstOrDefault(a =>
                            {
                                if (a is NamedArgumentResolveResult)
                                {
                                    return(((NamedArgumentResolveResult)a).ParameterName == prm.Name);
                                }

                                return(prmIndex == rr.Arguments.IndexOf(a));
                            });

                            if (arg != null && arg.ConstantValue != null && arg.ConstantValue is int)
                            {
                                mode = (int)arg.ConstantValue;
                            }
                        }
                    }
                    else if (type != null)
                    {
                        mode = Emitter.Validator.GetObjectInitializationMode(type);
                    }
                }

                if (tinfo == null)
                {
                    if (mode == 2)
                    {
                        var properties = rr.Member.DeclaringTypeDefinition.GetProperties(null, GetMemberOptions.IgnoreInheritedMembers);
                        foreach (var prop in properties)
                        {
                            var name = OverloadsCollection.Create(Emitter, prop).GetOverloadName();

                            if (names.Contains(name))
                            {
                                continue;
                            }

                            if (needComma)
                            {
                                WriteComma();
                            }

                            needComma = true;

                            WriteIdentifier(name, true, true);
                            Write(": ");

                            var argType  = prop.ReturnType;
                            var defValue = Inspector.GetDefaultFieldValue(argType, null);
                            if (defValue == argType)
                            {
                                Write(Inspector.GetStructDefaultValue(argType, Emitter));
                            }
                            else
                            {
                                Write(defValue);
                            }
                        }
                    }

                    return;
                }

                if (mode != 0)
                {
                    var members = tinfo.InstanceConfig.Fields.Concat(tinfo.InstanceConfig.Properties);

                    if (members.Any())
                    {
                        foreach (var member in members)
                        {
                            if (mode == 1 && (member.VarInitializer == null || member.VarInitializer.Initializer.IsNull) && !member.IsPropertyInitializer)
                            {
                                continue;
                            }

                            var name = member.GetName(Emitter);

                            if (names.Contains(name))
                            {
                                continue;
                            }

                            if (needComma)
                            {
                                WriteComma();
                            }

                            needComma = true;

                            WriteIdentifier(name, true, true);
                            Write(": ");

                            if (mode == 2 && (member.Initializer == null || member.Initializer.IsNull) && !(member.VarInitializer == null || member.VarInitializer.Initializer.IsNull))
                            {
                                var argType  = Emitter.Resolver.ResolveNode(member.VarInitializer).Type;
                                var defValue = Inspector.GetDefaultFieldValue(argType, null);
                                if (defValue == argType)
                                {
                                    Write(Inspector.GetStructDefaultValue(argType, Emitter));
                                }
                                else
                                {
                                    Write(defValue);
                                }
                            }
                            else
                            {
                                if (member.Initializer is PrimitiveExpression primitiveExpr && primitiveExpr.Value is AstType)
                                {
                                    Write(Inspector.GetStructDefaultValue((AstType)primitiveExpr.Value, Emitter));
                                }
                                else if (member.Initializer != null)
                                {
                                    member.Initializer.AcceptVisitor(Emitter);
                                }
                                else
                                {
                                    Write("null");
                                }
                            }
                        }
                    }