Skip to content

Commit 0480dec

Browse files
committed
Support MatchType in semanticdb
1 parent 7817912 commit 0480dec

File tree

5 files changed

+116
-4
lines changed

5 files changed

+116
-4
lines changed

compiler/src/dotty/tools/dotc/semanticdb/PPrint.scala

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ class SymbolInformationPrinter (symtab: PrinterSymtab):
125125
if (tparams.infos.nonEmpty)
126126
sb.append(tparams.infos.map(pprintDef).mkString("[", ", ", "]"))
127127
if (lo == hi) {
128-
sb.append(s" = ${pprint(lo)}")
128+
if (lo == Type.Empty) ()
129+
else sb.append(s" = ${pprint(lo)}")
129130
} else {
130131
lo match
131132
case TypeRef(Type.Empty, "scala/Nothing#", Nil) => ()
@@ -191,7 +192,16 @@ class SymbolInformationPrinter (symtab: PrinterSymtab):
191192
s"=> ${normal(utpe)}"
192193
case RepeatedType(utpe) =>
193194
s"${normal(utpe)}*"
194-
case _ =>
195+
case MatchType(scrutinee, cases) =>
196+
val casesStr = cases.map { caseType =>
197+
s"${pprint(caseType.key)} => ${pprint(caseType.body)}"
198+
}.mkString(", ")
199+
s"${pprint(scrutinee)} match { ${casesStr} }"
200+
case LambdaType(params, result) =>
201+
val paramsStr = params.infos.map(pprintDef).mkString("[", ", ", "]")
202+
val resultStr = pprint(result)
203+
s"${paramsStr} =>> ${resultStr}"
204+
case x =>
195205
"<?>"
196206

197207
def normal(tpe: Type): String = tpe match

compiler/src/dotty/tools/dotc/semanticdb/TypeOps.scala

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import collection.mutable
1515

1616
import dotty.tools.dotc.{semanticdb => s}
1717
import Scala3.{FakeSymbol, SemanticSymbol, WildcardTypeSymbol, TypeParamRefSymbol, TermParamRefSymbol, RefinementSymbol}
18+
import dotty.tools.dotc.core.Names.Designator
1819

1920
class TypeOps:
2021
import SymbolScopeOps._
@@ -81,6 +82,10 @@ class TypeOps:
8182
else
8283
enterParamRef(lam.resType)
8384

85+
// for CaseType `case Array[t] => t` which is represented as [t] =>> MatchCase[Array[t], t]
86+
case m: MatchType =>
87+
m.cases.foreach(enterParamRef)
88+
8489
// for class constructor
8590
// class C[T] { ... }
8691
case cls: ClassInfo if sym.info.isInstanceOf[LambdaType] =>
@@ -276,6 +281,31 @@ class TypeOps:
276281
case ConstantType(const) =>
277282
s.ConstantType(const.toSemanticConst)
278283

284+
case matchType: MatchType =>
285+
val scases = matchType.cases.map { caseType => caseType match {
286+
case lam: HKTypeLambda => // case Array[t] => t
287+
val paramSyms = lam.paramNames.flatMap { paramName =>
288+
val key = (lam, paramName)
289+
paramRefSymtab.get(key)
290+
}.sscope
291+
lam.resType match {
292+
case defn.MatchCase(key, body) =>
293+
s.MatchType.CaseType(
294+
loop(key),
295+
loop(body)
296+
)
297+
case _ => s.MatchType.CaseType() // shouldn't happen
298+
}
299+
case defn.MatchCase(key, body) =>
300+
val skey = loop(key)
301+
val sbody = loop(body)
302+
s.MatchType.CaseType(skey, sbody)
303+
case _ => s.MatchType.CaseType() // shouldn't happen
304+
}}
305+
val sscrutinee = loop(matchType.scrutinee)
306+
val sbound = loop(matchType.bound)
307+
s.MatchType(sscrutinee, scases)
308+
279309
case rt @ RefinedType(parent, name, info) =>
280310
// `X { def x: Int; def y: Int }`
281311
// RefinedType(
@@ -405,8 +435,6 @@ class TypeOps:
405435
// Not yet supported
406436
case _: HKTypeLambda =>
407437
s.Type.Empty
408-
case _: MatchType =>
409-
s.Type.Empty
410438

411439
case tvar: TypeVar =>
412440
loop(tvar.stripped)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package example
2+
3+
type Elem/*<-example::MatchType$package.Elem#*/[X/*<-example::MatchType$package.Elem#[X]*/] = X/*->example::MatchType$package.Elem#[X]*/ match
4+
case String/*->scala::Predef.String#*/ => Char/*->scala::Char#*/
5+
case Array/*->scala::Array#*/[t/*<-local0*/] => t/*->local0*/
6+
case Iterable/*->scala::package.Iterable#*/[t/*<-local1*/] => t/*->local1*/
7+
8+
type Concat/*<-example::MatchType$package.Concat#*/[Xs/*<-example::MatchType$package.Concat#[Xs]*/ <: Tuple/*->scala::Tuple#*/, +Ys/*<-example::MatchType$package.Concat#[Ys]*/ <: Tuple/*->scala::Tuple#*/] <: Tuple/*->scala::Tuple#*/ = Xs/*->example::MatchType$package.Concat#[Xs]*/ match
9+
case EmptyTuple/*->scala::Tuple$package.EmptyTuple#*/ => Ys/*->example::MatchType$package.Concat#[Ys]*/
10+
case x/*<-local2*/ *:/*->scala::`*:`#*/ xs/*<-local3*/ => x/*->local2*/ *:/*->scala::`*:`#*/ Concat/*->example::MatchType$package.Concat#*/[xs/*->local3*/, Ys/*->example::MatchType$package.Concat#[Ys]*/]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package example
2+
3+
type Elem[X] = X match
4+
case String => Char
5+
case Array[t] => t
6+
case Iterable[t] => t
7+
8+
type Concat[Xs <: Tuple, +Ys <: Tuple] <: Tuple = Xs match
9+
case EmptyTuple => Ys
10+
case x *: xs => x *: Concat[xs, Ys]

tests/semanticdb/metac.expect

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,6 +2016,60 @@ Occurrences:
20162016
Synthetics:
20172017
[5:4..5:8):List => *.apply[Int]
20182018

2019+
expect/MatchType.scala
2020+
----------------------
2021+
2022+
Summary:
2023+
Schema => SemanticDB v4
2024+
Uri => MatchType.scala
2025+
Text => empty
2026+
Language => Scala
2027+
Symbols => 10 entries
2028+
Occurrences => 29 entries
2029+
2030+
Symbols:
2031+
example/MatchType$package. => final package object example extends Object { self: example.type => +3 decls }
2032+
example/MatchType$package.Concat# => type Concat [typeparam Xs <: Tuple, covariant typeparam Ys <: Tuple] = Xs match { EmptyTuple => Ys, *:[x, xs] => *:[x, Concat[xs, Ys]] }
2033+
example/MatchType$package.Concat#[Xs] => typeparam Xs <: Tuple
2034+
example/MatchType$package.Concat#[Ys] => covariant typeparam Ys <: Tuple
2035+
example/MatchType$package.Elem# => type Elem [typeparam X ] = X match { String => Char, Array[t] => t, Iterable[t] => t }
2036+
example/MatchType$package.Elem#[X] => typeparam X
2037+
local0 => case val method t
2038+
local1 => case val method t
2039+
local2 => case val method x
2040+
local3 => case val method xs
2041+
2042+
Occurrences:
2043+
[0:8..0:15): example <- example/
2044+
[2:5..2:9): Elem <- example/MatchType$package.Elem#
2045+
[2:10..2:11): X <- example/MatchType$package.Elem#[X]
2046+
[2:15..2:16): X -> example/MatchType$package.Elem#[X]
2047+
[3:7..3:13): String -> scala/Predef.String#
2048+
[3:17..3:21): Char -> scala/Char#
2049+
[4:7..4:12): Array -> scala/Array#
2050+
[4:13..4:14): t <- local0
2051+
[4:19..4:20): t -> local0
2052+
[5:7..5:15): Iterable -> scala/package.Iterable#
2053+
[5:16..5:17): t <- local1
2054+
[5:22..5:23): t -> local1
2055+
[7:5..7:11): Concat <- example/MatchType$package.Concat#
2056+
[7:12..7:14): Xs <- example/MatchType$package.Concat#[Xs]
2057+
[7:18..7:23): Tuple -> scala/Tuple#
2058+
[7:26..7:28): Ys <- example/MatchType$package.Concat#[Ys]
2059+
[7:32..7:37): Tuple -> scala/Tuple#
2060+
[7:42..7:47): Tuple -> scala/Tuple#
2061+
[7:50..7:52): Xs -> example/MatchType$package.Concat#[Xs]
2062+
[8:7..8:17): EmptyTuple -> scala/Tuple$package.EmptyTuple#
2063+
[8:21..8:23): Ys -> example/MatchType$package.Concat#[Ys]
2064+
[9:7..9:8): x <- local2
2065+
[9:9..9:11): *: -> scala/`*:`#
2066+
[9:12..9:14): xs <- local3
2067+
[9:18..9:19): x -> local2
2068+
[9:20..9:22): *: -> scala/`*:`#
2069+
[9:23..9:29): Concat -> example/MatchType$package.Concat#
2070+
[9:30..9:32): xs -> local3
2071+
[9:34..9:36): Ys -> example/MatchType$package.Concat#[Ys]
2072+
20192073
expect/MetacJava.scala
20202074
----------------------
20212075

0 commit comments

Comments
 (0)