Skip to content

Commit 85e48f7

Browse files
authored
Merge pull request #10504 from BarkingBad/scala3doc-exports
Handle exports presenting in scala3doc
2 parents 377ce48 + 1efc4af commit 85e48f7

File tree

14 files changed

+91
-7
lines changed

14 files changed

+91
-7
lines changed

compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2464,6 +2464,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
24642464
def EmptyFlags = dotc.core.Flags.EmptyFlags
24652465
def Enum: Flags = dotc.core.Flags.Enum
24662466
def Erased: Flags = dotc.core.Flags.Erased
2467+
def Exported: Flags = dotc.core.Flags.Exported
24672468
def ExtensionMethod: Flags = dotc.core.Flags.ExtensionMethod
24682469
def FieldAccessor: Flags = dotc.core.Flags.Accessor
24692470
def Final: Flags = dotc.core.Flags.Final

compiler/src/scala/quoted/runtime/impl/printers/Extractors.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ object Extractors {
2929
if (flags.is(Flags.Enum)) flagList += "Flags.Enum"
3030
if (flags.is(Flags.Erased)) flagList += "Flags.Erased"
3131
if (flags.is(Flags.ExtensionMethod)) flagList += "Flags.ExtensionMethod"
32+
if (flags.is(Flags.Exported)) flagList += "Flags.Exported"
3233
if (flags.is(Flags.FieldAccessor)) flagList += "Flags.FieldAccessor"
3334
if (flags.is(Flags.Final)) flagList += "Flags.Final"
3435
if (flags.is(Flags.HasDefault)) flagList += "Flags.HasDefault"

compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ object SourceCode {
3030
if (flags.is(Flags.Enum)) flagList += "enum"
3131
if (flags.is(Flags.Erased)) flagList += "erased"
3232
if (flags.is(Flags.ExtensionMethod)) flagList += "extension"
33+
if (flags.is(Flags.Exported)) flagList += "exported"
3334
if (flags.is(Flags.FieldAccessor)) flagList += "accessor"
3435
if (flags.is(Flags.Final)) flagList += "final"
3536
if (flags.is(Flags.HasDefault)) flagList += "hasDefault"

library/src/scala/quoted/Quotes.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3911,6 +3911,9 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
39113911
/** Is this symbol `erased` */
39123912
def Erased: Flags
39133913

3914+
/** Is this symbol exported from provided instance */
3915+
def Exported: Flags
3916+
39143917
/** Is this symbol a `def` defined in an `extension` */
39153918
def ExtensionMethod: Flags
39163919

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package tests
2+
package exports
3+
4+
class A:
5+
def aDefInt: Int = 1
6+
def aDef1: 1 = 1
7+
val aValInt: Int = 1
8+
val aVal1: 1 = 1
9+
var aVarInt: Int = 1
10+
var aVar1: 1 = 1
11+
12+
object X:
13+
def xDefInt: Int = 1
14+
def xDef1: 1 = 1
15+
val xValInt: Int = 1
16+
val xVal1: 1 = 1
17+
var xVarInt: Int = 1
18+
var xVar1: 1 = 1
19+
20+
class B:
21+
val a = new A
22+
export a._
23+
export X._

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ enum Kind(val name: String){
6363
case Constructor extends Kind("def")
6464
case Var extends Kind("var")
6565
case Val extends Kind("val")
66+
case Exported extends Kind("export")
6667
case Type(concreate: Boolean, opaque: Boolean) extends Kind("Type") // should we handle opaque as modifier?
6768
case Given(as: Option[Signature], conversion: Option[ImplicitConversion]) extends Kind("Given") with ImplicitConversionProvider
6869
case Implicit(kind: Kind, conversion: Option[ImplicitConversion]) extends Kind(kind.name) with ImplicitConversionProvider
@@ -73,6 +74,7 @@ enum Origin:
7374
case InheritedFrom(name: String, dri: DRI)
7475
case ImplicitlyAddedBy(name: String, dri: DRI)
7576
case ExtensionFrom(name: String, dri: DRI)
77+
case ExportedFrom(name: String, dri: Option[DRI])
7678
case DefinedWithin
7779

7880
case class Annotation(val dri: DRI, val params: List[Annotation.AnnotationParameter])

scala3doc/src/dotty/dokka/site/PartiallyRenderedContent.scala

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,23 @@ case class PartiallyRenderedContent(
4040
}
4141
}// forrach does not work here
4242
document.outerHtml()
43+
44+
45+
class A:
46+
def defInt: Int = 1
47+
def def1: 1 = 1
48+
val valInt: Int = 1
49+
val val1: 1 = 1
50+
var varInt: Int = 1
51+
var var1: 1 = 1
52+
53+
object X:
54+
def x: Int = 1
55+
val x2: 1 = 1
56+
var x3: Int = 1
57+
58+
class B:
59+
val a = new A
60+
export a._
61+
export X._
62+

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,21 @@ trait ClassLikeSupport:
123123
.map { _ =>
124124
parseMethod(dd.symbol, kind = Kind.Given(getGivenInstance(dd).map(_.asSignature), None))
125125
}
126+
127+
case dd: DefDef if !dd.symbol.isHiddenByVisibility && dd.symbol.isExported =>
128+
val exportedTarget = dd.rhs.collect {
129+
case a: Apply => a.fun.asInstanceOf[Select]
130+
case s: Select => s
131+
}
132+
val functionName = exportedTarget.fold("function")(_.name)
133+
val instanceName = exportedTarget.collect {
134+
case Select(qualifier: Select, _) => qualifier.name
135+
case Select(qualifier: Ident, _) => qualifier.tpe.typeSymbol.normalizedName
136+
}.getOrElse("instance")
137+
val dri = dd.rhs.collect {
138+
case s: Select if s.symbol.isDefDef => s.symbol.dri
139+
}.orElse(exportedTarget.map(_.qualifier.tpe.typeSymbol.dri))
140+
Some(parseMethod(dd.symbol, kind = Kind.Exported).withOrigin(Origin.ExportedFrom(s"$instanceName.$functionName", dri)))
126141

127142
case dd: DefDef if !dd.symbol.isHiddenByVisibility && !dd.symbol.isGiven && !dd.symbol.isSyntheticFunc && !dd.symbol.isExtensionMethod =>
128143
Some(parseMethod(dd.symbol))
@@ -184,7 +199,6 @@ trait ClassLikeSupport:
184199
case dd: DefDef if !dd.symbol.isClassConstructor && !(dd.symbol.isSuperBridgeMethod || dd.symbol.isDefaultHelperMethod) => dd
185200
case other => other
186201
}
187-
188202
c.membersToDocument.flatMap(parseMember) ++
189203
inherited.flatMap(s => parseInheritedMember(s))
190204
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ class SymOps[Q <: Quotes](val q: Q):
8282

8383
def isGiven: Boolean = sym.flags.is(Flags.Given)
8484

85+
def isExported: Boolean = sym.flags.is(Flags.Exported)
86+
8587
def isExtensionMethod: Boolean = sym.flags.is(Flags.ExtensionMethod)
8688

8789
def isLeftAssoc(d: Symbol): Boolean = !d.name.endsWith(":")

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,9 +215,12 @@ trait TypesSupport:
215215
// case _ =>
216216
// throw Exception("Match error in TypeRef. This should not happen, please open an issue. " + convertTypeOrBoundsToReference(reflect)(qual))
217217
// }
218-
case tr @ TermRef(qual, typeName) => qual match {
219-
case _ => link(tr.termSymbol)
220-
}
218+
case tr @ TermRef(qual, typeName) =>
219+
tr.termSymbol.tree match
220+
case vd: ValDef => inner(vd.tpt.tpe)
221+
case _ => link(tr.termSymbol)
222+
223+
221224
// convertTypeOrBoundsToReference(reflect)(qual) match {
222225
// case TypeReference(label, link, xs, _) => TypeReference(typeName + "$", link + "/" + label, xs)
223226
// case EmptyReference => TypeReference(typeName, "", Nil)

scala3doc/src/dotty/dokka/translators/FilterAttributes.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ object FilterAttributes:
4343
case Origin.InheritedFrom(name, _) => Map("inherited" -> name)
4444
case Origin.ImplicitlyAddedBy(name, _) => Map("implicitly" -> s"by $name")
4545
case Origin.ExtensionFrom(name, _) => Map("extension" -> s"from $name")
46+
case Origin.ExportedFrom(name, _) => Map("export" -> s"from $name")
4647
case _ => Map.empty
4748
case null =>
4849
Map.empty

scala3doc/src/dotty/dokka/translators/ScalaContentBuilder.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,11 @@ class ScalaPageContentBuilder(
489489
val originInfo = documentable.origin match {
490490
case Origin.ImplicitlyAddedBy(name, dri) => Signature("Implicitly added by ", SLink(name, dri))
491491
case Origin.ExtensionFrom(name, dri) => Signature("Extension method from ", SLink(name, dri))
492+
case Origin.ExportedFrom(name, dri) =>
493+
val signatureName: String | dotty.dokka.model.api.Link = dri match
494+
case Some(dri: DRI) => SLink(name, dri)
495+
case None => name
496+
Signature("Exported from ", signatureName)
492497
case _ => Nil
493498
}
494499

scala3doc/src/dotty/dokka/translators/ScalaPageCreator.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ class ScalaPageCreator(
351351
val (definedTypes, inheritedTypes) = s.membersBy(_.kind.isInstanceOf[Kind.Type])
352352
val (definedGivens, inheritedGives) = s.membersBy(_.kind.isInstanceOf[Kind.Given])
353353
val (definedExtensions, inheritedExtensions) = s.membersBy(_.kind.isInstanceOf[Kind.Extension])
354+
val exports = s.allMembers.filter(_.kind == Kind.Exported)
354355
val (definedImplicits, inheritedImplicits) = s.membersBy(_.kind.isInstanceOf[Kind.Implicit])
355356

356357
b
@@ -381,6 +382,9 @@ class ScalaPageCreator(
381382
DocumentableGroup(Some("Defined implicits"), definedImplicits),
382383
DocumentableGroup(Some("Inherited implicits"), inheritedImplicits)
383384
)
385+
.documentableTab("Exports")(
386+
DocumentableGroup(Some("Defined exports"), exports)
387+
)
384388

385389

386390
def contentForEnum(c: DClass) =

scala3doc/src/dotty/dokka/translators/ScalaSignatureProvider.scala

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ object ScalaSignatureProvider:
4949
extensionSignature(extension, builder)
5050
case method: DFunction if method.kind.isInstanceOf[Kind.Given] =>
5151
givenMethodSignature(method, builder)
52+
case exprt: DFunction if exprt.kind == Kind.Exported =>
53+
exportedMethodSignature(exprt, builder)
5254
case method: DFunction =>
5355
methodSignature(method, builder)
5456
case enumEntry: DClass if enumEntry.kind == Kind.EnumCase =>
@@ -138,14 +140,14 @@ object ScalaSignatureProvider:
138140
} else {
139141
extension.getParameters.asScala(0)
140142
}
141-
val withSinature = builder
143+
val withSignature = builder
142144
.modifiersAndVisibility(extension, "def")
143145
.name(extension.getName, extension.getDri)
144146
.generics(extension)
145147
.functionParameters(extension)
146148

147-
if extension.isConstructor then withSinature
148-
else withSinature.text(":").text(" ").typeSignature(extension.getType)
149+
if extension.isConstructor then withSignature
150+
else withSignature.text(":").text(" ").typeSignature(extension.getType)
149151

150152
private def givenMethodSignature(method: DFunction, builder: SignatureBuilder): SignatureBuilder = method.kind match
151153
case Kind.Given(Some(instance), _) =>
@@ -156,6 +158,8 @@ object ScalaSignatureProvider:
156158
case _ =>
157159
builder.text("given ").name(method.getName, method.getDri)
158160

161+
private def exportedMethodSignature(method: DFunction, builder: SignatureBuilder): SignatureBuilder =
162+
methodSignature(method, builder)
159163

160164
private def methodSignature(method: DFunction, builder: SignatureBuilder): SignatureBuilder =
161165
val bdr = builder

0 commit comments

Comments
 (0)