diff options
author | Rico Wind <ricow@google.com> | 2017-10-26 14:41:27 +0000 |
---|---|---|
committer | Rico Wind <ricow@google.com> | 2017-10-26 14:41:27 +0000 |
commit | 464b0f90f906a01141f325328b6bdf4453bb4090 (patch) | |
tree | d9ec97e1b2b6b531d2f0c5a6ec3607fee88c2cec | |
parent | f76614b69a9a5cdf865087797546add35401ab07 (diff) | |
download | r8-464b0f90f906a01141f325328b6bdf4453bb4090.tar.gz |
Revert "Define distinct access-flag types for classes, methods and fields."
This reverts commit f76614b69a9a5cdf865087797546add35401ab07.
Reason for revert: <INSERT REASONING HERE>
Change-Id: I9c57ea39b5f78ef4e960f875da1f754db2d27349
47 files changed, 590 insertions, 1017 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 12ae77ff8..50af413c7 100644 --- a/src/main/java/com/android/tools/r8/dex/Constants.java +++ b/src/main/java/com/android/tools/r8/dex/Constants.java @@ -115,7 +115,6 @@ 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 4b0d6e2fc..64909cc3a 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,8 +50,6 @@ 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; @@ -557,7 +555,7 @@ public class DexFileReader { for (int i = 0; i < size; i++) { fieldIndex += file.getUleb128(); DexField field = indexedItems.getField(fieldIndex); - FieldAccessFlags accessFlags = FieldAccessFlags.fromDexAccessFlags(file.getUleb128()); + DexAccessFlags accessFlags = new DexAccessFlags(file.getUleb128()); DexAnnotationSet fieldAnnotations = annotationIterator.getNextFor(field); DexValue staticValue = null; if (accessFlags.isStatic()) { @@ -582,7 +580,7 @@ public class DexFileReader { new MemberAnnotationIterator<>(parameters, DexAnnotationSetRefList::empty); for (int i = 0; i < size; i++) { methodIndex += file.getUleb128(); - MethodAccessFlags accessFlags = MethodAccessFlags.fromDexAccessFlags(file.getUleb128()); + DexAccessFlags accessFlags = new DexAccessFlags(file.getUleb128()); int codeOff = file.getUleb128(); DexCode code = null; if (!skipCodes) { @@ -635,7 +633,7 @@ public class DexFileReader { DexString source = srcIdx == NO_INDEX ? null : indexedItems.getString(srcIdx); // fix annotations. DexType type = indexedItems.getType(classIndices[i]); - ClassAccessFlags flags = ClassAccessFlags.fromDexAccessFlags(accessFlags[i]); + DexAccessFlags flags = new DexAccessFlags(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 27dedb195..dccf88711 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.getAsDexAccessFlags()); + dest.putInt(clazz.accessFlags.get()); 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.getAsDexAccessFlags()); + dest.putUleb128(field.accessFlags.get()); } } @@ -565,7 +565,7 @@ public class FileWriter { assert nextOffset - currentOffset >= 0; dest.putUleb128(nextOffset - currentOffset); currentOffset = nextOffset; - dest.putUleb128(method.accessFlags.getAsDexAccessFlags()); + dest.putUleb128(method.accessFlags.get()); 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 deleted file mode 100644 index 9f0471e6a..000000000 --- a/src/main/java/com/android/tools/r8/graph/AccessFlags.java +++ /dev/null @@ -1,187 +0,0 @@ -// 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 deleted file mode 100644 index 64309244e..000000000 --- a/src/main/java/com/android/tools/r8/graph/ClassAccessFlags.java +++ /dev/null @@ -1,134 +0,0 @@ -// 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 f8c4cbde5..90644e5ad 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, - ClassAccessFlags accessFlags, + DexAccessFlags accessFlags, DexType superType, DexTypeList interfaces, DexString sourceFile, @@ -39,7 +39,7 @@ public enum ClassKind { DexType type, ProgramResource.Kind kind, Origin origin, - ClassAccessFlags accessFlags, + DexAccessFlags 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 new file mode 100644 index 000000000..a8f9526cb --- /dev/null +++ b/src/main/java/com/android/tools/r8/graph/DexAccessFlags.java @@ -0,0 +1,310 @@ +// 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 2aba23b97..505071166 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 ClassAccessFlags accessFlags; + public final DexAccessFlags 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, - ClassAccessFlags accessFlags, + DexAccessFlags 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 292b368eb..d39763e5d 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, - ClassAccessFlags accessFlags, + DexAccessFlags 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 bdfadfc8f..1ba7755ab 100644 --- a/src/main/java/com/android/tools/r8/graph/DexEncodedField.java +++ b/src/main/java/com/android/tools/r8/graph/DexEncodedField.java @@ -13,14 +13,11 @@ public class DexEncodedField extends KeyedDexItem<DexField> { public static final DexEncodedField[] EMPTY_ARRAY = new DexEncodedField[]{}; public final DexField field; - public final FieldAccessFlags accessFlags; + public final DexAccessFlags accessFlags; public DexAnnotationSet annotations; public DexValue staticValue; - public DexEncodedField( - DexField field, - FieldAccessFlags accessFlags, - DexAnnotationSet annotations, + public DexEncodedField(DexField field, DexAccessFlags 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 9c0c39cb2..19743978f 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 MethodAccessFlags accessFlags; + public final DexAccessFlags accessFlags; public DexAnnotationSet annotations; public DexAnnotationSetRefList parameterAnnotations; private Code code; @@ -186,12 +186,8 @@ public class DexEncodedMethod extends KeyedDexItem<DexMethod> { public List<DebugPositionRange> debugPositionRangeList = null; - public DexEncodedMethod( - DexMethod method, - MethodAccessFlags accessFlags, - DexAnnotationSet annotations, - DexAnnotationSetRefList parameterAnnotations, - Code code) { + public DexEncodedMethod(DexMethod method, DexAccessFlags accessFlags, + DexAnnotationSet annotations, DexAnnotationSetRefList parameterAnnotations, Code code) { this.method = method; this.accessFlags = accessFlags; this.annotations = annotations; @@ -671,7 +667,7 @@ public class DexEncodedMethod extends KeyedDexItem<DexMethod> { private static class Builder { private DexMethod method; - private MethodAccessFlags accessFlags; + private DexAccessFlags accessFlags; private DexAnnotationSet annotations; private DexAnnotationSetRefList parameterAnnotations; private Code code; @@ -681,7 +677,7 @@ public class DexEncodedMethod extends KeyedDexItem<DexMethod> { private Builder(DexEncodedMethod from) { // Copy all the mutable state of a DexEncodedMethod here. method = from.method; - accessFlags = from.accessFlags.copy(); + accessFlags = new DexAccessFlags(from.accessFlags.get()); 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 f2e262b1d..3c9cbdd2b 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, - ClassAccessFlags accessFlags, + DexAccessFlags 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 4d1654859..ad1af107f 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, - ClassAccessFlags accessFlags, + DexAccessFlags 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, - ClassAccessFlags accessFlags, + DexAccessFlags 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 deleted file mode 100644 index b56e60fb3..000000000 --- a/src/main/java/com/android/tools/r8/graph/FieldAccessFlags.java +++ /dev/null @@ -1,93 +0,0 @@ -// 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 46f796686..9742df7d3 100644 --- a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java +++ b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java @@ -40,6 +40,7 @@ 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; @@ -66,9 +67,9 @@ public class JarClassFileReader { origin, classKind, reader.b, application, classConsumer), SKIP_FRAMES); } - 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 DexAccessFlags createAccessFlags(int access) { + // Clear the "synthetic attribute" and "deprecated" flags if preset. + return new DexAccessFlags(access & ~ACC_SYNTHETIC_ATTRIBUTE & ~ACC_DEPRECATED); } private static AnnotationVisitor createAnnotationVisitor(String desc, boolean visible, @@ -102,7 +103,7 @@ public class JarClassFileReader { // DexClass data. private int version; private DexType type; - private ClassAccessFlags accessFlags; + private DexAccessFlags accessFlags; private DexType superType; private DexTypeList interfaces; private DexString sourceFile; @@ -175,7 +176,10 @@ public class JarClassFileReader { public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { this.version = version; - accessFlags = ClassAccessFlags.fromCfAccessFlags(cleanAccessFlags(access)); + accessFlags = createAccessFlags(access); + // Unset the (in dex) non-existent ACC_SUPER flag on the class. + assert Constants.ACC_SYNCHRONIZED == Opcodes.ACC_SUPER; + accessFlags.unsetSynchronized(); type = application.getTypeFromName(name); assert superName != null || name.equals(Constants.JAVA_LANG_OBJECT_NAME); superType = superName == null ? null : application.getTypeFromName(superName); @@ -328,7 +332,7 @@ public class JarClassFileReader { @Override public void visitEnd() { - FieldAccessFlags flags = FieldAccessFlags.fromCfAccessFlags(cleanAccessFlags(access)); + DexAccessFlags flags = createAccessFlags(access); DexField dexField = parent.application.getField(parent.type, name, desc); DexAnnotationSet annotationSet = createAnnotationSet(annotations); DexValue staticValue = flags.isStatic() ? getStaticValue(value, dexField.type) : null; @@ -510,7 +514,7 @@ public class JarClassFileReader { @Override public void visitEnd() { DexMethod method = parent.application.getMethod(parent.type, name, desc); - MethodAccessFlags flags = createMethodAccessFlags(access); + DexAccessFlags flags = createMethodAccessFlags(access); Code code = null; if (!flags.isAbstract() && !flags.isNative() @@ -563,11 +567,20 @@ public class JarClassFileReader { getAnnotations().add(annotation); } - 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); + 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; } } diff --git a/src/main/java/com/android/tools/r8/graph/MethodAccessFlags.java b/src/main/java/com/android/tools/r8/graph/MethodAccessFlags.java deleted file mode 100644 index 37a6facf3..000000000 --- a/src/main/java/com/android/tools/r8/graph/MethodAccessFlags.java +++ /dev/null @@ -1,184 +0,0 @@ -// 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 4bafe6211..a71f32605 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,6 +29,7 @@ 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; @@ -39,7 +40,6 @@ 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 MethodAccessFlags accessFlags; + private final DexAccessFlags 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 246079899..1cf64fd2b 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. - MethodAccessFlags flags = descriptor().getAccessibility(); + DexAccessFlags 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 fa0958bfc..09371f774 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); - MethodAccessFlags newFlags = defaultMethod.accessFlags.copy(); + DexAccessFlags newFlags = new DexAccessFlags(defaultMethod.accessFlags.get()); 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 1714b9308..fb3507be6 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,7 +16,6 @@ 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; @@ -57,7 +56,7 @@ final class InterfaceProcessor { + "interface method: " + virtual.method.toSourceString()); } - MethodAccessFlags newFlags = virtual.accessFlags.copy(); + DexAccessFlags newFlags = new DexAccessFlags(virtual.accessFlags.get()); newFlags.unsetBridge(); newFlags.setStatic(); DexCode dexCode = code.asDexCode(); @@ -116,7 +115,7 @@ final class InterfaceProcessor { return; // No methods to create, companion class not needed. } - ClassAccessFlags companionClassFlags = iface.accessFlags.copy(); + DexAccessFlags companionClassFlags = new DexAccessFlags(iface.accessFlags.get()); 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 43548c2b5..569d088a7 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.ClassAccessFlags; +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; @@ -25,8 +25,6 @@ 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; @@ -123,7 +121,7 @@ final class LambdaClass { type, null, null, - ClassAccessFlags.fromDexAccessFlags(Constants.ACC_FINAL | Constants.ACC_SYNTHETIC), + new DexAccessFlags(Constants.ACC_FINAL | Constants.ACC_SYNTHETIC), rewriter.factory.objectType, buildInterfaces(), rewriter.factory.createString("lambda"), @@ -157,31 +155,24 @@ final class LambdaClass { // Synthesize main method. DexMethod mainMethod = rewriter.factory .createMethod(type, descriptor.erasedProto, descriptor.name); - methods[index++] = - new DexEncodedMethod( - mainMethod, - MethodAccessFlags.fromSharedAccessFlags( - Constants.ACC_PUBLIC | Constants.ACC_FINAL, false), - DexAnnotationSet.empty(), - DexAnnotationSetRefList.empty(), - new SynthesizedCode(new LambdaMainMethodSourceCode(this, mainMethod))); + methods[index++] = new DexEncodedMethod( + mainMethod, + new DexAccessFlags(Constants.ACC_PUBLIC | Constants.ACC_FINAL), + 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, - 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))); + 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))); } return methods; } @@ -192,27 +183,23 @@ final class LambdaClass { DexEncodedMethod[] methods = new DexEncodedMethod[stateless ? 2 : 1]; // Constructor. - 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))); + 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))); // Class constructor for stateless lambda classes. if (stateless) { - methods[1] = - new DexEncodedMethod( - classConstructor, - MethodAccessFlags.fromSharedAccessFlags( - Constants.ACC_SYNTHETIC | Constants.ACC_STATIC, true), - DexAnnotationSet.empty(), - DexAnnotationSetRefList.empty(), - new SynthesizedCode(new LambdaClassConstructorSourceCode(this))); + 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))); } return methods; } @@ -223,9 +210,8 @@ final class LambdaClass { int fieldCount = fieldTypes.length; DexEncodedField[] fields = new DexEncodedField[fieldCount]; for (int i = 0; i < fieldCount; i++) { - FieldAccessFlags accessFlags = - FieldAccessFlags.fromSharedAccessFlags( - Constants.ACC_FINAL | Constants.ACC_SYNTHETIC | Constants.ACC_PRIVATE); + DexAccessFlags accessFlags = new DexAccessFlags( + Constants.ACC_FINAL | Constants.ACC_SYNTHETIC | Constants.ACC_PRIVATE); fields[i] = new DexEncodedField( getCaptureField(i), accessFlags, DexAnnotationSet.empty(), null); } @@ -241,16 +227,12 @@ final class LambdaClass { // Create instance field for stateless lambda. assert this.instanceField != null; DexEncodedField[] fields = new DexEncodedField[1]; - fields[0] = - new DexEncodedField( - this.instanceField, - FieldAccessFlags.fromSharedAccessFlags( - Constants.ACC_PUBLIC - | Constants.ACC_FINAL - | Constants.ACC_SYNTHETIC - | Constants.ACC_STATIC), - DexAnnotationSet.empty(), - DexValueNull.NULL); + fields[0] = new DexEncodedField( + this.instanceField, + new DexAccessFlags(Constants.ACC_PUBLIC | Constants.ACC_FINAL + | Constants.ACC_SYNTHETIC | Constants.ACC_STATIC), + DexAnnotationSet.empty(), + DexValueNull.NULL); return fields; } @@ -515,12 +497,9 @@ final class LambdaClass { DexProgramClass accessorClass = programDefinitionFor(callTarget.holder); assert accessorClass != null; - MethodAccessFlags accessorFlags = - MethodAccessFlags.fromSharedAccessFlags( - Constants.ACC_SYNTHETIC - | Constants.ACC_STATIC - | (accessorClass.isInterface() ? Constants.ACC_PUBLIC : 0), - false); + DexAccessFlags accessorFlags = new DexAccessFlags( + Constants.ACC_SYNTHETIC | Constants.ACC_STATIC | + (accessorClass.isInterface() ? Constants.ACC_PUBLIC : 0)); 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 5d5252300..bba7b23f0 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,6 +6,7 @@ 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; @@ -16,7 +17,6 @@ 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 MethodAccessFlags getAccessibility() { + final DexAccessFlags getAccessibility() { return targetMethod == null ? null : targetMethod.accessFlags; } @@ -198,7 +198,7 @@ final class LambdaDescriptor { return true; } - MethodAccessFlags flags = targetMethod.accessFlags; + DexAccessFlags 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 b15d254c2..ad4639e7f 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, AccessFlags flags) { + private boolean isVisibleWithFlags(DexType target, DexType context, DexAccessFlags flags) { if (flags.isPublic()) { return true; } @@ -166,11 +166,8 @@ public class Inliner { assert SUBCLASS.ordinal() < ALWAYS.ordinal(); } - public static Constraint deriveConstraint( - DexType contextHolder, - DexType targetHolder, - AccessFlags flags, - AppInfoWithSubtyping appInfo) { + public static Constraint deriveConstraint(DexType contextHolder, DexType targetHolder, + DexAccessFlags 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 d799e7d79..74afdcd14 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,7 +23,6 @@ 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; @@ -1059,9 +1058,7 @@ public class Outliner { List<Outline> outlines = new ArrayList<>(candidates.keySet()); outlines.sort(Comparator.naturalOrder()); for (Outline outline : outlines) { - MethodAccessFlags methodAccess = - MethodAccessFlags.fromSharedAccessFlags( - Constants.ACC_PUBLIC | Constants.ACC_STATIC, false); + DexAccessFlags methodAccess = new DexAccessFlags(Constants.ACC_PUBLIC, Constants.ACC_STATIC); DexString methodName = dexItemFactory.createString(options.outline.methodPrefix + count); DexMethod method = outline.buildMethod(type, methodName); direct[count] = new DexEncodedMethod(method, methodAccess, DexAnnotationSet.empty(), @@ -1075,7 +1072,7 @@ public class Outliner { DexType superType = dexItemFactory.createType("Ljava/lang/Object;"); DexTypeList interfaces = DexTypeList.empty(); DexString sourceFile = dexItemFactory.createString("outline"); - ClassAccessFlags accessFlags = ClassAccessFlags.fromSharedAccessFlags(Constants.ACC_PUBLIC); + DexAccessFlags accessFlags = new DexAccessFlags(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 95e6e6afa..4662cd0a8 100644 --- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java +++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java @@ -3,8 +3,11 @@ // 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; @@ -50,7 +53,7 @@ public class CfApplicationWriter { ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES); writer.visitSource(clazz.sourceFile.toString(), null); int version = clazz.getClassFileVersion(); - int access = clazz.accessFlags.getAsCfAccessFlags(); + int access = classAndInterfaceAccessFlags(clazz.accessFlags); String desc = clazz.type.toDescriptorString(); String name = internalName(clazz.type); String signature = null; // TODO(zerny): Support generic signatures. @@ -69,7 +72,7 @@ public class CfApplicationWriter { } private void writeMethod(DexEncodedMethod method, ClassWriter writer) { - int access = method.accessFlags.getAsCfAccessFlags(); + int access = method.accessFlags.get(); String name = method.method.name.toString(); String desc = method.descriptor(); String signature = null; // TODO(zerny): Support generic signatures. @@ -78,6 +81,13 @@ 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 deleted file mode 100644 index 749ce835c..000000000 --- a/src/main/java/com/android/tools/r8/shaking/ProguardAccessFlags.java +++ /dev/null @@ -1,176 +0,0 @@ -// 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 ab8342df6..524afd200 100644 --- a/src/main/java/com/android/tools/r8/shaking/ProguardAlwaysInlineRule.java +++ b/src/main/java/com/android/tools/r8/shaking/ProguardAlwaysInlineRule.java @@ -3,6 +3,7 @@ // 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 { @@ -21,8 +22,8 @@ public class ProguardAlwaysInlineRule extends ProguardConfigurationRule { private ProguardAlwaysInlineRule( ProguardTypeMatcher classAnnotation, - ProguardAccessFlags classAccessFlags, - ProguardAccessFlags negatedClassAccessFlags, + DexAccessFlags classAccessFlags, + DexAccessFlags 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 736c7789b..a01dd897b 100644 --- a/src/main/java/com/android/tools/r8/shaking/ProguardAssumeNoSideEffectRule.java +++ b/src/main/java/com/android/tools/r8/shaking/ProguardAssumeNoSideEffectRule.java @@ -3,6 +3,7 @@ // 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 { @@ -20,8 +21,8 @@ public class ProguardAssumeNoSideEffectRule extends ProguardConfigurationRule { private ProguardAssumeNoSideEffectRule( ProguardTypeMatcher classAnnotation, - ProguardAccessFlags classAccessFlags, - ProguardAccessFlags negatedClassAccessFlags, + DexAccessFlags classAccessFlags, + DexAccessFlags 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 97cb5c383..94cf7588f 100644 --- a/src/main/java/com/android/tools/r8/shaking/ProguardAssumeValuesRule.java +++ b/src/main/java/com/android/tools/r8/shaking/ProguardAssumeValuesRule.java @@ -3,6 +3,7 @@ // 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 { @@ -19,8 +20,8 @@ public class ProguardAssumeValuesRule extends ProguardConfigurationRule { private ProguardAssumeValuesRule( ProguardTypeMatcher classAnnotation, - ProguardAccessFlags classAccessFlags, - ProguardAccessFlags negatedClassAccessFlags, + DexAccessFlags classAccessFlags, + DexAccessFlags 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 da5bb2653..7f69e18bc 100644 --- a/src/main/java/com/android/tools/r8/shaking/ProguardCheckDiscardRule.java +++ b/src/main/java/com/android/tools/r8/shaking/ProguardCheckDiscardRule.java @@ -3,6 +3,7 @@ // 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 { @@ -21,8 +22,8 @@ public class ProguardCheckDiscardRule extends ProguardConfigurationRule { private ProguardCheckDiscardRule( ProguardTypeMatcher classAnnotation, - ProguardAccessFlags classAccessFlags, - ProguardAccessFlags negatedClassAccessFlags, + DexAccessFlags classAccessFlags, + DexAccessFlags 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 8e981a73e..b8006d321 100644 --- a/src/main/java/com/android/tools/r8/shaking/ProguardClassSpecification.java +++ b/src/main/java/com/android/tools/r8/shaking/ProguardClassSpecification.java @@ -3,6 +3,7 @@ // 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; @@ -14,8 +15,8 @@ public abstract class ProguardClassSpecification { public static class Builder { protected ProguardTypeMatcher classAnnotation; - protected ProguardAccessFlags classAccessFlags = new ProguardAccessFlags(); - protected ProguardAccessFlags negatedClassAccessFlags = new ProguardAccessFlags(); + protected DexAccessFlags classAccessFlags = new DexAccessFlags(0); + protected DexAccessFlags negatedClassAccessFlags = new DexAccessFlags(0); protected boolean classTypeNegated = false; protected ProguardClassType classType; protected ProguardClassNameList classNames; @@ -87,19 +88,19 @@ public abstract class ProguardClassSpecification { this.classTypeNegated = classTypeNegated; } - public ProguardAccessFlags getClassAccessFlags() { + public DexAccessFlags getClassAccessFlags() { return classAccessFlags; } - public void setClassAccessFlags(ProguardAccessFlags flags) { + public void setClassAccessFlags(DexAccessFlags flags) { classAccessFlags = flags; } - public ProguardAccessFlags getNegatedClassAccessFlags() { + public DexAccessFlags getNegatedClassAccessFlags() { return negatedClassAccessFlags; } - public void setNegatedClassAccessFlags(ProguardAccessFlags flags) { + public void setNegatedClassAccessFlags(DexAccessFlags flags) { negatedClassAccessFlags = flags; } @@ -118,8 +119,8 @@ public abstract class ProguardClassSpecification { } private final ProguardTypeMatcher classAnnotation; - private final ProguardAccessFlags classAccessFlags; - private final ProguardAccessFlags negatedClassAccessFlags; + private final DexAccessFlags classAccessFlags; + private final DexAccessFlags negatedClassAccessFlags; private final boolean classTypeNegated; private final ProguardClassType classType; private final ProguardClassNameList classNames; @@ -130,8 +131,8 @@ public abstract class ProguardClassSpecification { protected ProguardClassSpecification( ProguardTypeMatcher classAnnotation, - ProguardAccessFlags classAccessFlags, - ProguardAccessFlags negatedClassAccessFlags, + DexAccessFlags classAccessFlags, + DexAccessFlags negatedClassAccessFlags, boolean classTypeNegated, ProguardClassType classType, ProguardClassNameList classNames, @@ -183,11 +184,11 @@ public abstract class ProguardClassSpecification { return classTypeNegated; } - public ProguardAccessFlags getClassAccessFlags() { + public DexAccessFlags getClassAccessFlags() { return classAccessFlags; } - public ProguardAccessFlags getNegatedClassAccessFlags() { + public DexAccessFlags 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 7997b4425..d24a3578f 100644 --- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java +++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java @@ -6,6 +6,7 @@ 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; @@ -560,10 +561,9 @@ public class ProguardConfigurationParser { assert builder.getClassAnnotation() == null; builder.setClassAnnotation(annotation); } else { - ProguardAccessFlags flags = - parseNegation() - ? builder.getNegatedClassAccessFlags() - : builder.getClassAccessFlags(); + DexAccessFlags 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; - ProguardAccessFlags flags = + DexAccessFlags 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 223307cfa..1021f6744 100644 --- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java +++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java @@ -3,14 +3,15 @@ // 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, - ProguardAccessFlags classAccessFlags, - ProguardAccessFlags negatedClassAccessFlags, + DexAccessFlags classAccessFlags, + DexAccessFlags 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 e006bd444..6cfd15449 100644 --- a/src/main/java/com/android/tools/r8/shaking/ProguardIdentifierNameStringRule.java +++ b/src/main/java/com/android/tools/r8/shaking/ProguardIdentifierNameStringRule.java @@ -3,6 +3,7 @@ // 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 { @@ -20,8 +21,8 @@ public class ProguardIdentifierNameStringRule extends ProguardConfigurationRule private ProguardIdentifierNameStringRule( ProguardTypeMatcher classAnnotation, - ProguardAccessFlags classAccessFlags, - ProguardAccessFlags negatedClassAccessFlags, + DexAccessFlags classAccessFlags, + DexAccessFlags 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 c4731c625..f6db32686 100644 --- a/src/main/java/com/android/tools/r8/shaking/ProguardKeepPackageNamesRule.java +++ b/src/main/java/com/android/tools/r8/shaking/ProguardKeepPackageNamesRule.java @@ -3,6 +3,7 @@ // 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 { @@ -21,8 +22,8 @@ public class ProguardKeepPackageNamesRule extends ProguardConfigurationRule { private ProguardKeepPackageNamesRule( ProguardTypeMatcher classAnnotation, - ProguardAccessFlags classAccessFlags, - ProguardAccessFlags negatedClassAccessFlags, + DexAccessFlags classAccessFlags, + DexAccessFlags 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 7edceed23..59acd461d 100644 --- a/src/main/java/com/android/tools/r8/shaking/ProguardKeepRule.java +++ b/src/main/java/com/android/tools/r8/shaking/ProguardKeepRule.java @@ -3,6 +3,7 @@ // 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 { @@ -35,8 +36,8 @@ public class ProguardKeepRule extends ProguardConfigurationRule { private ProguardKeepRule( ProguardTypeMatcher classAnnotation, - ProguardAccessFlags classAccessFlags, - ProguardAccessFlags negatedClassAccessFlags, + DexAccessFlags classAccessFlags, + DexAccessFlags 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 5fb5cb2aa..121641b69 100644 --- a/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java +++ b/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java @@ -4,6 +4,7 @@ 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; @@ -16,8 +17,8 @@ public class ProguardMemberRule { public static class Builder { private ProguardTypeMatcher annotation; - private ProguardAccessFlags accessFlags = new ProguardAccessFlags(); - private ProguardAccessFlags negatedAccessFlags = new ProguardAccessFlags(); + private DexAccessFlags accessFlags = new DexAccessFlags(0); + private DexAccessFlags negatedAccessFlags = new DexAccessFlags(0); private ProguardMemberType ruleType; private ProguardNameMatcher name; private ProguardTypeMatcher type; @@ -30,19 +31,19 @@ public class ProguardMemberRule { this.annotation = annotation; } - public ProguardAccessFlags getAccessFlags() { + public DexAccessFlags getAccessFlags() { return accessFlags; } - public void setAccessFlags(ProguardAccessFlags flags) { + public void setAccessFlags(DexAccessFlags flags) { accessFlags = flags; } - public ProguardAccessFlags getNegatedAccessFlags() { + public DexAccessFlags getNegatedAccessFlags() { return negatedAccessFlags; } - public void setNegatedAccessFlags(ProguardAccessFlags flags) { + public void setNegatedAccessFlags(DexAccessFlags flags) { negatedAccessFlags = flags; } @@ -82,8 +83,8 @@ public class ProguardMemberRule { } private final ProguardTypeMatcher annotation; - private final ProguardAccessFlags accessFlags; - private final ProguardAccessFlags negatedAccessFlags; + private final DexAccessFlags accessFlags; + private final DexAccessFlags negatedAccessFlags; private final ProguardMemberType ruleType; private final ProguardNameMatcher name; private final ProguardTypeMatcher type; @@ -92,8 +93,8 @@ public class ProguardMemberRule { private ProguardMemberRule( ProguardTypeMatcher annotation, - ProguardAccessFlags accessFlags, - ProguardAccessFlags negatedAccessFlags, + DexAccessFlags accessFlags, + DexAccessFlags negatedAccessFlags, ProguardMemberType ruleType, ProguardNameMatcher name, ProguardTypeMatcher type, @@ -120,11 +121,11 @@ public class ProguardMemberRule { return annotation; } - public ProguardAccessFlags getAccessFlags() { + public DexAccessFlags getAccessFlags() { return accessFlags; } - public ProguardAccessFlags getNegatedAccessFlags() { + public DexAccessFlags getNegatedAccessFlags() { return negatedAccessFlags; } @@ -161,8 +162,8 @@ public class ProguardMemberRule { case ALL: case ALL_FIELDS: // Access flags check. - if (!getAccessFlags().containsAll(field.accessFlags) - || !getNegatedAccessFlags().containsNone(field.accessFlags)) { + if (!field.accessFlags.containsAllOf(getAccessFlags()) || + !field.accessFlags.containsNoneOf(getNegatedAccessFlags())) { break; } // Annotations check. @@ -174,8 +175,8 @@ public class ProguardMemberRule { break; } // Access flags check. - if (!getAccessFlags().containsAll(field.accessFlags) - || !getNegatedAccessFlags().containsNone(field.accessFlags)) { + if (!(field.accessFlags.containsAllOf(getAccessFlags()) && + field.accessFlags.containsNoneOf(getNegatedAccessFlags()))) { break; } // Type check. @@ -205,8 +206,8 @@ public class ProguardMemberRule { // Fall through for all other methods. case ALL: // Access flags check. - if (!getAccessFlags().containsAll(method.accessFlags) - || !getNegatedAccessFlags().containsNone(method.accessFlags)) { + if (!method.accessFlags.containsAllOf(getAccessFlags()) || + !method.accessFlags.containsNoneOf(getNegatedAccessFlags())) { break; } // Annotations check. @@ -225,8 +226,8 @@ public class ProguardMemberRule { break; } // Access flags check. - if (!getAccessFlags().containsAll(method.accessFlags) - || !getNegatedAccessFlags().containsNone(method.accessFlags)) { + if (!(method.accessFlags.containsAllOf(getAccessFlags()) && + method.accessFlags.containsNoneOf(getNegatedAccessFlags()))) { 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 ef839265d..e029b77fe 100644 --- a/src/main/java/com/android/tools/r8/shaking/ProguardWhyAreYouKeepingRule.java +++ b/src/main/java/com/android/tools/r8/shaking/ProguardWhyAreYouKeepingRule.java @@ -3,6 +3,7 @@ // 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 { @@ -21,8 +22,8 @@ public class ProguardWhyAreYouKeepingRule extends ProguardConfigurationRule { private ProguardWhyAreYouKeepingRule( ProguardTypeMatcher classAnnotation, - ProguardAccessFlags classAccessFlags, - ProguardAccessFlags negatedClassAccessFlags, + DexAccessFlags classAccessFlags, + DexAccessFlags 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 604cf5109..47893e563 100644 --- a/src/main/java/com/android/tools/r8/shaking/ReasonPrinter.java +++ b/src/main/java/com/android/tools/r8/shaking/ReasonPrinter.java @@ -112,7 +112,11 @@ public class ReasonPrinter { private void printReasonFor(DexEncodedField item) { KeepReason reason = liveFields.get(item); if (reason == null) { - printNoIdeaWhy(item.field, formatter); + if (item.accessFlags.isAbstract()) { + printOnlyAbstractShell(item, formatter); + } else { + 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 bb8c08a08..177493adc 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 (!rule.getClassAccessFlags().containsAll(clazz.accessFlags)) { + if (!clazz.accessFlags.containsAllOf(rule.getClassAccessFlags())) { return; } - if (!rule.getNegatedClassAccessFlags().containsNone(clazz.accessFlags)) { + if (!clazz.accessFlags.containsNoneOf(rule.getNegatedClassAccessFlags())) { 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 e3e9ea0e3..98f107102 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,7 +99,8 @@ public class JumboStringProcessing { null, null, null); - MethodAccessFlags flags = MethodAccessFlags.fromSharedAccessFlags(Constants.ACC_PUBLIC, false); + DexAccessFlags flags = new DexAccessFlags(0); + flags.setPublic(); 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 e0d97b189..add8637e1 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.ClassAccessFlags; +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; @@ -23,7 +23,6 @@ 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; @@ -73,13 +72,10 @@ 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"), - MethodAccessFlags.fromSharedAccessFlags(Constants.ACC_PUBLIC, false), - DexAnnotationSet.empty(), - DexAnnotationSetRefList.empty(), - code); + return new DexEncodedMethod(dexItemFactory + .createMethod(holder, dexItemFactory.createProto(dexItemFactory.voidType), "theMethod"), + new DexAccessFlags(Constants.ACC_PUBLIC), DexAnnotationSet.empty(), + DexAnnotationSetRefList.empty(), code); } private DexProgramClass makeClass(String name, int stringCount, int startOffset, @@ -90,7 +86,7 @@ public class SharedClassWritingTest { type, null, null, - ClassAccessFlags.fromSharedAccessFlags(Constants.ACC_PUBLIC), + new DexAccessFlags(Constants.ACC_PUBLIC), dexItemFactory.objectType, DexTypeList.empty(), null, @@ -98,7 +94,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 29299960d..a358e26fc 100644 --- a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java +++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java @@ -21,9 +21,10 @@ 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.ClassAccessFlags; +import com.android.tools.r8.graph.AppInfoWithSubtyping; 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; @@ -35,7 +36,6 @@ 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++) { - MethodAccessFlags access = MethodAccessFlags.fromSharedAccessFlags(0, false); + DexAccessFlags access = new DexAccessFlags(); access.setPublic(); access.setStatic(); Code code = new SynthesizedCode(new ReturnVoidCode()); @@ -602,7 +602,7 @@ public class MainDexListTests extends TestBase { type, null, null, - ClassAccessFlags.fromSharedAccessFlags(0), + new DexAccessFlags(), 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 d119423d8..6dc19aa5a 100644 --- a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java +++ b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java @@ -14,10 +14,8 @@ 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.ClassAccessFlags; +import com.android.tools.r8.graph.DexAccessFlags; 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; @@ -226,39 +224,33 @@ public class ProguardConfigurationParserTest extends TestBase { List<ProguardConfigurationRule> rules = parser.getConfig().getRules(); assertEquals(1, rules.size()); ProguardConfigurationRule rule = rules.get(0); - ClassAccessFlags publicAndFinalFlags = ClassAccessFlags.fromSharedAccessFlags(0); + DexAccessFlags publicAndFinalFlags = new DexAccessFlags(0); publicAndFinalFlags.setPublic(); publicAndFinalFlags.setFinal(); - assertTrue(rule.getClassAccessFlags().containsNone(publicAndFinalFlags)); - assertTrue(rule.getNegatedClassAccessFlags().containsAll(publicAndFinalFlags)); - ClassAccessFlags abstractFlags = ClassAccessFlags.fromSharedAccessFlags(0); + assertTrue(rule.getClassAccessFlags().containsNoneOf(publicAndFinalFlags)); + assertTrue(rule.getNegatedClassAccessFlags().containsAllOf(publicAndFinalFlags)); + DexAccessFlags abstractFlags = new DexAccessFlags(0); abstractFlags.setAbstract(); - assertTrue(rule.getClassAccessFlags().containsAll(abstractFlags)); - assertTrue(rule.getNegatedClassAccessFlags().containsNone(abstractFlags)); + assertTrue(rule.getClassAccessFlags().containsAllOf(abstractFlags)); + assertTrue(rule.getNegatedClassAccessFlags().containsNoneOf(abstractFlags)); for (ProguardMemberRule member : rule.getMemberRules()) { if (member.getRuleType() == ProguardMemberType.ALL_FIELDS) { - FieldAccessFlags publicFlags = FieldAccessFlags.fromSharedAccessFlags(0); - publicFlags.setPublic(); - assertTrue(member.getAccessFlags().containsAll(publicFlags)); - assertTrue(member.getNegatedAccessFlags().containsNone(publicFlags)); - FieldAccessFlags staticFlags = FieldAccessFlags.fromSharedAccessFlags(0); + DexAccessFlags publicFlags = new DexAccessFlags(0); + publicAndFinalFlags.setPublic(); + assertTrue(member.getAccessFlags().containsAllOf(publicFlags)); + assertTrue(member.getNegatedAccessFlags().containsNoneOf(publicFlags)); + DexAccessFlags staticFlags = new DexAccessFlags(0); staticFlags.setStatic(); - assertTrue(member.getAccessFlags().containsNone(staticFlags)); - assertTrue(member.getNegatedAccessFlags().containsAll(staticFlags)); + assertTrue(member.getAccessFlags().containsNoneOf(staticFlags)); + assertTrue(member.getNegatedAccessFlags().containsAllOf(staticFlags)); } else { assertTrue(member.getRuleType() == ProguardMemberType.ALL_METHODS); - - 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)); + DexAccessFlags publicProtectedVolatileFlags = new DexAccessFlags(0); + publicProtectedVolatileFlags.setPublic(); + publicProtectedVolatileFlags.setProtected(); + publicProtectedVolatileFlags.setVolatile(); + assertTrue(member.getAccessFlags().containsNoneOf(publicProtectedVolatileFlags)); + assertTrue(member.getNegatedAccessFlags().containsAllOf(publicProtectedVolatileFlags)); } } } 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 32cfb1493..b285ac060 100644 --- a/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java +++ b/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java @@ -9,6 +9,8 @@ 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; @@ -194,13 +196,14 @@ public class TreeShakingTest { private static void hasNoPrivateMethods(DexInspector inspector) { inspector.forAllClasses(clazz -> clazz.forAllMethods( - method -> Assert.assertTrue(!method.getMethod().accessFlags.isPrivate()))); + method -> Assert.assertTrue(method.hasNone(new DexAccessFlags(Constants.ACC_PRIVATE))) + )); } private static void hasNoPublicMethodsButPrivate(DexInspector inspector) { inspector.forAllClasses(clazz -> clazz.forAllMethods(method -> { if (!method.isStatic() && !method.isFinal()) { - Assert.assertTrue(!method.getMethod().accessFlags.isPublic()); + Assert.assertTrue(method.hasNone(new DexAccessFlags(Constants.ACC_PUBLIC))); } })); Assert.assertTrue(inspector.clazz("shaking6.Superclass") @@ -252,7 +255,7 @@ public class TreeShakingTest { private static void shaking7HasOnlyPublicFields(DexInspector inspector) { inspector.forAllClasses(clazz -> { clazz.forAllFields(field -> { - Assert.assertTrue(field.getField().accessFlags.isPublic()); + Assert.assertTrue(field.hasAll(new DexAccessFlags(Constants.ACC_PUBLIC))); }); }); ClassSubject subclass = inspector.clazz("shaking7.Subclass"); @@ -280,7 +283,7 @@ public class TreeShakingTest { private static void shaking7HasOnlyPublicFieldsNamedTheDoubleField(DexInspector inspector) { inspector.forAllClasses(clazz -> { clazz.forAllFields(field -> { - Assert.assertTrue(field.getField().accessFlags.isPublic()); + Assert.assertTrue(field.hasAll(new DexAccessFlags(Constants.ACC_PUBLIC))); }); }); ClassSubject subclass = inspector.clazz("shaking7.Subclass"); @@ -294,7 +297,7 @@ public class TreeShakingTest { private static void shaking7HasOnlyPublicFieldsNamedTheIntField(DexInspector inspector) { inspector.forAllClasses(clazz -> { clazz.forAllFields(field -> { - Assert.assertTrue(field.getField().accessFlags.isPublic()); + Assert.assertTrue(field.hasAll(new DexAccessFlags(Constants.ACC_PUBLIC))); }); }); 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 e70f6f7f6..612043efe 100644 --- a/src/test/java/com/android/tools/r8/utils/DexInspector.java +++ b/src/test/java/com/android/tools/r8/utils/DexInspector.java @@ -43,6 +43,7 @@ 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; @@ -502,6 +503,10 @@ 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(); @@ -546,6 +551,16 @@ 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; } @@ -607,6 +622,16 @@ 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(); } @@ -679,6 +704,16 @@ 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; } @@ -735,6 +770,16 @@ 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 8d47c33c4..8096b5903 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 ! native <methods>; + !public !protected ! volatile <methods>; }
\ No newline at end of file |