Refactored GroowtAntlrPlugin to be much simpler.
This commit is contained in:
parent
b66ecd89b7
commit
f573f1cec4
@ -1,5 +0,0 @@
|
||||
package groowt.gradle.antlr;
|
||||
|
||||
import org.gradle.api.plugins.antlr.AntlrTask;
|
||||
|
||||
public class GroowtAntlrAllTask extends AntlrTask {}
|
@ -0,0 +1,95 @@
|
||||
package groowt.gradle.antlr;
|
||||
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.file.DirectoryProperty;
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.model.ObjectFactory;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputFile;
|
||||
import org.gradle.api.tasks.OutputDirectory;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.gradle.api.tasks.options.Option;
|
||||
import org.gradle.process.ExecOperations;
|
||||
import org.gradle.process.ExecResult;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.File;
|
||||
|
||||
public class GroowtAntlrExecTask extends DefaultTask {
|
||||
|
||||
private final ExecOperations execOperations;
|
||||
private final Provider<Configuration> configurationProvider;
|
||||
private final RegularFileProperty antlrSourceFile;
|
||||
private final DirectoryProperty outputDirectory;
|
||||
private final Property<String> packageName;
|
||||
private final Property<Boolean> visitor;
|
||||
|
||||
@Inject
|
||||
public GroowtAntlrExecTask(
|
||||
ObjectFactory objectFactory,
|
||||
ExecOperations execOperations,
|
||||
Provider<Configuration> configurationProvider
|
||||
) {
|
||||
this.execOperations = execOperations;
|
||||
this.configurationProvider = configurationProvider;
|
||||
this.antlrSourceFile = objectFactory.fileProperty();
|
||||
this.outputDirectory = objectFactory.directoryProperty();
|
||||
this.packageName = objectFactory.property(String.class);
|
||||
this.visitor = objectFactory.property(Boolean.class);
|
||||
this.visitor.convention(false);
|
||||
}
|
||||
|
||||
@InputFile
|
||||
public RegularFileProperty getAntlrSourceFile() {
|
||||
return this.antlrSourceFile;
|
||||
}
|
||||
|
||||
@OutputDirectory
|
||||
public DirectoryProperty getOutputDirectory() {
|
||||
return this.outputDirectory;
|
||||
}
|
||||
|
||||
@Option(option = "packageName", description = "The packageName argument for Antlr.")
|
||||
@Input
|
||||
public Property<String> getPackageName() {
|
||||
return this.packageName;
|
||||
}
|
||||
|
||||
@Option(option = "visitor", description = "Whether Antlr should generate visitor classes or not.")
|
||||
@Input
|
||||
public Property<Boolean> getVisitor() {
|
||||
return this.visitor;
|
||||
}
|
||||
|
||||
public File resolveOutputFile(String name) {
|
||||
return new File(this.outputDirectory.get().getAsFile(), name);
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
public void doGenerate() {
|
||||
final Configuration antlrConfiguration = configurationProvider.get();
|
||||
|
||||
final ExecResult result = this.execOperations.javaexec(javaExecSpec -> {
|
||||
javaExecSpec.classpath(antlrConfiguration);
|
||||
javaExecSpec.getMainClass().set("org.antlr.v4.Tool");
|
||||
|
||||
final String visitorArg = this.visitor.map(isVisitor -> isVisitor ? "-visitor" : "").get();
|
||||
if (!visitorArg.isEmpty()) {
|
||||
javaExecSpec.args(visitorArg);
|
||||
}
|
||||
final String packageNameArg = this.packageName.getOrElse("");
|
||||
if (!packageNameArg.isEmpty()) {
|
||||
javaExecSpec.args("-package", packageNameArg);
|
||||
}
|
||||
javaExecSpec.args("-o", this.outputDirectory.get().getAsFile().toString());
|
||||
|
||||
javaExecSpec.args(this.antlrSourceFile.getAsFile().get().toString());
|
||||
});
|
||||
|
||||
result.assertNormalExitValue();
|
||||
}
|
||||
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package groowt.gradle.antlr;
|
||||
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.model.ObjectFactory;
|
||||
import org.gradle.api.provider.Property;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public abstract class GroowtAntlrExtension {
|
||||
|
||||
private final SourceSpecContainer sourceSpecs;
|
||||
|
||||
@Inject
|
||||
public GroowtAntlrExtension(ObjectFactory objectFactory) {
|
||||
this.sourceSpecs = objectFactory.newInstance(SourceSpecContainer.class, (Action<SourceSpec>) sourceSpec -> {
|
||||
sourceSpec.getPackageName().convention(this.getPackageName());
|
||||
sourceSpec.getVisitor().convention(this.getVisitor());
|
||||
sourceSpec.getIsCompileDependency().convention(true);
|
||||
sourceSpec.getDebug().convention(false);
|
||||
});
|
||||
}
|
||||
|
||||
public abstract Property<String> getPackageName();
|
||||
public abstract Property<Boolean> getVisitor();
|
||||
|
||||
public SourceSpecContainer getSourceSpecs() {
|
||||
return this.sourceSpecs;
|
||||
}
|
||||
|
||||
public void sourceSpecs(Action<SourceSpecContainer> configure) {
|
||||
configure.execute(this.getSourceSpecs());
|
||||
}
|
||||
|
||||
}
|
@ -1,216 +1,76 @@
|
||||
package groowt.gradle.antlr;
|
||||
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.file.FileTree;
|
||||
import org.gradle.api.model.ObjectFactory;
|
||||
import org.gradle.api.plugins.JavaPluginExtension;
|
||||
import org.gradle.api.plugins.antlr.AntlrPlugin;
|
||||
import org.gradle.api.plugins.antlr.AntlrSourceDirectorySet;
|
||||
import org.gradle.api.plugins.antlr.AntlrTask;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.gradle.api.tasks.TaskContainer;
|
||||
import org.gradle.api.tasks.compile.JavaCompile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static groowt.gradle.antlr.GroowtAntlrUtil.*;
|
||||
|
||||
public final class GroowtAntlrPlugin implements Plugin<Project> {
|
||||
|
||||
public static final String taskGroup = "groowtAntlr";
|
||||
public static final String GROOWT_ANTLR = "groowtAntlr";
|
||||
|
||||
private static final String packageArg = "-package";
|
||||
private static final String traceArg = "-trace";
|
||||
private static final String visitorArg = "-visitor";
|
||||
@Override
|
||||
public void apply(Project project) {
|
||||
// register configuration
|
||||
final var configurationProvider = project.getConfigurations().register(GROOWT_ANTLR, configuration -> {
|
||||
configuration.setCanBeConsumed(false);
|
||||
configuration.setCanBeResolved(true);
|
||||
});
|
||||
|
||||
private final ObjectFactory objectFactory;
|
||||
// register extension
|
||||
final var extension = project.getExtensions().create(GROOWT_ANTLR, GroowtAntlrSimpleExtension.class);
|
||||
|
||||
@Inject
|
||||
public GroowtAntlrPlugin(ObjectFactory objectFactory) {
|
||||
this.objectFactory = objectFactory;
|
||||
}
|
||||
|
||||
private static NullableProviderList<String> getArguments(SourceSpec sourceSpec) {
|
||||
final NullableProviderList<String> arguments = new NullableProviderList<>();
|
||||
arguments.addCollectionProvider(sourceSpec.getPackageName().map(packageName -> List.of(packageArg, packageName)));
|
||||
arguments.addProvider(sourceSpec.getVisitor().map(isVisitor -> isVisitor ? visitorArg : null));
|
||||
arguments.addProvider(sourceSpec.getDebug().map(isDebug -> isDebug ? traceArg : null));
|
||||
return arguments;
|
||||
}
|
||||
|
||||
// For afterEvaluate!
|
||||
private static List<GroowtAntlrTask> createAndRegister(Project project, GroowtAntlrExtension extension) {
|
||||
final TaskContainer taskContainer = project.getTasks();
|
||||
return extension.getSourceSpecs().stream().map(sourceSpec -> {
|
||||
return taskContainer.create(
|
||||
getGenerateTaskName(sourceSpec),
|
||||
GroowtAntlrTask.class,
|
||||
sourceSpec,
|
||||
(Action<GroowtAntlrTask>) task -> {
|
||||
task.setGroup(taskGroup);
|
||||
task.setArguments(getArguments(sourceSpec));
|
||||
task.setSource(sourceSpec.getResolvedSource().getSourceFile());
|
||||
task.setOutputDirectory(
|
||||
getOutputDirectory(
|
||||
project,
|
||||
sourceSpec.getResolvedSource().getSourceSet(),
|
||||
sourceSpec.getPackageName()
|
||||
)
|
||||
);
|
||||
}
|
||||
// register tasks for each source file
|
||||
project.getExtensions().getByType(JavaPluginExtension.class).getSourceSets().forEach(sourceSet -> {
|
||||
// register sourceDirectorySet
|
||||
final var antlrSourceDirectorySet = project.getObjects().sourceDirectorySet(GROOWT_ANTLR, GROOWT_ANTLR);
|
||||
antlrSourceDirectorySet.srcDir(
|
||||
String.join(File.separator, "src", sourceSet.getName(), "antlr")
|
||||
);
|
||||
}).toList();
|
||||
}
|
||||
sourceSet.getAllSource().source(antlrSourceDirectorySet);
|
||||
|
||||
// For afterEvaluate!
|
||||
private static void addCompileDependencies(Project project, List<GroowtAntlrTask> tasks) {
|
||||
tasks.forEach(task -> {
|
||||
// if it is a compile dependency, add it as input to java source set
|
||||
final var isCompileDependency = task.getSourceSpec().getIsCompileDependency().get();
|
||||
if (isCompileDependency) {
|
||||
project.getTasks().withType(JavaCompile.class).configureEach(javaCompile -> {
|
||||
javaCompile.dependsOn(task);
|
||||
final var baseOutputDir = project.getLayout().getBuildDirectory().dir(String.join(
|
||||
File.separator,
|
||||
"generated-src",
|
||||
"antlr",
|
||||
sourceSet.getName()
|
||||
));
|
||||
|
||||
sourceSet.getJava().srcDir(baseOutputDir);
|
||||
|
||||
final var sourceSetTasks = antlrSourceDirectorySet.getFiles().stream()
|
||||
.filter(GroowtAntlrUtil::isAntlrFile)
|
||||
.map(file -> {
|
||||
final var taskProvider = project.getTasks().register(
|
||||
GroowtAntlrUtil.getGenerateTaskName(sourceSet, file),
|
||||
GroowtAntlrExecTask.class,
|
||||
configurationProvider
|
||||
);
|
||||
taskProvider.configure(task -> {
|
||||
task.setGroup(GROOWT_ANTLR);
|
||||
task.getAntlrSourceFile().set(file);
|
||||
task.getOutputDirectory().convention(
|
||||
baseOutputDir.flatMap(base -> base.dir(
|
||||
task.getPackageName().map(packageName ->
|
||||
packageName.replace(".", File.separator)
|
||||
)
|
||||
))
|
||||
);
|
||||
task.getVisitor().convention(extension.getVisitor());
|
||||
task.getPackageName().convention(extension.getPackageName());
|
||||
});
|
||||
return taskProvider;
|
||||
})
|
||||
.toList();
|
||||
|
||||
if (!sourceSetTasks.isEmpty()) {
|
||||
project.getTasks().register(sourceSet.getTaskName("generate", "AllAntlr"), task -> {
|
||||
task.dependsOn(sourceSetTasks);
|
||||
task.setGroup(GROOWT_ANTLR);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private record GenerateAllSpec(
|
||||
@Nullable FileTree source,
|
||||
@NotNull List<String> args,
|
||||
@NotNull Provider<String> packageName
|
||||
) {}
|
||||
|
||||
private GenerateAllSpec getBlankGenerateAllSpec() {
|
||||
return new GenerateAllSpec(null, List.of(), this.objectFactory.property(String.class));
|
||||
}
|
||||
|
||||
private static GenerateAllSpec getGenerateAllSpecFromTask(GroowtAntlrTask task) {
|
||||
return new GenerateAllSpec(task.getSource(), task.getArguments(), task.getSourceSpec().getPackageName());
|
||||
}
|
||||
|
||||
private static @Nullable FileTree combineFileTrees(@Nullable FileTree f0, @Nullable FileTree f1) {
|
||||
if (f0 != null && f1 != null) {
|
||||
return f0.plus(f1);
|
||||
} else if (f0 != null) {
|
||||
return f0;
|
||||
} else {
|
||||
return f1; // null
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> combineArguments(List<String> a0, List<String> a1) {
|
||||
final List<String> result = new ArrayList<>(a0);
|
||||
final Iterator<String> a1Iter = a1.iterator();
|
||||
while (a1Iter.hasNext()) {
|
||||
final String arg = a1Iter.next();
|
||||
if (arg.equals(packageArg) && result.contains(packageArg)) {
|
||||
if (!a1Iter.hasNext()) {
|
||||
throw new IllegalStateException("shouldn't get here");
|
||||
}
|
||||
final String a0PackageName = result.get(result.indexOf(arg) + 1);
|
||||
final String a1PackageName = a1Iter.next();
|
||||
if (!a0PackageName.equals(a1PackageName)) {
|
||||
throw new IllegalArgumentException("Cannot have separate package arguments for two files from the same source set.");
|
||||
}
|
||||
} else if (!result.contains(arg)) {
|
||||
result.add(arg);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Provider<String> combinePackageNames(Provider<String> p0, Provider<String> p1) {
|
||||
return p0.zip(p1, (pn0, pn1) -> {
|
||||
if (!pn0.equals(pn1)) {
|
||||
throw new IllegalArgumentException("Cannot have separate package names for two files from the same source set.");
|
||||
}
|
||||
return pn0;
|
||||
});
|
||||
}
|
||||
|
||||
private static GenerateAllSpec combineGenerateAllSpecs(GenerateAllSpec s0, GenerateAllSpec s1) {
|
||||
return new GenerateAllSpec(
|
||||
combineFileTrees(s0.source(), s1.source()),
|
||||
combineArguments(s0.args(), s1.args()),
|
||||
combinePackageNames(s0.packageName(), s1.packageName())
|
||||
);
|
||||
}
|
||||
|
||||
// For afterEvaluate!
|
||||
private static void addGenerateAllTasks(Project project, List<GroowtAntlrTask> tasks) {
|
||||
final Map<SourceSet, List<GroowtAntlrTask>> sourceSetToTasks = tasks.stream().collect(Collectors.groupingBy(
|
||||
task -> task.getSourceSpec().getResolvedSource().getSourceSet()
|
||||
));
|
||||
|
||||
final Map<SourceSet, GenerateAllSpec> sourceSetToSpec = new HashMap<>();
|
||||
sourceSetToTasks.forEach((sourceSet, sourceSetTasks) -> {
|
||||
List<GenerateAllSpec> specs = sourceSetTasks.stream().map(task ->
|
||||
new GenerateAllSpec(task.getSource(), task.getArguments(), task.getSourceSpec().getPackageName())
|
||||
).toList();
|
||||
specs.stream().reduce(GroowtAntlrPlugin::combineGenerateAllSpecs).ifPresent(allSpec -> {
|
||||
sourceSetToSpec.put(sourceSet, allSpec);
|
||||
});
|
||||
});
|
||||
|
||||
sourceSetToSpec.forEach((sourceSet, spec) -> {
|
||||
project.getTasks().register(
|
||||
getGenerateAllTaskName(sourceSet),
|
||||
GroowtAntlrAllTask.class,
|
||||
task -> {
|
||||
task.setGroup(taskGroup);
|
||||
if (spec.source() != null) {
|
||||
task.setSource(spec.source());
|
||||
}
|
||||
task.setArguments(spec.args());
|
||||
task.setOutputDirectory(
|
||||
getOutputDirectory(project, sourceSet, spec.packageName()).get().getAsFile()
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Project project) {
|
||||
project.getPluginManager().apply(AntlrPlugin.class);
|
||||
|
||||
// undo the antlr plugin creating its own tasks
|
||||
project.getTasks().withType(AntlrTask.class, antlrTask -> {
|
||||
if (!(antlrTask instanceof GroowtAntlrTask || antlrTask instanceof GroowtAntlrAllTask)) {
|
||||
antlrTask.setEnabled(false);
|
||||
}
|
||||
});
|
||||
|
||||
// create extension
|
||||
final GroowtAntlrExtension extension = project.getExtensions().create("groowtAntlr", GroowtAntlrExtension.class);
|
||||
extension.getPackageName().convention("");
|
||||
extension.getVisitor().convention(false);
|
||||
|
||||
// find all antlr files first and add them to extension
|
||||
project.getExtensions().getByType(JavaPluginExtension.class).getSourceSets().forEach(sourceSet -> {
|
||||
final Set<File> antlrFiles = sourceSet.getExtensions().getByType(AntlrSourceDirectorySet.class).getFiles();
|
||||
for (final File antlrFile : antlrFiles) {
|
||||
if (isAntlrSourceFile(antlrFile)) {
|
||||
extension.getSourceSpecs().register(sourceSet, antlrFile);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// after evaluate, generate tasks for each registered sourceSpec
|
||||
project.afterEvaluate(postEvaluateProject -> {
|
||||
final List<GroowtAntlrTask> tasks = createAndRegister(postEvaluateProject, extension);
|
||||
addCompileDependencies(project, tasks);
|
||||
addGenerateAllTasks(project, tasks);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
package groowt.gradle.antlr;
|
||||
|
||||
import org.gradle.api.provider.Property;
|
||||
|
||||
public interface GroowtAntlrSimpleExtension {
|
||||
Property<String> getPackageName();
|
||||
Property<Boolean> getVisitor();
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
package groowt.gradle.antlr;
|
||||
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.file.Directory;
|
||||
import org.gradle.api.file.DirectoryProperty;
|
||||
import org.gradle.api.model.ObjectFactory;
|
||||
import org.gradle.api.plugins.antlr.AntlrTask;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Internal;
|
||||
import org.gradle.api.tasks.Nested;
|
||||
import org.gradle.api.tasks.OutputDirectory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
public class GroowtAntlrTask extends AntlrTask {
|
||||
|
||||
private final ObjectFactory objectFactory;
|
||||
private final SourceSpec sourceSpec;
|
||||
|
||||
private Provider<Directory> outputDirectory;
|
||||
private NullableProviderList<String> arguments;
|
||||
|
||||
@Inject
|
||||
public GroowtAntlrTask(ObjectFactory objectFactory, SourceSpec sourceSpec, Action<? super GroowtAntlrTask> configure) {
|
||||
this.objectFactory = objectFactory;
|
||||
this.sourceSpec = sourceSpec;
|
||||
configure.execute(this);
|
||||
}
|
||||
|
||||
@Nested
|
||||
public SourceSpec getSourceSpec() {
|
||||
return this.sourceSpec;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull File getOutputDirectory() {
|
||||
return this.outputDirectory.get().getAsFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOutputDirectory(@NotNull File outputDirectory) {
|
||||
final DirectoryProperty directoryProperty = this.objectFactory.directoryProperty();
|
||||
directoryProperty.set(outputDirectory);
|
||||
this.outputDirectory = directoryProperty;
|
||||
}
|
||||
|
||||
public void setOutputDirectory(Provider<Directory> outputDirectoryProvider) {
|
||||
this.outputDirectory = outputDirectoryProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Internal
|
||||
public @NotNull List<String> getArguments() {
|
||||
return this.arguments.getElements();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setArguments(@NotNull List<String> arguments) {
|
||||
this.arguments = new NullableProviderList<>();
|
||||
this.arguments.addAllElements(arguments);
|
||||
}
|
||||
|
||||
public void setArguments(@NotNull NullableProviderList<String> arguments) {
|
||||
this.arguments = arguments;
|
||||
}
|
||||
|
||||
}
|
@ -1,147 +1,35 @@
|
||||
package groowt.gradle.antlr;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.file.Directory;
|
||||
import org.gradle.api.file.SourceDirectorySet;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public final class GroowtAntlrUtil {
|
||||
|
||||
public static final List<String> antlrFileExtensions = List.of("g4", "g");
|
||||
public static final List<String> antlrExtensions = List.of("g4", "g");
|
||||
|
||||
private static final Pattern extensionPattern = Pattern.compile("(?<name>.*)\\.(?<ext>.*)$");
|
||||
private static final Pattern nameAndExtension = Pattern.compile("(?<name>.*)\\.(?<ext>.*)$");
|
||||
|
||||
public static File resolve(File from, File to) {
|
||||
return from.toPath().resolve(to.toPath()).toFile();
|
||||
}
|
||||
|
||||
public static File relativize(File from, File to) {
|
||||
return from.toPath().relativize(to.toPath()).toFile();
|
||||
}
|
||||
|
||||
public static boolean isAntlrSourceFile(File file) {
|
||||
final var m = extensionPattern.matcher(file.getName());
|
||||
if (m.matches()) {
|
||||
return antlrFileExtensions.contains(m.group("ext"));
|
||||
} else {
|
||||
throw new IllegalArgumentException("Cannot determine extension of file: " + file);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> sourceFileToIdentifierParts(File sourceDir, File sourceFile) {
|
||||
final var relative = getRelativePathToSourceFile(sourceDir, sourceFile);
|
||||
final List<String> result = new ArrayList<>();
|
||||
for (int i = 0; i < relative.getNameCount(); i++) {
|
||||
final var name = relative.getName(i);
|
||||
final var m = extensionPattern.matcher(name.toString());
|
||||
if (m.matches()) {
|
||||
result.add(m.group("name"));
|
||||
} else {
|
||||
result.add(name.toString());
|
||||
public static boolean isAntlrFile(File file) {
|
||||
for (final var antlrExtension : antlrExtensions) {
|
||||
if (file.getName().endsWith(antlrExtension)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Path getRelativePathToSourceFile(File sourceDir, File sourceFile) {
|
||||
if (!sourceDir.isAbsolute()) {
|
||||
throw new IllegalArgumentException("sourceDir must be absolute, given: " + sourceDir);
|
||||
}
|
||||
if (sourceFile.isAbsolute()) {
|
||||
final var sourceDirPath = sourceDir.toPath();
|
||||
final var sourceFilePath = sourceFile.toPath();
|
||||
return sourceDirPath.relativize(sourceFilePath);
|
||||
public static String getGenerateTaskName(SourceSet sourceSet, File sourceFile) {
|
||||
final var matcher = nameAndExtension.matcher(sourceFile.getName());
|
||||
if (matcher.matches()) {
|
||||
return sourceSet.getTaskName("generate", matcher.group("name"));
|
||||
} else {
|
||||
return sourceFile.toPath();
|
||||
throw new IllegalArgumentException("Cannot determine source name for " + sourceFile);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getSourceIdentifier(ResolvedSource resolvedSource) {
|
||||
final List<String> parts = new ArrayList<>();
|
||||
if (!resolvedSource.getSourceSet().getName().equals("main")) {
|
||||
parts.add(resolvedSource.getSourceSet().getName());
|
||||
}
|
||||
parts.addAll(sourceFileToIdentifierParts(resolvedSource.getSourceDir(), resolvedSource.getSourceFile()));
|
||||
final List<String> capitalizedParts = parts.stream()
|
||||
.map(part -> {
|
||||
final var first = part.substring(0, 1);
|
||||
final var rest = part.substring(1);
|
||||
return first.toUpperCase() + rest;
|
||||
})
|
||||
.toList();
|
||||
return String.join("", capitalizedParts);
|
||||
}
|
||||
|
||||
public static Provider<Directory> getOutputDirectory(
|
||||
Project project,
|
||||
SourceSet sourceSet,
|
||||
Provider<String> packageNameProvider
|
||||
) {
|
||||
return project.getLayout().getBuildDirectory().flatMap(buildDir -> {
|
||||
return buildDir.dir(packageNameProvider.map(packageName -> {
|
||||
return String.join(File.separator, List.of(
|
||||
"generated-src",
|
||||
"antlr",
|
||||
sourceSet.getName(),
|
||||
packageName.replace(".", File.separator)
|
||||
));
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
public static String getGenerateTaskName(SourceSpec sourceSpec) {
|
||||
return sourceSpec.getResolvedSource().getSourceSet().getTaskName("generate", sourceSpec.getIdentifier());
|
||||
}
|
||||
|
||||
public static String getGenerateAllTaskName(SourceSet sourceSet) {
|
||||
return sourceSet.getTaskName("generate", "AllAntlr");
|
||||
}
|
||||
|
||||
public static ResolvedSource resolveSource(
|
||||
Project project,
|
||||
SourceSet sourceSet,
|
||||
SourceDirectorySet sourceDirectorySet,
|
||||
File sourceFile
|
||||
) {
|
||||
if (!isAntlrSourceFile(sourceFile)) {
|
||||
throw new IllegalArgumentException(
|
||||
"The given source file " + sourceFile + " is not a recognized antlr file (bad extension)."
|
||||
);
|
||||
}
|
||||
|
||||
final List<File> potentialSrcDirs = new ArrayList<>();
|
||||
|
||||
if (sourceFile.isAbsolute()) {
|
||||
for (final File srcDir : sourceDirectorySet.getSrcDirs()) {
|
||||
if (sourceFile.getPath().startsWith(srcDir.getPath())) {
|
||||
potentialSrcDirs.add(srcDir);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (final File srcDir : sourceDirectorySet.getSrcDirs()) {
|
||||
if (resolve(srcDir, sourceFile).exists()) {
|
||||
potentialSrcDirs.add(srcDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (potentialSrcDirs.size() > 1) {
|
||||
throw new IllegalArgumentException("Multiple source directories in " + sourceDirectorySet.getName() + " contain a source file " + sourceFile);
|
||||
} else if (potentialSrcDirs.isEmpty()) {
|
||||
throw new IllegalArgumentException("No directories in " + sourceDirectorySet.getName() + " contain a source file " + sourceFile);
|
||||
}
|
||||
|
||||
final File srcDir = potentialSrcDirs.getFirst();
|
||||
return new ResolvedSource(project, sourceSet, srcDir, resolve(srcDir, sourceFile));
|
||||
}
|
||||
|
||||
private GroowtAntlrUtil() {}
|
||||
|
||||
}
|
||||
|
@ -1,160 +0,0 @@
|
||||
package groowt.gradle.antlr;
|
||||
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public final class NullableProviderList<T> {
|
||||
|
||||
private sealed interface Element<T> extends Iterable<T> permits BareElement, ElementProvider, CollectionProvider {
|
||||
boolean isPresent();
|
||||
}
|
||||
|
||||
private static final class BareElement<T> implements Element<T> {
|
||||
|
||||
private final T element;
|
||||
|
||||
public BareElement(T element) {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPresent() {
|
||||
return this.element != null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return new Iterator<>() {
|
||||
private boolean hasNext = true;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return this.hasNext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
if (!this.hasNext) throw new IllegalStateException();
|
||||
this.hasNext = false;
|
||||
return BareElement.this.element;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class ElementProvider<T> implements Element<T> {
|
||||
|
||||
private final Provider<T> provider;
|
||||
|
||||
public ElementProvider(Provider<T> provider) {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPresent() {
|
||||
return this.provider.isPresent();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return new Iterator<T>() {
|
||||
private boolean hasNext = true;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return this.hasNext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
if (!this.hasNext) throw new IllegalStateException();
|
||||
this.hasNext = false;
|
||||
return ElementProvider.this.provider.get();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class CollectionProvider<T> implements Element<T> {
|
||||
|
||||
private final Provider<Collection<T>> collectionProvider;
|
||||
|
||||
public CollectionProvider(Provider<Collection<T>> collectionProvider) {
|
||||
this.collectionProvider = collectionProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPresent() {
|
||||
return this.collectionProvider.isPresent();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return this.collectionProvider.get().iterator();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final List<Element<T>> elements = new ArrayList<>();
|
||||
|
||||
public void addElement(@Nullable T element) {
|
||||
this.elements.add(new BareElement<>(element));
|
||||
}
|
||||
|
||||
public void addProvider(Provider<T> elementProvider) {
|
||||
this.elements.add(new ElementProvider<>(elementProvider));
|
||||
}
|
||||
|
||||
public void addCollectionProvider(Provider<Collection<T>> collectionProvider) {
|
||||
this.elements.add(new CollectionProvider<>(collectionProvider));
|
||||
}
|
||||
|
||||
public void addAllElements(Collection<T> elements) {
|
||||
for (final T element : elements) {
|
||||
this.elements.add(new BareElement<>(element));
|
||||
}
|
||||
}
|
||||
|
||||
public void addAllProviders(Collection<Provider<T>> providers) {
|
||||
for (final Provider<T> provider : providers) {
|
||||
this.elements.add(new ElementProvider<>(provider));
|
||||
}
|
||||
}
|
||||
|
||||
public void addAllCollectionProviders(Collection<Provider<Collection<T>>> collectionProviders) {
|
||||
for (final Provider<Collection<T>> collectionProvider : collectionProviders) {
|
||||
this.elements.add(new CollectionProvider<>(collectionProvider));
|
||||
}
|
||||
}
|
||||
|
||||
public List<T> getElements() {
|
||||
return this.getElements(null);
|
||||
}
|
||||
|
||||
public List<T> getElements(@Nullable Supplier<T> onNullElement) {
|
||||
final List<T> result = new ArrayList<>();
|
||||
for (final Element<T> element : this.elements) {
|
||||
if (element.isPresent()) {
|
||||
for (final T t : element) {
|
||||
result.add(t);
|
||||
}
|
||||
} else if (onNullElement != null) {
|
||||
result.add(onNullElement.get());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
package groowt.gradle.antlr;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.tasks.InputDirectory;
|
||||
import org.gradle.api.tasks.InputFile;
|
||||
import org.gradle.api.tasks.Internal;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import static groowt.gradle.antlr.GroowtAntlrUtil.relativize;
|
||||
|
||||
public final class ResolvedSource {
|
||||
|
||||
private final Project project;
|
||||
private final SourceSet sourceSet;
|
||||
private final File sourceDir;
|
||||
private final File sourceFile;
|
||||
|
||||
public ResolvedSource(Project project, SourceSet sourceSet, File sourceDir, File sourceFile) {
|
||||
this.project = project;
|
||||
this.sourceSet = sourceSet;
|
||||
this.sourceDir = sourceDir;
|
||||
this.sourceFile = sourceFile;
|
||||
}
|
||||
|
||||
@Internal
|
||||
public Project getProject() {
|
||||
return this.project;
|
||||
}
|
||||
|
||||
@Internal
|
||||
public SourceSet getSourceSet() {
|
||||
return this.sourceSet;
|
||||
}
|
||||
|
||||
@InputDirectory
|
||||
public File getSourceDir() {
|
||||
return this.sourceDir;
|
||||
}
|
||||
|
||||
@InputFile
|
||||
public File getSourceFile() {
|
||||
return this.sourceFile;
|
||||
}
|
||||
|
||||
private String relativizeSourceDir() {
|
||||
return relativize(this.project.getProjectDir(), this.sourceDir).toString();
|
||||
}
|
||||
|
||||
private String relativeSourceFile() {
|
||||
return relativize(this.sourceDir, this.sourceFile).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
} else if (obj instanceof ResolvedSource other) {
|
||||
return this.project.equals(other.project)
|
||||
&& this.sourceSet.equals(other.sourceSet)
|
||||
&& this.sourceDir.equals(other.sourceDir)
|
||||
&& this.sourceFile.equals(other.sourceFile);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = this.project.hashCode();
|
||||
result = 31 * result + this.sourceSet.hashCode();
|
||||
result = 31 * result + this.sourceDir.hashCode();
|
||||
result = 31 * result + this.sourceFile.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ResolvedSource("
|
||||
+ String.join(", ", List.of(
|
||||
"sourceSet: " + this.sourceSet.getName(),
|
||||
"sourceDir: " + this.relativizeSourceDir(),
|
||||
"sourceFile: " + this.relativeSourceFile()
|
||||
))
|
||||
+ ")";
|
||||
}
|
||||
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package groowt.gradle.antlr;
|
||||
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.Internal;
|
||||
import org.gradle.api.tasks.Nested;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public abstract class SourceSpec {
|
||||
|
||||
private final String identifier;
|
||||
private final ResolvedSource resolvedSource;
|
||||
|
||||
@Inject
|
||||
public SourceSpec(String identifier, ResolvedSource resolvedSource) {
|
||||
this.identifier = identifier;
|
||||
this.resolvedSource = resolvedSource;
|
||||
}
|
||||
|
||||
@Internal
|
||||
public String getIdentifier() {
|
||||
return this.identifier;
|
||||
}
|
||||
|
||||
@Nested
|
||||
public ResolvedSource getResolvedSource() {
|
||||
return this.resolvedSource;
|
||||
}
|
||||
|
||||
@Input
|
||||
public abstract Property<Boolean> getIsCompileDependency();
|
||||
|
||||
@Input
|
||||
public abstract Property<Boolean> getDebug();
|
||||
|
||||
@Input
|
||||
public abstract Property<String> getPackageName();
|
||||
|
||||
@Input
|
||||
public abstract Property<Boolean> getVisitor();
|
||||
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
package groowt.gradle.antlr;
|
||||
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.internal.CollectionCallbackActionDecorator;
|
||||
import org.gradle.api.internal.DefaultDomainObjectSet;
|
||||
import org.gradle.api.model.ObjectFactory;
|
||||
import org.gradle.api.plugins.antlr.AntlrSourceDirectorySet;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.File;
|
||||
|
||||
import static groowt.gradle.antlr.GroowtAntlrUtil.getSourceIdentifier;
|
||||
import static groowt.gradle.antlr.GroowtAntlrUtil.resolveSource;
|
||||
|
||||
public class SourceSpecContainer extends DefaultDomainObjectSet<SourceSpec> {
|
||||
|
||||
private final Project project;
|
||||
private final ObjectFactory objectFactory;
|
||||
private final Action<SourceSpec> applyConventions;
|
||||
|
||||
@Inject
|
||||
public SourceSpecContainer(Project project, ObjectFactory objectFactory, Action<SourceSpec> applyConventions) {
|
||||
super(SourceSpec.class, CollectionCallbackActionDecorator.NOOP);
|
||||
this.project = project;
|
||||
this.objectFactory = objectFactory;
|
||||
this.applyConventions = applyConventions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sourceFilePaths instances of File or String
|
||||
*/
|
||||
public void ignore(SourceSet sourceSet, Object... sourceFilePaths) {
|
||||
for (final Object sourceFilePath : sourceFilePaths) {
|
||||
switch (sourceFilePath) {
|
||||
case File f -> this.ignoreFile(sourceSet, f);
|
||||
case String s -> this.ignoreFile(sourceSet, new File(s));
|
||||
default -> throw new IllegalArgumentException("Can only ignore Files or Strings, given: " + sourceFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ignoreFile(SourceSet sourceSet, File target) {
|
||||
this.removeIf(potentialSourceSpec -> {
|
||||
final SourceSet potentialSourceSet = potentialSourceSpec.getResolvedSource().getSourceSet();
|
||||
if (!sourceSet.equals(potentialSourceSet)) {
|
||||
return false;
|
||||
}
|
||||
final var antlrSourceDirectorySet = sourceSet.getExtensions().getByType(AntlrSourceDirectorySet.class);
|
||||
final ResolvedSource toIgnore = resolveSource(this.project, sourceSet, antlrSourceDirectorySet, target);
|
||||
final File potentialSourceFile = potentialSourceSpec.getResolvedSource().getSourceFile();
|
||||
return toIgnore.getSourceFile().equals(potentialSourceFile);
|
||||
});
|
||||
}
|
||||
|
||||
public void register(SourceSet sourceSet, String sourceFilePath) {
|
||||
this.register(sourceSet, new File(sourceFilePath), sourceSpec -> {}); // no-op action
|
||||
}
|
||||
|
||||
public void register(SourceSet sourceSet, File sourceFile) {
|
||||
this.register(sourceSet, sourceFile, sourceSpec -> {});
|
||||
}
|
||||
|
||||
public void register(SourceSet sourceSet, String sourceFilePath, Action<? super SourceSpec> action) {
|
||||
this.register(sourceSet, new File(sourceFilePath), action);
|
||||
}
|
||||
|
||||
public void register(SourceSet sourceSet, File sourceFile, Action<? super SourceSpec> action) {
|
||||
final var antlrSourceDirectorySet = sourceSet.getExtensions().getByType(AntlrSourceDirectorySet.class);
|
||||
final var resolvedSource = resolveSource(this.project, sourceSet, antlrSourceDirectorySet, sourceFile);
|
||||
|
||||
final String identifier = getSourceIdentifier(resolvedSource);
|
||||
final var specOptional = this.stream().filter(sourceSpec -> sourceSpec.getIdentifier().equals(identifier)).findFirst();
|
||||
|
||||
if (specOptional.isPresent()) {
|
||||
// we already have one, so find and run the action against it
|
||||
final var spec = specOptional.get();
|
||||
action.execute(spec);
|
||||
} else {
|
||||
// create a new one
|
||||
final var spec = this.objectFactory.newInstance(SourceSpec.class, identifier, resolvedSource);
|
||||
this.applyConventions.execute(spec);
|
||||
action.execute(spec);
|
||||
this.add(spec);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
//file:noinspection ConfigurationAvoidance
|
||||
package groowt.gradle.antlr
|
||||
|
||||
import org.gradle.api.plugins.JavaPlugin
|
||||
import org.gradle.api.plugins.JavaPluginExtension
|
||||
import org.gradle.api.plugins.antlr.AntlrPlugin
|
||||
import org.gradle.testfixtures.ProjectBuilder
|
||||
import org.junit.jupiter.api.Disabled
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.function.Executable
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow
|
||||
|
||||
class GroowtAntlrPluginTests {
|
||||
|
||||
@Disabled('TODO: figure out why register(SourceSet, String) is not working.')
|
||||
@Test
|
||||
void smokeScreen() {
|
||||
def projectDir = File.createTempDir()
|
||||
new FileTreeBuilder(projectDir).tap {
|
||||
dir(['src', 'main', 'antlr'].join(File.separator)) {
|
||||
file('MyGrammar.g4') {
|
||||
write("parser grammar MyGrammar;")
|
||||
}
|
||||
}
|
||||
}
|
||||
def project = ProjectBuilder.builder().with {
|
||||
withProjectDir(projectDir)
|
||||
build()
|
||||
}
|
||||
|
||||
project.pluginManager.with {
|
||||
apply(JavaPlugin)
|
||||
apply(AntlrPlugin)
|
||||
apply(GroowtAntlrPlugin)
|
||||
}
|
||||
|
||||
def mainSourceSet = project.extensions.getByType(JavaPluginExtension).sourceSets.findByName('main')
|
||||
|
||||
project.extensions.getByType(GroowtAntlrExtension).sourceSpecs.with {
|
||||
register(mainSourceSet, 'MyGrammar.g4')
|
||||
}
|
||||
|
||||
def findTask = {
|
||||
project.tasks.named('generateMyGrammar', GroowtAntlrTask)
|
||||
} as Executable
|
||||
|
||||
assertDoesNotThrow(findTask) {
|
||||
"Could not find task 'generateMyGrammar' (all tasks: ${project.tasks*.name.join(', ')})"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
//file:noinspection ConfigurationAvoidance
|
||||
package groowt.gradle.antlr
|
||||
|
||||
import groovy.transform.TupleConstructor
|
||||
import org.gradle.api.plugins.JavaPlugin
|
||||
import org.gradle.api.plugins.JavaPluginExtension
|
||||
import org.gradle.api.plugins.antlr.AntlrPlugin
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.SourceSet
|
||||
import org.gradle.testfixtures.ProjectBuilder
|
||||
import org.junit.jupiter.api.DynamicTest
|
||||
import org.junit.jupiter.api.TestFactory
|
||||
|
||||
import java.nio.file.Path
|
||||
|
||||
import static groowt.gradle.antlr.GroowtAntlrUtil.*
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals
|
||||
import static org.junit.jupiter.api.Assertions.assertIterableEquals
|
||||
import static org.junit.jupiter.api.DynamicTest.dynamicTest
|
||||
|
||||
class GroowtAntlrUtilTests {
|
||||
|
||||
@TupleConstructor
|
||||
private static class SourceFileToIdentifierTestSpec {
|
||||
File srcDir
|
||||
File srcFile
|
||||
List<String> expected
|
||||
}
|
||||
|
||||
@TestFactory
|
||||
Collection<DynamicTest> sourceFileToIdentifierPartsTests() {
|
||||
def srcDir = File.createTempDir()
|
||||
def getSpec = { String path, List<String> expected ->
|
||||
new SourceFileToIdentifierTestSpec(srcDir, new File(path), expected)
|
||||
}
|
||||
|
||||
def specs = [
|
||||
getSpec('MyGrammar.g4', ['MyGrammar']),
|
||||
getSpec('subDir/MyGrammar.g4', ['subDir', 'MyGrammar']),
|
||||
getSpec('subDir/subSubDir/MyGrammar.g4', ['subDir', 'subSubDir', 'MyGrammar']),
|
||||
getSpec('My.grammar.g4', ['My.grammar'])
|
||||
]
|
||||
|
||||
return specs.collect { spec ->
|
||||
dynamicTest(spec.srcFile.toString()) {
|
||||
def actual = sourceFileToIdentifierParts(spec.srcDir, spec.srcFile)
|
||||
assertIterableEquals(spec.expected, actual) {
|
||||
"Unexpected result: ${actual}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestFactory
|
||||
Collection<DynamicTest> getSourceIdentifierTests() {
|
||||
def projectDir = File.createTempDir()
|
||||
File srcDir
|
||||
new FileTreeBuilder(projectDir).with {
|
||||
srcDir = dir(['src', 'main', 'antlr'].join(File.separator))
|
||||
}
|
||||
|
||||
def project = ProjectBuilder.builder()
|
||||
.withProjectDir(projectDir)
|
||||
.build()
|
||||
project.pluginManager.with {
|
||||
apply(JavaPlugin)
|
||||
apply(AntlrPlugin)
|
||||
}
|
||||
def mainSourceSet = project.extensions.getByType(JavaPluginExtension)
|
||||
.sourceSets.getByName('main')
|
||||
|
||||
def getResolvedSource = { String path ->
|
||||
new ResolvedSource(project, mainSourceSet, srcDir, new File(path))
|
||||
}
|
||||
|
||||
Closure<Tuple2<String, ResolvedSource>> getSpec = { String expected, String path ->
|
||||
new Tuple2(expected, getResolvedSource(path))
|
||||
}
|
||||
|
||||
def specs = [
|
||||
getSpec('MyGrammar', 'MyGrammar.g4'),
|
||||
getSpec('SubDirMyGrammar', 'subDir/MyGrammar.g4')
|
||||
]
|
||||
|
||||
return specs.collect { spec ->
|
||||
dynamicTest(spec.v2.sourceFile.toString()) {
|
||||
def actual = getSourceIdentifier(spec.v2)
|
||||
assertEquals(spec.v1, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestFactory
|
||||
Collection<DynamicTest> getOutputDirTests() {
|
||||
def project = ProjectBuilder.builder().build()
|
||||
project.pluginManager.tap {
|
||||
apply(JavaPlugin)
|
||||
apply(AntlrPlugin)
|
||||
}
|
||||
project.layout.buildDirectory.set(new File('build'))
|
||||
|
||||
def mainSourceSet = project.extensions.getByType(JavaPluginExtension)
|
||||
.sourceSets.getByName('main')
|
||||
|
||||
Closure<Tuple3<Path, SourceSet, Provider<String>>> getSpec = { String givenPackageName ->
|
||||
def expectedPackagePath = givenPackageName.replace('.', File.separator)
|
||||
def expected = Path.of('build', ['generated-src', 'antlr', mainSourceSet.name, expectedPackagePath] as String[])
|
||||
def packageProperty = project.objects.property(String).tap { set(givenPackageName) }
|
||||
new Tuple3(expected, mainSourceSet, packageProperty)
|
||||
}
|
||||
|
||||
List<Tuple3<Path, SourceSet, Provider<String>>> specs = [
|
||||
getSpec('antlr.one.two.three'), // build/generated-src/antlr/main/antlr/one/two/three
|
||||
getSpec('test.antlr'), // build/generated-src/antlr/main/test/antlr
|
||||
getSpec('antlr'), // build/generated-src/antlr/main/antlr
|
||||
getSpec('') // build/generated-src/antlr/main
|
||||
]
|
||||
|
||||
def projectPath = project.layout.projectDirectory.asFile.toPath()
|
||||
|
||||
return specs.collect { spec ->
|
||||
def givenPackageName = spec.v3.get()
|
||||
dynamicTest(givenPackageName.empty ? '<empty>' : givenPackageName) {
|
||||
def actualPath = getOutputDirectory(project, spec.v2, spec.v3)
|
||||
.get().asFile.toPath()
|
||||
def result = projectPath.relativize(actualPath)
|
||||
assertEquals(spec.v1, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,11 +1,10 @@
|
||||
import groovy.transform.NullCheck
|
||||
import groowt.gradle.antlr.GroowtAntlrTask
|
||||
import groowt.gradle.antlr.GroowtAntlrExecTask
|
||||
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'java-library'
|
||||
id 'groovy'
|
||||
id 'antlr'
|
||||
id 'GroowtAntlrPlugin'
|
||||
id 'org.jetbrains.kotlin.jvm'
|
||||
id 'java-test-fixtures'
|
||||
@ -49,7 +48,7 @@ dependencies {
|
||||
project(':di'),
|
||||
project(':extensible')
|
||||
)
|
||||
antlr libs.antlr
|
||||
groowtAntlr libs.antlr
|
||||
runtimeOnly libs.log4j.slf4jBinding
|
||||
|
||||
def testLibs = [
|
||||
@ -82,23 +81,19 @@ groowtAntlr {
|
||||
visitor = true
|
||||
}
|
||||
|
||||
// Must be temporarily afterEvaluate unless we switch the GroowtAntlr plugin
|
||||
// to eagerly create the tasks upon plugin application
|
||||
afterEvaluate {
|
||||
tasks.named('generateWebViewComponentsLexerBase', GroowtAntlrTask) { task ->
|
||||
doLast {
|
||||
def pattern = ~/public class WebViewComponentsLexerBase(.*)/
|
||||
def lexerSource = new File(task.outputDirectory, 'WebViewComponentsLexerBase.java')
|
||||
def outLines = lexerSource.readLines().collect {
|
||||
def matcher = pattern.matcher(it)
|
||||
if (matcher.matches()) {
|
||||
return 'public abstract class WebViewComponentsLexerBase' + matcher.group(1)
|
||||
} else {
|
||||
return it
|
||||
}
|
||||
tasks.named('generateWebViewComponentsLexerBase', GroowtAntlrExecTask) { task ->
|
||||
doLast {
|
||||
def pattern = ~/public class WebViewComponentsLexerBase(.*)/
|
||||
def lexerSource = task.resolveOutputFile 'WebViewComponentsLexerBase.java'
|
||||
def outLines = lexerSource.readLines().collect {
|
||||
def matcher = pattern.matcher(it)
|
||||
if (matcher.matches()) {
|
||||
return 'public abstract class WebViewComponentsLexerBase' + matcher.group(1)
|
||||
} else {
|
||||
return it
|
||||
}
|
||||
lexerSource.write(outLines.join('\n'))
|
||||
}
|
||||
lexerSource.write(outLines.join('\n'))
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,11 +173,6 @@ tasks.register('cleanBin', Delete) {
|
||||
delete file('bin')
|
||||
}
|
||||
|
||||
// Hacky
|
||||
tasks.named('compileKotlin').configure {
|
||||
dependsOn 'generateLexerFragments', 'generateWebViewComponentsLexerBase', 'generateWebViewComponentsParser'
|
||||
}
|
||||
|
||||
test {
|
||||
jvmArgs '-XX:+EnableDynamicAgentLoading' // for mockito/bytebuddy
|
||||
testLogging.showStandardStreams = true
|
||||
|
Loading…
Reference in New Issue
Block a user