예제 #1
0
        protected override Type ResolveInternal(Context ctx, bool mustReturn)
        {
            if (Expressions.Count == 0)
            {
                Error(CompilerMessages.TupleNoArgs);
            }

            if (Expressions.Count > 8)
            {
                Error(CompilerMessages.TupleTooManyArgs);
            }

            var types = new List <Type>();

            foreach (var curr in Expressions)
            {
                var type = curr.Resolve(ctx);
                ctx.CheckTypedExpression(curr, type);

                types.Add(type);
            }

            _types = types.ToArray();
            return(FunctionalHelper.CreateTupleType(_types));
        }
예제 #2
0
        protected override Type ResolveInternal(Context ctx, bool mustReturn)
        {
            var argTypes = new List <Type>();

            foreach (var curr in Arguments)
            {
                if (curr.IsVariadic)
                {
                    Error(CompilerMessages.VariadicArgumentLambda);
                }

                var type = curr.GetArgumentType(ctx);
                argTypes.Add(type);

                if (type == typeof(UnspecifiedType))
                {
                    MustInferArgTypes = true;
                }
            }

            if (MustInferArgTypes)
            {
                return(FunctionalHelper.CreateLambdaType(argTypes.ToArray()));
            }

            Body.Scope.RegisterArguments(ctx, false, Arguments);

            var retType = Body.Resolve(ctx);

            return(FunctionalHelper.CreateDelegateType(retType, argTypes.ToArray()));
        }
예제 #3
0
        protected override Type ResolveInternal(Context ctx, bool mustReturn)
        {
            ResolveSelf(ctx);

            if (_type != null)
            {
                CheckTypeInSafeMode(ctx, _type);
            }

            if (Expression != null && Expression.Resolve(ctx).IsArray&& MemberName == "Length")
            {
                return(typeof(int));
            }

            if (_field != null)
            {
                return(_field.FieldType);
            }

            if (_property != null)
            {
                return(_property.PropertyType);
            }

            return(_method.ReturnType.IsVoid()
                ? FunctionalHelper.CreateActionType(_method.ArgumentTypes)
                : FunctionalHelper.CreateFuncType(_method.ReturnType, _method.ArgumentTypes));
        }
        private static Func <string, string, bool> ProduceGetIsSubnav()
        {
            var getControllerSubnavs =
                FunctionalHelper.Memoize <string, HashSet <string> >(
                    (controllerName) =>
            {
                IEnumerable <NavigationMenuItem> navItems = GetSubnavigationItemsForController(controllerName);

                if (navItems == null)
                {
                    navItems = new NavigationMenuItem[0];
                }

                navItems = navItems.Where(
                    t =>
                    (t != null) &&
                    !string.IsNullOrEmpty(t.Action));

                return(new HashSet <string>(navItems.Select(t => t.Action)));
            });

            return((controllerName, actionName) =>
            {
                if (string.IsNullOrEmpty(actionName))
                {
                    return false;
                }

                return getControllerSubnavs(controllerName).Contains(actionName);
            });
        }
예제 #5
0
        /// <summary>
        /// Creates a pure wrapper for function with 2 and more arguments.
        /// </summary>
        private void createPureWrapperMany(MethodEntity wrapper, string pureName)
        {
            var args = wrapper.GetArgumentTypes(Context);

            var fieldName = string.Format(EntityNames.PureMethodCacheNameTemplate, wrapper.Name);
            var tupleType = FunctionalHelper.CreateTupleType(args);
            var fieldType = typeof(Dictionary <,>).MakeGenericType(tupleType, wrapper.ReturnType);

            CreateField(fieldName, fieldType, true);

            var argGetters = wrapper.Arguments.Select(a => (NodeBase)Expr.Get(a)).ToArray();
            var tupleName  = "<args>";

            wrapper.Body = Expr.Block(
                ScopeKind.FunctionRoot,

                // $tmp = new Tuple<...> $arg1 $arg2 ...
                Expr.Let(tupleName, Expr.New(tupleType, argGetters)),

                // if ($dict == null) $dict = new Dictionary<$tupleType, $valueType> ()
                Expr.If(
                    Expr.Equal(
                        Expr.GetMember(EntityNames.MainTypeName, fieldName),
                        Expr.Null()
                        ),
                    Expr.Block(
                        Expr.SetMember(
                            EntityNames.MainTypeName, fieldName,
                            Expr.New(fieldType)
                            )
                        )
                    ),

                // if(not $dict.ContainsKey key) $dict.Add ($internal arg)
                Expr.If(
                    Expr.Not(
                        Expr.Invoke(
                            Expr.GetMember(EntityNames.MainTypeName, fieldName),
                            "ContainsKey",
                            Expr.Get(tupleName)
                            )
                        ),
                    Expr.Block(
                        Expr.Invoke(
                            Expr.GetMember(EntityNames.MainTypeName, fieldName),
                            "Add",
                            Expr.Get(tupleName),
                            Expr.Invoke(EntityNames.MainTypeName, pureName, argGetters)
                            )
                        )
                    ),

                // $dict[arg]
                Expr.GetIdx(
                    Expr.GetMember(EntityNames.MainTypeName, fieldName),
                    Expr.Get(tupleName)
                    )

                );
        }
예제 #6
0
        public void CreateFuncTypeTest()
        {
            Assert.AreEqual(
                typeof(Func <int, string, TimeSpan>),
                FunctionalHelper.CreateFuncType(typeof(TimeSpan), typeof(int), typeof(string))
                );

            Assert.AreEqual(typeof(Func <bool>), FunctionalHelper.CreateFuncType(typeof(bool)));

            Assert.Throws <LensCompilerException>(() => FunctionalHelper.CreateFuncType(typeof(int), new Type[20]));
        }
예제 #7
0
        public void CreateLambdaTypeTest()
        {
            Assert.AreEqual(
                typeof(Lambda <int, string, TimeSpan>),
                FunctionalHelper.CreateLambdaType(typeof(int), typeof(string), typeof(TimeSpan))
                );

            Assert.AreEqual(typeof(Lambda <bool>), FunctionalHelper.CreateLambdaType(typeof(bool)));
            Assert.AreEqual(typeof(Func <UnspecifiedType>), FunctionalHelper.CreateLambdaType());

            Assert.Throws <LensCompilerException>(() => FunctionalHelper.CreateLambdaType(new Type[20]));
        }
예제 #8
0
        protected override void EmitInternal(Context ctx, bool mustReturn)
        {
            var gen = ctx.CurrentMethod.Generator;

            // find constructor
            var type = FunctionalHelper.CreateDelegateType(Body.Resolve(ctx), _method.ArgumentTypes);
            var ctor = ctx.ResolveConstructor(type, new[] { typeof(object), typeof(IntPtr) });

            var closureInstance = ctx.Scope.ActiveClosure.ClosureVariable;

            gen.EmitLoadLocal(closureInstance);
            gen.EmitLoadFunctionPointer(_method.MethodBuilder);
            gen.EmitCreateObject(ctor.ConstructorInfo);
        }
예제 #9
0
        /// <summary>
        /// Resolves the expression type in case of partial application.
        /// </summary>
        protected static Type resolvePartial(CallableWrapperBase wrapper, Type returnType, Type[] argTypes)
        {
            if (!wrapper.IsPartiallyApplied)
            {
                return(returnType);
            }

            var lambdaArgTypes = new List <Type>();

            for (var idx = 0; idx < argTypes.Length; idx++)
            {
                if (argTypes[idx] == typeof(UnspecifiedType))
                {
                    lambdaArgTypes.Add(wrapper.ArgumentTypes[idx]);
                }
            }

            return(FunctionalHelper.CreateDelegateType(returnType, lambdaArgTypes.ToArray()));
        }
예제 #10
0
        protected override Type resolve(Context ctx, bool mustReturn)
        {
            var argTypes = new List <Type>();

            foreach (var curr in Arguments)
            {
                if (curr.IsVariadic)
                {
                    error(CompilerMessages.VariadicArgumentLambda);
                }

                var type = curr.GetArgumentType(ctx);
                argTypes.Add(type);

                if (type == typeof(UnspecifiedType))
                {
                    MustInferArgTypes = true;
                }
            }

            if (MustInferArgTypes)
            {
                return(FunctionalHelper.CreateLambdaType(argTypes.ToArray()));
            }

            Body.Scope.RegisterArguments(ctx, false, Arguments);

            var retType = Body.Resolve(ctx);

            if (_InferredDelegateType != null)
            {
                if (!_InferredReturnType.IsExtendablyAssignableFrom(retType))
                {
                    error(CompilerMessages.LambdaReturnTypeMismatch, _InferredDelegateType.Name, retType.Name, _InferredReturnType.Name);
                }

                return(_InferredDelegateType);
            }

            return(FunctionalHelper.CreateDelegateType(retType, argTypes.ToArray()));
        }
예제 #11
0
        /// <summary>
        /// Emits code for getting the method as a delegate instance.
        /// </summary>
        private void EmitMethod(Context ctx, ILGenerator gen)
        {
            if (RefArgumentRequired)
            {
                Error(CompilerMessages.MethodRef);
            }

            if (_isStatic)
            {
                gen.EmitNull();
            }

            var retType = _method.ReturnType;
            var type    = retType.IsVoid()
                ? FunctionalHelper.CreateActionType(_method.ArgumentTypes)
                : FunctionalHelper.CreateFuncType(retType, _method.ArgumentTypes);

            var ctor = ctx.ResolveConstructor(type, new[] { typeof(object), typeof(IntPtr) });

            gen.EmitLoadFunctionPointer(_method.MethodInfo);
            gen.EmitCreateObject(ctor.ConstructorInfo);
        }
예제 #12
0
        protected override Type ResolveInternal(Context ctx, bool mustReturn)
        {
            if (Identifier == "_")
            {
                Error(CompilerMessages.UnderscoreNameUsed);
            }

            // local variable
            var local = Local ?? ctx.Scope.FindLocal(Identifier);

            if (local != null)
            {
                // only local constants are cached
                // because mutable variables could be closured later on
                if (local.IsConstant && local.IsImmutable && ctx.Options.UnrollConstants)
                {
                    _localConstant = local;
                }

                return(local.Type);
            }

            // static function declared in the script
            try
            {
                var methods = ctx.MainType.ResolveMethodGroup(Identifier);
                if (methods.Length > 1)
                {
                    Error(CompilerMessages.FunctionInvocationAmbiguous, Identifier);
                }

                _method = methods[0];
                return(FunctionalHelper.CreateFuncType(_method.ReturnType, _method.GetArgumentTypes(ctx)));
            }
            catch (KeyNotFoundException)
            {
            }

            // algebraic type without a constructor
            var type = ctx.FindType(Identifier);

            if (type != null && type.Kind == TypeEntityKind.TypeLabel)
            {
                try
                {
                    type.ResolveConstructor(new Type[0]);
                    _type = type;
                    return(_type.TypeInfo);
                }
                catch (KeyNotFoundException)
                {
                }
            }

            // global property
            try
            {
                _property = ctx.ResolveGlobalProperty(Identifier);
                return(_property.PropertyType);
            }
            catch (KeyNotFoundException)
            {
                Error(CompilerMessages.IdentifierNotFound, Identifier);
            }

            return(typeof(UnitType));
        }