예제 #1
0
        public IErrorReporter ErrorIsTypeAlienSealed()
        {
            NameResolver resolver = null;

            foreach (var mutability in Options.AllMutabilityModes)
            {
                var env = Environment.Create(new Options()
                {
                }.SetMutability(mutability));
                var root_ns = env.Root;

                root_ns.AddBuilder(TypeBuilder.CreateInterface("IWhat"));

                root_ns.AddBuilder(TypeBuilder.Create("What")
                                   .Parents("IWhat"));

                // comparison does not make sense, because string is sealed and it is not possible to be given interface
                IsType is_type = IsType.Create(NameReference.Create("x"), NameFactory.StringNameReference());
                root_ns.AddBuilder(FunctionBuilder.Create("foo",
                                                          NameFactory.BoolNameReference(),
                                                          Block.CreateStatement(
                                                              VariableDeclaration.CreateStatement("x", NameFactory.PointerNameReference("IWhat"), Undef.Create()),
                                                              Return.Create(is_type)
                                                              )));


                resolver = NameResolver.Create(env);

                Assert.AreEqual(1, resolver.ErrorManager.Errors.Count);
                Assert.IsTrue(resolver.ErrorManager.HasError(ErrorCode.TypeMismatch, is_type));
            }

            return(resolver);
        }
예제 #2
0
        public IErrorReporter TypeTesting()
        {
            NameResolver resolver = null;

            foreach (var mutability in Options.AllMutabilityModes)
            {
                var env = Language.Environment.Create(new Options()
                {
                    GlobalVariables = true,
                    RelaxedMode     = true
                }.SetMutability(mutability));
                var root_ns   = env.Root;
                var system_ns = env.SystemNamespace;

                IsType is_type  = IsType.Create(NameReference.Create("foo"), NameFactory.PointerNameReference(NameFactory.RealNameReference()));
                var    decl_src = VariableDeclaration.CreateStatement("foo", NameFactory.PointerNameReference(NameFactory.IObjectNameReference()),
                                                                      initValue: Undef.Create(), modifier: EntityModifier.Public);
                var decl_dst = VariableDeclaration.CreateStatement("bar", null, initValue: is_type, modifier: EntityModifier.Public);
                root_ns.AddNode(decl_src);
                root_ns.AddNode(decl_dst);

                resolver = NameResolver.Create(env);

                Assert.AreEqual(0, resolver.ErrorManager.Errors.Count);
            }

            return(resolver);
        }
예제 #3
0
파일: Templates.cs 프로젝트: macias/Skila
        public IInterpreter CheckingTraitRuntimeType()
        {
            var interpreter = new Interpreter.Interpreter();

            foreach (var mutability in Options.AllMutabilityModes)
            {
                var env = Environment.Create(new Options()
                {
                    DebugThrowOnError      = true,
                    AllowInvalidMainResult = true
                }.SetMutability(mutability));
                var root_ns = env.Root;

                root_ns.AddBuilder(TypeBuilder.CreateInterface("ISay")
                                   .With(FunctionBuilder.CreateDeclaration("say", ExpressionReadMode.ReadRequired, NameFactory.Int64NameReference())));

                root_ns.AddBuilder(TypeBuilder.Create("Say")
                                   .With(FunctionBuilder.Create("say", ExpressionReadMode.ReadRequired, NameFactory.Int64NameReference(),
                                                                Block.CreateStatement(new[] {
                    Return.Create(Int64Literal.Create("7"))
                }))
                                         .SetModifier(EntityModifier.Override))
                                   .Parents("ISay"));

                root_ns.AddBuilder(TypeBuilder.Create("Greeter", "T"));

                root_ns.AddBuilder(TypeBuilder.Create("Greeter", "X")
                                   .Constraints(ConstraintBuilder.Create("X").Inherits("ISay"))
                                   .SetModifier(EntityModifier.Trait)
                                   .Parents("ISay")
                                   .With(FunctionBuilder.Create("say", ExpressionReadMode.ReadRequired, NameFactory.Int64NameReference(),
                                                                Block.CreateStatement(
                                                                    Return.Create(Int64Literal.Create("2"))
                                                                    )).SetModifier(EntityModifier.Override)));

                root_ns.AddBuilder(FunctionBuilder.Create(
                                       "main",
                                       ExpressionReadMode.OptionalUse,
                                       NameFactory.Int64NameReference(),
                                       Block.CreateStatement(
                                           VariableDeclaration.CreateStatement("g", NameFactory.PointerNameReference(NameFactory.IObjectNameReference()),
                                                                               ExpressionFactory.HeapConstructor(NameReference.Create("Greeter", NameReference.Create("Say")))),
                                           Return.Create(ExpressionFactory.Ternary(IsType.Create(NameReference.Create("g"), NameReference.Create("ISay")),
                                                                                   Int64Literal.Create("2"), Int64Literal.Create("88")))
                                           )));

                ExecValue result = interpreter.TestRun(env);

                Assert.AreEqual(2L, result.RetValue.PlainValue);
            }

            return(interpreter);
        }
예제 #4
0
파일: Templates.cs 프로젝트: macias/Skila
        public IInterpreter ResolvingGenericArgumentInRuntime()
        {
            var interpreter = new Interpreter.Interpreter();

            foreach (var mutability in Options.AllMutabilityModes)
            {
                var env = Environment.Create(new Options()
                {
                    DebugThrowOnError = true
                }.SetMutability(mutability));
                var root_ns = env.Root;

                root_ns.AddBuilder(FunctionBuilder.Create("oracle", "O", VarianceMode.None,
                                                          NameFactory.BoolNameReference(),
                                                          Block.CreateStatement(
                                                              Return.Create(IsType.Create(NameReference.Create("thing"), NameReference.Create("O")))
                                                              ))
                                   .Parameters(FunctionParameter.Create("thing", NameFactory.ReferenceNameReference(NameFactory.IObjectNameReference()))));

                root_ns.AddBuilder(FunctionBuilder.Create(
                                       "main",
                                       ExpressionReadMode.OptionalUse,
                                       NameFactory.Nat8NameReference(),
                                       Block.CreateStatement(
                                           VariableDeclaration.CreateStatement("acc", null, Nat8Literal.Create("0"), env.Options.ReassignableModifier()),
                                           VariableDeclaration.CreateStatement("i", null, ExpressionFactory.HeapConstructor(NameFactory.IntNameReference(), IntLiteral.Create("7"))),
                                           VariableDeclaration.CreateStatement("d", null, ExpressionFactory.HeapConstructor(NameFactory.RealNameReference(), RealLiteral.Create("3.3"))),
                                           IfBranch.CreateIf(FunctionCall.Create(NameReference.Create("oracle", NameFactory.IntNameReference()),
                                                                                 NameReference.Create("i")),
                                                             new[] { ExpressionFactory.IncBy("acc", Nat8Literal.Create("2")) }),
                                           IfBranch.CreateIf(FunctionCall.Create(NameReference.Create("oracle", NameFactory.IntNameReference()),
                                                                                 NameReference.Create("d")),
                                                             new[] { ExpressionFactory.IncBy("acc", Nat8Literal.Create("88")) }),
                                           Return.Create(NameReference.Create("acc"))
                                           )));

                ExecValue result = interpreter.TestRun(env);

                Assert.AreEqual((byte)2, result.RetValue.PlainValue);
            }

            return(interpreter);
        }
예제 #5
0
        public void Converter_IsTypeTests()
        {
            IsType conv = new IsType();

            conv.Type = typeof(double);
            double dval = 1.0f;
            float  fval = 1.0f;

            Assert.AreEqual(true, conv.Convert(dval, typeof(bool), null, CultureInfo.CurrentCulture),
                            "IsType Convert did not return the correct value");
            Assert.AreEqual(false, conv.Convert(fval, typeof(bool), null, CultureInfo.CurrentCulture),
                            "IsType Convert did not return the correct value");
            try
            {
                conv.ConvertBack(true, typeof(object), null, CultureInfo.CurrentCulture);
                Assert.Fail("IsType ConvertBack did not throw a NotImplemented exception");
            }
            catch (NotImplementedException) { }
        }
예제 #6
0
        public IErrorReporter ErrorTestingValueType()
        {
            NameResolver resolver = null;

            foreach (var mutability in Options.AllMutabilityModes)
            {
                var env = Language.Environment.Create(new Options()
                {
                    GlobalVariables = true,
                    RelaxedMode     = true,
                    DiscardingAnyExpressionDuringTests = true
                }.SetMutability(mutability));
                var root_ns   = env.Root;
                var system_ns = env.SystemNamespace;

                IsType is_type  = IsType.Create(NameReference.Create("foo"), NameFactory.RealNameReference());
                var    decl_src = VariableDeclaration.CreateStatement("foo", NameFactory.IObjectNameReference(), initValue: Undef.Create(), modifier: EntityModifier.Public);
                var    decl_dst = VariableDeclaration.CreateStatement("bar", null, initValue: is_type, modifier: EntityModifier.Public);
                root_ns.AddNode(decl_src);
                root_ns.AddNode(decl_dst);

                IsType is_type_ref = IsType.Create(NameReference.Create("u"), NameFactory.ISequenceNameReference("G"));
                root_ns.AddBuilder(FunctionBuilder.Create("more", "G", VarianceMode.None,
                                                          NameFactory.UnitNameReference(),
                                                          Block.CreateStatement(
                                                              ExpressionFactory.Readout(is_type_ref)
                                                              ))
                                   .Parameters(FunctionParameter.Create("u", NameFactory.ReferenceNameReference(
                                                                            NameFactory.ISequenceNameReference("G", mutability: TypeMutability.ReadOnly)))));

                resolver = NameResolver.Create(env);

                Assert.AreEqual(2, resolver.ErrorManager.Errors.Count);
                Assert.IsTrue(resolver.ErrorManager.HasError(ErrorCode.IsTypeOfKnownTypes, is_type));
                Assert.IsTrue(resolver.ErrorManager.HasError(ErrorCode.IsTypeOfKnownTypes, is_type_ref));
            }

            return(resolver);
        }
예제 #7
0
        /// <summary>
        ///     获得当前页面客户端的IP
        /// </summary>
        /// <returns>当前页面客户端的IP</returns>
        public static string GetIP()
        {
            var ip      = "";
            var context = HttpContext.Current;

            if (context != null)
            {
                ip = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                if (string.IsNullOrWhiteSpace(ip))
                {
                    ip = context.Request.ServerVariables["REMOTE_ADDR"];
                }
                if (string.IsNullOrWhiteSpace(ip) || !IsType.IsIP(ip))
                {
                    ip = context.Request.UserHostAddress;
                }
                if (string.IsNullOrWhiteSpace(ip) || !IsType.IsIP(ip))
                {
                    return("0.0.0.0");
                }
                return(ip);
            }
            else
            {
                var strHostName = Dns.GetHostName();
                var ipHost      = Dns.GetHostEntry(strHostName);
                foreach (var item in ipHost.AddressList)
                {
                    if (item.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                    {
                        ip = item.ToString();
                    }
                }
            }
            return(ip);
        }
예제 #8
0
        /// <summary>
        ///     将方法转换成T-SQL特殊函数名
        /// </summary>
        /// <param name="m">自定义特殊的函数</param>
        protected override Expression VisitMethodCall(MethodCallExpression m)
        {
            base.VisitMethodCall(m);
            if (ClearCallSql())
            {
                return(m);
            }

            #region 字段、参数、值类型
            Type   fieldType;
            Type   paramType;
            string fieldName, paramName;

            if (m.Object == null)
            {
                if (!m.Arguments[0].Type.IsGenericType || m.Arguments[0].Type.GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    fieldType = m.Arguments[0].Type; paramType = m.Arguments[1].Type; fieldName = SqlList.Pop(); paramName = SqlList.Pop();
                }
                else
                {
                    paramType = m.Arguments[0].Type; fieldType = m.Arguments[1].Type; paramName = SqlList.Pop(); fieldName = SqlList.Pop();
                }
            }
            else
            {
                if (!m.Object.Type.IsGenericType || m.Object.Type.GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    fieldType = m.Object.Type; paramType = m.Arguments[0].Type; paramName = SqlList.Pop(); fieldName = SqlList.Pop();
                }
                else
                {
                    paramType = m.Object.Type; fieldType = m.Arguments[0].Type; fieldName = SqlList.Pop(); paramName = SqlList.Pop();
                }
            }
            #endregion

            switch (m.Method.Name.ToUpper())
            {
            case "CONTAINS":
            {
                if (!paramType.IsGenericType || paramType.GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    #region 搜索值串的处理
                    var param = ParamsList.Find(o => o.ParameterName == paramName);
                    if (param != null && IsType.IsDigital(param.Value.ToString()) && (Type.GetTypeCode(fieldType) == TypeCode.Int16 || Type.GetTypeCode(fieldType) == TypeCode.Int32 || Type.GetTypeCode(fieldType) == TypeCode.Decimal || Type.GetTypeCode(fieldType) == TypeCode.Double || Type.GetTypeCode(fieldType) == TypeCode.Int64 || Type.GetTypeCode(fieldType) == TypeCode.UInt16 || Type.GetTypeCode(fieldType) == TypeCode.UInt32 || Type.GetTypeCode(fieldType) == TypeCode.UInt64))
                    {
                        param.Value  = "," + param.Value + ",";
                        param.DbType = DbType.String;
                        if (dbProvider.CreateTableAegis("").Length > 0)
                        {
                            fieldName = "','+" + fieldName.Substring(1, fieldName.Length - 2) + "+','";
                        }
                        else
                        {
                            fieldName = "','+" + fieldName + "+','";
                        }
                    }
                    #endregion

                    SqlList.Push(String.Format("{0} LIKE {1}", fieldName, paramName));
                }
                else
                {
                    if (Type.GetTypeCode(fieldType) == TypeCode.String)
                    {
                        base.ParamsList.GetLast().Value = "'" + base.ParamsList.GetLast().Value.ToString().Replace(",", "','") + "'";
                    }
                    SqlList.Push(String.Format("{0} IN ({1})", fieldName, base.ParamsList.GetLast().Value));
                    base.ParamsList.Remove(base.ParamsList.GetLast());
                }

                break;
            }

            case "STARTSWITH":
            {
                SqlList.Push(String.Format("{0} LIKE {1}", fieldName, paramName));
                ParamsList.GetLast().Value = string.Format("{0}%", ParamsList.GetLast().Value);
                break;
            }

            case "ENDSWITH":
            {
                SqlList.Push(String.Format("{0} LIKE {1}", fieldName, paramName));
                ParamsList.GetLast().Value = string.Format("%{0}", ParamsList.GetLast().Value);
                break;
            }

            case "ISEQUALS":
            {
                SqlList.Push(String.Format("{0} = {1}", fieldName, paramName));
                break;
            }

            default:
            {
                if (m.Arguments.Count == 0 && m.Object != null)
                {
                    return(m);
                }
                else
                {
                    return(VisitConvert(m)); throw new Exception(string.Format("暂不支持该方法的SQL转换:" + m.Method.Name.ToUpper()));
                }
            }
            }
            return(m);
        }
예제 #9
0
 object Evaluate(IsType t)
 {
     return(t.IncludeSubtypes
                         ? _reflection.IsSubtype(Evaluate(t.Object), t.Type.FullName)
                         : _reflection.IsType(Evaluate(t.Object), t.Type.FullName));
 }
예제 #10
0
        private static bool IsTypeConversion(ConversionBlock block, Expression expression, ResolveResult rr, IType expectedType, Conversion conversion, string typeName, IsType isType)
        {
            if (conversion.IsUserDefined)
            {
                var m = conversion.Method;
                if (isType(m.ReturnType, block.Emitter.Resolver))
                {
                    return(false);
                }
            }

            var invocationExpression = expression.Parent as InvocationExpression;

            if (invocationExpression != null && invocationExpression.Arguments.Any(a => a == expression))
            {
                var index = invocationExpression.Arguments.ToList().IndexOf(expression);
                var methodResolveResult = block.Emitter.Resolver.ResolveNode(invocationExpression, block.Emitter) as MemberResolveResult;

                if (methodResolveResult != null)
                {
                    var m   = methodResolveResult.Member as IMethod;
                    var arg = m.Parameters[index < m.Parameters.Count ? index : (m.Parameters.Count - 1)];

                    if (isType(arg.Type, block.Emitter.Resolver, arg.IsParams) && !isType(rr.Type, block.Emitter.Resolver))
                    {
                        if (expression.IsNull)
                        {
                            return(false);
                        }

                        if (expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression)
                        {
                            return(false);
                        }
                        return(true);
                    }
                }
            }

            var objectCreateExpression = expression.Parent as ObjectCreateExpression;

            if (objectCreateExpression != null && objectCreateExpression.Arguments.Any(a => a == expression))
            {
                var index = objectCreateExpression.Arguments.ToList().IndexOf(expression);
                var methodResolveResult = block.Emitter.Resolver.ResolveNode(objectCreateExpression, block.Emitter) as MemberResolveResult;

                if (methodResolveResult != null)
                {
                    var m   = methodResolveResult.Member as IMethod;
                    var arg = m.Parameters[index < m.Parameters.Count ? index : (m.Parameters.Count - 1)];

                    if (isType(arg.Type, block.Emitter.Resolver, arg.IsParams) && !isType(rr.Type, block.Emitter.Resolver))
                    {
                        if (expression.IsNull)
                        {
                            return(false);
                        }

                        if (expression is CastExpression &&
                            ((CastExpression)expression).Expression is ParenthesizedExpression)
                        {
                            return(false);
                        }
                        return(true);
                    }
                }
            }

            var namedArgExpression = expression.Parent as NamedArgumentExpression;

            if (namedArgExpression != null)
            {
                var namedArgResolveResult = block.Emitter.Resolver.ResolveNode(namedArgExpression, block.Emitter) as NamedArgumentResolveResult;

                if (isType(namedArgResolveResult.Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver))
                {
                    if (expression.IsNull)
                    {
                        return(false);
                    }

                    if (expression is CastExpression &&
                        ((CastExpression)expression).Expression is ParenthesizedExpression)
                    {
                        return(false);
                    }

                    return(true);
                }
            }

            var namedExpression = expression.Parent as NamedExpression;

            if (namedExpression != null)
            {
                var namedResolveResult = block.Emitter.Resolver.ResolveNode(namedExpression, block.Emitter);

                if (isType(namedResolveResult.Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver))
                {
                    if (expression.IsNull)
                    {
                        return(false);
                    }

                    if (expression is CastExpression &&
                        ((CastExpression)expression).Expression is ParenthesizedExpression)
                    {
                        return(false);
                    }
                    return(true);
                }
            }

            var binaryOpExpr = expression.Parent as BinaryOperatorExpression;

            if (binaryOpExpr != null)
            {
                var idx        = binaryOpExpr.Left == expression ? 0 : 1;
                var binaryOpRr = block.Emitter.Resolver.ResolveNode(binaryOpExpr, block.Emitter) as OperatorResolveResult;

                if (binaryOpRr != null && isType(binaryOpRr.Operands[idx].Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver))
                {
                    if (expression.IsNull)
                    {
                        return(false);
                    }

                    if (expression is CastExpression &&
                        ((CastExpression)expression).Expression is ParenthesizedExpression)
                    {
                        return(false);
                    }

                    return(true);
                }
            }

            var conditionalExpr = expression.Parent as ConditionalExpression;

            if (conditionalExpr != null && conditionalExpr.Condition != expression)
            {
                var idx           = conditionalExpr.TrueExpression == expression ? 0 : 1;
                var conditionalrr = block.Emitter.Resolver.ResolveNode(conditionalExpr, block.Emitter) as OperatorResolveResult;

                if (conditionalrr != null && isType(conditionalrr.Operands[idx].Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver))
                {
                    if (expression.IsNull)
                    {
                        return(false);
                    }

                    if (expression is CastExpression &&
                        ((CastExpression)expression).Expression is ParenthesizedExpression)
                    {
                        return(false);
                    }

                    return(true);
                }
            }

            var assignmentExpr = expression.Parent as AssignmentExpression;

            if (assignmentExpr != null)
            {
                var assigmentRr = block.Emitter.Resolver.ResolveNode(assignmentExpr, block.Emitter) as OperatorResolveResult;

                if (isType(assigmentRr.Operands[1].Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver))
                {
                    if (expression.IsNull)
                    {
                        return(false);
                    }

                    if (expression is CastExpression &&
                        ((CastExpression)expression).Expression is ParenthesizedExpression)
                    {
                        return(false);
                    }

                    return(true);
                }
            }

            var arrayInit = expression.Parent as ArrayInitializerExpression;

            if (arrayInit != null)
            {
                while (arrayInit.Parent is ArrayInitializerExpression)
                {
                    arrayInit = (ArrayInitializerExpression)arrayInit.Parent;
                }

                IType elementType = null;
                var   arrayCreate = arrayInit.Parent as ArrayCreateExpression;
                if (arrayCreate != null)
                {
                    var rrArrayType = block.Emitter.Resolver.ResolveNode(arrayCreate, block.Emitter);
                    if (rrArrayType.Type is TypeWithElementType)
                    {
                        elementType = ((TypeWithElementType)rrArrayType.Type).ElementType;
                    }
                    else
                    {
                        elementType = rrArrayType.Type;
                    }
                }
                else
                {
                    var rrElemenet = block.Emitter.Resolver.ResolveNode(arrayInit.Parent, block.Emitter);
                    var pt         = rrElemenet.Type as ParameterizedType;
                    if (pt != null)
                    {
                        elementType = pt.TypeArguments.Count > 0 ? pt.TypeArguments.First() : null;
                    }
                    else
                    {
                        var arrayType = rrElemenet.Type as TypeWithElementType;
                        if (arrayType != null)
                        {
                            elementType = arrayType.ElementType;
                        }
                        else
                        {
                            elementType = rrElemenet.Type;
                        }
                    }
                }

                if (elementType != null && isType(elementType, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver))
                {
                    if (expression.IsNull)
                    {
                        return(false);
                    }

                    if (expression is CastExpression &&
                        ((CastExpression)expression).Expression is ParenthesizedExpression)
                    {
                        return(false);
                    }

                    return(true);
                }
                else if (Helpers.Is64Type(rr.Type, block.Emitter.Resolver) &&
                         Helpers.IsFloatType(elementType, block.Emitter.Resolver) &&
                         !Helpers.IsDecimalType(elementType, block.Emitter.Resolver) &&
                         isType(rr.Type, block.Emitter.Resolver))
                {
                    if (expression is CastExpression &&
                        ((CastExpression)expression).Expression is ParenthesizedExpression)
                    {
                        return(false);
                    }
                    return(true);
                }
            }

            if (isType(expectedType, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver) && !(conversion.IsExplicit && conversion.IsNumericConversion))
            {
                var           castExpr   = expression.Parent as CastExpression;
                ResolveResult castTypeRr = null;
                if (castExpr != null)
                {
                    castTypeRr = block.Emitter.Resolver.ResolveNode(castExpr.Type, block.Emitter);
                }

                /*if (castTypeRr == null || !isType(castTypeRr.Type, block.Emitter.Resolver))*/
                if (castTypeRr == null || !conversion.IsExplicit)
                {
                    if (expression.IsNull)
                    {
                        return(false);
                    }

                    if (expression is CastExpression &&
                        ((CastExpression)expression).Expression is ParenthesizedExpression)
                    {
                        return(false);
                    }

                    return(true);
                }
            }

            return(false);
        }
예제 #11
0
        private static bool CheckTypeConversion(ConversionBlock block, Expression expression, ResolveResult rr, IType expectedType, Conversion conversion, string typeName, IsType isType, bool ignoreConversionResolveResult)
        {
            if (conversion.IsUserDefined)
            {
                var m = conversion.Method;
                if (isType(m.ReturnType, block.Emitter.Resolver))
                {
                    return(false);
                }
            }

            if (expression is CastExpression && !ignoreConversionResolveResult)
            {
                var nestedExpr = ((CastExpression)expression).Expression;
                var nested_rr  = block.Emitter.Resolver.ResolveNode(nestedExpr, block.Emitter);

                if (!(nested_rr is ConversionResolveResult))
                {
                    return(false);
                }
            }

            var invocationExpression = expression.Parent as InvocationExpression;

            if (invocationExpression != null && invocationExpression.Arguments.Any(a => a == expression))
            {
                var index = invocationExpression.Arguments.ToList().IndexOf(expression);
                var methodResolveResult = block.Emitter.Resolver.ResolveNode(invocationExpression, block.Emitter) as MemberResolveResult;

                if (methodResolveResult != null)
                {
                    var m   = methodResolveResult.Member as IMethod;
                    var arg = m.Parameters[index < m.Parameters.Count ? index : (m.Parameters.Count - 1)];

                    if (isType(arg.Type, block.Emitter.Resolver, arg.IsParams) && !isType(rr.Type, block.Emitter.Resolver))
                    {
                        if (expression.IsNull)
                        {
                            return(false);
                        }

                        block.Write(typeName);
                        if (NullableType.IsNullable(arg.Type) && ConversionBlock.ShouldBeLifted(expression))
                        {
                            block.Write("." + JS.Funcs.Math.LIFT);
                        }
                        if (!ignoreConversionResolveResult && expression is CastExpression &&
                            ((CastExpression)expression).Expression is ParenthesizedExpression)
                        {
                            return(false);
                        }
                        block.WriteOpenParentheses();
                        return(true);
                    }
                }
            }

            var objectCreateExpression = expression.Parent as ObjectCreateExpression;

            if (objectCreateExpression != null && objectCreateExpression.Arguments.Any(a => a == expression))
            {
                var index = objectCreateExpression.Arguments.ToList().IndexOf(expression);
                var methodResolveResult = block.Emitter.Resolver.ResolveNode(objectCreateExpression, block.Emitter) as MemberResolveResult;

                if (methodResolveResult != null)
                {
                    var m   = methodResolveResult.Member as IMethod;
                    var arg = m.Parameters[index < m.Parameters.Count ? index : (m.Parameters.Count - 1)];

                    if (isType(arg.Type, block.Emitter.Resolver, arg.IsParams) && !isType(rr.Type, block.Emitter.Resolver))
                    {
                        if (expression.IsNull)
                        {
                            return(false);
                        }

                        block.Write(typeName);
                        if (NullableType.IsNullable(arg.Type) && ConversionBlock.ShouldBeLifted(expression))
                        {
                            block.Write("." + JS.Funcs.Math.LIFT);
                        }
                        if (!ignoreConversionResolveResult && expression is CastExpression &&
                            ((CastExpression)expression).Expression is ParenthesizedExpression)
                        {
                            return(false);
                        }
                        block.WriteOpenParentheses();
                        return(true);
                    }
                }
            }

            var namedArgExpression = expression.Parent as NamedArgumentExpression;

            if (namedArgExpression != null)
            {
                var namedArgResolveResult = block.Emitter.Resolver.ResolveNode(namedArgExpression, block.Emitter) as NamedArgumentResolveResult;

                if (isType(namedArgResolveResult.Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver))
                {
                    if (expression.IsNull)
                    {
                        return(false);
                    }

                    block.Write(typeName);
                    if (NullableType.IsNullable(namedArgResolveResult.Type) && ConversionBlock.ShouldBeLifted(expression))
                    {
                        block.Write("." + JS.Funcs.Math.LIFT);
                    }
                    if (!ignoreConversionResolveResult && expression is CastExpression &&
                        ((CastExpression)expression).Expression is ParenthesizedExpression)
                    {
                        return(false);
                    }
                    block.WriteOpenParentheses();
                    return(true);
                }
            }

            var namedExpression = expression.Parent as NamedExpression;

            if (namedExpression != null)
            {
                var namedResolveResult = block.Emitter.Resolver.ResolveNode(namedExpression, block.Emitter);

                if (isType(namedResolveResult.Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver))
                {
                    if (expression.IsNull)
                    {
                        return(false);
                    }

                    block.Write(typeName);
                    if (NullableType.IsNullable(namedResolveResult.Type) && ConversionBlock.ShouldBeLifted(expression))
                    {
                        block.Write("." + JS.Funcs.Math.LIFT);
                    }
                    if (!ignoreConversionResolveResult && expression is CastExpression &&
                        ((CastExpression)expression).Expression is ParenthesizedExpression)
                    {
                        return(false);
                    }
                    block.WriteOpenParentheses();
                    return(true);
                }
            }

            var binaryOpExpr = expression.Parent as BinaryOperatorExpression;

            if (binaryOpExpr != null)
            {
                var idx        = binaryOpExpr.Left == expression ? 0 : 1;
                var binaryOpRr = block.Emitter.Resolver.ResolveNode(binaryOpExpr, block.Emitter) as OperatorResolveResult;

                if (binaryOpRr != null && isType(binaryOpRr.Operands[idx].Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver))
                {
                    var isNullable = NullableType.IsNullable(binaryOpRr.Operands[idx].Type);
                    if (expression.IsNull)
                    {
                        return(false);
                    }

                    block.Write(typeName);
                    if (isNullable && ConversionBlock.ShouldBeLifted(expression))
                    {
                        block.Write("." + JS.Funcs.Math.LIFT);
                    }
                    if (!ignoreConversionResolveResult && expression is CastExpression &&
                        ((CastExpression)expression).Expression is ParenthesizedExpression)
                    {
                        return(false);
                    }
                    block.WriteOpenParentheses();
                    return(true);
                }
            }

            var conditionalExpr = expression.Parent as ConditionalExpression;

            if (conditionalExpr != null && conditionalExpr.Condition != expression)
            {
                var idx           = conditionalExpr.TrueExpression == expression ? 1 : 2;
                var conditionalrr = block.Emitter.Resolver.ResolveNode(conditionalExpr, block.Emitter) as OperatorResolveResult;

                if (conditionalrr != null && isType(conditionalrr.Operands[idx].Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver))
                {
                    if (expression.IsNull)
                    {
                        return(false);
                    }

                    block.Write(typeName);
                    if (NullableType.IsNullable(conditionalrr.Operands[idx].Type) && ConversionBlock.ShouldBeLifted(expression))
                    {
                        block.Write("." + JS.Funcs.Math.LIFT);
                    }
                    if (!ignoreConversionResolveResult && expression is CastExpression &&
                        ((CastExpression)expression).Expression is ParenthesizedExpression)
                    {
                        return(false);
                    }
                    block.WriteOpenParentheses();
                    return(true);
                }
            }

            var assignmentExpr = expression.Parent as AssignmentExpression;

            if (assignmentExpr != null)
            {
                var assigmentRr = block.Emitter.Resolver.ResolveNode(assignmentExpr, block.Emitter) as OperatorResolveResult;

                if (isType(assigmentRr.Operands[1].Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver))
                {
                    if (expression.IsNull)
                    {
                        return(false);
                    }

                    block.Write(typeName);
                    if (NullableType.IsNullable(assigmentRr.Operands[1].Type) && ConversionBlock.ShouldBeLifted(expression))
                    {
                        block.Write("." + JS.Funcs.Math.LIFT);
                    }
                    if (!ignoreConversionResolveResult && expression is CastExpression &&
                        ((CastExpression)expression).Expression is ParenthesizedExpression)
                    {
                        return(false);
                    }
                    block.WriteOpenParentheses();
                    return(true);
                }
            }

            var indexerExpr = expression.Parent as IndexerExpression;

            if (indexerExpr != null)
            {
                var index = indexerExpr.Arguments.ToList().IndexOf(expression);

                if (index >= 0)
                {
                    var invocationrr = block.Emitter.Resolver.ResolveNode(indexerExpr, block.Emitter) as InvocationResolveResult;
                    if (invocationrr != null)
                    {
                        var parameters = invocationrr.Member.Parameters;
                        if (parameters.Count <= index)
                        {
                            index = parameters.Count - 1;
                        }

                        if (isType(invocationrr.Member.Parameters.ElementAt(index).Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver))
                        {
                            if (expression.IsNull)
                            {
                                return(false);
                            }

                            block.Write(typeName);
                            if (NullableType.IsNullable(invocationrr.Member.Parameters.ElementAt(index).Type) && ConversionBlock.ShouldBeLifted(expression))
                            {
                                block.Write("." + JS.Funcs.Math.LIFT);
                            }
                            if (!ignoreConversionResolveResult && expression is CastExpression &&
                                ((CastExpression)expression).Expression is ParenthesizedExpression)
                            {
                                return(false);
                            }
                            block.WriteOpenParentheses();
                            return(true);
                        }
                    }
                }
            }

            var arrayInit = expression.Parent as ArrayInitializerExpression;

            if (arrayInit != null)
            {
                while (arrayInit.Parent is ArrayInitializerExpression)
                {
                    arrayInit = (ArrayInitializerExpression)arrayInit.Parent;
                }

                IType elementType = null;
                var   arrayCreate = arrayInit.Parent as ArrayCreateExpression;
                if (arrayCreate != null)
                {
                    var rrArrayType = block.Emitter.Resolver.ResolveNode(arrayCreate, block.Emitter);
                    if (rrArrayType.Type is TypeWithElementType)
                    {
                        elementType = ((TypeWithElementType)rrArrayType.Type).ElementType;
                    }
                    else
                    {
                        elementType = rrArrayType.Type;
                    }
                }
                else
                {
                    var rrElemenet = block.Emitter.Resolver.ResolveNode(arrayInit.Parent, block.Emitter);
                    var pt         = rrElemenet.Type as ParameterizedType;
                    if (pt != null && pt.TypeArguments.Count > 0)
                    {
                        if (pt.TypeArguments.Count == 1)
                        {
                            elementType = pt.TypeArguments.First();
                        }
                        else
                        {
                            var index = 0;
                            arrayInit = expression.Parent as ArrayInitializerExpression;

                            for (int i = 0; i < arrayInit.Elements.Count; i++)
                            {
                                if (expression == arrayInit.Elements.ElementAt(i))
                                {
                                    index = i;
                                    break;
                                }
                            }

                            elementType = index < pt.TypeArguments.Count ? pt.TypeArguments.ElementAt(index) : pt.TypeArguments.ElementAt(0);
                        }
                    }
                    else
                    {
                        var arrayType = rrElemenet.Type as TypeWithElementType;
                        if (arrayType != null)
                        {
                            elementType = arrayType.ElementType;
                        }
                        else
                        {
                            elementType = rrElemenet.Type;
                        }
                    }
                }

                if (elementType != null && isType(elementType, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver))
                {
                    if (expression.IsNull)
                    {
                        return(false);
                    }

                    block.Write(typeName);
                    if (NullableType.IsNullable(elementType) && ConversionBlock.ShouldBeLifted(expression))
                    {
                        block.Write("." + JS.Funcs.Math.LIFT);
                    }
                    if (!ignoreConversionResolveResult && expression is CastExpression &&
                        ((CastExpression)expression).Expression is ParenthesizedExpression)
                    {
                        return(false);
                    }
                    block.WriteOpenParentheses();
                    return(true);
                }
                else if (Helpers.Is64Type(rr.Type, block.Emitter.Resolver) &&
                         Helpers.IsFloatType(elementType, block.Emitter.Resolver) &&
                         !Helpers.IsDecimalType(elementType, block.Emitter.Resolver) &&
                         isType(rr.Type, block.Emitter.Resolver))
                {
                    block.Write(JS.Types.System.Int64.TONUMBER);
                    if (!ignoreConversionResolveResult && expression is CastExpression &&
                        ((CastExpression)expression).Expression is ParenthesizedExpression)
                    {
                        return(false);
                    }
                    block.WriteOpenParentheses();
                    return(true);
                }
            }

            if (isType(expectedType, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver) && !(conversion.IsExplicit && conversion.IsNumericConversion))
            {
                var           castExpr   = expression.Parent as CastExpression;
                ResolveResult castTypeRr = null;
                if (castExpr != null)
                {
                    castTypeRr = block.Emitter.Resolver.ResolveNode(castExpr.Type, block.Emitter);
                }

                /*if (castTypeRr == null || !isType(castTypeRr.Type, block.Emitter.Resolver))*/
                if (castTypeRr == null || !conversion.IsExplicit)
                {
                    if (expression.IsNull)
                    {
                        return(false);
                    }

                    block.Write(typeName);
                    if (NullableType.IsNullable(expectedType) && ConversionBlock.ShouldBeLifted(expression))
                    {
                        block.Write("." + JS.Funcs.Math.LIFT);
                    }

                    if (!ignoreConversionResolveResult && expression is CastExpression &&
                        ((CastExpression)expression).Expression is ParenthesizedExpression)
                    {
                        return(false);
                    }
                    block.WriteOpenParentheses();
                    return(true);
                }
            }

            return(false);
        }
예제 #12
0
        public IErrorReporter DuckTypingOnEmptyInterface()
        {
            NameResolver resolver = null;

            foreach (var mutability in Options.AllMutabilityModes)
            {
                var env = Environment.Create(new Options()
                {
                    DiscardingAnyExpressionDuringTests = true,
                    // we test this option here or more precisely duck typing
                    InterfaceDuckTyping = true
                }.SetMutability(mutability));
                var root_ns = env.Root;

                // please note it is not the interface is empty (it is not because IObject is not empty),
                // but it does not add anything, so in this sense it is empty
                root_ns.AddBuilder(TypeBuilder.CreateInterface("IWhat"));

                root_ns.AddBuilder(FunctionBuilder.Create("foo",
                                                          NameFactory.UnitNameReference(),
                                                          Block.CreateStatement(
                                                              VariableDeclaration.CreateStatement("x", NameFactory.PointerNameReference(NameFactory.IObjectNameReference()), Undef.Create()),
                                                              // should be legal despite duck typing, i.e. we should not error that the types are exchangable
                                                              // they are in sense of duck typing but checking if the type IS another type should be duck-free
                                                              ExpressionFactory.Readout(IsType.Create(NameReference.Create("x"), NameReference.Create("IWhat"))),
                                                              VariableDeclaration.CreateStatement("y", NameFactory.PointerNameReference(NameReference.Create("IWhat")), Undef.Create()),
                                                              ExpressionFactory.Readout(IsSame.Create(NameReference.Create("x"), NameReference.Create("y")))
                                                              )));


                resolver = NameResolver.Create(env);

                Assert.AreEqual(0, resolver.ErrorManager.Errors.Count);
            }

            return(resolver);
        }
예제 #13
0
        /// <summary>
        /// IExpressionリスト取得
        /// </summary>
        /// <param name="operation">IOperationインスタンス</param>
        /// <param name="container">イベントコンテナ</param>
        /// <returns>IExpressionリスト</returns>
        public static List <IExpression> GetExpressionList(IOperation operation, EventContainer container)
        {
            List <IExpression> result = new List <IExpression>();

            AbstractOperation instance = null;

            switch (operation)
            {
            // 式系
            case ISimpleAssignmentOperation param:
                instance = new SimpleAssignment(param, container);
                break;

            case IInvocationOperation param:
                instance = new Invocation(param, container);
                break;

            case IBinaryOperation param:
                instance = new Binary(param, container);
                break;

            case IIncrementOrDecrementOperation param:
                instance = new Increment(param, container);
                break;

            case ICompoundAssignmentOperation param:
                instance = new CompoundAssignment(param, container);
                break;

            case IConversionOperation param:
                result.AddRange(GetExpressionList(param.Operand, container));
                break;

            // 参照系
            case IInstanceReferenceOperation param:
                instance = new InstanceReference(param, container);
                break;

            case IFieldReferenceOperation param:
                instance = new FieldReference(param, container);
                break;

            case IPropertyReferenceOperation param:
                instance = new PropertyReference(param, container);
                break;

            case ILocalReferenceOperation param:
                instance = new LocalReference(param, container);
                break;

            case IParameterReferenceOperation param:
                instance = new ParameterReference(param, container);
                break;

            case IArrayElementReferenceOperation param:
                instance = new ArrayElementReference(param, container);
                break;

            case IArgumentOperation param:
                instance = new Argument(param, container);
                break;

            // 生成系
            case IObjectCreationOperation param:
                instance = new ObjectCreation(param, container);
                break;

            case IArrayCreationOperation param:
                instance = new ArrayCreation(param, container);
                break;

            case IArrayInitializerOperation param:
                instance = new ArrayInitializer(param, container);
                break;

            case IVariableDeclaratorOperation param:
                instance = new VariableDeclarator(param, container);
                break;

            // 直値
            case ILiteralOperation param:
                instance = new Literal(param, container);
                break;

            // Switch Case系
            case IDefaultCaseClauseOperation param:
                instance = new DefalutCase(param, container);
                break;

            case IDeclarationPatternOperation param:
                instance = new DeclarationPattern(param, container);
                break;

            //If系
            case IIsPatternOperation param:
                instance = new IsPattern(param, container);
                break;

            case IIsTypeOperation param:
                instance = new IsType(param, container);
                break;


            default:
                Console.Write($" [{operation.Kind} is none] ");
                break;
            }

            // リスト追加
            if (instance != null)
            {
                result.AddRange(instance.Expressions);
            }

            return(result);
        }