public SubstType ( |
||
typeSrc | ||
atsCls | ||
Результат |
///////////////////////////////////////////////////////////////////////////////// // 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)); }
public AggregateType GetBaseClass() { if (_baseType == null) { Type baseSysType = AssociatedSystemType.BaseType; if (baseSysType == null) { return(null); } // If we have a generic type definition, then we need to set the // base class to be our current base type, and use that to calculate // our agg type and its base, then set it to be the generic version of the // base type. This is because: // // Suppose we have Foo<T> : IFoo<T> // // Initially, the BaseType will be IFoo<Foo.T>, which gives us the substitution // that we want to use for our agg type's base type. However, in the Symbol chain, // we want the base type to be IFoo<IFoo.T>. So we need to substitute. // // If we don't have a generic type definition, then we just need to set our base // class. This is so that if we have a base type that's generic, we'll be // getting the correctly instantiated base type. TypeManager manager = GetOwningAggregate().GetTypeManager(); AggregateType baseClass = manager.SymbolTable.GetCTypeFromType(baseSysType) as AggregateType; Debug.Assert(baseClass != null); _baseType = manager.SubstType(baseClass, GetTypeArgsAll()); } return(_baseType); }
public static ACCESSERROR CheckAccess2(Symbol symCheck, AggregateType atsCheck, Symbol symWhere, CType typeThru) { Debug.Assert(symCheck != null); Debug.Assert(atsCheck == null || symCheck.parent == atsCheck.OwningAggregate); Debug.Assert(typeThru == null || typeThru is AggregateType || typeThru is TypeParameterType || typeThru is ArrayType || typeThru is NullableType); #if DEBUG switch (symCheck.getKind()) { case SYMKIND.SK_MethodSymbol: case SYMKIND.SK_PropertySymbol: case SYMKIND.SK_FieldSymbol: case SYMKIND.SK_EventSymbol: Debug.Assert(atsCheck != null); break; } #endif // DEBUG ACCESSERROR error = CheckAccessCore(symCheck, atsCheck, symWhere, typeThru); if (ACCESSERROR.ACCESSERROR_NOERROR != error) { return(error); } // Check the accessibility of the return CType. CType type = symCheck.getType(); if (type == null) { return(ACCESSERROR.ACCESSERROR_NOERROR); } // For members of AGGSYMs, atsCheck should always be specified! Debug.Assert(atsCheck != null); // Substitute on the CType. if (atsCheck.TypeArgsAll.Count > 0) { type = TypeManager.SubstType(type, atsCheck); } return(CheckTypeAccess(type, symWhere) ? ACCESSERROR.ACCESSERROR_NOERROR : ACCESSERROR.ACCESSERROR_NOACCESS); }
private static Expr GenerateUserDefinedConversion(Expr arg, CType CType, Expr target, MethWithInst method) { // The user-defined explicit conversion from enum? to decimal or decimal? requires // that we convert the enum? to its nullable underlying CType. if (isEnumToDecimalConversion(arg.Type, CType)) { // Special case: If we have enum? to decimal? then we need to emit // a conversion from enum? to its nullable underlying CType first. // This is unfortunate; we ought to reorganize how conversions are // represented in the Expr tree so that this is more transparent. // converting an enum to its underlying CType never fails, so no need to check it. CType underlyingType = arg.Type.StripNubs().UnderlyingEnumType; CType nullableType = TypeManager.GetNullable(underlyingType); Expr typeofNubEnum = CreateTypeOf(nullableType); target = GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, target, typeofNubEnum); } // If the methodinfo does not return the target CType AND this is not a lifted conversion // from one value CType to another, then we need to wrap the whole thing in another conversion, // e.g. if we have a user-defined conversion from int to S? and we have (S)myint, then we need to generate // Convert(Convert(myint, typeof(S?), op_implicit), typeof(S)) CType pMethodReturnType = TypeManager.SubstType(method.Meth().RetType, method.GetType(), method.TypeArgs); bool fDontLiftReturnType = (pMethodReturnType == CType || (IsNullableValueType(arg.Type) && IsNullableValueType(CType))); Expr typeofInner = CreateTypeOf(fDontLiftReturnType ? CType : pMethodReturnType); Expr methodInfo = ExprFactory.CreateMethodInfo(method); PREDEFMETH pdmInner = arg.isChecked() ? PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED_USER_DEFINED : PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED; Expr callUserDefinedConversion = GenerateCall(pdmInner, target, typeofInner, methodInfo); if (fDontLiftReturnType) { return(callUserDefinedConversion); } PREDEFMETH pdmOuter = arg.isChecked() ? PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED : PREDEFMETH.PM_EXPRESSION_CONVERT; Expr typeofOuter = CreateTypeOf(CType); return(GenerateCall(pdmOuter, callUserDefinedConversion, typeofOuter)); }
private static bool IsDelegateType(CType pSrcType, AggregateType pAggType) => TypeManager.SubstType(pSrcType, pAggType, pAggType.TypeArgsAll).IsDelegateType;