From 94f38f1068432c9eadd923b5e7672708adafda79 Mon Sep 17 00:00:00 2001 From: Matt Bovel Date: Tue, 26 Nov 2024 20:26:20 +0000 Subject: [PATCH 1/5] Do not lift annotation arguments [Cherry-picked 49f287ac081fb3d10a18fdcc56e2bfb75c5054d4] --- .../src/dotty/tools/dotc/ast/TreeInfo.scala | 8 ++++-- .../tools/dotc/printing/RefinedPrinter.scala | 2 +- .../dotty/tools/dotc/typer/Applications.scala | 7 +++++- .../dependent-annot-default-args.check | 25 +++++++++++++++++++ .../dependent-annot-default-args.scala | 5 ++++ 5 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 tests/printing/dependent-annot-default-args.check create mode 100644 tests/printing/dependent-annot-default-args.scala diff --git a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala index d221f396fcd6..8c682971adcb 100644 --- a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala +++ b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala @@ -108,6 +108,10 @@ trait TreeInfo[T <: Untyped] { self: Trees.Instance[T] => case _ => tree + def stripNamedArg(tree: Tree) = tree match + case NamedArg(_, arg) => arg + case _ => tree + /** The number of arguments in an application */ def numArgs(tree: Tree): Int = unsplice(tree) match { case Apply(fn, args) => numArgs(fn) + args.length @@ -138,7 +142,7 @@ trait TreeInfo[T <: Untyped] { self: Trees.Instance[T] => def allTermArguments(tree: Tree): List[Tree] = unsplice(tree) match { case Apply(fn, args) => allTermArguments(fn) ::: args case TypeApply(fn, args) => allTermArguments(fn) - case Block(_, expr) => allTermArguments(expr) + case Block(Nil, expr) => allTermArguments(expr) case _ => Nil } @@ -146,7 +150,7 @@ trait TreeInfo[T <: Untyped] { self: Trees.Instance[T] => def allArguments(tree: Tree): List[Tree] = unsplice(tree) match { case Apply(fn, args) => allArguments(fn) ::: args case TypeApply(fn, args) => allArguments(fn) ::: args - case Block(_, expr) => allArguments(expr) + case Block(Nil, expr) => allArguments(expr) case _ => Nil } diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index fad1e2b1bd9f..f70a4ffef914 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -1039,7 +1039,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { def recur(t: untpd.Tree): Text = t match case Apply(fn, Nil) => recur(fn) case Apply(fn, args) => - val explicitArgs = args.filterNot(_.symbol.name.is(DefaultGetterName)) + val explicitArgs = args.filterNot(untpd.stripNamedArg(_).symbol.name.is(DefaultGetterName)) recur(fn) ~ "(" ~ toTextGlobal(explicitArgs, ", ") ~ ")" case TypeApply(fn, args) => recur(fn) ~ "[" ~ toTextGlobal(args, ", ") ~ "]" case Select(qual, nme.CONSTRUCTOR) => recur(qual) diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index 819eb92febb0..f8594e1460a8 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -459,7 +459,7 @@ trait Applications extends Compatibility { case tp => args.size } - !isJavaAnnotConstr(methRef.symbol) && + !isAnnotConstr(methRef.symbol) && args.size < requiredArgNum(funType) } @@ -591,6 +591,11 @@ trait Applications extends Compatibility { def isJavaAnnotConstr(sym: Symbol): Boolean = sym.is(JavaDefined) && sym.isConstructor && sym.owner.is(JavaAnnotation) + + /** Is `sym` a constructor of an annotation? */ + def isAnnotConstr(sym: Symbol): Boolean = + sym.isConstructor && sym.owner.isAnnotation + /** Match re-ordered arguments against formal parameters * @param n The position of the first parameter in formals in `methType`. */ diff --git a/tests/printing/dependent-annot-default-args.check b/tests/printing/dependent-annot-default-args.check new file mode 100644 index 000000000000..44c1fe31e2d1 --- /dev/null +++ b/tests/printing/dependent-annot-default-args.check @@ -0,0 +1,25 @@ +[[syntax trees at end of typer]] // tests/printing/dependent-annot-default-args.scala +package { + class annot(x: Any, y: Any) extends annotation.Annotation() { + private[this] val x: Any + private[this] val y: Any + } + final lazy module val annot: annot = new annot() + final module class annot() extends AnyRef() { this: annot.type => + def $lessinit$greater$default$2: Any @uncheckedVariance = 42 + } + final lazy module val dependent-annot-default-args$package: + dependent-annot-default-args$package = + new dependent-annot-default-args$package() + final module class dependent-annot-default-args$package() extends Object() { + this: dependent-annot-default-args$package.type => + def f(x: Int): Int @annot(x) = x + def test: Unit = + { + val y: Int = ??? + val z: Int @annot(y) = f(y) + () + } + } +} + diff --git a/tests/printing/dependent-annot-default-args.scala b/tests/printing/dependent-annot-default-args.scala new file mode 100644 index 000000000000..7ddce711fedc --- /dev/null +++ b/tests/printing/dependent-annot-default-args.scala @@ -0,0 +1,5 @@ +class annot(x: Any, y: Any = 42) extends annotation.Annotation +def f(x: Int): Int @annot(x) = x +def test = + val y: Int = ??? + val z = f(y) From 405b104f5fcfc7f38110043016798475baa0b160 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 14:36:03 +0000 Subject: [PATCH 2/5] Bump webrick from 1.8.2 to 1.9.1 in /docs/_spec Bumps [webrick](https://github.com/ruby/webrick) from 1.8.2 to 1.9.1. - [Release notes](https://github.com/ruby/webrick/releases) - [Commits](https://github.com/ruby/webrick/compare/v1.8.2...v1.9.1) --- updated-dependencies: - dependency-name: webrick dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] [Cherry-picked f47d103eb9dc3d679441d5efad6b3b08129ccca5] --- docs/_spec/Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_spec/Gemfile.lock b/docs/_spec/Gemfile.lock index c703a87bf993..38a790c676eb 100644 --- a/docs/_spec/Gemfile.lock +++ b/docs/_spec/Gemfile.lock @@ -41,7 +41,7 @@ GEM sass-listen (4.0.0) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) - webrick (1.8.2) + webrick (1.9.1) PLATFORMS ruby From 92a79c610f5ecb193bced56758ee54cbd186fb8e Mon Sep 17 00:00:00 2001 From: Matt Bovel Date: Tue, 3 Dec 2024 16:15:56 +0000 Subject: [PATCH 3/5] Update Scala CLI to 1.5.4 (was 1.5.1) & `coursier` to 2.1.18 (was 2.1.13) (#22021) https://github.com/VirtusLab/scala-cli/releases/tag/v1.5.4 https://github.com/coursier/coursier/releases/tag/v2.1.18 cc @WojciechMazur --- .github/workflows/ci.yaml | 6 ++-- build.sbt | 2 +- .../dotty/tools/pc/base/BasePCSuite.scala | 8 ++--- project/Build.scala | 33 +++++++++---------- 4 files changed, 23 insertions(+), 26 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index da65d980b706..b8fc6d624997 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -27,10 +27,10 @@ on: - cron: '0 3 * * *' # Every day at 3 AM workflow_dispatch: -# Cancels any in-progress runs within the same group identified by workflow name and GH reference (branch or tag) +# Cancels any in-progress runs within the same group identified by workflow name and GH reference (branch or tag) # For example it would: # - terminate previous PR CI execution after pushing more changes to the same PR branch -# - terminate previous on-push CI run after merging new PR to main +# - terminate previous on-push CI run after merging new PR to main concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} @@ -183,7 +183,7 @@ jobs: uses: actions/checkout@v4 - name: Test - run: sbt ";scala3-bootstrapped/compile; scala3-bootstrapped/testCompilation; scala3-presentation-compiler-bootstrapped/test; scala3-language-server/test" + run: sbt ";scala3-bootstrapped/compile; scala3-bootstrapped/testCompilation; scala3-presentation-compiler/test; scala3-language-server/test" shell: cmd - name: build binary diff --git a/build.sbt b/build.sbt index d6a366305f96..8f4a78338a97 100644 --- a/build.sbt +++ b/build.sbt @@ -29,7 +29,7 @@ val dist = Build.dist val `community-build` = Build.`community-build` val `sbt-community-build` = Build.`sbt-community-build` val `scala3-presentation-compiler` = Build.`scala3-presentation-compiler` -val `scala3-presentation-compiler-bootstrapped` = Build.`scala3-presentation-compiler-bootstrapped` +val `scala3-presentation-compiler-testcases` = Build.`scala3-presentation-compiler-testcases` val sjsSandbox = Build.sjsSandbox val sjsJUnitTests = Build.sjsJUnitTests diff --git a/presentation-compiler/test/dotty/tools/pc/base/BasePCSuite.scala b/presentation-compiler/test/dotty/tools/pc/base/BasePCSuite.scala index 9249d813a880..ae1e49e068fe 100644 --- a/presentation-compiler/test/dotty/tools/pc/base/BasePCSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/base/BasePCSuite.scala @@ -25,9 +25,9 @@ import org.junit.runner.RunWith import scala.meta.pc.CompletionItemPriority object TestResources: - val scalaLibrary = BuildInfo.ideTestsDependencyClasspath.map(_.toPath).toSeq + val classpath = BuildInfo.ideTestsDependencyClasspath.map(_.toPath).toSeq val classpathSearch = - ClasspathSearch.fromClasspath(scalaLibrary, ExcludedPackagesHandler.default) + ClasspathSearch.fromClasspath(classpath, ExcludedPackagesHandler.default) @RunWith(classOf[ReusableClassRunner]) abstract class BasePCSuite extends PcAssertions: @@ -38,11 +38,11 @@ abstract class BasePCSuite extends PcAssertions: val executorService: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor() val testingWorkspaceSearch = TestingWorkspaceSearch( - TestResources.scalaLibrary.map(_.toString) + TestResources.classpath.map(_.toString) ) lazy val presentationCompiler: PresentationCompiler = - val myclasspath: Seq[Path] = TestResources.scalaLibrary + val myclasspath: Seq[Path] = TestResources.classpath val scalacOpts = scalacOptions(myclasspath) val search = new MockSymbolSearch( testingWorkspaceSearch, diff --git a/project/Build.scala b/project/Build.scala index b19b1b5440c2..db68a8b794a4 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1152,27 +1152,25 @@ object Build { libraryDependencies += ("org.scala-sbt" %% "zinc-apiinfo" % "1.8.0" % Test).cross(CrossVersion.for3Use2_13) ) - lazy val `scala3-presentation-compiler` = project.in(file("presentation-compiler")) - .asScala3PresentationCompiler(NonBootstrapped) - lazy val `scala3-presentation-compiler-bootstrapped` = project.in(file("presentation-compiler")) - .asScala3PresentationCompiler(Bootstrapped) - def scala3PresentationCompiler(implicit mode: Mode): Project = mode match { - case NonBootstrapped => `scala3-presentation-compiler` - case Bootstrapped => `scala3-presentation-compiler-bootstrapped` - } + lazy val `scala3-presentation-compiler` = project.in(file("presentation-compiler")) + .withCommonSettings(Bootstrapped) + .dependsOn(`scala3-compiler-bootstrapped`, `scala3-library-bootstrapped`, `scala3-presentation-compiler-testcases` % "test->test") + .settings(presentationCompilerSettings) + .settings(scala3PresentationCompilerBuildInfo) - def scala3PresentationCompilerBuildInfo(implicit mode: Mode) = + def scala3PresentationCompilerBuildInfo = Seq( ideTestsDependencyClasspath := { - val dottyLib = (dottyLibrary / Compile / classDirectory).value + val testCasesLib = (`scala3-presentation-compiler-testcases` / Compile / classDirectory).value + val dottyLib = (`scala3-library-bootstrapped` / Compile / classDirectory).value val scalaLib = - (dottyLibrary / Compile / dependencyClasspath) + (`scala3-library-bootstrapped` / Compile / dependencyClasspath) .value .map(_.data) .filter(_.getName.matches("scala-library.*\\.jar")) .toList - dottyLib :: scalaLib + testCasesLib :: dottyLib :: scalaLib // Nil }, Compile / buildInfoPackage := "dotty.tools.pc.buildinfo", @@ -1231,6 +1229,10 @@ object Build { ) } + lazy val `scala3-presentation-compiler-testcases` = project.in(file("presentation-compiler-testcases")) + .dependsOn(`scala3-compiler-bootstrapped`) + .settings(commonBootstrappedSettings) + lazy val `scala3-language-server` = project.in(file("language-server")). dependsOn(dottyCompiler(Bootstrapped)). settings(commonBootstrappedSettings). @@ -1959,7 +1961,7 @@ object Build { // FIXME: we do not aggregate `bin` because its tests delete jars, thus breaking other tests def asDottyRoot(implicit mode: Mode): Project = project.withCommonSettings. - aggregate(`scala3-interfaces`, dottyLibrary, dottyCompiler, tastyCore, `scala3-sbt-bridge`, scala3PresentationCompiler). + aggregate(`scala3-interfaces`, dottyLibrary, dottyCompiler, tastyCore, `scala3-sbt-bridge`, `scala3-presentation-compiler`). bootstrappedAggregate(`scala3-language-server`, `scala3-staging`, `scala3-tasty-inspector`, `scala3-library-bootstrappedJS`, scaladoc). dependsOn(tastyCore). @@ -2038,11 +2040,6 @@ object Build { settings(commonBenchmarkSettings). enablePlugins(JmhPlugin) - def asScala3PresentationCompiler(implicit mode: Mode): Project = project.withCommonSettings. - dependsOn(dottyCompiler, dottyLibrary). - settings(presentationCompilerSettings). - settings(scala3PresentationCompilerBuildInfo) - def asDist(implicit mode: Mode): Project = project. enablePlugins(PackPlugin). withCommonSettings. From 0d07deac2338029d3cedfcfa88df9cb6fd5f2702 Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Tue, 11 Mar 2025 12:16:21 +0100 Subject: [PATCH 4/5] Add test cases project for presentation compiler [Cherry-picked 75f1ec78e68739bb9064081f8651840b2fce9b74][modified] From d4e90f816864544a2f77284bd313e5d32a827c1a Mon Sep 17 00:00:00 2001 From: Matt Bovel Date: Tue, 3 Dec 2024 16:22:20 +0000 Subject: [PATCH 5/5] Add test cases for #20560 [Cherry-picked 39f54dfdaccd518a4ddd54ca228a836495b62d99] --- .../src/tests/macros/20560.scala | 16 ++++++++++++++++ .../tools/pc/tests/hover/HoverTermSuite.scala | 15 +++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 presentation-compiler-testcases/src/tests/macros/20560.scala diff --git a/presentation-compiler-testcases/src/tests/macros/20560.scala b/presentation-compiler-testcases/src/tests/macros/20560.scala new file mode 100644 index 000000000000..f72fc473f452 --- /dev/null +++ b/presentation-compiler-testcases/src/tests/macros/20560.scala @@ -0,0 +1,16 @@ +package tests.macros + +import scala.quoted.{Expr, Quotes} + +object Macro20560: + transparent inline def loadJavaSqlDriver: Int = ${ loadJavaSqlDriverImpl } + + private def loadJavaSqlDriverImpl(using Quotes): Expr[42] = + Class.forName("java.sql.Driver") + '{42} + + transparent inline def loadJavaSqlInexisting: Int = ${ loadJavaSqlInexistingImpl } + + private def loadJavaSqlInexistingImpl(using Quotes): Expr[42] = + Class.forName("java.sql.Inexisting") + '{42} diff --git a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTermSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTermSuite.scala index ac42663d929c..2828b946c7c3 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTermSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTermSuite.scala @@ -596,6 +596,21 @@ class HoverTermSuite extends BaseHoverSuite: |""".stripMargin ) + @Test def `i20560`= + check( + "val re@@s = tests.macros.Macro20560.loadJavaSqlDriver", + """```scala + |val res: Int + |``` + |""".stripMargin + ) + + @Test def `i20560-2`= + check( + "val re@@s = tests.macros.Macro20560.loadJavaSqlInexisting", + "", // crashes in the Macro; no type info + ) + @Test def `import-rename` = check( """