示例#1
0
        /// <summary>
        /// Creates the lambda expression from the statements attached to this entry and the parameter definitions in the provided program context.
        /// </summary>
        public LambdaExpression CreateLambda(VisualProgram context)
        {
            if (!context.Environment.EntryDefinitions.TryGetValue(VisualEntryId, out var def))
            {
                throw new KeyNotFoundException($"Could not find an entry with ID '{VisualEntryId}' in the VisualProgram's entry definitions.");
            }

            // Create a parameter for each expected/defined parameter
            var parameters = def.Parameters.Map(Expression.Parameter);

            return(Expression.Lambda(
                       Expression.Block(
                           // Before doing the main body of the entry function, make expressions to copy the incoming parameters to variables
                           ParameterMap
                           .Where(mapping => !string.IsNullOrWhiteSpace(mapping.Value)) // Exclude any that don't actually map to anything
                           .Select(p => VariableAccessorFactory.CreateSetterExpression(
                                       context,
                                       VariableReference.Create(def.Parameters[p.Key], p.Value),
                                       parameters[p.Key]
                                       )
                                   ).Concat(
                               // Then do the actual main body
                               NodeUtils.FlattenExpressions(context, FirstStatement)
                               )
                           ),

                       // All lambdas will get a context parameter
                       // We also pass the defined parameters to the lambda so it knows what types to expect and what signature to have.
                       // This needs to happen regardless or not of whether the parameters are actually used by the entry function as this determines the delegate's signature.
                       new[] { context.Variables.compiledInstanceParameter }.Concat(parameters)
                       ));
        }
        /// <summary>Resolves this reference into a single <see cref="BlockExpression"/> containing all the sequential statements.
        /// If there are no statements that would end up in the block, throws an exception.</summary>
        /// <exception cref="Exception"></exception>
        public BlockExpression ResolveRequiredStatement(VisualProgram context)
        {
            var body = NodeUtils.FlattenExpressions(context, this);

            if (body.Count() == 0)
            {
                throw new Exception();                                // TODO Add meaningful message
            }
            return(Expression.Block(expressions: body));
        }
示例#3
0
 public void Validate(VisualProgram context)
 {
     if (string.IsNullOrWhiteSpace(Name))
     {
         throw new Exception();                 // TODO: Add meaningful error message. If this is thrown, variable isn't provided
     }
     if (!context.Variables.TryGetVariable(Name, out var def))
     {
         throw new Exception();                 // TODO: Add meaninful error message. If this is thrown, could not find a variable with the target name.
     }
     if (def.Type != Type)
     {
         throw new Exception();                 // TODO: Add meaningful message. If this is thrown, variable is wrong type
     }
 }
示例#4
0
 /// <summary>Gets the Linq Expression for this node.</summary>
 /// <param name="context">The program context. Required for variables, resolving links, etc.</param>
 public abstract Expression CreateExpression(VisualProgram context);
示例#5
0
 public Expression ResolveRequiredExpression(VisualProgram context) => ResolveExpression(context) ?? throw new Exception();
示例#6
0
 public Expression?ResolveExpression(VisualProgram context) => isValue
                 ? Expression.Constant(value, typeof(TValue))
                 : nodeId.HasValue ? context.Nodes[nodeId.Value]?.CreateExpression(context) : null;
示例#7
0
 public VisualNode ResolveRequiredNode(VisualProgram context) => ResolveNode(context) ?? throw new Exception();
示例#8
0
#pragma warning restore CS8653

        public VisualNode?ResolveNode(VisualProgram context) => isValue || !nodeId.HasValue ? null : context.Nodes[nodeId.Value];
示例#9
0
 /// <summary>Alias for <see cref="CreateLambda(VisualProgram)"/>.</summary>
 public override Expression CreateExpression(VisualProgram context) => CreateLambda(context);
示例#10
0
 public Expression?ResolveSetterExpression(VisualProgram context, Expression value)
 {
     try { return(ResolveRequiredSetterExpression(context, value)); } catch { return(null); }
 }
示例#11
0
 public Expression ResolveRequiredSetterExpression(VisualProgram context, Expression value) => VariableAccessorFactory.CreateSetterExpression(context, this, value);
示例#12
0
 public Expression?ResolveGetterExpression(VisualProgram context)
 {
     try { return(ResolveRequiredGetterExpression(context)); } catch { return(null); }
 }
示例#13
0
 public Expression ResolveRequiredGetterExpression(VisualProgram context) => VariableAccessorFactory.CreateGetterExpression(context, this, typeof(TVar));
 /// <summary>Resolves this reference into a single <see cref="BlockExpression"/> containing all the sequential statements.</summary>
 public BlockExpression ResolveStatement(VisualProgram context) => Expression.Block(expressions: NodeUtils.FlattenExpressions(context, this));
 public Expression?ResolveExpression(VisualProgram context) => ResolveNode(context)?.CreateExpression(context);
 public VisualNode?ResolveNode(VisualProgram context) => context.Nodes[nodeId];