summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2014-05-08 22:51:18 +0200
committerJason Zaugg <jzaugg@gmail.com>2014-05-08 22:51:18 +0200
commita469cabc3eaf18a8a41cbcb1de4da6a7d459c861 (patch)
treeb947a3a1bc0fdc6cfe8955b50f63a38926daaa5a
parent6a0b66185096dd9703010a2069fc79cc1e53031d (diff)
parentb7f91a206cca9ab9bb87d0f7872ddf213ba10f82 (diff)
downloadscala-a469cabc3eaf18a8a41cbcb1de4da6a7d459c861.tar.gz
scala-a469cabc3eaf18a8a41cbcb1de4da6a7d459c861.tar.bz2
scala-a469cabc3eaf18a8a41cbcb1de4da6a7d459c861.zip
Merge pull request #3728 from retronym/topic/merge-2.10.x
Merge 2.10.x to 2.11.x
-rw-r--r--bincompat-forward.whitelist.conf4
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeInfo.scala10
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala10
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala5
-rw-r--r--src/reflect/scala/reflect/internal/AnnotationInfos.scala2
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala5
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala11
-rw-r--r--test/files/run/t8196.check7
-rw-r--r--test/files/run/t8196.scala51
-rw-r--r--test/files/run/t8442.check1
-rw-r--r--test/files/run/t8442/A_1.java4
-rw-r--r--test/files/run/t8442/B_1.java3
-rw-r--r--test/files/run/t8442/C_2.scala5
-rw-r--r--test/files/run/t8442/Test.scala29
-rw-r--r--test/scaladoc/run/SI-8479.check1
-rwxr-xr-xtest/scaladoc/run/SI-8479.scala32
16 files changed, 168 insertions, 12 deletions
diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf
index 5e869e3215..ca8f7468eb 100644
--- a/bincompat-forward.whitelist.conf
+++ b/bincompat-forward.whitelist.conf
@@ -226,6 +226,10 @@ filter {
{
matchName="scala.reflect.api.Internals$ReificationSupportApi$SyntacticTypeProjectionExtractor"
problemName=MissingClassProblem
+ },
+ {
+ matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$followStatic"
+ problemName=MissingMethodProblem
}
]
}
diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
index 0731d78a9b..689e6405d0 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
@@ -74,6 +74,11 @@ abstract class TreeInfo extends scala.reflect.internal.TreeInfo {
}
}
+ // TODO these overrides, and the slow trickle of bugs that they solve (e.g. SI-8479),
+ // suggest that we should pursue an alternative design in which the DocDef nodes
+ // are eliminated from the tree before typer, and instead are modelled as tree
+ // attachments.
+
/** Is tree legal as a member definition of an interface?
*/
override def isInterfaceMember(tree: Tree): Boolean = tree match {
@@ -81,6 +86,11 @@ abstract class TreeInfo extends scala.reflect.internal.TreeInfo {
case _ => super.isInterfaceMember(tree)
}
+ override def isConstructorWithDefault(t: Tree) = t match {
+ case DocDef(_, definition) => isConstructorWithDefault(definition)
+ case _ => super.isConstructorWithDefault(t)
+ }
+
/** Is tree a pure (i.e. non-side-effecting) definition?
*/
override def isPureDef(tree: Tree): Boolean = tree match {
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index ea600bc586..d7cd92adf2 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -356,9 +356,13 @@ abstract class ClassfileParser {
// SI-5593 Scaladoc's current strategy is to visit all packages in search of user code that can be documented
// therefore, it will rummage through the classpath triggering errors whenever it encounters package objects
// that are not in their correct place (see bug for details)
- if (!settings.isScaladoc)
- warning(s"Class $name not found - continuing with a stub.")
- return NoSymbol.newClass(name.toTypeName)
+
+ // TODO More consistency with use of stub symbols in `Unpickler`
+ // - better owner than `NoSymbol`
+ // - remove eager warning
+ val msg = s"Class $name not found - continuing with a stub."
+ if (!settings.isScaladoc) warning(msg)
+ return NoSymbol.newStubSymbol(name.toTypeName, msg)
}
val completer = new loaders.ClassfileLoader(file)
var owner: Symbol = rootMirror.RootClass
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 23dc57d5b9..4382a2c6f7 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -711,10 +711,7 @@ trait Namers extends MethodSynthesis {
val m = ensureCompanionObject(tree, caseModuleDef)
m.moduleClass.updateAttachment(new ClassForCaseCompanionAttachment(tree))
}
- val hasDefault = impl.body exists {
- case DefDef(_, nme.CONSTRUCTOR, _, vparamss, _, _) => mexists(vparamss)(_.mods.hasDefault)
- case _ => false
- }
+ val hasDefault = impl.body exists treeInfo.isConstructorWithDefault
if (hasDefault) {
val m = ensureCompanionObject(tree)
m.updateAttachment(new ConstructorDefaultsAttachment(tree, null))
diff --git a/src/reflect/scala/reflect/internal/AnnotationInfos.scala b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
index 19e9eef851..f814a746f5 100644
--- a/src/reflect/scala/reflect/internal/AnnotationInfos.scala
+++ b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
@@ -302,7 +302,7 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
*/
def defaultTargets = symbol.annotations map (_.symbol) filter isMetaAnnotation
// Test whether the typeSymbol of atp conforms to the given class.
- def matches(clazz: Symbol) = symbol isNonBottomSubClass clazz
+ def matches(clazz: Symbol) = !symbol.isInstanceOf[StubSymbol] && (symbol isNonBottomSubClass clazz)
// All subtrees of all args are considered.
def hasArgWhich(p: Tree => Boolean) = args exists (_ exists p)
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 7cf749c048..b7d7d4df88 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -51,6 +51,11 @@ abstract class TreeInfo {
case _ => false
}
+ def isConstructorWithDefault(t: Tree) = t match {
+ case DefDef(_, nme.CONSTRUCTOR, _, vparamss, _, _) => mexists(vparamss)(_.mods.hasDefault)
+ case _ => false
+ }
+
/** Is tree a pure (i.e. non-side-effecting) definition?
*/
def isPureDef(tree: Tree): Boolean = tree match {
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index f5bddb1784..6584d80de3 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -760,8 +760,7 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive
module.moduleClass setInfo new ClassInfoType(List(), newScope, module.moduleClass)
}
- def enter(sym: Symbol, mods: JavaAccFlags) =
- ( if (mods.isStatic) module.moduleClass else clazz ).info.decls enter sym
+ def enter(sym: Symbol, mods: JavaAccFlags) = followStatic(clazz, module, mods).info.decls enter sym
def enterEmptyCtorIfNecessary(): Unit = {
if (jclazz.getConstructors.isEmpty)
@@ -801,8 +800,12 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive
* If Java modifiers `mods` contain STATIC, return the module class
* of the companion module of `clazz`, otherwise the class `clazz` itself.
*/
- private def followStatic(clazz: Symbol, mods: JavaAccFlags) =
- if (mods.isStatic) clazz.companionModule.moduleClass else clazz
+ private def followStatic(clazz: Symbol, mods: JavaAccFlags): Symbol = followStatic(clazz, clazz.companionModule, mods)
+
+ private def followStatic(clazz: Symbol, module: Symbol, mods: JavaAccFlags): Symbol =
+ // SI-8196 `orElse(clazz)` needed for implementation details of the backend, such as the static
+ // field containing the cache for structural calls.
+ if (mods.isStatic) module.moduleClass.orElse(clazz) else clazz
/** Methods which need to be treated with care
* because they either are getSimpleName or call getSimpleName:
diff --git a/test/files/run/t8196.check b/test/files/run/t8196.check
new file mode 100644
index 0000000000..b32f42cf07
--- /dev/null
+++ b/test/files/run/t8196.check
@@ -0,0 +1,7 @@
+t8196.scala:26: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+ form2.g1 // comment this line in order to make the test pass
+ ^
+warning: there were 2 feature warning(s); re-run with -feature for details
+Scope{
+ final private val f1: Int
+}
diff --git a/test/files/run/t8196.scala b/test/files/run/t8196.scala
new file mode 100644
index 0000000000..e219ac166b
--- /dev/null
+++ b/test/files/run/t8196.scala
@@ -0,0 +1,51 @@
+import scala.reflect.runtime.{ universe => ru }
+
+object Test extends App {
+
+ trait FormTrait {
+
+ val runtimeMirror = ru.runtimeMirror(this.getClass.getClassLoader)
+ val instanceMirror = runtimeMirror.reflect(this)
+ val members = instanceMirror.symbol.typeSignature.members
+ def fields = members.filter(_.typeSignature <:< ru.typeOf[Int])
+ }
+
+ val f = () => {
+
+ class Form1 extends FormTrait {
+ val f1 = 5
+ }
+ val form1 = new Form1
+
+ println(form1.fields)
+
+ val form2 = new FormTrait {
+ val g1 = new Form1
+ }
+
+ form2.g1 // comment this line in order to make the test pass
+ ()
+ }
+
+ val g = () => {
+ // Reported as SI-8195, same root cause
+ trait Form {
+
+ private val runtimeMirror = ru.runtimeMirror(this.getClass.getClassLoader)
+ private val instanceMirror = runtimeMirror.reflect(this)
+ private val members = instanceMirror.symbol.typeSignature.members
+
+ }
+
+ val f1 = new Form {
+ val a = 1
+ }
+
+ val f2 = new Form {
+ val b = f1.a
+ }
+ }
+
+ f()
+ g()
+}
diff --git a/test/files/run/t8442.check b/test/files/run/t8442.check
new file mode 100644
index 0000000000..ce9e8b52ff
--- /dev/null
+++ b/test/files/run/t8442.check
@@ -0,0 +1 @@
+pos: NoPosition Class A_1 not found - continuing with a stub. WARNING
diff --git a/test/files/run/t8442/A_1.java b/test/files/run/t8442/A_1.java
new file mode 100644
index 0000000000..227451eecd
--- /dev/null
+++ b/test/files/run/t8442/A_1.java
@@ -0,0 +1,4 @@
+@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
+public @interface A_1 {
+
+} \ No newline at end of file
diff --git a/test/files/run/t8442/B_1.java b/test/files/run/t8442/B_1.java
new file mode 100644
index 0000000000..1680684495
--- /dev/null
+++ b/test/files/run/t8442/B_1.java
@@ -0,0 +1,3 @@
+public class B_1 {
+ @A_1 public String get() { return ""; }
+}
diff --git a/test/files/run/t8442/C_2.scala b/test/files/run/t8442/C_2.scala
new file mode 100644
index 0000000000..d75d4bd910
--- /dev/null
+++ b/test/files/run/t8442/C_2.scala
@@ -0,0 +1,5 @@
+class C_2 {
+ def foo(b: B_1) {
+ b.get()
+ }
+}
diff --git a/test/files/run/t8442/Test.scala b/test/files/run/t8442/Test.scala
new file mode 100644
index 0000000000..ff6da4e206
--- /dev/null
+++ b/test/files/run/t8442/Test.scala
@@ -0,0 +1,29 @@
+import scala.tools.partest._
+import java.io.File
+
+object Test extends StoreReporterDirectTest {
+ def code = ???
+
+ def compileCode(code: String) = {
+ val classpath = List(sys.props("partest.lib"), testOutput.path) mkString sys.props("path.separator")
+ compileString(newCompiler("-cp", classpath, "-d", testOutput.path))(code)
+ }
+
+ def app = """
+ class C_2 {
+ def foo(b: B_1) {
+ b.get()
+ }
+ }
+ """
+
+ def show(): Unit = {
+ val tClass = new File(testOutput.path, "A_1.class")
+ assert(tClass.exists)
+ assert(tClass.delete())
+
+ // Expecting stub symbol warning, but no stack trace!
+ compileCode(app)
+ println(filteredInfos.mkString("\n"))
+ }
+}
diff --git a/test/scaladoc/run/SI-8479.check b/test/scaladoc/run/SI-8479.check
new file mode 100644
index 0000000000..619c56180b
--- /dev/null
+++ b/test/scaladoc/run/SI-8479.check
@@ -0,0 +1 @@
+Done.
diff --git a/test/scaladoc/run/SI-8479.scala b/test/scaladoc/run/SI-8479.scala
new file mode 100755
index 0000000000..3c91395025
--- /dev/null
+++ b/test/scaladoc/run/SI-8479.scala
@@ -0,0 +1,32 @@
+import scala.tools.nsc.doc.model._
+import scala.tools.nsc.doc.base._
+import scala.tools.nsc.doc.base.comment._
+import scala.tools.partest.ScaladocModelTest
+import java.net.{URI, URL}
+import java.io.File
+
+object Test extends ScaladocModelTest {
+
+ override def code =
+ """
+ |object Test {
+ | val x = new SparkContext(master = "")
+ |}
+ |
+ |class SparkContext(config: Any) {
+ |
+ | /** Scaladoc comment */
+ | def this(
+ | master: String,
+ | appName: String = "") = this(null)
+ |}
+ |
+ |
+ """.stripMargin
+
+ override def scaladocSettings = ""
+
+ def testModel(rootPackage: Package) {
+ // it didn't crash
+ }
+}