Skip to content

Commit

Permalink
bugfix: do not emit cases in pattern match as enum cases
Browse files Browse the repository at this point in the history
  • Loading branch information
kasiaMarek committed Aug 8, 2023
1 parent 5fefeff commit 0660721
Show file tree
Hide file tree
Showing 72 changed files with 1,035 additions and 71 deletions.
5 changes: 3 additions & 2 deletions mtags/src/main/scala/scala/meta/internal/mtags/Mtags.scala
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,15 @@ object Mtags {

def allToplevels(
input: Input.VirtualFile,
dialect: Dialect
dialect: Dialect,
includeMembers: Boolean = true
)(implicit rc: ReportContext = EmptyReportContext): TextDocument = {
input.toLanguage match {
case Language.JAVA =>
new JavaMtags(input, includeMembers = true).index()
case Language.SCALA =>
val mtags =
new ScalaToplevelMtags(input, true, includeMembers = true, dialect)
new ScalaToplevelMtags(input, true, includeMembers, dialect)
mtags.index()
case _ =>
TextDocument()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,19 +124,6 @@ class ScalaToplevelMtags(
def needToParseExtension(expect: ExpectTemplate): Boolean =
includeInnerClasses && expect.isExtension && !expect.ignoreBody

def nextIsNL: Boolean = {
scanner.nextToken()
scanner.curr.token match {
case WHITESPACE if isNewline => true
case WHITESPACE =>
nextIsNL
case COMMENT =>
scanner.skipComment()
nextIsNL
case _ => false
}
}

def needEmitMember(region: Region): Boolean =
includeInnerClasses || region.acceptMembers

Expand Down Expand Up @@ -200,7 +187,7 @@ class ScalaToplevelMtags(
// also covers extension methods because of `def` inside
case DEF
// extension group
if (dialect.allowExtensionMethods && currRegion.isExtension) =>
if (includeMembers && dialect.allowExtensionMethods && currRegion.isExtension) =>
acceptTrivia()
newIdentifier.foreach { name =>
withOwner(currRegion.owner) {
Expand All @@ -209,7 +196,10 @@ class ScalaToplevelMtags(
}
loop(indent, isAfterNewline = false, currRegion, newExpectIgnoreBody)
// inline extension method `extension (...) def foo = ...`
case DEF if expectTemplate.map(needToParseExtension).getOrElse(false) =>
case DEF
if includeMembers && expectTemplate
.map(needToParseExtension)
.getOrElse(false) =>
expectTemplate match {
case None =>
reportError(
Expand Down Expand Up @@ -240,14 +230,14 @@ class ScalaToplevelMtags(
expectTemplate
)
case DEF | VAL | VAR | GIVEN | TYPE
if needEmitTermMember() && expectTemplate
.map(!_.isExtension)
.getOrElse(true) =>
withOwner(currRegion.termOwner) {
emitTerm(currRegion)
}
if expectTemplate.map(!_.isExtension).getOrElse(true) =>
if (needEmitTermMember()) {
withOwner(currRegion.termOwner) {
emitTerm(currRegion)
}
} else scanner.nextToken()
loop(indent, isAfterNewline = false, currRegion, newExpectIgnoreBody)
case IMPORT =>
case IMPORT | EXPORT =>
// skip imports because they might have `given` kw
acceptToStatSep()
loop(indent, isAfterNewline = false, currRegion, expectTemplate)
Expand Down Expand Up @@ -295,16 +285,26 @@ class ScalaToplevelMtags(
expectTemplate
)
}
case MATCH if dialect.allowSignificantIndentation && nextIsNL =>
val nextIndent = acceptWhileIndented(indent)
loop(
nextIndent,
isAfterNewline = false,
currRegion,
None
)
case MATCH | THEN | ELSE | DO | WHILE | TRY | FINALLY | THROW | RETURN |
YIELD | FOR if dialect.allowSignificantIndentation =>
if (nextIsNL()) {
val nextIndent = acceptWhileIndented(indent)
loop(
nextIndent,
isAfterNewline = false,
currRegion,
None
)
} else {
loop(
indent,
isAfterNewline = false,
currRegion,
expectTemplate
)
}
case COLON if dialect.allowSignificantIndentation =>
(expectTemplate, nextIsNL) match {
(expectTemplate, nextIsNL()) match {
case (Some(expect), true) if needToParseBody(expect) =>
val next = expect.startIndentedRegion(currRegion)
resetRegion(next)
Expand Down Expand Up @@ -347,7 +347,7 @@ class ScalaToplevelMtags(
case _ =>
acceptBalancedDelimeters(LBRACE, RBRACE)
scanner.nextToken()
loop(indent, isAfterNewline = false, currRegion, expectTemplate)
loop(indent, isAfterNewline = false, currRegion, None)
}
case RBRACE =>
val nextRegion = currRegion match {
Expand Down Expand Up @@ -418,14 +418,15 @@ class ScalaToplevelMtags(
expectTemplate
)
case CASE =>
acceptTrivia()
val shouldCreateClassTemplate = emitEnumCases(region)
val nextIsNewLine = nextIsNL()
val (shouldCreateClassTemplate, isAfterNewline) =
emitEnumCases(region, nextIsNewLine)
val nextExpectTemplate =
if (shouldCreateClassTemplate) newExpectClassTemplate
else expectTemplate.filter(!_.isPackageBody)
loop(
indent,
isAfterNewline = false,
isAfterNewline,
currRegion,
if (scanner.curr.token == CLASS) newExpectCaseClassTemplate
else nextExpectTemplate
Expand Down Expand Up @@ -564,7 +565,10 @@ class ScalaToplevelMtags(
}

@tailrec
private def emitEnumCases(region: Region): Boolean = {
private def emitEnumCases(
region: Region,
nextIsNewLine: Boolean
): (Boolean, Boolean) = {
def ownerCompanionObject =
if (currentOwner.endsWith("#"))
s"${currentOwner.stripSuffix("#")}."
Expand All @@ -583,13 +587,13 @@ class ScalaToplevelMtags(
)
}
}
acceptTrivia()
val nextIsNewLine0 = nextIsNL()
scanner.curr.token match {
case COMMA =>
emitEnumCaseObject()
resetRegion(region)
acceptTrivia()
emitEnumCases(region)
val nextIsNewLine1 = nextIsNL()
emitEnumCases(region, nextIsNewLine1)
case LPAREN | LBRACKET =>
currentOwner = ownerCompanionObject
tpe(
Expand All @@ -598,12 +602,12 @@ class ScalaToplevelMtags(
Kind.CLASS,
SymbolInformation.Property.VAL.value
)
true
(true, false)
case _ =>
emitEnumCaseObject()
false
(false, nextIsNewLine0)
}
case _ => false
case _ => (false, nextIsNewLine)
}
}

Expand Down Expand Up @@ -677,6 +681,19 @@ class ScalaToplevelMtags(
}
}

private def nextIsNL(): Boolean = {
scanner.nextToken()
scanner.curr.token match {
case WHITESPACE if isNewline => true
case WHITESPACE =>
nextIsNL()
case COMMENT =>
scanner.skipComment()
nextIsNL()
case _ => false
}
}

/**
* Returns a name and position for the current identifier token
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
class EmptyPackage/*_empty_.EmptyPackage#*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package example

abstract class AbstractGiven/*example.AbstractGiven#*/:
given int: Int
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package example

trait Cancelable/*example.Cancelable#*/
trait Movable/*example.Movable#*/

type/*example.AndOrType$package.*/ Y = (Cancelable & Movable)

type X = String | Int
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package example

class AnonymousClasses/*example.AnonymousClasses#*/ {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package example

enum Color/*example.Color#*/(val rgb: Int):
case Red/*example.Color.Red.*/ extends Color(0xff0000)
case Green/*example.Color.Green.*/ extends Color(0x00ff00)
case Blue/*example.Color.Blue.*/ extends Color(0x0000ff)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package example

class /* comment */ Comments/*example.Comments#*/ {
object /* comment */ A/*example.Comments#A.*/
trait /* comment */ A/*example.Comments#A#*/
val /* comment */ a = 1
def /* comment */ b = 1
var /* comment */ c = 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package example

abstract class Companion/*example.Companion#*/() extends Object() {}

object Companion/*example.Companion.*/ {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package example

class EtaExpansion/*example.EtaExpansion#*/ {
List(1).map(identity)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package example

extension/*example.Extension$package.*/ (i: Int) def asString: String = i.toString

extension (s: String)
def asInt: Int = s.toInt
def double: String = s * 2

trait AbstractExtension/*example.AbstractExtension#*/:
extension (d: Double)
def abc: String
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package example

enum FooEnum/*example.FooEnum#*/:
case Bar/*example.FooEnum.Bar.*/, Baz/*example.FooEnum.Baz.*/
object FooEnum/*example.FooEnum.*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package example

class ForComprehensions/*example.ForComprehensions#*/ {
for {
a <- List(1)
b <- List(a)
if (
a,
b,
) == (1, 2)
(
c,
d,
) <- List((a, b))
if (
a,
b,
c,
d,
) == (1, 2, 3, 4)
e = (
a,
b,
c,
d,
)
if e == (1, 2, 3, 4)
f <- List(e)
} yield {
(
a,
b,
c,
d,
e,
f,
)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package example

given/*example.GivenAlias$package.*/ intValue: Int = 4
given String = "str"
given (using i: Int): Double = 4.0
given [T]: List[T] = Nil
given given_Char: Char = '?'
given `given_Float`: Float = 3.0
given `* *` : Long = 5

def method(using Int) = ""

object X/*example.X.*/:
given Double = 4.0
val double = given_Double

given of[A]: Option[A] = ???

trait Xg/*example.Xg#*/:
def doX: Int

trait Yg/*example.Yg#*/:
def doY: String

trait Zg/*example.Zg#*/[T]:
def doZ: List[T]

given Xg with
def doX = 7

given (using Xg): Yg with
def doY = "7"

given [T]: Zg[T] with
def doZ: List[T] = Nil

val a = intValue
val b = given_String
val c = X.given_Double
val d = given_List_T[Int]
val e = given_Char
val f = given_Float
val g = `* *`
val i = X.of[Int]
val x = given_Xg
val y = given_Yg
val z = given_Zg_T[String]
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package example

object ImplicitClasses/*example.ImplicitClasses.*/ {
implicit class Xtension/*example.ImplicitClasses.Xtension#*/(number: Int) {
def increment: Int = number + 1
}
implicit class XtensionAnyVal/*example.ImplicitClasses.XtensionAnyVal#*/(private val number: Int) extends AnyVal {
def double: Int = number * 2
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package example

import util.{Failure => NotGood}
import math.{floor => _, _}

class Imports/*example.Imports#*/ {
// rename reference
NotGood(null)
max(1, 2)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package example

class JavaThenScala/*example.JavaThenScala#*/ {
new JavaClass(42)
}
Loading

0 comments on commit 0660721

Please sign in to comment.