From 6803c09645cc3a0752d2f1b04d12d34edf5df876 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Fri, 20 Aug 2021 18:27:46 -0500 Subject: [PATCH] fixes for Antlr tasks --- hibernate-core/hibernate-core.gradle | 4 - hibernate-orm-build/build.gradle | 2 +- .../org/hibernate/orm/antlr/Antlr4Plugin.java | 81 ---------- .../org/hibernate/orm/antlr/AntlrHelper.java | 79 ++++++++++ .../org/hibernate/orm/antlr/AntlrPlugin.java | 99 +++++++++++++ .../antlr/{Antlr4Spec.java => AntlrSpec.java} | 21 ++- .../hibernate/orm/antlr/GeneratorTask.java | 78 ---------- .../orm/antlr/GrammarDescriptor.java | 37 ----- .../orm/antlr/GrammarDescriptorFactory.java | 48 ++++++ .../orm/antlr/SplitGrammarDescriptor.java | 77 ++++++++++ .../orm/antlr/SplitGrammarGenerationTask.java | 140 ++++++++++++++++++ 11 files changed, 460 insertions(+), 206 deletions(-) delete mode 100644 hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/Antlr4Plugin.java create mode 100644 hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/AntlrHelper.java create mode 100644 hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/AntlrPlugin.java rename hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/{Antlr4Spec.java => AntlrSpec.java} (66%) delete mode 100644 hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/GeneratorTask.java delete mode 100644 hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/GrammarDescriptor.java create mode 100644 hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/GrammarDescriptorFactory.java create mode 100644 hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/SplitGrammarDescriptor.java create mode 100644 hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/SplitGrammarGenerationTask.java diff --git a/hibernate-core/hibernate-core.gradle b/hibernate-core/hibernate-core.gradle index 7054e4e7b5..171dc288a8 100644 --- a/hibernate-core/hibernate-core.gradle +++ b/hibernate-core/hibernate-core.gradle @@ -195,10 +195,6 @@ xjc { } -//sourceSets.main.sourceGeneratorsTask.dependsOn xjc -//sourceSets.main.sourceGeneratorsTask.dependsOn antlr -tasks.compile.dependsOn antlr - task copyBundleResources (type: Copy) { ext { bundlesTargetDir = file( "${buildDir}/bundles" ) diff --git a/hibernate-orm-build/build.gradle b/hibernate-orm-build/build.gradle index fe7b4a0cc6..57fa7e155a 100644 --- a/hibernate-orm-build/build.gradle +++ b/hibernate-orm-build/build.gradle @@ -32,7 +32,7 @@ gradlePlugin { } antlrPlugin { id = 'org.hibernate.orm.antlr' - implementationClass = 'org.hibernate.orm.antlr.Antlr4Plugin' + implementationClass = 'org.hibernate.orm.antlr.AntlrPlugin' } jakartaPlugin { id = 'org.hibernate.orm.jakarta' diff --git a/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/Antlr4Plugin.java b/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/Antlr4Plugin.java deleted file mode 100644 index ffafd95e21..0000000000 --- a/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/Antlr4Plugin.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later - * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html - */ -package org.hibernate.orm.antlr; - -import org.gradle.api.Plugin; -import org.gradle.api.Project; -import org.gradle.api.Task; -import org.gradle.api.artifacts.Configuration; -import org.gradle.api.plugins.JavaPluginConvention; -import org.gradle.api.tasks.SourceSet; - -/** - * Custom Antlr v4 Plugin - * - * The Gradle-supplied Antlr plugin attempts to simultaneously support multiple - * versions of Antlr which leads to many difficulties. This custom plugin provides - * dedicated and simplified support for Antlr v4 - * - * @author Steve Ebersole - */ -public class Antlr4Plugin implements Plugin { - public static final String HQL_PKG = "org.hibernate.grammars.hql"; - public static final String IMPORT_SQL_PKG = "org.hibernate.grammars.importsql"; - public static final String GRAPH_PKG = "org.hibernate.grammars.graph"; - public static final String ORDER_PKG = "org.hibernate.grammars.ordering"; - public static final String ANTLR = "antlr"; - - public final GrammarDescriptor[] grammarDescriptors = new GrammarDescriptor[] { - new GrammarDescriptor( "HqlLexer", HQL_PKG ), - new GrammarDescriptor( "HqlParser", HQL_PKG ), - new GrammarDescriptor( "SqlScriptLexer", IMPORT_SQL_PKG ), - new GrammarDescriptor( "SqlScriptParser", IMPORT_SQL_PKG ), - new GrammarDescriptor( "GraphLanguageLexer", GRAPH_PKG ), - new GrammarDescriptor( "GraphLanguageParser", GRAPH_PKG ), - new GrammarDescriptor( "OrderingLexer", ORDER_PKG ), - new GrammarDescriptor( "OrderingParser", ORDER_PKG ) - }; - - @Override - public void apply(Project project) { - final Antlr4Spec antlr4Spec = project.getExtensions().create( - Antlr4Spec.REGISTRATION_NAME, - Antlr4Spec.class - ); - - final Configuration antlrDependencies = project.getConfigurations().maybeCreate( ANTLR ); - - final Task groupingTask = project.getTasks().create( ANTLR ); - groupingTask.setDescription( "Performs all defined Antlr grammar generations" ); - groupingTask.setGroup( ANTLR ); - - for ( GrammarDescriptor grammarDescriptor : grammarDescriptors ) { - final GeneratorTask generatorTask = project.getTasks().create( - "generate" + grammarDescriptor.getGrammarName() + "Grammar", - GeneratorTask.class, - grammarDescriptor, - antlr4Spec - ); - generatorTask.setDescription( "Performs Antlr grammar generation for `" + grammarDescriptor.getGrammarName() + "`" ); - generatorTask.setGroup( ANTLR ); - groupingTask.dependsOn( generatorTask ); - } - - final SourceSet mainSourceSet = project.getConvention() - .getPlugin( JavaPluginConvention.class ) - .getSourceSets() - .getByName( SourceSet.MAIN_SOURCE_SET_NAME ); - mainSourceSet.setCompileClasspath( mainSourceSet.getCompileClasspath().plus( antlrDependencies ) ); - mainSourceSet.getJava().srcDir( antlr4Spec.getOutputBaseDirectory() ); - - final Task compileTask = project.getTasks().getByName( mainSourceSet.getCompileJavaTaskName() ); - compileTask.dependsOn( groupingTask ); - -// SourceSet testSourceSet = project.convention.getPlugin( JavaPluginConvention ).sourceSets.getByName( SourceSet.TEST_SOURCE_SET_NAME ); -// testSourceSet.compileClasspath += configurations.antlr - } -} diff --git a/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/AntlrHelper.java b/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/AntlrHelper.java new file mode 100644 index 0000000000..02c054a8b2 --- /dev/null +++ b/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/AntlrHelper.java @@ -0,0 +1,79 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.orm.antlr; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +import org.gradle.api.Project; + +/** + * @author Steve Ebersole + */ +public class AntlrHelper { + private AntlrHelper() { + // disallow direct instantiation + } + + public static void stripSillyGeneratedFromLines(File outputDirectory, Project project) { + // https://github.com/antlr/antlr4/issues/2634 + // :shrug: + + final File[] generatedJavaFiles = outputDirectory.listFiles( (dir, name) -> name.endsWith( ".java" ) ); + if ( generatedJavaFiles == null ) { + // warn? + return; + } + + for ( int i = 0; i < generatedJavaFiles.length; i++ ) { + stripSillyGeneratedFromLineFromFile( generatedJavaFiles[i], project ); + } + + } + + private static void stripSillyGeneratedFromLineFromFile(File generatedJavaFile, Project project) { + try { + final File tmpFile = project.getLayout() + .getBuildDirectory() + .get() + .dir( "tmp" ) + .file( generatedJavaFile.getName() ) + .getAsFile(); + + tmpFile.getParentFile().mkdirs(); + tmpFile.createNewFile(); + + final BufferedReader reader = new BufferedReader( new FileReader( generatedJavaFile ) ); + final BufferedWriter writer = new BufferedWriter( new FileWriter( tmpFile ) ); + + boolean found = false; + String currentLine; + + while ( ( currentLine = reader.readLine() ) != null ) { + if ( ! found && currentLine.startsWith( "// Generated from" ) ) { + found = true; + continue; + } + writer.write( currentLine + System.lineSeparator() ); + } + + writer.close(); + reader.close(); + + generatedJavaFile.delete(); + tmpFile.renameTo( generatedJavaFile ); + } + catch (IOException e) { + project.getLogger().lifecycle( "Unable to remove the generated-from line added by Antlr to the generated file" ); + } + } + +} diff --git a/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/AntlrPlugin.java b/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/AntlrPlugin.java new file mode 100644 index 0000000000..4a24975a39 --- /dev/null +++ b/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/AntlrPlugin.java @@ -0,0 +1,99 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.orm.antlr; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.Task; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.plugins.JavaPluginConvention; +import org.gradle.api.tasks.SourceSet; + +/** + * Custom Antlr v4 Plugin + * + * The Gradle-supplied Antlr plugin attempts to simultaneously support multiple + * versions of Antlr which leads to many difficulties. This custom plugin provides + * dedicated and simplified support for Antlr v4 + * + * @author Steve Ebersole + */ +@SuppressWarnings("unused") +public class AntlrPlugin implements Plugin { + public static final String ANTLR = "antlr"; + + public static final String HQL_PKG = "org.hibernate.grammars.hql"; + public static final String SQL_PKG = "org.hibernate.grammars.importsql"; + public static final String GRAPH_PKG = "org.hibernate.grammars.graph"; + public static final String ORDER_PKG = "org.hibernate.grammars.ordering"; + + @Override + public void apply(Project project) { + final Task groupingTask = project.getTasks().create( "generateParsers" ); + groupingTask.setDescription( "Performs all defined Antlr grammar generations" ); + groupingTask.setGroup( ANTLR ); + + final AntlrSpec antlrSpec = project.getExtensions().create( + AntlrSpec.REGISTRATION_NAME, + AntlrSpec.class, + project, + groupingTask + ); + + final Configuration antlrDependencies = project.getConfigurations().maybeCreate( ANTLR ); + + final SourceSet mainSourceSet = project.getConvention() + .getPlugin( JavaPluginConvention.class ) + .getSourceSets() + .getByName( SourceSet.MAIN_SOURCE_SET_NAME ); + mainSourceSet.setCompileClasspath( mainSourceSet.getCompileClasspath().plus( antlrDependencies ) ); + mainSourceSet.getJava().srcDir( antlrSpec.getOutputBaseDirectory() ); + + final Task compileTask = project.getTasks().getByName( mainSourceSet.getCompileJavaTaskName() ); + compileTask.dependsOn( groupingTask ); + + populateGrammars( antlrSpec ); + } + + private void populateGrammars(AntlrSpec antlrSpec) { + antlrSpec.getGrammarDescriptors().create( + "hql", + (grammarDescriptor) -> { + grammarDescriptor.getPackageName().set( HQL_PKG ); + grammarDescriptor.getLexerFileName().set( "HqlLexer.g4" ); + grammarDescriptor.getParserFileName().set( "HqlParser.g4" ); + } + ); + + antlrSpec.getGrammarDescriptors().create( + "graph", + (grammarDescriptor) -> { + grammarDescriptor.getPackageName().set( GRAPH_PKG ); + grammarDescriptor.getLexerFileName().set( "GraphLanguageLexer.g4" ); + grammarDescriptor.getParserFileName().set( "GraphLanguageParser.g4" ); + } + ); + + antlrSpec.getGrammarDescriptors().create( + "sqlScript", + (grammarDescriptor) -> { + grammarDescriptor.getPackageName().set( SQL_PKG ); + grammarDescriptor.getLexerFileName().set( "SqlScriptLexer.g4" ); + grammarDescriptor.getParserFileName().set( "SqlScriptParser.g4" ); + } + ); + + antlrSpec.getGrammarDescriptors().create( + "ordering", + (grammarDescriptor) -> { + grammarDescriptor.getPackageName().set( ORDER_PKG ); + grammarDescriptor.getLexerFileName().set( "OrderingLexer.g4" ); + grammarDescriptor.getParserFileName().set( "OrderingParser.g4" ); + } + ); + } +} diff --git a/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/Antlr4Spec.java b/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/AntlrSpec.java similarity index 66% rename from hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/Antlr4Spec.java rename to hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/AntlrSpec.java index ce3ecf06df..1e34091af8 100644 --- a/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/Antlr4Spec.java +++ b/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/AntlrSpec.java @@ -6,7 +6,11 @@ */ package org.hibernate.orm.antlr; +import javax.inject.Inject; + import org.gradle.api.NamedDomainObjectContainer; +import org.gradle.api.Project; +import org.gradle.api.Task; import org.gradle.api.file.DirectoryProperty; import org.gradle.api.file.ProjectLayout; import org.gradle.api.model.ObjectFactory; @@ -14,23 +18,30 @@ import org.gradle.api.model.ObjectFactory; /** * @author Steve Ebersole */ -public class Antlr4Spec { +public class AntlrSpec { public static final String REGISTRATION_NAME = "antlr4"; private final DirectoryProperty grammarBaseDirectory; private final DirectoryProperty outputBaseDirectory; - private final NamedDomainObjectContainer grammarDescriptors; + private final NamedDomainObjectContainer grammarDescriptors; + @Inject @SuppressWarnings("UnstableApiUsage") - public Antlr4Spec(ObjectFactory objectFactory, ProjectLayout layout) { + public AntlrSpec(Project project, Task groupingTask) { + final ObjectFactory objectFactory = project.getObjects(); + final ProjectLayout layout = project.getLayout(); + grammarBaseDirectory = objectFactory.directoryProperty(); grammarBaseDirectory.convention( layout.getProjectDirectory().dir( "src/main/antlr" ) ); outputBaseDirectory = objectFactory.directoryProperty(); outputBaseDirectory.convention( layout.getBuildDirectory().dir( "generated/sources/antlr/main" ) ); - grammarDescriptors = objectFactory.domainObjectContainer( GrammarDescriptor.class ); + grammarDescriptors = objectFactory.domainObjectContainer( + SplitGrammarDescriptor.class, + new GrammarDescriptorFactory( this, groupingTask, project ) + ); } public DirectoryProperty getGrammarBaseDirectory() { @@ -41,7 +52,7 @@ public class Antlr4Spec { return outputBaseDirectory; } - public NamedDomainObjectContainer getGrammarDescriptors() { + public NamedDomainObjectContainer getGrammarDescriptors() { return grammarDescriptors; } } diff --git a/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/GeneratorTask.java b/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/GeneratorTask.java deleted file mode 100644 index 2ab50e96c4..0000000000 --- a/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/GeneratorTask.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later - * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html - */ -package org.hibernate.orm.antlr; - -import java.io.File; - -import javax.inject.Inject; - -import org.gradle.api.DefaultTask; -import org.gradle.api.file.Directory; -import org.gradle.api.file.RegularFile; -import org.gradle.api.provider.Provider; -import org.gradle.api.tasks.CacheableTask; -import org.gradle.api.tasks.InputFile; -import org.gradle.api.tasks.OutputDirectory; -import org.gradle.api.tasks.PathSensitive; -import org.gradle.api.tasks.PathSensitivity; -import org.gradle.api.tasks.TaskAction; - -/** - * @author Steve Ebersole - */ -@CacheableTask -public abstract class GeneratorTask extends DefaultTask { - private final Provider grammarFile; - private final Provider outputDirectory; - - @Inject - public GeneratorTask(GrammarDescriptor grammarDescriptor, Antlr4Spec antlrSpec) { - final String relativePackagePath = grammarDescriptor.getPackageName().replace( '.', '/' ); - - grammarFile = antlrSpec.getGrammarBaseDirectory().file( relativePackagePath + "/" + grammarDescriptor.getGrammarName() + ".g4" ); - outputDirectory = antlrSpec.getOutputBaseDirectory().dir( relativePackagePath ); - } - - @InputFile - @PathSensitive( PathSensitivity.RELATIVE ) - public Provider getGrammarFile() { - return grammarFile; - } - - @OutputDirectory - public Provider getOutputDirectory() { - return outputDirectory; - } - - @TaskAction - public void generate() { - final File grammarFileAsFile = grammarFile.get().getAsFile(); - final File outputDirectoryAsFile = outputDirectory.get().getAsFile(); - - getProject().getLogger().info( - "Starting Antlr grammar generation `{}` -> `{}`", - grammarFileAsFile.getName(), - outputDirectoryAsFile.getAbsolutePath() - ); - - outputDirectoryAsFile.mkdirs(); - - getProject().javaexec( - (javaExecSpec) -> { - javaExecSpec.setMain( "org.antlr.v4.Tool" ); - javaExecSpec.classpath( getProject().getConfigurations().getByName( "antlr" ) ); - javaExecSpec.args( - "-o", outputDirectoryAsFile.getAbsolutePath(), - "-long-messages", - "-listener", - "-visitor", - grammarFileAsFile.getAbsolutePath() - ); - } - ); - } -} diff --git a/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/GrammarDescriptor.java b/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/GrammarDescriptor.java deleted file mode 100644 index 612b378047..0000000000 --- a/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/GrammarDescriptor.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later - * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html - */ -package org.hibernate.orm.antlr; - -import org.gradle.api.Named; - -/** - * Describes a grammar for generation - * - * @author Steve Ebersole - */ -public class GrammarDescriptor implements Named { - private final String grammarName; - private final String packageName; - - GrammarDescriptor(String grammarName, String packageName) { - this.grammarName = grammarName; - this.packageName = packageName; - } - - @Override - public String getName() { - return getGrammarName(); - } - - public String getPackageName() { - return packageName; - } - - public String getGrammarName() { - return grammarName; - } -} diff --git a/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/GrammarDescriptorFactory.java b/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/GrammarDescriptorFactory.java new file mode 100644 index 0000000000..2598d6a9df --- /dev/null +++ b/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/GrammarDescriptorFactory.java @@ -0,0 +1,48 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.orm.antlr; + +import org.gradle.api.NamedDomainObjectFactory; +import org.gradle.api.Project; +import org.gradle.api.Task; + +/** + * @author Steve Ebersole + */ +public class GrammarDescriptorFactory implements NamedDomainObjectFactory { + private final AntlrSpec antlrSpec; + private final Task groupingTask; + private final Project project; + + public GrammarDescriptorFactory(AntlrSpec antlrSpec, Task groupingTask, Project project) { + this.antlrSpec = antlrSpec; + this.groupingTask = groupingTask; + this.project = project; + } + + @Override + public SplitGrammarDescriptor create(String name) { + final SplitGrammarDescriptor descriptor = new SplitGrammarDescriptor( name, antlrSpec, project.getObjects() ); + + final SplitGrammarGenerationTask generatorTask = project.getTasks().create( + determineTaskName( name ), + SplitGrammarGenerationTask.class, + descriptor, + antlrSpec + ); + generatorTask.setDescription( "Performs Antlr grammar generation for the `" + name + "` grammar" ); + generatorTask.setGroup( "antlr" ); + groupingTask.dependsOn( generatorTask ); + + return descriptor; + } + + private String determineTaskName(String grammarName) { + final String titularGrammarName = Character.toTitleCase( grammarName.charAt(0) ) + grammarName.substring(1); + return "generate" + titularGrammarName + "Parser"; + } +} diff --git a/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/SplitGrammarDescriptor.java b/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/SplitGrammarDescriptor.java new file mode 100644 index 0000000000..a9e78bb706 --- /dev/null +++ b/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/SplitGrammarDescriptor.java @@ -0,0 +1,77 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.orm.antlr; + +import javax.inject.Inject; + +import org.gradle.api.Named; +import org.gradle.api.model.ObjectFactory; +import org.gradle.api.provider.Property; + +/** + * @author Steve Ebersole + */ +public class SplitGrammarDescriptor implements Named { + private final String name; + private final AntlrSpec antlrSpec; + + private final Property packageName; + private final Property lexerFileName; + private final Property parserFileName; + + private final Property generateVisitor; + private final Property generateListener; + + @Inject + public SplitGrammarDescriptor(String name, AntlrSpec antlrSpec, ObjectFactory objectFactory) { + this.name = name; + this.antlrSpec = antlrSpec; + + packageName = objectFactory.property( String.class ); + lexerFileName = objectFactory.property( String.class ); + parserFileName = objectFactory.property( String.class ); + + generateVisitor = objectFactory.property( Boolean.class ); + generateVisitor.convention( true ); + + generateListener = objectFactory.property( Boolean.class ); + generateListener.convention( true ); + } + + @Override + public String getName() { + return name; + } + + public Property getPackageName() { + return packageName; + } + + public Property getLexerFileName() { + return lexerFileName; + } + + public Property getParserFileName() { + return parserFileName; + } + + public Property getGenerateVisitor() { + return generateVisitor; + } + + public Property getGenerateListener() { + return generateListener; + } + + public Property generateVisitor() { + return generateListener; + } + + public Property generateListener() { + return generateListener; + } +} diff --git a/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/SplitGrammarGenerationTask.java b/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/SplitGrammarGenerationTask.java new file mode 100644 index 0000000000..494d64aeaf --- /dev/null +++ b/hibernate-orm-build/src/main/java/org/hibernate/orm/antlr/SplitGrammarGenerationTask.java @@ -0,0 +1,140 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.orm.antlr; + +import java.io.File; + +import javax.inject.Inject; + +import org.gradle.api.DefaultTask; +import org.gradle.api.file.Directory; +import org.gradle.api.file.RegularFile; +import org.gradle.api.provider.Provider; +import org.gradle.api.tasks.InputFile; +import org.gradle.api.tasks.OutputDirectory; +import org.gradle.api.tasks.PathSensitive; +import org.gradle.api.tasks.PathSensitivity; +import org.gradle.api.tasks.TaskAction; + +import static org.hibernate.orm.antlr.AntlrHelper.stripSillyGeneratedFromLines; + +/** + * @author Steve Ebersole + */ +public abstract class SplitGrammarGenerationTask extends DefaultTask { + private final SplitGrammarDescriptor grammarDescriptor; + + private final Provider lexerGrammarFile; + private final Provider parserGrammarFile; + private final Provider outputDirectory; + + @Inject + public SplitGrammarGenerationTask(SplitGrammarDescriptor grammarDescriptor, AntlrSpec antlrSpec) { + this.grammarDescriptor = grammarDescriptor; + + lexerGrammarFile = getProject().provider( () -> { + final Directory grammarBaseDirectory = antlrSpec.getGrammarBaseDirectory().get(); + final Directory grammarDirectory = grammarBaseDirectory.dir( grammarDescriptor.getPackageName().get().replace( '.', '/' ) ); + return grammarDirectory.file( grammarDescriptor.getLexerFileName().get() ); + } ); + + parserGrammarFile = getProject().provider( () -> { + final Directory grammarBaseDirectory = antlrSpec.getGrammarBaseDirectory().get(); + final Directory grammarDirectory = grammarBaseDirectory.dir( grammarDescriptor.getPackageName().get().replace( '.', '/' ) ); + return grammarDirectory.file( grammarDescriptor.getParserFileName().get() ); + } ); + + outputDirectory = getProject().provider( () -> { + final Directory outputBaseDirectory = antlrSpec.getOutputBaseDirectory().get(); + return outputBaseDirectory.dir( grammarDescriptor.getPackageName().get().replace( '.', '/' ) ); + } ); + } + + @InputFile + @PathSensitive( PathSensitivity.RELATIVE ) + public Provider getLexerGrammarFile() { + return lexerGrammarFile; + } + + @InputFile + @PathSensitive( PathSensitivity.RELATIVE ) + public Provider getParserGrammarFile() { + return parserGrammarFile; + } + + @OutputDirectory + public Provider getOutputDirectory() { + return outputDirectory; + } + + @TaskAction + public void generateLexerAndParser() { + final File outputDir = outputDirectory.get().getAsFile(); + outputDir.mkdirs(); + + generateLexer( outputDir ); + generateParser( outputDir ); + + stripSillyGeneratedFromLines( outputDir, getProject() ); + } + + + private void generateLexer(File outputDir) { + final File lexerFile = getLexerGrammarFile().get().getAsFile(); + + getProject().getLogger().info( + "Starting Antlr lexer grammar generation `{}` : `{}` -> `{}`", + grammarDescriptor.getName(), + lexerFile.getAbsolutePath(), + outputDir.getAbsolutePath() + ); + + + getProject().javaexec( + (javaExecSpec) -> { + javaExecSpec.setMain( "org.antlr.v4.Tool" ); + javaExecSpec.classpath( getProject().getConfigurations().getByName( "antlr" ) ); + javaExecSpec.args( + "-o", getProject().relativePath( outputDir.getAbsolutePath() ), + "-long-messages", + lexerFile.getAbsolutePath() + ); + } + ); + } + + private void generateParser(File outputDir) { + final File parserFile = getParserGrammarFile().get().getAsFile(); + + getProject().getLogger().info( + "Starting Antlr parser grammar generation `{}` : `{}` -> `{}`", + grammarDescriptor.getName(), + parserFile.getAbsolutePath(), + outputDir.getAbsolutePath() + ); + + + getProject().javaexec( + (javaExecSpec) -> { + javaExecSpec.setMain( "org.antlr.v4.Tool" ); + javaExecSpec.classpath( getProject().getConfigurations().getByName( "antlr" ) ); + javaExecSpec.args( + "-o", getProject().relativePath( outputDir.getAbsolutePath() ), + "-long-messages", + parserFile.getAbsolutePath() + ); + + if ( grammarDescriptor.generateListener().get() ) { + javaExecSpec.args( "-listener" ); + } + if ( grammarDescriptor.generateVisitor().get() ) { + javaExecSpec.args( "-visitor" ); + } + } + ); + } +}