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)); }
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())); }
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); }); }
/// <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) ) ); }
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])); }
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])); }
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); }
/// <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())); }
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())); }
/// <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); }
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)); }