Skip to content

Commit

Permalink
Avoid extra lookahead
Browse files Browse the repository at this point in the history
  • Loading branch information
mbovel committed Oct 17, 2024
1 parent b779cd1 commit 361bc03
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 44 deletions.
26 changes: 4 additions & 22 deletions compiler/src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1092,25 +1092,6 @@ object Parsers {
|| in.lookahead.token == EOF // important for REPL completions
|| ctx.mode.is(Mode.Interactive) // in interactive mode the next tokens might be missing

/** Under `qualifiedTypes` language import: is the token sequence following
* the current `{` classified as a qualified type? This is the case if the
* next token is an `IDENT`, followed by `:`.
*/
def followingIsQualifiedType(): Boolean =
in.featureEnabled(Feature.qualifiedTypes) && {
val lookahead = in.LookaheadScanner(allowIndent = true)

if in.token == INDENT then
() // The LookaheadScanner doesn't see previous indents, so no need to skip it
else
lookahead.nextToken() // skips the opening brace

lookahead.token == IDENTIFIER && {
lookahead.nextToken()
lookahead.token == COLONfollow
}
}

/* --------- OPERAND/OPERATOR STACK --------------------------------------- */

var opStack: List[OpInfo] = Nil
Expand Down Expand Up @@ -2071,10 +2052,11 @@ object Parsers {
atSpan(in.offset) {
makeTupleOrParens(inParensWithCommas(argTypes(namedOK = false, wildOK = true, tupleOK = true)))
}
else if in.token == LBRACE && followingIsQualifiedType() then
qualifiedType()
else if in.token == LBRACE then
atSpan(in.offset) { RefinedTypeTree(EmptyTree, refinement(indentOK = false)) }
if in.featureEnabled(Feature.qualifiedTypes) && in.lookahead.token == IDENTIFIER then
qualifiedType()
else
atSpan(in.offset) { RefinedTypeTree(EmptyTree, refinement(indentOK = false)) }
else if (isSplice)
splice(isType = true)
else
Expand Down
89 changes: 78 additions & 11 deletions tests/printing/qualifiers.check
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ package example {
new example.qualifiers$package()
final module class qualifiers$package() extends Object() {
this: example.qualifiers$package.type =>
type Useless =
type Neg =
Int @qualified[Int](
{
def $anonfun(x: Int): Boolean = true
def $anonfun(x: Int): Boolean = x.<(0)
closure($anonfun)
}
)
Expand All @@ -29,14 +29,39 @@ package example {
closure($anonfun)
}
)
type Neg =
type Pos2 =
Int @qualified[Int](
{
def $anonfun(x: Int): Boolean = x.<(0)
def $anonfun(x: Int): Boolean = x.>(0)
closure($anonfun)
}
)
type Nesting =
type Pos3 =
Int @qualified[Int](
{
def $anonfun(x: Int): Boolean = x.>(0)
closure($anonfun)
}
)
type Pos4 =
Int @qualified[Int](
{
def $anonfun(x: Int): Boolean = x.>(0)
closure($anonfun)
}
)
type Pos5 =
Int @qualified[Int](
{
def $anonfun(x: Int): Boolean =
{
val res: Boolean = x.>(0)
res:Boolean
}
closure($anonfun)
}
)
type Nested =
Int @qualified[Int](
{
def $anonfun(x: Int): Boolean =
Expand All @@ -54,7 +79,7 @@ package example {
closure($anonfun)
}
)
type Pos2 =
type Intersection =
Int &
Int @qualified[Int](
{
Expand All @@ -76,7 +101,7 @@ package example {
def id[T >: Nothing <: Any](x: T): T = x
def test(): Unit =
{
val x1: example.Pos = 1
val x: example.Pos = 1
val x2:
Int @qualified[Int](
{
Expand All @@ -88,12 +113,28 @@ package example {
val x3:
Int @qualified[Int](
{
def $anonfun(x3: Int): Boolean = x3.>(0)
def $anonfun(x: Int): Boolean = x.>(0)
closure($anonfun)
}
)
= 1
val x4:
Int @qualified[Int](
{
def $anonfun(x: Int): Boolean = x.>(0)
closure($anonfun)
}
)
= 1
val x4: Int =
val x5:
Int @qualified[Int](
{
def $anonfun(x5: Int): Boolean = x.>(0)
closure($anonfun)
}
)
= 1
val x6: Int =
example.id[
Int @qualified[Int](
{
Expand Down Expand Up @@ -137,12 +178,38 @@ package example {
val b: Boolean = false
example.id[Boolean](true)
}
type B =
type T1 =
Object
{
val x: Int
}
type T2 =
Object
{
val x: Int
}
type T3 =
Object
{
type T = Int
}
type T4 =
Object
{
def x: Int
}
type T5 =
Object
{
def x: Int
def x_=(x$1: Int): _root_.scala.Unit
}
type T6 =
Object
{
val x: Int
}
type C =
type T7 =
Object
{
val x: Int
Expand Down
45 changes: 34 additions & 11 deletions tests/printing/qualifiers.scala
Original file line number Diff line number Diff line change
@@ -1,22 +1,37 @@
package example

type Useless = {x: Int with true}
type Pos =
type Neg = {x: Int with x < 0}
type Pos = {x: Int with x > 0}
type Pos2 = {x: Int
with x > 0
}
type Pos3 = {x: Int with
x > 0
}
type Pos4 =
{x: Int with x > 0}
type Neg = {x: Int with
x < 0
type Pos5 = {x: Int with
val res = x > 0
res
}
type Nesting = {x: Int with { val y: {z: Int with z > 0} = ??? ; x > y }}
type Pos2 = Int & {x: Int with x > 0}

type Nested = {x: Int with { val y: {z: Int with z > 0} = ??? ; x > y }}
type Intersection = Int & {x: Int with x > 0}
type ValRefinement = {val x: Int with x > 0}

def id[T](x: T): T = x

def test() =
val x1: Pos = 1
val x: Pos = 1
val x2: {x: Int with x > 0} = 1
val x3: Int with x3 > 0 = 1
val x4: Int = id[{x: Int with x < 0}](1) + id[Neg](-1)
val x3: {
x: Int with x > 0
} = 1
val x4: {x: Int with
x > 0
} = 1
val x5: Int with x > 0 = 1
val x6: Int = id[{x: Int with x < 0}](1) + id[Neg](-1)

def bar(x: Int with x > 0) = ???
def secondGreater1(x: Int, y: Int)(z: {w: Int with x > y}) = ???
Expand All @@ -32,5 +47,13 @@ given A with
id(true)

// Also not qualified types:
type B = {val x: Int}
type C = Object {val x: Int}
type T1 = {val x: Int}
type T2 = {
val x: Int
}
type T3 = {type T = Int}
type T4 = {def x: Int}
type T5 = {var x: Int}
type T6 = Object {val x: Int}
type T7 = Object:
val x: Int

0 comments on commit 361bc03

Please sign in to comment.