summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorMiles Sabin <miles@milessabin.com>2010-01-06 18:48:13 +0000
committerMiles Sabin <miles@milessabin.com>2010-01-06 18:48:13 +0000
commit7315339782f6e19ddd6199768352a91ef66eb27d (patch)
tree7d81761a40130b99ff40c75f07cb325db8ef84f4 /src/compiler
parent64b0678d3344380666d62c855cab2dad8a6ef08b (diff)
downloadscala-7315339782f6e19ddd6199768352a91ef66eb27d.tar.gz
scala-7315339782f6e19ddd6199768352a91ef66eb27d.tar.bz2
scala-7315339782f6e19ddd6199768352a91ef66eb27d.zip
scalac portion of fix for #2689.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/Settings.scala31
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala12
3 files changed, 43 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala
index 23ceb37c95..b039a9e90d 100644
--- a/src/compiler/scala/tools/nsc/Settings.scala
+++ b/src/compiler/scala/tools/nsc/Settings.scala
@@ -372,6 +372,37 @@ object Settings {
}
}
}
+
+ /** Return the source file path(s) which correspond to the given
+ * classfile path and SourceFile attribute value, subject to the
+ * condition that source files are arranged in the filesystem
+ * according to Java package layout conventions.
+ *
+ * The given classfile path must be contained in at least one of
+ * the specified output directories. If it does not then this
+ * method returns Nil.
+ *
+ * Note that the source file is not required to exist, so assuming
+ * a valid classfile path this method will always return a list
+ * containing at least one element.
+ *
+ * Also that if two or more source path elements target the same
+ * output directory there will be two or more candidate source file
+ * paths.
+ */
+ def srcFilesFor(classFile : AbstractFile, srcPath : String) : List[AbstractFile] = {
+ def isBelow(srcDir: AbstractFile, outDir: AbstractFile) =
+ classFile.path.startsWith(outDir.path)
+
+ singleOutDir match {
+ case Some(d) => Nil
+ case None =>
+ (outputs filter (isBelow _).tuple) match {
+ case Nil => Nil
+ case matches => matches.map(_._1.lookupPath(srcPath, false))
+ }
+ }
+ }
}
// The Setting companion object holds all the factory methods
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
index 5d779e90a2..3daa4e8ac2 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
@@ -249,6 +249,7 @@ abstract class SymbolLoaders {
classfileParser.parse(classfile, root)
stopTimer(classReadNanos, start)
}
+ override protected def sourcefile = classfileParser.srcfile
}
class MSILTypeLoader(typ: MSILType) extends SymbolLoader {
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index da4e0aaa49..5c4679625b 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -8,7 +8,7 @@ package scala.tools.nsc
package symtab
package classfile
-import java.io.IOException
+import java.io.{ File, IOException }
import java.lang.Integer.toHexString
import scala.collection.immutable.{Map, ListMap}
@@ -41,6 +41,9 @@ abstract class ClassfileParser {
protected var busy: Option[Symbol] = None // lock to detect recursive reads
private var externalName: Name = _ // JVM name of the current class
protected var classTParams = Map[Name,Symbol]()
+ protected var srcfile0 : Option[AbstractFile] = None
+
+ def srcfile = srcfile0
private object metaParser extends MetaParser {
val global: ClassfileParser.this.global.type = ClassfileParser.this.global
@@ -813,6 +816,13 @@ abstract class ClassfileParser {
case nme.ExceptionsATTR if (!isScala) =>
parseExceptions(attrLen)
+ case nme.SourceFileATTR =>
+ val srcfileLeaf = pool.getName(in.nextChar).toString.trim
+ val srcpath = sym.enclosingPackage match {
+ case NoSymbol => srcfileLeaf
+ case pkg => pkg.fullNameString(File.separatorChar)+File.separator+srcfileLeaf
+ }
+ srcfile0 = settings.outputDirs.srcFilesFor(in.file, srcpath).find(_.exists)
case _ =>
in.skip(attrLen)
}