codeconsole opened a new pull request, #15717:
URL: https://github.com/apache/grails-core/pull/15717
## Problem
A scaffolded service declared with a parameterized base, e.g.
`@Scaffold(GormMongoService<Book>)`, is given the **raw** type
`GormService`/`GormMongoService` as its superclass — the `<Book>` type argument
is dropped. So every inherited generic method (`get():T`, `list():List<T>`,
`save(T):T`, …) resolves to the `GormEntity` upper bound rather than the
concrete domain type.
Under `@GrailsCompileStatic`/`@CompileStatic` this forces a cast at every
call site:
```groovy
Book b = bookService.get(id) // Cannot assign value of type
GormEntity to variable of type Book
List<Book> all = bookService.list(params) // List<GormEntity>
```
## Root cause
In `ScaffoldingServiceInjector.performInjectionOnAnnotatedClass`:
```groovy
superClassNode = valueClassNode.getPlainNodeReference()
// strips the <Book> generic
...
classNode.setSuperClass(GrailsASTUtils.nonGeneric(superClassNode,
domainClass))
```
`getPlainNodeReference()` removes the generics, so the following
`nonGeneric(raw, domain)` is a no-op: `replaceGenericsPlaceholders`
early-returns the plain node because the type is no longer using generics. The
domain type is known but never applied to the superclass.
## Fix
Set the superclass to a parameterized `GormService<Domain>`:
```groovy
ClassNode parameterizedSuper = superClassNode.getPlainNodeReference()
parameterizedSuper.setGenericsTypes(
[new GenericsType(GrailsASTUtils.nonGeneric(domainClass))] as
GenericsType[])
classNode.setSuperClass(parameterizedSuper)
```
## Impact
Inherited scaffold-service methods now resolve to the domain type with no
casts under static compilation:
```groovy
Book b = bookService.get(id) // ✅ Book
List<Book> all = bookService.list(params) // ✅ List<Book>
```
Generics are compile-time only, so there is no runtime behavior change.
Verified against a real app's `@Scaffold(GormMongoService<T>)` services —
`get()`/`list()` compile to the domain type under `@GrailsCompileStatic` with
zero casts (previously every such call required a cast or `@CompileDynamic`).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]