summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVlad Ureche <vlad.ureche@gmail.com>2012-03-27 10:35:40 +0200
committerVlad Ureche <vlad.ureche@gmail.com>2012-03-27 10:35:40 +0200
commit5632167f6cacec16d82b1961d233d7e761cf6036 (patch)
tree13cf3cdd1b8e41ddaa7c0a22d805dbbc6cfa7bb7
parenta532ba0600444b3564b6b015688ebc4cdf084ba6 (diff)
downloadscala-5632167f6cacec16d82b1961d233d7e761cf6036.tar.gz
scala-5632167f6cacec16d82b1961d233d7e761cf6036.tar.bz2
scala-5632167f6cacec16d82b1961d233d7e761cf6036.zip
Fixes SI-5373
And adds basic support for scaladoc model tests (class partest.ScaladocModelTest)
-rw-r--r--build.xml3
-rw-r--r--src/compiler/scala/tools/nsc/doc/DocFactory.scala18
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/page/Template.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala5
-rw-r--r--src/partest/scala/tools/partest/ScaladocModelTest.scala124
-rw-r--r--test/scaladoc/run/SI-5373.check1
-rw-r--r--test/scaladoc/run/SI-5373.scala34
-rw-r--r--test/scaladoc/scala/html.flags1
-rw-r--r--test/scaladoc/scalacheck/CommentFactoryTest.scala (renamed from test/scaladoc/scala/model/CommentFactoryTest.scala)0
-rw-r--r--test/scaladoc/scalacheck/HtmlFactoryTest.flags (renamed from test/scaladoc/scala/html/HtmlFactoryTest.flags)0
-rw-r--r--test/scaladoc/scalacheck/HtmlFactoryTest.scala (renamed from test/scaladoc/scala/html/HtmlFactoryTest.scala)4
-rw-r--r--test/scaladoc/scalacheck/IndexScriptTest.scala (renamed from test/scaladoc/scala/IndexScriptTest.scala)2
-rw-r--r--test/scaladoc/scalacheck/IndexTest.scala (renamed from test/scaladoc/scala/IndexTest.scala)2
13 files changed, 182 insertions, 14 deletions
diff --git a/build.xml b/build.xml
index 2f655c2077..b5fead5bec 100644
--- a/build.xml
+++ b/build.xml
@@ -1916,7 +1916,8 @@ BOOTRAPING TEST AND TEST SUITE
<path refid="pack.classpath"/>
<fileset dir="${partest.dir}/files/lib" includes="*.jar" />
</compilationpath>
- <scalachecktests dir="${partest.dir}/scaladoc/scala" includes="**/*.scala" />
+ <runtests dir="${partest.dir}/scaladoc/run" includes="*.scala" />
+ <scalachecktests dir="${partest.dir}/scaladoc/scalacheck" includes="*.scala" />
</partest>
</target>
diff --git a/src/compiler/scala/tools/nsc/doc/DocFactory.scala b/src/compiler/scala/tools/nsc/doc/DocFactory.scala
index 9a025b0d14..f32564f097 100644
--- a/src/compiler/scala/tools/nsc/doc/DocFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/DocFactory.scala
@@ -8,7 +8,7 @@ package doc
import scala.util.control.ControlThrowable
import reporters.Reporter
-import util.NoPosition
+import util.{ NoPosition, BatchSourceFile}
import io.{ File, Directory }
import DocParser.Parsed
@@ -46,13 +46,19 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor
override def forScaladoc = true
}
- /** Creates a scaladoc site for all symbols defined in this call's `files`,
- * as well as those defined in `files` of previous calls to the same processor.
+ /** Creates a scaladoc site for all symbols defined in this call's `source`,
+ * as well as those defined in `sources` of previous calls to the same processor.
* @param files The list of paths (relative to the compiler's source path,
* or absolute) of files to document. */
- def makeUniverse(files: List[String]): Option[Universe] = {
+ def makeUniverse(source: Either[List[String], String]): Option[Universe] = {
assert(settings.docformat.value == "html")
- new compiler.Run() compile files
+ source match {
+ case Left(files) =>
+ new compiler.Run() compile files
+ case Right(sourceCode) =>
+ new compiler.Run() compileSources List(new BatchSourceFile("newSource", sourceCode))
+ }
+
if (reporter.hasErrors)
return None
@@ -111,7 +117,7 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor
docletInstance match {
case universer: Universer =>
- val universe = makeUniverse(files) getOrElse { throw NoCompilerRunException }
+ val universe = makeUniverse(Left(files)) getOrElse { throw NoCompilerRunException }
universer setUniverse universe
docletInstance match {
diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
index c8c5f1ec11..f059b5c0cb 100644
--- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
@@ -35,7 +35,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
</xml:group>
val valueMembers =
- tpl.methods.filterNot(_.isBridge) ++ tpl.values ++ tpl.templates.filter(x => x.isObject || x.isPackage) sorted
+ tpl.methods ++ tpl.values ++ tpl.templates.filter(x => x.isObject || x.isPackage) sorted
val (absValueMembers, nonAbsValueMembers) =
valueMembers partition (_.isAbstract)
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
index 496d004fd8..dd1c75c322 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
@@ -247,7 +247,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
protected lazy val memberSyms =
// Only this class's constructors are part of its members, inherited constructors are not.
- sym.info.members.filter(s => localShouldDocument(s) && (!s.isConstructor || s.owner == sym))
+ sym.info.members.filter(s => localShouldDocument(s) && (!s.isConstructor || s.owner == sym) && !isPureBridge(sym) )
val members = memberSyms flatMap (makeMember(_, this))
val templates = members collect { case c: DocTemplateEntity => c }
@@ -705,4 +705,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
def localShouldDocument(aSym: Symbol): Boolean = {
!aSym.isPrivate && (aSym.isProtected || aSym.privateWithin == NoSymbol) && !aSym.isSynthetic
}
+
+ /** Filter '@bridge' methods only if *they don't override non-bridge methods*. See SI-5373 for details */
+ def isPureBridge(sym: Symbol) = sym.isBridge && sym.allOverriddenSymbols.forall(_.isBridge)
}
diff --git a/src/partest/scala/tools/partest/ScaladocModelTest.scala b/src/partest/scala/tools/partest/ScaladocModelTest.scala
new file mode 100644
index 0000000000..2eb026ceee
--- /dev/null
+++ b/src/partest/scala/tools/partest/ScaladocModelTest.scala
@@ -0,0 +1,124 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Vlad Ureche
+ */
+
+package scala.tools.partest
+
+import scala.tools.partest._
+import java.io._
+import scala.tools.nsc._
+import scala.tools.nsc.util.CommandLineParser
+import scala.tools.nsc.doc.{Settings, DocFactory, Universe}
+import scala.tools.nsc.doc.model._
+import scala.tools.nsc.reporters.ConsoleReporter
+
+/** A class for testing scaladoc model generation
+ * - you need to specify the code in the `code` method
+ * - you need to override the testModel method to test the model
+ * - you may specify extra parameters to send to scaladoc in `scaladocSettings`
+ * {{{
+ import scala.tools.nsc.doc.model._
+ import scala.tools.partest.ScaladocModelTest
+
+ object Test extends ScaladocModelTest {
+
+ def code = """ ... """
+ def scaladocSettings = ""
+ def testModel(rootPackage: Package) = {
+ // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s))
+ import access._
+
+ // just need to check the member exists, access methods will throw an error if there's a problem
+ rootPackage._package("scala")._package("test")._class("C")._method("foo")
+ }
+ }
+ * }}}
+ */
+abstract class ScaladocModelTest extends DirectTest {
+
+ /** Override this to give scaladoc command line parameters */
+ def scaladocSettings: String
+
+ /** Override this to test the model */
+ def testModel(root: Package): Unit
+
+ // Implementation follows:
+ override def extraSettings: String = "-usejavacp"
+
+ override def show(): Unit = {
+ // redirect err to out, for logging
+ val prevErr = System.err
+ System.setErr(System.out)
+
+ try {
+ // 1 - compile with scaladoc and get the model out
+ val args = scaladocSettings.split(" ")
+ val universe = model(args:_*).getOrElse({sys.error("Scaladoc Model Test ERROR: No universe generated!")})
+ // 2 - check the model generated
+ testModel(universe.rootPackage)
+ } catch {
+ case e =>
+ println(e)
+ e.printStackTrace
+ }
+ // set err back to the real err handler
+ System.setErr(prevErr)
+ }
+
+ // create a new scaladoc compiler
+ def newDocFactory(args: String*): DocFactory = {
+ val settings = new Settings(_ => ())
+ val command = new ScalaDoc.Command((CommandLineParser tokenize extraSettings) ++ args.toList, settings)
+ val docFact = new DocFactory(new ConsoleReporter(settings), settings)
+ docFact
+ }
+
+ // compile with scaladoc and output the result
+ def model(args: String*): Option[Universe] = newDocFactory(args: _*).makeUniverse(Right(code))
+
+ // so we don't get the newSettings warning
+ override def isDebug = false
+
+
+ // finally, enable easy navigation inside the entities
+ object access {
+
+ // Make it easy to access things
+ class TemplateAccess(tpl: DocTemplateEntity) {
+
+ def _class(name: String): DocTemplateEntity = getTheFirst(_classes(name), tpl.qualifiedName + ".class(" + name + ")")
+ def _classes(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).flatMap({ case c: Class => List(c)})
+
+ def _trait(name: String): DocTemplateEntity = getTheFirst(_traits(name), tpl.qualifiedName + ".trait(" + name + ")")
+ def _traits(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).flatMap({ case t: Trait => List(t)})
+
+ def _object(name: String): DocTemplateEntity = getTheFirst(_objects(name), tpl.qualifiedName + ".object(" + name + ")")
+ def _objects(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).flatMap({ case o: Object => List(o)})
+
+ def _method(name: String): Def = getTheFirst(_methods(name), tpl.qualifiedName + ".method(" + name + ")")
+ def _methods(name: String): List[Def] = tpl.methods.filter(_.name == name)
+
+ def _value(name: String): Val = getTheFirst(_values(name), tpl.qualifiedName + ".value(" + name + ")")
+ def _values(name: String): List[Val] = tpl.values.filter(_.name == name)
+
+ def getTheFirst[T](list: List[T], expl: String): T = {
+ if (list.length == 1)
+ list.head
+ else if (list.length == 0)
+ sys.error("Error getting " + expl + ": No such element. All elements in list: [" + list.mkString(", ") + "]")
+ else
+ sys.error("Error getting " + expl + ": " + list.length + " elements with this name. " +
+ "All elements in list: [" + list.mkString(", ") + "]")
+ }
+ }
+
+ class PackageAccess(pack: Package) extends TemplateAccess(pack) {
+ def _package(name: String): Package = getTheFirst(_packages(name), pack.qualifiedName + ".package(" + name + ")")
+ def _packages(name: String): List[Package] = pack.packages.filter(_.name == name)
+ }
+
+ implicit def templateAccess(tpl: DocTemplateEntity) = new TemplateAccess(tpl)
+ implicit def packageAccess(pack: Package) = new PackageAccess(pack)
+ }
+}
diff --git a/test/scaladoc/run/SI-5373.check b/test/scaladoc/run/SI-5373.check
new file mode 100644
index 0000000000..c55eb001cf
--- /dev/null
+++ b/test/scaladoc/run/SI-5373.check
@@ -0,0 +1 @@
+model contains 6 documentable templates
diff --git a/test/scaladoc/run/SI-5373.scala b/test/scaladoc/run/SI-5373.scala
new file mode 100644
index 0000000000..af433a1844
--- /dev/null
+++ b/test/scaladoc/run/SI-5373.scala
@@ -0,0 +1,34 @@
+import scala.tools.nsc.doc.model._
+import scala.tools.partest.ScaladocModelTest
+
+object Test extends ScaladocModelTest {
+
+ def code = """
+ import scala.annotation.bridge
+
+ package scala.test {
+
+ trait A {
+ def foo = ()
+ }
+
+ trait B {
+ @bridge()
+ def foo = ()
+ }
+
+ class C extends A with B
+ }
+ """
+
+ // no need for special settings
+ def scaladocSettings = ""
+
+ def testModel(rootPackage: Package) = {
+ // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s))
+ import access._
+
+ // just need to check the member exists, access methods will throw an error if there's a problem
+ rootPackage._package("scala")._package("test")._class("C")._method("foo")
+ }
+} \ No newline at end of file
diff --git a/test/scaladoc/scala/html.flags b/test/scaladoc/scala/html.flags
deleted file mode 100644
index b2264ec4f4..0000000000
--- a/test/scaladoc/scala/html.flags
+++ /dev/null
@@ -1 +0,0 @@
--encoding UTF-8 \ No newline at end of file
diff --git a/test/scaladoc/scala/model/CommentFactoryTest.scala b/test/scaladoc/scalacheck/CommentFactoryTest.scala
index 69c314a64c..69c314a64c 100644
--- a/test/scaladoc/scala/model/CommentFactoryTest.scala
+++ b/test/scaladoc/scalacheck/CommentFactoryTest.scala
diff --git a/test/scaladoc/scala/html/HtmlFactoryTest.flags b/test/scaladoc/scalacheck/HtmlFactoryTest.flags
index b2264ec4f4..b2264ec4f4 100644
--- a/test/scaladoc/scala/html/HtmlFactoryTest.flags
+++ b/test/scaladoc/scalacheck/HtmlFactoryTest.flags
diff --git a/test/scaladoc/scala/html/HtmlFactoryTest.scala b/test/scaladoc/scalacheck/HtmlFactoryTest.scala
index 28c7a4b94f..5b6f75426e 100644
--- a/test/scaladoc/scala/html/HtmlFactoryTest.scala
+++ b/test/scaladoc/scalacheck/HtmlFactoryTest.scala
@@ -50,7 +50,7 @@ object Test extends Properties("HtmlFactory") {
def createTemplates(basename: String) = {
val result = scala.collection.mutable.Map[String, scala.xml.NodeSeq]()
- createFactory.makeUniverse(List(RESOURCES+basename)) match {
+ createFactory.makeUniverse(Left(List(RESOURCES+basename))) match {
case Some(universe) => {
val index = IndexModelFactory.makeIndex(universe)
(new HtmlFactory(universe, index)).writeTemplates((page) => {
@@ -64,7 +64,7 @@ object Test extends Properties("HtmlFactory") {
}
def createReferenceIndex(basename: String) = {
- createFactory.makeUniverse(List(RESOURCES+basename)) match {
+ createFactory.makeUniverse(Left(List(RESOURCES+basename))) match {
case Some(universe) => {
val index = IndexModelFactory.makeIndex(universe)
val pages = index.firstLetterIndex.map({
diff --git a/test/scaladoc/scala/IndexScriptTest.scala b/test/scaladoc/scalacheck/IndexScriptTest.scala
index e0372020fd..5aef38e00a 100644
--- a/test/scaladoc/scala/IndexScriptTest.scala
+++ b/test/scaladoc/scalacheck/IndexScriptTest.scala
@@ -24,7 +24,7 @@ object Test extends Properties("IndexScript") {
val indexModelFactory = doc.model.IndexModelFactory
def createIndexScript(path: String) =
- docFactory.makeUniverse(List(path)) match {
+ docFactory.makeUniverse(Left(List(path))) match {
case Some(universe) => {
val index = new IndexScript(universe,
indexModelFactory.makeIndex(universe))
diff --git a/test/scaladoc/scala/IndexTest.scala b/test/scaladoc/scalacheck/IndexTest.scala
index c14fd98297..29e337da2b 100644
--- a/test/scaladoc/scala/IndexTest.scala
+++ b/test/scaladoc/scalacheck/IndexTest.scala
@@ -37,7 +37,7 @@ object Test extends Properties("Index") {
//val original = Console.out
//Console.setOut(stream)
- val result = docFactory.makeUniverse(List(path))
+ val result = docFactory.makeUniverse(Left(List(path)))
// assert(stream.toString == "model contains 2 documentable templates\n")
//Console.setOut(original)