/// <summary> /// Resolves static properties. /// </summary> public DProperty/*!*/ ResolveProperty(DType/*!*/ type, VariableName propertyName, Position position, bool staticOnly, PhpType referringType, PhpRoutine referringRoutine, out bool checkVisibilityAtRuntime) { Debug.Assert(type != null); checkVisibilityAtRuntime = false; // we cannot resolve a property unless we know the inherited members: if (type.IsDefinite) { DProperty property; GetMemberResult member_result = type.GetProperty(propertyName, referringType, out property); switch (member_result) { case GetMemberResult.OK: if (staticOnly && !property.IsStatic) goto case GetMemberResult.NotFound; return property; case GetMemberResult.NotFound: ErrorSink.Add(Errors.UnknownPropertyAccessed, SourceUnit, position, type.FullName, propertyName); return new UnknownProperty(type, propertyName.Value); case GetMemberResult.BadVisibility: if (referringType == null && referringRoutine == null) { // visibility must be checked at run-time: checkVisibilityAtRuntime = true; return property; } else { // definitive error: if (property.IsPrivate) { ErrorSink.Add(Errors.PrivatePropertyAccessed, SourceUnit, position, type.FullName, propertyName.Value, referringType.FullName); } else { ErrorSink.Add(Errors.ProtectedPropertyAccessed, SourceUnit, position, type.FullName, propertyName.Value, referringType.FullName); } return new UnknownProperty(type, propertyName.Value); } default: Debug.Fail(); throw null; } } else { // warning (if any) reported by the type resolver: return new UnknownProperty(type, propertyName.Value); } }