From 7af9a40d8320c9ae3177e3438bd479f7ef228d8c Mon Sep 17 00:00:00 2001 From: rochala Date: Tue, 5 Apr 2022 17:36:41 +0200 Subject: [PATCH 1/8] fix uncompiling snippets and incorrect indentation for reflection snippet docs --- library/src/scala/Tuple.scala | 4 +- library/src/scala/quoted/Exprs.scala | 7 +-- library/src/scala/quoted/Quotes.scala | 13 ++--- library/src/scala/quoted/Type.scala | 21 ++------ library/src/scala/quoted/Varargs.scala | 21 ++------ project/Build.scala | 3 +- .../src/tests/snippetCompilerTests.scala | 20 +++++++- .../scaladoc/snippets/SnippetChecker.scala | 48 ++++++++++++++----- .../snippets/SnippetCompilerArgs.scala | 16 +++---- .../scaladoc/snippets/WrappedSnippet.scala | 48 ++++++++++--------- 10 files changed, 105 insertions(+), 96 deletions(-) diff --git a/library/src/scala/Tuple.scala b/library/src/scala/Tuple.scala index cc26061c203c..59a1652ac623 100644 --- a/library/src/scala/Tuple.scala +++ b/library/src/scala/Tuple.scala @@ -156,11 +156,11 @@ object Tuple { /** Filters out those members of the tuple for which the predicate `P` returns `false`. * A predicate `P[X]` is a type that can be either `true` or `false`. For example: * ```scala - * type IsString[x] = x match { + * type IsString[x] <: Boolean = x match { * case String => true * case _ => false * } - * Filter[(1, "foo", 2, "bar"), IsString] =:= ("foo", "bar") + * summon[Tuple.Filter[(1, "foo", 2, "bar"), IsString] =:= ("foo", "bar")] * ``` * @syntax markdown */ diff --git a/library/src/scala/quoted/Exprs.scala b/library/src/scala/quoted/Exprs.scala index 24e1ed16552f..450f501c9d4f 100644 --- a/library/src/scala/quoted/Exprs.scala +++ b/library/src/scala/quoted/Exprs.scala @@ -5,14 +5,11 @@ object Exprs: /** Matches literal sequence of literal constant value expressions and return a sequence of values. * * Usage: - * ```scala sc:nocompile + * ```scala sc:macrocompile * inline def sum(args: Int*): Int = ${ sumExpr('args) } * def sumExpr(argsExpr: Expr[Seq[Int]])(using Quotes): Expr[Int] = argsExpr match - * case Varargs(Exprs(args)) => - * case Varargs(Exprs(args)) => + * case Varargs(Exprs(args)) => ??? * // args: Seq[Int] - * ... - * } * ``` * To directly get the value of all expressions in a sequence `exprs: Seq[Expr[T]]` consider using `exprs.map(_.value)`/`exprs.map(_.valueOrError)` instead. */ diff --git a/library/src/scala/quoted/Quotes.scala b/library/src/scala/quoted/Quotes.scala index c1ceb98ea5d3..b528fedb0f8d 100644 --- a/library/src/scala/quoted/Quotes.scala +++ b/library/src/scala/quoted/Quotes.scala @@ -6,10 +6,11 @@ import scala.reflect.TypeTest /** Current Quotes in scope * * Usage: - * ```scala sc:nocompile + * ```scala + * import scala.quoted._ * def myExpr[T](using Quotes): Expr[T] = { * import quotes.reflect._ - * ... + * ??? * } * ``` */ @@ -2532,17 +2533,11 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => /** Convert this `TypeRepr` to an `Type[?]` * * Usage: - * ```scala - * //{ - * def f(using Quotes) = { + * ```scala sc:usingquotes * val typeRepr: TypeRepr = ??? - * //} * typeRepr.asType match * case '[t] => * '{ val x: t = ??? } - * //{ - * } - * //} * ``` */ def asType: Type[?] diff --git a/library/src/scala/quoted/Type.scala b/library/src/scala/quoted/Type.scala index b4306a51fff0..eda1c26fe7db 100644 --- a/library/src/scala/quoted/Type.scala +++ b/library/src/scala/quoted/Type.scala @@ -26,20 +26,13 @@ object Type: * Returns None if the type is not a singleton constant type. * * Example usage: - * ```scala - * //{ + * ```scala sc:usingquotes * import scala.deriving.* - * def f(using Quotes) = { * import quotes.reflect.* * val expr: Expr[Any] = ??? - * //} - * expr match { + * expr match * case '{ $mirrorExpr : Mirror.Sum { type MirroredLabel = label } } => * Type.valueOfConstant[label] // Option[String] - * } - * //{ - * } - * //} * ``` */ def valueOfConstant[T](using Type[T])(using Quotes): Option[T] = @@ -50,20 +43,14 @@ object Type: * Returns None if the type is not a tuple singleton constant types. * * Example usage: - * ```scala + * ```scala sc:usingquotes * //{ * import scala.deriving.* - * def f(using Quotes) = { * import quotes.reflect.* * val expr: Expr[Any] = ??? - * //} - * expr match { + * expr match * case '{ type label <: Tuple; $mirrorExpr : Mirror.Sum { type MirroredElemLabels = `label` } } => * Type.valueOfTuple[label] // Option[Tuple] - * } - * //{ - * } - * //} * ``` */ @since("3.1") diff --git a/library/src/scala/quoted/Varargs.scala b/library/src/scala/quoted/Varargs.scala index e69f11e479f7..28cd80a20ec8 100644 --- a/library/src/scala/quoted/Varargs.scala +++ b/library/src/scala/quoted/Varargs.scala @@ -16,15 +16,9 @@ object Varargs { * `'{ Seq($e1, $e2, ...) }` typed as an `Expr[Seq[T]]` * * Usage: - * ```scala - * //{ - * def f(using Quotes) = { + * ```scala sc:usingquotes * import quotes.reflect.* - * //} * '{ List(${Varargs(List('{1}, '{2}, '{3}))}: _*) } // equivalent to '{ List(1, 2, 3) } - * //{ - * } - * //} * ``` */ def apply[T](xs: Seq[Expr[T]])(using Type[T])(using Quotes): Expr[Seq[T]] = { @@ -35,19 +29,12 @@ object Varargs { /** Matches a literal sequence of expressions and return a sequence of expressions. * * Usage: - * ```scala sc:nocompile - * //{ - * object O { - * //} + * ```scala sc:macrocompile * inline def sum(args: Int*): Int = ${ sumExpr('args) } * def sumExpr(argsExpr: Expr[Seq[Int]])(using Quotes): Expr[Int] = argsExpr match - * case Varargs(argVarargs) => + * case Varargs(argVarargs) => ??? * // argVarargs: Seq[Expr[Int]] - * ??? - * //{ - * } - * //} - * ``` + * */ def unapply[T](expr: Expr[Seq[T]])(using Quotes): Option[Seq[Expr[T]]] = { import quotes.reflect._ diff --git a/project/Build.scala b/project/Build.scala index 52f4176e6be9..0974ff6ab882 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1845,8 +1845,7 @@ object ScaladocConfigs { .add(VersionsDictionaryUrl("https://scala-lang.org/api/versions.json")) .add(DocumentSyntheticTypes(true)) .add(SnippetCompiler(List( - s"${dottyLibRoot}/scala/quoted=compile", - s"${dottyLibRoot}/scala/compiletime=compile" + s"${dottyLibRoot}/scala=compile", ))) .add(SiteRoot("docs")) .add(ApiSubdirectory(true)) diff --git a/scaladoc-testcases/src/tests/snippetCompilerTests.scala b/scaladoc-testcases/src/tests/snippetCompilerTests.scala index 3d03438f7f3c..a14cf7e75fd9 100644 --- a/scaladoc-testcases/src/tests/snippetCompilerTests.scala +++ b/scaladoc-testcases/src/tests/snippetCompilerTests.scala @@ -54,6 +54,24 @@ class A { */ class B { } +/** + * ```scala sc:macrocompile + * inline def sum(args: Int*): Int = ${ sumExpr('args) } + * def sumExpr(argsExpr: Expr[Seq[Int]])(using Quotes): Expr[Int] = argsExpr match + * case Varargs(Exprs(args)) => ??? + * // args: Seq[Int] + * ``` + */ +class C { } + +/** + * ```scala sc:usingquotes + * import quotes.reflect.* + * '{ List(${Varargs(List('{1}, '{2}, '{3}))}: _*) } // equivalent to '{ List(1, 2, 3) } + * ``` + */ +class D { } + trait Quotes { val reflect: reflectModule = ??? trait reflectModule { self: reflect.type => @@ -65,4 +83,4 @@ trait Quotes { */ def a = 3 } -} \ No newline at end of file +} diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala index 77ab539d34fa..55bf3f394309 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala @@ -44,18 +44,42 @@ class SnippetChecker(val args: Scaladoc.Args)(using cctx: CompilerContext): lineOffset: SnippetChecker.LineOffset, sourceFile: SourceFile ): Option[SnippetCompilationResult] = { - if arg.flag != SCFlags.NoCompile then - val wrapped = WrappedSnippet( - snippet, - data.map(_.packageName), - data.fold(Nil)(_.classInfos), - data.map(_.imports).getOrElse(Nil), - lineOffset + data.fold(0)(_.position.line) + constantLineOffset, - data.fold(0)(_.position.column) + constantColumnOffset - ) - val res = compiler.compile(wrapped, arg, sourceFile) - Some(res) - else None + arg.flag match + case SCFlags.Compile | SCFlags.Fail => + val wrapped = WrappedSnippet( + snippet, + data.map(_.packageName), + data.fold(Nil)(_.classInfos), + data.map(_.imports).getOrElse(Nil), + lineOffset + data.fold(0)(_.position.line) + constantLineOffset, + data.fold(0)(_.position.column) + constantColumnOffset + ) + val res = compiler.compile(wrapped, arg, sourceFile) + Some(res) + case SCFlags.MacroCompile => + val wrapped = WrappedSnippet( + snippet, + data.map(_.packageName), + data.map(_.imports).getOrElse(Nil), + lineOffset + data.fold(0)(_.position.line) + constantLineOffset, + data.fold(0)(_.position.column) + constantColumnOffset + ) + val res = compiler.compile(wrapped, arg, sourceFile) + Some(res) + case SCFlags.UsingQuotes => + val wrapped = WrappedSnippet( + snippet, + data.map(_.packageName), + data.fold(Nil)(_.classInfos), + data.map(_.imports).getOrElse(Nil), + lineOffset + data.fold(0)(_.position.line) + constantLineOffset, + data.fold(0)(_.position.column) + constantColumnOffset, + true + ) + val res = compiler.compile(wrapped, arg, sourceFile) + Some(res) + case SCFlags.NoCompile => None + } object SnippetChecker: diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompilerArgs.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompilerArgs.scala index 240c99840032..cae8f48b36a9 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompilerArgs.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompilerArgs.scala @@ -6,14 +6,12 @@ import java.nio.file.Path case class SnippetCompilerArg(flag: SCFlags): def overrideFlag(f: SCFlags): SnippetCompilerArg = copy(flag = f) -sealed trait SCFlags(val flagName: String) - -object SCFlags: - case object Compile extends SCFlags("compile") - case object NoCompile extends SCFlags("nocompile") - case object Fail extends SCFlags("fail") - - def values: Seq[SCFlags] = Seq(Compile, NoCompile, Fail) +enum SCFlags(val flagName: String): + case Compile extends SCFlags("compile") + case MacroCompile extends SCFlags("macrocompile") + case UsingQuotes extends SCFlags("usingquotes") + case NoCompile extends SCFlags("nocompile") + case Fail extends SCFlags("fail") case class SnippetCompilerArgs(scFlags: PathBased[SCFlags], defaultFlag: SCFlags): def get(member: Member): SnippetCompilerArg = @@ -41,6 +39,8 @@ object SnippetCompilerArgs: | |Available flags: |compile - Enables snippet checking. + |macrocompile - Enables snippet checking for macros. + |usingquotes - Enables checking snippet additionally wrapped in `scala.quoted.Quotes` impilicit scope. |nocompile - Disables snippet checking. |fail - Enables snippet checking, asserts that snippet doesn't compile. | diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/WrappedSnippet.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/WrappedSnippet.scala index d3ad8db8f9d3..49718edd7e81 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/WrappedSnippet.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/WrappedSnippet.scala @@ -10,18 +10,14 @@ object WrappedSnippet: val indent: Int = 2 - def apply(str: String): WrappedSnippet = - val baos = new ByteArrayOutputStream() - val ps = new PrintStream(baos) - ps.startHide() - ps.println("package snippets") - ps.println("object Snippet {") - ps.endHide() - str.split('\n').foreach(ps.printlnWithIndent(indent, _)) - ps.startHide() - ps.println("}") - ps.endHide() - WrappedSnippet(baos.toString, 0, 0, indent + 2 /*Hide tokens*/, indent) + def apply( + str: String, + packageName: Option[String], + imports: List[String], + outerLineOffset: Int, + outerColumnOffset: Int + ): WrappedSnippet = + apply(str, packageName, Nil, imports, outerLineOffset, outerColumnOffset) def apply( str: String, @@ -29,31 +25,37 @@ object WrappedSnippet: classInfos: Seq[SnippetCompilerData.ClassInfo], imports: List[String], outerLineOffset: Int, - outerColumnOffset: Int + outerColumnOffset: Int, + usingQuotes: Boolean = false ): WrappedSnippet = val baos = new ByteArrayOutputStream() val ps = new PrintStream(baos) ps.startHide() ps.println(s"package ${packageName.getOrElse("snippets")}") imports.foreach(i => ps.println(s"import $i")) - val notEmptyClassInfos = if classInfos.isEmpty then Seq(SnippetCompilerData.ClassInfo(None, Nil, None)) else classInfos - notEmptyClassInfos.zipWithIndex.foreach { (info, i) => - ps.printlnWithIndent(indent * i, s"trait Snippet$i${info.generics.getOrElse("")} { ${info.tpe.fold("")(cn => s"self: $cn =>")}") - info.names.foreach{ name => - ps.printlnWithIndent(indent * i + indent, s"val $name = self") + val classInfoSize = if classInfos.isEmpty then 1 else classInfos.length + (if usingQuotes then 1 else 0) + if classInfos.isEmpty then + ps.println("object Snippet {") + else + classInfos.zipWithIndex.foreach { (info, i) => + ps.printlnWithIndent(indent * i, s"trait Snippet$i${info.generics.getOrElse("")} { ${info.tpe.fold("")(cn => s"self: $cn =>")}") + info.names.foreach{ name => + ps.printlnWithIndent(indent * i + indent, s"val $name = self") + } } - } + if usingQuotes then + ps.printlnWithIndent(classInfos.length * indent, "def f(using Quotes) = {") ps.endHide() - str.split('\n').foreach(ps.printlnWithIndent(notEmptyClassInfos.size * indent, _)) + str.split('\n').foreach(ps.printlnWithIndent(classInfoSize * indent, _)) ps.startHide() - (0 to notEmptyClassInfos.size -1).reverse.foreach( i => ps.printlnWithIndent(i * indent, "}")) + (0 to classInfoSize -1).reverse.foreach( i => ps.printlnWithIndent(i * indent, "}")) ps.endHide() WrappedSnippet( baos.toString, outerLineOffset, outerColumnOffset, - notEmptyClassInfos.size + notEmptyClassInfos.flatMap(_.names).size + packageName.size + 2 /*Hide tokens*/, - notEmptyClassInfos.size * indent + classInfoSize + classInfos.flatMap(_.names).size + packageName.size + 2 /*Hide tokens*/, + classInfoSize * indent ) extension (ps: PrintStream) From 04d4d87e9313c91590bd9a12313d52e43dbf810f Mon Sep 17 00:00:00 2001 From: rochala Date: Tue, 5 Apr 2022 18:33:01 +0200 Subject: [PATCH 2/8] variable rename --- .../dotty/tools/scaladoc/snippets/WrappedSnippet.scala | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/WrappedSnippet.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/WrappedSnippet.scala index 49718edd7e81..ea429c1e13a9 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/WrappedSnippet.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/WrappedSnippet.scala @@ -33,7 +33,7 @@ object WrappedSnippet: ps.startHide() ps.println(s"package ${packageName.getOrElse("snippets")}") imports.foreach(i => ps.println(s"import $i")) - val classInfoSize = if classInfos.isEmpty then 1 else classInfos.length + (if usingQuotes then 1 else 0) + val nestLevels = if classInfos.isEmpty then 1 else classInfos.length + (if usingQuotes then 1 else 0) if classInfos.isEmpty then ps.println("object Snippet {") else @@ -46,16 +46,16 @@ object WrappedSnippet: if usingQuotes then ps.printlnWithIndent(classInfos.length * indent, "def f(using Quotes) = {") ps.endHide() - str.split('\n').foreach(ps.printlnWithIndent(classInfoSize * indent, _)) + str.split('\n').foreach(ps.printlnWithIndent(nestLevels * indent, _)) ps.startHide() - (0 to classInfoSize -1).reverse.foreach( i => ps.printlnWithIndent(i * indent, "}")) + (0 to nestLevels -1).reverse.foreach( i => ps.printlnWithIndent(i * indent, "}")) ps.endHide() WrappedSnippet( baos.toString, outerLineOffset, outerColumnOffset, - classInfoSize + classInfos.flatMap(_.names).size + packageName.size + 2 /*Hide tokens*/, - classInfoSize * indent + nestLevels + classInfos.flatMap(_.names).size + packageName.size + 2 /*Hide tokens*/, + nestLevels * indent ) extension (ps: PrintStream) From 40c9c1c9dd26c1cef3dbfcc97e8896f65a65d54f Mon Sep 17 00:00:00 2001 From: rochala Date: Tue, 5 Apr 2022 18:49:27 +0200 Subject: [PATCH 3/8] pattern matching refactor --- .../scaladoc/snippets/SnippetChecker.scala | 23 ++++--------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala index 55bf3f394309..f7a2ea6c8ef1 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala @@ -45,17 +45,17 @@ class SnippetChecker(val args: Scaladoc.Args)(using cctx: CompilerContext): sourceFile: SourceFile ): Option[SnippetCompilationResult] = { arg.flag match - case SCFlags.Compile | SCFlags.Fail => + case flag @ (SCFlags.Compile | SCFlags.Fail | SCFlags.UsingQuotes) => val wrapped = WrappedSnippet( snippet, data.map(_.packageName), data.fold(Nil)(_.classInfos), data.map(_.imports).getOrElse(Nil), lineOffset + data.fold(0)(_.position.line) + constantLineOffset, - data.fold(0)(_.position.column) + constantColumnOffset + data.fold(0)(_.position.column) + constantColumnOffset, + flag == SCFlags.UsingQuotes ) - val res = compiler.compile(wrapped, arg, sourceFile) - Some(res) + Some(compiler.compile(wrapped, arg, sourceFile)) case SCFlags.MacroCompile => val wrapped = WrappedSnippet( snippet, @@ -64,20 +64,7 @@ class SnippetChecker(val args: Scaladoc.Args)(using cctx: CompilerContext): lineOffset + data.fold(0)(_.position.line) + constantLineOffset, data.fold(0)(_.position.column) + constantColumnOffset ) - val res = compiler.compile(wrapped, arg, sourceFile) - Some(res) - case SCFlags.UsingQuotes => - val wrapped = WrappedSnippet( - snippet, - data.map(_.packageName), - data.fold(Nil)(_.classInfos), - data.map(_.imports).getOrElse(Nil), - lineOffset + data.fold(0)(_.position.line) + constantLineOffset, - data.fold(0)(_.position.column) + constantColumnOffset, - true - ) - val res = compiler.compile(wrapped, arg, sourceFile) - Some(res) + Some(compiler.compile(wrapped, arg, sourceFile)) case SCFlags.NoCompile => None } From 8057f8dff5610c4ef6c94ce1ada35bf596ca84b7 Mon Sep 17 00:00:00 2001 From: rochala Date: Tue, 5 Apr 2022 22:10:51 +0200 Subject: [PATCH 4/8] remove usingquotes arg, fix unnecessary changes --- library/src/scala/quoted/Quotes.scala | 16 +++++--- library/src/scala/quoted/Type.scala | 37 +++++++++++++------ library/src/scala/quoted/Varargs.scala | 12 ++++-- .../src/tests/snippetCompilerTests.scala | 18 +++------ .../scaladoc/snippets/SnippetChecker.scala | 35 +++++++----------- .../snippets/SnippetCompilerArgs.scala | 4 +- .../scaladoc/snippets/WrappedSnippet.scala | 35 ++++++++---------- 7 files changed, 81 insertions(+), 76 deletions(-) diff --git a/library/src/scala/quoted/Quotes.scala b/library/src/scala/quoted/Quotes.scala index 9fb88cb90665..cea8c8efe4de 100644 --- a/library/src/scala/quoted/Quotes.scala +++ b/library/src/scala/quoted/Quotes.scala @@ -2533,11 +2533,17 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => /** Convert this `TypeRepr` to an `Type[?]` * * Usage: - * ```scala sc:usingquotes - * val typeRepr: TypeRepr = ??? - * typeRepr.asType match - * case '[t] => - * '{ val x: t = ??? } + * ```scala + * //{ + * def f(using Quotes) = { + * val typeRepr: TypeRepr = ??? + * //} + * typeRepr.asType match + * case '[t] => + * '{ val x: t = ??? } + * //{ + * } + * //} * ``` */ def asType: Type[?] diff --git a/library/src/scala/quoted/Type.scala b/library/src/scala/quoted/Type.scala index eda1c26fe7db..78813d41b615 100644 --- a/library/src/scala/quoted/Type.scala +++ b/library/src/scala/quoted/Type.scala @@ -26,13 +26,20 @@ object Type: * Returns None if the type is not a singleton constant type. * * Example usage: - * ```scala sc:usingquotes + * ```scala + * //{ * import scala.deriving.* - * import quotes.reflect.* - * val expr: Expr[Any] = ??? - * expr match - * case '{ $mirrorExpr : Mirror.Sum { type MirroredLabel = label } } => - * Type.valueOfConstant[label] // Option[String] + * def f(using Quotes) = { + * import quotes.reflect.* + * val expr: Expr[Any] = ??? + * //} + * expr match { + * case '{ $mirrorExpr : Mirror.Sum { type MirroredLabel = label } } => + * Type.valueOfConstant[label] // Option[String] + * } + * //{ + * } + * //} * ``` */ def valueOfConstant[T](using Type[T])(using Quotes): Option[T] = @@ -43,14 +50,20 @@ object Type: * Returns None if the type is not a tuple singleton constant types. * * Example usage: - * ```scala sc:usingquotes + * ```scala * //{ * import scala.deriving.* - * import quotes.reflect.* - * val expr: Expr[Any] = ??? - * expr match - * case '{ type label <: Tuple; $mirrorExpr : Mirror.Sum { type MirroredElemLabels = `label` } } => - * Type.valueOfTuple[label] // Option[Tuple] + * def f(using Quotes) = { + * import quotes.reflect.* + * val expr: Expr[Any] = ??? + * //} + * expr match { + * case '{ type label <: Tuple; $mirrorExpr : Mirror.Sum { type MirroredElemLabels = `label` } } => + * Type.valueOfTuple[label] // Option[Tuple] + * } + * //{ + * } + * //} * ``` */ @since("3.1") diff --git a/library/src/scala/quoted/Varargs.scala b/library/src/scala/quoted/Varargs.scala index 28cd80a20ec8..ce1545654a87 100644 --- a/library/src/scala/quoted/Varargs.scala +++ b/library/src/scala/quoted/Varargs.scala @@ -16,9 +16,15 @@ object Varargs { * `'{ Seq($e1, $e2, ...) }` typed as an `Expr[Seq[T]]` * * Usage: - * ```scala sc:usingquotes - * import quotes.reflect.* - * '{ List(${Varargs(List('{1}, '{2}, '{3}))}: _*) } // equivalent to '{ List(1, 2, 3) } + * ```scala + * //{ + * def f(using Quotes) = { + * import quotes.reflect.* + * //} + * '{ List(${Varargs(List('{1}, '{2}, '{3}))}: _*) } // equivalent to '{ List(1, 2, 3) } + * //{ + * } + * //} * ``` */ def apply[T](xs: Seq[Expr[T]])(using Type[T])(using Quotes): Expr[Seq[T]] = { diff --git a/scaladoc-testcases/src/tests/snippetCompilerTests.scala b/scaladoc-testcases/src/tests/snippetCompilerTests.scala index a14cf7e75fd9..517617748b26 100644 --- a/scaladoc-testcases/src/tests/snippetCompilerTests.scala +++ b/scaladoc-testcases/src/tests/snippetCompilerTests.scala @@ -56,21 +56,15 @@ class B { } /** * ```scala sc:macrocompile - * inline def sum(args: Int*): Int = ${ sumExpr('args) } - * def sumExpr(argsExpr: Expr[Seq[Int]])(using Quotes): Expr[Int] = argsExpr match - * case Varargs(Exprs(args)) => ??? - * // args: Seq[Int] + * import scala.quoted._ + * inline def sum(args: Int*): Int = ${ sumExpr('args) } + * def sumExpr(argsExpr: Expr[Seq[Int]])(using Quotes): Expr[Int] = argsExpr match + * case Varargs(Exprs(args)) => ??? + * // args: Seq[Int] * ``` */ -class C { } -/** - * ```scala sc:usingquotes - * import quotes.reflect.* - * '{ List(${Varargs(List('{1}, '{2}, '{3}))}: _*) } // equivalent to '{ List(1, 2, 3) } - * ``` - */ -class D { } +class C { } trait Quotes { val reflect: reflectModule = ??? diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala index f7a2ea6c8ef1..0ab3216f7e35 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala @@ -44,28 +44,19 @@ class SnippetChecker(val args: Scaladoc.Args)(using cctx: CompilerContext): lineOffset: SnippetChecker.LineOffset, sourceFile: SourceFile ): Option[SnippetCompilationResult] = { - arg.flag match - case flag @ (SCFlags.Compile | SCFlags.Fail | SCFlags.UsingQuotes) => - val wrapped = WrappedSnippet( - snippet, - data.map(_.packageName), - data.fold(Nil)(_.classInfos), - data.map(_.imports).getOrElse(Nil), - lineOffset + data.fold(0)(_.position.line) + constantLineOffset, - data.fold(0)(_.position.column) + constantColumnOffset, - flag == SCFlags.UsingQuotes - ) - Some(compiler.compile(wrapped, arg, sourceFile)) - case SCFlags.MacroCompile => - val wrapped = WrappedSnippet( - snippet, - data.map(_.packageName), - data.map(_.imports).getOrElse(Nil), - lineOffset + data.fold(0)(_.position.line) + constantLineOffset, - data.fold(0)(_.position.column) + constantColumnOffset - ) - Some(compiler.compile(wrapped, arg, sourceFile)) - case SCFlags.NoCompile => None + if arg.flag != SCFlags.NoCompile then + val wrapped = WrappedSnippet( + snippet, + data.map(_.packageName), + data.fold(Nil)(_.classInfos), + data.map(_.imports).getOrElse(Nil), + lineOffset + data.fold(0)(_.position.line) + constantLineOffset, + data.fold(0)(_.position.column) + constantColumnOffset, + arg.flag + ) + Some(compiler.compile(wrapped, arg, sourceFile)) + else + None } diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompilerArgs.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompilerArgs.scala index cae8f48b36a9..495db23e35ca 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompilerArgs.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompilerArgs.scala @@ -9,7 +9,6 @@ case class SnippetCompilerArg(flag: SCFlags): enum SCFlags(val flagName: String): case Compile extends SCFlags("compile") case MacroCompile extends SCFlags("macrocompile") - case UsingQuotes extends SCFlags("usingquotes") case NoCompile extends SCFlags("nocompile") case Fail extends SCFlags("fail") @@ -39,8 +38,7 @@ object SnippetCompilerArgs: | |Available flags: |compile - Enables snippet checking. - |macrocompile - Enables snippet checking for macros. - |usingquotes - Enables checking snippet additionally wrapped in `scala.quoted.Quotes` impilicit scope. + |macrocompile - Enables snippet checking for macros. |nocompile - Disables snippet checking. |fail - Enables snippet checking, asserts that snippet doesn't compile. | diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/WrappedSnippet.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/WrappedSnippet.scala index ea429c1e13a9..63342712e8bb 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/WrappedSnippet.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/WrappedSnippet.scala @@ -10,15 +10,6 @@ object WrappedSnippet: val indent: Int = 2 - def apply( - str: String, - packageName: Option[String], - imports: List[String], - outerLineOffset: Int, - outerColumnOffset: Int - ): WrappedSnippet = - apply(str, packageName, Nil, imports, outerLineOffset, outerColumnOffset) - def apply( str: String, packageName: Option[String], @@ -26,36 +17,42 @@ object WrappedSnippet: imports: List[String], outerLineOffset: Int, outerColumnOffset: Int, - usingQuotes: Boolean = false + flag: SCFlags, ): WrappedSnippet = val baos = new ByteArrayOutputStream() val ps = new PrintStream(baos) ps.startHide() ps.println(s"package ${packageName.getOrElse("snippets")}") imports.foreach(i => ps.println(s"import $i")) - val nestLevels = if classInfos.isEmpty then 1 else classInfos.length + (if usingQuotes then 1 else 0) - if classInfos.isEmpty then + val nonEmptyClassInfos = if classInfos.isEmpty then Seq(SnippetCompilerData.ClassInfo(None, Nil, None)) else classInfos + + if flag == SCFlags.MacroCompile then ps.println("object Snippet {") else - classInfos.zipWithIndex.foreach { (info, i) => + nonEmptyClassInfos.zipWithIndex.foreach { (info, i) => ps.printlnWithIndent(indent * i, s"trait Snippet$i${info.generics.getOrElse("")} { ${info.tpe.fold("")(cn => s"self: $cn =>")}") info.names.foreach{ name => ps.printlnWithIndent(indent * i + indent, s"val $name = self") } } - if usingQuotes then - ps.printlnWithIndent(classInfos.length * indent, "def f(using Quotes) = {") + ps.endHide() - str.split('\n').foreach(ps.printlnWithIndent(nestLevels * indent, _)) + val (indentsMade, createdVals) = if flag == SCFlags.MacroCompile then + (1, 1) + else + (nonEmptyClassInfos.size, nonEmptyClassInfos.flatMap(_.names).size) + + str.split('\n').foreach(ps.printlnWithIndent(indentsMade * indent, _)) ps.startHide() - (0 to nestLevels -1).reverse.foreach( i => ps.printlnWithIndent(i * indent, "}")) + (0 to indentsMade -1).reverse.foreach( i => ps.printlnWithIndent(i * indent, "}")) ps.endHide() + WrappedSnippet( baos.toString, outerLineOffset, outerColumnOffset, - nestLevels + classInfos.flatMap(_.names).size + packageName.size + 2 /*Hide tokens*/, - nestLevels * indent + indentsMade + imports.length + createdVals + packageName.size + 2 /*Hide tokens*/, + indentsMade * indent ) extension (ps: PrintStream) From b2869dc0ede0fe264be3d32af3656786809440e4 Mon Sep 17 00:00:00 2001 From: rochala Date: Tue, 5 Apr 2022 22:48:00 +0200 Subject: [PATCH 5/8] fix build --- .../src/dotty/tools/scaladoc/snippets/SnippetChecker.scala | 2 +- .../src/dotty/tools/scaladoc/snippets/WrappedSnippet.scala | 6 +++--- .../dotty/tools/scaladoc/snippets/SnippetCompilerTest.scala | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala index 0ab3216f7e35..f397346a9854 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala @@ -52,7 +52,7 @@ class SnippetChecker(val args: Scaladoc.Args)(using cctx: CompilerContext): data.map(_.imports).getOrElse(Nil), lineOffset + data.fold(0)(_.position.line) + constantLineOffset, data.fold(0)(_.position.column) + constantColumnOffset, - arg.flag + arg.flag == SCFlags.MacroCompile ) Some(compiler.compile(wrapped, arg, sourceFile)) else diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/WrappedSnippet.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/WrappedSnippet.scala index 63342712e8bb..5448a0e2b54e 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/WrappedSnippet.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/WrappedSnippet.scala @@ -17,7 +17,7 @@ object WrappedSnippet: imports: List[String], outerLineOffset: Int, outerColumnOffset: Int, - flag: SCFlags, + isMacro: Boolean = false, ): WrappedSnippet = val baos = new ByteArrayOutputStream() val ps = new PrintStream(baos) @@ -26,7 +26,7 @@ object WrappedSnippet: imports.foreach(i => ps.println(s"import $i")) val nonEmptyClassInfos = if classInfos.isEmpty then Seq(SnippetCompilerData.ClassInfo(None, Nil, None)) else classInfos - if flag == SCFlags.MacroCompile then + if isMacro then ps.println("object Snippet {") else nonEmptyClassInfos.zipWithIndex.foreach { (info, i) => @@ -37,7 +37,7 @@ object WrappedSnippet: } ps.endHide() - val (indentsMade, createdVals) = if flag == SCFlags.MacroCompile then + val (indentsMade, createdVals) = if isMacro then (1, 1) else (nonEmptyClassInfos.size, nonEmptyClassInfos.flatMap(_.names).size) diff --git a/scaladoc/test/dotty/tools/scaladoc/snippets/SnippetCompilerTest.scala b/scaladoc/test/dotty/tools/scaladoc/snippets/SnippetCompilerTest.scala index dc0bcefbc1cc..7dd4ace7a2c3 100644 --- a/scaladoc/test/dotty/tools/scaladoc/snippets/SnippetCompilerTest.scala +++ b/scaladoc/test/dotty/tools/scaladoc/snippets/SnippetCompilerTest.scala @@ -15,7 +15,7 @@ class SnippetCompilerTest { Nil, Nil, 0, - 0 + 0, ) def runTest(str: String) = compiler.compile(wrapFn(str), SnippetCompilerArg(SCFlags.Compile), dotty.tools.dotc.util.SourceFile.virtual("test", str)) @@ -65,4 +65,4 @@ class SnippetCompilerTest { assertMessageLevelPresent(warningSnippet, MessageLevel.Warning) //No test for Info } -} \ No newline at end of file +} From adde57a18db6d089d7aad2d76dc304fa4824b203 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Zyba=C5=82a?= Date: Thu, 7 Apr 2022 08:55:03 +0200 Subject: [PATCH 6/8] Remove snippet context feature --- library/src/scala/quoted/Exprs.scala | 2 +- library/src/scala/quoted/Varargs.scala | 2 +- .../src/tests/snippetCompilerTests.scala | 2 +- .../src/tests/snippetTestcase1.scala | 10 ++-- .../src/tests/snippetTestcase2.scala | 10 ++-- .../src/tests/snippetTestcase3.scala | 8 +-- scaladoc/src/dotty/tools/scaladoc/api.scala | 4 -- .../dotty/tools/scaladoc/site/templates.scala | 4 +- .../snippets/FlexmarkSnippetProcessor.scala | 16 ++---- .../scaladoc/snippets/SelfTypePrinter.scala | 55 ------------------- .../scaladoc/snippets/SnippetChecker.scala | 5 +- .../scaladoc/snippets/SnippetCompiler.scala | 4 +- .../snippets/SnippetCompilerArgs.scala | 2 - .../SnippetCompilerDataCollector.scala | 53 +----------------- .../scaladoc/snippets/WrappedSnippet.scala | 31 +++-------- .../scaladoc/tasty/comments/Comments.scala | 2 +- .../markdown/DocFlexmarkExtension.scala | 3 +- .../comments/markdown/SnippetRenderer.scala | 5 +- .../snippets/SnippetCompilerTest.scala | 2 - .../scaladoc/snippets/SnippetsE2eTest.scala | 6 +- 20 files changed, 42 insertions(+), 184 deletions(-) delete mode 100644 scaladoc/src/dotty/tools/scaladoc/snippets/SelfTypePrinter.scala diff --git a/library/src/scala/quoted/Exprs.scala b/library/src/scala/quoted/Exprs.scala index 450f501c9d4f..48b0200236bf 100644 --- a/library/src/scala/quoted/Exprs.scala +++ b/library/src/scala/quoted/Exprs.scala @@ -5,7 +5,7 @@ object Exprs: /** Matches literal sequence of literal constant value expressions and return a sequence of values. * * Usage: - * ```scala sc:macrocompile + * ```scala * inline def sum(args: Int*): Int = ${ sumExpr('args) } * def sumExpr(argsExpr: Expr[Seq[Int]])(using Quotes): Expr[Int] = argsExpr match * case Varargs(Exprs(args)) => ??? diff --git a/library/src/scala/quoted/Varargs.scala b/library/src/scala/quoted/Varargs.scala index ce1545654a87..e2e74c3879c6 100644 --- a/library/src/scala/quoted/Varargs.scala +++ b/library/src/scala/quoted/Varargs.scala @@ -35,7 +35,7 @@ object Varargs { /** Matches a literal sequence of expressions and return a sequence of expressions. * * Usage: - * ```scala sc:macrocompile + * ```scala * inline def sum(args: Int*): Int = ${ sumExpr('args) } * def sumExpr(argsExpr: Expr[Seq[Int]])(using Quotes): Expr[Int] = argsExpr match * case Varargs(argVarargs) => ??? diff --git a/scaladoc-testcases/src/tests/snippetCompilerTests.scala b/scaladoc-testcases/src/tests/snippetCompilerTests.scala index 517617748b26..9cb90e20ee20 100644 --- a/scaladoc-testcases/src/tests/snippetCompilerTests.scala +++ b/scaladoc-testcases/src/tests/snippetCompilerTests.scala @@ -55,7 +55,7 @@ class A { class B { } /** - * ```scala sc:macrocompile + * ```scala * import scala.quoted._ * inline def sum(args: Int*): Int = ${ sumExpr('args) } * def sumExpr(argsExpr: Expr[Seq[Int]])(using Quotes): Expr[Int] = argsExpr match diff --git a/scaladoc-testcases/src/tests/snippetTestcase1.scala b/scaladoc-testcases/src/tests/snippetTestcase1.scala index dccb92368041..4aef7d01208f 100644 --- a/scaladoc-testcases/src/tests/snippetTestcase1.scala +++ b/scaladoc-testcases/src/tests/snippetTestcase1.scala @@ -2,7 +2,7 @@ package tests.snippetTestcase1 class SnippetTestcase1: /** - * SNIPPET(OUTERLINEOFFSET:8,OUTERCOLUMNOFFSET:6,INNERLINEOFFSET:5,INNERCOLUMNOFFSET:2) + * SNIPPET(OUTERLINEOFFSET:7,OUTERCOLUMNOFFSET:6,INNERLINEOFFSET:4,INNERCOLUMNOFFSET:2) * ERROR(LINE:8,COLUMN:8) * ```scala sc:fail * 2 + List() @@ -11,19 +11,19 @@ class SnippetTestcase1: */ def a = 3 /** - * SNIPPET(OUTERLINEOFFSET:16,OUTERCOLUMNOFFSET:6,INNERLINEOFFSET:5,INNERCOLUMNOFFSET:2) + * SNIPPET(OUTERLINEOFFSET:15,OUTERCOLUMNOFFSET:6,INNERLINEOFFSET:4,INNERCOLUMNOFFSET:2) * ```scala sc:compile sc-name:1 * val xs: List[Int] = List() * ``` * - * SNIPPET(OUTERLINEOFFSET:21,OUTERCOLUMNOFFSET:6,INNERLINEOFFSET:5,INNERCOLUMNOFFSET:2) + * SNIPPET(OUTERLINEOFFSET:20,OUTERCOLUMNOFFSET:6,INNERLINEOFFSET:4,INNERCOLUMNOFFSET:2) * ```scala sc:compile sc-compile-with:1 sc-name:2 * val ys = xs.map(x => x * 2) * ``` * - * SNIPPET(OUTERLINEOFFSET:26,OUTERCOLUMNOFFSET:6,INNERLINEOFFSET:5,INNERCOLUMNOFFSET:2) + * SNIPPET(OUTERLINEOFFSET:25,OUTERCOLUMNOFFSET:6,INNERLINEOFFSET:4,INNERCOLUMNOFFSET:2) * ```scala sc:compile sc-compile-with:2 * xs ++ ys * ``` */ - def b = 3 \ No newline at end of file + def b = 3 diff --git a/scaladoc-testcases/src/tests/snippetTestcase2.scala b/scaladoc-testcases/src/tests/snippetTestcase2.scala index 3f99b316592f..c85207b46f59 100644 --- a/scaladoc-testcases/src/tests/snippetTestcase2.scala +++ b/scaladoc-testcases/src/tests/snippetTestcase2.scala @@ -7,7 +7,7 @@ trait Quotes2[A] { type X object Y { /** - * SNIPPET(OUTERLINEOFFSET:13,OUTERCOLUMNOFFSET:10,INNERLINEOFFSET:8,INNERCOLUMNOFFSET:6) + * SNIPPET(OUTERLINEOFFSET:12,OUTERCOLUMNOFFSET:10,INNERLINEOFFSET:4,INNERCOLUMNOFFSET:2) * ERROR(LINE:13,COLUMN:12) * ```scala sc:fail * 2 + List() @@ -19,7 +19,7 @@ trait Quotes2[A] { val z: zModule = ??? trait zModule { /** - * SNIPPET(OUTERLINEOFFSET:25,OUTERCOLUMNOFFSET:10,INNERLINEOFFSET:9,INNERCOLUMNOFFSET:6) + * SNIPPET(OUTERLINEOFFSET:24,OUTERCOLUMNOFFSET:10,INNERLINEOFFSET:4,INNERCOLUMNOFFSET:2) * ERROR(LINE:25,COLUMN:12) * ```scala sc:fail * 2 + List() @@ -33,7 +33,7 @@ trait Quotes2[A] { type X object Y { /** - * SNIPPET(OUTERLINEOFFSET:39,OUTERCOLUMNOFFSET:10,INNERLINEOFFSET:7,INNERCOLUMNOFFSET:6) + * SNIPPET(OUTERLINEOFFSET:38,OUTERCOLUMNOFFSET:10,INNERLINEOFFSET:4,INNERCOLUMNOFFSET:2) * ERROR(LINE:39,COLUMN:12) * ```scala sc:fail * 2 + List() @@ -45,7 +45,7 @@ trait Quotes2[A] { val z: zModule = ??? trait zModule { /** - * SNIPPET(OUTERLINEOFFSET:51,OUTERCOLUMNOFFSET:10,INNERLINEOFFSET:8,INNERCOLUMNOFFSET:6) + * SNIPPET(OUTERLINEOFFSET:50,OUTERCOLUMNOFFSET:10,INNERLINEOFFSET:4,INNERCOLUMNOFFSET:2) * ERROR(LINE:51,COLUMN:12) * ```scala sc:fail * 2 + List() @@ -55,4 +55,4 @@ trait Quotes2[A] { type ZZ } } -} \ No newline at end of file +} diff --git a/scaladoc-testcases/src/tests/snippetTestcase3.scala b/scaladoc-testcases/src/tests/snippetTestcase3.scala index bb7def9a4b4c..7bcf6ee7e4ee 100644 --- a/scaladoc-testcases/src/tests/snippetTestcase3.scala +++ b/scaladoc-testcases/src/tests/snippetTestcase3.scala @@ -5,7 +5,7 @@ package snippetTestcase3 class SnippetTestcase3: /** Text on line 0. * - * SNIPPET(OUTERLINEOFFSET:11,OUTERCOLUMNOFFSET:6,INNERLINEOFFSET:5,INNERCOLUMNOFFSET:2) + * SNIPPET(OUTERLINEOFFSET:10,OUTERCOLUMNOFFSET:6,INNERLINEOFFSET:4,INNERCOLUMNOFFSET:2) * ERROR(LINE:11,COLUMN:8) * ```scala sc:fail * 2 + List() @@ -15,7 +15,7 @@ class SnippetTestcase3: /** * Text on line 1. * - * SNIPPET(OUTERLINEOFFSET:21,OUTERCOLUMNOFFSET:6,INNERLINEOFFSET:5,INNERCOLUMNOFFSET:2) + * SNIPPET(OUTERLINEOFFSET:20,OUTERCOLUMNOFFSET:6,INNERLINEOFFSET:4,INNERCOLUMNOFFSET:2) * ERROR(LINE:21,COLUMN:8) * ```scala sc:fail * 2 + List() @@ -26,10 +26,10 @@ class SnippetTestcase3: * * Text on line 2. * - * SNIPPET(OUTERLINEOFFSET:32,OUTERCOLUMNOFFSET:6,INNERLINEOFFSET:5,INNERCOLUMNOFFSET:2) + * SNIPPET(OUTERLINEOFFSET:31,OUTERCOLUMNOFFSET:6,INNERLINEOFFSET:4,INNERCOLUMNOFFSET:2) * ERROR(LINE:32,COLUMN:8) * ```scala sc:fail * 2 + List() * ``` */ - def c = 3 \ No newline at end of file + def c = 3 diff --git a/scaladoc/src/dotty/tools/scaladoc/api.scala b/scaladoc/src/dotty/tools/scaladoc/api.scala index d896c69f690e..2f5ebba9ab66 100644 --- a/scaladoc/src/dotty/tools/scaladoc/api.scala +++ b/scaladoc/src/dotty/tools/scaladoc/api.scala @@ -251,12 +251,8 @@ case class TastyMemberSource(path: java.nio.file.Path, lineNumber: Int) object SnippetCompilerData: case class Position(line: Int, column: Int) - case class ClassInfo(tpe: Option[String], names: Seq[String], generics: Option[String]) - case class SnippetCompilerData( packageName: String, - classInfos: Seq[SnippetCompilerData.ClassInfo], - imports: List[String], position: SnippetCompilerData.Position ) diff --git a/scaladoc/src/dotty/tools/scaladoc/site/templates.scala b/scaladoc/src/dotty/tools/scaladoc/site/templates.scala index 873fde2dd1bb..ba932e09653e 100644 --- a/scaladoc/src/dotty/tools/scaladoc/site/templates.scala +++ b/scaladoc/src/dotty/tools/scaladoc/site/templates.scala @@ -86,8 +86,6 @@ case class TemplateFile( val arg = argOverride.fold(pathBasedArg)(pathBasedArg.overrideFlag(_)) val compilerData = SnippetCompilerData( "staticsitesnippet", - Seq(SnippetCompilerData.ClassInfo(None, Nil, None)), - Nil, SnippetCompilerData.Position(configOffset - 1, 0) ) ssctx.snippetChecker.checkSnippet(str, Some(compilerData), arg, lineOffset, sourceFile).collect { @@ -124,7 +122,7 @@ case class TemplateFile( // Snippet compiler currently supports markdown only val parser: Parser = Parser.builder(defaultMarkdownOptions).build() val parsedMd = parser.parse(rendered).pipe { md => - FlexmarkSnippetProcessor.processSnippets(md, None, snippetCheckingFunc, withContext = false)(using ssctx.outerCtx) + FlexmarkSnippetProcessor.processSnippets(md, None, snippetCheckingFunc)(using ssctx.outerCtx) }.pipe { md => FlexmarkSectionWrapper(md) } diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/FlexmarkSnippetProcessor.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/FlexmarkSnippetProcessor.scala index f65d0e32508d..bc3bce308541 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/FlexmarkSnippetProcessor.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/FlexmarkSnippetProcessor.scala @@ -11,7 +11,7 @@ import dotty.tools.scaladoc.tasty.comments.markdown.ExtendedFencedCodeBlock import dotty.tools.scaladoc.tasty.comments.PreparsedComment object FlexmarkSnippetProcessor: - def processSnippets[T <: mdu.Node](root: T, preparsed: Option[PreparsedComment], checkingFunc: => SnippetChecker.SnippetCheckingFunc, withContext: Boolean)(using CompilerContext): T = { + def processSnippets[T <: mdu.Node](root: T, preparsed: Option[PreparsedComment], checkingFunc: => SnippetChecker.SnippetCheckingFunc)(using CompilerContext): T = { lazy val cf: SnippetChecker.SnippetCheckingFunc = checkingFunc val nodes = root.getDescendants().asScala.collect { @@ -68,23 +68,15 @@ object FlexmarkSnippetProcessor: val fullSnippet = Seq(snippetImports, snippet).mkString("\n").trim val snippetCompilationResult = cf(fullSnippet, lineOffset, argOverride) match { - case Some(result @ SnippetCompilationResult(wrapped, _, _, messages)) if !withContext => + case Some(result @ SnippetCompilationResult(wrapped, _, _, messages)) => node.setContentString(fullSnippet) - val innerLineOffset = wrapped.innerLineOffset - Some(result.copy(messages = result.messages.map { - case m @ SnippetCompilerMessage(Some(pos), _, _) => - m.copy(position = Some(pos.copy(relativeLine = pos.relativeLine - innerLineOffset))) - case m => m - })) - case result@Some(SnippetCompilationResult(wrapped, _, _, _)) => - node.setContentString(wrapped.snippet) - result + Some(result) case result => node.setContentString(fullSnippet) result } - node.insertBefore(ExtendedFencedCodeBlock(id, node, snippetCompilationResult, withContext)) + node.insertBefore(ExtendedFencedCodeBlock(id, node, snippetCompilationResult)) node.unlink() id.fold(snippetMap)(id => val snippetAsImport = s"""|//{i:$id diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/SelfTypePrinter.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/SelfTypePrinter.scala deleted file mode 100644 index 9a12a1e93dcc..000000000000 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/SelfTypePrinter.scala +++ /dev/null @@ -1,55 +0,0 @@ -package dotty.tools.scaladoc -package snippets - -import dotty.tools.dotc.printing.RefinedPrinter -import dotty.tools.dotc.core._ -import dotty.tools.dotc.printing.Texts._ -import dotty.tools.dotc.core.Types._ -import dotty.tools.dotc.core.Flags._ -import dotty.tools.dotc.core.Names._ -import dotty.tools.dotc.core.Symbols._ -import dotty.tools.dotc.core.NameOps._ -import dotty.tools.dotc.core.TypeErasure.ErasedValueType -import dotty.tools.dotc.core.Contexts._ -import dotty.tools.dotc.core.Annotations.Annotation -import dotty.tools.dotc.core.Denotations._ -import dotty.tools.dotc.core.SymDenotations._ -import dotty.tools.dotc.core.StdNames.{nme, tpnme} -import dotty.tools.dotc.ast.{Trees, untpd} -import dotty.tools.dotc.typer.{Implicits, Namer, Applications} -import dotty.tools.dotc.typer.ProtoTypes._ -import dotty.tools.dotc.ast.Trees._ -import dotty.tools.dotc.core.TypeApplications._ -import dotty.tools.dotc.core.Decorators._ -import dotty.tools.dotc.util.Chars.isOperatorPart -import dotty.tools.dotc.transform.TypeUtils._ -import dotty.tools.dotc.transform.SymUtils._ - -import language.implicitConversions -import dotty.tools.dotc.util.{NameTransformer, SourcePosition} -import dotty.tools.dotc.ast.untpd.{MemberDef, Modifiers, PackageDef, RefTree, Template, TypeDef, ValOrDefDef} - -class SelfTypePrinter(using _ctx: Context) extends RefinedPrinter(_ctx): - - private def refinementChain(tp: Type): List[Type] = - tp :: (tp match { - case tp: RefinedType => refinementChain(tp.parent.stripTypeVar) - case _ => Nil - }) - - override def toText(tp: Type): Text = tp match - case tp: RefinedType => - val parent :: (refined: List[RefinedType @unchecked]) = - refinementChain(tp).reverse - toTextLocal(parent) - case tp => super.toText(tp) - - override def toTextSingleton(tp: SingletonType): Text = - tp match - case ConstantType(value) => - if value.tag == Constants.ByteTag || value.tag == Constants.ShortTag then - toText(value) ~ s" /*${value.tpe.show}*/" - else - toText(value) - case _: TermRef => toTextRef(tp) ~ ".type /*" ~ toTextGlobal(tp.underlying) ~ "*/" - case _ => "(" ~ toTextRef(tp) ~ ": " ~ toTextGlobal(tp.underlying) ~ ")" diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala index f397346a9854..8f8b73a576d1 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala @@ -48,11 +48,8 @@ class SnippetChecker(val args: Scaladoc.Args)(using cctx: CompilerContext): val wrapped = WrappedSnippet( snippet, data.map(_.packageName), - data.fold(Nil)(_.classInfos), - data.map(_.imports).getOrElse(Nil), lineOffset + data.fold(0)(_.position.line) + constantLineOffset, - data.fold(0)(_.position.column) + constantColumnOffset, - arg.flag == SCFlags.MacroCompile + data.fold(0)(_.position.column) + constantColumnOffset ) Some(compiler.compile(wrapped, arg, sourceFile)) else diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompiler.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompiler.scala index 3f5002a42662..03fdd4e849ff 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompiler.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompiler.scala @@ -63,11 +63,11 @@ class SnippetCompiler( case _ => NoSourcePosition val offsetFromLine = sourceFile match case NoSource => 0 - case sf: SourceFile => sf.lineToOffset(diagPos.line + line - innerLineOffset - 1) + case sf: SourceFile => sf.lineToOffset(diagPos.line + line - innerLineOffset) val offsetFromColumn = diagPos.column + column - innerColumnOffset val span = Span(offsetFromLine + offsetFromColumn, offsetFromLine + offsetFromColumn) val pos = Some( - Position(dotty.tools.dotc.util.SourcePosition(sourceFile, span), diagPos.line) + Position(dotty.tools.dotc.util.SourcePosition(sourceFile, span), diagPos.line - innerLineOffset) ) val dmsg = Try(diagnostic.message) match { case Success(msg) => msg diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompilerArgs.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompilerArgs.scala index 495db23e35ca..35a89d985d8e 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompilerArgs.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompilerArgs.scala @@ -8,7 +8,6 @@ case class SnippetCompilerArg(flag: SCFlags): enum SCFlags(val flagName: String): case Compile extends SCFlags("compile") - case MacroCompile extends SCFlags("macrocompile") case NoCompile extends SCFlags("nocompile") case Fail extends SCFlags("fail") @@ -38,7 +37,6 @@ object SnippetCompilerArgs: | |Available flags: |compile - Enables snippet checking. - |macrocompile - Enables snippet checking for macros. |nocompile - Disables snippet checking. |fail - Enables snippet checking, asserts that snippet doesn't compile. | diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompilerDataCollector.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompilerDataCollector.scala index c1629f8d35cc..91c49feaa560 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompilerDataCollector.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompilerDataCollector.scala @@ -20,57 +20,10 @@ class SnippetCompilerDataCollector[Q <: Quotes](val qctx: Q): def getSnippetCompilerData(sym: Symbol, originalSym: Symbol): SnippetCompilerData = val packageName = sym.packageName - if !sym.isPackageDef then sym.tree match { - case c: qctx.reflect.ClassDef => - import dotty.tools.dotc - import dotty.tools.dotc.core.Decorators._ - given dotc.core.Contexts.Context = qctx.asInstanceOf[scala.quoted.runtime.impl.QuotesImpl].ctx - val printer: dotc.printing.Printer = SelfTypePrinter() - val classSym = c.symbol.asInstanceOf[Symbols.ClassSymbol] - - def getOwners(sym: Symbols.ClassSymbol): Seq[Symbols.ClassSymbol] = Seq(sym) ++ - (if sym.owner.isClass && !sym.owner.is(dotc.core.Flags.Package) then getOwners(sym.owner.asInstanceOf[Symbols.ClassSymbol]) else Nil) - - def collectNames(tp: Types.Type): Seq[String] = tp match { - case Types.AndType(t1, t2) => collectNames(t1) ++ collectNames(t2) - case Types.AppliedType(tpe, _) => collectNames(tpe) - case Types.AnnotatedType(tpe, _) => collectNames(tpe) - case t: Types.NamedType => if t.symbol.is(dotc.core.Flags.Module) then Seq() else Seq(t.symbol.name.show) - case t: Types.ThisType => Seq(t.cls.name.show) - case _ => Seq() - } - - val allSyms = getOwners(classSym) - - val allProcessed = allSyms.map { cSym => - def createTypeConstructor(tpe: Types.Type, topLevel: Boolean = true): String = tpe match { - case t @ Types.TypeBounds(upper, lower) => lower match { - case l: Types.HKTypeLambda => - (if topLevel then "" else "?") + l.paramInfos.map(p => createTypeConstructor(p, false)).mkString("[",", ","]") - case _ => (if topLevel then "" else "_") - } - } - val classType = - val ct = cSym.classInfo.selfType.toText(printer).show.replace(".this","").replace("\n", " ").stripPrefix(s"$packageName.") - Some(ct) - val classNames = collectNames(cSym.classInfo.selfType) - val classGenerics = Option.when( - !cSym.typeParams.isEmpty - )( - cSym.typeParams.map(_.typeRef).map(t => - t.show + - createTypeConstructor(t.asInstanceOf[Types.TypeRef].underlying) - ).mkString("[",", ","]") - ) - SnippetCompilerData.ClassInfo(classType, classNames, classGenerics) - } - val firstProcessed = allProcessed.head - SnippetCompilerData(packageName, allProcessed.reverse, Nil, position(hackGetPositionOfDocstring(using qctx)(originalSym))) - case _ => getSnippetCompilerData(sym.maybeOwner, originalSym) - } else SnippetCompilerData(packageName, Nil, Nil, position(hackGetPositionOfDocstring(using qctx)(originalSym))) + SnippetCompilerData(packageName, position(hackGetPositionOfDocstring(using qctx)(originalSym))) private def position(p: Option[qctx.reflect.Position]): SnippetCompilerData.Position = - p.fold(SnippetCompilerData.Position(0, 0))(p => SnippetCompilerData.Position(p.startLine, p.startColumn)) + p.fold(SnippetCompilerData.Position(0, 0))(p => SnippetCompilerData.Position(p.startLine - 1, p.startColumn)) private def hackGetPositionOfDocstring(using Quotes)(s: qctx.reflect.Symbol): Option[qctx.reflect.Position] = import dotty.tools.dotc.core.Comments.CommentsContext @@ -88,4 +41,4 @@ class SnippetCompilerDataCollector[Q <: Quotes](val qctx: Q): docstring.span ).asInstanceOf[qctx.reflect.Position] } - } \ No newline at end of file + } diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/WrappedSnippet.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/WrappedSnippet.scala index 5448a0e2b54e..9355b57c08e9 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/WrappedSnippet.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/WrappedSnippet.scala @@ -13,46 +13,29 @@ object WrappedSnippet: def apply( str: String, packageName: Option[String], - classInfos: Seq[SnippetCompilerData.ClassInfo], - imports: List[String], outerLineOffset: Int, outerColumnOffset: Int, - isMacro: Boolean = false, ): WrappedSnippet = val baos = new ByteArrayOutputStream() val ps = new PrintStream(baos) + ps.startHide() ps.println(s"package ${packageName.getOrElse("snippets")}") - imports.foreach(i => ps.println(s"import $i")) - val nonEmptyClassInfos = if classInfos.isEmpty then Seq(SnippetCompilerData.ClassInfo(None, Nil, None)) else classInfos - - if isMacro then - ps.println("object Snippet {") - else - nonEmptyClassInfos.zipWithIndex.foreach { (info, i) => - ps.printlnWithIndent(indent * i, s"trait Snippet$i${info.generics.getOrElse("")} { ${info.tpe.fold("")(cn => s"self: $cn =>")}") - info.names.foreach{ name => - ps.printlnWithIndent(indent * i + indent, s"val $name = self") - } - } - + ps.println("object Snippet {") ps.endHide() - val (indentsMade, createdVals) = if isMacro then - (1, 1) - else - (nonEmptyClassInfos.size, nonEmptyClassInfos.flatMap(_.names).size) - str.split('\n').foreach(ps.printlnWithIndent(indentsMade * indent, _)) + str.split('\n').foreach(ps.printlnWithIndent(indent, _)) + ps.startHide() - (0 to indentsMade -1).reverse.foreach( i => ps.printlnWithIndent(i * indent, "}")) + ps.println("}") ps.endHide() WrappedSnippet( baos.toString, outerLineOffset, outerColumnOffset, - indentsMade + imports.length + createdVals + packageName.size + 2 /*Hide tokens*/, - indentsMade * indent + 2 + 2 /*Hide tokens*/, + indent ) extension (ps: PrintStream) diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/Comments.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/Comments.scala index 50f293487f57..b62b1b7b3df8 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/Comments.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/Comments.scala @@ -200,7 +200,7 @@ class MarkdownCommentParser(repr: Repr)(using dctx: DocContext) .mapValues(stringToMarkup).to(SortedMap) def processSnippets(root: mdu.Node, preparsed: PreparsedComment): mdu.Node = - FlexmarkSnippetProcessor.processSnippets(root, Some(preparsed), snippetCheckingFunc(owner), withContext = true) + FlexmarkSnippetProcessor.processSnippets(root, Some(preparsed), snippetCheckingFunc(owner)) } class WikiCommentParser(repr: Repr)(using DocContext) diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/DocFlexmarkExtension.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/DocFlexmarkExtension.scala index 8bee19864773..1b9f10fb3185 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/DocFlexmarkExtension.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/DocFlexmarkExtension.scala @@ -25,8 +25,7 @@ class DocLinkNode( case class ExtendedFencedCodeBlock( name: Option[String], codeBlock: ast.FencedCodeBlock, - compilationResult: Option[SnippetCompilationResult], - hasContext: Boolean + compilationResult: Option[SnippetCompilationResult] ) extends BlankLine(codeBlock.getContentChars()) case class Section( diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SnippetRenderer.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SnippetRenderer.scala index 65e14fa343c4..acf2e99e0e52 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SnippetRenderer.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SnippetRenderer.scala @@ -133,10 +133,10 @@ object SnippetRenderer: div(cls := "snippet-label")(name) ).toString - def renderSnippetWithMessages(snippetName: Option[String], codeLines: Seq[String], messages: Seq[SnippetCompilerMessage], hasContext: Boolean, success: Boolean): String = + def renderSnippetWithMessages(snippetName: Option[String], codeLines: Seq[String], messages: Seq[SnippetCompilerMessage], success: Boolean): String = val transformedLines = wrapCodeLines.andThen(addCompileMessages(messages)).apply(codeLines).map(_.toHTML) val codeHTML = s"""${transformedLines.mkString("")}""" - val isRunnable = !hasContext && success + val isRunnable = success val attrs = Seq( Option.when(isRunnable)(Attr("runnable") := "") ).flatten @@ -153,6 +153,5 @@ object SnippetRenderer: node.name, node.codeBlock.getContentChars.toString.split("\n").map(_ + "\n").toSeq, node.compilationResult.toSeq.flatMap(_.messages), - node.hasContext, node.compilationResult.fold(false)(_.isSuccessful) ) diff --git a/scaladoc/test/dotty/tools/scaladoc/snippets/SnippetCompilerTest.scala b/scaladoc/test/dotty/tools/scaladoc/snippets/SnippetCompilerTest.scala index 7dd4ace7a2c3..0442c3114eba 100644 --- a/scaladoc/test/dotty/tools/scaladoc/snippets/SnippetCompilerTest.scala +++ b/scaladoc/test/dotty/tools/scaladoc/snippets/SnippetCompilerTest.scala @@ -12,8 +12,6 @@ class SnippetCompilerTest { def wrapFn: String => WrappedSnippet = (str: String) => WrappedSnippet( str, Some("test"), - Nil, - Nil, 0, 0, ) diff --git a/scaladoc/test/dotty/tools/scaladoc/snippets/SnippetsE2eTest.scala b/scaladoc/test/dotty/tools/scaladoc/snippets/SnippetsE2eTest.scala index cf0c52ee2a50..11398855fc87 100644 --- a/scaladoc/test/dotty/tools/scaladoc/snippets/SnippetsE2eTest.scala +++ b/scaladoc/test/dotty/tools/scaladoc/snippets/SnippetsE2eTest.scala @@ -82,8 +82,8 @@ abstract class SnippetsE2eTest(testName: String, flag: SCFlags) extends Scaladoc def checkRelativeLines(msg: Message, cmsg: SnippetCompilerMessage): Seq[String] = val pos = cmsg.position.get - if !(pos.relativeLine == pos.srcPos.line + ws.innerLineOffset - ws.outerLineOffset + 1) then Seq( - s"Expected ${msg.level.text} message at relative line: ${pos.srcPos.line + ws.innerLineOffset - ws.outerLineOffset + 1} " + + if !(pos.relativeLine == pos.srcPos.line - ws.outerLineOffset) then Seq( + s"Expected ${msg.level.text} message at relative line: ${pos.srcPos.line - ws.outerLineOffset} " + s"but found at ${pos.relativeLine}" ) else Nil @@ -163,4 +163,4 @@ object SnippetsE2eTest: raw"INNERLINEOFFSET:(\d+),INNERCOLUMNOFFSET:(\d+)\)").r val warningRegex = raw"WARNING\(LINE:(\d+),COLUMN:(\d+)\)".r - val errorRegex = raw"ERROR\(LINE:(\d+),COLUMN:(\d+)\)".r \ No newline at end of file + val errorRegex = raw"ERROR\(LINE:(\d+),COLUMN:(\d+)\)".r From f8969ae33773f23cec957a832b8ad08bef6c034f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Zyba=C5=82a?= Date: Thu, 7 Apr 2022 11:24:08 +0200 Subject: [PATCH 7/8] Fix failing snippets --- library/src/scala/compiletime/ops/any.scala | 15 ++++ .../src/scala/compiletime/ops/boolean.scala | 12 +++ .../src/scala/compiletime/ops/double.scala | 48 +++++++++++ library/src/scala/compiletime/ops/float.scala | 48 +++++++++++ library/src/scala/compiletime/ops/int.scala | 75 +++++++++++++++++ library/src/scala/compiletime/ops/long.scala | 69 ++++++++++++++++ .../src/scala/compiletime/ops/string.scala | 12 +++ library/src/scala/quoted/Quotes.scala | 81 ++++++++++++++----- 8 files changed, 341 insertions(+), 19 deletions(-) diff --git a/library/src/scala/compiletime/ops/any.scala b/library/src/scala/compiletime/ops/any.scala index b3898f7896bb..77b18af638f6 100644 --- a/library/src/scala/compiletime/ops/any.scala +++ b/library/src/scala/compiletime/ops/any.scala @@ -6,6 +6,9 @@ import annotation.experimental object any: /** Equality comparison of two singleton types. * ```scala + * //{ + * import compiletime.ops.any._ + * //} * val eq1: 1 == 1 = true * val eq2: 1 == "1" = false * val eq3: "1" == "1" = true @@ -16,6 +19,9 @@ object any: /** Inequality comparison of two singleton types. * ```scala + * //{ + * import compiletime.ops.any._ + * //} * val eq1: 1 != 1 = false * val eq2: 1 != "1" = true * val eq3: "1" != "1" = false @@ -26,6 +32,9 @@ object any: /** Tests if a type is a constant. * ```scala + * //{ + * import compiletime.ops.any._ + * //} * val c1: IsConst[1] = true * val c2: IsConst["hi"] = true * val c3: IsConst[false] = true @@ -34,6 +43,9 @@ object any: * If the type is not yet known, then `IsConst` remains unevaluated, and * will be evaluated only at its concrete type application. E.g.: * ```scala + * //{ + * import compiletime.ops.any._ + * //} * //def `isConst`` returns the type `IsConst[X]`, since `X` is not yet known. * def isConst[X] : IsConst[X] = ??? * val c5 : true = isConst[1] //now the type is known to be a constant @@ -46,6 +58,9 @@ object any: /** String conversion of a constant singleton type. * ```scala + * //{ + * import compiletime.ops.any._ + * //} * val s1: ToString[1] = "1" * val sTrue: ToString[true] = "true" * ``` diff --git a/library/src/scala/compiletime/ops/boolean.scala b/library/src/scala/compiletime/ops/boolean.scala index c67ca28e5d22..8724f60c1ec6 100644 --- a/library/src/scala/compiletime/ops/boolean.scala +++ b/library/src/scala/compiletime/ops/boolean.scala @@ -5,6 +5,9 @@ object boolean: /** Negation of a `Boolean` singleton type. * ```scala + * //{ + * import compiletime.ops.boolean._ + * //} * val notFalse: ![false] = true * val notTrue: ![true] = false * ``` @@ -14,6 +17,9 @@ object boolean: /** Exclusive disjunction of two `Boolean` singleton types. * ```scala + * //{ + * import compiletime.ops.boolean._ + * //} * val a: true ^ true = false * val b: false ^ true = true * ``` @@ -23,6 +29,9 @@ object boolean: /** Conjunction of two `Boolean` singleton types. * ```scala + * //{ + * import compiletime.ops.boolean._ + * //} * val a: true && true = true * val b: false && true = false * ``` @@ -32,6 +41,9 @@ object boolean: /** Disjunction of two `Boolean` singleton types. * ```scala + * //{ + * import compiletime.ops.boolean._ + * //} * val a: true || false = true * val b: false || false = false * ``` diff --git a/library/src/scala/compiletime/ops/double.scala b/library/src/scala/compiletime/ops/double.scala index e8eb85291a65..d5dd30ecc85a 100644 --- a/library/src/scala/compiletime/ops/double.scala +++ b/library/src/scala/compiletime/ops/double.scala @@ -7,6 +7,9 @@ import scala.annotation.experimental object double: /** Addition of two `Double` singleton types. * ```scala + * //{ + * import compiletime.ops.double._ + * //} * val sum: 2.0 + 2.0 = 4.0 * ``` * @syntax markdown @@ -15,6 +18,9 @@ object double: /** Subtraction of two `Double` singleton types. * ```scala + * //{ + * import compiletime.ops.double._ + * //} * val sub: 4.0 - 2.0 = 2.0 * ``` * @syntax markdown @@ -23,6 +29,9 @@ object double: /** Multiplication of two `Double` singleton types. * ```scala + * //{ + * import compiletime.ops.double._ + * //} * val mul: 4.0 * 2.0 = 8.0 * ``` * @syntax markdown @@ -31,6 +40,9 @@ object double: /** Integer division of two `Double` singleton types. * ```scala + * //{ + * import compiletime.ops.double._ + * //} * val div: 5.0 / 2.0 = 2.5 * ``` * @syntax markdown @@ -39,6 +51,9 @@ object double: /** Remainder of the division of `X` by `Y`. * ```scala + * //{ + * import compiletime.ops.double._ + * //} * val mod: 5.0 % 2.0 = 1.0 * ``` * @syntax markdown @@ -47,6 +62,9 @@ object double: /** Less-than comparison of two `Double` singleton types. * ```scala + * //{ + * import compiletime.ops.double._ + * //} * val lt1: 4.0 < 2.0 = false * val lt2: 2.0 < 4.0 = true * ``` @@ -56,6 +74,9 @@ object double: /** Greater-than comparison of two `Double` singleton types. * ```scala + * //{ + * import compiletime.ops.double._ + * //} * val gt1: 4.0 > 2.0 = true * val gt2: 2.0 > 2.0 = false * ``` @@ -65,6 +86,9 @@ object double: /** Greater-or-equal comparison of two `Double` singleton types. * ```scala + * //{ + * import compiletime.ops.double._ + * //} * val ge1: 4.0 >= 2.0 = true * val ge2: 2.0 >= 3.0 = false * ``` @@ -74,6 +98,9 @@ object double: /** Less-or-equal comparison of two `Double` singleton types. * ```scala + * //{ + * import compiletime.ops.double._ + * //} * val lt1: 4.0 <= 2.0 = false * val lt2: 2.0 <= 2.0 = true * ``` @@ -83,6 +110,9 @@ object double: /** Absolute value of an `Double` singleton type. * ```scala + * //{ + * import compiletime.ops.double._ + * //} * val abs: Abs[-1.0] = 1.0 * ``` * @syntax markdown @@ -91,6 +121,9 @@ object double: /** Negation of an `Double` singleton type. * ```scala + * //{ + * import compiletime.ops.double._ + * //} * val neg1: Negate[-1.0] = 1.0 * val neg2: Negate[1.0] = -1.0 * ``` @@ -100,6 +133,9 @@ object double: /** Minimum of two `Double` singleton types. * ```scala + * //{ + * import compiletime.ops.double._ + * //} * val min: Min[-1.0, 1.0] = -1.0 * ``` * @syntax markdown @@ -108,6 +144,9 @@ object double: /** Maximum of two `Double` singleton types. * ```scala + * //{ + * import compiletime.ops.double._ + * //} * val max: Max[-1.0, 1.0] = 1.0 * ``` * @syntax markdown @@ -116,6 +155,9 @@ object double: /** Int conversion of a `Double` singleton type. * ```scala + * //{ + * import compiletime.ops.double._ + * //} * val x: ToInt[1.0] = 1 * ``` * @syntax markdown @@ -124,6 +166,9 @@ object double: /** Long conversion of a `Double` singleton type. * ```scala + * //{ + * import compiletime.ops.double._ + * //} * val x: ToLong[1.0] = 1L * ``` * @syntax markdown @@ -132,6 +177,9 @@ object double: /** Float conversion of a `Double` singleton type. * ```scala + * //{ + * import compiletime.ops.double._ + * //} * val x: ToFloat[1.0] = 1.0f * ``` * @syntax markdown diff --git a/library/src/scala/compiletime/ops/float.scala b/library/src/scala/compiletime/ops/float.scala index 3b9a3452929f..3fccc1e1dc6e 100644 --- a/library/src/scala/compiletime/ops/float.scala +++ b/library/src/scala/compiletime/ops/float.scala @@ -7,6 +7,9 @@ import scala.annotation.experimental object float: /** Addition of two `Float` singleton types. * ```scala + * //{ + * import compiletime.ops.float._ + * //} * val sum: 2.0f + 2.0f = 4.0f * ``` * @syntax markdown @@ -15,6 +18,9 @@ object float: /** Subtraction of two `Float` singleton types. * ```scala + * //{ + * import compiletime.ops.float._ + * //} * val sub: 4.0f - 2.0f = 2.0f * ``` * @syntax markdown @@ -23,6 +29,9 @@ object float: /** Multiplication of two `Float` singleton types. * ```scala + * //{ + * import compiletime.ops.float._ + * //} * val mul: 4.0f * 2.0f = 8.0f * ``` * @syntax markdown @@ -31,6 +40,9 @@ object float: /** Integer division of two `Float` singleton types. * ```scala + * //{ + * import compiletime.ops.float._ + * //} * val div: 5.0f / 2.0f = 2.5f * ``` * @syntax markdown @@ -39,6 +51,9 @@ object float: /** Remainder of the division of `X` by `Y`. * ```scala + * //{ + * import compiletime.ops.float._ + * //} * val mod: 5.0f % 2.0f = 1.0f * ``` * @syntax markdown @@ -47,6 +62,9 @@ object float: /** Less-than comparison of two `Float` singleton types. * ```scala + * //{ + * import compiletime.ops.float._ + * //} * val lt1: 4.0f < 2.0f = false * val lt2: 2.0f < 4.0f = true * ``` @@ -56,6 +74,9 @@ object float: /** Greater-than comparison of two `Float` singleton types. * ```scala + * //{ + * import compiletime.ops.float._ + * //} * val gt1: 4.0f > 2.0f = true * val gt2: 2.0f > 2.0f = false * ``` @@ -65,6 +86,9 @@ object float: /** Greater-or-equal comparison of two `Float` singleton types. * ```scala + * //{ + * import compiletime.ops.float._ + * //} * val ge1: 4.0f >= 2.0f = true * val ge2: 2.0f >= 3.0f = false * ``` @@ -74,6 +98,9 @@ object float: /** Less-or-equal comparison of two `Float` singleton types. * ```scala + * //{ + * import compiletime.ops.float._ + * //} * val lt1: 4.0f <= 2.0f = false * val lt2: 2.0f <= 2.0f = true * ``` @@ -83,6 +110,9 @@ object float: /** Absolute value of an `Float` singleton type. * ```scala + * //{ + * import compiletime.ops.float._ + * //} * val abs: Abs[-1.0f] = 1.0f * ``` * @syntax markdown @@ -91,6 +121,9 @@ object float: /** Negation of an `Float` singleton type. * ```scala + * //{ + * import compiletime.ops.float._ + * //} * val neg1: Negate[-1.0f] = 1.0f * val neg2: Negate[1.0f] = -1.0f * ``` @@ -100,6 +133,9 @@ object float: /** Minimum of two `Float` singleton types. * ```scala + * //{ + * import compiletime.ops.float._ + * //} * val min: Min[-1.0f, 1.0f] = -1.0f * ``` * @syntax markdown @@ -108,6 +144,9 @@ object float: /** Maximum of two `Float` singleton types. * ```scala + * //{ + * import compiletime.ops.float._ + * //} * val max: Max[-1.0f, 1.0f] = 1.0f * ``` * @syntax markdown @@ -116,6 +155,9 @@ object float: /** Int conversion of a `Float` singleton type. * ```scala + * //{ + * import compiletime.ops.float._ + * //} * val x: ToInt[1.0f] = 1 * ``` * @syntax markdown @@ -124,6 +166,9 @@ object float: /** Long conversion of a `Float` singleton type. * ```scala + * //{ + * import compiletime.ops.float._ + * //} * val x: ToLong[1.0f] = 1L * ``` * @syntax markdown @@ -132,6 +177,9 @@ object float: /** Double conversion of a `Float` singleton type. * ```scala + * //{ + * import compiletime.ops.float._ + * //} * val x: ToDouble[1.0f] = 1.0 * ``` * @syntax markdown diff --git a/library/src/scala/compiletime/ops/int.scala b/library/src/scala/compiletime/ops/int.scala index 935d0dd2a45c..09eb8ff292fc 100644 --- a/library/src/scala/compiletime/ops/int.scala +++ b/library/src/scala/compiletime/ops/int.scala @@ -7,6 +7,9 @@ object int: /** Successor of a natural number where zero is the type 0 and successors are reduced as if the definition was: * * ```scala + * //{ + * import compiletime.ops.int._ + * //} * type S[N <: Int] <: Int = N match { * case 0 => 1 * case 1 => 2 @@ -21,6 +24,9 @@ object int: /** Addition of two `Int` singleton types. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val sum: 2 + 2 = 4 * ``` * @syntax markdown @@ -29,6 +35,9 @@ object int: /** Subtraction of two `Int` singleton types. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val sub: 4 - 2 = 2 * ``` * @syntax markdown @@ -37,6 +46,9 @@ object int: /** Multiplication of two `Int` singleton types. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val mul: 4 * 2 = 8 * ``` * @syntax markdown @@ -45,6 +57,9 @@ object int: /** Integer division of two `Int` singleton types. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val div: 5 / 2 = 2 * ``` * @syntax markdown @@ -53,6 +68,9 @@ object int: /** Remainder of the division of `X` by `Y`. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val mod: 5 % 2 = 1 * ``` * @syntax markdown @@ -61,6 +79,9 @@ object int: /** Binary left shift of `X` by `Y`. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val lshift: 1 << 2 = 4 * ``` * @syntax markdown @@ -69,6 +90,9 @@ object int: /** Binary right shift of `X` by `Y`. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val rshift: 10 >> 1 = 5 * ``` * @syntax markdown @@ -77,6 +101,9 @@ object int: /** Binary right shift of `X` by `Y`, filling the left with zeros. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val rshiftzero: 10 >>> 1 = 5 * ``` * @syntax markdown @@ -85,6 +112,9 @@ object int: /** Bitwise xor of `X` and `Y`. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val xor: 10 ^ 30 = 20 * ``` * @syntax markdown @@ -93,6 +123,9 @@ object int: /** Less-than comparison of two `Int` singleton types. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val lt1: 4 < 2 = false * val lt2: 2 < 4 = true * ``` @@ -102,6 +135,9 @@ object int: /** Greater-than comparison of two `Int` singleton types. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val gt1: 4 > 2 = true * val gt2: 2 > 2 = false * ``` @@ -111,6 +147,9 @@ object int: /** Greater-or-equal comparison of two `Int` singleton types. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val ge1: 4 >= 2 = true * val ge2: 2 >= 3 = false * ``` @@ -120,6 +159,9 @@ object int: /** Less-or-equal comparison of two `Int` singleton types. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val lt1: 4 <= 2 = false * val lt2: 2 <= 2 = true * ``` @@ -129,6 +171,9 @@ object int: /** Bitwise and of `X` and `Y`. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val and1: BitwiseAnd[4, 4] = 4 * val and2: BitwiseAnd[10, 5] = 0 * ``` @@ -138,6 +183,9 @@ object int: /** Bitwise or of `X` and `Y`. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val or: BitwiseOr[10, 11] = 11 * ``` * @syntax markdown @@ -146,6 +194,9 @@ object int: /** Absolute value of an `Int` singleton type. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val abs: Abs[-1] = 1 * ``` * @syntax markdown @@ -154,6 +205,9 @@ object int: /** Negation of an `Int` singleton type. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val neg1: Negate[-1] = 1 * val neg2: Negate[1] = -1 * ``` @@ -163,6 +217,9 @@ object int: /** Minimum of two `Int` singleton types. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val min: Min[-1, 1] = -1 * ``` * @syntax markdown @@ -171,6 +228,9 @@ object int: /** Maximum of two `Int` singleton types. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val max: Max[-1, 1] = 1 * ``` * @syntax markdown @@ -179,6 +239,9 @@ object int: /** String conversion of an `Int` singleton type. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val abs: ToString[1] = "1" * ``` * @syntax markdown @@ -188,6 +251,9 @@ object int: /** Long conversion of an `Int` singleton type. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val x: ToLong[1] = 1L * ``` * @syntax markdown @@ -197,6 +263,9 @@ object int: /** Float conversion of an `Int` singleton type. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val x: ToFloat[1] = 1.0f * ``` * @syntax markdown @@ -206,6 +275,9 @@ object int: /** Double conversion of an `Int` singleton type. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val x: ToDouble[1] = 1.0 * ``` * @syntax markdown @@ -218,6 +290,9 @@ object int: * Returns 32 if the specified singleton type has no one-bits in its two's complement representation, * in other words if it is equal to zero. * ```scala + * //{ + * import compiletime.ops.int._ + * //} * val zero_lzc: NumberOfLeadingZeros[0] = 32 * val eight_lzc: NumberOfLeadingZeros[8] = 28 * type Log2[N <: Int] = 31 - NumberOfLeadingZeros[N] diff --git a/library/src/scala/compiletime/ops/long.scala b/library/src/scala/compiletime/ops/long.scala index 87c0c90631c9..353271a592de 100644 --- a/library/src/scala/compiletime/ops/long.scala +++ b/library/src/scala/compiletime/ops/long.scala @@ -22,6 +22,9 @@ object long: /** Addition of two `Long` singleton types. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val sum: 2L + 2L = 4L * ``` * @syntax markdown @@ -30,6 +33,9 @@ object long: /** Subtraction of two `Long` singleton types. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val sub: 4L - 2L = 2L * ``` * @syntax markdown @@ -38,6 +44,9 @@ object long: /** Multiplication of two `Long` singleton types. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val mul: 4L * 2L = 8L * ``` * @syntax markdown @@ -46,6 +55,9 @@ object long: /** Integer division of two `Long` singleton types. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val div: 5L / 2L = 2L * ``` * @syntax markdown @@ -54,6 +66,9 @@ object long: /** Remainder of the division of `X` by `Y`. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val mod: 5L % 2L = 1L * ``` * @syntax markdown @@ -62,6 +77,9 @@ object long: /** Binary left shift of `X` by `Y`. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val lshift: 1L << 2L = 4L * ``` * @syntax markdown @@ -70,6 +88,9 @@ object long: /** Binary right shift of `X` by `Y`. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val rshift: 10L >> 1L = 5L * ``` * @syntax markdown @@ -78,6 +99,9 @@ object long: /** Binary right shift of `X` by `Y`, filling the left with zeros. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val rshiftzero: 10L >>> 1L = 5L * ``` * @syntax markdown @@ -86,6 +110,9 @@ object long: /** Bitwise xor of `X` and `Y`. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val xor: 10L ^ 30L = 20L * ``` * @syntax markdown @@ -94,6 +121,9 @@ object long: /** Less-than comparison of two `Long` singleton types. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val lt1: 4L < 2L = false * val lt2: 2L < 4L = true * ``` @@ -103,6 +133,9 @@ object long: /** Greater-than comparison of two `Long` singleton types. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val gt1: 4L > 2L = true * val gt2: 2L > 2L = false * ``` @@ -112,6 +145,9 @@ object long: /** Greater-or-equal comparison of two `Long` singleton types. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val ge1: 4L >= 2L = true * val ge2: 2L >= 3L = false * ``` @@ -121,6 +157,9 @@ object long: /** Less-or-equal comparison of two `Long` singleton types. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val lt1: 4L <= 2L = false * val lt2: 2L <= 2L = true * ``` @@ -130,6 +169,9 @@ object long: /** Bitwise and of `X` and `Y`. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val and1: BitwiseAnd[4L, 4L] = 4L * val and2: BitwiseAnd[10L, 5L] = 0L * ``` @@ -139,6 +181,9 @@ object long: /** Bitwise or of `X` and `Y`. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val or: BitwiseOr[10L, 11L] = 11L * ``` * @syntax markdown @@ -147,6 +192,9 @@ object long: /** Absolute value of an `Long` singleton type. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val abs: Abs[-1L] = 1L * ``` * @syntax markdown @@ -155,6 +203,9 @@ object long: /** Negation of an `Long` singleton type. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val neg1: Negate[-1L] = 1L * val neg2: Negate[1L] = -1L * ``` @@ -164,6 +215,9 @@ object long: /** Minimum of two `Long` singleton types. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val min: Min[-1L, 1L] = -1L * ``` * @syntax markdown @@ -172,6 +226,9 @@ object long: /** Maximum of two `Long` singleton types. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val max: Max[-1L, 1L] = 1L * ``` * @syntax markdown @@ -183,6 +240,9 @@ object long: * Returns 64 if the specified singleton type has no one-bits in its two's complement representation, * in other words if it is equal to zero. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val zero_lzc: NumberOfLeadingZeros[0L] = 64 * val eight_lzc: NumberOfLeadingZeros[8L] = 60 * type Log2[N <: Long] = int.-[63, NumberOfLeadingZeros[N]] @@ -194,6 +254,9 @@ object long: /** Int conversion of a `Long` singleton type. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val x: ToInt[1L] = 1 * ``` * @syntax markdown @@ -202,6 +265,9 @@ object long: /** Float conversion of a `Long` singleton type. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val x: ToFloat[1L] = 1.0f * ``` * @syntax markdown @@ -210,6 +276,9 @@ object long: /** Double conversion of a `Long` singleton type. * ```scala + * //{ + * import compiletime.ops.long._ + * //} * val x: ToDouble[1L] = 1.0 * ``` * @syntax markdown diff --git a/library/src/scala/compiletime/ops/string.scala b/library/src/scala/compiletime/ops/string.scala index 472895dca46f..49650b8b7343 100644 --- a/library/src/scala/compiletime/ops/string.scala +++ b/library/src/scala/compiletime/ops/string.scala @@ -6,6 +6,9 @@ import scala.annotation.experimental object string: /** Concatenation of two `String` singleton types. * ```scala + * //{ + * import compiletime.ops.string._ + * //} * val hello: "hello " + "world" = "hello world" * ``` * @syntax markdown @@ -14,6 +17,9 @@ object string: /** Length of a `String` singleton type. * ```scala + * //{ + * import compiletime.ops.string._ + * //} * val helloSize: Length["hello"] = 5 * ``` * @syntax markdown @@ -26,6 +32,9 @@ object string: * The substring begins at the specified IBeg and extends to the character at index IEnd - 1. * Thus the length of the substring is IEnd-IBeg. * ```scala + * //{ + * import compiletime.ops.string._ + * //} * val x: Substring["hamburger", 4, 8] = "urge" * val y: Substring["smiles", 1, 5] = "mile" * ``` @@ -37,6 +46,9 @@ object string: /** Tests if this `String` singleton type matches the given * regular expression `String` singleton type. * ```scala + * //{ + * import compiletime.ops.string._ + * //} * val x: Matches["unhappy", "un.*"] = true * ``` * @syntax markdown diff --git a/library/src/scala/quoted/Quotes.scala b/library/src/scala/quoted/Quotes.scala index cea8c8efe4de..5f6a5fd1d210 100644 --- a/library/src/scala/quoted/Quotes.scala +++ b/library/src/scala/quoted/Quotes.scala @@ -2299,9 +2299,18 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => * * `ParamClause` encodes the following enumeration * ```scala - * enum ParamClause: - * case TypeParamClause(params: List[TypeDef]) - * case TermParamClause(params: List[ValDef]) + * //{ + * import scala.quoted._ + * def inQuotes(using Quotes) = { + * val q: Quotes = summon[Quotes] + * import q.reflect._ + * //} + * enum ParamClause: + * case TypeParamClause(params: List[TypeDef]) + * case TermParamClause(params: List[ValDef]) + * //{ + * } + * //} * ``` */ type ParamClause <: AnyRef @@ -2535,7 +2544,10 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => * Usage: * ```scala * //{ + * import scala.quoted._ * def f(using Quotes) = { + * val q: Quotes = summon[Quotes] + * import q.reflect._ * val typeRepr: TypeRepr = ??? * //} * typeRepr.asType match @@ -3942,22 +3954,32 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => * * Usages: * ```scala - * def rhsExpr(using Quotes): Expr[Unit] = '{ val y = ???; (y, y) } - * def aValDef(using Quotes)(owner: Symbol) = + * def rhsExpr(using q: Quotes): Expr[Unit] = + * import q.reflect._ + * '{ val y = ???; (y, y) } + * def aValDef(using q: Quotes)(owner: q.reflect.Symbol) = + * import q.reflect._ * val sym = Symbol.newVal(owner, "x", TypeRepr.of[Unit], Flags.EmptyFlags, Symbol.noSymbol) * val rhs = rhsExpr(using sym.asQuotes).asTerm * ValDef(sym, Some(rhs)) * ``` * * ```scala - * new TreeMap: - * override def transformTerm(tree: Term)(owner: Symbol): Term = - * tree match - * case tree: Ident => - * given Quotes = owner.asQuotes - * // Definitions contained in the quote will be owned by `owner`. - * // No need to use `changeOwner` in this case. - * '{ val x = ???; x }.asTerm + * //{ + * def inQuotes(using q: Quotes) = { + * import q.reflect._ + * //} + * new TreeMap: + * override def transformTerm(tree: Term)(owner: Symbol): Term = + * tree match + * case tree: Ident => + * given Quotes = owner.asQuotes + * // Definitions contained in the quote will be owned by `owner`. + * // No need to use `changeOwner` in this case. + * '{ val x = ???; x }.asTerm + * //{ + * } + * //} * ``` */ @experimental @@ -4528,9 +4550,16 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => * * Usage: * ```scala - * class MyTreeAccumulator[X] extends TreeAccumulator[X] { - * def foldTree(x: X, tree: Tree)(owner: Symbol): X = ??? + * //{ + * def inQuotes(using q: Quotes) = { + * import q.reflect._ + * //} + * class MyTreeAccumulator[X] extends TreeAccumulator[X] { + * def foldTree(x: X, tree: Tree)(owner: Symbol): X = ??? + * } + * //{ * } + * //} * ``` */ trait TreeAccumulator[X]: @@ -4634,9 +4663,16 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => * * Usage: * ```scala - * class MyTraverser extends TreeTraverser { - * override def traverseTree(tree: Tree)(owner: Symbol): Unit = ??? + * //{ + * def inQuotes(using q: Quotes) = { + * import q.reflect._ + * //} + * class MyTraverser extends TreeTraverser { + * override def traverseTree(tree: Tree)(owner: Symbol): Unit = ??? + * } + * //{ * } + * //} * ``` */ trait TreeTraverser extends TreeAccumulator[Unit]: @@ -4653,9 +4689,16 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => * * Usage: * ```scala - * class MyTreeMap extends TreeMap { - * override def transformTree(tree: Tree)(owner: Symbol): Tree = ??? + * //{ + * def inQuotes(using q: Quotes) = { + * import q.reflect._ + * //} + * class MyTreeMap extends TreeMap { + * override def transformTree(tree: Tree)(owner: Symbol): Tree = ??? + * } + * //{ * } + * //} * ``` * * Use `Symbol.asQuotes` to create quotes with the correct owner within the TreeMap. From ecebebb9d7f193931ef52deed8534a9de5660349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Zyba=C5=82a?= Date: Thu, 9 Jun 2022 14:38:48 +0200 Subject: [PATCH 8/8] Fix uncompiling snippets --- library/src/scala/annotation/MainAnnotation.scala | 4 ++-- library/src/scala/compiletime/ops/string.scala | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/library/src/scala/annotation/MainAnnotation.scala b/library/src/scala/annotation/MainAnnotation.scala index 9d2f5362ba15..865674d7cb69 100644 --- a/library/src/scala/annotation/MainAnnotation.scala +++ b/library/src/scala/annotation/MainAnnotation.scala @@ -11,7 +11,7 @@ package scala.annotation * - a call to `command.run` with the closure of user-main applied to all arguments. * * Example: - * ```scala + * ```scala sc:nocompile * /** Sum all the numbers * * * * @param first Fist number to sum @@ -20,7 +20,7 @@ package scala.annotation * @myMain def sum(first: Int, second: Int = 0, rest: Int*): Int = first + second + rest.sum * ``` * generates - * ```scala + * ```scala sc:nocompile * object foo { * def main(args: Array[String]): Unit = { * val mainAnnot = new myMain() diff --git a/library/src/scala/compiletime/ops/string.scala b/library/src/scala/compiletime/ops/string.scala index cfb1be066772..ee7ade3f0136 100644 --- a/library/src/scala/compiletime/ops/string.scala +++ b/library/src/scala/compiletime/ops/string.scala @@ -55,6 +55,9 @@ object string: * An index ranges from 0 to Length[S] - 1. The first Char of * the sequence is at index 0, the next at index 1, and so on. * ```scala + * //{ + * import string._ + * //} * val c: CharAt["hello", 0] = 'h' * ``` * @syntax markdown