com.strumenta.antlrkotlin.gradleplugin.AntlrKotlinTask Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of antlr-kotlin-gradle-plugin Show documentation
Show all versions of antlr-kotlin-gradle-plugin Show documentation
Kotlin multiplatform port of ANTLR
/*
* Copyright 2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.strumenta.antlrkotlin.gradleplugin;
import com.strumenta.antlrkotlin.gradleplugin.internal.*;
import org.gradle.api.DefaultTask;
import org.gradle.api.file.*;
import org.gradle.api.tasks.*;
import org.gradle.process.internal.worker.*;
import org.gradle.work.*;
import org.slf4j.*;
import javax.inject.*;
import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.concurrent.atomic.*;
import static org.gradle.api.tasks.PathSensitivity.RELATIVE;
/**
* Generates parsers from Antlr grammars.
*/
@CacheableTask
public abstract class AntlrKotlinTask extends DefaultTask {
private static final Logger LOGGER = LoggerFactory.getLogger(AntlrKotlinTask.class);
private boolean trace;
private boolean traceLexer;
private boolean traceParser;
private boolean traceTreeWalker;
private List arguments = new ArrayList();
private FileCollection antlrClasspath;
private File outputDirectory;
private String maxHeapSize;
private String packageName;
private SourceDirectorySet sourceDirectorySet;
private ConfigurableFileCollection source;
/**
* Specifies that all rules call {@code traceIn}/{@code traceOut}.
*/
@Input
public boolean isTrace() {
return trace;
}
public void setTrace(boolean trace) {
this.trace = trace;
}
/**
* Specifies that all lexer rules call {@code traceIn}/{@code traceOut}.
*/
@Input
public boolean isTraceLexer() {
return traceLexer;
}
public void setTraceLexer(boolean traceLexer) {
this.traceLexer = traceLexer;
}
/**
* Specifies that all parser rules call {@code traceIn}/{@code traceOut}.
*/
@Input
public boolean isTraceParser() {
return traceParser;
}
public void setTraceParser(boolean traceParser) {
this.traceParser = traceParser;
}
/**
* Specifies that all tree walker rules call {@code traceIn}/{@code traceOut}.
*/
@Input
public boolean isTraceTreeWalker() {
return traceTreeWalker;
}
public void setTraceTreeWalker(boolean traceTreeWalker) {
this.traceTreeWalker = traceTreeWalker;
}
/**
* The maximum heap size for the forked antlr process (ex: '1g').
*/
@Internal
public String getMaxHeapSize() {
return maxHeapSize;
}
public void setMaxHeapSize(String maxHeapSize) {
this.maxHeapSize = maxHeapSize;
}
/**
* The package name of the generated files.
*/
@Internal
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public void setArguments(List arguments) {
if (arguments != null) {
this.arguments = arguments;
}
}
/**
* List of command-line arguments passed to the antlr process
*
* @return The antlr command-line arguments
*/
@Input
public List getArguments() {
return arguments;
}
/**
* Returns the directory to generate the parser source files into.
*
* @return The output directory.
*/
@OutputDirectory
public File getOutputDirectory() {
return outputDirectory;
}
/**
* Specifies the directory to generate the parser source files into.
*
* @param outputDirectory The output directory. Must not be null.
*/
public void setOutputDirectory(File outputDirectory) {
if (!outputDirectory.isAbsolute()) {
outputDirectory = new File(getProject().getProjectDir(), outputDirectory.getPath());
}
this.outputDirectory = outputDirectory;
}
/**
* Returns the classpath containing the Ant ANTLR task implementation.
*
* @return The Ant task implementation classpath.
*/
@Classpath
public FileCollection getAntlrClasspath() {
return antlrClasspath;
}
/**
* Specifies the classpath containing the Ant ANTLR task implementation.
*
* @param antlrClasspath The Ant task implementation classpath. Must not be null.
*/
public void setAntlrClasspath(FileCollection antlrClasspath) {
this.antlrClasspath = antlrClasspath;
}
@Inject
protected WorkerProcessFactory getWorkerProcessBuilderFactory() {
throw new UnsupportedOperationException();
}
@TaskAction
public void execute(InputChanges inputs) throws IOException {
ConfigurableFileCollection source = getSource();
final Set sourceFiles = source.getFiles();
final Set grammarFiles = new HashSet();
final AtomicBoolean cleanRebuild = new AtomicBoolean();
inputs.getFileChanges(source).forEach((change) -> {
if (change.getFileType() == FileType.DIRECTORY) {
return;
}
grammarFiles.add(change.getFile());
if (change.getChangeType() == ChangeType.REMOVED) {
cleanRebuild.set(true);
} else {
// classpath change?
cleanRebuild.set(true);
}
});
if (cleanRebuild.get()) {
if (outputDirectory.exists()) {
Files.walk(outputDirectory.toPath())
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
}
grammarFiles.addAll(sourceFiles);
}
AntlrWorkerManager manager = new AntlrWorkerManager();
LOGGER.debug("AntlrWorkerManager created");
AntlrSpec spec = new AntlrSpecFactory().create(this, grammarFiles, sourceDirectorySet);
LOGGER.debug("AntlrSpec created");
AntlrResult result = manager.runWorker(getProject().getProjectDir(), getWorkerProcessBuilderFactory(), getAntlrClasspath(), spec);
LOGGER.debug("AntlrResult obtained");
evaluate(result);
}
private void evaluate(AntlrResult result) {
int errorCount = result.getErrorCount();
if (errorCount < 0) {
throw new AntlrSourceGenerationException("There were errors during grammar generation", result.getException());
} else if (errorCount == 1) {
throw new AntlrSourceGenerationException("There was 1 error during grammar generation", result.getException());
} else if (errorCount > 1) {
throw new AntlrSourceGenerationException("There were "
+ errorCount
+ " errors during grammar generation", result.getException());
}
}
public void setSource(FileTree source) {
setSource((Object) source);
}
public void setSource(Object source) {
this.source=getProject().getObjects().fileCollection().from(source);
if (source instanceof SourceDirectorySet) {
this.sourceDirectorySet = (SourceDirectorySet) source;
}
}
@PathSensitive(PathSensitivity.RELATIVE)
@Incremental
@InputFiles
public ConfigurableFileCollection getSource() {
return source;
}
}