summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-01-17 08:50:44 -0800
committerPaul Phillips <paulp@improving.org>2012-01-17 10:26:21 -0800
commit2820770bffe2e7d180bccbcd7a3d83944b1dd8d6 (patch)
treed2f7e2408419dbaf1129f28b54619685191d635b
parentcc9871f8dd4f685660976f1a6e5e07c28a4c53a7 (diff)
downloadscala-2820770bffe2e7d180bccbcd7a3d83944b1dd8d6.tar.gz
scala-2820770bffe2e7d180bccbcd7a3d83944b1dd8d6.tar.bz2
scala-2820770bffe2e7d180bccbcd7a3d83944b1dd8d6.zip
Fixing inliner visibility issue.
Changes motivated by ICodeReader neglecting to utilize logic which exists in its superclass. Now you can enjoy empty package classes being inlined into other empty package classes. Closes SI-4925.
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala96
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala45
-rw-r--r--test/files/pos/t4925.flags1
-rw-r--r--test/files/pos/t4925/S_1.scala6
-rw-r--r--test/files/pos/t4925/S_2.scala8
5 files changed, 80 insertions, 76 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 099145d3ae..f2786737aa 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -439,62 +439,58 @@ abstract class ClassfileParser {
// println("found: " + sym)
sym
}
-
- /** Return the class symbol of the given name. */
- def classNameToSymbol(name: Name): Symbol = {
- def loadClassSymbol(name: Name): Symbol = {
- val file = global.classPath findSourceFile ("" +name) getOrElse {
- warning("Class " + name + " not found - continuing with a stub.")
- return NoSymbol.newClass(name.toTypeName)
- }
- val completer = new global.loaders.ClassfileLoader(file)
- var owner: Symbol = definitions.RootClass
- var sym: Symbol = NoSymbol
- var ss: Name = null
- var start = 0
- var end = name indexOf '.'
-
- while (end > 0) {
- ss = name.subName(start, end)
- sym = owner.info.decls lookup ss
- if (sym == NoSymbol) {
- sym = owner.newPackage(ss) setInfo completer
- sym.moduleClass setInfo completer
- owner.info.decls enter sym
- }
- owner = sym.moduleClass
- start = end + 1
- end = name.indexOf('.', start)
- }
- ss = name.subName(0, start)
- owner.info.decls lookup ss orElse {
- sym = owner.newClass(ss.toTypeName) setInfoAndEnter completer
- debuglog("loaded "+sym+" from file "+file)
- sym
- }
+
+ protected def lookupClass(name: Name) = {
+ val sym = name match {
+ case fulltpnme.RuntimeNothing => definitions.NothingClass
+ case fulltpnme.RuntimeNull => definitions.NullClass
+ case _ =>
+ if (innerClasses contains name) // check inner classes
+ innerClasses.classSymbol(innerClasses(name).externalName)
+ else if (name containsChar '.') // qualified name
+ definitions.getClassIfDefined(name)
+ else // might be in the empty package
+ definitions.getMember(definitions.EmptyPackageClass, name.toTypeName)
}
- def lookupClass(name: Name) = try {
- if (name.pos('.') == name.length)
- definitions.getMember(definitions.EmptyPackageClass, name.toTypeName)
- else
- definitions.getClass(name) // see tickets #2464, #3756
- } catch {
- case _: FatalError => loadClassSymbol(name)
- }
+ sym orElse loadClassSymbol(name)
+ }
- innerClasses.get(name) match {
- case Some(entry) =>
- //println("found inner class " + name)
- val res = innerClasses.classSymbol(entry.externalName)
- //println("\trouted to: " + res)
- res
- case None =>
- //if (name.toString.contains("$")) println("No inner class: " + name + innerClasses + " while parsing " + in.file.name)
- lookupClass(name)
+ protected def loadClassSymbol(name: Name): Symbol = {
+ val file = global.classPath findSourceFile ("" +name) getOrElse {
+ warning("Class " + name + " not found - continuing with a stub.")
+ return NoSymbol.newClass(name.toTypeName)
+ }
+ val completer = new global.loaders.ClassfileLoader(file)
+ var owner: Symbol = definitions.RootClass
+ var sym: Symbol = NoSymbol
+ var ss: Name = null
+ var start = 0
+ var end = name indexOf '.'
+
+ while (end > 0) {
+ ss = name.subName(start, end)
+ sym = owner.info.decls lookup ss
+ if (sym == NoSymbol) {
+ sym = owner.newPackage(ss) setInfo completer
+ sym.moduleClass setInfo completer
+ owner.info.decls enter sym
+ }
+ owner = sym.moduleClass
+ start = end + 1
+ end = name.indexOf('.', start)
+ }
+ ss = name.subName(0, start)
+ owner.info.decls lookup ss orElse {
+ sym = owner.newClass(ss.toTypeName) setInfoAndEnter completer
+ debuglog("loaded "+sym+" from file "+file)
+ sym
}
}
+ /** Return the class symbol of the given name. */
+ def classNameToSymbol(name: Name): Symbol = lookupClass(name)
+
var sawPrivateConstructor = false
def parseClass() {
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
index 3c97122c9c..489fc9ff54 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
@@ -160,34 +160,27 @@ abstract class ICodeReader extends ClassfileParser {
}
override def classNameToSymbol(name: Name) = {
- val sym = if (name == fulltpnme.RuntimeNothing)
- definitions.NothingClass
- else if (name == fulltpnme.RuntimeNull)
- definitions.NullClass
- else if (nme.isImplClassName(name)) {
- val iface = definitions.getClass(nme.interfaceName(name))
- log("forcing " + iface.owner + " at phase: " + phase + " impl: " + iface.implClass)
- iface.owner.info // force the mixin type-transformer
- definitions.getClass(name)
- }
- else if (nme.isModuleName(name)) {
- val strippedName = nme.stripModuleSuffix(name)
- val sym = forceMangledName(newTermName(strippedName.decode), true)
-
- if (sym == NoSymbol) definitions.getModule(strippedName)
- else sym
- }
- else {
- forceMangledName(name, false)
- atPhase(currentRun.flattenPhase.next)(definitions.getClass(name))
- }
- if (sym.isModule)
- sym.moduleClass
- else
- sym
+ val sym = (
+ if (nme.isImplClassName(name)) {
+ val iface = lookupClass(nme.interfaceName(name))
+ log("forcing " + iface.owner + " at phase: " + phase + " impl: " + iface.implClass)
+ iface.owner.info // force the mixin type-transformer
+ lookupClass(name.toTypeName)
+ }
+ else if (nme.isModuleName(name)) {
+ val strippedName = nme.stripModuleSuffix(name).toTermName
+ val sym = forceMangledName(strippedName.decodedName, true)
+ sym orElse definitions.getModule(strippedName)
+ }
+ else {
+ forceMangledName(name, false)
+ atPhase(currentRun.flattenPhase.next)(lookupClass(name))
+ }
+ )
+ if (sym.isModule) sym.moduleClass
+ else sym
}
-
var maxStack: Int = _
var maxLocals: Int = _
val JVM = ClassfileConstants // shorter, uppercase alias for use in case patterns
diff --git a/test/files/pos/t4925.flags b/test/files/pos/t4925.flags
new file mode 100644
index 0000000000..ea03113c66
--- /dev/null
+++ b/test/files/pos/t4925.flags
@@ -0,0 +1 @@
+-optimise -Xfatal-warnings \ No newline at end of file
diff --git a/test/files/pos/t4925/S_1.scala b/test/files/pos/t4925/S_1.scala
new file mode 100644
index 0000000000..0b3a75b8f7
--- /dev/null
+++ b/test/files/pos/t4925/S_1.scala
@@ -0,0 +1,6 @@
+class A {
+ final class Inner {
+ @inline def foo = 7
+ }
+ def inner = new Inner
+}
diff --git a/test/files/pos/t4925/S_2.scala b/test/files/pos/t4925/S_2.scala
new file mode 100644
index 0000000000..f32d871367
--- /dev/null
+++ b/test/files/pos/t4925/S_2.scala
@@ -0,0 +1,8 @@
+class B {
+ def baz = {
+ val a = new A
+ val o = a.inner
+ val z = o.foo
+ println(z)
+ }
+}