blob: d775cb365eb172fe3a9b3847395d5cdacd318eeb [file] [log] [blame]
// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.graph;
/**
* Definitions of access control routines.
*
* <p>Follows SE 11, jvm spec, section 5.4.4 on "Access Control", except for aspects related to
* "run-time module", for which all items are assumed to be in the same single such module.
*/
public class AccessControl {
public static boolean isClassAccessible(DexClass clazz, DexProgramClass context) {
if (clazz.accessFlags.isPublic()) {
return true;
}
return clazz.getType().isSamePackage(context.getType());
}
public static boolean isMethodAccessible(
DexEncodedMethod method,
DexClass holder,
DexProgramClass context,
AppInfoWithClassHierarchy appInfo) {
return isMemberAccessible(method.accessFlags, holder, context, appInfo);
}
public static boolean isFieldAccessible(
DexEncodedField field,
DexClass holder,
DexProgramClass context,
AppInfoWithSubtyping appInfo) {
return isMemberAccessible(field.accessFlags, holder, context, appInfo);
}
private static boolean isMemberAccessible(
AccessFlags<?> memberFlags,
DexClass holder,
DexProgramClass context,
AppInfoWithClassHierarchy appInfo) {
if (!isClassAccessible(holder, context)) {
return false;
}
if (memberFlags.isPublic()) {
return true;
}
if (memberFlags.isPrivate()) {
return isNestMate(holder, context);
}
if (holder.getType().isSamePackage(context.getType())) {
return true;
}
if (!memberFlags.isProtected()) {
return false;
}
return appInfo.isSubtype(context.getType(), holder.getType());
}
private static boolean isNestMate(DexClass clazz, DexProgramClass context) {
if (clazz == context) {
return true;
}
if (!clazz.isInANest() || !context.isInANest()) {
return false;
}
return clazz.getNestHost() == context.getNestHost();
}
}