Skip to content

Commit 0c9d50b

Browse files
committed
Merge branch 'main' into scaladoc-types-rendering-fixes
2 parents 9baaddd + c47f7e0 commit 0c9d50b

File tree

19 files changed

+191
-160
lines changed

19 files changed

+191
-160
lines changed

.vscode-template/settings.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"**/*.class": true,
1010
"**/*.tasty": true,
1111
"**/target/": true,
12-
"community-build/community-projects": true
12+
"community-build/community-projects": true,
13+
"tests/pos-with-compiler-cc/dotc/**/*.scala": true
1314
}
1415
}

compiler/src/dotty/tools/dotc/inlines/Inlines.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import transform.{PostTyper, Inlining, CrossVersionChecks}
1717
import staging.StagingLevel
1818

1919
import collection.mutable
20-
import reporting.trace
20+
import reporting.{NotConstant, trace}
2121
import util.Spans.Span
2222

2323
/** Support for querying inlineable methods and for inlining calls to such methods */
@@ -413,7 +413,7 @@ object Inlines:
413413
if (inlinedMethod == defn.Compiletime_constValue) {
414414
val constVal = tryConstValue
415415
if constVal.isEmpty then
416-
val msg = em"not a constant type: ${callTypeArgs.head}; cannot take constValue"
416+
val msg = NotConstant("cannot take constValue", callTypeArgs.head.tpe)
417417
return ref(defn.Predef_undefined).withSpan(call.span).withType(ErrorType(msg))
418418
else
419419
return constVal

compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala

+1
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ enum ErrorMessageID(val isActive: Boolean = true) extends java.lang.Enum[ErrorMe
195195
case MatchTypeScrutineeCannotBeHigherKindedID // errorNumber: 179
196196
case AmbiguousExtensionMethodID // errorNumber 180
197197
case UnqualifiedCallToAnyRefMethodID // errorNumber: 181
198+
case NotConstantID // errorNumber: 182
198199

199200
def errorNumber = ordinal - 1
200201

compiler/src/dotty/tools/dotc/reporting/messages.scala

+7
Original file line numberDiff line numberDiff line change
@@ -2624,6 +2624,13 @@ extends TypeMsg(NotClassTypeID), ShowMatchTrace(tp):
26242624
def msg(using Context) = i"$tp is not a class type"
26252625
def explain(using Context) = ""
26262626

2627+
class NotConstant(suffix: String, tp: Type)(using Context)
2628+
extends TypeMsg(NotConstantID), ShowMatchTrace(tp):
2629+
def msg(using Context) =
2630+
i"$tp is not a constant type"
2631+
+ (if suffix.isEmpty then "" else i"; $suffix")
2632+
def explain(using Context) = ""
2633+
26272634
class MissingImplicitArgument(
26282635
arg: tpd.Tree,
26292636
pt: Type,

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ object QuoteMatcher {
354354
/* Match new */
355355
case New(tpt1) =>
356356
pattern match
357-
case New(tpt2) if tpt1.tpe.typeSymbol == tpt2.tpe.typeSymbol => matched
357+
case New(tpt2) if tpt1.tpe.dealias.typeSymbol == tpt2.tpe.dealias.typeSymbol => matched
358358
case _ => notMatched
359359

360360
/* Match this */

docs/_docs/contributing/setting-up-your-ide.md

+15-7
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,34 @@ sbt:scala3> projects
2222
...
2323
```
2424

25-
These duplicated projects can be confusing and cause issues in IDEs.
25+
These duplicated projects can be confusing and cause issues in IDEs, so it's
26+
import to import the project in a specific way depending on your editor.
2627

2728
### Metals
2829

2930
When using Metals, the `-bootstrapped` projects are not exported by default.
3031
Normally this is fine, but if you're working on certain modules like `scaladoc`
3132
you'll actually want these modules exported. In order to achieve this you'll
32-
first want to ensure you're using `sbt` as your build server instead of the
33-
default Bloop. You can achieve this with the `Metals: Switch Build Server`
34-
command and then choosing sbt. Once you do this, you'll want to find and change
35-
the following under `commonBootstrappedSettings` which is found in the
36-
[`Build.scala`](https://github.com/lampepfl/dotty/blob/main/project/Build.scala)
37-
file.
33+
want to make sure you do two things:
34+
35+
1. You'll want to find and change the following under
36+
`commonBootstrappedSettings` which is found in the
37+
[`Build.scala`](https://github.com/lampepfl/dotty/blob/main/project/Build.scala)
38+
file.
3839

3940
```diff
4041

4142
- bspEnabled := false,
4243
+ bspEnabled := true,
4344
```
4445

46+
2. Set `sbt` as your build server instead of the default, Bloop. You can achieve
47+
this with the `Metals: Switch Build Server` command and then choosing sbt. In
48+
VSCode, this looks like this:
49+
50+
![bsp-switch](https://user-images.githubusercontent.com/777748/241986423-0724ae74-0ebd-42ef-a1b7-4d17678992b4.png)
51+
52+
4553
### IntelliJ
4654

4755
In IntelliJ IDEA, we recommend importing the dotty codebase through BSP, then

scaladoc/src/dotty/tools/scaladoc/ScalaModuleProvider.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ case class Module(rootPackage: Member, members: Map[DRI, Member])
88

99
object ScalaModuleProvider:
1010
def mkModule()(using ctx: DocContext): Module =
11-
val (result, rootDoc) = ScaladocTastyInspector.loadDocs()
11+
val (result, rootDoc) = ScaladocTastyInspector().result()
1212
val (rootPck, rest) = result.partition(_.name == "API")
1313
val (emptyPackages, nonemptyPackages) = (rest ++ rootPck.flatMap(_.members))
1414
.filter(p => p.members.nonEmpty || p.docs.nonEmpty).sortBy(_.name)

scaladoc/src/dotty/tools/scaladoc/tasty/TastyParser.scala

+32-35
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ package tasty
55
import java.util.regex.Pattern
66

77
import scala.util.{Try, Success, Failure}
8-
import scala.tasty.inspector.{TastyInspector, Inspector, Tasty}
8+
import scala.tasty.inspector.DocTastyInspector
99
import scala.quoted._
1010

1111
import dotty.tools.dotc
@@ -24,12 +24,24 @@ import ScaladocSupport._
2424
*
2525
* Delegates most of the work to [[TastyParser]] [[dotty.tools.scaladoc.tasty.TastyParser]].
2626
*/
27-
case class ScaladocTastyInspector()(using ctx: DocContext) extends Inspector:
27+
case class ScaladocTastyInspector()(using ctx: DocContext) extends DocTastyInspector:
2828

2929
private val topLevels = Seq.newBuilder[(String, Member)]
3030
private var rootDoc: Option[Comment] = None
3131

32-
def inspect(using Quotes)(tastys: List[scala.tasty.inspector.Tasty[quotes.type]]): Unit =
32+
def processCompilationUnit(using Quotes)(root: reflect.Tree): Unit = ()
33+
34+
override def postProcess(using Quotes): Unit =
35+
// hack into the compiler to get a list of all top-level trees
36+
// in principle, to do this, one would collect trees in processCompilationUnit
37+
// however, path-dependent types disallow doing so w/o using casts
38+
inline def hackForeachTree(thunk: reflect.Tree => Unit): Unit =
39+
given dctx: dotc.core.Contexts.Context = quotes.asInstanceOf[scala.quoted.runtime.impl.QuotesImpl].ctx
40+
dctx.run.nn.units.foreach { compilationUnit =>
41+
// mirrors code from TastyInspector
42+
thunk(compilationUnit.tpdTree.asInstanceOf[reflect.Tree])
43+
}
44+
3345
val symbolsToSkip: Set[reflect.Symbol] =
3446
ctx.args.identifiersToSkip.flatMap { ref =>
3547
val qrSymbol = reflect.Symbol
@@ -104,8 +116,7 @@ case class ScaladocTastyInspector()(using ctx: DocContext) extends Inspector:
104116
rootDoc = Some(parseCommentString(using parser.qctx, summon[DocContext])(content, topLevelPck, None))
105117
}
106118

107-
for tasty <- tastys do {
108-
val root = tasty.ast
119+
hackForeachTree { root =>
109120
if !isSkipped(root.symbol) then
110121
val treeRoot = root.asInstanceOf[parser.qctx.reflect.Tree]
111122
processRootDocIfNeeded(treeRoot)
@@ -130,7 +141,23 @@ case class ScaladocTastyInspector()(using ctx: DocContext) extends Inspector:
130141
topLevels += "scala" -> Member(scalaPckg.fullName, "", scalaPckg.dri, Kind.Package)
131142
topLevels += mergeAnyRefAliasAndObject(parser)
132143

144+
def result(): (List[Member], Option[Comment]) =
145+
topLevels.clear()
146+
rootDoc = None
147+
val filePaths = ctx.args.tastyFiles.map(_.getAbsolutePath).toList
148+
val classpath = ctx.args.classpath.split(java.io.File.pathSeparator).toList
133149

150+
if filePaths.nonEmpty then inspectFilesInContext(classpath, filePaths)
151+
152+
val all = topLevels.result()
153+
all.groupBy(_._1).map { case (pckName, members) =>
154+
val (pcks, rest) = members.map(_._2).partition(_.kind == Kind.Package)
155+
val basePck = pcks.reduce( (p1, p2) =>
156+
val withNewMembers = p1.withNewMembers(p2.members)
157+
if withNewMembers.docs.isEmpty then withNewMembers.withDocs(p2.docs) else withNewMembers
158+
)
159+
basePck.withMembers((basePck.members ++ rest).sortBy(_.name))
160+
}.toList -> rootDoc
134161

135162
def mergeAnyRefAliasAndObject(parser: TastyParser) =
136163
import parser.qctx.reflect._
@@ -144,36 +171,6 @@ case class ScaladocTastyInspector()(using ctx: DocContext) extends Inspector:
144171
kind = Kind.Class(Nil, Nil),
145172
members = objectMembers
146173
)
147-
148-
object ScaladocTastyInspector:
149-
150-
def loadDocs()(using ctx: DocContext): (List[Member], Option[Comment]) =
151-
val filePaths = ctx.args.tastyFiles.map(_.getAbsolutePath).toList
152-
val classpath = ctx.args.classpath.split(java.io.File.pathSeparator).toList
153-
154-
val inspector = new ScaladocTastyInspector
155-
156-
val (tastyPaths, nonTastyPaths) = filePaths.partition(_.endsWith(".tasty"))
157-
val (jarPaths, invalidPaths) = nonTastyPaths.partition(_.endsWith(".jar"))
158-
159-
for invalidPath <- invalidPaths do
160-
report.error("File extension is not `tasty` or `jar`: " + invalidPath)
161-
162-
if tastyPaths.nonEmpty then
163-
TastyInspector.inspectAllTastyFiles(tastyPaths, jarPaths, classpath)(inspector)
164-
165-
val all = inspector.topLevels.result()
166-
all.groupBy(_._1).map { case (pckName, members) =>
167-
val (pcks, rest) = members.map(_._2).partition(_.kind == Kind.Package)
168-
val basePck = pcks.reduce( (p1, p2) =>
169-
val withNewMembers = p1.withNewMembers(p2.members)
170-
if withNewMembers.docs.isEmpty then withNewMembers.withDocs(p2.docs) else withNewMembers
171-
)
172-
basePck.withMembers((basePck.members ++ rest).sortBy(_.name))
173-
}.toList -> inspector.rootDoc
174-
175-
end ScaladocTastyInspector
176-
177174
/** Parses a single Tasty compilation unit. */
178175
case class TastyParser(
179176
qctx: Quotes,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package scala.tasty.inspector
2+
3+
import dotty.tools.dotc.core.Contexts.Context
4+
5+
abstract class DocTastyInspector extends OldTastyInspector:
6+
def inspectFilesInDocContext(
7+
classpath: List[String],
8+
filePaths: List[String])(
9+
using Context): Unit = inspectFilesInContext(classpath, filePaths)

scaladoc/src/scala/tasty/inspector/Inspector.scala

-33
This file was deleted.

0 commit comments

Comments
 (0)