コード例 #1
0
ファイル: MethodBlock.cs プロジェクト: theolivenbaum/h5
        protected void EmitEventAccessor(EventDeclaration e, VariableInitializer evtVar, bool add)
        {
            string name = evtVar.Name;

            Write(Helpers.GetAddOrRemove(add), name, " : ");
            WriteFunction();
            WriteOpenParentheses();
            Write("value");
            WriteCloseParentheses();
            WriteSpace();
            BeginBlock();
            WriteThis();
            WriteDot();
            Write(Emitter.GetEntityName(e));
            Write(" = ");
            Write(add ? JS.Funcs.H5_COMBINE : JS.Funcs.H5_REMOVE);
            WriteOpenParentheses();
            WriteThis();
            WriteDot();
            Write(Emitter.GetEntityName(e));
            WriteComma();
            WriteSpace();
            Write("value");
            WriteCloseParentheses();
            WriteSemiColon();
            WriteNewLine();
            EndBlock();
        }
コード例 #2
0
        protected virtual void EmitNameExpression(string name, Expression namedExpression, Expression expression)
        {
            var resolveResult = Emitter.Resolver.ResolveNode(namedExpression);

            if (resolveResult is MemberResolveResult)
            {
                var member = ((MemberResolveResult)resolveResult).Member;
                name = Emitter.GetEntityName(member);

                bool isSet = IsSet ?? !(expression is ArrayInitializerExpression);
                if (member is IProperty)
                {
                    Write(Helpers.GetPropertyRef(member, Emitter, isSet));
                }
                else if (member is IEvent)
                {
                    Write(Helpers.GetEventRef(member, Emitter, !isSet));
                }
                else
                {
                    Write(name);
                }
            }
            else
            {
                Write(name);
            }

            WriteColon();
            expression.AcceptVisitor(Emitter);
        }
コード例 #3
0
        private void GenereateCtor(AnonymousType type)
        {
            EnsureComma();
            Write(JS.Fields.KIND);
            WriteColon();
            WriteScript(TypeKind.Anonymous.ToString().ToLowerInvariant());
            WriteComma(true);
            Write(JS.Fields.CTORS);
            WriteColon();
            BeginBlock();
            Write(JS.Funcs.CONSTRUCTOR + ": function (");
            foreach (var property in type.Properties)
            {
                EnsureComma(false);
                Write(property.Name.ToLowerCamelCase());
                Emitter.Comma = true;
            }
            Write(") ");
            Emitter.Comma = false;
            BeginBlock();

            foreach (var property in type.Properties)
            {
                var name = Emitter.GetEntityName(property);

                Write(string.Format("this.{0} = {1};", name, property.Name.ToLowerCamelCase()));
                WriteNewLine();
            }

            EndBlock();
            WriteNewLine();
            EndBlock();
            Emitter.Comma = true;
        }
コード例 #4
0
        private void GenerateHashCode(IAnonymousTypeConfig config)
        {
            EnsureComma();
            Write(JS.Funcs.GETHASHCODE + ": function () ");
            BeginBlock();
            Write("var h = " + JS.Funcs.H5_ADDHASH + "([");

            var nameHashValue = new HashHelper().GetDeterministicHash(config.Name);

            Write(nameHashValue);

            foreach (var property in config.Type.Properties)
            {
                var name = Emitter.GetEntityName(property);
                Write(", this." + name);
            }

            Write("]);");

            WriteNewLine();
            Write("return h;");
            WriteNewLine();
            EndBlock();
            Emitter.Comma = true;
        }
コード例 #5
0
ファイル: ClassBlock.cs プロジェクト: theolivenbaum/h5
        protected virtual IEnumerable <string> GetAfterDefineMethods()
        {
            return(GetDefineMethods(InitPosition.After,
                                    (method, rrMethod) =>
            {
                Emitter.InitPosition = InitPosition.After;

                var callback = JS.Types.H5.INIT + "(function () { " + H5Types.ToJsName(rrMethod.DeclaringTypeDefinition, Emitter) + "." +
                               Emitter.GetEntityName(method) + "(); });";

                Emitter.InitPosition = null;

                return callback;
            }));
        }
コード例 #6
0
        protected virtual void EmitEvents(IEnumerable <EventDeclaration> events)
        {
            foreach (var evt in events)
            {
                foreach (var evtVar in evt.Variables)
                {
                    Emitter.Translator.EmitNode = evtVar;
                    string name = Emitter.GetEntityName(evt);

                    Write("this.", name, " = ");
                    evtVar.Initializer.AcceptVisitor(Emitter);
                    WriteSemiColon();
                    WriteNewLine();
                }
            }
        }
コード例 #7
0
ファイル: ClassBlock.cs プロジェクト: theolivenbaum/h5
        protected virtual void EmitStaticBlock()
        {
            int  pos     = Emitter.Output.Length;
            bool comma   = Emitter.Comma;
            bool newLine = Emitter.IsNewLine;

            Emitter.StaticBlock = true;
            EnsureComma();

            if (TypeInfo.InstanceMethods.Any(m => m.Value.Any(subm => Emitter.GetEntityName(subm) == JS.Fields.STATICS)) ||
                TypeInfo.InstanceConfig.Fields.Any(m => m.GetName(Emitter) == JS.Fields.STATICS))
            {
                Write(JS.Vars.D);
            }

            Write(JS.Fields.STATICS);
            WriteColon();
            BeginBlock();
            int checkOutputPos = Emitter.Output.Length;

            var ctorBlock = new ConstructorBlock(Emitter, TypeInfo, true);

            ctorBlock.Emit();
            HasEntryPoint = ctorBlock.HasEntryPoint;

            new MethodBlock(Emitter, TypeInfo, true).Emit();
            var clear = checkOutputPos == Emitter.Output.Length;

            WriteNewLine();
            EndBlock();

            if (clear)
            {
                Emitter.Output.Length = pos;
                Emitter.Comma         = comma;
                Emitter.IsNewLine     = newLine;
            }
            else
            {
                Emitter.Comma = true;
            }

            Emitter.StaticBlock = false;
        }
コード例 #8
0
        private void GenereateEquals(IAnonymousTypeConfig config)
        {
            EnsureComma();
            Write(JS.Funcs.EQUALS + ": function (o) ");
            BeginBlock();

            Write("if (!" + JS.Types.H5.IS + "(o, ");
            Write(config.Name);
            Write(")) ");
            BeginBlock();
            Write("return false;");
            WriteNewLine();
            EndBlock();
            WriteNewLine();
            Write("return ");

            bool and = false;

            foreach (var property in config.Type.Properties)
            {
                var name = Emitter.GetEntityName(property);

                if (and)
                {
                    Write(" && ");
                }

                and = true;

                Write(JS.Funcs.H5_EQUALS + "(this.");
                Write(name);
                Write(", o.");
                Write(name);
                Write(")");
            }

            Write(";");

            WriteNewLine();
            EndBlock();
            Emitter.Comma = true;
        }
コード例 #9
0
ファイル: ObjectCreateBlock.cs プロジェクト: theolivenbaum/h5
        private void WriteInitializerExpression(Expression item, string tempVar)
        {
            var rr = Emitter.Resolver.ResolveNode(item) as MemberResolveResult;

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

            if (inlineCode != null)
            {
                WriteComma();
                Write(inlineCode);
            }
            else if (item is NamedExpression)
            {
                WriteNamedExptession(((NamedExpression)item).Expression, tempVar, rr);
            }
            else if (item is NamedArgumentExpression)
            {
                WriteNamedExptession(((NamedArgumentExpression)item).Expression, tempVar, rr);
            }
            else if (item is ArrayInitializerExpression arrayInitializer)
            {
                foreach (var el in arrayInitializer.Elements)
                {
                    WriteInitializerExpression(el, tempVar + "." + Emitter.GetEntityName(rr.Member));
                }
            }
            else if (item is IdentifierExpression)
            {
                WriteComma();
                var identifierExpression = (IdentifierExpression)item;
                new IdentifierBlock(Emitter, identifierExpression).Emit();
            }
            else
            {
                WriteComma();
                item.AcceptVisitor(Emitter);
            }
        }
コード例 #10
0
        private void GenereateToJSON(IAnonymousTypeConfig config)
        {
            EnsureComma();
            Write(JS.Funcs.TOJSON + ": function () ");
            BeginBlock();
            Write("return ");
            BeginBlock();

            foreach (var property in config.Type.Properties)
            {
                EnsureComma();
                var name = Emitter.GetEntityName(property);

                Write(string.Format("{0} : this.{0}", name));
                Emitter.Comma = true;
            }

            WriteNewLine();
            EndBlock();
            WriteSemiColon();
            WriteNewLine();
            EndBlock();
            Emitter.Comma = true;
        }
コード例 #11
0
        protected virtual void WriteObjectInitializer(IEnumerable <Expression> expressions, bool changeCase, bool valuesOnly = false)
        {
            bool needComma = false;

            foreach (Expression item in expressions)
            {
                NamedExpression           namedExression            = null;
                NamedArgumentExpression   namedArgumentExpression   = null;
                IdentifierExpression      identifierExpression      = null;
                MemberReferenceExpression memberReferenceExpression = null;

                namedExression = item as NamedExpression;
                if (namedExression == null)
                {
                    namedArgumentExpression = item as NamedArgumentExpression;

                    if (namedArgumentExpression == null)
                    {
                        identifierExpression = item as IdentifierExpression;
                        if (identifierExpression == null)
                        {
                            memberReferenceExpression = item as MemberReferenceExpression;
                        }
                    }
                }

                if (needComma)
                {
                    WriteComma();
                }

                needComma = true;
                string     name = null;
                Expression expression;


                if (Emitter.Resolver.ResolveNode(item) is MemberResolveResult rr)
                {
                    name       = Emitter.GetEntityName(rr.Member);
                    changeCase = false;
                }

                if (namedExression != null)
                {
                    name       = name ?? namedExression.Name;
                    expression = namedExression.Expression;
                }
                else if (namedArgumentExpression != null)
                {
                    name       = name ?? namedArgumentExpression.Name;
                    expression = namedArgumentExpression.Expression;
                }
                else if (identifierExpression != null)
                {
                    name       = name ?? identifierExpression.Identifier;
                    expression = identifierExpression;
                }
                else
                {
                    name       = name ?? memberReferenceExpression.MemberName;
                    expression = memberReferenceExpression;
                }

                if (changeCase)
                {
                    name = Object.Net.Utilities.StringUtils.ToLowerCamelCase(name);
                }

                if (!valuesOnly)
                {
                    Write(name, ": ");
                }

                expression.AcceptVisitor(Emitter);
            }
        }
コード例 #12
0
ファイル: FieldBlock.cs プロジェクト: theolivenbaum/h5
        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);
        }
コード例 #13
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();
                }
            });
        }
コード例 #14
0
        protected void VisitIdentifierExpression()
        {
            IdentifierExpression identifierExpression = IdentifierExpression;
            int           pos           = Emitter.Output.Length;
            ResolveResult resolveResult = null;

            isRefArg         = Emitter.IsRefArg;
            Emitter.IsRefArg = false;

            resolveResult = Emitter.Resolver.ResolveNode(identifierExpression);

            var id = identifierExpression.Identifier;

            var isResolved   = resolveResult != null && !(resolveResult is ErrorResolveResult);
            var memberResult = resolveResult as MemberResolveResult;

            if (Emitter.Locals != null && Emitter.Locals.ContainsKey(id) && resolveResult is LocalResolveResult)
            {
                var lrr = (LocalResolveResult)resolveResult;
                if (Emitter.LocalsMap != null && Emitter.LocalsMap.ContainsKey(lrr.Variable) && !(identifierExpression.Parent is DirectionExpression))
                {
                    Write(Emitter.LocalsMap[lrr.Variable]);
                }
                else if (Emitter.LocalsNamesMap != null && Emitter.LocalsNamesMap.ContainsKey(id))
                {
                    Write(Emitter.LocalsNamesMap[id]);
                }
                else
                {
                    Write(id);
                }

                Helpers.CheckValueTypeClone(resolveResult, identifierExpression, this, pos);

                return;
            }

            if (resolveResult is TypeResolveResult)
            {
                Write(H5Types.ToJsName(resolveResult.Type, Emitter));

                /*if (this.Emitter.Validator.IsExternalType(resolveResult.Type.GetDefinition()) || resolveResult.Type.Kind == TypeKind.Enum)
                 * {
                 *  this.Write(H5Types.ToJsName(resolveResult.Type, this.Emitter));
                 * }
                 * else
                 * {
                 *  this.Write("H5.get(" + H5Types.ToJsName(resolveResult.Type, this.Emitter) + ")");
                 * }*/

                return;
            }

            string inlineCode = memberResult != null?Emitter.GetInline(memberResult.Member) : null;

            var isInvoke = identifierExpression.Parent is InvocationExpression && (((InvocationExpression)(identifierExpression.Parent)).Target == identifierExpression);

            if (memberResult != null && memberResult.Member is IMethod && isInvoke)
            {
                if (Emitter.Resolver.ResolveNode(identifierExpression.Parent) is CSharpInvocationResolveResult i_rr && !i_rr.IsExpandedForm)
                {
                    var tpl = Emitter.GetAttribute(memberResult.Member.Attributes, JS.NS.H5 + ".TemplateAttribute");

                    if (tpl != null && tpl.PositionalArguments.Count == 2)
                    {
                        inlineCode = tpl.PositionalArguments[1].ConstantValue.ToString();
                    }
                }
            }

            if (string.IsNullOrEmpty(inlineCode) && memberResult != null &&
                memberResult.Member is IMethod &&
                !(memberResult is InvocationResolveResult) &&
                !(
                    identifierExpression.Parent is InvocationExpression &&
                    identifierExpression.NextSibling != null &&
                    identifierExpression.NextSibling.Role is TokenRole &&
                    ((TokenRole)identifierExpression.NextSibling.Role).Token == "("
                    )
                )
            {
                if (!(identifierExpression.Parent is InvocationExpression parentInvocation) || parentInvocation.Target != identifierExpression)
                {
                    var method = (IMethod)memberResult.Member;
                    if (method.TypeArguments.Count > 0)
                    {
                        inlineCode = MemberReferenceBlock.GenerateInlineForMethodReference(method, Emitter);
                    }
                }
            }

            bool hasInline = !string.IsNullOrEmpty(inlineCode);

            inlineCode = hasInline ? Helpers.ConvertTokens(Emitter, inlineCode, memberResult.Member) : inlineCode;
            bool hasThis = hasInline && Helpers.HasThis(inlineCode);

            if (hasInline && inlineCode.StartsWith("<self>"))
            {
                hasThis    = true;
                inlineCode = inlineCode.Substring(6);
            }

            if (hasThis)
            {
                Emitter.ThisRefCounter++;
                Write("");
                var oldBuilder = Emitter.Output;
                Emitter.Output = new StringBuilder();

                if (memberResult.Member.IsStatic)
                {
                    Write(H5Types.ToJsName(memberResult.Member.DeclaringType, Emitter, ignoreLiteralName: false));

                    /*if (!this.Emitter.Validator.IsExternalType(memberResult.Member.DeclaringTypeDefinition) && memberResult.Member.DeclaringTypeDefinition.Kind != TypeKind.Enum)
                     * {
                     *  this.Write("(H5.get(" + H5Types.ToJsName(memberResult.Member.DeclaringType, this.Emitter) + "))");
                     * }
                     * else
                     * {
                     *  this.Write(H5Types.ToJsName(memberResult.Member.DeclaringType, this.Emitter));
                     * }*/
                }
                else
                {
                    WriteThis();
                }

                var oldInline = inlineCode;
                var thisArg   = Emitter.Output.ToString();
                int thisIndex = inlineCode.IndexOf("{this}");
                inlineCode     = inlineCode.Replace("{this}", thisArg);
                Emitter.Output = oldBuilder;

                int[] range = null;

                if (thisIndex > -1)
                {
                    range = new[] { thisIndex, thisIndex + thisArg.Length };
                }

                if (resolveResult is InvocationResolveResult)
                {
                    PushWriter(inlineCode, null, thisArg, range);
                }
                else
                {
                    if (memberResult.Member is IMethod)
                    {
                        ResolveResult targetrr = null;
                        if (memberResult.Member.IsStatic)
                        {
                            targetrr = new TypeResolveResult(memberResult.Member.DeclaringType);
                        }

                        new InlineArgumentsBlock(Emitter, new ArgumentsInfo(Emitter, IdentifierExpression, resolveResult), oldInline, (IMethod)memberResult.Member, targetrr).EmitFunctionReference();
                    }
                    else if (memberResult != null && memberResult.Member is IField && inlineCode.Contains("{0}"))
                    {
                        PushWriter(inlineCode, null, thisArg, range);
                    }
                    else if (InlineArgumentsBlock.FormatArgRegex.IsMatch(inlineCode))
                    {
                        PushWriter(inlineCode, null, thisArg, range);
                    }
                    else
                    {
                        Write(inlineCode);
                    }
                }

                return;
            }

            if (hasInline)
            {
                if (!memberResult.Member.IsStatic)
                {
                    inlineCode = "this." + inlineCode;
                }

                if (resolveResult is InvocationResolveResult)
                {
                    PushWriter(inlineCode);
                }
                else
                {
                    if (memberResult.Member is IMethod)
                    {
                        ResolveResult targetrr = null;
                        if (memberResult.Member.IsStatic)
                        {
                            targetrr = new TypeResolveResult(memberResult.Member.DeclaringType);
                        }

                        new InlineArgumentsBlock(Emitter, new ArgumentsInfo(Emitter, IdentifierExpression, resolveResult), inlineCode, (IMethod)memberResult.Member, targetrr).EmitFunctionReference();
                    }
                    else if (InlineArgumentsBlock.FormatArgRegex.IsMatch(inlineCode))
                    {
                        PushWriter(inlineCode);
                    }
                    else
                    {
                        Write(inlineCode);
                    }
                }

                return;
            }

            string appendAdditionalCode = null;

            if (memberResult != null &&
                memberResult.Member is IMethod &&
                !(memberResult is InvocationResolveResult) &&
                !(
                    identifierExpression.Parent is InvocationExpression &&
                    identifierExpression.NextSibling != null &&
                    identifierExpression.NextSibling.Role is TokenRole &&
                    ((TokenRole)identifierExpression.NextSibling.Role).Token == "("
                    )
                )
            {
                if (!(identifierExpression.Parent is InvocationExpression parentInvocation) || parentInvocation.Target != identifierExpression)
                {
                    if (!string.IsNullOrEmpty(inlineCode))
                    {
                        ResolveResult targetrr = null;
                        if (memberResult.Member.IsStatic)
                        {
                            targetrr = new TypeResolveResult(memberResult.Member.DeclaringType);
                        }

                        new InlineArgumentsBlock(Emitter,
                                                 new ArgumentsInfo(Emitter, identifierExpression, resolveResult), inlineCode,
                                                 (IMethod)memberResult.Member, targetrr).EmitFunctionReference();
                    }
                    else
                    {
                        var  resolvedMethod = (IMethod)memberResult.Member;
                        bool isStatic       = resolvedMethod != null && resolvedMethod.IsStatic;

                        if (!isStatic)
                        {
                            var isExtensionMethod = resolvedMethod.IsExtensionMethod;
                            Write(isExtensionMethod ? JS.Funcs.H5_BIND_SCOPE : JS.Funcs.H5_CACHE_BIND);
                            WriteOpenParentheses();
                            WriteThis();
                            Write(", ");
                            appendAdditionalCode = ")";
                        }
                    }
                }
            }

            if (memberResult != null && memberResult.Member.SymbolKind == SymbolKind.Field && Emitter.IsMemberConst(memberResult.Member) && Emitter.IsInlineConst(memberResult.Member))
            {
                WriteScript(memberResult.ConstantValue);
                return;
            }

            if (memberResult != null && memberResult.Member.SymbolKind == SymbolKind.Property && memberResult.TargetResult.Type.Kind != TypeKind.Anonymous)
            {
                bool   isStatement = false;
                string valueVar    = null;

                if (Emitter.IsUnaryAccessor)
                {
                    isStatement = identifierExpression.Parent is UnaryOperatorExpression && identifierExpression.Parent.Parent is ExpressionStatement;

                    if (NullableType.IsNullable(memberResult.Type))
                    {
                        isStatement = false;
                    }

                    if (!isStatement)
                    {
                        WriteOpenParentheses();

                        valueVar = GetTempVarName();

                        Write(valueVar);
                        Write(" = ");
                    }
                }

                WriteTarget(memberResult);

                if (!string.IsNullOrWhiteSpace(inlineCode))
                {
                    //this.Write(inlineCode);
                    if (resolveResult is InvocationResolveResult || (memberResult.Member.SymbolKind == SymbolKind.Property && Emitter.IsAssignment))
                    {
                        PushWriter(inlineCode);
                    }
                    else
                    {
                        Write(inlineCode);
                    }
                }
                else if (memberResult.Member is IProperty)
                {
                    var name = Helpers.GetPropertyRef(memberResult.Member, Emitter);

                    WriteIdentifier(name);
                }
                else if (!Emitter.IsAssignment)
                {
                    if (Emitter.IsUnaryAccessor)
                    {
                        bool isDecimal  = Helpers.IsDecimalType(memberResult.Member.ReturnType, Emitter.Resolver);
                        bool isLong     = Helpers.Is64Type(memberResult.Member.ReturnType, Emitter.Resolver);
                        bool isNullable = NullableType.IsNullable(memberResult.Member.ReturnType);
                        if (isStatement)
                        {
                            Write(Helpers.GetPropertyRef(memberResult.Member, Emitter, true));
                            WriteOpenParentheses();

                            if (isDecimal || isLong)
                            {
                                if (isNullable)
                                {
                                    Write(JS.Types.SYSTEM_NULLABLE + "." + JS.Funcs.Math.LIFT1);
                                    WriteOpenParentheses();
                                    if (Emitter.UnaryOperatorType == UnaryOperatorType.Increment ||
                                        Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                    {
                                        WriteScript(JS.Funcs.Math.INC);
                                    }
                                    else
                                    {
                                        WriteScript(JS.Funcs.Math.DEC);
                                    }

                                    WriteComma();

                                    WriteTarget(memberResult);

                                    Write(Helpers.GetPropertyRef(memberResult.Member, Emitter, false));
                                    WriteOpenParentheses();
                                    WriteCloseParentheses();
                                    WriteCloseParentheses();
                                }
                                else
                                {
                                    WriteTarget(memberResult);
                                    Write(Helpers.GetPropertyRef(memberResult.Member, Emitter, false));
                                    WriteOpenParentheses();
                                    WriteCloseParentheses();
                                    WriteDot();

                                    if (Emitter.UnaryOperatorType == UnaryOperatorType.Increment ||
                                        Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                    {
                                        Write(JS.Funcs.Math.INC);
                                    }
                                    else
                                    {
                                        Write(JS.Funcs.Math.DEC);
                                    }

                                    WriteOpenParentheses();
                                    WriteCloseParentheses();
                                }
                            }
                            else
                            {
                                WriteTarget(memberResult);

                                Write(Helpers.GetPropertyRef(memberResult.Member, Emitter, false));
                                WriteOpenParentheses();
                                WriteCloseParentheses();

                                if (Emitter.UnaryOperatorType == UnaryOperatorType.Increment || Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                {
                                    Write("+");
                                }
                                else
                                {
                                    Write("-");
                                }

                                Write("1");
                            }

                            WriteCloseParentheses();
                        }
                        else
                        {
                            Write(Helpers.GetPropertyRef(memberResult.Member, Emitter, false));
                            WriteOpenParentheses();
                            WriteCloseParentheses();
                            WriteComma();

                            WriteTarget(memberResult);
                            Write(Helpers.GetPropertyRef(memberResult.Member, Emitter, true));
                            WriteOpenParentheses();

                            if (isDecimal || isLong)
                            {
                                if (isNullable)
                                {
                                    Write(JS.Types.SYSTEM_NULLABLE + "." + JS.Funcs.Math.LIFT1);
                                    WriteOpenParentheses();
                                    if (Emitter.UnaryOperatorType == UnaryOperatorType.Increment ||
                                        Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                    {
                                        WriteScript(JS.Funcs.Math.INC);
                                    }
                                    else
                                    {
                                        WriteScript(JS.Funcs.Math.DEC);
                                    }

                                    WriteComma();
                                    Write(valueVar);
                                    WriteCloseParentheses();
                                }
                                else
                                {
                                    Write(valueVar);

                                    WriteDot();

                                    if (Emitter.UnaryOperatorType == UnaryOperatorType.Increment ||
                                        Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                    {
                                        Write(JS.Funcs.Math.INC);
                                    }
                                    else
                                    {
                                        Write(JS.Funcs.Math.DEC);
                                    }

                                    WriteOpenParentheses();
                                    WriteCloseParentheses();
                                }
                            }
                            else
                            {
                                Write(valueVar);

                                if (Emitter.UnaryOperatorType == UnaryOperatorType.Increment || Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                {
                                    Write("+");
                                }
                                else
                                {
                                    Write("-");
                                }

                                Write("1");
                            }

                            WriteCloseParentheses();
                            WriteComma();

                            if (Emitter.UnaryOperatorType == UnaryOperatorType.Increment ||
                                Emitter.UnaryOperatorType == UnaryOperatorType.Decrement)
                            {
                                WriteTarget(memberResult);
                                Write(Helpers.GetPropertyRef(memberResult.Member, Emitter, false));
                                WriteOpenParentheses();
                                WriteCloseParentheses();
                            }
                            else
                            {
                                Write(valueVar);
                            }

                            WriteCloseParentheses();

                            if (valueVar != null)
                            {
                                RemoveTempVar(valueVar);
                            }
                        }
                    }
                    else
                    {
                        Write(Helpers.GetPropertyRef(memberResult.Member, Emitter));
                        WriteOpenParentheses();
                        WriteCloseParentheses();
                    }
                }
                else if (Emitter.AssignmentType != AssignmentOperatorType.Assign)
                {
                    string trg;

                    if (memberResult.Member.IsStatic)
                    {
                        trg = H5Types.ToJsName(memberResult.Member.DeclaringType, Emitter, ignoreLiteralName: false);
                    }
                    else
                    {
                        trg = "this";
                    }

                    bool isBool  = memberResult != null && NullableType.IsNullable(memberResult.Member.ReturnType) ? NullableType.GetUnderlyingType(memberResult.Member.ReturnType).IsKnownType(KnownTypeCode.Boolean) : memberResult.Member.ReturnType.IsKnownType(KnownTypeCode.Boolean);
                    bool skipGet = false;
                    bool special = Emitter.Resolver.ResolveNode(identifierExpression.Parent) is OperatorResolveResult orr && orr.IsLiftedOperator;

                    if (!special && isBool &&
                        (Emitter.AssignmentType == AssignmentOperatorType.BitwiseAnd ||
                         Emitter.AssignmentType == AssignmentOperatorType.BitwiseOr))
                    {
                        skipGet = true;
                    }

                    if (skipGet)
                    {
                        PushWriter(string.Concat(Helpers.GetPropertyRef(memberResult.Member, Emitter, true), "({0})"));
                    }
                    else
                    {
                        PushWriter(string.Concat(Helpers.GetPropertyRef(memberResult.Member, Emitter, true),
                                                 "(",
                                                 trg,
                                                 ".",
                                                 Helpers.GetPropertyRef(memberResult.Member, Emitter, false),
                                                 "()",
                                                 "{0})"));
                    }
                }
                else
                {
                    PushWriter(Helpers.GetPropertyRef(memberResult.Member, Emitter, true) + "({0})");
                }
            }
            else if (memberResult != null && memberResult.Member is IEvent)
            {
                if (Emitter.IsAssignment &&
                    (Emitter.AssignmentType == AssignmentOperatorType.Add ||
                     Emitter.AssignmentType == AssignmentOperatorType.Subtract))
                {
                    WriteTarget(memberResult);

                    if (!string.IsNullOrWhiteSpace(inlineCode))
                    {
                        Write(inlineCode);
                    }
                    else
                    {
                        Write(Helpers.GetAddOrRemove(Emitter.AssignmentType == AssignmentOperatorType.Add));
                        Write(
                            OverloadsCollection.Create(Emitter, memberResult.Member,
                                                       Emitter.AssignmentType == AssignmentOperatorType.Subtract).GetOverloadName());
                    }

                    WriteOpenParentheses();
                }
                else
                {
                    WriteTarget(memberResult);
                    Write(Emitter.GetEntityName(memberResult.Member));
                }
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(inlineCode))
                {
                    Write(inlineCode);
                }
                else if (isResolved)
                {
                    if (resolveResult is LocalResolveResult localResolveResult)
                    {
                        Write(localResolveResult.Variable.Name);
                    }
                    else if (memberResult != null)
                    {
                        WriteTarget(memberResult);
                        string name = OverloadsCollection.Create(Emitter, memberResult.Member).GetOverloadName();
                        if (isRefArg)
                        {
                            WriteScript(name);
                        }
                        else if (memberResult.Member is IField)
                        {
                            WriteIdentifier(name);
                        }
                        else
                        {
                            Write(name);
                        }
                    }
                    else
                    {
                        Write(resolveResult.ToString());
                    }
                }
                else
                {
                    throw new EmitterException(identifierExpression, "Cannot resolve identifier: " + id);
                }
            }

            if (appendAdditionalCode != null)
            {
                Write(appendAdditionalCode);
            }

            Helpers.CheckValueTypeClone(resolveResult, identifierExpression, this, pos);
        }
コード例 #15
0
        private void HandleAttributes(List <string> list, KeyValuePair <string, List <MethodDeclaration> > methodGroup, MethodDeclaration method, out bool hasReadyAttribute)
        {
            hasReadyAttribute = false;
            var isGenericType   = IsGenericType();
            var isGenericMethod = IsGenericMethod(method);

            foreach (var attrSection in method.Attributes)
            {
                foreach (var attr in attrSection.Attributes)
                {
                    if (Emitter.Resolver.ResolveNode(attr) is InvocationResolveResult resolveResult)
                    {
                        if (resolveResult.Type.FullName == CS.Attributes.READY_ATTRIBUTE_NAME)
                        {
                            hasReadyAttribute = true;

                            if (isGenericType || isGenericMethod)
                            {
                                LogAutoStartupWarning(method);
                                continue;
                            }
                        }

                        var baseTypes = resolveResult.Type.GetAllBaseTypes().ToArray();

                        if (baseTypes.Any(t => t.FullName == "H5.AdapterAttribute"))
                        {
                            if (methodGroup.Value.Count > 1)
                            {
                                throw new EmitterException(attr, "Overloaded method cannot be event handler");
                            }

                            var staticFlagField = resolveResult.Type.GetFields(f => f.Name == "StaticOnly");

                            if (staticFlagField.Count() > 0)
                            {
                                var staticValue = staticFlagField.First().ConstantValue;

                                if (staticValue is bool boolean && boolean && !method.HasModifier(Modifiers.Static))
                                {
                                    throw new EmitterException(attr, resolveResult.Type.FullName + " can be applied for static methods only");
                                }
                            }

                            string eventName  = methodGroup.Key;
                            var    eventField = resolveResult.Type.GetFields(f => f.Name == "Event");

                            if (eventField.Count() > 0)
                            {
                                eventName = eventField.First().ConstantValue.ToString();
                            }

                            string format      = null;
                            string formatName  = StaticBlock ? "Format" : "FormatScope";
                            var    formatField = resolveResult.Type.GetFields(f => f.Name == formatName, GetMemberOptions.IgnoreInheritedMembers);

                            if (formatField.Count() > 0)
                            {
                                format = formatField.First().ConstantValue.ToString();
                            }
                            else
                            {
                                for (int i = baseTypes.Length - 1; i >= 0; i--)
                                {
                                    formatField = baseTypes[i].GetFields(f => f.Name == formatName);

                                    if (formatField.Count() > 0)
                                    {
                                        format = formatField.First().ConstantValue.ToString();
                                        break;
                                    }
                                }
                            }

                            bool isCommon    = false;
                            var  commonField = resolveResult.Type.GetFields(f => f.Name == "IsCommonEvent");

                            if (commonField.Count() > 0)
                            {
                                isCommon = Convert.ToBoolean(commonField.First().ConstantValue);
                            }

                            if (isCommon)
                            {
                                var eventArg = attr.Arguments.First();

                                if (eventArg is PrimitiveExpression primitiveArg)
                                {
                                    eventName = primitiveArg.Value.ToString();
                                }
                                else
                                {
                                    if (eventArg is MemberReferenceExpression memberArg)
                                    {
                                        if (Emitter.Resolver.ResolveNode(memberArg) is MemberResolveResult memberResolveResult)
                                        {
                                            eventName = Emitter.GetEntityName(memberResolveResult.Member);
                                        }
                                    }
                                }
                            }

                            int    selectorIndex = isCommon ? 1 : 0;
                            string selector      = null;

                            if (attr.Arguments.Count > selectorIndex)
                            {
                                selector = ((PrimitiveExpression)(attr.Arguments.ElementAt(selectorIndex))).Value.ToString();
                            }
                            else
                            {
                                var resolvedmethod = resolveResult.Member as IMethod;

                                if (resolvedmethod.Parameters.Count > selectorIndex)
                                {
                                    selector = resolvedmethod.Parameters[selectorIndex].ConstantValue.ToString();
                                }
                            }

                            if (attr.Arguments.Count > (selectorIndex + 1))
                            {
                                if (Emitter.Resolver.ResolveNode(attr.Arguments.ElementAt(selectorIndex + 1)) is MemberResolveResult memberResolveResult && memberResolveResult.Member.Attributes.Count > 0)
                                {
                                    var template = Emitter.Validator.GetAttribute(memberResolveResult.Member.Attributes, "H5.TemplateAttribute");

                                    if (template != null)
                                    {
                                        selector = string.Format(template.PositionalArguments.First().ConstantValue.ToString(), selector);
                                    }
                                }
                            }
                            else
                            {
                                var resolvedmethod = resolveResult.Member as IMethod;

                                if (resolvedmethod.Parameters.Count > (selectorIndex + 1))
                                {
                                    var templateType  = resolvedmethod.Parameters[selectorIndex + 1].Type;
                                    var templateValue = Convert.ToInt32(resolvedmethod.Parameters[selectorIndex + 1].ConstantValue);

                                    var fields = templateType.GetFields(f =>
                                    {
                                        if (f is DefaultResolvedField field && field.ConstantValue != null && Convert.ToInt32(field.ConstantValue.ToString()) == templateValue)
                                        {
                                            return(true);
                                        }


                                        if (f is DefaultUnresolvedField field1 && field1.ConstantValue != null && Convert.ToInt32(field1.ConstantValue.ToString()) == templateValue)
                                        {
                                            return(true);
                                        }

                                        return(false);
                                    }, GetMemberOptions.IgnoreInheritedMembers);

                                    if (fields.Count() > 0)
                                    {
                                        var template = Emitter.Validator.GetAttribute(fields.First().Attributes, "H5.TemplateAttribute");

                                        if (template != null)
                                        {
                                            selector = string.Format(template.PositionalArguments.First().ConstantValue.ToString(), selector);
                                        }
                                    }
                                }
                            }

                            list.Add(string.Format(format, eventName, selector, Emitter.GetEntityName(method)));
                        }
                    }
                }
            }
        }
コード例 #16
0
ファイル: OperatorBlock.cs プロジェクト: theolivenbaum/h5
        protected void EmitOperatorDeclaration(OperatorDeclaration operatorDeclaration)
        {
            foreach (var attrSection in operatorDeclaration.Attributes)
            {
                foreach (var attr in attrSection.Attributes)
                {
                    var rr = Emitter.Resolver.ResolveNode(attr.Type);
                    if (rr.Type.FullName == "H5.ExternalAttribute")
                    {
                        return;
                    }
                }
            }

            XmlToJsDoc.EmitComment(this, operatorDeclaration);
            EnsureComma();
            ResetLocals();
            var prevMap      = BuildLocalsMap();
            var prevNamesMap = BuildLocalsNamesMap();

            AddLocals(operatorDeclaration.Parameters, operatorDeclaration.Body);

            var overloads = OverloadsCollection.Create(Emitter, operatorDeclaration);

            if (overloads.HasOverloads)
            {
                string name = overloads.GetOverloadName();
                Write(name);
            }
            else
            {
                Write(Emitter.GetEntityName(operatorDeclaration));
            }

            WriteColon();

            WriteFunction();

            EmitMethodParameters(operatorDeclaration.Parameters, null, operatorDeclaration);

            WriteSpace();

            var script = Emitter.GetScript(operatorDeclaration);

            if (script == null)
            {
                operatorDeclaration.Body.AcceptVisitor(Emitter);
            }
            else
            {
                BeginBlock();

                WriteLines(script);

                EndBlock();
            }

            ClearLocalsMap(prevMap);
            ClearLocalsNamesMap(prevNamesMap);
            Emitter.Comma = true;
        }
コード例 #17
0
ファイル: ClassBlock.cs プロジェクト: theolivenbaum/h5
        protected virtual void EmitClassHeader()
        {
            WriteTopInitMethods();

            var    typeDef = Emitter.GetTypeDefinition();
            string name    = Emitter.Validator.GetCustomTypeName(typeDef, Emitter, false);

            IsGeneric = typeDef.GenericParameters.Count > 0 && !Helpers.IsIgnoreGeneric(TypeInfo.Type, Emitter);

            if (name.IsEmpty())
            {
                name = H5Types.ToJsName(TypeInfo.Type, Emitter, asDefinition: true, nomodule: true, ignoreLiteralName: false);
            }

            if (typeDef.IsInterface && typeDef.HasGenericParameters)
            {
                Write(JS.Types.H5.DEFINE_I);
            }
            else
            {
                Write(JS.Types.H5.DEFINE);
            }

            WriteOpenParentheses();

            WriteScript(name);
            StartPosition = Emitter.Output.Length;
            Write(", ");

            if (IsGeneric)
            {
                if (TypeInfo.Module != null)
                {
                    Write(TypeInfo.Module.Name);
                    Write(", ");
                }

                WriteFunction();
                WriteOpenParentheses();

                foreach (var p in typeDef.GenericParameters)
                {
                    if (typeDef.GenericParameters.Count(gp => gp.FullName == p.FullName) > 1)
                    {
                        throw new EmitterException(TypeInfo.TypeDeclaration, $"Type parameter '{p.FullName}' has the same name as the type parameter from outer type.");
                    }
                    EnsureComma(false);
                    Write(p.Name);
                    Emitter.Comma = true;
                }
                Emitter.Comma = false;
                WriteCloseParentheses();

                Write(" { return ");
            }

            BeginBlock();

            string extend = Emitter.GetTypeHierarchy();

            if (extend.IsNotEmpty() && !TypeInfo.IsEnum)
            {
                var h5Type = Emitter.H5Types.Get(Emitter.TypeInfo);

                if (TypeInfo.InstanceMethods.Any(m => m.Value.Any(subm => Emitter.GetEntityName(subm) == JS.Fields.INHERITS)) ||
                    TypeInfo.InstanceConfig.Fields.Any(m => m.GetName(Emitter) == JS.Fields.INHERITS))
                {
                    Write(JS.Vars.D);
                }

                Write(JS.Fields.INHERITS);
                WriteColon();
                if (Helpers.IsTypeArgInSubclass(h5Type.TypeDefinition, h5Type.TypeDefinition, Emitter, false))
                {
                    WriteFunction();
                    WriteOpenCloseParentheses(true);
                    WriteOpenBrace(true);
                    WriteReturn(true);
                    Write(extend);
                    WriteSemiColon();
                    WriteCloseBrace(true);
                }
                else
                {
                    Write(extend);
                }

                Emitter.Comma = true;
            }

            WriteKind();
            EmitMetadata();
            WriteObjectLiteral();

            if (TypeInfo.Module != null)
            {
                WriteScope();
                WriteModule();
            }

            WriteVariance();
        }
コード例 #18
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);
                            }
                        }
                    }
                }
コード例 #19
0
        protected void VisitInvocationExpression()
        {
            InvocationExpression invocationExpression = InvocationExpression;
            int pos = Emitter.Output.Length;

            if (Emitter.IsForbiddenInvocation(invocationExpression))
            {
                throw new EmitterException(invocationExpression, "This method cannot be invoked directly");
            }

            var oldValue = Emitter.ReplaceAwaiterByVar;
            var oldAsyncExpressionHandling = Emitter.AsyncExpressionHandling;

            if (Emitter.IsAsync && !Emitter.AsyncExpressionHandling)
            {
                WriteAwaiters(invocationExpression);
                Emitter.ReplaceAwaiterByVar     = true;
                Emitter.AsyncExpressionHandling = true;
            }

            Tuple <bool, bool, string> inlineInfo = Emitter.GetInlineCode(invocationExpression);
            var argsInfo = new ArgumentsInfo(Emitter, invocationExpression);

            var argsExpressions = argsInfo.ArgumentsExpressions;
            var paramsArg       = argsInfo.ParamsExpression;

            var targetResolve    = Emitter.Resolver.ResolveNode(invocationExpression);
            var csharpInvocation = targetResolve as CSharpInvocationResolveResult;
            MemberReferenceExpression targetMember = invocationExpression.Target as MemberReferenceExpression;
            bool isObjectLiteral = csharpInvocation != null && csharpInvocation.Member.DeclaringTypeDefinition != null?Emitter.Validator.IsObjectLiteral(csharpInvocation.Member.DeclaringTypeDefinition) : false;

            if (inlineInfo != null)
            {
                bool   isStaticMethod = inlineInfo.Item1;
                bool   isInlineMethod = inlineInfo.Item2;
                string inlineScript   = inlineInfo.Item3;

                if (isInlineMethod)
                {
                    if (invocationExpression.Arguments.Count > 0)
                    {
                        var code = invocationExpression.Arguments.First();

                        if (!(code is PrimitiveExpression inlineExpression))
                        {
                            throw new EmitterException(invocationExpression, "Only primitive expression can be inlined");
                        }

                        string value = inlineExpression.Value.ToString().Trim();

                        if (value.Length > 0)
                        {
                            value = InlineArgumentsBlock.ReplaceInlineArgs(this, inlineExpression.Value.ToString(), invocationExpression.Arguments.Skip(1).ToArray());
                            Write(value);

                            value = value.Trim();
                            if (value[value.Length - 1] == ';' || value.EndsWith("*/", StringComparison.InvariantCulture) || value.StartsWith("//"))
                            {
                                Emitter.SkipSemiColon = true;
                                WriteNewLine();
                            }
                        }
                        else
                        {
                            // Empty string, emit nothing.
                            Emitter.SkipSemiColon = true;
                        }

                        Emitter.ReplaceAwaiterByVar     = oldValue;
                        Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

                        return;
                    }
                }
                else
                {
                    bool isBase = invocationExpression.Target is MemberReferenceExpression targetMemberRef && targetMemberRef.Target is BaseReferenceExpression;

                    if (!String.IsNullOrEmpty(inlineScript) && (isBase || invocationExpression.Target is IdentifierExpression))
                    {
                        argsInfo.ThisArgument = "this";
                        bool noThis = !Helpers.HasThis(inlineScript);

                        if (inlineScript.StartsWith("<self>"))
                        {
                            noThis       = false;
                            inlineScript = inlineScript.Substring(6);
                        }

                        if (!noThis)
                        {
                            Emitter.ThisRefCounter++;
                        }

                        if (!isStaticMethod && noThis)
                        {
                            WriteThis();
                            WriteDot();
                        }

                        new InlineArgumentsBlock(Emitter, argsInfo, inlineScript).Emit();
                        Emitter.ReplaceAwaiterByVar     = oldValue;
                        Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

                        return;
                    }
                }
            }

            if (targetMember != null || isObjectLiteral)
            {
                var member = targetMember != null?Emitter.Resolver.ResolveNode(targetMember.Target) : null;

                if (targetResolve != null)
                {
                    InvocationResolveResult invocationResult;
                    bool isExtensionMethodInvocation = false;
                    if (csharpInvocation != null)
                    {
                        if (member != null && member.Type.Kind == TypeKind.Delegate && (/*csharpInvocation.Member.Name == "Invoke" || */ csharpInvocation.Member.Name == "BeginInvoke" || csharpInvocation.Member.Name == "EndInvoke") && !csharpInvocation.IsExtensionMethodInvocation)
                        {
                            throw new EmitterException(invocationExpression, "Delegate's 'Invoke' methods are not supported. Please use direct delegate invoke.");
                        }

                        if (csharpInvocation.IsExtensionMethodInvocation)
                        {
                            invocationResult            = csharpInvocation;
                            isExtensionMethodInvocation = true;
                            if (invocationResult.Member is IMethod resolvedMethod && resolvedMethod.IsExtensionMethod)
                            {
                                string inline   = Emitter.GetInline(resolvedMethod);
                                bool   isNative = IsNativeMethod(resolvedMethod);

                                if (string.IsNullOrWhiteSpace(inline) && isNative)
                                {
                                    invocationResult = null;
                                }
                            }
                        }
                        else
                        {
                            invocationResult = null;
                        }

                        if (IsEmptyPartialInvoking(csharpInvocation.Member as IMethod) || IsConditionallyRemoved(invocationExpression, csharpInvocation.Member))
                        {
                            Emitter.SkipSemiColon           = true;
                            Emitter.ReplaceAwaiterByVar     = oldValue;
                            Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

                            return;
                        }
                    }
                    else
                    {
                        invocationResult = targetResolve as InvocationResolveResult;

                        if (invocationResult != null && (IsEmptyPartialInvoking(invocationResult.Member as IMethod) || IsConditionallyRemoved(invocationExpression, invocationResult.Member)))
                        {
                            Emitter.SkipSemiColon           = true;
                            Emitter.ReplaceAwaiterByVar     = oldValue;
                            Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

                            return;
                        }
                    }

                    if (invocationResult == null)
                    {
                        invocationResult = Emitter.Resolver.ResolveNode(invocationExpression) as InvocationResolveResult;
                    }

                    if (invocationResult != null)
                    {
                        if (invocationResult.Member is IMethod resolvedMethod && (resolvedMethod.IsExtensionMethod || isObjectLiteral))
                        {
                            string inline   = Emitter.GetInline(resolvedMethod);
                            bool   isNative = IsNativeMethod(resolvedMethod);

                            if (isExtensionMethodInvocation || isObjectLiteral)
                            {
                                if (!string.IsNullOrWhiteSpace(inline))
                                {
                                    Write("");
                                    StringBuilder savedBuilder = Emitter.Output;
                                    Emitter.Output = new StringBuilder();
                                    WriteThisExtension(invocationExpression.Target);
                                    argsInfo.ThisArgument = Emitter.Output.ToString();
                                    Emitter.Output        = savedBuilder;
                                    new InlineArgumentsBlock(Emitter, argsInfo, inline).Emit();
                                }
                                else if (!isNative)
                                {
                                    var overloads = OverloadsCollection.Create(Emitter, resolvedMethod);

                                    if (isObjectLiteral && !resolvedMethod.IsStatic && resolvedMethod.DeclaringType.Kind == TypeKind.Interface)
                                    {
                                        Write("H5.getType(");
                                        WriteThisExtension(invocationExpression.Target);
                                        Write(").");
                                    }
                                    else
                                    {
                                        string name = H5Types.ToJsName(resolvedMethod.DeclaringType, Emitter, ignoreLiteralName: false) + ".";
                                        Write(name);
                                    }

                                    if (isObjectLiteral && !resolvedMethod.IsStatic)
                                    {
                                        Write(JS.Fields.PROTOTYPE + "." + overloads.GetOverloadName() + "." + JS.Funcs.CALL);
                                    }
                                    else
                                    {
                                        Write(overloads.GetOverloadName());
                                    }

                                    var isIgnoreClass = resolvedMethod.DeclaringTypeDefinition != null && Emitter.Validator.IsExternalType(resolvedMethod.DeclaringTypeDefinition);
                                    int openPos       = Emitter.Output.Length;
                                    WriteOpenParentheses();

                                    Emitter.Comma = false;

                                    if (isObjectLiteral && !resolvedMethod.IsStatic)
                                    {
                                        WriteThisExtension(invocationExpression.Target);
                                        Emitter.Comma = true;
                                    }

                                    if (!isIgnoreClass && !Helpers.IsIgnoreGeneric(resolvedMethod, Emitter) && argsInfo.HasTypeArguments)
                                    {
                                        EnsureComma(false);
                                        new TypeExpressionListBlock(Emitter, argsInfo.TypeArguments).Emit();
                                        Emitter.Comma = true;
                                    }

                                    if (!isObjectLiteral && resolvedMethod.IsStatic)
                                    {
                                        EnsureComma(false);
                                        WriteThisExtension(invocationExpression.Target);
                                        Emitter.Comma = true;
                                    }

                                    if (invocationExpression.Arguments.Count > 0)
                                    {
                                        EnsureComma(false);
                                    }

                                    new ExpressionListBlock(Emitter, argsExpressions, paramsArg, invocationExpression, openPos).Emit();

                                    WriteCloseParentheses();
                                }

                                if (!string.IsNullOrWhiteSpace(inline) || !isNative)
                                {
                                    Emitter.ReplaceAwaiterByVar     = oldValue;
                                    Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

                                    return;
                                }
                            }
                            else if (isNative)
                            {
                                if (!string.IsNullOrWhiteSpace(inline))
                                {
                                    Write("");
                                    StringBuilder savedBuilder = Emitter.Output;
                                    Emitter.Output = new StringBuilder();
                                    WriteThisExtension(invocationExpression.Target);
                                    argsInfo.ThisArgument = Emitter.Output.ToString();
                                    Emitter.Output        = savedBuilder;
                                    new InlineArgumentsBlock(Emitter, argsInfo, inline).Emit();
                                }
                                else
                                {
                                    argsExpressions.First().AcceptVisitor(Emitter);
                                    WriteDot();
                                    string name = Emitter.GetEntityName(resolvedMethod);
                                    Write(name);
                                    int openPos = Emitter.Output.Length;
                                    WriteOpenParentheses();
                                    new ExpressionListBlock(Emitter, argsExpressions.Skip(1), paramsArg, invocationExpression, openPos).Emit();
                                    WriteCloseParentheses();
                                }

                                Emitter.ReplaceAwaiterByVar     = oldValue;
                                Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

                                return;
                            }
                        }
                    }
                }
            }

            var proto = false;

            if (targetMember != null && targetMember.Target is BaseReferenceExpression)
            {
                if (Emitter.Resolver.ResolveNode(targetMember) is MemberResolveResult rr)
                {
                    proto = rr.IsVirtualCall;

                    /*var method = rr.Member as IMethod;
                     * if (method != null && method.IsVirtual)
                     * {
                     *  proto = true;
                     * }
                     * else
                     * {
                     *  var prop = rr.Member as IProperty;
                     *
                     *  if (prop != null && prop.IsVirtual)
                     *  {
                     *      proto = true;
                     *  }
                     * }*/
                }
            }

            if (proto)
            {
                var baseType = Emitter.GetBaseMethodOwnerTypeDefinition(targetMember.MemberName, targetMember.TypeArguments.Count);

                bool isIgnore = Emitter.Validator.IsExternalType(baseType);

                bool needComma = false;

                var resolveResult = Emitter.Resolver.ResolveNode(targetMember);

                string name = null;

                if (Emitter.TypeInfo.GetBaseTypes(Emitter).Any())
                {
                    name = H5Types.ToJsName(Emitter.TypeInfo.GetBaseClass(Emitter), Emitter);
                }
                else
                {
                    name = H5Types.ToJsName(baseType, Emitter);
                }

                string baseMethod;
                bool   isIgnoreGeneric = false;
                if (resolveResult is MemberResolveResult memberResult)
                {
                    baseMethod      = OverloadsCollection.Create(Emitter, memberResult.Member).GetOverloadName();
                    isIgnoreGeneric = Helpers.IsIgnoreGeneric(memberResult.Member, Emitter);
                }
                else
                {
                    baseMethod = targetMember.MemberName;
                    baseMethod = Object.Net.Utilities.StringUtils.ToLowerCamelCase(baseMethod);
                }

                Write(name, "." + JS.Fields.PROTOTYPE + ".", baseMethod);

                WriteCall();
                WriteOpenParentheses();
                WriteThis();
                Emitter.Comma = true;
                if (!isIgnore && !isIgnoreGeneric && argsInfo.HasTypeArguments)
                {
                    new TypeExpressionListBlock(Emitter, argsInfo.TypeArguments).Emit();
                }

                needComma = false;

                foreach (var arg in argsExpressions)
                {
                    if (arg == null)
                    {
                        continue;
                    }

                    EnsureComma(false);

                    if (needComma)
                    {
                        WriteComma();
                    }

                    needComma = true;
                    arg.AcceptVisitor(Emitter);
                }
                Emitter.Comma = false;
                WriteCloseParentheses();
            }
            else
            {
                IMethod method = null;

                if (Emitter.Resolver.ResolveNode(invocationExpression) is DynamicInvocationResolveResult dynamicResolveResult)
                {
                    if (dynamicResolveResult.Target is MethodGroupResolveResult group && group.Methods.Count() > 1)
                    {
                        method = group.Methods.FirstOrDefault(m =>
                        {
                            if (dynamicResolveResult.Arguments.Count != m.Parameters.Count)
                            {
                                return(false);
                            }

                            for (int i = 0; i < m.Parameters.Count; i++)
                            {
                                var argType = dynamicResolveResult.Arguments[i].Type;

                                if (argType.Kind == TypeKind.Dynamic)
                                {
                                    argType = Emitter.Resolver.Compilation.FindType(TypeCode.Object);
                                }

                                if (!m.Parameters[i].Type.Equals(argType))
                                {
                                    return(false);
                                }
                            }

                            return(true);
                        });

                        if (method == null)
                        {
                            throw new EmitterException(invocationExpression, Constants.Messages.Exceptions.DYNAMIC_INVOCATION_TOO_MANY_OVERLOADS);
                        }
                    }
                }
                else
                {
                    var targetResolveResult = Emitter.Resolver.ResolveNode(invocationExpression.Target);

                    if (targetResolveResult is MemberResolveResult invocationResolveResult)
                    {
                        method = invocationResolveResult.Member as IMethod;
                    }
                }

                if (IsEmptyPartialInvoking(method) || IsConditionallyRemoved(invocationExpression, method))
                {
                    Emitter.SkipSemiColon           = true;
                    Emitter.ReplaceAwaiterByVar     = oldValue;
                    Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;
                    return;
                }

                bool isIgnore = method != null && method.DeclaringTypeDefinition != null && Emitter.Validator.IsExternalType(method.DeclaringTypeDefinition);

                bool needExpand = false;
                if (method != null)
                {
                    string paramsName = null;

                    var paramsParam = method.Parameters.FirstOrDefault(p => p.IsParams);
                    if (paramsParam != null)
                    {
                        paramsName = paramsParam.Name;
                    }

                    if (paramsName != null)
                    {
                        if (csharpInvocation != null && !csharpInvocation.IsExpandedForm)
                        {
                            needExpand = true;
                        }
                    }
                }

                int count = Emitter.Writers.Count;
                invocationExpression.Target.AcceptVisitor(Emitter);

                if (Emitter.Writers.Count > count)
                {
                    var writer = Emitter.Writers.Pop();

                    if (method != null && method.IsExtensionMethod)
                    {
                        StringBuilder savedBuilder = Emitter.Output;
                        Emitter.Output = new StringBuilder();
                        WriteThisExtension(invocationExpression.Target);
                        argsInfo.ThisArgument = Emitter.Output.ToString();
                        Emitter.Output        = savedBuilder;
                    }
                    else if (writer.ThisArg != null)
                    {
                        argsInfo.ThisArgument = writer.ThisArg;
                    }

                    new InlineArgumentsBlock(Emitter, argsInfo, writer.InlineCode)
                    {
                        IgnoreRange = writer.IgnoreRange
                    }.Emit();
                    var result = Emitter.Output.ToString();
                    Emitter.Output    = writer.Output;
                    Emitter.IsNewLine = writer.IsNewLine;
                    Write(result);

                    if (writer.Callback != null)
                    {
                        writer.Callback.Invoke();
                    }
                }
                else
                {
                    if (needExpand && isIgnore)
                    {
                        Write("." + JS.Funcs.APPLY);
                    }
                    int openPos = Emitter.Output.Length;
                    WriteOpenParentheses();

                    bool isIgnoreGeneric = false;

                    if (targetResolve is InvocationResolveResult invocationResult)
                    {
                        isIgnoreGeneric = Helpers.IsIgnoreGeneric(invocationResult.Member, Emitter);
                    }

                    bool isWrapRest = false;

                    if (needExpand && isIgnore)
                    {
                        StringBuilder savedBuilder = Emitter.Output;
                        Emitter.Output = new StringBuilder();
                        WriteThisExtension(invocationExpression.Target);
                        var thisArg = Emitter.Output.ToString();
                        Emitter.Output = savedBuilder;

                        Write(thisArg);

                        Emitter.Comma = true;

                        if (!isIgnore && !isIgnoreGeneric && argsInfo.HasTypeArguments)
                        {
                            new TypeExpressionListBlock(Emitter, argsInfo.TypeArguments).Emit();
                        }

                        EnsureComma(false);

                        if (argsExpressions.Length > 1)
                        {
                            WriteOpenBracket();
                            var elb = new ExpressionListBlock(Emitter, argsExpressions.Take(argsExpressions.Length - 1).ToArray(), paramsArg, invocationExpression, openPos);
                            elb.IgnoreExpandParams = true;
                            elb.Emit();
                            WriteCloseBracket();
                            Write(".concat(");
                            elb = new ExpressionListBlock(Emitter, new Expression[] { argsExpressions[argsExpressions.Length - 1] }, paramsArg, invocationExpression, openPos);
                            elb.IgnoreExpandParams = true;
                            elb.Emit();
                            Write(")");
                        }
                        else
                        {
                            new ExpressionListBlock(Emitter, argsExpressions, paramsArg, invocationExpression, -1).Emit();
                        }
                    }
                    else
                    {
                        if (method != null && method.Attributes.Any(a => a.AttributeType.FullName == "H5.WrapRestAttribute"))
                        {
                            isWrapRest = true;
                        }

                        Emitter.Comma = false;
                        if (!isIgnore && !isIgnoreGeneric && argsInfo.HasTypeArguments)
                        {
                            new TypeExpressionListBlock(Emitter, argsInfo.TypeArguments).Emit();
                        }

                        if (invocationExpression.Arguments.Count > 0 || argsExpressions.Length > 0 && !argsExpressions.All(expr => expr == null))
                        {
                            EnsureComma(false);
                        }

                        new ExpressionListBlock(Emitter, argsExpressions, paramsArg, invocationExpression, openPos).Emit();
                    }


                    if (isWrapRest)
                    {
                        EnsureComma(false);
                        Write("H5.fn.bind(this, function () ");
                        BeginBlock();
                        Emitter.WrapRestCounter++;
                        Emitter.SkipSemiColon = true;
                    }
                    else
                    {
                        Emitter.Comma = false;
                        WriteCloseParentheses();
                    }
                }
            }

            if (targetResolve is InvocationResolveResult irr && irr.Member.MemberDefinition != null && irr.Member.MemberDefinition.ReturnType.Kind == TypeKind.TypeParameter)
            {
                Helpers.CheckValueTypeClone(Emitter.Resolver.ResolveNode(invocationExpression), invocationExpression, this, pos);
            }

            Emitter.ReplaceAwaiterByVar     = oldValue;
            Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;
        }