<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />

CSemanticChecker

static class CSemanticChecker
using Microsoft.CSharp.RuntimeBinder.Errors; namespace Microsoft.CSharp.RuntimeBinder.Semantics { internal static class CSemanticChecker { public static void CheckForStaticClass(CType type) { if (type.IsStaticClass) throw ErrorHandling.Error(ErrorCode.ERR_ConvertToStaticClass, type); } public static ACCESSERROR CheckAccess2(Symbol symCheck, AggregateType atsCheck, Symbol symWhere, CType typeThru) { ACCESSERROR aCCESSERROR = CheckAccessCore(symCheck, atsCheck, symWhere, typeThru); if (ACCESSERROR.ACCESSERROR_NOERROR != aCCESSERROR) return aCCESSERROR; CType cType = symCheck.getType(); if (cType == null) return ACCESSERROR.ACCESSERROR_NOERROR; if (atsCheck.TypeArgsAll.Count > 0) cType = TypeManager.SubstType(cType, atsCheck); if (!CheckTypeAccess(cType, symWhere)) return ACCESSERROR.ACCESSERROR_NOACCESS; return ACCESSERROR.ACCESSERROR_NOERROR; } public static bool CheckTypeAccess(CType type, Symbol symWhere) { type = type.GetNakedType(true); AggregateType aggregateType = type as AggregateType; if (aggregateType == null) return true; do { if (ACCESSERROR.ACCESSERROR_NOERROR != CheckAccessCore(aggregateType.OwningAggregate, aggregateType.OuterType, symWhere, null)) return false; aggregateType = aggregateType.OuterType; } while (aggregateType != null); TypeArray typeArgsAll = ((AggregateType)type).TypeArgsAll; for (int i = 0; i < typeArgsAll.Count; i++) { if (!CheckTypeAccess(typeArgsAll[i], symWhere)) return false; } return true; } private static ACCESSERROR CheckAccessCore(Symbol symCheck, AggregateType atsCheck, Symbol symWhere, CType typeThru) { switch (symCheck.GetAccess()) { default: throw Error.InternalCompilerError(); case ACCESS.ACC_UNKNOWN: return ACCESSERROR.ACCESSERROR_NOACCESS; case ACCESS.ACC_PUBLIC: return ACCESSERROR.ACCESSERROR_NOERROR; case ACCESS.ACC_PRIVATE: case ACCESS.ACC_PROTECTED: if (symWhere == null) return ACCESSERROR.ACCESSERROR_NOACCESS; break; case ACCESS.ACC_INTERNAL: case ACCESS.ACC_INTERNALPROTECTED: if (symWhere == null) return ACCESSERROR.ACCESSERROR_NOACCESS; if (symWhere.SameAssemOrFriend(symCheck)) return ACCESSERROR.ACCESSERROR_NOERROR; if (symCheck.GetAccess() == ACCESS.ACC_INTERNAL) return ACCESSERROR.ACCESSERROR_NOACCESS; break; case ACCESS.ACC_INTERNAL_AND_PROTECTED: if (symWhere == null || !symWhere.SameAssemOrFriend(symCheck)) return ACCESSERROR.ACCESSERROR_NOACCESS; break; } AggregateSymbol aggregateSymbol = null; for (Symbol symbol = symWhere; symbol != null; symbol = symbol.parent) { AggregateSymbol aggregateSymbol2 = symbol as AggregateSymbol; if (aggregateSymbol2 != null) { aggregateSymbol = aggregateSymbol2; break; } } if (aggregateSymbol == null) return ACCESSERROR.ACCESSERROR_NOACCESS; AggregateSymbol aggregateSymbol3 = symCheck.parent as AggregateSymbol; for (AggregateSymbol aggregateSymbol4 = aggregateSymbol; aggregateSymbol4 != null; aggregateSymbol4 = aggregateSymbol4.GetOuterAgg()) { if (aggregateSymbol4 == aggregateSymbol3) return ACCESSERROR.ACCESSERROR_NOERROR; } if (symCheck.GetAccess() == ACCESS.ACC_PRIVATE) return ACCESSERROR.ACCESSERROR_NOACCESS; AggregateType aggregateType = null; if (typeThru != null && !symCheck.isStatic) aggregateType = typeThru.GetAts(); bool flag = false; for (AggregateSymbol aggregateSymbol5 = aggregateSymbol; aggregateSymbol5 != null; aggregateSymbol5 = aggregateSymbol5.GetOuterAgg()) { if (aggregateSymbol5.FindBaseAgg(aggregateSymbol3)) { flag = true; if (aggregateType == null || aggregateType.OwningAggregate.FindBaseAgg(aggregateSymbol5)) return ACCESSERROR.ACCESSERROR_NOERROR; } } if (!flag) return ACCESSERROR.ACCESSERROR_NOACCESS; return ACCESSERROR.ACCESSERROR_NOACCESSTHRU; } public static bool CheckBogus(Symbol sym) { return (sym as PropertySymbol)?.Bogus ?? false; } public static RuntimeBinderException ReportAccessError(SymWithType swtBad, Symbol symWhere, CType typeQual) { if (CheckAccess2(swtBad.Sym, swtBad.GetType(), symWhere, typeQual) != ACCESSERROR.ACCESSERROR_NOACCESSTHRU) return ErrorHandling.Error(ErrorCode.ERR_BadAccess, swtBad); return ErrorHandling.Error(ErrorCode.ERR_BadProtectedAccess, swtBad, typeQual, symWhere); } public static bool CheckAccess(Symbol symCheck, AggregateType atsCheck, Symbol symWhere, CType typeThru) { return CheckAccess2(symCheck, atsCheck, symWhere, typeThru) == ACCESSERROR.ACCESSERROR_NOERROR; } } }