-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add class term parameters, flags, and privateWithin to newClass in re…
…flect API
- Loading branch information
Showing
13 changed files
with
216 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
|
||
-- Error: tests/neg-macros/newClassParamsMissingArgument/Test_2.scala:4:2 ---------------------------------------------- | ||
4 | makeClass("foo") // error // error | ||
| ^^^^^^^^^^^^^^^^ | ||
|wrong number of arguments at inlining (while expanding macro) for (idx: Int): foo: (foo#<init> : (idx: Int): foo), expected: 1, found: 0 | ||
-- Error: tests/neg-macros/newClassParamsMissingArgument/Test_2.scala:4:11 --------------------------------------------- | ||
4 | makeClass("foo") // error // error | ||
| ^^^^^^^^^^^^^^^^ | ||
|Malformed tree was found while expanding macro with -Xcheck-macros. | ||
|The tree does not conform to the compiler's tree invariants. | ||
| | ||
|Macro was: | ||
|scala.quoted.runtime.Expr.splice[java.lang.Object](((contextual$1: scala.quoted.Quotes) ?=> Macro_1$package.inline$makeClassExpr(scala.quoted.runtime.Expr.quote[scala.Predef.String]("foo").apply(using contextual$1))(contextual$1))) | ||
| | ||
|The macro returned: | ||
|{ | ||
| class foo(val idx: scala.Int) extends java.lang.Object | ||
| | ||
| (new foo(): java.lang.Object) | ||
|} | ||
| | ||
|Error: | ||
|missing argument for parameter idx of constructor foo in class foo: (idx: Int): foo | ||
| | ||
|stacktrace available when compiling with `-Ydebug` | ||
|--------------------------------------------------------------------------------------------------------------------- | ||
|Inline stack trace | ||
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||
|This location contains code that was inlined from Macro_1.scala:5 | ||
5 |inline def makeClass(inline name: String): Object = ${ makeClassExpr('name) } | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
--------------------------------------------------------------------------------------------------------------------- |
24 changes: 24 additions & 0 deletions
24
tests/neg-macros/newClassParamsMissingArgument/Macro_1.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
//> using options -experimental | ||
|
||
import scala.quoted._ | ||
|
||
inline def makeClass(inline name: String): Object = ${ makeClassExpr('name) } | ||
private def makeClassExpr(nameExpr: Expr[String])(using Quotes): Expr[Object] = { | ||
import quotes.reflect.* | ||
|
||
val name = nameExpr.valueOrAbort | ||
val parents = List(TypeTree.of[Object]) | ||
def decls(cls: Symbol): List[Symbol] = Nil | ||
|
||
val cls = Symbol.newClass(Symbol.spliceOwner, name, parents = parents.map(_.tpe), decls, selfType = None, List("idx"), List(TypeRepr.of[Int]), Flags.EmptyFlags, Symbol.noSymbol) | ||
|
||
val clsDef = ClassDef(cls, parents, body = Nil) | ||
val newCls = Typed(Apply(Select(New(TypeIdent(cls)), cls.primaryConstructor), Nil), TypeTree.of[Object]) | ||
|
||
Block(List(clsDef), newCls).asExprOf[Object] | ||
|
||
// '{ | ||
// class `name`(idx: Int) | ||
// new `name` | ||
// } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
//> using options -experimental | ||
|
||
@main def Test: Unit = { | ||
makeClass("foo") // error // error | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Foo method call with (10, test) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
//> using options -experimental | ||
|
||
import scala.quoted._ | ||
|
||
inline def makeClassAndCall(inline name: String, idx: Int, str: String): Unit = ${ makeClassAndCallExpr('name, 'idx, 'str) } | ||
private def makeClassAndCallExpr(nameExpr: Expr[String], idxExpr: Expr[Int], strExpr: Expr[String])(using Quotes): Expr[Unit] = { | ||
import quotes.reflect.* | ||
|
||
val name = nameExpr.valueOrAbort | ||
|
||
def decls(cls: Symbol): List[Symbol] = List(Symbol.newMethod(cls, "foo", MethodType(Nil)(_ => Nil, _ => TypeRepr.of[Unit]))) | ||
val parents = List(TypeTree.of[Object]) | ||
val cls = Symbol.newClass(Symbol.spliceOwner, name, parents = parents.map(_.tpe), decls, selfType = None, List("idx", "str"), List(TypeRepr.of[Int], TypeRepr.of[String]), Flags.EmptyFlags, Symbol.noSymbol) | ||
|
||
val fooDef = DefDef(cls.methodMember("foo")(0), argss => Some('{println(s"Foo method call with (${${Ref(cls.fieldMember("idx")).asExpr}}, ${${Ref(cls.fieldMember("str")).asExpr}})")}.asTerm)) | ||
val clsDef = ClassDef(cls, parents, body = List(fooDef)) | ||
val newCls = Apply(Select(New(TypeIdent(cls)), cls.primaryConstructor), List(idxExpr.asTerm, strExpr.asTerm)) | ||
|
||
Block(List(clsDef), Apply(Select(newCls, cls.methodMember("foo")(0)), Nil)).asExprOf[Unit] | ||
|
||
// '{ | ||
// class `name`(idx: Int, str: String) { | ||
// def foo() = println("Foo method call with ($idx, $str)") | ||
// } | ||
// new `name`(`idx`, `str`) | ||
// } | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
//> using options -experimental | ||
|
||
@main def Test: Unit = { | ||
makeClassAndCall("bar", 10, "test") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Calling Foo.foo with i = 22 | ||
class Test_2$package$foo$1 | ||
Calling Foo.foo with i = 22 | ||
class Test_2$package$bar$1 |
30 changes: 30 additions & 0 deletions
30
tests/run-macros/newClassParamsExtendsClassParams/Macro_1.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
//> using options -experimental | ||
|
||
import scala.quoted._ | ||
|
||
inline def makeClass(inline name: String): Foo = ${ makeClassExpr('name) } | ||
private def makeClassExpr(nameExpr: Expr[String])(using Quotes): Expr[Foo] = { | ||
import quotes.reflect.* | ||
|
||
val name = nameExpr.valueOrAbort | ||
val parents = List('{ new Foo(1) }.asTerm) | ||
def decls(cls: Symbol): List[Symbol] = Nil | ||
|
||
val cls = Symbol.newClass(Symbol.spliceOwner, name, parents = parents.map(_.tpe), decls, selfType = None, List("idx"), List(TypeRepr.of[Int]), Flags.EmptyFlags, Symbol.noSymbol) | ||
|
||
val parentsWithSym = List(Apply(Select(New(TypeTree.of[Foo]), TypeRepr.of[Foo].typeSymbol.primaryConstructor), List(Ref(cls.fieldMember("idx"))))) | ||
val clsDef = ClassDef(cls, parentsWithSym, body = Nil) | ||
val newCls = Typed(Apply(Select(New(TypeIdent(cls)), cls.primaryConstructor), List(Literal(IntConstant(22)))), TypeTree.of[Foo]) | ||
|
||
Block(List(clsDef), newCls).asExprOf[Foo] | ||
|
||
// '{ | ||
// class `name`(idx: Int) extends Foo(idx) | ||
// new `name`(22) | ||
// } | ||
} | ||
|
||
class Foo(i: Int) { | ||
def foo(): Unit = println(s"Calling Foo.foo with i = $i") | ||
} | ||
|
10 changes: 10 additions & 0 deletions
10
tests/run-macros/newClassParamsExtendsClassParams/Test_2.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
//> using options -experimental | ||
|
||
@main def Test: Unit = { | ||
val foo: Foo = makeClass("foo") | ||
foo.foo() | ||
println(foo.getClass) | ||
val bar: Foo = makeClass("bar") | ||
bar.foo() | ||
println(bar.getClass) | ||
} |