summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/reflect/internal/SymbolFlags.scala2
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala46
-rw-r--r--src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala4
-rw-r--r--src/compiler/scala/tools/nsc/io/PlainFile.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala10
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala7
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala24
-rw-r--r--src/library/scala/runtime/ScalaRunTime.scala11
-rw-r--r--src/partest/scala/tools/partest/nest/Worker.scala2
-rw-r--r--test/files/neg/macro-invalidsig-context-bounds.check6
-rw-r--r--test/files/neg/macro-invalidsig-context-bounds/Macros_Test_1.scala (renamed from test/files/neg/macro-invalidsig-context-bounds/Macros_Test_2.scala)0
-rw-r--r--test/files/neg/overloaded-unapply.check3
-rw-r--r--test/files/neg/primitive-sigs-1.check6
-rw-r--r--test/files/neg/primitive-sigs-1/A.scala (renamed from test/files/neg/primitive-sigs-1/A_1.scala)0
-rw-r--r--test/files/neg/primitive-sigs-1/B.scala (renamed from test/files/neg/primitive-sigs-1/A_3.scala)2
-rw-r--r--test/files/neg/primitive-sigs-1/J.java (renamed from test/files/neg/primitive-sigs-1/J_2.java)2
-rw-r--r--test/files/neg/t200.check3
-rw-r--r--test/files/neg/t2779.check3
-rw-r--r--test/files/neg/t278.check3
-rw-r--r--test/files/neg/t5504.check4
-rw-r--r--test/files/neg/t5504/s_1.scala4
-rw-r--r--test/files/neg/t5504/s_2.scala8
-rw-r--r--test/files/neg/t591.check3
-rw-r--r--test/files/neg/t800.check9
24 files changed, 113 insertions, 50 deletions
diff --git a/src/compiler/scala/reflect/internal/SymbolFlags.scala b/src/compiler/scala/reflect/internal/SymbolFlags.scala
index 7741d700b9..4ce8ac40df 100644
--- a/src/compiler/scala/reflect/internal/SymbolFlags.scala
+++ b/src/compiler/scala/reflect/internal/SymbolFlags.scala
@@ -162,7 +162,7 @@ trait SymbolFlags {
case _ => abort("setNotFlag on invalid flag: " + flag)
})
- protected def shortSymbolClass = getClass.getName.split('.').last.stripPrefix("Symbols$")
+ def shortSymbolClass = getClass.getName.split('.').last.stripPrefix("Symbols$")
def symbolCreationString: String = (
"%s%25s | %-40s | %s".format(
if (settings.uniqid.value) "%06d | ".format(id) else "",
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 78cec02c0a..2a5b759f94 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -2036,13 +2036,27 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def isExpandedModuleClass: Boolean = name(name.length - 1) == '$'
*/
- def sourceFile: AbstractFileType =
- if (isModule) moduleClass.sourceFile
- else enclosingTopLevelClass.sourceFile
- def sourceFile_=(f: AbstractFileType) {
- abort("sourceFile_= inapplicable for " + this)
- }
+ /** Desire to re-use the field in ClassSymbol which stores the source
+ * file to also store the classfile, but without changing the behavior
+ * of sourceFile (which is expected at least in the IDE only to
+ * return actual source code.) So sourceFile has classfiles filtered out.
+ */
+ private def sourceFileOnly(file: AbstractFileType): AbstractFileType =
+ if ((file eq null) || (file.path endsWith ".class")) null else file
+
+ private def binaryFileOnly(file: AbstractFileType): AbstractFileType =
+ if ((file eq null) || !(file.path endsWith ".class")) null else file
+
+ final def binaryFile: AbstractFileType = binaryFileOnly(associatedFile)
+ final def sourceFile: AbstractFileType = sourceFileOnly(associatedFile)
+
+ /** Overridden in ModuleSymbols to delegate to the module class. */
+ def associatedFile: AbstractFileType = enclosingTopLevelClass.associatedFile
+ def associatedFile_=(f: AbstractFileType) { abort("associatedFile_= inapplicable for " + this) }
+
+ @deprecated("Use associatedFile_= instead", "2.10.0")
+ def sourceFile_=(f: AbstractFileType): Unit = associatedFile_=(f)
/** If this is a sealed class, its known direct subclasses.
* Otherwise, the empty set.
@@ -2423,6 +2437,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def distinguishingFlag = MODULE
private var flatname: TermName = null
+ override def associatedFile = moduleClass.associatedFile
+ override def associatedFile_=(f: AbstractFileType) { moduleClass.associatedFile = f }
+
override def isModule = true
override def moduleClass = referenced
override def companionClass =
@@ -2718,9 +2735,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
extends TypeSymbol(initOwner, initPos, initName) with ClassSymbolApi {
type TypeOfClonedSymbol = ClassSymbol
- private[this] var flatname: TypeName = _
- private[this] var source: AbstractFileType = _
- private[this] var thissym: Symbol = this
+ private[this] var flatname: TypeName = _
+ private[this] var _associatedFile: AbstractFileType = _
+ private[this] var thissym: Symbol = this
private[this] var thisTypeCache: Type = _
private[this] var thisTypePeriod = NoPeriod
@@ -2819,10 +2836,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
if (c.isOverloaded) c.alternatives.head else c
}
- override def sourceFile =
- if (owner.isPackageClass) source
- else super.sourceFile
- override def sourceFile_=(f: AbstractFileType) { source = f }
+ override def associatedFile = if (owner.isPackageClass) _associatedFile else super.associatedFile
+ override def associatedFile_=(f: AbstractFileType) { _associatedFile = f }
override def reset(completer: Type): this.type = {
super.reset(completer)
@@ -2867,6 +2882,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
clone.typeOfThis = typeOfThis
clone.thisSym setName thisSym.name
}
+ if (_associatedFile ne null)
+ clone.associatedFile = _associatedFile
+
clone
}
@@ -3021,7 +3039,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def enclosingTopLevelClass: Symbol = this
override def enclosingPackageClass: Symbol = this
override def enclMethod: Symbol = this
- override def sourceFile: AbstractFileType = null
+ override def associatedFile = null
override def ownerChain: List[Symbol] = List()
override def ownersIterator: Iterator[Symbol] = Iterator.empty
override def alternatives: List[Symbol] = List()
diff --git a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
index 8378f1a892..2322911220 100644
--- a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
+++ b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
@@ -121,8 +121,8 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable =>
}
trait SynchronizedClassSymbol extends ClassSymbol with SynchronizedTypeSymbol {
- override def sourceFile = synchronized { super.sourceFile }
- override def sourceFile_=(f: AbstractFileType) = synchronized { super.sourceFile_=(f) }
+ override def associatedFile = synchronized { super.associatedFile }
+ override def associatedFile_=(f: AbstractFileType) = synchronized { super.associatedFile_=(f) }
override def thisSym: Symbol = synchronized { super.thisSym }
override def thisType: Type = synchronized { super.thisType }
override def typeOfThis: Type = synchronized { super.typeOfThis }
diff --git a/src/compiler/scala/tools/nsc/io/PlainFile.scala b/src/compiler/scala/tools/nsc/io/PlainFile.scala
index 83b8cc32c4..21276e8740 100644
--- a/src/compiler/scala/tools/nsc/io/PlainFile.scala
+++ b/src/compiler/scala/tools/nsc/io/PlainFile.scala
@@ -51,6 +51,7 @@ class PlainFile(val givenPath: Path) extends AbstractFile {
override def output = givenPath.toFile.outputStream()
override def sizeOption = Some(givenPath.length.toInt)
+ override def toString = path
override def hashCode(): Int = fpath.hashCode
override def equals(that: Any): Boolean = that match {
case x: PlainFile => fpath == x.fpath
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
index 7eb04eaf40..390b1a5ec6 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
@@ -232,6 +232,16 @@ abstract class SymbolLoaders {
protected def doComplete(root: Symbol) {
val start = startTimer(classReadNanos)
classfileParser.parse(classfile, root)
+ if (root.associatedFile eq null) {
+ root match {
+ // In fact, the ModuleSymbol forwards its setter to the module class
+ case _: ClassSymbol | _: ModuleSymbol =>
+ debuglog("ClassfileLoader setting %s.associatedFile = %s".format(root.name, classfile))
+ root.associatedFile = classfile
+ case _ =>
+ debuglog("Not setting associatedFile to %s because %s is a %s".format(classfile, root.name, root.shortSymbolClass))
+ }
+ }
stopTimer(classReadNanos, start)
}
override def sourcefile: Option[AbstractFile] = classfileParser.srcfile
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 0117bfb037..ef73d6db1a 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -1064,7 +1064,8 @@ abstract class ClassfileParser {
def className(name: Name): Name =
name.subName(name.lastPos('.') + 1, name.length)
- def enterClassAndModule(entry: InnerClassEntry, completer: global.loaders.SymbolLoader, jflags: Int) {
+ def enterClassAndModule(entry: InnerClassEntry, file: AbstractFile, jflags: Int) {
+ val completer = new global.loaders.ClassfileLoader(file)
val name = entry.originalName
var sflags = toScalaClassFlags(jflags)
val owner = getOwner(jflags)
@@ -1073,6 +1074,8 @@ abstract class ClassfileParser {
val innerModule = owner.newModule(name.toTermName, NoPosition, sflags) setInfo completer
innerModule.moduleClass setInfo global.loaders.moduleClassLoader
+ List(innerClass, innerModule.moduleClass) foreach (_.associatedFile = file)
+
scope enter innerClass
scope enter innerModule
@@ -1094,7 +1097,7 @@ abstract class ClassfileParser {
val file = global.classPath.findSourceFile(entry.externalName.toString) getOrElse {
throw new AssertionError(entry.externalName)
}
- enterClassAndModule(entry, new global.loaders.ClassfileLoader(file), entry.jflags)
+ enterClassAndModule(entry, file, entry.jflags)
}
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index 2d1369b11d..6932030fc2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -622,19 +622,23 @@ trait ContextErrors {
setError(tree)
}
- // checkNoDoubleDefs...
- // @PP: I hacked the filename in (context0.unit) to work around SI-4893. It would be
- // much better if every symbol could offer some idea of where it came from, else
- // the obviously untrue claim that something has been defined twice can only frustrate.
- // There's no direct test because partest doesn't work, but to reproduce, separately
- // compile the next two lines:
- // package object foo { val x: Class[_] = null }
- // package foo
def DefDefinedTwiceError(sym0: Symbol, sym1: Symbol) = {
+ // Most of this hard work is associated with SI-4893.
val isBug = sym0.isAbstractType && sym1.isAbstractType && (sym0.name startsWith "_$")
- issueSymbolTypeError(sym0, sym1+" is defined twice in " + context0.unit
- + ( if (isBug) "\n(this error is likely due to a bug in the scala compiler involving wildcards in package objects)" else "" )
+ val addendums = List(
+ if (sym0.associatedFile eq sym1.associatedFile)
+ Some("conflicting symbols both originated in file '%s'".format(sym0.associatedFile.canonicalPath))
+ else if ((sym0.associatedFile ne null) && (sym1.associatedFile ne null))
+ Some("conflicting symbols originated in files '%s' and '%s'".format(sym0.associatedFile.canonicalPath, sym1.associatedFile.canonicalPath))
+ else None ,
+ if (isBug) Some("Note: this may be due to a bug in the compiler involving wildcards in package objects") else None
)
+ val addendum = addendums.flatten match {
+ case Nil => ""
+ case xs => xs.mkString("\n ", "\n ", "")
+ }
+
+ issueSymbolTypeError(sym0, sym1+" is defined twice" + addendum)
}
// cyclic errors
diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala
index 9d67644d61..0797b65fb0 100644
--- a/src/library/scala/runtime/ScalaRunTime.scala
+++ b/src/library/scala/runtime/ScalaRunTime.scala
@@ -293,8 +293,12 @@ object ScalaRunTime {
*/
def stringOf(arg: Any): String = stringOf(arg, scala.Int.MaxValue)
def stringOf(arg: Any, maxElements: Int): String = {
- def isScalaClass(x: AnyRef) =
- Option(x.getClass.getPackage) exists (_.getName startsWith "scala.")
+ def packageOf(x: AnyRef) = x.getClass.getPackage match {
+ case null => ""
+ case p => p.getName
+ }
+ def isScalaClass(x: AnyRef) = packageOf(x) startsWith "scala."
+ def isScalaCompilerClass(x: AnyRef) = packageOf(x) startsWith "scala.tools.nsc."
// When doing our own iteration is dangerous
def useOwnToString(x: Any) = x match {
@@ -310,7 +314,8 @@ object ScalaRunTime {
case _: TraversableView[_, _] => true
// Don't want to a) traverse infinity or b) be overly helpful with peoples' custom
// collections which may have useful toString methods - ticket #3710
- case x: Traversable[_] => !x.hasDefiniteSize || !isScalaClass(x)
+ // or c) print AbstractFiles which are somehow also Iterable[AbstractFile]s.
+ case x: Traversable[_] => !x.hasDefiniteSize || !isScalaClass(x) || isScalaCompilerClass(x)
// Otherwise, nothing could possibly go wrong
case _ => false
}
diff --git a/src/partest/scala/tools/partest/nest/Worker.scala b/src/partest/scala/tools/partest/nest/Worker.scala
index c69609ec58..9326a8b232 100644
--- a/src/partest/scala/tools/partest/nest/Worker.scala
+++ b/src/partest/scala/tools/partest/nest/Worker.scala
@@ -357,11 +357,11 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
private def compareOutput(dir: File, logFile: File): String = {
val checkFile = getCheckFilePath(dir, kind)
- // if check file exists, compare with log file
val diff =
if (checkFile.canRead) compareFiles(logFile, checkFile.jfile)
else file2String(logFile)
+ // if check file exists, compare with log file
if (diff != "" && fileManager.updateCheck) {
NestUI.verbose("Updating checkfile " + checkFile.jfile)
val toWrite = if (checkFile.exists) checkFile else getCheckFilePath(dir, "")
diff --git a/test/files/neg/macro-invalidsig-context-bounds.check b/test/files/neg/macro-invalidsig-context-bounds.check
index dd68e5db1b..a37b891df6 100644
--- a/test/files/neg/macro-invalidsig-context-bounds.check
+++ b/test/files/neg/macro-invalidsig-context-bounds.check
@@ -1,4 +1,2 @@
-Impls_1.scala:4: error: macro implementations cannot have implicit parameters other than TypeTag evidences
- def foo[U: c.TypeTag: Numeric](c: Ctx) = {
- ^
-one error found
+error: macro implementations cannot have implicit parameters other than TypeTag evidences
+one error found
diff --git a/test/files/neg/macro-invalidsig-context-bounds/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-context-bounds/Macros_Test_1.scala
index 5b4602f328..5b4602f328 100644
--- a/test/files/neg/macro-invalidsig-context-bounds/Macros_Test_2.scala
+++ b/test/files/neg/macro-invalidsig-context-bounds/Macros_Test_1.scala
diff --git a/test/files/neg/overloaded-unapply.check b/test/files/neg/overloaded-unapply.check
index 1da93f6939..68a826bac2 100644
--- a/test/files/neg/overloaded-unapply.check
+++ b/test/files/neg/overloaded-unapply.check
@@ -7,7 +7,8 @@ match argument types (List[a])
overloaded-unapply.scala:22: error: cannot resolve overloaded unapply
case List(x, xs) => 7
^
-overloaded-unapply.scala:12: error: method unapply is defined twice in overloaded-unapply.scala
+overloaded-unapply.scala:12: error: method unapply is defined twice
+ conflicting symbols both originated in file 'overloaded-unapply.scala'
def unapply[a](xs: List[a]): Option[Null] = xs match {
^
three errors found
diff --git a/test/files/neg/primitive-sigs-1.check b/test/files/neg/primitive-sigs-1.check
index 8713d95cc3..77dc457a49 100644
--- a/test/files/neg/primitive-sigs-1.check
+++ b/test/files/neg/primitive-sigs-1.check
@@ -1,6 +1,6 @@
-A_3.scala:3: error: type mismatch;
+B.scala:3: error: type mismatch;
found : Bippy
required: AC[Integer]
- J_2.f(new Bippy())
- ^
+ J.f(new Bippy())
+ ^
one error found
diff --git a/test/files/neg/primitive-sigs-1/A_1.scala b/test/files/neg/primitive-sigs-1/A.scala
index 0dd83b5d6a..0dd83b5d6a 100644
--- a/test/files/neg/primitive-sigs-1/A_1.scala
+++ b/test/files/neg/primitive-sigs-1/A.scala
diff --git a/test/files/neg/primitive-sigs-1/A_3.scala b/test/files/neg/primitive-sigs-1/B.scala
index dec617a111..0958bcda57 100644
--- a/test/files/neg/primitive-sigs-1/A_3.scala
+++ b/test/files/neg/primitive-sigs-1/B.scala
@@ -1,5 +1,5 @@
object Test {
def main(args: Array[String]): Unit = {
- J_2.f(new Bippy())
+ J.f(new Bippy())
}
}
diff --git a/test/files/neg/primitive-sigs-1/J_2.java b/test/files/neg/primitive-sigs-1/J.java
index b416befb4d..2e43b8330c 100644
--- a/test/files/neg/primitive-sigs-1/J_2.java
+++ b/test/files/neg/primitive-sigs-1/J.java
@@ -1,6 +1,6 @@
// java: often the java or scala compiler will save us from
// the untruth in the signature, but not always.
-public class J_2 {
+public class J {
public static Integer f(AC<Integer> x) { return x.f(); }
public static void main(String[] args) {
f(new Bippy());
diff --git a/test/files/neg/t200.check b/test/files/neg/t200.check
index 3ef6665fe5..b6b1a32267 100644
--- a/test/files/neg/t200.check
+++ b/test/files/neg/t200.check
@@ -1,4 +1,5 @@
-t200.scala:7: error: method foo is defined twice in t200.scala
+t200.scala:7: error: method foo is defined twice
+ conflicting symbols both originated in file 't200.scala'
def foo: Int;
^
one error found
diff --git a/test/files/neg/t2779.check b/test/files/neg/t2779.check
index d642541e3e..0ab4c50d0f 100644
--- a/test/files/neg/t2779.check
+++ b/test/files/neg/t2779.check
@@ -1,4 +1,5 @@
-t2779.scala:16: error: method f is defined twice in t2779.scala
+t2779.scala:16: error: method f is defined twice
+ conflicting symbols both originated in file 't2779.scala'
override def f = List(M1)
^
one error found
diff --git a/test/files/neg/t278.check b/test/files/neg/t278.check
index 0c2dfeb67a..405f7d225c 100644
--- a/test/files/neg/t278.check
+++ b/test/files/neg/t278.check
@@ -4,7 +4,8 @@ t278.scala:5: error: overloaded method value a with alternatives:
does not take type parameters
println(a[A])
^
-t278.scala:4: error: method a is defined twice in t278.scala
+t278.scala:4: error: method a is defined twice
+ conflicting symbols both originated in file 't278.scala'
def a = (p:A) => ()
^
two errors found
diff --git a/test/files/neg/t5504.check b/test/files/neg/t5504.check
new file mode 100644
index 0000000000..2827c02d10
--- /dev/null
+++ b/test/files/neg/t5504.check
@@ -0,0 +1,4 @@
+error: type _$1 is defined twice
+ conflicting symbols both originated in file 't5504/s_1.scala'
+ Note: this may be due to a bug in the compiler involving wildcards in package objects
+one error found
diff --git a/test/files/neg/t5504/s_1.scala b/test/files/neg/t5504/s_1.scala
new file mode 100644
index 0000000000..35cb2c8bae
--- /dev/null
+++ b/test/files/neg/t5504/s_1.scala
@@ -0,0 +1,4 @@
+// a.scala
+package object foo {
+ val m: List[_] = Nil
+}
diff --git a/test/files/neg/t5504/s_2.scala b/test/files/neg/t5504/s_2.scala
new file mode 100644
index 0000000000..03eecf6e19
--- /dev/null
+++ b/test/files/neg/t5504/s_2.scala
@@ -0,0 +1,8 @@
+// b.scala
+package foo
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ println(foo.m)
+ }
+}
diff --git a/test/files/neg/t591.check b/test/files/neg/t591.check
index 5cdeebf079..d33f6d7a2f 100644
--- a/test/files/neg/t591.check
+++ b/test/files/neg/t591.check
@@ -1,4 +1,5 @@
-t591.scala:38: error: method input_= is defined twice in t591.scala
+t591.scala:38: error: method input_= is defined twice
+ conflicting symbols both originated in file 't591.scala'
def input_=(in : Input) = {}
^
one error found
diff --git a/test/files/neg/t800.check b/test/files/neg/t800.check
index 44c316a95b..8ba95fddde 100644
--- a/test/files/neg/t800.check
+++ b/test/files/neg/t800.check
@@ -1,13 +1,16 @@
t800.scala:4: error: qualification is already defined as value qualification
val qualification = false;
^
-t800.scala:8: error: method qualification is defined twice in t800.scala
+t800.scala:8: error: method qualification is defined twice
+ conflicting symbols both originated in file 't800.scala'
val qualification = false;
^
-t800.scala:12: error: value qualification is defined twice in t800.scala
+t800.scala:12: error: value qualification is defined twice
+ conflicting symbols both originated in file 't800.scala'
var qualification = false;
^
-t800.scala:16: error: method qualification is defined twice in t800.scala
+t800.scala:16: error: method qualification is defined twice
+ conflicting symbols both originated in file 't800.scala'
var qualification = false;
^
four errors found