//////////////////////////////////////////////////////////////////////////////// // Determine whether the arg type satisfies the typeBnd constraint. Note that // typeBnd could be just about any type (since we added naked type parameter // constraints). private static bool SatisfiesBound(CSemanticChecker checker, CType arg, CType typeBnd) { if (typeBnd == arg) { return(true); } switch (typeBnd.GetTypeKind()) { default: Debug.Assert(false, "Unexpected type."); return(false); case TypeKind.TK_VoidType: case TypeKind.TK_PointerType: case TypeKind.TK_ErrorType: return(false); case TypeKind.TK_ArrayType: case TypeKind.TK_TypeParameterType: break; case TypeKind.TK_NullableType: typeBnd = typeBnd.AsNullableType().GetAts(checker.GetErrorContext()); if (null == typeBnd) { return(true); } break; case TypeKind.TK_AggregateType: break; } Debug.Assert(typeBnd.IsAggregateType() || typeBnd.IsTypeParameterType() || typeBnd.IsArrayType()); switch (arg.GetTypeKind()) { default: return(false); case TypeKind.TK_ErrorType: case TypeKind.TK_PointerType: return(false); case TypeKind.TK_NullableType: arg = arg.AsNullableType().GetAts(checker.GetErrorContext()); if (null == arg) { return(true); } // Fall through. goto case TypeKind.TK_TypeParameterType; case TypeKind.TK_TypeParameterType: case TypeKind.TK_ArrayType: case TypeKind.TK_AggregateType: return(checker.GetSymbolLoader().HasBaseConversion(arg, typeBnd)); } }
// Check the constraints of any type arguments in the given Type. public static bool CheckConstraints(CSemanticChecker checker, ErrorHandling errHandling, CType type, CheckConstraintsFlags flags) { type = type.GetNakedType(false); if (type is NullableType nub) { CType typeT = nub.GetAts(checker.GetErrorContext()); if (typeT != null) { type = typeT; } else { type = type.GetNakedType(true); } } if (!(type is AggregateType ats)) { return(true); } if (ats.GetTypeArgsAll().Count == 0) { // Common case: there are no type vars, so there are no constraints. ats.fConstraintsChecked = true; ats.fConstraintError = false; return(true); } if (ats.fConstraintsChecked) { // Already checked. if (!ats.fConstraintError || (flags & CheckConstraintsFlags.NoDupErrors) != 0) { // No errors or no need to report errors again. return(!ats.fConstraintError); } } TypeArray typeVars = ats.getAggregate().GetTypeVars(); TypeArray typeArgsThis = ats.GetTypeArgsThis(); TypeArray typeArgsAll = ats.GetTypeArgsAll(); Debug.Assert(typeVars.Count == typeArgsThis.Count); if (!ats.fConstraintsChecked) { ats.fConstraintsChecked = true; ats.fConstraintError = false; } // Check the outer type first. If CheckConstraintsFlags.Outer is not specified and the // outer type has already been checked then don't bother checking it. if (ats.outerType != null && ((flags & CheckConstraintsFlags.Outer) != 0 || !ats.outerType.fConstraintsChecked)) { CheckConstraints(checker, errHandling, ats.outerType, flags); ats.fConstraintError |= ats.outerType.fConstraintError; } if (typeVars.Count > 0) { ats.fConstraintError |= !CheckConstraintsCore(checker, errHandling, ats.getAggregate(), typeVars, typeArgsThis, typeArgsAll, null, (flags & CheckConstraintsFlags.NoErrors)); } // Now check type args themselves. for (int i = 0; i < typeArgsThis.Count; i++) { CType arg = typeArgsThis[i].GetNakedType(true); if (arg is AggregateType atArg && !atArg.fConstraintsChecked) { CheckConstraints(checker, errHandling, atArg, flags | CheckConstraintsFlags.Outer); if (atArg.fConstraintError) { ats.fConstraintError = true; } } } return(!ats.fConstraintError); }
//////////////////////////////////////////////////////////////////////////////// // Determine whether the arg type satisfies the typeBnd constraint. Note that // typeBnd could be just about any type (since we added naked type parameter // constraints). private static bool SatisfiesBound(CSemanticChecker checker, CType arg, CType typeBnd) { if (typeBnd == arg) return true; switch (typeBnd.GetTypeKind()) { default: Debug.Assert(false, "Unexpected type."); return false; case TypeKind.TK_VoidType: case TypeKind.TK_PointerType: case TypeKind.TK_ErrorType: return false; case TypeKind.TK_ArrayType: case TypeKind.TK_TypeParameterType: break; case TypeKind.TK_NullableType: typeBnd = typeBnd.AsNullableType().GetAts(checker.GetErrorContext()); if (null == typeBnd) return true; break; case TypeKind.TK_AggregateType: break; } Debug.Assert(typeBnd.IsAggregateType() || typeBnd.IsTypeParameterType() || typeBnd.IsArrayType()); switch (arg.GetTypeKind()) { default: return false; case TypeKind.TK_ErrorType: case TypeKind.TK_PointerType: return false; case TypeKind.TK_NullableType: arg = arg.AsNullableType().GetAts(checker.GetErrorContext()); if (null == arg) return true; // Fall through. goto case TypeKind.TK_TypeParameterType; case TypeKind.TK_TypeParameterType: case TypeKind.TK_ArrayType: case TypeKind.TK_AggregateType: return checker.GetSymbolLoader().HasBaseConversion(arg, typeBnd); } }
// Check the constraints of any type arguments in the given Type. public static bool CheckConstraints(CSemanticChecker checker, ErrorHandling errHandling, CType type, CheckConstraintsFlags flags) { type = type.GetNakedType(false); if (type.IsNullableType()) { CType typeT = type.AsNullableType().GetAts(checker.GetErrorContext()); if (typeT != null) type = typeT; else type = type.GetNakedType(true); } if (!type.IsAggregateType()) return true; AggregateType ats = type.AsAggregateType(); if (ats.GetTypeArgsAll().size == 0) { // Common case: there are no type vars, so there are no constraints. ats.fConstraintsChecked = true; ats.fConstraintError = false; return true; } if (ats.fConstraintsChecked) { // Already checked. if (!ats.fConstraintError || (flags & CheckConstraintsFlags.NoDupErrors) != 0) { // No errors or no need to report errors again. return !ats.fConstraintError; } } TypeArray typeVars = ats.getAggregate().GetTypeVars(); TypeArray typeArgsThis = ats.GetTypeArgsThis(); TypeArray typeArgsAll = ats.GetTypeArgsAll(); Debug.Assert(typeVars.size == typeArgsThis.size); if (!ats.fConstraintsChecked) { ats.fConstraintsChecked = true; ats.fConstraintError = false; } // Check the outer type first. If CheckConstraintsFlags.Outer is not specified and the // outer type has already been checked then don't bother checking it. if (ats.outerType != null && ((flags & CheckConstraintsFlags.Outer) != 0 || !ats.outerType.fConstraintsChecked)) { CheckConstraints(checker, errHandling, ats.outerType, flags); ats.fConstraintError |= ats.outerType.fConstraintError; } if (typeVars.size > 0) ats.fConstraintError |= !CheckConstraintsCore(checker, errHandling, ats.getAggregate(), typeVars, typeArgsThis, typeArgsAll, null, (flags & CheckConstraintsFlags.NoErrors)); // Now check type args themselves. for (int i = 0; i < typeArgsThis.size; i++) { CType arg = typeArgsThis.Item(i).GetNakedType(true); if (arg.IsAggregateType() && !arg.AsAggregateType().fConstraintsChecked) { CheckConstraints(checker, errHandling, arg.AsAggregateType(), flags | CheckConstraintsFlags.Outer); if (arg.AsAggregateType().fConstraintError) ats.fConstraintError = true; } } return !ats.fConstraintError; }
private void Reset() { _controller = new RuntimeBinderController(); _semanticChecker = new LangCompiler(_controller, new NameManager()); BSYMMGR bsymmgr = _semanticChecker.getBSymmgr(); NameManager nameManager = _semanticChecker.GetNameManager(); InputFile infile = bsymmgr.GetMiscSymFactory().CreateMDInfile(nameManager.Lookup(""), (mdToken)0); infile.SetAssemblyID(bsymmgr.AidAlloc(infile)); infile.AddToAlias(KAID.kaidThisAssembly); infile.AddToAlias(KAID.kaidGlobal); _symbolTable = new SymbolTable( bsymmgr.GetSymbolTable(), bsymmgr.GetSymFactory(), nameManager, _semanticChecker.GetTypeManager(), bsymmgr, _semanticChecker, infile); _semanticChecker.getPredefTypes().Init(_semanticChecker.GetErrorContext(), _symbolTable); _semanticChecker.GetTypeManager().InitTypeFactory(_symbolTable); SymbolLoader.getPredefinedMembers().RuntimeBinderSymbolTable = _symbolTable; SymbolLoader.SetSymbolTable(_symbolTable); _exprFactory = new ExprFactory(_semanticChecker.GetSymbolLoader().GetGlobalSymbolContext()); _outputContext = new OutputContext(); _nameGenerator = new NameGenerator(); _bindingContext = BindingContext.CreateInstance( _semanticChecker, _exprFactory, _outputContext, _nameGenerator, false, true, false, false, false, false, 0); _binder = new ExpressionBinder(_bindingContext); }