From 48c91ee86270a5036f75a41d959e255f7412d8ce Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Mon, 25 Mar 2024 09:40:32 +0100 Subject: [PATCH] chore: Update scalameta to 4.9.3 I inlined usages of Chars since that part of scalameta is internal and not checked, so better to have these few small methods inside Metals. I also updated scalafix to latest snapshot to avoid OOM --- .../meta/internal/metals/Diagnostics.scala | 6 +++-- .../internal/pc/completions/Completions.scala | 2 +- .../pc/completions/CompletionPos.scala | 2 +- .../metals/docstrings/ScaladocUtils.scala | 8 +++--- .../meta/internal/mtags/CharArrayReader.scala | 19 ++++++------- .../scala/meta/internal/mtags/Chars.scala | 27 +++++++++++++++++++ .../internal/mtags/JavaToplevelMtags.scala | 12 ++++----- project/V.scala | 2 +- project/plugins.sbt | 2 +- .../tests/feature/SyntaxErrorLspSuite.scala | 4 +-- 10 files changed, 57 insertions(+), 27 deletions(-) create mode 100644 mtags/src/main/scala/scala/meta/internal/mtags/Chars.scala diff --git a/metals/src/main/scala/scala/meta/internal/metals/Diagnostics.scala b/metals/src/main/scala/scala/meta/internal/metals/Diagnostics.scala index 0774f160125..09d9b38754f 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/Diagnostics.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/Diagnostics.scala @@ -247,9 +247,11 @@ final class Diagnostics( diag.getRange() == d.getRange() && diag.getMessage() == d.getMessage() ) isDuplicate = - d.getMessage.startsWith("identifier expected but") && + d.getMessage.replace("`", "").startsWith("identifier expected but") && all.asScala.exists { other => - other.getMessage.startsWith("identifier expected") && + other.getMessage + .replace("`", "") + .startsWith("identifier expected") && other.getRange().getStart() == d.getRange().getStart() } if !isDuplicate && !isSameMessage diff --git a/mtags/src/main/scala-2/scala/meta/internal/pc/completions/Completions.scala b/mtags/src/main/scala-2/scala/meta/internal/pc/completions/Completions.scala index a8271d106e6..b04986b9486 100644 --- a/mtags/src/main/scala-2/scala/meta/internal/pc/completions/Completions.scala +++ b/mtags/src/main/scala-2/scala/meta/internal/pc/completions/Completions.scala @@ -5,6 +5,7 @@ import java.util.logging.Level import scala.collection.immutable.Nil import scala.collection.mutable +import scala.reflect.internal.Chars import scala.util.control.NonFatal import scala.meta.internal.jdk.CollectionConverters._ @@ -16,7 +17,6 @@ import scala.meta.internal.pc.InterpolationSplice import scala.meta.internal.pc.MemberOrdering import scala.meta.internal.pc.MetalsGlobal import scala.meta.internal.semanticdb.Scala._ -import scala.meta.internal.tokenizers.Chars import org.eclipse.{lsp4j => l} diff --git a/mtags/src/main/scala-3/scala/meta/internal/pc/completions/CompletionPos.scala b/mtags/src/main/scala-3/scala/meta/internal/pc/completions/CompletionPos.scala index 6cd6d88122f..dae967d4b01 100644 --- a/mtags/src/main/scala-3/scala/meta/internal/pc/completions/CompletionPos.scala +++ b/mtags/src/main/scala-3/scala/meta/internal/pc/completions/CompletionPos.scala @@ -6,13 +6,13 @@ import java.net.URI import scala.annotation.tailrec import scala.meta.internal.mtags.MtagsEnrichments.* -import scala.meta.internal.tokenizers.Chars import scala.meta.pc.OffsetParams import dotty.tools.dotc.ast.tpd.* import dotty.tools.dotc.ast.untpd.ImportSelector import dotty.tools.dotc.core.Contexts.* import dotty.tools.dotc.core.StdNames.* +import dotty.tools.dotc.util.Chars import dotty.tools.dotc.util.SourcePosition import dotty.tools.dotc.util.Spans import org.eclipse.lsp4j as l diff --git a/mtags/src/main/scala/scala/meta/internal/metals/docstrings/ScaladocUtils.scala b/mtags/src/main/scala/scala/meta/internal/metals/docstrings/ScaladocUtils.scala index 34e83adb64b..099e54606fc 100644 --- a/mtags/src/main/scala/scala/meta/internal/metals/docstrings/ScaladocUtils.scala +++ b/mtags/src/main/scala/scala/meta/internal/metals/docstrings/ScaladocUtils.scala @@ -1,6 +1,6 @@ package scala.meta.internal.docstrings -import scala.meta.internal.tokenizers.Chars._ +import scala.meta.internal.mtags.Chars /** * Utility methods for doc comment strings @@ -9,7 +9,7 @@ object ScaladocUtils { /** Is character a whitespace character (but not a new line)? */ def isWhitespace(c: Char): Boolean = - c == ' ' || c == '\t' || c == CR + c == ' ' || c == '\t' || c == Chars.CR /** * Returns index of string `str` following `start` skipping longest @@ -25,7 +25,7 @@ object ScaladocUtils { * sequence of identifier characters. */ def skipIdent(str: String, start: Int): Int = - if (start < str.length && isIdentifierPart(str charAt start)) + if (start < str.length && Chars.isIdentifierPart(str charAt start)) skipIdent(str, start + 1) else start @@ -143,7 +143,7 @@ object ScaladocUtils { startsWithTag(str, section._1, tag) def startsWithTag(str: String, start: Int, tag: String): Boolean = - str.startsWith(tag, start) && !isIdentifierPart( + str.startsWith(tag, start) && !Chars.isIdentifierPart( str charAt (start + tag.length) ) diff --git a/mtags/src/main/scala/scala/meta/internal/mtags/CharArrayReader.scala b/mtags/src/main/scala/scala/meta/internal/mtags/CharArrayReader.scala index 1dfd6de8849..e0613a1a949 100644 --- a/mtags/src/main/scala/scala/meta/internal/mtags/CharArrayReader.scala +++ b/mtags/src/main/scala/scala/meta/internal/mtags/CharArrayReader.scala @@ -2,7 +2,6 @@ package scala.meta.internal.mtags import scala.meta.Dialect import scala.meta.inputs._ -import scala.meta.internal.tokenizers.Chars._ import scala.meta.internal.tokenizers.Reporter private[meta] case class CharArrayReader private ( @@ -10,7 +9,7 @@ private[meta] case class CharArrayReader private ( dialect: Dialect, reporter: Reporter, /** the last read character */ - var ch: Int = SU, + var ch: Int = Chars.SU, /** The offset one past the last read character */ var begCharOffset: Int = -1, // included var endCharOffset: Int = 0, // excluded @@ -42,7 +41,7 @@ private[meta] case class CharArrayReader private ( final def nextCommentChar(): Unit = { if (endCharOffset >= buf.length) { - ch = SU + ch = Chars.SU } else { ch = buf(endCharOffset) begCharOffset = endCharOffset @@ -57,7 +56,7 @@ private[meta] case class CharArrayReader private ( */ final def nextRawChar(): Unit = { if (endCharOffset >= buf.length) { - ch = SU + ch = Chars.SU } else { begCharOffset = endCharOffset val (hi, hiEnd) = readUnicodeChar(endCharOffset) @@ -113,7 +112,7 @@ private[meta] case class CharArrayReader private ( return (c, firstOffset) def udigit: Int = - try digit2int(buf(escapedOffset), 16) + try Chars.digit2int(buf(escapedOffset), 16) finally escapedOffset += 1 val code = udigit << 12 | udigit << 8 | udigit << 4 | udigit @@ -122,10 +121,12 @@ private[meta] case class CharArrayReader private ( /** replace CR;LF by LF */ private def skipCR() = - if (ch == CR && endCharOffset < buf.length && buf(endCharOffset) == '\\') { + if ( + ch == Chars.CR && endCharOffset < buf.length && buf(endCharOffset) == '\\' + ) { val (c, nextOffset) = readUnicodeChar(endCharOffset) - if (c == LF) { - ch = LF + if (c == Chars.LF) { + ch = Chars.LF endCharOffset = nextOffset } } @@ -141,7 +142,7 @@ private[meta] case class CharArrayReader private ( } private def checkLineEnd(): Boolean = { - val ok = ch == LF || ch == FF + val ok = ch == Chars.LF || ch == Chars.FF if (ok) { lastLineStartOffset = lineStartOffset lineStartOffset = endCharOffset diff --git a/mtags/src/main/scala/scala/meta/internal/mtags/Chars.scala b/mtags/src/main/scala/scala/meta/internal/mtags/Chars.scala new file mode 100644 index 00000000000..38be2eaa701 --- /dev/null +++ b/mtags/src/main/scala/scala/meta/internal/mtags/Chars.scala @@ -0,0 +1,27 @@ +package scala.meta.internal.mtags + +object Chars { + final val LF = '\u000A' + final val FF = '\u000C' + final val CR = '\u000D' + final val SU = '\u001A' + + /** + * Convert a character digit to an Int according to given base, -1 if no success + */ + def digit2int(ch: Int, base: Int): Int = { + val num = + ( + if (ch <= '9') ch - '0' + else if ('a' <= ch && ch <= 'z') ch - 'a' + 10 + else if ('A' <= ch && ch <= 'Z') ch - 'A' + 10 + else -1 + ) + if (0 <= num && num < base) num else -1 + } + + /** Can character form part of an alphanumeric Scala identifier? */ + def isIdentifierPart(c: Int): Boolean = + (c == '$') || Character.isUnicodeIdentifierPart(c) + +} diff --git a/mtags/src/main/scala/scala/meta/internal/mtags/JavaToplevelMtags.scala b/mtags/src/main/scala/scala/meta/internal/mtags/JavaToplevelMtags.scala index 4c57145b317..19d63e8389a 100644 --- a/mtags/src/main/scala/scala/meta/internal/mtags/JavaToplevelMtags.scala +++ b/mtags/src/main/scala/scala/meta/internal/mtags/JavaToplevelMtags.scala @@ -7,7 +7,6 @@ import scala.meta.inputs.Input import scala.meta.inputs.Position import scala.meta.internal.semanticdb.Language import scala.meta.internal.semanticdb.SymbolInformation -import scala.meta.internal.tokenizers.Chars._ import scala.meta.internal.tokenizers.Reporter class JavaToplevelMtags(val input: Input.VirtualFile) extends MtagsIndexer { @@ -87,7 +86,7 @@ class JavaToplevelMtags(val input: Input.VirtualFile) extends MtagsIndexer { @tailrec def kwOrIdent(start: Int, builder: StringBuilder): Token = { val ch = reader.ch - if (ch != SU && Character.isJavaIdentifierPart(ch)) { + if (ch != Chars.SU && Character.isJavaIdentifierPart(ch)) { reader.nextChar() kwOrIdent(start, builder.append(ch.toChar)) } else if (builder.isEmpty) { @@ -116,7 +115,7 @@ class JavaToplevelMtags(val input: Input.VirtualFile) extends MtagsIndexer { case ',' | '<' | '>' | '&' | '|' | '!' | '=' | '+' | '-' | '*' | '@' | ':' | '?' | '%' | '^' | '~' => (Token.SpecialSym, false) - case SU => (Token.EOF, false) + case Chars.SU => (Token.EOF, false) case '.' => (Token.Dot, false) case '{' => (Token.LBrace, false) case '}' => (Token.RBrace, false) @@ -176,7 +175,7 @@ class JavaToplevelMtags(val input: Input.VirtualFile) extends MtagsIndexer { private def isWhitespace(ch: Char): Boolean = { ch match { - case ' ' | '\t' | CR | LF | FF => true + case ' ' | '\t' | Chars.CR | Chars.LF | Chars.FF => true case _ => false } } @@ -209,7 +208,8 @@ class JavaToplevelMtags(val input: Input.VirtualFile) extends MtagsIndexer { } private def skipLine: Unit = - while ({ val ch = reader.ch; ch != SU && ch != '\n' }) reader.nextChar() + while ({ val ch = reader.ch; ch != Chars.SU && ch != '\n' }) + reader.nextChar() @tailrec private def toNextNonWhiteSpace(): Unit = { @@ -222,7 +222,7 @@ class JavaToplevelMtags(val input: Input.VirtualFile) extends MtagsIndexer { private def readCurrentLine: String = { def loop(builder: StringBuilder): String = { val ch = reader.ch.toChar - if (ch == '\n' || ch == SU) + if (ch == '\n' || ch == Chars.SU) builder.mkString else { val next = builder.append(ch) diff --git a/project/V.scala b/project/V.scala index de304400287..e64b494721c 100644 --- a/project/V.scala +++ b/project/V.scala @@ -46,7 +46,7 @@ object V { val scalaCli = "1.2.0" val scalafix = "0.12.0" val scalafmt = "3.7.15" - val scalameta = "4.9.1" + val scalameta = "4.9.3" val scribe = "3.13.0" val qdox = "2.1.0" diff --git a/project/plugins.sbt b/project/plugins.sbt index f1aa7866847..b314ea5e606 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.7") -addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.12.0") +addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.12.0+5-aba10632-SNAPSHOT") addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.12") addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.5.2") addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.11.0") diff --git a/tests/slow/src/test/scala/tests/feature/SyntaxErrorLspSuite.scala b/tests/slow/src/test/scala/tests/feature/SyntaxErrorLspSuite.scala index e40ca88e9c3..a7abf26f2f9 100644 --- a/tests/slow/src/test/scala/tests/feature/SyntaxErrorLspSuite.scala +++ b/tests/slow/src/test/scala/tests/feature/SyntaxErrorLspSuite.scala @@ -64,7 +64,7 @@ class SyntaxErrorLspSuite extends BaseLspSuite("syntax-error") { _ = assertNoDiff( client.workspaceDiagnostics, """ - |Main.scala:1:8: error: identifier expected but object found + |Main.scala:1:8: error: `identifier` expected but `object` found |object object A | ^^^^^^ |project/plugins.sbt:1:6: error: repeated modifier @@ -247,7 +247,7 @@ class SyntaxErrorLspSuite extends BaseLspSuite("syntax-error") { | required: Int | "". | ^ - |a/src/main/scala/A.scala:3:1: error: identifier expected but } found + |a/src/main/scala/A.scala:3:1: error: `identifier` expected but `}` found |} |^ |""".stripMargin,