/////////////////////////////////////////////////////////////////////////////////
        // Expression types.

        private ExprBinOp VisitBoundLambda(ExprBoundLambda anonmeth)
        {
            Debug.Assert(anonmeth != null);

            MethodSymbol  lambdaMethod     = GetPreDefMethod(PREDEFMETH.PM_EXPRESSION_LAMBDA);
            AggregateType delegateType     = anonmeth.DelegateType;
            TypeArray     lambdaTypeParams = TypeArray.Allocate(delegateType);
            AggregateType expressionType   = SymbolLoader.GetPredefindType(PredefinedType.PT_EXPRESSION);
            MethWithInst  mwi = new MethWithInst(lambdaMethod, expressionType, lambdaTypeParams);
            Expr          createParameters = CreateWraps(anonmeth);

            Debug.Assert(createParameters != null);
            Debug.Assert(anonmeth.Expression != null);
            Expr body = Visit(anonmeth.Expression);

            Debug.Assert(anonmeth.ArgumentScope.nextChild == null);
            Expr            parameters = GenerateParamsArray(null, PredefinedType.PT_PARAMETEREXPRESSION);
            Expr            args       = ExprFactory.CreateList(body, parameters);
            CType           typeRet    = TypeManager.SubstType(mwi.Meth().RetType, mwi.GetType(), mwi.TypeArgs);
            ExprMemberGroup pMemGroup  = ExprFactory.CreateMemGroup(null, mwi);
            ExprCall        call       = ExprFactory.CreateCall(0, typeRet, args, pMemGroup, mwi);

            call.PredefinedMethod = PREDEFMETH.PM_EXPRESSION_LAMBDA;
            return(ExprFactory.CreateSequence(createParameters, call));
        }
Beispiel #2
0
        public static ExprMemberGroup CreateMemGroup(Expr obj, MethPropWithInst method)
        {
            Name name = method.Sym?.name;

            return(CreateMemGroup(
                       0, name, method.TypeArgs, method.MethProp()?.getKind() ?? SYMKIND.SK_MethodSymbol, method.GetType(),
                       obj, new CMemberLookupResults(TypeArray.Allocate((CType)method.GetType()), name)));
        }
Beispiel #3
0
        ////////////////////////////////////////////////////////////////////////////////
        // We need to rearange the method parameters so that the type of any specified named argument
        // appears in the same place as the named argument. Consider the example below:
        //    Foo(int x = 4, string y = "", long l = 4)
        //    Foo(string y = "", string x="", long l = 5)
        // and the call site:
        //    Foo(y:"a")
        // After rearranging the parameter types we will have:
        //   (string, int, long) and (string, string, long)
        // By rearranging the arguments as such we make sure that any specified named arguments appear in the same position for both
        // methods and we also maintain the relative order of the other parameters (the type long appears after int in the above example)

        private static TypeArray RearrangeNamedArguments(TypeArray pta, MethPropWithInst mpwi, CType pTypeThrough, ArgInfos args)
        {
#if DEBUG
            // We never have a named argument that is in a position in the argument
            // list past the end of what would be the formal parameter list.
            for (int i = pta.Count; i < args.carg; i++)
            {
                Debug.Assert(!(args.prgexpr[i] is ExprNamedArgumentSpecification));
            }
#endif
            // If we've no args we can skip. If the last argument isn't named then either we
            // have no named arguments, and we can skip, or we have non-trailing named arguments
            // and we MUST skip!
            if (args.carg == 0 || !(args.prgexpr[args.carg - 1] is ExprNamedArgumentSpecification))
            {
                return(pta);
            }

            CType   type     = pTypeThrough != null ? pTypeThrough : mpwi.GetType();
            CType[] typeList = new CType[pta.Count];
            MethodOrPropertySymbol methProp = GroupToArgsBinder.FindMostDerivedMethod(mpwi.MethProp(), type);

            // We initialize the new type array with the parameters for the method.
            for (int iParam = 0; iParam < pta.Count; iParam++)
            {
                typeList[iParam] = pta[iParam];
            }

            var prgexpr = args.prgexpr;
            // We then go over the specified arguments and put the type for any named argument in the right position in the array.
            for (int iParam = 0; iParam < args.carg; iParam++)
            {
                if (prgexpr[iParam] is ExprNamedArgumentSpecification named)
                {
                    // We find the index of the type of the argument in the method parameter list and store that in a temp
                    int   index    = FindName(methProp.ParameterNames, named.Name);
                    CType tempType = pta[index];

                    // Starting from the current position in the type list up until the location of the type of the optional argument
                    //  We shift types by one:
                    //   before: (int, string, long)
                    //   after: (string, int, long)
                    // We only touch the types between the current position and the position of the type we need to move
                    for (int iShift = iParam; iShift < index; iShift++)
                    {
                        typeList[iShift + 1] = typeList[iShift];
                    }

                    typeList[iParam] = tempType;
                }
            }

            return(TypeArray.Allocate(typeList));
        }
Beispiel #4
0
        private static TypeArray LoadTypeArrayFromSignature(int[] signature, ref int indexIntoSignatures, TypeArray classTyVars)
        {
            Debug.Assert(signature != null);

            int count = signature[indexIntoSignatures];

            indexIntoSignatures++;

            Debug.Assert(count >= 0);

            CType[] ptypes = new CType[count];
            for (int i = 0; i < ptypes.Length; i++)
            {
                ptypes[i] = LoadTypeFromSignature(signature, ref indexIntoSignatures, classTyVars);
            }

            return(TypeArray.Allocate(ptypes));
        }
Beispiel #5
0
        private static CType LoadTypeFromSignature(int[] signature, ref int indexIntoSignatures, TypeArray classTyVars)
        {
            Debug.Assert(signature != null);

            MethodSignatureEnum current = (MethodSignatureEnum)signature[indexIntoSignatures];

            indexIntoSignatures++;

            switch (current)
            {
            case MethodSignatureEnum.SIG_SZ_ARRAY:
                return(TypeManager.GetArray(LoadTypeFromSignature(signature, ref indexIntoSignatures, classTyVars), 1, true));

            case MethodSignatureEnum.SIG_METH_TYVAR:
                return(TypeManager.GetStdMethTypeVar(signature[indexIntoSignatures++]));

            case MethodSignatureEnum.SIG_CLASS_TYVAR:
                return(classTyVars[signature[indexIntoSignatures++]]);

            case (MethodSignatureEnum)PredefinedType.PT_VOID:
                return(VoidType.Instance);

            default:
                Debug.Assert(current >= 0 && (int)current < (int)PredefinedType.PT_COUNT);
                AggregateSymbol agg       = GetPredefAgg((PredefinedType)current);
                int             typeCount = agg.GetTypeVars().Count;
                if (typeCount == 0)
                {
                    return(TypeManager.GetAggregate(agg, TypeArray.Empty));
                }

                CType[] typeArgs = new CType[typeCount];
                for (int iTypeArg = 0; iTypeArg < typeArgs.Length; iTypeArg++)
                {
                    typeArgs[iTypeArg] = LoadTypeFromSignature(signature, ref indexIntoSignatures, classTyVars);
                }

                return(TypeManager.GetAggregate(agg, TypeArray.Allocate(typeArgs)));
            }
        }
Beispiel #6
0
 public override AggregateType GetAts() =>
 _ats ?? (_ats = TypeManager.GetAggregate(TypeManager.GetNullable(), TypeArray.Allocate(UnderlyingType)));