Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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());
        }
Esempio n. 3
0
        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);
            }
        }