@@ -14,7 +14,8 @@ import symtab.Flags
1414import model .{ RootPackage => RootPackageEntity }
1515
1616/** This trait extracts all required information for documentation from compilation units */
17- class ModelFactory (val global : Global , val settings : doc.Settings ) { thisFactory : ModelFactory with CommentFactory with TreeFactory =>
17+ class ModelFactory (val global : Global , val settings : doc.Settings ) {
18+ thisFactory : ModelFactory with CommentFactory with TreeFactory =>
1819
1920 import global ._
2021 import definitions .{ ObjectClass , ScalaObjectClass , RootPackage , EmptyPackage , NothingClass , AnyClass , AnyValClass , AnyRefClass }
@@ -24,6 +25,20 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { thisFactory
2425
2526 private var modelFinished = false
2627 private var universe : Universe = null
28+
29+ private def dbg (msg : String ) = if (sys.props contains " scala.scaladoc.debug" ) println(msg)
30+ private def closestPackage (sym : Symbol ) = {
31+ if (sym.isPackage || sym.isPackageClass) sym
32+ else sym.enclosingPackage
33+ }
34+
35+ private def printWithoutPrefix (memberSym : Symbol , templateSym : Symbol ) = {
36+ dbg(
37+ " memberSym " + memberSym + " templateSym " + templateSym + " encls = " +
38+ closestPackage(memberSym) + " , " + closestPackage(templateSym)
39+ )
40+ memberSym.inDefaultNamespace || (closestPackage(memberSym) == closestPackage(templateSym))
41+ }
2742
2843 private lazy val noSubclassCache = Set (AnyClass , AnyRefClass , ObjectClass , ScalaObjectClass )
2944
@@ -33,18 +48,18 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { thisFactory
3348 thisFactory.universe = thisUniverse
3449 val settings = thisFactory.settings
3550 private val rootPackageMaybe = makeRootPackage
36- val rootPackage = rootPackageMaybe getOrElse null
51+ val rootPackage = rootPackageMaybe.orNull
3752 }
3853 modelFinished = true
39- if (universe.rootPackage != null ) Some (universe) else None
54+ Some (universe) filter (_ .rootPackage != null )
4055 }
4156
4257 /** */
4358 protected val templatesCache =
4459 new mutable.LinkedHashMap [Symbol , DocTemplateImpl ]
4560
4661 def findTemplate (query : String ): Option [DocTemplateImpl ] = {
47- if (! modelFinished) throw new Error (" cannot find template in unfinished universe" )
62+ if (! modelFinished) sys.error (" cannot find template in unfinished universe" )
4863 templatesCache.values find { tpl => tpl.qualifiedName == query && ! tpl.isObject }
4964 }
5065
@@ -53,8 +68,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { thisFactory
5368
5469 /* ============== IMPLEMENTATION PROVIDING ENTITY TYPES ============== */
5570
56- /** Provides a default implementation for instances of the `Entity` type. */
57- abstract class EntityImpl (val sym : Symbol , inTpl : => TemplateImpl ) extends Entity {
71+ abstract class EntityImpl (val sym : Symbol , inTpl : => TemplateImpl ) extends Entity {
5872 val name = optimize(sym.nameString)
5973 def inTemplate : TemplateImpl = inTpl
6074 def toRoot : List [EntityImpl ] = this :: inTpl.toRoot
@@ -63,8 +77,6 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { thisFactory
6377 def annotations = sym.annotations.map(makeAnnotation)
6478 }
6579
66- /** Provides a default implementation for instances of the `WeakTemplateEntity` type. It must be instantiated as a
67- * `SymbolicEntity` to access the compiler symbol that underlies the entity. */
6880 trait TemplateImpl extends EntityImpl with TemplateEntity {
6981 override def qualifiedName : String =
7082 if (inTemplate.isRootPackage) name else optimize(inTemplate.qualifiedName + " ." + name)
@@ -77,14 +89,10 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { thisFactory
7789 def selfType = if (sym.thisSym eq sym) None else Some (makeType(sym.thisSym.typeOfThis, this ))
7890 }
7991
80- /** Provides a default implementation for instances of the `WeakTemplateEntity` type. It must be instantiated as a
81- * `SymbolicEntity` to access the compiler symbol that underlies the entity. */
8292 class NoDocTemplateImpl (sym : Symbol , inTpl : => TemplateImpl ) extends EntityImpl (sym, inTpl) with TemplateImpl with NoDocTemplate {
8393 def isDocTemplate = false
8494 }
8595
86- /** Provides a default implementation for instances of the `MemberEntity` type. It must be instantiated as a
87- * `SymbolicEntity` to access the compiler symbol that underlies the entity. */
8896 abstract class MemberImpl (sym : Symbol , inTpl : => DocTemplateImpl ) extends EntityImpl (sym, inTpl) with MemberEntity {
8997 lazy val comment =
9098 if (inTpl == null ) None else thisFactory.comment(sym, inTpl)
@@ -152,14 +160,9 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { thisFactory
152160 def isTemplate = false
153161 }
154162
155- /** Provides a default implementation for instances of the `TemplateEntity` type. It must be instantiated as a
156- * `TemplateSymbolicEntity` to access the compiler symbol that underlies the entity and to be registered with the
157- * `templatesCache` at the very start of its instantiation.
158- *
159- * The instantiation of `TemplateImpl` triggers the creation of the following entities.
160- * * The owner of the template (as a full template);
161- * * All ancestors of the template (as weak templates);
162- * * All non-package members (including other templates, as full templates). */
163+ /** The instantiation of `TemplateImpl` triggers the creation of the following entities:
164+ * All ancestors of the template and all non-package members.
165+ */
163166 abstract class DocTemplateImpl (sym : Symbol , inTpl : => DocTemplateImpl ) extends MemberImpl (sym, inTpl) with TemplateImpl with HigherKindedImpl with DocTemplateEntity {
164167 // if (inTpl != null) println("mbr " + sym + " in " + (inTpl.toRoot map (_.sym)).mkString(" > "))
165168 if (settings.verbose.value)
@@ -176,10 +179,8 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { thisFactory
176179
177180 def sourceUrl = {
178181 def fixPath (s : String ) = s.replaceAll(" \\ " + java.io.File .separator, " /" )
179- val assumedSourceRoot : String = {
180- val fixed = fixPath(settings.sourcepath.value)
181- if (fixed endsWith " /" ) fixed.dropRight(1 ) else fixed
182- }
182+ val assumedSourceRoot = fixPath(settings.sourcepath.value) stripSuffix " /"
183+
183184 if (! settings.docsourceurl.isDefault)
184185 inSource map { case (file, _) =>
185186 val filePath = fixPath(file.path).replaceFirst(" ^" + assumedSourceRoot, " " ).stripSuffix(" .scala" )
@@ -204,16 +205,16 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { thisFactory
204205 }
205206 }
206207 val linearization : List [(TemplateEntity , TypeEntity )] = {
207- val acs = sym.ancestors filterNot (_ == ScalaObjectClass )
208- val tps = acs map (cls => makeType(sym.info.baseType(cls ), this ) )
209- val tpls = acs map makeTemplate
210-
211- tpls foreach {
212- case dtpl : DocTemplateImpl => dtpl.registerSubClass( this )
213- case _ =>
208+ sym.ancestors filter (_ != ScalaObjectClass ) map { ancestor =>
209+ val typeEntity = makeType(sym.info.baseType(ancestor ), this )
210+ val tmplEntity = makeTemplate(ancestor) match {
211+ case tmpl : DocTemplateImpl => tmpl registerSubClass this ; tmpl
212+ case tmpl => tmpl
213+ }
214+ (tmplEntity, typeEntity)
214215 }
215- tpls zip tps
216216 }
217+
217218 def linearizationTemplates = linearization map { _._1 }
218219 def linearizationTypes = linearization map { _._2 }
219220
@@ -545,7 +546,9 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { thisFactory
545546 }
546547
547548 /** */
548- def makeType (aType : Type , inTpl : => TemplateImpl ): TypeEntity =
549+ def makeType (aType : Type , inTpl : => TemplateImpl ): TypeEntity = {
550+ def templatePackage = closestPackage(inTpl.sym)
551+
549552 new TypeEntity {
550553 private val nameBuffer = new StringBuilder
551554 private var refBuffer = new immutable.TreeMap [Int , (TemplateEntity , Int )]
@@ -558,18 +561,15 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { thisFactory
558561 nameBuffer append sep
559562 appendTypes0(tps, sep)
560563 }
561- private def checkFunctionType (tpe : TypeRef ): Boolean = {
562- val TypeRef (_, sym, args) = tpe
563- (args.length > 0 ) && (args.length - 1 <= definitions.MaxFunctionArity ) &&
564- (sym == definitions.FunctionClass (args.length - 1 ))
565- }
564+
566565 private def appendType0 (tpe : Type ): Unit = tpe match {
567566 /* Type refs */
568- case tp : TypeRef if (checkFunctionType(tp)) =>
567+ case tp : TypeRef if definitions.isFunctionType(tp) =>
568+ val args = tp.normalize.typeArgs
569569 nameBuffer append '('
570- appendTypes0(tp. args.init, " , " )
570+ appendTypes0(args.init, " , " )
571571 nameBuffer append " ) ⇒ "
572- appendType0(tp. args.last)
572+ appendType0(args.last)
573573 case tp : TypeRef if definitions.isScalaRepeatedParamType(tp) =>
574574 appendType0(tp.args.head)
575575 nameBuffer append '*'
@@ -581,6 +581,18 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { thisFactory
581581 appendTypes0(tp.args, " , " )
582582 nameBuffer append ')'
583583 case TypeRef (pre, aSym, targs) =>
584+ val preSym = pre.widen.typeSymbol
585+ // There's a work in progress here trying to deal with the
586+ // places where undesirable prefixes are printed.
587+ // ...
588+ // If the prefix is something worthy of printing, see if the prefix type
589+ // is in the same package as the enclosing template. If so, print it
590+ // unqualified and they'll figure it out.
591+ //
592+ // val stripPrefixes = List(templatePackage.fullName + ".", "package.", "java.lang.")
593+ // if (!preSym.printWithoutPrefix) {
594+ // nameBuffer append stripPrefixes.foldLeft(pre.prefixString)(_ stripPrefix _)
595+ // }
584596 val bSym = normalizeTemplate(aSym)
585597 if (bSym.isNonClassType)
586598 nameBuffer append bSym.name
@@ -597,7 +609,12 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { thisFactory
597609 }
598610 /* Refined types */
599611 case RefinedType (parents, defs) =>
600- appendTypes0((if (parents.length > 1 ) parents filterNot (_ == ObjectClass .tpe) else parents), " with " )
612+ val ignoreParents = Set (AnyClass , ObjectClass )
613+ val filtParents = parents filterNot (x => ignoreParents(x.typeSymbol)) match {
614+ case Nil => parents
615+ case ps => ps
616+ }
617+ appendTypes0(filtParents, " with " )
601618 // XXX Still todo: properly printing refinements.
602619 // Since I didn't know how to go about displaying a multi-line type, I went with
603620 // printing single method refinements (which should be the most common) and printing
@@ -627,6 +644,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { thisFactory
627644 val refEntity = refBuffer
628645 val name = optimize(nameBuffer.toString)
629646 }
647+ }
630648
631649 def templateShouldDocument (aSym : Symbol ): Boolean = {
632650 // TODO: document sourceless entities (e.g., Any, etc), based on a new Setting to be added
0 commit comments