private void CheckLambdaExpression(LambdaExpression e, TypeCheckingContext context) { e.Type = typeof(LambdaExpression); if (e.Level != context.LambdaContext.GetCallerStackSize()) { return; } context.LambdaContext.PushVariables(e.VariableNames); e.VariableTypes = new Type[e.VariableNames.Length]; int index = 0; foreach (string variableName in e.VariableNames) { LambdaVariable variable = context.LambdaContext.GetVariable(variableName); Expression lambdaOperand; string methodName; if (variable.CallerMethod is MethodCallExpression) { MethodCallExpression mc = variable.CallerMethod as MethodCallExpression; lambdaOperand = mc.IsExtension ? mc.Operand : mc.Parameters[0]; methodName = mc.MethodName; } else { FunctionCallExpression fc = variable.CallerMethod as FunctionCallExpression; lambdaOperand = fc.Parameters[0]; methodName = fc.MethodName; } Type type = ResolveLambdaParameterType(lambdaOperand.Type, index); if (type == null) { context.ErrorProvider.ThrowException(string.Format("Cannot apply lambda parameter {0} to method {1}", variableName, methodName), e); } e.VariableTypes[index] = type; context.LambdaContext.GetVariable(variableName).Type = type; index++; } PerformTypeChecking(e.Body, context); context.LambdaContext.PopVariables(e.VariableNames.Length); }
public LambdaAction(ParseInfo parseInfo, Scope scope, LambdaExpression context) { _context = context; _lambdaScope = scope.Child(); _parseInfo = parseInfo; _contextualParameterTypesKnown = _parseInfo.ExpectingLambda != null && _parseInfo.ExpectingLambda.Type.ParameterTypesKnown; RecursiveCallHandler = new LambdaRecursionHandler(this); CallInfo = new CallInfo(RecursiveCallHandler, parseInfo.Script); This = scope.GetThis(); _isExplicit = context.Parameters.Any(p => p.Type != null); var parameterState = context.Parameters.Count == 0 || _isExplicit ? ParameterState.CountAndTypesKnown : ParameterState.CountKnown; // Get the lambda parameters. Parameters = new Var[context.Parameters.Count]; InvokedState = new SubLambdaInvoke[Parameters.Length]; _argumentTypes = new CodeType[Parameters.Length]; for (int i = 0; i < Parameters.Length; i++) { if (_isExplicit && context.Parameters[i].Type == null) { parseInfo.Script.Diagnostics.Error("Inconsistent lambda parameter usage; parameter types must be all explicit or all implicit", context.Parameters[i].Range); } InvokedState[i] = new SubLambdaInvoke(); Parameters[i] = new LambdaVariable(i, _parseInfo.ExpectingLambda?.Type, _lambdaScope, new LambdaContextHandler(parseInfo, context.Parameters[i]), InvokedState[i]); _argumentTypes[i] = Parameters[i].CodeType; } new CheckLambdaContext( parseInfo, this, "Cannot determine lambda in the current context", context.Range, parameterState ).Check(); // Add hover info // parseInfo.Script.AddHover(context.Arrow.Range, new MarkupBuilder().StartCodeLine().Add(LambdaType.GetName()).EndCodeLine().ToString()); }
private void CheckVariableExpression(VariableExpression e, TypeCheckingContext context) { LambdaVariable variable = context.LambdaContext.GetVariable(e.VariableName); if (variable != null) { e.Type = context.LambdaContext.GetVariable(variable.Name).Type; } else if (context.VariableContext.HasVariable(e.VariableName)) { e.Type = context.VariableContext.GetType(e.VariableName); } else if (context.CreateVariableOnAssign && context.RightOperandType != null) { context.VariableContext.Set(e.VariableName, context.CreateAutoCreatedVariableValue(context.RightOperandType)); e.Type = context.VariableContext.GetType(e.VariableName); } else { context.ErrorProvider.ThrowException(string.Format("{0} not defined.", e.VariableName), e); } }