diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9049dd13c..ad88219d2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,6 +51,7 @@ jobs: JVM_OPTS: -Xms800M -Xmx2G -Xss6M -XX:ReservedCodeCacheSize=128M -server -Dsbt.io.virtual=false -Dfile.encoding=UTF-8 SCALA_212: 2.12.15 SCALA_213: 2.13.6 + SCALA_3: 3.1.0 UTIL_TESTS: "utilCache/test utilControl/test utilInterface/test utilLogging/test utilPosition/test utilRelation/test utilScripted/test utilTracking/test" SBT_LOCAL: false TEST_SBT_VER: 1.5.0 @@ -134,7 +135,7 @@ jobs: if: ${{ matrix.jobtype == 5 }} shell: bash run: | - ./sbt -v "++$SCALA_213!; test;" + ./sbt -v "++$SCALA_213!; test; ++$SCALA_3!; all utilControl/test utilRelation/test utilPosition/test" - name: Build and test (6) if: ${{ matrix.jobtype == 6 }} shell: bash diff --git a/.scalafmt.conf b/.scalafmt.conf index 213dea496..06a114f59 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -21,3 +21,8 @@ align.openParenDefnSite = false danglingParentheses = true trailingCommas = preserve + +# TODO update scalafmt and enable Scala 3 +project.excludeFilters = [ + "internal/util-position/src/main/scala-3/sbt/internal/util/SourcePositionMacro.scala" +] diff --git a/internal/util-position/src/main/scala-2/sbt/internal/util/SourcePositionMacro.scala b/internal/util-position/src/main/scala-2/sbt/internal/util/SourcePositionMacro.scala new file mode 100644 index 000000000..a4a38e744 --- /dev/null +++ b/internal/util-position/src/main/scala-2/sbt/internal/util/SourcePositionMacro.scala @@ -0,0 +1,53 @@ +/* + * sbt + * Copyright 2011 - 2018, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under Apache License 2.0 (see LICENSE) + */ + +package sbt.internal.util + +import scala.language.experimental.macros +import scala.annotation.tailrec +import scala.reflect.macros.blackbox +import scala.reflect.internal.util.UndefinedPosition + +abstract class SourcePositionImpl { + + /** Creates a SourcePosition by using the enclosing position of the invocation of this method. + * @return SourcePosition + */ + def fromEnclosing(): SourcePosition = macro SourcePositionMacro.fromEnclosingImpl +} + +final class SourcePositionMacro(val c: blackbox.Context) { + import c.universe.{ NoPosition => _, _ } + + def fromEnclosingImpl(): Expr[SourcePosition] = { + val pos = c.enclosingPosition + if (!pos.isInstanceOf[UndefinedPosition] && pos.line >= 0 && pos.source != null) { + val f = pos.source.file + val name = constant[String](ownerSource(f.path, f.name)) + val line = constant[Int](pos.line) + reify { LinePosition(name.splice, line.splice) } + } else + reify { NoPosition } + } + + private[this] def ownerSource(path: String, name: String): String = { + @tailrec def inEmptyPackage(s: Symbol): Boolean = + s != NoSymbol && ( + s.owner == c.mirror.EmptyPackage + || s.owner == c.mirror.EmptyPackageClass + || inEmptyPackage(s.owner) + ) + + c.internal.enclosingOwner match { + case ec if !ec.isStatic => name + case ec if inEmptyPackage(ec) => path + case ec => s"(${ec.fullName}) $name" + } + } + + private[this] def constant[T: WeakTypeTag](t: T): Expr[T] = c.Expr[T](Literal(Constant(t))) +} diff --git a/internal/util-position/src/main/scala-3/sbt/internal/util/SourcePositionMacro.scala b/internal/util-position/src/main/scala-3/sbt/internal/util/SourcePositionMacro.scala new file mode 100644 index 000000000..f6e45f37d --- /dev/null +++ b/internal/util-position/src/main/scala-3/sbt/internal/util/SourcePositionMacro.scala @@ -0,0 +1,34 @@ +/* + * sbt + * Copyright 2011 - 2018, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under Apache License 2.0 (see LICENSE) + */ + +package sbt.internal.util + +import scala.quoted.{ Expr, Quotes, quotes } + +abstract class SourcePositionImpl { + + /** Creates a SourcePosition by using the enclosing position of the invocation of this method. + * + * @return SourcePosition + */ + inline def fromEnclosing(): SourcePosition = + ${ SourcePositionImpl.fromEnclosingImpl } +} + +object SourcePositionImpl { + + def fromEnclosingImpl(using Quotes): Expr[SourcePosition] = { + val x = quotes.reflect.Position.ofMacroExpansion + + '{ + LinePosition( + path = ${Expr(x.sourceFile.name)}, + startLine = ${Expr(x.startLine + 1)} + ) + } + } +} diff --git a/internal/util-position/src/main/scala/sbt/internal/util/Positions.scala b/internal/util-position/src/main/scala/sbt/internal/util/Positions.scala index c3895a4bd..78deb8e48 100644 --- a/internal/util-position/src/main/scala/sbt/internal/util/Positions.scala +++ b/internal/util-position/src/main/scala/sbt/internal/util/Positions.scala @@ -7,8 +7,6 @@ package sbt.internal.util -import scala.language.experimental.macros - sealed trait SourcePosition sealed trait FilePosition extends SourcePosition { @@ -28,47 +26,4 @@ final case class RangePosition(path: String, range: LineRange) extends FilePosit def startLine = range.start } -object SourcePosition { - - /** Creates a SourcePosition by using the enclosing position of the invocation of this method. - * @return SourcePosition - */ - def fromEnclosing(): SourcePosition = macro SourcePositionMacro.fromEnclosingImpl - -} - -import scala.annotation.tailrec -import scala.reflect.macros.blackbox -import scala.reflect.internal.util.UndefinedPosition - -final class SourcePositionMacro(val c: blackbox.Context) { - import c.universe.{ NoPosition => _, _ } - - def fromEnclosingImpl(): Expr[SourcePosition] = { - val pos = c.enclosingPosition - if (!pos.isInstanceOf[UndefinedPosition] && pos.line >= 0 && pos.source != null) { - val f = pos.source.file - val name = constant[String](ownerSource(f.path, f.name)) - val line = constant[Int](pos.line) - reify { LinePosition(name.splice, line.splice) } - } else - reify { NoPosition } - } - - private[this] def ownerSource(path: String, name: String): String = { - @tailrec def inEmptyPackage(s: Symbol): Boolean = - s != NoSymbol && ( - s.owner == c.mirror.EmptyPackage - || s.owner == c.mirror.EmptyPackageClass - || inEmptyPackage(s.owner) - ) - - c.internal.enclosingOwner match { - case ec if !ec.isStatic => name - case ec if inEmptyPackage(ec) => path - case ec => s"(${ec.fullName}) $name" - } - } - - private[this] def constant[T: WeakTypeTag](t: T): Expr[T] = c.Expr[T](Literal(Constant(t))) -} +object SourcePosition extends SourcePositionImpl