aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Zerny <zerny@google.com>2017-10-26 13:36:14 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2017-10-26 13:36:14 +0000
commitbc8be4d8a8438ebd0be73fe655e160e22da3be9d (patch)
treebf673bdf67ec542a3a59977056ae396b172e7443
parent4d22d2d18bab390754a423972ffc2a7b47fbde79 (diff)
parentf76614b69a9a5cdf865087797546add35401ab07 (diff)
downloadr8-bc8be4d8a8438ebd0be73fe655e160e22da3be9d.tar.gz
Merge "Define distinct access-flag types for classes, methods and fields."
-rw-r--r--src/main/java/com/android/tools/r8/dex/Constants.java1
-rw-r--r--src/main/java/com/android/tools/r8/dex/DexFileReader.java10
-rw-r--r--src/main/java/com/android/tools/r8/dex/FileWriter.java6
-rw-r--r--src/main/java/com/android/tools/r8/graph/AccessFlags.java187
-rw-r--r--src/main/java/com/android/tools/r8/graph/ClassAccessFlags.java134
-rw-r--r--src/main/java/com/android/tools/r8/graph/ClassKind.java4
-rw-r--r--src/main/java/com/android/tools/r8/graph/DexAccessFlags.java310
-rw-r--r--src/main/java/com/android/tools/r8/graph/DexClass.java4
-rw-r--r--src/main/java/com/android/tools/r8/graph/DexClasspathClass.java2
-rw-r--r--src/main/java/com/android/tools/r8/graph/DexEncodedField.java7
-rw-r--r--src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java14
-rw-r--r--src/main/java/com/android/tools/r8/graph/DexLibraryClass.java2
-rw-r--r--src/main/java/com/android/tools/r8/graph/DexProgramClass.java4
-rw-r--r--src/main/java/com/android/tools/r8/graph/FieldAccessFlags.java93
-rw-r--r--src/main/java/com/android/tools/r8/graph/JarClassFileReader.java37
-rw-r--r--src/main/java/com/android/tools/r8/graph/MethodAccessFlags.java184
-rw-r--r--src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java4
-rw-r--r--src/main/java/com/android/tools/r8/ir/desugar/AccessorMethodSourceCode.java4
-rw-r--r--src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java4
-rw-r--r--src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java7
-rw-r--r--src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java103
-rw-r--r--src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java6
-rw-r--r--src/main/java/com/android/tools/r8/ir/optimize/Inliner.java11
-rw-r--r--src/main/java/com/android/tools/r8/ir/optimize/Outliner.java9
-rw-r--r--src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java14
-rw-r--r--src/main/java/com/android/tools/r8/shaking/ProguardAccessFlags.java176
-rw-r--r--src/main/java/com/android/tools/r8/shaking/ProguardAlwaysInlineRule.java5
-rw-r--r--src/main/java/com/android/tools/r8/shaking/ProguardAssumeNoSideEffectRule.java5
-rw-r--r--src/main/java/com/android/tools/r8/shaking/ProguardAssumeValuesRule.java5
-rw-r--r--src/main/java/com/android/tools/r8/shaking/ProguardCheckDiscardRule.java5
-rw-r--r--src/main/java/com/android/tools/r8/shaking/ProguardClassSpecification.java25
-rw-r--r--src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java10
-rw-r--r--src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java5
-rw-r--r--src/main/java/com/android/tools/r8/shaking/ProguardIdentifierNameStringRule.java5
-rw-r--r--src/main/java/com/android/tools/r8/shaking/ProguardKeepPackageNamesRule.java5
-rw-r--r--src/main/java/com/android/tools/r8/shaking/ProguardKeepRule.java5
-rw-r--r--src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java41
-rw-r--r--src/main/java/com/android/tools/r8/shaking/ProguardWhyAreYouKeepingRule.java5
-rw-r--r--src/main/java/com/android/tools/r8/shaking/ReasonPrinter.java6
-rw-r--r--src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java4
-rw-r--r--src/test/java/com/android/tools/r8/dex/JumboStringProcessing.java5
-rw-r--r--src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java18
-rw-r--r--src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java8
-rw-r--r--src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java48
-rw-r--r--src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java13
-rw-r--r--src/test/java/com/android/tools/r8/utils/DexInspector.java45
-rw-r--r--src/test/proguard/valid/access-flags.flags2
47 files changed, 1017 insertions, 590 deletions
diff --git a/src/main/java/com/android/tools/r8/dex/Constants.java b/src/main/java/com/android/tools/r8/dex/Constants.java
index 50af413c7..12ae77ff8 100644
--- a/src/main/java/com/android/tools/r8/dex/Constants.java
+++ b/src/main/java/com/android/tools/r8/dex/Constants.java
@@ -115,6 +115,7 @@ public class Constants {
public static final int ACC_PROTECTED = 0x4;
public static final int ACC_STATIC = 0x8;
public static final int ACC_FINAL = 0x10;
+ public static final int ACC_SUPER = 0x20;
public static final int ACC_SYNCHRONIZED = 0x20;
public static final int ACC_VOLATILE = 0x40;
public static final int ACC_BRIDGE = 0x40;
diff --git a/src/main/java/com/android/tools/r8/dex/DexFileReader.java b/src/main/java/com/android/tools/r8/dex/DexFileReader.java
index 64909cc3a..4b0d6e2fc 100644
--- a/src/main/java/com/android/tools/r8/dex/DexFileReader.java
+++ b/src/main/java/com/android/tools/r8/dex/DexFileReader.java
@@ -12,9 +12,9 @@ import com.android.tools.r8.Resource.Origin;
import com.android.tools.r8.Resource.PathOrigin;
import com.android.tools.r8.code.Instruction;
import com.android.tools.r8.code.InstructionFactory;
+import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.ClassKind;
import com.android.tools.r8.graph.Descriptor;
-import com.android.tools.r8.graph.DexAccessFlags;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotationElement;
import com.android.tools.r8.graph.DexAnnotationSet;
@@ -50,6 +50,8 @@ import com.android.tools.r8.graph.DexValue.DexValueMethodHandle;
import com.android.tools.r8.graph.DexValue.DexValueMethodType;
import com.android.tools.r8.graph.DexValue.DexValueNull;
import com.android.tools.r8.graph.DexValue.DexValueString;
+import com.android.tools.r8.graph.FieldAccessFlags;
+import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.OffsetToObjectMapping;
import com.android.tools.r8.logging.Log;
import com.android.tools.r8.utils.ProgramResource.Kind;
@@ -555,7 +557,7 @@ public class DexFileReader {
for (int i = 0; i < size; i++) {
fieldIndex += file.getUleb128();
DexField field = indexedItems.getField(fieldIndex);
- DexAccessFlags accessFlags = new DexAccessFlags(file.getUleb128());
+ FieldAccessFlags accessFlags = FieldAccessFlags.fromDexAccessFlags(file.getUleb128());
DexAnnotationSet fieldAnnotations = annotationIterator.getNextFor(field);
DexValue staticValue = null;
if (accessFlags.isStatic()) {
@@ -580,7 +582,7 @@ public class DexFileReader {
new MemberAnnotationIterator<>(parameters, DexAnnotationSetRefList::empty);
for (int i = 0; i < size; i++) {
methodIndex += file.getUleb128();
- DexAccessFlags accessFlags = new DexAccessFlags(file.getUleb128());
+ MethodAccessFlags accessFlags = MethodAccessFlags.fromDexAccessFlags(file.getUleb128());
int codeOff = file.getUleb128();
DexCode code = null;
if (!skipCodes) {
@@ -633,7 +635,7 @@ public class DexFileReader {
DexString source = srcIdx == NO_INDEX ? null : indexedItems.getString(srcIdx);
// fix annotations.
DexType type = indexedItems.getType(classIndices[i]);
- DexAccessFlags flags = new DexAccessFlags(accessFlags[i]);
+ ClassAccessFlags flags = ClassAccessFlags.fromDexAccessFlags(accessFlags[i]);
DexClass clazz;
DexEncodedField[] staticFields = DexEncodedField.EMPTY_ARRAY;
DexEncodedField[] instanceFields = DexEncodedField.EMPTY_ARRAY;
diff --git a/src/main/java/com/android/tools/r8/dex/FileWriter.java b/src/main/java/com/android/tools/r8/dex/FileWriter.java
index dccf88711..27dedb195 100644
--- a/src/main/java/com/android/tools/r8/dex/FileWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/FileWriter.java
@@ -405,7 +405,7 @@ public class FileWriter {
private void writeClassDefItem(DexProgramClass clazz) {
dest.putInt(mapping.getOffsetFor(clazz.type));
- dest.putInt(clazz.accessFlags.get());
+ dest.putInt(clazz.accessFlags.getAsDexAccessFlags());
dest.putInt(
clazz.superType == null ? Constants.NO_INDEX : mapping.getOffsetFor(clazz.superType));
dest.putInt(mixedSectionOffsets.getOffsetFor(clazz.interfaces));
@@ -553,7 +553,7 @@ public class FileWriter {
assert nextOffset - currentOffset >= 0;
dest.putUleb128(nextOffset - currentOffset);
currentOffset = nextOffset;
- dest.putUleb128(field.accessFlags.get());
+ dest.putUleb128(field.accessFlags.getAsDexAccessFlags());
}
}
@@ -565,7 +565,7 @@ public class FileWriter {
assert nextOffset - currentOffset >= 0;
dest.putUleb128(nextOffset - currentOffset);
currentOffset = nextOffset;
- dest.putUleb128(method.accessFlags.get());
+ dest.putUleb128(method.accessFlags.getAsDexAccessFlags());
if (method.getCode() == null) {
assert method.accessFlags.isAbstract() || method.accessFlags.isNative();
dest.putUleb128(0);
diff --git a/src/main/java/com/android/tools/r8/graph/AccessFlags.java b/src/main/java/com/android/tools/r8/graph/AccessFlags.java
new file mode 100644
index 000000000..9f0471e6a
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/graph/AccessFlags.java
@@ -0,0 +1,187 @@
+// Copyright (c) 2017, 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;
+
+import com.android.tools.r8.dex.Constants;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import java.util.function.BooleanSupplier;
+
+/** Access flags common to classes, methods and fields. */
+public abstract class AccessFlags {
+
+ protected static final int BASE_FLAGS
+ = Constants.ACC_PUBLIC
+ | Constants.ACC_PRIVATE
+ | Constants.ACC_PROTECTED
+ | Constants.ACC_STATIC
+ | Constants.ACC_FINAL
+ | Constants.ACC_SYNTHETIC;
+
+ // Ordered list of flag names. Must be consistent with getPredicates.
+ private static final List<String> NAMES = ImmutableList.of(
+ "public",
+ "private",
+ "protected",
+ "static",
+ "final",
+ "synthetic"
+ );
+
+ // Get ordered list of flag predicates. Must be consistent with getNames.
+ protected List<BooleanSupplier> getPredicates() {
+ return ImmutableList.of(
+ this::isPublic,
+ this::isPrivate,
+ this::isProtected,
+ this::isStatic,
+ this::isFinal,
+ this::isSynthetic);
+ }
+
+ // Get ordered list of flag names. Must be consistent with getPredicates.
+ protected List<String> getNames() {
+ return NAMES;
+ }
+
+ protected int flags;
+
+ protected AccessFlags(int flags) {
+ this.flags = flags;
+ }
+
+ public abstract int getAsCfAccessFlags();
+
+ public abstract int getAsDexAccessFlags();
+
+ @Override
+ public boolean equals(Object other) {
+ if (other instanceof AccessFlags) {
+ return flags == ((AccessFlags) other).flags;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return flags;
+ }
+
+ public boolean isPublic() {
+ return isSet(Constants.ACC_PUBLIC);
+ }
+
+ public void setPublic() {
+ assert !isPrivate() && !isProtected();
+ set(Constants.ACC_PUBLIC);
+ }
+
+ public void unsetPublic() {
+ unset(Constants.ACC_PUBLIC);
+ }
+
+ public boolean isPrivate() {
+ return isSet(Constants.ACC_PRIVATE);
+ }
+
+ public void setPrivate() {
+ assert !isPublic() && !isProtected();
+ set(Constants.ACC_PRIVATE);
+ }
+
+ public void unsetPrivate() {
+ unset(Constants.ACC_PRIVATE);
+ }
+
+ public boolean isProtected() {
+ return isSet(Constants.ACC_PROTECTED);
+ }
+
+ public void setProtected() {
+ assert !isPublic() && !isPrivate();
+ set(Constants.ACC_PROTECTED);
+ }
+
+ public void unsetProtected() {
+ unset(Constants.ACC_PROTECTED);
+ }
+
+ public boolean isStatic() {
+ return isSet(Constants.ACC_STATIC);
+ }
+
+ public void setStatic() {
+ set(Constants.ACC_STATIC);
+ }
+
+ public boolean isFinal() {
+ return isSet(Constants.ACC_FINAL);
+ }
+
+ public void setFinal() {
+ set(Constants.ACC_FINAL);
+ }
+
+ public void unsetFinal() {
+ unset(Constants.ACC_FINAL);
+ }
+
+ public boolean isSynthetic() {
+ return isSet(Constants.ACC_SYNTHETIC);
+ }
+
+ public void setSynthetic() {
+ set(Constants.ACC_SYNTHETIC);
+ }
+
+ public void unsetSynthetic() {
+ unset(Constants.ACC_SYNTHETIC);
+ }
+
+ public void promoteNonPrivateToPublic() {
+ if (!isPrivate()) {
+ unsetProtected();
+ setPublic();
+ }
+ }
+
+ public void promoteToPublic() {
+ unsetProtected();
+ unsetPrivate();
+ setPublic();
+ }
+
+ protected boolean isSet(int flag) {
+ return (flags & flag) != 0;
+ }
+
+ protected void set(int flag) {
+ flags |= flag;
+ }
+
+ protected void unset(int flag) {
+ flags &= ~flag;
+ }
+
+
+ public String toSmaliString() {
+ return toString();
+ }
+
+ @Override
+ public String toString() {
+ List<String> names = getNames();
+ List<BooleanSupplier> predicates = getPredicates();
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < names.size(); i++) {
+ if (predicates.get(i).getAsBoolean()) {
+ if (builder.length() > 0) {
+ builder.append(' ');
+ }
+ builder.append(names.get(i));
+ }
+ }
+ return builder.toString();
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/graph/ClassAccessFlags.java b/src/main/java/com/android/tools/r8/graph/ClassAccessFlags.java
new file mode 100644
index 000000000..64309244e
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/graph/ClassAccessFlags.java
@@ -0,0 +1,134 @@
+// Copyright (c) 2017, 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;
+
+import com.android.tools.r8.dex.Constants;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import java.util.function.BooleanSupplier;
+
+public class ClassAccessFlags extends AccessFlags {
+
+ // List of valid flags for both DEX and Java.
+ private static final int SHARED_FLAGS
+ = AccessFlags.BASE_FLAGS
+ | Constants.ACC_INTERFACE
+ | Constants.ACC_ABSTRACT
+ | Constants.ACC_ANNOTATION
+ | Constants.ACC_ENUM;
+
+ private static final int DEX_FLAGS
+ = SHARED_FLAGS;
+
+ private static final int CF_FLAGS
+ = SHARED_FLAGS
+ | Constants.ACC_SUPER;
+
+ @Override
+ protected List<String> getNames() {
+ return new ImmutableList.Builder<String>()
+ .addAll(super.getNames())
+ .add("interface")
+ .add("abstract")
+ .add("annotation")
+ .add("enum")
+ .build();
+ }
+
+ @Override
+ protected List<BooleanSupplier> getPredicates() {
+ return new ImmutableList.Builder<BooleanSupplier>()
+ .addAll(super.getPredicates())
+ .add(this::isInterface)
+ .add(this::isAbstract)
+ .add(this::isAnnotation)
+ .add(this::isEnum)
+ .build();
+ }
+
+ private ClassAccessFlags(int flags) {
+ super(flags);
+ }
+
+ public static ClassAccessFlags fromSharedAccessFlags(int access) {
+ assert (access & SHARED_FLAGS) == access;
+ assert SHARED_FLAGS == DEX_FLAGS;
+ return fromDexAccessFlags(access);
+ }
+
+ public static ClassAccessFlags fromDexAccessFlags(int access) {
+ // Assume that the SUPER flag should be set (behaviour for Java versions > 1.1).
+ return new ClassAccessFlags((access & DEX_FLAGS) | Constants.ACC_SUPER);
+ }
+
+ public static ClassAccessFlags fromCfAccessFlags(int access) {
+ return new ClassAccessFlags(access & CF_FLAGS);
+ }
+
+ public ClassAccessFlags copy() {
+ return new ClassAccessFlags(flags);
+ }
+
+ @Override
+ public int getAsDexAccessFlags() {
+ return flags & ~Constants.ACC_SUPER;
+ }
+
+ @Override
+ public int getAsCfAccessFlags() {
+ return flags;
+ }
+
+ public boolean isInterface() {
+ return isSet(Constants.ACC_INTERFACE);
+ }
+
+ public void setInterface() {
+ set(Constants.ACC_INTERFACE);
+ }
+
+ public void unsetInterface() {
+ unset(Constants.ACC_INTERFACE);
+ }
+
+ public boolean isAbstract() {
+ return isSet(Constants.ACC_ABSTRACT);
+ }
+
+ public void setAbstract() {
+ set(Constants.ACC_ABSTRACT);
+ }
+
+ public void unsetAbstract() {
+ unset(Constants.ACC_ABSTRACT);
+ }
+
+ public boolean isAnnotation() {
+ return isSet(Constants.ACC_ANNOTATION);
+ }
+
+ public void setAnnotation() {
+ set(Constants.ACC_ANNOTATION);
+ }
+
+ public boolean isEnum() {
+ return isSet(Constants.ACC_ENUM);
+ }
+
+ public void setEnum() {
+ set(Constants.ACC_ENUM);
+ }
+
+ public boolean isSuper() {
+ return isSet(Constants.ACC_SUPER);
+ }
+
+ public void setSuper() {
+ set(Constants.ACC_SUPER);
+ }
+
+ public void unsetSuper() {
+ unset(Constants.ACC_SUPER);
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/graph/ClassKind.java b/src/main/java/com/android/tools/r8/graph/ClassKind.java
index 90644e5ad..f8c4cbde5 100644
--- a/src/main/java/com/android/tools/r8/graph/ClassKind.java
+++ b/src/main/java/com/android/tools/r8/graph/ClassKind.java
@@ -16,7 +16,7 @@ public enum ClassKind {
DexType type,
ProgramResource.Kind kind,
Origin origin,
- DexAccessFlags accessFlags,
+ ClassAccessFlags accessFlags,
DexType superType,
DexTypeList interfaces,
DexString sourceFile,
@@ -39,7 +39,7 @@ public enum ClassKind {
DexType type,
ProgramResource.Kind kind,
Origin origin,
- DexAccessFlags accessFlags,
+ ClassAccessFlags accessFlags,
DexType superType,
DexTypeList interfaces,
DexString sourceFile,
diff --git a/src/main/java/com/android/tools/r8/graph/DexAccessFlags.java b/src/main/java/com/android/tools/r8/graph/DexAccessFlags.java
deleted file mode 100644
index a8f9526cb..000000000
--- a/src/main/java/com/android/tools/r8/graph/DexAccessFlags.java
+++ /dev/null
@@ -1,310 +0,0 @@
-// Copyright (c) 2016, 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;
-
-import com.android.tools.r8.dex.Constants;
-
-public class DexAccessFlags {
-
- private static final String[] ACC_NAMES = {
- "public",
- "private",
- "protected",
- "static",
- "final",
- "synchronized",
- "volatile(bridge)",
- "transient(varargs)",
- "native",
- "interface",
- "abstract",
- "strictfp",
- "synthetic",
- "annotation",
- "enum",
- "<unused>",
- "<init>",
- "synchronized",
- };
-
- private int flags;
-
- public DexAccessFlags(int flags) {
- this.flags = flags;
- }
-
- public DexAccessFlags(int... flags) {
- this(combineFlags(flags));
- }
-
- private static int combineFlags(int[] flags) {
- int combined = 0;
- for (int flag : flags) {
- combined |= flag;
- }
- return combined;
- }
-
- @Override
- public boolean equals(Object other) {
- if (other instanceof DexAccessFlags) {
- return flags == ((DexAccessFlags) other).flags;
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return get();
- }
-
- public int get() {
- return flags;
- }
-
- public boolean containsAllOf(DexAccessFlags other) {
- return (flags & other.get()) == other.get();
- }
-
- public boolean containsNoneOf(DexAccessFlags other) {
- return (flags & other.get()) == 0;
- }
-
- public boolean isPublic() {
- return isSet(Constants.ACC_PUBLIC);
- }
-
- public void setPublic() {
- set(Constants.ACC_PUBLIC);
- }
-
- public void unsetPublic() {
- unset(Constants.ACC_PUBLIC);
- }
-
- public boolean isPrivate() {
- return isSet(Constants.ACC_PRIVATE);
- }
-
- public void setPrivate() {
- set(Constants.ACC_PRIVATE);
- }
-
- public void unsetPrivate() {
- unset(Constants.ACC_PRIVATE);
- }
-
- public boolean isProtected() {
- return isSet(Constants.ACC_PROTECTED);
- }
-
- public void setProtected() {
- set(Constants.ACC_PROTECTED);
- }
-
- public void unsetProtected() {
- unset(Constants.ACC_PROTECTED);
- }
-
- public boolean isStatic() {
- return isSet(Constants.ACC_STATIC);
- }
-
- public void setStatic() {
- set(Constants.ACC_STATIC);
- }
-
- public boolean isFinal() {
- return isSet(Constants.ACC_FINAL);
- }
-
- public void setFinal() {
- set(Constants.ACC_FINAL);
- }
-
- public void unsetFinal() {
- unset(Constants.ACC_FINAL);
- }
-
- public boolean isSynchronized() {
- return isSet(Constants.ACC_SYNCHRONIZED);
- }
-
- public void setSynchronized() {
- set(Constants.ACC_SYNCHRONIZED);
- }
-
- public void unsetSynchronized() {
- unset(Constants.ACC_SYNCHRONIZED);
- }
-
- public boolean isVolatile() {
- return isSet(Constants.ACC_VOLATILE);
- }
-
- public void setVolatile() {
- set(Constants.ACC_VOLATILE);
- }
-
- public boolean isBridge() {
- return isSet(Constants.ACC_BRIDGE);
- }
-
- public void setBridge() {
- set(Constants.ACC_BRIDGE);
- }
-
- public void unsetBridge() {
- unset(Constants.ACC_BRIDGE);
- }
-
- public boolean isTransient() {
- return isSet(Constants.ACC_TRANSIENT);
- }
-
- public void setTransient() {
- set(Constants.ACC_TRANSIENT);
- }
-
- public boolean isVarargs() {
- return isSet(Constants.ACC_VARARGS);
- }
-
- public void setVarargs() {
- set(Constants.ACC_VARARGS);
- }
-
- public boolean isNative() {
- return isSet(Constants.ACC_NATIVE);
- }
-
- public void setNative() {
- set(Constants.ACC_NATIVE);
- }
-
- public boolean isInterface() {
- return isSet(Constants.ACC_INTERFACE);
- }
-
- public void setInterface() {
- set(Constants.ACC_INTERFACE);
- }
-
- public void unsetInterface() {
- unset(Constants.ACC_INTERFACE);
- }
-
- public boolean isAbstract() {
- return isSet(Constants.ACC_ABSTRACT);
- }
-
- public void setAbstract() {
- set(Constants.ACC_ABSTRACT);
- }
-
- public void unsetAbstract() {
- unset(Constants.ACC_ABSTRACT);
- }
-
- public boolean isStrict() {
- return isSet(Constants.ACC_STRICT);
- }
-
- public void setStrict() {
- set(Constants.ACC_STRICT);
- }
-
- public boolean isSynthetic() {
- return isSet(Constants.ACC_SYNTHETIC);
- }
-
- public void setSynthetic() {
- set(Constants.ACC_SYNTHETIC);
- }
-
- public void unsetSynthetic() {
- unset(Constants.ACC_SYNTHETIC);
- }
-
- public boolean isAnnotation() {
- return isSet(Constants.ACC_ANNOTATION);
- }
-
- public void setAnnotation() {
- set(Constants.ACC_ANNOTATION);
- }
-
- public boolean isEnum() {
- return isSet(Constants.ACC_ENUM);
- }
-
- public void setEnum() {
- set(Constants.ACC_ENUM);
- }
-
- public boolean isConstructor() {
- return isSet(Constants.ACC_CONSTRUCTOR);
- }
-
- public void setConstructor() {
- set(Constants.ACC_CONSTRUCTOR);
- }
-
- public void unsetConstructor() {
- unset(Constants.ACC_CONSTRUCTOR);
- }
-
- public boolean isDeclaredSynchronized() {
- return isSet(Constants.ACC_DECLARED_SYNCHRONIZED);
- }
-
- public void setDeclaredSynchronized() {
- set(Constants.ACC_DECLARED_SYNCHRONIZED);
- }
-
- public void promoteNonPrivateToPublic() {
- if (!isPrivate()) {
- flags &= ~Constants.ACC_PROTECTED;
- flags |= Constants.ACC_PUBLIC;
- }
- }
-
- public void promoteToPublic() {
- flags &= ~Constants.ACC_PROTECTED & ~Constants.ACC_PRIVATE;
- flags |= Constants.ACC_PUBLIC;
- }
-
- private boolean isSet(int flag) {
- return (flags & flag) != 0;
- }
-
- private void set(int flag) {
- flags |= flag;
- }
-
- private void unset(int flag) {
- flags &= ~flag;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- int flags = this.flags;
- flags &= ~Constants.ACC_CONSTRUCTOR; // Don't include the constructor flag in the string.
- for (int i = 0; i < ACC_NAMES.length && flags != 0; i++, flags >>= 1) {
- if ((flags & 0x1) != 0) {
- if (builder.length() > 0) {
- builder.append(' ');
- }
- builder.append(ACC_NAMES[i]);
- }
- }
- assert flags == 0;
- return builder.toString();
- }
-
- public String toSmaliString() {
- return toString();
- }
-}
diff --git a/src/main/java/com/android/tools/r8/graph/DexClass.java b/src/main/java/com/android/tools/r8/graph/DexClass.java
index 505071166..2aba23b97 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -19,7 +19,7 @@ public abstract class DexClass extends DexItem {
public final Origin origin;
public final DexType type;
- public final DexAccessFlags accessFlags;
+ public final ClassAccessFlags accessFlags;
public DexType superType;
public DexTypeList interfaces;
public DexString sourceFile;
@@ -45,7 +45,7 @@ public abstract class DexClass extends DexItem {
public DexClass(
DexString sourceFile,
DexTypeList interfaces,
- DexAccessFlags accessFlags,
+ ClassAccessFlags accessFlags,
DexType superType,
DexType type,
DexEncodedField[] staticFields,
diff --git a/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java b/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java
index d39763e5d..292b368eb 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java
@@ -17,7 +17,7 @@ public class DexClasspathClass extends DexClass implements Supplier<DexClasspath
DexType type,
ProgramResource.Kind kind,
Origin origin,
- DexAccessFlags accessFlags,
+ ClassAccessFlags accessFlags,
DexType superType,
DexTypeList interfaces,
DexString sourceFile,
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedField.java b/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
index 1ba7755ab..bdfadfc8f 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
@@ -13,11 +13,14 @@ public class DexEncodedField extends KeyedDexItem<DexField> {
public static final DexEncodedField[] EMPTY_ARRAY = new DexEncodedField[]{};
public final DexField field;
- public final DexAccessFlags accessFlags;
+ public final FieldAccessFlags accessFlags;
public DexAnnotationSet annotations;
public DexValue staticValue;
- public DexEncodedField(DexField field, DexAccessFlags accessFlags, DexAnnotationSet annotations,
+ public DexEncodedField(
+ DexField field,
+ FieldAccessFlags accessFlags,
+ DexAnnotationSet annotations,
DexValue staticValue) {
assert !accessFlags.isStatic() || staticValue != null;
this.field = field;
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index 19743978f..9c0c39cb2 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -85,7 +85,7 @@ public class DexEncodedMethod extends KeyedDexItem<DexMethod> {
new DexEncodedMethod(null, null, null, null, null);
public final DexMethod method;
- public final DexAccessFlags accessFlags;
+ public final MethodAccessFlags accessFlags;
public DexAnnotationSet annotations;
public DexAnnotationSetRefList parameterAnnotations;
private Code code;
@@ -186,8 +186,12 @@ public class DexEncodedMethod extends KeyedDexItem<DexMethod> {
public List<DebugPositionRange> debugPositionRangeList = null;
- public DexEncodedMethod(DexMethod method, DexAccessFlags accessFlags,
- DexAnnotationSet annotations, DexAnnotationSetRefList parameterAnnotations, Code code) {
+ public DexEncodedMethod(
+ DexMethod method,
+ MethodAccessFlags accessFlags,
+ DexAnnotationSet annotations,
+ DexAnnotationSetRefList parameterAnnotations,
+ Code code) {
this.method = method;
this.accessFlags = accessFlags;
this.annotations = annotations;
@@ -667,7 +671,7 @@ public class DexEncodedMethod extends KeyedDexItem<DexMethod> {
private static class Builder {
private DexMethod method;
- private DexAccessFlags accessFlags;
+ private MethodAccessFlags accessFlags;
private DexAnnotationSet annotations;
private DexAnnotationSetRefList parameterAnnotations;
private Code code;
@@ -677,7 +681,7 @@ public class DexEncodedMethod extends KeyedDexItem<DexMethod> {
private Builder(DexEncodedMethod from) {
// Copy all the mutable state of a DexEncodedMethod here.
method = from.method;
- accessFlags = new DexAccessFlags(from.accessFlags.get());
+ accessFlags = from.accessFlags.copy();
annotations = from.annotations;
parameterAnnotations = from.parameterAnnotations;
code = from.code;
diff --git a/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java b/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java
index 3c9cbdd2b..f2e262b1d 100644
--- a/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java
@@ -17,7 +17,7 @@ public class DexLibraryClass extends DexClass implements Supplier<DexLibraryClas
DexType type,
ProgramResource.Kind kind,
Origin origin,
- DexAccessFlags accessFlags,
+ ClassAccessFlags accessFlags,
DexType superType,
DexTypeList interfaces,
DexString sourceFile,
diff --git a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
index ad1af107f..4d1654859 100644
--- a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
@@ -31,7 +31,7 @@ public class DexProgramClass extends DexClass implements Supplier<DexProgramClas
DexType type,
ProgramResource.Kind originKind,
Origin origin,
- DexAccessFlags accessFlags,
+ ClassAccessFlags accessFlags,
DexType superType,
DexTypeList interfaces,
DexString sourceFile,
@@ -60,7 +60,7 @@ public class DexProgramClass extends DexClass implements Supplier<DexProgramClas
DexType type,
ProgramResource.Kind originKind,
Origin origin,
- DexAccessFlags accessFlags,
+ ClassAccessFlags accessFlags,
DexType superType,
DexTypeList interfaces,
DexString sourceFile,
diff --git a/src/main/java/com/android/tools/r8/graph/FieldAccessFlags.java b/src/main/java/com/android/tools/r8/graph/FieldAccessFlags.java
new file mode 100644
index 000000000..b56e60fb3
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/graph/FieldAccessFlags.java
@@ -0,0 +1,93 @@
+// Copyright (c) 2017, 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;
+
+import com.android.tools.r8.dex.Constants;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import java.util.function.BooleanSupplier;
+
+public class FieldAccessFlags extends AccessFlags {
+
+ private static final int FLAGS
+ = AccessFlags.BASE_FLAGS
+ | Constants.ACC_VOLATILE
+ | Constants.ACC_TRANSIENT
+ | Constants.ACC_ENUM;
+
+ @Override
+ protected List<String> getNames() {
+ return new ImmutableList.Builder<String>()
+ .addAll(super.getNames())
+ .add("volatile")
+ .add("transient")
+ .add("enum")
+ .build();
+ }
+
+ @Override
+ protected List<BooleanSupplier> getPredicates() {
+ return new ImmutableList.Builder<BooleanSupplier>()
+ .addAll(super.getPredicates())
+ .add(this::isVolatile)
+ .add(this::isTransient)
+ .add(this::isEnum)
+ .build();
+ }
+
+ private FieldAccessFlags(int flags) {
+ super(flags);
+ }
+
+ public FieldAccessFlags copy() {
+ return new FieldAccessFlags(flags);
+ }
+
+ public static FieldAccessFlags fromSharedAccessFlags(int access) {
+ assert (access & FLAGS) == access;
+ return new FieldAccessFlags(access & FLAGS);
+ }
+
+ public static FieldAccessFlags fromDexAccessFlags(int access) {
+ return new FieldAccessFlags(access & FLAGS);
+ }
+
+ public static FieldAccessFlags fromCfAccessFlags(int access) {
+ return new FieldAccessFlags(access & FLAGS);
+ }
+
+ @Override
+ public int getAsCfAccessFlags() {
+ return flags;
+ }
+
+ @Override
+ public int getAsDexAccessFlags() {
+ return flags;
+ }
+
+ public boolean isVolatile() {
+ return isSet(Constants.ACC_VOLATILE);
+ }
+
+ public void setVolatile() {
+ set(Constants.ACC_VOLATILE);
+ }
+
+ public boolean isTransient() {
+ return isSet(Constants.ACC_TRANSIENT);
+ }
+
+ public void setTransient() {
+ set(Constants.ACC_TRANSIENT);
+ }
+
+ public boolean isEnum() {
+ return isSet(Constants.ACC_ENUM);
+ }
+
+ public void setEnum() {
+ set(Constants.ACC_ENUM);
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
index 9742df7d3..46f796686 100644
--- a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
+++ b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
@@ -40,7 +40,6 @@ import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.TypePath;
@@ -67,9 +66,9 @@ public class JarClassFileReader {
origin, classKind, reader.b, application, classConsumer), SKIP_FRAMES);
}
- private static DexAccessFlags createAccessFlags(int access) {
- // Clear the "synthetic attribute" and "deprecated" flags if preset.
- return new DexAccessFlags(access & ~ACC_SYNTHETIC_ATTRIBUTE & ~ACC_DEPRECATED);
+ private static int cleanAccessFlags(int access) {
+ // Clear the "synthetic attribute" and "deprecated" attribute-flags if present.
+ return access & ~ACC_SYNTHETIC_ATTRIBUTE & ~ACC_DEPRECATED;
}
private static AnnotationVisitor createAnnotationVisitor(String desc, boolean visible,
@@ -103,7 +102,7 @@ public class JarClassFileReader {
// DexClass data.
private int version;
private DexType type;
- private DexAccessFlags accessFlags;
+ private ClassAccessFlags accessFlags;
private DexType superType;
private DexTypeList interfaces;
private DexString sourceFile;
@@ -176,10 +175,7 @@ public class JarClassFileReader {
public void visit(int version, int access, String name, String signature, String superName,
String[] interfaces) {
this.version = version;
- accessFlags = createAccessFlags(access);
- // Unset the (in dex) non-existent ACC_SUPER flag on the class.
- assert Constants.ACC_SYNCHRONIZED == Opcodes.ACC_SUPER;
- accessFlags.unsetSynchronized();
+ accessFlags = ClassAccessFlags.fromCfAccessFlags(cleanAccessFlags(access));
type = application.getTypeFromName(name);
assert superName != null || name.equals(Constants.JAVA_LANG_OBJECT_NAME);
superType = superName == null ? null : application.getTypeFromName(superName);
@@ -332,7 +328,7 @@ public class JarClassFileReader {
@Override
public void visitEnd() {
- DexAccessFlags flags = createAccessFlags(access);
+ FieldAccessFlags flags = FieldAccessFlags.fromCfAccessFlags(cleanAccessFlags(access));
DexField dexField = parent.application.getField(parent.type, name, desc);
DexAnnotationSet annotationSet = createAnnotationSet(annotations);
DexValue staticValue = flags.isStatic() ? getStaticValue(value, dexField.type) : null;
@@ -514,7 +510,7 @@ public class JarClassFileReader {
@Override
public void visitEnd() {
DexMethod method = parent.application.getMethod(parent.type, name, desc);
- DexAccessFlags flags = createMethodAccessFlags(access);
+ MethodAccessFlags flags = createMethodAccessFlags(access);
Code code = null;
if (!flags.isAbstract()
&& !flags.isNative()
@@ -567,20 +563,11 @@ public class JarClassFileReader {
getAnnotations().add(annotation);
}
- private DexAccessFlags createMethodAccessFlags(int access) {
- DexAccessFlags flags = createAccessFlags(access);
- // Set just the dex specific declared-synchronized flag if the method is synchronized.
- // TODO(zerny): Should declared sync also be set if it is native?
- if (flags.isSynchronized() && !flags.isNative()) {
- flags.unsetSynchronized();
- flags.setDeclaredSynchronized();
- }
- // Set the constructor bit on instance and class initializers.
- if (name.equals(Constants.INSTANCE_INITIALIZER_NAME) || name.equals(
- Constants.CLASS_INITIALIZER_NAME)) {
- flags.setConstructor();
- }
- return flags;
+ private MethodAccessFlags createMethodAccessFlags(int access) {
+ boolean isConstructor =
+ name.equals(Constants.INSTANCE_INITIALIZER_NAME)
+ || name.equals(Constants.CLASS_INITIALIZER_NAME);
+ return MethodAccessFlags.fromCfAccessFlags(cleanAccessFlags(access), isConstructor);
}
}
diff --git a/src/main/java/com/android/tools/r8/graph/MethodAccessFlags.java b/src/main/java/com/android/tools/r8/graph/MethodAccessFlags.java
new file mode 100644
index 000000000..37a6facf3
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/graph/MethodAccessFlags.java
@@ -0,0 +1,184 @@
+// Copyright (c) 2017, 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;
+
+import com.android.tools.r8.dex.Constants;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import java.util.function.BooleanSupplier;
+
+public class MethodAccessFlags extends AccessFlags {
+
+ private static final int SHARED_FLAGS
+ = AccessFlags.BASE_FLAGS
+ | Constants.ACC_SYNCHRONIZED
+ | Constants.ACC_BRIDGE
+ | Constants.ACC_VARARGS
+ | Constants.ACC_NATIVE
+ | Constants.ACC_ABSTRACT
+ | Constants.ACC_STRICT;
+
+ private static final int CF_FLAGS
+ = SHARED_FLAGS;
+
+ private static final int DEX_FLAGS
+ = SHARED_FLAGS
+ | Constants.ACC_CONSTRUCTOR
+ | Constants.ACC_DECLARED_SYNCHRONIZED;
+
+ @Override
+ protected List<String> getNames() {
+ return new ImmutableList.Builder<String>()
+ .addAll(super.getNames())
+ .add("synchronized")
+ .add("bridge")
+ .add("varargs")
+ .add("native")
+ .add("abstract")
+ .add("strictfp")
+ .build();
+ }
+
+ @Override
+ protected List<BooleanSupplier> getPredicates() {
+ return new ImmutableList.Builder<BooleanSupplier>()
+ .addAll(super.getPredicates())
+ .add(this::isSynchronized)
+ .add(this::isBridge)
+ .add(this::isVarargs)
+ .add(this::isNative)
+ .add(this::isAbstract)
+ .add(this::isStrict)
+ .build();
+ }
+
+ private MethodAccessFlags(int flags) {
+ super(flags);
+ }
+
+ public MethodAccessFlags copy() {
+ return new MethodAccessFlags(flags);
+ }
+
+ public static MethodAccessFlags fromSharedAccessFlags(int access, boolean isConstructor) {
+ assert (access & SHARED_FLAGS) == access;
+ assert CF_FLAGS == SHARED_FLAGS;
+ return fromCfAccessFlags(access, isConstructor);
+ }
+
+ public static MethodAccessFlags fromCfAccessFlags(int access, boolean isConstructor) {
+ return new MethodAccessFlags(
+ (access & CF_FLAGS) | (isConstructor ? Constants.ACC_CONSTRUCTOR : 0));
+ }
+
+ public static MethodAccessFlags fromDexAccessFlags(int access) {
+ MethodAccessFlags flags = new MethodAccessFlags(access & DEX_FLAGS);
+ if (flags.isDeclaredSynchronized()) {
+ flags.setSynchronized();
+ flags.unsetDeclaredSynchronized();
+ }
+ return flags;
+ }
+
+ @Override
+ public int getAsDexAccessFlags() {
+ MethodAccessFlags copy = copy();
+ if (copy.isSynchronized() && !copy.isNative()) {
+ copy.unsetSynchronized();
+ copy.setDeclaredSynchronized();
+ }
+ return copy.flags;
+ }
+
+ @Override
+ public int getAsCfAccessFlags() {
+ return flags & ~Constants.ACC_CONSTRUCTOR;
+ }
+
+ public boolean isSynchronized() {
+ return isSet(Constants.ACC_SYNCHRONIZED);
+ }
+
+ public void setSynchronized() {
+ set(Constants.ACC_SYNCHRONIZED);
+ }
+
+ public void unsetSynchronized() {
+ unset(Constants.ACC_SYNCHRONIZED);
+ }
+
+ public boolean isBridge() {
+ return isSet(Constants.ACC_BRIDGE);
+ }
+
+ public void setBridge() {
+ set(Constants.ACC_BRIDGE);
+ }
+
+ public void unsetBridge() {
+ unset(Constants.ACC_BRIDGE);
+ }
+
+ public boolean isVarargs() {
+ return isSet(Constants.ACC_VARARGS);
+ }
+
+ public void setVarargs() {
+ set(Constants.ACC_VARARGS);
+ }
+
+ public boolean isNative() {
+ return isSet(Constants.ACC_NATIVE);
+ }
+
+ public void setNative() {
+ set(Constants.ACC_NATIVE);
+ }
+
+ public boolean isAbstract() {
+ return isSet(Constants.ACC_ABSTRACT);
+ }
+
+ public void setAbstract() {
+ set(Constants.ACC_ABSTRACT);
+ }
+
+ public void unsetAbstract() {
+ unset(Constants.ACC_ABSTRACT);
+ }
+
+ public boolean isStrict() {
+ return isSet(Constants.ACC_STRICT);
+ }
+
+ public void setStrict() {
+ set(Constants.ACC_STRICT);
+ }
+
+ public boolean isConstructor() {
+ return isSet(Constants.ACC_CONSTRUCTOR);
+ }
+
+ public void setConstructor() {
+ set(Constants.ACC_CONSTRUCTOR);
+ }
+
+ public void unsetConstructor() {
+ unset(Constants.ACC_CONSTRUCTOR);
+ }
+
+ // DEX only declared-synchronized flag.
+
+ private boolean isDeclaredSynchronized() {
+ return isSet(Constants.ACC_DECLARED_SYNCHRONIZED);
+ }
+
+ private void setDeclaredSynchronized() {
+ set(Constants.ACC_DECLARED_SYNCHRONIZED);
+ }
+
+ private void unsetDeclaredSynchronized() {
+ unset(Constants.ACC_DECLARED_SYNCHRONIZED);
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java b/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java
index a71f32605..4bafe6211 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java
@@ -29,7 +29,6 @@ import com.android.tools.r8.code.SwitchPayload;
import com.android.tools.r8.code.Throw;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DebugLocalInfo;
-import com.android.tools.r8.graph.DexAccessFlags;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.graph.DexCode.Try;
import com.android.tools.r8.graph.DexCode.TryHandler;
@@ -40,6 +39,7 @@ import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.ir.code.CatchHandlers;
import com.android.tools.r8.ir.code.MoveType;
import com.android.tools.r8.ir.code.Position;
@@ -53,7 +53,7 @@ import java.util.Set;
public class DexSourceCode implements SourceCode {
private final DexCode code;
- private final DexAccessFlags accessFlags;
+ private final MethodAccessFlags accessFlags;
private final DexProto proto;
// Mapping from instruction offset to instruction index in the DexCode instruction array.
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/AccessorMethodSourceCode.java b/src/main/java/com/android/tools/r8/ir/desugar/AccessorMethodSourceCode.java
index 1cf64fd2b..246079899 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/AccessorMethodSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/AccessorMethodSourceCode.java
@@ -5,11 +5,11 @@
package com.android.tools.r8.ir.desugar;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexAccessFlags;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexMethodHandle;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.ir.code.Invoke;
import com.android.tools.r8.ir.code.MoveType;
import com.android.tools.r8.ir.conversion.IRBuilder;
@@ -57,7 +57,7 @@ final class AccessorMethodSourceCode extends SynthesizedLambdaSourceCode {
private boolean isPrivateMethod() {
// We should be able to find targets for all private impl-methods, so
// we can rely on knowing accessibility flags for them.
- DexAccessFlags flags = descriptor().getAccessibility();
+ MethodAccessFlags flags = descriptor().getAccessibility();
return flags != null && flags.isPrivate();
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
index 09371f774..fa0958bfc 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
@@ -5,11 +5,11 @@
package com.android.tools.r8.ir.desugar;
import com.android.tools.r8.errors.CompilationError;
-import com.android.tools.r8.graph.DexAccessFlags;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.ir.code.Invoke;
import com.android.tools.r8.ir.synthetic.ForwardMethodSourceCode;
import com.android.tools.r8.ir.synthetic.SynthesizedCode;
@@ -109,7 +109,7 @@ final class ClassProcessor {
// New method will have the same name, proto, and also all the flags of the
// default method, including bridge flag.
DexMethod newMethod = rewriter.factory.createMethod(clazz.type, method.proto, method.name);
- DexAccessFlags newFlags = new DexAccessFlags(defaultMethod.accessFlags.get());
+ MethodAccessFlags newFlags = defaultMethod.accessFlags.copy();
return new DexEncodedMethod(newMethod, newFlags,
defaultMethod.annotations, defaultMethod.parameterAnnotations,
new SynthesizedCode(new ForwardMethodSourceCode(
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
index fb3507be6..1714b9308 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
@@ -6,8 +6,8 @@ package com.android.tools.r8.ir.desugar;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.Unimplemented;
+import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.Code;
-import com.android.tools.r8.graph.DexAccessFlags;
import com.android.tools.r8.graph.DexAnnotationSet;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.graph.DexEncodedField;
@@ -16,6 +16,7 @@ import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
+import com.android.tools.r8.graph.MethodAccessFlags;
import java.util.ArrayList;
import java.util.Collections;
import java.util.IdentityHashMap;
@@ -56,7 +57,7 @@ final class InterfaceProcessor {
+ "interface method: " + virtual.method.toSourceString());
}
- DexAccessFlags newFlags = new DexAccessFlags(virtual.accessFlags.get());
+ MethodAccessFlags newFlags = virtual.accessFlags.copy();
newFlags.unsetBridge();
newFlags.setStatic();
DexCode dexCode = code.asDexCode();
@@ -115,7 +116,7 @@ final class InterfaceProcessor {
return; // No methods to create, companion class not needed.
}
- DexAccessFlags companionClassFlags = new DexAccessFlags(iface.accessFlags.get());
+ ClassAccessFlags companionClassFlags = iface.accessFlags.copy();
companionClassFlags.unsetAbstract();
companionClassFlags.unsetInterface();
companionClassFlags.setFinal();
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
index 569d088a7..43548c2b5 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
@@ -8,7 +8,7 @@ import com.android.tools.r8.ApiLevelException;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexAccessFlags;
+import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.DexAnnotationSet;
import com.android.tools.r8.graph.DexAnnotationSetRefList;
import com.android.tools.r8.graph.DexClass;
@@ -25,6 +25,8 @@ import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.DexValue.DexValueNull;
+import com.android.tools.r8.graph.FieldAccessFlags;
+import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.ir.code.Invoke;
import com.android.tools.r8.ir.synthetic.SynthesizedCode;
import java.util.ArrayList;
@@ -121,7 +123,7 @@ final class LambdaClass {
type,
null,
null,
- new DexAccessFlags(Constants.ACC_FINAL | Constants.ACC_SYNTHETIC),
+ ClassAccessFlags.fromDexAccessFlags(Constants.ACC_FINAL | Constants.ACC_SYNTHETIC),
rewriter.factory.objectType,
buildInterfaces(),
rewriter.factory.createString("lambda"),
@@ -155,24 +157,31 @@ final class LambdaClass {
// Synthesize main method.
DexMethod mainMethod = rewriter.factory
.createMethod(type, descriptor.erasedProto, descriptor.name);
- methods[index++] = new DexEncodedMethod(
- mainMethod,
- new DexAccessFlags(Constants.ACC_PUBLIC | Constants.ACC_FINAL),
- DexAnnotationSet.empty(),
- DexAnnotationSetRefList.empty(),
- new SynthesizedCode(new LambdaMainMethodSourceCode(this, mainMethod)));
+ methods[index++] =
+ new DexEncodedMethod(
+ mainMethod,
+ MethodAccessFlags.fromSharedAccessFlags(
+ Constants.ACC_PUBLIC | Constants.ACC_FINAL, false),
+ DexAnnotationSet.empty(),
+ DexAnnotationSetRefList.empty(),
+ new SynthesizedCode(new LambdaMainMethodSourceCode(this, mainMethod)));
// Synthesize bridge methods.
for (DexProto bridgeProto : descriptor.bridges) {
DexMethod bridgeMethod = rewriter.factory.createMethod(type, bridgeProto, descriptor.name);
- methods[index++] = new DexEncodedMethod(
- bridgeMethod,
- new DexAccessFlags(Constants.ACC_PUBLIC | Constants.ACC_FINAL
- | Constants.ACC_SYNTHETIC | Constants.ACC_BRIDGE),
- DexAnnotationSet.empty(),
- DexAnnotationSetRefList.empty(),
- new SynthesizedCode(
- new LambdaBridgeMethodSourceCode(this, mainMethod, bridgeMethod)));
+ methods[index++] =
+ new DexEncodedMethod(
+ bridgeMethod,
+ MethodAccessFlags.fromSharedAccessFlags(
+ Constants.ACC_PUBLIC
+ | Constants.ACC_FINAL
+ | Constants.ACC_SYNTHETIC
+ | Constants.ACC_BRIDGE,
+ false),
+ DexAnnotationSet.empty(),
+ DexAnnotationSetRefList.empty(),
+ new SynthesizedCode(
+ new LambdaBridgeMethodSourceCode(this, mainMethod, bridgeMethod)));
}
return methods;
}
@@ -183,23 +192,27 @@ final class LambdaClass {
DexEncodedMethod[] methods = new DexEncodedMethod[stateless ? 2 : 1];
// Constructor.
- methods[0] = new DexEncodedMethod(
- constructor,
- new DexAccessFlags((stateless ? Constants.ACC_PRIVATE : Constants.ACC_PUBLIC) |
- Constants.ACC_SYNTHETIC | Constants.ACC_CONSTRUCTOR),
- DexAnnotationSet.empty(),
- DexAnnotationSetRefList.empty(),
- new SynthesizedCode(new LambdaConstructorSourceCode(this)));
+ methods[0] =
+ new DexEncodedMethod(
+ constructor,
+ MethodAccessFlags.fromSharedAccessFlags(
+ (stateless ? Constants.ACC_PRIVATE : Constants.ACC_PUBLIC)
+ | Constants.ACC_SYNTHETIC,
+ true),
+ DexAnnotationSet.empty(),
+ DexAnnotationSetRefList.empty(),
+ new SynthesizedCode(new LambdaConstructorSourceCode(this)));
// Class constructor for stateless lambda classes.
if (stateless) {
- methods[1] = new DexEncodedMethod(
- classConstructor,
- new DexAccessFlags(
- Constants.ACC_SYNTHETIC | Constants.ACC_CONSTRUCTOR | Constants.ACC_STATIC),
- DexAnnotationSet.empty(),
- DexAnnotationSetRefList.empty(),
- new SynthesizedCode(new LambdaClassConstructorSourceCode(this)));
+ methods[1] =
+ new DexEncodedMethod(
+ classConstructor,
+ MethodAccessFlags.fromSharedAccessFlags(
+ Constants.ACC_SYNTHETIC | Constants.ACC_STATIC, true),
+ DexAnnotationSet.empty(),
+ DexAnnotationSetRefList.empty(),
+ new SynthesizedCode(new LambdaClassConstructorSourceCode(this)));
}
return methods;
}
@@ -210,8 +223,9 @@ final class LambdaClass {
int fieldCount = fieldTypes.length;
DexEncodedField[] fields = new DexEncodedField[fieldCount];
for (int i = 0; i < fieldCount; i++) {
- DexAccessFlags accessFlags = new DexAccessFlags(
- Constants.ACC_FINAL | Constants.ACC_SYNTHETIC | Constants.ACC_PRIVATE);
+ FieldAccessFlags accessFlags =
+ FieldAccessFlags.fromSharedAccessFlags(
+ Constants.ACC_FINAL | Constants.ACC_SYNTHETIC | Constants.ACC_PRIVATE);
fields[i] = new DexEncodedField(
getCaptureField(i), accessFlags, DexAnnotationSet.empty(), null);
}
@@ -227,12 +241,16 @@ final class LambdaClass {
// Create instance field for stateless lambda.
assert this.instanceField != null;
DexEncodedField[] fields = new DexEncodedField[1];
- fields[0] = new DexEncodedField(
- this.instanceField,
- new DexAccessFlags(Constants.ACC_PUBLIC | Constants.ACC_FINAL
- | Constants.ACC_SYNTHETIC | Constants.ACC_STATIC),
- DexAnnotationSet.empty(),
- DexValueNull.NULL);
+ fields[0] =
+ new DexEncodedField(
+ this.instanceField,
+ FieldAccessFlags.fromSharedAccessFlags(
+ Constants.ACC_PUBLIC
+ | Constants.ACC_FINAL
+ | Constants.ACC_SYNTHETIC
+ | Constants.ACC_STATIC),
+ DexAnnotationSet.empty(),
+ DexValueNull.NULL);
return fields;
}
@@ -497,9 +515,12 @@ final class LambdaClass {
DexProgramClass accessorClass = programDefinitionFor(callTarget.holder);
assert accessorClass != null;
- DexAccessFlags accessorFlags = new DexAccessFlags(
- Constants.ACC_SYNTHETIC | Constants.ACC_STATIC |
- (accessorClass.isInterface() ? Constants.ACC_PUBLIC : 0));
+ MethodAccessFlags accessorFlags =
+ MethodAccessFlags.fromSharedAccessFlags(
+ Constants.ACC_SYNTHETIC
+ | Constants.ACC_STATIC
+ | (accessorClass.isInterface() ? Constants.ACC_PUBLIC : 0),
+ false);
DexEncodedMethod accessorEncodedMethod = new DexEncodedMethod(
callTarget, accessorFlags, DexAnnotationSet.empty(), DexAnnotationSetRefList.empty(),
new SynthesizedCode(new AccessorMethodSourceCode(LambdaClass.this)));
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java
index bba7b23f0..5d5252300 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java
@@ -6,7 +6,6 @@ package com.android.tools.r8.ir.desugar;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
-import com.android.tools.r8.graph.DexAccessFlags;
import com.android.tools.r8.graph.DexCallSite;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
@@ -17,6 +16,7 @@ import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.DexValue;
+import com.android.tools.r8.graph.MethodAccessFlags;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.List;
@@ -140,7 +140,7 @@ final class LambdaDescriptor {
return encodedMethod.accessFlags.isPrivate() && isInstanceMethod(encodedMethod);
}
- final DexAccessFlags getAccessibility() {
+ final MethodAccessFlags getAccessibility() {
return targetMethod == null ? null : targetMethod.accessFlags;
}
@@ -198,7 +198,7 @@ final class LambdaDescriptor {
return true;
}
- DexAccessFlags flags = targetMethod.accessFlags;
+ MethodAccessFlags flags = targetMethod.accessFlags;
// Private methods always need accessors.
if (flags.isPrivate()) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
index ad4639e7f..b15d254c2 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
@@ -4,8 +4,8 @@
package com.android.tools.r8.ir.optimize;
import com.android.tools.r8.ApiLevelException;
+import com.android.tools.r8.graph.AccessFlags;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
-import com.android.tools.r8.graph.DexAccessFlags;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
@@ -91,7 +91,7 @@ public class Inliner {
return isVisibleWithFlags(target.method.holder, method.method.holder, targetClass.accessFlags);
}
- private boolean isVisibleWithFlags(DexType target, DexType context, DexAccessFlags flags) {
+ private boolean isVisibleWithFlags(DexType target, DexType context, AccessFlags flags) {
if (flags.isPublic()) {
return true;
}
@@ -166,8 +166,11 @@ public class Inliner {
assert SUBCLASS.ordinal() < ALWAYS.ordinal();
}
- public static Constraint deriveConstraint(DexType contextHolder, DexType targetHolder,
- DexAccessFlags flags, AppInfoWithSubtyping appInfo) {
+ public static Constraint deriveConstraint(
+ DexType contextHolder,
+ DexType targetHolder,
+ AccessFlags flags,
+ AppInfoWithSubtyping appInfo) {
if (flags.isPublic()) {
return ALWAYS;
} else if (flags.isPrivate()) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
index 74afdcd14..d799e7d79 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
@@ -8,9 +8,9 @@ import com.android.tools.r8.ApiLevelException;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DebugLocalInfo;
-import com.android.tools.r8.graph.DexAccessFlags;
import com.android.tools.r8.graph.DexAnnotationSet;
import com.android.tools.r8.graph.DexAnnotationSetRefList;
import com.android.tools.r8.graph.DexClass;
@@ -23,6 +23,7 @@ import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
+import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.UseRegistry;
import com.android.tools.r8.ir.code.Add;
import com.android.tools.r8.ir.code.BasicBlock;
@@ -1058,7 +1059,9 @@ public class Outliner {
List<Outline> outlines = new ArrayList<>(candidates.keySet());
outlines.sort(Comparator.naturalOrder());
for (Outline outline : outlines) {
- DexAccessFlags methodAccess = new DexAccessFlags(Constants.ACC_PUBLIC, Constants.ACC_STATIC);
+ MethodAccessFlags methodAccess =
+ MethodAccessFlags.fromSharedAccessFlags(
+ Constants.ACC_PUBLIC | Constants.ACC_STATIC, false);
DexString methodName = dexItemFactory.createString(options.outline.methodPrefix + count);
DexMethod method = outline.buildMethod(type, methodName);
direct[count] = new DexEncodedMethod(method, methodAccess, DexAnnotationSet.empty(),
@@ -1072,7 +1075,7 @@ public class Outliner {
DexType superType = dexItemFactory.createType("Ljava/lang/Object;");
DexTypeList interfaces = DexTypeList.empty();
DexString sourceFile = dexItemFactory.createString("outline");
- DexAccessFlags accessFlags = new DexAccessFlags(Constants.ACC_PUBLIC);
+ ClassAccessFlags accessFlags = ClassAccessFlags.fromSharedAccessFlags(Constants.ACC_PUBLIC);
DexProgramClass clazz = new DexProgramClass(
type,
null,
diff --git a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
index 83788c7c2..483327b3d 100644
--- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
@@ -3,11 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.jar;
-import static org.objectweb.asm.Opcodes.ACC_SUPER;
-
import com.android.tools.r8.OutputSink;
import com.android.tools.r8.errors.Unimplemented;
-import com.android.tools.r8.graph.DexAccessFlags;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexProgramClass;
@@ -53,7 +50,7 @@ public class CfApplicationWriter {
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
writer.visitSource(clazz.sourceFile.toString(), null);
int version = clazz.getClassFileVersion();
- int access = classAndInterfaceAccessFlags(clazz.accessFlags);
+ int access = clazz.accessFlags.getAsCfAccessFlags();
String desc = clazz.type.toDescriptorString();
String name = internalName(clazz.type);
String signature = null; // TODO(zerny): Support generic signatures.
@@ -72,7 +69,7 @@ public class CfApplicationWriter {
}
private void writeMethod(DexEncodedMethod method, ClassWriter writer) {
- int access = method.accessFlags.get();
+ int access = method.accessFlags.getAsCfAccessFlags();
String name = method.method.name.toString();
String desc = method.descriptor();
String signature = null; // TODO(zerny): Support generic signatures.
@@ -81,13 +78,6 @@ public class CfApplicationWriter {
method.getCode().asJarCode().writeTo(visitor);
}
- private static int classAndInterfaceAccessFlags(DexAccessFlags accessFlags) {
- // TODO(zerny): Refactor access flags to account for the union of both DEX and Java flags.
- int access = accessFlags.get();
- access |= ACC_SUPER;
- return access;
- }
-
private static String internalName(DexType type) {
return Type.getType(type.toDescriptorString()).getInternalName();
}
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardAccessFlags.java b/src/main/java/com/android/tools/r8/shaking/ProguardAccessFlags.java
new file mode 100644
index 000000000..749ce835c
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardAccessFlags.java
@@ -0,0 +1,176 @@
+// Copyright (c) 2017, 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.shaking;
+
+import com.android.tools.r8.dex.Constants;
+import com.android.tools.r8.graph.AccessFlags;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import java.util.function.BooleanSupplier;
+
+public class ProguardAccessFlags {
+
+ private int flags = 0;
+
+ // Ordered list of flag names. Must be consistent with getPredicates.
+ private static final List<String> NAMES = ImmutableList.of(
+ "public",
+ "private",
+ "protected",
+ "static",
+ "final",
+ "abstract",
+ "volatile",
+ "transient",
+ "synchronized",
+ "native",
+ "strictfp"
+ );
+
+ // Get ordered list of flag predicates. Must be consistent with getNames.
+ private List<BooleanSupplier> getPredicates() {
+ return ImmutableList.of(
+ this::isPublic,
+ this::isPrivate,
+ this::isProtected,
+ this::isStatic,
+ this::isFinal,
+ this::isAbstract,
+ this::isVolatile,
+ this::isTransient,
+ this::isSynchronized,
+ this::isNative,
+ this::isStrict);
+ }
+
+ private boolean containsAll(int other) {
+ return (flags & other) == flags;
+ }
+
+ private boolean containsNone(int other) {
+ return (flags & other) == 0;
+ }
+
+ public boolean containsAll(AccessFlags other) {
+ return containsAll(other.getAsCfAccessFlags());
+ }
+
+ public boolean containsNone(AccessFlags other) {
+ return containsNone(other.getAsCfAccessFlags());
+ }
+
+ public void setPublic() {
+ set(Constants.ACC_PUBLIC);
+ }
+
+ public boolean isPublic() {
+ return isSet(Constants.ACC_PUBLIC);
+ }
+
+ public void setPrivate() {
+ set(Constants.ACC_PRIVATE);
+ }
+
+ public boolean isPrivate() {
+ return isSet(Constants.ACC_PRIVATE);
+ }
+
+ public void setProtected() {
+ set(Constants.ACC_PROTECTED);
+ }
+
+ public boolean isProtected() {
+ return isSet(Constants.ACC_PROTECTED);
+ }
+
+ public void setStatic() {
+ set(Constants.ACC_STATIC);
+ }
+
+ public boolean isStatic() {
+ return isSet(Constants.ACC_STATIC);
+ }
+
+ public void setFinal() {
+ set(Constants.ACC_FINAL);
+ }
+
+ public boolean isFinal() {
+ return isSet(Constants.ACC_FINAL);
+ }
+
+ public void setAbstract() {
+ set(Constants.ACC_ABSTRACT);
+ }
+
+ public boolean isAbstract() {
+ return isSet(Constants.ACC_ABSTRACT);
+ }
+
+ public void setVolatile() {
+ set(Constants.ACC_VOLATILE);
+ }
+
+ public boolean isVolatile() {
+ return isSet(Constants.ACC_VOLATILE);
+ }
+
+ public void setTransient() {
+ set(Constants.ACC_TRANSIENT);
+ }
+
+ public boolean isTransient() {
+ return isSet(Constants.ACC_TRANSIENT);
+ }
+
+ public void setSynchronized() {
+ set(Constants.ACC_SYNCHRONIZED);
+ }
+
+ public boolean isSynchronized() {
+ return isSet(Constants.ACC_SYNCHRONIZED);
+ }
+
+ public void setNative() {
+ set(Constants.ACC_NATIVE);
+ }
+
+ public boolean isNative() {
+ return isSet(Constants.ACC_NATIVE);
+ }
+
+ public void setStrict() {
+ set(Constants.ACC_STRICT);
+ }
+
+ public boolean isStrict() {
+ return isSet(Constants.ACC_STRICT);
+ }
+
+ private boolean isSet(int flag) {
+ return (flags & flag) != 0;
+ }
+
+ private void set(int flag) {
+ flags |= flag;
+ }
+
+ @Override
+ public String toString() {
+ List<BooleanSupplier> predicates = getPredicates();
+ StringBuilder builder = new StringBuilder();
+ boolean space = false;
+ for (int i = 0; i < NAMES.size(); i++) {
+ if (predicates.get(i).getAsBoolean()) {
+ if (space) {
+ builder.append(' ');
+ } else {
+ space = true;
+ }
+ builder.append(NAMES.get(i));
+ }
+ }
+ return builder.toString();
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardAlwaysInlineRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardAlwaysInlineRule.java
index 524afd200..ab8342df6 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardAlwaysInlineRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardAlwaysInlineRule.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
-import com.android.tools.r8.graph.DexAccessFlags;
import java.util.Set;
public class ProguardAlwaysInlineRule extends ProguardConfigurationRule {
@@ -22,8 +21,8 @@ public class ProguardAlwaysInlineRule extends ProguardConfigurationRule {
private ProguardAlwaysInlineRule(
ProguardTypeMatcher classAnnotation,
- DexAccessFlags classAccessFlags,
- DexAccessFlags negatedClassAccessFlags,
+ ProguardAccessFlags classAccessFlags,
+ ProguardAccessFlags negatedClassAccessFlags,
boolean classTypeNegated,
ProguardClassType classType,
ProguardClassNameList classNames,
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardAssumeNoSideEffectRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardAssumeNoSideEffectRule.java
index a01dd897b..736c7789b 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardAssumeNoSideEffectRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardAssumeNoSideEffectRule.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
-import com.android.tools.r8.graph.DexAccessFlags;
import java.util.Set;
public class ProguardAssumeNoSideEffectRule extends ProguardConfigurationRule {
@@ -21,8 +20,8 @@ public class ProguardAssumeNoSideEffectRule extends ProguardConfigurationRule {
private ProguardAssumeNoSideEffectRule(
ProguardTypeMatcher classAnnotation,
- DexAccessFlags classAccessFlags,
- DexAccessFlags negatedClassAccessFlags,
+ ProguardAccessFlags classAccessFlags,
+ ProguardAccessFlags negatedClassAccessFlags,
boolean classTypeNegated,
ProguardClassType classType,
ProguardClassNameList classNames,
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardAssumeValuesRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardAssumeValuesRule.java
index 94cf7588f..97cb5c383 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardAssumeValuesRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardAssumeValuesRule.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
-import com.android.tools.r8.graph.DexAccessFlags;
import java.util.Set;
public class ProguardAssumeValuesRule extends ProguardConfigurationRule {
@@ -20,8 +19,8 @@ public class ProguardAssumeValuesRule extends ProguardConfigurationRule {
private ProguardAssumeValuesRule(
ProguardTypeMatcher classAnnotation,
- DexAccessFlags classAccessFlags,
- DexAccessFlags negatedClassAccessFlags,
+ ProguardAccessFlags classAccessFlags,
+ ProguardAccessFlags negatedClassAccessFlags,
boolean classTypeNegated,
ProguardClassType classType,
ProguardClassNameList classNames,
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardCheckDiscardRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardCheckDiscardRule.java
index 7f69e18bc..da5bb2653 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardCheckDiscardRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardCheckDiscardRule.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
-import com.android.tools.r8.graph.DexAccessFlags;
import java.util.Set;
public class ProguardCheckDiscardRule extends ProguardConfigurationRule {
@@ -22,8 +21,8 @@ public class ProguardCheckDiscardRule extends ProguardConfigurationRule {
private ProguardCheckDiscardRule(
ProguardTypeMatcher classAnnotation,
- DexAccessFlags classAccessFlags,
- DexAccessFlags negatedClassAccessFlags,
+ ProguardAccessFlags classAccessFlags,
+ ProguardAccessFlags negatedClassAccessFlags,
boolean classTypeNegated,
ProguardClassType classType,
ProguardClassNameList classNames,
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardClassSpecification.java b/src/main/java/com/android/tools/r8/shaking/ProguardClassSpecification.java
index b8006d321..8e981a73e 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardClassSpecification.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardClassSpecification.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
-import com.android.tools.r8.graph.DexAccessFlags;
import com.android.tools.r8.utils.StringUtils;
import java.util.Collections;
import java.util.LinkedHashSet;
@@ -15,8 +14,8 @@ public abstract class ProguardClassSpecification {
public static class Builder {
protected ProguardTypeMatcher classAnnotation;
- protected DexAccessFlags classAccessFlags = new DexAccessFlags(0);
- protected DexAccessFlags negatedClassAccessFlags = new DexAccessFlags(0);
+ protected ProguardAccessFlags classAccessFlags = new ProguardAccessFlags();
+ protected ProguardAccessFlags negatedClassAccessFlags = new ProguardAccessFlags();
protected boolean classTypeNegated = false;
protected ProguardClassType classType;
protected ProguardClassNameList classNames;
@@ -88,19 +87,19 @@ public abstract class ProguardClassSpecification {
this.classTypeNegated = classTypeNegated;
}
- public DexAccessFlags getClassAccessFlags() {
+ public ProguardAccessFlags getClassAccessFlags() {
return classAccessFlags;
}
- public void setClassAccessFlags(DexAccessFlags flags) {
+ public void setClassAccessFlags(ProguardAccessFlags flags) {
classAccessFlags = flags;
}
- public DexAccessFlags getNegatedClassAccessFlags() {
+ public ProguardAccessFlags getNegatedClassAccessFlags() {
return negatedClassAccessFlags;
}
- public void setNegatedClassAccessFlags(DexAccessFlags flags) {
+ public void setNegatedClassAccessFlags(ProguardAccessFlags flags) {
negatedClassAccessFlags = flags;
}
@@ -119,8 +118,8 @@ public abstract class ProguardClassSpecification {
}
private final ProguardTypeMatcher classAnnotation;
- private final DexAccessFlags classAccessFlags;
- private final DexAccessFlags negatedClassAccessFlags;
+ private final ProguardAccessFlags classAccessFlags;
+ private final ProguardAccessFlags negatedClassAccessFlags;
private final boolean classTypeNegated;
private final ProguardClassType classType;
private final ProguardClassNameList classNames;
@@ -131,8 +130,8 @@ public abstract class ProguardClassSpecification {
protected ProguardClassSpecification(
ProguardTypeMatcher classAnnotation,
- DexAccessFlags classAccessFlags,
- DexAccessFlags negatedClassAccessFlags,
+ ProguardAccessFlags classAccessFlags,
+ ProguardAccessFlags negatedClassAccessFlags,
boolean classTypeNegated,
ProguardClassType classType,
ProguardClassNameList classNames,
@@ -184,11 +183,11 @@ public abstract class ProguardClassSpecification {
return classTypeNegated;
}
- public DexAccessFlags getClassAccessFlags() {
+ public ProguardAccessFlags getClassAccessFlags() {
return classAccessFlags;
}
- public DexAccessFlags getNegatedClassAccessFlags() {
+ public ProguardAccessFlags getNegatedClassAccessFlags() {
return negatedClassAccessFlags;
}
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
index d24a3578f..7997b4425 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
@@ -6,7 +6,6 @@ package com.android.tools.r8.shaking;
import com.android.tools.r8.CompilationException;
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.dex.Constants;
-import com.android.tools.r8.graph.DexAccessFlags;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexString;
@@ -561,9 +560,10 @@ public class ProguardConfigurationParser {
assert builder.getClassAnnotation() == null;
builder.setClassAnnotation(annotation);
} else {
- DexAccessFlags flags =
- parseNegation() ? builder.getNegatedClassAccessFlags() :
- builder.getClassAccessFlags();
+ ProguardAccessFlags flags =
+ parseNegation()
+ ? builder.getNegatedClassAccessFlags()
+ : builder.getClassAccessFlags();
skipWhitespace();
if (acceptString("public")) {
flags.setPublic();
@@ -636,7 +636,7 @@ public class ProguardConfigurationParser {
boolean found = true;
while (found && !eof()) {
found = false;
- DexAccessFlags flags =
+ ProguardAccessFlags flags =
parseNegation() ? ruleBuilder.getNegatedAccessFlags() : ruleBuilder.getAccessFlags();
skipWhitespace();
switch (peekChar()) {
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java
index 1021f6744..223307cfa 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java
@@ -3,15 +3,14 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
-import com.android.tools.r8.graph.DexAccessFlags;
import com.android.tools.r8.utils.StringUtils;
import java.util.Set;
public abstract class ProguardConfigurationRule extends ProguardClassSpecification {
ProguardConfigurationRule(
ProguardTypeMatcher classAnnotation,
- DexAccessFlags classAccessFlags,
- DexAccessFlags negatedClassAccessFlags,
+ ProguardAccessFlags classAccessFlags,
+ ProguardAccessFlags negatedClassAccessFlags,
boolean classTypeNegated,
ProguardClassType classType,
ProguardClassNameList classNames,
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardIdentifierNameStringRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardIdentifierNameStringRule.java
index 6cfd15449..e006bd444 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardIdentifierNameStringRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardIdentifierNameStringRule.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
-import com.android.tools.r8.graph.DexAccessFlags;
import java.util.Set;
public class ProguardIdentifierNameStringRule extends ProguardConfigurationRule {
@@ -21,8 +20,8 @@ public class ProguardIdentifierNameStringRule extends ProguardConfigurationRule
private ProguardIdentifierNameStringRule(
ProguardTypeMatcher classAnnotation,
- DexAccessFlags classAccessFlags,
- DexAccessFlags negatedClassAccessFlags,
+ ProguardAccessFlags classAccessFlags,
+ ProguardAccessFlags negatedClassAccessFlags,
boolean classTypeNegated,
ProguardClassType classType,
ProguardClassNameList classNames,
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardKeepPackageNamesRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardKeepPackageNamesRule.java
index f6db32686..c4731c625 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardKeepPackageNamesRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardKeepPackageNamesRule.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
-import com.android.tools.r8.graph.DexAccessFlags;
import java.util.Set;
public class ProguardKeepPackageNamesRule extends ProguardConfigurationRule {
@@ -22,8 +21,8 @@ public class ProguardKeepPackageNamesRule extends ProguardConfigurationRule {
private ProguardKeepPackageNamesRule(
ProguardTypeMatcher classAnnotation,
- DexAccessFlags classAccessFlags,
- DexAccessFlags negatedClassAccessFlags,
+ ProguardAccessFlags classAccessFlags,
+ ProguardAccessFlags negatedClassAccessFlags,
boolean classTypeNegated,
ProguardClassType classType,
ProguardClassNameList classNames,
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardKeepRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardKeepRule.java
index 59acd461d..7edceed23 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardKeepRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardKeepRule.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
-import com.android.tools.r8.graph.DexAccessFlags;
import java.util.Set;
public class ProguardKeepRule extends ProguardConfigurationRule {
@@ -36,8 +35,8 @@ public class ProguardKeepRule extends ProguardConfigurationRule {
private ProguardKeepRule(
ProguardTypeMatcher classAnnotation,
- DexAccessFlags classAccessFlags,
- DexAccessFlags negatedClassAccessFlags,
+ ProguardAccessFlags classAccessFlags,
+ ProguardAccessFlags negatedClassAccessFlags,
boolean classTypeNegated,
ProguardClassType classType,
ProguardClassNameList classNames,
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java
index 121641b69..5fb5cb2aa 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.shaking;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexAccessFlags;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexType;
@@ -17,8 +16,8 @@ public class ProguardMemberRule {
public static class Builder {
private ProguardTypeMatcher annotation;
- private DexAccessFlags accessFlags = new DexAccessFlags(0);
- private DexAccessFlags negatedAccessFlags = new DexAccessFlags(0);
+ private ProguardAccessFlags accessFlags = new ProguardAccessFlags();
+ private ProguardAccessFlags negatedAccessFlags = new ProguardAccessFlags();
private ProguardMemberType ruleType;
private ProguardNameMatcher name;
private ProguardTypeMatcher type;
@@ -31,19 +30,19 @@ public class ProguardMemberRule {
this.annotation = annotation;
}
- public DexAccessFlags getAccessFlags() {
+ public ProguardAccessFlags getAccessFlags() {
return accessFlags;
}
- public void setAccessFlags(DexAccessFlags flags) {
+ public void setAccessFlags(ProguardAccessFlags flags) {
accessFlags = flags;
}
- public DexAccessFlags getNegatedAccessFlags() {
+ public ProguardAccessFlags getNegatedAccessFlags() {
return negatedAccessFlags;
}
- public void setNegatedAccessFlags(DexAccessFlags flags) {
+ public void setNegatedAccessFlags(ProguardAccessFlags flags) {
negatedAccessFlags = flags;
}
@@ -83,8 +82,8 @@ public class ProguardMemberRule {
}
private final ProguardTypeMatcher annotation;
- private final DexAccessFlags accessFlags;
- private final DexAccessFlags negatedAccessFlags;
+ private final ProguardAccessFlags accessFlags;
+ private final ProguardAccessFlags negatedAccessFlags;
private final ProguardMemberType ruleType;
private final ProguardNameMatcher name;
private final ProguardTypeMatcher type;
@@ -93,8 +92,8 @@ public class ProguardMemberRule {
private ProguardMemberRule(
ProguardTypeMatcher annotation,
- DexAccessFlags accessFlags,
- DexAccessFlags negatedAccessFlags,
+ ProguardAccessFlags accessFlags,
+ ProguardAccessFlags negatedAccessFlags,
ProguardMemberType ruleType,
ProguardNameMatcher name,
ProguardTypeMatcher type,
@@ -121,11 +120,11 @@ public class ProguardMemberRule {
return annotation;
}
- public DexAccessFlags getAccessFlags() {
+ public ProguardAccessFlags getAccessFlags() {
return accessFlags;
}
- public DexAccessFlags getNegatedAccessFlags() {
+ public ProguardAccessFlags getNegatedAccessFlags() {
return negatedAccessFlags;
}
@@ -162,8 +161,8 @@ public class ProguardMemberRule {
case ALL:
case ALL_FIELDS:
// Access flags check.
- if (!field.accessFlags.containsAllOf(getAccessFlags()) ||
- !field.accessFlags.containsNoneOf(getNegatedAccessFlags())) {
+ if (!getAccessFlags().containsAll(field.accessFlags)
+ || !getNegatedAccessFlags().containsNone(field.accessFlags)) {
break;
}
// Annotations check.
@@ -175,8 +174,8 @@ public class ProguardMemberRule {
break;
}
// Access flags check.
- if (!(field.accessFlags.containsAllOf(getAccessFlags()) &&
- field.accessFlags.containsNoneOf(getNegatedAccessFlags()))) {
+ if (!getAccessFlags().containsAll(field.accessFlags)
+ || !getNegatedAccessFlags().containsNone(field.accessFlags)) {
break;
}
// Type check.
@@ -206,8 +205,8 @@ public class ProguardMemberRule {
// Fall through for all other methods.
case ALL:
// Access flags check.
- if (!method.accessFlags.containsAllOf(getAccessFlags()) ||
- !method.accessFlags.containsNoneOf(getNegatedAccessFlags())) {
+ if (!getAccessFlags().containsAll(method.accessFlags)
+ || !getNegatedAccessFlags().containsNone(method.accessFlags)) {
break;
}
// Annotations check.
@@ -226,8 +225,8 @@ public class ProguardMemberRule {
break;
}
// Access flags check.
- if (!(method.accessFlags.containsAllOf(getAccessFlags()) &&
- method.accessFlags.containsNoneOf(getNegatedAccessFlags()))) {
+ if (!getAccessFlags().containsAll(method.accessFlags)
+ || !getNegatedAccessFlags().containsNone(method.accessFlags)) {
break;
}
// Annotations check.
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardWhyAreYouKeepingRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardWhyAreYouKeepingRule.java
index e029b77fe..ef839265d 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardWhyAreYouKeepingRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardWhyAreYouKeepingRule.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
-import com.android.tools.r8.graph.DexAccessFlags;
import java.util.Set;
public class ProguardWhyAreYouKeepingRule extends ProguardConfigurationRule {
@@ -22,8 +21,8 @@ public class ProguardWhyAreYouKeepingRule extends ProguardConfigurationRule {
private ProguardWhyAreYouKeepingRule(
ProguardTypeMatcher classAnnotation,
- DexAccessFlags classAccessFlags,
- DexAccessFlags negatedClassAccessFlags,
+ ProguardAccessFlags classAccessFlags,
+ ProguardAccessFlags negatedClassAccessFlags,
boolean classTypeNegated,
ProguardClassType classType,
ProguardClassNameList classNames,
diff --git a/src/main/java/com/android/tools/r8/shaking/ReasonPrinter.java b/src/main/java/com/android/tools/r8/shaking/ReasonPrinter.java
index 47893e563..604cf5109 100644
--- a/src/main/java/com/android/tools/r8/shaking/ReasonPrinter.java
+++ b/src/main/java/com/android/tools/r8/shaking/ReasonPrinter.java
@@ -112,11 +112,7 @@ public class ReasonPrinter {
private void printReasonFor(DexEncodedField item) {
KeepReason reason = liveFields.get(item);
if (reason == null) {
- if (item.accessFlags.isAbstract()) {
- printOnlyAbstractShell(item, formatter);
- } else {
- printNoIdeaWhy(item.field, formatter);
- }
+ printNoIdeaWhy(item.field, formatter);
} else {
formatter.startItem(item.field);
formatter.pushIsLivePrefix();
diff --git a/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java b/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
index 177493adc..bb8c08a08 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
@@ -117,10 +117,10 @@ public class RootSetBuilder {
// Process a class with the keep rule.
private void process(DexClass clazz, ProguardConfigurationRule rule) {
- if (!clazz.accessFlags.containsAllOf(rule.getClassAccessFlags())) {
+ if (!rule.getClassAccessFlags().containsAll(clazz.accessFlags)) {
return;
}
- if (!clazz.accessFlags.containsNoneOf(rule.getNegatedClassAccessFlags())) {
+ if (!rule.getNegatedClassAccessFlags().containsNone(clazz.accessFlags)) {
return;
}
if (!containsAnnotation(rule.getClassAnnotation(), clazz.annotations)) {
diff --git a/src/test/java/com/android/tools/r8/dex/JumboStringProcessing.java b/src/test/java/com/android/tools/r8/dex/JumboStringProcessing.java
index 98f107102..e3e9ea0e3 100644
--- a/src/test/java/com/android/tools/r8/dex/JumboStringProcessing.java
+++ b/src/test/java/com/android/tools/r8/dex/JumboStringProcessing.java
@@ -12,12 +12,12 @@ import com.android.tools.r8.code.IfNe;
import com.android.tools.r8.code.IfNez;
import com.android.tools.r8.code.Instruction;
import com.android.tools.r8.code.ReturnVoid;
-import com.android.tools.r8.graph.DexAccessFlags;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.graph.DexCode.Try;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexString;
+import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.naming.NamingLens;
import java.util.ArrayList;
import java.util.List;
@@ -99,8 +99,7 @@ public class JumboStringProcessing {
null,
null,
null);
- DexAccessFlags flags = new DexAccessFlags(0);
- flags.setPublic();
+ MethodAccessFlags flags = MethodAccessFlags.fromSharedAccessFlags(Constants.ACC_PUBLIC, false);
DexEncodedMethod method = new DexEncodedMethod(null, flags, null, null, code);
new JumboStringRewriter(method, string, factory).rewrite();
return method.getCode().asDexCode();
diff --git a/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java b/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java
index add8637e1..e0d97b189 100644
--- a/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java
+++ b/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java
@@ -8,7 +8,7 @@ import com.android.tools.r8.code.Instruction;
import com.android.tools.r8.code.ReturnVoid;
import com.android.tools.r8.errors.DexOverflowException;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexAccessFlags;
+import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.DexAnnotationSet;
import com.android.tools.r8.graph.DexAnnotationSetRefList;
import com.android.tools.r8.graph.DexApplication;
@@ -23,6 +23,7 @@ import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.DirectMappedDexApplication;
+import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.IgnoreContentsOutputSink;
@@ -72,10 +73,13 @@ public class SharedClassWritingTest {
instructions[stringCount] = new ReturnVoid();
DexCode code = new DexCode(1, 0, 0, instructions, new Try[0], new TryHandler[0], null,
strings[startOffset + stringCount - 1]);
- return new DexEncodedMethod(dexItemFactory
- .createMethod(holder, dexItemFactory.createProto(dexItemFactory.voidType), "theMethod"),
- new DexAccessFlags(Constants.ACC_PUBLIC), DexAnnotationSet.empty(),
- DexAnnotationSetRefList.empty(), code);
+ return new DexEncodedMethod(
+ dexItemFactory.createMethod(
+ holder, dexItemFactory.createProto(dexItemFactory.voidType), "theMethod"),
+ MethodAccessFlags.fromSharedAccessFlags(Constants.ACC_PUBLIC, false),
+ DexAnnotationSet.empty(),
+ DexAnnotationSetRefList.empty(),
+ code);
}
private DexProgramClass makeClass(String name, int stringCount, int startOffset,
@@ -86,7 +90,7 @@ public class SharedClassWritingTest {
type,
null,
null,
- new DexAccessFlags(Constants.ACC_PUBLIC),
+ ClassAccessFlags.fromSharedAccessFlags(Constants.ACC_PUBLIC),
dexItemFactory.objectType,
DexTypeList.empty(),
null,
@@ -94,7 +98,7 @@ public class SharedClassWritingTest {
DexEncodedField.EMPTY_ARRAY,
DexEncodedField.EMPTY_ARRAY,
DexEncodedMethod.EMPTY_ARRAY,
- new DexEncodedMethod[]{makeMethod(type, stringCount, startOffset)},
+ new DexEncodedMethod[] {makeMethod(type, stringCount, startOffset)},
synthesizedFrom);
}
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
index a358e26fc..29299960d 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
@@ -21,10 +21,9 @@ import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.DexOverflowException;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.AppInfoWithSubtyping;
+import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DebugLocalInfo;
-import com.android.tools.r8.graph.DexAccessFlags;
import com.android.tools.r8.graph.DexAnnotationSet;
import com.android.tools.r8.graph.DexAnnotationSetRefList;
import com.android.tools.r8.graph.DexApplication;
@@ -36,6 +35,7 @@ import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.DirectMappedDexApplication;
+import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.ir.code.CatchHandlers;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Position;
@@ -577,7 +577,7 @@ public class MainDexListTests extends TestBase {
DexType type = factory.createType(desc);
DexEncodedMethod[] directMethods = new DexEncodedMethod[methodCount];
for (int i = 0; i < methodCount; i++) {
- DexAccessFlags access = new DexAccessFlags();
+ MethodAccessFlags access = MethodAccessFlags.fromSharedAccessFlags(0, false);
access.setPublic();
access.setStatic();
Code code = new SynthesizedCode(new ReturnVoidCode());
@@ -602,7 +602,7 @@ public class MainDexListTests extends TestBase {
type,
null,
null,
- new DexAccessFlags(),
+ ClassAccessFlags.fromSharedAccessFlags(0),
factory.objectType,
DexTypeList.empty(),
null,
diff --git a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
index 6dc19aa5a..d119423d8 100644
--- a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
@@ -14,8 +14,10 @@ import static org.junit.Assert.fail;
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.graph.DexAccessFlags;
+import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.FieldAccessFlags;
+import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.utils.DefaultDiagnosticsHandler;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.InternalOptions.PackageObfuscationMode;
@@ -224,33 +226,39 @@ public class ProguardConfigurationParserTest extends TestBase {
List<ProguardConfigurationRule> rules = parser.getConfig().getRules();
assertEquals(1, rules.size());
ProguardConfigurationRule rule = rules.get(0);
- DexAccessFlags publicAndFinalFlags = new DexAccessFlags(0);
+ ClassAccessFlags publicAndFinalFlags = ClassAccessFlags.fromSharedAccessFlags(0);
publicAndFinalFlags.setPublic();
publicAndFinalFlags.setFinal();
- assertTrue(rule.getClassAccessFlags().containsNoneOf(publicAndFinalFlags));
- assertTrue(rule.getNegatedClassAccessFlags().containsAllOf(publicAndFinalFlags));
- DexAccessFlags abstractFlags = new DexAccessFlags(0);
+ assertTrue(rule.getClassAccessFlags().containsNone(publicAndFinalFlags));
+ assertTrue(rule.getNegatedClassAccessFlags().containsAll(publicAndFinalFlags));
+ ClassAccessFlags abstractFlags = ClassAccessFlags.fromSharedAccessFlags(0);
abstractFlags.setAbstract();
- assertTrue(rule.getClassAccessFlags().containsAllOf(abstractFlags));
- assertTrue(rule.getNegatedClassAccessFlags().containsNoneOf(abstractFlags));
+ assertTrue(rule.getClassAccessFlags().containsAll(abstractFlags));
+ assertTrue(rule.getNegatedClassAccessFlags().containsNone(abstractFlags));
for (ProguardMemberRule member : rule.getMemberRules()) {
if (member.getRuleType() == ProguardMemberType.ALL_FIELDS) {
- DexAccessFlags publicFlags = new DexAccessFlags(0);
- publicAndFinalFlags.setPublic();
- assertTrue(member.getAccessFlags().containsAllOf(publicFlags));
- assertTrue(member.getNegatedAccessFlags().containsNoneOf(publicFlags));
- DexAccessFlags staticFlags = new DexAccessFlags(0);
+ FieldAccessFlags publicFlags = FieldAccessFlags.fromSharedAccessFlags(0);
+ publicFlags.setPublic();
+ assertTrue(member.getAccessFlags().containsAll(publicFlags));
+ assertTrue(member.getNegatedAccessFlags().containsNone(publicFlags));
+ FieldAccessFlags staticFlags = FieldAccessFlags.fromSharedAccessFlags(0);
staticFlags.setStatic();
- assertTrue(member.getAccessFlags().containsNoneOf(staticFlags));
- assertTrue(member.getNegatedAccessFlags().containsAllOf(staticFlags));
+ assertTrue(member.getAccessFlags().containsNone(staticFlags));
+ assertTrue(member.getNegatedAccessFlags().containsAll(staticFlags));
} else {
assertTrue(member.getRuleType() == ProguardMemberType.ALL_METHODS);
- DexAccessFlags publicProtectedVolatileFlags = new DexAccessFlags(0);
- publicProtectedVolatileFlags.setPublic();
- publicProtectedVolatileFlags.setProtected();
- publicProtectedVolatileFlags.setVolatile();
- assertTrue(member.getAccessFlags().containsNoneOf(publicProtectedVolatileFlags));
- assertTrue(member.getNegatedAccessFlags().containsAllOf(publicProtectedVolatileFlags));
+
+ MethodAccessFlags publicNativeFlags = MethodAccessFlags.fromSharedAccessFlags(0, false);
+ publicNativeFlags.setPublic();
+ publicNativeFlags.setNative();
+ assertTrue(member.getAccessFlags().containsAll(publicNativeFlags));
+ assertFalse(member.getNegatedAccessFlags().containsNone(publicNativeFlags));
+
+ MethodAccessFlags protectedNativeFlags = MethodAccessFlags.fromSharedAccessFlags(0, false);
+ protectedNativeFlags.setProtected();
+ protectedNativeFlags.setNative();
+ assertTrue(member.getAccessFlags().containsAll(protectedNativeFlags));
+ assertFalse(member.getNegatedAccessFlags().containsNone(protectedNativeFlags));
}
}
}
diff --git a/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java b/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java
index b285ac060..32cfb1493 100644
--- a/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java
@@ -9,8 +9,6 @@ import com.android.tools.r8.CompilationException;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.ArtCommandBuilder;
-import com.android.tools.r8.dex.Constants;
-import com.android.tools.r8.graph.DexAccessFlags;
import com.android.tools.r8.naming.MemberNaming.FieldSignature;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.utils.AndroidApp;
@@ -196,14 +194,13 @@ public class TreeShakingTest {
private static void hasNoPrivateMethods(DexInspector inspector) {
inspector.forAllClasses(clazz -> clazz.forAllMethods(
- method -> Assert.assertTrue(method.hasNone(new DexAccessFlags(Constants.ACC_PRIVATE)))
- ));
+ method -> Assert.assertTrue(!method.getMethod().accessFlags.isPrivate())));
}
private static void hasNoPublicMethodsButPrivate(DexInspector inspector) {
inspector.forAllClasses(clazz -> clazz.forAllMethods(method -> {
if (!method.isStatic() && !method.isFinal()) {
- Assert.assertTrue(method.hasNone(new DexAccessFlags(Constants.ACC_PUBLIC)));
+ Assert.assertTrue(!method.getMethod().accessFlags.isPublic());
}
}));
Assert.assertTrue(inspector.clazz("shaking6.Superclass")
@@ -255,7 +252,7 @@ public class TreeShakingTest {
private static void shaking7HasOnlyPublicFields(DexInspector inspector) {
inspector.forAllClasses(clazz -> {
clazz.forAllFields(field -> {
- Assert.assertTrue(field.hasAll(new DexAccessFlags(Constants.ACC_PUBLIC)));
+ Assert.assertTrue(field.getField().accessFlags.isPublic());
});
});
ClassSubject subclass = inspector.clazz("shaking7.Subclass");
@@ -283,7 +280,7 @@ public class TreeShakingTest {
private static void shaking7HasOnlyPublicFieldsNamedTheDoubleField(DexInspector inspector) {
inspector.forAllClasses(clazz -> {
clazz.forAllFields(field -> {
- Assert.assertTrue(field.hasAll(new DexAccessFlags(Constants.ACC_PUBLIC)));
+ Assert.assertTrue(field.getField().accessFlags.isPublic());
});
});
ClassSubject subclass = inspector.clazz("shaking7.Subclass");
@@ -297,7 +294,7 @@ public class TreeShakingTest {
private static void shaking7HasOnlyPublicFieldsNamedTheIntField(DexInspector inspector) {
inspector.forAllClasses(clazz -> {
clazz.forAllFields(field -> {
- Assert.assertTrue(field.hasAll(new DexAccessFlags(Constants.ACC_PUBLIC)));
+ Assert.assertTrue(field.getField().accessFlags.isPublic());
});
});
ClassSubject subclass = inspector.clazz("shaking7.Subclass");
diff --git a/src/test/java/com/android/tools/r8/utils/DexInspector.java b/src/test/java/com/android/tools/r8/utils/DexInspector.java
index 612043efe..e70f6f7f6 100644
--- a/src/test/java/com/android/tools/r8/utils/DexInspector.java
+++ b/src/test/java/com/android/tools/r8/utils/DexInspector.java
@@ -43,7 +43,6 @@ import com.android.tools.r8.code.SputObject;
import com.android.tools.r8.code.SputShort;
import com.android.tools.r8.code.SputWide;
import com.android.tools.r8.dex.ApplicationReader;
-import com.android.tools.r8.graph.DexAccessFlags;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexClass;
@@ -503,10 +502,6 @@ public class DexInspector {
public abstract class MemberSubject extends Subject {
- public abstract boolean hasAll(DexAccessFlags flags);
-
- public abstract boolean hasNone(DexAccessFlags flags);
-
public abstract boolean isStatic();
public abstract boolean isFinal();
@@ -551,16 +546,6 @@ public class DexInspector {
}
@Override
- public boolean hasAll(DexAccessFlags flags) {
- return false;
- }
-
- @Override
- public boolean hasNone(DexAccessFlags flags) {
- return true;
- }
-
- @Override
public boolean isStatic() {
return false;
}
@@ -622,16 +607,6 @@ public class DexInspector {
}
@Override
- public boolean hasAll(DexAccessFlags flags) {
- return dexMethod.accessFlags.containsAllOf(flags);
- }
-
- @Override
- public boolean hasNone(DexAccessFlags flags) {
- return dexMethod.accessFlags.containsNoneOf(flags);
- }
-
- @Override
public boolean isStatic() {
return dexMethod.accessFlags.isStatic();
}
@@ -704,16 +679,6 @@ public class DexInspector {
public class AbsentFieldSubject extends FieldSubject {
@Override
- public boolean hasAll(DexAccessFlags flags) {
- return false;
- }
-
- @Override
- public boolean hasNone(DexAccessFlags flags) {
- return true;
- }
-
- @Override
public boolean isStatic() {
return false;
}
@@ -770,16 +735,6 @@ public class DexInspector {
}
@Override
- public boolean hasAll(DexAccessFlags flags) {
- return dexField.accessFlags.containsAllOf(flags);
- }
-
- @Override
- public boolean hasNone(DexAccessFlags flags) {
- return dexField.accessFlags.containsNoneOf(flags);
- }
-
- @Override
public boolean isStatic() {
return dexField.accessFlags.isStatic();
}
diff --git a/src/test/proguard/valid/access-flags.flags b/src/test/proguard/valid/access-flags.flags
index 8096b5903..8d47c33c4 100644
--- a/src/test/proguard/valid/access-flags.flags
+++ b/src/test/proguard/valid/access-flags.flags
@@ -1,4 +1,4 @@
-keep !public abstract !final @com.company.Something class * {
public !static <fields>;
- !public !protected ! volatile <methods>;
+ !public !protected ! native <methods>;
} \ No newline at end of file