matrei commented on code in PR #16042:
URL: https://github.com/apache/grails-core/pull/16042#discussion_r3673025227
##########
grails-core/src/main/groovy/org/grails/compiler/injection/GlobalGrailsClassInjectorTransformation.groovy:
##########
@@ -211,153 +231,419 @@ class GlobalGrailsClassInjectorTransformation
implements ASTTransformation, Comp
return targetDirectory
}
+ /**
+ * Adds the compiled class to the {@code META-INF/grails.factories} entry
for the supplied type
+ * when it is a concrete subtype of that type. Existing generated entries
and matching
+ * project-source entries are preserved, and the resulting factory file is
written to the
+ * compilation target directory.
+ *
+ * @param classNode the class being compiled
+ * @param superType the factory interface or superclass whose
implementations are registered
+ * @param compilationTargetDirectory the compilation output directory
containing the factory file
+ * @return {@code true} when {@code classNode} is a non-abstract subtype
of {@code superType} and
+ * was registered; {@code false} otherwise
+ */
static boolean updateGrailsFactoriesWithType(ClassNode classNode,
ClassNode superType, File compilationTargetDirectory) {
- FactoriesFileWriter.updateFactoriesWithType(classNode, superType,
compilationTargetDirectory,
- 'META-INF/grails.factories',
['src/main/resources/META-INF/grails.factories'])
+ FactoriesFileWriter.updateFactoriesWithType(
+ classNode,
+ superType,
+ compilationTargetDirectory,
+ 'META-INF/grails.factories',
+ ['src/main/resources/META-INF/grails.factories']
+ )
}
- static LinkedHashSet<String> pendingPluginClasses = []
- static Collection<String> pluginExcludes = []
+ private static boolean updateGrailsFactoriesWithTypes(ClassNode classNode,
Collection<ClassNode> superTypes, File compilationTargetDirectory) {
+ superTypes.any {
+ updateGrailsFactoriesWithType(classNode, it,
compilationTargetDirectory)
+ }
+ }
- protected static void generatePluginXml(ClassNode pluginClassNode, String
pluginVersion, Set<String> transformedClasses, File pluginXmlFile) {
+ /**
+ * Creates or updates the generated {@code META-INF/grails-plugin.xml}
descriptor and carries
+ * forward artefact classes collected during compilation.
+ *
+ * @param pluginClassNode the compiled plugin descriptor class, or {@code
null} when none was found
+ * @param pluginVersion the plugin version, or {@code null} when no
concrete plugin descriptor
+ * is being generated
+ * @param transformedClassNames the artefact classes transformed in the
current source unit
+ * @param pluginXmlFile the generated plugin descriptor file
+ */
+ protected void generatePluginXml(
+ @Nullable ClassNode pluginClassNode,
+ @Nullable String pluginVersion,
+ Set<String> transformedClassNames,
+ File pluginXmlFile
+ ) {
+ // first check if plugin.xml exists
+ pluginXmlFile.parentFile.mkdirs()
def pluginXmlExists = pluginXmlFile.exists()
- LinkedHashSet<String> pluginClasses = []
- pluginClasses.addAll(transformedClasses)
- pluginClasses.addAll(pendingPluginClasses)
-
- // if the class being transformed is a *GrailsPlugin class then if it
doesn't exist create it
- if (pluginClassNode && !pluginClassNode.isAbstract()) {
+ def pluginClasses = [] as LinkedHashSet<String>
+ pluginClasses.addAll(transformedClassNames)
+ pluginClasses.addAll(pendingPluginClassNames)
+ // Reset excludes from a previous source unit so that patterns
declared by one plugin
+ // do not leak into a subsequent compilation within the same Gradle
worker.
+ pluginExcludePatterns.clear()
+
+ // Create or update grails-plugin.xml when a concrete plugin class is
present; otherwise,
+ // update an existing descriptor or defer resource names until the
descriptor is compiled.
+ if (pluginClassNode && !pluginClassNode.abstract) {
+ if (!pluginVersion) {
+ throw new IllegalStateException(
+ "Unable to generate '${pluginXmlFile}' because plugin
class '${pluginClassNode.name}' " +
+ 'does not define a plugin version.'
+ )
+ }
if (!pluginXmlExists) {
+ // The plugin descriptor is being compiled for the first time.
writePluginXml(pluginClassNode, pluginVersion, pluginXmlFile,
pluginClasses)
} else {
- // otherwise if the file does exist, update it with the plugin
name
+ // Refresh the existing descriptor with the current plugin
metadata and resources.
updatePluginXml(pluginClassNode, pluginVersion, pluginXmlFile,
pluginClasses)
}
} else if (pluginXmlExists) {
- // if the class isn't the *GrailsPlugin class then only update the
plugin.xml if it already exists
+ // Add resources from this source unit to the existing descriptor.
updatePluginXml(null, pluginVersion, pluginXmlFile, pluginClasses)
} else {
- // otherwise add it to a list of pending classes to populated when
the plugin.xml is created
- pendingPluginClasses.addAll(transformedClasses)
+ // Defer these resource names until a source unit compiles the
plugin descriptor.
+ pendingPluginClassNames.addAll(transformedClassNames)
}
}
- @CompileDynamic
- static void writePluginXml(ClassNode pluginClassNode, String
pluginVersion, File pluginXml, Collection<String> artefactClasses) {
+ /**
+ * Writes a new plugin descriptor from the plugin class metadata and
supplied artefact classes.
+ *
+ * @param pluginClassNode the plugin descriptor class
+ * @param pluginVersion the required plugin version when {@code
pluginClassNode} is present
+ * @param pluginXml the output descriptor file
+ * @param artefactClassNames artefact class names to include as resources
+ */
+ void writePluginXml(
+ @Nullable ClassNode pluginClassNode,
+ String pluginVersion,
+ File pluginXml,
+ Collection<String> artefactClassNames
+ ) {
+ pluginXml.parentFile.mkdirs()
if (pluginClassNode) {
- PluginAstReader pluginAstReader = new PluginAstReader()
- def info = pluginAstReader.readPluginInfo(pluginClassNode)
-
- pluginXml.withWriter(StandardCharsets.UTF_8.name()) { Writer
writer ->
- def mkp = new MarkupBuilder(writer)
- def pluginName =
GrailsNameUtils.getLogicalPropertyName(pluginClassNode.name, 'GrailsPlugin')
-
- def pluginProperties = info.getProperties()
- def excludes = pluginProperties.get('pluginExcludes')
- if (excludes instanceof List) {
- pluginExcludes.clear()
- pluginExcludes.addAll(excludes)
- }
+ writePluginXmlWithDescriptor(pluginClassNode, pluginVersion,
pluginXml, artefactClassNames)
+ } else {
+ writePluginXmlWithoutDescriptor(pluginXml, artefactClassNames)
+ }
+ pendingPluginClassNames.clear()
Review Comment:
Went the "delete the unusable file" path.
--
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]