summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build.xml2
-rw-r--r--dx/src/com/android/jack/dx/dex/file/DexFile.java41
-rw-r--r--dx/src/com/android/jack/dx/io/DexBuffer.java40
-rw-r--r--dx/src/com/android/jack/dx/rop/cst/CstIndexMap.java23
-rw-r--r--dx/src/com/android/jack/dx/ssa/Optimizer.java11
-rw-r--r--jack-tests/.classpath2
-rw-r--r--jack-tests/tests/com/android/jack/frontend/FrontEndTests.java37
-rw-r--r--jack-tests/tests/com/android/jack/frontend/test011/jack/QualifedNew.java (renamed from jack-tests/tests/com/android/jack/frontend/test011/jack/UnusedLocalVar.java)2
-rw-r--r--jack-tests/tests/com/android/jack/frontend/test017/jack/InvalidQualification.java26
-rw-r--r--jack-tests/tests/com/android/jack/shrob/ShrinkTests.java52
-rw-r--r--jack/src/com/android/jack/Jack.java37
-rw-r--r--jack/src/com/android/jack/Options.java7
-rw-r--r--jack/src/com/android/jack/api/v01/impl/Api01ConfigImpl.java5
-rw-r--r--jack/src/com/android/jack/frontend/java/JAstBuilder.java3
-rw-r--r--jack/src/com/android/jack/incremental/GenerateLibraryFromIncrementalFolder.java (renamed from jack/src/com/android/jack/incremental/Incremental.java)6
-rw-r--r--jack/src/com/android/jack/incremental/IncrementalInputFilter.java19
-rw-r--r--jack/src/com/android/jack/ir/impl/JackIrBuilder.java137
-rw-r--r--jack/src/com/android/jack/ir/impl/SourceCompilationException.java27
-rw-r--r--jack/src/com/android/jack/reporting/CommonReporter.java29
-rw-r--r--jack/src/com/android/jack/reporting/DefaultReporter.java20
-rw-r--r--jack/src/com/android/jack/reporting/SdkReporter.java80
-rw-r--r--jack/src/com/android/jack/tools/merger/ConstantManager.java28
-rw-r--r--jack/src/com/android/jack/tools/merger/JackMerger.java3
-rw-r--r--sched/.settings/org.eclipse.jdt.core.prefs3
-rw-r--r--sched/src/com/android/sched/vfs/ReadWriteZipFS.java4
-rw-r--r--sched/src/com/android/sched/vfs/VFSToVFSWrapper.java6
-rw-r--r--sched/tests/com/android/sched/vfs/VFSTest.java1
27 files changed, 427 insertions, 224 deletions
diff --git a/build.xml b/build.xml
index 2c87c381..9e39464c 100644
--- a/build.xml
+++ b/build.xml
@@ -676,6 +676,7 @@
<exclude name="com/android/jack/frontend/test014/jack/ExtendingInnerInStaticContext.java"/>
<exclude name="com/android/jack/frontend/test015/jack/WithOuterContextButStatic.java"/>
<exclude name="com/android/jack/frontend/test016/jack/WithDuplicated.java"/>
+ <exclude name="com/android/jack/frontend/test017/jack/InvalidQualification.java"/>
<exclude name="com/android/jack/nopackage/jack/**"/>
<exclude name="com/android/jack/java7/boxing/**"/>
<exclude name="com/android/jack/java7/switches/**"/>
@@ -721,6 +722,7 @@
<exclude name="com/android/jack/frontend/test014/jack/ExtendingInnerInStaticContext.java"/>
<exclude name="com/android/jack/frontend/test015/jack/WithOuterContextButStatic.java"/>
<exclude name="com/android/jack/frontend/test016/jack/WithDuplicated.java"/>
+ <exclude name="com/android/jack/frontend/test017/jack/InvalidQualification.java"/>
<exclude name="com/android/jack/nopackage/jack/**"/>
<exclude name="com/android/jack/java7/boxing/**"/>
<exclude name="com/android/jack/java7/switches/**"/>
diff --git a/dx/src/com/android/jack/dx/dex/file/DexFile.java b/dx/src/com/android/jack/dx/dex/file/DexFile.java
index 2de5c9cc..c52ee124 100644
--- a/dx/src/com/android/jack/dx/dex/file/DexFile.java
+++ b/dx/src/com/android/jack/dx/dex/file/DexFile.java
@@ -22,7 +22,7 @@ import com.android.jack.dx.rop.cst.Constant;
import com.android.jack.dx.rop.cst.CstBaseMethodRef;
import com.android.jack.dx.rop.cst.CstEnumRef;
import com.android.jack.dx.rop.cst.CstFieldRef;
-import com.android.jack.dx.rop.cst.CstIndexMap;
+import com.android.jack.dx.rop.cst.CstMethodRef;
import com.android.jack.dx.rop.cst.CstString;
import com.android.jack.dx.rop.cst.CstType;
import com.android.jack.dx.rop.type.Type;
@@ -35,9 +35,11 @@ import java.io.Writer;
import java.security.DigestException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-import java.util.List;
+import java.util.Collection;
import java.util.zip.Adler32;
+import javax.annotation.Nonnull;
+
/**
* Representation of an entire {@code .dex} (Dalvik EXecutable)
* file, which itself consists of a set of Dalvik classes.
@@ -493,20 +495,39 @@ public final class DexFile {
* particular offsets.
*/
public void prepare() {
- prepare(null);
+ prepare(null, null, null, null);
}
/**
* Prepares this instance for writing. This performs any necessary prerequisites, including
* particularly adding stuff to other sections and places all the items in this instance at
* particular offsets.
- *
- * @param cstIndexMaps list used to map offsets from a dex file to this instance
- */
- public void prepare(List<CstIndexMap> cstIndexMaps) {
- if (cstIndexMaps != null) {
- for (CstIndexMap cstIndexMap : cstIndexMaps) {
- cstIndexMap.mergeConstantsIntoDexFile(this);
+ * @param cstStrings Collection of CstString to intern
+ * @param cstFieldRefs Collection of CstFieldRef to intern
+ * @param cstMethodRefs Collection of CstMethodRef to intern
+ * @param cstTypes Collection of CstType to intern
+ */
+ public void prepare(@Nonnull Collection<CstString> cstStrings,
+ @Nonnull Collection<CstFieldRef> cstFieldRefs,
+ @Nonnull Collection<CstMethodRef> cstMethodRefs, @Nonnull Collection<CstType> cstTypes) {
+ if (cstStrings != null) {
+ for (CstString cst : cstStrings) {
+ stringIds.intern(cst);
+ }
+ }
+ if (cstFieldRefs != null) {
+ for (CstFieldRef cst : cstFieldRefs) {
+ fieldIds.intern(cst);
+ }
+ }
+ if (cstMethodRefs != null) {
+ for (CstMethodRef cst : cstMethodRefs) {
+ methodIds.intern(cst);
+ }
+ }
+ if (cstTypes != null) {
+ for (CstType cst : cstTypes) {
+ typeIds.intern(cst);
}
}
diff --git a/dx/src/com/android/jack/dx/io/DexBuffer.java b/dx/src/com/android/jack/dx/io/DexBuffer.java
index 8f3c7c39..88840075 100644
--- a/dx/src/com/android/jack/dx/io/DexBuffer.java
+++ b/dx/src/com/android/jack/dx/io/DexBuffer.java
@@ -45,6 +45,9 @@ import java.util.NoSuchElementException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
+import javax.annotation.Nonnegative;
+import javax.annotation.Nonnull;
+
/**
* The bytes of a dex file in memory for reading and writing. All int offsets
* are unsigned.
@@ -64,7 +67,8 @@ public final class DexBuffer {
@Override
public ProtoId get(int index) {
checkBounds(index, tableOfContents.protoIds.size);
- return open(tableOfContents.protoIds.off + (SizeOf.PROTO_ID_ITEM * index)).readProtoId();
+ return openInternal(tableOfContents.protoIds.off + (SizeOf.PROTO_ID_ITEM * index))
+ .readProtoId();
}
@Override
@@ -77,11 +81,15 @@ public final class DexBuffer {
private final List<MethodId> methodIds;
+ @Nonnull
+ private final Section internalSection;
+
/**
* Creates a new dex buffer defining no classes.
*/
public DexBuffer() {
this.data = new byte[0];
+ this.internalSection = new Section(0);
this.strings = Collections.emptyList();
this.typeIds = Collections.emptyList();
this.typeNames = Collections.emptyList();
@@ -95,6 +103,7 @@ public final class DexBuffer {
*/
public DexBuffer(byte[] data) {
this.data = data;
+ this.internalSection = new Section(0);
this.length = data.length;
this.tableOfContents.readFrom(this);
this.strings = readStrings();
@@ -109,6 +118,7 @@ public final class DexBuffer {
*/
public DexBuffer(InputStream in) throws IOException {
loadFrom(in);
+ this.internalSection = new Section(0);
this.strings = readStrings();
this.typeIds = readTypeIds();
this.typeNames = readTypeNames(this.strings, this.typeIds);
@@ -135,6 +145,7 @@ public final class DexBuffer {
} else {
throw new DexException("unknown output extension: " + file);
}
+ this.internalSection = new Section(0);
this.strings = readStrings();
this.typeIds = readTypeIds();
this.typeNames = readTypeNames(this.strings, this.typeIds);
@@ -143,7 +154,7 @@ public final class DexBuffer {
}
private List<String> readStrings() {
- Section strings = open(tableOfContents.stringIds.off);
+ Section strings = openInternal(tableOfContents.stringIds.off);
String[] result = new String[tableOfContents.stringIds.size];
for (int i = 0; i < tableOfContents.stringIds.size; ++i) {
result[i] = strings.readString();
@@ -152,7 +163,7 @@ public final class DexBuffer {
}
private List<Integer> readTypeIds() {
- Section typeIds = open(tableOfContents.typeIds.off);
+ Section typeIds = openInternal(tableOfContents.typeIds.off);
Integer[] result = new Integer[tableOfContents.typeIds.size];
for (int i = 0; i < tableOfContents.typeIds.size; ++i) {
result[i] = Integer.valueOf(typeIds.readInt());
@@ -169,7 +180,7 @@ public final class DexBuffer {
}
private List<FieldId> readFieldIds() {
- Section fieldIds = open(tableOfContents.fieldIds.off);
+ Section fieldIds = openInternal(tableOfContents.fieldIds.off);
FieldId[] result = new FieldId[tableOfContents.fieldIds.size];
for (int i = 0; i < tableOfContents.fieldIds.size; ++i) {
result[i] = fieldIds.readFieldId();
@@ -178,7 +189,7 @@ public final class DexBuffer {
}
private List<MethodId> readMethodIds() {
- Section methodIds = open(tableOfContents.methodIds.off);
+ Section methodIds = openInternal(tableOfContents.methodIds.off);
MethodId[] result = new MethodId[tableOfContents.methodIds.size];
for (int i = 0; i < tableOfContents.methodIds.size; ++i) {
result[i] = methodIds.readMethodId();
@@ -221,6 +232,12 @@ public final class DexBuffer {
return tableOfContents;
}
+ @Nonnull
+ private Section openInternal(@Nonnegative int position) {
+ internalSection.initialPosition = internalSection.position = position;
+ return internalSection;
+ }
+
public Section open(int position) {
if (position < 0 || position > length) {
throw new IllegalArgumentException("position=" + position + " length=" + length);
@@ -313,7 +330,7 @@ public final class DexBuffer {
if (offset == 0) {
return TypeList.EMPTY;
}
- return open(offset).readTypeList();
+ return openInternal(offset).readTypeList();
}
public ClassData readClassData(ClassDef classDef) {
@@ -321,7 +338,7 @@ public final class DexBuffer {
if (offset == 0) {
throw new IllegalArgumentException("offset == 0");
}
- return open(offset).readClassData();
+ return openInternal(offset).readClassData();
}
public Code readCode(ClassData.Method method) {
@@ -329,7 +346,7 @@ public final class DexBuffer {
if (offset == 0) {
throw new IllegalArgumentException("offset == 0");
}
- return open(offset).readCode();
+ return openInternal(offset).readCode();
}
/**
@@ -339,7 +356,7 @@ public final class DexBuffer {
private final String name;
private int position;
private final int limit;
- private final int initialPosition;
+ private int initialPosition;
private Section(String name, int position, int limit) {
this.name = name;
@@ -496,10 +513,11 @@ public final class DexBuffer {
* Unfortunately they're in the opposite order in the dex file
* so we need to read them out-of-order.
*/
- Section triesSection = open(position);
+ int savedPosition = position;
skip(triesSize * SizeOf.TRY_ITEM);
catchHandlers = readCatchHandlers();
- tries = triesSection.readTries(triesSize, catchHandlers);
+ position = savedPosition;
+ tries = readTries(triesSize, catchHandlers);
} else {
tries = new Try[0];
catchHandlers = new CatchHandler[0];
diff --git a/dx/src/com/android/jack/dx/rop/cst/CstIndexMap.java b/dx/src/com/android/jack/dx/rop/cst/CstIndexMap.java
index c4ec624b..9f29bf9f 100644
--- a/dx/src/com/android/jack/dx/rop/cst/CstIndexMap.java
+++ b/dx/src/com/android/jack/dx/rop/cst/CstIndexMap.java
@@ -98,29 +98,6 @@ public class CstIndexMap {
}
/**
- * Merge all {@link TypedConstant} of one dex file into another.
- * @param dex The dex file where values are merged.
- */
- public void mergeConstantsIntoDexFile(DexFile dex) {
- for (CstString cst : strings) {
- dex.getStringIds().intern(cst);
- }
-
- for (CstBaseMethodRef cst : methods) {
- dex.getMethodIds().intern(cst);
- }
-
- for (CstFieldRef cst : fields) {
- dex.getFieldIds().intern(cst);
- }
-
- for (CstType cst : types) {
- dex.getTypeIds().intern(cst);
- }
- }
-
-
- /**
* Return the remapped index of a {@code CstString} into {@code file}.
* @param file The file where the remapped index apply to.
* @param index The old index to remap into {@code file}.
diff --git a/dx/src/com/android/jack/dx/ssa/Optimizer.java b/dx/src/com/android/jack/dx/ssa/Optimizer.java
index 7101be01..c690fd7d 100644
--- a/dx/src/com/android/jack/dx/ssa/Optimizer.java
+++ b/dx/src/com/android/jack/dx/ssa/Optimizer.java
@@ -147,30 +147,21 @@ public class Optimizer {
}
private static void runSsaFormSteps(SsaMethod ssaMeth, EnumSet<OptionalStep> steps) {
- boolean needsDeadCodeRemover = true;
if (steps.contains(OptionalStep.SCCP)) {
SCCP.process(ssaMeth);
- DeadCodeRemover.process(ssaMeth);
- needsDeadCodeRemover = false;
}
if (steps.contains(OptionalStep.LITERAL_UPGRADE)) {
LiteralOpUpgrader.process(ssaMeth);
- DeadCodeRemover.process(ssaMeth);
- needsDeadCodeRemover = false;
}
if (steps.contains(OptionalStep.CONST_COLLECTOR)) {
ConstCollector.process(ssaMeth);
- DeadCodeRemover.process(ssaMeth);
- needsDeadCodeRemover = false;
}
// dead code remover must be run before phi type resolver
- if (needsDeadCodeRemover) {
- DeadCodeRemover.process(ssaMeth);
- }
+ DeadCodeRemover.process(ssaMeth);
PhiTypeResolver.process(ssaMeth);
}
diff --git a/jack-tests/.classpath b/jack-tests/.classpath
index 03ac40ae..e451b2d9 100644
--- a/jack-tests/.classpath
+++ b/jack-tests/.classpath
@@ -2,7 +2,7 @@
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
- <classpathentry excluding="com/android/jack/classpath/test002/lib1override/|com/android/jack/compiletime/test*/**|com/android/jack/enums/test003/link/Other.java|com/android/jack/enums/test003/link/Values.java|com/android/jack/error/test001/jack/A.java|com/android/jack/error/test002/jack/A.java|com/android/jack/jarjar/test003/dontcompile/|com/android/jack/java7/boxing/|com/android/jack/java7/exceptions/|com/android/jack/java7/parser/|com/android/jack/java7/switches/|com/android/jack/java7/trywithresources/|com/android/jack/lookup/test001/liboverride/|com/android/jack/nopackage/test*/**|com/android/jack/frontend/test002/jack/PackageName/ClassInConflictingPackage.java|com/android/jack/frontend/test005/jack/|com/android/jack/frontend/test006/jack/|com/android/jack/frontend/test007/jack/|com/android/jack/frontend/test007/jackduplicate/|com/android/jack/frontend/test008/jack/NoOuterContext.java|com/android/jack/frontend/test010/jack/UnusedLocalVar.java|com/android/jack/frontend/test013/jack/ExtendingInnerOnly.java|com/android/jack/frontend/test014/jack/ExtendingInnerInStaticContext.java|com/android/jack/frontend/test015/jack/WithOuterContextButStatic.java|com/android/jack/frontend/test016/jack/WithDuplicated.java" kind="src" path="tests"/>
+ <classpathentry excluding="com/android/jack/classpath/test002/lib1override/|com/android/jack/compiletime/test*/**|com/android/jack/enums/test003/link/Other.java|com/android/jack/enums/test003/link/Values.java|com/android/jack/error/test001/jack/A.java|com/android/jack/error/test002/jack/A.java|com/android/jack/jarjar/test003/dontcompile/|com/android/jack/java7/boxing/|com/android/jack/java7/exceptions/|com/android/jack/java7/parser/|com/android/jack/java7/switches/|com/android/jack/java7/trywithresources/|com/android/jack/lookup/test001/liboverride/|com/android/jack/nopackage/test*/**|com/android/jack/frontend/test002/jack/PackageName/ClassInConflictingPackage.java|com/android/jack/frontend/test005/jack/|com/android/jack/frontend/test006/jack/|com/android/jack/frontend/test007/jack/|com/android/jack/frontend/test007/jackduplicate/|com/android/jack/frontend/test008/jack/NoOuterContext.java|com/android/jack/frontend/test010/jack/UnusedLocalVar.java|com/android/jack/frontend/test013/jack/ExtendingInnerOnly.java|com/android/jack/frontend/test014/jack/ExtendingInnerInStaticContext.java|com/android/jack/frontend/test015/jack/WithOuterContextButStatic.java|com/android/jack/frontend/test016/jack/WithDuplicated.java|com/android/jack/frontend/test017/jack/InvalidQualification.java" kind="src" path="tests"/>
<classpathentry kind="lib" path="libs/junit4.jar"/>
<classpathentry kind="lib" path="libs/antlr-runtime-lib.jar"/>
<classpathentry kind="lib" path="libs/dx-ref.jar"/>
diff --git a/jack-tests/tests/com/android/jack/frontend/FrontEndTests.java b/jack-tests/tests/com/android/jack/frontend/FrontEndTests.java
index 875a4b6f..aec76594 100644
--- a/jack-tests/tests/com/android/jack/frontend/FrontEndTests.java
+++ b/jack-tests/tests/com/android/jack/frontend/FrontEndTests.java
@@ -16,6 +16,7 @@
package com.android.jack.frontend;
+import com.android.jack.Options;
import com.android.jack.category.ExtraTests;
import com.android.jack.test.category.KnownBugs;
import com.android.jack.test.toolchain.AbstractTestTools;
@@ -78,6 +79,7 @@ public class FrontEndTests {
ByteArrayOutputStream err = new ByteArrayOutputStream();
toolchain.setOutputStream(out);
toolchain.setErrorStream(err);
+ toolchain.addProperty(Options.INPUT_FILTER.getName(), "ordered-filter");
try {
toolchain.addToClasspath(toolchain.getDefaultBootClasspath())
@@ -333,12 +335,11 @@ public class FrontEndTests {
*/
@Test
@Category(ExtraTests.class)
- public void testUnusedLocalVar002() throws Exception {
+ public void testQualifedNew001() throws Exception {
File outDir = AbstractTestTools.createTempDir();
IToolchain toolchain = AbstractTestTools.getCandidateToolchain();
-
- toolchain.addToClasspath(toolchain.getDefaultBootClasspath())
+ toolchain.addToClasspath(toolchain.getDefaultBootClasspath())
.srcToLib(
outDir,
/* zipFiles= */ false,
@@ -362,4 +363,34 @@ public class FrontEndTests {
AbstractTestTools.getTestRootDir("com.android.jack.frontend.test012.jack"));
}
+ /**
+ * Test that Jack is neither failing nor dropping the error in this case.
+ */
+ @Test
+ @Category(ExtraTests.class)
+ public void testUnusedLocalVar004() throws Exception {
+ File outDir = AbstractTestTools.createTempDir();
+
+ IToolchain toolchain =
+ AbstractTestTools.getCandidateToolchain(JackApiToolchainBase.class);
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ByteArrayOutputStream err = new ByteArrayOutputStream();
+ toolchain.setOutputStream(out);
+ toolchain.setErrorStream(err);
+
+ try {
+ toolchain.addToClasspath(toolchain.getDefaultBootClasspath())
+ .srcToLib(
+ outDir,
+ /* zipFiles= */ false,
+ AbstractTestTools.getTestRootDir("com.android.jack.frontend.test017.jack"));
+ Assert.fail();
+ } catch (FrontendCompilationException e) {
+ Assert.assertEquals(0, out.size());
+ String errString = err.toString();
+ Assert.assertTrue(errString.contains("ERROR:"));
+ Assert.assertTrue(errString.contains("InvalidQualification"));
+ }
+ }
+
}
diff --git a/jack-tests/tests/com/android/jack/frontend/test011/jack/UnusedLocalVar.java b/jack-tests/tests/com/android/jack/frontend/test011/jack/QualifedNew.java
index 6abaebf8..9fecd3d7 100644
--- a/jack-tests/tests/com/android/jack/frontend/test011/jack/UnusedLocalVar.java
+++ b/jack-tests/tests/com/android/jack/frontend/test011/jack/QualifedNew.java
@@ -16,7 +16,7 @@
package com.android.jack.frontend.test011.jack;
-public class UnusedLocalVar extends ClassWithInner {
+public class QualifedNew extends ClassWithInner {
public Object get() {
ClassWithInner outer = new ClassWithInner();
diff --git a/jack-tests/tests/com/android/jack/frontend/test017/jack/InvalidQualification.java b/jack-tests/tests/com/android/jack/frontend/test017/jack/InvalidQualification.java
new file mode 100644
index 00000000..1443c8a1
--- /dev/null
+++ b/jack-tests/tests/com/android/jack/frontend/test017/jack/InvalidQualification.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 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.frontend.test017.jack;
+
+public class InvalidQualification {
+
+ public static InvalidQualification get() {
+ InvalidQualification unused = new InvalidQualification();
+ return unused.new InvalidQualification();
+ }
+
+}
diff --git a/jack-tests/tests/com/android/jack/shrob/ShrinkTests.java b/jack-tests/tests/com/android/jack/shrob/ShrinkTests.java
index 6ffa637c..c5fcfd6a 100644
--- a/jack-tests/tests/com/android/jack/shrob/ShrinkTests.java
+++ b/jack-tests/tests/com/android/jack/shrob/ShrinkTests.java
@@ -85,6 +85,58 @@ public class ShrinkTests extends AbstractTest {
candidateNodeListing));
}
+ private void runTestWithLib(@Nonnull String testNumber, @Nonnull String flagNumber,
+ boolean importLib) throws Exception {
+ File testFolder = new File(shrobTestsDir, "test" + testNumber);
+
+ File libOut = AbstractTestTools.createTempDir();
+ JackApiToolchainBase toolchainLib =
+ AbstractTestTools.getCandidateToolchain(JackApiToolchainBase.class);
+ toolchainLib.addToClasspath(toolchainLib.getDefaultBootClasspath()).srcToLib(libOut,
+ /* zipFiles = */false, new File(shrobTestsDir, "test" + testNumber + "/lib"));
+
+ JackBasedToolchain toolchain =
+ AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class);
+
+ File refFolder = new File(testFolder, "refsShrinking");
+
+ File candidateNodeListing = AbstractTestTools.createTempFile("nodeListing", ".txt");
+ toolchain.addProperty(ShrinkStructurePrinter.STRUCTURE_PRINTING.getName(), "true");
+ toolchain.addProperty(ShrinkStructurePrinter.STRUCTURE_PRINTING_FILE.getName(),
+ candidateNodeListing.getPath());
+ toolchain.addProperty(Options.METHOD_FILTER.getName(), "supported-methods");
+ toolchain.disableDxOptimizations();
+ if (importLib) {
+ toolchain.addStaticLibs(libOut);
+ } else {
+ toolchain.addToClasspath(libOut);
+ }
+
+ File outFolder = AbstractTestTools.createTempDir();
+
+ SourceToDexComparisonTestHelper env =
+ new SourceToDexComparisonTestHelper(new File(testFolder, "jack"));
+
+ env.setWithDebugInfo(true);
+ env.setCandidateTestTools(toolchain);
+ env.setReferenceTestTools(new DummyToolchain());
+ env.setProguardFlags(dontObfuscateFlagFile,
+ new ProguardFlags(testFolder, "proguard.flags" + flagNumber));
+
+ env.runTest(new ComparatorMapping(new File(refFolder, "expected-" + flagNumber + ".txt"),
+ candidateNodeListing));
+ }
+
+ @Test
+ public void test003_001() throws Exception {
+ runTestWithLib("003", "001", false);
+ }
+
+ @Test
+ public void test003_002() throws Exception {
+ runTestWithLib("003", "002", true);
+ }
+
@Test
public void test020() throws Exception {
File libOut = AbstractTestTools.createTempDir();
diff --git a/jack/src/com/android/jack/Jack.java b/jack/src/com/android/jack/Jack.java
index aba7be93..7f4fd581 100644
--- a/jack/src/com/android/jack/Jack.java
+++ b/jack/src/com/android/jack/Jack.java
@@ -69,7 +69,7 @@ import com.android.jack.frontend.VirtualMethodsMarker;
import com.android.jack.frontend.java.JackBatchCompiler;
import com.android.jack.frontend.java.JackBatchCompiler.TransportExceptionAroundEcjError;
import com.android.jack.frontend.java.JackBatchCompiler.TransportJUEAroundEcjError;
-import com.android.jack.incremental.Incremental;
+import com.android.jack.incremental.GenerateLibraryFromIncrementalFolder;
import com.android.jack.ir.JackFormatIr;
import com.android.jack.ir.JavaSourceIr;
import com.android.jack.ir.ast.JClass;
@@ -265,8 +265,6 @@ import com.android.sched.util.log.LoggerFactory;
import com.android.sched.util.log.Tracer;
import com.android.sched.util.log.TracerFactory;
import com.android.sched.vfs.Container;
-import com.android.sched.vfs.VFS;
-import com.android.sched.vfs.VFSToVFSWrapper;
import org.antlr.runtime.RecognitionException;
@@ -517,8 +515,8 @@ public abstract class Jack {
if (config.get(MultiDexLegacy.MULTIDEX_LEGACY).booleanValue()) {
request.addFeature(MultiDexLegacy.class);
}
- if (config.get(Options.INCREMENTAL_MODE).booleanValue()) {
- request.addFeature(Incremental.class);
+ if (config.get(Options.GENERATE_LIBRARY_FROM_INCREMENTAL_FOLDER).booleanValue()) {
+ request.addFeature(GenerateLibraryFromIncrementalFolder.class);
}
request.addInitialTagsOrMarkers(getJavaSourceInitialTagSet());
@@ -606,18 +604,6 @@ public abstract class Jack {
&& config.get(Options.DEX_OUTPUT_CONTAINER_TYPE) == Container.ZIP) {
config.get(Options.DEX_OUTPUT_ZIP).close();
}
-
- if (config.get(Options.GENERATE_LIBRARY_FROM_INCREMENTAL_FOLDER).booleanValue()) {
- VFS incrementalFolder = config.get(Options.LIBRARY_OUTPUT_DIR);
- Event timeToZip =
- TracerFactory.getTracer().start(JackEventType.ZIP_JACK_LIBRARY_IN_INCREMENTAL);
- try {
- new VFSToVFSWrapper(incrementalFolder, config.get(Options.LIBRARY_OUTPUT_ZIP))
- .close();
- } finally {
- timeToZip.end();
- }
- }
} catch (LibraryIOException e) {
throw new AssertionError(e);
} catch (IOException e) {
@@ -881,7 +867,6 @@ public abstract class Jack {
FeatureSet features = planBuilder.getRequest().getFeatures();
ProductionSet productions = planBuilder.getRequest().getTargetProductions();
boolean hasSanityChecks = features.contains(SanityChecks.class);
- Config config = ThreadConfig.getConfig();
// TODO(jack-team): Remove this hack
boolean preDexing = !getSession().getImportedLibraries().isEmpty();
@@ -1027,12 +1012,10 @@ public abstract class Jack {
{
SubPlanBuilder<JDefinedClassOrInterface> typePlan;
// In incremental library mode, Jayce files must be copied into output library
- if (features.contains(Incremental.class)
- && ((!config.get(Options.GENERATE_JACK_LIBRARY).booleanValue())
- || config.get(Options.LIBRARY_OUTPUT_CONTAINER_TYPE) != Container.ZIP)) {
- typePlan = planBuilder.appendSubPlan(ExcludeTypeFromLibWithBinaryAdapter.class);
- } else {
+ if (features.contains(GenerateLibraryFromIncrementalFolder.class)) {
typePlan = planBuilder.appendSubPlan(JDefinedClassOrInterfaceAdapter.class);
+ } else {
+ typePlan = planBuilder.appendSubPlan(ExcludeTypeFromLibWithBinaryAdapter.class);
}
if (productions.contains(JayceInLibraryProduct.class)) {
typePlan.append(JayceInLibraryWriter.class);
@@ -1182,12 +1165,10 @@ public abstract class Jack {
{
SubPlanBuilder<JDefinedClassOrInterface> typePlan;
// In incremental library mode, dex files must be copied into output library
- if (features.contains(Incremental.class)
- && ((!config.get(Options.GENERATE_JACK_LIBRARY).booleanValue())
- || config.get(Options.LIBRARY_OUTPUT_CONTAINER_TYPE) != Container.ZIP)) {
- typePlan = planBuilder.appendSubPlan(ExcludeTypeFromLibWithBinaryAdapter.class);
- } else {
+ if (features.contains(GenerateLibraryFromIncrementalFolder.class)) {
typePlan = planBuilder.appendSubPlan(JDefinedClassOrInterfaceAdapter.class);
+ } else {
+ typePlan = planBuilder.appendSubPlan(ExcludeTypeFromLibWithBinaryAdapter.class);
}
if (productions.contains(DexInLibraryProduct.class)) {
typePlan.append(DexInLibraryWriter.class);
diff --git a/jack/src/com/android/jack/Options.java b/jack/src/com/android/jack/Options.java
index a96ccf07..78005d2c 100644
--- a/jack/src/com/android/jack/Options.java
+++ b/jack/src/com/android/jack/Options.java
@@ -840,13 +840,13 @@ public class Options {
if (incrementalFolder != null) {
if (multiDexKind == MultiDexKind.LEGACY) {
LoggerFactory.getLogger().log(Level.WARNING,
- "Incremental mode is disable due to multi-dex legacy mode");
+ "Incremental mode is disabled due to multi-dex legacy mode");
} else if (flags != null) {
LoggerFactory.getLogger().log(Level.WARNING,
- "Incremental mode is disable due to usage of shrink or obfuscation");
+ "Incremental mode is disabled due to usage of shrinking or obfuscation");
} else if (jarjarRulesFile != null) {
LoggerFactory.getLogger().log(Level.WARNING,
- "Incremental mode is disable due to usage of jarjar");
+ "Incremental mode is disabled due to usage of jarjar");
} else {
configBuilder.set(Options.INCREMENTAL_MODE, true);
configBuilder.setString(Options.INPUT_FILTER, "incremental");
@@ -1042,7 +1042,6 @@ public class Options {
this.standardOutput = standardOutput;
}
- //STOPSHIP: Hack to handle working directory with proguard flags file
public List<File> getProguardFlagsFile() {
List<File> proguardFlagsFileFromWorkingDir = new ArrayList<File>(proguardFlagsFiles.size());
for (File proguardFlagsFile : proguardFlagsFiles) {
diff --git a/jack/src/com/android/jack/api/v01/impl/Api01ConfigImpl.java b/jack/src/com/android/jack/api/v01/impl/Api01ConfigImpl.java
index ce57d80c..2ec3070d 100644
--- a/jack/src/com/android/jack/api/v01/impl/Api01ConfigImpl.java
+++ b/jack/src/com/android/jack/api/v01/impl/Api01ConfigImpl.java
@@ -65,7 +65,7 @@ public class Api01ConfigImpl implements Api01Config {
@Override
@Nonnull
public Api01CompilationTask getTask() throws ConfigurationException {
- RunnableHooks configHooks = new RunnableHooks(); //STOPSHIP: run configHooks
+ RunnableHooks configHooks = new RunnableHooks();
try {
Jack.check(options, configHooks);
} catch (com.android.sched.util.config.ConfigurationException e) {
@@ -116,8 +116,7 @@ public class Api01ConfigImpl implements Api01Config {
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
} else {
- throw new RuntimeException(e); //STOPSHIP: we have Throwables here that we can't throw as
- //is
+ throw new RuntimeException(e);
}
} finally {
runSessionHooks.runHooks();
diff --git a/jack/src/com/android/jack/frontend/java/JAstBuilder.java b/jack/src/com/android/jack/frontend/java/JAstBuilder.java
index 0d628196..e5f7a3e0 100644
--- a/jack/src/com/android/jack/frontend/java/JAstBuilder.java
+++ b/jack/src/com/android/jack/frontend/java/JAstBuilder.java
@@ -27,6 +27,7 @@ import com.android.jack.ir.ast.JSession;
import com.android.jack.ir.impl.EcjSourceTypeLoader;
import com.android.jack.ir.impl.JackIrBuilder;
import com.android.jack.ir.impl.ReferenceMapper;
+import com.android.jack.ir.impl.SourceCompilationException;
import com.android.sched.util.location.FileLocation;
import com.android.sched.util.log.Event;
import com.android.sched.util.log.Tracer;
@@ -132,6 +133,8 @@ class JAstBuilder extends JavaParser {
List<JDefinedClassOrInterface> types;
try {
types = astBuilder.process(unit);
+ } catch (SourceCompilationException e) {
+ return;
} finally {
jackIrBuilderEvent.end();
}
diff --git a/jack/src/com/android/jack/incremental/Incremental.java b/jack/src/com/android/jack/incremental/GenerateLibraryFromIncrementalFolder.java
index cc791a2b..276c77a6 100644
--- a/jack/src/com/android/jack/incremental/Incremental.java
+++ b/jack/src/com/android/jack/incremental/GenerateLibraryFromIncrementalFolder.java
@@ -20,8 +20,8 @@ import com.android.sched.item.Description;
import com.android.sched.item.Feature;
/**
- * A {@link Feature} that represents incremental support.
+ * A {@link Feature} specifying that a library is generated with incremental support.
*/
-@Description("Incremental support")
-public class Incremental implements Feature {
+@Description("Generate library with incremental support")
+public class GenerateLibraryFromIncrementalFolder implements Feature {
}
diff --git a/jack/src/com/android/jack/incremental/IncrementalInputFilter.java b/jack/src/com/android/jack/incremental/IncrementalInputFilter.java
index 5d5a3d24..f925926c 100644
--- a/jack/src/com/android/jack/incremental/IncrementalInputFilter.java
+++ b/jack/src/com/android/jack/incremental/IncrementalInputFilter.java
@@ -53,6 +53,7 @@ import com.android.sched.util.log.stats.Counter;
import com.android.sched.util.log.stats.CounterImpl;
import com.android.sched.util.log.stats.StatisticId;
import com.android.sched.vfs.InputVFile;
+import com.android.sched.vfs.ReadWriteZipFS;
import com.android.sched.vfs.VFS;
import com.android.sched.vfs.VPath;
@@ -467,11 +468,19 @@ public class IncrementalInputFilter extends CommonFilter implements InputFilter
@Override
@Nonnull
public OutputJackLibrary getOutputJackLibrary() {
- if (incrementalInputLibrary == null) {
- return getOutputJackLibraryFromVfs();
+ if (ThreadConfig.get(Options.GENERATE_LIBRARY_FROM_INCREMENTAL_FOLDER).booleanValue()) {
+ VFS dirVFS = ThreadConfig.get(Options.LIBRARY_OUTPUT_DIR);
+ ReadWriteZipFS zipVFS = (ReadWriteZipFS) ThreadConfig.get(Options.LIBRARY_OUTPUT_ZIP);
+ zipVFS.setWorkVFS(dirVFS);
+ return JackLibraryFactory.getOutputLibrary(zipVFS, Jack.getEmitterId(),
+ Jack.getVersion().getVerboseVersion());
+ } else {
+ if (incrementalInputLibrary == null) {
+ return getOutputJackLibraryFromVfs();
+ } else {
+ return (JackLibraryFactory.getOutputLibrary(ThreadConfig.get(Options.LIBRARY_OUTPUT_DIR),
+ Jack.getEmitterId(), Jack.getVersion().getVerboseVersion()));
+ }
}
-
- return (JackLibraryFactory.getOutputLibrary(ThreadConfig.get(Options.LIBRARY_OUTPUT_DIR),
- Jack.getEmitterId(), Jack.getVersion().getVerboseVersion()));
}
}
diff --git a/jack/src/com/android/jack/ir/impl/JackIrBuilder.java b/jack/src/com/android/jack/ir/impl/JackIrBuilder.java
index e45298c0..83f942ed 100644
--- a/jack/src/com/android/jack/ir/impl/JackIrBuilder.java
+++ b/jack/src/com/android/jack/ir/impl/JackIrBuilder.java
@@ -841,20 +841,8 @@ public class JackIrBuilder {
ReferenceBinding superClass = x.binding.declaringClass;
boolean nestedSuper = isNested(superClass);
- if (x.qualification != null
- && (!x.qualification.resolvedType.isCompatibleWith(superClass.enclosingType())
- || !nestedSuper)) {
- // JLS 8.8.7.1. Explicit Constructor Invocations
- // Let C be the class being instantiated, and let S be the direct superclass of C.
- // Let O be the innermost lexically enclosing class of S
- // If invocation is qualified, it is a compile-time error if the type of qualified
- // expression is not O or a subclass of O
- scope.problemReporter().unnecessaryEnclosingInstanceSpecification(
- x.qualification,
- superClass);
- }
if (nestedSuper) {
- processSuperCallThisArgs(superClass, call, qualifier, x.qualification);
+ processSuperCallThisArgs(superClass, call, qualifier, x);
}
call.addArgs(callArgs);
if (nestedSuper) {
@@ -1291,7 +1279,7 @@ public class JackIrBuilder {
ReferenceBinding targetType =
scope.enclosingSourceType().enclosingTypeAt(
(x.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
- receiver = makeThisReference(info, targetType, true, scope);
+ receiver = makeThisReference(info, targetType, true, scope, x);
}
}
@@ -1488,7 +1476,7 @@ public class JackIrBuilder {
try {
SourceInfo info = makeSourceInfo(x);
ReferenceBinding targetType = (ReferenceBinding) x.qualification.resolvedType;
- push(makeThisReference(info, targetType, true, scope));
+ push(makeThisReference(info, targetType, true, scope, x));
} catch (JTypeLookupException e) {
throw translateException(x, e);
} catch (RuntimeException e) {
@@ -1861,6 +1849,22 @@ public class JackIrBuilder {
@Override
public boolean visit(ExplicitConstructorCall explicitConstructor, BlockScope scope) {
+ ReferenceBinding allocated = explicitConstructor.binding.declaringClass;
+ if (explicitConstructor.isSuperAccess() && explicitConstructor.qualification != null
+ && !explicitConstructor.qualification.resolvedType.isCompatibleWith(
+ allocated.enclosingType())) {
+ // JLS 8.8.7.1. Explicit Constructor Invocations
+ // Let C be the class being instantiated, and let S be the direct superclass of C.
+ // Let O be the innermost lexically enclosing class of S
+ // If invocation is qualified, it is a compile-time error if the type of qualified
+ // expression is not O or a subclass of O
+ scope.problemReporter().unnecessaryEnclosingInstanceSpecification(
+ explicitConstructor.qualification,
+ allocated);
+ throw new FrontendCompilationError();
+ }
+ // STOPSHIP Check other cases and report error to the user
+
scope.methodScope().isConstructorCall = true;
return true;
}
@@ -2026,6 +2030,13 @@ public class JackIrBuilder {
return visit(typeDecl);
}
+ @Override
+ public boolean visit(QualifiedAllocationExpression allocation, BlockScope scope) {
+ ReferenceBinding allocated = allocation.binding.declaringClass;
+ // STOPSHIP Check error cases and report error to the user
+ return super.visit(allocation, scope);
+ }
+
protected void endVisit(TypeDeclaration x) {
assert !JackIrBuilder.hasError(x);
try {
@@ -2476,11 +2487,38 @@ public class JackIrBuilder {
return new JThisRef(info, jThis);
}
+ @Nonnull
+ private Object[] getEmulationPath(@Nonnull BlockScope scope,
+ @Nonnull ReferenceBinding targetType,
+ boolean exactMatch,
+ boolean denyEnclosingArgInConstructorCall,
+ ASTNode node) {
+ Object[] path = scope.getEmulationPath(targetType, exactMatch,
+ denyEnclosingArgInConstructorCall);
+ // STOPSHIP Check other cases and report error to the user
+ if (path == null) {
+ throw new FrontendCompilationError();
+ }
+ return path;
+ }
+
+ @Nonnull
+ private VariableBinding[] getEmulationPath(@Nonnull BlockScope scope,
+ @Nonnull LocalVariableBinding localVariable,
+ ASTNode node) {
+ VariableBinding[] path = scope.getEmulationPath(localVariable);
+ // STOPSHIP Report error to the user
+ if (path == null) {
+ throw new FrontendCompilationError();
+ }
+ return path;
+ }
+
private JExpression makeThisReference(SourceInfo info, ReferenceBinding targetType,
- boolean exactMatch, BlockScope scope) throws JTypeLookupException {
+ boolean exactMatch, BlockScope scope, ASTNode node) throws JTypeLookupException {
targetType = (ReferenceBinding) targetType.erasure();
- Object[] path = scope.getEmulationPath(targetType, exactMatch, false);
- assert path != null : "No emulation path.";
+ Object[] path = getEmulationPath(scope, targetType, exactMatch,
+ /* denyEnclosingArgInConstructorCall = */ false, node);
if (path == BlockScope.EmulationPathToImplicitThis) {
return makeThisRef(info);
}
@@ -2627,15 +2665,16 @@ public class JackIrBuilder {
}
private void processSuperCallThisArgs(ReferenceBinding superClass, JMethodCall call,
- JExpression qualifier, Expression qualification) throws JTypeLookupException {
+ JExpression qualifier, ExplicitConstructorCall expression) throws JTypeLookupException {
if (superClass.syntheticEnclosingInstanceTypes() != null) {
+ Expression qualification = expression.qualification;
for (ReferenceBinding targetType : superClass.syntheticEnclosingInstanceTypes()) {
if (qualification != null && superClass.enclosingType() == targetType) {
assert qualification.resolvedType.erasure().isCompatibleWith(targetType);
call.addArg(qualifier);
} else {
call.addArg(makeThisReference(call.getSourceInfo(), targetType, false,
- curMethod.scope));
+ curMethod.scope, expression));
}
}
}
@@ -2760,15 +2799,6 @@ public class JackIrBuilder {
targetBinding.isAnonymousType() ? (ReferenceBinding) targetBinding.superclass()
.erasure() : targetBinding;
- if (qualifier != null
- && (!isNested || checkedTargetType.isStatic())) {
- // If the class is not an inner class or is declared in a static context,
- // a compile-time error occurs
- curClass.scope.problemReporter().unnecessaryEnclosingInstanceSpecification(qualifier,
- checkedTargetType);
- return;
- }
-
if (isNested) {
// Synthetic this args for inner classes
if (targetBinding.syntheticEnclosingInstanceTypes() != null) {
@@ -2797,16 +2827,13 @@ public class JackIrBuilder {
JMultiExpression multiExpr = new JMultiExpression(info, exprs);
call.addArg(multiExpr);
} else {
- JExpression thisRef = makeThisReference(info, argType, false, scope);
+ JExpression thisRef = makeThisReference(info, argType, false, scope, x);
call.addArg(thisRef);
- Object[] emulationPath = scope.getEmulationPath(
+ Object[] emulationPath = getEmulationPath(scope,
argType,
false /* onlyExactMatch */,
- true /* denyEnclosingArgInConstructorCall */);
- if (emulationPath == BlockScope.NoEnclosingInstanceInConstructorCall) {
- scope.problemReporter().noSuchEnclosingInstance(checkedTargetType,
- x.concreteStatement(), true);
- }
+ true /* denyEnclosingArgInConstructorCall */,
+ x);
}
}
}
@@ -2900,16 +2927,7 @@ public class JackIrBuilder {
if (binding instanceof LocalVariableBinding) {
LocalVariableBinding b = (LocalVariableBinding) binding;
if ((x.bits & ASTNode.DepthMASK) != 0) {
- VariableBinding[] path = scope.getEmulationPath(b);
- if (path == null) {
- /*
- * Don't like this, but in rare cases (e.g. the variable is only
- * ever used as an unnecessary qualifier) JDT provides no emulation
- * to the desired variable.
- */
- // throw new InternalCompilerException("No emulation path.");
- return null;
- }
+ VariableBinding[] path = getEmulationPath(scope, b, x);
assert path.length == 1;
if (curMethod.scope.isInsideInitializer()
&& path[0] instanceof SyntheticArgumentBinding) {
@@ -2948,7 +2966,7 @@ public class JackIrBuilder {
ReferenceBinding targetType =
scope.enclosingSourceType().enclosingTypeAt(
(x.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
- thisRef = makeThisReference(info, targetType, true /* exactMatch */, scope);
+ thisRef = makeThisReference(info, targetType, true /* exactMatch */, scope, x);
} else {
thisRef = makeThisRef(info);
}
@@ -3266,6 +3284,15 @@ public class JackIrBuilder {
}
}
+ private static class FrontendCompilationError extends Error {
+
+ private static final long serialVersionUID = 1L;
+
+ public FrontendCompilationError() {
+ super();
+ }
+ }
+
private static final String ARRAY_LENGTH_FIELD = "length";
/**
@@ -3395,7 +3422,8 @@ public class JackIrBuilder {
return typeMap;
}
- public List<JDefinedClassOrInterface> process(CompilationUnitDeclaration cud) {
+ public List<JDefinedClassOrInterface> process(CompilationUnitDeclaration cud)
+ throws SourceCompilationException {
if (cud.types == null) {
return Collections.emptyList();
}
@@ -3425,9 +3453,18 @@ public class JackIrBuilder {
// Create fields and empty methods.
createMembers(typeDecl);
}
+ boolean hasErrors = false;
for (TypeDeclaration typeDecl : cud.types) {
- // Build the code.
- typeDecl.traverse(astVisitor, cud.scope);
+ try {
+ // Build the code.
+ typeDecl.traverse(astVisitor, cud.scope);
+ } catch (FrontendCompilationError e) {
+ hasErrors = true;
+ }
+ }
+
+ if (hasErrors) {
+ throw new SourceCompilationException();
}
List<JDefinedClassOrInterface> result = newTypes;
diff --git a/jack/src/com/android/jack/ir/impl/SourceCompilationException.java b/jack/src/com/android/jack/ir/impl/SourceCompilationException.java
new file mode 100644
index 00000000..0c8ae1a8
--- /dev/null
+++ b/jack/src/com/android/jack/ir/impl/SourceCompilationException.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 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.ir.impl;
+
+/**
+ * Thrown when an error in a method body is detected. This exception is thrown after reporting to
+ * the user.
+ */
+public class SourceCompilationException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/jack/src/com/android/jack/reporting/CommonReporter.java b/jack/src/com/android/jack/reporting/CommonReporter.java
index b2bdd24d..549837f1 100644
--- a/jack/src/com/android/jack/reporting/CommonReporter.java
+++ b/jack/src/com/android/jack/reporting/CommonReporter.java
@@ -20,6 +20,7 @@ import com.android.jack.Jack;
import com.android.jack.Options;
import com.android.jack.Options.VerbosityLevel;
import com.android.jack.frontend.java.EcjProblem;
+import com.android.jack.ir.sourceinfo.SourceInfo;
import com.android.jack.reporting.Reportable.ProblemLevel;
import com.android.sched.util.config.ThreadConfig;
import com.android.sched.util.file.OutputStreamFile;
@@ -32,7 +33,6 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.LinkedBlockingDeque;
-import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
@@ -92,14 +92,18 @@ abstract class CommonReporter implements Reporter {
if (reportable instanceof EcjProblem) {
assert severity == Severity.NON_FATAL;
CategorizedProblem problem = ((EcjProblem) reportable).getProblem();
+ SourceInfo sourceInfo;
+
+ if (problem.getOriginatingFileName() == null) {
+ sourceInfo = SourceInfo.UNKNOWN;
+ } else {
+ sourceInfo = Jack.getSession().getSourceInfoFactory().create(problem.getSourceLineNumber(),
+ SourceInfo.UNKNOWN_LINE_NUMBER, String.valueOf(problem.getOriginatingFileName()));
+ }
+
printFilteredProblem(reportable.getDefaultProblemLevel(),
- reportable.getMessage(),
- problem.getOriginatingFileName() != null ?
- String.valueOf(problem.getOriginatingFileName()) : null,
- problem.getSourceLineNumber(),
- -1 /* endLine */,
- problem.getSourceEnd(),
- -1 /* endColumn */);
+ reportable.getMessage(), sourceInfo);
+
} else {
// default behavior
if (severity == Severity.FATAL) {
@@ -111,16 +115,11 @@ abstract class CommonReporter implements Reporter {
}
private void printFilteredProblem(@Nonnull ProblemLevel problemLevel, @Nonnull String message) {
- printFilteredProblem(problemLevel, message, null /* fileName */, -1, -1, -1, -1);
+ printFilteredProblem(problemLevel, message, SourceInfo.UNKNOWN);
}
protected abstract void printFilteredProblem(@Nonnull ProblemLevel problemLevel,
- @Nonnull String message,
- @CheckForNull String fileName,
- int startLine,
- int endLine,
- int startColumn,
- int endColumn);
+ @Nonnull String message, @Nonnull SourceInfo sourceInfo);
class RunReporter implements Runnable {
diff --git a/jack/src/com/android/jack/reporting/DefaultReporter.java b/jack/src/com/android/jack/reporting/DefaultReporter.java
index 83718787..c68f7cd7 100644
--- a/jack/src/com/android/jack/reporting/DefaultReporter.java
+++ b/jack/src/com/android/jack/reporting/DefaultReporter.java
@@ -16,12 +16,12 @@
package com.android.jack.reporting;
+import com.android.jack.ir.sourceinfo.SourceInfo;
import com.android.jack.reporting.Reportable.ProblemLevel;
import com.android.sched.util.codec.ImplementationName;
import java.io.PrintStream;
-import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
@@ -32,22 +32,18 @@ import javax.annotation.Nonnull;
public class DefaultReporter extends CommonReporter {
@Override
- protected void printFilteredProblem(@Nonnull ProblemLevel problemLevel,
- @Nonnull String message,
- @CheckForNull String fileName,
- int startLine,
- int endLine,
- int startColumn,
- int endColumn) {
+ protected void printFilteredProblem(@Nonnull ProblemLevel problemLevel, @Nonnull String message,
+ @Nonnull SourceInfo sourceInfo) {
StringBuffer messageBuffer = new StringBuffer(problemLevel.toString());
- if (fileName != null) {
+ if (sourceInfo != SourceInfo.UNKNOWN) {
messageBuffer.append(": ");
- messageBuffer.append(fileName);
- if (startLine >= 0) {
+ messageBuffer.append(sourceInfo.getFileName());
+ if (sourceInfo.getStartLine() >= 0) {
messageBuffer.append(":");
- messageBuffer.append(startLine);
+ messageBuffer.append(sourceInfo.getStartLine());
}
}
+
messageBuffer.append(": ");
messageBuffer.append(message);
diff --git a/jack/src/com/android/jack/reporting/SdkReporter.java b/jack/src/com/android/jack/reporting/SdkReporter.java
index c72eab3e..f7df277a 100644
--- a/jack/src/com/android/jack/reporting/SdkReporter.java
+++ b/jack/src/com/android/jack/reporting/SdkReporter.java
@@ -16,12 +16,13 @@
package com.android.jack.reporting;
+import com.android.jack.ir.sourceinfo.SourceInfo;
import com.android.jack.reporting.Reportable.ProblemLevel;
import com.android.sched.util.codec.ImplementationName;
+import java.io.File;
import java.io.PrintStream;
-import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
@@ -31,39 +32,42 @@ import javax.annotation.Nonnull;
@ImplementationName(iface = Reporter.class, name = "sdk")
public class SdkReporter extends CommonReporter {
- private static final char MESSAGE_SEPARATOR = ':';
-
@Override
protected void printFilteredProblem(@Nonnull ProblemLevel problemLevel,
- @Nonnull String message,
- @CheckForNull String fileName,
- int startLine,
- int endLine,
- int startColumn,
- int endColumn) {
- StringBuffer messageBuffer = new StringBuffer(problemLevel.toString());
- messageBuffer.append(MESSAGE_SEPARATOR);
- if (fileName != null) {
- messageBuffer.append(fileName);
- }
- messageBuffer.append(MESSAGE_SEPARATOR);
- if (startLine >= 0) {
- messageBuffer.append(startLine);
- }
- messageBuffer.append(MESSAGE_SEPARATOR);
- if (endLine >= 0) {
- messageBuffer.append(endLine);
- }
- messageBuffer.append(MESSAGE_SEPARATOR);
- if (startColumn >= 0) {
- messageBuffer.append(startColumn);
- }
- messageBuffer.append(MESSAGE_SEPARATOR);
- if (endColumn >= 0) {
- messageBuffer.append(endColumn);
+ @Nonnull String message, @Nonnull SourceInfo sourceInfo) {
+ StringBuffer messageBuffer = new StringBuffer("MESSAGE:{");
+
+ messageBuffer.append("\"kind\":\"").append(convertLevelName(problemLevel)).append("\",");
+ messageBuffer.append("\"text\":\"").append(message).append("\",");
+ messageBuffer.append("\"sources\":[{");
+
+ if (sourceInfo != SourceInfo.UNKNOWN) {
+ String fileName = new File(sourceInfo.getFileName()).getAbsolutePath();
+
+ messageBuffer.append("\"file\":\"").append(fileName).append("\",");
+ messageBuffer.append("\"position\":{");
+
+ // Convert unknown values to match sdk expectations
+ int startLine = sourceInfo.getStartLine() == SourceInfo.UNKNOWN_LINE_NUMBER ? -1
+ : sourceInfo.getStartLine();
+ int startColumn = sourceInfo.getStartColumn() == SourceInfo.UNKNOWN_COLUMN_NUMBER ? -1
+ : sourceInfo.getStartColumn();
+ int endLine =
+ sourceInfo.getEndLine() == SourceInfo.UNKNOWN_LINE_NUMBER ? -1 : sourceInfo.getEndLine();
+ int endColumn = sourceInfo.getEndColumn() == SourceInfo.UNKNOWN_COLUMN_NUMBER ? -1
+ : sourceInfo.getEndColumn();
+
+ messageBuffer.append("\"startLine\":").append(startLine).append(',');
+ messageBuffer.append("\"startColumn\":").append(startColumn).append(',');
+ messageBuffer.append("\"startOffset\":-1,");
+ messageBuffer.append("\"endLine\":").append(endLine).append(',');
+ messageBuffer.append("\"endColumn\":").append(endColumn).append(',');
+ messageBuffer.append("\"endOffset\":-1");
+
+ messageBuffer.append('}');
}
- messageBuffer.append(MESSAGE_SEPARATOR);
- messageBuffer.append(message);
+
+ messageBuffer.append("}]}");
PrintStream printer = streamByLevel.get(problemLevel);
if (printer == null) {
@@ -72,4 +76,18 @@ public class SdkReporter extends CommonReporter {
printer.println(messageBuffer.toString());
}
+
+ private String convertLevelName(@Nonnull ProblemLevel problemLevel) {
+ switch (problemLevel) {
+ case ERROR:
+ return "ERROR";
+ case WARNING:
+ return "WARNING";
+ case INFO:
+ return "INFO";
+ default:
+ throw new AssertionError("Unkown problem level: '" + problemLevel.name() + "'");
+ }
+ }
+
}
diff --git a/jack/src/com/android/jack/tools/merger/ConstantManager.java b/jack/src/com/android/jack/tools/merger/ConstantManager.java
index e56be8c0..ef1fc3eb 100644
--- a/jack/src/com/android/jack/tools/merger/ConstantManager.java
+++ b/jack/src/com/android/jack/tools/merger/ConstantManager.java
@@ -15,6 +15,7 @@
*/
package com.android.jack.tools.merger;
+import com.android.jack.Jack;
import com.android.jack.dx.dex.DexFormat;
import com.android.jack.dx.dex.file.DexFile;
import com.android.jack.dx.io.DexBuffer;
@@ -30,6 +31,7 @@ import com.android.jack.dx.rop.cst.CstType;
import com.android.jack.dx.rop.type.Type;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -58,7 +60,24 @@ public class ConstantManager extends MergerTools {
private final Map<String, CstString> protoStr2CstString = new HashMap<String, CstString>();
@Nonnull
- private final List<CstIndexMap> cstIndexMaps = new ArrayList<CstIndexMap>();
+ public Collection<CstString> getCstStrings() {
+ return Jack.getUnmodifiableCollections().getUnmodifiableCollection(string2CstStrings.values());
+ }
+
+ @Nonnull
+ public Collection<CstFieldRef> getCstFieldRefs() {
+ return Jack.getUnmodifiableCollections().getUnmodifiableCollection(cstFieldRefs);
+ }
+
+ @Nonnull
+ public Collection<CstMethodRef> getCstMethodRefs() {
+ return Jack.getUnmodifiableCollections().getUnmodifiableCollection(cstMethodRefs);
+ }
+
+ @Nonnull
+ public Collection<CstType> getCstTypes() {
+ return Jack.getUnmodifiableCollections().getUnmodifiableCollection(cstTypes);
+ }
@Nonnull
public CstIndexMap addDexFile(@Nonnull DexBuffer dexBuffer) throws MergingOverflowException {
@@ -164,8 +183,6 @@ public class ConstantManager extends MergerTools {
throw new TypeIdOverflowException();
}
- cstIndexMaps.add(cstIndexMap);
-
return cstIndexMap;
}
@@ -178,11 +195,6 @@ public class ConstantManager extends MergerTools {
cstTypes.removeAll(cstTypesToRemove);
}
- @Nonnull
- public List<CstIndexMap> getCstIndexMaps() {
- return cstIndexMaps;
- }
-
public boolean validate(@Nonnull DexFile dexFile) {
return ((dexFile.getStringIds().items().size() == string2CstStrings.size())
&& (dexFile.getFieldIds().items().size() == cstFieldRefs.size())
diff --git a/jack/src/com/android/jack/tools/merger/JackMerger.java b/jack/src/com/android/jack/tools/merger/JackMerger.java
index 01108b3a..8462763f 100644
--- a/jack/src/com/android/jack/tools/merger/JackMerger.java
+++ b/jack/src/com/android/jack/tools/merger/JackMerger.java
@@ -144,7 +144,8 @@ public class JackMerger extends MergerTools {
}
public void finish(@Nonnull OutputStream out) throws IOException {
- dexResult.prepare(cstManager.getCstIndexMaps());
+ dexResult.prepare(cstManager.getCstStrings(), cstManager.getCstFieldRefs(),
+ cstManager.getCstMethodRefs(), cstManager.getCstTypes());
if (!cstManager.validate(dexResult)) {
throw new AssertionError();
}
diff --git a/sched/.settings/org.eclipse.jdt.core.prefs b/sched/.settings/org.eclipse.jdt.core.prefs
index 34af0151..58cab3f5 100644
--- a/sched/.settings/org.eclipse.jdt.core.prefs
+++ b/sched/.settings/org.eclipse.jdt.core.prefs
@@ -98,9 +98,6 @@ org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
org.eclipse.jdt.core.compiler.processAnnotations=enabled
org.eclipse.jdt.core.compiler.source=1.6
-org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled
-org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,LOW,HIGH,HIGH,LOW
-org.eclipse.jdt.core.compiler.taskTags=TODO(jplesot)\:,TODO,FIXME,XXX,FINDBUGS
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field=1585
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field.count_dependent=1585|-1|1585
diff --git a/sched/src/com/android/sched/vfs/ReadWriteZipFS.java b/sched/src/com/android/sched/vfs/ReadWriteZipFS.java
index 7664e4c8..956c908e 100644
--- a/sched/src/com/android/sched/vfs/ReadWriteZipFS.java
+++ b/sched/src/com/android/sched/vfs/ReadWriteZipFS.java
@@ -203,4 +203,8 @@ public class ReadWriteZipFS extends BaseVFS<BaseVDir, BaseVFile> implements VFS
Location getVDirLocation(@Nonnull BaseVDir parent, @Nonnull VPath path) {
return vfs.getVDirLocation(parent, path);
}
+
+ public void setWorkVFS(@Nonnull VFS workVFS) {
+ vfs.setWorkVFS(workVFS);
+ }
}
diff --git a/sched/src/com/android/sched/vfs/VFSToVFSWrapper.java b/sched/src/com/android/sched/vfs/VFSToVFSWrapper.java
index 7ee1c220..322fa48c 100644
--- a/sched/src/com/android/sched/vfs/VFSToVFSWrapper.java
+++ b/sched/src/com/android/sched/vfs/VFSToVFSWrapper.java
@@ -42,7 +42,7 @@ import javax.annotation.Nonnull;
public class VFSToVFSWrapper extends BaseVFS<BaseVDir, BaseVFile> implements VFS {
@Nonnull
- private final BaseVFS<BaseVDir, BaseVFile> workVFS;
+ private BaseVFS<BaseVDir, BaseVFile> workVFS;
@Nonnull
private final BaseVFS<BaseVDir, BaseVFile> finalVFS;
@Nonnull
@@ -254,4 +254,8 @@ public class VFSToVFSWrapper extends BaseVFS<BaseVDir, BaseVFile> implements VFS
return workVFS.getVDirLocation(parent, path);
}
+ @SuppressWarnings("unchecked")
+ public void setWorkVFS(@Nonnull VFS temporaryVFS) {
+ workVFS = (BaseVFS<BaseVDir, BaseVFile>) temporaryVFS;
+ }
}
diff --git a/sched/tests/com/android/sched/vfs/VFSTest.java b/sched/tests/com/android/sched/vfs/VFSTest.java
index 23953fcd..40d97205 100644
--- a/sched/tests/com/android/sched/vfs/VFSTest.java
+++ b/sched/tests/com/android/sched/vfs/VFSTest.java
@@ -629,7 +629,6 @@ public class VFSTest {
new OutputZipFile(path, null, Existence.MAY_EXIST, ChangePermission.NOCHANGE)));
testOutputVFS(zipVFS);
testDelete(zipVFS);
- //STOPSHIP: should be a ZipLocation but is currently a FileOrDirLocation
// checkZipLocations(zipVFS);
testInputVFS(zipVFS);
zipVFS.close();