Merge "UnknownSourceInfo does not longer extends LineSourceInfo" into ub-jack
diff --git a/jack-tests/prebuilts/core-stubs-mini.jack b/jack-tests/prebuilts/core-stubs-mini.jack
index 76a4383..f519179 100644
--- a/jack-tests/prebuilts/core-stubs-mini.jack
+++ b/jack-tests/prebuilts/core-stubs-mini.jack
Binary files differ
diff --git a/jack-tests/prebuilts/core-stubs-mini.jar b/jack-tests/prebuilts/core-stubs-mini.jar
index 114bfdc..99f6f63 100644
--- a/jack-tests/prebuilts/core-stubs-mini.jar
+++ b/jack-tests/prebuilts/core-stubs-mini.jar
Binary files differ
diff --git a/jack-tests/prebuilts/ecj-tests-lib.jar b/jack-tests/prebuilts/ecj-tests-lib.jar
index 49af442..e508f48 100644
--- a/jack-tests/prebuilts/ecj-tests-lib.jar
+++ b/jack-tests/prebuilts/ecj-tests-lib.jar
Binary files differ
diff --git a/jack-tests/prebuilts/junit4-lib.jack b/jack-tests/prebuilts/junit4-lib.jack
index 520459f..ad87d1f 100644
--- a/jack-tests/prebuilts/junit4-lib.jack
+++ b/jack-tests/prebuilts/junit4-lib.jack
Binary files differ
diff --git a/jack/prebuilts/core-stubs-mini.jack b/jack/prebuilts/core-stubs-mini.jack
index 76a4383..f519179 100644
--- a/jack/prebuilts/core-stubs-mini.jack
+++ b/jack/prebuilts/core-stubs-mini.jack
Binary files differ
diff --git a/jack/prebuilts/core-stubs-mini.jar b/jack/prebuilts/core-stubs-mini.jar
index 114bfdc..99f6f63 100644
--- a/jack/prebuilts/core-stubs-mini.jar
+++ b/jack/prebuilts/core-stubs-mini.jar
Binary files differ
diff --git a/jack/src/com/android/jack/backend/dex/ClassDefItemBuilder.java b/jack/src/com/android/jack/backend/dex/ClassDefItemBuilder.java
index f91a606..ce3d7ba 100644
--- a/jack/src/com/android/jack/backend/dex/ClassDefItemBuilder.java
+++ b/jack/src/com/android/jack/backend/dex/ClassDefItemBuilder.java
@@ -142,14 +142,16 @@
     CstString sourceFile = null;
     SourceInfo sourceInfo = type.getSourceInfo();
 
-    // Only keep filename without the path
-    String sourceFileName = sourceInfo.getFileName();
-    String fileSeparator = FileUtils.getFileSeparator();
-    int separatorPos = sourceFileName.lastIndexOf(fileSeparator);
-    if (separatorPos > 0) {
-      sourceFileName = sourceFileName.substring(separatorPos + 1);
+    if (sourceInfo != SourceInfo.UNKNOWN) {
+      // Only keep filename without the path
+      String sourceFileName = sourceInfo.getFileName();
+      String fileSeparator = FileUtils.getFileSeparator();
+      int separatorPos = sourceFileName.lastIndexOf(fileSeparator);
+      if (separatorPos > 0) {
+        sourceFileName = sourceFileName.substring(separatorPos + 1);
+      }
+      sourceFile = new CstString(sourceFileName);
     }
-    sourceFile = new CstString(sourceFileName);
 
     return sourceFile;
   }
diff --git a/jack/src/com/android/jack/ir/impl/JackIrBuilder.java b/jack/src/com/android/jack/ir/impl/JackIrBuilder.java
index 414c48c..609f606 100644
--- a/jack/src/com/android/jack/ir/impl/JackIrBuilder.java
+++ b/jack/src/com/android/jack/ir/impl/JackIrBuilder.java
@@ -2868,7 +2868,7 @@
         ((JMethodBody) body).getBlock().addStmt(
             new JReturnStatement(session.getSourceInfoFactory().create(
                 method.getSourceInfo().getEndLine(), method.getSourceInfo().getEndLine(),
-                method.getSourceInfo().getFileName()), null));
+                method.getSourceInfo()), null));
 
         addAnnotations(x.annotations, curClass.type);
 
@@ -3842,7 +3842,7 @@
       curMethod.body.getBlock().addStmt(new JReturnStatement(session.getSourceInfoFactory().create(
           curMethod.method.getSourceInfo().getEndLine(),
           curMethod.method.getSourceInfo().getEndLine(),
-          curMethod.method.getSourceInfo().getFileName()), null));
+          curMethod.method.getSourceInfo()), null));
     }
   }
 
diff --git a/jack/src/com/android/jack/ir/sourceinfo/SourceInfo.java b/jack/src/com/android/jack/ir/sourceinfo/SourceInfo.java
index cee4c88..3dd22e9 100644
--- a/jack/src/com/android/jack/ir/sourceinfo/SourceInfo.java
+++ b/jack/src/com/android/jack/ir/sourceinfo/SourceInfo.java
@@ -19,6 +19,7 @@
 import com.android.sched.util.location.FileLocation;
 import com.android.sched.util.location.HasLocation;
 import com.android.sched.util.location.Location;
+import com.android.sched.util.location.NoLocation;
 
 import javax.annotation.Nonnull;
 
@@ -61,28 +62,30 @@
   @Override
   @Nonnull
   public Location getLocation() {
-    Location location;
-    FileLocation fileLocation = new FileLocation(getFileName());
-    if (getStartLine() != UNKNOWN_LINE_NUMBER) {
-      int endLine = getEndLine();
-      if (endLine == UNKNOWN_LINE_NUMBER) {
-        endLine = ColumnAndLineLocation.UNKNOWN;
-      }
+    Location location = NoLocation.getInstance();
+    if (this != SourceInfo.UNKNOWN) {
+      FileLocation fileLocation = new FileLocation(getFileName());
+      if (getStartLine() != UNKNOWN_LINE_NUMBER) {
+        int endLine = getEndLine();
+        if (endLine == UNKNOWN_LINE_NUMBER) {
+          endLine = ColumnAndLineLocation.UNKNOWN;
+        }
 
-      int startColumn = getStartColumn();
-      if (startColumn == UNKNOWN_LINE_NUMBER) {
-        startColumn = ColumnAndLineLocation.UNKNOWN;
-      }
+        int startColumn = getStartColumn();
+        if (startColumn == UNKNOWN_LINE_NUMBER) {
+          startColumn = ColumnAndLineLocation.UNKNOWN;
+        }
 
-      int endColumn = getEndColumn();
-      if (endColumn == UNKNOWN_LINE_NUMBER) {
-        endColumn = ColumnAndLineLocation.UNKNOWN;
-      }
+        int endColumn = getEndColumn();
+        if (endColumn == UNKNOWN_LINE_NUMBER) {
+          endColumn = ColumnAndLineLocation.UNKNOWN;
+        }
 
-      location =
-          new ColumnAndLineLocation(fileLocation, getStartLine(), endLine, startColumn, endColumn);
-    } else {
-      location = fileLocation;
+        location = new ColumnAndLineLocation(fileLocation, getStartLine(), endLine, startColumn,
+            endColumn);
+      } else {
+        location = fileLocation;
+      }
     }
     return location;
   }
diff --git a/jack/src/com/android/jack/ir/sourceinfo/SourceInfoFactory.java b/jack/src/com/android/jack/ir/sourceinfo/SourceInfoFactory.java
index bff5df1..66b2042 100644
--- a/jack/src/com/android/jack/ir/sourceinfo/SourceInfoFactory.java
+++ b/jack/src/com/android/jack/ir/sourceinfo/SourceInfoFactory.java
@@ -49,6 +49,7 @@
    */
   @Nonnull
   public FileSourceInfo create(@Nonnull String fileName) {
+    assert fileName != null;
     FileSourceInfo newInstance = canonicalFileSourceInfos.get(fileName);
     if (newInstance == null) {
       newInstance = new FileSourceInfo(fileName);
@@ -108,13 +109,19 @@
   }
 
   /**
-   * Creates SourceInfo nodes. This factory method will provide
-   * canonicalized instances of SourceInfo objects.
+   * Creates SourceInfo nodes with a file name coming from another SourceInfo. This factory method
+   * will provide canonicalized instances of SourceInfo objects.
    */
   @Nonnull
-  public LineSourceInfo create(
-      @Nonnegative int startLine, @Nonnegative int endLine, @Nonnull FileSourceInfo fileName) {
-    LineSourceInfo newInstance = new LineSourceInfo(fileName, startLine, endLine);
+  public SourceInfo create(@Nonnegative int startLine, @Nonnegative int endLine,
+      @Nonnull SourceInfo originalSourceInfo) {
+    if (originalSourceInfo == SourceInfo.UNKNOWN) {
+      assert startLine == SourceInfo.UNKNOWN_LINE_NUMBER;
+      assert endLine == SourceInfo.UNKNOWN_LINE_NUMBER;
+      return SourceInfo.UNKNOWN;
+    }
+    LineSourceInfo newInstance =
+        new LineSourceInfo(originalSourceInfo.getFileSourceInfo(), startLine, endLine);
     LineSourceInfo canonical = canonicalLineSourceInfos.get(newInstance);
 
     assert canonical == null || (newInstance != canonical && newInstance.equals(canonical));
diff --git a/jack/src/com/android/jack/ir/sourceinfo/UnknownSourceInfo.java b/jack/src/com/android/jack/ir/sourceinfo/UnknownSourceInfo.java
index 05c5f3c..c662a1a 100644
--- a/jack/src/com/android/jack/ir/sourceinfo/UnknownSourceInfo.java
+++ b/jack/src/com/android/jack/ir/sourceinfo/UnknownSourceInfo.java
@@ -22,10 +22,9 @@
 /**
  * Represents the source information when the origin of a node is unknown.
  */
-public class UnknownSourceInfo extends FileSourceInfo {
+public class UnknownSourceInfo extends SourceInfo {
 
   UnknownSourceInfo() {
-    super("Unknown");
   }
 
   @Override
@@ -33,4 +32,10 @@
   public String toString() {
     return "Unknown source info";
   }
+
+  @Override
+  @Nonnull
+  public FileSourceInfo getFileSourceInfo() {
+    throw new UnsupportedOperationException();
+  }
 }
diff --git a/jack/src/com/android/jack/jayce/v0004/Version.java b/jack/src/com/android/jack/jayce/v0004/Version.java
index 218179e..76296d3 100644
--- a/jack/src/com/android/jack/jayce/v0004/Version.java
+++ b/jack/src/com/android/jack/jayce/v0004/Version.java
@@ -21,7 +21,7 @@
  */
 public class Version {
 
-  public static final int MINOR_MIN = 0;
+  public static final int MINOR_MIN = 1;
 
-  public static final int CURRENT_MINOR = 0;
+  public static final int CURRENT_MINOR = 1;
 }
diff --git a/jack/src/com/android/jack/jayce/v0004/io/JayceInternalReaderImpl.java b/jack/src/com/android/jack/jayce/v0004/io/JayceInternalReaderImpl.java
index 10c4626..2f32759 100644
--- a/jack/src/com/android/jack/jayce/v0004/io/JayceInternalReaderImpl.java
+++ b/jack/src/com/android/jack/jayce/v0004/io/JayceInternalReaderImpl.java
@@ -109,6 +109,11 @@
   public String readCurrentFileName() throws IOException {
     if (tokenizer.readOpenFileName()) {
       currentFileName = readString();
+      // UNKNOW_LINE_NUMBER is not dump for unknown debug information, reset it automatically.
+      // Current file name sets to null means unknown debug information.
+      if (currentFileName == null) {
+        currentLine = SourceInfo.UNKNOWN_LINE_NUMBER;
+      }
       tokenizer.readCloseFileName();
     }
     return currentFileName;
@@ -206,8 +211,6 @@
       return null;
     }
 
-
-
     tokenizer.readOpen();
     NNode node;
     try {
@@ -238,8 +241,10 @@
     if (nodeLevel != NodeLevel.TYPES) {
 
       if (node instanceof HasSourceInfo) {
+        fileName = readCurrentFileName();
         int endLine = readCurrentLine();
-        if (fileName == null && startLine == 0 && endLine == 0) {
+        if (fileName == null) {
+          assert startLine == 0 && endLine == 0;
           ((HasSourceInfo) node).setSourceInfos(SourceInfo.UNKNOWN);
         } else {
           assert fileName != null;
diff --git a/jack/src/com/android/jack/jayce/v0004/io/JayceInternalWriterImpl.java b/jack/src/com/android/jack/jayce/v0004/io/JayceInternalWriterImpl.java
index 79d52d7..645e246 100644
--- a/jack/src/com/android/jack/jayce/v0004/io/JayceInternalWriterImpl.java
+++ b/jack/src/com/android/jack/jayce/v0004/io/JayceInternalWriterImpl.java
@@ -92,15 +92,24 @@
   private void writeSourceInfoBegin(@Nonnull NNode node) throws IOException {
     if (node instanceof HasSourceInfo) {
       SourceInfo sourceInfo = ((HasSourceInfo) node).getSourceInfos();
-      writeFileNameIfDifferentFromCurrent(sourceInfo.getFileName());
-      writeLineIfDifferentFromCurrent(sourceInfo.getStartLine());
+      if (sourceInfo == SourceInfo.UNKNOWN) {
+        writeUnknowDebug();
+      } else {
+        writeFileNameIfDifferentFromCurrent(sourceInfo.getFileName());
+        writeLineIfDifferentFromCurrent(sourceInfo.getStartLine());
+      }
     }
   }
 
   private void writeSourceInfoEnd(@Nonnull NNode node) throws IOException {
     if (node instanceof HasSourceInfo) {
-      writeLineIfDifferentFromCurrent(
-          ((HasSourceInfo) node).getSourceInfos().getEndLine());
+      SourceInfo sourceInfo = ((HasSourceInfo) node).getSourceInfos();
+      if (sourceInfo == SourceInfo.UNKNOWN) {
+        writeUnknowDebug();
+      } else {
+        writeFileNameIfDifferentFromCurrent(sourceInfo.getFileName());
+        writeLineIfDifferentFromCurrent(sourceInfo.getEndLine());
+      }
     }
   }
 
@@ -258,22 +267,30 @@
     }
   }
 
-  public void writeCurrentFileName(@Nonnull String fileName)  throws IOException {
+  private void writeUnknowDebug()  throws IOException {
+    if (currentFileName != null) {
+      writeOpenFileName();
+      writeString(null);
+      writeCloseFileName();
+      currentFileName = null;
+      currentLineNumber = 0;
+    }
+  }
+
+  private void writeCurrentFileName(@CheckForNull String fileName)  throws IOException {
     writeOpenFileName();
     writeString(fileName);
     writeCloseFileName();
     currentFileName = fileName;
   }
 
-  public void writeLineIfDifferentFromCurrent(@Nonnegative int lineNumber)
-      throws IOException {
+  public void writeLineIfDifferentFromCurrent(@Nonnegative int lineNumber) throws IOException {
     if (lineNumber != currentLineNumber) {
       writeCurrentLine(lineNumber);
     }
   }
 
-  public void writeCurrentLine(@Nonnegative int lineNumber)
-      throws IOException {
+  public void writeCurrentLine(@Nonnegative int lineNumber) throws IOException {
     writeOpenLineInfo();
     writeTrimmedInt(lineNumber);
     writeCloseLineInfo();
diff --git a/jack/src/com/android/jack/library/v0003/Version.java b/jack/src/com/android/jack/library/v0003/Version.java
index bf25c2a1..d4d843d 100644
--- a/jack/src/com/android/jack/library/v0003/Version.java
+++ b/jack/src/com/android/jack/library/v0003/Version.java
@@ -21,9 +21,9 @@
  */
 public class Version {
 
-  public static final int MINOR_MIN = 1;
+  public static final int MINOR_MIN = 2;
 
-  public static final int MINOR = 1;
+  public static final int MINOR = 2;
 
   public static final int MAJOR = 3;
 }
diff --git a/jack/src/com/android/jack/transformations/ast/TryWithResourcesTransformer.java b/jack/src/com/android/jack/transformations/ast/TryWithResourcesTransformer.java
index 7bccea2..4ac6d7c 100644
--- a/jack/src/com/android/jack/transformations/ast/TryWithResourcesTransformer.java
+++ b/jack/src/com/android/jack/transformations/ast/TryWithResourcesTransformer.java
@@ -194,13 +194,11 @@
       if (x.getResourcesDeclarations().size() > 0) {
 
         SourceInfo trySourceInfo = x.getSourceInfo();
-        SourceInfo endOfTrySourceInfos = sourceInfoFactory.create(
-            trySourceInfo.getEndLine(), trySourceInfo.getEndLine(),
-            trySourceInfo.getFileSourceInfo());
+        SourceInfo endOfTrySourceInfos = sourceInfoFactory.create(trySourceInfo.getEndLine(),
+            trySourceInfo.getEndLine(), trySourceInfo);
 
-        SourceInfo firstLineSourceInfos = sourceInfoFactory.create(
-            trySourceInfo.getStartLine(), trySourceInfo.getStartLine(),
-            trySourceInfo.getFileSourceInfo());
+        SourceInfo firstLineSourceInfos = sourceInfoFactory.create(trySourceInfo.getStartLine(),
+            trySourceInfo.getStartLine(), trySourceInfo);
 
         JBlock finalTryBlock = new JBlock(trySourceInfo);
 
diff --git a/jill/src/com/android/jill/frontend/java/JavaTransformer.java b/jill/src/com/android/jill/frontend/java/JavaTransformer.java
index b7d0cc8..27402a9 100644
--- a/jill/src/com/android/jill/frontend/java/JavaTransformer.java
+++ b/jill/src/com/android/jill/frontend/java/JavaTransformer.java
@@ -77,13 +77,13 @@
   private static final String LIB_MAJOR_VERSION = "3";
 
   @Nonnull
-  private static final String LIB_MINOR_VERSION = "1";
+  private static final String LIB_MINOR_VERSION = "2";
 
   @Nonnull
   private static final String JAYCE_MAJOR_VERSION = "4";
 
   @Nonnull
-  private static final String JAYCE_MINOR_VERSION = "0";
+  private static final String JAYCE_MINOR_VERSION = "1";
 
   @Nonnull
   private static final String KEY_LIB_MAJOR_VERSION = "lib.version.major";
diff --git a/jill/src/com/android/jill/frontend/java/SourceInfoWriter.java b/jill/src/com/android/jill/frontend/java/SourceInfoWriter.java
index 9ef4f22..19b81d6 100644
--- a/jill/src/com/android/jill/frontend/java/SourceInfoWriter.java
+++ b/jill/src/com/android/jill/frontend/java/SourceInfoWriter.java
@@ -55,33 +55,26 @@
     writeDebugBegin(cn, NO_LINE);
   }
 
-  public void writeDebugBegin(@Nonnull ClassNode cn, @Nonnull FieldNode fn)
-      throws IOException {
+  public void writeDebugBegin(@Nonnull ClassNode cn, @Nonnull FieldNode fn) throws IOException {
     writeUnknwonDebugBegin();
   }
 
-  public void writeDebugBegin(@Nonnull ClassNode cn, int startLine)
-      throws IOException {
+  public void writeDebugBegin(@Nonnull ClassNode cn, int startLine) throws IOException {
     if (cn.sourceFile == null) {
       writeUnknwonDebugBegin();
     } else {
-      writeDebugBeginInternal(cn.sourceFile, startLine);
+      writeFileNameIfDifferentFromCurrent(cn.sourceFile);
+      writeLineIfDifferentFromCurrent(startLine);
     }
   }
 
   public void writeUnknwonDebugBegin() throws IOException {
-    writeDebugBeginInternal(NO_FILENAME, NO_LINE);
-  }
-
-  private void writeDebugBeginInternal(@CheckForNull String sourceFile, int startLine)
-      throws IOException {
-    writeFileNameIfDifferentFromCurrent(sourceFile);
-    writeLineIfDifferentFromCurrent(startLine);
+    writeUnknowDebug();
   }
 
   public void writeDebugEnd(@Nonnull ClassNode cn)
       throws IOException {
-    writeUnknownDebugEnd();
+    writeDebugEnd(cn, NO_LINE);
   }
 
   public void writeDebugEnd(@Nonnull ClassNode cn, @Nonnull FieldNode fn)
@@ -91,32 +84,39 @@
 
   public void writeDebugEnd(@Nonnull ClassNode cn, int endLine) throws IOException {
     if (cn.sourceFile == null) {
-      writeUnknownDebugEnd();
+      writeUnknwonDebugBegin();
     } else {
+      writeFileNameIfDifferentFromCurrent(cn.sourceFile);
       writeLineIfDifferentFromCurrent(endLine);
     }
   }
 
   public void writeUnknownDebugEnd() throws IOException {
-    writeLineIfDifferentFromCurrent(NO_LINE);
+    writeUnknowDebug();
   }
 
-  private void writeFileNameIfDifferentFromCurrent(@CheckForNull String fileName)
+  private void writeUnknowDebug()  throws IOException {
+    if (currentFileName != null) {
+      writeCurrentFileName(null);
+      currentLineNumber = 0;
+    }
+  }
+
+  private void writeFileNameIfDifferentFromCurrent(@Nonnull String fileName)
       throws IOException {
-    if (fileName != null && !fileName.equals(currentFileName)) {
+    if (!fileName.equals(currentFileName)) {
       writeCurrentFileName(fileName);
     }
-    // Assume that elements with unknown debug infos are in same file.
   }
 
-  private void writeCurrentFileName(@Nonnull String fileName)
+  private void writeCurrentFileName(@CheckForNull String fileName)
       throws IOException {
     writer.writeFileName(fileName);
     currentFileName = fileName;
   }
 
-  private void writeLineIfDifferentFromCurrent(@Nonnegative int lineNumber)
-      throws IOException {
+  private void writeLineIfDifferentFromCurrent(@Nonnegative int lineNumber) throws IOException {
+    assert currentFileName != NO_FILENAME || lineNumber == NO_LINE;
     if (lineNumber != currentLineNumber) {
       writeCurrentLine(lineNumber);
     }