protected virtual void EmitPropertyMethod(CustomEventDeclaration customEventDeclaration, Accessor accessor, bool remover)
        {
            if (!accessor.IsNull && Emitter.GetInline(accessor) == null)
            {
                EnsureComma();

                ResetLocals();

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

                AddLocals(new ParameterDeclaration[] { new ParameterDeclaration {
                                                           Name = "value"
                                                       } }, accessor.Body);
                XmlToJsDoc.EmitComment(this, CustomEventDeclaration);
                var member_rr = (MemberResolveResult)Emitter.Resolver.ResolveNode(customEventDeclaration);

                Write(Helpers.GetEventRef(customEventDeclaration, Emitter, remover, false, false, OverloadsCollection.ExcludeTypeParameterForDefinition(member_rr)));
                WriteColon();
                WriteFunction();
                var m_rr = (MemberResolveResult)Emitter.Resolver.ResolveNode(customEventDeclaration);
                var nm   = Helpers.GetFunctionName(Emitter.AssemblyInfo.NamedFunctions, m_rr.Member, Emitter, remover);
                if (nm != null)
                {
                    Write(nm);
                }
                WriteOpenParentheses();
                Write("value");
                WriteCloseParentheses();
                WriteSpace();

                var script = Emitter.GetScript(accessor);

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

                    WriteLines(script);

                    EndBlock();
                }

                ClearLocalsMap(prevMap);
                ClearLocalsNamesMap(prevNamesMap);
                Emitter.Comma = true;
            }
        }
        protected bool ResolveOperator(UnaryOperatorExpression unaryOperatorExpression, OperatorResolveResult orr)
        {
            if (orr != null && orr.UserDefinedOperatorMethod != null)
            {
                var method = orr.UserDefinedOperatorMethod;
                var inline = Emitter.GetInline(method);

                if (!string.IsNullOrWhiteSpace(inline))
                {
                    new InlineArgumentsBlock(Emitter, new ArgumentsInfo(Emitter, unaryOperatorExpression, orr, method), inline).Emit();
                    return(true);
                }
                else
                {
                    if (orr.IsLiftedOperator)
                    {
                        Write(JS.Types.SYSTEM_NULLABLE + "." + JS.Funcs.Math.LIFT + "(");
                    }

                    Write(H5Types.ToJsName(method.DeclaringType, Emitter));
                    WriteDot();

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

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

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

                    return(true);
                }
            }

            return(false);
        }
Exemple #3
0
        protected bool IsUserOperator(OperatorResolveResult orr)
        {
            var method = orr?.UserDefinedOperatorMethod;

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

                if (!string.IsNullOrWhiteSpace(inline))
                {
                    return(true);
                }
                else if (!Emitter.Validator.IsExternalType(method.DeclaringTypeDefinition))
                {
                    return(true);
                }
            }

            return(false);
        }
Exemple #4
0
        public IMethod GetCastMethod(IType fromType, IType toType, out string template)
        {
            string inline = null;
            var    method = fromType.GetMethods().FirstOrDefault(m =>
            {
                if (m.IsOperator && (m.Name == "op_Explicit" || m.Name == "op_Implicit") &&
                    m.Parameters.Count == 1 &&
                    m.ReturnType.ReflectionName == toType.ReflectionName &&
                    m.Parameters[0].Type.ReflectionName == fromType.ReflectionName
                    )
                {
                    inline = Emitter.GetInline(m);
                    return(true);
                }

                return(false);
            });

            if (method == null)
            {
                method = toType.GetMethods().FirstOrDefault(m =>
                {
                    if (m.IsOperator && (m.Name == "op_Explicit" || m.Name == "op_Implicit") &&
                        m.Parameters.Count == 1 &&
                        m.ReturnType.ReflectionName == toType.ReflectionName &&
                        (m.Parameters[0].Type.ReflectionName == fromType.ReflectionName)
                        )
                    {
                        inline = Emitter.GetInline(m);
                        return(true);
                    }

                    return(false);
                });
            }

            template = inline;
            return(method);
        }
Exemple #5
0
        private void HandleType(ResolveResult resolveOperator, string variable, string op_name, KnownTypeCode typeCode)
        {
            if (AssignmentExpression.Operator == AssignmentOperatorType.Assign)
            {
                if (variable != null)
                {
                    Write(variable);
                }
                else
                {
                    new ExpressionListBlock(Emitter, new Expression[] { AssignmentExpression.Right }, null, null, 0).Emit();
                }

                return;
            }

            var orr           = resolveOperator as OperatorResolveResult;
            var method        = orr?.UserDefinedOperatorMethod;
            var assigmentType = Helpers.TypeOfAssignment(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 = Emitter.GetInline(method);

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

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

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

                    WriteOpenParentheses();

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

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

                    Write(action);
                    WriteOpenParentheses();
                    WriteScript(op_name);
                    WriteComma();
                    if (variable != null)
                    {
                        new ExpressionListBlock(Emitter, new Expression[] { AssignmentExpression.Left }, null, null, 0).Emit();
                    }
                    else
                    {
                        new ExpressionListBlock(Emitter, new Expression[] { AssignmentExpression.Left, AssignmentExpression.Right }, null, null, 0).Emit();
                    }
                    AddOveflowFlag(typeCode, op_name);
                    WriteCloseParentheses();
                }
                else
                {
                    AssignmentExpression.Left.AcceptVisitor(Emitter);
                    WriteDot();
                    Write(op_name);
                    WriteOpenParentheses();
                    AssignmentExpression.Right.AcceptVisitor(Emitter);
                    AddOveflowFlag(typeCode, op_name);
                    WriteCloseParentheses();
                }
            }
        }
Exemple #6
0
        protected bool ResolveOperator(AssignmentExpression assignmentExpression, OperatorResolveResult orr, int initCount, bool thisAssignment)
        {
            var method = orr?.UserDefinedOperatorMethod;

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

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

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

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

                    if (orr.IsLiftedOperator)
                    {
                        Write(JS.Types.SYSTEM_NULLABLE + "." + JS.Funcs.Math.LIFT + ".(");
                    }

                    Write(H5Types.ToJsName(method.DeclaringType, Emitter));
                    WriteDot();

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

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

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

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

            return(false);
        }
Exemple #7
0
        protected void VisitAssignmentExpression()
        {
            AssignmentExpression assignmentExpression = AssignmentExpression;
            var    oldAssigment     = Emitter.IsAssignment;
            var    oldAssigmentType = Emitter.AssignmentType;
            string variable         = null;

            bool needReturnValue = !(assignmentExpression.Parent is ExpressionStatement);

            if (needReturnValue && assignmentExpression.Parent is LambdaExpression)
            {
                if (Emitter.Resolver.ResolveNode(assignmentExpression.Parent) is LambdaResolveResult lambdarr && lambdarr.ReturnType.Kind == TypeKind.Void)
                {
                    needReturnValue = false;
                }
            }

            var  delegateAssigment = false;
            bool isEvent           = false;
            var  initCount         = Emitter.Writers.Count;

            var asyncExpressionHandling = Emitter.AsyncExpressionHandling;

            WriteAwaiters(assignmentExpression.Left);
            WriteAwaiters(assignmentExpression.Right);

            var  leftResolverResult  = Emitter.Resolver.ResolveNode(assignmentExpression.Left);
            var  rightResolverResult = Emitter.Resolver.ResolveNode(assignmentExpression.Right);
            var  rr                = Emitter.Resolver.ResolveNode(assignmentExpression);
            var  orr               = rr as OperatorResolveResult;
            bool isDecimal         = Helpers.IsDecimalType(rr.Type, Emitter.Resolver);
            bool isLong            = Helpers.Is64Type(rr.Type, Emitter.Resolver);
            var  expectedType      = Emitter.Resolver.Resolver.GetExpectedType(assignmentExpression);
            bool isDecimalExpected = Helpers.IsDecimalType(expectedType, Emitter.Resolver);
            bool isLongExpected    = Helpers.Is64Type(expectedType, Emitter.Resolver);
            bool isUserOperator    = IsUserOperator(orr);

            var rrType = rr.Type;

            if (rrType.Kind == TypeKind.Enum)
            {
                rrType = rrType.GetDefinition().EnumUnderlyingType;
            }

            bool isUint = rrType.IsKnownType(KnownTypeCode.UInt16) ||
                          rrType.IsKnownType(KnownTypeCode.UInt32) ||
                          rrType.IsKnownType(KnownTypeCode.UInt64);

            if (!isLong && rr.Type.Kind == TypeKind.Enum && Helpers.Is64Type(rr.Type.GetDefinition().EnumUnderlyingType, Emitter.Resolver))
            {
                isLong = true;
            }

            if (!isLongExpected && expectedType.Kind == TypeKind.Enum && Helpers.Is64Type(expectedType.GetDefinition().EnumUnderlyingType, Emitter.Resolver))
            {
                isLongExpected = true;
            }

            var charToString = -1;

            if (orr != null && orr.Type.IsKnownType(KnownTypeCode.String))
            {
                for (int i = 0; i < orr.Operands.Count; i++)
                {
                    if (orr.Operands[i] is ConversionResolveResult crr && crr.Input.Type.IsKnownType(KnownTypeCode.Char))
                    {
                        charToString = i;
                    }
                }
            }

            var  memberTargetrr = leftResolverResult as MemberResolveResult;
            bool isField        = (memberTargetrr != null && memberTargetrr.Member is IField &&
                                   (memberTargetrr.TargetResult is ThisResolveResult ||
                                    memberTargetrr.TargetResult is LocalResolveResult)) || leftResolverResult is ThisResolveResult || leftResolverResult is LocalResolveResult || leftResolverResult is ConstantResolveResult;

            var  rightMemberTargetrr = rightResolverResult as MemberResolveResult;
            bool isRightSimple       = (rightMemberTargetrr != null && rightMemberTargetrr.Member is IField &&
                                        (rightMemberTargetrr.TargetResult is ThisResolveResult ||
                                         rightMemberTargetrr.TargetResult is LocalResolveResult)) || rightResolverResult is ThisResolveResult || rightResolverResult is LocalResolveResult || rightResolverResult is ConstantResolveResult;

            var needTempVar = needReturnValue && (!isRightSimple && !isField || assignmentExpression.Operator != AssignmentOperatorType.Assign);

            /*if (assignmentExpression.Operator == AssignmentOperatorType.Any)
             * {
             *  needTempVar = false;
             * }*/

            if (needReturnValue)
            {
                if (needTempVar)
                {
                    variable = GetTempVarName();
                    Write("(" + variable + " = ");

                    var oldValue1 = Emitter.ReplaceAwaiterByVar;
                    Emitter.ReplaceAwaiterByVar = true;
                    assignmentExpression.Right.AcceptVisitor(Emitter);

                    Emitter.ReplaceAwaiterByVar = oldValue1;
                    Write(", ");
                }
                else
                {
                    Write("(");
                }
            }

            if (assignmentExpression.Operator == AssignmentOperatorType.Divide && Emitter.Rules.Integer == IntegerRule.Managed &&
                !(Emitter.IsJavaScriptOverflowMode && !InsideOverflowContext(Emitter, assignmentExpression)) &&
                !isLong && !isLongExpected &&
                (
                    (Helpers.IsIntegerType(leftResolverResult.Type, Emitter.Resolver) &&
                     Helpers.IsIntegerType(rightResolverResult.Type, Emitter.Resolver)) ||

                    (Helpers.IsIntegerType(Emitter.Resolver.Resolver.GetExpectedType(assignmentExpression.Left), Emitter.Resolver) &&
                     Helpers.IsIntegerType(Emitter.Resolver.Resolver.GetExpectedType(assignmentExpression.Right), Emitter.Resolver))
                ))
            {
                Emitter.IsAssignment   = true;
                Emitter.AssignmentType = AssignmentOperatorType.Assign;
                var oldValue1 = Emitter.ReplaceAwaiterByVar;
                Emitter.ReplaceAwaiterByVar = true;
                AcceptLeftExpression(assignmentExpression.Left, memberTargetrr);

                if (Emitter.Writers.Count == initCount)
                {
                    Write(" = ");
                }

                Emitter.ReplaceAwaiterByVar = oldValue1;
                Emitter.AssignmentType      = oldAssigmentType;
                Emitter.IsAssignment        = oldAssigment;

                Write(JS.Types.H5_INT + "." + JS.Funcs.Math.DIV + "(");
                assignmentExpression.Left.AcceptVisitor(Emitter);
                Write(", ");
                oldValue1 = Emitter.ReplaceAwaiterByVar;
                Emitter.ReplaceAwaiterByVar = true;

                assignmentExpression.Right.AcceptVisitor(Emitter);

                Write(")");

                Emitter.ReplaceAwaiterByVar     = oldValue1;
                Emitter.AsyncExpressionHandling = asyncExpressionHandling;

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

                if (needReturnValue && !isField)
                {
                    if (needTempVar)
                    {
                        Write(", " + variable);
                    }
                    else
                    {
                        Write(", ");
                        Emitter.IsAssignment = false;
                        assignmentExpression.Right.AcceptVisitor(Emitter);
                        Emitter.IsAssignment = oldAssigment;
                    }
                }

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

                return;
            }

            if (assignmentExpression.Operator == AssignmentOperatorType.Multiply && Emitter.Rules.Integer == IntegerRule.Managed &&
                !(Emitter.IsJavaScriptOverflowMode && !InsideOverflowContext(Emitter, assignmentExpression)) &&
                !isLong && !isLongExpected &&
                (
                    (Helpers.IsInteger32Type(leftResolverResult.Type, Emitter.Resolver) &&
                     Helpers.IsInteger32Type(rightResolverResult.Type, Emitter.Resolver) &&
                     Helpers.IsInteger32Type(rr.Type, Emitter.Resolver)) ||

                    (Helpers.IsInteger32Type(Emitter.Resolver.Resolver.GetExpectedType(assignmentExpression.Left), Emitter.Resolver) &&
                     Helpers.IsInteger32Type(Emitter.Resolver.Resolver.GetExpectedType(assignmentExpression.Right), Emitter.Resolver) &&
                     Helpers.IsInteger32Type(rr.Type, Emitter.Resolver))
                ))
            {
                Emitter.IsAssignment   = true;
                Emitter.AssignmentType = AssignmentOperatorType.Assign;
                var oldValue1 = Emitter.ReplaceAwaiterByVar;
                Emitter.ReplaceAwaiterByVar = true;
                AcceptLeftExpression(assignmentExpression.Left, memberTargetrr);

                if (Emitter.Writers.Count == initCount)
                {
                    Write(" = ");
                }

                Emitter.ReplaceAwaiterByVar = oldValue1;
                Emitter.AssignmentType      = oldAssigmentType;
                Emitter.IsAssignment        = oldAssigment;

                isUint = NullableType.GetUnderlyingType(rr.Type).IsKnownType(KnownTypeCode.UInt32);
                Write(JS.Types.H5_INT + "." + (isUint ? JS.Funcs.Math.UMUL : JS.Funcs.Math.MUL) + "(");
                assignmentExpression.Left.AcceptVisitor(Emitter);
                Write(", ");
                oldValue1 = Emitter.ReplaceAwaiterByVar;
                Emitter.ReplaceAwaiterByVar = true;

                assignmentExpression.Right.AcceptVisitor(Emitter);

                if (IsInCheckedContext(Emitter, assignmentExpression))
                {
                    Write(", 1");
                }

                Write(")");

                Emitter.ReplaceAwaiterByVar     = oldValue1;
                Emitter.AsyncExpressionHandling = asyncExpressionHandling;

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

                if (needReturnValue && !isField)
                {
                    if (needTempVar)
                    {
                        Write(", " + variable);
                    }
                    else
                    {
                        Write(", ");
                        Emitter.IsAssignment = false;
                        assignmentExpression.Right.AcceptVisitor(Emitter);
                        Emitter.IsAssignment = oldAssigment;
                    }
                }

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

                return;
            }

            bool templateDelegateAssigment = false;

            if (assignmentExpression.Operator == AssignmentOperatorType.Add ||
                assignmentExpression.Operator == AssignmentOperatorType.Subtract)
            {
                var add = assignmentExpression.Operator == AssignmentOperatorType.Add;

                if (Emitter.Validator.IsDelegateOrLambda(leftResolverResult))
                {
                    delegateAssigment = true;

                    if (leftResolverResult is MemberResolveResult leftMemberResolveResult)
                    {
                        isEvent = leftMemberResolveResult.Member is IEvent;
                        Emitter.IsAssignment      = true;
                        Emitter.AssignmentType    = assignmentExpression.Operator;
                        templateDelegateAssigment = !string.IsNullOrWhiteSpace(Emitter.GetInline(leftMemberResolveResult.Member));
                        Emitter.IsAssignment      = false;
                    }

                    if (!isEvent)
                    {
                        Emitter.IsAssignment   = true;
                        Emitter.AssignmentType = AssignmentOperatorType.Assign;
                        AcceptLeftExpression(assignmentExpression.Left, memberTargetrr);
                        Emitter.IsAssignment = false;

                        if (Emitter.Writers.Count == initCount)
                        {
                            Write(" = ");
                        }

                        Write(add ? JS.Funcs.H5_COMBINE : JS.Funcs.H5_REMOVE);
                        WriteOpenParentheses();
                    }
                }
            }

            bool   nullable = orr != null && orr.IsLiftedOperator;
            string root     = JS.Types.SYSTEM_NULLABLE + ".";

            bool special = nullable;

            Emitter.IsAssignment   = true;
            Emitter.AssignmentType = assignmentExpression.Operator;
            var oldValue = Emitter.ReplaceAwaiterByVar;

            Emitter.ReplaceAwaiterByVar = true;

            bool thisAssignment = leftResolverResult is ThisResolveResult;

            if (!thisAssignment)
            {
                if (special || (isDecimal && isDecimalExpected) || (isLong && isLongExpected) || isUserOperator)
                {
                    Emitter.AssignmentType = AssignmentOperatorType.Assign;
                }

                if (delegateAssigment && !isEvent)
                {
                    Emitter.IsAssignment = false;
                }

                AcceptLeftExpression(assignmentExpression.Left, memberTargetrr);

                if (delegateAssigment)
                {
                    Emitter.IsAssignment = true;
                }
            }
            else
            {
                Write("(");
            }

            Emitter.ReplaceAwaiterByVar = oldValue;
            Emitter.AssignmentType      = oldAssigmentType;
            Emitter.IsAssignment        = oldAssigment;

            if (Emitter.Writers.Count == initCount && !delegateAssigment && !thisAssignment)
            {
                WriteSpace();
            }

            if (isDecimal && isDecimalExpected)
            {
                if (Emitter.Writers.Count == initCount)
                {
                    Write("= ");
                }

                oldValue = Emitter.ReplaceAwaiterByVar;
                Emitter.ReplaceAwaiterByVar = true;

                HandleDecimal(rr, variable);

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

                if (needTempVar)
                {
                    Write(", " + variable + ")");
                }
                else if (needReturnValue)
                {
                    if (!isField)
                    {
                        Write(", ");
                        Emitter.IsAssignment = false;
                        assignmentExpression.Right.AcceptVisitor(Emitter);
                        Emitter.IsAssignment = oldAssigment;
                    }

                    Write(")");
                }

                Emitter.ReplaceAwaiterByVar = oldValue;
                return;
            }

            if (isLong && isLongExpected)
            {
                if (Emitter.Writers.Count == initCount)
                {
                    Write("= ");
                }

                oldValue = Emitter.ReplaceAwaiterByVar;
                Emitter.ReplaceAwaiterByVar = true;

                HandleLong(rr, variable, isUint);

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

                if (needTempVar)
                {
                    Write(", " + variable + ")");
                }
                else if (needReturnValue)
                {
                    if (!isField)
                    {
                        Write(", ");
                        Emitter.IsAssignment = false;
                        assignmentExpression.Right.AcceptVisitor(Emitter);
                        Emitter.IsAssignment = oldAssigment;
                    }

                    Write(")");
                }
                Emitter.ReplaceAwaiterByVar = oldValue;
                return;
            }

            if (ResolveOperator(assignmentExpression, orr, initCount, thisAssignment))
            {
                if (thisAssignment)
                {
                    Write(")." + JS.Funcs.CLONE + "(this)");
                }
                else if (needReturnValue)
                {
                    Write(")");
                }
                return;
            }

            bool isBool = NullableType.IsNullable(rr.Type) ? NullableType.GetUnderlyingType(rr.Type).IsKnownType(KnownTypeCode.Boolean) : rr.Type.IsKnownType(KnownTypeCode.Boolean);

            if (!delegateAssigment)
            {
                if (!special)
                {
                    switch (assignmentExpression.Operator)
                    {
                    case AssignmentOperatorType.Assign:
                        break;

                    case AssignmentOperatorType.Add:
                        Write("+");
                        break;

                    case AssignmentOperatorType.BitwiseAnd:
                        if (!isBool)
                        {
                            Write("&");
                        }
                        break;

                    case AssignmentOperatorType.BitwiseOr:
                        if (!isBool)
                        {
                            Write("|");
                        }

                        break;

                    case AssignmentOperatorType.Divide:
                        Write("/");
                        break;

                    case AssignmentOperatorType.ExclusiveOr:
                        if (!isBool)
                        {
                            Write("^");
                        }
                        break;

                    case AssignmentOperatorType.Modulus:
                        Write("%");
                        break;

                    case AssignmentOperatorType.Multiply:
                        Write("*");
                        break;

                    case AssignmentOperatorType.ShiftLeft:
                        Write("<<");
                        break;

                    case AssignmentOperatorType.ShiftRight:
                        Write(isUint ? ">>>" : ">>");
                        break;

                    case AssignmentOperatorType.Subtract:
                        Write("-");
                        break;

                    default:
                        throw new EmitterException(assignmentExpression,
                                                   "Unsupported assignment operator: " + assignmentExpression.Operator.ToString());
                    }
                }

                if (special)
                {
                    if (Emitter.Writers.Count == initCount)
                    {
                        Write("= ");
                    }
                    Write(root);

                    switch (assignmentExpression.Operator)
                    {
                    case AssignmentOperatorType.Assign:
                        break;

                    case AssignmentOperatorType.Add:
                        Write(JS.Funcs.Math.ADD);
                        break;

                    case AssignmentOperatorType.BitwiseAnd:
                        Write(isBool ? JS.Funcs.Math.AND : JS.Funcs.Math.BAND);
                        break;

                    case AssignmentOperatorType.BitwiseOr:
                        Write(isBool ? JS.Funcs.Math.OR : JS.Funcs.Math.BOR);
                        break;

                    case AssignmentOperatorType.Divide:
                        Write(JS.Funcs.Math.DIV);
                        break;

                    case AssignmentOperatorType.ExclusiveOr:
                        Write(JS.Funcs.Math.XOR);
                        break;

                    case AssignmentOperatorType.Modulus:
                        Write(JS.Funcs.Math.MOD);
                        break;

                    case AssignmentOperatorType.Multiply:
                        Write(JS.Funcs.Math.MUL);
                        break;

                    case AssignmentOperatorType.ShiftLeft:
                        Write(JS.Funcs.Math.SL);
                        break;

                    case AssignmentOperatorType.ShiftRight:
                        Write(isUint ? JS.Funcs.Math.SRR : JS.Funcs.Math.SR);
                        break;

                    case AssignmentOperatorType.Subtract:
                        Write(JS.Funcs.Math.SUB);
                        break;

                    default:
                        throw new EmitterException(assignmentExpression,
                                                   "Unsupported assignment operator: " + assignmentExpression.Operator.ToString());
                    }

                    WriteOpenParentheses();

                    assignmentExpression.Left.AcceptVisitor(Emitter);
                    Write(", ");
                }

                if (Emitter.Writers.Count == initCount && !thisAssignment && !special)
                {
                    Write("= ");
                }
            }
            else if (!isEvent)
            {
                WriteComma();
            }

            if (!special && isBool && (assignmentExpression.Operator == AssignmentOperatorType.BitwiseAnd || assignmentExpression.Operator == AssignmentOperatorType.BitwiseOr || assignmentExpression.Operator == AssignmentOperatorType.ExclusiveOr))
            {
                if (assignmentExpression.Operator != AssignmentOperatorType.ExclusiveOr)
                {
                    Write("!!(");
                }

                assignmentExpression.Left.AcceptVisitor(Emitter);

                string op = null;
                switch (assignmentExpression.Operator)
                {
                case AssignmentOperatorType.BitwiseAnd:
                    op = " & ";
                    break;

                case AssignmentOperatorType.BitwiseOr:
                    op = " | ";
                    break;

                case AssignmentOperatorType.ExclusiveOr:
                    op = " != ";
                    break;
                }
                Write(op);
            }

            oldValue = Emitter.ReplaceAwaiterByVar;
            Emitter.ReplaceAwaiterByVar = true;

            if (charToString == 1)
            {
                Write(JS.Funcs.STRING_FROMCHARCODE + "(");
            }

            if (needTempVar)
            {
                int pos = Emitter.Output.Length;
                Write(variable);
                Helpers.CheckValueTypeClone(rr, assignmentExpression.Right, this, pos);
            }
            else
            {
                var wrap = assignmentExpression.Operator != AssignmentOperatorType.Assign &&
                           Emitter.Writers.Count > initCount &&
                           !AssigmentExpressionHelper.CheckIsRightAssigmentExpression(assignmentExpression);

                if (wrap)
                {
                    WriteOpenParentheses();
                }

                assignmentExpression.Right.AcceptVisitor(Emitter);

                if (wrap)
                {
                    WriteCloseParentheses();
                }
            }

            if (!special && isBool &&
                (assignmentExpression.Operator == AssignmentOperatorType.BitwiseAnd ||
                 assignmentExpression.Operator == AssignmentOperatorType.BitwiseOr))
            {
                WriteCloseParentheses();
            }

            if (charToString == 1)
            {
                WriteCloseParentheses();
            }

            if (special)
            {
                WriteCloseParentheses();
            }

            if (thisAssignment)
            {
                Write(")." + JS.Funcs.CLONE + "(this)");
            }

            Emitter.ReplaceAwaiterByVar     = oldValue;
            Emitter.AsyncExpressionHandling = asyncExpressionHandling;

            if (Emitter.Writers.Count > initCount)
            {
                var writerCount = Emitter.Writers.Count;
                for (int i = initCount; i < writerCount; i++)
                {
                    PopWriter();
                }
            }

            if (delegateAssigment && !templateDelegateAssigment)
            {
                WriteCloseParentheses();
            }

            if (needTempVar)
            {
                Write(", " + variable + ")");
            }
            else if (needReturnValue)
            {
                if (!isField)
                {
                    Write(", ");
                    Emitter.IsAssignment = false;
                    assignmentExpression.Right.AcceptVisitor(Emitter);
                    Emitter.IsAssignment = oldAssigment;
                }

                Write(")");
            }
        }
Exemple #8
0
        private void HandleType(ResolveResult resolveOperator, KnownTypeCode typeCode, string op_name, string action)
        {
            var orr    = resolveOperator as OperatorResolveResult;
            var method = orr?.UserDefinedOperatorMethod;

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

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

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

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

                    WriteOpenParentheses();

                    new ExpressionListBlock(Emitter,
                                            new Expression[] { BinaryOperatorExpression.Left, BinaryOperatorExpression.Right }, null, null, 0)
                    .Emit();
                    AddOveflowFlag(typeCode, op_name);
                    WriteCloseParentheses();
                }
            }
            else
            {
                if (orr.IsLiftedOperator)
                {
                    Write(JS.Types.SYSTEM_NULLABLE + ".");
                    Write(action);
                    WriteOpenParentheses();
                    WriteScript(op_name);
                    WriteComma();
                    new ExpressionListBlock(Emitter,
                                            new Expression[] { BinaryOperatorExpression.Left, BinaryOperatorExpression.Right }, null, null, 0)
                    .Emit();
                    AddOveflowFlag(typeCode, op_name);
                    WriteCloseParentheses();
                }
                else
                {
                    BinaryOperatorExpression.Left.AcceptVisitor(Emitter);
                    WriteDot();
                    Write(op_name);
                    WriteOpenParentheses();
                    BinaryOperatorExpression.Right.AcceptVisitor(Emitter);
                    AddOveflowFlag(typeCode, op_name);
                    WriteCloseParentheses();
                }
            }
        }
Exemple #9
0
        protected void VisitForeachStatement(bool?replaceAwaiterByVar = null)
        {
            ForeachStatement foreachStatement = ForeachStatement;
            var jumpStatements = Emitter.JumpStatements;

            Emitter.JumpStatements = null;

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

            WriteSourceMapName(foreachStatement.VariableName);
            var iteratorVar  = GetTempVarName();
            var iteratorName = AddLocal(iteratorVar, null, AstType.Null);

            var rr     = (ForEachResolveResult)Emitter.Resolver.ResolveNode(foreachStatement);
            var get_rr = rr.GetEnumeratorCall as InvocationResolveResult;
            var in_rr  = Emitter.Resolver.ResolveNode(foreachStatement.InExpression);
            var inline = get_rr != null?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;

            Write(iteratorName, " = ");

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

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

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

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

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

            PushLocals();
            Action ac = () =>
            {
                bool isReferenceLocal = false;

                if (Emitter.LocalsMap != null && Emitter.LocalsMap.ContainsKey(rr.ElementVariable))
                {
                    isReferenceLocal = Emitter.LocalsMap[rr.ElementVariable].EndsWith(".v");
                }

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

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

                if (isReferenceLocal)
                {
                    Write("{ v : ");
                }

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

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

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

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

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

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

                WriteSemiColon();
                WriteNewLine();
            };

            Emitter.BeforeBlock = ac;


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

            if (foreachStatement.EmbeddedStatement is BlockStatement block)
            {
                Emitter.NoBraceBlock = block;
            }

            foreachStatement.EmbeddedStatement.AcceptVisitor(Emitter);

            PopLocals();

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

            EndBlock();
            WriteNewLine();

            EndBlock();
            WriteSpace();
            WriteFinally();
            BeginBlock();
            Write($"if ({JS.Types.H5.IS}({iteratorName}, {JS.Types.System.IDisposable.NAME})) ");
            BeginBlock();
            Write($"{iteratorName}.{JS.Types.System.IDisposable.INTERFACE_DISPOSE}();");
            WriteNewLine();
            EndBlock();
            WriteNewLine();
            EndBlock();
            WriteNewLine();
            Emitter.JumpStatements = jumpStatements;
        }
Exemple #10
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);
        }
Exemple #11
0
        private void BuildArgumentsList(IList <Expression> arguments)
        {
            Expression paramsArg     = null;
            string     paramArgName  = null;
            var        resolveResult = ResolveResult;

            if (resolveResult != null)
            {
                var parameters = resolveResult.Member.Parameters;
                var isDelegate = resolveResult.Member.DeclaringType.Kind == TypeKind.Delegate;
                int shift      = 0;

                if (resolveResult.Member is IMethod resolvedMethod && resolveResult is CSharpInvocationResolveResult invocationResult &&
                    resolvedMethod.IsExtensionMethod && invocationResult.IsExtensionMethodInvocation)
                {
                    shift             = 1;
                    ThisName          = resolvedMethod.Parameters[0].Name;
                    IsExtensionMethod = true;
                }

                Expression[] result            = new Expression[parameters.Count - shift];
                string[]     names             = new string[result.Length];
                bool         named             = false;
                int          i                 = 0;
                bool         isInterfaceMember = false;

                if (resolveResult.Member != null)
                {
                    var inlineStr = Emitter.GetInline(resolveResult.Member);
                    named = !string.IsNullOrEmpty(inlineStr);

                    isInterfaceMember = resolveResult.Member.DeclaringTypeDefinition != null &&
                                        resolveResult.Member.DeclaringTypeDefinition.Kind == TypeKind.Interface;
                }

                var expandParams = resolveResult.Member.Attributes.Any(a => a.AttributeType.FullName == "H5.ExpandParamsAttribute");

                foreach (var arg in arguments)
                {
                    if (arg is NamedArgumentExpression namedArg)
                    {
                        var namedParam = parameters.First(p => p.Name == namedArg.Name);
                        var index      = parameters.IndexOf(namedParam) - shift;

                        result[index] = namedArg.Expression;
                        names[index]  = namedArg.Name;
                        named         = true;

                        if (paramsArg == null && parameters.FirstOrDefault(p => p.Name == namedArg.Name).IsParams)
                        {
                            if (resolveResult.Member.DeclaringTypeDefinition == null || !Emitter.Validator.IsExternalType(resolveResult.Member.DeclaringTypeDefinition))
                            {
                                paramsArg = namedArg.Expression;
                            }

                            paramArgName = namedArg.Name;
                        }
                    }
                    else
                    {
                        if (paramsArg == null && (parameters.Count > (i + shift)) && parameters[i + shift].IsParams)
                        {
                            if (resolveResult.Member.DeclaringTypeDefinition == null || !Emitter.Validator.IsExternalType(resolveResult.Member.DeclaringTypeDefinition) || expandParams)
                            {
                                paramsArg = arg;
                            }

                            paramArgName = parameters[i + shift].Name;
                        }

                        if (i >= result.Length)
                        {
                            var list = result.ToList();
                            list.AddRange(new Expression[arguments.Count - i]);

                            var strList = names.ToList();
                            strList.AddRange(new string[arguments.Count - i]);

                            result = list.ToArray();
                            names  = strList.ToArray();
                        }

                        result[i] = arg;
                        names[i]  = (i + shift) < parameters.Count ? parameters[i + shift].Name : paramArgName;
                    }

                    i++;
                }

                for (i = 0; i < result.Length; i++)
                {
                    if (result[i] == null)
                    {
                        var    p = parameters[i + shift];
                        object t = null;
                        if (p.Type.Kind == TypeKind.Enum)
                        {
                            t = Helpers.GetEnumValue(Emitter, p.Type, p.ConstantValue);
                        }
                        else
                        {
                            t = p.ConstantValue;
                        }
                        if ((named || isInterfaceMember || isDelegate) && !p.IsParams)
                        {
                            if (t == null)
                            {
                                result[i] = new PrimitiveExpression(new RawValue("void 0"));
                            }
                            else
                            {
                                result[i] = new PrimitiveExpression(t);
                            }
                        }

                        names[i] = parameters[i + shift].Name;
                    }
                }

                ArgumentsExpressions = result;
                ArgumentsNames       = names;
                ParamsExpression     = paramsArg;
                NamedExpressions     = CreateNamedExpressions(names, result);
            }
            else
            {
                ArgumentsExpressions = arguments.ToArray();
            }
        }
Exemple #12
0
        private void BuildDynamicArgumentsList(DynamicInvocationResolveResult drr, IList <Expression> arguments)
        {
            Expression paramsArg    = null;
            string     paramArgName = null;
            IMethod    method       = null;

            if (drr.Target is MethodGroupResolveResult group && group.Methods.Count() > 1)
            {
                method = group.Methods.FirstOrDefault(m =>
                {
                    if (drr.Arguments.Count != m.Parameters.Count)
                    {
                        return(false);
                    }

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

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

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

                    return(true);
                });

                if (method == null)
                {
                    throw new EmitterException(Expression, Constants.Messages.Exceptions.DYNAMIC_INVOCATION_TOO_MANY_OVERLOADS);
                }
            }

            if (method != null)
            {
                var member     = method;
                var parameters = method.Parameters;

                Expression[] result            = new Expression[parameters.Count];
                string[]     names             = new string[result.Length];
                bool         named             = false;
                int          i                 = 0;
                bool         isInterfaceMember = false;

                if (member != null)
                {
                    var inlineStr = Emitter.GetInline(member);
                    named = !string.IsNullOrEmpty(inlineStr);

                    isInterfaceMember = member.DeclaringTypeDefinition != null &&
                                        member.DeclaringTypeDefinition.Kind == TypeKind.Interface;
                }

                foreach (var arg in arguments)
                {
                    if (arg is NamedArgumentExpression namedArg)
                    {
                        var namedParam = parameters.First(p => p.Name == namedArg.Name);
                        var index      = parameters.IndexOf(namedParam);

                        result[index] = namedArg.Expression;
                        names[index]  = namedArg.Name;
                        named         = true;

                        if (paramsArg == null && (parameters.Count > i) && parameters[i].IsParams)
                        {
                            if (member.DeclaringTypeDefinition == null || !Emitter.Validator.IsExternalType(member.DeclaringTypeDefinition))
                            {
                                paramsArg = namedArg.Expression;
                            }

                            paramArgName = namedArg.Name;
                        }
                    }
                    else
                    {
                        if (paramsArg == null && (parameters.Count > i) && parameters[i].IsParams)
                        {
                            if (member.DeclaringTypeDefinition == null || !Emitter.Validator.IsExternalType(member.DeclaringTypeDefinition))
                            {
                                paramsArg = arg;
                            }

                            paramArgName = parameters[i].Name;
                        }

                        if (i >= result.Length)
                        {
                            var list = result.ToList();
                            list.AddRange(new Expression[arguments.Count - i]);

                            var strList = names.ToList();
                            strList.AddRange(new string[arguments.Count - i]);

                            result = list.ToArray();
                            names  = strList.ToArray();
                        }

                        result[i] = arg;
                        names[i]  = i < parameters.Count ? parameters[i].Name : paramArgName;
                    }

                    i++;
                }

                for (i = 0; i < result.Length; i++)
                {
                    if (result[i] == null)
                    {
                        var    p = parameters[i];
                        object t = null;
                        if (p.Type.Kind == TypeKind.Enum)
                        {
                            t = Helpers.GetEnumValue(Emitter, p.Type, p.ConstantValue);
                        }
                        else
                        {
                            t = p.ConstantValue;
                        }
                        if ((named || isInterfaceMember) && !p.IsParams)
                        {
                            if (t == null)
                            {
                                result[i] = new PrimitiveExpression(new RawValue("void 0"));
                            }
                            else
                            {
                                result[i] = new PrimitiveExpression(t);
                            }
                        }

                        names[i] = parameters[i].Name;
                    }
                }

                ArgumentsExpressions = result;
                ArgumentsNames       = names;
                ParamsExpression     = paramsArg;
                NamedExpressions     = CreateNamedExpressions(names, result);
            }
            else
            {
                ArgumentsExpressions = arguments.ToArray();
            }
        }
Exemple #13
0
        public IMethod GetCastMethod(IType fromType, IType toType, out string template)
        {
            string inline = null;
            var    method = fromType.GetMethods().FirstOrDefault(m =>
            {
                if (m.IsOperator && (m.Name == "op_Explicit" || m.Name == "op_Implicit") &&
                    m.Parameters.Count == 1 &&
                    m.ReturnType.ReflectionName == toType.ReflectionName &&
                    m.Parameters[0].Type.ReflectionName == fromType.ReflectionName
                    )
                {
                    string tmpInline = Emitter.GetInline(m);

                    if (!string.IsNullOrWhiteSpace(tmpInline))
                    {
                        inline = tmpInline;
                        return(true);
                    }
                }

                return(false);
            });

            if (method == null)
            {
                method = toType.GetMethods().FirstOrDefault(m =>
                {
                    if (m.IsOperator && (m.Name == "op_Explicit" || m.Name == "op_Implicit") &&
                        m.Parameters.Count == 1 &&
                        m.ReturnType.ReflectionName == toType.ReflectionName &&
                        (m.Parameters[0].Type.ReflectionName == fromType.ReflectionName)
                        )
                    {
                        string tmpInline = Emitter.GetInline(m);

                        if (!string.IsNullOrWhiteSpace(tmpInline))
                        {
                            inline = tmpInline;
                            return(true);
                        }
                    }

                    return(false);
                });
            }

            if (method == null && CastExpression != null)
            {
                var conversion = Emitter.Resolver.Resolver.GetConversion(CastExpression);

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

                    string tmpInline = Emitter.GetInline(method);

                    if (!string.IsNullOrWhiteSpace(tmpInline))
                    {
                        inline = tmpInline;
                    }
                }
            }

            template = inline;
            return(method);
        }
Exemple #14
0
        protected virtual void EmitMethods(Dictionary <string, List <MethodDeclaration> > methods, Dictionary <string, List <EntityDeclaration> > properties, Dictionary <OperatorType, List <OperatorDeclaration> > operators)
        {
            int pos        = Emitter.Output.Length;
            var writerInfo = SaveWriter();

            string globalTarget = H5Types.GetGlobalTarget(TypeInfo.Type.GetDefinition(), TypeInfo.TypeDeclaration);

            if (globalTarget == null)
            {
                EnsureComma();
                Write(JS.Fields.METHODS);
                WriteColon();
                BeginBlock();
            }

            int checkPos = Emitter.Output.Length;

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

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

                foreach (var prop in props)
                {
                    if (prop is PropertyDeclaration)
                    {
                        Emitter.VisitPropertyDeclaration((PropertyDeclaration)prop);
                    }
                    else if (prop is CustomEventDeclaration)
                    {
                        Emitter.VisitCustomEventDeclaration((CustomEventDeclaration)prop);
                    }
                    else if (prop is IndexerDeclaration)
                    {
                        Emitter.VisitIndexerDeclaration((IndexerDeclaration)prop);
                    }
                }
            }

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

            foreach (var name in names)
            {
                EmitMethodsGroup(methods[name]);
            }

            if (operators != null)
            {
                var ops = new List <OperatorType>(operators.Keys);

                foreach (var op in ops)
                {
                    EmitOperatorGroup(operators[op]);
                }
            }

            if (TypeInfo.ClassType == ClassType.Struct)
            {
                if (!StaticBlock)
                {
                    EmitStructMethods();
                }
                else
                {
                    string structName = H5Types.ToJsName(TypeInfo.Type, Emitter);
                    if (TypeInfo.Type.TypeArguments.Count > 0 &&
                        !Helpers.IsIgnoreGeneric(TypeInfo.Type, Emitter))
                    {
                        structName = "(" + structName + ")";
                    }

                    EnsureComma();
                    Write(JS.Funcs.GETDEFAULTVALUE + ": function () { return new " + structName + "(); }");
                    Emitter.Comma = true;
                }
            }
            else if (StaticBlock)
            {
                var ctor = TypeInfo.Type.GetConstructors().FirstOrDefault(c => c.Parameters.Count == 0 && Emitter.GetInline(c) != null);

                if (ctor != null)
                {
                    var code = Emitter.GetInline(ctor);
                    EnsureComma();
                    Write(JS.Funcs.GETDEFAULTVALUE + ": function () ");
                    BeginBlock();
                    Write("return ");
                    var argsInfo = new ArgumentsInfo(Emitter, ctor);
                    new InlineArgumentsBlock(Emitter, argsInfo, code).Emit();
                    Write(";");
                    WriteNewLine();
                    EndBlock();
                    Emitter.Comma = true;
                }
            }

            if (globalTarget == null)
            {
                if (checkPos == Emitter.Output.Length)
                {
                    Emitter.IsNewLine = writerInfo.IsNewLine;
                    Emitter.ResetLevel(writerInfo.Level);
                    Emitter.Comma         = writerInfo.Comma;
                    Emitter.Output.Length = pos;
                }
                else
                {
                    WriteNewLine();
                    EndBlock();
                }
            }
        }
Exemple #15
0
        protected void VisitObjectCreateExpression()
        {
            ObjectCreateExpression objectCreateExpression = ObjectCreateExpression;

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

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

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

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

                return;
            }

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

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

                if (wrap)
                {
                    WriteOpenParentheses();
                }

                Write("H5.fn.$build([");
                objectCreateExpression.Arguments.First().AcceptVisitor(Emitter);
                Write("])");

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

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

            string inlineCode = null;

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

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

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

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

            AstNodeCollection <Expression> elements = null;

            if (hasInitializer)
            {
                elements = objectCreateExpression.Initializer.Elements;
            }

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

            if (inlineCode == null && isPlainObjectCtor && isPlainMode)
            {
                WriteOpenBrace();
                WriteSpace();
                var pos = Emitter.Output.Length;

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

                if (pos < Emitter.Output.Length)
                {
                    WriteSpace();
                }

                WriteCloseBrace();
            }
            else
            {
                string tempVar = null;
                if (hasInitializer)
                {
                    tempVar = GetTempVarName();
                    WriteOpenParentheses();
                    Write(tempVar);
                    Write(" = ");
                }

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

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

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

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

                        var typerr    = Emitter.Resolver.ResolveNode(objectCreateExpression.Type).Type;
                        var td        = typerr.GetDefinition();
                        var isGeneric = typerr.TypeArguments.Count > 0 && !Helpers.IsIgnoreGeneric(typerr, Emitter) || td != null && Validator.IsVirtualTypeStatic(td);

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

                        objectCreateExpression.Type.AcceptVisitor(Emitter);

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

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

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

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

                if (hasInitializer)
                {
                    if (isObjectLiteral && isPlainMode)
                    {
                        WriteObjectInitializer(objectCreateExpression.Initializer.Elements, type, invocationResolveResult, true);
                    }
                    else
                    {
                        foreach (Expression item in elements)
                        {
                            WriteInitializerExpression(item, tempVar);
                        }
                    }

                    WriteComma();
                    Write(tempVar);
                    WriteCloseParentheses();
                    RemoveTempVar(tempVar);
                }
            }

            //Helpers.CheckValueTypeClone(invocationResolveResult, this.ObjectCreateExpression, this, pos);
        }
Exemple #16
0
        protected void VisitAsyncForeachStatement()
        {
            ForeachStatement foreachStatement = ForeachStatement;

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

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

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

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

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

            Emitter.ReplaceAwaiterByVar = true;

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

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

            var for_rr = (ForEachResolveResult)Emitter.Resolver.ResolveNode(foreachStatement);
            var get_rr = for_rr.GetEnumeratorCall as InvocationResolveResult;
            var in_rr  = Emitter.Resolver.ResolveNode(foreachStatement.InExpression);
            var inline = get_rr != null?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;

            Write(iteratorName, " = ");

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

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

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

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

            IAsyncStep conditionStep = Emitter.AsyncBlock.AddAsyncStep();

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

            PushLocals();

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

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

            var rr = Emitter.Resolver.ResolveNode(foreachStatement) as ForEachResolveResult;

            bool isReferenceLocal = false;

            if (Emitter.LocalsMap != null && Emitter.LocalsMap.ContainsKey(rr.ElementVariable))
            {
                isReferenceLocal = Emitter.LocalsMap[rr.ElementVariable].EndsWith(".v");
            }

            if (isReferenceLocal)
            {
                Write("{ v : ");
            }

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

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

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

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

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

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

            WriteSemiColon();
            WriteNewLine();

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


            var writer = SaveWriter();

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

            if (foreachStatement.EmbeddedStatement is BlockStatement block)
            {
                block.AcceptChildren(Emitter);
            }
            else
            {
                foreachStatement.EmbeddedStatement.AcceptVisitor(Emitter);
            }

            IAsyncStep loopStep = null;

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

            RestoreWriter(writer);

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

            PopLocals();

            WriteNewLine();
            EndBlock();
            WriteNewLine();

            var nextStep = Emitter.AsyncBlock.AddAsyncStep();

            conditionStep.JumpToStep = nextStep.Step;

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

            Emitter.JumpStatements = jumpStatements;
        }
        protected virtual void EmitIndexerMethod(IndexerDeclaration indexerDeclaration, IProperty prop, Accessor accessor, IMethod propAccessor, bool setter)
        {
            var isIgnore = propAccessor != null && Emitter.Validator.IsExternalType(propAccessor);

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

                ResetLocals();

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

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

                XmlToJsDoc.EmitComment(this, IndexerDeclaration, !setter);

                string accName = null;

                if (prop != null)
                {
                    accName = Emitter.GetEntityNameFromAttr(prop, setter);

                    if (string.IsNullOrEmpty(accName))
                    {
                        var member_rr = (MemberResolveResult)Emitter.Resolver.ResolveNode(indexerDeclaration);

                        var overloads = OverloadsCollection.Create(Emitter, indexerDeclaration, setter);
                        accName = overloads.GetOverloadName(false, Helpers.GetSetOrGet(setter), OverloadsCollection.ExcludeTypeParameterForDefinition(member_rr));
                    }
                }

                Write(accName);
                WriteColon();
                WriteFunction();
                EmitMethodParameters(indexerDeclaration.Parameters, null, indexerDeclaration, setter);

                if (setter)
                {
                    Write(", value)");
                }
                WriteSpace();

                var script = Emitter.GetScript(accessor);

                if (script == null)
                {
                    if (YieldBlock.HasYield(accessor.Body))
                    {
                        new GeneratorBlock(Emitter, accessor).Emit();
                    }
                    else
                    {
                        accessor.Body.AcceptVisitor(Emitter);
                    }
                }
                else
                {
                    BeginBlock();

                    WriteLines(script);

                    EndBlock();
                }

                ClearLocalsMap(prevMap);
                ClearLocalsNamesMap(prevNamesMap);
                Emitter.Comma = true;
            }
        }
Exemple #18
0
        protected void VisitIdentifierExpression()
        {
            IdentifierExpression identifierExpression = IdentifierExpression;
            int           pos           = Emitter.Output.Length;
            ResolveResult resolveResult = null;

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

            resolveResult = Emitter.Resolver.ResolveNode(identifierExpression);

            var id = identifierExpression.Identifier;

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

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

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

                return;
            }

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

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

                return;
            }

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

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

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

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

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

            bool hasInline = !string.IsNullOrEmpty(inlineCode);

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

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

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

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

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

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

                int[] range = null;

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

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

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

                return;
            }

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

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

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

                return;
            }

            string appendAdditionalCode = null;

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

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

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

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

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

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

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

                    if (!isStatement)
                    {
                        WriteOpenParentheses();

                        valueVar = GetTempVarName();

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

                WriteTarget(memberResult);

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

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

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

                                    WriteComma();

                                    WriteTarget(memberResult);

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

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

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

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

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

                                Write("1");
                            }

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

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

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

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

                                    WriteDot();

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

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

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

                                Write("1");
                            }

                            WriteCloseParentheses();
                            WriteComma();

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

                            WriteCloseParentheses();

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

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

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

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

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

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

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

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

            Helpers.CheckValueTypeClone(resolveResult, identifierExpression, this, pos);
        }
Exemple #19
0
        private void EmitExternalBaseCtor(ConstructorDeclaration ctor, ref bool requireNewLine)
        {
            IMember member         = null;
            var     hasInitializer = ctor.Initializer != null && !ctor.Initializer.IsNull;
            var     baseType       = Emitter.GetBaseTypeDefinition();

            if (hasInitializer)
            {
                member = ((InvocationResolveResult)Emitter.Resolver.ResolveNode(ctor.Initializer)).Member;
            }

            if (member != null)
            {
                var inlineCode = Emitter.GetInline(member);

                if (!string.IsNullOrEmpty(inlineCode))
                {
                    if (requireNewLine)
                    {
                        WriteNewLine();
                        requireNewLine = false;
                    }

                    Write(JS.Types.H5.APPLY);
                    WriteOpenParentheses();

                    Write("this, ");
                    var argsInfo = new ArgumentsInfo(Emitter, ctor.Initializer);
                    new InlineArgumentsBlock(Emitter, argsInfo, inlineCode).Emit();
                    WriteCloseParentheses();
                    WriteSemiColon();
                    WriteNewLine();

                    return;
                }
            }

            if (hasInitializer || (baseType.FullName != "System.Object" && baseType.FullName != "System.ValueType" && baseType.FullName != "System.Enum" && !baseType.CustomAttributes.Any(a => a.AttributeType.FullName == "H5.NonScriptableAttribute") && !baseType.IsInterface))
            {
                if (requireNewLine)
                {
                    WriteNewLine();
                    requireNewLine = false;
                }


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

                Write(name);
                WriteCall();
                int openPos = Emitter.Output.Length;
                WriteOpenParentheses();
                Write("this");

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

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

                WriteCloseParentheses();
                WriteSemiColon();
                WriteNewLine();
            }
        }
Exemple #20
0
        protected void VisitInvocationExpression()
        {
            InvocationExpression invocationExpression = InvocationExpression;
            int pos = Emitter.Output.Length;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                        return;
                    }
                }
            }

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

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

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

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

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

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

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

                            return;
                        }
                    }

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

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

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

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

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

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

                                    Emitter.Comma = false;

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

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

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

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

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

                                    WriteCloseParentheses();
                                }

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

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

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

                                return;
                            }
                        }
                    }
                }
            }

            var proto = false;

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

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

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

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

                bool needComma = false;

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

                string name = null;

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

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

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

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

                needComma = false;

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

                    EnsureComma(false);

                    if (needComma)
                    {
                        WriteComma();
                    }

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

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

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

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

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

                            return(true);
                        });

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

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

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

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

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

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

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

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

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

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

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

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

                    bool isIgnoreGeneric = false;

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

                    bool isWrapRest = false;

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

                        Write(thisArg);

                        Emitter.Comma = true;

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

                        EnsureComma(false);

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

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

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

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


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

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

            Emitter.ReplaceAwaiterByVar     = oldValue;
            Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;
        }
Exemple #21
0
        private void WritePart(Expression expression, bool toString, ResolveResult rr, bool isCoalescing = false)
        {
            if (isCoalescing)
            {
                expressionInWork.Add(expression);
            }

            bool wrapString = false;

            if (NullStringCheck && rr.Type.IsKnownType(KnownTypeCode.String))
            {
                wrapString = !(expression is BinaryOperatorExpression) && !(expression is PrimitiveExpression || rr.Type.IsReferenceType != null && !rr.Type.IsReferenceType.Value);
            }

            if (toString)
            {
                var toStringMethod = rr.Type.GetMembers().FirstOrDefault(m =>
                {
                    if (m.Name == CS.Methods.TOSTRING && !m.IsStatic && m.ReturnType.IsKnownType(KnownTypeCode.String) && m.IsOverride)
                    {
                        if (m is IMethod method && method.Parameters.Count == 0 && method.TypeParameters.Count == 0)
                        {
                            return(true);
                        }
                    }

                    return(false);
                });

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

                    if (inline != null)
                    {
                        var writer = new Writer
                        {
                            InlineCode = inline,
                            Output     = Emitter.Output,
                            IsNewLine  = Emitter.IsNewLine
                        };
                        Emitter.IsNewLine = false;
                        Emitter.Output    = new StringBuilder();

                        expression.AcceptVisitor(Emitter);

                        string result = Emitter.Output.ToString();
                        Emitter.Output    = writer.Output;
                        Emitter.IsNewLine = writer.IsNewLine;

                        var argsInfo = new ArgumentsInfo(Emitter, expression, (IMethod)toStringMethod);
                        argsInfo.ArgumentsExpressions = new Expression[] { expression };
                        argsInfo.ArgumentsNames       = new string[] { "this" };
                        argsInfo.ThisArgument         = result;
                        new InlineArgumentsBlock(Emitter, argsInfo, writer.InlineCode).Emit();
                        return;
                    }
                }
            }

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

            expression.AcceptVisitor(Emitter);

            if (wrapString)
            {
                Write(" || \"\")");
            }

            if (isCoalescing)
            {
                expressionInWork.Remove(expression);
            }
        }
        public virtual void EmitPropertyMethod(PropertyDeclaration propertyDeclaration, Accessor accessor, IMethod method, bool setter, bool isObjectLiteral)
        {
            if ((!accessor.IsNull || method != null && Helpers.IsScript(method)) && Emitter.GetInline(accessor) == null)
            {
                EnsureComma();

                ResetLocals();

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

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

                //XmlToJsDoc.EmitComment(this, this.PropertyDeclaration);

                Write(setter ? JS.Funcs.Property.SET : JS.Funcs.Property.GET);

                WriteColon();
                WriteFunction();

                var m_rr = (MemberResolveResult)Emitter.Resolver.ResolveNode(propertyDeclaration);

                WriteOpenParentheses();
                Write(setter ? "value" : "");
                WriteCloseParentheses();
                WriteSpace();

                var script = Emitter.GetScript(accessor);

                if (script == null)
                {
                    if (YieldBlock.HasYield(accessor.Body))
                    {
                        new GeneratorBlock(Emitter, accessor).Emit();
                    }
                    else
                    {
                        accessor.Body.AcceptVisitor(Emitter);
                    }
                }
                else
                {
                    BeginBlock();

                    WriteLines(script);

                    EndBlock();
                }

                ClearLocalsMap(prevMap);
                ClearLocalsNamesMap(prevNamesMap);
                Emitter.Comma = true;
            }
        }
Exemple #23
0
        protected override void DoEmit()
        {
            IAttribute attribute = Attribute;

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

            var argsInfo = new ArgumentsInfo(Emitter, attribute);

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

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

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

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

                WriteCloseBrace();
            }
            else
            {
                if (hasInitializer)
                {
                    Write(JS.Types.H5.APPLY);
                    WriteOpenParentheses();
                }

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

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

                    WriteOpenParentheses();

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

                if (hasInitializer)
                {
                    WriteComma();

                    BeginBlock();

                    var inlineInit = WriteObjectInitializer(attribute.NamedArguments, type, attribute);

                    WriteNewLine();

                    EndBlock();

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

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

                        EndBlock();
                    }

                    WriteSpace();
                    WriteCloseParentheses();
                }
            }
        }
Exemple #24
0
        protected bool ResolveOperator(BinaryOperatorExpression binaryOperatorExpression, OperatorResolveResult orr)
        {
            var method = orr?.UserDefinedOperatorMethod;

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

                if (!string.IsNullOrWhiteSpace(inline))
                {
                    new InlineArgumentsBlock(Emitter,
                                             new ArgumentsInfo(Emitter, binaryOperatorExpression, orr, method), inline).Emit();
                    return(true);
                }
                else if (!Emitter.Validator.IsExternalType(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];
                        bool isField = left is MemberResolveResult memberTargetrr && 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))
                        {
                            WriteOpenParentheses();

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

                            binaryOperatorExpression.Left.AcceptVisitor(Emitter);

                            WriteComma();

                            addClose = true;
                        }

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

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

                        WriteOpenParentheses();

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

                        WriteCloseParentheses();

                        Write(" ? ");

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

                        Write(" : ");
                    }

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

                        string action = JS.Funcs.Math.LIFT;

                        switch (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;
                        }

                        Write(action + "(");
                    }

                    Write(H5Types.ToJsName(method.DeclaringType, Emitter));
                    WriteDot();

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

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

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

                    WriteCloseParentheses();

                    if (addClose)
                    {
                        WriteCloseParentheses();
                    }

                    return(true);
                }
            }

            return(false);
        }