Skip to content

Commit

Permalink
Merge pull request #328 from matthiasbalke/issue-326-antlr4
Browse files Browse the repository at this point in the history
[WIP] Add ANTLR4 support
  • Loading branch information
nedtwigg authored Jul 1, 2020
2 parents f8198b5 + 60b9805 commit 5070536
Show file tree
Hide file tree
Showing 16 changed files with 459 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
### Added
* `prettier` will now autodetect the parser (and formatter) to use based on the filename, unless you override this using `config` or `configFile` with the option `parser` or `filepath`. ([#620](https://github.com/diffplug/spotless/pull/620))
* `GitRatchet` now lives in `lib-extra`, and is shared across `plugin-gradle` and `plugin-maven` ([#626](https://github.com/diffplug/spotless/pull/626)).
* Added ANTLR4 support ([#326](https://github.com/diffplug/spotless/issues/326)).
### Changed
* **BREAKING** `FileSignature` can no longer sign folders, only files. Signatures are now based only on filename (not path), size, and a content hash. It throws an error if a signature is attempted on a folder or on multiple files with different paths but the same filename - it never breaks silently. This change does not break any of Spotless' internal logic, so it is unlikely to affect any of Spotless' consumers either. ([#571](https://github.com/diffplug/spotless/pull/571))
* This change allows the maven plugin to cache classloaders across subprojects when loading config resources from the classpath (fixes [#559](https://github.com/diffplug/spotless/issues/559)).
Expand Down
31 changes: 31 additions & 0 deletions lib/src/main/java/com/diffplug/spotless/antlr4/Antlr4Defaults.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2016-2020 DiffPlug
*
* 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.diffplug.spotless.antlr4;

public class Antlr4Defaults {
private static final String LICENSE_HEADER_DELIMITER = "(grammar|lexer grammar|parser grammar)";
private static final String INCLUDES = "src/*/antlr4/**/*.g4";

private Antlr4Defaults() {}

public static String licenseHeaderDelimiter() {
return LICENSE_HEADER_DELIMITER;
}

public static String includes() {
return INCLUDES;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright 2016-2020 DiffPlug
*
* 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.diffplug.spotless.antlr4;

import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.diffplug.spotless.*;

public class Antlr4FormatterStep {

public static final String NAME = "antlr4Formatter";

private Antlr4FormatterStep() {}

private static final String MAVEN_COORDINATE = "com.khubla.antlr4formatter:antlr4-formatter:";
private static final String DEFAULT_VERSION = "1.2.1";

public static FormatterStep create(Provisioner provisioner) {
return create(defaultVersion(), provisioner);
}

public static FormatterStep create(String version, Provisioner provisioner) {
return FormatterStep.createLazy(NAME, () -> new State(version, provisioner), State::createFormat);
}

public static String defaultVersion() {
return DEFAULT_VERSION;
}

static final class State implements Serializable {
private static final long serialVersionUID = 1L;

/**
* The jar that contains the formatter.
*/
final JarState jarState;

State(String version, Provisioner provisioner) throws IOException {
this.jarState = JarState.from(MAVEN_COORDINATE + version, provisioner);
}

FormatterFunc createFormat() throws ClassNotFoundException, NoSuchMethodException {
ClassLoader classLoader = jarState.getClassLoader();

// String Antlr4Formatter::format(String input)
Class<?> formatter = classLoader.loadClass("com.khubla.antlr4formatter.Antlr4Formatter");
Method formatterMethod = formatter.getMethod("format", String.class);

return input -> {
try {
return (String) formatterMethod.invoke(null, input);
} catch (InvocationTargetException e) {
throw ThrowingEx.unwrapCause(e);
}
};
}
}
}
1 change: 1 addition & 0 deletions plugin-gradle/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
* Full support for the Gradle buildcache - previously only supported local, now supports remote too. Fixes [#566](https://github.com/diffplug/spotless/issues/566) and [#280](https://github.com/diffplug/spotless/issues/280), via changes in [#621](https://github.com/diffplug/spotless/pull/621) and [#571](https://github.com/diffplug/spotless/pull/571).
* `prettier` will now autodetect the parser (and formatter) to use based on the filename, unless you override this using `config()` or `configFile()` with the option `parser` or `filepath`. ([#620](https://github.com/diffplug/spotless/pull/620))
* (user-invisible) moved the deprecated lib code which was only being used in deprecated parts of `plugin-gradle` into the `.libdeprecated` package. ([#630](https://github.com/diffplug/spotless/pull/630))
* Added ANTLR4 support ([#326](https://github.com/diffplug/spotless/issues/326)).
### Fixed
* LineEndings.GIT_ATTRIBUTES is now a bit more efficient, and paves the way for remote build cache support in Gradle. ([#621](https://github.com/diffplug/spotless/pull/621))
* `ratchetFrom` now ratchets from the merge base of `HEAD` and the specified branch. This fixes the surprising behavior when a remote branch advanced ([#631](https://github.com/diffplug/spotless/pull/631) fixes [#627](https://github.com/diffplug/spotless/issues/627)).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright 2016-2020 DiffPlug
*
* 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.diffplug.gradle.spotless;

import java.util.Objects;

import com.diffplug.spotless.FormatterStep;
import com.diffplug.spotless.antlr4.Antlr4Defaults;
import com.diffplug.spotless.antlr4.Antlr4FormatterStep;

public class Antlr4Extension extends FormatExtension implements HasBuiltinDelimiterForLicense {
static final String NAME = "antlr4";

public Antlr4Extension(SpotlessExtensionBase rootExtension) {
super(rootExtension);
}

public Antlr4FormatterConfig antlr4Formatter() {
return antlr4Formatter(Antlr4FormatterStep.defaultVersion());
}

public Antlr4FormatterConfig antlr4Formatter(String version) {
return new Antlr4FormatterConfig(version);
}

public class Antlr4FormatterConfig {

private final String version;

Antlr4FormatterConfig(String version) {
this.version = Objects.requireNonNull(version);
addStep(createStep());
}

private FormatterStep createStep() {
return Antlr4FormatterStep.create(this.version, provisioner());
}
}

@Override
protected void setupTask(SpotlessTask task) {
if (target == null) {
target = parseTarget(Antlr4Defaults.includes());
}
super.setupTask(task);
}

@Override
public LicenseHeaderConfig licenseHeader(String licenseHeader) {
return licenseHeader(licenseHeader, Antlr4Defaults.licenseHeaderDelimiter());
}

@Override
public LicenseHeaderConfig licenseHeaderFile(Object licenseHeaderFile) {
return licenseHeaderFile(licenseHeaderFile, Antlr4Defaults.licenseHeaderDelimiter());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ public void typescript(Action<TypescriptExtension> closure) {
format(TypescriptExtension.NAME, TypescriptExtension.class, closure);
}

/** Configures the special antlr4-specific extension for antlr4 files. */
public void antlr4(Action<Antlr4Extension> closure) {
format(Antlr4Extension.NAME, Antlr4Extension.class, closure);
}

/** Configures a custom extension. */
public void format(String name, Action<FormatExtension> closure) {
requireNonNull(name, "name");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright 2016-2020 DiffPlug
*
* 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.diffplug.gradle.spotless;

import java.io.IOException;

import org.junit.Test;

public class Antlr4ExtensionTest extends GradleIntegrationHarness {

@Test
public void applyUsingDefaultVersion() throws IOException {
String[] buildScript = {
"buildscript {",
" repositories {",
" mavenCentral()",
" }",
"}",
"plugins {",
" id 'com.diffplug.gradle.spotless'",
"}",
"spotless {",
" antlr4 {",
" target 'src/main/antlr4/**/*.g4'",
" antlr4Formatter()",
" }",
"}"};

assertAppliedFormat(buildScript);
}

@Test
public void applyUsingCustomVersion() throws IOException {
String[] buildScript = {
"buildscript {",
" repositories {",
" mavenCentral()",
" }",
"}",
"plugins {",
" id 'com.diffplug.gradle.spotless'",
"}",
"spotless {",
" antlr4 {",
" target 'src/main/antlr4/**/*.g4'",
" antlr4Formatter('1.2.1')",
" }",
"}"};

assertAppliedFormat(buildScript);
}

private void assertAppliedFormat(String... buildScript) throws IOException {
String testFile = "src/main/antlr4/Hello.g4";

setFile("build.gradle").toLines(buildScript);

String unformatted = "antlr4/Hello.unformatted.g4";
String formatted = "antlr4/Hello.formatted.g4";
setFile(testFile).toResource(unformatted);

gradleRunner().withArguments("spotlessApply").build();

assertFile(testFile).sameAsResource(formatted);
}
}
1 change: 1 addition & 0 deletions plugin-maven/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
* Huge speed improvement for multi-module projects thanks to improved cross-project classloader caching ([#571](https://github.com/diffplug/spotless/pull/571), fixes [#559](https://github.com/diffplug/spotless/issues/559)).
* If you specify `-DspotlessSetLicenseHeaderYearsFromGitHistory=true`, Spotless will perform an expensive search through git history to determine the oldest and newest commits for each file, and uses that to determine license header years. ([#626](https://github.com/diffplug/spotless/pull/626))
* `prettier` will now autodetect the parser (and formatter) to use based on the filename, unless you override this using `config` or `configFile` with the option `parser` or `filepath` ([#620](https://github.com/diffplug/spotless/pull/620)).
* Added ANTLR4 support ([#326](https://github.com/diffplug/spotless/issues/326)).
### Removed
* **BREAKING** the long-deprecated `<xml>` and `<css>` formats have been removed, in favor of the long-available [`<eclipseWtp>`](https://github.com/diffplug/spotless/tree/main/plugin-maven#eclipse-wtp) step which is available in every generic format.
* This probably doesn't affect you, but if it does, you just need to change `<xml>...` into `<formats><format><eclipseWtp><type>XML</type>...`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import com.diffplug.spotless.LineEnding;
import com.diffplug.spotless.Provisioner;
import com.diffplug.spotless.generic.LicenseHeaderStep;
import com.diffplug.spotless.maven.antlr4.Antlr4;
import com.diffplug.spotless.maven.cpp.Cpp;
import com.diffplug.spotless.maven.generic.Format;
import com.diffplug.spotless.maven.generic.LicenseHeader;
Expand Down Expand Up @@ -108,6 +109,9 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo {
@Parameter
private Typescript typescript;

@Parameter
private Antlr4 antlr4;

@Parameter(property = "spotlessFiles")
private String filePatterns;

Expand Down Expand Up @@ -194,7 +198,7 @@ private FileLocator getFileLocator() {
}

private List<FormatterFactory> getFormatterFactories() {
return Stream.concat(formats.stream(), Stream.of(java, scala, kotlin, cpp, typescript))
return Stream.concat(formats.stream(), Stream.of(java, scala, kotlin, cpp, typescript, antlr4))
.filter(Objects::nonNull)
.collect(toList());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright 2016-2020 DiffPlug
*
* 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.diffplug.spotless.maven.antlr4;

import java.util.Set;

import com.diffplug.common.collect.ImmutableSet;
import com.diffplug.spotless.antlr4.Antlr4Defaults;
import com.diffplug.spotless.maven.FormatterFactory;
import com.diffplug.spotless.maven.generic.LicenseHeader;

/**
* A {@link FormatterFactory} implementation that corresponds to {@code <antlr4>...</antlr4>} configuration element.
* <p>
* It defines a formatter for ANTLR4 source files that can execute both language agnostic (e.g. {@link LicenseHeader})
* and anltr4-specific (e.g. {@link Antlr4Formatter}) steps.
*/
public class Antlr4 extends FormatterFactory {
@Override
public Set<String> defaultIncludes() {
return ImmutableSet.of(Antlr4Defaults.includes());
}

@Override
public String licenseHeaderDelimiter() {
return Antlr4Defaults.licenseHeaderDelimiter();
}

public void addAntlr4Formatter(Antlr4Formatter antlr4Formatter) {
addStepFactory(antlr4Formatter);
}

}
Loading

0 comments on commit 5070536

Please sign in to comment.