Skip to content

Commit 807d775

Browse files
committed
MIgrate away from Kotlin Documentable
Scala3doc was only loosly using dokka model and it has started to blocking us. This PR standarize over Member and expand semantic of Kind. This allow us to have more typesafe way to reason about code. It will also make migration away from dokka easier if needed.
1 parent 266725f commit 807d775

21 files changed

+508
-543
lines changed

scala3doc-testcases/src/tests/extensionMethodSignatures.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ class ClassOne
1717
extension (c: ClassTwo)
1818
def |||:(a: Int, b: Int, d: Int)(e: String): Int
1919
= 56
20+
def ++:(a: Int): Int
21+
= 45
2022

2123
extension (b: Int)
2224
def secondGroup(): String

scala3doc-testcases/src/tests/givenSignatures.scala

Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,15 @@ package tests
22

33
package givenSignatures
44

5+
object Obj
56

7+
given Seq[String] = Nil
68

7-
class GivenClass {
8-
trait B
9-
trait C[T]
10-
val r: Int = 5
11-
type R = Int
12-
given R = r
13-
trait Ord[T] {
14-
def compare(x: T, y: T): Int
15-
extension (x: T) def < (y: T) = compare(x, y) < 0
16-
extension (x: T) def > (y: T) = compare(x, y) > 0
17-
}
18-
given intOrd: Ord[Int] with {
19-
def compare(x: Int, y: Int) =
20-
if (x < y) -1 else if (x > y) +1 else 0
21-
}
9+
given GivenType = GivenType()
2210

23-
given asd(using int: Int): B with {}
11+
class GivenType
2412

25-
given asd2[T]: C[T] with {}
26-
27-
given listOrd[T](using ord: Ord[T]): Ord[List[T]] with {
28-
29-
def compare(xs: List[T], ys: List[T]): Int = (xs, ys) match
30-
case (Nil, Nil) => 0
31-
case (Nil, _) => -1
32-
case (_, Nil) => +1
33-
case (x :: xs1, y :: ys1) =>
34-
val fst = ord.compare(x, y)
35-
if (fst != 0) fst else compare(xs1, ys1)
36-
}
37-
38-
given IntOps: Int.type = Int
39-
40-
given GivenType = GivenType()
41-
42-
class GivenType
43-
}
13+
trait Ord[T]
4414

15+
given listOrd[T](using ord: Ord[T]): Ord[List[T]]
16+
= ???
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package tests
2+
3+
package givenSignaturesPg
4+
5+
6+
7+
class GivenClass {
8+
trait B
9+
trait C[T]
10+
val r: Int = 5
11+
type R = Int
12+
given R = r
13+
trait Ord[T] {
14+
def compare(x: T, y: T): Int
15+
extension (x: T) def < (y: T) = compare(x, y) < 0
16+
extension (x: T) def > (y: T) = compare(x, y) > 0
17+
}
18+
given intOrd: Ord[Int] with {
19+
def compare(x: Int, y: Int) =
20+
if (x < y) -1 else if (x > y) +1 else 0
21+
}
22+
23+
given asd(using int: Int): B with {}
24+
25+
given asd2[T]: C[T] with {}
26+
27+
given listOrd[T](using ord: Ord[T]): Ord[List[T]] with {
28+
29+
def compare(xs: List[T], ys: List[T]): Int = (xs, ys) match
30+
case (Nil, Nil) => 0
31+
case (Nil, _) => -1
32+
case (_, Nil) => +1
33+
case (x :: xs1, y :: ys1) =>
34+
val fst = ord.compare(x, y)
35+
if (fst != 0) fst else compare(xs1, ys1)
36+
}
37+
38+
given IntOps: Int.type = Int
39+
40+
given GivenType = GivenType()
41+
42+
class GivenType
43+
}
44+

scala3doc-testcases/src/tests/methodsAndConstructors.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,10 @@ class Methods:
4747

4848
def arrays(a: Array[String], b: Array[Int]): Array[Double]
4949
= ???
50+
51+
def rightA1(a: Int): Int
52+
= ???
53+
54+
def ++:(a: Int)(b: Double): Int
55+
= ???
56+

scala3doc-testcases/src/tests/modifiersSignatureTestSource.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ abstract class Methods()
2424

2525
implicit def toImplicitString(): String
2626
= "asd"
27+
28+
inline def method2(inline name: String): String
29+
= "ala"
2730
}
2831

2932
class ImplementedMethods() extends Methods/*<-*/()/*->*/

scala3doc/src/dotty/dokka/DocContext.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ case class DocContext(args: Scala3doc.Args, compilerContext: CompilerContext)
7575
override def getOfflineMode: Boolean = false
7676
override def getFailOnWarning: Boolean = false
7777
override def getSourceSets: JList[DokkaSourceSet] = JList(mkSourceSet)
78-
override def getModules: JList[DokkaConfiguration.DokkaModuleDescription] = JList()
79-
override def getPluginsClasspath: JList[File] = JList()
78+
override def getModules: JList[DokkaConfiguration.DokkaModuleDescription] = JNil
79+
override def getPluginsClasspath: JList[File] = JNil
8080
override def getModuleName(): String = "ModuleName"
8181
override def getModuleVersion(): String = ""
8282

@@ -94,13 +94,13 @@ case class DocContext(args: Scala3doc.Args, compilerContext: CompilerContext)
9494
)(using compilerContext))
9595

9696
override def getPluginsConfiguration: JList[DokkaConfiguration.PluginConfiguration] =
97-
JList()
97+
JNil
9898

9999
val mkSourceSet: DokkaSourceSet =
100100
new DokkaSourceSetImpl(
101101
/*displayName=*/ args.name,
102102
/*sourceSetID=*/ new DokkaSourceSetID(args.name, "main"),
103-
/*classpath=*/ JList(),
103+
/*classpath=*/ JNil,
104104
/*sourceRoots=*/ JSet(),
105105
/*dependentSourceSets=*/ JSet(),
106106
/*samples=*/ JSet(),

scala3doc/src/dotty/dokka/DottyDokkaPlugin.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,9 @@ class DottyDokkaPlugin extends DokkaJavaPlugin:
120120

121121
val implicitMembersExtensionTransformer = extend(
122122
_.extensionPoint(CoreExtensions.INSTANCE.getDocumentableTransformer)
123-
.fromRecipe(ImplicitMembersExtensionTransformer(_))
124-
.name("implicitMembersExtensionTransformer")
123+
.fromRecipe { case ctx @ given DokkaContext =>
124+
new ImplicitMembersExtensionTransformer
125+
}.name("implicitMembersExtensionTransformer")
125126
)
126127

127128
val customDocumentationProvider = extend(

scala3doc/src/dotty/dokka/compat.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ type JMap[K, V] = java.util.Map[K, V]
2828
type JHashMap[K, V] = java.util.HashMap[K, V]
2929
type JMapEntry[K, V] = java.util.Map.Entry[K, V]
3030

31+
private val emptyListInst = JList()
32+
def JNil[A] = emptyListInst.asInstanceOf[JList[A]]
33+
34+
private val emptyMapInst = JMap()
35+
def emptyJMap[A, B] = emptyMapInst.asInstanceOf[JMap[A, B]]
36+
3137
type DRI = org.jetbrains.dokka.links.DRI
3238
val topLevelDri = org.jetbrains.dokka.links.DRI.Companion.getTopLevel
3339

scala3doc/src/dotty/dokka/model/api/api.scala

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,20 +53,26 @@ trait ImplicitConversionProvider { def conversion: Option[ImplicitConversion] }
5353
trait Classlike
5454

5555
enum Kind(val name: String){
56-
case Class extends Kind("class") with Classlike
56+
case Class(typeParams: Seq[TypeParameter], argsLists: Seq[Seq[Parameter]])
57+
extends Kind("class") with Classlike
5758
case Object extends Kind("object") with Classlike
58-
case Trait extends Kind("trait") with Classlike
59+
case Trait(typeParams: Seq[TypeParameter], argsLists: Seq[Seq[Parameter]])
60+
extends Kind("trait") with Classlike
5961
case Enum extends Kind("enum") with Classlike
60-
case EnumCase extends Kind("case")
61-
case Def extends Kind("def")
62-
case Extension(on: ExtensionTarget) extends Kind("def")
63-
case Constructor extends Kind("def")
62+
case EnumCase(kind: Object.type | Type | Val.type) extends Kind("case")
63+
case Def(typeParams: Seq[TypeParameter], argsLists: Seq[Seq[Parameter]])
64+
extends Kind("def")
65+
case Extension(on: ExtensionTarget, m: Kind.Def) extends Kind("def")
66+
case Constructor(base: Kind.Def) extends Kind("def")
6467
case Var extends Kind("var")
6568
case Val extends Kind("val")
66-
case Exported extends Kind("export")
67-
case Type(concreate: Boolean, opaque: Boolean) extends Kind("Type") // should we handle opaque as modifier?
68-
case Given(as: Option[Signature], conversion: Option[ImplicitConversion]) extends Kind("Given") with ImplicitConversionProvider
69-
case Implicit(kind: Kind, conversion: Option[ImplicitConversion]) extends Kind(kind.name) with ImplicitConversionProvider
69+
case Exported(m: Kind.Def) extends Kind("export")
70+
case Type(concreate: Boolean, opaque: Boolean, typeParams: Seq[TypeParameter])
71+
extends Kind("Type") // should we handle opaque as modifier?
72+
case Given(kind: Def | Class, as: Option[Signature], conversion: Option[ImplicitConversion])
73+
extends Kind("Given") with ImplicitConversionProvider
74+
case Implicit(kind: Kind.Def | Kind.Val.type, conversion: Option[ImplicitConversion])
75+
extends Kind(kind.name) with ImplicitConversionProvider
7076
case Unknown extends Kind("Unknown")
7177
}
7278

@@ -87,6 +93,23 @@ object Annotation:
8793
case class LinkParameter(name: Option[String] = None, dri: DRI, value: String) extends AnnotationParameter
8894
case class UnresolvedParameter(name: Option[String] = None, unresolvedText: String) extends AnnotationParameter
8995

96+
case class Parameter(
97+
annotations: Seq[Annotation],
98+
modifiers: String,
99+
name: String,
100+
dri: DRI,
101+
signature: Signature,
102+
isExtendedSymbol: Boolean = false,
103+
isGrouped: Boolean = false
104+
)
105+
106+
case class TypeParameter(
107+
variance: "" | "+" | "-",
108+
name: String,
109+
dri: DRI,
110+
signature: Signature
111+
)
112+
90113
// TODO (longterm) properly represent signatures
91114
case class Link(name: String, dri: DRI)
92115
type Signature = Seq[String | Link]
@@ -110,7 +133,7 @@ object HierarchyGraph:
110133
def withEdges(edges: Seq[(LinkToType, LinkToType)]) = HierarchyGraph.empty ++ edges
111134

112135

113-
type Member = Documentable // with WithExtraProperty[_] // Kotlin does not add generics to ExtraProperty implemented by e.g. DFunction
136+
type Member = Documentable
114137

115138
object Member:
116139
def unapply(d: Documentable): Option[(String, DRI, Visibility, Kind, Origin)] =
@@ -141,9 +164,10 @@ extension[T] (member: Member):
141164
def parents: Seq[LinkToType] = compositeMemberExt.fold(Nil)(_.parents)
142165
def directParents: Seq[Signature] = compositeMemberExt.fold(Nil)(_.directParents)
143166
def knownChildren: Seq[LinkToType] = compositeMemberExt.fold(Nil)(_.knownChildren)
167+
def companion: Option[DRI] = compositeMemberExt.fold(None)(_.companion)
144168

145-
def membersBy(op: Member => Boolean): (Seq[Member], Seq[Member]) = allMembers.filter(op).partition(_.origin == Origin.DefinedWithin)
146169

170+
def membersBy(op: Member => Boolean): (Seq[Member], Seq[Member]) = allMembers.filter(op).partition(_.origin == Origin.DefinedWithin)
147171

148172
extension (module: DModule):
149173
def driMap: Map[DRI, Member] = ModuleExtension.getFrom(module).fold(Map.empty)(_.driMap)

scala3doc/src/dotty/dokka/model/api/internalExtensions.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import collection.JavaConverters._
2020
import org.jetbrains.dokka.model.doc.DocumentationNode
2121
import org.jetbrains.dokka.model.properties._
2222

23-
private [model] case class MemberExtension(
23+
case class MemberExtension(
2424
visibility: Visibility,
2525
modifiers: Seq[dotty.dokka.model.api.Modifier],
2626
kind: Kind,
@@ -39,7 +39,8 @@ case class CompositeMemberExtension(
3939
members : Seq[Member] = Nil,
4040
directParents: Seq[Signature] = Nil,
4141
parents: Seq[LinkToType] = Nil,
42-
knownChildren: Seq[LinkToType] = Nil
42+
knownChildren: Seq[LinkToType] = Nil,
43+
companion: Option[DRI] = None,
4344
) extends ExtraProperty[Documentable]:
4445
override def getKey = CompositeMemberExtension
4546

scala3doc/src/dotty/dokka/model/extras.scala

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,3 @@ case class ModuleExtension(driMap: Map[DRI, Member]) extends ExtraProperty[DModu
1313
override def getKey = ModuleExtension
1414

1515
object ModuleExtension extends BaseKey[DModule, ModuleExtension]
16-
17-
case class MethodExtension(parametersListSizes: Seq[Int]) extends ExtraProperty[DFunction]:
18-
override def getKey = MethodExtension
19-
20-
object MethodExtension extends BaseKey[DFunction, MethodExtension]
21-
22-
case class ParameterExtension(isExtendedSymbol: Boolean, isGrouped: Boolean) extends ExtraProperty[DParameter]:
23-
override def getKey = ParameterExtension
24-
25-
object ParameterExtension extends BaseKey[DParameter, ParameterExtension]
26-
27-
case class ClasslikeExtension(
28-
constructor: Option[DFunction], // will be replaced by signature
29-
companion: Option[DRI], // moved to kind?
30-
) extends ExtraProperty[DClasslike]:
31-
override def getKey = ClasslikeExtension
32-
33-
object ClasslikeExtension extends BaseKey[DClasslike, ClasslikeExtension]
34-
35-
case class IsInherited(flag: Boolean) extends ExtraProperty[Documentable]:
36-
override def getKey = IsInherited
37-
38-
object IsInherited extends BaseKey[Documentable, IsInherited]

scala3doc/src/dotty/dokka/tasty/BasicSupport.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,6 @@ trait BasicSupport:
4848
def getAnnotations(): List[Annotation] =
4949
sym.annotations.filterNot(_.symbol.packageName.startsWith("scala.annotation.internal")).map(parseAnnotation).reverse
5050

51+
def isLeftAssoc: Boolean = !sym.name.endsWith(":")
52+
5153

0 commit comments

Comments
 (0)