From fe1ff8f0570d3d582a884a9b8f35a14235c0c71f Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 19 Jul 2016 15:19:04 +0200 Subject: Fix #28: render functions passed as arguments --- dottydoc/js/src/html/Member.scala | 50 +++++++++++++++++++++- dottydoc/js/src/model/references.scala | 12 ++++++ .../jvm/src/dotty/tools/dottydoc/model/json.scala | 4 ++ .../dottydoc/model/comment/BodyEntities.scala | 2 + .../dotty/tools/dottydoc/model/factories.scala | 38 ++++++++-------- 5 files changed, 85 insertions(+), 21 deletions(-) (limited to 'dottydoc') diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala index 271885753..1d84e7831 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -119,7 +119,7 @@ trait MemberLayout { "[", tref .paramLinks - .map(linkToAnchor) + .map(referenceToLinks) .flatMap(link => Seq(link, span(cls := "type-separator no-left-margin", ",").render)) .toList.dropRight(1), "]" @@ -141,6 +141,30 @@ trait MemberLayout { span(cls := "type-separator", "&"), referenceToLinks(right) ).render + + case "BoundsReference" => + val (low, high) = (ref.asInstanceOf[BoundsReference].low, ref.asInstanceOf[BoundsReference].high) + span( + referenceToLinks(low), + span(cls := "type-separator", "<:"), + referenceToLinks(high) + ).render + + case "FunctionReference" => { + val func = ref.asInstanceOf[FunctionReference] + span( + cls := "no-left-margin", + if (func.args.length > 1) "(" else "", + if (func.args.isEmpty) + span("()") + else func + .args + .map(referenceToLinks) + .flatMap(link => Seq(link, span(cls := "type-separator no-left-margin", ",").render)).init.toList, + if (func.args.length > 1) ") => " else " => ", + referenceToLinks(func.returnValue) + ).render + } } } @@ -183,7 +207,7 @@ trait MemberLayout { returnValue, "[", trv.paramLinks - .map(decodeTpeLink) + .map(link) .flatMap { sp => Seq(sp, span(cls := "type-separator no-left-margin", ",").render) } @@ -208,6 +232,28 @@ trait MemberLayout { span(cls := "type-separator", "&"), link(right) ).render + + case "BoundsReference" => + val (low, high) = (rv.asInstanceOf[BoundsReference].low, rv.asInstanceOf[BoundsReference].high) + span( + link(low), + span(cls := "type-separator", "<:"), + link(high) + ).render + case "FunctionReference" => + val func = rv.asInstanceOf[FunctionReference] + span( + cls := "no-left-margin", + if (func.args.length > 1) "(" else "", + if (func.args.isEmpty) + span("()") + else func + .args + .map(link) + .flatMap(link => Seq(link, span(cls := "type-separator no-left-margin", ",").render)).init.toList, + if (func.args.length > 1) ") => " else " => ", + link(func.returnValue) + ).render } } diff --git a/dottydoc/js/src/model/references.scala b/dottydoc/js/src/model/references.scala index b0e8a8674..7cd396e94 100644 --- a/dottydoc/js/src/model/references.scala +++ b/dottydoc/js/src/model/references.scala @@ -31,6 +31,12 @@ trait AndTypeReference extends Reference { val right: Reference } +@ScalaJSDefined +trait BoundsReference extends Reference { + val low: Reference + val high: Reference +} + @ScalaJSDefined trait NamedReference extends Reference { val title: String @@ -43,6 +49,12 @@ trait ConstantReference extends Reference { val title: String } +@ScalaJSDefined +trait FunctionReference extends Reference { + val args: sjs.Array[Reference] + val returnValue: Reference +} + /** Materializable links */ @ScalaJSDefined sealed trait MaterializableLink extends sjs.Object { diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala index 621ab0868..52bb9d36c 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala @@ -46,10 +46,14 @@ object json { s"""{"left":${refToJson(ref.left)},"right":${refToJson(ref.right)},"kind":"AndTypeReference"}""" case ref: OrTypeReference => s"""{"left":${refToJson(ref.left)},"right":${refToJson(ref.right)},"kind":"OrTypeReference"}""" + case ref: BoundsReference => + s"""{"low":${refToJson(ref.low)},"high":${refToJson(ref.high)},"kind":"BoundsReference"}""" case ref: NamedReference => s"""{"title":${ref.title.json},"ref":${refToJson(ref.ref)},"isByName":${ref.isByName.json},"kind":"NamedReference"}""" case ref: ConstantReference => s"""{"title":${ref.title.json},"kind": "ConstantReference"}""" + case ref: FunctionReference => + s"""{"args":${ref.args.map(refToJson).mkString("[",",","]")},"returnValue":${refToJson(ref.returnValue)},"kind": "FunctionReference"}""" } implicit class ReferenceJson(val ref: Reference) extends AnyVal { def json: String = refToJson(ref) } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala index 691661ac5..b8918c493 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala @@ -103,5 +103,7 @@ sealed trait Reference final case class TypeReference(title: String, tpeLink: MaterializableLink, paramLinks: List[Reference]) extends Reference final case class OrTypeReference(left: Reference, right: Reference) extends Reference final case class AndTypeReference(left: Reference, right: Reference) extends Reference +final case class FunctionReference(args: List[Reference], returnValue: Reference) extends Reference +final case class BoundsReference(low: Reference, high: Reference) extends Reference final case class NamedReference(title: String, ref: Reference, isByName: Boolean = false) extends Reference final case class ConstantReference(title: String) extends Reference diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index 8453b528f..a48f6d9b0 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -55,25 +55,23 @@ object factories { TypeReference(name, UnsetLink(name, realQuery), params) } - def expandTpe(t: Type, params: List[MaterializableLink] = Nil): Reference = t match { - case ref @ RefinedType(parent, rn, info) => { - val paramName = (info match { - case ta: TypeAlias if ta.alias.isInstanceOf[NamedType] => - ta.alias.asInstanceOf[NamedType].name.show - case _ => rn.show - }).split("\\$").last - val param = UnsetLink(paramName, paramName) - expandTpe(parent, param :: params) - } - case HKApply(tycon, args) => - def paramName: Type => String = { tpe => - (tpe match { - case ta: TypeAlias if ta.alias.isInstanceOf[NamedType] => - ta.alias.asInstanceOf[NamedType].name.show - case _ => tpe.show - }).split("\\$").last - } - expandTpe(tycon, args.map(paramName).map(x => UnsetLink(x,x))) + 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) => + FunctionReference(args.init.map(expandTpe(_, Nil)), expandTpe(args.last)) + 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) @@ -83,6 +81,8 @@ object factories { 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) => -- cgit v1.2.3