From 1dfafc96a4ec6d4abe5e1dd815eb9750828118b8 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Wed, 2 Oct 2024 10:21:57 +0200 Subject: [PATCH 1/2] Quotes type printing: take `infix` type modifier into account This is similar to how the regular compiler `.show` handles `infix` but using explicit parens everywhere to not have to reimplement the precedence logic (maybe quote type printing should just use `.show` eventually). [Cherry-picked 936c009b8a33d4d673a71f4a69c148155ddf0886] --- .../runtime/impl/printers/SourceCode.scala | 15 ++++++++-- tests/run-macros/type-print.check | 12 ++++++++ tests/run-macros/type-print/Macro_1.scala | 29 +++++++++++++++++++ tests/run-macros/type-print/Test_2.scala | 15 ++++++++++ 4 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 tests/run-macros/type-print.check create mode 100644 tests/run-macros/type-print/Macro_1.scala create mode 100644 tests/run-macros/type-print/Test_2.scala diff --git a/compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala b/compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala index 11a4c855f37e..017ee7eecb7e 100644 --- a/compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala +++ b/compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala @@ -1150,8 +1150,19 @@ object SourceCode { case tp: TypeRef if tp.typeSymbol == Symbol.requiredClass("scala.") => this += "_*" case _ => - printType(tp) - inSquare(printTypesOrBounds(args, ", ")) + if !fullNames && args.lengthCompare(2) == 0 && tp.typeSymbol.flags.is(Flags.Infix) then + val lhs = args(0) + val rhs = args(1) + this += "(" + printType(lhs) + this += " " + printType(tp) + this += " " + printType(rhs) + this += ")" + else + printType(tp) + inSquare(printTypesOrBounds(args, ", ")) } case AnnotatedType(tp, annot) => diff --git a/tests/run-macros/type-print.check b/tests/run-macros/type-print.check new file mode 100644 index 000000000000..5eae94d4a1bf --- /dev/null +++ b/tests/run-macros/type-print.check @@ -0,0 +1,12 @@ +List[Int] +scala.collection.immutable.List[scala.Int] +scala.collection.immutable.List[scala.Int] +AppliedType(TypeRef(ThisType(TypeRef(NoPrefix(), "immutable")), "List"), List(TypeRef(TermRef(ThisType(TypeRef(NoPrefix(), "")), "scala"), "Int"))) +(3 + (a * b)) +scala.compiletime.ops.int.+[3, scala.compiletime.ops.int.*[a, b]] +scala.compiletime.ops.int.+[3, scala.compiletime.ops.int.*[a, b]] +AppliedType(TypeRef(TermRef(TermRef(TermRef(TermRef(ThisType(TypeRef(NoPrefix(), "")), "scala"), "compiletime"), "ops"), "int"), "+"), List(ConstantType(IntConstant(3)), AppliedType(TypeRef(TermRef(TermRef(TermRef(TermRef(ThisType(TypeRef(NoPrefix(), "")), "scala"), "compiletime"), "ops"), "int"), "*"), List(TermRef(NoPrefix(), "a"), TermRef(NoPrefix(), "b"))))) +((3 + a) * b) +scala.compiletime.ops.int.*[scala.compiletime.ops.int.+[3, a], b] +scala.compiletime.ops.int.*[scala.compiletime.ops.int.+[3, a], b] +AppliedType(TypeRef(TermRef(TermRef(TermRef(TermRef(ThisType(TypeRef(NoPrefix(), "")), "scala"), "compiletime"), "ops"), "int"), "*"), List(AppliedType(TypeRef(TermRef(TermRef(TermRef(TermRef(ThisType(TypeRef(NoPrefix(), "")), "scala"), "compiletime"), "ops"), "int"), "+"), List(ConstantType(IntConstant(3)), TermRef(NoPrefix(), "a"))), TermRef(NoPrefix(), "b"))) diff --git a/tests/run-macros/type-print/Macro_1.scala b/tests/run-macros/type-print/Macro_1.scala new file mode 100644 index 000000000000..c0dd57e33018 --- /dev/null +++ b/tests/run-macros/type-print/Macro_1.scala @@ -0,0 +1,29 @@ +import scala.quoted.* + +inline def printTypeShort[T]: String = + ${ printTypeShortImpl[T] } + +inline def printType[T]: String = + ${ printTypeImpl[T] } + +inline def printTypeAnsi[T]: String = + ${ printTypeAnsiImpl[T] } + +inline def printTypeStructure[T]: String = + ${ printTypeStructureImpl[T] } + +def printTypeShortImpl[T: Type](using Quotes): Expr[String] = + import quotes.reflect.* + Expr(Printer.TypeReprShortCode.show(TypeRepr.of[T])) + +def printTypeImpl[T: Type](using Quotes): Expr[String] = + import quotes.reflect.* + Expr(Printer.TypeReprCode.show(TypeRepr.of[T])) + +def printTypeAnsiImpl[T: Type](using Quotes): Expr[String] = + import quotes.reflect.* + Expr(Printer.TypeReprAnsiCode.show(TypeRepr.of[T])) + +def printTypeStructureImpl[T: Type](using Quotes): Expr[String] = + import quotes.reflect.* + Expr(Printer.TypeReprStructure.show(TypeRepr.of[T])) diff --git a/tests/run-macros/type-print/Test_2.scala b/tests/run-macros/type-print/Test_2.scala new file mode 100644 index 000000000000..f2ea6c3ba8b1 --- /dev/null +++ b/tests/run-macros/type-print/Test_2.scala @@ -0,0 +1,15 @@ +import scala.compiletime.ops.int.* + +inline def printAll[T]: Unit = + println(printTypeShort[T]) + println(printType[T]) + println(printTypeAnsi[T]) + println(printTypeStructure[T]) + +@main +def Test: Unit = + printAll[List[Int]] + val a = 1 + val b = 2 + printAll[3 + a.type * b.type] + printAll[(3 + a.type) * b.type] From 1b4a464d369f005628ebb14527c433f2f0873ed2 Mon Sep 17 00:00:00 2001 From: Wojciech Mazur Date: Thu, 5 Dec 2024 22:40:20 +0100 Subject: [PATCH 2/2] Make the test pass in LTS - int ops are not made infix in the LTS --- tests/run-macros/type-print.check | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/run-macros/type-print.check b/tests/run-macros/type-print.check index 5eae94d4a1bf..6ded89ec4e88 100644 --- a/tests/run-macros/type-print.check +++ b/tests/run-macros/type-print.check @@ -2,11 +2,11 @@ List[Int] scala.collection.immutable.List[scala.Int] scala.collection.immutable.List[scala.Int] AppliedType(TypeRef(ThisType(TypeRef(NoPrefix(), "immutable")), "List"), List(TypeRef(TermRef(ThisType(TypeRef(NoPrefix(), "")), "scala"), "Int"))) -(3 + (a * b)) ++[3, *[a, b]] scala.compiletime.ops.int.+[3, scala.compiletime.ops.int.*[a, b]] scala.compiletime.ops.int.+[3, scala.compiletime.ops.int.*[a, b]] AppliedType(TypeRef(TermRef(TermRef(TermRef(TermRef(ThisType(TypeRef(NoPrefix(), "")), "scala"), "compiletime"), "ops"), "int"), "+"), List(ConstantType(IntConstant(3)), AppliedType(TypeRef(TermRef(TermRef(TermRef(TermRef(ThisType(TypeRef(NoPrefix(), "")), "scala"), "compiletime"), "ops"), "int"), "*"), List(TermRef(NoPrefix(), "a"), TermRef(NoPrefix(), "b"))))) -((3 + a) * b) +*[+[3, a], b] scala.compiletime.ops.int.*[scala.compiletime.ops.int.+[3, a], b] scala.compiletime.ops.int.*[scala.compiletime.ops.int.+[3, a], b] AppliedType(TypeRef(TermRef(TermRef(TermRef(TermRef(ThisType(TypeRef(NoPrefix(), "")), "scala"), "compiletime"), "ops"), "int"), "*"), List(AppliedType(TypeRef(TermRef(TermRef(TermRef(TermRef(ThisType(TypeRef(NoPrefix(), "")), "scala"), "compiletime"), "ops"), "int"), "+"), List(ConstantType(IntConstant(3)), TermRef(NoPrefix(), "a"))), TermRef(NoPrefix(), "b")))