jamesfredley commented on code in PR #15557:
URL: https://github.com/apache/grails-core/pull/15557#discussion_r3343108331


##########
grails-datastore-core/src/test/groovy/org/grails/datastore/mapping/reflect/ClassPropertyFetcherTests.groovy:
##########
@@ -114,8 +114,8 @@ class ClassPropertyFetcherTests  {
     }
 }
 
-trait TestTrait<F extends Serializable> {
-    F from
+trait TestTrait<T> {

Review Comment:
   Restored the `Serializable` bound: `trait TestTrait<F extends 
Serializable>`. It was an incidental change; the datastore test keeps 
exercising the bounded trait type parameter.



##########
grails-fields/src/main/groovy/grails/plugin/formfields/BeanPropertyAccessorFactory.groovy:
##########
@@ -125,12 +125,31 @@ class BeanPropertyAccessorFactory implements 
GrailsApplicationAware {
 
     private Constrained resolveConstraints(BeanWrapper beanWrapper, String 
propertyName) {
         Class<?> type = beanWrapper.wrappedClass
-        boolean defaultNullable = Validateable.isAssignableFrom(type) ? 
type.metaClass.invokeStaticMethod(type, 'defaultNullable') : false
+        boolean defaultNullable = Validateable.isAssignableFrom(type) ? 
resolveDefaultNullable(type) : false
         ConstrainedProperty constraint = constraintsEvaluator.evaluate(type, 
defaultNullable)[propertyName]
 
         new Constrained(constraint ?: createDefaultConstraint(beanWrapper, 
propertyName))
     }
 
+    private static boolean resolveDefaultNullable(Class<?> clazz) {

Review Comment:
   Added a doc comment explaining it. The switch from 
`type.metaClass.invokeStaticMethod(type, 'defaultNullable')` to reflection is 
needed because under Groovy 5 `Validateable`'s `TraitReceiverTransformer` 
rewrites the in-trait `defaultNullable()` call to a direct trait-helper static 
call, which loses the implementing class's override and always returns the 
trait default. A reflective `Class.getMethod('defaultNullable').invoke(null)` 
resolves the actual override. See GROOVY-11985. Mirrors 
`Validateable.resolveDefaultNullable`.



##########
grails-geb/src/testFixtures/groovy/grails/plugin/geb/WebDriverContainerHolder.groovy:
##########
@@ -499,7 +504,8 @@ class WebDriverContainerHolder {
             private static class InterceptingProperties extends Properties {
                 @Override
                 String getProperty(String key) {
-                    def v = OVERRIDDEN_SYSTEM_PROPERTIES.get().get(key)
+                    Map<String, String> overrides = getOverriddenProperties()

Review Comment:
   It is a Groovy 5 STC limitation: from the nested 
`InterceptingProperties.getProperty(String)`, Groovy 5 could not statically 
resolve the enclosing class's private static `OVERRIDDEN_SYSTEM_PROPERTIES` 
ThreadLocal and the type of its `.get()`, so the typed 
`getOverriddenProperties()` accessor is the workaround. It could instead be an 
inline `((Map<String, String>) OVERRIDDEN_SYSTEM_PROPERTIES.get())` cast if 
you'd rather not keep the helper - let me know your preference.



##########
grails-gradle/gradle/docs-config.gradle:
##########
@@ -25,11 +25,13 @@ dependencies {
     // TODO: Remove jline:jline (JLine 2) when upgrading to Groovy 5 
(groovy-groovysh 5.x uses JLine 3)
     add('documentation', 'jline:jline')
     add('documentation', 'com.github.javaparser:javaparser-core')
-    add('documentation', 
"org.apache.groovy:groovy:${bomDependencyVersions['groovy.version']}")
-    add('documentation', 
"org.apache.groovy:groovy-groovydoc:${bomDependencyVersions['groovy.version']}")
-    add('documentation', 
"org.apache.groovy:groovy-ant:${bomDependencyVersions['groovy.version']}")
-    add('documentation', 
"org.apache.groovy:groovy-docgenerator:${bomDependencyVersions['groovy.version']}")
-    add('documentation', 
"org.apache.groovy:groovy-templates:${bomDependencyVersions['groovy.version']}")
+    // grails-gradle subprojects target Gradle's embedded Groovy 4 (see 
gradleBomDependencyVersions['gradle-groovy.version']).
+    // Do NOT use the main Groovy version here - that is Groovy 5.x in Grails 
8 and would override the gradle-groovy-bom platform.

Review Comment:
   Simplified to a single line: `// Use Gradle's embedded Groovy 
(gradle-groovy.version), not the project's main Groovy version.`



##########
grails-gradle/tasks/build.gradle:
##########
@@ -40,7 +40,9 @@ ext {
 dependencies {
     implementation platform(project(':grails-gradle-bom'))
 
-    implementation 
"org.apache.groovy:groovy:${bomDependencyVersions['groovy.version']}"
+    // grails-gradle-tasks targets Gradle's embedded Groovy 4 
(gradleBomDependencyVersions['gradle-groovy.version']).

Review Comment:
   Simplified, version reference dropped: `// Use Gradle's embedded Groovy, not 
the project's main Groovy version.`



##########
grails-gsp/core/src/test/groovy/org/grails/gsp/GspCompileStaticSpec.groovy:
##########
@@ -146,6 +153,9 @@ out.print(messageClosure('World'))
         t.metaInfo.compilationException.message.contains('Cannot find matching 
method java.util.Date#getTimeTypo()')
     }
 
+    // Note: In Groovy 5, the type checking extension behavior changed and 
undeclared variables
+    // in GSP templates may not trigger compilation errors. This is a known 
limitation.

Review Comment:
   To be clear about scope: GSP **static compilation still works** - `g.*` 
taglib calls from `@CompileStatic` GSPs resolve via the namespace-matching 
`methodNotFound` handler in `GroovyPageTypeCheckingExtension` (the GROOVY-12041 
approach). What these two `@IgnoreIf` tests assert is the *negative* case: that 
referencing an **undeclared** variable (`${somename}`) raises a compile error. 
Under Groovy 5 the STC `unresolvedVariable`/`unresolvedProperty` callbacks do 
not fire when the receiver inherits `getProperty(String)`, so that compile 
error is not produced and the negative assertion cannot hold. So this is a loss 
of *strictness* in detecting undeclared GSP variables, not a loss of static 
compilation. Tracked against GROOVY-6362 / GROOVY-11817 / GROOVY-12041, and 
related to #15669 (`@GrailsCompileStatic` taglib support). @paulk-asert any 
history on the undeclared-variable callback change would be appreciated.



##########
grails-logging/src/main/groovy/org/grails/compiler/logging/LoggingTransformer.java:
##########
@@ -78,11 +80,24 @@ public void performInjectionOnAnnotatedClass(SourceUnit 
source, ClassNode classN
             return;
         }
 
-        AnnotationNode annotationNode = new 
AnnotationNode(ClassHelper.make(Slf4j.class));
-        LogASTTransformation logASTTransformation = new LogASTTransformation();
-        logASTTransformation.setCompilationUnit(new CompilationUnit(new 
GroovyClassLoader(getClass().getClassLoader())));
-        logASTTransformation.visit(new ASTNode[]{ annotationNode, classNode}, 
source);
-        classNode.putNodeMetaData(Slf4j.class, annotationNode);
+        // Groovy 5: an @Slf4j added during an AST transform is not processed, 
so inject the log field manually.

Review Comment:
   The issue is applying `@Slf4j` *programmatically from inside another AST 
transform*: in Groovy 5 the `LogASTTransformation` invoked from our injector is 
not picked up (the annotation added mid-transform is not processed), so no 
`log` field is generated. The PR injects the `log` field directly 
(`LoggerFactory.getLogger(<class>)`) instead. @paulk-asert if this was fixed in 
a `GROOVY_5_0_X` snapshot, point me at it and I'll revert to letting 
`LogASTTransformation` do it.



-- 
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]

Reply via email to