Skip to content

Commit

Permalink
ScalametaParser: parse quoted type blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
kitbellew committed Mar 6, 2024
1 parent 8ff7213 commit 0603be1
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 11 deletions.
Expand Up @@ -849,6 +849,23 @@ class ScalametaParser(input: Input)(implicit dialect: Dialect) { parser =>
}).getOrElse(t)
}

def typeBlock(): Type =
// TypeBlock, https://dotty.epfl.ch/docs/internals/syntax.html#expressions-3
if (dialect.allowQuotedTypeVariables && token.is[KwType]) autoPos {
val typeDefs = listBy[Stat.TypeDef] { buf =>
@tailrec def iter(): Unit = {
buf += typeDefOrDcl(Nil)
if (StatSep(token)) {
next()
if (token.is[KwType]) iter()
}
}
iter()
}
Type.Block(typeDefs, typ())
}
else typ()

private def typeFuncOnArrow(
paramPos: Int,
params: List[Type],
Expand Down Expand Up @@ -2297,7 +2314,7 @@ class ScalametaParser(input: Input)(implicit dialect: Dialect) { parser =>
next()
token match {
case _: LeftBrace => Term.QuotedMacroExpr(autoPos(inBracesOnOpen(blockWithinDelims())))
case _: LeftBracket => Term.QuotedMacroType(inBracketsOnOpen(typ()))
case _: LeftBracket => Term.QuotedMacroType(inBracketsOnOpen(typeBlock()))
case t => syntaxError("Quotation only works for expressions and types", at = t)
}
})
Expand Down Expand Up @@ -2982,6 +2999,7 @@ class ScalametaParser(input: Input)(implicit dialect: Dialect) { parser =>
* initiated from non-pattern context.
*/
def typ() = outPattern.typ()
private def typeBlock() = outPattern.typeBlock()
def typeIndentedOpt() = outPattern.typeIndentedOpt()
def quasiquoteType() = outPattern.quasiquoteType()
def entrypointType() = outPattern.entrypointType()
Expand Down
Expand Up @@ -449,19 +449,23 @@ class MacroSuite extends BaseDottySuite {

test("#3610 2") {
val code = "'[ type t = Int; List[t] ]"
val error =
"""|<input>:1: error: identifier expected but type found
|'[ type t = Int; List[t] ]
| ^""".stripMargin
runTestError[Stat](code, error)
val tree = Term.QuotedMacroType(
Type.Block(
List(Defn.Type(Nil, pname("t"), Nil, pname("Int"), noBounds)),
Type.Apply(pname("List"), List(pname("t")))
)
)
runTestAssert[Stat](code)(tree)
}

test("#3610 3") {
val code = "'[ type tail <: Tuple; *:[Int, tail] ]"
val error =
"""|<input>:1: error: identifier expected but type found
|'[ type tail <: Tuple; *:[Int, tail] ]
| ^""".stripMargin
runTestError[Stat](code, error)
val tree = Term.QuotedMacroType(
Type.Block(
List(Decl.Type(Nil, pname("tail"), Nil, bounds(hi = "Tuple"))),
Type.Apply(pname("*:"), List(pname("Int"), pname("tail")))
)
)
runTestAssert[Stat](code)(tree)
}
}

0 comments on commit 0603be1

Please sign in to comment.