Beispiel #1
0
        private void WriteInitializerExpression(Expression item, string tempVar)
        {
            var rr = this.Emitter.Resolver.ResolveNode(item, this.Emitter) as MemberResolveResult;

            var inlineCode = ObjectCreateBlock.GetInlineInit(item, this, tempVar);

            if (inlineCode != null)
            {
                this.WriteComma();
                this.Write(inlineCode);
            }
            else if (item is NamedExpression)
            {
                this.WriteNamedExptession(((NamedExpression)item).Expression, tempVar, rr);
            }
            else if (item is NamedArgumentExpression)
            {
                this.WriteNamedExptession(((NamedArgumentExpression)item).Expression, tempVar, rr);
            }
            else if (item is ArrayInitializerExpression)
            {
                var arrayInitializer = (ArrayInitializerExpression)item;

                foreach (var el in arrayInitializer.Elements)
                {
                    this.WriteInitializerExpression(el, tempVar + "." + this.Emitter.GetEntityName(rr.Member));
                }
            }
            else if (item is IdentifierExpression)
            {
                this.WriteComma();
                var identifierExpression = (IdentifierExpression)item;
                new IdentifierBlock(this.Emitter, identifierExpression).Emit();
            }
            else
            {
                this.WriteComma();
                item.AcceptVisitor(this.Emitter);
            }
        }
Beispiel #2
0
        protected void VisitObjectCreateExpression()
        {
            ObjectCreateExpression objectCreateExpression = this.ObjectCreateExpression;

            var resolveResult = this.Emitter.Resolver.ResolveNode(objectCreateExpression.Type, this.Emitter) as TypeResolveResult;

            if (resolveResult != null && resolveResult.Type.Kind == TypeKind.Enum)
            {
                this.Write("(0)");
                return;
            }

            bool isTypeParam             = resolveResult != null && resolveResult.Type.Kind == TypeKind.TypeParameter;
            var  invocationResolveResult = this.Emitter.Resolver.ResolveNode(objectCreateExpression, this.Emitter) as InvocationResolveResult;
            var  hasInitializer          = !objectCreateExpression.Initializer.IsNull && objectCreateExpression.Initializer.Elements.Count > 0;

            if (isTypeParam && invocationResolveResult != null && invocationResolveResult.Member.Parameters.Count == 0 && !hasInitializer)
            {
                this.Write(JS.Funcs.BRIDGE_CREATEINSTANCE);
                this.WriteOpenParentheses();
                this.Write(resolveResult.Type.Name);
                this.WriteCloseParentheses();

                return;
            }

            var type            = isTypeParam ? null : this.Emitter.GetTypeDefinition(objectCreateExpression.Type);
            var isObjectLiteral = type != null && this.Emitter.Validator.IsObjectLiteral(type);

            if (type != null && type.BaseType != null && type.BaseType.FullName == "System.MulticastDelegate")
            {
                bool wrap   = false;
                var  parent = objectCreateExpression.Parent as InvocationExpression;
                if (parent != null && parent.Target == objectCreateExpression)
                {
                    wrap = true;
                }

                if (wrap)
                {
                    this.WriteOpenParentheses();
                }

                objectCreateExpression.Arguments.First().AcceptVisitor(this.Emitter);

                if (wrap)
                {
                    this.WriteCloseParentheses();
                }
                return;
            }

            var argsInfo        = new ArgumentsInfo(this.Emitter, objectCreateExpression);
            var argsExpressions = argsInfo.ArgumentsExpressions;
            var paramsArg       = argsInfo.ParamsExpression;

            string inlineCode = null;

            if (invocationResolveResult != null)
            {
                if (invocationResolveResult.Member.DeclaringType.Kind == TypeKind.Struct && objectCreateExpression.Arguments.Count == 0)
                {
                    var ctors   = invocationResolveResult.Member.DeclaringType.GetConstructors(c => c.Parameters.Count == 1);
                    var defCtor = ctors.FirstOrDefault(c => c.Parameters.First().Type.FullName == "System.Runtime.CompilerServices.DummyTypeUsedToAddAttributeToDefaultValueTypeConstructor");

                    if (defCtor != null)
                    {
                        inlineCode = this.Emitter.GetInline(defCtor);
                    }
                }

                if (inlineCode == null)
                {
                    inlineCode = this.Emitter.GetInline(invocationResolveResult.Member);
                }
            }

            var customCtor = isTypeParam ? "" : (this.Emitter.Validator.GetCustomConstructor(type) ?? "");

            bool isCollectionInitializer            = false;
            AstNodeCollection <Expression> elements = null;

            if (hasInitializer)
            {
                elements = objectCreateExpression.Initializer.Elements;
                isCollectionInitializer = elements.Count > 0 && elements.First() is ArrayInitializerExpression;
            }

            var isPlainObjectCtor = Regex.Match(customCtor, @"\s*\{\s*\}\s*").Success;
            var isPlainMode       = type != null && this.Emitter.Validator.GetObjectCreateMode(type) == 0;

            if (inlineCode == null && isPlainObjectCtor && isPlainMode)
            {
                this.WriteOpenBrace();
                this.WriteSpace();

                this.WriteObjectInitializer(objectCreateExpression.Initializer.Elements, type, invocationResolveResult, false);

                this.WriteSpace();
                this.WriteCloseBrace();

                /*bool close = isObjectLiteral;
                 * if (isObjectLiteral)
                 * {
                 *  if (this.Emitter.Validator.IsExternalType(type))
                 *  {
                 *      var name = BridgeTypes.ToJsName(objectCreateExpression.Type, this.Emitter);
                 *
                 *      if (name != JS.Types.System.Object.NAME)
                 *      {
                 *          this.Write(JS.Funcs.BRIDGE_LITERAL + "(" + name + ", ");
                 *      }
                 *      else
                 *      {
                 *          close = false;
                 *      }
                 *  }
                 *  else
                 *  {
                 *      objectCreateExpression.Type.AcceptVisitor(this.Emitter);
                 *      this.Write(".");
                 *      this.Write(JS.Funcs.CONSTRUCTOR);
                 *      this.WriteOpenParentheses();
                 *  }
                 * }
                 *
                 * this.WriteOpenBrace();
                 * this.WriteSpace();
                 *
                 * this.WriteObjectInitializer(objectCreateExpression.Initializer.Elements, type, invocationResolveResult, false);
                 * this.WriteSpace();
                 *
                 * this.WriteCloseBrace();
                 *
                 * if (close)
                 * {
                 *  this.WriteCloseParentheses();
                 * }*/
            }
            else
            {
                if (hasInitializer)
                {
                    this.Write(JS.Funcs.BRIDGE_MERGE);
                    this.WriteOpenParentheses();
                }

                if (inlineCode != null)
                {
                    new InlineArgumentsBlock(this.Emitter, argsInfo, inlineCode).Emit();
                }
                else
                {
                    var  ctorMember   = ((InvocationResolveResult)this.Emitter.Resolver.ResolveNode(objectCreateExpression, this.Emitter)).Member;
                    var  expandParams = ctorMember.Attributes.Any(a => a.AttributeType.FullName == "Bridge.ExpandParamsAttribute");
                    bool applyCtor    = false;

                    if (expandParams)
                    {
                        var ctor_rr = this.Emitter.Resolver.ResolveNode(paramsArg, this.Emitter);

                        if (ctor_rr.Type.Kind == TypeKind.Array && !(paramsArg is ArrayCreateExpression) && objectCreateExpression.Arguments.Last() == paramsArg)
                        {
                            this.Write(JS.Types.Bridge.Reflection.APPLYCONSTRUCTOR + "(");
                            applyCtor = true;
                        }
                    }

                    if (String.IsNullOrEmpty(customCtor) || (isObjectLiteral && isPlainObjectCtor))
                    {
                        if (!applyCtor && !isObjectLiteral)
                        {
                            this.WriteNew();
                        }

                        var typerr    = this.Emitter.Resolver.ResolveNode(objectCreateExpression.Type, this.Emitter).Type;
                        var isGeneric = typerr.TypeArguments.Count > 0 && !Helpers.IsIgnoreGeneric(typerr, this.Emitter);

                        if (isGeneric && !applyCtor)
                        {
                            this.WriteOpenParentheses();
                        }

                        objectCreateExpression.Type.AcceptVisitor(this.Emitter);

                        if (isGeneric && !applyCtor)
                        {
                            this.WriteCloseParentheses();
                        }
                    }
                    else
                    {
                        this.Write(customCtor);
                    }

                    if (!isTypeParam && !this.Emitter.Validator.IsExternalType(type) && type.Methods.Count(m => m.IsConstructor && !m.IsStatic) > (type.IsValueType || isObjectLiteral ? 0 : 1))
                    {
                        this.WriteDot();
                        var name = OverloadsCollection.Create(this.Emitter, ((InvocationResolveResult)this.Emitter.Resolver.ResolveNode(objectCreateExpression, this.Emitter)).Member).GetOverloadName();
                        this.Write(name);
                    }

                    if (applyCtor)
                    {
                        this.Write(", ");
                    }
                    else
                    {
                        this.WriteOpenParentheses();
                    }

                    new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg, objectCreateExpression, -1).Emit();
                    this.WriteCloseParentheses();
                }

                if (hasInitializer)
                {
                    this.WriteComma();

                    bool needComma = false;

                    if (isCollectionInitializer && !isObjectLiteral)
                    {
                        this.Write("[");
                        this.WriteNewLine();
                        this.Indent();
                    }
                    else
                    {
                        this.BeginBlock();
                    }

                    List <string> inlineInit = new List <string>();

                    if (isObjectLiteral)
                    {
                        this.WriteObjectInitializer(objectCreateExpression.Initializer.Elements, type, invocationResolveResult, true);
                    }
                    else
                    {
                        foreach (Expression item in elements)
                        {
                            if (needComma)
                            {
                                this.WriteComma(true);
                            }

                            needComma = true;

                            inlineCode = ObjectCreateBlock.GetInlineInit(item, this);

                            if (inlineCode != null)
                            {
                                inlineInit.Add(inlineCode);
                            }
                            else if (item is NamedExpression)
                            {
                                var namedExpression = (NamedExpression)item;
                                new NameBlock(this.Emitter, namedExpression.Name, namedExpression, namedExpression.Expression, true).Emit();
                            }
                            else if (item is NamedArgumentExpression)
                            {
                                var namedArgumentExpression = (NamedArgumentExpression)item;
                                new NameBlock(this.Emitter, namedArgumentExpression.Name, namedArgumentExpression, namedArgumentExpression.Expression, true).Emit();
                            }
                            else if (item is ArrayInitializerExpression)
                            {
                                var arrayInitializer = (ArrayInitializerExpression)item;
                                this.Write("[");

                                foreach (var el in arrayInitializer.Elements)
                                {
                                    this.EnsureComma(false);
                                    el.AcceptVisitor(this.Emitter);
                                    this.Emitter.Comma = true;
                                }

                                this.Write("]");
                                this.Emitter.Comma = false;
                            }
                            else if (item is IdentifierExpression)
                            {
                                var identifierExpression = (IdentifierExpression)item;
                                new IdentifierBlock(this.Emitter, identifierExpression).Emit();
                            }
                        }
                    }

                    this.WriteNewLine();

                    if (isCollectionInitializer && !isObjectLiteral)
                    {
                        this.Outdent();
                        this.Write("]");
                    }
                    else
                    {
                        this.EndBlock();
                    }

                    if (inlineInit.Count > 0)
                    {
                        this.Write(", function () ");
                        this.BeginBlock();

                        foreach (var init in inlineInit)
                        {
                            this.Write(init);
                            this.WriteNewLine();
                        }

                        this.EndBlock();
                    }

                    this.WriteSpace();
                    this.WriteCloseParentheses();
                }
            }

            //Helpers.CheckValueTypeClone(invocationResolveResult, this.ObjectCreateExpression, this, pos);
        }