aboutsummaryrefslogtreecommitdiff
path: root/dottydoc/src/dotty/tools/dottydoc/model/factories.scala
diff options
context:
space:
mode:
authorFelix Mulder <felix.mulder@gmail.com>2016-08-09 18:42:54 +0200
committerFelix Mulder <felix.mulder@gmail.com>2016-08-19 15:37:33 +0200
commit5cd1d51c3cb44b2c9b2c1abd433da50a00e5219e (patch)
tree2f87a0e18b2c44cce28a2b424f2b3b1e97ac1732 /dottydoc/src/dotty/tools/dottydoc/model/factories.scala
parent079e3db0f157ee6eae9e8a34b3bbf7a75cdaa929 (diff)
downloaddotty-5cd1d51c3cb44b2c9b2c1abd433da50a00e5219e.tar.gz
dotty-5cd1d51c3cb44b2c9b2c1abd433da50a00e5219e.tar.bz2
dotty-5cd1d51c3cb44b2c9b2c1abd433da50a00e5219e.zip
Remove client from dottydoc - no more Scala.JS deps!
Diffstat (limited to 'dottydoc/src/dotty/tools/dottydoc/model/factories.scala')
-rw-r--r--dottydoc/src/dotty/tools/dottydoc/model/factories.scala176
1 files changed, 176 insertions, 0 deletions
diff --git a/dottydoc/src/dotty/tools/dottydoc/model/factories.scala b/dottydoc/src/dotty/tools/dottydoc/model/factories.scala
new file mode 100644
index 000000000..b5cf15148
--- /dev/null
+++ b/dottydoc/src/dotty/tools/dottydoc/model/factories.scala
@@ -0,0 +1,176 @@
+package dotty.tools.dottydoc
+package model
+
+import comment._
+import references._
+import dotty.tools.dotc
+import dotc.core.Types._
+import dotc.core.TypeApplications._
+import dotc.core.Flags
+import dotc.core.Contexts.Context
+import dotc.core.Symbols.Symbol
+import dotty.tools.dotc.core.SymDenotations._
+import dotty.tools.dotc.core.Names.TypeName
+import dotc.core.{ Flags => DottyFlags }
+import dotc.ast.Trees._
+
+
+object factories {
+ import dotty.tools.dotc.ast.tpd._
+ import dotty.tools.dottydoc.model.internal.ParamListImpl
+ import DottyFlags._
+
+ type TypeTree = dotty.tools.dotc.ast.Trees.Tree[Type]
+
+ def flags(t: Tree)(implicit ctx: Context): List[String] =
+ (t.symbol.flags & SourceModifierFlags)
+ .flagStrings.toList
+ .filter(_ != "<trait>")
+ .filter(_ != "interface")
+
+ def path(sym: Symbol)(implicit ctx: Context): List[String] = sym match {
+ case sym if sym.name.decode.toString == "<root>" => Nil
+ case sym => path(sym.owner) :+ sym.name.show
+ }
+
+
+ private val product = """Product[1-9][0-9]*""".r
+
+ def returnType(t: Type)(implicit ctx: Context): Reference = {
+ val defn = ctx.definitions
+
+ def typeRef(name: String, query: String = "", params: List[Reference] = Nil) = {
+ val realQuery = if (query != "") query else name
+ TypeReference(name, UnsetLink(name, realQuery), params)
+ }
+
+ def expandTpe(t: Type, params: List[Reference] = Nil): Reference = t match {
+ case tl: TypeLambda =>
+ //FIXME: should be handled correctly
+ // example, in `Option`:
+ //
+ // {{{
+ // def companion: GenericCompanion[collection.Iterable]
+ // }}}
+ //
+ // Becomes: def companion: [+X0] -> collection.Iterable[X0]
+ typeRef(tl.show + " (not handled)")
+ case AppliedType(tycon, args) =>
+ val cls = tycon.typeSymbol
+ if (tycon.isRepeatedParam)
+ expandTpe(args.head)
+ else if (defn.isFunctionClass(cls))
+ FunctionReference(args.init.map(expandTpe(_, Nil)), expandTpe(args.last))
+ else if (defn.isTupleClass(cls))
+ TupleReference(args.map(expandTpe(_, Nil)))
+ else {
+ val query = tycon.show
+ val name = query.split("\\.").last
+ typeRef(name, query, params = args.map(expandTpe(_, Nil)))
+ }
+
+ case ref @ RefinedType(parent, rn, info) =>
+ expandTpe(parent) //FIXME: will be a refined HK, aka class Foo[X] { def bar: List[X] } or similar
+ case ref @ HKApply(tycon, args) =>
+ expandTpe(tycon, args.map(expandTpe(_, params)))
+ case TypeRef(_, n) =>
+ val name = n.decode.toString.split("\\$").last
+ typeRef(name, params = params)
+ case ta: TypeAlias =>
+ expandTpe(ta.alias.widenDealias)
+ case OrType(left, right) =>
+ OrTypeReference(expandTpe(left), expandTpe(right))
+ case AndType(left, right) =>
+ AndTypeReference(expandTpe(left), expandTpe(right))
+ case tb @ TypeBounds(lo, hi) =>
+ BoundsReference(expandTpe(lo), expandTpe(hi))
+ case AnnotatedType(tpe, _) =>
+ expandTpe(tpe)
+ case ExprType(tpe) =>
+ expandTpe(tpe)
+ case c: ConstantType =>
+ ConstantReference(c.show)
+ case tt: ThisType =>
+ expandTpe(tt.underlying)
+ case ci: ClassInfo =>
+ val query = path(ci.typeSymbol).mkString(".")
+ typeRef(ci.cls.name.show, query = query)
+ case mt: MethodType =>
+ expandTpe(mt.resultType)
+ case pt: PolyType =>
+ expandTpe(pt.resultType)
+ case pp: PolyParam =>
+ val paramName = pp.paramName.show
+ val name =
+ if (paramName.contains('$'))
+ paramName.split("\\$\\$").last
+ else paramName
+
+ typeRef(name)
+ }
+
+ expandTpe(t)
+ }
+
+ def typeParams(sym: Symbol)(implicit ctx: Context): List[String] =
+ sym.info match {
+ case pt: PolyType => // TODO: not sure if this case is needed anymore
+ pt.paramNames.map(_.show.split("\\$").last)
+ case ClassInfo(_, _, _, decls, _) =>
+ decls.iterator
+ .filter(_.flags is Flags.TypeParam)
+ .map { tp =>
+ val prefix =
+ if (tp.flags is Flags.Covariant) "+"
+ else if (tp.flags is Flags.Contravariant) "-"
+ else ""
+ prefix + tp.name.show.split("\\$").last
+ }
+ .toList
+ case _ =>
+ Nil
+ }
+
+ def paramLists(tpe: Type)(implicit ctx: Context): List[ParamList] = tpe match {
+ case pt: PolyType =>
+ paramLists(pt.resultType)
+
+ case mt: MethodType =>
+ ParamListImpl(mt.paramNames.zip(mt.paramTypes).map { case (name, tpe) =>
+ NamedReference(
+ name.decode.toString,
+ returnType(tpe),
+ isByName = tpe.isInstanceOf[ExprType],
+ isRepeated = tpe.isRepeatedParam
+ )
+ }, mt.isImplicit) :: paramLists(mt.resultType)
+
+ case annot: AnnotatedType => paramLists(annot.tpe)
+ case (_: PolyParam | _: RefinedType | _: TypeRef | _: ThisType |
+ _: ExprType | _: OrType | _: AndType | _: HKApply) => Nil // return types should not be in the paramlist
+ }
+
+ def superTypes(t: Tree)(implicit ctx: Context): List[MaterializableLink] = t.symbol.denot match {
+ case cd: ClassDenotation =>
+ def isJavaLangObject(prefix: Type): Boolean =
+ prefix match {
+ case TypeRef(ThisType(TypeRef(NoPrefix, outerName)), innerName) =>
+ outerName.toString == "lang" && innerName.toString == "Object"
+ case _ => false
+ }
+
+ def isProductWithArity(prefix: Type): Boolean = prefix match {
+ case TypeRef(TermRef(TermRef(NoPrefix, root), scala), prod) =>
+ root.toString == "_root_" &&
+ scala.toString == "scala" &&
+ product.findFirstIn(prod.toString).isDefined
+ case _ => false
+ }
+
+ cd.classParents.collect {
+ case t: TypeRef if !isJavaLangObject(t) && !isProductWithArity(t) =>
+ UnsetLink(t.name.toString, path(t.symbol).mkString("."))
+ }
+ case _ => Nil
+ }
+}