All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.strumenta.antlrkotlin.gradleplugin.AntlrKotlinTask Maven / Gradle / Ivy

There is a newer version: 0.0.18
Show newest version
/*
 * 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;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy