Ejemplo n.º 1
0
        protected virtual void EmitPropertyMethod(PropertyDeclaration propertyDeclaration, Accessor accessor, bool setter)
        {
            var memberResult = this.Emitter.Resolver.ResolveNode(propertyDeclaration, this.Emitter) as MemberResolveResult;

            if (memberResult != null &&
                (memberResult.Member.Attributes.Any(a => a.AttributeType.FullName == "Bridge.FieldPropertyAttribute") ||
                 (propertyDeclaration.Getter.IsNull && propertyDeclaration.Setter.IsNull)))
            {
                return;
            }

            if (!accessor.IsNull && this.Emitter.GetInline(accessor) == null)
            {
                this.EnsureComma();

                this.ResetLocals();

                var prevMap      = this.BuildLocalsMap();
                var prevNamesMap = this.BuildLocalsNamesMap();

                if (setter)
                {
                    this.AddLocals(new ParameterDeclaration[] { new ParameterDeclaration {
                                                                    Name = "value"
                                                                } }, accessor.Body);
                }

                var    overloads = OverloadsCollection.Create(this.Emitter, propertyDeclaration, setter);
                string name      = overloads.GetOverloadName();
                this.Write((setter ? "set" : "get") + name);
                this.WriteColon();
                this.WriteFunction();
                this.WriteOpenParentheses();
                this.Write(setter ? "value" : "");
                this.WriteCloseParentheses();
                this.WriteSpace();

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

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

                    foreach (var line in script)
                    {
                        this.Write(line);
                        this.WriteNewLine();
                    }

                    this.EndBlock();
                }

                this.ClearLocalsMap(prevMap);
                this.ClearLocalsNamesMap(prevNamesMap);
                this.Emitter.Comma = true;
            }
        }
Ejemplo n.º 2
0
        protected bool ResolveOperator(BinaryOperatorExpression binaryOperatorExpression, OperatorResolveResult orr)
        {
            var method = orr != null ? orr.UserDefinedOperatorMethod : null;

            if (method != null)
            {
                var inline = this.Emitter.GetInline(method);

                if (!string.IsNullOrWhiteSpace(inline))
                {
                    new InlineArgumentsBlock(this.Emitter,
                                             new ArgumentsInfo(this.Emitter, binaryOperatorExpression, orr, method), inline).Emit();
                    return(true);
                }
                else if (!this.Emitter.Validator.IsIgnoreType(method.DeclaringTypeDefinition))
                {
                    bool   addClose             = false;
                    string leftInterfaceTempVar = null;

                    if (orr.OperatorType == ExpressionType.OrElse || orr.OperatorType == ExpressionType.AndAlso)
                    {
                        var  orElse         = orr.OperatorType == ExpressionType.OrElse;
                        var  left           = orr.Operands[0];
                        var  memberTargetrr = left as MemberResolveResult;
                        bool isField        = memberTargetrr != null && memberTargetrr.Member is IField &&
                                              (memberTargetrr.TargetResult is ThisResolveResult ||
                                               memberTargetrr.TargetResult is LocalResolveResult);

                        if (!(left is ThisResolveResult || left is TypeResolveResult || left is LocalResolveResult || left is ConstantResolveResult || isField))
                        {
                            this.WriteOpenParentheses();

                            leftInterfaceTempVar = this.GetTempVarName();
                            this.Write(leftInterfaceTempVar);
                            this.Write(" = ");

                            binaryOperatorExpression.Left.AcceptVisitor(this.Emitter);

                            this.WriteComma();

                            addClose = true;
                        }

                        var m = FindOperatorTrueOrFalse(left.Type, orElse);

                        this.Write(BridgeTypes.ToJsName(m.DeclaringType, this.Emitter));
                        this.WriteDot();
                        this.Write(OverloadsCollection.Create(this.Emitter, m).GetOverloadName());

                        this.WriteOpenParentheses();

                        if (leftInterfaceTempVar != null)
                        {
                            this.Write(leftInterfaceTempVar);
                        }
                        else
                        {
                            binaryOperatorExpression.Left.AcceptVisitor(this.Emitter);
                        }

                        this.WriteCloseParentheses();

                        this.Write(" ? ");

                        if (leftInterfaceTempVar != null)
                        {
                            this.Write(leftInterfaceTempVar);
                        }
                        else
                        {
                            binaryOperatorExpression.Left.AcceptVisitor(this.Emitter);
                        }

                        this.Write(" : ");
                    }

                    if (orr.IsLiftedOperator)
                    {
                        this.Write(JS.Types.SYSTEM_NULLABLE + ".");

                        string action = JS.Funcs.Math.LIFT;

                        switch (this.BinaryOperatorExpression.Operator)
                        {
                        case BinaryOperatorType.GreaterThan:
                            action = JS.Funcs.Math.LIFTCMP;
                            break;

                        case BinaryOperatorType.GreaterThanOrEqual:
                            action = JS.Funcs.Math.LIFTCMP;
                            break;

                        case BinaryOperatorType.Equality:
                            action = JS.Funcs.Math.LIFTEQ;
                            break;

                        case BinaryOperatorType.InEquality:
                            action = JS.Funcs.Math.LIFTNE;
                            break;

                        case BinaryOperatorType.LessThan:
                            action = JS.Funcs.Math.LIFTCMP;
                            break;

                        case BinaryOperatorType.LessThanOrEqual:
                            action = JS.Funcs.Math.LIFTCMP;
                            break;
                        }

                        this.Write(action + "(");
                    }

                    this.Write(BridgeTypes.ToJsName(method.DeclaringType, this.Emitter));
                    this.WriteDot();

                    this.Write(OverloadsCollection.Create(this.Emitter, method).GetOverloadName());

                    if (orr.IsLiftedOperator)
                    {
                        this.WriteComma();
                    }
                    else
                    {
                        this.WriteOpenParentheses();
                    }

                    if (leftInterfaceTempVar != null)
                    {
                        this.Write(leftInterfaceTempVar);
                        this.Write(", ");
                        binaryOperatorExpression.Right.AcceptVisitor(this.Emitter);
                    }
                    else
                    {
                        new ExpressionListBlock(this.Emitter,
                                                new Expression[] { binaryOperatorExpression.Left, binaryOperatorExpression.Right }, null, null, 0).Emit();
                    }

                    this.WriteCloseParentheses();

                    if (addClose)
                    {
                        this.WriteCloseParentheses();
                    }

                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 3
0
        protected virtual bool WriteObject(string objectName, List <TypeConfigItem> members, string format, string interfaceFormat)
        {
            bool        hasProperties = HasProperties(objectName, members);
            int         pos           = 0;
            IWriterInfo writer        = null;
            bool        beginBlock    = false;

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

                WriteColon();
                BeginBlock();
            }

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

            foreach (var member in members)
            {
                object constValue  = null;
                bool   isPrimitive = false;
                bool   write       = false;
                bool   writeScript = false;

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

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

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

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

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

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

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

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

                        writeScript = true;
                    }
                }

                var isNullable = false;

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

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

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

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

                bool isAutoProperty = false;

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

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

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

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

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

                    var name = member.GetName(Emitter);

                    bool isValidIdentifier = Helpers.IsValidIdentifier(name);

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

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

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

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

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

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

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

                count++;

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

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

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

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

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

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

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

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

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

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

                if (IsObjectLiteral)
                {
                    WriteSemiColon(true);
                }

                Emitter.Comma = true;
            }

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

                Emitter.Output.Length = pos;
            }

            return(count > 0);
        }
Ejemplo n.º 4
0
        private void WriteInterfaceMember(string interfaceTempVar, MemberResolveResult resolveResult, bool isSetter, string prefix = null)
        {
            var  itypeDef          = resolveResult.Member.DeclaringTypeDefinition;
            var  externalInterface = this.Emitter.Validator.IsExternalInterface(itypeDef);
            bool variance          = MetadataUtils.IsJsGeneric(itypeDef, this.Emitter) &&
                                     itypeDef.TypeParameters != null &&
                                     itypeDef.TypeParameters.Any(typeParameter => typeParameter.Variance != VarianceModifier.Invariant);

            if (interfaceTempVar != null && externalInterface == null && !variance)
            {
                this.WriteComma();
                this.Write(interfaceTempVar);
            }

            if (externalInterface != null && externalInterface.IsDualImplementation || variance)
            {
                if (interfaceTempVar != null)
                {
                    this.WriteCloseParentheses();
                }

                this.WriteOpenBracket();
                this.Write(JS.Funcs.BRIDGE_GET_I);
                this.WriteOpenParentheses();

                if (interfaceTempVar != null)
                {
                    this.Write(interfaceTempVar);
                }
                else
                {
                    this.WriteSimpleTarget(resolveResult);
                }

                this.WriteComma();

                var interfaceName = OverloadsCollection.Create(Emitter, resolveResult.Member, isSetter).GetOverloadName(false, prefix);

                if (interfaceName.StartsWith("\""))
                {
                    this.Write(interfaceName);
                }
                else
                {
                    this.WriteScript(interfaceName);
                }

                if (variance)
                {
                    this.WriteComma();
                    this.WriteScript(OverloadsCollection.Create(Emitter, resolveResult.Member, isSetter).GetOverloadName(false, prefix, withoutTypeParams: true));
                }

                /*this.WriteComma();
                 * this.WriteScript(OverloadsCollection.Create(Emitter, resolveResult.Member, isSetter).GetOverloadName(true, prefix));*/

                this.Write(")");
                this.WriteCloseBracket();

                return;
            }

            this.WriteOpenBracket();
            this.Write(OverloadsCollection.Create(Emitter, resolveResult.Member, isSetter).GetOverloadName(externalInterface != null && externalInterface.IsSimpleImplementation, prefix));
            this.WriteCloseBracket();

            if (interfaceTempVar != null)
            {
                this.WriteCloseParentheses();
            }
        }
Ejemplo n.º 5
0
        protected void VisitMethodDeclaration(MethodDeclaration methodDeclaration)
        {
            var typeDef   = this.Emitter.GetTypeDefinition();
            var overloads = OverloadsCollection.Create(this.Emitter, methodDeclaration);

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

            var isGeneric = methodDeclaration.TypeParameters.Count > 0;

            if (isGeneric)
            {
                bool needComma = false;
                this.Write("<");
                foreach (var p in methodDeclaration.TypeParameters)
                {
                    if (needComma)
                    {
                        this.WriteComma();
                    }

                    needComma = true;
                    this.Write(p.Name);
                }
                this.Write(">");

                this.WriteOpenParentheses();

                var comma = false;
                foreach (var p in methodDeclaration.TypeParameters)
                {
                    if (comma)
                    {
                        this.WriteComma();
                    }
                    this.Write(p.Name);
                    this.WriteColon();
                    this.WriteOpenBrace();
                    this.Write("prototype");
                    this.WriteColon();
                    this.Write(p.Name);

                    this.WriteCloseBrace();
                    comma = true;
                }

                this.WriteCloseParentheses();

                this.WriteColon();
                this.WriteOpenBrace();
                this.WriteSpace();
            }

            this.EmitMethodParameters(methodDeclaration.Parameters, methodDeclaration);
            this.WriteColon();

            var retType = BridgeTypes.ToJsName(methodDeclaration.ReturnType, this.Emitter);

            retType = EmitBlock.HandleType(retType);
            this.Write(retType);

            if (isGeneric)
            {
                this.WriteSpace();
                this.WriteCloseBrace();
            }

            this.WriteSemiColon();
            this.WriteNewLine();
        }
Ejemplo n.º 6
0
        public static bool CheckConversion(ConversionBlock block, Expression expression)
        {
            Conversion conversion = null;

            try
            {
                var rr = block.Emitter.Resolver.ResolveNode(expression, block.Emitter);
                conversion = block.Emitter.Resolver.Resolver.GetConversion(expression);

                if (conversion == null)
                {
                    return(false);
                }

                if (conversion.IsIdentityConversion)
                {
                    return(false);
                }

                var isNumLifted = conversion.IsImplicit && conversion.IsLifted && conversion.IsNumericConversion && !(expression is BinaryOperatorExpression);
                if (isNumLifted && !conversion.IsUserDefined)
                {
                    return(false);
                }

                if (conversion.IsLifted && !isNumLifted)
                {
                    block.Write("Bridge.Nullable.lift(");
                }

                if (conversion.IsUserDefined)
                {
                    var method = conversion.Method;

                    string inline = block.Emitter.GetInline(method);

                    if (conversion.IsExplicit && !string.IsNullOrWhiteSpace(inline))
                    {
                        // Still returns true if Nullable.lift( was written.
                        return(conversion.IsLifted);
                    }

                    if (!string.IsNullOrWhiteSpace(inline))
                    {
                        if (expression is InvocationExpression)
                        {
                            new InlineArgumentsBlock(block.Emitter, new ArgumentsInfo(block.Emitter, (InvocationExpression)expression), inline).Emit();
                        }
                        else if (expression is ObjectCreateExpression)
                        {
                            new InlineArgumentsBlock(block.Emitter, new ArgumentsInfo(block.Emitter, (InvocationExpression)expression), inline).Emit();
                        }
                        else if (expression is UnaryOperatorExpression)
                        {
                            var unaryExpression       = (UnaryOperatorExpression)expression;
                            var resolveOperator       = block.Emitter.Resolver.ResolveNode(unaryExpression, block.Emitter);
                            OperatorResolveResult orr = resolveOperator as OperatorResolveResult;
                            new InlineArgumentsBlock(block.Emitter, new ArgumentsInfo(block.Emitter, unaryExpression, orr), inline).Emit();
                        }
                        else if (expression is BinaryOperatorExpression)
                        {
                            var binaryExpression      = (BinaryOperatorExpression)expression;
                            var resolveOperator       = block.Emitter.Resolver.ResolveNode(binaryExpression, block.Emitter);
                            OperatorResolveResult orr = resolveOperator as OperatorResolveResult;
                            new InlineArgumentsBlock(block.Emitter, new ArgumentsInfo(block.Emitter, binaryExpression, orr), inline).Emit();
                        }
                        else
                        {
                            new InlineArgumentsBlock(block.Emitter, new ArgumentsInfo(block.Emitter, expression), inline).Emit();
                        }

                        block.DisableEmitConversionExpression = true;

                        // Still returns true if Nullable.lift( was written.
                        return(conversion.IsLifted);
                    }
                    else
                    {
                        if (method.DeclaringTypeDefinition != null && block.Emitter.Validator.IsIgnoreType(method.DeclaringTypeDefinition))
                        {
                            // Still returns true if Nullable.lift( was written.
                            return(conversion.IsLifted);
                        }

                        block.Write(BridgeTypes.ToJsName(method.DeclaringType, block.Emitter));
                        block.WriteDot();

                        block.Write(OverloadsCollection.Create(block.Emitter, method).GetOverloadName());
                    }

                    if (conversion.IsLifted)
                    {
                        block.WriteComma();
                    }
                    else
                    {
                        block.WriteOpenParentheses();
                    }

                    return(true);
                }
                // Still returns true if Nullable.lift( was written.
                return(conversion.IsLifted);
            }
            catch
            {
            }

            return(false);
        }
Ejemplo n.º 7
0
        private void HandleDecimal(ResolveResult resolveOperator)
        {
            if (this.AssignmentExpression.Operator == AssignmentOperatorType.Assign)
            {
                new ExpressionListBlock(this.Emitter,
                                        new Expression[] { this.AssignmentExpression.Right }, null).Emit();
                return;
            }

            var orr           = resolveOperator as OperatorResolveResult;
            var method        = orr != null ? orr.UserDefinedOperatorMethod : null;
            var assigmentType = Helpers.TypeOfAssignment(this.AssignmentExpression.Operator);

            if (orr != null && method == null)
            {
                var name = Helpers.GetBinaryOperatorMethodName(assigmentType);
                var type = NullableType.IsNullable(orr.Type) ? NullableType.GetUnderlyingType(orr.Type) : orr.Type;
                method = type.GetMethods(m => m.Name == name, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault();
            }

            if (method != null)
            {
                var inline = this.Emitter.GetInline(method);

                if (orr.IsLiftedOperator)
                {
                    this.Write(Bridge.Translator.Emitter.ROOT + ".Nullable.");
                    string action  = "lift2";
                    string op_name = null;

                    switch (assigmentType)
                    {
                    case BinaryOperatorType.GreaterThan:
                        op_name = "gt";
                        break;

                    case BinaryOperatorType.GreaterThanOrEqual:
                        op_name = "gte";
                        break;

                    case BinaryOperatorType.Equality:
                        op_name = "equals";
                        break;

                    case BinaryOperatorType.InEquality:
                        op_name = "ne";
                        break;

                    case BinaryOperatorType.LessThan:
                        op_name = "lt";
                        break;

                    case BinaryOperatorType.LessThanOrEqual:
                        op_name = "lte";
                        break;

                    case BinaryOperatorType.Add:
                        op_name = "add";
                        break;

                    case BinaryOperatorType.Subtract:
                        op_name = "sub";
                        break;

                    case BinaryOperatorType.Multiply:
                        op_name = "mul";
                        break;

                    case BinaryOperatorType.Divide:
                        op_name = "div";
                        break;

                    case BinaryOperatorType.Modulus:
                        op_name = "mod";
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }

                    this.Write(action);
                    this.WriteOpenParentheses();
                    this.WriteScript(op_name);
                    this.WriteComma();
                    new ExpressionListBlock(this.Emitter,
                                            new Expression[] { this.AssignmentExpression.Left, this.AssignmentExpression.Right }, null).Emit();
                    this.WriteCloseParentheses();
                }
                else if (!string.IsNullOrWhiteSpace(inline))
                {
                    new InlineArgumentsBlock(this.Emitter,
                                             new ArgumentsInfo(this.Emitter, this.AssignmentExpression, orr, method), inline).Emit();
                }
                else if (!this.Emitter.Validator.IsIgnoreType(method.DeclaringTypeDefinition))
                {
                    this.Write(BridgeTypes.ToJsName(method.DeclaringType, this.Emitter));
                    this.WriteDot();

                    this.Write(OverloadsCollection.Create(this.Emitter, method).GetOverloadName());

                    this.WriteOpenParentheses();

                    new ExpressionListBlock(this.Emitter,
                                            new Expression[] { this.AssignmentExpression.Left, this.AssignmentExpression.Right }, null).Emit();
                    this.WriteCloseParentheses();
                }
            }
        }
Ejemplo n.º 8
0
        protected void VisitIdentifierExpression()
        {
            IdentifierExpression identifierExpression = this.IdentifierExpression;
            int           pos           = this.Emitter.Output.Length;
            ResolveResult resolveResult = null;

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

            resolveResult = this.Emitter.Resolver.ResolveNode(identifierExpression, this.Emitter);

            var id = identifierExpression.Identifier;

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

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

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

                return;
            }

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

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

                return;
            }

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

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

            if (memberResult != null && memberResult.Member is IMethod && isInvoke)
            {
                var i_rr = this.Emitter.Resolver.ResolveNode(identifierExpression.Parent, this.Emitter) as CSharpInvocationResolveResult;

                if (i_rr != null && !i_rr.IsExpandedForm)
                {
                    var tpl = this.Emitter.GetAttribute(memberResult.Member.Attributes, JS.NS.BRIDGE + ".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 == "("
                    )
                )
            {
                var method = (IMethod)memberResult.Member;
                if (method.TypeArguments.Count > 0)
                {
                    inlineCode = MemberReferenceBlock.GenerateInlineForMethodReference(method, this.Emitter);
                }
            }

            bool hasInline = !string.IsNullOrEmpty(inlineCode);
            bool hasThis   = hasInline && inlineCode.Contains("{this}");

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

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

                if (memberResult.Member.IsStatic)
                {
                    this.Write(BridgeTypes.ToJsName(memberResult.Member.DeclaringType, this.Emitter));

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

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

                int[] range = null;

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

                if (resolveResult is InvocationResolveResult)
                {
                    this.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(this.Emitter, new ArgumentsInfo(this.Emitter, this.IdentifierExpression, resolveResult), oldInline, (IMethod)memberResult.Member, targetrr).EmitFunctionReference();
                    }
                    else if (memberResult != null && memberResult.Member is IField && inlineCode.Contains("{0}"))
                    {
                        this.PushWriter(inlineCode, null, thisArg, range);
                    }
                    else if (InlineArgumentsBlock.FormatArgRegex.IsMatch(inlineCode))
                    {
                        this.PushWriter(inlineCode, null, thisArg, range);
                    }
                    else
                    {
                        this.Write(inlineCode);
                    }
                }

                return;
            }

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

                        new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, this.IdentifierExpression, resolveResult), inlineCode, (IMethod)memberResult.Member, targetrr).EmitFunctionReference();
                    }
                    else if (InlineArgumentsBlock.FormatArgRegex.IsMatch(inlineCode))
                    {
                        this.PushWriter(inlineCode);
                    }
                    else
                    {
                        this.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 (!string.IsNullOrEmpty(inlineCode))
                {
                    ResolveResult targetrr = null;
                    if (memberResult.Member.IsStatic)
                    {
                        targetrr = new TypeResolveResult(memberResult.Member.DeclaringType);
                    }

                    new InlineArgumentsBlock(this.Emitter,
                                             new ArgumentsInfo(this.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;
                        this.Write(isExtensionMethod ? JS.Funcs.BRIDGE_BIND_SCOPE : JS.Funcs.BRIDGE_CACHE_BIND);
                        this.WriteOpenParentheses();
                        this.WriteThis();
                        this.Write(", ");
                        appendAdditionalCode = ")";
                    }
                }
            }

            if (memberResult != null && memberResult.Member.SymbolKind == SymbolKind.Field && this.Emitter.IsMemberConst(memberResult.Member) && this.Emitter.IsInlineConst(memberResult.Member))
            {
                this.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 (this.Emitter.IsUnaryAccessor)
                {
                    isStatement = identifierExpression.Parent is UnaryOperatorExpression && identifierExpression.Parent.Parent is ExpressionStatement;

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

                    if (!isStatement)
                    {
                        this.WriteOpenParentheses();

                        valueVar = this.GetTempVarName();

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

                this.WriteTarget(memberResult);

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

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

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

                                    this.WriteComma();

                                    this.WriteTarget(memberResult);

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

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

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

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

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

                                this.Write("1");
                            }

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

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

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

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

                                    this.WriteDot();

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

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

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

                                this.Write("1");
                            }

                            this.WriteCloseParentheses();
                            this.WriteComma();

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

                            this.WriteCloseParentheses();

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

                    if (memberResult.Member.IsStatic)
                    {
                        trg = BridgeTypes.ToJsName(memberResult.Member.DeclaringType, this.Emitter);
                    }
                    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;
                    var  orr     = this.Emitter.Resolver.ResolveNode(identifierExpression.Parent, this.Emitter) as OperatorResolveResult;
                    bool special = orr != null && orr.IsLiftedOperator;

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

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

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

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

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

            Helpers.CheckValueTypeClone(resolveResult, identifierExpression, this, pos);
        }
Ejemplo n.º 9
0
        protected void VisitMethodDeclaration(MethodDeclaration methodDeclaration)
        {
            foreach (var attrSection in methodDeclaration.Attributes)
            {
                foreach (var attr in attrSection.Attributes)
                {
                    var rr = this.Emitter.Resolver.ResolveNode(attr.Type, this.Emitter);
                    if (rr.Type.FullName == "Bridge.ExternalAttribute" || rr.Type.FullName == "Bridge.IgnoreAttribute")
                    {
                        return;
                    }
                    else if (rr.Type.FullName == "Bridge.InitAttribute")
                    {
                        int initPosition = 0;

                        if (attr.HasArgumentList)
                        {
                            if (attr.Arguments.Any())
                            {
                                var argExpr = attr.Arguments.First();
                                var argrr   = this.Emitter.Resolver.ResolveNode(argExpr, this.Emitter);
                                if (argrr.ConstantValue is int)
                                {
                                    initPosition = (int)argrr.ConstantValue;
                                }
                            }
                        }

                        if (initPosition > 0)
                        {
                            return;
                        }
                    }
                }
            }

            //this.EnsureComma();
            this.EnsureNewLine();
            this.ResetLocals();

            var prevMap      = this.BuildLocalsMap();
            var prevNamesMap = this.BuildLocalsNamesMap();

            this.AddLocals(methodDeclaration.Parameters, methodDeclaration.Body);

            var typeDef   = this.Emitter.GetTypeDefinition();
            var overloads = OverloadsCollection.Create(this.Emitter, methodDeclaration);

            XmlToJsDoc.EmitComment(this, this.MethodDeclaration);

            string name = overloads.GetOverloadName();

            TransformCtx.CurClassMethodNames.Add(new TransformCtx.MethodInfo()
            {
                Name      = name,
                IsPrivate = methodDeclaration.HasModifier(Modifiers.Private),
            });

            this.Write(name);
            this.WriteEqualsSign();

            /*
             * if (methodDeclaration.TypeParameters.Count > 0)
             * {
             *  this.WriteFunction();
             *  this.EmitTypeParameters(methodDeclaration.TypeParameters, methodDeclaration);
             *  this.WriteSpace();
             *  this.BeginBlock();
             *  this.WriteReturn(true);
             *  this.Write("Bridge.fn.bind(this, ");
             * }*/

            this.WriteFunction();

            this.EmitMethodParameters(methodDeclaration.Parameters, methodDeclaration, true);
            if (methodDeclaration.TypeParameters.Count > 0)
            {
                if (methodDeclaration.Parameters.Count > 0 || !methodDeclaration.HasModifier(Modifiers.Static))
                {
                    this.WriteComma();
                }
                this.EmitTypeParameters(methodDeclaration.TypeParameters, methodDeclaration);
            }
            this.WriteCloseParentheses();

            this.WriteSpace();

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

            if (script == null)
            {
                if (methodDeclaration.HasModifier(Modifiers.Async))
                {
                    new AsyncBlock(this.Emitter, methodDeclaration).Emit();
                }
                else
                {
                    this.BeginFunctionBlock();
                    bool isYieldExists = YieldBlock.HasYield(methodDeclaration.Body);
                    if (isYieldExists)
                    {
                        YieldBlock.EmitYield(this, null);
                    }
                    else
                    {
                        this.ConvertParamsToReferences(methodDeclaration.Parameters);
                    }

                    MarkTempVars();
                    methodDeclaration.Body.AcceptVisitor(this.Emitter);
                    EmitTempVars();

                    if (isYieldExists)
                    {
                        var returnResolveResult = this.Emitter.Resolver.ResolveNode(methodDeclaration.ReturnType, this.Emitter);
                        YieldBlock.EmitYieldReturn(this, returnResolveResult.Type);
                    }
                    else
                    {
                        PrimitiveType returnType = methodDeclaration.ReturnType as PrimitiveType;
                        if (returnType != null)
                        {
                            if (returnType.KnownTypeCode == ICSharpCode.NRefactory.TypeSystem.KnownTypeCode.Void)
                            {
                                string refArgsString = GetRefArgsString(this.Emitter, methodDeclaration);
                                if (refArgsString != null)
                                {
                                    this.WriteReturn(true);
                                    this.Write(refArgsString);
                                    this.WriteNewLine();
                                }
                            }
                        }
                    }
                    this.EndFunctionBlock();
                }
            }
            else
            {
                this.BeginBlock();

                foreach (var line in script)
                {
                    this.Write(line);
                    this.WriteNewLine();
                }

                this.EndBlock();
            }

            /*
             * if (methodDeclaration.TypeParameters.Count > 0)
             * {
             *  this.Write(");");
             *  this.WriteNewLine();
             *  this.EndBlock();
             * }*/

            this.ClearLocalsMap(prevMap);
            this.ClearLocalsNamesMap(prevNamesMap);
            this.Emitter.Comma = true;
        }
Ejemplo n.º 10
0
        protected void VisitMemberReferenceExpression()
        {
            MemberReferenceExpression memberReferenceExpression = this.MemberReferenceExpression;
            int pos = this.Emitter.Output.Length;

            ResolveResult resolveResult           = null;
            ResolveResult expressionResolveResult = null;
            string        targetVar     = null;
            string        valueVar      = null;
            bool          isStatement   = false;
            bool          isConstTarget = false;

            var targetrr = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Target, this.Emitter);

            if (targetrr is ConstantResolveResult)
            {
                isConstTarget = true;
            }

            var memberTargetrr = targetrr as MemberResolveResult;

            if (memberTargetrr != null && memberTargetrr.Type.Kind == TypeKind.Enum && memberTargetrr.Member is DefaultResolvedField && this.Emitter.Validator.EnumEmitMode(memberTargetrr.Type) == 2)
            {
                isConstTarget = true;
            }

            if (memberReferenceExpression.Parent is InvocationExpression && (((InvocationExpression)(memberReferenceExpression.Parent)).Target == memberReferenceExpression))
            {
                resolveResult           = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter);
                expressionResolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression, this.Emitter);

                if (expressionResolveResult is InvocationResolveResult)
                {
                    resolveResult = expressionResolveResult;
                }
            }
            else
            {
                resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression, this.Emitter);
            }

            bool oldIsAssignment = this.Emitter.IsAssignment;
            bool oldUnary        = this.Emitter.IsUnaryAccessor;

            if (resolveResult == null)
            {
                this.Emitter.IsAssignment    = false;
                this.Emitter.IsUnaryAccessor = false;
                if (isConstTarget)
                {
                    this.Write("(");
                }
                memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                if (isConstTarget)
                {
                    this.Write(")");
                }
                this.Emitter.IsAssignment    = oldIsAssignment;
                this.Emitter.IsUnaryAccessor = oldUnary;
                this.WriteDot();
                string name = memberReferenceExpression.MemberName;
                this.Write(name.ToLowerCamelCase());

                return;
            }

            if (resolveResult is DynamicInvocationResolveResult)
            {
                resolveResult = ((DynamicInvocationResolveResult)resolveResult).Target;
            }

            if (resolveResult is MethodGroupResolveResult)
            {
                var oldResult = (MethodGroupResolveResult)resolveResult;
                resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter);

                if (resolveResult is DynamicInvocationResolveResult)
                {
                    var method = oldResult.Methods.Last();
                    resolveResult = new MemberResolveResult(new TypeResolveResult(method.DeclaringType), method);
                }
            }

            MemberResolveResult member = resolveResult as MemberResolveResult;
            var globalTarget           = member != null?this.Emitter.IsGlobalTarget(member.Member) : null;

            if (globalTarget != null && globalTarget.Item1)
            {
                var target = globalTarget.Item2;

                if (!string.IsNullOrWhiteSpace(target))
                {
                    bool assign           = false;
                    var  memberExpression = member.Member is IMethod ? memberReferenceExpression.Parent.Parent : memberReferenceExpression.Parent;
                    var  targetExpression = member.Member is IMethod ? memberReferenceExpression.Parent : memberReferenceExpression;
                    var  assignment       = memberExpression as AssignmentExpression;
                    if (assignment != null && assignment.Right == targetExpression)
                    {
                        assign = true;
                    }
                    else
                    {
                        var varInit = memberExpression as VariableInitializer;
                        if (varInit != null && varInit.Initializer == targetExpression)
                        {
                            assign = true;
                        }
                        else if (memberExpression is InvocationExpression)
                        {
                            var targetInvocation = (InvocationExpression)memberExpression;
                            if (targetInvocation.Arguments.Any(a => a == targetExpression))
                            {
                                assign = true;
                            }
                        }
                    }

                    if (assign)
                    {
                        if (resolveResult is InvocationResolveResult)
                        {
                            this.PushWriter(target);
                        }
                        else
                        {
                            this.Write(target);
                        }

                        return;
                    }
                }

                if (resolveResult is InvocationResolveResult)
                {
                    this.PushWriter("");
                }

                return;
            }

            Tuple <bool, bool, string> inlineInfo = member != null?this.Emitter.GetInlineCode(memberReferenceExpression) : null;

            //string inline = member != null ? this.Emitter.GetInline(member.Member) : null;
            string inline    = inlineInfo != null ? inlineInfo.Item3 : null;
            bool   hasInline = !string.IsNullOrEmpty(inline);
            bool   hasThis   = hasInline && inline.Contains("{this}");

            if (hasThis)
            {
                this.Write("");
                var oldBuilder = this.Emitter.Output;
                this.Emitter.Output          = new StringBuilder();
                this.Emitter.IsAssignment    = false;
                this.Emitter.IsUnaryAccessor = false;
                if (isConstTarget)
                {
                    this.Write("(");
                }
                memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                if (isConstTarget)
                {
                    this.Write(")");
                }
                this.Emitter.IsAssignment    = oldIsAssignment;
                this.Emitter.IsUnaryAccessor = oldUnary;
                inline = inline.Replace("{this}", this.Emitter.Output.ToString());
                this.Emitter.Output = oldBuilder;

                if (resolveResult is InvocationResolveResult)
                {
                    this.PushWriter(inline);
                }
                else
                {
                    if (member != null && member.Member is IMethod)
                    {
                        throw new EmitterException(memberReferenceExpression, "The templated method (" + member.Member.FullName + ") cannot be used like reference");
                    }
                    else
                    {
                        this.Write(inline);
                    }
                }

                return;
            }

            if (member != null && member.Member.SymbolKind == SymbolKind.Field && this.Emitter.IsMemberConst(member.Member) && this.Emitter.IsInlineConst(member.Member))
            {
                this.WriteScript(member.ConstantValue);
            }
            else if (hasInline && member.Member.IsStatic)
            {
                if (resolveResult is InvocationResolveResult)
                {
                    this.PushWriter(inline);
                }
                else
                {
                    if (member != null && member.Member is IMethod)
                    {
                        var r     = new Regex(@"([$\w\.]+)\(\s*\S.*\)");
                        var match = r.Match(inline);

                        if (match.Success)
                        {
                            this.Write(match.Groups[1].Value);
                        }
                        else
                        {
                            throw new EmitterException(memberReferenceExpression, "The templated method (" + member.Member.FullName + ") cannot be used like reference");
                        }
                    }
                    else
                    {
                        new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline).Emit();
                    }
                }
            }
            else
            {
                if (member != null && member.IsCompileTimeConstant && member.Member.DeclaringType.Kind == TypeKind.Enum)
                {
                    var typeDef = member.Member.DeclaringType as DefaultResolvedTypeDefinition;

                    if (typeDef != null)
                    {
                        var enumMode = this.Emitter.Validator.EnumEmitMode(typeDef);

                        if ((this.Emitter.Validator.IsIgnoreType(typeDef) && enumMode == -1) || enumMode == 2)
                        {
                            this.WriteScript(member.ConstantValue);

                            return;
                        }

                        if (enumMode >= 3)
                        {
                            string enumStringName = member.Member.Name;
                            var    attr           = Helpers.GetInheritedAttribute(member.Member, Translator.Bridge_ASSEMBLY + ".NameAttribute");

                            if (attr != null)
                            {
                                enumStringName = this.Emitter.GetEntityName(member.Member);
                            }
                            else
                            {
                                switch (enumMode)
                                {
                                case 3:
                                    enumStringName = Object.Net.Utilities.StringUtils.ToLowerCamelCase(member.Member.Name);
                                    break;

                                case 4:
                                    break;

                                case 5:
                                    enumStringName = enumStringName.ToLowerInvariant();
                                    break;

                                case 6:
                                    enumStringName = enumStringName.ToUpperInvariant();
                                    break;
                                }
                            }

                            this.WriteScript(enumStringName);

                            return;
                        }
                    }
                }

                if (resolveResult is TypeResolveResult)
                {
                    TypeResolveResult typeResolveResult = (TypeResolveResult)resolveResult;
                    var isNative = this.Emitter.Validator.IsIgnoreType(typeResolveResult.Type.GetDefinition()) || typeResolveResult.Type.Kind == TypeKind.Enum;
                    if (isNative)
                    {
                        this.Write(BridgeTypes.ToJsName(typeResolveResult.Type, this.Emitter));
                    }
                    else
                    {
                        this.Write("Bridge.get(" + BridgeTypes.ToJsName(typeResolveResult.Type, this.Emitter) + ")");
                    }

                    return;
                }
                else if (member != null &&
                         member.Member is IMethod &&
                         !(member is InvocationResolveResult) &&
                         !(
                             memberReferenceExpression.Parent is InvocationExpression &&
                             memberReferenceExpression.NextSibling != null &&
                             memberReferenceExpression.NextSibling.Role is TokenRole &&
                             ((TokenRole)memberReferenceExpression.NextSibling.Role).Token == "("
                             )
                         )
                {
                    var  resolvedMethod = (IMethod)member.Member;
                    bool isStatic       = resolvedMethod != null && resolvedMethod.IsStatic;

                    var isExtensionMethod = resolvedMethod.IsExtensionMethod;

                    this.Emitter.IsAssignment    = false;
                    this.Emitter.IsUnaryAccessor = false;

                    if (!isStatic)
                    {
                        this.Write(Bridge.Translator.Emitter.ROOT + "." + (isExtensionMethod ? Bridge.Translator.Emitter.DELEGATE_BIND_SCOPE : Bridge.Translator.Emitter.DELEGATE_BIND) + "(");
                        memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                        this.Write(", ");
                    }

                    this.Emitter.IsAssignment    = oldIsAssignment;
                    this.Emitter.IsUnaryAccessor = oldUnary;

                    if (isExtensionMethod)
                    {
                        this.Write(BridgeTypes.ToJsName(resolvedMethod.DeclaringType, this.Emitter));
                    }
                    else
                    {
                        this.Emitter.IsAssignment    = false;
                        this.Emitter.IsUnaryAccessor = false;
                        if (isConstTarget)
                        {
                            this.Write("(");
                        }
                        memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                        if (isConstTarget)
                        {
                            this.Write(")");
                        }
                        this.Emitter.IsAssignment    = oldIsAssignment;
                        this.Emitter.IsUnaryAccessor = oldUnary;
                    }

                    this.WriteDot();

                    this.Write(OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName());

                    if (!isStatic)
                    {
                        this.Write(")");
                    }

                    return;
                }
                else
                {
                    bool isProperty = false;

                    if (member != null && member.Member.SymbolKind == SymbolKind.Property && member.TargetResult.Type.Kind != TypeKind.Anonymous && !this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition))
                    {
                        isProperty = true;
                        bool writeTargetVar = false;

                        if (this.Emitter.IsAssignment && this.Emitter.AssignmentType != AssignmentOperatorType.Assign)
                        {
                            writeTargetVar = true;
                        }
                        else if (this.Emitter.IsUnaryAccessor)
                        {
                            writeTargetVar = true;

                            isStatement = memberReferenceExpression.Parent is UnaryOperatorExpression && memberReferenceExpression.Parent.Parent is ExpressionStatement;

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

                            if (!isStatement)
                            {
                                this.WriteOpenParentheses();
                            }
                        }

                        if (writeTargetVar)
                        {
                            bool isField = memberTargetrr != null && memberTargetrr.Member is IField && (memberTargetrr.TargetResult is ThisResolveResult || memberTargetrr.TargetResult is LocalResolveResult);

                            if (!(targetrr is ThisResolveResult || targetrr is TypeResolveResult || targetrr is LocalResolveResult || isField))
                            {
                                targetVar = this.GetTempVarName();

                                this.Write(targetVar);
                                this.Write(" = ");
                            }
                        }
                    }

                    if (isProperty && this.Emitter.IsUnaryAccessor && !isStatement && targetVar == null)
                    {
                        valueVar = this.GetTempVarName();

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

                    this.Emitter.IsAssignment    = false;
                    this.Emitter.IsUnaryAccessor = false;
                    if (isConstTarget)
                    {
                        this.Write("(");
                    }
                    memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                    if (isConstTarget)
                    {
                        this.Write(")");
                    }
                    this.Emitter.IsAssignment    = oldIsAssignment;
                    this.Emitter.IsUnaryAccessor = oldUnary;

                    if (targetVar != null)
                    {
                        if (this.Emitter.IsUnaryAccessor && !isStatement)
                        {
                            this.WriteComma(false);

                            valueVar = this.GetTempVarName();

                            this.Write(valueVar);
                            this.Write(" = ");

                            this.Write(targetVar);
                        }
                        else
                        {
                            this.WriteSemiColon();
                            this.WriteNewLine();
                            this.Write(targetVar);
                        }
                    }
                }

                var targetResolveResult = targetrr as MemberResolveResult;

                if (targetResolveResult == null || this.Emitter.IsGlobalTarget(targetResolveResult.Member) == null)
                {
                    this.WriteDot();
                }

                if (member == null)
                {
                    if (targetrr != null && targetrr.Type.Kind == TypeKind.Dynamic)
                    {
                        this.Write(memberReferenceExpression.MemberName);
                    }
                    else
                    {
                        this.Write(memberReferenceExpression.MemberName.ToLowerCamelCase());
                    }
                }
                else if (!string.IsNullOrEmpty(inline))
                {
                    if (resolveResult is InvocationResolveResult || (member.Member.SymbolKind == SymbolKind.Property && this.Emitter.IsAssignment))
                    {
                        this.PushWriter(inline);
                    }
                    else
                    {
                        this.Write(inline);
                    }
                }
                else if (member.Member.SymbolKind == SymbolKind.Property && member.TargetResult.Type.Kind != TypeKind.Anonymous && !this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition))
                {
                    var proto = false;
                    if (this.MemberReferenceExpression.Target is BaseReferenceExpression && member != null)
                    {
                        var prop = member.Member as IProperty;

                        if (prop != null && (prop.IsVirtual || prop.IsOverride))
                        {
                            proto = true;
                        }
                    }

                    if (Helpers.IsFieldProperty(member.Member, this.Emitter))
                    {
                        this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter));
                    }
                    else if (!this.Emitter.IsAssignment)
                    {
                        if (this.Emitter.IsUnaryAccessor)
                        {
                            bool isNullable = NullableType.IsNullable(member.Member.ReturnType);
                            bool isDecimal  = Helpers.IsDecimalType(member.Member.ReturnType, this.Emitter.Resolver);

                            if (isStatement)
                            {
                                this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, true));
                                if (proto)
                                {
                                    this.Write(".call");
                                    this.WriteOpenParentheses();
                                    this.WriteThis();
                                    this.WriteComma();
                                }
                                else
                                {
                                    this.WriteOpenParentheses();
                                }

                                if (isDecimal)
                                {
                                    if (isNullable)
                                    {
                                        this.Write("Bridge.Nullable.lift1");
                                        this.WriteOpenParentheses();
                                        if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                        {
                                            this.WriteScript("inc");
                                        }
                                        else
                                        {
                                            this.WriteScript("dec");
                                        }

                                        this.WriteComma();

                                        if (targetVar != null)
                                        {
                                            this.Write(targetVar);
                                        }
                                        else
                                        {
                                            memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                                        }

                                        this.WriteDot();

                                        this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false));

                                        if (proto)
                                        {
                                            this.Write(".call");
                                            this.WriteOpenParentheses();
                                            this.WriteThis();
                                            this.WriteCloseParentheses();
                                        }
                                        else
                                        {
                                            this.WriteOpenParentheses();
                                            this.WriteCloseParentheses();
                                        }

                                        this.WriteCloseParentheses();
                                    }
                                    else
                                    {
                                        if (targetVar != null)
                                        {
                                            this.Write(targetVar);
                                        }
                                        else
                                        {
                                            memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                                        }

                                        this.WriteDot();

                                        this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false));

                                        if (proto)
                                        {
                                            this.Write(".call");
                                            this.WriteOpenParentheses();
                                            this.WriteThis();
                                            this.WriteCloseParentheses();
                                        }
                                        else
                                        {
                                            this.WriteOpenParentheses();
                                            this.WriteCloseParentheses();
                                        }

                                        this.WriteDot();

                                        if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                        {
                                            this.Write("inc");
                                        }
                                        else
                                        {
                                            this.Write("dec");
                                        }

                                        this.WriteOpenParentheses();
                                        this.WriteCloseParentheses();

                                        this.WriteCloseParentheses();
                                    }
                                }
                                else
                                {
                                    if (targetVar != null)
                                    {
                                        this.Write(targetVar);
                                    }
                                    else
                                    {
                                        if (isConstTarget)
                                        {
                                            this.Write("(");
                                        }
                                        memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                                        if (isConstTarget)
                                        {
                                            this.Write(")");
                                        }
                                    }

                                    this.WriteDot();

                                    this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false));

                                    if (proto)
                                    {
                                        this.Write(".call");
                                        this.WriteOpenParentheses();
                                        this.WriteThis();
                                        this.WriteCloseParentheses();
                                    }
                                    else
                                    {
                                        this.WriteOpenParentheses();
                                        this.WriteCloseParentheses();
                                    }

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

                                    this.Write("1");
                                    this.WriteCloseParentheses();
                                }
                            }
                            else
                            {
                                this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false));
                                if (proto)
                                {
                                    this.Write(".call");
                                    this.WriteOpenParentheses();
                                    this.WriteThis();
                                    this.WriteCloseParentheses();
                                }
                                else
                                {
                                    this.WriteOpenParentheses();
                                    this.WriteCloseParentheses();
                                }
                                this.WriteComma();

                                if (targetVar != null)
                                {
                                    this.Write(targetVar);
                                }
                                else
                                {
                                    if (isConstTarget)
                                    {
                                        this.Write("(");
                                    }
                                    memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                                    if (isConstTarget)
                                    {
                                        this.Write(")");
                                    }
                                }

                                this.WriteDot();
                                this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, true));

                                if (proto)
                                {
                                    this.Write(".call");
                                    this.WriteOpenParentheses();
                                    this.WriteThis();
                                    this.WriteComma();
                                }
                                else
                                {
                                    this.WriteOpenParentheses();
                                }

                                if (isDecimal)
                                {
                                    if (isNullable)
                                    {
                                        this.Write("Bridge.Nullable.lift1");
                                        this.WriteOpenParentheses();
                                        if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                        {
                                            this.WriteScript("inc");
                                        }
                                        else
                                        {
                                            this.WriteScript("dec");
                                        }
                                        this.WriteComma();
                                        this.Write(valueVar);
                                        this.WriteCloseParentheses();
                                    }
                                    else
                                    {
                                        this.Write(valueVar);
                                        this.WriteDot();
                                        if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                        {
                                            this.Write("inc");
                                        }
                                        else
                                        {
                                            this.Write("dec");
                                        }
                                        this.WriteOpenParentheses();
                                        this.WriteCloseParentheses();
                                    }
                                }
                                else
                                {
                                    this.Write(valueVar);

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

                                this.WriteCloseParentheses();
                                this.WriteComma();

                                bool isPreOp = this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment ||
                                               this.Emitter.UnaryOperatorType == UnaryOperatorType.Decrement;

                                if (isPreOp)
                                {
                                    if (targetVar != null)
                                    {
                                        this.Write(targetVar);
                                    }
                                    else
                                    {
                                        memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                                    }
                                    this.WriteDot();
                                    this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false));
                                    this.WriteOpenParentheses();
                                    this.WriteCloseParentheses();
                                }
                                else
                                {
                                    this.Write(valueVar);
                                }
                                this.WriteCloseParentheses();

                                if (valueVar != null)
                                {
                                    this.RemoveTempVar(valueVar);
                                }
                            }

                            if (targetVar != null)
                            {
                                this.RemoveTempVar(targetVar);
                            }
                        }
                        else
                        {
                            this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter));
                            if (proto)
                            {
                                this.Write(".call");
                                this.WriteOpenParentheses();
                                this.WriteThis();
                                this.WriteCloseParentheses();
                            }
                            else
                            {
                                //Only write "()" if the property is NOT on an external class
                                //And if the property has a body. When it has a body, we generate a javascript
                                //getter function and need to actually invoke the function

                                var declaringTypeDef = member.Member.DeclaringTypeDefinition;
                                if (declaringTypeDef != null && !Emitter.Validator.IsIgnoreType(declaringTypeDef))
                                {
                                    IProperty prop = null;
                                    if (declaringTypeDef.Properties != null)
                                    {
                                        prop =
                                            declaringTypeDef.Properties.FirstOrDefault(p => p.FullName == member.Member.FullName);
                                    }
                                    if (prop != null && !prop.Equals(default(IProperty)) && prop.Getter != null &&
                                        !prop.Getter.BodyRegion.IsEmpty)
                                    {
                                        this.WriteOpenParentheses();
                                        this.WriteCloseParentheses();
                                    }
                                }
                            }
                        }
                    }
                    else if (this.Emitter.AssignmentType != AssignmentOperatorType.Assign)
                    {
                        if (targetVar != null)
                        {
                            this.PushWriter(string.Concat(Helpers.GetPropertyRef(member.Member, this.Emitter, true),
                                                          proto ? ".call(this, " : "(",
                                                          targetVar,
                                                          ".",
                                                          Helpers.GetPropertyRef(member.Member, this.Emitter, false),
                                                          proto ? ".call(this)" : "()",
                                                          "{0})"), () =>
                            {
                                this.RemoveTempVar(targetVar);
                            });
                        }
                        else
                        {
                            var oldWriter = this.SaveWriter();
                            this.NewWriter();

                            this.Emitter.IsAssignment    = false;
                            this.Emitter.IsUnaryAccessor = false;
                            memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                            this.Emitter.IsAssignment    = oldIsAssignment;
                            this.Emitter.IsUnaryAccessor = oldUnary;
                            var trg = this.Emitter.Output.ToString();

                            this.RestoreWriter(oldWriter);
                            this.PushWriter(string.Concat(Helpers.GetPropertyRef(member.Member, this.Emitter, true),
                                                          proto ? ".call(this, " : "(",
                                                          trg,
                                                          ".",
                                                          Helpers.GetPropertyRef(member.Member, this.Emitter, false),
                                                          proto ? ".call(this)" : "()",
                                                          "{0})"));
                        }
                    }
                    else
                    {
                        if (proto)
                        {
                            this.PushWriter(Helpers.GetPropertyRef(member.Member, this.Emitter, true) + ".call(this, {0})");
                        }
                        else
                        {
                            //Property setter
                            //If a property has a body, call the property like a function .Interaction(2);
                            //If no body, then .Interaction = 2;

                            var       declaringTypeDef = member.Member.DeclaringTypeDefinition;
                            IProperty prop             = null;
                            if (declaringTypeDef != null && declaringTypeDef.Properties != null)
                            {
                                prop = declaringTypeDef.Properties.FirstOrDefault(p => p.FullName == member.Member.FullName);
                            }
                            var propRef = Helpers.GetPropertyRef(member.Member, this.Emitter, true);

                            if (prop != null && !prop.Equals(default(IProperty)) && prop.Setter != null &&
                                !prop.Setter.BodyRegion.IsEmpty)
                            {
                                this.PushWriter(propRef + "({0})");
                            }
                            else
                            {
                                this.PushWriter(propRef + " = {0}");
                            }
                        }
                    }
                }
                else if (member.Member.SymbolKind == SymbolKind.Field)
                {
                    bool isConst = this.Emitter.IsMemberConst(member.Member);

                    if (isConst && this.Emitter.IsInlineConst(member.Member))
                    {
                        this.WriteScript(member.ConstantValue);
                    }
                    else
                    {
                        this.Write(OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName());
                    }
                }
                else if (resolveResult is InvocationResolveResult)
                {
                    InvocationResolveResult       invocationResult  = (InvocationResolveResult)resolveResult;
                    CSharpInvocationResolveResult cInvocationResult = (CSharpInvocationResolveResult)resolveResult;
                    var expresssionMember = expressionResolveResult as MemberResolveResult;

                    if (expresssionMember != null &&
                        cInvocationResult != null &&
                        cInvocationResult.IsDelegateInvocation &&
                        invocationResult.Member != expresssionMember.Member)
                    {
                        this.Write(OverloadsCollection.Create(this.Emitter, expresssionMember.Member).GetOverloadName());
                    }
                    else
                    {
                        this.Write(OverloadsCollection.Create(this.Emitter, invocationResult.Member).GetOverloadName());
                    }
                }
                else if (member.Member is DefaultResolvedEvent)
                {
                    if (this.Emitter.IsAssignment &&
                        (this.Emitter.AssignmentType == AssignmentOperatorType.Add ||
                         this.Emitter.AssignmentType == AssignmentOperatorType.Subtract))
                    {
                        this.Write(this.Emitter.AssignmentType == AssignmentOperatorType.Add ? "add_" : "remove_");
                        this.Write(
                            OverloadsCollection.Create(this.Emitter, member.Member,
                                                       this.Emitter.AssignmentType == AssignmentOperatorType.Subtract).GetOverloadName());
                        this.WriteOpenParentheses();
                    }
                    else
                    {
                        this.Write(this.Emitter.GetEntityName(member.Member, true));
                    }
                }
                else
                {
                    this.Write(this.Emitter.GetEntityName(member.Member));
                }

                Helpers.CheckValueTypeClone(resolveResult, memberReferenceExpression, this, pos);
            }
        }
Ejemplo n.º 11
0
        protected virtual void EmitBaseConstructor(ConstructorDeclaration ctor, string ctorName, bool isObjectLiteral)
        {
            var initializer = ctor.Initializer != null && !ctor.Initializer.IsNull ? ctor.Initializer : new ConstructorInitializer()
            {
                ConstructorInitializerType = ConstructorInitializerType.Base
            };

            bool appendScope         = false;
            bool isBaseObjectLiteral = false;

            if (initializer.ConstructorInitializerType == ConstructorInitializerType.Base)
            {
                var baseType = Emitter.GetBaseTypeDefinition();
                //var baseName = JS.Funcs.CONSTRUCTOR;
                string baseName = null;
                isBaseObjectLiteral = Emitter.Validator.IsObjectLiteral(baseType);

                if (ctor.Initializer != null && !ctor.Initializer.IsNull)
                {
                    var member    = ((InvocationResolveResult)Emitter.Resolver.ResolveNode(ctor.Initializer)).Member;
                    var overloads = OverloadsCollection.Create(Emitter, member);
                    if (overloads.HasOverloads)
                    {
                        baseName = overloads.GetOverloadName();
                    }
                }

                string name = null;

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

                if (!isObjectLiteral && isBaseObjectLiteral)
                {
                    Write(JS.Types.H5.COPY_PROPERTIES);
                    WriteOpenParentheses();

                    Write("this, ");
                }

                Write(name, ".");

                if (baseName == null)
                {
                    var baseIType = Emitter.H5Types.Get(baseType).Type;

                    var baseCtor = baseIType.GetConstructors().SingleOrDefault(c => c.Parameters.Count == 0);
                    if (baseCtor == null)
                    {
                        baseCtor = baseIType.GetConstructors().SingleOrDefault(c => c.Parameters.All(p => p.IsOptional));
                    }

                    if (baseCtor == null)
                    {
                        baseCtor = baseIType.GetConstructors().SingleOrDefault(c => c.Parameters.Count == 1 && c.Parameters.First().IsParams);
                    }

                    if (baseCtor != null)
                    {
                        baseName = OverloadsCollection.Create(Emitter, baseCtor).GetOverloadName();
                    }
                    else
                    {
                        baseName = JS.Funcs.CONSTRUCTOR;
                    }
                }

                Write(baseName);

                if (!isObjectLiteral)
                {
                    WriteCall();
                    appendScope = true;
                }
            }
            else
            {
                // this.WriteThis();
                string name = H5Types.ToJsName(TypeInfo.Type, Emitter);
                Write(name);
                WriteDot();

                var baseName  = JS.Funcs.CONSTRUCTOR;
                var member    = ((InvocationResolveResult)Emitter.Resolver.ResolveNode(ctor.Initializer)).Member;
                var overloads = OverloadsCollection.Create(Emitter, member);
                if (overloads.HasOverloads)
                {
                    baseName = overloads.GetOverloadName();
                }

                Write(baseName);

                if (!isObjectLiteral)
                {
                    WriteCall();
                    appendScope = true;
                }
            }
            int openPos = Emitter.Output.Length;

            WriteOpenParentheses();

            if (appendScope)
            {
                WriteThis();

                if (initializer.Arguments.Count > 0)
                {
                    WriteComma();
                }
            }

            if (initializer.Arguments.Count > 0)
            {
                var argsInfo        = new ArgumentsInfo(Emitter, ctor.Initializer);
                var argsExpressions = argsInfo.ArgumentsExpressions;
                var paramsArg       = argsInfo.ParamsExpression;

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

            if (!isObjectLiteral && isBaseObjectLiteral)
            {
                WriteCloseParentheses();
            }

            WriteCloseParentheses();
            WriteSemiColon();

            if (!isObjectLiteral)
            {
                WriteNewLine();
            }
        }
Ejemplo n.º 12
0
        private void HandleType(ResolveResult resolveOperator, string variable, string op_name, KnownTypeCode typeCode)
        {
            if (this.AssignmentExpression.Operator == AssignmentOperatorType.Assign)
            {
                if (variable != null)
                {
                    this.Write(variable);
                }
                else
                {
                    new ExpressionListBlock(this.Emitter, new Expression[] { this.AssignmentExpression.Right }, null, null, 0).Emit();
                }

                return;
            }

            var orr           = resolveOperator as OperatorResolveResult;
            var method        = orr != null ? orr.UserDefinedOperatorMethod : null;
            var assigmentType = Helpers.TypeOfAssignment(this.AssignmentExpression.Operator);

            if (orr != null && method == null)
            {
                var name = Helpers.GetBinaryOperatorMethodName(assigmentType);
                var type = NullableType.IsNullable(orr.Type) ? NullableType.GetUnderlyingType(orr.Type) : orr.Type;
                method = type.GetMethods(m => m.Name == name, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault();
            }

            if (method != null)
            {
                var inline = this.Emitter.GetInline(method);

                if (orr.IsLiftedOperator)
                {
                    this.Write(JS.Types.SYSTEM_NULLABLE + ".");
                    string action = JS.Funcs.Math.LIFT2;

                    this.Write(action);
                    this.WriteOpenParentheses();
                    this.WriteScript(op_name);
                    this.WriteComma();
                    if (variable != null)
                    {
                        new ExpressionListBlock(this.Emitter, new Expression[] { this.AssignmentExpression.Left }, null, null, 0).Emit();
                    }
                    else
                    {
                        new ExpressionListBlock(this.Emitter, new Expression[] { this.AssignmentExpression.Left, this.AssignmentExpression.Right }, null, null, 0).Emit();
                    }
                    this.AddOveflowFlag(typeCode, op_name);
                    this.WriteCloseParentheses();
                }
                else if (!string.IsNullOrWhiteSpace(inline))
                {
                    new InlineArgumentsBlock(this.Emitter,
                                             new ArgumentsInfo(this.Emitter, this.AssignmentExpression, orr, method), inline).Emit();
                }
                else if (!this.Emitter.Validator.IsExternalType(method.DeclaringTypeDefinition))
                {
                    this.Write(BridgeTypes.ToJsName(method.DeclaringType, this.Emitter));
                    this.WriteDot();

                    this.Write(OverloadsCollection.Create(this.Emitter, method).GetOverloadName());

                    this.WriteOpenParentheses();

                    if (variable != null)
                    {
                        new ExpressionListBlock(this.Emitter, new Expression[] { this.AssignmentExpression.Left }, null, null, 0).Emit();
                        this.Write(", " + variable);
                    }
                    else
                    {
                        new ExpressionListBlock(this.Emitter, new Expression[] { this.AssignmentExpression.Left, this.AssignmentExpression.Right }, null, null, 0).Emit();
                    }

                    this.WriteCloseParentheses();
                }
            }
            else
            {
                if (orr.IsLiftedOperator)
                {
                    this.Write(JS.Types.SYSTEM_NULLABLE + ".");
                    string action = JS.Funcs.Math.LIFT2;

                    this.Write(action);
                    this.WriteOpenParentheses();
                    this.WriteScript(op_name);
                    this.WriteComma();
                    if (variable != null)
                    {
                        new ExpressionListBlock(this.Emitter, new Expression[] { this.AssignmentExpression.Left }, null, null, 0).Emit();
                    }
                    else
                    {
                        new ExpressionListBlock(this.Emitter, new Expression[] { this.AssignmentExpression.Left, this.AssignmentExpression.Right }, null, null, 0).Emit();
                    }
                    this.AddOveflowFlag(typeCode, op_name);
                    this.WriteCloseParentheses();
                }
                else
                {
                    this.AssignmentExpression.Left.AcceptVisitor(this.Emitter);
                    this.WriteDot();
                    this.Write(op_name);
                    this.WriteOpenParentheses();
                    this.AssignmentExpression.Right.AcceptVisitor(this.Emitter);
                    this.AddOveflowFlag(typeCode, op_name);
                    this.WriteCloseParentheses();
                }
            }
        }
Ejemplo n.º 13
0
        protected void VisitAsyncForeachStatement()
        {
            ForeachStatement foreachStatement = this.ForeachStatement;

            if (foreachStatement.EmbeddedStatement is EmptyStatement)
            {
                return;
            }

            var oldValue       = this.Emitter.ReplaceAwaiterByVar;
            var jumpStatements = this.Emitter.JumpStatements;

            this.Emitter.JumpStatements = new List <IJumpInfo>();
            this.WriteAwaiters(foreachStatement.InExpression);

            bool containsAwaits = false;
            var  awaiters       = this.GetAwaiters(foreachStatement.EmbeddedStatement);

            if (awaiters != null && awaiters.Length > 0)
            {
                containsAwaits = true;
            }

            this.Emitter.ReplaceAwaiterByVar = true;

            if (!containsAwaits)
            {
                this.VisitForeachStatement(oldValue);
                return;
            }

            var iteratorName = this.AddLocal(this.GetTempVarName(), null, AstType.Null);

            var for_rr = (ForEachResolveResult)this.Emitter.Resolver.ResolveNode(foreachStatement, this.Emitter);
            var get_rr = for_rr.GetEnumeratorCall as InvocationResolveResult;
            var in_rr  = this.Emitter.Resolver.ResolveNode(foreachStatement.InExpression, this.Emitter);
            var inline = get_rr != null?this.Emitter.GetInline(get_rr.Member) : null;

            var checkEnum = in_rr.Type.Kind != TypeKind.Array && !in_rr.Type.IsKnownType(KnownTypeCode.String) &&
                            !in_rr.Type.IsKnownType(KnownTypeCode.Array);
            var isGenericEnumerable = for_rr.CollectionType.IsParameterized &&
                                      for_rr.CollectionType.FullName == "System.Collections.Generic.IEnumerable";
            var emitInline = checkEnum && !isGenericEnumerable && inline != null;

            this.Write(iteratorName, " = ");

            if (!emitInline)
            {
                this.Write(JS.Funcs.BRIDGE_GET_ENUMERATOR);
                this.WriteOpenParentheses();
                foreachStatement.InExpression.AcceptVisitor(this.Emitter);
            }

            if (checkEnum)
            {
                if (for_rr.CollectionType.IsParameterized &&
                    for_rr.CollectionType.FullName == "System.Collections.Generic.IEnumerable")
                {
                    this.WriteComma(false);
                    this.Write(BridgeTypes.ToJsName(((ParameterizedType)for_rr.CollectionType).TypeArguments[0], this.Emitter));
                }
                else if (get_rr != null)
                {
                    if (inline != null)
                    {
                        var argsInfo = new ArgumentsInfo(this.Emitter, foreachStatement.InExpression, get_rr);
                        new InlineArgumentsBlock(this.Emitter, argsInfo, inline).Emit();
                    }
                    else
                    {
                        var name = OverloadsCollection.Create(this.Emitter, get_rr.Member).GetOverloadName();

                        if (name != "getEnumerator" && name != "System$Collections$IEnumerable$getEnumerator")
                        {
                            this.WriteComma(false);
                            this.WriteScript(name);
                        }
                    }
                }
            }

            this.Emitter.ReplaceAwaiterByVar = oldValue;
            if (!emitInline)
            {
                this.WriteCloseParentheses();
            }
            this.WriteSemiColon();
            this.WriteNewLine();
            this.Write(JS.Vars.ASYNC_STEP + " = " + this.Emitter.AsyncBlock.Step + ";");
            this.WriteNewLine();
            this.Write("continue;");
            this.WriteNewLine();

            IAsyncStep conditionStep = this.Emitter.AsyncBlock.AddAsyncStep();

            this.WriteIf();
            this.WriteOpenParentheses();
            this.Write(iteratorName);
            this.WriteDot();
            this.Write(JS.Funcs.MOVE_NEXT);
            this.WriteOpenCloseParentheses();
            this.WriteCloseParentheses();
            this.WriteSpace();
            this.BeginBlock();

            this.PushLocals();

            var varName = this.AddLocal(foreachStatement.VariableName, foreachStatement.VariableNameToken, foreachStatement.VariableType);

            this.WriteVar();
            this.Write(varName + " = ");

            var    rr       = this.Emitter.Resolver.ResolveNode(foreachStatement, this.Emitter) as ForEachResolveResult;
            string castCode = this.GetCastCode(rr.ElementType, rr.ElementVariable.Type);

            if (castCode != null)
            {
                this.EmitInlineCast(iteratorName + "." + JS.Funcs.GET_CURRENT, castCode);
            }
            else if (this.CastMethod != null)
            {
                this.Write(BridgeTypes.ToJsName(this.CastMethod.DeclaringType, this.Emitter));
                this.WriteDot();
                this.Write(OverloadsCollection.Create(this.Emitter, this.CastMethod).GetOverloadName());
                this.WriteOpenParentheses();
                var pos = this.Emitter.Output.Length;
                this.Write(iteratorName + "." + JS.Funcs.GET_CURRENT);
                Helpers.CheckValueTypeClone(rr, this.ForeachStatement.InExpression, this, pos);
                this.WriteCloseParentheses();
            }
            else
            {
                var needCast = !rr.ElementType.Equals(rr.ElementVariable.Type);
                if (needCast)
                {
                    this.Write(JS.Funcs.BRIDGE_CAST);
                    this.WriteOpenParentheses();
                }

                var pos = this.Emitter.Output.Length;
                this.Write(iteratorName);

                this.WriteDot();
                this.Write(JS.Funcs.GET_CURRENT);
                Helpers.CheckValueTypeClone(rr, this.ForeachStatement.InExpression, this, pos);

                if (needCast)
                {
                    this.Write(", ", BridgeTypes.ToJsName(rr.ElementVariable.Type, this.Emitter), ")");
                }
            }

            this.WriteSemiColon();
            this.WriteNewLine();

            this.Write(JS.Vars.ASYNC_STEP + " = " + this.Emitter.AsyncBlock.Step + ";");
            this.WriteNewLine();
            this.Write("continue;");

            BlockStatement block = foreachStatement.EmbeddedStatement as BlockStatement;

            var writer = this.SaveWriter();

            this.Emitter.AsyncBlock.AddAsyncStep();
            this.Emitter.IgnoreBlock = foreachStatement.EmbeddedStatement;
            var startCount = this.Emitter.AsyncBlock.Steps.Count;

            if (block != null)
            {
                block.AcceptChildren(this.Emitter);
            }
            else
            {
                foreachStatement.EmbeddedStatement.AcceptVisitor(this.Emitter);
            }

            IAsyncStep loopStep = null;

            if (this.Emitter.AsyncBlock.Steps.Count > startCount)
            {
                loopStep            = this.Emitter.AsyncBlock.Steps.Last();
                loopStep.JumpToStep = conditionStep.Step;
            }

            this.RestoreWriter(writer);

            if (!AbstractEmitterBlock.IsJumpStatementLast(this.Emitter.Output.ToString()))
            {
                this.Write(JS.Vars.ASYNC_STEP + " = " + conditionStep.Step + ";");
                this.WriteNewLine();
                this.Write("continue;");
                this.WriteNewLine();
            }

            this.PopLocals();

            this.WriteNewLine();
            this.EndBlock();
            this.WriteNewLine();

            var nextStep = this.Emitter.AsyncBlock.AddAsyncStep();

            conditionStep.JumpToStep = nextStep.Step;

            if (this.Emitter.JumpStatements.Count > 0)
            {
                this.Emitter.JumpStatements.Sort((j1, j2) => - j1.Position.CompareTo(j2.Position));
                foreach (var jump in this.Emitter.JumpStatements)
                {
                    jump.Output.Insert(jump.Position, jump.Break ? nextStep.Step : conditionStep.Step);
                }
            }

            this.Emitter.JumpStatements = jumpStatements;
        }
Ejemplo n.º 14
0
        protected void VisitForeachStatement(bool?replaceAwaiterByVar = null)
        {
            ForeachStatement foreachStatement = this.ForeachStatement;
            var jumpStatements = this.Emitter.JumpStatements;

            this.Emitter.JumpStatements = null;

            if (foreachStatement.EmbeddedStatement is EmptyStatement)
            {
                return;
            }

            var iteratorVar  = this.GetTempVarName();
            var iteratorName = this.AddLocal(iteratorVar, null, AstType.Null);

            var rr     = (ForEachResolveResult)this.Emitter.Resolver.ResolveNode(foreachStatement, this.Emitter);
            var get_rr = rr.GetEnumeratorCall as InvocationResolveResult;
            var in_rr  = this.Emitter.Resolver.ResolveNode(foreachStatement.InExpression, this.Emitter);
            var inline = get_rr != null?this.Emitter.GetInline(get_rr.Member) : null;

            var checkEnum = in_rr.Type.Kind != TypeKind.Array && !in_rr.Type.IsKnownType(KnownTypeCode.String) &&
                            !in_rr.Type.IsKnownType(KnownTypeCode.Array);
            var isGenericEnumerable = rr.CollectionType.IsParameterized &&
                                      rr.CollectionType.FullName == "System.Collections.Generic.IEnumerable";
            var emitInline = checkEnum && !isGenericEnumerable && inline != null;

            this.Write(iteratorName, " = ");

            if (!emitInline)
            {
                this.Write(JS.Funcs.BRIDGE_GET_ENUMERATOR);
                this.WriteOpenParentheses();
                foreachStatement.InExpression.AcceptVisitor(this.Emitter);
            }

            if (checkEnum)
            {
                if (isGenericEnumerable)
                {
                    this.WriteComma(false);
                    this.Write(BridgeTypes.ToJsName(((ParameterizedType)rr.CollectionType).TypeArguments[0], this.Emitter));
                }
                else if (get_rr != null)
                {
                    if (inline != null)
                    {
                        var argsInfo = new ArgumentsInfo(this.Emitter, foreachStatement.InExpression, get_rr);
                        new InlineArgumentsBlock(this.Emitter, argsInfo, inline).Emit();
                    }
                    else
                    {
                        var name = OverloadsCollection.Create(this.Emitter, get_rr.Member).GetOverloadName();

                        if (name != "getEnumerator" && name != "System$Collections$IEnumerable$getEnumerator")
                        {
                            this.WriteComma(false);
                            this.WriteScript(name);
                        }
                    }
                }
            }

            if (!emitInline)
            {
                this.WriteCloseParentheses();
            }
            this.WriteSemiColon();
            this.WriteNewLine();

            this.WriteTry();
            this.BeginBlock();
            this.WriteWhile();
            this.WriteOpenParentheses();
            this.Write(iteratorName);
            this.WriteDot();
            this.Write(JS.Funcs.MOVE_NEXT);
            this.WriteOpenCloseParentheses();
            this.WriteCloseParentheses();
            this.WriteSpace();
            this.BeginBlock();

            this.PushLocals();
            Action ac = () =>
            {
                var varName = this.AddLocal(foreachStatement.VariableName, foreachStatement.VariableNameToken, foreachStatement.VariableType);

                this.WriteVar();
                this.Write(varName + " = ");

                string castCode = this.GetCastCode(rr.ElementType, rr.ElementVariable.Type);

                if (castCode != null)
                {
                    this.EmitInlineCast(iteratorName + "." + JS.Funcs.GET_CURRENT, castCode);
                }
                else if (this.CastMethod != null)
                {
                    this.Write(BridgeTypes.ToJsName(this.CastMethod.DeclaringType, this.Emitter));
                    this.WriteDot();
                    this.Write(OverloadsCollection.Create(this.Emitter, this.CastMethod).GetOverloadName());
                    this.WriteOpenParentheses();
                    int pos = this.Emitter.Output.Length;
                    this.Write(iteratorName + "." + JS.Funcs.GET_CURRENT);
                    Helpers.CheckValueTypeClone(rr, this.ForeachStatement.InExpression, this, pos);
                    this.WriteCloseParentheses();
                }
                else
                {
                    var needCast = !rr.ElementType.Equals(rr.ElementVariable.Type);
                    if (needCast)
                    {
                        this.Write(JS.Funcs.BRIDGE_CAST);
                        this.WriteOpenParentheses();
                    }
                    int pos = this.Emitter.Output.Length;
                    this.Write(iteratorName);

                    this.WriteDot();
                    this.Write(JS.Funcs.GET_CURRENT);

                    Helpers.CheckValueTypeClone(rr, this.ForeachStatement.InExpression, this, pos);

                    if (needCast)
                    {
                        this.Write(", ", BridgeTypes.ToJsName(rr.ElementVariable.Type, this.Emitter), ")");
                    }
                }

                this.WriteSemiColon();
                this.WriteNewLine();
            };

            this.Emitter.BeforeBlock = ac;

            BlockStatement block = foreachStatement.EmbeddedStatement as BlockStatement;

            if (replaceAwaiterByVar.HasValue)
            {
                this.Emitter.ReplaceAwaiterByVar = replaceAwaiterByVar.Value;
            }

            if (block != null)
            {
                this.Emitter.NoBraceBlock = block;
            }

            foreachStatement.EmbeddedStatement.AcceptVisitor(this.Emitter);

            this.PopLocals();

            if (!this.Emitter.IsNewLine)
            {
                this.WriteNewLine();
            }

            this.EndBlock();
            this.WriteNewLine();

            this.EndBlock();
            this.WriteFinally();
            this.BeginBlock();
            this.Write($"if ({JS.Types.Bridge.IS}({iteratorName}, {JS.Types.System.IDisposable.NAME})) ");
            this.BeginBlock();
            this.Write($"{iteratorName}.{JS.Types.System.IDisposable.INTERFACE_DISPOSE}();");
            this.WriteNewLine();
            this.EndBlock();
            this.WriteNewLine();
            this.EndBlock();
            this.Emitter.JumpStatements = jumpStatements;
        }
Ejemplo n.º 15
0
        protected virtual void WriteObjectInitializer(IEnumerable <Expression> expressions, bool preserveMemberCase, TypeDefinition type, InvocationResolveResult rr)
        {
            bool          needComma = false;
            List <string> names     = new List <string>();

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

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

                    var itemrr = this.Emitter.Resolver.ResolveNode(item, this.Emitter) as MemberResolveResult;
                    if (itemrr != null)
                    {
                        var oc = OverloadsCollection.Create(this.Emitter, itemrr.Member);
                        name = oc.GetOverloadName();
                    }

                    if (needComma)
                    {
                        this.WriteComma();
                    }

                    needComma = true;

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

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

                    names.Add(name);
                }
            }

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

                if (tinfo == null)
                {
                    return;
                }
                var itype = tinfo.Type as ITypeDefinition;

                var mode = 0;
                if (rr != null)
                {
                    if (rr.Member.Parameters.Count == 1 &&
                        rr.Member.Parameters.First().Type.FullName == "Bridge.DefaultValueMode")
                    {
                        var arg = rr.Arguments.FirstOrDefault();
                        if (arg != null && arg.ConstantValue != null)
                        {
                            mode = (int)arg.ConstantValue;
                        }
                    }
                    else if (itype != null)
                    {
                        var attr = this.Emitter.Validator.GetAttribute(itype.Attributes, Translator.Bridge_ASSEMBLY + ".ObjectLiteralAttribute");
                        if (attr.PositionalArguments.Count > 0)
                        {
                            var value = attr.PositionalArguments.First().ConstantValue;

                            if (value != null && 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(this.Emitter);

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

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

                            if (needComma)
                            {
                                this.WriteComma();
                            }

                            needComma = true;

                            this.Write(name, ": ");

                            var primitiveExpr = member.Initializer as PrimitiveExpression;

                            if (primitiveExpr != null && primitiveExpr.Value is AstType)
                            {
                                this.Write(Inspector.GetStructDefaultValue((AstType)primitiveExpr.Value, this.Emitter));
                            }
                            else
                            {
                                member.Initializer.AcceptVisitor(this.Emitter);
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 16
0
        protected virtual void EmitCtorForInstantiableClass()
        {
            var baseType        = this.Emitter.GetBaseTypeDefinition();
            var typeDef         = this.Emitter.GetTypeDefinition();
            var isObjectLiteral = this.Emitter.Validator.IsObjectLiteral(typeDef);
            var isPlainMode     = this.Emitter.Validator.GetObjectCreateMode(typeDef) == 0;

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

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

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

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

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

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

                var ctorName = JS.Funcs.CONSTRUCTOR;

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

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

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

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

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

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

                this.ConvertParamsToReferences(ctor.Parameters);

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

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

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

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

                    this.WriteNewLine();

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

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

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

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

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

                        var properties = this.TypeInfo.InstanceProperties;

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

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

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

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

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

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

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

                        ctor.Body.AcceptChildren(this.Emitter);

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

                    this.WriteLines(script);
                }

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

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

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

            if (this.ctorHeader)
            {
                this.WriteNewLine();
                this.EndBlock();
            }
        }
Ejemplo n.º 17
0
        protected void VisitObjectCreateExpression()
        {
            ObjectCreateExpression objectCreateExpression = this.ObjectCreateExpression;
            int pos = this.Emitter.Output.Length;

            var  resolveResult = this.Emitter.Resolver.ResolveNode(objectCreateExpression.Type, this.Emitter) as TypeResolveResult;
            bool isTypeParam   = resolveResult.Type.Kind == TypeKind.TypeParameter;
            var  type          = isTypeParam ? null : this.Emitter.GetTypeDefinition(objectCreateExpression.Type);

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

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

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

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

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

            var    invocationResolveResult = this.Emitter.Resolver.ResolveNode(objectCreateExpression, this.Emitter) as InvocationResolveResult;
            string inlineCode = null;

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

            var customCtor     = isTypeParam ? "" : (this.Emitter.Validator.GetCustomConstructor(type) ?? "");
            var hasInitializer = !objectCreateExpression.Initializer.IsNull && objectCreateExpression.Initializer.Elements.Count > 0;

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

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

            if (inlineCode == null && Regex.Match(customCtor, @"\s*\{\s*\}\s*").Success)
            {
                this.WriteOpenBrace();
                this.WriteSpace();

                if (hasInitializer)
                {
                    this.WriteObjectInitializer(objectCreateExpression.Initializer.Elements, this.Emitter.AssemblyInfo.PreserveMemberCase, type, invocationResolveResult);
                    this.WriteSpace();
                }
                else if (this.Emitter.Validator.IsObjectLiteral(type))
                {
                    this.WriteObjectInitializer(null, this.Emitter.AssemblyInfo.PreserveMemberCase, type, invocationResolveResult);
                    this.WriteSpace();
                }

                this.WriteCloseBrace();
            }
            else
            {
                if (hasInitializer)
                {
                    this.Write(Bridge.Translator.Emitter.ROOT);
                    this.WriteDot();
                    this.Write(Bridge.Translator.Emitter.MERGE_OBJECT);
                    this.WriteOpenParentheses();
                }

                if (inlineCode != null)
                {
                    new InlineArgumentsBlock(this.Emitter, argsInfo, inlineCode).Emit();
                }
                else
                {
                    if (String.IsNullOrEmpty(customCtor))
                    {
                        this.WriteNew();
                        objectCreateExpression.Type.AcceptVisitor(this.Emitter);
                    }
                    else
                    {
                        this.Write(customCtor);
                    }

                    this.WriteOpenParentheses();

                    if (!isTypeParam && !this.Emitter.Validator.IsIgnoreType(type) && type.Methods.Count(m => m.IsConstructor && !m.IsStatic) > (type.IsValueType ? 0 : 1))
                    {
                        this.WriteScript(OverloadsCollection.Create(this.Emitter, ((InvocationResolveResult)this.Emitter.Resolver.ResolveNode(objectCreateExpression, this.Emitter)).Member).GetOverloadName());

                        if (argsExpressions.Length > 0)
                        {
                            this.WriteComma();
                        }
                    }

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

                if (hasInitializer)
                {
                    this.WriteComma();

                    bool needComma = false;

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

                    foreach (Expression item in elements)
                    {
                        if (needComma)
                        {
                            this.WriteComma(true);
                        }

                        needComma = true;

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

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

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

                    this.WriteNewLine();

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

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

            //Helpers.CheckValueTypeClone(invocationResolveResult, this.ObjectCreateExpression, this, pos);
        }
Ejemplo n.º 18
0
        protected virtual void EmitBaseConstructor(ConstructorDeclaration ctor, string ctorName, bool isObjectLiteral)
        {
            var initializer = ctor.Initializer != null && !ctor.Initializer.IsNull ? ctor.Initializer : new ConstructorInitializer()
            {
                ConstructorInitializerType = ConstructorInitializerType.Base
            };

            bool appendScope = false;

            if (initializer.ConstructorInitializerType == ConstructorInitializerType.Base)
            {
                var baseType = this.Emitter.GetBaseTypeDefinition();
                var baseName = JS.Funcs.CONSTRUCTOR;
                if (ctor.Initializer != null && !ctor.Initializer.IsNull)
                {
                    var member    = ((InvocationResolveResult)this.Emitter.Resolver.ResolveNode(ctor.Initializer, this.Emitter)).Member;
                    var overloads = OverloadsCollection.Create(this.Emitter, member);
                    if (overloads.HasOverloads)
                    {
                        baseName = overloads.GetOverloadName();
                    }
                }

                string name = null;

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

                this.Write(name, ".");
                this.Write(baseName);

                if (!isObjectLiteral)
                {
                    this.WriteCall();
                    appendScope = true;
                }
            }
            else
            {
                // this.WriteThis();
                string name = BridgeTypes.ToJsName(this.TypeInfo.Type, this.Emitter);
                this.Write(name);
                this.WriteDot();

                var baseName  = JS.Funcs.CONSTRUCTOR;
                var member    = ((InvocationResolveResult)this.Emitter.Resolver.ResolveNode(ctor.Initializer, this.Emitter)).Member;
                var overloads = OverloadsCollection.Create(this.Emitter, member);
                if (overloads.HasOverloads)
                {
                    baseName = overloads.GetOverloadName();
                }

                this.Write(baseName);

                if (!isObjectLiteral)
                {
                    this.WriteCall();
                    appendScope = true;
                }
            }
            int openPos = this.Emitter.Output.Length;

            this.WriteOpenParentheses();

            if (appendScope)
            {
                this.WriteThis();

                if (initializer.Arguments.Count > 0)
                {
                    this.WriteComma();
                }
            }

            if (initializer.Arguments.Count > 0)
            {
                var argsInfo        = new ArgumentsInfo(this.Emitter, ctor.Initializer);
                var argsExpressions = argsInfo.ArgumentsExpressions;
                var paramsArg       = argsInfo.ParamsExpression;

                new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg, ctor.Initializer, openPos).Emit();
            }

            this.WriteCloseParentheses();
            this.WriteSemiColon();

            if (!isObjectLiteral)
            {
                this.WriteNewLine();
            }
        }
Ejemplo n.º 19
0
        protected bool ResolveOperator(AssignmentExpression assignmentExpression, OperatorResolveResult orr, int initCount)
        {
            var method = orr != null ? orr.UserDefinedOperatorMethod : null;

            if (method != null)
            {
                var inline = this.Emitter.GetInline(method);

                if (!string.IsNullOrWhiteSpace(inline))
                {
                    if (this.Emitter.Writers.Count == initCount)
                    {
                        this.Write("= ");
                    }

                    new InlineArgumentsBlock(this.Emitter,
                                             new ArgumentsInfo(this.Emitter, assignmentExpression, orr, method), inline).Emit();

                    if (this.Emitter.Writers.Count > initCount)
                    {
                        this.PopWriter();
                    }
                    return(true);
                }
                else if (!this.Emitter.Validator.IsIgnoreType(method.DeclaringTypeDefinition))
                {
                    if (this.Emitter.Writers.Count == initCount)
                    {
                        this.Write("= ");
                    }

                    if (orr.IsLiftedOperator)
                    {
                        this.Write(Bridge.Translator.Emitter.ROOT + ".Nullable.lift(");
                    }

                    this.Write(BridgeTypes.ToJsName(method.DeclaringType, this.Emitter));
                    this.WriteDot();

                    this.Write(OverloadsCollection.Create(this.Emitter, method).GetOverloadName());

                    if (orr.IsLiftedOperator)
                    {
                        this.WriteComma();
                    }
                    else
                    {
                        this.WriteOpenParentheses();
                    }

                    new ExpressionListBlock(this.Emitter,
                                            new Expression[] { assignmentExpression.Left, assignmentExpression.Right }, null).Emit();
                    this.WriteCloseParentheses();

                    if (this.Emitter.Writers.Count > initCount)
                    {
                        this.PopWriter();
                    }
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 20
0
        protected virtual void EmitCtorForInstantiableClass()
        {
            this.EmitInitMembers();

            if (!this.TypeInfo.HasInstantiable || this.Emitter.Plugins.HasConstructorInjectors(this))
            {
                return;
            }

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

            if (typeDef.IsValueType)
            {
                this.TypeInfo.Ctors.Add(new ConstructorDeclaration
                {
                    Modifiers = Modifiers.Public,
                    Body      = new BlockStatement()
                });
            }

            foreach (var ctor in this.TypeInfo.Ctors)
            {
                bool skip = false;
                foreach (var attrSection in ctor.Attributes)
                {
                    foreach (var attr in attrSection.Attributes)
                    {
                        var rr = this.Emitter.Resolver.ResolveNode(attr.Type, this.Emitter);
                        if (rr.Type.FullName == "Bridge.ExternalAttribute" || rr.Type.FullName == "Bridge.IgnoreAttribute")
                        {
                            skip = true;
                        }
                    }
                }

                if (skip)
                {
                    continue;
                }

                this.EnsureComma();
                this.ResetLocals();
                var prevMap      = this.BuildLocalsMap();
                var prevNamesMap = this.BuildLocalsNamesMap();
                this.AddLocals(ctor.Parameters, ctor.Body);

                var ctorName = "constructor";

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

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

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

                this.EmitMethodParameters(ctor.Parameters, ctor);

                this.WriteSpace();
                this.BeginBlock();

                var requireNewLine = false;

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

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

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

                        this.ConvertParamsToReferences(ctor.Parameters);
                        ctor.Body.AcceptChildren(this.Emitter);

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

                    foreach (var line in script)
                    {
                        this.Write(line);
                        this.WriteNewLine();
                    }
                }

                this.EndBlock();
                this.Emitter.Comma = true;
                this.ClearLocalsMap(prevMap);
                this.ClearLocalsNamesMap(prevNamesMap);
            }
        }
Ejemplo n.º 21
0
        protected override void DoEmit()
        {
            IAttribute attribute = this.Attribute;

            var type = this.Emitter.GetTypeDefinition(attribute.AttributeType);

            var argsInfo = new ArgumentsInfo(this.Emitter, attribute);

            string inlineCode = this.Emitter.GetInline(attribute.Constructor);

            var customCtor     = this.Emitter.Validator.GetCustomConstructor(type) ?? "";
            var hasInitializer = attribute.NamedArguments.Count > 0;

            if (inlineCode == null && Regex.Match(customCtor, @"\s*\{\s*\}\s*").Success)
            {
                this.WriteOpenBrace();
                this.WriteSpace();

                if (hasInitializer)
                {
                    this.WriteObjectInitializer(attribute.NamedArguments, this.Emitter.AssemblyInfo.PreserveMemberCase, type, attribute);
                    this.WriteSpace();
                }
                else if (this.Emitter.Validator.IsObjectLiteral(type))
                {
                    this.WriteObjectInitializer(null, this.Emitter.AssemblyInfo.PreserveMemberCase, type, attribute);
                    this.WriteSpace();
                }

                this.WriteCloseBrace();
            }
            else
            {
                if (hasInitializer)
                {
                    this.Write(JS.Funcs.BRIDGE_MERGE);
                    this.WriteOpenParentheses();
                }

                if (inlineCode != null)
                {
                    new InlineArgumentsBlock(this.Emitter, argsInfo, inlineCode, attribute.Constructor).Emit();
                }
                else
                {
                    if (String.IsNullOrEmpty(customCtor))
                    {
                        this.WriteNew();
                        this.Write(BridgeTypes.ToJsName(attribute.AttributeType, this.Emitter));
                    }
                    else
                    {
                        this.Write(customCtor);
                    }

                    if (!this.Emitter.Validator.IsExternalType(type) && type.Methods.Count(m => m.IsConstructor && !m.IsStatic) > (type.IsValueType ? 0 : 1))
                    {
                        this.WriteDot();
                        var name = OverloadsCollection.Create(this.Emitter, attribute.Constructor).GetOverloadName();
                        this.Write(name);
                    }

                    this.WriteOpenParentheses();

                    this.WritePositionalList(attribute.PositionalArguments, attribute);
                    this.WriteCloseParentheses();
                }

                if (hasInitializer)
                {
                    this.WriteComma();

                    this.BeginBlock();

                    var inlineInit = this.WriteObjectInitializer(attribute.NamedArguments, this.Emitter.AssemblyInfo.PreserveMemberCase, type, attribute);

                    this.WriteNewLine();

                    this.EndBlock();

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

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

                        this.EndBlock();
                    }

                    this.WriteSpace();
                    this.WriteCloseParentheses();
                }
            }
        }
Ejemplo n.º 22
0
        protected virtual void EmitBaseConstructor(ConstructorDeclaration ctor, string ctorName)
        {
            var initializer = ctor.Initializer != null && !ctor.Initializer.IsNull ? ctor.Initializer : new ConstructorInitializer()
            {
                ConstructorInitializerType = ConstructorInitializerType.Base
            };

            bool appendScope = false;

            if (initializer.ConstructorInitializerType == ConstructorInitializerType.Base)
            {
                var baseType = this.Emitter.GetBaseTypeDefinition();
                var baseName = "constructor";
                if (ctor.Initializer != null && !ctor.Initializer.IsNull)
                {
                    var member    = ((InvocationResolveResult)this.Emitter.Resolver.ResolveNode(ctor.Initializer, this.Emitter)).Member;
                    var overloads = OverloadsCollection.Create(this.Emitter, member);
                    if (overloads.HasOverloads)
                    {
                        baseName = overloads.GetOverloadName();
                    }
                }

                if (baseName == "constructor")
                {
                    baseName = "$constructor";
                }

                string name = null;

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

                this.Write(name, ".prototype.");
                this.Write(baseName);
                this.Write(".call");
                appendScope = true;
            }
            else
            {
                // this.WriteThis();
                string name = BridgeTypes.ToJsName(this.TypeInfo.Type, this.Emitter);
                this.Write(name, ".prototype");
                this.WriteDot();

                var baseName  = "constructor";
                var member    = ((InvocationResolveResult)this.Emitter.Resolver.ResolveNode(ctor.Initializer, this.Emitter)).Member;
                var overloads = OverloadsCollection.Create(this.Emitter, member);
                if (overloads.HasOverloads)
                {
                    baseName = overloads.GetOverloadName();
                }

                if (baseName == "constructor")
                {
                    baseName = "$constructor";
                }

                this.Write(baseName);
                this.Write(".call");
                appendScope = true;
            }

            this.WriteOpenParentheses();

            if (appendScope)
            {
                this.WriteThis();

                if (initializer.Arguments.Count > 0)
                {
                    this.WriteComma();
                }
            }

            var args = new List <Expression>(initializer.Arguments);

            for (int i = 0; i < args.Count; i++)
            {
                args[i].AcceptVisitor(this.Emitter);
                if (i != (args.Count - 1))
                {
                    this.WriteComma();
                }
            }

            this.WriteCloseParentheses();
            this.WriteSemiColon();
            this.WriteNewLine();
        }
Ejemplo n.º 23
0
        protected void VisitMemberReferenceExpression()
        {
            MemberReferenceExpression memberReferenceExpression = this.MemberReferenceExpression;
            int  pos      = this.Emitter.Output.Length;
            bool isRefArg = this.Emitter.IsRefArg;

            this.Emitter.IsRefArg = false;

            ResolveResult resolveResult           = null;
            ResolveResult expressionResolveResult = null;
            string        targetVar     = null;
            string        valueVar      = null;
            bool          isStatement   = false;
            bool          isConstTarget = false;

            var targetrr = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Target, this.Emitter);

            if (targetrr is ConstantResolveResult)
            {
                isConstTarget = true;
            }

            var memberTargetrr = targetrr as MemberResolveResult;

            if (memberTargetrr != null && memberTargetrr.Type.Kind == TypeKind.Enum && memberTargetrr.Member is DefaultResolvedField && Helpers.EnumEmitMode(memberTargetrr.Type) == 2)
            {
                isConstTarget = true;
            }

            if (memberReferenceExpression.Target is ParenthesizedExpression ||
                (targetrr is ConstantResolveResult && targetrr.Type.IsKnownType(KnownTypeCode.Int64)) ||
                (targetrr is ConstantResolveResult && targetrr.Type.IsKnownType(KnownTypeCode.UInt64)) ||
                (targetrr is ConstantResolveResult && targetrr.Type.IsKnownType(KnownTypeCode.Decimal)))
            {
                isConstTarget = false;
            }

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

            if (isInvoke)
            {
                resolveResult           = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter);
                expressionResolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression, this.Emitter);

                if (expressionResolveResult is InvocationResolveResult)
                {
                    resolveResult = expressionResolveResult;
                }
                else if (expressionResolveResult is MemberResolveResult)
                {
                    if (((MemberResolveResult)expressionResolveResult).Member is IProperty)
                    {
                        resolveResult = expressionResolveResult;
                    }
                }
            }
            else
            {
                resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression, this.Emitter);
            }

            bool oldIsAssignment = this.Emitter.IsAssignment;
            bool oldUnary        = this.Emitter.IsUnaryAccessor;

            if (resolveResult == null)
            {
                this.Emitter.IsAssignment    = false;
                this.Emitter.IsUnaryAccessor = false;
                if (isConstTarget)
                {
                    this.Write("(");
                }
                memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                if (isConstTarget)
                {
                    this.Write(")");
                }
                this.Emitter.IsAssignment    = oldIsAssignment;
                this.Emitter.IsUnaryAccessor = oldUnary;
                this.WriteDot();
                string name = memberReferenceExpression.MemberName;
                this.Write(name.ToLowerCamelCase());

                return;
            }

            bool isDynamic = false;

            if (resolveResult is DynamicInvocationResolveResult)
            {
                var dynamicResolveResult = (DynamicInvocationResolveResult)resolveResult;
                var group = dynamicResolveResult.Target as MethodGroupResolveResult;

                if (group != null && group.Methods.Count() > 1)
                {
                    var 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 = this.Emitter.Resolver.Compilation.FindType(TypeCode.Object);
                            }

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

                        return(true);
                    }) ?? group.Methods.Last();

                    isDynamic     = true;
                    resolveResult = new MemberResolveResult(new TypeResolveResult(method.DeclaringType), method);
                    resolveResult = new InvocationResolveResult(resolveResult, method, dynamicResolveResult.Arguments);
                }
            }

            if (resolveResult is MethodGroupResolveResult)
            {
                var oldResult = (MethodGroupResolveResult)resolveResult;
                resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter);

                if (resolveResult is DynamicInvocationResolveResult)
                {
                    var method = oldResult.Methods.Last();
                    resolveResult = new MemberResolveResult(new TypeResolveResult(method.DeclaringType), method);
                }
            }

            MemberResolveResult member = resolveResult as MemberResolveResult;
            var globalTarget           = member != null?this.Emitter.IsGlobalTarget(member.Member) : null;

            if (member != null &&
                member.Member.Attributes.Any(a => a.AttributeType.FullName == "Bridge.NonScriptableAttribute"))
            {
                throw new EmitterException(this.MemberReferenceExpression, "Member " + member.ToString() + " is marked as not usable from script");
            }

            if (!(resolveResult is InvocationResolveResult) && member != null && member.Member is IMethod)
            {
                var interceptor = this.Emitter.Plugins.OnReference(this, this.MemberReferenceExpression, member);

                if (interceptor.Cancel)
                {
                    return;
                }

                if (!string.IsNullOrEmpty(interceptor.Replacement))
                {
                    this.Write(interceptor.Replacement);
                    return;
                }
            }

            if (globalTarget != null && globalTarget.Item1)
            {
                var target = globalTarget.Item2;

                if (!string.IsNullOrWhiteSpace(target))
                {
                    bool assign           = false;
                    var  memberExpression = member.Member is IMethod ? memberReferenceExpression.Parent.Parent : memberReferenceExpression.Parent;
                    var  targetExpression = member.Member is IMethod ? memberReferenceExpression.Parent : memberReferenceExpression;
                    var  assignment       = memberExpression as AssignmentExpression;
                    if (assignment != null && assignment.Right == targetExpression)
                    {
                        assign = true;
                    }
                    else
                    {
                        var varInit = memberExpression as VariableInitializer;
                        if (varInit != null && varInit.Initializer == targetExpression)
                        {
                            assign = true;
                        }
                        else if (memberExpression is InvocationExpression)
                        {
                            var targetInvocation = (InvocationExpression)memberExpression;
                            if (targetInvocation.Arguments.Any(a => a == targetExpression))
                            {
                                assign = true;
                            }
                        }
                    }

                    if (assign)
                    {
                        if (resolveResult is InvocationResolveResult)
                        {
                            this.PushWriter(target);
                        }
                        else
                        {
                            this.Write(target);
                        }

                        return;
                    }
                }

                if (resolveResult is InvocationResolveResult)
                {
                    this.PushWriter("");
                }

                return;
            }

            Tuple <bool, bool, string> inlineInfo = member != null ? (isDynamic ? ((Emitter)this.Emitter).GetInlineCodeFromMember(member.Member, null) : this.Emitter.GetInlineCode(memberReferenceExpression)) : null;
            //string inline = member != null ? this.Emitter.GetInline(member.Member) : null;
            string inline = inlineInfo != null ? inlineInfo.Item3 : null;

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

            if (member != null && member.Member is IMethod && isInvoke)
            {
                var i_rr = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter) as CSharpInvocationResolveResult;

                if (i_rr != null && !i_rr.IsExpandedForm)
                {
                    var tpl = this.Emitter.GetAttribute(member.Member.Attributes, JS.NS.BRIDGE + ".TemplateAttribute");

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

            bool hasInline = !string.IsNullOrEmpty(inline);
            bool hasThis   = hasInline && Helpers.HasThis(inline);

            inline = hasInline ? Helpers.ConvertTokens(this.Emitter, inline, member.Member) : inline;
            bool isInterfaceMember = false;

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

            bool nativeImplementation = true;
            bool isInterface          = inline == null && member != null && member.Member.DeclaringTypeDefinition != null && member.Member.DeclaringTypeDefinition.Kind == TypeKind.Interface;
            var  hasTypeParemeter     = isInterface && Helpers.IsTypeParameterType(member.Member.DeclaringType);

            if (isInterface)
            {
                var itypeDef = member.Member.DeclaringTypeDefinition;
                var variance = MetadataUtils.IsJsGeneric(itypeDef, this.Emitter) &&
                               itypeDef.TypeParameters != null &&
                               itypeDef.TypeParameters.Any(typeParameter => typeParameter.Variance != VarianceModifier.Invariant);

                if (variance)
                {
                    isInterfaceMember = true;
                }
                else
                {
                    var ei = this.Emitter.Validator.IsExternalInterface(itypeDef);

                    if (ei != null)
                    {
                        nativeImplementation = ei.IsNativeImplementation;
                    }
                    else
                    {
                        nativeImplementation = member.Member.DeclaringTypeDefinition.ParentAssembly.AssemblyName == CS.NS.BRIDGE ||
                                               !this.Emitter.Validator.IsExternalType(member.Member.DeclaringTypeDefinition);
                    }

                    if (ei != null && ei.IsSimpleImplementation)
                    {
                        nativeImplementation = false;
                        isInterfaceMember    = false;
                    }
                    else if (ei != null || hasTypeParemeter)
                    {
                        if (hasTypeParemeter || !nativeImplementation)
                        {
                            isInterfaceMember = true;
                        }
                    }
                }
            }

            string interfaceTempVar = null;

            if (hasThis)
            {
                this.Write("");
                var    oldBuilder = this.Emitter.Output;
                var    oldInline  = inline;
                string thisArg    = null;
                bool   isSimple   = true;

                if (this.MemberReferenceExpression.Target is BaseReferenceExpression)
                {
                    thisArg = "this";
                }
                else
                {
                    this.Emitter.Output          = new StringBuilder();
                    this.Emitter.IsAssignment    = false;
                    this.Emitter.IsUnaryAccessor = false;
                    if (isConstTarget)
                    {
                        this.Write("(");
                    }
                    this.WriteSimpleTarget(resolveResult);
                    if (isConstTarget)
                    {
                        this.Write(")");
                    }

                    thisArg = this.Emitter.Output.ToString();

                    if (Regex.Matches(inline, @"\{(\*?)this\}").Count > 1)
                    {
                        var  mrr     = resolveResult as MemberResolveResult;
                        bool isField = mrr != null && mrr.Member is IField &&
                                       (mrr.TargetResult is ThisResolveResult ||
                                        mrr.TargetResult is LocalResolveResult || mrr.TargetResult is MemberResolveResult && ((MemberResolveResult)mrr.TargetResult).Member is IField);

                        isSimple = (mrr != null && (mrr.TargetResult is ThisResolveResult || mrr.TargetResult is ConstantResolveResult || mrr.TargetResult is LocalResolveResult)) || isField;
                    }
                }

                int thisIndex;
                inline = member != null?Helpers.ConvertTokens(this.Emitter, inline, member.Member) : inline;

                if (!isSimple)
                {
                    StringBuilder sb = new StringBuilder();

                    sb.Append("(");
                    var tempVar = this.GetTempVarName();
                    inline    = inline.Replace("{this}", tempVar);
                    thisIndex = tempVar.Length + 2;

                    sb.Append(tempVar);
                    sb.Append(" = ");
                    sb.Append(thisArg);
                    sb.Append(", ");

                    sb.Append(inline);
                    sb.Append(")");

                    inline = sb.ToString();
                }
                else
                {
                    thisIndex = inline.IndexOf("{this}", StringComparison.Ordinal);
                    inline    = inline.Replace("{this}", thisArg);
                }

                if (member != null && member.Member is IProperty)
                {
                    this.Emitter.Output = new StringBuilder();
                    inline = inline.Replace("{0}", "[[0]]");
                    new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline).Emit();
                    inline = this.Emitter.Output.ToString();
                    inline = inline.Replace("[[0]]", "{0}");
                }
                else if (member != null && member.Member is IEvent)
                {
                    this.Emitter.Output = new StringBuilder();
                    inline = inline.Replace("{0}", "[[0]]");
                    new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline).Emit();
                    inline = this.Emitter.Output.ToString();
                    inline = inline.Replace("[[0]]", "{0}");
                }

                this.Emitter.Output = new StringBuilder(inline);
                Helpers.CheckValueTypeClone(resolveResult, this.MemberReferenceExpression, this, pos);
                inline = this.Emitter.Output.ToString();

                this.Emitter.IsAssignment    = oldIsAssignment;
                this.Emitter.IsUnaryAccessor = oldUnary;
                this.Emitter.Output          = oldBuilder;

                int[] range = null;

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

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

                return;
            }

            if (member != null && member.Member.SymbolKind == SymbolKind.Field && this.Emitter.IsMemberConst(member.Member) && this.Emitter.IsInlineConst(member.Member))
            {
                var  parentExpression = memberReferenceExpression.Parent as MemberReferenceExpression;
                bool wrap             = false;

                if (parentExpression != null)
                {
                    var ii = this.Emitter.GetInlineCode(parentExpression);

                    if (string.IsNullOrEmpty(ii.Item3))
                    {
                        wrap = true;
                        this.WriteOpenParentheses();
                    }
                }

                this.WriteScript(Bridge.Translator.Emitter.ConvertConstant(member.ConstantValue, memberReferenceExpression, this.Emitter));

                if (wrap)
                {
                    this.WriteCloseParentheses();
                }
            }
            else if (hasInline && member.Member.IsStatic)
            {
                if (resolveResult is InvocationResolveResult)
                {
                    this.PushWriter(inline);
                }
                else
                {
                    if (member != null && member.Member is IMethod)
                    {
                        new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline, (IMethod)member.Member, targetrr).EmitFunctionReference();
                    }
                    else
                    {
                        new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline).Emit();
                    }
                }
            }
            else
            {
                if (member != null && member.IsCompileTimeConstant && member.Member.DeclaringType.Kind == TypeKind.Enum)
                {
                    var typeDef = member.Member.DeclaringType as ITypeDefinition;

                    if (typeDef != null)
                    {
                        var enumMode = Helpers.EnumEmitMode(typeDef);

                        if ((this.Emitter.Validator.IsExternalType(typeDef) && enumMode == -1) || enumMode == 2)
                        {
                            this.WriteScript(member.ConstantValue);

                            return;
                        }

                        if (enumMode >= 3 && enumMode < 7)
                        {
                            string enumStringName = this.Emitter.GetEntityName(member.Member);
                            this.WriteScript(enumStringName);
                            return;
                        }
                    }
                }

                if (resolveResult is TypeResolveResult)
                {
                    TypeResolveResult typeResolveResult = (TypeResolveResult)resolveResult;
                    this.Write(BridgeTypes.ToJsName(typeResolveResult.Type, this.Emitter));
                    return;
                }
                else
                {
                    if (member != null &&
                        member.Member is IMethod &&
                        !(member is InvocationResolveResult) &&
                        !(
                            memberReferenceExpression.Parent is InvocationExpression &&
                            memberReferenceExpression.NextSibling != null &&
                            memberReferenceExpression.NextSibling.Role is TokenRole &&
                            ((TokenRole)memberReferenceExpression.NextSibling.Role).Token == "("
                            )
                        )
                    {
                        var parentInvocation = memberReferenceExpression.Parent as InvocationExpression;
                        if (parentInvocation == null || parentInvocation.Target != memberReferenceExpression)
                        {
                            if (!string.IsNullOrEmpty(inline))
                            {
                                if (!(resolveResult is InvocationResolveResult) && member != null && member.Member is IMethod)
                                {
                                    new InlineArgumentsBlock(this.Emitter,
                                                             new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline,
                                                             (IMethod)member.Member, targetrr).EmitFunctionReference();
                                }
                                else if (resolveResult is InvocationResolveResult ||
                                         (member.Member.SymbolKind == SymbolKind.Property && this.Emitter.IsAssignment))
                                {
                                    this.PushWriter(inline);
                                }
                                else
                                {
                                    this.Write(inline);
                                }
                            }
                            else
                            {
                                var  resolvedMethod = (IMethod)member.Member;
                                bool isStatic       = resolvedMethod != null && resolvedMethod.IsStatic;

                                var isExtensionMethod = resolvedMethod.IsExtensionMethod;

                                this.Emitter.IsAssignment    = false;
                                this.Emitter.IsUnaryAccessor = false;

                                if (!isStatic)
                                {
                                    this.Write(isExtensionMethod ? JS.Funcs.BRIDGE_BIND_SCOPE : JS.Funcs.BRIDGE_CACHE_BIND);
                                    this.WriteOpenParentheses();

                                    if (memberReferenceExpression.Target is BaseReferenceExpression)
                                    {
                                        this.WriteThis();
                                    }
                                    else
                                    {
                                        interfaceTempVar = this.WriteTarget(resolveResult, isInterfaceMember, memberTargetrr, targetrr, false);
                                    }

                                    this.Write(", ");
                                }

                                this.Emitter.IsAssignment    = oldIsAssignment;
                                this.Emitter.IsUnaryAccessor = oldUnary;

                                if (isExtensionMethod)
                                {
                                    this.Write(BridgeTypes.ToJsName(resolvedMethod.DeclaringType, this.Emitter));
                                }
                                else
                                {
                                    this.Emitter.IsAssignment    = false;
                                    this.Emitter.IsUnaryAccessor = false;
                                    if (isConstTarget)
                                    {
                                        this.Write("(");
                                    }

                                    if (interfaceTempVar != null)
                                    {
                                        this.Write(interfaceTempVar);
                                    }
                                    else
                                    {
                                        this.WriteSimpleTarget(resolveResult);
                                    }

                                    if (isConstTarget)
                                    {
                                        this.Write(")");
                                    }
                                    this.Emitter.IsAssignment    = oldIsAssignment;
                                    this.Emitter.IsUnaryAccessor = oldUnary;
                                }

                                if (isInterfaceMember)
                                {
                                    this.WriteInterfaceMember(interfaceTempVar, member, false);
                                }
                                else
                                {
                                    this.WriteDot();
                                    this.Write(OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName(!nativeImplementation));
                                }

                                if (!isStatic)
                                {
                                    this.Write(")");
                                }
                            }

                            return;
                        }
                    }

                    bool isProperty = false;

                    if (member != null && member.Member.SymbolKind == SymbolKind.Property && (member.Member.DeclaringTypeDefinition == null || !this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition)))
                    {
                        isProperty = true;
                        bool writeTargetVar = false;

                        if (this.Emitter.IsAssignment && this.Emitter.AssignmentType != AssignmentOperatorType.Assign)
                        {
                            writeTargetVar = true;
                        }
                        else if (this.Emitter.IsUnaryAccessor)
                        {
                            writeTargetVar = true;

                            isStatement = memberReferenceExpression.Parent is UnaryOperatorExpression && memberReferenceExpression.Parent.Parent is ExpressionStatement;

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

                            if (!isStatement)
                            {
                                this.WriteOpenParentheses();
                            }
                        }

                        if (writeTargetVar)
                        {
                            bool isField = memberTargetrr != null && memberTargetrr.Member is IField && (memberTargetrr.TargetResult is ThisResolveResult || memberTargetrr.TargetResult is LocalResolveResult);

                            if (!(targetrr is ThisResolveResult || targetrr is TypeResolveResult || targetrr is LocalResolveResult || isField))
                            {
                                targetVar = this.GetTempVarName();

                                this.Write(targetVar);
                                this.Write(" = ");
                            }
                        }
                    }

                    if (isProperty && this.Emitter.IsUnaryAccessor && !isStatement && targetVar == null)
                    {
                        valueVar = this.GetTempVarName();

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

                    this.Emitter.IsAssignment    = false;
                    this.Emitter.IsUnaryAccessor = false;
                    if (isConstTarget)
                    {
                        this.Write("(");
                    }

                    if (targetVar == null && isInterfaceMember)
                    {
                        interfaceTempVar = this.WriteTarget(resolveResult, isInterfaceMember, memberTargetrr, targetrr, true);
                    }
                    else
                    {
                        this.WriteSimpleTarget(resolveResult);
                    }

                    if (member != null && targetrr != null && targetrr.Type.Kind == TypeKind.Delegate && (member.Member.Name == "Invoke"))
                    {
                        var method = member.Member as IMethod;
                        if (!(method != null && method.IsExtensionMethod))
                        {
                            return;
                        }
                    }

                    if (isConstTarget)
                    {
                        this.Write(")");
                    }
                    this.Emitter.IsAssignment    = oldIsAssignment;
                    this.Emitter.IsUnaryAccessor = oldUnary;

                    if (targetVar != null)
                    {
                        if (this.Emitter.IsUnaryAccessor && !isStatement)
                        {
                            this.WriteComma(false);

                            valueVar = this.GetTempVarName();

                            this.Write(valueVar);
                            this.Write(" = ");

                            this.Write(targetVar);
                        }
                        else
                        {
                            this.WriteSemiColon();
                            this.WriteNewLine();
                            this.Write(targetVar);
                        }
                    }
                }

                var targetResolveResult = targetrr as MemberResolveResult;

                if (targetResolveResult == null || this.Emitter.IsGlobalTarget(targetResolveResult.Member) == null)
                {
                    if (isRefArg)
                    {
                        this.WriteComma();
                    }
                    else if (!isInterfaceMember && !this.NoTarget)
                    {
                        this.WriteDot();
                    }
                }

                if (member == null)
                {
                    if (targetrr != null && targetrr.Type.Kind == TypeKind.Dynamic)
                    {
                        this.Write(memberReferenceExpression.MemberName);
                    }
                    else
                    {
                        this.Write(memberReferenceExpression.MemberName.ToLowerCamelCase());
                    }
                }
                else if (!string.IsNullOrEmpty(inline))
                {
                    if (!(resolveResult is InvocationResolveResult) && member != null && member.Member is IMethod)
                    {
                        new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline, (IMethod)member.Member, targetrr).EmitFunctionReference();
                    }
                    else if (resolveResult is InvocationResolveResult ||
                             (member.Member.SymbolKind == SymbolKind.Property && this.Emitter.IsAssignment) ||
                             (member.Member != null && member.Member is IEvent))
                    {
                        this.PushWriter(inline);
                    }
                    else
                    {
                        this.Write(inline);
                    }
                }
                else if (member.Member.SymbolKind == SymbolKind.Property && (member.Member.DeclaringTypeDefinition == null || (!this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition) || member.Member.IsStatic)))
                {
                    if (member.Member is IProperty && targetrr != null && targetrr.Type.GetDefinition() != null && this.Emitter.Validator.IsObjectLiteral(targetrr.Type.GetDefinition()) && !this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition))
                    {
                        this.Write(this.Emitter.GetLiteralEntityName(member.Member));
                    }
                    else
                    {
                        if (isInterfaceMember)
                        {
                            this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, false);
                        }
                        else
                        {
                            var name     = OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName(!nativeImplementation);
                            var property = (IProperty)member.Member;
                            var proto    = member.IsVirtualCall || property.IsVirtual || property.IsOverride;

                            if (this.MemberReferenceExpression.Target is BaseReferenceExpression && !property.IsIndexer && proto)
                            {
                                var alias = BridgeTypes.ToJsName(member.Member.DeclaringType, this.Emitter,
                                                                 isAlias: true);
                                if (alias.StartsWith("\""))
                                {
                                    alias = alias.Insert(1, "$");
                                    name  = alias + "+\"$" + name + "\"";
                                    this.WriteIdentifier(name, false);
                                }
                                else
                                {
                                    name = "$" + alias + "$" + name;
                                    this.WriteIdentifier(name);
                                }
                            }
                            else
                            {
                                this.WriteIdentifier(name);
                            }
                        }
                    }
                }
                else if (member.Member.SymbolKind == SymbolKind.Field)
                {
                    bool isConst = this.Emitter.IsMemberConst(member.Member);

                    if (isConst && this.Emitter.IsInlineConst(member.Member))
                    {
                        this.WriteScript(Bridge.Translator.Emitter.ConvertConstant(member.ConstantValue, memberReferenceExpression, this.Emitter));
                    }
                    else
                    {
                        if (isInterfaceMember)
                        {
                            this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, false);
                        }
                        else
                        {
                            var fieldName = OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName(!nativeImplementation);

                            if (isRefArg)
                            {
                                this.WriteScript(fieldName);
                            }
                            else
                            {
                                this.WriteIdentifier(fieldName);
                            }
                        }
                    }
                }
                else if (resolveResult is InvocationResolveResult)
                {
                    InvocationResolveResult       invocationResult  = (InvocationResolveResult)resolveResult;
                    CSharpInvocationResolveResult cInvocationResult = resolveResult as CSharpInvocationResolveResult;
                    var expresssionMember = expressionResolveResult as MemberResolveResult;

                    if (isInterfaceMember)
                    {
                        this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, false);
                    }
                    else if (expresssionMember != null &&
                             cInvocationResult != null &&
                             cInvocationResult.IsDelegateInvocation &&
                             invocationResult.Member != expresssionMember.Member)
                    {
                        this.Write(OverloadsCollection.Create(this.Emitter, expresssionMember.Member).GetOverloadName(!nativeImplementation));
                    }
                    else
                    {
                        this.Write(OverloadsCollection.Create(this.Emitter, invocationResult.Member).GetOverloadName(!nativeImplementation));
                    }
                }
                else if (member.Member is IEvent)
                {
                    if (this.Emitter.IsAssignment &&
                        (this.Emitter.AssignmentType == AssignmentOperatorType.Add ||
                         this.Emitter.AssignmentType == AssignmentOperatorType.Subtract))
                    {
                        if (isInterfaceMember)
                        {
                            this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, this.Emitter.AssignmentType == AssignmentOperatorType.Subtract, Helpers.GetAddOrRemove(this.Emitter.AssignmentType == AssignmentOperatorType.Add));
                        }
                        else
                        {
                            this.Write(Helpers.GetEventRef(member.Member, this.Emitter, this.Emitter.AssignmentType != AssignmentOperatorType.Add, ignoreInterface: !nativeImplementation));
                        }

                        this.WriteOpenParentheses();
                    }
                    else
                    {
                        if (isInterfaceMember)
                        {
                            this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, false);
                        }
                        else
                        {
                            this.Write(this.Emitter.GetEntityName(member.Member));
                        }
                    }
                }
                else
                {
                    if (isInterfaceMember)
                    {
                        this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, false);
                    }
                    else
                    {
                        var memberName = this.Emitter.GetEntityName(member.Member);
                        if (isRefArg)
                        {
                            this.WriteScript(memberName);
                        }
                        else
                        {
                            this.WriteIdentifier(memberName);
                        }
                    }
                }

                Helpers.CheckValueTypeClone(resolveResult, memberReferenceExpression, this, pos);
            }
        }
Ejemplo n.º 24
0
        protected void VisitMethodDeclaration(MethodDeclaration methodDeclaration)
        {
            foreach (var attrSection in methodDeclaration.Attributes)
            {
                foreach (var attr in attrSection.Attributes)
                {
                    var rr = this.Emitter.Resolver.ResolveNode(attr.Type, this.Emitter);
                    if (rr.Type.FullName == "Bridge.ExternalAttribute")
                    {
                        return;
                    }
                    else if (rr.Type.FullName == "Bridge.InitAttribute")
                    {
                        InitPosition initPosition = InitPosition.After;

                        if (attr.HasArgumentList)
                        {
                            if (attr.Arguments.Any())
                            {
                                var argExpr = attr.Arguments.First();
                                var argrr   = this.Emitter.Resolver.ResolveNode(argExpr, this.Emitter);
                                if (argrr.ConstantValue is int)
                                {
                                    initPosition = (InitPosition)argrr.ConstantValue;
                                }
                            }
                        }

                        if (initPosition > 0)
                        {
                            return;
                        }
                    }
                }
            }

            this.EnsureComma();
            this.ResetLocals();

            var prevMap      = this.BuildLocalsMap();
            var prevNamesMap = this.BuildLocalsNamesMap();

            this.AddLocals(methodDeclaration.Parameters, methodDeclaration.Body);

            var overloads = OverloadsCollection.Create(this.Emitter, methodDeclaration);

            XmlToJsDoc.EmitComment(this, this.MethodDeclaration);
            var isEntryPoint = Helpers.IsEntryPointMethod(this.Emitter, this.MethodDeclaration);
            var member_rr    = (MemberResolveResult)this.Emitter.Resolver.ResolveNode(this.MethodDeclaration, this.Emitter);

            string name = overloads.GetOverloadName(false, null, OverloadsCollection.ExcludeTypeParameterForDefinition(member_rr));

            if (isEntryPoint)
            {
                this.Write(JS.Funcs.ENTRY_POINT_NAME);
            }
            else
            {
                this.Write(name);
            }

            this.WriteColon();

            this.WriteFunction();

            if (isEntryPoint)
            {
                this.Write(name);
                this.WriteSpace();
            }
            else
            {
                var nm = Helpers.GetFunctionName(this.Emitter.AssemblyInfo.NamedFunctions, member_rr.Member, this.Emitter);
                if (nm != null)
                {
                    this.Write(nm);
                    this.WriteSpace();
                }
            }

            this.EmitMethodParameters(methodDeclaration.Parameters, methodDeclaration.TypeParameters.Count > 0 && Helpers.IsIgnoreGeneric(methodDeclaration, this.Emitter) ? null : methodDeclaration.TypeParameters, methodDeclaration);

            this.WriteSpace();

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

            if (script == null)
            {
                if (YieldBlock.HasYield(methodDeclaration.Body))
                {
                    new GeneratorBlock(this.Emitter, methodDeclaration).Emit();
                }
                else if (methodDeclaration.HasModifier(Modifiers.Async) || AsyncBlock.HasGoto(methodDeclaration.Body))
                {
                    new AsyncBlock(this.Emitter, methodDeclaration).Emit();
                }
                else
                {
                    methodDeclaration.Body.AcceptVisitor(this.Emitter);
                }
            }
            else
            {
                this.BeginBlock();

                this.WriteLines(script);

                this.EndBlock();
            }

            this.ClearLocalsMap(prevMap);
            this.ClearLocalsNamesMap(prevNamesMap);
            this.Emitter.Comma = true;
        }
Ejemplo n.º 25
0
        private void HandleDecimal(ResolveResult resolveOperator, bool isLong = false)
        {
            var orr         = resolveOperator as OperatorResolveResult;
            var op          = this.UnaryOperatorExpression.Operator;
            var oldType     = this.Emitter.UnaryOperatorType;
            var oldAccessor = this.Emitter.IsUnaryAccessor;
            var typeCode    = isLong ? KnownTypeCode.Int64 : KnownTypeCode.Decimal;

            this.Emitter.UnaryOperatorType = op;

            var  argResolverResult       = this.Emitter.Resolver.ResolveNode(this.UnaryOperatorExpression.Expression, this.Emitter);
            bool nullable                = NullableType.IsNullable(argResolverResult.Type);
            bool isAccessor              = false;
            var  memberArgResolverResult = argResolverResult as MemberResolveResult;

            if (memberArgResolverResult != null && memberArgResolverResult.Member is IProperty)
            {
                var isIgnore           = this.Emitter.Validator.IsExternalType(memberArgResolverResult.Member.DeclaringTypeDefinition);
                var inlineAttr         = this.Emitter.GetAttribute(memberArgResolverResult.Member.Attributes, Translator.Bridge_ASSEMBLY + ".TemplateAttribute");
                var ignoreAccessor     = this.Emitter.Validator.IsExternalType(((IProperty)memberArgResolverResult.Member).Getter);
                var isAccessorsIndexer = this.Emitter.Validator.IsAccessorsIndexer(memberArgResolverResult.Member);

                isAccessor = ((IProperty)memberArgResolverResult.Member).IsIndexer;

                if (inlineAttr == null && (isIgnore || ignoreAccessor) && !isAccessorsIndexer)
                {
                    isAccessor = false;
                }
            }
            else if (argResolverResult is ArrayAccessResolveResult)
            {
                isAccessor = ((ArrayAccessResolveResult)argResolverResult).Indexes.Count > 1;
            }

            var isOneOp = op == UnaryOperatorType.Increment ||
                          op == UnaryOperatorType.Decrement ||
                          op == UnaryOperatorType.PostIncrement ||
                          op == UnaryOperatorType.PostDecrement;

            if (isAccessor && isOneOp)
            {
                this.Emitter.IsUnaryAccessor = true;

                if (nullable)
                {
                    this.Write(JS.Funcs.BRIDGE_HASVALUE);
                    this.WriteOpenParentheses();
                    this.Emitter.IsUnaryAccessor = false;
                    this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter);
                    this.Write(") ? ");
                    this.Emitter.IsUnaryAccessor = true;
                    this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter);
                    this.Write(" : null)");
                }
                else
                {
                    this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter);
                }

                this.Emitter.UnaryOperatorType = oldType;
                this.Emitter.IsUnaryAccessor   = oldAccessor;

                return;
            }

            var method = orr != null ? orr.UserDefinedOperatorMethod : null;

            if (orr != null && method == null)
            {
                var name = Helpers.GetUnaryOperatorMethodName(this.UnaryOperatorExpression.Operator);
                var type = NullableType.IsNullable(orr.Type) ? NullableType.GetUnderlyingType(orr.Type) : orr.Type;
                method = type.GetMethods(m => m.Name == name, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault();
            }

            if (orr != null && orr.IsLiftedOperator)
            {
                if (!isOneOp)
                {
                    this.Write(JS.Types.SYSTEM_NULLABLE + ".");
                }

                string action  = JS.Funcs.Math.LIFT1;
                string op_name = null;

                switch (this.UnaryOperatorExpression.Operator)
                {
                case UnaryOperatorType.Minus:
                    op_name = JS.Funcs.Math.NEG;
                    break;

                case UnaryOperatorType.Plus:
                    op_name = "clone";
                    break;

                case UnaryOperatorType.BitNot:
                    op_name = "not";
                    break;

                case UnaryOperatorType.Increment:
                case UnaryOperatorType.Decrement:
                    this.Write(JS.Funcs.BRIDGE_HASVALUE);
                    this.WriteOpenParentheses();
                    this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter);
                    this.Write(") ? ");
                    this.WriteOpenParentheses();
                    this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter);
                    this.Write(" = " + JS.Types.SYSTEM_NULLABLE + "." + JS.Funcs.Math.LIFT1 + "(\"" + (op == UnaryOperatorType.Decrement ? JS.Funcs.Math.DEC : JS.Funcs.Math.INC) + "\", ");
                    this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter);
                    this.AddOveflowFlag(typeCode, JS.Funcs.Math.DEC, true);
                    this.Write(")");
                    this.WriteCloseParentheses();

                    this.Write(" : null");
                    break;

                case UnaryOperatorType.PostIncrement:
                case UnaryOperatorType.PostDecrement:
                    this.Write(JS.Funcs.BRIDGE_HASVALUE);
                    this.WriteOpenParentheses();
                    this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter);
                    this.Write(") ? ");
                    this.WriteOpenParentheses();
                    var valueVar = this.GetTempVarName();

                    this.Write(valueVar);
                    this.Write(" = ");

                    this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter);
                    this.WriteComma();
                    this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter);
                    this.Write(" = " + JS.Types.SYSTEM_NULLABLE + "." + JS.Funcs.Math.LIFT1 + "(\"" + (op == UnaryOperatorType.PostDecrement ? JS.Funcs.Math.DEC : JS.Funcs.Math.INC) + "\", ");
                    this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter);
                    this.AddOveflowFlag(typeCode, JS.Funcs.Math.DEC, true);
                    this.Write(")");
                    this.WriteComma();
                    this.Write(valueVar);
                    this.WriteCloseParentheses();
                    this.RemoveTempVar(valueVar);

                    this.Write(" : null");
                    break;
                }

                if (!isOneOp)
                {
                    this.Write(action);
                    this.WriteOpenParentheses();
                    this.WriteScript(op_name);
                    this.WriteComma();
                    new ExpressionListBlock(this.Emitter,
                                            new Expression[] { this.UnaryOperatorExpression.Expression }, null, null, 0).Emit();
                    this.AddOveflowFlag(typeCode, op_name, true);
                    this.WriteCloseParentheses();
                }
            }
            else if (method == null)
            {
                string op_name     = null;
                var    isStatement = this.UnaryOperatorExpression.Parent is ExpressionStatement;

                if (isStatement)
                {
                    if (op == UnaryOperatorType.PostIncrement)
                    {
                        op = UnaryOperatorType.Increment;
                    }
                    else if (op == UnaryOperatorType.PostDecrement)
                    {
                        op = UnaryOperatorType.Decrement;
                    }
                }

                switch (op)
                {
                case UnaryOperatorType.Minus:
                    op_name = JS.Funcs.Math.NEG;
                    break;

                case UnaryOperatorType.Plus:
                    op_name = "clone";
                    break;

                case UnaryOperatorType.BitNot:
                    op_name = "not";
                    break;

                case UnaryOperatorType.Increment:
                case UnaryOperatorType.Decrement:
                    if (!isStatement)
                    {
                        this.WriteOpenParentheses();
                    }

                    this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter);
                    this.Write(" = ");
                    this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter);
                    this.Write("." + (op == UnaryOperatorType.Decrement ? JS.Funcs.Math.DEC : JS.Funcs.Math.INC) + "(");
                    this.AddOveflowFlag(typeCode, JS.Funcs.Math.DEC, false);
                    this.Write(")");

                    if (!isStatement)
                    {
                        this.WriteCloseParentheses();
                    }
                    break;

                case UnaryOperatorType.PostIncrement:
                case UnaryOperatorType.PostDecrement:
                    this.WriteOpenParentheses();
                    var valueVar = this.GetTempVarName();

                    this.Write(valueVar);
                    this.Write(" = ");

                    this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter);
                    this.WriteComma();
                    this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter);
                    this.Write(" = ");
                    this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter);
                    this.Write("." + (op == UnaryOperatorType.PostDecrement ? JS.Funcs.Math.DEC : JS.Funcs.Math.INC) + "(");
                    this.AddOveflowFlag(typeCode, JS.Funcs.Math.DEC, false);
                    this.Write("), ");
                    this.Write(valueVar);
                    this.WriteCloseParentheses();
                    this.RemoveTempVar(valueVar);
                    break;
                }

                if (!isOneOp)
                {
                    this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter);
                    this.WriteDot();
                    this.Write(op_name);
                    this.WriteOpenParentheses();
                    this.AddOveflowFlag(typeCode, op_name, false);
                    this.WriteCloseParentheses();
                }
            }
            else
            {
                var inline = this.Emitter.GetInline(method);

                if (!string.IsNullOrWhiteSpace(inline))
                {
                    if (isOneOp)
                    {
                        var isStatement = this.UnaryOperatorExpression.Parent is ExpressionStatement;

                        if (isStatement || this.UnaryOperatorExpression.Operator == UnaryOperatorType.Increment ||
                            this.UnaryOperatorExpression.Operator == UnaryOperatorType.Decrement)
                        {
                            if (!isStatement)
                            {
                                this.WriteOpenParentheses();
                            }

                            this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter);
                            this.Write(" = ");
                            new InlineArgumentsBlock(this.Emitter,
                                                     new ArgumentsInfo(this.Emitter, this.UnaryOperatorExpression, orr, method), inline).Emit
                                ();
                            if (!isStatement)
                            {
                                this.WriteCloseParentheses();
                            }
                        }
                        else
                        {
                            this.WriteOpenParentheses();
                            var valueVar = this.GetTempVarName();

                            this.Write(valueVar);
                            this.Write(" = ");

                            this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter);
                            this.WriteComma();
                            this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter);
                            this.Write(" = ");
                            new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, this.UnaryOperatorExpression, orr, method), inline).Emit();
                            this.WriteComma();
                            this.Write(valueVar);
                            this.WriteCloseParentheses();
                            this.RemoveTempVar(valueVar);
                        }
                    }
                    else
                    {
                        new InlineArgumentsBlock(this.Emitter,
                                                 new ArgumentsInfo(this.Emitter, this.UnaryOperatorExpression, orr, method), inline).Emit();
                    }
                }
                else if (!this.Emitter.Validator.IsExternalType(method.DeclaringTypeDefinition))
                {
                    this.Write(BridgeTypes.ToJsName(method.DeclaringType, this.Emitter));
                    this.WriteDot();

                    this.Write(OverloadsCollection.Create(this.Emitter, method).GetOverloadName());

                    this.WriteOpenParentheses();

                    new ExpressionListBlock(this.Emitter,
                                            new Expression[] { this.UnaryOperatorExpression.Expression }, null, null, 0).Emit();
                    this.WriteCloseParentheses();
                }
            }

            this.Emitter.UnaryOperatorType = oldType;
        }
Ejemplo n.º 26
0
        private void WriteInterfaceMember(string interfaceTempVar, MemberResolveResult resolveResult, bool isSetter, string prefix = null)
        {
            var externalInterface = this.Emitter.Validator.IsExternalInterface(resolveResult.Member.DeclaringTypeDefinition);

            if (interfaceTempVar != null && externalInterface == null)
            {
                this.WriteComma();
                this.Write(interfaceTempVar);
            }

            if (externalInterface != null && externalInterface.IsDualImplementation)
            {
                if (interfaceTempVar != null)
                {
                    this.WriteCloseParentheses();
                }

                this.WriteOpenBracket();
                this.Write(JS.Funcs.BRIDGE_GET_I);
                this.WriteOpenParentheses();

                if (interfaceTempVar != null)
                {
                    this.Write(interfaceTempVar);
                }
                else
                {
                    this.WriteSimpleTarget(resolveResult);
                }

                this.WriteComma();

                var interfaceName = OverloadsCollection.Create(Emitter, resolveResult.Member, isSetter).GetOverloadName(false, prefix);

                if (interfaceName.StartsWith("\""))
                {
                    this.Write(interfaceName);
                }
                else
                {
                    this.WriteScript(interfaceName);
                }

                this.WriteComma();
                this.WriteScript(OverloadsCollection.Create(Emitter, resolveResult.Member, isSetter).GetOverloadName(true, prefix));

                this.Write(")");
                this.WriteCloseBracket();

                return;
            }

            this.WriteOpenBracket();
            this.Write(OverloadsCollection.Create(Emitter, resolveResult.Member, isSetter).GetOverloadName(externalInterface != null && externalInterface.IsSimpleImplementation, prefix));
            this.WriteCloseBracket();

            if (interfaceTempVar != null)
            {
                this.WriteCloseParentheses();
            }
        }
Ejemplo n.º 27
0
        private void HandleType(ResolveResult resolveOperator, KnownTypeCode typeCode, string op_name, string action)
        {
            var orr    = resolveOperator as OperatorResolveResult;
            var method = orr != null ? orr.UserDefinedOperatorMethod : null;

            if (orr != null && method == null)
            {
                var name = Helpers.GetBinaryOperatorMethodName(this.BinaryOperatorExpression.Operator);
                var type = this.Emitter.Resolver.Compilation.FindType(typeCode);
                method = type.GetMethods(m => m.Name == name, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault();
            }

            if (method != null)
            {
                var inline = this.Emitter.GetInline(method);

                if (orr.IsLiftedOperator)
                {
                    this.Write(JS.Types.SYSTEM_NULLABLE + ".");
                    this.Write(action);
                    this.WriteOpenParentheses();
                    this.WriteScript(op_name);
                    this.WriteComma();
                    new ExpressionListBlock(this.Emitter,
                                            new Expression[] { this.BinaryOperatorExpression.Left, this.BinaryOperatorExpression.Right }, null, null, 0)
                    .Emit();
                    this.AddOveflowFlag(typeCode, op_name);
                    this.WriteCloseParentheses();
                }
                else if (!string.IsNullOrWhiteSpace(inline))
                {
                    new InlineArgumentsBlock(this.Emitter,
                                             new ArgumentsInfo(this.Emitter, this.BinaryOperatorExpression, orr, method), inline).Emit();
                }
                else if (!this.Emitter.Validator.IsIgnoreType(method.DeclaringTypeDefinition))
                {
                    this.Write(BridgeTypes.ToJsName(method.DeclaringType, this.Emitter));
                    this.WriteDot();

                    this.Write(OverloadsCollection.Create(this.Emitter, method).GetOverloadName());

                    this.WriteOpenParentheses();

                    new ExpressionListBlock(this.Emitter,
                                            new Expression[] { this.BinaryOperatorExpression.Left, this.BinaryOperatorExpression.Right }, null, null, 0)
                    .Emit();
                    this.AddOveflowFlag(typeCode, op_name);
                    this.WriteCloseParentheses();
                }
            }
            else
            {
                if (orr.IsLiftedOperator)
                {
                    this.Write(JS.Types.SYSTEM_NULLABLE + ".");
                    this.Write(action);
                    this.WriteOpenParentheses();
                    this.WriteScript(op_name);
                    this.WriteComma();
                    new ExpressionListBlock(this.Emitter,
                                            new Expression[] { this.BinaryOperatorExpression.Left, this.BinaryOperatorExpression.Right }, null, null, 0)
                    .Emit();
                    this.AddOveflowFlag(typeCode, op_name);
                    this.WriteCloseParentheses();
                }
                else
                {
                    this.BinaryOperatorExpression.Left.AcceptVisitor(this.Emitter);
                    this.WriteDot();
                    this.Write(op_name);
                    this.WriteOpenParentheses();
                    this.BinaryOperatorExpression.Right.AcceptVisitor(this.Emitter);
                    this.AddOveflowFlag(typeCode, op_name);
                    this.WriteCloseParentheses();
                }
            }
        }
Ejemplo n.º 28
0
        protected bool EmitMemberAlias(IMember member, IMember interfaceMember)
        {
            bool nonEmpty = false;

            if (member.IsShadowing || !member.IsOverride)
            {
                var baseMember = InheritanceHelper.GetBaseMember(member);

                if (baseMember != null && baseMember.ImplementedInterfaceMembers.Contains(interfaceMember))
                {
                    return(false);
                }
            }

            if (member is IProperty)
            {
                var property = (IProperty)member;
                if (property.CanGet)
                {
                    nonEmpty = true;
                    this.EnsureComma();
                    this.WriteScript(Helpers.GetPropertyRef(member, this.Emitter, false, false, false, true));
                    this.WriteComma();
                    var alias = Helpers.GetPropertyRef(interfaceMember, this.Emitter, false, false, false);

                    if (alias.StartsWith("\""))
                    {
                        this.Write(alias);
                    }
                    else
                    {
                        this.WriteScript(alias);
                    }

                    this.Emitter.Comma = true;
                }

                if (property.CanSet)
                {
                    nonEmpty = true;
                    this.EnsureComma();
                    this.WriteScript(Helpers.GetPropertyRef(member, this.Emitter, true, false, false, true));
                    this.WriteComma();
                    var alias = Helpers.GetPropertyRef(interfaceMember, this.Emitter, true, false, false);

                    if (alias.StartsWith("\""))
                    {
                        this.Write(alias);
                    }
                    else
                    {
                        this.WriteScript(alias);
                    }

                    this.Emitter.Comma = true;
                }
            }
            else if (member is IEvent)
            {
                var ev = (IEvent)member;
                if (ev.CanAdd)
                {
                    nonEmpty = true;
                    this.EnsureComma();
                    this.WriteScript(Helpers.GetEventRef(member, this.Emitter, false, false, false, true));
                    this.WriteComma();
                    var alias = Helpers.GetEventRef(interfaceMember, this.Emitter, false, false, false);

                    if (alias.StartsWith("\""))
                    {
                        this.Write(alias);
                    }
                    else
                    {
                        this.WriteScript(alias);
                    }

                    this.Emitter.Comma = true;
                }

                if (ev.CanRemove)
                {
                    nonEmpty = true;
                    this.EnsureComma();
                    this.WriteScript(Helpers.GetEventRef(member, this.Emitter, true, false, false, true));
                    this.WriteComma();
                    var alias = Helpers.GetEventRef(interfaceMember, this.Emitter, true, false, false);

                    if (alias.StartsWith("\""))
                    {
                        this.Write(alias);
                    }
                    else
                    {
                        this.WriteScript(alias);
                    }

                    this.Emitter.Comma = true;
                }
            }
            else
            {
                nonEmpty = true;
                this.EnsureComma();
                this.WriteScript(OverloadsCollection.Create(Emitter, member).GetOverloadName(false, null, true));
                this.WriteComma();
                var alias = OverloadsCollection.Create(Emitter, interfaceMember).GetOverloadName();

                if (alias.StartsWith("\""))
                {
                    this.Write(alias);
                }
                else
                {
                    this.WriteScript(alias);
                }
            }

            this.Emitter.Comma = true;
            return(nonEmpty);
        }
Ejemplo n.º 29
0
        protected bool EmitMemberAlias(IMember member, IMember interfaceMember)
        {
            bool nonEmpty = false;

            if (member.IsShadowing || !member.IsOverride)
            {
                var baseMember = InheritanceHelper.GetBaseMember(member);

                if (baseMember != null && baseMember.ImplementedInterfaceMembers.Contains(interfaceMember))
                {
                    return(false);
                }
            }

            var excludeTypeParam      = OverloadsCollection.ExcludeTypeParameterForDefinition(member);
            var excludeAliasTypeParam = member.IsExplicitInterfaceImplementation && !excludeTypeParam;
            var pair     = false;
            var itypeDef = interfaceMember.DeclaringTypeDefinition;

            if (!member.IsExplicitInterfaceImplementation &&
                MetadataUtils.IsJsGeneric(itypeDef, Emitter) &&
                itypeDef.TypeParameters != null &&
                itypeDef.TypeParameters.Any(typeParameter => typeParameter.Variance != VarianceModifier.Invariant))
            {
                pair = true;
            }

            if (member is IProperty && ((IProperty)member).IsIndexer)
            {
                var property = (IProperty)member;
                if (property.CanGet)
                {
                    nonEmpty = true;
                    EnsureComma();
                    WriteScript(Helpers.GetPropertyRef(member, Emitter, false, false, false, excludeTypeParam));
                    WriteComma();
                    var alias = Helpers.GetPropertyRef(interfaceMember, Emitter, false, false, false, withoutTypeParams: excludeAliasTypeParam);

                    if (pair)
                    {
                        WriteOpenBracket();
                    }

                    if (alias.StartsWith("\""))
                    {
                        Write(alias);
                    }
                    else
                    {
                        WriteScript(alias);
                    }

                    if (pair)
                    {
                        WriteComma();
                        WriteScript(Helpers.GetPropertyRef(interfaceMember, Emitter, withoutTypeParams: true));
                        WriteCloseBracket();
                    }

                    Emitter.Comma = true;
                }

                if (property.CanSet)
                {
                    nonEmpty = true;
                    EnsureComma();
                    WriteScript(Helpers.GetPropertyRef(member, Emitter, true, false, false, excludeTypeParam));
                    WriteComma();
                    var alias = Helpers.GetPropertyRef(interfaceMember, Emitter, true, false, false, withoutTypeParams: excludeAliasTypeParam);

                    if (pair)
                    {
                        WriteOpenBracket();
                    }

                    if (alias.StartsWith("\""))
                    {
                        Write(alias);
                    }
                    else
                    {
                        WriteScript(alias);
                    }

                    if (pair)
                    {
                        WriteComma();
                        WriteScript(Helpers.GetPropertyRef(interfaceMember, Emitter, true, withoutTypeParams: true));
                        WriteCloseBracket();
                    }

                    Emitter.Comma = true;
                }
            }
            else if (member is IEvent ev)
            {
                if (ev.CanAdd)
                {
                    nonEmpty = true;
                    EnsureComma();
                    WriteScript(Helpers.GetEventRef(member, Emitter, false, false, false, excludeTypeParam));
                    WriteComma();
                    var alias = Helpers.GetEventRef(interfaceMember, Emitter, false, false, false, excludeAliasTypeParam);

                    if (pair)
                    {
                        WriteOpenBracket();
                    }

                    if (alias.StartsWith("\""))
                    {
                        Write(alias);
                    }
                    else
                    {
                        WriteScript(alias);
                    }

                    if (pair)
                    {
                        WriteComma();
                        WriteScript(Helpers.GetEventRef(interfaceMember, Emitter, withoutTypeParams: true));
                        WriteCloseBracket();
                    }

                    Emitter.Comma = true;
                }

                if (ev.CanRemove)
                {
                    nonEmpty = true;
                    EnsureComma();
                    WriteScript(Helpers.GetEventRef(member, Emitter, true, false, false, excludeTypeParam));
                    WriteComma();
                    var alias = Helpers.GetEventRef(interfaceMember, Emitter, true, false, false, excludeAliasTypeParam);

                    if (pair)
                    {
                        WriteOpenBracket();
                    }

                    if (alias.StartsWith("\""))
                    {
                        Write(alias);
                    }
                    else
                    {
                        WriteScript(alias);
                    }

                    if (pair)
                    {
                        WriteComma();
                        WriteScript(Helpers.GetEventRef(interfaceMember, Emitter, true, withoutTypeParams: true));
                        WriteCloseBracket();
                    }

                    Emitter.Comma = true;
                }
            }
            else
            {
                nonEmpty = true;
                EnsureComma();
                WriteScript(OverloadsCollection.Create(Emitter, member).GetOverloadName(false, null, excludeTypeOnly: excludeTypeParam));
                WriteComma();
                var alias = OverloadsCollection.Create(Emitter, interfaceMember).GetOverloadName(withoutTypeParams: excludeAliasTypeParam);

                if (pair)
                {
                    WriteOpenBracket();
                }

                if (alias.StartsWith("\""))
                {
                    Write(alias);
                }
                else
                {
                    WriteScript(alias);
                }

                if (pair)
                {
                    WriteComma();
                    WriteScript(OverloadsCollection.Create(Emitter, interfaceMember).GetOverloadName(withoutTypeParams: true));
                    WriteCloseBracket();
                }
            }

            Emitter.Comma = true;
            return(nonEmpty);
        }
Ejemplo n.º 30
0
        public static int CheckConversion(ConversionBlock block, Expression expression)
        {
            try
            {
                var rr           = block.Emitter.Resolver.ResolveNode(expression, block.Emitter);
                var conversion   = block.Emitter.Resolver.Resolver.GetConversion(expression);
                var expectedType = block.Emitter.Resolver.Resolver.GetExpectedType(expression);
                int level        = 0;

                if (block.Emitter.IsAssignment)
                {
                    return(level);
                }

                /*if (expression is ParenthesizedExpression && expression.Parent is CastExpression)
                 * {
                 *  return level;
                 * }*/

                if (conversion.IsUserDefined && expression.Parent is CastExpression && ((CastExpression)expression.Parent).Expression == expression)
                {
                    var parentConversion = block.Emitter.Resolver.Resolver.GetConversion((CastExpression)expression.Parent);

                    if (!parentConversion.IsUserDefined || parentConversion.Method.Equals(conversion.Method))
                    {
                        return(level);
                    }
                }

                if (rr is ConstantResolveResult && expression is CastExpression && !conversion.IsUserDefined)
                {
                    return(level);
                }

                var convrr = rr as ConversionResolveResult;

                if (convrr != null && convrr.Input is ConstantResolveResult && !convrr.Conversion.IsUserDefined)
                {
                    return(level);
                }

                if (convrr != null && !conversion.IsUserDefined)
                {
                    conversion   = convrr.Conversion;
                    rr           = convrr.Input;
                    expectedType = convrr.Type;
                }

                if (!((expression.Parent is CastExpression) && !(expression is CastExpression)))
                {
                    CheckNumericConversion(block, expression, rr, expectedType, conversion);
                }

                if (!(conversion.IsExplicit && conversion.IsNumericConversion))
                {
                    level = ConversionBlock.CheckDecimalConversion(block, expression, rr, expectedType, conversion) ? (level + 1) : level;
                }

                if (Helpers.IsDecimalType(expectedType, block.Emitter.Resolver) && !conversion.IsUserDefined)
                {
                    return(level);
                }

                if (!(conversion.IsExplicit && conversion.IsNumericConversion))
                {
                    level = ConversionBlock.CheckLongConversion(block, expression, rr, expectedType, conversion)
                        ? (level + 1)
                        : level;
                }

                if (Helpers.Is64Type(expectedType, block.Emitter.Resolver) && !conversion.IsUserDefined)
                {
                    return(level);
                }


                if (conversion == null)
                {
                    return(level);
                }

                if (conversion.IsIdentityConversion)
                {
                    return(level);
                }

                var isNumLifted = conversion.IsImplicit && conversion.IsLifted && conversion.IsNumericConversion && !(expression is BinaryOperatorExpression);
                if (isNumLifted && !conversion.IsUserDefined)
                {
                    return(level);
                }
                bool isLifted = conversion.IsLifted && !isNumLifted && !(block is CastBlock) && !Helpers.IsDecimalType(expectedType, block.Emitter.Resolver) && !Helpers.Is64Type(expectedType, block.Emitter.Resolver) && !NullableType.IsNullable(expectedType);
                if (isLifted)
                {
                    level++;
                    block.Write("Bridge.Nullable.getValue(");
                }

                if (conversion.IsUserDefined)
                {
                    var method = conversion.Method;

                    string inline = block.Emitter.GetInline(method);

                    if (conversion.IsExplicit && !string.IsNullOrWhiteSpace(inline))
                    {
                        // Still returns true if Nullable.lift( was written.
                        return(level);
                    }

                    if (!string.IsNullOrWhiteSpace(inline))
                    {
                        if (expression is InvocationExpression)
                        {
                            new InlineArgumentsBlock(block.Emitter, new ArgumentsInfo(block.Emitter, (InvocationExpression)expression), inline).Emit();
                        }
                        else if (expression is ObjectCreateExpression)
                        {
                            new InlineArgumentsBlock(block.Emitter, new ArgumentsInfo(block.Emitter, (ObjectCreateExpression)expression), inline).Emit();
                        }
                        else if (expression is UnaryOperatorExpression)
                        {
                            var unaryExpression       = (UnaryOperatorExpression)expression;
                            var resolveOperator       = block.Emitter.Resolver.ResolveNode(unaryExpression, block.Emitter);
                            OperatorResolveResult orr = resolveOperator as OperatorResolveResult;
                            new InlineArgumentsBlock(block.Emitter, new ArgumentsInfo(block.Emitter, unaryExpression, orr, method), inline).Emit();
                        }
                        else if (expression is BinaryOperatorExpression)
                        {
                            var binaryExpression      = (BinaryOperatorExpression)expression;
                            var resolveOperator       = block.Emitter.Resolver.ResolveNode(binaryExpression, block.Emitter);
                            OperatorResolveResult orr = resolveOperator as OperatorResolveResult;
                            new InlineArgumentsBlock(block.Emitter, new ArgumentsInfo(block.Emitter, binaryExpression, orr, method), inline).Emit();
                        }
                        else
                        {
                            new InlineArgumentsBlock(block.Emitter, new ArgumentsInfo(block.Emitter, expression), inline).Emit();
                        }

                        block.DisableEmitConversionExpression = true;

                        // Still returns true if Nullable.lift( was written.
                        return(level);
                    }
                    else
                    {
                        if (method.DeclaringTypeDefinition != null && (block.Emitter.Validator.IsIgnoreType(method.DeclaringTypeDefinition) || Helpers.IsIgnoreCast(method.DeclaringTypeDefinition, block.Emitter)))
                        {
                            // Still returns true if Nullable.lift( was written.
                            return(level);
                        }

                        block.Write(BridgeTypes.ToJsName(method.DeclaringType, block.Emitter));
                        block.WriteDot();

                        block.Write(OverloadsCollection.Create(block.Emitter, method).GetOverloadName());
                    }

                    if (isLifted)
                    {
                        block.WriteComma();
                    }
                    else
                    {
                        block.WriteOpenParentheses();
                        level++;
                    }

                    var arg = method.Parameters[0];

                    if (Helpers.IsDecimalType(arg.Type, block.Emitter.Resolver, arg.IsParams) && !Helpers.IsDecimalType(rr.Type, block.Emitter.Resolver) && !expression.IsNull)
                    {
                        block.Write("Bridge.Decimal");
                        if (NullableType.IsNullable(arg.Type) && ConversionBlock.ShouldBeLifted(expression))
                        {
                            block.Write(".lift");
                        }
                        if (expression is CastExpression &&
                            ((CastExpression)expression).Expression is ParenthesizedExpression)
                        {
                            return(level);
                        }
                        block.WriteOpenParentheses();
                        level++;
                    }

                    if (Helpers.Is64Type(arg.Type, block.Emitter.Resolver, arg.IsParams) && !Helpers.Is64Type(rr.Type, block.Emitter.Resolver) && !expression.IsNull)
                    {
                        var isUint = Helpers.IsULongType(arg.Type, block.Emitter.Resolver, arg.IsParams);
                        block.Write("Bridge." + (isUint ? "ULong" : "Long"));
                        if (NullableType.IsNullable(arg.Type) && ConversionBlock.ShouldBeLifted(expression))
                        {
                            block.Write(".lift");
                        }
                        if (expression is CastExpression &&
                            ((CastExpression)expression).Expression is ParenthesizedExpression)
                        {
                            return(level);
                        }
                        block.WriteOpenParentheses();
                        level++;
                    }

                    return(level);
                }
                // Still returns true if Nullable.lift( was written.
                return(level);
            }
            catch
            {
            }

            return(0);
        }