diff options
author | Felix Mulder <felix.mulder@gmail.com> | 2016-08-09 18:42:54 +0200 |
---|---|---|
committer | Felix Mulder <felix.mulder@gmail.com> | 2016-08-19 15:37:33 +0200 |
commit | 5cd1d51c3cb44b2c9b2c1abd433da50a00e5219e (patch) | |
tree | 2f87a0e18b2c44cce28a2b424f2b3b1e97ac1732 /dottydoc/src/dotty/tools/dottydoc/model/factories.scala | |
parent | 079e3db0f157ee6eae9e8a34b3bbf7a75cdaa929 (diff) | |
download | dotty-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.scala | 176 |
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 + } +} |