diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2014-05-08 22:51:18 +0200 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2014-05-08 22:51:18 +0200 |
commit | a469cabc3eaf18a8a41cbcb1de4da6a7d459c861 (patch) | |
tree | b947a3a1bc0fdc6cfe8955b50f63a38926daaa5a | |
parent | 6a0b66185096dd9703010a2069fc79cc1e53031d (diff) | |
parent | b7f91a206cca9ab9bb87d0f7872ddf213ba10f82 (diff) | |
download | scala-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.conf | 4 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/TreeInfo.scala | 10 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala | 10 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Namers.scala | 5 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/AnnotationInfos.scala | 2 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/TreeInfo.scala | 5 | ||||
-rw-r--r-- | src/reflect/scala/reflect/runtime/JavaMirrors.scala | 11 | ||||
-rw-r--r-- | test/files/run/t8196.check | 7 | ||||
-rw-r--r-- | test/files/run/t8196.scala | 51 | ||||
-rw-r--r-- | test/files/run/t8442.check | 1 | ||||
-rw-r--r-- | test/files/run/t8442/A_1.java | 4 | ||||
-rw-r--r-- | test/files/run/t8442/B_1.java | 3 | ||||
-rw-r--r-- | test/files/run/t8442/C_2.scala | 5 | ||||
-rw-r--r-- | test/files/run/t8442/Test.scala | 29 | ||||
-rw-r--r-- | test/scaladoc/run/SI-8479.check | 1 | ||||
-rwxr-xr-x | test/scaladoc/run/SI-8479.scala | 32 |
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 + } +} |