public static Expression <TDelegate> Optimize <TDelegate>(LambdaExpression expression, int startIndex, IndexMap indexMap, bool tupleInput, bool factInput) { var parts = new ExpressionParts(expression, startIndex); if (tupleInput) { UnwrapTuple(parts, indexMap, factInput ? indexMap.Length - 1 : indexMap.Length); } if (factInput) { UnwrapFact(parts, indexMap); } var invocation = EnsureReturnType(expression.Body, typeof(TDelegate)); parts.Body.Add(invocation); var optimizedLambda = Expression.Lambda <TDelegate>( Expression.Block(parts.BodyParameters, parts.Body), parts.InputParameters); return(optimizedLambda); }
/// <summary> /// Calls an formatter /// </summary> /// <param name="functionName"></param> /// <param name="arguments"></param> /// <returns></returns> public PropertyMorestachioExpressionBuilder Call(string functionName, Func <MorestachioArgumentExpressionBuilder, MorestachioArgumentExpressionBuilder> arguments = null) { MorestachioExpression targetExpression; if (ExpressionParts.LastOrDefault() is MorestachioExpression exp && exp.FormatterName == null) { exp.FormatterName = functionName; targetExpression = exp; }
/// <summary> /// Goes one level up /// </summary> /// <returns></returns> public MorestachioParentPathExpressionBuilder GoToParent() { var morestachioExpression = new MorestachioExpression(CharacterLocation.Unknown); morestachioExpression.PathParts = new Traversable(new[] { new KeyValuePair <string, PathType>(null, PathType.ParentSelector) }); ExpressionParts.Add(morestachioExpression); return(new MorestachioParentPathExpressionBuilder(ExpressionParts, Column, morestachioExpression)); }
/// <summary> /// Returns the null value /// </summary> /// <returns></returns> public MorestachioExpressionBuilder Null() { var morestachioExpression = new MorestachioExpression(CharacterLocation.Unknown); morestachioExpression.PathParts = new Traversable(new[] { new KeyValuePair <string, PathType>(null, PathType.Null) }); ExpressionParts.Add(morestachioExpression); return(this); }
private static void UnwrapFact(ExpressionParts parts, IndexMap indexMap) { var factParameter = Expression.Parameter(typeof(Fact), "<fact>"); parts.InputParameters.Add(factParameter); var parameterIndex = indexMap[indexMap.Length - 1]; if (parameterIndex >= 0) { var bodyParameter = parts.BodyParameters[parameterIndex]; parts.Body.Add( AssignFactValue(factParameter, bodyParameter)); } }
/// <summary> /// Set Tobor's expression to given index /// </summary> /// <param name="expressionIndex"></param> public void SetExpression(int expressionIndex) { //Handle exception on first time setting expression try { _curExpression.LeftEye.SetActive(false); _curExpression.RightEye.SetActive(false); } catch (Exception) { } _curExpression = expressions[expressionIndex]; _curExpression.LeftEye.SetActive(true); _curExpression.RightEye.SetActive(true); }
public static Expression <TDelegate> Optimize <TDelegate>(LambdaExpression expression, IndexMap factIndexMap, List <DependencyElement> dependencies, IndexMap dependencyIndexMap) { var parts = new ExpressionParts(expression, 1); UnwrapTuple(parts, factIndexMap, factIndexMap.Length); ResolveDependencies(parts, dependencies, dependencyIndexMap); var invocation = EnsureReturnType(expression.Body, typeof(TDelegate)); parts.Body.Add(invocation); var optimizedLambda = Expression.Lambda <TDelegate>( Expression.Block(parts.BodyParameters, parts.Body), parts.InputParameters); return(optimizedLambda); }
private static void UnwrapTuple(ExpressionParts parts, IndexMap indexMap, int tupleSize) { var tupleParameter = Expression.Parameter(typeof(Tuple), "<tuple>"); parts.InputParameters.Add(tupleParameter); if (tupleSize <= 0) { return; } var enumerator = Expression.Variable(typeof(Tuple.Enumerator), "<enumerator>"); parts.BodyParameters.Add(enumerator); parts.Body.Add( Expression.Assign(enumerator, Expression.Call(tupleParameter, GetEnumeratorMethod))); var intermediateParts = new List <Expression>(tupleSize); for (int i = tupleSize - 1; i >= 0; i--) { intermediateParts.Add( Expression.Call(enumerator, MoveNextMethod)); var parameterIndex = indexMap[i]; if (parameterIndex >= 0) { parts.Body.AddRange(intermediateParts); intermediateParts.Clear(); var bodyParameter = parts.BodyParameters[parameterIndex]; var currentFact = Expression.Property(enumerator, CurrentProperty); parts.Body.Add( AssignFactValue(currentFact, bodyParameter)); } } }
/// <summary> /// Adds one or more .(dot) separated property paths to the expression or creates a new one /// </summary> /// <param name="property"></param> /// <returns></returns> public PropertyMorestachioExpressionBuilder Property(string property) { var parts = property.Split('.'); var pathParts = new PathTokenizer.PathPartsCollection(); foreach (var part in parts) { for (var index = 0; index < part.Length; index++) { var pathPartChar = part[index]; if (!Tokenizer.IsSingleExpressionPathChar(pathPartChar) && pathPartChar != '$') { throw new InvalidOperationException("The property " + part + " contains invalid chars at " + index); } } pathParts.Add(part, PathType.DataPath); } Column += property.Length; if (ExpressionParts.LastOrDefault() is MorestachioExpression exp && exp.FormatterName == null) { exp.PathParts = exp.PathParts.Expand(pathParts.GetList()); }
private static void ResolveDependencies(ExpressionParts parts, List <DependencyElement> dependencies, IndexMap indexMap) { var resolverParameter = Expression.Parameter(typeof(IDependencyResolver), "<resolver>"); parts.InputParameters.Add(resolverParameter); var resolutionContextParameter = Expression.Parameter(typeof(IResolutionContext), "<resolutionContext>"); parts.InputParameters.Add(resolutionContextParameter); for (int i = 0; i <= indexMap.Length; i++) { var parameterIndex = indexMap[i]; if (parameterIndex >= 0) { var parameter = parts.BodyParameters[parameterIndex]; var parameterType = dependencies[i].ServiceType; var resolveDependency = Expression.Call( resolverParameter, ResolveMethod, resolutionContextParameter, Expression.Constant(parameterType)); parts.Body.Add( Expression.Assign(parameter, Expression.Convert(resolveDependency, parameterType))); } } }
/// <summary> /// Adds a number at the start of an expression /// </summary> /// <param name="number"></param> /// <returns></returns> public MorestachioExpressionBuilder Number(Number number) { ExpressionParts.Add(new MorestachioExpressionNumber(number, new CharacterLocation(0, Column))); Column += number.AsParsableString().Length; return(this); }
/// <summary> /// Helper for parsing an fully qualified expression /// </summary> /// <param name="expression"></param> /// <returns></returns> public MorestachioExpressionBuilder Parse(string expression) { ExpressionParts.Add(MorestachioExpression.ParseFrom(expression, TokenzierContext.FromText(expression), out _)); return(this); }