Merge "Fix method index support in Jayce V2" into ub-jack
diff --git a/build.xml b/build.xml
index 1389787..06045f8 100644
--- a/build.xml
+++ b/build.xml
@@ -958,6 +958,11 @@
<arg line="${jack.static.libs.list}" />
<arg value="${jack-tests.dist.dir}/${jack-tests.execname}" />
</java>
+ <jar update="true" destfile="${jack-tests.dist.dir}/${jack-tests.execname}">
+ <metainf dir="${jack.dir}/rsc/META-INF" includes="services/**" />
+ <metainf dir="${jill.dir}/rsc/META-INF" includes="services/**" />
+ </jar>
+
</target>
@@ -2298,6 +2303,10 @@
<istrue value="${tests.console-output}"/>
</condition>
+ <condition property="jack.runtime.version" value="-Druntime.version=${runtime.version}" else="">
+ <isset property="runtime.version"/>
+ </condition>
+
<filelist id="jack.junit.tests.classpath" dir="/">
<file name="${jack-tests.dist.dir}/${jack-tests.execname}" />
<file name="${ddm-lib.dist.dir}/${ddm-lib.libname}" />
@@ -2323,6 +2332,7 @@
classname="com.android.jack.test.junit.JackJUnitLauncher">
<jvmarg value="-Dtests.dump=true" />
<jvmarg value="-Dtests.config=${tests.config}"/>
+ <jvmarg line="${jack.runtime.version}"/>
<classpath>
<filelist refid="jack.junit.tests.classpath" />
<filelist refid="ecj-test-libs"/>
@@ -2338,6 +2348,7 @@
classname="com.android.jack.test.junit.JackJUnitLauncher">
<jvmarg value="-Dtests.dump=true" />
<jvmarg value="-Dtests.config=${tests.config}"/>
+ <jvmarg line="${jack.runtime.version}"/>
<classpath>
<filelist refid="jack.junit.tests.classpath"/>
<filelist refid="ecj-test-libs"/>
@@ -2347,6 +2358,40 @@
</target>
+ <target name="test-jack-java8-pre-n-dump" depends="tests-check-config">
+ <mkdir dir="${jack-tests.dir}/dump"/>
+
+ <java fork="true" failonerror="true"
+ output="${jack-tests.dir}/dump/Java8AllTestPreN.js"
+ classname="com.android.jack.test.junit.JackJUnitLauncher">
+ <jvmarg value="-Dtests.dump=true" />
+ <jvmarg value="-Dtests.config=${tests.config}"/>
+ <classpath>
+ <filelist refid="jack.junit.tests.classpath" />
+ <filelist refid="ecj-test-libs"/>
+ </classpath>
+ <arg value="com.android.jack.java8.Java8AllTestPreN"/>
+ </java>
+
+ </target>
+
+ <target name="test-jack-java8-post-m-dump" depends="tests-check-config">
+ <mkdir dir="${jack-tests.dir}/dump"/>
+
+ <java fork="true" failonerror="true"
+ output="${jack-tests.dir}/dump/Java8AllTestPostM.js"
+ classname="com.android.jack.test.junit.JackJUnitLauncher">
+ <jvmarg value="-Dtests.dump=true" />
+ <jvmarg value="-Dtests.config=${tests.config}"/>
+ <classpath>
+ <filelist refid="jack.junit.tests.classpath" />
+ <filelist refid="ecj-test-libs"/>
+ </classpath>
+ <arg value="com.android.jack.java8.Java8AllTestPostM"/>
+ </java>
+
+ </target>
+
<target name="test-sched-dump" depends="tests-check-config">
<mkdir dir="${jack-tests.dir}/dump"/>
@@ -2375,6 +2420,7 @@
<jvmarg value="-Dfile.encoding=utf-8" />
<jvmarg value="-Dtests.config=${tests.config}"/>
<jvmarg value="${jack.tests.assertions}"/>
+ <jvmarg line="${jack.runtime.version}"/>
<classpath>
<filelist refid="jack.junit.tests.classpath" />
<filelist refid="ecj-test-libs"/>
@@ -2407,6 +2453,7 @@
<jvmarg value="-Dfile.encoding=utf-8" />
<jvmarg value="-Dtests.config=${tests.config}"/>
<jvmarg value="${jack.tests.assertions}"/>
+ <jvmarg line="${jack.runtime.version}"/>
<classpath>
<filelist refid="jack.junit.tests.classpath" />
<filelist refid="ecj-test-libs"/>
@@ -2439,6 +2486,7 @@
<jvmarg value="-Dfile.encoding=utf-8" />
<jvmarg value="-Dtests.config=${tests.config}"/>
<jvmarg value="${jack.tests.assertions}"/>
+ <jvmarg line="${jack.runtime.version}"/>
<classpath>
<filelist refid="jack.junit.tests.classpath" />
<filelist refid="ecj-test-libs"/>
@@ -2471,6 +2519,7 @@
<jvmarg value="-Dfile.encoding=utf-8" />
<jvmarg value="-Dtests.config=${tests.config}"/>
<jvmarg value="${jack.tests.assertions}"/>
+ <jvmarg line="${jack.runtime.version}"/>
<classpath>
<filelist refid="jack.junit.tests.classpath" />
<filelist refid="ecj-test-libs"/>
diff --git a/jack-jacoco-reporter/src/com/android/jack/tools/jacoco/JackCoverageAnalyzer.java b/jack-jacoco-reporter/src/com/android/jack/tools/jacoco/JackCoverageAnalyzer.java
index a3829b3..d9be8f7 100644
--- a/jack-jacoco-reporter/src/com/android/jack/tools/jacoco/JackCoverageAnalyzer.java
+++ b/jack-jacoco-reporter/src/com/android/jack/tools/jacoco/JackCoverageAnalyzer.java
@@ -32,21 +32,28 @@
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
+import java.util.regex.Pattern;
+import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
/**
* Code coverage report analyzer.
*/
public class JackCoverageAnalyzer {
- @Nonnull
- private final ExecutionDataStore executionDataStore;
+ @Nonnull private static final String CURRENT_VERSION = "1.0";
- @Nonnull
- private final ICoverageVisitor coverageVisitor;
+ @Nonnull private static final String JSON_VERSION_ATTRIBUTE = "version";
+
+ @Nonnull private static final String JSON_DATA_ATTRIBUTE = "data";
+
+ @Nonnull private final ExecutionDataStore executionDataStore;
+
+ @Nonnull private final ICoverageVisitor coverageVisitor;
public JackCoverageAnalyzer(
@Nonnull ExecutionDataStore executionDataStore, @Nonnull ICoverageVisitor coverageVisitor) {
@@ -66,15 +73,52 @@
"File " + jackCoverageDescriptionFile + " does not exist.");
}
- JsonReader jsonReader =
- new JsonReader(new InputStreamReader(new FileInputStream(jackCoverageDescriptionFile)));
+ InputStream is = new FileInputStream(jackCoverageDescriptionFile);
try {
- readClasses(jsonReader);
+ analyze(is);
} finally {
- jsonReader.close();
+ is.close();
}
}
+ private void analyze(@Nonnull InputStream coverageDescriptionInputStream) throws IOException {
+ JsonReader jsonReader = new JsonReader(new InputStreamReader(coverageDescriptionInputStream));
+ readMetadata(jsonReader);
+ }
+
+ private void checkVersion(@CheckForNull String version) {
+ if (version == null) {
+ throw new JsonParseException("Missing 'version' attribute before coverage metadadata");
+ }
+ String[] parts = version.split(Pattern.quote("."));
+ if (parts.length != 2) {
+ throw new JsonParseException("Version number format must be x.y");
+ }
+ if (!version.equals(CURRENT_VERSION)) {
+ throw new JsonParseException("Unknown version " + version);
+ }
+ }
+
+ private void readMetadata(@Nonnull JsonReader jsonReader) throws IOException {
+ jsonReader.beginObject();
+
+ String version = null;
+ while (jsonReader.hasNext()) {
+ String attributeName = jsonReader.nextName();
+ if (attributeName.equals(JSON_VERSION_ATTRIBUTE)) {
+ // Reads the version so we can parse the JSON accordingly.
+ version = jsonReader.nextString();
+ } else if (attributeName.equals(JSON_DATA_ATTRIBUTE)) {
+ checkVersion(version);
+ readClasses(jsonReader);
+ } else {
+ jsonReader.skipValue();
+ }
+ }
+
+ jsonReader.endObject();
+ }
+
private void readClasses(@Nonnull JsonReader jsonReader) throws IOException {
jsonReader.beginArray();
while (jsonReader.hasNext()) {
@@ -132,8 +176,9 @@
// Build the class coverage.
String[] interfacesArray = interfaces.toArray(new String[0]);
- ClassCoverageImpl c = new ClassCoverageImpl(
- className, id, noMatch, classSignature, superClassName, interfacesArray);
+ ClassCoverageImpl c =
+ new ClassCoverageImpl(
+ className, id, noMatch, classSignature, superClassName, interfacesArray);
c.setSourceFileName(sourceFile);
// Update methods with probes.
@@ -174,8 +219,10 @@
}
// Parses probes.
- private static void readProbes(@Nonnull JsonReader jsonReader,
- @Nonnull List<ProbeDescription> probes, @Nonnull List<? extends IMethodCoverage> methods)
+ private static void readProbes(
+ @Nonnull JsonReader jsonReader,
+ @Nonnull List<ProbeDescription> probes,
+ @Nonnull List<? extends IMethodCoverage> methods)
throws IOException {
jsonReader.beginArray();
while (jsonReader.hasNext()) {
diff --git a/jack-tests/.classpath b/jack-tests/.classpath
index 9194025..3203ed2 100644
--- a/jack-tests/.classpath
+++ b/jack-tests/.classpath
@@ -11,7 +11,6 @@
<classpathentry combineaccessrules="false" kind="src" path="/Scheduler"/>
<classpathentry kind="lib" path="libs/guava-lib.jar"/>
<classpathentry kind="lib" path="libs/dex-lib.jar"/>
- <classpathentry combineaccessrules="false" kind="src" path="/Jack"/>
<classpathentry kind="lib" path="libs/ddmlib.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/Dx"/>
<classpathentry combineaccessrules="false" kind="src" path="/jack-api"/>
@@ -21,5 +20,6 @@
<classpathentry kind="lib" path="prebuilts/org.eclipse.jdt.core_3.12.0.v20150913-1717.jar"/>
<classpathentry kind="lib" path="prebuilts/org.eclipse.jdt.core.tests.compiler_3.12.0.v20150913-1717.jar"/>
<classpathentry kind="lib" path="prebuilts/org.eclipse.test.performance_3.11.0.v20150223-0658.jar"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/Jack"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/jack-tests/src/com/android/jack/test/junit/JackTestRunner.java b/jack-tests/src/com/android/jack/test/junit/JackTestRunner.java
index b5485a6..9fd9cc3 100644
--- a/jack-tests/src/com/android/jack/test/junit/JackTestRunner.java
+++ b/jack-tests/src/com/android/jack/test/junit/JackTestRunner.java
@@ -37,6 +37,9 @@
private boolean dumpTests = false;
+ @Nonnull
+ private RuntimeVersion runtimeVersion;
+
private static class ToolchainFilter extends Filter {
@Nonnull
@@ -47,11 +50,15 @@
private boolean dumpTests = false;
- public ToolchainFilter(
- @Nonnull IToolchain candidate, @Nonnull IToolchain reference, boolean dumpTest) {
+ @Nonnull
+ private RuntimeVersion runtimeVersion;
+
+ public ToolchainFilter(@Nonnull IToolchain candidate, @Nonnull IToolchain reference,
+ boolean dumpTest, @Nonnull RuntimeVersion runtimeVersion) {
this.candidate = candidate;
this.reference = reference;
this.dumpTests = dumpTest;
+ this.runtimeVersion = runtimeVersion;
}
@Override
@@ -66,13 +73,17 @@
KnownIssue knownIssueAnnot = description.getAnnotation(KnownIssue.class);
- if (knownIssueAnnot == null) {
- shouldRun = true;
- } else {
- shouldRun = (knownIssueAnnot.candidate().length > 0
- || knownIssueAnnot.reference().length > 0)
- && (isValidToolchain(candidate, knownIssueAnnot.candidate())
- && isValidToolchain(reference, knownIssueAnnot.reference()));
+ MinRuntimeVersion minRuntimeVersion = description.getAnnotation(MinRuntimeVersion.class);
+
+ if (minRuntimeVersion == null || minRuntimeVersion.value().compareTo(runtimeVersion) <= 0) {
+ if (knownIssueAnnot == null) {
+ shouldRun = true;
+ } else {
+ shouldRun = (knownIssueAnnot.candidate().length > 0
+ || knownIssueAnnot.reference().length > 0)
+ && (isValidToolchain(candidate, knownIssueAnnot.candidate())
+ && isValidToolchain(reference, knownIssueAnnot.reference()));
+ }
}
if (dumpTests && description.getMethodName() != null) {
@@ -104,8 +115,11 @@
dumpTests = Boolean.parseBoolean(System.getProperty("tests.dump", "false"));
+ runtimeVersion =
+ RuntimeVersion.valueOf(System.getProperty("runtime.version", "M").toUpperCase());
+
ToolchainFilter filter = new ToolchainFilter(AbstractTestTools.getCandidateToolchain(),
- AbstractTestTools.getReferenceToolchain(), dumpTests);
+ AbstractTestTools.getReferenceToolchain(), dumpTests, runtimeVersion);
try {
filter(filter);
diff --git a/jack-tests/src/com/android/jack/test/junit/MinRuntimeVersion.java b/jack-tests/src/com/android/jack/test/junit/MinRuntimeVersion.java
new file mode 100644
index 0000000..18b8f2d
--- /dev/null
+++ b/jack-tests/src/com/android/jack/test/junit/MinRuntimeVersion.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.jack.test.junit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Tests that required a post M runtime.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE, ElementType.METHOD})
+public @interface MinRuntimeVersion {
+ RuntimeVersion value();
+}
+
diff --git a/jack-tests/src/com/android/jack/test/junit/RuntimeVersion.java b/jack-tests/src/com/android/jack/test/junit/RuntimeVersion.java
new file mode 100644
index 0000000..6a933a3
--- /dev/null
+++ b/jack-tests/src/com/android/jack/test/junit/RuntimeVersion.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.jack.test.junit;
+
+/**
+ * Runtime version.
+ */
+public enum RuntimeVersion {
+ D,
+ E,
+ F,
+ G,
+ H,
+ I,
+ J,
+ K,
+ L,
+ M,
+ N,
+ O
+}
+
diff --git a/jack-tests/src/com/android/jack/test/toolchain/AbstractTestTools.java b/jack-tests/src/com/android/jack/test/toolchain/AbstractTestTools.java
index b8b5dbe..5c1e34b 100644
--- a/jack-tests/src/com/android/jack/test/toolchain/AbstractTestTools.java
+++ b/jack-tests/src/com/android/jack/test/toolchain/AbstractTestTools.java
@@ -164,7 +164,8 @@
@Override
@Nonnull
public JackApiV01Toolchain build() {
- return new JackApiV01Toolchain(getPrebuilt("jack"));
+ File jackPrebuilt = isPrebuiltAvailable("jack") ? getPrebuilt("jack") : null;
+ return new JackApiV01Toolchain(jackPrebuilt);
}
}
@@ -173,7 +174,8 @@
@Override
@Nonnull
public JackApiV02IncrementalToolchain build() {
- return new JackApiV02IncrementalToolchain(getPrebuilt("jack"));
+ File jackPrebuilt = isPrebuiltAvailable("jack") ? getPrebuilt("jack") : null;
+ return new JackApiV02IncrementalToolchain(jackPrebuilt);
}
}
@@ -182,7 +184,8 @@
@Override
@Nonnull
public JackApiV02TwoStepsToolchain build() {
- return new JackApiV02TwoStepsToolchain(getPrebuilt("jack"));
+ File jackPrebuilt = isPrebuiltAvailable("jack") ? getPrebuilt("jack") : null;
+ return new JackApiV02TwoStepsToolchain(jackPrebuilt);
}
}
@@ -191,14 +194,15 @@
@Override
@Nonnull
public JackApiV02Toolchain build() {
- return new JackApiV02Toolchain(getPrebuilt("jack"));
+ File jackPrebuilt = isPrebuiltAvailable("jack") ? getPrebuilt("jack") : null;
+ return new JackApiV02Toolchain(jackPrebuilt);
}
}
private static class LegacyJillToolchainBuilder implements ToolchainBuilder {
@Override
- public IToolchain build() {
+ public LegacyJillToolchain build() {
return new LegacyJillToolchain(getPrebuilt("legacy-java-compiler"), getPrebuilt("jill"),
getPrebuilt("jack"), getPrebuilt("jarjar"), getPrebuilt("proguard"));
}
@@ -206,21 +210,30 @@
private static class JillApiV01ToolchainBuilder implements ToolchainBuilder {
-@Override
- public IToolchain build() {
- return new JillApiV01Toolchain(getPrebuilt("jill"), getPrebuilt("jack"),
+ @Override
+ public JillApiV01Toolchain build() {
+ File jillPrebuilt = isPrebuiltAvailable("jill") ? getPrebuilt("jill") : null;
+ return new JillApiV01Toolchain(jillPrebuilt, getPrebuilt("jack"),
getPrebuilt("legacy-java-compiler"), getPrebuilt("jarjar"), getPrebuilt("proguard"));
}
}
+ public static boolean isPrebuiltAvailable(@Nonnull String prebuiltName) {
+ return !getPrebuiltPath(prebuiltName).equals("");
+ }
+
+ @Nonnull
+ private static String getPrebuiltPath(@Nonnull String prebuiltName) {
+ return TestsProperties.getProperty(TOOLCHAIN_PREBUILT_PREFIX + prebuiltName).trim();
+ }
+
+ @Nonnull
public static File getPrebuilt(@Nonnull String prebuiltName) {
String prebuiltVarName = TOOLCHAIN_PREBUILT_PREFIX + prebuiltName;
- String prebuiltPath;
-
- prebuiltPath = TestsProperties.getProperty(prebuiltVarName);
+ String prebuiltPath = TestsProperties.getProperty(prebuiltVarName).trim();
if (prebuiltPath.equals("")) {
- throw new TestConfigurationException("Property '" + prebuiltVarName + "' is not set");
+ throw new AssertionError("Property '" + prebuiltVarName + "' is not set");
}
File result = new File(prebuiltPath);
@@ -761,14 +774,12 @@
printProperty(TOOLCHAIN_CANDIDATE_KEY);
printProperty(TOOLCHAIN_REFERENCE_KEY);
- String prebuiltPath = printProperty(TOOLCHAIN_PREBUILT_PREFIX + "jack");
- if (!prebuiltPath.equals("")) {
- System.out.println(TOOLCHAIN_PREBUILT_PREFIX + "jack.version = " + getVersion("jack"));
- }
- prebuiltPath = printProperty(TOOLCHAIN_PREBUILT_PREFIX + "jill");
- if (!prebuiltPath.equals("")) {
- System.out.println(TOOLCHAIN_PREBUILT_PREFIX + "jill.version = " + getVersion("jill"));
- }
+ printProperty(TOOLCHAIN_PREBUILT_PREFIX + "jack");
+ System.out.println(TOOLCHAIN_PREBUILT_PREFIX + "jack.version = " + getVersion("jack"));
+
+ printProperty(TOOLCHAIN_PREBUILT_PREFIX + "jill");
+ System.out.println(TOOLCHAIN_PREBUILT_PREFIX + "jill.version = " + getVersion("jill"));
+
printProperty(TOOLCHAIN_PREBUILT_PREFIX + "jarjar");
printProperty(TOOLCHAIN_PREBUILT_PREFIX + "proguard");
@@ -789,7 +800,7 @@
}
private static String printProperty(@Nonnull String propertyName) {
- String value = TestsProperties.getProperty(propertyName);
+ String value = TestsProperties.getProperty(propertyName).trim();
System.out.println(propertyName + " = " + value);
return value;
}
@@ -833,38 +844,60 @@
@Nonnull
private static String getVersion(@Nonnull String name) {
- File prebuilt = getPrebuilt(name);
+ String versionFileName = name + "-version.properties";
- if (prebuilt.getName().endsWith(".jar")) {
- JarFile jarFile = null;
- try {
- jarFile = new JarFile(prebuilt);
- ZipEntry entry = jarFile.getEntry(name + "-version.properties");
- InputStream is = jarFile.getInputStream(entry);
- Version version = new Version(is);
+ InputStream is = null;
+ JarFile jarFile = null;
- return version.getVerboseVersion();
+ try {
- } catch (IOException e) {
- throw new TestConfigurationException(e);
- } finally {
- if (jarFile != null) {
- try {
- jarFile.close();
- } catch (IOException e) {
- }
+ if (isPrebuiltAvailable(name)) {
+ File prebuilt = getPrebuilt(name);
+
+ if (prebuilt.getName().endsWith(".jar")) {
+
+ jarFile = new JarFile(prebuilt);
+ ZipEntry entry = jarFile.getEntry(name + "-version.properties");
+ is = jarFile.getInputStream(entry);
+ Version version = new Version(is);
+
+ return version.getVerboseVersion();
+
+ } else if (prebuilt.getName().endsWith("jack")) {
+ return getServerJackVersion(prebuilt);
+ } else {
+ System.err.println(
+ "Could not fetch version of prebuilt '" + name + "': '" + prebuilt.getName() + "'");
+ return "<unknown>";
+ }
+
+ } else {
+ is = AbstractTestTools.class.getClassLoader().getResourceAsStream(versionFileName);
+
+ if (is == null) {
+ throw new TestConfigurationException("Could not find '" + versionFileName + "'");
+ }
+
+ return new Version(is).getVerboseVersion() + " (found on classpath)";
+ }
+ } catch (IOException e) {
+ throw new TestConfigurationException(e);
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
}
}
- } else if (name.endsWith("jack")) {
- return getServerJackVersion(prebuilt);
- } else {
- System.err.println("Could not fetch version of prebuilt '" + name + "'");
- return "<unknown>";
+ if (jarFile != null) {
+ try {
+ jarFile.close();
+ } catch (IOException e) {
+ }
+ }
}
-
}
-
private static String getServerJackVersion(@Nonnull File jackScript) {
String[] arguments = new String[2];
diff --git a/jack-tests/src/com/android/jack/test/toolchain/JackApiToolchainBase.java b/jack-tests/src/com/android/jack/test/toolchain/JackApiToolchainBase.java
index 615e116..1550247 100644
--- a/jack-tests/src/com/android/jack/test/toolchain/JackApiToolchainBase.java
+++ b/jack-tests/src/com/android/jack/test/toolchain/JackApiToolchainBase.java
@@ -86,19 +86,40 @@
return compilerVersion;
}
- protected <T extends JackConfig> JackApiToolchainBase(@Nonnull File jackPrebuilt,
+ protected <T extends JackConfig> JackApiToolchainBase(@CheckForNull File jackPrebuilt,
@Nonnull Class<T> jackConfig) {
try {
- ClassLoader classLoader = URLClassLoader.newInstance(new URL[] {jackPrebuilt.toURI().toURL()},
- JackApiToolchainBase.class.getClassLoader());
- ServiceLoader<JackProvider> serviceLoader =
- ServiceLoader.load(JackProvider.class, classLoader);
+ ClassLoader classLoader = null;
+
+ ServiceLoader<JackProvider> serviceLoader;
+
+ if (jackPrebuilt != null) {
+ classLoader = URLClassLoader.newInstance(
+ new URL[] {jackPrebuilt.toURI().toURL()}, JackApiToolchainBase.class.getClassLoader());
+ serviceLoader = ServiceLoader.load(JackProvider.class, classLoader);
+ } else {
+ serviceLoader = ServiceLoader.load(JackProvider.class);
+ }
+
configProvider = serviceLoader.iterator().next();
+
+ if (jackPrebuilt != null && configProvider.getClass().getClassLoader() != classLoader) {
+ throw new TestConfigurationException("Jack compiler is not loaded from '" + jackPrebuilt
+ + "'. Unset jack prebuilt property in configuration file");
+ }
+
} catch (MalformedURLException e1) {
throw new TestConfigurationException(e1);
} catch (NoSuchElementException e) {
- throw new TestConfigurationException(e);
+ if (jackPrebuilt == null) {
+ throw new TestConfigurationException(
+ "JackProvider could not be loaded. Ensure Jack is present on classpath or prebuilt is"
+ + " specified in configuration file", e);
+ } else {
+ throw new TestConfigurationException(e);
+ }
+
}
assert configProvider != null;
diff --git a/jack-tests/src/com/android/jack/test/toolchain/JackApiV01Toolchain.java b/jack-tests/src/com/android/jack/test/toolchain/JackApiV01Toolchain.java
index ed00241..baf6808 100644
--- a/jack-tests/src/com/android/jack/test/toolchain/JackApiV01Toolchain.java
+++ b/jack-tests/src/com/android/jack/test/toolchain/JackApiV01Toolchain.java
@@ -37,6 +37,7 @@
import java.util.Collections;
import java.util.List;
+import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
/**
@@ -47,7 +48,7 @@
@Nonnull
private Api01Config apiV01Config;
- JackApiV01Toolchain(@Nonnull File jackPrebuilt) {
+ JackApiV01Toolchain(@CheckForNull File jackPrebuilt) {
super(jackPrebuilt, Api01Config.class);
apiV01Config = (Api01Config) config;
addProperty(Options.USE_DEFAULT_LIBRARIES.getName(), "false");
diff --git a/jack-tests/src/com/android/jack/test/toolchain/JackApiV02IncrementalToolchain.java b/jack-tests/src/com/android/jack/test/toolchain/JackApiV02IncrementalToolchain.java
index 97d74f5..044599b 100644
--- a/jack-tests/src/com/android/jack/test/toolchain/JackApiV02IncrementalToolchain.java
+++ b/jack-tests/src/com/android/jack/test/toolchain/JackApiV02IncrementalToolchain.java
@@ -20,6 +20,7 @@
import java.util.ArrayList;
import java.util.List;
+import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
/**
@@ -30,7 +31,7 @@
public class JackApiV02IncrementalToolchain
extends JackApiV02Toolchain implements IncrementalToolchain {
- JackApiV02IncrementalToolchain(@Nonnull File jackPrebuilt) {
+ JackApiV02IncrementalToolchain(@CheckForNull File jackPrebuilt) {
super(jackPrebuilt);
}
diff --git a/jack-tests/src/com/android/jack/test/toolchain/JillApiToolchainBase.java b/jack-tests/src/com/android/jack/test/toolchain/JillApiToolchainBase.java
index f0eafa4..fb2e3c5 100644
--- a/jack-tests/src/com/android/jack/test/toolchain/JillApiToolchainBase.java
+++ b/jack-tests/src/com/android/jack/test/toolchain/JillApiToolchainBase.java
@@ -57,22 +57,45 @@
private String compilerVersion;
- protected <T extends JillConfig> JillApiToolchainBase(@Nonnull File jillPrebuilt,
+ protected <T extends JillConfig> JillApiToolchainBase(@CheckForNull File jillPrebuilt,
@Nonnull File jackPrebuilt, @Nonnull Class<T> jillConfig, @Nonnull File refCompilerPrebuilt,
@Nonnull File jarjarPrebuilt, @Nonnull File proguardPrebuilt) {
- super(jillPrebuilt, jackPrebuilt, refCompilerPrebuilt, jarjarPrebuilt, proguardPrebuilt);
+ super(jackPrebuilt, refCompilerPrebuilt, jarjarPrebuilt, proguardPrebuilt);
if (configProvider == null) {
try {
- ClassLoader classLoader = URLClassLoader.newInstance(
- new URL[] {jillPrebuilt.toURI().toURL()}, JillApiToolchainBase.class.getClassLoader());
- ServiceLoader<JillProvider> serviceLoader =
- ServiceLoader.load(JillProvider.class, classLoader);
+ ClassLoader classLoader = null;
+
+ ServiceLoader<JillProvider> serviceLoader;
+
+ if (jillPrebuilt != null) {
+ classLoader = URLClassLoader.newInstance(
+ new URL[] {jillPrebuilt.toURI().toURL()},
+ JillApiToolchainBase.class.getClassLoader());
+ serviceLoader = ServiceLoader.load(JillProvider.class, classLoader);
+ } else {
+ serviceLoader = ServiceLoader.load(JillProvider.class);
+ }
+
configProvider = serviceLoader.iterator().next();
+
+ assert configProvider != null;
+
+ if (jillPrebuilt != null && configProvider.getClass().getClassLoader() != classLoader) {
+ throw new TestConfigurationException("Jill is not loaded from '" + jillPrebuilt
+ + "'. Unset jill prebuilt property in configuration file.");
+ }
+
} catch (MalformedURLException e1) {
throw new TestConfigurationException(e1);
} catch (NoSuchElementException e) {
- throw new TestConfigurationException(e);
+ if (jillPrebuilt == null) {
+ throw new TestConfigurationException(
+ "JillProvider could not be loaded. Ensure Jill is present on classpath or prebuilt"
+ + " is specified in configuration file", e);
+ } else {
+ throw new TestConfigurationException(e);
+ }
}
}
diff --git a/jack-tests/src/com/android/jack/test/toolchain/JillApiV01Toolchain.java b/jack-tests/src/com/android/jack/test/toolchain/JillApiV01Toolchain.java
index 15f3ef1..fdf7fe4 100644
--- a/jack-tests/src/com/android/jack/test/toolchain/JillApiV01Toolchain.java
+++ b/jack-tests/src/com/android/jack/test/toolchain/JillApiV01Toolchain.java
@@ -23,6 +23,7 @@
import java.io.File;
+import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
/**
@@ -33,7 +34,7 @@
@Nonnull
private Api01Config apiV01Config;
- JillApiV01Toolchain(@Nonnull File jillPrebuilt, @Nonnull File jackPrebuilt,
+ JillApiV01Toolchain(@CheckForNull File jillPrebuilt, @Nonnull File jackPrebuilt,
@Nonnull File refCompilerPrebuilt, @Nonnull File jarjarPrebuilt,
@Nonnull File proguardPrebuilt) {
super(jillPrebuilt, jackPrebuilt, Api01Config.class, refCompilerPrebuilt, jarjarPrebuilt,
diff --git a/jack-tests/src/com/android/jack/test/toolchain/JillBasedToolchain.java b/jack-tests/src/com/android/jack/test/toolchain/JillBasedToolchain.java
index b2a9648..7ace762 100644
--- a/jack-tests/src/com/android/jack/test/toolchain/JillBasedToolchain.java
+++ b/jack-tests/src/com/android/jack/test/toolchain/JillBasedToolchain.java
@@ -45,19 +45,16 @@
@Nonnull
private static final String RSC_DIR = "rsc";
@Nonnull
- protected File jillPrebuilt;
- @Nonnull
private File refCompilerPrebuilt;
@Nonnull
private File jarjarPrebuilt;
@Nonnull
private File proguardPrebuilt;
- JillBasedToolchain(@Nonnull File jillPrebuilt, @Nonnull File jackPrebuilt,
+ JillBasedToolchain(@Nonnull File jackPrebuilt,
@Nonnull File refCompilerPrebuilt, @Nonnull File jarjarPrebuilt,
@Nonnull File proguardPrebuilt) {
super(jackPrebuilt);
- this.jillPrebuilt = jillPrebuilt;
this.refCompilerPrebuilt = refCompilerPrebuilt;
this.jarjarPrebuilt = jarjarPrebuilt;
this.proguardPrebuilt = proguardPrebuilt;
diff --git a/jack-tests/src/com/android/jack/test/toolchain/LegacyJillToolchain.java b/jack-tests/src/com/android/jack/test/toolchain/LegacyJillToolchain.java
index f2ceacd..038657f 100644
--- a/jack-tests/src/com/android/jack/test/toolchain/LegacyJillToolchain.java
+++ b/jack-tests/src/com/android/jack/test/toolchain/LegacyJillToolchain.java
@@ -30,9 +30,13 @@
*/
public class LegacyJillToolchain extends JillBasedToolchain {
+ @Nonnull
+ private File jillPrebuilt;
+
public LegacyJillToolchain(@Nonnull File refCompilerPrebuilt, @Nonnull File jillPrebuilt,
@Nonnull File jackPrebuilt, @Nonnull File jarjarPrebuilt, @Nonnull File proguardPrebuilt) {
- super(jillPrebuilt, jackPrebuilt, refCompilerPrebuilt, jarjarPrebuilt, proguardPrebuilt);
+ super(jackPrebuilt, refCompilerPrebuilt, jarjarPrebuilt, proguardPrebuilt);
+ this.jillPrebuilt = jillPrebuilt;
}
@Override
diff --git a/jack-tests/tests/com/android/jack/AllTests.java b/jack-tests/tests/com/android/jack/AllTests.java
index 7842b68..4f40777 100644
--- a/jack-tests/tests/com/android/jack/AllTests.java
+++ b/jack-tests/tests/com/android/jack/AllTests.java
@@ -39,6 +39,8 @@
import com.android.jack.invoke.InvokeTests;
import com.android.jack.jarjar.JarjarTests;
import com.android.jack.java7.Java7AllTest;
+import com.android.jack.java8.Java8AllTest;
+import com.android.jack.java8.Java8AllTestPreN;
import com.android.jack.label.LabelTest;
import com.android.jack.library.LibraryTests;
import com.android.jack.lookup.LookupTests;
diff --git a/jack-tests/tests/com/android/jack/java8/DefaultMethodTest.java b/jack-tests/tests/com/android/jack/java8/DefaultMethodTest.java
index 43e4ceb..8aefce1 100644
--- a/jack-tests/tests/com/android/jack/java8/DefaultMethodTest.java
+++ b/jack-tests/tests/com/android/jack/java8/DefaultMethodTest.java
@@ -16,13 +16,6 @@
package com.android.jack.java8;
-import java.io.File;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.annotation.Nonnull;
-
import org.jf.dexlib.ClassDataItem.EncodedMethod;
import org.jf.dexlib.ClassDefItem;
import org.jf.dexlib.DexFile;
@@ -38,6 +31,13 @@
import com.android.jack.test.toolchain.JillBasedToolchain;
import com.android.jack.test.toolchain.Toolchain.SourceLevel;
+import java.io.File;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.annotation.Nonnull;
+
/**
* JUnit test for compilation of default method.
diff --git a/jack-tests/tests/com/android/jack/java8/EcjLambdaTest.java b/jack-tests/tests/com/android/jack/java8/EcjLambdaTest.java
index 963c665..155332f 100644
--- a/jack-tests/tests/com/android/jack/java8/EcjLambdaTest.java
+++ b/jack-tests/tests/com/android/jack/java8/EcjLambdaTest.java
@@ -60,7 +60,8 @@
@Override
public boolean shouldRun(Description description) {
if (testWithApiUsage.contains(description.getMethodName())
- || testWithOtherErrorMsg.contains(description.getMethodName())) {
+ || testWithOtherErrorMsg.contains(description.getMethodName())
+ || EcjLambdaTestPostM.testForNewRuntime.contains(description.getMethodName())) {
return false;
}
return true;
diff --git a/jack-tests/tests/com/android/jack/java8/EcjLambdaTestPostM.java b/jack-tests/tests/com/android/jack/java8/EcjLambdaTestPostM.java
new file mode 100644
index 0000000..7def70f
--- /dev/null
+++ b/jack-tests/tests/com/android/jack/java8/EcjLambdaTestPostM.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.jack.java8;
+
+import junit.framework.Assert;
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.Test;
+
+import org.junit.runner.Description;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.NoTestsRemainException;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+
+public class EcjLambdaTestPostM extends EcjLambdaTest {
+
+ public EcjLambdaTestPostM(@Nonnull String name) {
+ super(name);
+ }
+
+ public static final List<String> testForNewRuntime =
+ Arrays.asList("testReferenceExpressionInference1",
+ "testReferenceExpressionInference2",
+ "testReferenceExpressionInference3a",
+ "test425152",
+ "test431514",
+ "test431514a",
+ "test421712",
+ "test406744d");
+
+ public static class MyAdapter extends JUnit4TestAdapter {
+
+ public MyAdapter(Class<?> newTestClass) {
+ super(newTestClass);
+ try {
+ filter(new Filter() {
+ @Override
+ public boolean shouldRun(Description description) {
+ return testForNewRuntime.contains(description.getMethodName());
+ }
+
+ @Override
+ public String describe() {
+ return "EcjLambdaTestForNewRuntime";
+ }
+ });
+ } catch (NoTestsRemainException e) {
+ Assert.fail();
+ }
+ }
+ }
+
+ public static Test suite() {
+ return new MyAdapter(EcjLambdaTest.class);
+ }
+
+}
+
diff --git a/jack-tests/tests/com/android/jack/java8/GwtTest.java b/jack-tests/tests/com/android/jack/java8/GwtTest.java
index dc7efb1..35a4988 100644
--- a/jack-tests/tests/com/android/jack/java8/GwtTest.java
+++ b/jack-tests/tests/com/android/jack/java8/GwtTest.java
@@ -21,7 +21,6 @@
import javax.annotation.Nonnull;
import com.android.jack.test.helper.RuntimeTestHelper;
-import com.android.jack.test.junit.KnownIssue;
import com.android.jack.test.runtime.RuntimeTestInfo;
import com.android.jack.test.toolchain.AbstractTestTools;
import com.android.jack.test.toolchain.JackApiV01;
@@ -143,62 +142,6 @@
AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test027"),
"com.android.jack.java8.gwt.test027.jack.Java8Test");
- private RuntimeTestInfo GWT_LAMBDA_TEST_28 = new RuntimeTestInfo(
- AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test028"),
- "com.android.jack.java8.gwt.test028.jack.Java8Test");
-
- private RuntimeTestInfo GWT_LAMBDA_TEST_29 = new RuntimeTestInfo(
- AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test029"),
- "com.android.jack.java8.gwt.test029.jack.Java8Test");
-
- private RuntimeTestInfo GWT_LAMBDA_TEST_30 = new RuntimeTestInfo(
- AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test030"),
- "com.android.jack.java8.gwt.test030.jack.Java8Test");
-
- private RuntimeTestInfo GWT_LAMBDA_TEST_31 = new RuntimeTestInfo(
- AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test031"),
- "com.android.jack.java8.gwt.test031.jack.Java8Test");
-
- private RuntimeTestInfo GWT_LAMBDA_TEST_32 = new RuntimeTestInfo(
- AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test032"),
- "com.android.jack.java8.gwt.test032.jack.Java8Test");
-
- private RuntimeTestInfo GWT_LAMBDA_TEST_33 = new RuntimeTestInfo(
- AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test033"),
- "com.android.jack.java8.gwt.test033.jack.Java8Test");
-
- private RuntimeTestInfo GWT_LAMBDA_TEST_34 = new RuntimeTestInfo(
- AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test034"),
- "com.android.jack.java8.gwt.test034.jack.Java8Test");
-
- private RuntimeTestInfo GWT_LAMBDA_TEST_35 = new RuntimeTestInfo(
- AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test035"),
- "com.android.jack.java8.gwt.test035.jack.Java8Test");
-
- private RuntimeTestInfo GWT_LAMBDA_TEST_36 = new RuntimeTestInfo(
- AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test036"),
- "com.android.jack.java8.gwt.test036.jack.Java8Test");
-
- private RuntimeTestInfo GWT_LAMBDA_TEST_37 = new RuntimeTestInfo(
- AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test037"),
- "com.android.jack.java8.gwt.test037.jack.Java8Test");
-
- private RuntimeTestInfo GWT_LAMBDA_TEST_38 = new RuntimeTestInfo(
- AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test038"),
- "com.android.jack.java8.gwt.test038.jack.Java8Test");
-
- private RuntimeTestInfo GWT_LAMBDA_TEST_39 = new RuntimeTestInfo(
- AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test039"),
- "com.android.jack.java8.gwt.test039.jack.Java8Test");
-
- private RuntimeTestInfo GWT_LAMBDA_TEST_40 = new RuntimeTestInfo(
- AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test040"),
- "com.android.jack.java8.gwt.test040.jack.Java8Test");
-
- private RuntimeTestInfo GWT_LAMBDA_TEST_41 = new RuntimeTestInfo(
- AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test041"),
- "com.android.jack.java8.gwt.test041.jack.Java8Test");
-
private RuntimeTestInfo GWT_LAMBDA_TEST_42 = new RuntimeTestInfo(
AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test042"),
"com.android.jack.java8.gwt.test042.jack.Java8Test");
@@ -219,26 +162,6 @@
AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test046"),
"com.android.jack.java8.gwt.test046.jack.Java8Test");
- private RuntimeTestInfo GWT_LAMBDA_TEST_47 = new RuntimeTestInfo(
- AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test047"),
- "com.android.jack.java8.gwt.test047.jack.Java8Test");
-
- private RuntimeTestInfo GWT_LAMBDA_TEST_48 = new RuntimeTestInfo(
- AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test048"),
- "com.android.jack.java8.gwt.test048.jack.Java8Test");
-
- private RuntimeTestInfo GWT_LAMBDA_TEST_49 = new RuntimeTestInfo(
- AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test049"),
- "com.android.jack.java8.gwt.test049.jack.Java8Test");
-
- private RuntimeTestInfo GWT_LAMBDA_TEST_50 = new RuntimeTestInfo(
- AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test050"),
- "com.android.jack.java8.gwt.test050.jack.Java8Test");
-
- private RuntimeTestInfo GWT_LAMBDA_TEST_51 = new RuntimeTestInfo(
- AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test051"),
- "com.android.jack.java8.gwt.test051.jack.Java8Test");
-
@Test
public void testLambdaNoCapture() throws Exception {
run(GWT_LAMBDA_TEST_1);
@@ -375,77 +298,6 @@
}
@Test
- public void testDefaultInterfaceMethod() throws Exception {
- run(GWT_LAMBDA_TEST_28);
- }
-
- @Test
- @KnownIssue
- public void testDefaultInterfaceMethodVirtualUpRef() throws Exception {
- run(GWT_LAMBDA_TEST_29);
- }
-
- @Test
- public void DefaultInterfaceImplVirtualUpRefTwoInterfaces() throws Exception {
- run(GWT_LAMBDA_TEST_30);
- }
-
- @Test
- public void testDefenderMethodByInterfaceInstance() throws Exception {
- run(GWT_LAMBDA_TEST_31);
- }
-
- @Test
- public void testDefaultMethodReference() throws Exception {
- run(GWT_LAMBDA_TEST_32);
- }
-
- @Test
- public void testThisRefInDefenderMethod() throws Exception {
- run(GWT_LAMBDA_TEST_33);
- }
-
- @Test
- public void testClassImplementsTwoInterfacesWithSameDefenderMethod() throws Exception {
- run(GWT_LAMBDA_TEST_34);
- }
-
- @Test
- public void testAbstractClassImplementsInterface() throws Exception {
- run(GWT_LAMBDA_TEST_35);
- }
-
- @Test
- public void testSuperRefInDefenderMethod() throws Exception {
- run(GWT_LAMBDA_TEST_36);
- }
-
- @Test
- public void testSuperThisRefsInDefenderMethod() throws Exception {
- run(GWT_LAMBDA_TEST_37);
- }
-
- @Test
- public void testNestedInterfaceClass() throws Exception {
- run(GWT_LAMBDA_TEST_38);
- }
-
- @Test
- public void testBaseIntersectionCast() throws Exception {
- run(GWT_LAMBDA_TEST_39);
- }
-
- @Test
- public void testIntersectionCastWithLambdaExpr() throws Exception {
- run(GWT_LAMBDA_TEST_40);
- }
-
- @Test
- public void testIntersectionCastPolymorphism() throws Exception {
- run(GWT_LAMBDA_TEST_41);
- }
-
- @Test
public void testLambdaNestingInAnonymousCaptureLocal() throws Exception {
run(GWT_LAMBDA_TEST_42);
}
@@ -470,31 +322,6 @@
run(GWT_LAMBDA_TEST_46);
}
- @Test
- public void testMultipleDefaults_fromInterfaces_left() throws Exception {
- run(GWT_LAMBDA_TEST_47);
- }
-
- @Test
- public void testMultipleDefaults_fromInterfaces_right() throws Exception {
- run(GWT_LAMBDA_TEST_48);
- }
-
- @Test
- public void testMultipleDefaults_superclass_left() throws Exception {
- run(GWT_LAMBDA_TEST_49);
- }
-
- @Test
- public void testMultipleDefaults_superclass_right() throws Exception {
- run(GWT_LAMBDA_TEST_50);
- }
-
- @Test
- public void testInterfaceThis() throws Exception {
- run(GWT_LAMBDA_TEST_51);
- }
-
private void run(@Nonnull RuntimeTestInfo rti) throws Exception {
new RuntimeTestHelper(rti)
.setSourceLevel(SourceLevel.JAVA_8)
diff --git a/jack-tests/tests/com/android/jack/java8/GwtTestPostM.java b/jack-tests/tests/com/android/jack/java8/GwtTestPostM.java
new file mode 100644
index 0000000..1007c3f
--- /dev/null
+++ b/jack-tests/tests/com/android/jack/java8/GwtTestPostM.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.jack.java8;
+
+import com.android.jack.test.helper.RuntimeTestHelper;
+import com.android.jack.test.junit.KnownIssue;
+import com.android.jack.test.runtime.RuntimeTestInfo;
+import com.android.jack.test.toolchain.AbstractTestTools;
+import com.android.jack.test.toolchain.JillBasedToolchain;
+import com.android.jack.test.toolchain.Toolchain.SourceLevel;
+
+import org.junit.Test;
+
+import javax.annotation.Nonnull;
+
+
+
+/**
+ * JUnit test for Java 8 forked from GWT. These tests require a post N runtime.
+ */
+public class GwtTestPostM {
+
+ private RuntimeTestInfo GWT_LAMBDA_TEST_28 = new RuntimeTestInfo(
+ AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test028"),
+ "com.android.jack.java8.gwt.test028.jack.Java8Test");
+
+ private RuntimeTestInfo GWT_LAMBDA_TEST_29 = new RuntimeTestInfo(
+ AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test029"),
+ "com.android.jack.java8.gwt.test029.jack.Java8Test");
+
+ private RuntimeTestInfo GWT_LAMBDA_TEST_30 = new RuntimeTestInfo(
+ AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test030"),
+ "com.android.jack.java8.gwt.test030.jack.Java8Test");
+
+ private RuntimeTestInfo GWT_LAMBDA_TEST_31 = new RuntimeTestInfo(
+ AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test031"),
+ "com.android.jack.java8.gwt.test031.jack.Java8Test");
+
+ private RuntimeTestInfo GWT_LAMBDA_TEST_32 = new RuntimeTestInfo(
+ AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test032"),
+ "com.android.jack.java8.gwt.test032.jack.Java8Test");
+
+ private RuntimeTestInfo GWT_LAMBDA_TEST_33 = new RuntimeTestInfo(
+ AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test033"),
+ "com.android.jack.java8.gwt.test033.jack.Java8Test");
+
+ private RuntimeTestInfo GWT_LAMBDA_TEST_34 = new RuntimeTestInfo(
+ AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test034"),
+ "com.android.jack.java8.gwt.test034.jack.Java8Test");
+
+ private RuntimeTestInfo GWT_LAMBDA_TEST_35 = new RuntimeTestInfo(
+ AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test035"),
+ "com.android.jack.java8.gwt.test035.jack.Java8Test");
+
+ private RuntimeTestInfo GWT_LAMBDA_TEST_36 = new RuntimeTestInfo(
+ AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test036"),
+ "com.android.jack.java8.gwt.test036.jack.Java8Test");
+
+ private RuntimeTestInfo GWT_LAMBDA_TEST_37 = new RuntimeTestInfo(
+ AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test037"),
+ "com.android.jack.java8.gwt.test037.jack.Java8Test");
+
+ private RuntimeTestInfo GWT_LAMBDA_TEST_38 = new RuntimeTestInfo(
+ AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test038"),
+ "com.android.jack.java8.gwt.test038.jack.Java8Test");
+
+ private RuntimeTestInfo GWT_LAMBDA_TEST_39 = new RuntimeTestInfo(
+ AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test039"),
+ "com.android.jack.java8.gwt.test039.jack.Java8Test");
+
+ private RuntimeTestInfo GWT_LAMBDA_TEST_40 = new RuntimeTestInfo(
+ AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test040"),
+ "com.android.jack.java8.gwt.test040.jack.Java8Test");
+
+ private RuntimeTestInfo GWT_LAMBDA_TEST_41 = new RuntimeTestInfo(
+ AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test041"),
+ "com.android.jack.java8.gwt.test041.jack.Java8Test");
+
+ private RuntimeTestInfo GWT_LAMBDA_TEST_47 = new RuntimeTestInfo(
+ AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test047"),
+ "com.android.jack.java8.gwt.test047.jack.Java8Test");
+
+ private RuntimeTestInfo GWT_LAMBDA_TEST_48 = new RuntimeTestInfo(
+ AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test048"),
+ "com.android.jack.java8.gwt.test048.jack.Java8Test");
+
+ private RuntimeTestInfo GWT_LAMBDA_TEST_49 = new RuntimeTestInfo(
+ AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test049"),
+ "com.android.jack.java8.gwt.test049.jack.Java8Test");
+
+ private RuntimeTestInfo GWT_LAMBDA_TEST_50 = new RuntimeTestInfo(
+ AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test050"),
+ "com.android.jack.java8.gwt.test050.jack.Java8Test");
+
+ private RuntimeTestInfo GWT_LAMBDA_TEST_51 = new RuntimeTestInfo(
+ AbstractTestTools.getTestRootDir("com.android.jack.java8.gwt.test051"),
+ "com.android.jack.java8.gwt.test051.jack.Java8Test");
+
+ @Test
+ public void testDefaultInterfaceMethod() throws Exception {
+ run(GWT_LAMBDA_TEST_28);
+ }
+
+ @Test
+ @KnownIssue
+ public void testDefaultInterfaceMethodVirtualUpRef() throws Exception {
+ run(GWT_LAMBDA_TEST_29);
+ }
+
+ @Test
+ public void DefaultInterfaceImplVirtualUpRefTwoInterfaces() throws Exception {
+ run(GWT_LAMBDA_TEST_30);
+ }
+
+ @Test
+ public void testDefenderMethodByInterfaceInstance() throws Exception {
+ run(GWT_LAMBDA_TEST_31);
+ }
+
+ @Test
+ public void testDefaultMethodReference() throws Exception {
+ run(GWT_LAMBDA_TEST_32);
+ }
+
+ @Test
+ public void testThisRefInDefenderMethod() throws Exception {
+ run(GWT_LAMBDA_TEST_33);
+ }
+
+ @Test
+ public void testClassImplementsTwoInterfacesWithSameDefenderMethod() throws Exception {
+ run(GWT_LAMBDA_TEST_34);
+ }
+
+ @Test
+ public void testAbstractClassImplementsInterface() throws Exception {
+ run(GWT_LAMBDA_TEST_35);
+ }
+
+ @Test
+ public void testSuperRefInDefenderMethod() throws Exception {
+ run(GWT_LAMBDA_TEST_36);
+ }
+
+ @Test
+ public void testSuperThisRefsInDefenderMethod() throws Exception {
+ run(GWT_LAMBDA_TEST_37);
+ }
+
+ @Test
+ public void testNestedInterfaceClass() throws Exception {
+ run(GWT_LAMBDA_TEST_38);
+ }
+
+ @Test
+ public void testBaseIntersectionCast() throws Exception {
+ run(GWT_LAMBDA_TEST_39);
+ }
+
+ @Test
+ public void testIntersectionCastWithLambdaExpr() throws Exception {
+ run(GWT_LAMBDA_TEST_40);
+ }
+
+ @Test
+ public void testIntersectionCastPolymorphism() throws Exception {
+ run(GWT_LAMBDA_TEST_41);
+ }
+
+ @Test
+ public void testMultipleDefaults_fromInterfaces_left() throws Exception {
+ run(GWT_LAMBDA_TEST_47);
+ }
+
+ @Test
+ public void testMultipleDefaults_fromInterfaces_right() throws Exception {
+ run(GWT_LAMBDA_TEST_48);
+ }
+
+ @Test
+ public void testMultipleDefaults_superclass_left() throws Exception {
+ run(GWT_LAMBDA_TEST_49);
+ }
+
+ @Test
+ public void testMultipleDefaults_superclass_right() throws Exception {
+ run(GWT_LAMBDA_TEST_50);
+ }
+
+ @Test
+ public void testInterfaceThis() throws Exception {
+ run(GWT_LAMBDA_TEST_51);
+ }
+
+ private void run(@Nonnull RuntimeTestInfo rti) throws Exception {
+ new RuntimeTestHelper(rti)
+ .setSourceLevel(SourceLevel.JAVA_8)
+ .addIgnoredCandidateToolchain(JillBasedToolchain.class)
+ .compileAndRunTest();
+ }
+
+}
diff --git a/jack-tests/tests/com/android/jack/java8/IntersectionTypeTest.java b/jack-tests/tests/com/android/jack/java8/IntersectionTypeTest.java
index afb82c1..fbd6c7f 100644
--- a/jack-tests/tests/com/android/jack/java8/IntersectionTypeTest.java
+++ b/jack-tests/tests/com/android/jack/java8/IntersectionTypeTest.java
@@ -57,6 +57,10 @@
AbstractTestTools.getTestRootDir("com.android.jack.java8.intersectiontype.test005"),
"com.android.jack.java8.intersectiontype.test005.jack.Tests");
+ private RuntimeTestInfo INTERSECTION_TYPE_006 = new RuntimeTestInfo(
+ AbstractTestTools.getTestRootDir("com.android.jack.java8.intersectiontype.test006"),
+ "com.android.jack.java8.intersectiontype.test006.jack.Tests");
+
@Test
public void testIntersectionType001() throws Exception {
new RuntimeTestHelper(INTERSECTION_TYPE_001)
@@ -114,4 +118,14 @@
// Compilation error is ok
}
}
+
+ @Test
+ public void testIntersectionType006() throws Exception {
+ new RuntimeTestHelper(INTERSECTION_TYPE_006)
+ .setSourceLevel(SourceLevel.JAVA_8)
+ .addProperty(Options.LAMBDA_TO_ANONYMOUS_CONVERTER.getName(), Boolean.TRUE.toString())
+ .addIgnoredCandidateToolchain(JillBasedToolchain.class)
+ .addIgnoredCandidateToolchain(JackApiV01.class)
+ .compileAndRunTest();
+ }
}
diff --git a/jack-tests/tests/com/android/jack/java8/Java8AllTest.java b/jack-tests/tests/com/android/jack/java8/Java8AllTest.java
index 58c9837..70477f2 100644
--- a/jack-tests/tests/com/android/jack/java8/Java8AllTest.java
+++ b/jack-tests/tests/com/android/jack/java8/Java8AllTest.java
@@ -27,18 +27,8 @@
*/
@RunWith(JackTestRunner.class)
@SuiteClasses(value = {
- AnnotationTest.class,
- BridgeTest.class,
- DefaultMethodTest.class,
- EcjInterfaceMethodsTest.class,
- EcjLambdaTest.class,
- GwtTest.class,
- IntersectionTypeTest.class,
- LambdaTest.class,
- MethodRefTest.class,
- RetroLambdaTests.class,
- StaticMethodTest.class,
- TypeInferenceTest.class
+ Java8AllTestPreN.class,
+ Java8AllTestPostM.class
})
public class Java8AllTest {
}
diff --git a/jack-tests/tests/com/android/jack/java8/Java8AllTestPostM.java b/jack-tests/tests/com/android/jack/java8/Java8AllTestPostM.java
new file mode 100644
index 0000000..2f33a4b
--- /dev/null
+++ b/jack-tests/tests/com/android/jack/java8/Java8AllTestPostM.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.jack.java8;
+
+
+import com.android.jack.test.junit.JackTestRunner;
+import com.android.jack.test.junit.MinRuntimeVersion;
+import com.android.jack.test.junit.RuntimeVersion;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite.SuiteClasses;
+
+/**
+ * JUnit tests for compilation of Java 8 features which require a post M runtime.
+ */
+@RunWith(JackTestRunner.class)
+@SuiteClasses(value = {
+ DefaultMethodTest.class,
+ EcjInterfaceMethodsTest.class,
+ EcjLambdaTestPostM.class,
+ GwtTestPostM.class,
+ RetroLambdaTests.class,
+ StaticMethodTest.class,
+ })
+@MinRuntimeVersion(RuntimeVersion.N)
+public class Java8AllTestPostM {
+
+}
diff --git a/jack-tests/tests/com/android/jack/java8/Java8AllTestPreN.java b/jack-tests/tests/com/android/jack/java8/Java8AllTestPreN.java
new file mode 100644
index 0000000..922a462
--- /dev/null
+++ b/jack-tests/tests/com/android/jack/java8/Java8AllTestPreN.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.jack.java8;
+
+
+import com.android.jack.test.junit.JackTestRunner;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite.SuiteClasses;
+
+/**
+ * JUnit test for compilation of Java 8 features
+ */
+@RunWith(JackTestRunner.class)
+@SuiteClasses(value = {
+ AnnotationTest.class,
+ BridgeTest.class,
+ EcjLambdaTest.class,
+ GwtTest.class,
+ IntersectionTypeTest.class,
+ LambdaTest.class,
+ MethodRefTest.class,
+ TypeInferenceTest.class
+ })
+public class Java8AllTestPreN {
+}
diff --git a/jack-tests/tests/com/android/jack/java8/MethodRefTest.java b/jack-tests/tests/com/android/jack/java8/MethodRefTest.java
index e6f41c0..cfd74d7 100644
--- a/jack-tests/tests/com/android/jack/java8/MethodRefTest.java
+++ b/jack-tests/tests/com/android/jack/java8/MethodRefTest.java
@@ -69,6 +69,10 @@
AbstractTestTools.getTestRootDir("com.android.jack.java8.methodref.test009"),
"com.android.jack.java8.methodref.test009.jack.Tests");
+ private RuntimeTestInfo METHODREF010 = new RuntimeTestInfo(
+ AbstractTestTools.getTestRootDir("com.android.jack.java8.methodref.test010"),
+ "com.android.jack.java8.methodref.test010.jack.Tests");
+
@Test
public void testMethodRef001() throws Exception {
run(METHODREF001);
@@ -114,6 +118,11 @@
run(METHODREF009);
}
+ @Test
+ public void testMethodRef010() throws Exception {
+ run(METHODREF010);
+ }
+
private void run(@Nonnull RuntimeTestInfo rti) throws Exception {
new RuntimeTestHelper(rti)
.setSourceLevel(SourceLevel.JAVA_8)
diff --git a/jack-tests/tests/com/android/jack/java8/StaticMethodTest.java b/jack-tests/tests/com/android/jack/java8/StaticMethodTest.java
index 6d477cc..76210fc 100644
--- a/jack-tests/tests/com/android/jack/java8/StaticMethodTest.java
+++ b/jack-tests/tests/com/android/jack/java8/StaticMethodTest.java
@@ -28,6 +28,7 @@
import com.android.jack.test.toolchain.Toolchain.SourceLevel;
+
/**
* JUnit test for compilation of static method.
*/
diff --git a/jack-tests/tests/com/android/jack/java8/intersectiontype/test006/jack/Tests.java b/jack-tests/tests/com/android/jack/java8/intersectiontype/test006/jack/Tests.java
new file mode 100644
index 0000000..1f90fac
--- /dev/null
+++ b/jack-tests/tests/com/android/jack/java8/intersectiontype/test006/jack/Tests.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.jack.java8.intersectiontype.test006.jack;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+import java.io.Serializable;
+
+interface P<T> {
+ boolean check(T t);
+}
+
+
+public class Tests {
+
+ @Test
+ public void test() {
+ P<String> p = (P<String> & Serializable) s -> true;
+ Assert.assertTrue(p.check("abc"));
+ }
+}
diff --git a/jack-tests/tests/com/android/jack/java8/methodref/test010/jack/Tests.java b/jack-tests/tests/com/android/jack/java8/methodref/test010/jack/Tests.java
new file mode 100644
index 0000000..593d2f5
--- /dev/null
+++ b/jack-tests/tests/com/android/jack/java8/methodref/test010/jack/Tests.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.jack.java8.methodref.test010.jack;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+interface IntOp {
+ int apply(int i);
+}
+
+interface I {
+ char charAt0(String str);
+}
+
+/**
+ * Check that cast it correctly generated for the lambda representing string::charAt
+ */
+public class Tests {
+
+ public char test(IntOp op) {
+ return (char) op.apply(0);
+ }
+
+ @Test
+ public void test001() {
+ I i = string -> {
+ return test(string::charAt);
+ };
+ Assert.assertEquals('A', i.charAt0("ABC"));
+ }
+}
diff --git a/jack/src/com/android/jack/Jack.java b/jack/src/com/android/jack/Jack.java
index c34cc08..593c6cb 100644
--- a/jack/src/com/android/jack/Jack.java
+++ b/jack/src/com/android/jack/Jack.java
@@ -87,14 +87,11 @@
import com.android.jack.incremental.InputFilter;
import com.android.jack.ir.JackFormatIr;
import com.android.jack.ir.JavaSourceIr;
-import com.android.jack.ir.ast.JClass;
import com.android.jack.ir.ast.JDefinedClassOrInterface;
import com.android.jack.ir.ast.JField;
import com.android.jack.ir.ast.JMethod;
import com.android.jack.ir.ast.JPackage;
import com.android.jack.ir.ast.JSession;
-import com.android.jack.ir.ast.JType;
-import com.android.jack.ir.ast.JVisitor;
import com.android.jack.ir.formatter.InternalFormatter;
import com.android.jack.ir.formatter.TypePackageAndMethodFormatter;
import com.android.jack.ir.formatter.UserFriendlyFormatter;
@@ -107,7 +104,6 @@
import com.android.jack.library.LibraryIOException;
import com.android.jack.library.LibraryReadingException;
import com.android.jack.library.OutputJackLibrary;
-import com.android.jack.lookup.CommonTypes;
import com.android.jack.lookup.JPhantomLookup;
import com.android.jack.meta.LibraryMetaWriter;
import com.android.jack.meta.MetaImporter;
@@ -895,27 +891,6 @@
session.getReporter().report(Severity.FATAL, e);
throw new JackAbortException(e);
}
-
- if (options.flags != null && (options.flags.shrink() || options.flags.obfuscate())) {
- Event eventIdMerger = tracer.start(JackEventType.METHOD_ID_MERGER);
-
- try {
- JClass javaLangObject = session.getPhantomLookup().getClass(CommonTypes.JAVA_LANG_OBJECT);
- MethodIdMerger merger = new MethodIdMerger(javaLangObject);
- for (JType type : session.getTypesToEmit()) {
- merger.accept(type);
- }
- JVisitor remover = new VirtualMethodsMarker.Remover(javaLangObject);
- for (JType type : session.getTypesToEmit()) {
- remover.accept(type);
- }
- } finally {
- eventIdMerger.end();
- }
-
- MethodIdDuplicateRemover methodIdDupRemover = new MethodIdDuplicateRemover();
- methodIdDupRemover.accept(session.getTypesToEmit());
- }
}
private static void addPackageLoaderForLibrary(JSession session,
@@ -1032,6 +1007,14 @@
boolean hasSanityChecks = features.contains(SanityChecks.class);
// Build the plan
+ if (features.contains(Shrinking.class) || features.contains(Obfuscation.class)
+ || features.contains(MultiDexLegacy.class)) {
+ planBuilder.append(MethodIdMerger.class);
+ planBuilder.append(VirtualMethodsMarker.Remover.class);
+ planBuilder.appendSubPlan(JDefinedClassOrInterfaceAdapter.class)
+ .append(MethodIdDuplicateRemover.class);
+ }
+
if (hasSanityChecks) {
planBuilder.append(TypeDuplicateRemoverChecker.class);
}
diff --git a/jack/src/com/android/jack/JackAbortException.java b/jack/src/com/android/jack/JackAbortException.java
index ed1634b..70f1dcf 100644
--- a/jack/src/com/android/jack/JackAbortException.java
+++ b/jack/src/com/android/jack/JackAbortException.java
@@ -18,24 +18,35 @@
import com.android.jack.reporting.ReportableException;
+import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
/**
* A {@link RuntimeException} that should be fatal and cause Jack to abort. It should not be caught,
- * should have a cause {@link ReportableException} and no message.
+ * and should have no message.
+ * It can have a cause {@link ReportableException}
*/
public class JackAbortException extends RuntimeException {
private static final long serialVersionUID = 1L;
+ public JackAbortException() {
+
+ }
+
public JackAbortException(@Nonnull ReportableException cause) {
super(cause);
}
@Override
- @Nonnull
+ @CheckForNull
public String getMessage() {
- return getCause().getMessage();
+ Throwable cause = getCause();
+ if (cause != null) {
+ return cause.getMessage();
+ } else {
+ return null;
+ }
}
}
diff --git a/jack/src/com/android/jack/analysis/tracer/Tracer.java b/jack/src/com/android/jack/analysis/tracer/Tracer.java
index f89bd6d..307cdfa 100644
--- a/jack/src/com/android/jack/analysis/tracer/Tracer.java
+++ b/jack/src/com/android/jack/analysis/tracer/Tracer.java
@@ -17,6 +17,7 @@
package com.android.jack.analysis.tracer;
import com.android.jack.Jack;
+import com.android.jack.frontend.MethodIdDuplicateRemover.UniqMethodIds;
import com.android.jack.ir.ast.Annotable;
import com.android.jack.ir.ast.JAbstractMethodBody;
import com.android.jack.ir.ast.JAbstractStringLiteral;
@@ -65,6 +66,7 @@
import com.android.jack.shrob.shrink.PartialTypeHierarchy;
import com.android.sched.item.Description;
import com.android.sched.marker.LocalMarkerManager;
+import com.android.sched.schedulable.Constraint;
import com.android.sched.util.log.LoggerFactory;
import com.android.sched.util.log.TracerFactory;
@@ -78,6 +80,7 @@
* A visitor that traces dependencies
*/
@Description("traces dependencies")
+@Constraint(need = UniqMethodIds.class)
public class Tracer extends JVisitor {
@Nonnull
diff --git a/jack/src/com/android/jack/backend/dex/MainDexTracer.java b/jack/src/com/android/jack/backend/dex/MainDexTracer.java
index a8e06ff..9d2e81b 100644
--- a/jack/src/com/android/jack/backend/dex/MainDexTracer.java
+++ b/jack/src/com/android/jack/backend/dex/MainDexTracer.java
@@ -35,7 +35,7 @@
*/
@Description("Trace for main dex.")
@Constraint(need = ExtendingOrImplementingClassMarker.class)
-@Use(MultiDexLegacyTracerBrush.class)
+@Use({Tracer.class, MultiDexLegacyTracerBrush.class})
@Optional(@ToSupport(feature = SourceVersion8.class,
add = @Constraint(need = JAnnotation.RepeatedAnnotation.class)))
public class MainDexTracer implements RunnableSchedulable<JDefinedClassOrInterface> {
diff --git a/jack/src/com/android/jack/coverage/CodeCoverageMetadataFileWriter.java b/jack/src/com/android/jack/coverage/CodeCoverageMetadataFileWriter.java
index 7098460..0a8a5c9 100644
--- a/jack/src/com/android/jack/coverage/CodeCoverageMetadataFileWriter.java
+++ b/jack/src/com/android/jack/coverage/CodeCoverageMetadataFileWriter.java
@@ -61,6 +61,18 @@
@Produce(CodeCoverageMetadataFile.class)
public class CodeCoverageMetadataFileWriter implements RunnableSchedulable<JSession> {
+ /**
+ * The version of emitted JSON coverage information.
+ */
+ @Nonnull
+ private static final String VERSION = "1.0";
+
+ @Nonnull
+ private static final String JSON_VERSION_ATTRIBUTE = "version";
+
+ @Nonnull
+ private static final String JSON_DATA_ATTRIBUTE = "data";
+
@Nonnull
public static final PropertyId<OutputStreamFile> COVERAGE_METADATA_FILE = PropertyId.create(
"jack.coverage.metadata.file", "File where the coverage metadata will be emitted",
@@ -232,8 +244,7 @@
@Override
public void run(@Nonnull JSession session) throws Exception {
- OutputStreamFile outputFile = ThreadConfig.get(COVERAGE_METADATA_FILE);
- PrintStream writer = outputFile.getPrintStream();
+ PrintStream writer = ThreadConfig.get(COVERAGE_METADATA_FILE).getPrintStream();
try {
writeMetadata(session, writer);
} finally {
@@ -242,7 +253,13 @@
}
private void writeMetadata(@Nonnull JSession session, @Nonnull PrintStream writer) {
- writer.println('[');
+ writer.print("{ \"");
+ writer.print(JSON_VERSION_ATTRIBUTE);
+ writer.print("\":\"");
+ writer.print(VERSION);
+ writer.print("\", \"");
+ writer.print(JSON_DATA_ATTRIBUTE);
+ writer.println("\":[");
Iterator<JDefinedClassOrInterface> list = session.getTypesToEmit().iterator();
boolean first = true;
while (list.hasNext()) {
@@ -268,6 +285,7 @@
writer.println();
}
}
- writer.println(']');
+ writer.println("]}");
+ writer.flush();
}
}
diff --git a/jack/src/com/android/jack/frontend/MethodIdDuplicateRemover.java b/jack/src/com/android/jack/frontend/MethodIdDuplicateRemover.java
index 65cc08f..68c6cde 100644
--- a/jack/src/com/android/jack/frontend/MethodIdDuplicateRemover.java
+++ b/jack/src/com/android/jack/frontend/MethodIdDuplicateRemover.java
@@ -16,8 +16,11 @@
package com.android.jack.frontend;
+import com.android.jack.frontend.MethodIdDuplicateRemover.UniqMethodIds;
+import com.android.jack.frontend.MethodIdMerger.MethodIdMerged;
import com.android.jack.ir.ast.JAnnotation;
import com.android.jack.ir.ast.JClassOrInterface;
+import com.android.jack.ir.ast.JDefinedClassOrInterface;
import com.android.jack.ir.ast.JInterface;
import com.android.jack.ir.ast.JLambda;
import com.android.jack.ir.ast.JMethod;
@@ -28,59 +31,86 @@
import com.android.jack.ir.ast.JVisitor;
import com.android.jack.ir.ast.MethodKind;
import com.android.jack.lookup.JMethodWithReturnLookupException;
+import com.android.sched.item.Description;
+import com.android.sched.item.Name;
+import com.android.sched.item.Tag;
+import com.android.sched.schedulable.Constraint;
+import com.android.sched.schedulable.RunnableSchedulable;
+import com.android.sched.schedulable.Transform;
import java.util.Collection;
import javax.annotation.Nonnull;
/**
- * Update methodIds of {@link JMethodCall}s and {@link JNameValuePair}s.
+ * Update methodIds of {@link JMethodCall}s and {@link JNameValuePair}s so that they used the merged
+ * uniq ids.
*/
-public class MethodIdDuplicateRemover extends JVisitor {
+@Description("Update methodIds of JMethodCalls and JNameValuePairs so that they used the merged"
+ + " uniq ids")
+@Constraint(need = MethodIdMerged.class)
+@Transform(add = UniqMethodIds.class)
+public class MethodIdDuplicateRemover implements RunnableSchedulable<JDefinedClassOrInterface> {
- public MethodIdDuplicateRemover() {
- super(false /* needLoading */);
+ /**
+ * This tag means that Jack IR is using uniq JMethodIds.
+ */
+ @Description("Jack IR is using uniq JMethodIds")
+ @Name("UniqMethodIds")
+ public static class UniqMethodIds implements Tag {
}
- @Nonnull
- private JMethodId getResolvedMethodId(
- @Nonnull JClassOrInterface receiverType, @Nonnull JMethodId id) {
- Collection<JMethod> methods = id.getMethods();
- if (!methods.isEmpty()) {
- JMethod method = methods.iterator().next();
- return method.getMethodId();
- } else {
- return receiverType.getOrCreateMethodId(id.getName(), id.getParamTypes(), id.getKind());
+ private static class Visitor extends JVisitor {
+
+ private Visitor() {
+ super(false /* needLoading */);
+ }
+
+ @Nonnull
+ private JMethodId getResolvedMethodId(
+ @Nonnull JClassOrInterface receiverType, @Nonnull JMethodId id) {
+ Collection<JMethod> methods = id.getMethods();
+ if (!methods.isEmpty()) {
+ JMethod method = methods.iterator().next();
+ return method.getMethodId();
+ } else {
+ return receiverType.getOrCreateMethodId(id.getName(), id.getParamTypes(), id.getKind());
+ }
+ }
+
+ @Override
+ public boolean visit(@Nonnull JLambda lambda) {
+ JInterface lambdaType = lambda.getType();
+ try {
+ JMethodIdWithReturnType mthIdWithReturnType = lambda.getMethodIdToImplement();
+ JMethodId newMthId = lambdaType.getMethodId(mthIdWithReturnType.getName(),
+ mthIdWithReturnType.getParameterTypes(), MethodKind.INSTANCE_VIRTUAL);
+ mthIdWithReturnType.setMethodId(newMthId);
+ } catch (JMethodWithReturnLookupException e) {
+ throw new AssertionError();
+ }
+ return super.visit(lambda);
+ }
+
+ @Override
+ public boolean visit(@Nonnull JMethodCall call) {
+ JMethodId id = getResolvedMethodId(call.getReceiverType(), call.getMethodId());
+ call.resolveMethodId(id);
+ return super.visit(call);
+ }
+
+ @Override
+ public boolean visit(@Nonnull JAnnotation annotation) {
+ for (JNameValuePair pair : annotation.getNameValuePairs()) {
+ JMethodId id = getResolvedMethodId(annotation.getType(), pair.getMethodId());
+ pair.resolveMethodId(id);
+ }
+ return super.visit(annotation);
}
}
@Override
- public boolean visit(@Nonnull JLambda lambda) {
- JInterface lambdaType = lambda.getType();
- try {
- JMethodIdWithReturnType mthIdWithReturnType = lambda.getMethodIdToImplement();
- JMethodId newMthId = lambdaType.getMethodId(mthIdWithReturnType.getName(),
- mthIdWithReturnType.getParameterTypes(), MethodKind.INSTANCE_VIRTUAL);
- mthIdWithReturnType.setMethodId(newMthId);
- } catch (JMethodWithReturnLookupException e) {
- throw new AssertionError();
- }
- return super.visit(lambda);
- }
-
- @Override
- public boolean visit(@Nonnull JMethodCall call) {
- JMethodId id = getResolvedMethodId(call.getReceiverType(), call.getMethodId());
- call.resolveMethodId(id);
- return super.visit(call);
- }
-
- @Override
- public boolean visit(@Nonnull JAnnotation annotation) {
- for (JNameValuePair pair : annotation.getNameValuePairs()) {
- JMethodId id = getResolvedMethodId(annotation.getType(), pair.getMethodId());
- pair.resolveMethodId(id);
- }
- return super.visit(annotation);
+ public void run(JDefinedClassOrInterface type) throws Exception {
+ new Visitor().accept(type);
}
}
diff --git a/jack/src/com/android/jack/frontend/MethodIdMerger.java b/jack/src/com/android/jack/frontend/MethodIdMerger.java
index 622a607..82459db 100644
--- a/jack/src/com/android/jack/frontend/MethodIdMerger.java
+++ b/jack/src/com/android/jack/frontend/MethodIdMerger.java
@@ -16,6 +16,8 @@
package com.android.jack.frontend;
+import com.android.jack.Jack;
+import com.android.jack.frontend.MethodIdMerger.MethodIdMerged;
import com.android.jack.ir.ast.JClass;
import com.android.jack.ir.ast.JClassOrInterface;
import com.android.jack.ir.ast.JConstructor;
@@ -27,7 +29,14 @@
import com.android.jack.ir.ast.JMethodId;
import com.android.jack.ir.ast.JNode;
import com.android.jack.ir.ast.JPhantomClassOrInterface;
+import com.android.jack.ir.ast.JSession;
import com.android.jack.ir.ast.JVisitor;
+import com.android.jack.lookup.CommonTypes;
+import com.android.sched.item.Description;
+import com.android.sched.item.Name;
+import com.android.sched.item.Tag;
+import com.android.sched.schedulable.RunnableSchedulable;
+import com.android.sched.schedulable.Transform;
import java.util.Iterator;
@@ -37,140 +46,155 @@
/**
* Merges ids of {@link JMethod}s with the same name and arguments in the same hierarchy tree.
*/
-public class MethodIdMerger extends JVisitor {
-
- @Nonnull
- private final JClass javaLangObject;
-
- public MethodIdMerger(@Nonnull JClass javaLangObject) {
- this.javaLangObject = javaLangObject;
- }
-
- @Override
- public boolean visit(@Nonnull JDefinedClass node) {
- if (node.getMarker(VirtualMethodsMarker.class) != null) {
- return false;
- }
- handleDefinedClassOrInterface(node);
- return super.visit(node);
- }
-
- @Override
- public boolean visit(@Nonnull JDefinedInterface node) {
- if (node.getMarker(VirtualMethodsMarker.class) != null) {
- return false;
- }
- handleDefinedClassOrInterface(node);
- return super.visit(node);
- }
-
- @Override
- public boolean visit(@Nonnull JPhantomClassOrInterface node) {
- if (node.getMarker(VirtualMethodsMarker.class) != null) {
- return false;
- }
- ensureHierarchyVisited(node);
- return super.visit(node);
- }
-
- private void ensureHierarchyVisited(@Nonnull JClassOrInterface node) {
- JClass zuper = getSuper(node);
- if (zuper != null) {
- accept(zuper);
- }
- if (node instanceof JDefinedClassOrInterface) {
- for (JClassOrInterface interfaze : ((JDefinedClassOrInterface) node).getImplements()) {
- accept(interfaze);
- }
- }
- }
-
- private void handleDefinedClassOrInterface(@Nonnull JDefinedClassOrInterface node) {
- ensureHierarchyVisited(node);
-
- JClass zuper = getSuper(node);
- while (zuper instanceof JPhantomClassOrInterface) {
- zuper = getSuper(zuper);
- }
-
- VirtualMethodsMarker virtualMethods;
- if (zuper != null) {
- VirtualMethodsMarker superMarker = ((JNode) zuper).getMarker(VirtualMethodsMarker.class);
- assert superMarker != null;
- virtualMethods = superMarker.clone();
- } else {
- virtualMethods = new VirtualMethodsMarker();
- }
-
- for (JInterface interfaze : node.getImplements()) {
- if (interfaze instanceof JDefinedClassOrInterface) {
- addIds(virtualMethods, (JNode) interfaze);
- }
- }
-
- for (JMethod method : node.getMethods()) {
- if (((!method.isStatic()) && (!method.isPrivate()) && !(method instanceof JConstructor))) {
- addId(virtualMethods, method.getMethodId());
- }
- }
-
- node.addMarker(virtualMethods);
- }
-
- private void addIds(@Nonnull VirtualMethodsMarker mergeInto, @Nonnull JNode toMerge) {
- VirtualMethodsMarker methodsToMerge = toMerge.getMarker(VirtualMethodsMarker.class);
- assert methodsToMerge != null;
- for (JMethodId jMethodId : methodsToMerge) {
- addId(mergeInto, jMethodId);
- }
- }
-
- private void addId(@Nonnull VirtualMethodsMarker virtualMethods, @Nonnull JMethodId toAdd) {
- JMethodId existingMethod = virtualMethods.get(toAdd);
- if (existingMethod != null) {
- mergeId(existingMethod, toAdd);
- } else {
- virtualMethods.add(toAdd);
- }
- }
-
- private void mergeId(@Nonnull JMethodId keep, @Nonnull JMethodId duplicate) {
-
- keep = getKeptId(keep);
- duplicate = getKeptId(duplicate);
-
- if (keep == duplicate) {
- return;
- }
-
- for (JMethod method : duplicate.getMethods()) {
- method.setMethodId(keep);
- }
- }
+@Description("Merges ids of JMethods with the same name and arguments in the same hierarchy tree.")
+@Transform(add = {MethodIdMerged.class, VirtualMethodsMarker.class})
+public class MethodIdMerger implements RunnableSchedulable<JSession> {
/**
- * During the merge of {@link JMethodId} some are kept and some are dropped and because
- * {@link VirtualMethodsMarker} are not rewritten during merge, they contain dropped
- * {@code JMethodId}. This method retrieves the kept id from an id found in a
- * {@code VirtualMethodsMarker}
+ * This tag means that JMethodIds were merged when needed.
*/
- @Nonnull
- private JMethodId getKeptId(@Nonnull JMethodId possiblyDroppedId) {
- Iterator<JMethod> methods1 = possiblyDroppedId.getMethods().iterator();
- assert methods1.hasNext() :
- "Only method id contained in JMethod are considered by this visitor";
- return methods1.next().getMethodId();
+ @Description("JMethodId were merged")
+ @Name("MethodIdMerged")
+ public static class MethodIdMerged implements Tag {
}
- @CheckForNull
- private JClass getSuper(@Nonnull JClassOrInterface node) {
- if (node instanceof JDefinedClass) {
- return ((JDefinedClass) node).getSuperClass();
+ private static class Visitor extends JVisitor {
+
+ @Nonnull
+ private final JClass javaLangObject = Jack.getSession().getPhantomLookup()
+ .getClass(CommonTypes.JAVA_LANG_OBJECT);
+
+ @Override
+ public boolean visit(@Nonnull JDefinedClass node) {
+ if (node.getMarker(VirtualMethodsMarker.class) != null) {
+ return false;
+ }
+ handleDefinedClassOrInterface(node);
+ return super.visit(node);
}
- if (!node.isSameType(javaLangObject)) {
- return javaLangObject;
- } else {
- return null;
+
+ @Override
+ public boolean visit(@Nonnull JDefinedInterface node) {
+ if (node.getMarker(VirtualMethodsMarker.class) != null) {
+ return false;
+ }
+ handleDefinedClassOrInterface(node);
+ return super.visit(node);
}
+
+ @Override
+ public boolean visit(@Nonnull JPhantomClassOrInterface node) {
+ if (node.getMarker(VirtualMethodsMarker.class) != null) {
+ return false;
+ }
+ ensureHierarchyVisited(node);
+ return super.visit(node);
+ }
+
+ private void ensureHierarchyVisited(@Nonnull JClassOrInterface node) {
+ JClass zuper = getSuper(node);
+ if (zuper != null) {
+ accept(zuper);
+ }
+ if (node instanceof JDefinedClassOrInterface) {
+ for (JClassOrInterface interfaze : ((JDefinedClassOrInterface) node).getImplements()) {
+ accept(interfaze);
+ }
+ }
+ }
+
+ private void handleDefinedClassOrInterface(@Nonnull JDefinedClassOrInterface node) {
+ ensureHierarchyVisited(node);
+
+ JClass zuper = getSuper(node);
+ while (zuper instanceof JPhantomClassOrInterface) {
+ zuper = getSuper(zuper);
+ }
+
+ VirtualMethodsMarker virtualMethods;
+ if (zuper != null) {
+ VirtualMethodsMarker superMarker = ((JNode) zuper).getMarker(VirtualMethodsMarker.class);
+ assert superMarker != null;
+ virtualMethods = superMarker.clone();
+ } else {
+ virtualMethods = new VirtualMethodsMarker();
+ }
+
+ for (JInterface interfaze : node.getImplements()) {
+ if (interfaze instanceof JDefinedClassOrInterface) {
+ addIds(virtualMethods, (JNode) interfaze);
+ }
+ }
+
+ for (JMethod method : node.getMethods()) {
+ if (((!method.isStatic()) && (!method.isPrivate()) && !(method instanceof JConstructor))) {
+ addId(virtualMethods, method.getMethodId());
+ }
+ }
+
+ node.addMarker(virtualMethods);
+ }
+
+ private void addIds(@Nonnull VirtualMethodsMarker mergeInto, @Nonnull JNode toMerge) {
+ VirtualMethodsMarker methodsToMerge = toMerge.getMarker(VirtualMethodsMarker.class);
+ assert methodsToMerge != null;
+ for (JMethodId jMethodId : methodsToMerge) {
+ addId(mergeInto, jMethodId);
+ }
+ }
+
+ private void addId(@Nonnull VirtualMethodsMarker virtualMethods, @Nonnull JMethodId toAdd) {
+ JMethodId existingMethod = virtualMethods.get(toAdd);
+ if (existingMethod != null) {
+ mergeId(existingMethod, toAdd);
+ } else {
+ virtualMethods.add(toAdd);
+ }
+ }
+
+ private void mergeId(@Nonnull JMethodId keep, @Nonnull JMethodId duplicate) {
+
+ keep = getKeptId(keep);
+ duplicate = getKeptId(duplicate);
+
+ if (keep == duplicate) {
+ return;
+ }
+
+ for (JMethod method : duplicate.getMethods()) {
+ method.setMethodId(keep);
+ }
+ }
+
+ /**
+ * During the merge of {@link JMethodId} some are kept and some are dropped and because
+ * {@link VirtualMethodsMarker} are not rewritten during merge, they contain dropped
+ * {@code JMethodId}. This method retrieves the kept id from an id found in a
+ * {@code VirtualMethodsMarker}
+ */
+ @Nonnull
+ private JMethodId getKeptId(@Nonnull JMethodId possiblyDroppedId) {
+ Iterator<JMethod> methods1 = possiblyDroppedId.getMethods().iterator();
+ assert methods1.hasNext() :
+ "Only method id contained in JMethod are considered by this visitor";
+ return methods1.next().getMethodId();
+ }
+
+ @CheckForNull
+ private JClass getSuper(@Nonnull JClassOrInterface node) {
+ if (node instanceof JDefinedClass) {
+ return ((JDefinedClass) node).getSuperClass();
+ }
+ if (!node.isSameType(javaLangObject)) {
+ return javaLangObject;
+ } else {
+ return null;
+ }
+ }
+ }
+
+ @Override
+ public void run(JSession session) throws Exception {
+ new Visitor().accept(session.getTypesToEmit());
}
}
diff --git a/jack/src/com/android/jack/frontend/VirtualMethodsMarker.java b/jack/src/com/android/jack/frontend/VirtualMethodsMarker.java
index bcc4838..d3b7936 100644
--- a/jack/src/com/android/jack/frontend/VirtualMethodsMarker.java
+++ b/jack/src/com/android/jack/frontend/VirtualMethodsMarker.java
@@ -16,6 +16,7 @@
package com.android.jack.frontend;
+import com.android.jack.Jack;
import com.android.jack.ir.ast.JClass;
import com.android.jack.ir.ast.JClassOrInterface;
import com.android.jack.ir.ast.JDefinedClass;
@@ -23,11 +24,16 @@
import com.android.jack.ir.ast.JDefinedInterface;
import com.android.jack.ir.ast.JMethodId;
import com.android.jack.ir.ast.JPhantomClassOrInterface;
+import com.android.jack.ir.ast.JSession;
import com.android.jack.ir.ast.JType;
import com.android.jack.ir.ast.JVisitor;
+import com.android.jack.lookup.CommonTypes;
import com.android.sched.item.Description;
import com.android.sched.marker.Marker;
import com.android.sched.marker.ValidOn;
+import com.android.sched.schedulable.Constraint;
+import com.android.sched.schedulable.RunnableSchedulable;
+import com.android.sched.schedulable.Transform;
import java.util.HashMap;
import java.util.Iterator;
@@ -47,62 +53,72 @@
/**
* A remover for {@link VirtualMethodsMarker}
*/
- public static class Remover extends JVisitor {
+ @Description("Removes VirtualMethodsMarker")
+ @Transform(remove = VirtualMethodsMarker.class)
+ @Constraint(need = VirtualMethodsMarker.class)
+ public static class Remover implements RunnableSchedulable<JSession> {
+ private static class Visitor extends JVisitor {
- @Nonnull
- private final JClass javaLangObject;
+ @Nonnull
+ private final JClass javaLangObject = Jack.getSession().getPhantomLookup()
+ .getClass(CommonTypes.JAVA_LANG_OBJECT);
- public Remover(@Nonnull JClass javaLangObject) {
- super(false /* needLoading */);
- this.javaLangObject = javaLangObject;
- }
-
- @Override
- public boolean visit(@Nonnull JDefinedClass definedClass) {
- if (definedClass.removeMarker(VirtualMethodsMarker.class) != null) {
- ensureHierarchyVisited(definedClass);
+ private Visitor() {
+ super(false /* needLoading */);
}
- return false;
- }
- @Override
- public boolean visit(@Nonnull JDefinedInterface defineInterface) {
- if (defineInterface.removeMarker(VirtualMethodsMarker.class) != null) {
- ensureHierarchyVisited(defineInterface);
+ @Override
+ public boolean visit(@Nonnull JDefinedClass definedClass) {
+ if (definedClass.removeMarker(VirtualMethodsMarker.class) != null) {
+ ensureHierarchyVisited(definedClass);
+ }
+ return false;
}
- return false;
- }
- @Override
- public boolean visit(@Nonnull JPhantomClassOrInterface phantomClassOrInterface) {
- if (phantomClassOrInterface.removeMarker(VirtualMethodsMarker.class) != null) {
- ensureHierarchyVisited(phantomClassOrInterface);
+ @Override
+ public boolean visit(@Nonnull JDefinedInterface defineInterface) {
+ if (defineInterface.removeMarker(VirtualMethodsMarker.class) != null) {
+ ensureHierarchyVisited(defineInterface);
+ }
+ return false;
}
- return false;
- }
- private void ensureHierarchyVisited(@Nonnull JClassOrInterface node) {
- JClass zuper = getSuper(node);
- if (zuper != null) {
- accept(zuper);
+ @Override
+ public boolean visit(@Nonnull JPhantomClassOrInterface phantomClassOrInterface) {
+ if (phantomClassOrInterface.removeMarker(VirtualMethodsMarker.class) != null) {
+ ensureHierarchyVisited(phantomClassOrInterface);
+ }
+ return false;
}
- if (node instanceof JDefinedClassOrInterface) {
- for (JClassOrInterface interfaze : ((JDefinedClassOrInterface) node).getImplements()) {
- accept(interfaze);
+
+ private void ensureHierarchyVisited(@Nonnull JClassOrInterface node) {
+ JClass zuper = getSuper(node);
+ if (zuper != null) {
+ accept(zuper);
+ }
+ if (node instanceof JDefinedClassOrInterface) {
+ for (JClassOrInterface interfaze : ((JDefinedClassOrInterface) node).getImplements()) {
+ accept(interfaze);
+ }
+ }
+ }
+
+ @CheckForNull
+ private JClass getSuper(@Nonnull JClassOrInterface node) {
+ if (node instanceof JDefinedClass) {
+ return ((JDefinedClass) node).getSuperClass();
+ }
+ if (!node.isSameType(javaLangObject)) {
+ return javaLangObject;
+ } else {
+ return null;
}
}
}
- @CheckForNull
- private JClass getSuper(@Nonnull JClassOrInterface node) {
- if (node instanceof JDefinedClass) {
- return ((JDefinedClass) node).getSuperClass();
- }
- if (!node.isSameType(javaLangObject)) {
- return javaLangObject;
- } else {
- return null;
- }
+ @Override
+ public void run(JSession session) throws Exception {
+ new Visitor().accept(session.getTypesToEmit());
}
}
diff --git a/jack/src/com/android/jack/ir/ast/JSession.java b/jack/src/com/android/jack/ir/ast/JSession.java
index 5e2a4f6..c51809a 100644
--- a/jack/src/com/android/jack/ir/ast/JSession.java
+++ b/jack/src/com/android/jack/ir/ast/JSession.java
@@ -143,6 +143,7 @@
return phantomLookup;
}
+ @Deprecated
@Nonnull
public Logger getUserLogger() {
return userLogger;
diff --git a/jack/src/com/android/jack/ir/impl/JackIrBuilder.java b/jack/src/com/android/jack/ir/impl/JackIrBuilder.java
index 966b172..44e1d9f 100644
--- a/jack/src/com/android/jack/ir/impl/JackIrBuilder.java
+++ b/jack/src/com/android/jack/ir/impl/JackIrBuilder.java
@@ -1411,7 +1411,7 @@
boolean shouldCaptureInstance = isSuperRef || isThisRef;
exprRepresentingLambda = new JLambda(sourceInfo, methodIdToImplement, newMethodInfo.method,
- (JDefinedInterface) getTypeMap().get(referenceExpression.resolvedType),
+ (JDefinedInterface) getTypeMap().get(getLambdaType(referenceExpression, blockScope)),
shouldCaptureInstance, getInterfaceBounds(referenceExpression, blockScope));
((JLambda) exprRepresentingLambda).addBridgeMethodIds(getBridges(referenceExpression));
@@ -1477,7 +1477,8 @@
exprRepresentingLambda =
new JLambda(sourceInfo, methodIdToImplement, newMethodInfo.method,
- (JDefinedInterface) getTypeMap().get(referenceExpression.resolvedType),
+ (JDefinedInterface) getTypeMap()
+ .get(getLambdaType(referenceExpression, blockScope)),
/* captureInstance= */ false, getInterfaceBounds(referenceExpression, blockScope));
((JLambda) exprRepresentingLambda)
.addBridgeMethodIds(getBridges(referenceExpression));
@@ -1539,7 +1540,7 @@
JLambda lambda = new JLambda(sourceInfo,
getJMethodIdWithReturnType(referenceExpression.descriptor.original()),
newMethodInfo.method,
- (JDefinedInterface) getTypeMap().get(referenceExpression.resolvedType),
+ (JDefinedInterface) getTypeMap().get(getLambdaType(referenceExpression, blockScope)),
shouldCaptureInstance, getInterfaceBounds(referenceExpression, blockScope));
lambda.addBridgeMethodIds(getBridges(referenceExpression));
@@ -1733,7 +1734,7 @@
JLambda lambda = new JLambda(sourceInfo,
getJMethodIdWithReturnType(lambdaExpression.descriptor.original()),
lambdaMethodInfo.method,
- (JDefinedInterface) getTypeMap().get(lambdaExpression.resolvedType),
+ (JDefinedInterface) getTypeMap().get(getLambdaType(lambdaExpression, blockScope)),
lambdaExpression.shouldCaptureInstance, getInterfaceBounds(lambdaExpression, blockScope));
lambda.addBridgeMethodIds(getBridges(lambdaExpression));
@@ -1755,6 +1756,19 @@
}
@Nonnull
+ private TypeBinding getLambdaType(@Nonnull FunctionalExpression functionalExpression,
+ @Nonnull BlockScope blockScope) {
+ TypeBinding resolvedType = functionalExpression.resolvedType;
+
+ if (resolvedType instanceof IntersectionTypeBinding18) {
+ resolvedType = ((IntersectionTypeBinding18) resolvedType).getSAMType(blockScope);
+ }
+
+ assert resolvedType != null;
+ return resolvedType;
+ }
+
+ @Nonnull
private List<JInterface> getInterfaceBounds(
@Nonnull FunctionalExpression functionalExpression,
@Nonnull BlockScope blockScope) {
@@ -3154,9 +3168,7 @@
private JExpression maybeCast(JType expected, JExpression expression) {
if (!expected.isSameType(expression.getType())) {
- // Must be a generic; insert a cast operation.
- JReferenceType toType = (JReferenceType) expected;
- return new JDynamicCastOperation(expression.getSourceInfo(), expression, toType);
+ return new JDynamicCastOperation(expression.getSourceInfo(), expression, expected);
} else {
return expression;
}
diff --git a/jack/src/com/android/jack/shrob/obfuscation/MappingApplier.java b/jack/src/com/android/jack/shrob/obfuscation/MappingApplier.java
index 08b7852..ab372e2 100644
--- a/jack/src/com/android/jack/shrob/obfuscation/MappingApplier.java
+++ b/jack/src/com/android/jack/shrob/obfuscation/MappingApplier.java
@@ -20,6 +20,7 @@
import com.android.jack.Jack;
import com.android.jack.JackIOException;
+import com.android.jack.frontend.MethodIdDuplicateRemover.UniqMethodIds;
import com.android.jack.ir.ast.CanBeRenamed;
import com.android.jack.ir.ast.HasName;
import com.android.jack.ir.ast.JClassOrInterface;
@@ -39,6 +40,7 @@
import com.android.jack.transformations.request.TransformationRequest;
import com.android.jack.util.NamingTools;
import com.android.sched.marker.MarkerManager;
+import com.android.sched.schedulable.Constraint;
import com.android.sched.schedulable.Transform;
import com.android.sched.util.log.LoggerFactory;
@@ -58,6 +60,7 @@
* A class that parses a mapping file and rename the remapped nodes.
*/
@Transform(add = {OriginalNameMarker.class, OriginalPackageMarker.class, KeepNameMarker.class})
+@Constraint(need = UniqMethodIds.class)
public class MappingApplier {
@Nonnull
diff --git a/jack/src/com/android/jack/shrob/obfuscation/Renamer.java b/jack/src/com/android/jack/shrob/obfuscation/Renamer.java
index bd9835c..a71f38a 100644
--- a/jack/src/com/android/jack/shrob/obfuscation/Renamer.java
+++ b/jack/src/com/android/jack/shrob/obfuscation/Renamer.java
@@ -18,6 +18,7 @@
package com.android.jack.shrob.obfuscation;
import com.android.jack.Jack;
+import com.android.jack.frontend.MethodIdDuplicateRemover.UniqMethodIds;
import com.android.jack.ir.ast.CanBeRenamed;
import com.android.jack.ir.ast.HasName;
import com.android.jack.ir.ast.JClassOrInterface;
@@ -65,7 +66,8 @@
*/
@HasKeyId
@Description("Visitor that renames JNodes")
-@Constraint(need = {KeepNameMarker.class, OriginalNames.class}, no = FinalNames.class)
+@Constraint(need = {KeepNameMarker.class, OriginalNames.class, UniqMethodIds.class},
+ no = FinalNames.class)
@Transform(remove = OriginalNames.class,
add = {OriginalNameMarker.class, OriginalPackageMarker.class, FinalNames.class})
@Use(MappingApplier.class)
diff --git a/jack/src/com/android/jack/shrob/shrink/Keeper.java b/jack/src/com/android/jack/shrob/shrink/Keeper.java
index f9a8652..55d276f 100644
--- a/jack/src/com/android/jack/shrob/shrink/Keeper.java
+++ b/jack/src/com/android/jack/shrob/shrink/Keeper.java
@@ -36,7 +36,7 @@
*/
@Description("Marks all classes and members that will be kept when shrinking.")
@Constraint(need = {ExtendingOrImplementingClassMarker.class})
-@Use(KeeperBrush.class)
+@Use({Tracer.class, KeeperBrush.class})
@Optional(@ToSupport(feature = SourceVersion8.class,
add = @Constraint(need = JAnnotation.RepeatedAnnotation.class)))
public class Keeper implements RunnableSchedulable<JDefinedClassOrInterface> {
diff --git a/jack/src/com/android/jack/shrob/shrink/ShrinkAndMainDexTracer.java b/jack/src/com/android/jack/shrob/shrink/ShrinkAndMainDexTracer.java
index 3bffa40..707496a 100644
--- a/jack/src/com/android/jack/shrob/shrink/ShrinkAndMainDexTracer.java
+++ b/jack/src/com/android/jack/shrob/shrink/ShrinkAndMainDexTracer.java
@@ -38,7 +38,7 @@
*/
@Description("Trace for shrink and main dex.")
@Constraint(need = ExtendingOrImplementingClassMarker.class)
-@Use({KeeperBrush.class, MultiDexLegacyTracerBrush.class})
+@Use({Tracer.class, KeeperBrush.class, MultiDexLegacyTracerBrush.class})
@Optional(@ToSupport(feature = SourceVersion8.class,
add = @Constraint(need = JAnnotation.RepeatedAnnotation.class)))
public class ShrinkAndMainDexTracer implements RunnableSchedulable<JDefinedClassOrInterface> {