diff --git a/.eclipse/org.eclipse.jdt.core.prefs b/.eclipse/org.eclipse.jdt.core.prefs
index 1d379438..cc3e405e 100644
--- a/.eclipse/org.eclipse.jdt.core.prefs
+++ b/.eclipse/org.eclipse.jdt.core.prefs
@@ -127,7 +127,7 @@ org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
-org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=84
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
@@ -136,7 +136,7 @@ org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration
org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0
org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0
org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
-org.eclipse.jdt.core.formatter.align_selector_in_method_invocation_on_expression_first_line=false
+org.eclipse.jdt.core.formatter.align_selector_in_method_invocation_on_expression_first_line=true
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
org.eclipse.jdt.core.formatter.blank_lines_before_field=0
diff --git a/.github/actions/.bats/bats b/.github/actions/.bats/bats
new file mode 160000
index 00000000..902578da
--- /dev/null
+++ b/.github/actions/.bats/bats
@@ -0,0 +1 @@
+Subproject commit 902578da790fbcb035747d2964747f192f6e1603
diff --git a/.github/actions/.bats/test_helper/bats-assert b/.github/actions/.bats/test_helper/bats-assert
new file mode 160000
index 00000000..e2d855bc
--- /dev/null
+++ b/.github/actions/.bats/test_helper/bats-assert
@@ -0,0 +1 @@
+Subproject commit e2d855bc78619ee15b0c702b5c30fb074101159f
diff --git a/.github/actions/.bats/test_helper/bats-support b/.github/actions/.bats/test_helper/bats-support
new file mode 160000
index 00000000..9bf10e87
--- /dev/null
+++ b/.github/actions/.bats/test_helper/bats-support
@@ -0,0 +1 @@
+Subproject commit 9bf10e876dd6b624fe44423f0b35e064225f7556
diff --git a/.github/actions/create-github-release/action.yml b/.github/actions/create-github-release/action.yml
new file mode 100644
index 00000000..1d72cd3a
--- /dev/null
+++ b/.github/actions/create-github-release/action.yml
@@ -0,0 +1,21 @@
+name: Create GitHub Release
+description: Create the release on GitHub with a changelog
+inputs:
+ milestone:
+ required: true
+ token:
+ required: true
+runs:
+ using: composite
+ steps:
+ - name: Generate Changelog
+ uses: spring-io/github-changelog-generator@v0.0.10
+ with:
+ milestone: ${{ inputs.milestone }}
+ token: ${{ inputs.token }}
+ config-file: .github/actions/create-github-release/changelog-generator.yml
+ - name: Create GitHub Release
+ env:
+ GITHUB_TOKEN: ${{ inputs.token }}
+ shell: bash
+ run: gh release create ${{ format('v{0}', inputs.milestone) }} --notes-file changelog.md
diff --git a/.github/actions/create-github-release/changelog-generator.yml b/.github/actions/create-github-release/changelog-generator.yml
new file mode 100644
index 00000000..2ce74a09
--- /dev/null
+++ b/.github/actions/create-github-release/changelog-generator.yml
@@ -0,0 +1,2 @@
+changelog:
+ repository: spring-io/spring-javaformat
diff --git a/.github/actions/deduce-versions/action.yml b/.github/actions/deduce-versions/action.yml
new file mode 100644
index 00000000..b8e197c4
--- /dev/null
+++ b/.github/actions/deduce-versions/action.yml
@@ -0,0 +1,22 @@
+name: 'Deduce Versions'
+description: 'Deduce the version to stage and the next SNAPSHOT version'
+inputs:
+ current-version:
+ required: true
+ release-type:
+ required: true
+outputs:
+ release-version:
+ value: ${{ steps.deduce-versions.outputs.release-version }}
+ next-version:
+ value: ${{ steps.deduce-versions.outputs.next-version }}
+runs:
+ using: composite
+ steps:
+ - name: Deduce Versions
+ id: deduce-versions
+ shell: bash
+ run: . ${{ github.action_path }}/deduce-versions.sh; deduce_versions
+ env:
+ CURRENT_VERSION: "${{ inputs.current-version }}"
+ RELEASE_TYPE: "${{ inputs.release-type }}"
diff --git a/.github/actions/deduce-versions/deduce-versions.sh b/.github/actions/deduce-versions/deduce-versions.sh
new file mode 100755
index 00000000..6a3d14e0
--- /dev/null
+++ b/.github/actions/deduce-versions/deduce-versions.sh
@@ -0,0 +1,116 @@
+#!/usr/bin/env bash
+
+# Get the next milestone release for the given number by inspecting current tags
+get_next_milestone_release() {
+ [[ -n $1 ]] || { echo "missing get_next_milestone_release() version argument" >&2; return 1; }
+ get_next_tag_based_release "$1" "M"
+}
+
+# Get the next RC release for the given number by inspecting current tags
+get_next_rc_release() {
+ [[ -n $1 ]] || { echo "missing get_next_rc_release() version argument" >&2; return 1; }
+ get_next_tag_based_release "$1" "RC"
+}
+
+# Get the next release for the given number
+get_next_release() {
+ [[ -n $1 ]] || { echo "missing get_next_release() version argument" >&2; return 1; }
+ if [[ $1 =~ ^(.*)\.BUILD-SNAPSHOT$ ]]; then
+ local join="."
+ else
+ local join="-"
+ fi
+ local version
+ local result
+ version=$( strip_snapshot_suffix "$1" )
+ if [[ -n $2 ]]; then
+ result="${version}${join}${2}"
+ else
+ result="${version}"
+ fi
+ echo $result
+}
+
+# Get the next milestone or RC release for the given number by inspecting current tags
+get_next_tag_based_release() {
+ [[ -n $1 ]] || { echo "missing get_next_tag_based_release() version argument" >&2; return 1; }
+ [[ -n $2 ]] || { echo "missing get_next_tag_based_release() tag type argument" >&2; return 1; }
+ if [[ $1 =~ ^(.*)\.BUILD-SNAPSHOT$ ]]; then
+ local join="."
+ else
+ local join="-"
+ fi
+ local version
+ local last
+ version=$( strip_snapshot_suffix "$1" )
+ git fetch --tags --all > /dev/null
+ last=$( git tag --list "v${version}${join}${2}*" | sed -E "s/^.*${2}([0-9]+)$/\1/g" | sort -rn | head -n1 )
+ if [[ -z $last ]]; then
+ last="0"
+ fi
+ last="${version}${join}${2}${last}"
+ bump_version_number "$last"
+}
+
+# Remove any "-SNAPSHOT" or ".BUILD-SNAPSHOT" suffix
+strip_snapshot_suffix() {
+ [[ -n $1 ]] || { echo "missing get_relase_version() argument" >&2; return 1; }
+ if [[ $1 =~ ^(.*)\.BUILD-SNAPSHOT$ ]]; then
+ echo "${BASH_REMATCH[1]}"
+ elif [[ $1 =~ ^(.*)-SNAPSHOT$ ]]; then
+ echo "${BASH_REMATCH[1]}"
+ else
+ echo "$1"
+ fi
+}
+
+# Bump version number by incrementing the last numeric, RC or M token
+bump_version_number() {
+ local version=$1
+ [[ -n $version ]] || { echo "missing bump_version_number() argument" >&2; return 1; }
+ if [[ $version =~ ^(.*(\.|-)([A-Za-z]+))([0-9]+)$ ]]; then
+ local prefix=${BASH_REMATCH[1]}
+ local suffix=${BASH_REMATCH[4]}
+ (( suffix++ ))
+ echo "${prefix}${suffix}"
+ return 0;
+ fi
+ local suffix
+ if [[ $version =~ ^(.*)(\-SNAPSHOT)$ ]]; then
+ version=${BASH_REMATCH[1]}
+ suffix="-SNAPSHOT"
+ fi
+ tokens=(${version//\./ })
+ local bumpIndex
+ for i in "${!tokens[@]}"; do
+ if [[ "${tokens[$i]}" =~ ^[0-9]+$ ]] ; then
+ bumpIndex=$i
+ fi
+ done
+ [[ -n $bumpIndex ]] || { echo "unsupported version number" >&2; return 1; }
+ (( tokens[bumpIndex]++ ))
+ local bumpedVersion
+ IFS=. eval 'bumpedVersion="${tokens[*]}"'
+ echo "${bumpedVersion}${suffix}"
+}
+
+# Deduce versions
+deduce_versions() {
+ [[ -n ${GITHUB_OUTPUT} ]] || { echo "missing GITHUB_OUTPUT environment variable" >&2; return 1; }
+ [[ -n ${CURRENT_VERSION} ]] || { echo "missing CURRENT_VERSION environment variable" >&2; return 1; }
+ [[ -n ${RELEASE_TYPE} ]] || { echo "missing RELEASE_TYPE environment variable" >&2; return 1; }
+ if [[ ${RELEASE_TYPE,,} = "milestone" ]]; then
+ releaseVersion=$( get_next_milestone_release ${CURRENT_VERSION})
+ nextVersion=${CURRENT_VERSION}
+ elif [[ ${RELEASE_TYPE,,} = "release-candidate" ]]; then
+ releaseVersion=$( get_next_rc_release ${CURRENT_VERSION})
+ nextVersion=${CURRENT_VERSION}
+ elif [[ ${RELEASE_TYPE,,} = "release" ]]; then
+ releaseVersion=$( get_next_release ${CURRENT_VERSION})
+ nextVersion=$( bump_version_number ${CURRENT_VERSION})
+ else
+ echo "Unknown release type '${RELEASE_TYPE}'" >&2; exit 1;
+ fi
+ echo "release-version=${releaseVersion}" >> "$GITHUB_OUTPUT"
+ echo "next-version=${nextVersion}" >> "$GITHUB_OUTPUT"
+}
diff --git a/.github/actions/deduce-versions/test.sh b/.github/actions/deduce-versions/test.sh
new file mode 100755
index 00000000..0a8e4130
--- /dev/null
+++ b/.github/actions/deduce-versions/test.sh
@@ -0,0 +1 @@
+../.bats/bats/bin/bats test/*.bats
\ No newline at end of file
diff --git a/.github/actions/deduce-versions/test/bump_version.bats b/.github/actions/deduce-versions/test/bump_version.bats
new file mode 100644
index 00000000..5efd9f0b
--- /dev/null
+++ b/.github/actions/deduce-versions/test/bump_version.bats
@@ -0,0 +1,58 @@
+#!./test/libs/bats/bin/bats
+
+load '../../.bats/test_helper/bats-support/load'
+load '../../.bats/test_helper/bats-assert/load'
+
+source "$PWD/deduce-versions.sh"
+
+@test "bump_version_number() should bump '.M'" {
+ run bump_version_number "1.2.0.M2"
+ assert_output "1.2.0.M3"
+}
+
+@test "bump_version_number() should bump '.RC'" {
+ run bump_version_number "1.2.0.RC3"
+ assert_output "1.2.0.RC4"
+}
+
+@test "bump_version_number() should bump '-M'" {
+ run bump_version_number "1.2.0-M2"
+ assert_output "1.2.0-M3"
+}
+
+@test "bump_version_number() should bump '-RC'" {
+ run bump_version_number "1.2.0-RC3"
+ assert_output "1.2.0-RC4"
+}
+
+@test "bump_version_number() should bump without suffix" {
+ run bump_version_number "1.2.0"
+ assert_output "1.2.1"
+}
+
+@test "bump_version_number() should bump '.RELEASE'" {
+ run bump_version_number "1.2.0.RELEASE"
+ assert_output "1.2.1.RELEASE"
+}
+
+@test "bump_version_number() should bump '-SNAPSHOT'" {
+ run bump_version_number "1.2.0-SNAPSHOT"
+ assert_output "1.2.1-SNAPSHOT"
+}
+
+@test "bump_version_number() should bump '.BUILD-SNAPSHOT'" {
+ run bump_version_number "1.2.0.BUILD-SNAPSHOT"
+ assert_output "1.2.1.BUILD-SNAPSHOT"
+}
+
+@test "bump_version_number() when missing argument should fail" {
+ run bump_version_number
+ assert_output "missing bump_version_number() argument"
+ assert [ "$status" -eq 1 ]
+}
+
+@test "bump_version_number() when bad argument should fail" {
+ run bump_version_number "foo.bar.baz"
+ assert_output "unsupported version number"
+ assert [ "$status" -eq 1 ]
+}
diff --git a/.github/actions/deduce-versions/test/deduce_versions.bats b/.github/actions/deduce-versions/test/deduce_versions.bats
new file mode 100644
index 00000000..2ffbf599
--- /dev/null
+++ b/.github/actions/deduce-versions/test/deduce_versions.bats
@@ -0,0 +1,96 @@
+#!./test/libs/bats/bin/bats
+
+load '../../.bats/test_helper/bats-support/load'
+load '../../.bats/test_helper/bats-assert/load'
+
+source "$PWD/deduce-versions.sh"
+
+teardown() {
+ rm .githuboutput | true
+}
+
+@test "deduce_versions() when 'milestone' should export versions" {
+ repo=$( mock_git_repo "v1.2.3-M1" )
+ cd "$repo"
+ GITHUB_OUTPUT=".githuboutput"
+ CURRENT_VERSION="1.2.3-SNAPSHOT"
+ RELEASE_TYPE="milestone"
+ run deduce_versions
+ readarray -t githuboutput < .githuboutput
+ assert [ "$status" -eq 0 ]
+ assert [ "${githuboutput[0]}" = "release-version=1.2.3-M2" ]
+ assert [ "${githuboutput[1]}" = "next-version=1.2.3-SNAPSHOT" ]
+}
+
+@test "deduce_versions() when 'release-candidate' should export versions" {
+ repo=$( mock_git_repo "v1.2.3-M1" "v1.2.3-M2" "v1.2.3-RC1" )
+ cd "$repo"
+ GITHUB_OUTPUT=".githuboutput"
+ CURRENT_VERSION="1.2.3-SNAPSHOT"
+ RELEASE_TYPE="release-candidate"
+ run deduce_versions
+ readarray -t githuboutput < .githuboutput
+ assert [ "$status" -eq 0 ]
+ assert [ "${githuboutput[0]}" = "release-version=1.2.3-RC2" ]
+ assert [ "${githuboutput[1]}" = "next-version=1.2.3-SNAPSHOT" ]
+}
+
+@test "deduce_versions() when 'release' should export versions" {
+ repo=$( mock_git_repo "v1.2.3-M1" "v1.2.3-M2" "v1.2.3-RC1" )
+ cd "$repo"
+ GITHUB_OUTPUT=".githuboutput"
+ CURRENT_VERSION="1.2.3-SNAPSHOT"
+ RELEASE_TYPE="release"
+ run deduce_versions
+ readarray -t githuboutput < .githuboutput
+ assert [ "$status" -eq 0 ]
+ assert [ "${githuboutput[0]}" = "release-version=1.2.3" ]
+ assert [ "${githuboutput[1]}" = "next-version=1.2.4-SNAPSHOT" ]
+}
+
+@test "deduce_versions() when no GITHUB_OUTPUT should fail" {
+ CURRENT_VERSION="1.2.3-SNAPSHOT"
+ RELEASE_TYPE="release"
+ run deduce_versions
+ assert [ "$status" -eq 1 ]
+ assert_output "missing GITHUB_OUTPUT environment variable"
+}
+
+@test "deduce_versions() when no CURRENT_VERSION should fail" {
+ GITHUB_OUTPUT=".githuboutput"
+ RELEASE_TYPE="release"
+ run deduce_versions
+ assert [ "$status" -eq 1 ]
+ assert_output "missing CURRENT_VERSION environment variable"
+}
+
+@test "deduce_versions() when no RELEASE_TYPE should fail" {
+ GITHUB_OUTPUT=".githuboutput"
+ CURRENT_VERSION="1.2.3-SNAPSHOT"
+ run deduce_versions
+ assert [ "$status" -eq 1 ]
+ assert_output "missing RELEASE_TYPE environment variable"
+}
+
+@test "deduce_versions() when wrong RELEASE_TYPE should fail" {
+ GITHUB_OUTPUT=".githuboutput"
+ CURRENT_VERSION="1.2.3-SNAPSHOT"
+ RELEASE_TYPE="nope"
+ run deduce_versions
+ assert [ "$status" -eq 1 ]
+ assert_output "Unknown release type 'nope'"
+}
+
+mock_git_repo() {
+ local tmpdir=$(mktemp -d $BATS_TMPDIR/gitrepo.XXXXXX) >&2
+ mkdir -p "$tmpdir" >&2
+ cd "$tmpdir" >&2
+ git init >&2
+ echo "foo" > foo.txt
+ git add foo.txt >&2
+ git commit -m'Initial commit' >&2
+ for tag in "$@"; do
+ git tag "$tag" >&2
+ done
+ echo "$tmpdir"
+}
\ No newline at end of file
diff --git a/.github/actions/deduce-versions/test/get_next_release.bats b/.github/actions/deduce-versions/test/get_next_release.bats
new file mode 100644
index 00000000..b9be5c0e
--- /dev/null
+++ b/.github/actions/deduce-versions/test/get_next_release.bats
@@ -0,0 +1,119 @@
+#!./test/libs/bats/bin/bats
+
+load '../../.bats/test_helper/bats-support/load'
+load '../../.bats/test_helper/bats-assert/load'
+
+source "$PWD/deduce-versions.sh"
+
+@test "get_next_milestone_release() when has no version should fail" {
+ run get_next_milestone_release
+ assert [ "$status" -eq 1 ]
+ assert_output "missing get_next_milestone_release() version argument"
+}
+
+@test "get_next_rc_release() when has no version should fail" {
+ run get_next_rc_release
+ assert [ "$status" -eq 1 ]
+ assert_output "missing get_next_rc_release() version argument"
+}
+
+@test "get_next_tag_based_release() when has no version should fail" {
+ run get_next_tag_based_release
+ assert [ "$status" -eq 1 ]
+ assert_output "missing get_next_tag_based_release() version argument"
+}
+
+@test "get_next_tag_based_release() when has no tag type should fail" {
+ run get_next_tag_based_release "1.2.3"
+ assert [ "$status" -eq 1 ]
+ assert_output "missing get_next_tag_based_release() tag type argument"
+}
+
+@test "get_next_milestone_release() when has no tag should return M1" {
+ repo=$( mock_git_repo )
+ cd "$repo"
+ run get_next_milestone_release "1.2.3-SNAPSHOT"
+ assert_output "1.2.3-M1"
+}
+
+@test "get_next_rc_release() when has no tag should return RC1" {
+ repo=$( mock_git_repo )
+ cd "$repo"
+ run get_next_rc_release "1.2.3-SNAPSHOT"
+ assert_output "1.2.3-RC1"
+}
+
+@test "get_next_tag_based_release() when has no tag and dash SNAPSHOT suffix should return dashed X1" {
+ repo=$( mock_git_repo )
+ cd "$repo"
+ run get_next_tag_based_release "1.2.3-SNAPSHOT" "X"
+ assert_output "1.2.3-X1"
+}
+
+@test "get_next_tag_based_release() when has no tag and dash BUILD-SNAPSHOT suffix should return dashed X1" {
+ repo=$( mock_git_repo )
+ cd "$repo"
+ run get_next_tag_based_release "1.2.3.BUILD-SNAPSHOT" "X"
+ assert_output "1.2.3.X1"
+}
+
+@test "get_next_tag_based_release() when has tags and dashed should return dashed X tag+1" {
+ repo=$( mock_git_repo "v1.2.3-X1" "v1.2.3-X3" "v1.2.3-X2" )
+ cd "$repo"
+ run get_next_tag_based_release "1.2.3-SNAPSHOT" "X"
+ assert_output "1.2.3-X4"
+}
+
+@test "get_next_tag_based_release() when has tags and dashed should return dot X tag+1" {
+ repo=$( mock_git_repo "v1.2.3.X1" "v1.2.3.X3" "v1.2.3.X2" )
+ cd "$repo"
+ run get_next_tag_based_release "1.2.3.BUILD-SNAPSHOT" "X"
+ assert_output "1.2.3.X4"
+}
+
+@test "get_next_tag_based_release() when has multiple tags should return version match tag+1" {
+ repo=$( mock_git_repo "v1.5.0.A1" "v1.5.0.A2" "v1.5.0.B1" "v2.0.0.A1" "v2.0.0.B1" "v2.0.0.B2" )
+ cd "$repo"
+ run get_next_tag_based_release "1.5.0.BUILD-SNAPSHOT" "A"
+ assert_output "1.5.0.A3"
+ run get_next_tag_based_release "1.5.0.BUILD-SNAPSHOT" "B"
+ assert_output "1.5.0.B2"
+ run get_next_tag_based_release "2.0.0.BUILD-SNAPSHOT" "A"
+ assert_output "2.0.0.A2"
+ run get_next_tag_based_release "2.0.0.BUILD-SNAPSHOT" "B"
+ assert_output "2.0.0.B3"
+}
+
+@test "get_next_release() should return next release version with release suffix" {
+ run get_next_release "1.5.0.BUILD-SNAPSHOT" "RELEASE"
+ assert_output "1.5.0.RELEASE"
+ run get_next_release "1.5.0-SNAPSHOT" "RELEASE"
+ assert_output "1.5.0-RELEASE"
+}
+
+@test "get_next_release() should return next release version" {
+ run get_next_release "1.5.0.BUILD-SNAPSHOT"
+ assert_output "1.5.0"
+ run get_next_release "1.5.0-SNAPSHOT"
+ assert_output "1.5.0"
+}
+
+@test "get_next_release() when has no version should fail" {
+ run get_next_release
+ assert [ "$status" -eq 1 ]
+ assert_output "missing get_next_release() version argument"
+}
+
+mock_git_repo() {
+ local tmpdir=$(mktemp -d $BATS_TMPDIR/gitrepo.XXXXXX) >&2
+ mkdir -p "$tmpdir" >&2
+ cd "$tmpdir" >&2
+ git init >&2
+ echo "foo" > foo.txt
+ git add foo.txt >&2
+ git commit -m'Initial commit' >&2
+ for tag in "$@"; do
+ git tag "$tag" >&2
+ done
+ echo "$tmpdir"
+}
diff --git a/.github/actions/deduce-versions/test/strip_snapshot_suffix.bats b/.github/actions/deduce-versions/test/strip_snapshot_suffix.bats
new file mode 100644
index 00000000..bef64867
--- /dev/null
+++ b/.github/actions/deduce-versions/test/strip_snapshot_suffix.bats
@@ -0,0 +1,21 @@
+#!./test/libs/bats/bin/bats
+
+load '../../.bats/test_helper/bats-support/load'
+load '../../.bats/test_helper/bats-assert/load'
+
+source "$PWD/deduce-versions.sh"
+
+@test "strip_snapshot_suffix() should strip '-SNAPSHOT" {
+ run strip_snapshot_suffix "1.2.0-SNAPSHOT"
+ assert_output "1.2.0"
+}
+
+@test "strip_snapshot_suffix() should strip '.BUILD-SNAPSHOT" {
+ run strip_snapshot_suffix "1.2.0.BUILD-SNAPSHOT"
+ assert_output "1.2.0"
+}
+
+@test "strip_snapshot_suffix() when no suffix should return unchanged" {
+ run strip_snapshot_suffix "1.2.0"
+ assert_output "1.2.0"
+}
diff --git a/.github/actions/publish-eclipse-update-site/action.yml b/.github/actions/publish-eclipse-update-site/action.yml
new file mode 100644
index 00000000..4235c9e8
--- /dev/null
+++ b/.github/actions/publish-eclipse-update-site/action.yml
@@ -0,0 +1,22 @@
+name: 'Publish Eclipse Update Site '
+inputs:
+ version:
+ required: true
+ build-number:
+ required: true
+ artifactory-username:
+ required: true
+ artifactory-password:
+ required: true
+runs:
+ using: composite
+ steps:
+ - name: Stage
+ id: stage
+ shell: bash
+ run: . ${{ github.action_path }}/publish-eclipse-update-site.sh;
+ env:
+ VERSION: "${{ inputs.version }}"
+ BUILD_NUMBER: "${{ inputs.build-number }}"
+ ARTIFACTORY_USERNAME: "${{ inputs.artifactory-username }}"
+ ARTIFACTORY_PASSWORD: "${{ inputs.artifactory-password }}"
diff --git a/ci/scripts/publish-eclipse-update-site-pom-template.xml b/.github/actions/publish-eclipse-update-site/publish-eclipse-update-site-pom-template.xml
similarity index 100%
rename from ci/scripts/publish-eclipse-update-site-pom-template.xml
rename to .github/actions/publish-eclipse-update-site/publish-eclipse-update-site-pom-template.xml
diff --git a/ci/scripts/publish-eclipse-update-site.sh b/.github/actions/publish-eclipse-update-site/publish-eclipse-update-site.sh
old mode 100755
new mode 100644
similarity index 59%
rename from ci/scripts/publish-eclipse-update-site.sh
rename to .github/actions/publish-eclipse-update-site/publish-eclipse-update-site.sh
index 761f74c3..9ddcee29
--- a/ci/scripts/publish-eclipse-update-site.sh
+++ b/.github/actions/publish-eclipse-update-site/publish-eclipse-update-site.sh
@@ -1,14 +1,11 @@
-#!/bin/bash
-set -e
+buildInfo=$( jfrog rt curl api/build/spring-javaformat-${VERSION}/${BUILD_NUMBER} )
+groupId=$( echo ${buildInfo} | jq -r '.buildInfo.modules[0].id' | sed 's/\(.*\):.*:.*/\1/' )
+version=$( echo ${buildInfo} | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
-source $(dirname $0)/common.sh
+echo "Publishing ${buildName}/${buildNumber} (${groupId}:${version}) to Eclipse Update Site"
-buildName=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.name' )
-buildNumber=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.number' )
-groupId=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/\(.*\):.*:.*/\1/' )
-version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
+jfrog rt dl --build spring-javaformat-${VERSION}/${BUILD_NUMBER} '**/io.spring.javaformat.eclipse.site*.zip'
-echo "Publishing ${buildName}/${buildNumber} to Eclipse Update Site"
curl \
-s \
--connect-timeout 240 \
@@ -17,7 +14,7 @@ curl \
-f \
-H "X-Explode-Archive: true" \
-X PUT \
- -T "artifactory-repo/io/spring/javaformat/io.spring.javaformat.eclipse.site/${version}/io.spring.javaformat.eclipse.site-${version}.zip" \
+ -T "io/spring/javaformat/io.spring.javaformat.eclipse.site/${version}/io.spring.javaformat.eclipse.site-${version}.zip" \
"https://repo.spring.io/javaformat-eclipse-update-site/${version}/" > /dev/null || { echo "Failed to publish" >&2; exit 1; }
releasedVersions=$( curl -s -f -X GET https://repo.spring.io/api/storage/javaformat-eclipse-update-site | jq -r '.children[] | .uri' | cut -c 2- | grep '[0-9].*' | sort -V )
@@ -28,9 +25,8 @@ while read -r releasedVersion; do
repositories="${repositories}https://repo.spring.io/javaformat-eclipse-update-site/${releasedVersion}p2"
done <<< "${releasedVersions}"
-pushd git-repo > /dev/null
-sed "s|##repositories##|${repositories}|" ci/scripts/publish-eclipse-update-site-pom-template.xml > publish-eclipse-update-site-pom.xml
-run_maven -f publish-eclipse-update-site-pom.xml clean package || { echo "Failed to publish" >&2; exit 1; }
+sed "s|##repositories##|${repositories}|" ${GITHUB_ACTION_PATH}/publish-eclipse-update-site-pom-template.xml > publish-eclipse-update-site-pom.xml
+./mvnw -f publish-eclipse-update-site-pom.xml clean package || { echo "Failed to publish" >&2; exit 1; }
curl \
-s \
@@ -52,6 +48,4 @@ curl \
-T "target/repository/artifacts.jar" \
"https://repo.spring.io/javaformat-eclipse-update-site/" > /dev/null || { echo "Failed to publish" >&2; exit 1; }
-popd > /dev/null
-
echo "Publish complete"
diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml
new file mode 100644
index 00000000..c1d38d98
--- /dev/null
+++ b/.github/actions/setup/action.yml
@@ -0,0 +1,16 @@
+name: 'Setup'
+runs:
+ using: composite
+ steps:
+ - name: Set Up Utilities
+ shell: bash
+ run: sudo apt-get update && sudo apt-get -y install libxml2-utils
+ - name: Set Up Java
+ uses: actions/setup-java@v4
+ with:
+ distribution: 'liberica'
+ java-version: '17'
+ cache: maven
+ - name: Disable Java Problem Matcher
+ shell: bash
+ run: echo "::remove-matcher owner=java::"
diff --git a/.github/actions/stage-code/action.yml b/.github/actions/stage-code/action.yml
new file mode 100644
index 00000000..1fc1f060
--- /dev/null
+++ b/.github/actions/stage-code/action.yml
@@ -0,0 +1,22 @@
+name: 'Stage '
+inputs:
+ current-version:
+ required: true
+ release-version:
+ required: true
+ next-version:
+ required: true
+outputs:
+ distribution-repository:
+ value: ${{ steps.stage.outputs.distribution-repository }}
+runs:
+ using: composite
+ steps:
+ - name: Stage
+ id: stage
+ shell: bash
+ run: . ${{ github.action_path }}/stage.sh;
+ env:
+ CURRENT_VERSION: "${{ inputs.current-version }}"
+ RELEASE_VERSION: "${{ inputs.release-version }}"
+ NEXT_VERSION: "${{ inputs.next-version }}"
diff --git a/.github/actions/stage-code/stage.sh b/.github/actions/stage-code/stage.sh
new file mode 100644
index 00000000..6ac9c2f0
--- /dev/null
+++ b/.github/actions/stage-code/stage.sh
@@ -0,0 +1,32 @@
+repository=${GITHUB_WORKSPACE}/distribution-repository
+
+echo "Staging ${RELEASE_VERSION} to ${repository} (next version will be ${NEXT_VERSION})"
+
+./mvnw versions:set --batch-mode --no-transfer-progress -DnewVersion=${RELEASE_VERSION} -DgenerateBackupPoms=false
+./mvnw org.eclipse.tycho:tycho-versions-plugin:update-eclipse-metadata --batch-mode --no-transfer-progress
+./mvnw --projects io.spring.javaformat:spring-javaformat-vscode-extension --batch-mode --no-transfer-progress -P '!formatter-dependencies' antrun:run@update-version frontend:install-node-and-npm frontend:npm@update-package-lock
+
+git config user.name "Spring Builds" > /dev/null
+git config user.email "spring-builds@users.noreply.github.com" > /dev/null
+git add pom.xml > /dev/null
+git commit -m"Release v${RELEASE_VERSION}" > /dev/null
+git tag -a "v${RELEASE_VERSION}" -m"Release v${RELEASE_VERSION}" > /dev/null
+
+./mvnw clean deploy --batch-mode --no-transfer-progress -U -Dfull -DaltDeploymentRepository=distribution::file://${repository}
+
+git reset --hard HEAD^ > /dev/null
+if [[ ${NEXT_VERSION} != ${CURRENT_VERSION} ]]; then
+ echo "Setting next development version (v${NEXT_VERSION})"
+ ./mvnw versions:set --batch-mode --no-transfer-progress -DnewVersion=${NEXT_VERSION} -DgenerateBackupPoms=false
+ ./mvnw org.eclipse.tycho:tycho-versions-plugin:update-eclipse-metadata --batch-mode --no-transfer-progress
+ ./mvnw --projects io.spring.javaformat:spring-javaformat-vscode-extension --batch-mode --no-transfer-progress -P '!formatter-dependencies' antrun:run@update-version frontend:npm@update-package-lock
+ sed -i "s/:release-version:.*/:release-version: ${RELEASE_VERSION}/g" README.adoc
+ sed -i "s/spring-javaformat-gradle-plugin:.*/spring-javaformat-gradle-plugin:${NEXT_VERSION}\"\)/g" samples/spring-javaformat-gradle-sample/build.gradle
+ sed -i "s/spring-javaformat-checkstyle:.*/spring-javaformat-checkstyle:${NEXT_VERSION}\"\)/g" samples/spring-javaformat-gradle-sample/build.gradle
+ sed -i "s|.*|${NEXT_VERSION}|" samples/spring-javaformat-maven-sample/pom.xml
+ git add -u . > /dev/null
+ git commit -m"Next development version (v${NEXT_VERSION})" > /dev/null
+fi;
+
+echo "Staged the following files:"
+find ${repository}
diff --git a/.github/artifacts.spec b/.github/artifacts.spec
new file mode 100644
index 00000000..0f6c3aac
--- /dev/null
+++ b/.github/artifacts.spec
@@ -0,0 +1,23 @@
+{
+ "files": [
+ {
+ "aql": {
+ "items.find": {
+ "$and": [
+ {
+ "@build.name": "${buildName}",
+ "@build.number": "${buildNumber}",
+ "name": {
+ "$nmatch": "*.zip"
+ },
+ "name": {
+ "$nmatch": "*.zip.asc"
+ }
+ }
+ ]
+ }
+ },
+ "target": "nexus/"
+ }
+ ]
+}
diff --git a/.github/dco.yml b/.github/dco.yml
new file mode 100644
index 00000000..0c4b142e
--- /dev/null
+++ b/.github/dco.yml
@@ -0,0 +1,2 @@
+require:
+ members: false
diff --git a/.github/workflows/build-and-deploy-snapshot.yml b/.github/workflows/build-and-deploy-snapshot.yml
new file mode 100644
index 00000000..d269a903
--- /dev/null
+++ b/.github/workflows/build-and-deploy-snapshot.yml
@@ -0,0 +1,30 @@
+name: Build and Deploy Snapshot
+on:
+ push:
+ branches:
+ - main
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+jobs:
+ build-and-deploy-snapshot:
+ name: Build and Deploy Snapshot
+ runs-on: ubuntu-latest
+ if: ${{ github.repository == 'spring-io/spring-javaformat' }}
+ steps:
+ - name: Check Out
+ uses: actions/checkout@v4
+ - name: Set Up
+ uses: ./.github/actions/setup
+ - name: Build
+ run: ./mvnw clean deploy --batch-mode --no-transfer-progress --update-snapshots -DaltDeploymentRepository=distribution::file://$(pwd)/distribution-repository
+ - name: Deploy
+ uses: spring-io/artifactory-deploy-action@v0.0.1
+ with:
+ folder: 'distribution-repository'
+ uri: 'https://repo.spring.io'
+ repository: 'libs-snapshot-local'
+ build-name: spring-javaformat
+ username: ${{ secrets.ARTIFACTORY_USERNAME }}
+ password: ${{ secrets.ARTIFACTORY_PASSWORD }}
+ signing-key: ${{ secrets.GPG_PRIVATE_KEY }}
+ signing-passphrase: ${{ secrets.GPG_PASSPHRASE }}
diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml
new file mode 100644
index 00000000..9e085b69
--- /dev/null
+++ b/.github/workflows/build-pull-request.yml
@@ -0,0 +1,16 @@
+name: Build Pull Request
+on: pull_request
+permissions:
+ contents: read
+jobs:
+ build:
+ name: Build Pull Request
+ runs-on: ubuntu-latest
+ if: ${{ github.repository == 'spring-io/spring-javaformat' }}
+ steps:
+ - name: Check Out
+ uses: actions/checkout@v4
+ - name: Set Up
+ uses: ./.github/actions/setup
+ - name: Build
+ run: ./mvnw clean install --batch-mode --no-transfer-progress --update-snapshots
diff --git a/.github/workflows/promote.yml b/.github/workflows/promote.yml
new file mode 100644
index 00000000..e1faac58
--- /dev/null
+++ b/.github/workflows/promote.yml
@@ -0,0 +1,92 @@
+name: Promote
+run-name: >-
+ Promote of version ${{ inputs.version }} (build number ${{ inputs.build-number}}) by ${{ github.actor }} to '${{ inputs.environment }}' environment'
+on:
+ workflow_call:
+ inputs:
+ environment:
+ type: string
+ required: true
+ version:
+ type: string
+ required: true
+ build-number:
+ type: string
+ required: true
+ workflow_dispatch:
+ inputs:
+ environment:
+ description: Environment
+ type: environment
+ required: true
+ version:
+ description: The version number to promote
+ type: string
+ required: true
+ build-number:
+ description: The build number to promote
+ type: string
+ required: true
+jobs:
+ promote:
+ environment: ${{ inputs.environment }}
+ name: Promote
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check Out
+ uses: actions/checkout@v4
+ - name: Set Up JFrog CLI
+ uses: jfrog/setup-jfrog-cli@ff5cb544114ffc152db9cea1cd3d5978d5074946 # v4.5.11
+ env:
+ JF_ENV_SPRING: ${{ secrets.JF_ARTIFACTORY_SPRING }}
+ - name: Check Maven Central Sync Status
+ id: check-sync-status
+ run: |
+ url=${{ format('https://repo.maven.apache.org/maven2/io/spring/javaformat/spring-javaformat/{0}/spring-javaformat-{0}.pom', inputs.version) }}
+ status_code=$( curl --write-out '%{http_code}' --head --silent --output /dev/null ${url} )
+ if [ "${status_code}" != 200 ] && [ "${status_code}" != 404 ]; then
+ echo "Unexpected status code ${status_code}"
+ exit 1
+ fi
+ echo "status-code=${status_code}" >> $GITHUB_OUTPUT
+ - name: Download Release Artifacts
+ if: ${{ steps.check-sync-status.outputs.status-code == '404' }}
+ run: jf rt download --spec ./.github/artifacts.spec --spec-vars 'buildName=${{ format('spring-javaformat-{0}', inputs.version) }};buildNumber=${{ inputs.build-number }}'
+ - name: Sync to Maven Central
+ if: ${{ steps.check-sync-status.outputs.status-code == '404' }}
+ uses: spring-io/nexus-sync-action@v0.0.1
+ with:
+ username: ${{ secrets.OSSRH_S01_TOKEN_USERNAME }}
+ password: ${{ secrets.OSSRH_S01_TOKEN_PASSWORD }}
+ staging-profile-name: ${{ secrets.OSSRH_S01_STAGING_PROFILE }}
+ create: true
+ upload: true
+ close: true
+ release: true
+ generate-checksums: true
+ - name: Await Maven Central Sync
+ if: ${{ steps.check-sync-status.outputs.status-code == '404' }}
+ run: |
+ url=${{ format('https://repo.maven.apache.org/maven2/io/spring/javaformat/spring-javaformat/{0}/spring-javaformat-{0}.pom', inputs.version) }}
+ echo "Waiting for $url"
+ until curl --fail --head --silent $url > /dev/null
+ do
+ echo "."
+ sleep 60
+ done
+ echo "$url is available"
+ - name: Promote Build
+ if: ${{ steps.check-sync-status.outputs.status-code == '404' }}
+ run: jfrog rt build-promote ${{ format('spring-javaformat-{0}', inputs.version)}} ${{ inputs.build-number }} libs-release-local
+ - name: Publish Eclipse Update Site
+ uses: ./.github/actions/publish-eclipse-update-site
+ with:
+ version: ${{ inputs.version }}
+ build-number: ${{ inputs.build-number }}
+ artifactory-username: ${{ secrets.ARTIFACTORY_USERNAME }}
+ artifactory-password: ${{ secrets.ARTIFACTORY_PASSWORD }}
+ - name: Create GitHub Release
+ uses: ./.github/actions/create-github-release
+ with:
+ milestone: ${{ inputs.version }}
+ token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 00000000..c80a4091
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,59 @@
+name: Release
+run-name: >-
+ Release of '${{ github.ref_name }}' branch to '${{ inputs.environment }}' environment by ${{ github.actor }}
+on:
+ workflow_dispatch:
+ inputs:
+ environment:
+ description: Environment
+ type: environment
+ required: true
+jobs:
+ stage:
+ name: Stage
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check Out
+ uses: actions/checkout@v4
+ - name: Set Up
+ uses: ./.github/actions/setup
+ - name: Get Current Version
+ id: get-version
+ run: echo "current-version=$(xmllint --xpath '/*[local-name()="project"]/*[local-name()="version"]/text()' pom.xml)" >> $GITHUB_OUTPUT
+ - name: Deduce Versions
+ id: deduce-versions
+ uses: ./.github/actions/deduce-versions
+ with:
+ current-version: ${{ steps.get-version.outputs.current-version }}
+ release-type: ${{ inputs.environment }}
+ - name: Stage Code
+ id: stage-code
+ uses: ./.github/actions/stage-code
+ with:
+ current-version: ${{ steps.get-version.outputs.current-version }}
+ release-version: ${{ steps.deduce-versions.outputs.release-version }}
+ next-version: ${{ steps.deduce-versions.outputs.next-version }}
+ - name: Deploy to Staging
+ uses: spring-io/artifactory-deploy-action@v0.0.1
+ with:
+ folder: distribution-repository
+ uri: 'https://repo.spring.io'
+ repository: 'libs-staging-local'
+ build-name: ${{ format('spring-javaformat-{0}', steps.deduce-versions.outputs.release-version)}}
+ username: ${{ secrets.ARTIFACTORY_USERNAME }}
+ password: ${{ secrets.ARTIFACTORY_PASSWORD }}
+ signing-key: ${{ secrets.GPG_PRIVATE_KEY }}
+ signing-passphrase: ${{ secrets.GPG_PASSPHRASE }}
+ - name: Push
+ run: git push origin HEAD --tags
+ outputs:
+ release-version: ${{ steps.deduce-versions.outputs.release-version }}
+ release-build-number: ${{ github.run_number }}
+ promote:
+ name: Promote
+ needs: stage
+ uses: ./.github/workflows/promote.yml
+ with:
+ environment: ${{ inputs.environment }}
+ version: ${{needs.stage.outputs.release-version}}
+ build-number: ${{ needs.stage.outputs.release-build-number }}
diff --git a/.github/workflows/rollback.yml b/.github/workflows/rollback.yml
new file mode 100644
index 00000000..43e04a4d
--- /dev/null
+++ b/.github/workflows/rollback.yml
@@ -0,0 +1,41 @@
+name: Rollback
+run-name: >-
+ Rollback of version ${{ inputs.version }} (build number ${{ inputs.build-number}}) by ${{ github.actor }}
+on:
+ workflow_dispatch:
+ inputs:
+ environment:
+ description: Environment
+ type: environment
+ required: true
+ version:
+ description: The version number to roll back
+ type: string
+ required: true
+ build-number:
+ description: The build number to roll back
+ type: string
+ required: true
+jobs:
+ rollback:
+ environment: ${{ inputs.environment }}
+ name: Roll Back
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check Out
+ uses: actions/checkout@v4
+ - name: Set Up JFrog CLI
+ uses: jfrog/setup-jfrog-cli@7c95feb32008765e1b4e626b078dfd897c4340ad # v4.1.2
+ env:
+ JF_ENV_SPRING: ${{ secrets.JF_ARTIFACTORY_SPRING }}
+ - name: Delete Staged Artifacts
+ run: |
+ url=${{ format('libs-staging-local/io/spring/javaformat/spring-javaformat/{0}/spring-javaformat-{0}.pom', inputs.version) }}
+ artifact_count=$( jf rt s ${url} --count )
+ if [ "${artifact_count}" != 1 ]; then
+ echo "Unexpected aretifact count ${artifact_count}"
+ exit 1
+ fi
+ build_name=${{ format('spring-javaformat-{0}', inputs.version)}}
+ build_number=${{ inputs.build-number }}
+ jf rt delete --build ${build_name}/${build_number}
diff --git a/.gitignore b/.gitignore
index e43e9edb..20cd4cfc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,8 @@ target
*.ipr
*.iws
spring-javaformat-eclipse/io.spring.javaformat.eclipse/lib
+spring-javaformat-eclipse/io.spring.javaformat.eclipse.feature/lib
+spring-javaformat-eclipse/io.spring.javaformat.eclipse.site/lib
spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/lib
.gradle
spring-javaformat-gradle/spring-javaformat-gradle-plugin/bin
@@ -20,3 +22,12 @@ spring-javaformat/spring-javaformat-checkstyle/bin
spring-javaformat/spring-javaformat-formatter-eclipse-rewriter/bin
build.log
pid
+.factorypath
+
+# npm
+node_modules/
+
+# vscode
+spring-javaformat-vscode/spring-javaformat/out/
+spring-javaformat-vscode/spring-javaformat/runtime/
+*.vsix
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..64d1aa9d
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,12 @@
+[submodule ".github/actions/.bats/bats"]
+ path = .github/actions/.bats/bats
+ url = https://github.com/bats-core/bats-core.git
+ tag = v1.11.0
+[submodule ".github/actions/.bats/test_helper/bats-support"]
+ path = .github/actions/.bats/test_helper/bats-support
+ url = https://github.com/bats-core/bats-support.git
+ tag = v0.3.0
+[submodule ".github/actions/.bats/test_helper/bats-assert"]
+ path = .github/actions/.bats/test_helper/bats-assert
+ url = https://github.com/bats-core/bats-assert.git
+ tag = v2.1.0
diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java
deleted file mode 100644
index b901097f..00000000
--- a/.mvn/wrapper/MavenWrapperDownloader.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright 2007-present 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.
- */
-import java.net.*;
-import java.io.*;
-import java.nio.channels.*;
-import java.util.Properties;
-
-public class MavenWrapperDownloader {
-
- private static final String WRAPPER_VERSION = "0.5.6";
- /**
- * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
- */
- private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
- + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
-
- /**
- * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
- * use instead of the default one.
- */
- private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
- ".mvn/wrapper/maven-wrapper.properties";
-
- /**
- * Path where the maven-wrapper.jar will be saved to.
- */
- private static final String MAVEN_WRAPPER_JAR_PATH =
- ".mvn/wrapper/maven-wrapper.jar";
-
- /**
- * Name of the property which should be used to override the default download url for the wrapper.
- */
- private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
-
- public static void main(String args[]) {
- System.out.println("- Downloader started");
- File baseDirectory = new File(args[0]);
- System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
-
- // If the maven-wrapper.properties exists, read it and check if it contains a custom
- // wrapperUrl parameter.
- File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
- String url = DEFAULT_DOWNLOAD_URL;
- if(mavenWrapperPropertyFile.exists()) {
- FileInputStream mavenWrapperPropertyFileInputStream = null;
- try {
- mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
- Properties mavenWrapperProperties = new Properties();
- mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
- url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
- } catch (IOException e) {
- System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
- } finally {
- try {
- if(mavenWrapperPropertyFileInputStream != null) {
- mavenWrapperPropertyFileInputStream.close();
- }
- } catch (IOException e) {
- // Ignore ...
- }
- }
- }
- System.out.println("- Downloading from: " + url);
-
- File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
- if(!outputFile.getParentFile().exists()) {
- if(!outputFile.getParentFile().mkdirs()) {
- System.out.println(
- "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
- }
- }
- System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
- try {
- downloadFileFromURL(url, outputFile);
- System.out.println("Done");
- System.exit(0);
- } catch (Throwable e) {
- System.out.println("- Error downloading");
- e.printStackTrace();
- System.exit(1);
- }
- }
-
- private static void downloadFileFromURL(String urlString, File destination) throws Exception {
- if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
- String username = System.getenv("MVNW_USERNAME");
- char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
- Authenticator.setDefault(new Authenticator() {
- @Override
- protected PasswordAuthentication getPasswordAuthentication() {
- return new PasswordAuthentication(username, password);
- }
- });
- }
- URL website = new URL(urlString);
- ReadableByteChannel rbc;
- rbc = Channels.newChannel(website.openStream());
- FileOutputStream fos = new FileOutputStream(destination);
- fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
- fos.close();
- rbc.close();
- }
-
-}
diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar
index 2cc7d4a5..bf82ff01 100644
Binary files a/.mvn/wrapper/maven-wrapper.jar and b/.mvn/wrapper/maven-wrapper.jar differ
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
index 642d572c..6686a643 100644
--- a/.mvn/wrapper/maven-wrapper.properties
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -1,2 +1,18 @@
-distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
-wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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
+#
+# https://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.
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.0/apache-maven-3.9.0-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
diff --git a/.sdkmanrc b/.sdkmanrc
index 0262a261..83ec5a0a 100644
--- a/.sdkmanrc
+++ b/.sdkmanrc
@@ -1,3 +1,3 @@
# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
-java=11.0.11.hs-adpt
+java=17.0.14-librca
diff --git a/CONTRIBUTING.adoc b/CONTRIBUTING.adoc
index 055b745e..a7e07f62 100644
--- a/CONTRIBUTING.adoc
+++ b/CONTRIBUTING.adoc
@@ -12,10 +12,9 @@ Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
-== Sign the Contributor License Agreement
-Before we accept a non-trivial patch or pull request we will need you to https://cla.pivotal.io/sign/spring[sign the Contributor License Agreement].
-Signing the contributor's agreement does not grant anyone commit rights to the main repository, but it does mean that we can accept your contributions, and you will get an author credit if we do.
-Active contributors might be asked to join the core team, and given the ability to merge pull requests.
+== Include a Signed-off-by Trailer
+All commits must include a __Signed-off-by__ trailer at the end of each commit message to indicate that the contributor agrees to the https://en.wikipedia.org/wiki/Developer_Certificate_of_Origin[Developer Certificate of Origin (DCO)].
+For additional details, please refer to the blog post https://spring.io/blog/2025/01/06/hello-dco-goodbye-cla-simplifying-contributions-to-spring[Hello DCO, Goodbye CLA: Simplifying Contributions to Spring].
@@ -29,7 +28,7 @@ should also work without issue.
=== Building From Source
-To build the source you will need to install JDK 11.
+To build the source you will need to install JDK 17.
@@ -108,6 +107,7 @@ image::.github/images/setup-idea-dependency.png[Setup IntelliJ IDEA Dependencies
=== Setting up IntelliJ IDEA Plugin Development
+
==== Download Images
To develop the `spring-javaformat-intellij-idea-plugin` module, you need an IntelliJ IDEA application on your local machine.
@@ -166,6 +166,20 @@ To add gradle classes, convert this module to a gradle project.
+=== Setting up Visual Studio Code Extension Development
+The `spring-javaformat-vscode-extension` extension consists of a formatter written in Java and an extension written in TypeScript.
+If you want to work on the TypeScript code it can opened directly with Visual Studio Code.
+
+Maven delegates to `npm run package` to actually generate the extension.
+
+Code is formatted with prettier.
+If you need to reform the code you can run `npx prettier --write .`
+
+There is a basic test included with the project, but since it needs UI elements it doesn't run as part of the regular build.
+If you make changes to the extension, you should run "`Extension Tests`" from vscode.
+
+
+
=== Importing Into Other IDEs
Maven is well supported by most Java IDEs. Refer to your vendor documentation.
@@ -173,19 +187,27 @@ Maven is well supported by most Java IDEs. Refer to your vendor documentation.
== Understanding the Code
There are quite a few moving parts to this project and the build is quite complex.
-At the top level there are 5 projects:
+At the top level there are 6 projects:
* `spring-javaformat` - The main formatter project
* `spring-javaformat-eclipse` - The Eclipse plugin
* `spring-javaformat-gradle` - The Gradle plugin
* `spring-javaformat-intellij` - The IntelliJ IDEA plugin
* `spring-javaformat-maven` - The Maven plugin
+* `spring-javaformat-vscode` - The Visual Studo Code extension
Under `spring-javaformat` the following projects are defined:
* `spring-javaformat-checkstyle` - The checkstyle plugin
* `spring-javaformat-formatter` - The main formatter code
-* `spring-javaformat-formatter-eclipse` - The eclipse formatter (repackaged and slightly adapted)
+* `spring-javaformat-formatter-test-support` - Support classes for tests
+* `spring-javaformat-formatter-tests` - Tests for the formatter (external so that they we can test Java 8 and 11)
+* `spring-javaformat-formatter-shader` - Shader support classes
+* `spring-javaformat-formatter-shaded` - A shaded version of the formatter with all dependencies included
+* `spring-javaformat-formatter-eclipse-jdk8` - The eclipse JDK 8 formatter (repackaged and slightly adapted)
+* `spring-javaformat-formatter-eclipse-jdk17` - The eclipse JDK 17 formatter (repackaged and slightly adapted)
+* `spring-javaformat-formatter-eclipse-jdt-jdk8` - The eclipse JDT import for JDK 8
+* `spring-javaformat-formatter-eclipse-jdt-jdk17` - The eclipse JDT import for JDK 17
* `spring-javaformat-formatter-eclipse-rewriter` - Internal utility used to modify eclipse code
* `spring-javaformat-formatter-eclipse-runtime` - Eclipse runtime JAR for use when running outside of Eclipse
diff --git a/README.adoc b/README.adoc
index 5ed9aafc..907d9a2c 100644
--- a/README.adoc
+++ b/README.adoc
@@ -1,4 +1,4 @@
-:release-version: 0.0.34
+:release-version: 0.0.47
:checkstyle-version: 9.3
== Spring Java Format
@@ -9,7 +9,7 @@ A set of plugins that can be applied to any Java project to provide a consistent
The set currently consists of:
* A source formatter that applies wrapping and whitespace conventions
-* A checkstyle plugin that enforces consistency across a codebase
+* A Checkstyle plugin that enforces consistency across a codebase
Since the aim of this project is to provide consistency, each plugin is not generally configurable.
You need to change your code to match the required conventions.
@@ -76,10 +76,13 @@ NOTE: The source formatter does not fundamentally change your code.
For example, it will not change the order of import statements.
It is effectively limited to adding or removing whitespace and line feeds.
+TIP: You can use `-Dspring-javaformat.validate.skip=true` or `-Dspring-javaformat.apply.skip=true` command line arguments to temporarily skip the validation or format goals.
+If you want to skip both, you can use `-Dspring-javaformat.skip=true`.
-=== Checkstyle
-To enforce checksyle conventions add the checkstyle plugin and include a dependency on `spring-javaformat-checkstyle`:
+
+==== Checkstyle
+To enforce Checkstyle conventions, add the Checkstyle plugin and include a dependency on `spring-javaformat-checkstyle`:
[source,xml,indent=0,subs="normal"]
----
@@ -123,73 +126,93 @@ To enforce checksyle conventions add the checkstyle plugin and include a depende
=== Gradle
-
-
-
-==== Source Formatting
-For source formatting, add the `spring-javaformat-gradle-plugin` to your `build` plugins as follows:
+A plugin is provided.
+To use it, first update `settings.gradle` to add Maven Central as a plugin repository:
[source,groovy,indent=0,subs="normal"]
----
- buildscript {
- repositories {
- mavenCentral()
- }
- dependencies {
- classpath("io.spring.javaformat:spring-javaformat-gradle-plugin:{release-version}")
- }
+pluginManagement {
+ repositories {
+ gradlePluginPortal()
+ mavenCentral()
}
+}
+----
+
+The plugin can then be added in the usual way in `build.gradle`:
- apply plugin: 'io.spring.javaformat'
+[source,groovy,indent=0,subs="normal"]
+----
+plugins {
+ id "io.spring.javaformat" version "{release-version}"
+}
----
+==== Source Formatting
The plugin adds `format` and `checkFormat` tasks to your project.
-The `checkFormat` task is automatically applied when running the standard Gradle `check` task.
+The `checkFormat` task is automatically executed when running the standard Gradle `check` task.
-In case you want to exclude a package from being checked, for example if you generate sources, you can do this by adding following configuration:
+In case you want to exclude a package from being checked, for example if you generate sources, add configuration similar to the following:
[source,groovy,indent=0,subs="normal"]
----
tasks.withType(io.spring.javaformat.gradle.tasks.CheckFormat) {
- exclude "package/to/exclude"
+ exclude "package/to/exclude"
}
----
==== Checkstyle
-To enforce checksyle conventions add the checkstyle plugin and include a dependency on `spring-javaformat-checkstyle`:
+To enforce Checkstyle conventions, apply the Checkstyle plugin in addition to the `io.spring.javaformat` plugin:
[source,groovy,indent=0,subs="normal"]
----
-apply plugin: 'checkstyle'
+plugins {
+ id "io.spring.javaformat" version "{release-version}"
+ id "checkstyle"
+}
+----
+
+The Spring Java Format plugin will react to the Checkstyle plugin being applied and configure the necessary dependencies in the `checkstyle` configuration.
+
+You should also configure Checkstyle's tool version:
+[source,groovy,indent=0,subs="normal"]
+----
checkstyle {
toolVersion = "{checkstyle-version}"
}
+----
-dependencies {
- checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:{release-version}")
+To configure Checkstyle to use the default Spring checks, add the following configuration:
+
+[source,groovy,indent=0,subs="normal"]
+----
+springJavaFormat {
+ checkstyle {
+ applyDefaultConfig()
+ }
}
----
-Your `checkstyle.xml` file should look then like this:
+Alternatively, provide your own `checkstyle.xml` that configures the `io.spring.javaformat.checkstyle.SpringChecks` module.
-[source,xml,indent=0]
+If you want to use both Spring Java Format and Checkstyle but you do not want to use Spring Java Format's checks, disable the aforementioned dependency configuration:
+
+[source,groovy,indent=0,subs="normal"]
----
-
-
-
-
-
+springJavaFormat {
+ checkstyle {
+ configureDependencies = false
+ }
+}
----
=== Java 8 Support
-By default, the formatter requires Java 11.
+By default, the formatter requires Java 17.
If you are working on an older project, you can use a variation of the formatter based off Eclipse 2021-03 (the latest Eclipse JDT version built with Java 8).
To use the Java 8 version, add a file called `.springjavaformatconfig` to the root of your project with the following content:
@@ -205,9 +228,9 @@ java-baseline=8
The Eclipse plugin provides a custom formatter implementation and automatically applies project specific settings.
The plugin is automatically activated whenever the Maven or Gradle plugins are discovered in a project build script.
-If you need to customize the project specific settings that the plugin applies you should add a `.eclipse` folder in the root of your project.
+If you need to customize the project specific settings that the plugin applies, you should add a `.eclipse` folder in the root of your project.
All `.prefs` files from this folder will be copied to the project `.settings` folders.
-Usually you'll provide your own `org.eclipse.jdt.core.prefs` and `org.eclipse.jdt.ui.prefs` files.
+Usually, you'll provide your own `org.eclipse.jdt.core.prefs` and `org.eclipse.jdt.ui.prefs` files.
You can also add a `.eclipse/eclipse.properties` file to customize the following items:
@@ -219,16 +242,17 @@ You can also add a `.eclipse/eclipse.properties` file to customize the following
To install the plugin use the `io.spring.javaformat.eclipse.site` zip file.
You can download the latest version from
https://repo1.maven.org/maven2/io/spring/javaformat/io.spring.javaformat.eclipse.site/{release-version}[Maven Central]
-or use the https://repo.spring.io/javaformat-eclipse-update-site/[update site].
+or use the `https://repo.spring.io/javaformat-eclipse-update-site/` as an Eclipse update site (do not use the `/ui/native/` links that you are redirected to when using a web browser).
+
=== IntelliJ IDEA
The IntelliJ IDEA plugin provides custom formatter support for IntelliJ IDEA.
-The plugin is automatically activated whenever the Maven or Gradle plugins are discovered in a project build script.
+The plugin is automatically activated whenever the Maven or Gradle plugins are discovered in a project build script or if a `.springjavaformatconfig` file.
A Spring Java Format icon (image:spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/resources/spring-javaformat/formatOn.png[title="Icon"]) will also be displayed in the status bar to indicate the formatter is active.
You can use the standard `code` -> `reformat code` action to format the code.
-To install the plugin use the `spring-javaformat-intellij-idea-plugin` jar file.
+To install the plugin, use the `spring-javaformat-intellij-idea-plugin` jar file.
You can download the latest version from https://repo1.maven.org/maven2/io/spring/javaformat/spring-javaformat-intellij-idea-plugin/{release-version}[Maven Central].
@@ -240,6 +264,8 @@ The plugin is automatically enabled when one or more of the following conditions
* For a Maven-based project, `spring-javaformat-maven-plugin` plugin is defined in `pom.xml`
* For a Gradle-based project, `io.spring.javaformat` plugin is applied
+
+
==== CheckStyle-IDEA plugin
The https://plugins.jetbrains.com/plugin/1065-checkstyle-idea[CheckStyle-IDEA plugin] provides Checkstyle integration for IntelliJ IDEA.
@@ -258,23 +284,35 @@ To configure the plugin, create your own Checkstyle configuration file with the
Once the configuration file is created, configure your IDE to use it:
+* Download `spring-javaformat-checkstyle-{release-version}.jar` from https://repo1.maven.org/maven2/io/spring/javaformat/spring-javaformat-checkstyle/{release-version}[Maven Central].
+* Download `spring-javaformat-config-{release-version}.jar` from https://repo1.maven.org/maven2/io/spring/javaformat/spring-javaformat-config/{release-version}[Maven Central].
* Open `Preferences` - `Tools` - `Checkstyle`
* Add `spring-javaformat-checkstyle-{release-version}.jar` and `spring-javaformat-config-{release-version}.jar` to the `Third-Party Checks`
* Specify the appropriate `Checkstyle version`
-* Add your Checkstyle configuration file
+* Add and enable your Checkstyle configuration file
+
+
+
+=== Visual Studio Code
+The Visual Studio Code extension provides custom formatter support for Microsoft Visual Studio Code.
+The extension uses the https://code.visualstudio.com/api/references/vscode-api#DocumentFormattingEditProvider[`DocumentFormattingEditProvider`] API.
+Once installed it may be activated by using the "`Format Document`" action available in the editor context menu or from the Command Palette.
+
+To install the extension, select "`Install from VSIX`" in the extensions panel and choose the `spring-javaformat-vscode-extension` vsix file.
+You can download the latest version from https://repo1.maven.org/maven2/io/spring/javaformat/spring-javaformat-vscode-extension/{release-version}[Maven Central].
=== About the Conventions
-Most of the coding conventions and style comes from the Spring Framework and Spring Boot projects.
-Spring Framework manually formats code, where as Spring Boot uses automatic formatting.
+Most of the coding conventions and style come from the Spring Framework and Spring Boot projects.
+Spring Framework manually formats code, whereas Spring Boot uses automatic formatting.
=== Indenting With Spaces
-By default tabs are used for indenting formatted code.
+By default, tabs are used for indenting formatted code.
We strongly recommend that this default is not changed, especially for official Spring projects.
-If, however, you feel that you can't live with tabs then switching to spaces is the one configuration option that we do support.
+If, however, you feel that you can't live with tabs, switching to spaces is the one configuration option that we do support.
To use spaces rather than tabs, add a file called `.springjavaformatconfig` to the root of your project with the following content:
@@ -313,7 +351,7 @@ If you want most `SpringChecks` but need to exclude one or two, you can do somet
Some code isn't particularly amenable to automatic formatting.
For example, Spring Security configurations often work better when manually formatted.
-If you need to disable formatting for a specific block of code you can enclose it in a `@formatter:off` / `@formatter:on` set:
+If you need to disable formatting for a specific block of code, you can enclose it in a `@formatter:off` / `@formatter:on` set:
[source,java]
----
@@ -332,8 +370,8 @@ making use of available horizontal space in your IDE and avoiding unwanted addit
wrapping when viewing code on GitHub and the like.
If you're used to longer lines, 120 chars can take some getting used to. Specifically, if
-you have many nesting levels things can start to look quite bad. Generally, if you see
-code bunched up to the right of your screen you should take that as a signal to use the
+you have many nesting levels, things can start to look quite bad. Generally, if you see
+code bunched up to the right of your screen, you should take that as a signal to use the
"`extract method`" refactor. Extracting small private methods will improve formatting and
it helps when reading the code and debugging.
@@ -341,8 +379,8 @@ it helps when reading the code and debugging.
==== Whitespace
Keeping whitespace lines out of method bodies can help make the code easier to scan.
-If blank lines are only included between methods it becomes easier to see the overall structure of the class.
-If you find you need whitespace inside your method, consider if extracting a private method might give a better result.
+If blank lines are only included between methods, it becomes easier to see the overall structure of the class.
+If you find you need whitespace inside your method, consider whether extracting a private method might give a better result.
@@ -350,30 +388,30 @@ If you find you need whitespace inside your method, consider if extracting a pri
Try to add javadoc for each public method and constant.
Private methods shouldn't generally need javadoc, unless it provides a natural place to document unusual behavior.
-The checkstyle rules will enforce that all public classes have javadoc.
+The Checkstyle rules will enforce that all public classes have javadoc.
They will also ensure that `@author` tags are well formed.
==== Final
Private members should be `final` whenever possible.
-Local variable and parameters should generally not be explicitly declared as final since it adds so much noise.
+Local variables and parameters should generally not be explicitly declared as final since it adds so much noise.
==== Read-down Methods, Fields and Parameters
Methods don't need to be organized by scope.
There's no need to group all `private`, `protected` and `public` methods together.
-Instead try to make your code easy to read when scanning the file from top to bottom.
-In other words, try to have methods only reference method further down in the file.
+Instead, try to make your code easy to read when scanning the file from top to bottom.
+In other words, try to have methods only reference methods further down in the file.
Keep private methods as close to the thing that calls them as possible.
-It's also recommend that you try to keep consistent ordering with fields and constructor parameters.
+It's also recommended that you try to keep consistent ordering with fields and constructor parameters.
For example:
[source,java,indent=0,subs="normal"]
----
-class Name {
+public class Name {
private final String first;
diff --git a/ci/README.adoc b/ci/README.adoc
deleted file mode 100644
index bdf75bd5..00000000
--- a/ci/README.adoc
+++ /dev/null
@@ -1,18 +0,0 @@
-== Concourse pipeline
-
-Ensure that you've setup the target and can login
-
-[source]
-----
-$ fly -t spring-javaformat login -n spring-javaformat -c https://ci.spring.io
-----
-
-The pipeline can be deployed using the following command:
-
-[source]
-----
-$ fly -t spring-javaformat set-pipeline -p spring-javaformat -c ci/pipeline.yml -l ci/parameters.yml
-----
-
-NOTE: This assumes that you have credhub integration configured with the appropriate
-secrets.
diff --git a/ci/config/release-scripts.yml b/ci/config/release-scripts.yml
deleted file mode 100644
index d31f8cba..00000000
--- a/ci/config/release-scripts.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-logging:
- level:
- io.spring.concourse: DEBUG
-spring:
- main:
- banner-mode: off
-sonatype:
- exclude:
- - 'build-info\.json'
- - '.*\.zip'
diff --git a/ci/images/README.adoc b/ci/images/README.adoc
deleted file mode 100644
index 84eae160..00000000
--- a/ci/images/README.adoc
+++ /dev/null
@@ -1,21 +0,0 @@
-== CI Images
-
-These images are used by CI to run the actual builds.
-
-To build the image locally run the following from this directory:
-
-----
-$ docker build --no-cache -f /Dockerfile .
-----
-
-For example
-
-----
-$ docker build --no-cache -f spring-boot-ci-image/Dockerfile .
-----
-
-To test run:
-
-----
-$ docker run -it --entrypoint /bin/bash ✈
-----
diff --git a/ci/images/ci-image/Dockerfile b/ci/images/ci-image/Dockerfile
deleted file mode 100644
index 0fa33ae7..00000000
--- a/ci/images/ci-image/Dockerfile
+++ /dev/null
@@ -1,12 +0,0 @@
-FROM ubuntu:focal-20210401
-
-ADD setup.sh /setup.sh
-ADD get-jdk-url.sh /get-jdk-url.sh
-ADD get-docker-url.sh /get-docker-url.sh
-RUN ./setup.sh
-
-ENV JAVA_HOME /opt/openjdk
-ENV PATH $JAVA_HOME/bin:$PATH
-ADD docker-lib.sh /docker-lib.sh
-
-ENTRYPOINT [ "switch", "shell=/bin/bash", "--", "codep", "/bin/docker daemon" ]
diff --git a/ci/images/docker-lib.sh b/ci/images/docker-lib.sh
deleted file mode 100755
index 4c7b1d58..00000000
--- a/ci/images/docker-lib.sh
+++ /dev/null
@@ -1,112 +0,0 @@
-# Based on: https://github.com/concourse/docker-image-resource/blob/master/assets/common.sh
-
-DOCKER_LOG_FILE=${DOCKER_LOG_FILE:-/tmp/docker.log}
-SKIP_PRIVILEGED=${SKIP_PRIVILEGED:-false}
-STARTUP_TIMEOUT=${STARTUP_TIMEOUT:-120}
-
-sanitize_cgroups() {
- mkdir -p /sys/fs/cgroup
- mountpoint -q /sys/fs/cgroup || \
- mount -t tmpfs -o uid=0,gid=0,mode=0755 cgroup /sys/fs/cgroup
-
- mount -o remount,rw /sys/fs/cgroup
-
- sed -e 1d /proc/cgroups | while read sys hierarchy num enabled; do
- if [ "$enabled" != "1" ]; then
- # subsystem disabled; skip
- continue
- fi
-
- grouping="$(cat /proc/self/cgroup | cut -d: -f2 | grep "\\<$sys\\>")" || true
- if [ -z "$grouping" ]; then
- # subsystem not mounted anywhere; mount it on its own
- grouping="$sys"
- fi
-
- mountpoint="/sys/fs/cgroup/$grouping"
-
- mkdir -p "$mountpoint"
-
- # clear out existing mount to make sure new one is read-write
- if mountpoint -q "$mountpoint"; then
- umount "$mountpoint"
- fi
-
- mount -n -t cgroup -o "$grouping" cgroup "$mountpoint"
-
- if [ "$grouping" != "$sys" ]; then
- if [ -L "/sys/fs/cgroup/$sys" ]; then
- rm "/sys/fs/cgroup/$sys"
- fi
-
- ln -s "$mountpoint" "/sys/fs/cgroup/$sys"
- fi
- done
-
- if ! test -e /sys/fs/cgroup/systemd ; then
- mkdir /sys/fs/cgroup/systemd
- mount -t cgroup -o none,name=systemd none /sys/fs/cgroup/systemd
- fi
-}
-
-start_docker() {
- mkdir -p /var/log
- mkdir -p /var/run
-
- if [ "$SKIP_PRIVILEGED" = "false" ]; then
- sanitize_cgroups
-
- # check for /proc/sys being mounted readonly, as systemd does
- if grep '/proc/sys\s\+\w\+\s\+ro,' /proc/mounts >/dev/null; then
- mount -o remount,rw /proc/sys
- fi
- fi
-
- local mtu=$(cat /sys/class/net/$(ip route get 8.8.8.8|awk '{ print $5 }')/mtu)
- local server_args="--mtu ${mtu}"
- local registry=""
-
- server_args="${server_args}"
-
- for registry in $3; do
- server_args="${server_args} --insecure-registry ${registry}"
- done
-
- if [ -n "$4" ]; then
- server_args="${server_args} --registry-mirror $4"
- fi
-
- try_start() {
- dockerd --data-root /scratch/docker ${server_args} >$DOCKER_LOG_FILE 2>&1 &
- echo $! > /tmp/docker.pid
-
- sleep 1
-
- echo waiting for docker to come up...
- until docker info >/dev/null 2>&1; do
- sleep 1
- if ! kill -0 "$(cat /tmp/docker.pid)" 2>/dev/null; then
- return 1
- fi
- done
- }
-
- export server_args DOCKER_LOG_FILE
- declare -fx try_start
- trap stop_docker EXIT
-
- if ! timeout ${STARTUP_TIMEOUT} bash -ce 'while true; do try_start && break; done'; then
- echo Docker failed to start within ${STARTUP_TIMEOUT} seconds.
- return 1
- fi
-}
-
-stop_docker() {
- local pid=$(cat /tmp/docker.pid)
- if [ -z "$pid" ]; then
- return 0
- fi
-
- kill -TERM $pid
-}
-
diff --git a/ci/images/get-docker-url.sh b/ci/images/get-docker-url.sh
deleted file mode 100755
index 221b3462..00000000
--- a/ci/images/get-docker-url.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/bash
-set -e
-
-version="20.10.6"
-echo "https://download.docker.com/linux/static/stable/x86_64/docker-$version.tgz";
diff --git a/ci/images/get-jdk-url.sh b/ci/images/get-jdk-url.sh
deleted file mode 100755
index c539e19d..00000000
--- a/ci/images/get-jdk-url.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-set -e
-
-case "$1" in
- java8)
- echo "https://github.com/AdoptOpenJDK/openjdk8-binaries/releases/download/jdk8u292-b10/OpenJDK8U-jdk_x64_linux_hotspot_8u292b10.tar.gz"
- ;;
- java11)
- echo "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.11%2B9/OpenJDK11U-jdk_x64_linux_hotspot_11.0.11_9.tar.gz"
- ;;
- java16)
- echo "https://github.com/AdoptOpenJDK/openjdk16-binaries/releases/download/jdk-16%2B36/OpenJDK16-jdk_x64_linux_hotspot_16_36.tar.gz"
- ;;
- *)
- echo $"Unknown java version"
- exit 1
-esac
diff --git a/ci/images/setup.sh b/ci/images/setup.sh
deleted file mode 100755
index 52574521..00000000
--- a/ci/images/setup.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/bash
-set -ex
-
-###########################################################
-# UTILS
-###########################################################
-export DEBIAN_FRONTEND=noninteractive
-apt-get update
-apt-get install --no-install-recommends -y tzdata ca-certificates net-tools libxml2-utils git curl libudev1 libxml2-utils iptables iproute2 jq fontconfig
-ln -fs /usr/share/zoneinfo/UTC /etc/localtime
-dpkg-reconfigure --frontend noninteractive tzdata
-rm -rf /var/lib/apt/lists/*
-curl https://raw.githubusercontent.com/spring-io/concourse-java-scripts/v0.0.4/concourse-java.sh > /opt/concourse-java.sh
-curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/io/spring/concourse/releasescripts/concourse-release-scripts/0.3.2/concourse-release-scripts-0.3.2.jar
-
-###########################################################
-# JAVA
-###########################################################
-JDK_URL=$( ./get-jdk-url.sh java11 )
-
-mkdir -p /opt/openjdk
-cd /opt/openjdk
-curl -L ${JDK_URL} | tar zx --strip-components=1
-test -f /opt/openjdk/bin/java
-test -f /opt/openjdk/bin/javac
-
-###########################################################
-# DOCKER
-###########################################################
-cd /
-DOCKER_URL=$( ./get-docker-url.sh )
-curl -L ${DOCKER_URL} | tar zx
-mv /docker/* /bin/
-chmod +x /bin/docker*
-export ENTRYKIT_VERSION=0.4.0
-curl -L https://github.com/progrium/entrykit/releases/download/v${ENTRYKIT_VERSION}/entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz | tar zx
-chmod +x entrykit && \
-mv entrykit /bin/entrykit && \
-entrykit --symlink
\ No newline at end of file
diff --git a/ci/parameters.yml b/ci/parameters.yml
deleted file mode 100644
index d4564cd2..00000000
--- a/ci/parameters.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-project: spring-javaformat
-branch: main
-milestone: 0.0.x
-github-owner: spring-io
-github-repository: spring-javaformat
-docker-hub-ci-organization: springci
-ci-image: spring-javaformat-ci
-artifactory-server: https://repo.spring.io
-build-name: spring-javaformat
-task-timeout: 2h00m
diff --git a/ci/pipeline.yml b/ci/pipeline.yml
deleted file mode 100644
index a870f942..00000000
--- a/ci/pipeline.yml
+++ /dev/null
@@ -1,373 +0,0 @@
-anchors:
- github-release-source: &github-release-source
- owner: ((github-owner))
- repository: ((github-repository))
- access_token: ((github-ci-release-token))
- artifactory-repo-put-params: &artifactory-repo-put-params
- signing_key: ((signing-key))
- signing_passphrase: ((signing-passphrase))
- repo: libs-snapshot-local
- folder: distribution-repository
- build_uri: https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}
- build_number: ${BUILD_PIPELINE_NAME}-${BUILD_JOB_NAME}-${BUILD_NAME}
- disable_checksum_uploads: true
- threads: 8
- sonatype-task-params: &sonatype-task-params
- SONATYPE_USERNAME: ((sonatype-username))
- SONATYPE_PASSWORD: ((sonatype-password))
- SONATYPE_URL: ((sonatype-url))
- SONATYPE_STAGING_PROFILE_ID: ((sonatype-staging-profile-id))
- artifactory-task-params: &artifactory-task-params
- ARTIFACTORY_SERVER: ((artifactory-server))
- ARTIFACTORY_USERNAME: ((artifactory-username))
- ARTIFACTORY_PASSWORD: ((artifactory-password))
- docker-hub-task-params: &docker-hub-task-params
- DOCKER_HUB_USERNAME: ((docker-hub-username))
- DOCKER_HUB_PASSWORD: ((docker-hub-password))
- slack-fail-params: &slack-fail-params
- text: >
- :concourse-failed:
- silent: true
- icon_emoji: ":concourse:"
- username: concourse-ci
- slack-success-params: &slack-success-params
- text: >
- :concourse-succeeded:
- silent: true
- icon_emoji: ":concourse:"
- username: concourse-ci
-resource_types:
-- name: artifactory-resource
- type: registry-image
- source:
- repository: springio/artifactory-resource
- tag: "0.0.17"
-- name: pull-request
- type: registry-image
- source:
- repository: teliaoss/github-pr-resource
-- name: slack-notification
- type: registry-image
- source:
- repository: cfcommunity/slack-notification-resource
- tag: latest
-- name: github-release
- type: registry-image
- source:
- repository: concourse/github-release-resource
- tag: 1.7.0
-resources:
-- name: git-repo
- type: git
- icon: github
- source:
- uri: https://github.com/((github-owner))/((github-repository)).git
- username: ((github-username))
- password: ((github-ci-release-token))
- branch: ((branch))
-- name: git-pull-request
- type: pull-request
- icon: source-pull
- source:
- access_token: ((github-ci-pull-request-token))
- repository: ((github-owner))/((github-repository))
- base_branch: ((branch))
- ignore_paths: ["ci/*"]
-- name: github-pre-release
- type: github-release
- icon: briefcase-download-outline
- source:
- <<: *github-release-source
- pre_release: true
- release: false
-- name: github-release
- type: github-release
- icon: briefcase-download
- source:
- <<: *github-release-source
- pre_release: false
- release: true
-- name: ci-images-git-repo
- type: git
- icon: github
- source:
- uri: https://github.com/((github-owner))/((github-repository)).git
- branch: ((branch))
- paths: ["ci/images/*"]
-- name: ci-image
- type: registry-image
- icon: docker
- source:
- username: ((docker-hub-username))
- password: ((docker-hub-password))
- tag: ((milestone))
- repository: ((docker-hub-ci-organization))/((ci-image))
-- name: artifactory-repo
- type: artifactory-resource
- icon: package-variant
- source:
- uri: ((artifactory-server))
- username: ((artifactory-username))
- password: ((artifactory-password))
- build_name: ((build-name))
-- name: slack-alert
- type: slack-notification
- icon: slack
- source:
- url: ((slack-webhook-url))
-jobs:
-- name: build-ci-images
- plan:
- - get: ci-images-git-repo
- trigger: true
- - get: git-repo
- - task: build-ci-image
- privileged: true
- file: git-repo/ci/tasks/build-ci-image.yml
- params:
- DOCKER_HUB_AUTH: ((docker-hub-auth))
- output_mapping:
- image: ci-image
- - put: ci-image
- params:
- image: ci-image/image.tar
-- name: build
- serial: true
- public: true
- plan:
- - get: ci-image
- - get: git-repo
- trigger: true
- - do:
- - task: build-project
- image: ci-image
- privileged: true
- timeout: ((task-timeout))
- file: git-repo/ci/tasks/build-project.yml
- params:
- <<: *docker-hub-task-params
- BRANCH: ((branch))
- on_failure:
- do:
- - put: slack-alert
- params:
- <<: *slack-fail-params
- - put: artifactory-repo
- params:
- <<: *artifactory-repo-put-params
- get_params:
- threads: 8
- on_failure:
- do:
- - put: slack-alert
- params:
- <<: *slack-fail-params
- - put: slack-alert
- params:
- <<: *slack-success-params
-- name: build-pull-requests
- serial: true
- public: true
- plan:
- - get: ci-image
- - get: git-repo
- resource: git-pull-request
- trigger: true
- version: every
- - do:
- - put: git-pull-request
- params:
- path: git-repo
- status: pending
- - task: build-project
- image: ci-image
- file: git-repo/ci/tasks/build-pr-project.yml
- timeout: ((task-timeout))
- on_success:
- put: git-pull-request
- params:
- path: git-repo
- status: success
- on_failure:
- put: git-pull-request
- params:
- path: git-repo
- status: failure
-- name: stage-milestone
- serial: true
- plan:
- - get: ci-image
- - get: git-repo
- trigger: false
- - task: stage
- image: ci-image
- file: git-repo/ci/tasks/stage.yml
- params:
- <<: *docker-hub-task-params
- RELEASE_TYPE: M
- - put: artifactory-repo
- params:
- <<: *artifactory-repo-put-params
- repo: libs-staging-local
- - put: git-repo
- params:
- repository: stage-git-repo
-- name: stage-rc
- serial: true
- plan:
- - get: ci-image
- - get: git-repo
- trigger: false
- - task: stage
- image: ci-image
- file: git-repo/ci/tasks/stage.yml
- params:
- <<: *docker-hub-task-params
- RELEASE_TYPE: RC
- - put: artifactory-repo
- params:
- <<: *artifactory-repo-put-params
- repo: libs-staging-local
- - put: git-repo
- params:
- repository: stage-git-repo
-- name: stage-release
- serial: true
- plan:
- - get: ci-image
- - get: git-repo
- trigger: false
- - task: stage
- image: ci-image
- file: git-repo/ci/tasks/stage.yml
- params:
- <<: *docker-hub-task-params
- RELEASE_TYPE: RELEASE
- - put: artifactory-repo
- params:
- <<: *artifactory-repo-put-params
- repo: libs-staging-local
- - put: git-repo
- params:
- repository: stage-git-repo
-- name: promote-milestone
- serial: true
- plan:
- - get: ci-image
- - get: git-repo
- trigger: false
- - get: artifactory-repo
- trigger: false
- passed: [stage-milestone]
- params:
- download_artifacts: false
- save_build_info: true
- - task: promote
- image: ci-image
- file: git-repo/ci/tasks/promote.yml
- params:
- RELEASE_TYPE: M
- <<: *artifactory-task-params
- - task: generate-changelog
- file: git-repo/ci/tasks/generate-changelog.yml
- params:
- RELEASE_TYPE: M
- GITHUB_USERNAME: ((github-username))
- GITHUB_TOKEN: ((github-ci-release-token))
- - put: github-pre-release
- params:
- name: generated-changelog/tag
- tag: generated-changelog/tag
- body: generated-changelog/changelog.md
-- name: promote-rc
- serial: true
- plan:
- - get: ci-image
- - get: git-repo
- trigger: false
- - get: artifactory-repo
- trigger: false
- passed: [stage-rc]
- params:
- download_artifacts: false
- save_build_info: true
- - task: promote
- image: ci-image
- file: git-repo/ci/tasks/promote.yml
- params:
- RELEASE_TYPE: RC
- <<: *artifactory-task-params
- - task: generate-changelog
- file: git-repo/ci/tasks/generate-changelog.yml
- params:
- RELEASE_TYPE: RC
- - put: github-pre-release
- params:
- name: generated-changelog/tag
- tag: generated-changelog/tag
- body: generated-changelog/changelog.md
-- name: promote-release
- serial: true
- plan:
- - get: ci-image
- - get: git-repo
- trigger: false
- - get: artifactory-repo
- trigger: false
- passed: [stage-release]
- params:
- download_artifacts: true
- save_build_info: true
- - task: promote
- image: ci-image
- file: git-repo/ci/tasks/promote.yml
- params:
- RELEASE_TYPE: RELEASE
- <<: *artifactory-task-params
- <<: *sonatype-task-params
-- name: create-github-release
- serial: true
- plan:
- - get: ci-image
- - get: git-repo
- - get: artifactory-repo
- trigger: true
- passed: [promote-release]
- params:
- download_artifacts: false
- save_build_info: true
- - task: generate-changelog
- file: git-repo/ci/tasks/generate-changelog.yml
- params:
- RELEASE_TYPE: RELEASE
- - put: github-release
- params:
- name: generated-changelog/tag
- tag: generated-changelog/tag
- body: generated-changelog/changelog.md
-- name: publish-eclipse-update-site
- serial: true
- plan:
- - get: ci-image
- - get: git-repo
- trigger: false
- - get: artifactory-repo
- trigger: false
- passed: [promote-release]
- params:
- save_build_info: true
- - task: publish-eclipse-update-site
- image: ci-image
- file: git-repo/ci/tasks/publish-eclipse-update-site.yml
- params:
- ARTIFACTORY_USERNAME: ((artifactory-username))
- ARTIFACTORY_PASSWORD: ((artifactory-password))
-groups:
-- name: builds
- jobs: [build]
-- name: releases
- jobs: [stage-milestone, stage-rc, stage-release, promote-milestone, promote-rc, promote-release, create-github-release, publish-eclipse-update-site]
-- name: ci-images
- jobs: [build-ci-images]
-- name: pull-requests
- jobs: [build-pull-requests]
diff --git a/ci/scripts/build-project.sh b/ci/scripts/build-project.sh
deleted file mode 100755
index bc833d36..00000000
--- a/ci/scripts/build-project.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-set -e
-
-source $(dirname $0)/common.sh
-repository=$(pwd)/distribution-repository
-
-pushd git-repo > /dev/null
-run_maven clean deploy -U -Dfull -DaltDeploymentRepository=distribution::default::file://${repository}
-popd > /dev/null
diff --git a/ci/scripts/common.sh b/ci/scripts/common.sh
deleted file mode 100644
index 8eea3f79..00000000
--- a/ci/scripts/common.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-source /opt/concourse-java.sh
-
-setup_symlinks
-
-if [[ -n $DOCKER_HUB_USERNAME ]]; then
- docker login -u $DOCKER_HUB_USERNAME -p $DOCKER_HUB_PASSWORD
-fi
-
-cleanup_maven_repo "io.spring.javaformat"
diff --git a/ci/scripts/generate-changelog.sh b/ci/scripts/generate-changelog.sh
deleted file mode 100755
index 1e4b6e5b..00000000
--- a/ci/scripts/generate-changelog.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-set -e
-
-version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
-
-java -jar /github-changelog-generator.jar \
- --changelog.repository=spring-io/spring-javaformat \
- ${version} generated-changelog/changelog.md
-
-echo ${version} > generated-changelog/version
-echo v${version} > generated-changelog/tag
diff --git a/ci/scripts/promote.sh b/ci/scripts/promote.sh
deleted file mode 100755
index 30c3ace1..00000000
--- a/ci/scripts/promote.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-set -e
-
-source $(dirname $0)/common.sh
-CONFIG_DIR=git-repo/ci/config
-
-version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
-
-export BUILD_INFO_LOCATION=$(pwd)/artifactory-repo/build-info.json
-
-java -jar /opt/concourse-release-scripts.jar \
- --spring.config.location=${CONFIG_DIR}/release-scripts.yml \
- publishToCentral $RELEASE_TYPE $BUILD_INFO_LOCATION artifactory-repo || { exit 1; }
-
-java -jar /opt/concourse-release-scripts.jar \
- --spring.config.location=${CONFIG_DIR}/release-scripts.yml \
- promote $RELEASE_TYPE $BUILD_INFO_LOCATION || { exit 1; }
-
-echo "Promotion complete"
diff --git a/ci/scripts/stage.sh b/ci/scripts/stage.sh
deleted file mode 100755
index 21fc79d5..00000000
--- a/ci/scripts/stage.sh
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/bash
-set -e
-
-source $(dirname $0)/common.sh
-repository=$(pwd)/distribution-repository
-
-pushd git-repo > /dev/null
-git fetch --tags --all > /dev/null
-popd > /dev/null
-
-git clone git-repo stage-git-repo > /dev/null
-
-pushd stage-git-repo > /dev/null
-
-snapshotVersion=$( xmllint --xpath '/*[local-name()="project"]/*[local-name()="version"]/text()' pom.xml )
-if [[ $RELEASE_TYPE = "M" ]]; then
- stageVersion=$( get_next_milestone_release $snapshotVersion)
- nextVersion=$snapshotVersion
-elif [[ $RELEASE_TYPE = "RC" ]]; then
- stageVersion=$( get_next_rc_release $snapshotVersion)
- nextVersion=$snapshotVersion
-elif [[ $RELEASE_TYPE = "RELEASE" ]]; then
- stageVersion=$( get_next_release $snapshotVersion)
- nextVersion=$( bump_version_number $snapshotVersion)
-else
- echo "Unknown release type $RELEASE_TYPE" >&2; exit 1;
-fi
-
-echo "Staging ${stageVersion} (next version will be ${nextVersion})"
-run_maven versions:set -DnewVersion=${stageVersion} -DgenerateBackupPoms=false
-run_maven org.eclipse.tycho:tycho-versions-plugin:update-eclipse-metadata
-
-git config user.name "Spring Builds" > /dev/null
-git config user.email "spring-builds@users.noreply.github.com" > /dev/null
-git add pom.xml > /dev/null
-git commit -m"Release v${stageVersion}" > /dev/null
-git tag -a "v${stageVersion}" -m"Release v${stageVersion}" > /dev/null
-
-run_maven clean deploy -U -Dfull -DaltDeploymentRepository=distribution::default::file://${repository}
-
-git reset --hard HEAD^ > /dev/null
-if [[ $nextVersion != $snapshotVersion ]]; then
- echo "Setting next development version (v$nextVersion)"
- run_maven versions:set -DnewVersion=$nextVersion -DgenerateBackupPoms=false
- run_maven org.eclipse.tycho:tycho-versions-plugin:update-eclipse-metadata
- sed -i "s/:release-version:.*/:release-version: ${stageVersion}/g" README.adoc
- sed -i "s/spring-javaformat-gradle-plugin:.*/spring-javaformat-gradle-plugin:${nextVersion}\"\)/g" samples/spring-javaformat-gradle-sample/build.gradle
- sed -i "s/spring-javaformat-checkstyle:.*/spring-javaformat-checkstyle:${nextVersion}\"\)/g" samples/spring-javaformat-gradle-sample/build.gradle
- sed -i "s|.*|${nextVersion}|" samples/spring-javaformat-maven-sample/pom.xml
- git add -u . > /dev/null
- git commit -m"Next development version (v${nextVersion})" > /dev/null
-fi;
-
-popd > /dev/null
-
-echo "Staging Complete"
diff --git a/ci/scripts/sync-to-maven-central.sh b/ci/scripts/sync-to-maven-central.sh
deleted file mode 100755
index f691b9f9..00000000
--- a/ci/scripts/sync-to-maven-central.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-
-export BUILD_INFO_LOCATION=$(pwd)/artifactory-repo/build-info.json
-version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
-java -jar /opt/concourse-release-scripts.jar syncToCentral "RELEASE" $BUILD_INFO_LOCATION || { exit 1; }
-
-echo "Sync complete"
diff --git a/ci/tasks/build-ci-image.yml b/ci/tasks/build-ci-image.yml
deleted file mode 100644
index 18f97c02..00000000
--- a/ci/tasks/build-ci-image.yml
+++ /dev/null
@@ -1,25 +0,0 @@
----
-platform: linux
-image_resource:
- type: registry-image
- source:
- repository: vito/oci-build-task
-inputs:
-- name: ci-images-git-repo
-outputs:
-- name: image
-caches:
-- path: ci-image-cache
-params:
- CONTEXT: ci-images-git-repo/ci/images
- DOCKERFILE: ci-images-git-repo/ci/images/ci-image/Dockerfile
-run:
- path: /bin/sh
- args:
- - "-c"
- - |
- mkdir -p /root/.docker
- cat > /root/.docker/config.json < \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG="`dirname "$PRG"`/$link"
- fi
- done
-
- saveddir=`pwd`
-
- M2_HOME=`dirname "$PRG"`/..
-
- # make it fully qualified
- M2_HOME=`cd "$M2_HOME" && pwd`
-
- cd "$saveddir"
- # echo Using m2 at $M2_HOME
-fi
-
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
- [ -n "$M2_HOME" ] &&
- M2_HOME=`cygpath --unix "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
@@ -110,8 +85,6 @@ fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
- [ -n "$M2_HOME" ] &&
- M2_HOME="`(cd "$M2_HOME"; pwd)`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
fi
@@ -145,7 +118,7 @@ if [ -z "$JAVACMD" ] ; then
JAVACMD="$JAVA_HOME/bin/java"
fi
else
- JAVACMD="`which java`"
+ JAVACMD="`\\unset -f command; \\command -v java`"
fi
fi
@@ -159,12 +132,9 @@ if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
-CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
-
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
-
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
@@ -184,7 +154,7 @@ find_maven_basedir() {
fi
# end of workaround
done
- echo "${basedir}"
+ printf '%s' "$(cd "$basedir"; pwd)"
}
# concatenates all lines of a file
@@ -194,11 +164,16 @@ concat_lines() {
fi
}
-BASE_DIR=`find_maven_basedir "$(pwd)"`
+BASE_DIR=$(find_maven_basedir "$(dirname $0)")
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
+MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
+if [ "$MVNW_VERBOSE" = true ]; then
+ echo $MAVEN_PROJECTBASEDIR
+fi
+
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
@@ -212,16 +187,16 @@ else
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
if [ -n "$MVNW_REPOURL" ]; then
- jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
else
- jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
fi
while IFS="=" read key value; do
- case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+ case "$key" in (wrapperUrl) wrapperUrl="$value"; break ;;
esac
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then
- echo "Downloading from: $jarUrl"
+ echo "Downloading from: $wrapperUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
if $cygwin; then
@@ -229,42 +204,49 @@ else
fi
if command -v wget > /dev/null; then
+ QUIET="--quiet"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
+ QUIET=""
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
- wget "$jarUrl" -O "$wrapperJarPath"
+ wget $QUIET "$wrapperUrl" -O "$wrapperJarPath"
else
- wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
+ wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath"
fi
+ [ $? -eq 0 ] || rm -f "$wrapperJarPath"
elif command -v curl > /dev/null; then
+ QUIET="--silent"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
+ QUIET=""
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
- curl -o "$wrapperJarPath" "$jarUrl" -f
+ curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L
else
- curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+ curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L
fi
-
+ [ $? -eq 0 ] || rm -f "$wrapperJarPath"
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
- javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ javaSource="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
+ javaSource=`cygpath --path --windows "$javaSource"`
javaClass=`cygpath --path --windows "$javaClass"`
fi
- if [ -e "$javaClass" ]; then
- if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ if [ -e "$javaSource" ]; then
+ if [ ! -e "$javaClass" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
- ("$JAVA_HOME/bin/javac" "$javaClass")
+ ("$JAVA_HOME/bin/javac" "$javaSource")
fi
- if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ if [ -e "$javaClass" ]; then
# Running the downloader
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..."
@@ -278,16 +260,10 @@ fi
# End of extension
##########################################################################################
-export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
-if [ "$MVNW_VERBOSE" = true ]; then
- echo $MAVEN_PROJECTBASEDIR
-fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
- [ -n "$M2_HOME" ] &&
- M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
@@ -305,6 +281,7 @@ WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
exec "$JAVACMD" \
$MAVEN_OPTS \
+ $MAVEN_DEBUG_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
- "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/mvnw.cmd b/mvnw.cmd
index 86115719..cba1f040 100644
--- a/mvnw.cmd
+++ b/mvnw.cmd
@@ -1,182 +1,187 @@
-@REM ----------------------------------------------------------------------------
-@REM Licensed to the Apache Software Foundation (ASF) under one
-@REM or more contributor license agreements. See the NOTICE file
-@REM distributed with this work for additional information
-@REM regarding copyright ownership. The ASF licenses this file
-@REM to you under the Apache License, Version 2.0 (the
-@REM "License"); you may not use this file except in compliance
-@REM with the License. You may obtain a copy of the License at
-@REM
-@REM http://www.apache.org/licenses/LICENSE-2.0
-@REM
-@REM Unless required by applicable law or agreed to in writing,
-@REM software distributed under the License is distributed on an
-@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@REM KIND, either express or implied. See the License for the
-@REM specific language governing permissions and limitations
-@REM under the License.
-@REM ----------------------------------------------------------------------------
-
-@REM ----------------------------------------------------------------------------
-@REM Maven Start Up Batch script
-@REM
-@REM Required ENV vars:
-@REM JAVA_HOME - location of a JDK home dir
-@REM
-@REM Optional ENV vars
-@REM M2_HOME - location of maven2's installed home dir
-@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
-@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
-@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
-@REM e.g. to debug Maven itself, use
-@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
-@REM ----------------------------------------------------------------------------
-
-@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
-@echo off
-@REM set title of command window
-title %0
-@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
-@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
-
-@REM set %HOME% to equivalent of $HOME
-if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
-
-@REM Execute a user defined script before this one
-if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
-@REM check for pre script, once with legacy .bat ending and once with .cmd ending
-if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
-if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
-:skipRcPre
-
-@setlocal
-
-set ERROR_CODE=0
-
-@REM To isolate internal variables from possible post scripts, we use another setlocal
-@setlocal
-
-@REM ==== START VALIDATION ====
-if not "%JAVA_HOME%" == "" goto OkJHome
-
-echo.
-echo Error: JAVA_HOME not found in your environment. >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-:OkJHome
-if exist "%JAVA_HOME%\bin\java.exe" goto init
-
-echo.
-echo Error: JAVA_HOME is set to an invalid directory. >&2
-echo JAVA_HOME = "%JAVA_HOME%" >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-@REM ==== END VALIDATION ====
-
-:init
-
-@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
-@REM Fallback to current working directory if not found.
-
-set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
-IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
-
-set EXEC_DIR=%CD%
-set WDIR=%EXEC_DIR%
-:findBaseDir
-IF EXIST "%WDIR%"\.mvn goto baseDirFound
-cd ..
-IF "%WDIR%"=="%CD%" goto baseDirNotFound
-set WDIR=%CD%
-goto findBaseDir
-
-:baseDirFound
-set MAVEN_PROJECTBASEDIR=%WDIR%
-cd "%EXEC_DIR%"
-goto endDetectBaseDir
-
-:baseDirNotFound
-set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
-cd "%EXEC_DIR%"
-
-:endDetectBaseDir
-
-IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
-
-@setlocal EnableExtensions EnableDelayedExpansion
-for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
-@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
-
-:endReadAdditionalConfig
-
-SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
-set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
-set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
-
-FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
- IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
-)
-
-@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
-@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
-if exist %WRAPPER_JAR% (
- if "%MVNW_VERBOSE%" == "true" (
- echo Found %WRAPPER_JAR%
- )
-) else (
- if not "%MVNW_REPOURL%" == "" (
- SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
- )
- if "%MVNW_VERBOSE%" == "true" (
- echo Couldn't find %WRAPPER_JAR%, downloading it ...
- echo Downloading from: %DOWNLOAD_URL%
- )
-
- powershell -Command "&{"^
- "$webclient = new-object System.Net.WebClient;"^
- "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
- "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
- "}"^
- "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
- "}"
- if "%MVNW_VERBOSE%" == "true" (
- echo Finished downloading %WRAPPER_JAR%
- )
-)
-@REM End of extension
-
-@REM Provide a "standardized" way to retrieve the CLI args that will
-@REM work with both Windows and non-Windows executions.
-set MAVEN_CMD_LINE_ARGS=%*
-
-%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
-if ERRORLEVEL 1 goto error
-goto end
-
-:error
-set ERROR_CODE=1
-
-:end
-@endlocal & set ERROR_CODE=%ERROR_CODE%
-
-if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
-@REM check for post script, once with legacy .bat ending and once with .cmd ending
-if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
-if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
-:skipRcPost
-
-@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
-if "%MAVEN_BATCH_PAUSE%" == "on" pause
-
-if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
-
-exit /B %ERROR_CODE%
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Apache Maven Wrapper startup batch script, version 3.1.1
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
+if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
+
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Found %WRAPPER_JAR%
+ )
+) else (
+ if not "%MVNW_REPOURL%" == "" (
+ SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
+ )
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Couldn't find %WRAPPER_JAR%, downloading it ...
+ echo Downloading from: %WRAPPER_URL%
+ )
+
+ powershell -Command "&{"^
+ "$webclient = new-object System.Net.WebClient;"^
+ "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+ "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+ "}"^
+ "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
+ "}"
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Finished downloading %WRAPPER_JAR%
+ )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% ^
+ %JVM_CONFIG_MAVEN_PROPS% ^
+ %MAVEN_OPTS% ^
+ %MAVEN_DEBUG_OPTS% ^
+ -classpath %WRAPPER_JAR% ^
+ "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
+ %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
+if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%"=="on" pause
+
+if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
+
+cmd /C exit /B %ERROR_CODE%
diff --git a/pom.xml b/pom.xml
index 1b64fc88..c07e765a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
4.0.0io.spring.javaformatspring-javaformat-build
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTpomSpring JavaFormat BuildSpring JavaFormat
@@ -32,42 +32,47 @@
UTF-81.8https://download.eclipse.org/releases/2021-03/202103171000/
- https://download.eclipse.org/releases/2022-06/202206151000/
+ https://download.eclipse.org/releases/2024-03/202403131000/https://checkstyle.org/eclipse-cs-update-site/true1.8.11.0b3
- 7.3.1
+ 9.63.8.09.3
- 3.42.4.212.17.1
- 3.5.0
+ 3.8.8${maven-core.version}
- 3.5
+ 3.8.23.6.285.8.13.21.0-GA1.2
+ 4.0.31.16.01.16.03.0.3
- 2.5.0
- 2.5.0
+ 4.0.4
+ 4.0.4
+
+ com.github.eirslett
+ frontend-maven-plugin
+ 1.12.1
+ com.github.wvengenproguard-maven-plugin
- 2.3.1
+ 2.6.0com.guardsquare
- proguard-base
- 7.0.0
+ proguard-core
+ 9.0.7runtime
@@ -75,17 +80,17 @@
com.googlecode.maven-download-plugindownload-maven-plugin
- 1.6.0
+ 1.6.8org.apache.maven.pluginsmaven-antrun-plugin
- 1.8
+ 3.1.0org.apache.maven.pluginsmaven-checkstyle-plugin
- 3.1.1
+ 3.2.1com.puppycrawl.tools
@@ -97,22 +102,22 @@
org.apache.maven.pluginsmaven-clean-plugin
- 3.1.0
+ 3.2.0org.apache.maven.pluginsmaven-compiler-plugin
- 3.8.1
+ 3.10.1org.apache.maven.pluginsmaven-deploy-plugin
- 2.8.2
+ 3.0.0org.apache.maven.pluginsmaven-dependency-plugin
- 3.1.2
+ 3.5.0org.apache.maven.plugins
@@ -130,32 +135,32 @@
org.apache.maven.pluginsmaven-install-plugin
- 2.5.2
+ 3.1.0org.apache.maven.pluginsmaven-invoker-plugin
- 3.2.1
+ 3.4.0org.apache.maven.pluginsmaven-jar-plugin
- 3.2.0
+ 3.3.0org.apache.maven.pluginsmaven-plugin-plugin
- 3.6.0
+ 3.7.1org.apache.maven.pluginsmaven-shade-plugin
- 3.2.4
+ 3.4.1org.apache.maven.pluginsmaven-site-plugin
- 3.9.1
+ 3.12.1org.apache.maven.plugins
@@ -179,7 +184,7 @@
org.apache.maven.pluginsmaven-javadoc-plugin
- 3.2.0
+ 3.4.18-Xdoclint:none
@@ -188,22 +193,22 @@
org.apache.maven.pluginsmaven-resources-plugin
- 3.2.0
+ 3.3.0org.codehaus.mojoversions-maven-plugin
- 2.8.1
+ 2.14.2org.codehaus.mojoexec-maven-plugin
- 3.0.0
+ 3.1.0org.codehaus.mojobuild-helper-maven-plugin
- 3.2.0
+ 3.3.0org.eclipse.tycho
@@ -230,9 +235,9 @@
${tycho.version}
- org.eclipse.tycho.extras
+ org.eclipse.tychotycho-buildtimestamp-jgit
- ${tycho-extras.version}
+ ${tycho.version}
@@ -285,6 +290,11 @@
cocoax86_64
+
+ macosx
+ cocoa
+ aarch64
+
@@ -362,6 +372,25 @@
+
+
+
+ com.github.eirslett
+
+
+ frontend-maven-plugin
+
+
+ [1.12.1,)
+
+
+ npx
+
+
+
+
+
+
@@ -375,6 +404,11 @@
${java.version}${java.version}
+ -Werror
+ -Xlint:deprecation
+ -Xlint:rawtypes
+ -Xlint:unchecked
+ -Xlint:varargs
@@ -432,7 +466,6 @@
src/checkstyle/checkstyle-suppressions.xmlsrc/checkstyle/checkstyle-header.txtcheckstyle.build.directory=${project.build.directory}
- UTF-8truetruetrue
@@ -505,46 +538,6 @@
groovy${groovy.version}
-
- org.gradle
- gradle-base-services
- ${gradle.version}
-
-
- org.gradle
- gradle-base-services-groovy
- ${gradle.version}
-
-
- org.gradle
- gradle-core
- ${gradle.version}
-
-
- org.gradle
- gradle-language-java
- ${gradle.version}
-
-
- org.gradle
- gradle-language-jvm
- ${gradle.version}
-
-
- org.gradle
- gradle-platform-jvm
- ${gradle.version}
-
-
- org.gradle
- gradle-plugins
- ${gradle.version}
-
-
- org.gradle
- gradle-tooling-api
- ${gradle.version}
- org.javassistjavassist
@@ -565,6 +558,11 @@
picocontainer${picocontainer.version}
+
+ org.codehaus.plexus
+ plexus-utils
+ ${plexus-utils.version}
+ org.testcontainerstestcontainers
@@ -597,10 +595,11 @@
spring-javaformat
- spring-javaformat-maven
- spring-javaformat-gradlespring-javaformat-eclipse
+ spring-javaformat-gradlespring-javaformat-intellij-idea
+ spring-javaformat-maven
+ spring-javaformat-vscode
@@ -612,7 +611,7 @@
- -Xmx512m -XX:MaxPermSize=256m -XstartOnFirstThread
+ -Xmx512m -XstartOnFirstThread
@@ -624,7 +623,7 @@
- -Xmx512m -XX:MaxPermSize=256m
+ -Xmx512m
diff --git a/samples/spring-javaformat-gradle-sample/build.gradle b/samples/spring-javaformat-gradle-sample/build.gradle
index 4e280b55..3fa4c986 100644
--- a/samples/spring-javaformat-gradle-sample/build.gradle
+++ b/samples/spring-javaformat-gradle-sample/build.gradle
@@ -4,7 +4,7 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath("io.spring.javaformat:spring-javaformat-gradle-plugin:0.0.35-SNAPSHOT")
+ classpath("io.spring.javaformat:spring-javaformat-gradle-plugin:0.0.48-SNAPSHOT")
}
}
@@ -25,5 +25,5 @@ checkstyle {
}
dependencies {
- checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:0.0.35-SNAPSHOT")
+ checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:0.0.48-SNAPSHOT")
}
diff --git a/samples/spring-javaformat-gradle-sample/src/main/java/sample/SampleApplication.java b/samples/spring-javaformat-gradle-sample/src/main/java/sample/SampleApplication.java
index a01d0bb3..480785d1 100644
--- a/samples/spring-javaformat-gradle-sample/src/main/java/sample/SampleApplication.java
+++ b/samples/spring-javaformat-gradle-sample/src/main/java/sample/SampleApplication.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/samples/spring-javaformat-maven-sample/pom.xml b/samples/spring-javaformat-maven-sample/pom.xml
index 6497f9b3..9354db42 100644
--- a/samples/spring-javaformat-maven-sample/pom.xml
+++ b/samples/spring-javaformat-maven-sample/pom.xml
@@ -8,7 +8,7 @@
0.0.1-SNAPSHOTUTF-8
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOT
diff --git a/samples/spring-javaformat-maven-sample/src/main/java/sample/SampleApplication.java b/samples/spring-javaformat-maven-sample/src/main/java/sample/SampleApplication.java
index a01d0bb3..480785d1 100644
--- a/samples/spring-javaformat-maven-sample/src/main/java/sample/SampleApplication.java
+++ b/samples/spring-javaformat-maven-sample/src/main/java/sample/SampleApplication.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.feature/feature.xml b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.feature/feature.xml
index d1cf37a8..5204ad42 100755
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.feature/feature.xml
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.feature/feature.xml
@@ -2,7 +2,7 @@
@@ -22,7 +22,7 @@
id="io.spring.javaformat.eclipse"
download-size="0"
install-size="0"
- version="0.0.35.qualifier"
+ version="0.0.48.qualifier"
unpack="false"/>
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.feature/pom.xml b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.feature/pom.xml
index d05d16b0..7b294c42 100755
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.feature/pom.xml
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.feature/pom.xml
@@ -6,13 +6,13 @@
io.spring.javaformatspring-javaformat-eclipse
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTio.spring.javaformat.eclipse.featureeclipse-featureSpring JavaFormat Eclipse Plugin Feature${basedir}/../..
- 11
+ 17
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.site/category.xml b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.site/category.xml
index 6621e059..325568f3 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.site/category.xml
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.site/category.xml
@@ -3,7 +3,7 @@
Maven Integration for Eclipse (maven-eclipse-plugin support)
-
+
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.site/io.spring.javaformat.eclipse.product b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.site/io.spring.javaformat.eclipse.product
index 013ecb06..4fc99abc 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.site/io.spring.javaformat.eclipse.product
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.site/io.spring.javaformat.eclipse.product
@@ -1,7 +1,7 @@
-
+
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.site/pom.xml b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.site/pom.xml
index b75e09c2..5d4e2f97 100755
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.site/pom.xml
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.site/pom.xml
@@ -6,14 +6,14 @@
io.spring.javaformatspring-javaformat-eclipse
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTio.spring.javaformat.eclipse.siteeclipse-repositorySpring JavaFormat Eclipse Plugin Site${basedir}/../..
- 11
+ 17
@@ -22,7 +22,6 @@
tycho-packaging-plugin${project.artifactId}
- true
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/META-INF/MANIFEST.MF b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/META-INF/MANIFEST.MF
index 8118572c..650cb7b0 100755
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/META-INF/MANIFEST.MF
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/META-INF/MANIFEST.MF
@@ -1,16 +1,18 @@
Manifest-Version: 1.0
Fragment-Host: io.spring.javaformat.eclipse
+Import-Package: org.junit,
+ org.junit.jupiter.api,
+ org.junit.jupiter.api.io
Bundle-ManifestVersion: 2
Bundle-Name: Spring Java Format Plugin Tests
Bundle-SymbolicName: io.spring.javaformat.eclipse.tests
Automatic-Module-Name: io.spring.javaformat.eclipse.tests
-Bundle-Version: 0.0.35.qualifier
+Bundle-Version: 0.0.48.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-11
-Require-Bundle: org.junit,
- org.junit.jupiter.api
Bundle-ClassPath: .,
lib/assertj-core.jar,
lib/byte-buddy-agent.jar,
lib/byte-buddy.jar,
lib/mockito-core.jar,
- lib/objenesis.jar
+ lib/objenesis.jar,
+ lib/junit-jupiter-api.jar
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/build.properties b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/build.properties
index f084befe..b62f58dd 100755
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/build.properties
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/build.properties
@@ -6,4 +6,5 @@ bin.includes = META-INF/,\
lib/byte-buddy-agent.jar,\
lib/byte-buddy.jar,\
lib/mockito-core.jar,\
- lib/objenesis.jar
+ lib/objenesis.jar,\
+ lib/junit-jupiter-api.jar
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/pom.xml b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/pom.xml
index 8efbf27d..532aefb8 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/pom.xml
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/pom.xml
@@ -6,14 +6,15 @@
io.spring.javaformatspring-javaformat-eclipse
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTio.spring.javaformat.eclipse.testseclipse-test-pluginSpring JavaFormat Eclipse Test${basedir}/../..
- 11
+ 17
+ true
@@ -31,10 +32,31 @@
org.apache.maven.plugins
- maven-javadoc-plugin
-
- **/*Tests.java
-
+ maven-source-plugin
+
+
+ attach-sources
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+ empty-javadoc-jar
+ package
+
+ jar
+
+
+ javadoc
+
+
+
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/src/io/spring/javaformat/eclipse/MessagesTests.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/src/io/spring/javaformat/eclipse/MessagesTests.java
index 32020b10..7684c764 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/src/io/spring/javaformat/eclipse/MessagesTests.java
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/src/io/spring/javaformat/eclipse/MessagesTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -29,7 +29,7 @@
public class MessagesTests {
@Test
- public void bindHasCorrectMessage() {
+ void bindHasCorrectMessage() {
String message = NLS.bind(Messages.springFormatSettingsImportError, "reason");
assertThat(message).isEqualTo("Error importing project specific settings: reason");
}
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/src/io/spring/javaformat/eclipse/projectsettings/ProjectPropertiesTests.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/src/io/spring/javaformat/eclipse/projectsettings/ProjectPropertiesTests.java
index 0c7ed16b..a8568832 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/src/io/spring/javaformat/eclipse/projectsettings/ProjectPropertiesTests.java
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/src/io/spring/javaformat/eclipse/projectsettings/ProjectPropertiesTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2021 the original author or authors.
+ * Copyright 2012-present 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.
@@ -44,7 +44,7 @@ public class ProjectPropertiesTests {
public File temp;
@Test
- public void addFromFolderAddsEclipseProperties() throws IOException {
+ void addFromFolderAddsEclipseProperties() throws IOException {
File file = new File(this.temp, "eclipse.properties");
writeProperties(file, "2018");
ProjectProperties properties = new ProjectProperties();
@@ -53,7 +53,7 @@ public void addFromFolderAddsEclipseProperties() throws IOException {
}
@Test
- public void addFromFolderWhenAlreadySetDoesNotOverwrite() throws IOException {
+ void addFromFolderWhenAlreadySetDoesNotOverwrite() throws IOException {
ProjectProperties properties = new ProjectProperties();
File folder1 = new File(this.temp, "1");
folder1.mkdirs();
@@ -67,7 +67,7 @@ public void addFromFolderWhenAlreadySetDoesNotOverwrite() throws IOException {
}
@Test
- public void addFromEmptyFolderUsesDefaults() throws IOException {
+ void addFromEmptyFolderUsesDefaults() throws IOException {
ProjectProperties properties = new ProjectProperties();
properties.addFromFolder(this.temp);
String currentYear = String.valueOf(LocalDate.now().getYear());
@@ -75,7 +75,7 @@ public void addFromEmptyFolderUsesDefaults() throws IOException {
}
@Test
- public void getModifiedContentReplacesCopyrightYear() throws IOException {
+ void getModifiedContentReplacesCopyrightYear() throws IOException {
String year = "2016-2020";
File file = new File(this.temp, "eclipse.properties");
writeProperties(file, year);
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFileTests.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFileTests.java
index 4a0f3128..769226b6 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFileTests.java
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFileTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -39,21 +39,21 @@ public class ProjectSettingsFileTests {
public File temp;
@Test
- public void fromFileAdaptsFile() throws Exception {
+ void fromFileAdaptsFile() throws Exception {
File file = new File(this.temp, "file");
writeText(file, "test");
ProjectSettingsFile projectSettingsFile = ProjectSettingsFile.fromFile(file);
assertThat(projectSettingsFile.getName()).isEqualTo(file.getName());
assertThat(projectSettingsFile.getContent(JavaFormatConfig.DEFAULT))
- .hasSameContentAs(new ByteArrayInputStream("test".getBytes()));
+ .hasSameContentAs(new ByteArrayInputStream("test".getBytes()));
}
@Test
- public void fromClasspathResourceAdaptsResource() throws Exception {
+ void fromClasspathResourceAdaptsResource() throws Exception {
ProjectSettingsFile projectSettingsFile = ProjectSettingsFile.fromClasspath(getClass(), "test.txt");
assertThat(projectSettingsFile.getName()).isEqualTo("test.txt");
assertThat(projectSettingsFile.getContent(JavaFormatConfig.DEFAULT))
- .hasSameContentAs(new ByteArrayInputStream("test".getBytes()));
+ .hasSameContentAs(new ByteArrayInputStream("test".getBytes()));
}
private void writeText(File file, String s) throws FileNotFoundException {
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFilesLocatorTests.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFilesLocatorTests.java
index ea0afe78..26ca3380 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFilesLocatorTests.java
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFilesLocatorTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -45,23 +45,23 @@ public class ProjectSettingsFilesLocatorTests {
public File temp;
@Test
- public void locateSettingsFilesWhenNoFoldersShouldReturnDefault() throws IOException {
+ void locateSettingsFilesWhenNoFoldersReturnsDefault() throws IOException {
ProjectSettingsFiles files = new ProjectSettingsFilesLocator().locateSettingsFiles();
- assertThat(files.iterator()).extracting(ProjectSettingsFile::getName).containsOnly("org.eclipse.jdt.core.prefs",
- "org.eclipse.jdt.ui.prefs");
+ assertThat(files.iterator()).extracting(ProjectSettingsFile::getName)
+ .containsOnly("org.eclipse.jdt.core.prefs", "org.eclipse.jdt.ui.prefs");
}
@Test
- public void locateSettingsFilesOnlyFindPrefs() throws Exception {
+ void locateSettingsFilesOnlyFindPrefs() throws Exception {
writeFile(this.temp, "foo.prefs");
writeFile(this.temp, "bar.notprefs");
ProjectSettingsFiles files = new ProjectSettingsFilesLocator(this.temp).locateSettingsFiles();
- assertThat(files.iterator()).extracting(ProjectSettingsFile::getName).containsOnly("org.eclipse.jdt.core.prefs",
- "org.eclipse.jdt.ui.prefs", "foo.prefs");
+ assertThat(files.iterator()).extracting(ProjectSettingsFile::getName)
+ .containsOnly("org.eclipse.jdt.core.prefs", "org.eclipse.jdt.ui.prefs", "foo.prefs");
}
@Test
- public void locateSettingsFilesWhenMultipleFoldersFindsInEarliest() throws Exception {
+ void locateSettingsFilesWhenMultipleFoldersFindsInEarliest() throws Exception {
File folder1 = new File(this.temp, "1");
writeFile(folder1, "foo.prefs", "foo1");
File folder2 = new File(this.temp, "2");
@@ -71,32 +71,32 @@ public void locateSettingsFilesWhenMultipleFoldersFindsInEarliest() throws Excep
Map found = new LinkedHashMap<>();
files.iterator().forEachRemaining((f) -> found.put(f.getName(), f));
assertThat(found.get("foo.prefs").getContent(JavaFormatConfig.DEFAULT))
- .hasSameContentAs(new ByteArrayInputStream("foo1".getBytes()));
+ .hasSameContentAs(new ByteArrayInputStream("foo1".getBytes()));
assertThat(found.get("org.eclipse.jdt.core.prefs").getContent(JavaFormatConfig.DEFAULT))
- .hasSameContentAs(new ByteArrayInputStream("core2".getBytes()));
+ .hasSameContentAs(new ByteArrayInputStream("core2".getBytes()));
}
@Test
- public void jdtCorePrefsFormatterWhenDefaultShouldUseTabs() throws IOException {
+ void jdtCorePrefsFormatterWhenDefaultUsesTabs() throws IOException {
ProjectSettingsFiles files = new ProjectSettingsFilesLocator().locateSettingsFiles();
ProjectSettingsFile file = get(files, "org.eclipse.jdt.core.prefs");
try (InputStream content = file.getContent(JavaFormatConfig.DEFAULT)) {
Properties properties = new Properties();
properties.load(content);
assertThat(properties.get("org.eclipse.jdt.core.javaFormatter"))
- .isEqualTo("io.spring.javaformat.eclipse.formatter.jdk11.tabs");
+ .isEqualTo("io.spring.javaformat.eclipse.formatter.jdk17.tabs");
}
}
@Test
- public void jdtCorePrefsFormatterWhenSpacesShouldUseSpaces() throws IOException {
+ void jdtCorePrefsFormatterWhenSpacesUsesSpaces() throws IOException {
ProjectSettingsFiles files = new ProjectSettingsFilesLocator().locateSettingsFiles();
ProjectSettingsFile file = get(files, "org.eclipse.jdt.core.prefs");
try (InputStream content = file.getContent(JavaFormatConfig.of(JavaBaseline.V8, IndentationStyle.SPACES))) {
Properties properties = new Properties();
properties.load(content);
assertThat(properties.get("org.eclipse.jdt.core.javaFormatter"))
- .isEqualTo("io.spring.javaformat.eclipse.formatter.jdk8.spaces");
+ .isEqualTo("io.spring.javaformat.eclipse.formatter.jdk8.spaces");
}
}
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFilesTests.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFilesTests.java
index cdc6b297..a5eb2ed1 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFilesTests.java
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFilesTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -52,14 +52,14 @@ public class ProjectSettingsFilesTests {
public File temp;
@Test
- public void iteratorIteratesFiles() throws Exception {
+ void iteratorIteratesFiles() throws Exception {
ProjectSettingsFile file = ProjectSettingsFile.fromFile(new File(this.temp, "file.prefs"));
ProjectSettingsFiles files = new ProjectSettingsFiles(Collections.singleton(file), new ProjectProperties());
assertThat(files).containsOnly(file);
}
@Test
- public void applyToProjectWithoutFileCopiesToDotSettings() throws Exception {
+ void applyToProjectWithoutFileCopiesToDotSettings() throws Exception {
ProjectSettingsFile file = createPrefsFile();
ProjectSettingsFiles files = new ProjectSettingsFiles(Collections.singleton(file), new ProjectProperties());
IProject project = mock(IProject.class);
@@ -78,7 +78,7 @@ public void applyToProjectWithoutFileCopiesToDotSettings() throws Exception {
}
@Test
- public void applyToProjectWithFileMergesToDotSettings() throws Exception {
+ void applyToProjectWithFileMergesToDotSettings() throws Exception {
ProjectSettingsFile file = createPrefsFile();
ProjectSettingsFiles files = new ProjectSettingsFiles(Collections.singleton(file), new ProjectProperties());
IProject project = mock(IProject.class);
@@ -87,7 +87,7 @@ public void applyToProjectWithFileMergesToDotSettings() throws Exception {
given(project.getFile(".settings/foo.prefs")).willReturn(projectFile);
given(projectFile.exists()).willReturn(true);
given(projectFile.getContents(true))
- .willReturn(new ByteArrayInputStream("a=b\n".getBytes(StandardCharsets.UTF_8)));
+ .willReturn(new ByteArrayInputStream("a=b\n".getBytes(StandardCharsets.UTF_8)));
ByteArrayOutputStream out = new ByteArrayOutputStream();
will((invocation) -> {
invocation.getArgument(0, InputStream.class).transferTo(out);
@@ -95,7 +95,8 @@ public void applyToProjectWithFileMergesToDotSettings() throws Exception {
}).given(projectFile).setContents((InputStream) any(), anyInt(), any());
files.applyToProject(project, monitor);
verify(projectFile).setContents((InputStream) any(), eq(1), eq(monitor));
- assertThat(out.toString(StandardCharsets.UTF_8)).isEqualTo("a=b\ny=z\n");
+ assertThat(out.toString(StandardCharsets.UTF_8))
+ .isEqualToNormalizingNewlines("a=b\ny=z\n");
}
private ProjectSettingsFile createPrefsFile() throws IOException {
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/META-INF/MANIFEST.MF b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/META-INF/MANIFEST.MF
index 9115b09a..2e0f34c4 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/META-INF/MANIFEST.MF
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/META-INF/MANIFEST.MF
@@ -3,14 +3,13 @@ Bundle-ManifestVersion: 2
Bundle-Name: Spring Java Format Plugin
Bundle-SymbolicName: io.spring.javaformat.eclipse;singleton:=true
Automatic-Module-Name: io.spring.javaformat.eclipse
-Bundle-Version: 0.0.35.qualifier
+Bundle-Version: 0.0.48.qualifier
Bundle-Activator: io.spring.javaformat.eclipse.Activator
Bundle-RequiredExecutionEnvironment: JavaSE-11
Require-Bundle: org.eclipse.ui,
org.eclipse.core.resources,
org.eclipse.core.runtime,
org.eclipse.ui.ide,
- org.slf4j.api;bundle-version="1.7.0",
org.eclipse.jdt.core,
org.eclipse.jface.text,
org.eclipse.m2e.jdt;resolution:=optional,
@@ -22,6 +21,6 @@ Bundle-ClassPath: .,
lib/spring-javaformat-config.jar,
lib/spring-javaformat-formatter.jar,
lib/spring-javaformat-checkstyle.jar,
- lib/spring-javaformat-formatter-eclipse-jdt-jdk11.jar,
+ lib/spring-javaformat-formatter-eclipse-jdt-jdk17.jar,
lib/spring-javaformat-formatter-eclipse-jdt-jdk8.jar
Bundle-ActivationPolicy: lazy
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/build.properties b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/build.properties
index 7780dc22..9bd6565a 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/build.properties
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/build.properties
@@ -6,5 +6,5 @@ bin.includes = META-INF/,\
lib/spring-javaformat-checkstyle.jar,\
lib/spring-javaformat-config.jar,\
lib/spring-javaformat-formatter.jar,\
- lib/spring-javaformat-formatter-eclipse-jdt-jdk11.jar,\
+ lib/spring-javaformat-formatter-eclipse-jdt-jdk17.jar,\
lib/spring-javaformat-formatter-eclipse-jdt-jdk8.jar
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/plugin.xml b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/plugin.xml
index b6bdf963..f9864bd4 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/plugin.xml
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/plugin.xml
@@ -3,13 +3,13 @@
io.spring.javaformatspring-javaformat-eclipse
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTio.spring.javaformat.eclipseeclipse-pluginSpring JavaFormat Eclipse Plugin${basedir}/../..
+ 17
@@ -37,6 +38,18 @@
+
+ org.apache.maven.plugins
+ maven-source-plugin
+
+
+ attach-sources
+
+ jar
+
+
+
+ org.apache.maven.pluginsmaven-javadoc-plugin
@@ -59,7 +72,7 @@
io.spring.javaformat
- spring-javaformat-formatter-eclipse-jdt-jdk11
+ spring-javaformat-formatter-eclipse-jdt-jdk17${project.version}
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/Activator.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/Activator.java
index 4b03b9eb..bef6af6b 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/Activator.java
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/Activator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -41,7 +41,7 @@ public class Activator extends AbstractUIPlugin {
public Activator() {
this.javaCorePlugins.add(new io.spring.javaformat.eclipse.jdt.jdk8.core.JavaCore());
- this.javaCorePlugins.add(new io.spring.javaformat.eclipse.jdt.jdk11.core.JavaCore());
+ this.javaCorePlugins.add(new io.spring.javaformat.eclipse.jdt.jdk17.core.JavaCore());
}
@Override
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/Executor.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/Executor.java
index c5c0ec77..7782afd3 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/Executor.java
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/Executor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/Messages.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/Messages.java
index 8db3c5dc..3fc7ab01 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/Messages.java
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/Messages.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/Startup.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/Startup.java
index bf20fc1a..c19e50e9 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/Startup.java
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/Startup.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatter.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatter.java
index 01d5499e..d26d70bd 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatter.java
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk11Spaces.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk17Spaces.java
similarity index 80%
rename from spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk11Spaces.java
rename to spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk17Spaces.java
index e6775b74..d0682ff2 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk11Spaces.java
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk17Spaces.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -27,10 +27,10 @@
*
* @author Phillip Webb
*/
-public class SpringCodeFormatterJdk11Spaces extends SpringCodeFormatter {
+public class SpringCodeFormatterJdk17Spaces extends SpringCodeFormatter {
- public SpringCodeFormatterJdk11Spaces() {
- super(JavaFormatConfig.of(JavaBaseline.V11, IndentationStyle.SPACES));
+ public SpringCodeFormatterJdk17Spaces() {
+ super(JavaFormatConfig.of(JavaBaseline.V17, IndentationStyle.SPACES));
}
}
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk11Tabs.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk17Tabs.java
similarity index 80%
rename from spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk11Tabs.java
rename to spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk17Tabs.java
index 78bd7aba..718e9846 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk11Tabs.java
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk17Tabs.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -27,10 +27,10 @@
*
* @author Phillip Webb
*/
-public class SpringCodeFormatterJdk11Tabs extends SpringCodeFormatter {
+public class SpringCodeFormatterJdk17Tabs extends SpringCodeFormatter {
- public SpringCodeFormatterJdk11Tabs() {
- super(JavaFormatConfig.of(JavaBaseline.V11, IndentationStyle.TABS));
+ public SpringCodeFormatterJdk17Tabs() {
+ super(JavaFormatConfig.of(JavaBaseline.V17, IndentationStyle.TABS));
}
}
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk8Spaces.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk8Spaces.java
index 1b78c15a..536c85ef 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk8Spaces.java
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk8Spaces.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk8Tabs.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk8Tabs.java
index 6381f3e4..0750be23 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk8Tabs.java
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk8Tabs.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/gradle/GradleProjectSettingsConfigurator.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/gradle/GradleProjectSettingsConfigurator.java
index d21fe831..9ab4bb69 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/gradle/GradleProjectSettingsConfigurator.java
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/gradle/GradleProjectSettingsConfigurator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/m2e/MavenProjectSettingsConfigurator.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/m2e/MavenProjectSettingsConfigurator.java
index 5cc7aacd..62e94e26 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/m2e/MavenProjectSettingsConfigurator.java
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/m2e/MavenProjectSettingsConfigurator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
@@ -43,13 +43,13 @@ public void configure(ProjectConfigurationRequest request, IProgressMonitor moni
new Executor(Messages.springFormatSettingsImportError).run(() -> {
List searchFolders = getSearchFolders(request);
ProjectSettingsFiles settingsFiles = new ProjectSettingsFilesLocator(searchFolders).locateSettingsFiles();
- settingsFiles.applyToProject(request.getProject(), monitor);
+ settingsFiles.applyToProject(request.mavenProjectFacade().getProject(), monitor);
});
}
private List getSearchFolders(ProjectConfigurationRequest request) {
List files = new ArrayList<>();
- MavenProject project = request.getMavenProject();
+ MavenProject project = request.mavenProject();
while (project != null && project.getBasedir() != null) {
files.add(project.getBasedir());
project = project.getParent();
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/ProjectProperties.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/ProjectProperties.java
index 9cb095f0..982777bd 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/ProjectProperties.java
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/ProjectProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2021 the original author or authors.
+ * Copyright 2012-present 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.
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFile.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFile.java
index d07f1cf9..ec7ef383 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFile.java
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFile.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFiles.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFiles.java
index c7480cf6..2b40f5ae 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFiles.java
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFiles.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFilesLocator.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFilesLocator.java
index 792d207e..e5d5f412 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFilesLocator.java
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/ProjectSettingsFilesLocator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -73,7 +73,7 @@ private String updateFormatter(JavaFormatConfig javaFormatConfig, String content
String formatterId = getFormatterId(javaFormatConfig);
if (formatterId != null) {
return content.replace(
- "org.eclipse.jdt.core.javaFormatter=io.spring.javaformat.eclipse.formatter.jdk11.tabs",
+ "org.eclipse.jdt.core.javaFormatter=io.spring.javaformat.eclipse.formatter.jdk17.tabs",
"org.eclipse.jdt.core.javaFormatter=" + formatterId);
}
return content;
@@ -81,6 +81,7 @@ private String updateFormatter(JavaFormatConfig javaFormatConfig, String content
private String getFormatterId(JavaFormatConfig config) {
String jdk = config.getJavaBaseline().name().substring(1);
+ jdk = (!"11".equals(jdk)) ? jdk : "17";
String indentation = config.getIndentationStyle().name().toLowerCase();
return "io.spring.javaformat.eclipse.formatter.jdk" + jdk + "." + indentation;
}
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/org.eclipse.jdt.core.prefs b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/org.eclipse.jdt.core.prefs
index 155accf7..c08217ef 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/org.eclipse.jdt.core.prefs
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/org.eclipse.jdt.core.prefs
@@ -45,7 +45,7 @@ org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=default
org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
@@ -82,7 +82,7 @@ org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=info
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
@@ -99,7 +99,8 @@ org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=info
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.processAnnotations=disabled
-org.eclipse.jdt.core.javaFormatter=io.spring.javaformat.eclipse.formatter.jdk11.tabs
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.javaFormatter=io.spring.javaformat.eclipse.formatter.jdk17.tabs
diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/org.eclipse.jdt.ui.prefs b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/org.eclipse.jdt.ui.prefs
index af9117f9..23d79e64 100644
--- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/org.eclipse.jdt.ui.prefs
+++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/projectsettings/org.eclipse.jdt.ui.prefs
@@ -1,3 +1,4 @@
+cleanup.add_all=false
cleanup.add_default_serial_version_id=true
cleanup.add_generated_serial_version_id=false
cleanup.add_missing_annotations=true
diff --git a/spring-javaformat-eclipse/pom.xml b/spring-javaformat-eclipse/pom.xml
index 49bb8583..7bed9c79 100644
--- a/spring-javaformat-eclipse/pom.xml
+++ b/spring-javaformat-eclipse/pom.xml
@@ -6,20 +6,20 @@
io.spring.javaformatspring-javaformat-build
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTspring-javaformat-eclipsepomSpring JavaFormat Eclipse Parent${basedir}/..
- 11
+ 17
- eclipse-jdk8
+ eclipse-jdk17p2
- ${eclipse.jdk8.repository}
+ ${eclipse.jdk17.repository}eclipse-checkstyle
diff --git a/spring-javaformat-gradle/io.spring.javaformat.gradle.plugin/pom.xml b/spring-javaformat-gradle/io.spring.javaformat.gradle.plugin/pom.xml
index c365307a..1c2e0383 100644
--- a/spring-javaformat-gradle/io.spring.javaformat.gradle.plugin/pom.xml
+++ b/spring-javaformat-gradle/io.spring.javaformat.gradle.plugin/pom.xml
@@ -5,12 +5,15 @@
io.spring.javaformatspring-javaformat-gradle
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTio.spring.javaformatio.spring.javaformat.gradle.pluginpomSpring JavaFormat Gradle Plugin Marker Artifact
+
+ ${basedir}/../..
+ io.spring.javaformat
diff --git a/spring-javaformat-gradle/pom.xml b/spring-javaformat-gradle/pom.xml
index 2ce6f1b7..681a1645 100644
--- a/spring-javaformat-gradle/pom.xml
+++ b/spring-javaformat-gradle/pom.xml
@@ -6,7 +6,7 @@
io.spring.javaformatspring-javaformat-build
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTspring-javaformat-gradlepom
diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/build.gradle b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/build.gradle
index 706161d8..e088814b 100644
--- a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/build.gradle
+++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/build.gradle
@@ -8,9 +8,9 @@ repositories {
}
dependencies {
- compile fileTree(dir: 'target/dependencies/compile', include: '*.jar')
- testCompile gradleTestKit()
- testCompile fileTree(dir: 'target/dependencies/test', include: '*.jar')
+ implementation fileTree(dir: 'target/dependencies/compile', include: '*.jar')
+ testImplementation gradleTestKit()
+ testImplementation fileTree(dir: 'target/dependencies/test', include: '*.jar')
}
jar {
@@ -61,4 +61,10 @@ artifacts {
archives javadocJar
}
-
+tasks.withType(JavaCompile) {
+ options.compilerArgs.add("-Werror")
+ options.compilerArgs.add("-Xlint:deprecation")
+ options.compilerArgs.add("-Xlint:rawtypes")
+ options.compilerArgs.add("-Xlint:unchecked")
+ options.compilerArgs.add("-Xlint:varargs")
+}
diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/gradle/wrapper/gradle-wrapper.properties b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/gradle/wrapper/gradle-wrapper.properties
index 4d9ca164..070cb702 100644
--- a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/gradle/wrapper/gradle-wrapper.properties
+++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/gradlew b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/gradlew
index 9fcbaf9c..22cf4de8 100755
--- a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/gradlew
+++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/gradlew
@@ -1,7 +1,7 @@
#!/usr/bin/env sh
#
-# Copyright 2015-2020 the original author or authors.
+# Copyright 2015-2023 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.
diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/gradlew.bat b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/gradlew.bat
index 534325e8..18a320c0 100755
--- a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/gradlew.bat
+++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/gradlew.bat
@@ -1,5 +1,5 @@
@rem
-@rem Copyright 2015-2020 the original author or authors.
+@rem Copyright 2015-2023 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/pom.xml b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/pom.xml
index 183ddb78..3170b015 100644
--- a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/pom.xml
+++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/pom.xml
@@ -6,7 +6,7 @@
io.spring.javaformatspring-javaformat-gradle
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTspring-javaformat-gradle-pluginpom
@@ -115,6 +115,12 @@
spring-javaformat-formatter-shaded${project.version}
+
+
+ io.spring.javaformat
+ spring-javaformat-checkstyle
+ ${project.version}
+
diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/SpringJavaFormatExtension.java b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/SpringJavaFormatExtension.java
new file mode 100644
index 00000000..2f173b99
--- /dev/null
+++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/SpringJavaFormatExtension.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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 io.spring.javaformat.gradle;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import javax.inject.Inject;
+
+import org.gradle.api.Action;
+import org.gradle.api.Project;
+import org.gradle.api.plugins.quality.CheckstyleExtension;
+import org.gradle.api.provider.Property;
+import org.gradle.api.resources.TextResource;
+
+/**
+ * DSL extension for Spring Java Format.
+ *
+ * @author Andy Wilkinson
+ */
+public abstract class SpringJavaFormatExtension {
+
+ private final Checkstyle checkstyle;
+
+ @Inject
+ public SpringJavaFormatExtension(Project project) {
+ this.checkstyle = project.getObjects().newInstance(Checkstyle.class, project);
+ this.checkstyle.getConfigureDependencies().convention(true);
+ }
+
+ public Checkstyle getCheckstyle() {
+ return this.checkstyle;
+ }
+
+ public void checkstyle(Action action) {
+ action.execute(this.checkstyle);
+ }
+
+ public abstract static class Checkstyle {
+
+ private final Project project;
+
+ @Inject
+ public Checkstyle(Project project) {
+ this.project = project;
+ }
+
+ /**
+ * Property that controls whether Checkstyle's dependencies should be configured to
+ * use Spring Java Format's checks.
+ * @return the property
+ */
+ public abstract Property getConfigureDependencies();
+
+ /**
+ * Applies Spring Java Format's default Checkstyle config, enabling all Spring checks.
+ * @see CheckstyleExtension#setConfig(TextResource)
+ */
+ public void applyDefaultConfig() {
+ CheckstyleExtension extension = this.project.getExtensions().getByType(CheckstyleExtension.class);
+ StringWriter defaultConfig = new StringWriter();
+ PrintWriter writer = new PrintWriter(defaultConfig);
+ writer.println("");
+ writer.println("");
+ writer.println("");
+ writer.println(" ");
+ writer.println(" ");
+ writer.println("");
+ extension.setConfig(this.project.getResources().getText().fromString(defaultConfig.toString()));
+ }
+
+ }
+
+}
diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/SpringJavaFormatPlugin.java b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/SpringJavaFormatPlugin.java
index e5f27015..4dc2f423 100644
--- a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/SpringJavaFormatPlugin.java
+++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/SpringJavaFormatPlugin.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2022 the original author or authors.
+ * Copyright 2017-present 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.
@@ -17,17 +17,24 @@
package io.spring.javaformat.gradle;
import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.Task;
+import org.gradle.api.artifacts.Dependency;
+import org.gradle.api.artifacts.DependencySet;
import org.gradle.api.plugins.JavaBasePlugin;
-import org.gradle.api.plugins.JavaPluginConvention;
+import org.gradle.api.plugins.JavaPluginExtension;
+import org.gradle.api.plugins.quality.CheckstyleExtension;
+import org.gradle.api.plugins.quality.CheckstylePlugin;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.TaskContainer;
import org.gradle.api.tasks.TaskProvider;
import io.spring.javaformat.config.JavaFormatConfig;
+import io.spring.javaformat.formatter.Formatter;
import io.spring.javaformat.gradle.tasks.CheckFormat;
import io.spring.javaformat.gradle.tasks.Format;
import io.spring.javaformat.gradle.tasks.FormatterTask;
@@ -46,6 +53,13 @@ public class SpringJavaFormatPlugin implements Plugin {
public void apply(Project project) {
this.project = project;
addSourceTasks();
+ SpringJavaFormatExtension extension = registerExtension();
+ new CheckstyleConfigurer(project, extension).apply();
+ }
+
+ private SpringJavaFormatExtension registerExtension() {
+ SpringJavaFormatExtension extension = this.project.getExtensions().create("springJavaFormat", SpringJavaFormatExtension.class);
+ return extension;
}
private void addSourceTasks() {
@@ -56,24 +70,28 @@ private void addSourceTasks() {
TaskProvider checkAllProvider = tasks.register(CheckFormat.NAME);
checkAllProvider.configure((checkAll) -> checkAll.setDescription(CheckFormat.DESCRIPTION));
tasks.named(JavaBasePlugin.CHECK_TASK_NAME).configure((check) -> check.dependsOn(checkAllProvider));
- this.project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets()
- .all((sourceSet) -> addSourceTasks(sourceSet, checkAllProvider, formatAllProvider));
+ this.project.getExtensions()
+ .getByType(JavaPluginExtension.class)
+ .getSourceSets()
+ .all((sourceSet) -> addSourceTasks(sourceSet, checkAllProvider, formatAllProvider));
});
}
- private void addSourceTasks(SourceSet sourceSet, TaskProvider checkAllProvider, TaskProvider formatAllProvider) {
+ private void addSourceTasks(SourceSet sourceSet, TaskProvider checkAllProvider,
+ TaskProvider formatAllProvider) {
TaskProvider checkTaskProvider = addFormatterTask(sourceSet, CheckFormat.class, CheckFormat.NAME,
CheckFormat.DESCRIPTION);
checkTaskProvider.configure((checkTask) -> checkTask.setReportLocation(
new File(this.project.getBuildDir(), "reports/format/" + sourceSet.getName() + "/check-format.txt")));
checkAllProvider.configure((checkAll) -> checkAll.dependsOn(checkTaskProvider));
- TaskProvider formatTaskProvider = addFormatterTask(sourceSet, Format.class, Format.NAME, Format.DESCRIPTION);
+ TaskProvider formatTaskProvider = addFormatterTask(sourceSet, Format.class, Format.NAME,
+ Format.DESCRIPTION);
formatTaskProvider.configure((format) -> format.conventionMapping("encoding", () -> "UTF-8"));
formatAllProvider.configure((formatAll) -> formatAll.dependsOn(formatTaskProvider));
}
- private TaskProvider addFormatterTask(SourceSet sourceSet, Class taskType, String name,
- String desc) {
+ private TaskProvider addFormatterTask(SourceSet sourceSet, Class taskType,
+ String name, String desc) {
String taskName = sourceSet.getTaskName(name, null);
TaskProvider provider = this.project.getTasks().register(taskName, taskType);
provider.configure((task) -> {
@@ -86,4 +104,39 @@ private TaskProvider addFormatterTask(SourceSet sou
return provider;
}
+ private static final class CheckstyleConfigurer {
+
+ private final Project project;
+
+ private final SpringJavaFormatExtension extension;
+
+ private CheckstyleConfigurer(Project project, SpringJavaFormatExtension extension) {
+ this.project = project;
+ this.extension = extension;
+ }
+
+ private void apply() {
+ this.project.getPlugins().withType(CheckstylePlugin.class).configureEach((checkstylePlugin) -> {
+ CheckstyleExtension checkstyle = this.project.getExtensions().getByType(CheckstyleExtension.class);
+ DependencySet checkstyleDependencies = this.project.getConfigurations().getByName("checkstyle").getDependencies();
+ checkstyleDependencies.addAllLater(this.project.provider(() -> checkstyleDependencies(checkstyle)));
+ });
+ }
+
+ private List checkstyleDependencies(CheckstyleExtension checkstyle) {
+ List dependencies = new ArrayList<>();
+ if (configuringCheckstyleDependencies()) {
+ dependencies.add(this.project.getDependencies().create("com.puppycrawl.tools:checkstyle:" + checkstyle.getToolVersion()));
+ dependencies.add(this.project.getDependencies().create("io.spring.javaformat:spring-javaformat-checkstyle:"
+ + Formatter.class.getPackage().getImplementationVersion()));
+ }
+ return dependencies;
+ }
+
+ private boolean configuringCheckstyleDependencies() {
+ return Boolean.TRUE.equals(this.extension.getCheckstyle().getConfigureDependencies().get());
+ }
+
+ }
+
}
diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/tasks/CheckFormat.java b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/tasks/CheckFormat.java
index 6487ff6d..d6504edf 100644
--- a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/tasks/CheckFormat.java
+++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/tasks/CheckFormat.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2022 the original author or authors.
+ * Copyright 2017-present 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.
@@ -24,10 +24,10 @@
import java.util.List;
import java.util.stream.Collectors;
-import org.gradle.api.GradleException;
import org.gradle.api.tasks.CacheableTask;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;
+import org.gradle.api.tasks.VerificationException;
import io.spring.javaformat.formatter.FileEdit;
@@ -53,8 +53,9 @@ public class CheckFormat extends FormatterTask {
@TaskAction
public void checkFormatting() throws IOException, InterruptedException {
- List problems = formatFiles().filter(FileEdit::hasEdits).map(FileEdit::getFile)
- .collect(Collectors.toList());
+ List problems = formatFiles().filter(FileEdit::hasEdits)
+ .map(FileEdit::getFile)
+ .collect(Collectors.toList());
this.reportLocation.getParentFile().mkdirs();
if (!problems.isEmpty()) {
StringBuilder message = new StringBuilder("Formatting violations found in the following files:\n");
@@ -62,7 +63,7 @@ public void checkFormatting() throws IOException, InterruptedException {
message.append("\nRun `format` to fix.");
Files.write(this.reportLocation.toPath(), Collections.singletonList(message.toString()),
StandardOpenOption.CREATE);
- throw new GradleException(message.toString());
+ throw new VerificationException(message.toString());
}
else {
this.reportLocation.createNewFile();
diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/tasks/Format.java b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/tasks/Format.java
index d89abe61..b1f6b312 100644
--- a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/tasks/Format.java
+++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/tasks/Format.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2022 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/tasks/FormatterTask.java b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/tasks/FormatterTask.java
index ed55a945..b99ded44 100644
--- a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/tasks/FormatterTask.java
+++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/tasks/FormatterTask.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2022 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/java/io/spring/javaformat/gradle/CheckTaskTests.java b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/java/io/spring/javaformat/gradle/CheckTaskTests.java
index 6e38db7b..3f413277 100644
--- a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/java/io/spring/javaformat/gradle/CheckTaskTests.java
+++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/java/io/spring/javaformat/gradle/CheckTaskTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2022 the original author or authors.
+ * Copyright 2017-present 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.
@@ -18,12 +18,11 @@
import java.io.File;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
-import java.util.Collections;
import java.util.stream.Stream;
import org.gradle.testkit.runner.BuildResult;
@@ -52,13 +51,13 @@ public class CheckTaskTests {
public File temp;
@Test
- public void checkOk() throws IOException {
+ void checkOk() throws IOException {
BuildResult result = this.gradleBuild.source("src/test/resources/check-ok").build("check");
assertThat(result.task(":checkFormatMain").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
}
@Test
- public void whenFirstInvocationSucceedsThenSecondInvocationIsUpToDate() throws IOException {
+ void whenFirstInvocationSucceedsThenSecondInvocationIsUpToDate() throws IOException {
GradleBuild gradleBuild = this.gradleBuild.source("src/test/resources/check-ok");
BuildResult result = gradleBuild.build("check");
assertThat(result.task(":checkFormatMain").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
@@ -67,19 +66,19 @@ public void whenFirstInvocationSucceedsThenSecondInvocationIsUpToDate() throws I
}
@Test
- public void whenFirstInvocationSucceedsAndSourceIsModifiedThenSecondInvocationSucceeds() throws IOException {
- copyFolder(new File("src/test/resources/check-ok").toPath(), this.temp.toPath());
+ void whenFirstInvocationSucceedsAndSourceIsModifiedThenSecondInvocationSucceeds() throws IOException {
+ copyNormalizedFolder(new File("src/test/resources/check-ok").toPath(), this.temp.toPath());
GradleBuild gradleBuild = this.gradleBuild.source(this.temp);
BuildResult result = gradleBuild.build("check");
assertThat(result.task(":checkFormatMain").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
Files.write(new File(this.temp, "src/main/java/simple/Simple.java").toPath(),
- Collections.singletonList("// A change to the file"), StandardOpenOption.APPEND);
+ "// A change to the file\n".getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
result = gradleBuild.build("--debug", "check");
assertThat(result.task(":checkFormatMain").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
}
@Test
- public void whenFirstInvocationSucceedsAndIndentationStyleIsChangedThenSecondInvocationFails() throws IOException {
+ void whenFirstInvocationSucceedsAndIndentationStyleIsChangedThenSecondInvocationFails() throws IOException {
GradleBuild gradleBuild = this.gradleBuild.source("src/test/resources/check-ok");
BuildResult result = gradleBuild.build("check");
assertThat(result.task(":checkFormatMain").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
@@ -90,7 +89,7 @@ public void whenFirstInvocationSucceedsAndIndentationStyleIsChangedThenSecondInv
}
@Test
- public void whenFirstInvocationFailsAndIndentationStyleIsChangedThenSecondInvocationSucceeds() throws IOException {
+ void whenFirstInvocationFailsAndIndentationStyleIsChangedThenSecondInvocationSucceeds() throws IOException {
GradleBuild gradleBuild = this.gradleBuild.source("src/test/resources/check-spaces");
BuildResult result = gradleBuild.buildAndFail("check");
assertThat(result.task(":checkFormatMain").getOutcome()).isEqualTo(TaskOutcome.FAILED);
@@ -101,7 +100,8 @@ public void whenFirstInvocationFailsAndIndentationStyleIsChangedThenSecondInvoca
}
@Test
- public void whenFirstInvocationSucceedsAndJavaBaselineIsChangedThenSecondInvocationSucceedsAndThirdIsUpToDate() throws IOException {
+ void whenFirstInvocationSucceedsAndJavaBaselineIsChangedThenSecondInvocationSucceedsAndThirdIsUpToDate()
+ throws IOException {
GradleBuild gradleBuild = this.gradleBuild.source("src/test/resources/check-ok");
BuildResult result = gradleBuild.build("check");
assertThat(result.task(":checkFormatMain").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
@@ -114,13 +114,13 @@ public void whenFirstInvocationSucceedsAndJavaBaselineIsChangedThenSecondInvocat
}
@Test
- public void checkBad() throws IOException {
+ void checkBad() throws IOException {
BuildResult result = this.gradleBuild.source("src/test/resources/check-bad").buildAndFail("check");
assertThat(result.task(":checkFormatMain").getOutcome()).isEqualTo(TaskOutcome.FAILED);
}
@Test
- public void whenFirstInvocationFailsThenSecondInvocationFails() throws IOException {
+ void whenFirstInvocationFailsThenSecondInvocationFails() throws IOException {
GradleBuild gradleBuild = this.gradleBuild.source("src/test/resources/check-bad");
BuildResult result = gradleBuild.buildAndFail("check");
assertThat(result.task(":checkFormatMain").getOutcome()).isEqualTo(TaskOutcome.FAILED);
@@ -128,14 +128,17 @@ public void whenFirstInvocationFailsThenSecondInvocationFails() throws IOExcepti
assertThat(result.task(":checkFormatMain").getOutcome()).isEqualTo(TaskOutcome.FAILED);
}
- private void copyFolder(Path source, Path target) throws IOException {
+ private void copyNormalizedFolder(Path source, Path target) throws IOException {
try (Stream stream = Files.walk(source)) {
stream.forEach((child) -> {
try {
Path relative = source.relativize(child);
Path destination = target.resolve(relative);
- if (!destination.toFile().isDirectory()) {
- Files.copy(child, destination, StandardCopyOption.REPLACE_EXISTING);
+ if (!Files.isDirectory(child)) {
+ String content = new String(Files.readAllBytes(child), StandardCharsets.UTF_8);
+ String normalized = content.replace("\n\r", "\n").replace('\r', '\n');
+ Files.createDirectories(destination.getParent());
+ Files.write(destination, normalized.getBytes(StandardCharsets.UTF_8));
}
}
catch (Exception ex) {
diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/java/io/spring/javaformat/gradle/CheckstyleTests.java b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/java/io/spring/javaformat/gradle/CheckstyleTests.java
new file mode 100644
index 00000000..8995edad
--- /dev/null
+++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/java/io/spring/javaformat/gradle/CheckstyleTests.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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 io.spring.javaformat.gradle;
+
+import org.gradle.testkit.runner.BuildResult;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import io.spring.javaformat.gradle.testkit.GradleBuild;
+import io.spring.javaformat.gradle.testkit.GradleBuildExtension;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@ExtendWith(GradleBuildExtension.class)
+class CheckstyleTests {
+
+ private final GradleBuild gradleBuild = new GradleBuild();
+
+ @Test
+ void configureCheckstyle() {
+ BuildResult result = this.gradleBuild.source("src/test/resources/checkstyle-configure").build("checkstyleDependencies");
+ assertThat(result.getOutput()).contains("io.spring.javaformat:spring-javaformat-checkstyle:");
+ assertThat(result.getOutput()).contains("com.puppycrawl.tools:checkstyle:8.45.1");
+ }
+
+ @Test
+ void configureCheckstyleWithCustomToolVersion() {
+ BuildResult result = this.gradleBuild.source("src/test/resources/checkstyle-configure-with-custom-tool-version").build("checkstyleDependencies");
+ assertThat(result.getOutput()).contains("io.spring.javaformat:spring-javaformat-checkstyle:");
+ assertThat(result.getOutput()).contains("com.puppycrawl.tools:checkstyle:10.26.1");
+ }
+
+ @Test
+ void doNotConfigureCheckstyle() {
+ BuildResult result = this.gradleBuild.source("src/test/resources/checkstyle-do-not-configure").build("checkstyleDependencies");
+ assertThat(result.getOutput()).doesNotContain("spring-javaformat-checkstyle");
+ }
+
+ @Test
+ void applyDefaultConfigToCheckstyle() {
+ BuildResult result = this.gradleBuild.source("src/test/resources/checkstyle-apply-default-config").build("checkstyleConfig");
+ assertThat(result.getOutput()).contains("");
+ }
+
+}
diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/java/io/spring/javaformat/gradle/FormatTaskTests.java b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/java/io/spring/javaformat/gradle/FormatTaskTests.java
index 023b4d0d..e3d29e16 100644
--- a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/java/io/spring/javaformat/gradle/FormatTaskTests.java
+++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/java/io/spring/javaformat/gradle/FormatTaskTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2022 the original author or authors.
+ * Copyright 2017-present 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.
@@ -44,7 +44,7 @@ public class FormatTaskTests {
private final GradleBuild gradleBuild = new GradleBuild();
@Test
- public void checkOk() throws IOException {
+ void checkOk() throws IOException {
BuildResult result = this.gradleBuild.source("src/test/resources/format").build("format");
assertThat(result.task(":formatMain").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
File formattedFile = new File(this.gradleBuild.getProjectDir(), "src/main/java/simple/Simple.java");
@@ -53,7 +53,7 @@ public void checkOk() throws IOException {
}
@Test
- public void checkUpToDate() throws IOException {
+ void checkUpToDate() throws IOException {
GradleRunner runner = this.gradleBuild.source("src/test/resources/format").prepareRunner("format");
// Format that changes files
assertThat(runner.build().task(":formatMain").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
@@ -64,7 +64,7 @@ public void checkUpToDate() throws IOException {
}
@Test
- public void notUpToDateWhenJavaBaselineChanges() throws IOException {
+ void notUpToDateWhenJavaBaselineChanges() throws IOException {
GradleRunner runner = this.gradleBuild.source("src/test/resources/format").prepareRunner("format");
// Format that changes files
assertThat(runner.build().task(":formatMain").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
@@ -78,7 +78,7 @@ public void notUpToDateWhenJavaBaselineChanges() throws IOException {
}
@Test
- public void notUpToDateWhenIndentationStyleChanges() throws IOException {
+ void notUpToDateWhenIndentationStyleChanges() throws IOException {
GradleRunner runner = this.gradleBuild.source("src/test/resources/format").prepareRunner("format");
// Format that changes files
assertThat(runner.build().task(":formatMain").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
@@ -92,7 +92,7 @@ public void notUpToDateWhenIndentationStyleChanges() throws IOException {
}
@Test
- public void checkSpacesOk() throws IOException {
+ void checkSpacesOk() throws IOException {
BuildResult result = this.gradleBuild.source("src/test/resources/format-spaces").build("format");
assertThat(result.task(":formatMain").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
File formattedFile = new File(this.gradleBuild.getProjectDir(), "src/main/java/simple/Simple.java");
diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/java/io/spring/javaformat/gradle/testkit/GradleBuild.java b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/java/io/spring/javaformat/gradle/testkit/GradleBuild.java
index a045feb5..1414da78 100644
--- a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/java/io/spring/javaformat/gradle/testkit/GradleBuild.java
+++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/java/io/spring/javaformat/gradle/testkit/GradleBuild.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/java/io/spring/javaformat/gradle/testkit/GradleBuildExtension.java b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/java/io/spring/javaformat/gradle/testkit/GradleBuildExtension.java
index d5b1cc80..bb5b8a6d 100644
--- a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/java/io/spring/javaformat/gradle/testkit/GradleBuildExtension.java
+++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/java/io/spring/javaformat/gradle/testkit/GradleBuildExtension.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/checkstyle-apply-default-config/build.gradle b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/checkstyle-apply-default-config/build.gradle
new file mode 100644
index 00000000..302352be
--- /dev/null
+++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/checkstyle-apply-default-config/build.gradle
@@ -0,0 +1,27 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'checkstyle'
+apply plugin: 'java'
+apply plugin: 'io.spring.javaformat'
+
+sourceCompatibility = 1.8
+
+repositories {
+ mavenCentral()
+}
+
+springJavaFormat {
+ checkstyle {
+ applyDefaultConfig()
+ }
+}
+
+tasks.register("checkstyleConfig") {
+ doFirst {
+ println checkstyle.config.asString()
+ }
+}
diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/checkstyle-configure-with-custom-tool-version/build.gradle b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/checkstyle-configure-with-custom-tool-version/build.gradle
new file mode 100644
index 00000000..cc42d068
--- /dev/null
+++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/checkstyle-configure-with-custom-tool-version/build.gradle
@@ -0,0 +1,25 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'checkstyle'
+apply plugin: 'java'
+apply plugin: 'io.spring.javaformat'
+
+sourceCompatibility = 1.8
+
+repositories {
+ mavenCentral()
+}
+
+checkstyle {
+ toolVersion = "10.26.1"
+}
+
+tasks.register("checkstyleDependencies") {
+ doFirst {
+ configurations.checkstyle.dependencies.each { println "${it.group}:${it.name}:${it.version}" }
+ }
+}
diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/checkstyle-configure/build.gradle b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/checkstyle-configure/build.gradle
new file mode 100644
index 00000000..08207b88
--- /dev/null
+++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/checkstyle-configure/build.gradle
@@ -0,0 +1,21 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'checkstyle'
+apply plugin: 'java'
+apply plugin: 'io.spring.javaformat'
+
+sourceCompatibility = 1.8
+
+repositories {
+ mavenCentral()
+}
+
+tasks.register("checkstyleDependencies") {
+ doFirst {
+ configurations.checkstyle.dependencies.each { println "${it.group}:${it.name}:${it.version}" }
+ }
+}
diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/checkstyle-do-not-configure/build.gradle b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/checkstyle-do-not-configure/build.gradle
new file mode 100644
index 00000000..561ffa61
--- /dev/null
+++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/checkstyle-do-not-configure/build.gradle
@@ -0,0 +1,23 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'checkstyle'
+apply plugin: 'java'
+apply plugin: 'io.spring.javaformat'
+
+sourceCompatibility = 1.8
+
+springJavaFormat {
+ checkstyle {
+ configureDependencies = false
+ }
+}
+
+tasks.register("checkstyleDependencies") {
+ doFirst {
+ configurations.checkstyle.dependencies.each { println "${it.group}:${it.name}:${it.version}" }
+ }
+}
diff --git a/spring-javaformat-intellij-idea/pom.xml b/spring-javaformat-intellij-idea/pom.xml
index f15ad773..9de7cec6 100644
--- a/spring-javaformat-intellij-idea/pom.xml
+++ b/spring-javaformat-intellij-idea/pom.xml
@@ -5,7 +5,7 @@
io.spring.javaformatspring-javaformat-build
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTspring-javaformat-intellij-ideapom
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/pom.xml b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/pom.xml
index 84d6d21e..7915af9f 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/pom.xml
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/pom.xml
@@ -6,21 +6,16 @@
io.spring.javaformatspring-javaformat-intellij-idea
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTspring-javaformat-intellij-idea-pluginSpring JavaFormat IntelliJ IDEA Plugin${basedir}/../..
- 11
+ 17
-
- io.spring.javaformat
- spring-javaformat-formatter
- ${project.version}
- io.spring.javaformatspring-javaformat-formatter-eclipse-runtime
@@ -32,6 +27,11 @@
+
+ io.spring.javaformat
+ spring-javaformat-formatter
+ ${project.version}
+ io.spring.javaformat
@@ -41,20 +41,20 @@
provided
- io.spring.javaformat.intellij.idea
+ org.jetbrainsannotations
- ${project.version}
+ 13.0providedio.spring.javaformat.intellij.idea
- platform-api
+ app${project.version}providedio.spring.javaformat.intellij.idea
- platform-impl
+ jps-model${project.version}provided
@@ -66,7 +66,7 @@
io.spring.javaformat.intellij.idea
- idea
+ util_rt${project.version}provided
@@ -78,7 +78,7 @@
io.spring.javaformat.intellij.idea
- maven-server-api
+ maven-server${project.version}provided
@@ -110,6 +110,18 @@
picocontainerprovided
+
+ org.jetbrains.kotlinx
+ kotlinx-coroutines-core
+ 1.6.4
+ provided
+
+
+ it.unimi.dsi
+ fastutil
+ 8.5.11
+ provided
+
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/SpringFormat.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/SpringFormat.java
deleted file mode 100644
index 79a76382..00000000
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/SpringFormat.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright 2017-2021 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
- *
- * https://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 io.spring.format.formatter.intellij;
-
-import java.lang.reflect.Method;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-import com.intellij.ide.plugins.IdeaPluginDescriptor;
-import com.intellij.ide.plugins.PluginManagerCore;
-import com.intellij.ide.util.PropertiesComponent;
-import com.intellij.openapi.application.ApplicationInfo;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.extensions.PluginDescriptor;
-import com.intellij.openapi.extensions.PluginId;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Disposer;
-import com.intellij.psi.codeStyle.CodeStyleManager;
-import com.intellij.serviceContainer.ComponentManagerImpl;
-import org.picocontainer.MutablePicoContainer;
-
-import io.spring.format.formatter.intellij.codestyle.SpringCodeStyleManager;
-import io.spring.format.formatter.intellij.codestyle.monitor.FileMonitor;
-import io.spring.format.formatter.intellij.codestyle.monitor.GradleMonitor;
-import io.spring.format.formatter.intellij.codestyle.monitor.MavenMonitor;
-import io.spring.format.formatter.intellij.codestyle.monitor.Monitors;
-import io.spring.format.formatter.intellij.codestyle.monitor.Trigger.State;
-
-/**
- * Spring Java Format IntelliJ support added to a {@link Project}.
- *
- * @author Phillip Webb
- */
-public class SpringFormat {
-
- private static final String CODE_STYLE_MANAGER_KEY = CodeStyleManager.class.getName();
-
- private static final String ACTIVE_PROPERTY = SpringFormat.class.getName() + ".ACTIVE";
-
- private static final Logger logger = Logger.getInstance(SpringFormat.class);
-
- private final Project project;
-
- private final StatusIndicator statusIndicator;
-
- private final Lock lock = new ReentrantLock();
-
- private Monitors monitors;
-
- private PropertiesComponent properties;
-
- protected SpringFormat(Project project) {
- logger.info("Initializing Spring Format for project " + project.getName());
- this.project = project;
- this.statusIndicator = new StatusIndicator(project);
- this.properties = PropertiesComponent.getInstance(project);
- if (this.properties.getBoolean(ACTIVE_PROPERTY, false)) {
- update(State.ACTIVE);
- }
- this.monitors = new Monitors(this.project, this::update, FileMonitor.factory(), MavenMonitor.factory(),
- GradleMonitor.factory());
- Disposer.register(project, this::dispose);
- }
-
- private void dispose() {
- if (this.monitors != null) {
- this.monitors.stop();
- this.monitors = null;
- }
- }
-
- private void update(State state) {
- logger.info("Updating state of " + this.project.getName() + " to " + state);
- this.lock.lock();
- try {
- CodeStyleManager manager = CodeStyleManager.getInstance(this.project);
- if (manager == null) {
- logger.warn("Unable to find exiting CodeStyleManager");
- return;
- }
- if (state == State.ACTIVE && !(manager instanceof SpringCodeStyleManager)) {
- logger.debug("Enabling SpringCodeStyleManager");
- registerCodeStyleManager(new SpringCodeStyleManager(manager));
- this.properties.setValue(ACTIVE_PROPERTY, true);
- }
- if (state == State.NOT_ACTIVE && (manager instanceof SpringCodeStyleManager)) {
- logger.debug("Disabling SpringCodeStyleManager");
- registerCodeStyleManager(((SpringCodeStyleManager) manager).getDelegate());
- this.properties.setValue(ACTIVE_PROPERTY, false);
- }
- ApplicationManager.getApplication().invokeLater(() -> this.statusIndicator.update(state));
- }
- finally {
- this.lock.unlock();
- }
- }
-
- private void registerCodeStyleManager(CodeStyleManager manager) {
- if (ApplicationInfo.getInstance().getBuild().getBaselineVersion() >= 193) {
- IdeaPluginDescriptor plugin = PluginManagerCore.getPlugin(PluginId.getId("spring-javaformat"));
- try {
- ((ComponentManagerImpl) this.project).registerServiceInstance(CodeStyleManager.class, manager, plugin);
- }
- catch (NoSuchMethodError ex) {
- Method method = findRegisterServiceInstanceMethod(this.project.getClass());
- invokeRegisterServiceInstanceMethod(manager, plugin, method);
- }
- }
- else {
- MutablePicoContainer container = (MutablePicoContainer) this.project.getPicoContainer();
- container.unregisterComponent(CODE_STYLE_MANAGER_KEY);
- container.registerComponentInstance(CODE_STYLE_MANAGER_KEY, manager);
- }
- }
-
- private Method findRegisterServiceInstanceMethod(Class> projectClass) {
- if (projectClass != null) {
- Method[] methods = projectClass.getDeclaredMethods();
- for (Method method : methods) {
- if (method.getName().equals("registerServiceInstance") && method.getParameterCount() == 3) {
- if (PluginDescriptor.class.isAssignableFrom(method.getParameterTypes()[2])) {
- return method;
- }
- }
- }
- return findRegisterServiceInstanceMethod(projectClass.getSuperclass());
- }
- return null;
- }
-
- private void invokeRegisterServiceInstanceMethod(CodeStyleManager manager, IdeaPluginDescriptor plugin,
- Method method) {
- if (method == null) {
- throw new IllegalStateException("Unsupported IntelliJ IDEA version");
- }
- method.setAccessible(true);
- try {
- method.invoke(this.project, manager, plugin);
- }
- catch (Exception ex) {
- throw new IllegalStateException(ex);
- }
- }
-
-}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/DelegatingCodeStyleManager.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/DelegatingCodeStyleManager.java
deleted file mode 100644
index c133d872..00000000
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/DelegatingCodeStyleManager.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright 2017-2021 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
- *
- * https://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 io.spring.format.formatter.intellij.codestyle;
-
-import java.util.Collection;
-
-import com.intellij.formatting.FormattingMode;
-import com.intellij.lang.ASTNode;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.codeStyle.ChangedRangesInfo;
-import com.intellij.psi.codeStyle.CodeStyleManager;
-import com.intellij.psi.codeStyle.DocCommentSettings;
-import com.intellij.psi.codeStyle.FormattingModeAwareIndentAdjuster;
-import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.ThrowableRunnable;
-
-/**
- * {@link CodeStyleManager} implementation that delegates all calls.
- *
- * @author Phillip Webb
- */
-public class DelegatingCodeStyleManager extends CodeStyleManager implements FormattingModeAwareIndentAdjuster {
-
- private final CodeStyleManager delegate;
-
- public DelegatingCodeStyleManager(CodeStyleManager delegate) {
- this.delegate = delegate;
- }
-
- public CodeStyleManager getDelegate() {
- return this.delegate;
- }
-
- @Override
- public int getSpacing(PsiFile file, int offset) {
- return this.delegate.getSpacing(file, offset);
- }
-
- @Override
- public int getMinLineFeeds(PsiFile file, int offset) {
- return this.delegate.getMinLineFeeds(file, offset);
- }
-
- @Override
- public void runWithDocCommentFormattingDisabled(PsiFile file, Runnable runnable) {
- this.delegate.runWithDocCommentFormattingDisabled(file, runnable);
- }
-
- @Override
- public DocCommentSettings getDocCommentSettings(PsiFile file) {
- return this.delegate.getDocCommentSettings(file);
- }
-
- @Override
- public Project getProject() {
- return this.delegate.getProject();
- }
-
- @Override
- public PsiElement reformat(PsiElement element) throws IncorrectOperationException {
- return this.delegate.reformat(element);
- }
-
- @Override
- public PsiElement reformat(PsiElement element, boolean canChangeWhiteSpacesOnly)
- throws IncorrectOperationException {
- return this.delegate.reformat(element, canChangeWhiteSpacesOnly);
- }
-
- @Override
- public PsiElement reformatRange(PsiElement element, int startOffset, int endOffset)
- throws IncorrectOperationException {
- return this.delegate.reformatRange(element, startOffset, endOffset);
- }
-
- @Override
- public PsiElement reformatRange(PsiElement element, int startOffset, int endOffset,
- boolean canChangeWhiteSpacesOnly) throws IncorrectOperationException {
- return this.delegate.reformatRange(element, startOffset, endOffset, canChangeWhiteSpacesOnly);
- }
-
- @Override
- public void reformatText(PsiFile file, int startOffset, int endOffset) throws IncorrectOperationException {
- this.delegate.reformatText(file, startOffset, endOffset);
- }
-
- @Override
- public void reformatText(PsiFile file, Collection extends TextRange> ranges) throws IncorrectOperationException {
- this.delegate.reformatText(file, ranges);
- }
-
- @Override
- public void reformatTextWithContext(PsiFile file, ChangedRangesInfo info) throws IncorrectOperationException {
- this.delegate.reformatTextWithContext(file, info);
- }
-
- @Override
- public void adjustLineIndent(PsiFile file, TextRange rangeToAdjust) throws IncorrectOperationException {
- this.delegate.adjustLineIndent(file, rangeToAdjust);
- }
-
- @Override
- public int adjustLineIndent(PsiFile file, int offset) throws IncorrectOperationException {
- return this.delegate.adjustLineIndent(file, offset);
- }
-
- @Override
- public int adjustLineIndent(Document document, int offset) {
- return this.delegate.adjustLineIndent(document, offset);
- }
-
- @Override
- @Deprecated
- public boolean isLineToBeIndented(PsiFile file, int offset) {
- return this.delegate.isLineToBeIndented(file, offset);
- }
-
- @Override
- public String getLineIndent(PsiFile file, int offset) {
- return this.delegate.getLineIndent(file, offset);
- }
-
- @Override
- public String getLineIndent(Document document, int offset) {
- return this.delegate.getLineIndent(document, offset);
- }
-
- @Override
- public String getLineIndent(PsiFile file, int offset, FormattingMode mode) {
- return this.delegate.getLineIndent(file, offset, mode);
- }
-
- @Override
- @Deprecated
- public com.intellij.psi.codeStyle.Indent getIndent(String text, FileType fileType) {
- return this.delegate.getIndent(text, fileType);
- }
-
- @Override
- @Deprecated
- public String fillIndent(com.intellij.psi.codeStyle.Indent indent, FileType fileType) {
- return this.delegate.fillIndent(indent, fileType);
- }
-
- @Override
- @Deprecated
- public com.intellij.psi.codeStyle.Indent zeroIndent() {
- return this.delegate.zeroIndent();
- }
-
- @Override
- public void reformatNewlyAddedElement(ASTNode block, ASTNode addedElement) throws IncorrectOperationException {
- this.delegate.reformatNewlyAddedElement(block, addedElement);
- }
-
- @Override
- public boolean isSequentialProcessingAllowed() {
- return this.delegate.isSequentialProcessingAllowed();
- }
-
- @Override
- public void performActionWithFormatterDisabled(Runnable r) {
- this.delegate.performActionWithFormatterDisabled(r);
- }
-
- @Override
- public void performActionWithFormatterDisabled(ThrowableRunnable r) throws T {
- this.delegate.performActionWithFormatterDisabled(r);
- }
-
- @Override
- public T performActionWithFormatterDisabled(Computable r) {
- return this.delegate.performActionWithFormatterDisabled(r);
- }
-
- @Override
- public int adjustLineIndent(Document document, int offset, FormattingMode mode) {
- if (this.delegate instanceof FormattingModeAwareIndentAdjuster) {
- return ((FormattingModeAwareIndentAdjuster) this.delegate).adjustLineIndent(document, offset, mode);
- }
- return offset;
- }
-
- @Override
- public FormattingMode getCurrentFormattingMode() {
- if (this.delegate instanceof FormattingModeAwareIndentAdjuster) {
- return ((FormattingModeAwareIndentAdjuster) this.delegate).getCurrentFormattingMode();
- }
- return FormattingMode.REFORMAT;
- }
-
- @Override
- public void scheduleIndentAdjustment(Document document, int offset) {
- this.delegate.scheduleIndentAdjustment(document, offset);
- }
-
- @Override
- public void scheduleReformatWhenSettingsComputed(PsiFile file) {
- this.delegate.scheduleReformatWhenSettingsComputed(file);
- }
-
-}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/SpringCodeStyleManager.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/SpringCodeStyleManager.java
deleted file mode 100644
index 56b94ab5..00000000
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/SpringCodeStyleManager.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2017-2021 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
- *
- * https://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 io.spring.format.formatter.intellij.codestyle;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.function.Supplier;
-
-import com.intellij.openapi.util.TextRange;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.codeStyle.ChangedRangesInfo;
-import com.intellij.psi.codeStyle.CodeStyleManager;
-import com.intellij.util.IncorrectOperationException;
-
-/**
- * {@link CodeStyleManager} to apply Spring Formatting conventions.
- *
- * @author Phillip Webb
- */
-public class SpringCodeStyleManager extends DelegatingCodeStyleManager {
-
- private final SpringReformatter springReformatter;
-
- public SpringCodeStyleManager(CodeStyleManager delegate) {
- super(delegate);
- this.springReformatter = new SpringReformatter(() -> getProject());
- }
-
- SpringCodeStyleManager(CodeStyleManager delegate, SpringReformatter springReformatter) {
- super(delegate);
- this.springReformatter = springReformatter;
- }
-
- @Override
- public void reformatText(PsiFile file, int startOffset, int endOffset) throws IncorrectOperationException {
- reformat(file, () -> Collections.singleton(new TextRange(startOffset, endOffset)),
- () -> super.reformatText(file, startOffset, endOffset));
- }
-
- @Override
- public void reformatText(PsiFile file, Collection extends TextRange> ranges) throws IncorrectOperationException {
- reformat(file, () -> ranges, () -> super.reformatText(file, ranges));
- }
-
- @Override
- public void reformatTextWithContext(PsiFile file, ChangedRangesInfo info) throws IncorrectOperationException {
- reformat(file, () -> info.allChangedRanges, () -> super.reformatTextWithContext(file, info));
- }
-
- private void reformat(PsiFile file, Supplier> ranges, Runnable delegate) {
- if (this.springReformatter.canReformat(file)) {
- this.springReformatter.reformat(file, ranges.get());
- }
- else {
- delegate.run();
- }
- }
-
-}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/SpringReformatter.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/SpringReformatter.java
deleted file mode 100644
index be1ceed0..00000000
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/SpringReformatter.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright 2017-2021 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
- *
- * https://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 io.spring.format.formatter.intellij.codestyle;
-
-import java.util.Collection;
-import java.util.function.Supplier;
-
-import com.intellij.core.CoreBundle;
-import com.intellij.openapi.application.Application;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.command.WriteCommandAction;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.FileTypeManager;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiDirectory;
-import com.intellij.psi.PsiDocumentManager;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.util.IncorrectOperationException;
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.text.edits.TextEdit;
-
-import io.spring.javaformat.config.JavaFormatConfig;
-import io.spring.javaformat.formatter.Formatter;
-
-/**
- * Reformatter used by {@link SpringCodeStyleManager} to determine when formatting can
- * apply and to perform the actual formatting.
- *
- * @author Phillip Webb
- */
-class SpringReformatter {
-
- private static final String NORMALIZED_LINE_SEPARATOR = "\n";
-
- private static final FileType JAVA_FILE_TYPE = FileTypeManager.getInstance().getStdFileType("JAVA");
-
- private final Supplier project;
-
- private final Supplier application;
-
- private final Supplier documentManager;
-
- SpringReformatter(Supplier project) {
- this.project = project;
- this.application = () -> ApplicationManager.getApplication();
- this.documentManager = () -> PsiDocumentManager.getInstance(project.get());
- }
-
- SpringReformatter(Supplier project, Supplier application,
- Supplier documentManager) {
- this.project = project;
- this.application = application;
- this.documentManager = documentManager;
- }
-
- public boolean canReformat(PsiFile file) {
- return JAVA_FILE_TYPE.equals(file.getFileType());
- }
-
- public void reformat(PsiFile file, Collection extends TextRange> ranges) {
- this.application.get().assertWriteAccessAllowed();
- this.documentManager.get().commitAllDocuments();
- if (!file.isWritable()) {
- throwNotWritableException(file);
- }
- reformat(file, ranges, this.documentManager.get().getDocument(file));
- }
-
- private void throwNotWritableException(PsiElement element) throws IncorrectOperationException {
- if (element instanceof PsiDirectory) {
- String url = ((PsiDirectory) element).getVirtualFile().getPresentableUrl();
- throw new IncorrectOperationException(CoreBundle.message("cannot.modify.a.read.only.directory", url));
- }
- PsiFile file = element.getContainingFile();
- if (file == null) {
- throw new IncorrectOperationException();
- }
- VirtualFile virtualFile = file.getVirtualFile();
- if (virtualFile == null) {
- throw new IncorrectOperationException();
- }
- throw new IncorrectOperationException(
- CoreBundle.message("cannot.modify.a.read.only.file", virtualFile.getPresentableUrl()));
- }
-
- private void reformat(PsiFile file, Collection extends TextRange> ranges, Document document) {
- if (document != null && file.getVirtualFile() != null) {
- JavaFormatConfig javaFormatConfig = JavaFormatConfig.findFrom(file.getVirtualFile().toNioPath());
- Formatter formatter = new Formatter(javaFormatConfig);
- String source = document.getText();
- IRegion[] regions = EclipseRegionAdapter.asArray(ranges);
- TextEdit edit = formatter.format(source, regions, NORMALIZED_LINE_SEPARATOR);
- applyEdit(document, edit);
- }
- }
-
- private void applyEdit(Document document, TextEdit textEdit) {
- runWriteCommandAction(() -> {
- try {
- EclipseDocumentAdapter adapter = new EclipseDocumentAdapter(document);
- textEdit.apply(adapter);
- this.documentManager.get().commitDocument(document);
- }
- catch (Exception ex) {
- throw new IllegalStateException(ex);
- }
- });
- }
-
- protected void runWriteCommandAction(Runnable runnable) {
- WriteCommandAction.runWriteCommandAction(this.project.get(), runnable);
- }
-
-}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/EclipseDocumentAdapter.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/formatting/EclipseDocumentAdapter.java
similarity index 92%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/EclipseDocumentAdapter.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/formatting/EclipseDocumentAdapter.java
index 99dadda0..255a72f1 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/EclipseDocumentAdapter.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/formatting/EclipseDocumentAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-present 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij.codestyle;
+package io.spring.format.formatter.intellij.formatting;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/EclipseRegionAdapter.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/formatting/EclipseRegionAdapter.java
similarity index 79%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/EclipseRegionAdapter.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/formatting/EclipseRegionAdapter.java
index 59169754..1b1fdc9e 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/EclipseRegionAdapter.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/formatting/EclipseRegionAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-present 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.
@@ -14,10 +14,9 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij.codestyle;
+package io.spring.format.formatter.intellij.formatting;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
import com.intellij.openapi.util.TextRange;
@@ -29,15 +28,15 @@
*
* @author Phillip Webb
*/
-public class EclipseRegionAdapter extends Region {
+class EclipseRegionAdapter extends Region {
private static final IRegion[] NO_REGIONS = {};
- public EclipseRegionAdapter(TextRange range) {
+ EclipseRegionAdapter(TextRange range) {
super(range.getStartOffset(), range.getLength());
}
- public static IRegion[] asArray(Collection extends TextRange> ranges) {
+ static IRegion[] asArray(List ranges) {
if (ranges == null) {
return NO_REGIONS;
}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/formatting/SpringJavaFormatFormattingService.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/formatting/SpringJavaFormatFormattingService.java
new file mode 100644
index 00000000..70bb51e9
--- /dev/null
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/formatting/SpringJavaFormatFormattingService.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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 io.spring.format.formatter.intellij.formatting;
+
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Set;
+import java.util.function.BiConsumer;
+
+import com.intellij.formatting.FormattingContext;
+import com.intellij.formatting.service.AbstractDocumentFormattingService;
+import com.intellij.formatting.service.FormattingService;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.text.edits.TextEdit;
+import org.jetbrains.annotations.NotNull;
+
+import io.spring.format.formatter.intellij.state.State;
+import io.spring.javaformat.config.JavaFormatConfig;
+import io.spring.javaformat.formatter.Formatter;
+
+/**
+ * {@link FormattingService} to apply Spring formatting conventions.
+ *
+ * @author Phillip Webb
+ */
+public class SpringJavaFormatFormattingService extends AbstractDocumentFormattingService {
+
+ private static final String NORMALIZED_LINE_SEPARATOR = "\n";
+
+ private static final Set FEATURES = Set.of(Feature.FORMAT_FRAGMENTS);
+
+ private static final FileType JAVA_FILE_TYPE = FileTypeManager.getInstance().getStdFileType("JAVA");
+
+ private final BiConsumer runAction;
+
+ public SpringJavaFormatFormattingService() {
+ this(WriteCommandAction::runWriteCommandAction);
+ }
+
+ SpringJavaFormatFormattingService(BiConsumer runAction) {
+ this.runAction = runAction;
+ }
+
+ @Override
+ public @NotNull Set getFeatures() {
+ return FEATURES;
+ }
+
+ @Override
+ public boolean canFormat(@NotNull PsiFile file) {
+ return JAVA_FILE_TYPE.equals(file.getFileType()) && State.get(file.getProject()) == State.ACTIVE;
+ }
+
+ @Override
+ public void formatDocument(@NotNull Document document, @NotNull List formattingRanges,
+ @NotNull FormattingContext formattingContext, boolean canChangeWhiteSpaceOnly, boolean quickFormat) {
+ VirtualFile file = formattingContext.getVirtualFile();
+ Path path = (file != null) ? file.getFileSystem().getNioPath(file) : null;
+ JavaFormatConfig config = JavaFormatConfig.findFrom(path);
+ Formatter formatter = new Formatter(config);
+ String source = document.getText();
+ formattingRanges = (!formattingRanges.isEmpty()) ? formattingRanges : List.of(TextRange.allOf(source));
+ IRegion[] regions = EclipseRegionAdapter.asArray(formattingRanges);
+ TextEdit edit = formatter.format(source, regions, NORMALIZED_LINE_SEPARATOR);
+ applyEdit(formattingContext.getProject(), document, edit);
+ }
+
+ private void applyEdit(Project project, Document document, TextEdit textEdit) {
+ this.runAction.accept(project, () -> {
+ try {
+ IDocument adapted = new EclipseDocumentAdapter(document);
+ textEdit.apply(adapted);
+ }
+ catch (Exception ex) {
+ throw new IllegalStateException(ex);
+ }
+ });
+ }
+
+}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/FileMonitor.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/FileMonitor.java
similarity index 88%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/FileMonitor.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/FileMonitor.java
index cc93579c..84128c15 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/FileMonitor.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/FileMonitor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-present 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij.codestyle.monitor;
+package io.spring.format.formatter.intellij.monitor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
@@ -24,16 +24,16 @@
import com.intellij.openapi.vfs.VirtualFileMoveEvent;
import com.intellij.openapi.vfs.VirtualFilePropertyEvent;
-import io.spring.format.formatter.intellij.codestyle.monitor.Trigger.State;
+import io.spring.format.formatter.intellij.state.State;
/**
- * {@link Monitor} that looks for a {@literal .springformat} file.
+ * {@link Monitor} that looks for a {@literal .springjavaformatconfig} file.
*
* @author Phillip Webb
*/
public class FileMonitor extends Monitor {
- private static final String TRIGGER_FILE = ".springformat";
+ private static final String TRIGGER_FILE = ".springjavaformatconfig";
private final VirtualFileManager fileManager;
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/GradleMonitor.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/GradleMonitor.java
similarity index 85%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/GradleMonitor.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/GradleMonitor.java
index a90c9ce6..8a41e441 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/GradleMonitor.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/GradleMonitor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -14,11 +14,10 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij.codestyle.monitor;
+package io.spring.format.formatter.intellij.monitor;
import java.util.Collection;
-import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.ExternalProjectInfo;
@@ -27,9 +26,10 @@
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataImportListener;
import com.intellij.openapi.project.Project;
import com.intellij.util.messages.MessageBusConnection;
+import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.util.GradleConstants;
-import io.spring.format.formatter.intellij.codestyle.monitor.Trigger.State;
+import io.spring.format.formatter.intellij.state.State;
/**
* {@link Monitor} that looks for a {@code spring-javaformat-gradle-plugin} declaration in
@@ -46,12 +46,19 @@ public class GradleMonitor extends Monitor {
public GradleMonitor(Project project, Trigger trigger) {
super(project, trigger);
MessageBusConnection messageBus = project.getMessageBus().connect();
- messageBus.subscribe(ProjectDataImportListener.TOPIC, (path) -> check());
+ messageBus.subscribe(ProjectDataImportListener.TOPIC, new ProjectDataImportListener() {
+
+ @Override
+ public void onImportFinished(@Nullable String projectPath) {
+ check();
+ }
+
+ });
}
private void check() {
logger.info("Checking " + getProject().getName() + " for use of Spring Java Format");
- ProjectDataManager projectDataManager = ServiceManager.getService(ProjectDataManager.class);
+ ProjectDataManager projectDataManager = ProjectDataManager.getInstance();
boolean hasFormatPlugin = hasFormatPlugin(
projectDataManager.getExternalProjectsData(getProject(), GradleConstants.SYSTEM_ID));
getTrigger().updateState(hasFormatPlugin ? State.ACTIVE : State.NOT_ACTIVE);
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/MavenMonitor.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/MavenMonitor.java
similarity index 93%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/MavenMonitor.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/MavenMonitor.java
index c0cab821..6ddb20e8 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/MavenMonitor.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/MavenMonitor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-present 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij.codestyle.monitor;
+package io.spring.format.formatter.intellij.monitor;
import java.util.List;
@@ -26,7 +26,7 @@
import org.jetbrains.idea.maven.project.MavenProjectsTree.Listener;
import org.jetbrains.idea.maven.server.NativeMavenProjectHolder;
-import io.spring.format.formatter.intellij.codestyle.monitor.Trigger.State;
+import io.spring.format.formatter.intellij.state.State;
/**
* {@link Monitor} that looks for a {@code spring-javaformat-maven-plugin} declaration in
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/Monitor.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/Monitor.java
similarity index 93%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/Monitor.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/Monitor.java
index 81710cd5..d0663c86 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/Monitor.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/Monitor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-present 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij.codestyle.monitor;
+package io.spring.format.formatter.intellij.monitor;
import com.intellij.openapi.project.Project;
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/Monitors.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/Monitors.java
similarity index 94%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/Monitors.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/Monitors.java
index 33d1b7e1..cfe8dc4a 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/Monitors.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/Monitors.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-present 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij.codestyle.monitor;
+package io.spring.format.formatter.intellij.monitor;
import java.util.ArrayList;
import java.util.Arrays;
@@ -24,7 +24,7 @@
import com.intellij.openapi.project.Project;
-import io.spring.format.formatter.intellij.codestyle.monitor.Trigger.State;
+import io.spring.format.formatter.intellij.state.State;
/**
* Utility class used to manage a collection of {@link Monitors}. Creates and manages
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/Trigger.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/Trigger.java
similarity index 73%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/Trigger.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/Trigger.java
index 10bbc5ba..f1c7d223 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/Trigger.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/Trigger.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-present 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.
@@ -14,7 +14,9 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij.codestyle.monitor;
+package io.spring.format.formatter.intellij.monitor;
+
+import io.spring.format.formatter.intellij.state.State;
/**
* Trigger used to to update the state for this monitor. Triggers are thread safe and can
@@ -30,21 +32,4 @@ public interface Trigger {
*/
void updateState(State state);
- /**
- * The desired state of the plugin for this monitor.
- */
- enum State {
-
- /**
- * The plugin should be active.
- */
- ACTIVE,
-
- /**
- * The plugin need not be active.
- */
- NOT_ACTIVE
-
- }
-
}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/startup/ManagedSpringJavaFormatProject.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/startup/ManagedSpringJavaFormatProject.java
new file mode 100644
index 00000000..2b87dd56
--- /dev/null
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/startup/ManagedSpringJavaFormatProject.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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 io.spring.format.formatter.intellij.startup;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
+
+import io.spring.format.formatter.intellij.monitor.FileMonitor;
+import io.spring.format.formatter.intellij.monitor.GradleMonitor;
+import io.spring.format.formatter.intellij.monitor.MavenMonitor;
+import io.spring.format.formatter.intellij.monitor.Monitors;
+import io.spring.format.formatter.intellij.state.State;
+import io.spring.format.formatter.intellij.ui.StatusIndicator;
+
+/**
+ * Spring Java Format IntelliJ support added to a {@link Project}.
+ *
+ * @author Phillip Webb
+ */
+class ManagedSpringJavaFormatProject {
+
+ private static final String ACTIVE_PROPERTY = ManagedSpringJavaFormatProject.class.getName() + ".ACTIVE";
+
+ private static final Logger logger = Logger.getInstance(ManagedSpringJavaFormatProject.class);
+
+ private final Project project;
+
+ private final StatusIndicator statusIndicator;
+
+ private final Lock lock = new ReentrantLock();
+
+ private Monitors monitors;
+
+ private PropertiesComponent properties;
+
+ protected ManagedSpringJavaFormatProject(Project project) {
+ logger.info("Initializing Spring Format for project " + project.getName());
+ this.project = project;
+ this.statusIndicator = new StatusIndicator(project);
+ this.properties = PropertiesComponent.getInstance(project);
+ if (this.properties.getBoolean(ACTIVE_PROPERTY, false)) {
+ update(State.ACTIVE);
+ }
+ this.monitors = new Monitors(this.project, this::update, FileMonitor.factory(), MavenMonitor.factory(),
+ GradleMonitor.factory());
+ Disposer.register(project, this::dispose);
+ }
+
+ private void dispose() {
+ if (this.monitors != null) {
+ logger.info("Stopping monitors for " + this.project.getName());
+ this.monitors.stop();
+ this.monitors = null;
+ }
+ }
+
+ private void update(State state) {
+ logger.info("Updating state of " + this.project.getName() + " to " + state);
+ this.lock.lock();
+ try {
+ state.put(this.project);
+ ApplicationManager.getApplication().invokeLater(() -> this.statusIndicator.update(state));
+ }
+ finally {
+ this.lock.unlock();
+ }
+ }
+
+}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/SpringFormatStartupActivity.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/startup/SpringJavaFormatStartupActivity.java
similarity index 71%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/SpringFormatStartupActivity.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/startup/SpringJavaFormatStartupActivity.java
index 8005c961..f11e345c 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/SpringFormatStartupActivity.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/startup/SpringJavaFormatStartupActivity.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-present 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.
@@ -14,21 +14,21 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij;
+package io.spring.format.formatter.intellij.startup;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupActivity;
/**
- * {@link StartupActivity} hook for {@link SpringFormat}.
+ * {@link StartupActivity} hook for {@link ManagedSpringJavaFormatProject}.
*
* @author Phillip Webb
*/
-public class SpringFormatStartupActivity implements StartupActivity {
+public class SpringJavaFormatStartupActivity implements StartupActivity {
@Override
public void runActivity(Project project) {
- new SpringFormat(project);
+ new ManagedSpringJavaFormatProject(project);
}
}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/state/State.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/state/State.java
new file mode 100644
index 00000000..6d8fe7c1
--- /dev/null
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/state/State.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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 io.spring.format.formatter.intellij.state;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
+
+/**
+ * The state of the plugin.
+ *
+ * @author Phillip Webb
+ */
+public enum State {
+
+ /**
+ * The plugin is active.
+ */
+ ACTIVE,
+
+ /**
+ * The plugin is not active.
+ */
+ NOT_ACTIVE;
+
+ private static final Key KEY = Key.create(State.class.getName());
+
+ /**
+ * Put this state to the given project.
+ * @param project the project that should save the state
+ */
+ public void put(Project project) {
+ project.putUserData(KEY, this);
+ }
+
+ /**
+ * Return the state from the given project.
+ * @param project the project to check
+ * @return the state of the project
+ */
+ public static State get(Project project) {
+ State state = (project != null) ? project.getUserData(KEY) : null;
+ return (state != null) ? state : NOT_ACTIVE;
+ }
+
+}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/StatusIndicator.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/ui/StatusIndicator.java
similarity index 89%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/StatusIndicator.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/ui/StatusIndicator.java
index e7a2ee89..935b738e 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/StatusIndicator.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/ui/StatusIndicator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2020 the original author or authors.
+ * Copyright 2012-present 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij;
+package io.spring.format.formatter.intellij.ui;
import java.awt.event.MouseEvent;
import java.util.concurrent.TimeUnit;
@@ -30,26 +30,26 @@
import com.intellij.util.Consumer;
import com.intellij.util.concurrency.AppExecutorUtil;
-import io.spring.format.formatter.intellij.codestyle.monitor.Trigger.State;
+import io.spring.format.formatter.intellij.state.State;
/**
* Indicator used to show when Spring Formatting is active.
*
* @author Phillip Webb
*/
-class StatusIndicator {
+public class StatusIndicator {
private final Project project;
private Widget widget;
- StatusIndicator(Project project) {
+ public StatusIndicator(Project project) {
this.project = project;
}
public void update(State state) {
WindowManager windowManager = WindowManager.getInstance();
- final StatusBar statusBar = windowManager.getStatusBar(this.project);
+ StatusBar statusBar = windowManager.getStatusBar(this.project);
if (statusBar == null) {
AppExecutorUtil.getAppScheduledExecutorService().schedule(() -> retryUpdate(state), 1, TimeUnit.SECONDS);
return;
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/resources/META-INF/plugin.xml b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/resources/META-INF/plugin.xml
index ccbca400..21c74b0f 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/resources/META-INF/plugin.xml
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/resources/META-INF/plugin.xml
@@ -9,6 +9,7 @@
org.jetbrains.idea.mavenorg.jetbrains.plugins.gradle
-
+
+
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/DelegatingCodeStyleManagerTests.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/DelegatingCodeStyleManagerTests.java
deleted file mode 100644
index b8ab5809..00000000
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/DelegatingCodeStyleManagerTests.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright 2017-2021 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
- *
- * https://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 io.spring.format.formatter.intellij.codestyle;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import com.intellij.lang.ASTNode;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.codeStyle.ChangedRangesInfo;
-import com.intellij.psi.codeStyle.CodeStyleManager;
-import com.intellij.util.ThrowableRunnable;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-/**
- * Tests for {@link DelegatingCodeStyleManager}.
- *
- * @author Phillip Webb
- */
-public class DelegatingCodeStyleManagerTests {
-
- @Mock
- private CodeStyleManager delegate;
-
- private DelegatingCodeStyleManager delegating;
-
- @Mock
- private PsiElement element;
-
- @Mock
- private PsiFile file;
-
- @Mock
- private TextRange range;
-
- private Collection ranges;
-
- @Mock
- private Document document;
-
- @Mock
- private FileType fileType;
-
- @Mock
- private ASTNode block;
-
- @Mock
- private ASTNode node;
-
- @Mock
- private ChangedRangesInfo changedRangesInfo;
-
- @BeforeEach
- public void setup() {
- MockitoAnnotations.initMocks(this);
- this.delegating = new DelegatingCodeStyleManager(this.delegate);
- this.ranges = Collections.singleton(mock(TextRange.class));
- }
-
- @Test
- public void getDelegateShouldGetDelegate() throws Exception {
- assertThat(this.delegating.getDelegate()).isEqualTo(this.delegate);
- }
-
- @Test
- public void getProjectShouldCallDelegate() throws Exception {
- this.delegating.getProject();
- verify(this.delegate).getProject();
- }
-
- @Test
- public void reformatShouldCallDelegate() throws Exception {
- this.delegating.reformat(this.element);
- verify(this.delegate).reformat(this.element);
- }
-
- @Test
- public void reformatWithCanChangeWhiteSpacesOnlyShouldCallDelegate() throws Exception {
- this.delegating.reformat(this.element, true);
- verify(this.delegate).reformat(this.element, true);
- }
-
- @Test
- public void reformatRangeShouldCallDelegate() throws Exception {
- this.delegating.reformatRange(this.element, 12, 34);
- verify(this.delegate).reformatRange(this.element, 12, 34);
- }
-
- @Test
- public void reformatRangeWithCanChangeWhiteSpacesOnlyShouldCallDelegate() throws Exception {
- this.delegating.reformatRange(this.element, 12, 34, true);
- verify(this.delegate).reformatRange(this.element, 12, 34, true);
- }
-
- @Test
- public void reformatTextShouldCallDelegate() throws Exception {
- this.delegating.reformatText(this.file, 12, 34);
- verify(this.delegate).reformatText(this.file, 12, 34);
- }
-
- @Test
- public void reformatTextWithRangeCollectionShouldCallDelegate() throws Exception {
- this.delegating.reformatText(this.file, this.ranges);
- verify(this.delegate).reformatText(this.file, this.ranges);
- }
-
- @Test
- public void reformatTextWithContextShouldCallDelegate() throws Exception {
- this.delegating.reformatTextWithContext(this.file, this.ranges);
- ArgumentCaptor changedRanges = ArgumentCaptor.forClass(ChangedRangesInfo.class);
- verify(this.delegate).reformatTextWithContext(eq(this.file), changedRanges.capture());
- assertThat(changedRanges.getValue().allChangedRanges).containsExactlyElementsOf(this.ranges);
- }
-
- @Test
- public void reformatTextWithContextInfoShouldCallDelegate() throws Exception {
- this.delegating.reformatTextWithContext(this.file, this.changedRangesInfo);
- verify(this.delegate).reformatTextWithContext(this.file, this.changedRangesInfo);
- }
-
- @Test
- public void adjustLineIndentForFileWithRangeShouldCallDelegate() throws Exception {
- this.delegating.adjustLineIndent(this.file, this.range);
- verify(this.delegate).adjustLineIndent(this.file, this.range);
- }
-
- @Test
- public void adjustLineIndentForFileShouldCallDelegate() throws Exception {
- this.delegating.adjustLineIndent(this.file, 123);
- verify(this.delegate).adjustLineIndent(this.file, 123);
- }
-
- @Test
- public void adjustLineIndentForDocumentShouldCallDelegate() throws Exception {
- this.delegating.adjustLineIndent(this.document, 123);
- verify(this.delegate).adjustLineIndent(this.document, 123);
- }
-
- @Test
- @Deprecated
- public void isLineToBeIndentedShouldCallDelegate() throws Exception {
- this.delegating.isLineToBeIndented(this.file, 123);
- verify(this.delegate).isLineToBeIndented(this.file, 123);
- }
-
- @Test
- public void getLineIndentForFileShouldCallDelegate() throws Exception {
- this.delegating.getLineIndent(this.file, 123);
- verify(this.delegate).getLineIndent(this.file, 123);
- }
-
- @Test
- public void getLineIndentForDocumentShouldCallDelegate() throws Exception {
- this.delegating.getLineIndent(this.document, 123);
- verify(this.delegate).getLineIndent(this.document, 123);
- }
-
- @Test
- @Deprecated
- public void getIndentShouldCallDelegate() throws Exception {
- this.delegating.getIndent("hello", this.fileType);
- verify(this.delegate).getIndent("hello", this.fileType);
- }
-
- @Test
- @Deprecated
- public void fillIndentShouldCallDelegate() throws Exception {
- com.intellij.psi.codeStyle.Indent indent = mock(com.intellij.psi.codeStyle.Indent.class);
- this.delegating.fillIndent(indent, this.fileType);
- verify(this.delegate).fillIndent(indent, this.fileType);
- }
-
- @Test
- @Deprecated
- public void zeroIndentShouldCallDelegate() throws Exception {
- this.delegating.zeroIndent();
- verify(this.delegate).zeroIndent();
- }
-
- @Test
- public void reformatNewlyAddedElementShouldCallDelegate() throws Exception {
- this.delegating.reformatNewlyAddedElement(this.block, this.node);
- verify(this.delegate).reformatNewlyAddedElement(this.block, this.node);
- }
-
- @Test
- public void isSequentialProcessingAllowedShouldCallDelegate() throws Exception {
- this.delegating.isSequentialProcessingAllowed();
- verify(this.delegate).isSequentialProcessingAllowed();
- }
-
- @Test
- public void performActionWithFormatterDisabledWithRunnableShouldCallDelegate() throws Exception {
- Runnable runnable = mock(Runnable.class);
- this.delegating.performActionWithFormatterDisabled(runnable);
- verify(this.delegate).performActionWithFormatterDisabled(runnable);
- }
-
- @Test
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public void performActionWithFormatterDisabledWithThrowableRunnableShouldCallDelegate() throws Throwable {
- ThrowableRunnable runnable = mock(ThrowableRunnable.class);
- this.delegating.performActionWithFormatterDisabled(runnable);
- verify(this.delegate).performActionWithFormatterDisabled(runnable);
- }
-
- @Test
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public void performActionWithFormatterDisabledWithComputableShouldCallDelegate() throws Exception {
- Computable computable = mock(Computable.class);
- this.delegating.performActionWithFormatterDisabled(computable);
- verify(this.delegate).performActionWithFormatterDisabled(computable);
- }
-
-}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/SpringCodeStyleManagerTests.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/SpringCodeStyleManagerTests.java
deleted file mode 100644
index cfe25a39..00000000
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/SpringCodeStyleManagerTests.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright 2017-2021 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
- *
- * https://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 io.spring.format.formatter.intellij.codestyle;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-import com.intellij.openapi.util.TextRange;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.codeStyle.ChangedRangesInfo;
-import com.intellij.psi.codeStyle.CodeStyleManager;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-
-/**
- * Tests for {@link SpringCodeStyleManager}.
- *
- * @author Phillip Webb
- */
-public class SpringCodeStyleManagerTests {
-
- @Mock
- private CodeStyleManager delegate;
-
- @Mock
- private SpringReformatter springReformatter;
-
- private SpringCodeStyleManager styleManager;
-
- @Mock
- private PsiFile file;
-
- @BeforeEach
- public void setup() {
- MockitoAnnotations.initMocks(this);
- this.styleManager = new SpringCodeStyleManager(this.delegate, this.springReformatter);
- }
-
- @Test
- public void reformatTextWithOffsetWhenCantFormatShouldCallDelegate() {
- given(this.springReformatter.canReformat(any())).willReturn(false);
- this.styleManager.reformatText(this.file, 10, 20);
- verify(this.delegate).reformatText(this.file, 10, 20);
- }
-
- @Test
- public void reformatTextWithOffsetWhenCanFormatShouldCallFormatter() {
- given(this.springReformatter.canReformat(any())).willReturn(true);
- Set ranges = new HashSet<>(Arrays.asList(new TextRange(10, 20)));
- this.styleManager.reformatText(this.file, 10, 20);
- verify(this.springReformatter).reformat(this.file, ranges);
- verifyZeroInteractions(this.delegate);
- }
-
- @Test
- public void reformatTextWithRangeWhenCantFormatShouldCallDelegate() {
- given(this.springReformatter.canReformat(any())).willReturn(false);
- Collection ranges = Arrays.asList(new TextRange(10, 20));
- this.styleManager.reformatText(this.file, ranges);
- verify(this.delegate).reformatText(this.file, ranges);
- }
-
- @Test
- public void reformatTextWithRangeWhenCanFormatShouldCallFormatter() {
- given(this.springReformatter.canReformat(any())).willReturn(true);
- Collection ranges = Arrays.asList(new TextRange(10, 20));
- this.styleManager.reformatText(this.file, ranges);
- verify(this.springReformatter).reformat(this.file, ranges);
- verifyZeroInteractions(this.delegate);
- }
-
- @Test
- public void reformatTextWithContextWhenCantFormatShouldCallDelegate() {
- given(this.springReformatter.canReformat(any())).willReturn(false);
- Collection ranges = Arrays.asList(new TextRange(10, 20));
- this.styleManager.reformatTextWithContext(this.file, ranges);
- ArgumentCaptor changedRanges = ArgumentCaptor.forClass(ChangedRangesInfo.class);
- verify(this.delegate).reformatTextWithContext(eq(this.file), changedRanges.capture());
- assertThat(changedRanges.getValue().allChangedRanges).containsExactlyElementsOf(ranges);
- }
-
- @Test
- public void reformatTextWithContextWhenCanFormatShouldCallFormatter() {
- given(this.springReformatter.canReformat(any())).willReturn(true);
- Collection ranges = Arrays.asList(new TextRange(10, 20));
- this.styleManager.reformatTextWithContext(this.file, ranges);
- verify(this.springReformatter).reformat(this.file, ranges);
- verifyZeroInteractions(this.delegate);
- }
-
-}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/SpringReformatterTests.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/SpringReformatterTests.java
deleted file mode 100644
index a37ddce7..00000000
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/SpringReformatterTests.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright 2017-2021 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
- *
- * https://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 io.spring.format.formatter.intellij.codestyle;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.function.Supplier;
-
-import com.intellij.openapi.application.Application;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiDocumentManager;
-import com.intellij.psi.PsiFile;
-import com.intellij.util.IncorrectOperationException;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-/**
- * Tests for {@link SpringReformatter}.
- *
- * @author Phillip Webb
- */
-public class SpringReformatterTests {
-
- @Mock
- private Project project;
-
- @Mock
- private Application application;
-
- @Mock
- private PsiDocumentManager documentManager;
-
- private SpringReformatter reformatter;
-
- @Mock
- private PsiFile file;
-
- @Mock
- VirtualFile virtualFile;
-
- private Collection ranges = Arrays.asList(new TextRange(10, 20));
-
- @BeforeEach
- public void setup() {
- MockitoAnnotations.initMocks(this);
- given(this.file.getVirtualFile()).willReturn(this.virtualFile);
- this.reformatter = new TestSpringReformatter(() -> this.project, () -> this.application,
- () -> this.documentManager);
- }
-
- @Test
- public void reformatShouldAssertWriteAccess() throws Exception {
- given(this.file.isWritable()).willReturn(true);
- this.reformatter.reformat(this.file, this.ranges);
- verify(this.application).assertWriteAccessAllowed();
- }
-
- @Test
- public void reformatShouldCommitAllDocuments() throws Exception {
- given(this.file.isWritable()).willReturn(true);
- this.reformatter.reformat(this.file, this.ranges);
- verify(this.documentManager).commitAllDocuments();
- }
-
- @Test
- public void reformatWhenFileIsNotWriteableShouldThrow() throws Exception {
- assertThatExceptionOfType(IncorrectOperationException.class)
- .isThrownBy(() -> this.reformatter.reformat(this.file, this.ranges));
- }
-
- @Test
- public void reformatShouldReformatDocument() throws Exception {
- given(this.file.isWritable()).willReturn(true);
- Document document = mock(Document.class);
- String text = "public class Hello {}";
- given(document.getText()).willReturn(text);
- given(this.documentManager.getDocument(this.file)).willReturn(document);
- this.reformatter.reformat(this.file, Arrays.asList(new TextRange(0, text.length())));
- verify(document).replaceString(20, 20, "\n\n");
- verify(this.documentManager).commitDocument(document);
- }
-
- static class TestSpringReformatter extends SpringReformatter {
-
- TestSpringReformatter(Supplier project, Supplier application,
- Supplier documentManager) {
- super(project, application, documentManager);
- }
-
- @Override
- protected void runWriteCommandAction(Runnable runnable) {
- runnable.run();
- }
-
- }
-
-}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/EclipseDocumentAdapterTests.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/formatting/EclipseDocumentAdapterTests.java
similarity index 83%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/EclipseDocumentAdapterTests.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/formatting/EclipseDocumentAdapterTests.java
index 4d9b4b4d..4fe90665 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/EclipseDocumentAdapterTests.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/formatting/EclipseDocumentAdapterTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij.codestyle;
+package io.spring.format.formatter.intellij.formatting;
import com.intellij.openapi.editor.Document;
import org.junit.jupiter.api.Test;
@@ -29,10 +29,10 @@
*
* @author Phillip Webb
*/
-public class EclipseDocumentAdapterTests {
+class EclipseDocumentAdapterTests {
@Test
- public void createShouldUseDocumentText() throws Exception {
+ void createUsesDocumentText() throws Exception {
Document intellijDocument = mock(Document.class);
given(intellijDocument.getText()).willReturn("hello");
EclipseDocumentAdapter adapter = new EclipseDocumentAdapter(intellijDocument);
@@ -40,7 +40,7 @@ public void createShouldUseDocumentText() throws Exception {
}
@Test
- public void replaceShouldApplyToIntellijDocument() throws Exception {
+ void replaceAppliesToIntellijDocument() throws Exception {
Document intellijDocument = mock(Document.class);
given(intellijDocument.getText()).willReturn("hello");
EclipseDocumentAdapter adapter = new EclipseDocumentAdapter(intellijDocument);
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/EclipseRegionAdapterTests.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/formatting/EclipseRegionAdapterTests.java
similarity index 81%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/EclipseRegionAdapterTests.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/formatting/EclipseRegionAdapterTests.java
index b281ad5c..f4c2d2a4 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/EclipseRegionAdapterTests.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/formatting/EclipseRegionAdapterTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij.codestyle;
+package io.spring.format.formatter.intellij.formatting;
import java.util.Arrays;
import java.util.List;
@@ -33,25 +33,25 @@
public class EclipseRegionAdapterTests {
@Test
- public void getOffsetShouldReturnStartOffset() throws Exception {
+ void getOffsetReturnsStartOffset() throws Exception {
IRegion region = new EclipseRegionAdapter(new TextRange(10, 20));
assertThat(region.getOffset()).isEqualTo(10);
}
@Test
- public void getLengthShouldReturnLength() throws Exception {
+ void getLengthReturnsLength() throws Exception {
IRegion region = new EclipseRegionAdapter(new TextRange(10, 20));
assertThat(region.getLength()).isEqualTo(10);
}
@Test
- public void asArrayWhenCollectionIsNullShouldReturnEmptyArray() throws Exception {
+ void asArrayWhenCollectionIsNullReturnsEmptyArray() throws Exception {
IRegion[] regions = EclipseRegionAdapter.asArray(null);
assertThat(regions).isNotNull().isEmpty();
}
@Test
- public void asArrayShouldReturnArray() throws Exception {
+ void asArrayReturnsArray() throws Exception {
List ranges = Arrays.asList(new TextRange(10, 20), new TextRange(30, 35));
IRegion[] regions = EclipseRegionAdapter.asArray(ranges);
assertThat(regions).hasSize(2);
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/formatting/SpringJavaFormatFormattingServiceTests.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/formatting/SpringJavaFormatFormattingServiceTests.java
new file mode 100644
index 00000000..6524e10d
--- /dev/null
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/formatting/SpringJavaFormatFormattingServiceTests.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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 io.spring.format.formatter.intellij.formatting;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collections;
+
+import com.intellij.formatting.FormattingContext;
+import com.intellij.formatting.service.FormattingService.Feature;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.fileTypes.PlainTextFileType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.local.CoreLocalFileSystem;
+import com.intellij.openapi.vfs.local.CoreLocalVirtualFile;
+import com.intellij.psi.PsiFile;
+import com.intellij.testFramework.LightVirtualFile;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import io.spring.format.formatter.intellij.state.State;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.BDDMockito.willAnswer;
+import static org.mockito.Mockito.mock;
+
+/**
+ * Tests for {@link SpringJavaFormatFormattingService}.
+ *
+ * @author Phillip Webb
+ */
+class SpringJavaFormatFormattingServiceTests {
+
+ private SpringJavaFormatFormattingService service = new SpringJavaFormatFormattingService(
+ (project, runnable) -> runnable.run());
+
+ @Test
+ void getFeaturesReturnsFormatFragments() {
+ assertThat(this.service.getFeatures()).containsExactly(Feature.FORMAT_FRAGMENTS);
+ }
+
+ @Test
+ void canFormatWhenNotJavaReturnsFalse() {
+ FileType fileType = PlainTextFileType.INSTANCE;
+ PsiFile file = mockFile(fileType, State.ACTIVE);
+ assertThat(this.service.canFormat(file)).isFalse();
+ }
+
+ @Test
+ void canFormatWhenJavaFileAndNotActiveReturnsFalse() {
+ FileType fileType = FileTypeManager.getInstance().getStdFileType("JAVA");
+ PsiFile file = mockFile(fileType, State.NOT_ACTIVE);
+ assertThat(this.service.canFormat(file)).isFalse();
+ }
+
+ @Test
+ void canFormatWhenJavaFileAndActiveReturnsTrue() {
+ FileType fileType = FileTypeManager.getInstance().getStdFileType("JAVA");
+ PsiFile file = mockFile(fileType, State.ACTIVE);
+ assertThat(this.service.canFormat(file)).isTrue();
+ }
+
+ @Test
+ void formatDocumentAppliesFormatting(@TempDir Path projectDir) throws Exception {
+ Files.writeString(projectDir.resolve(".springjavaformatconfig"), "indentation-style=spaces");
+ Document document = mockDocument("public class Hello{"
+ + "\tpublic void hello() {"
+ + "\tString value =\t\"Hello World\";}}");
+ FormattingContext formattingContext = mock(FormattingContext.class);
+ VirtualFile virtualFile = new CoreLocalVirtualFile(new CoreLocalFileSystem(), projectDir.resolve("Hello.java"));
+ given(formattingContext.getVirtualFile()).willReturn(virtualFile);
+ this.service.formatDocument(document, Collections.emptyList(), formattingContext, false, false);
+ assertThat(document.getText()).isEqualTo("public class Hello {\n\n"
+ + " public void hello() {\n"
+ + " String value = \"Hello World\";\n"
+ + " }\n\n"
+ + "}");
+ }
+
+ @Test
+ void formatDocumentAppliesFormatting() {
+ Document document = mockDocument("public class Hello{"
+ + "\tpublic void hello() {"
+ + "\tString value =\t\"Hello World\";}}");
+ FormattingContext formattingContext = mock(FormattingContext.class);
+ VirtualFile virtualFile = new LightVirtualFile("Hello.java", document.getText());
+ given(formattingContext.getVirtualFile()).willReturn(virtualFile);
+ this.service.formatDocument(document, Collections.emptyList(), formattingContext, false, false);
+ assertThat(document.getText()).isEqualTo("public class Hello {\n\n"
+ + "\tpublic void hello() {\n"
+ + "\t\tString value = \"Hello World\";\n"
+ + "\t}\n\n"
+ + "}");
+ }
+
+
+ private Document mockDocument(String text) {
+ Document document = mock(Document.class);
+ StringBuilder documentText = new StringBuilder(text);
+ willAnswer((invocation) -> {
+ documentText.replace(invocation.getArgument(0), invocation.getArgument(1), invocation.getArgument(2));
+ return null;
+ }).given(document).replaceString(any(Integer.class), any(Integer.class), any(CharSequence.class));
+ given(document.getText()).willAnswer((invocation) -> documentText.toString());
+ return document;
+ }
+
+ private PsiFile mockFile(FileType fileType, State state) {
+ PsiFile file = mock(PsiFile.class);
+ given(file.getFileType()).willReturn(fileType);
+ Project project = mock(Project.class);
+ given(project.getUserData(any())).willReturn(state);
+ given(file.getProject()).willReturn(project);
+ return file;
+ }
+
+}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-runtime/pom.xml b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-runtime/pom.xml
index 5f64a236..b6202b0d 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-runtime/pom.xml
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-runtime/pom.xml
@@ -6,16 +6,17 @@
io.spring.javaformatspring-javaformat-intellij-idea
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTspring-javaformat-intellij-idea-runtimepomSpring JavaFormat IntelliJ IDEA Runtime${basedir}/../..
- https://download.jetbrains.com/idea/ideaIC-2021.2.tar.gz
- https://github.com/JetBrains/intellij-community/archive/idea/212.4746.92.zip
- idea-IC-212.4746.92
+ https://download.jetbrains.com/idea/ideaIC-2022.3.2.tar.gz
+ https://github.com/JetBrains/intellij-community/archive/idea/223.8617.56.zip
+ ${project.build.directory}/intellij-source
+ idea-IC-223.8617.56
@@ -66,64 +67,71 @@
-
+
+ dest="${project.build.directory}/intellij">
+
+ src="${intellij.source.directory}.zip"
+ dest="${intellij.source.directory}">
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -134,150 +142,136 @@
maven-install-plugin
- install-intellij-annotations
- install
- false
-
- install-file
-
-
- ${project.build.directory}/intellij/annotations.jar
- io.spring.javaformat.intellij.idea
- annotations
- ${project.version}
- jar
- true
-
-
-
- install-intellij-platform-api
+ install-intellij-utilinstallfalseinstall-file
- ${project.build.directory}/intellij/platform-api.jar
- ${project.build.directory}/intellij-source/platform-api-sources.zip
+ ${project.build.directory}/intellij/util.jar
+ ${intellij.source.directory}/util-sources.zipio.spring.javaformat.intellij.idea
- platform-api
+ util${project.version}jartrue
- install-intellij-platform-impl
+ install-intellij-util_rtinstallfalseinstall-file
- ${project.build.directory}/intellij/platform-impl.jar
- ${project.build.directory}/intellij-source/platform-impl-sources.zip
+ ${project.build.directory}/intellij/util_rt.jar
+ ${intellij.source.directory}/util_rt-sources.zipio.spring.javaformat.intellij.idea
- platform-impl
+ util_rt${project.version}jartrue
- install-intellij-util
+ install-intellij-appinstallfalseinstall-file
- ${project.build.directory}/intellij/util.jar
- ${project.build.directory}/intellij-source/util-sources.zip
+ ${project.build.directory}/intellij/app.jar
+ ${intellij.source.directory}/app-sources.zipio.spring.javaformat.intellij.idea
- util
+ app${project.version}jartrue
- install-intellij-idea
+ install-intellij-maveninstallfalseinstall-file
- ${project.build.directory}/intellij/idea.jar
+ ${project.build.directory}/intellij/maven.jar
+ ${intellij.source.directory}/maven-sources.zipio.spring.javaformat.intellij.idea
- idea
+ maven${project.version}jartrue
- install-intellij-maven
+ install-intellij-maven-serverinstallfalseinstall-file
- ${project.build.directory}/intellij/maven.jar
- ${project.build.directory}/intellij-source/maven-sources.zip
+ ${project.build.directory}/intellij/maven-server.jar
+ ${intellij.source.directory}/maven-server-sources.zipio.spring.javaformat.intellij.idea
- maven
+ maven-server${project.version}jartrue
- install-intellij-maven-server-api
+ install-intellij-gradleinstallfalseinstall-file
- ${project.build.directory}/intellij/maven-server-api.jar
+ ${project.build.directory}/intellij/gradle.jar
+ ${intellij.source.directory}/gradle-sources.zipio.spring.javaformat.intellij.idea
- maven-server-api
+ gradle${project.version}jartrue
- install-intellij-gradle
+ install-intellij-gradle-tooling-extension-apiinstallfalseinstall-file
- ${project.build.directory}/intellij/gradle.jar
- ${project.build.directory}/intellij-source/gradle-sources.zip
+ ${project.build.directory}/intellij/gradle-tooling-extension-api.jar
+ ${intellij.source.directory}/gradle-tooling-extension-api-sources.zipio.spring.javaformat.intellij.idea
- gradle
+ gradle-tooling-extension-api${project.version}jartrue
- install-intellij-gradle-tooling-extension-api
+ install-intellij-jps-modelinstallfalseinstall-file
- ${project.build.directory}/intellij/gradle-tooling-extension-api.jar
- ${project.build.directory}/intellij-source/gradle-tooling-extension-api-sources.zip
+ ${project.build.directory}/intellij/jps-model.jar
+ ${intellij.source.directory}/jps-model-sources.zipio.spring.javaformat.intellij.idea
- gradle-tooling-extension-api
+ jps-model${project.version}jartrue
@@ -292,7 +286,7 @@
${project.build.directory}/intellij/gradle-tooling-extension-impl.jar
- ${project.build.directory}/intellij-source/gradle-tooling-extension-impl-sources.zip
+ ${intellij.source.directory}/gradle-tooling-extension-impl-sources.zipio.spring.javaformat.intellij.ideagradle-tooling-extension-impl${project.version}
diff --git a/spring-javaformat-maven/pom.xml b/spring-javaformat-maven/pom.xml
index 405bc19d..61cb5d27 100644
--- a/spring-javaformat-maven/pom.xml
+++ b/spring-javaformat-maven/pom.xml
@@ -6,7 +6,7 @@
io.spring.javaformatspring-javaformat-build
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTspring-javaformat-mavenpom
diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/pom.xml b/spring-javaformat-maven/spring-javaformat-maven-plugin/pom.xml
index 8108c9fd..af8474d3 100644
--- a/spring-javaformat-maven/spring-javaformat-maven-plugin/pom.xml
+++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/pom.xml
@@ -5,7 +5,7 @@
io.spring.javaformatspring-javaformat-maven
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTspring-javaformat-maven-pluginmaven-plugin
@@ -15,6 +15,16 @@
+
+ maven-clean-plugin
+
+
+
+ out
+
+
+
+ org.apache.maven.pluginsmaven-invoker-plugin
@@ -91,15 +101,21 @@
+
+ org.codehaus.plexus
+ plexus-utils
+
+
org.apache.mavenmaven-core
+ providedorg.apache.mavenmaven-plugin-api
+ provided
-
org.apache.maven.plugin-toolsmaven-plugin-annotations
diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-skip/pom.xml b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-skip/pom.xml
new file mode 100644
index 00000000..213305b9
--- /dev/null
+++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-skip/pom.xml
@@ -0,0 +1,32 @@
+
+
+ 4.0.0
+ io.spring.javaformat
+ apply-skip
+ 0.0.1.BUILD-SNAPSHOT
+
+ UTF-8
+ 1.8
+ 1.8
+
+
+
+
+ @project.groupId@
+ @project.artifactId@
+ @project.version@
+
+
+
+ apply
+
+
+ true
+
+
+
+
+
+
+
diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-skip/src/main/java/simple/Simple.java b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-skip/src/main/java/simple/Simple.java
new file mode 100644
index 00000000..10016e5d
--- /dev/null
+++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-skip/src/main/java/simple/Simple.java
@@ -0,0 +1,14 @@
+package simple;
+
+/**
+ * Simple.
+ * @author Phillip Webb
+ * @since 1.0.0
+ */
+public class Simple {
+
+ public static void main(String[] args) throws Exception {
+ // Main method
+ }
+
+}
diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-skip/verify.groovy b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-skip/verify.groovy
new file mode 100644
index 00000000..5ffd403d
--- /dev/null
+++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-skip/verify.groovy
@@ -0,0 +1 @@
+new io.spring.format.maven.VerifyApply().verifyNoApply(basedir)
diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-skip-global-property/pom.xml b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-skip-global-property/pom.xml
new file mode 100644
index 00000000..d05c8e80
--- /dev/null
+++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-skip-global-property/pom.xml
@@ -0,0 +1,30 @@
+
+
+ 4.0.0
+ io.spring.javaformat
+ validate-skip-global-property
+ 0.0.1.BUILD-SNAPSHOT
+
+ UTF-8
+ 1.8
+ 1.8
+ true
+
+
+
+
+ @project.groupId@
+ @project.artifactId@
+ @project.version@
+
+
+
+ validate
+
+
+
+
+
+
+
diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-skip-global-property/src/main/java/simple/Simple.java b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-skip-global-property/src/main/java/simple/Simple.java
new file mode 100644
index 00000000..14f14516
--- /dev/null
+++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-skip-global-property/src/main/java/simple/Simple.java
@@ -0,0 +1,15 @@
+package simple;
+
+/**
+ * Simple.
+ *
+ * @author Phillip Webb
+ * @since 1.0.0
+ */
+public class Simple {
+
+ public static void main(String[] args) throws Exception {
+ // Main method
+ }
+
+}
diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-skip-property/pom.xml b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-skip-property/pom.xml
new file mode 100644
index 00000000..e0319c25
--- /dev/null
+++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-skip-property/pom.xml
@@ -0,0 +1,30 @@
+
+
+ 4.0.0
+ io.spring.javaformat
+ validate-skip-property
+ 0.0.1.BUILD-SNAPSHOT
+
+ UTF-8
+ 1.8
+ 1.8
+ true
+
+
+
+
+ @project.groupId@
+ @project.artifactId@
+ @project.version@
+
+
+
+ validate
+
+
+
+
+
+
+
diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-skip-property/src/main/java/simple/Simple.java b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-skip-property/src/main/java/simple/Simple.java
new file mode 100644
index 00000000..14f14516
--- /dev/null
+++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-skip-property/src/main/java/simple/Simple.java
@@ -0,0 +1,15 @@
+package simple;
+
+/**
+ * Simple.
+ *
+ * @author Phillip Webb
+ * @since 1.0.0
+ */
+public class Simple {
+
+ public static void main(String[] args) throws Exception {
+ // Main method
+ }
+
+}
diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/main/java/io/spring/format/maven/ApplyMojo.java b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/main/java/io/spring/format/maven/ApplyMojo.java
index a519102b..3d8bdc6d 100644
--- a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/main/java/io/spring/format/maven/ApplyMojo.java
+++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/main/java/io/spring/format/maven/ApplyMojo.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -24,6 +24,7 @@
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
import io.spring.javaformat.formatter.FileEdit;
import io.spring.javaformat.formatter.FileFormatterException;
@@ -36,9 +37,19 @@
@Mojo(name = "apply", defaultPhase = LifecyclePhase.PROCESS_SOURCES, threadSafe = true)
public class ApplyMojo extends FormatMojo {
+ /**
+ * Skip the execution.
+ */
+ @Parameter(property = "spring-javaformat.apply.skip", defaultValue = "false")
+ private boolean skip;
+
@Override
protected void execute(List files, Charset encoding, String lineSeparator)
throws MojoExecutionException, MojoFailureException {
+ if (this.skip || skipGlobally()) {
+ getLog().info("skipping format apply as per configuration.");
+ return;
+ }
try {
getFormatter().formatFiles(files, encoding, lineSeparator).filter(FileEdit::hasEdits).forEach(this::save);
}
diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/main/java/io/spring/format/maven/FormatMojo.java b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/main/java/io/spring/format/maven/FormatMojo.java
index 5e7e85c8..6270b549 100644
--- a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/main/java/io/spring/format/maven/FormatMojo.java
+++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/main/java/io/spring/format/maven/FormatMojo.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -26,9 +26,11 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Properties;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
@@ -68,6 +70,12 @@ public abstract class FormatMojo extends AbstractMojo {
@Parameter(defaultValue = "${project}", readonly = true, required = true)
protected MavenProject project;
+ /**
+ * The Maven Session Object.
+ */
+ @Parameter(defaultValue = "${session}", readonly = true, required = true)
+ protected MavenSession session;
+
/**
* Specifies the location of the source directories to use.
*/
@@ -130,8 +138,9 @@ public final void execute() throws MojoExecutionException, MojoFailureException
}
private Stream resolve(List directories) {
- return directories.stream().map(directory -> FileUtils.resolveFile(this.project.getBasedir(), directory))
- .filter(this::include);
+ return directories.stream()
+ .map(directory -> FileUtils.resolveFile(this.project.getBasedir(), directory))
+ .filter(this::include);
}
private boolean include(File file) {
@@ -168,8 +177,10 @@ private List scan(File directory) {
scanner.setCaseSensitive(false);
scanner.setFollowSymlinks(false);
scanner.scan();
- return Arrays.asList(scanner.getIncludedFiles()).stream().map(name -> new File(directory, name))
- .collect(Collectors.toList());
+ return Arrays.asList(scanner.getIncludedFiles())
+ .stream()
+ .map(name -> new File(directory, name))
+ .collect(Collectors.toList());
}
private boolean hasLength(Object[] array) {
@@ -192,4 +203,16 @@ protected final FileFormatter getFormatter() {
return new FileFormatter(javaFormatConfig);
}
+ protected boolean skipGlobally() {
+ boolean result = false;
+ result = result || skipGlobally(this.session.getUserProperties());
+ result = result || skipGlobally(this.session.getSystemProperties());
+ result = result || skipGlobally(this.project.getProperties());
+ return result;
+ }
+
+ private boolean skipGlobally(Properties properties) {
+ return Boolean.valueOf(properties.getProperty("spring-javaformat.skip"));
+ }
+
}
diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/main/java/io/spring/format/maven/ValidateMojo.java b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/main/java/io/spring/format/maven/ValidateMojo.java
index 534fb7f7..c9a77b81 100644
--- a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/main/java/io/spring/format/maven/ValidateMojo.java
+++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/main/java/io/spring/format/maven/ValidateMojo.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -40,18 +40,20 @@ public class ValidateMojo extends FormatMojo {
/**
* Skip the execution.
*/
- @Parameter(property = "spring-javaformat.skip", defaultValue = "false")
+ @Parameter(property = "spring-javaformat.validate.skip", defaultValue = "false")
private boolean skip;
@Override
protected void execute(List files, Charset encoding, String lineSeparator)
throws MojoExecutionException, MojoFailureException {
- if (this.skip) {
- getLog().debug("skipping validation as per configuration.");
+ if (this.skip || skipGlobally()) {
+ getLog().info("skipping format validate as per configuration.");
return;
}
- List problems = getFormatter().formatFiles(files, encoding, lineSeparator).filter(FileEdit::hasEdits)
- .map(FileEdit::getFile).collect(Collectors.toList());
+ List problems = getFormatter().formatFiles(files, encoding, lineSeparator)
+ .filter(FileEdit::hasEdits)
+ .map(FileEdit::getFile)
+ .collect(Collectors.toList());
if (!problems.isEmpty()) {
StringBuilder message = new StringBuilder("Formatting violations found in the following files:\n");
problems.stream().forEach((f) -> message.append(" * " + f + "\n"));
diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/test/java/io/spring/format/maven/VerifyApply.java b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/test/java/io/spring/format/maven/VerifyApply.java
index 65fc2ec0..4338b633 100644
--- a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/test/java/io/spring/format/maven/VerifyApply.java
+++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/test/java/io/spring/format/maven/VerifyApply.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -30,16 +30,14 @@
*/
public class VerifyApply {
- private static final String LF = System.lineSeparator();
-
private static final String JAVA_FILE = "src/main/java/simple/Simple.java";
public void verify(File base) throws IOException {
- verify(base, LF);
+ verify(base, null);
}
public void verify(File base, boolean spaces) throws IOException {
- verify(base, LF, spaces);
+ verify(base, null, spaces);
}
public void verify(File base, String lineSeparator) throws IOException {
@@ -48,15 +46,20 @@ public void verify(File base, String lineSeparator) throws IOException {
public void verify(File base, String lineSeparator, boolean spaces) throws IOException {
String formated = new String(Files.readAllBytes(base.toPath().resolve(JAVA_FILE)), StandardCharsets.UTF_8);
+ if (lineSeparator == null) {
+ formated = formated.replace("\r\n", "\n").replace('\r', '\n');
+ lineSeparator = "\n";
+ }
String indent = (!spaces) ? " " : " ";
assertThat(formated).contains("Simple." + lineSeparator + " *" + lineSeparator + " * @author")
- .contains("public class Simple {").contains(indent + "public static void main");
+ .contains("public class Simple {")
+ .contains(indent + "public static void main");
}
- public static void main(String[] args) throws IOException {
- new VerifyApply().verify(new File(
- "/Users/pwebb/projects/spring-javaformat/code/spring-javaformat-maven/spring-javaformat-maven-plugin/target/it/apply-line-separator"),
- "\r");
+ public void verifyNoApply(File base) throws IOException {
+ String formated = new String(Files.readAllBytes(base.toPath().resolve(JAVA_FILE)), StandardCharsets.UTF_8);
+ formated = formated.replace("\r\n", "\n").replace('\r', '\n');
+ assertThat(formated).contains("Simple {");
}
}
diff --git a/spring-javaformat-vscode/README.md b/spring-javaformat-vscode/README.md
new file mode 100644
index 00000000..e6dea6c9
--- /dev/null
+++ b/spring-javaformat-vscode/README.md
@@ -0,0 +1,19 @@
+# spring-javaformat-vscode
+
+`spring-javaformat` extension for visual studio code.
+
+
+
+## Prerequisites
+
+* Install [node.js](https://nodejs.org/en/download/)
+* Install [yarn](https://yarnpkg.com/en/docs/install)
+* Install [vsce](https://code.visualstudio.com/api/working-with-extensions/publishing-extension#vsce)
+
+## Generate extension
+
+Just `mvn clean package`
+
+
+> `spring-javaformat-1.0.0.vsix` will be generated there
+
diff --git a/spring-javaformat-vscode/format.gif b/spring-javaformat-vscode/format.gif
new file mode 100644
index 00000000..fd1fdacd
Binary files /dev/null and b/spring-javaformat-vscode/format.gif differ
diff --git a/spring-javaformat-vscode/pom.xml b/spring-javaformat-vscode/pom.xml
new file mode 100644
index 00000000..f42bc4bb
--- /dev/null
+++ b/spring-javaformat-vscode/pom.xml
@@ -0,0 +1,20 @@
+
+
+ 4.0.0
+
+ io.spring.javaformat
+ spring-javaformat-build
+ 0.0.48-SNAPSHOT
+
+ spring-javaformat-vscode
+ pom
+ Spring JavaFormat Visual Studio Code
+
+ ${basedir}/..
+
+
+ spring-javaformat-vscode-extension
+
+
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/.gitignore b/spring-javaformat-vscode/spring-javaformat-vscode-extension/.gitignore
new file mode 100644
index 00000000..2c32c547
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/.gitignore
@@ -0,0 +1,7 @@
+out
+runtime
+dist
+node
+node_modules
+.vscode-test/
+*.vsix
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/.prettierignore b/spring-javaformat-vscode/spring-javaformat-vscode-extension/.prettierignore
new file mode 100644
index 00000000..717380fe
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/.prettierignore
@@ -0,0 +1,5 @@
+out
+target
+node
+.vscode
+.vscode-test
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/.prettierrc b/spring-javaformat-vscode/spring-javaformat-vscode-extension/.prettierrc
new file mode 100644
index 00000000..995d5360
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/.prettierrc
@@ -0,0 +1,6 @@
+{
+ "tabWidth": 2,
+ "semi": false,
+ "singleQuote": true,
+ "printWidth": 120
+}
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/.vscode/extensions.json b/spring-javaformat-vscode/spring-javaformat-vscode-extension/.vscode/extensions.json
new file mode 100644
index 00000000..c0a2258b
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/.vscode/extensions.json
@@ -0,0 +1,5 @@
+{
+ // See http://go.microsoft.com/fwlink/?LinkId=827846
+ // for the documentation about the extensions.json format
+ "recommendations": ["dbaeumer.vscode-eslint"]
+}
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/.vscode/launch.json b/spring-javaformat-vscode/spring-javaformat-vscode-extension/.vscode/launch.json
new file mode 100644
index 00000000..3baae646
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/.vscode/launch.json
@@ -0,0 +1,31 @@
+// A launch configuration that compiles the extension and then opens it inside a new window
+// Use IntelliSense to learn about possible attributes.
+// Hover to view descriptions of existing attributes.
+// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Run Extension",
+ "type": "extensionHost",
+ "request": "launch",
+ "runtimeExecutable": "${execPath}",
+ "args": ["--extensionDevelopmentPath=${workspaceFolder}"],
+ "outFiles": ["${workspaceFolder}/out/**/*.js"],
+ "preLaunchTask": "build"
+ },
+ {
+ "name": "Extension Tests",
+ "type": "extensionHost",
+ "request": "launch",
+ "runtimeExecutable": "${execPath}",
+ "args": [
+ "--disable-extensions",
+ "--extensionDevelopmentPath=${workspaceFolder}",
+ "--extensionTestsPath=${workspaceFolder}/out/test/suite/index"
+ ],
+ "outFiles": ["${workspaceFolder}/out/test/**/*.js"],
+ "preLaunchTask": "build"
+ }
+ ]
+}
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/.vscode/settings.json b/spring-javaformat-vscode/spring-javaformat-vscode-extension/.vscode/settings.json
new file mode 100644
index 00000000..5c3ffd3c
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/.vscode/settings.json
@@ -0,0 +1,12 @@
+// Place your settings in this file to overwrite default and user settings.
+{
+ "files.exclude": {
+ "out": false // set this to true to hide the "out" folder with the compiled JS files
+ },
+ "search.exclude": {
+ "out": true // set this to false to include "out" folder in search results
+ },
+ // Turn off tsc task auto detection since we have the necessary tasks as npm scripts
+ "typescript.tsc.autoDetect": "off",
+ "java.configuration.updateBuildConfiguration": "interactive"
+}
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/.vscode/tasks.json b/spring-javaformat-vscode/spring-javaformat-vscode-extension/.vscode/tasks.json
new file mode 100644
index 00000000..0a101bd2
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/.vscode/tasks.json
@@ -0,0 +1,21 @@
+// See https://go.microsoft.com/fwlink/?LinkId=733558
+// for the documentation about the tasks.json format
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "build",
+ "type": "npm",
+ "script": "watch",
+ "problemMatcher": "$tsc-watch",
+ "isBackground": true,
+ "presentation": {
+ "reveal": "never"
+ },
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ }
+ }
+ ]
+}
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/.vscodeignore b/spring-javaformat-vscode/spring-javaformat-vscode-extension/.vscodeignore
new file mode 100644
index 00000000..4b30b77f
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/.vscodeignore
@@ -0,0 +1,17 @@
+.gitignore
+.prettierrc
+.project
+.classpath
+.vscode/**
+.vscode-test/**
+.settings/**
+out/test/**
+**/tsconfig.json
+**/tslint.json
+**/*.map
+**/*.ts
+target/**
+node/**
+src/**
+README.md
+**pom.xml
\ No newline at end of file
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/LICENSE.txt b/spring-javaformat-vscode/spring-javaformat-vscode-extension/LICENSE.txt
new file mode 100644
index 00000000..ff773796
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/LICENSE.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ https://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright {yyyy} {name of copyright owner}
+
+ 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
+
+ https://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.
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/package-lock.json b/spring-javaformat-vscode/spring-javaformat-vscode-extension/package-lock.json
new file mode 100644
index 00000000..5da1cec7
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/package-lock.json
@@ -0,0 +1,3756 @@
+{
+ "name": "spring-javaformat-vscode-extension",
+ "version": "0.0.48-SNAPSHOT",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "spring-javaformat-vscode-extension",
+ "version": "0.0.48-SNAPSHOT",
+ "devDependencies": {
+ "@types/glob": "^8.0.1",
+ "@types/mocha": "^10.0.1",
+ "@types/node": "16.x",
+ "@types/vscode": "^1.75.0",
+ "@typescript-eslint/eslint-plugin": "^5.52.0",
+ "@vscode/test-electron": "^2.2.2",
+ "@vscode/vsce": "^2.19.0",
+ "eslint": "^8.33.0",
+ "glob": "8.1.0",
+ "mocha": "10.2.0",
+ "prettier": "3.0.3",
+ "typescript": "^4.9.4"
+ },
+ "engines": {
+ "vscode": "^1.75.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz",
+ "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==",
+ "dev": true,
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^9.4.0",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array": {
+ "version": "0.11.8",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
+ "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==",
+ "dev": true,
+ "dependencies": {
+ "@humanwhocodes/object-schema": "^1.2.1",
+ "debug": "^4.1.1",
+ "minimatch": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=10.10.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/object-schema": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
+ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
+ "dev": true
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@tootallnate/once": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
+ "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/@types/glob": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.0.1.tgz",
+ "integrity": "sha512-8bVUjXZvJacUFkJXHdyZ9iH1Eaj5V7I8c4NdH5sQJsdXkqT4CA5Dhb4yb4VE/3asyx4L9ayZr1NIhTsWHczmMw==",
+ "dev": true,
+ "dependencies": {
+ "@types/minimatch": "^5.1.2",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.11",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
+ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
+ "dev": true
+ },
+ "node_modules/@types/minimatch": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
+ "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==",
+ "dev": true
+ },
+ "node_modules/@types/mocha": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz",
+ "integrity": "sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q==",
+ "dev": true
+ },
+ "node_modules/@types/node": {
+ "version": "16.18.12",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.12.tgz",
+ "integrity": "sha512-vzLe5NaNMjIE3mcddFVGlAXN1LEWueUsMsOJWaT6wWMJGyljHAWHznqfnKUQWGzu7TLPrGvWdNAsvQYW+C0xtw==",
+ "dev": true
+ },
+ "node_modules/@types/semver": {
+ "version": "7.3.13",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz",
+ "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
+ "dev": true
+ },
+ "node_modules/@types/vscode": {
+ "version": "1.75.1",
+ "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.75.1.tgz",
+ "integrity": "sha512-emg7wdsTFzdi+elvoyoA+Q8keEautdQHyY5LNmHVM4PTpY8JgOTVADrGVyXGepJ6dVW2OS5/xnLUWh+nZxvdiA==",
+ "dev": true
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "5.52.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.52.0.tgz",
+ "integrity": "sha512-lHazYdvYVsBokwCdKOppvYJKaJ4S41CgKBcPvyd0xjZNbvQdhn/pnJlGtQksQ/NhInzdaeaSarlBjDXHuclEbg==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "5.52.0",
+ "@typescript-eslint/type-utils": "5.52.0",
+ "@typescript-eslint/utils": "5.52.0",
+ "debug": "^4.3.4",
+ "grapheme-splitter": "^1.0.4",
+ "ignore": "^5.2.0",
+ "natural-compare-lite": "^1.4.0",
+ "regexpp": "^3.2.0",
+ "semver": "^7.3.7",
+ "tsutils": "^3.21.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^5.0.0",
+ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "5.52.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.52.0.tgz",
+ "integrity": "sha512-e2KiLQOZRo4Y0D/b+3y08i3jsekoSkOYStROYmPUnGMEoA0h+k2qOH5H6tcjIc68WDvGwH+PaOrP1XRzLJ6QlA==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "5.52.0",
+ "@typescript-eslint/types": "5.52.0",
+ "@typescript-eslint/typescript-estree": "5.52.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "5.52.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.52.0.tgz",
+ "integrity": "sha512-AR7sxxfBKiNV0FWBSARxM8DmNxrwgnYMPwmpkC1Pl1n+eT8/I2NAUPuwDy/FmDcC6F8pBfmOcaxcxRHspgOBMw==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "5.52.0",
+ "@typescript-eslint/visitor-keys": "5.52.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "5.52.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.52.0.tgz",
+ "integrity": "sha512-tEKuUHfDOv852QGlpPtB3lHOoig5pyFQN/cUiZtpw99D93nEBjexRLre5sQZlkMoHry/lZr8qDAt2oAHLKA6Jw==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": "5.52.0",
+ "@typescript-eslint/utils": "5.52.0",
+ "debug": "^4.3.4",
+ "tsutils": "^3.21.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "5.52.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.52.0.tgz",
+ "integrity": "sha512-oV7XU4CHYfBhk78fS7tkum+/Dpgsfi91IIDy7fjCyq2k6KB63M6gMC0YIvy+iABzmXThCRI6xpCEyVObBdWSDQ==",
+ "dev": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "5.52.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.52.0.tgz",
+ "integrity": "sha512-WeWnjanyEwt6+fVrSR0MYgEpUAuROxuAH516WPjUblIrClzYJj0kBbjdnbQXLpgAN8qbEuGywiQsXUVDiAoEuQ==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "5.52.0",
+ "@typescript-eslint/visitor-keys": "5.52.0",
+ "debug": "^4.3.4",
+ "globby": "^11.1.0",
+ "is-glob": "^4.0.3",
+ "semver": "^7.3.7",
+ "tsutils": "^3.21.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "5.52.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.52.0.tgz",
+ "integrity": "sha512-As3lChhrbwWQLNk2HC8Ree96hldKIqk98EYvypd3It8Q1f8d5zWyIoaZEp2va5667M4ZyE7X8UUR+azXrFl+NA==",
+ "dev": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.9",
+ "@types/semver": "^7.3.12",
+ "@typescript-eslint/scope-manager": "5.52.0",
+ "@typescript-eslint/types": "5.52.0",
+ "@typescript-eslint/typescript-estree": "5.52.0",
+ "eslint-scope": "^5.1.1",
+ "eslint-utils": "^3.0.0",
+ "semver": "^7.3.7"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "5.52.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.52.0.tgz",
+ "integrity": "sha512-qMwpw6SU5VHCPr99y274xhbm+PRViK/NATY6qzt+Et7+mThGuFSl/ompj2/hrBlRP/kq+BFdgagnOSgw9TB0eA==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "5.52.0",
+ "eslint-visitor-keys": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@vscode/test-electron": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.2.3.tgz",
+ "integrity": "sha512-7DmdGYQTqRNaLHKG3j56buc9DkstriY4aV0S3Zj32u0U9/T0L8vwWAC9QGCh1meu1VXDEla1ze27TkqysHGP0Q==",
+ "dev": true,
+ "dependencies": {
+ "http-proxy-agent": "^4.0.1",
+ "https-proxy-agent": "^5.0.0",
+ "rimraf": "^3.0.2",
+ "unzipper": "^0.10.11"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@vscode/vsce": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-2.19.0.tgz",
+ "integrity": "sha512-dAlILxC5ggOutcvJY24jxz913wimGiUrHaPkk16Gm9/PGFbz1YezWtrXsTKUtJws4fIlpX2UIlVlVESWq8lkfQ==",
+ "dev": true,
+ "dependencies": {
+ "azure-devops-node-api": "^11.0.1",
+ "chalk": "^2.4.2",
+ "cheerio": "^1.0.0-rc.9",
+ "commander": "^6.1.0",
+ "glob": "^7.0.6",
+ "hosted-git-info": "^4.0.2",
+ "jsonc-parser": "^3.2.0",
+ "leven": "^3.1.0",
+ "markdown-it": "^12.3.2",
+ "mime": "^1.3.4",
+ "minimatch": "^3.0.3",
+ "parse-semver": "^1.1.1",
+ "read": "^1.0.7",
+ "semver": "^5.1.0",
+ "tmp": "^0.2.1",
+ "typed-rest-client": "^1.8.4",
+ "url-join": "^4.0.1",
+ "xml2js": "^0.5.0",
+ "yauzl": "^2.3.1",
+ "yazl": "^2.2.2"
+ },
+ "bin": {
+ "vsce": "vsce"
+ },
+ "engines": {
+ "node": ">= 14"
+ },
+ "optionalDependencies": {
+ "keytar": "^7.7.0"
+ }
+ },
+ "node_modules/@vscode/vsce/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@vscode/vsce/node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.8.2",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
+ "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "dev": true,
+ "dependencies": {
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-colors": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
+ "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true
+ },
+ "node_modules/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/azure-devops-node-api": {
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-11.2.0.tgz",
+ "integrity": "sha512-XdiGPhrpaT5J8wdERRKs5g8E0Zy1pvOYTli7z9E8nmOn3YGp4FhtjhrOyFmX/8veWCwdI69mCHKJw6l+4J/bHA==",
+ "dev": true,
+ "dependencies": {
+ "tunnel": "0.0.6",
+ "typed-rest-client": "^1.8.4"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "optional": true
+ },
+ "node_modules/big-integer": {
+ "version": "1.6.51",
+ "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
+ "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/binary": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz",
+ "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==",
+ "dev": true,
+ "dependencies": {
+ "buffers": "~0.1.1",
+ "chainsaw": "~0.1.0"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/bl": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
+ "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "node_modules/bluebird": {
+ "version": "3.4.7",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz",
+ "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==",
+ "dev": true
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "dev": true
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browser-stdout": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
+ "dev": true
+ },
+ "node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "optional": true,
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "node_modules/buffer-crc32": {
+ "version": "0.2.13",
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+ "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
+ "dev": true,
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/buffer-indexof-polyfill": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz",
+ "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/buffers": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz",
+ "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.2.0"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/chainsaw": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz",
+ "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==",
+ "dev": true,
+ "dependencies": {
+ "traverse": ">=0.3.0 <0.4"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/cheerio": {
+ "version": "1.0.0-rc.12",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
+ "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==",
+ "dev": true,
+ "dependencies": {
+ "cheerio-select": "^2.1.0",
+ "dom-serializer": "^2.0.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1",
+ "htmlparser2": "^8.0.1",
+ "parse5": "^7.0.0",
+ "parse5-htmlparser2-tree-adapter": "^7.0.0"
+ },
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
+ "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
+ "dev": true,
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-select": "^5.1.0",
+ "css-what": "^6.1.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ ],
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chokidar/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/chownr": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "node_modules/commander": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
+ "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "dev": true
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/css-select": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
+ "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
+ "dev": true,
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.1.0",
+ "domhandler": "^5.0.2",
+ "domutils": "^3.0.1",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
+ "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decamelize": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
+ "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/decompress-response": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
+ "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "mimic-response": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true
+ },
+ "node_modules/detect-libc": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz",
+ "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/diff": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
+ "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "dev": true,
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ]
+ },
+ "node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dev": true,
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
+ "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
+ "dev": true,
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/duplexer2": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
+ "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==",
+ "dev": true,
+ "dependencies": {
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "node_modules/duplexer2/node_modules/readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/duplexer2/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ },
+ "node_modules/duplexer2/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "node_modules/end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
+ "node_modules/entities": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
+ "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "8.34.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.34.0.tgz",
+ "integrity": "sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg==",
+ "dev": true,
+ "dependencies": {
+ "@eslint/eslintrc": "^1.4.1",
+ "@humanwhocodes/config-array": "^0.11.8",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "ajv": "^6.10.0",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "doctrine": "^3.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^7.1.1",
+ "eslint-utils": "^3.0.0",
+ "eslint-visitor-keys": "^3.3.0",
+ "espree": "^9.4.0",
+ "esquery": "^1.4.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "grapheme-splitter": "^1.0.4",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.0.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "js-sdsl": "^4.1.4",
+ "js-yaml": "^4.1.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.1",
+ "regexpp": "^3.2.0",
+ "strip-ansi": "^6.0.1",
+ "strip-json-comments": "^3.1.0",
+ "text-table": "^0.2.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "dev": true,
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/eslint-utils": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
+ "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
+ "dev": true,
+ "dependencies": {
+ "eslint-visitor-keys": "^2.0.0"
+ },
+ "engines": {
+ "node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ },
+ "peerDependencies": {
+ "eslint": ">=5"
+ }
+ },
+ "node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+ "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
+ "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
+ "dev": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/eslint/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/eslint/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/eslint/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/eslint/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/eslint-scope": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
+ "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
+ "dev": true,
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/eslint/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/eslint/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/espree": {
+ "version": "9.4.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz",
+ "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==",
+ "dev": true,
+ "dependencies": {
+ "acorn": "^8.8.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
+ "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esquery/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esrecurse/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/expand-template": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
+ "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true
+ },
+ "node_modules/fast-glob": {
+ "version": "3.2.12",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
+ "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true
+ },
+ "node_modules/fastq": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
+ "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
+ "dev": true,
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fd-slicer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+ "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
+ "dev": true,
+ "dependencies": {
+ "pend": "~1.2.0"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+ "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "dev": true,
+ "dependencies": {
+ "flat-cache": "^3.0.4"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+ "dev": true,
+ "bin": {
+ "flat": "cli.js"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
+ "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
+ "dev": true,
+ "dependencies": {
+ "flatted": "^3.1.0",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
+ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
+ "dev": true
+ },
+ "node_modules/fs-constants": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/fstream": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
+ "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "inherits": "~2.0.0",
+ "mkdirp": ">=0.5 0",
+ "rimraf": "2"
+ },
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/fstream/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/fstream/node_modules/rimraf": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "dev": true,
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz",
+ "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/github-from-package": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
+ "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/glob": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+ "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/glob/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/glob/node_modules/minimatch": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/globals": {
+ "version": "13.20.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
+ "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globby": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+ "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dev": true,
+ "dependencies": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.9",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+ "dev": true
+ },
+ "node_modules/grapheme-splitter": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
+ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
+ "dev": true
+ },
+ "node_modules/has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "dev": true,
+ "bin": {
+ "he": "bin/he"
+ }
+ },
+ "node_modules/hosted-git-info": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
+ "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/htmlparser2": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz",
+ "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==",
+ "dev": true,
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "domutils": "^3.0.1",
+ "entities": "^4.3.0"
+ }
+ },
+ "node_modules/http-proxy-agent": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
+ "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
+ "dev": true,
+ "dependencies": {
+ "@tootallnate/once": "1",
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+ "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+ "dev": true,
+ "dependencies": {
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "optional": true
+ },
+ "node_modules/ignore": {
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
+ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "dev": true,
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-plain-obj": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-unicode-supported": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
+ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "dev": true
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "node_modules/js-sdsl": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz",
+ "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==",
+ "dev": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/js-sdsl"
+ }
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true
+ },
+ "node_modules/jsonc-parser": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
+ "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
+ "dev": true
+ },
+ "node_modules/keytar": {
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz",
+ "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "dependencies": {
+ "node-addon-api": "^4.3.0",
+ "prebuild-install": "^7.0.1"
+ }
+ },
+ "node_modules/leven": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/linkify-it": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
+ "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
+ "dev": true,
+ "dependencies": {
+ "uc.micro": "^1.0.1"
+ }
+ },
+ "node_modules/listenercount": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz",
+ "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==",
+ "dev": true
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true
+ },
+ "node_modules/log-symbols": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
+ "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "is-unicode-supported": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-symbols/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/log-symbols/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/log-symbols/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/log-symbols/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/log-symbols/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/log-symbols/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/markdown-it": {
+ "version": "12.3.2",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
+ "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^2.0.1",
+ "entities": "~2.1.0",
+ "linkify-it": "^3.0.1",
+ "mdurl": "^1.0.1",
+ "uc.micro": "^1.0.5"
+ },
+ "bin": {
+ "markdown-it": "bin/markdown-it.js"
+ }
+ },
+ "node_modules/markdown-it/node_modules/entities": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
+ "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/mdurl": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
+ "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==",
+ "dev": true
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "dev": true,
+ "dependencies": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "dev": true,
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/mimic-response": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
+ "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/mkdirp": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+ "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+ "dev": true,
+ "dependencies": {
+ "minimist": "^1.2.6"
+ },
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ }
+ },
+ "node_modules/mkdirp-classic": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/mocha": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz",
+ "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==",
+ "dev": true,
+ "dependencies": {
+ "ansi-colors": "4.1.1",
+ "browser-stdout": "1.3.1",
+ "chokidar": "3.5.3",
+ "debug": "4.3.4",
+ "diff": "5.0.0",
+ "escape-string-regexp": "4.0.0",
+ "find-up": "5.0.0",
+ "glob": "7.2.0",
+ "he": "1.2.0",
+ "js-yaml": "4.1.0",
+ "log-symbols": "4.1.0",
+ "minimatch": "5.0.1",
+ "ms": "2.1.3",
+ "nanoid": "3.3.3",
+ "serialize-javascript": "6.0.0",
+ "strip-json-comments": "3.1.1",
+ "supports-color": "8.1.1",
+ "workerpool": "6.2.1",
+ "yargs": "16.2.0",
+ "yargs-parser": "20.2.4",
+ "yargs-unparser": "2.0.0"
+ },
+ "bin": {
+ "_mocha": "bin/_mocha",
+ "mocha": "bin/mocha.js"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mochajs"
+ }
+ },
+ "node_modules/mocha/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mocha/node_modules/glob": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
+ "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/mocha/node_modules/glob/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/mocha/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/mocha/node_modules/minimatch": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
+ "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/mocha/node_modules/minimatch/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/mocha/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true
+ },
+ "node_modules/mocha/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node_modules/mute-stream": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
+ "dev": true
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz",
+ "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==",
+ "dev": true,
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/napi-build-utils": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
+ "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true
+ },
+ "node_modules/natural-compare-lite": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
+ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
+ "dev": true
+ },
+ "node_modules/node-abi": {
+ "version": "3.33.0",
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.33.0.tgz",
+ "integrity": "sha512-7GGVawqyHF4pfd0YFybhv/eM9JwTtPqx0mAanQ146O3FlSh3pA24zf9IRQTOsfTSqXTNzPSP5iagAJ94jjuVog==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/node-addon-api": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
+ "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dev": true,
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.12.3",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
+ "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
+ "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+ "dev": true,
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.3"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-semver": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz",
+ "integrity": "sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^5.1.0"
+ }
+ },
+ "node_modules/parse-semver/node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/parse5": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
+ "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
+ "dev": true,
+ "dependencies": {
+ "entities": "^4.4.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz",
+ "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==",
+ "dev": true,
+ "dependencies": {
+ "domhandler": "^5.0.2",
+ "parse5": "^7.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
+ "dev": true
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/prebuild-install": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
+ "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "detect-libc": "^2.0.0",
+ "expand-template": "^2.0.3",
+ "github-from-package": "0.0.0",
+ "minimist": "^1.2.3",
+ "mkdirp-classic": "^0.5.3",
+ "napi-build-utils": "^1.0.1",
+ "node-abi": "^3.3.0",
+ "pump": "^3.0.0",
+ "rc": "^1.2.7",
+ "simple-get": "^4.0.0",
+ "tar-fs": "^2.0.0",
+ "tunnel-agent": "^0.6.0"
+ },
+ "bin": {
+ "prebuild-install": "bin.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz",
+ "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==",
+ "dev": true,
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true
+ },
+ "node_modules/pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
+ "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.11.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
+ "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
+ "dev": true,
+ "dependencies": {
+ "side-channel": "^1.0.4"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ },
+ "bin": {
+ "rc": "cli.js"
+ }
+ },
+ "node_modules/rc/node_modules/strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/read": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
+ "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==",
+ "dev": true,
+ "dependencies": {
+ "mute-stream": "~0.0.4"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/regexpp": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
+ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true,
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rimraf/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/sax": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
+ "dev": true
+ },
+ "node_modules/semver": {
+ "version": "7.3.8",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
+ "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/serialize-javascript": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
+ "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
+ "dev": true,
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/setimmediate": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
+ "dev": true
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+ "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "get-intrinsic": "^1.0.2",
+ "object-inspect": "^1.9.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/simple-concat": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "optional": true
+ },
+ "node_modules/simple-get": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
+ "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "optional": true,
+ "dependencies": {
+ "decompress-response": "^6.0.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ }
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/tar-fs": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
+ "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "chownr": "^1.1.1",
+ "mkdirp-classic": "^0.5.2",
+ "pump": "^3.0.0",
+ "tar-stream": "^2.1.4"
+ }
+ },
+ "node_modules/tar-stream": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
+ "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "bl": "^4.0.3",
+ "end-of-stream": "^1.4.1",
+ "fs-constants": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.1.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
+ "dev": true
+ },
+ "node_modules/tmp": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
+ "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
+ "dev": true,
+ "dependencies": {
+ "rimraf": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8.17.0"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/traverse": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz",
+ "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==",
+ "dev": true,
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ },
+ "node_modules/tsutils": {
+ "version": "3.21.0",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
+ "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
+ "dev": true,
+ "dependencies": {
+ "tslib": "^1.8.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ },
+ "peerDependencies": {
+ "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
+ }
+ },
+ "node_modules/tunnel": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
+ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.6.11 <=0.7.0 || >=0.7.3"
+ }
+ },
+ "node_modules/tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typed-rest-client": {
+ "version": "1.8.9",
+ "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.9.tgz",
+ "integrity": "sha512-uSmjE38B80wjL85UFX3sTYEUlvZ1JgCRhsWj/fJ4rZ0FqDUFoIuodtiVeE+cUqiVTOKPdKrp/sdftD15MDek6g==",
+ "dev": true,
+ "dependencies": {
+ "qs": "^6.9.1",
+ "tunnel": "0.0.6",
+ "underscore": "^1.12.1"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "4.9.5",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
+ "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
+ "dev": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=4.2.0"
+ }
+ },
+ "node_modules/uc.micro": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
+ "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
+ "dev": true
+ },
+ "node_modules/underscore": {
+ "version": "1.13.6",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
+ "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==",
+ "dev": true
+ },
+ "node_modules/unzipper": {
+ "version": "0.10.11",
+ "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz",
+ "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==",
+ "dev": true,
+ "dependencies": {
+ "big-integer": "^1.6.17",
+ "binary": "~0.3.0",
+ "bluebird": "~3.4.1",
+ "buffer-indexof-polyfill": "~1.0.0",
+ "duplexer2": "~0.1.4",
+ "fstream": "^1.0.12",
+ "graceful-fs": "^4.2.2",
+ "listenercount": "~1.0.1",
+ "readable-stream": "~2.3.6",
+ "setimmediate": "~1.0.4"
+ }
+ },
+ "node_modules/unzipper/node_modules/readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/unzipper/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ },
+ "node_modules/unzipper/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/url-join": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
+ "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==",
+ "dev": true
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/workerpool": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz",
+ "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==",
+ "dev": true
+ },
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true
+ },
+ "node_modules/xml2js": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
+ "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
+ "dev": true,
+ "dependencies": {
+ "sax": ">=0.6.0",
+ "xmlbuilder": "~11.0.0"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/xmlbuilder": {
+ "version": "11.0.1",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "node_modules/yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dev": true,
+ "dependencies": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "20.2.4",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
+ "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs-unparser": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
+ "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
+ "dev": true,
+ "dependencies": {
+ "camelcase": "^6.0.0",
+ "decamelize": "^4.0.0",
+ "flat": "^5.0.2",
+ "is-plain-obj": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yauzl": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+ "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
+ "dev": true,
+ "dependencies": {
+ "buffer-crc32": "~0.2.3",
+ "fd-slicer": "~1.1.0"
+ }
+ },
+ "node_modules/yazl": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz",
+ "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==",
+ "dev": true,
+ "dependencies": {
+ "buffer-crc32": "~0.2.3"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/package.json b/spring-javaformat-vscode/spring-javaformat-vscode-extension/package.json
new file mode 100644
index 00000000..c10d286e
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/package.json
@@ -0,0 +1,43 @@
+{
+ "name": "spring-javaformat-vscode-extension",
+ "description": "Spring JavaFormat Visual Studio Code Extension",
+ "displayName": "Spring JavaFormat",
+ "version": "0.0.48-SNAPSHOT",
+ "publisher": "io.spring.javaformat",
+ "engines": {
+ "vscode": "^1.75.0"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/spring-io/spring-javaformat.git"
+ },
+ "categories": [
+ "Formatters"
+ ],
+ "activationEvents": [
+ "onLanguage:java"
+ ],
+ "main": "./out/extension.js",
+ "scripts": {
+ "vscode:prepublish": "npm run compile",
+ "compile": "tsc -b ./",
+ "watch": "tsc -b ./ -watch",
+ "pretest": "npm run compile",
+ "test": "node ./out/test/runTest.js",
+ "package": "vsce package --out ./target/spring-javaformat.vsix"
+ },
+ "devDependencies": {
+ "@types/glob": "^8.0.1",
+ "@types/mocha": "^10.0.1",
+ "@types/node": "16.x",
+ "@types/vscode": "^1.75.0",
+ "@typescript-eslint/eslint-plugin": "^5.52.0",
+ "@vscode/test-electron": "^2.2.2",
+ "@vscode/vsce": "^2.19.0",
+ "eslint": "^8.33.0",
+ "glob": "8.1.0",
+ "mocha": "10.2.0",
+ "prettier": "3.0.3",
+ "typescript": "^4.9.4"
+ }
+}
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/pom.xml b/spring-javaformat-vscode/spring-javaformat-vscode-extension/pom.xml
new file mode 100644
index 00000000..7891d15d
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/pom.xml
@@ -0,0 +1,177 @@
+
+
+ 4.0.0
+
+ io.spring.javaformat
+ spring-javaformat-vscode
+ 0.0.48-SNAPSHOT
+
+ spring-javaformat-vscode-extension
+ Spring JavaFormat Visual Studio Code Extension
+
+ ${basedir}/../..
+
+
+
+
+ maven-clean-plugin
+
+
+
+ out
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+
+
+ attach-sources
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+
+
+ package
+
+ shade
+
+
+ ${basedir}/runtime/spring-java-format.jar
+ false
+
+
+ *:*
+
+ META-INF/MANIFEST.MF
+
+
+
+
+
+ io.spring.format.vscode.VisualStudioCodeFormatter
+
+
+
+
+
+
+
+ com.github.eirslett
+ frontend-maven-plugin
+
+
+ install-node-and-npm
+ initialize
+
+ install-node-and-npm
+
+
+
+ npm-install
+ initialize
+
+ npm
+
+
+
+ prettier-check
+ compile
+
+ npx
+
+
+ prettier --check .
+
+
+
+ vsce-package
+ package
+
+ npm
+
+
+ run package
+
+
+
+ update-package-lock
+
+ npm
+
+
+ install --package-lock-only
+
+
+
+
+ v19.6.0
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+
+
+ add-source
+ generate-sources
+
+ attach-artifact
+
+
+
+
+ ${project.build.directory}/spring-javaformat.vsix
+ vsix
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+
+
+ update-version
+
+ run
+
+
+
+
+
+
+
+
+
+
+
+
+
+ formatter-dependencies
+
+ true
+
+
+
+ io.spring.javaformat
+ spring-javaformat-formatter-shaded
+ ${project.version}
+
+
+
+
+
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/main/java/io/spring/format/vscode/VisualStudioCodeFormatter.java b/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/main/java/io/spring/format/vscode/VisualStudioCodeFormatter.java
new file mode 100644
index 00000000..1c4178f5
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/main/java/io/spring/format/vscode/VisualStudioCodeFormatter.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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 io.spring.format.vscode;
+
+import java.io.File;
+
+import io.spring.javaformat.config.JavaFormatConfig;
+import io.spring.javaformat.formatter.StreamsFormatter;
+
+/**
+ * Called from the Visual Studio Code extension to format source code.
+ *
+ * @author Howard Zuo
+ * @author Phillip Webb
+ */
+public final class VisualStudioCodeFormatter {
+
+ private VisualStudioCodeFormatter() {
+ }
+
+ private void run(String[] args) throws Exception {
+ File location = new File(".").getAbsoluteFile();
+ log(String.format("Loading formatter from location '%s'", location));
+ JavaFormatConfig config = JavaFormatConfig.findFrom(location);
+ StreamsFormatter formatter = new StreamsFormatter(config);
+ formatter.format(System.in).writeTo((Appendable) System.out);
+ }
+
+ private void log(String message) {
+ System.err.println(message);
+ }
+
+ public static void main(String[] args) {
+ try {
+ new VisualStudioCodeFormatter().run(args);
+ }
+ catch (Exception ex) {
+ ex.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+}
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/main/typescript/SpringDocumentFormattingEditProvider.ts b/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/main/typescript/SpringDocumentFormattingEditProvider.ts
new file mode 100644
index 00000000..cd26b056
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/main/typescript/SpringDocumentFormattingEditProvider.ts
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2017-2023 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
+ *
+ * https://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.
+ */
+
+import path = require('path')
+import vscode = require('vscode')
+import childprocess = require('child_process')
+
+const JAR_PATH = path.resolve(__dirname, '..', 'runtime', 'spring-java-format.jar')
+
+export default class SpringDocumentFormattingEditProvider implements vscode.DocumentFormattingEditProvider {
+ provideDocumentFormattingEdits(
+ document: vscode.TextDocument,
+ options: vscode.FormattingOptions,
+ token: vscode.CancellationToken,
+ ): vscode.ProviderResult {
+ if (vscode.window.visibleTextEditors.every((editor) => editor.document.fileName !== document.fileName)) {
+ return []
+ }
+ return this.runFormatter(document, token).then(
+ (edits) => edits,
+ (err) => {
+ if (err) {
+ console.log(err)
+ return Promise.reject(`Check the console in dev tools to find errors when formatting spring-javaformat`)
+ }
+ },
+ )
+ }
+
+ private runFormatter(document: vscode.TextDocument, token: vscode.CancellationToken): Promise {
+ return new Promise((resolve, reject) => {
+ console.log(`formatting ${document.uri} using spring-javaformat`)
+ let stdout = ''
+ let stderr = ''
+ const cwd = path.dirname(document.fileName)
+ const args = ['-jar', JAR_PATH]
+ const process = childprocess.spawn('java', args, { cwd })
+ token.onCancellationRequested(() => !process.killed && process.kill())
+ process.stdout.setEncoding('utf8')
+ process.stdout.on('data', (data) => (stdout += data))
+ process.stderr.on('data', (data) => (stderr += data))
+ process.on('error', (err) => {
+ console.log(`spring-javaformat returned error ${err}`)
+ if (err && (err).code === 'ENOENT') {
+ return reject(`failed to find run spring-javaformat due to missing 'java' executable`)
+ }
+ })
+ process.on('close', (code) => {
+ if (code !== 0) {
+ console.log(`spring-javaformat returned error code ${code}`)
+ return reject(stderr)
+ }
+ console.log('spring-javaformat returned without error')
+ const fileStart = new vscode.Position(0, 0)
+ const fileEnd = document.lineAt(document.lineCount - 1).range.end
+ const textEdits: vscode.TextEdit[] = [new vscode.TextEdit(new vscode.Range(fileStart, fileEnd), stdout)]
+ return resolve(textEdits)
+ })
+ if (process.pid) {
+ console.log('sending document data to spring-javaformat')
+ process.stdin.end(document.getText())
+ }
+ })
+ }
+}
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/main/typescript/extension.ts b/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/main/typescript/extension.ts
new file mode 100644
index 00000000..3b4fb826
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/main/typescript/extension.ts
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2017-2023 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
+ *
+ * https://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.
+ */
+
+import * as vscode from 'vscode'
+import SpringDocumentFormattingEditProvider from './SpringDocumentFormattingEditProvider'
+
+export function activate(context: vscode.ExtensionContext) {
+ console.log('Activated spring-javaformat extension')
+ context.subscriptions.push(
+ vscode.languages.registerDocumentFormattingEditProvider(
+ [
+ {
+ language: 'java',
+ scheme: 'file',
+ },
+ ],
+ new SpringDocumentFormattingEditProvider(),
+ ),
+ )
+}
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/main/typescript/tsconfig.json b/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/main/typescript/tsconfig.json
new file mode 100644
index 00000000..431716b1
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/main/typescript/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "extends": "../../../tsconfig-base.json",
+ "compilerOptions": {
+ "outDir": "../../../out",
+ "rootDir": "."
+ }
+}
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/test/typescript/runTest.ts b/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/test/typescript/runTest.ts
new file mode 100644
index 00000000..19b689c6
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/test/typescript/runTest.ts
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2017-2023 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
+ *
+ * https://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.
+ */
+
+import * as path from 'path'
+
+import { runTests } from '@vscode/test-electron'
+
+async function main() {
+ try {
+ const extensionDevelopmentPath = path.resolve(__dirname, '../../../../')
+ const extensionTestsPath = path.resolve(__dirname, './suite/index')
+ await runTests({ extensionDevelopmentPath, extensionTestsPath, launchArgs: ['--disable-extensions'] })
+ } catch (err) {
+ console.error('Failed to run tests')
+ process.exit(1)
+ }
+}
+
+main()
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/test/typescript/suite/extension.test.ts b/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/test/typescript/suite/extension.test.ts
new file mode 100644
index 00000000..e73b4c89
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/test/typescript/suite/extension.test.ts
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2017-2023 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
+ *
+ * https://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.
+ */
+
+import * as assert from 'assert'
+import * as vscode from 'vscode'
+import * as path from 'path'
+import * as fs from 'fs'
+
+export const WORKSPACE_PATH = path.resolve(__dirname, '..', '..', '..', 'test-workspace')
+export const FILE_PATH = path.resolve(WORKSPACE_PATH, 'Test.java')
+
+suite('Extension Test Suite', () => {
+ test('Format file', async () => {
+ const initial = 'public static class Test {public static void main(String[] args){}}\n'
+ const expected = 'public static class Test {\n\n\tpublic static void main(String[] args) {\n\t}\n\n}\n'
+ if (!fs.existsSync(WORKSPACE_PATH)) {
+ fs.mkdirSync(WORKSPACE_PATH)
+ }
+ fs.closeSync(fs.openSync(FILE_PATH, 'w'))
+ const document = await vscode.workspace.openTextDocument(vscode.Uri.file(FILE_PATH))
+ const editor = await vscode.window.showTextDocument(document)
+ await editor.edit((builder) => {
+ builder.delete(new vscode.Range(new vscode.Position(0, 0), document.positionAt(document.getText().length)))
+ builder.insert(new vscode.Position(0, 0), initial)
+ })
+ editor.selection = new vscode.Selection(0, 0, 0, 0)
+ await vscode.commands.executeCommand('editor.action.formatDocument')
+ const actual = document.getText()
+ assert.deepEqual(actual, expected)
+ })
+})
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/test/typescript/suite/index.ts b/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/test/typescript/suite/index.ts
new file mode 100644
index 00000000..3301b793
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/test/typescript/suite/index.ts
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2017-2023 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
+ *
+ * https://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.
+ */
+
+import * as path from 'path'
+import * as Mocha from 'mocha'
+import * as glob from 'glob'
+
+export function run(): Promise {
+ const mocha = new Mocha({
+ ui: 'tdd',
+ })
+ const testsRoot = path.resolve(__dirname, '..')
+ return new Promise((resolve, reject) => {
+ glob('**/**.test.js', { cwd: testsRoot }, (err, files) => {
+ console.log(files)
+ if (err) {
+ return reject(err)
+ }
+ files.forEach((f) => mocha.addFile(path.resolve(testsRoot, f)))
+ try {
+ mocha.run((failures) => {
+ if (failures > 0) {
+ reject(new Error(`${failures} tests failed.`))
+ } else {
+ resolve()
+ }
+ })
+ } catch (err) {
+ console.error(err)
+ reject(err)
+ }
+ })
+ })
+}
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/test/typescript/tsconfig.json b/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/test/typescript/tsconfig.json
new file mode 100644
index 00000000..7412944e
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/src/test/typescript/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "extends": "../../../tsconfig-base.json",
+ "compilerOptions": {
+ "outDir": "../../../out/test",
+ "rootDirs": ["../../main/typescript", "."]
+ }
+}
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/test-workspace/Test.java b/spring-javaformat-vscode/spring-javaformat-vscode-extension/test-workspace/Test.java
new file mode 100644
index 00000000..e69de29b
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/tsconfig-base.json b/spring-javaformat-vscode/spring-javaformat-vscode-extension/tsconfig-base.json
new file mode 100644
index 00000000..7c273362
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/tsconfig-base.json
@@ -0,0 +1,9 @@
+{
+ "compilerOptions": {
+ "module": "commonjs",
+ "target": "ES2020",
+ "lib": ["ES2020"],
+ "sourceMap": true,
+ "strict": true
+ }
+}
diff --git a/spring-javaformat-vscode/spring-javaformat-vscode-extension/tsconfig.json b/spring-javaformat-vscode/spring-javaformat-vscode-extension/tsconfig.json
new file mode 100644
index 00000000..a6df75bd
--- /dev/null
+++ b/spring-javaformat-vscode/spring-javaformat-vscode-extension/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [], // this root tsconfig just exists to compose sub-projects
+ "references": [
+ {
+ "path": "./src/main/typescript"
+ },
+ {
+ "path": "./src/test/typescript"
+ }
+ ]
+}
diff --git a/spring-javaformat/pom.xml b/spring-javaformat/pom.xml
index 3565d503..849cefc1 100644
--- a/spring-javaformat/pom.xml
+++ b/spring-javaformat/pom.xml
@@ -6,7 +6,7 @@
io.spring.javaformatspring-javaformat-build
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTspring-javaformatpom
@@ -38,9 +38,9 @@
spring-javaformat-formatter-testsspring-javaformat-formatter-eclipse-rewriterspring-javaformat-formatter-eclipse-jdk8
- spring-javaformat-formatter-eclipse-jdk11
+ spring-javaformat-formatter-eclipse-jdk17spring-javaformat-formatter-eclipse-jdt-jdk8
- spring-javaformat-formatter-eclipse-jdt-jdk11
+ spring-javaformat-formatter-eclipse-jdt-jdk17spring-javaformat-formatter-eclipse-runtimespring-javaformat-formatter-shaderspring-javaformat-formatter-shaded
diff --git a/spring-javaformat/spring-javaformat-checkstyle/pom.xml b/spring-javaformat/spring-javaformat-checkstyle/pom.xml
index 0372eb22..5605577e 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/pom.xml
+++ b/spring-javaformat/spring-javaformat-checkstyle/pom.xml
@@ -5,7 +5,7 @@
io.spring.javaformatspring-javaformat
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTspring-javaformat-checkstyleSpring JavaFormat CheckStyle
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/FilteredModuleFactory.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/FilteredModuleFactory.java
index 3a5a9921..e595863f 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/FilteredModuleFactory.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/FilteredModuleFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/SpringChecks.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/SpringChecks.java
index c006edcb..244b7edf 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/SpringChecks.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/SpringChecks.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/SpringConfigurationLoader.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/SpringConfigurationLoader.java
index f801f130..0be1ecc6 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/SpringConfigurationLoader.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/SpringConfigurationLoader.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-present 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.
@@ -16,7 +16,11 @@
package io.spring.javaformat.checkstyle;
+import java.io.IOException;
import java.io.InputStream;
+import java.io.StringReader;
+import java.io.UncheckedIOException;
+import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
import java.util.stream.Collectors;
@@ -24,11 +28,14 @@
import com.puppycrawl.tools.checkstyle.ConfigurationLoader;
import com.puppycrawl.tools.checkstyle.ConfigurationLoader.IgnoredModulesOptions;
import com.puppycrawl.tools.checkstyle.PropertyResolver;
-import com.puppycrawl.tools.checkstyle.api.AutomaticBean;
import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
+import com.puppycrawl.tools.checkstyle.api.Configurable;
import com.puppycrawl.tools.checkstyle.api.Configuration;
import com.puppycrawl.tools.checkstyle.api.Context;
+import com.puppycrawl.tools.checkstyle.api.Contextualizable;
import com.puppycrawl.tools.checkstyle.api.FileSetCheck;
+import com.puppycrawl.tools.checkstyle.api.Scope;
+import com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocVariableCheck;
import org.xml.sax.InputSource;
/**
@@ -49,15 +56,45 @@ class SpringConfigurationLoader {
}
public Collection load(PropertyResolver propertyResolver) {
- Configuration config = loadConfiguration(getClass().getResourceAsStream("spring-checkstyle.xml"),
- propertyResolver);
- return Arrays.stream(config.getChildren()).filter(this.moduleFactory::nonFiltered).map(this::load)
- .collect(Collectors.toList());
+ Configuration config = loadConfiguration(loadConfigurationSource(), propertyResolver);
+ return Arrays.stream(config.getChildren())
+ .filter(this.moduleFactory::nonFiltered)
+ .map(this::load)
+ .collect(Collectors.toList());
}
- private Configuration loadConfiguration(InputStream inputStream, PropertyResolver propertyResolver) {
+ private String loadConfigurationSource() {
+ try (InputStream stream = getClass().getResourceAsStream("spring-checkstyle.xml")) {
+ StringBuilder builder = new StringBuilder();
+ byte[] buffer = new byte[4096];
+ int read;
+ while ((read = stream.read(buffer)) > 0) {
+ builder.append(new String(buffer, 0, read, StandardCharsets.UTF_8));
+ }
+ return preprocessConfigurationSource(builder.toString());
+ }
+ catch (IOException ex) {
+ throw new UncheckedIOException(ex);
+ }
+ }
+
+ private String preprocessConfigurationSource(String source) {
+ return source.replace("{{javadocVariableCheckScopeProperty}}", javadocVariableCheckScopeProperty());
+ }
+
+ private String javadocVariableCheckScopeProperty() {
try {
- InputSource inputSource = new InputSource(inputStream);
+ JavadocVariableCheck.class.getMethod("setScope", Scope.class);
+ return "scope";
+ }
+ catch (NoSuchMethodException ex) {
+ return "accessModifiers";
+ }
+ }
+
+ private Configuration loadConfiguration(String source, PropertyResolver propertyResolver) {
+ try {
+ InputSource inputSource = new InputSource(new StringReader(source));
return ConfigurationLoader.loadConfiguration(inputSource, propertyResolver, IgnoredModulesOptions.EXECUTE);
}
catch (CheckstyleException ex) {
@@ -77,9 +114,7 @@ private Object createModule(Configuration configuration) {
String name = configuration.getName();
try {
Object module = this.moduleFactory.createModule(name);
- if (module instanceof AutomaticBean) {
- initialize(configuration, (AutomaticBean) module);
- }
+ initialize(configuration, module);
return module;
}
catch (CheckstyleException ex) {
@@ -87,9 +122,13 @@ private Object createModule(Configuration configuration) {
}
}
- private void initialize(Configuration configuration, AutomaticBean bean) throws CheckstyleException {
- bean.contextualize(this.context);
- bean.configure(configuration);
+ private void initialize(Configuration configuration, Object module) throws CheckstyleException {
+ if (module instanceof Contextualizable) {
+ ((Contextualizable) module).contextualize(this.context);
+ }
+ if (module instanceof Configurable) {
+ ((Configurable) module).configure(configuration);
+ }
}
}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/AbstractSpringCheck.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/AbstractSpringCheck.java
index 347f1ed1..af4511d2 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/AbstractSpringCheck.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/AbstractSpringCheck.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringAnnotationAttributeConciseValueCheck.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringAnnotationAttributeConciseValueCheck.java
new file mode 100644
index 00000000..b8b0ad81
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringAnnotationAttributeConciseValueCheck.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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 io.spring.javaformat.checkstyle.check;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.api.TokenTypes;
+
+/**
+ * Spring-specific check of the concision of an annotation's attribute values.
+ *
+ * @author Andy Wilkinson
+ */
+public class SpringAnnotationAttributeConciseValueCheck extends AbstractCheck {
+
+ private final List imports = new ArrayList<>();
+
+ @Override
+ public int[] getDefaultTokens() {
+ return getRequiredTokens();
+ }
+
+ @Override
+ public int[] getAcceptableTokens() {
+ return getRequiredTokens();
+ }
+
+ @Override
+ public int[] getRequiredTokens() {
+ return new int[] { TokenTypes.ANNOTATION, TokenTypes.IMPORT };
+ }
+
+ @Override
+ public void init() {
+ this.imports.clear();
+ }
+
+ @Override
+ public void visitToken(DetailAST ast) {
+ if (ast.getType() == TokenTypes.IMPORT) {
+ visitImport(ast);
+ }
+ else if (ast.getType() == TokenTypes.ANNOTATION) {
+ visitAnnotation(ast);
+ }
+ }
+
+ private void visitImport(DetailAST importNode) {
+ List components = dotSeparatedComponents(importNode.getFirstChild());
+ if (components != null) {
+ this.imports.add(new ImportStatement(components));
+ }
+ }
+
+ private void visitAnnotation(DetailAST annotation) {
+ int valuePairCount = annotation.getChildCount(TokenTypes.ANNOTATION_MEMBER_VALUE_PAIR);
+ if (valuePairCount == 0) {
+ DetailAST valueExpression = annotation.findFirstToken(TokenTypes.EXPR);
+ visitValueExpression(valueExpression, annotation, "value");
+ }
+ else {
+ DetailAST candidate = annotation.getFirstChild();
+ while (candidate != null) {
+ if (candidate.getType() == TokenTypes.ANNOTATION_MEMBER_VALUE_PAIR) {
+ visitMemberValuePair(candidate);
+ }
+ candidate = candidate.getNextSibling();
+ }
+ }
+ }
+
+ private void visitMemberValuePair(DetailAST annotationValue) {
+ DetailAST annotation = annotationValue.getParent();
+ DetailAST attribute = annotationValue.findFirstToken(TokenTypes.IDENT);
+ DetailAST valueExpression = annotationValue.findFirstToken(TokenTypes.EXPR);
+ visitValueExpression(valueExpression, annotation, attribute.getText());
+ }
+
+ private void visitValueExpression(DetailAST valueExpression, DetailAST annotation, String attributeName) {
+ if (valueExpression == null || valueExpression.getChildCount() != 1) {
+ return;
+ }
+ List expressionComponents = dotSeparatedComponents(valueExpression.getFirstChild());
+ if (expressionComponents == null || expressionComponents.size() <= 2) {
+ return;
+ }
+ String outerTypeName = expressionComponents.get(0);
+ DetailAST annotationIdent = annotation.findFirstToken(TokenTypes.IDENT);
+ if (annotationIdent == null) {
+ return;
+ }
+ String annotationName = annotationIdent.getText();
+ if (outerTypeName.equals(annotationName)) {
+ String innerTypeName = expressionComponents.get(1);
+ if (!existingClashingImport(outerTypeName, innerTypeName)) {
+ String toImport = outerTypeName + "." + innerTypeName;
+ String replacement = String.join(".", expressionComponents.subList(1, expressionComponents.size()));
+ log(valueExpression.getLineNo(), valueExpression.getColumnNo(),
+ "annotation.attribute.overlyVerboseValue", attributeName, toImport, replacement);
+ }
+ }
+ }
+
+ private List dotSeparatedComponents(DetailAST ast) {
+ if (ast.getType() == TokenTypes.IDENT) {
+ return Collections.singletonList(ast.getText());
+ }
+ if (ast.getType() == TokenTypes.DOT) {
+ List left = dotSeparatedComponents(ast.getFirstChild());
+ List right = dotSeparatedComponents(ast.getLastChild());
+ if (left != null && right != null) {
+ List components = new ArrayList<>();
+ components.addAll(left);
+ components.addAll(right);
+ return components;
+ }
+ }
+ return null;
+ }
+
+ private boolean existingClashingImport(String outer, String inner) {
+ return this.imports.stream().filter((imported) -> imported.clashesWith(outer, inner)).findFirst().isPresent();
+ }
+
+ static class ImportStatement {
+
+ private final String imported;
+
+ ImportStatement(List components) {
+ this.imported = String.join(".", components);
+ }
+
+ boolean clashesWith(String outer, String inner) {
+ return this.imported.endsWith("." + inner) && !this.imported.endsWith("." + outer + "." + inner);
+ }
+
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringAnnotationLocationCheck.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringAnnotationLocationCheck.java
new file mode 100644
index 00000000..c697521f
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringAnnotationLocationCheck.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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 io.spring.javaformat.checkstyle.check;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.api.TokenTypes;
+import com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationLocationCheck;
+import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
+
+/**
+ * Spring variant of {@link AnnotationLocationCheck}.
+ *
+ * @author Phillip Webb
+ */
+public class SpringAnnotationLocationCheck extends AbstractCheck {
+
+ private static final Set JSPECIFY_ANNOTATION_NAMES = new HashSet<>(
+ Arrays.asList("NonNull", "Nullable", "NullMarked", "NullUnmarked"));
+
+ @Override
+ public int[] getDefaultTokens() {
+ return new int[] { TokenTypes.CLASS_DEF, TokenTypes.INTERFACE_DEF, TokenTypes.PACKAGE_DEF,
+ TokenTypes.ENUM_CONSTANT_DEF, TokenTypes.ENUM_DEF, TokenTypes.METHOD_DEF, TokenTypes.CTOR_DEF,
+ TokenTypes.VARIABLE_DEF, TokenTypes.RECORD_DEF, TokenTypes.COMPACT_CTOR_DEF, };
+ }
+
+ @Override
+ public int[] getAcceptableTokens() {
+ return new int[] { TokenTypes.CLASS_DEF, TokenTypes.INTERFACE_DEF, TokenTypes.PACKAGE_DEF,
+ TokenTypes.ENUM_CONSTANT_DEF, TokenTypes.ENUM_DEF, TokenTypes.METHOD_DEF, TokenTypes.CTOR_DEF,
+ TokenTypes.VARIABLE_DEF, TokenTypes.ANNOTATION_DEF, TokenTypes.ANNOTATION_FIELD_DEF,
+ TokenTypes.RECORD_DEF, TokenTypes.COMPACT_CTOR_DEF, };
+ }
+
+ @Override
+ public int[] getRequiredTokens() {
+ return CommonUtil.EMPTY_INT_ARRAY;
+ }
+
+ @Override
+ public void visitToken(DetailAST ast) {
+ if (ast.getType() != TokenTypes.VARIABLE_DEF || ast.getParent().getType() == TokenTypes.OBJBLOCK) {
+ DetailAST node = ast.findFirstToken(TokenTypes.MODIFIERS);
+ node = (node != null) ? node : ast.findFirstToken(TokenTypes.ANNOTATIONS);
+ checkAnnotations(node, getExpectedAnnotationIndentation(node));
+ }
+ }
+
+ private int getExpectedAnnotationIndentation(DetailAST node) {
+ return node.getColumnNo();
+ }
+
+ private void checkAnnotations(DetailAST node, int correctIndentation) {
+ DetailAST annotation = node.getFirstChild();
+ while (annotation != null && annotation.getType() == TokenTypes.ANNOTATION) {
+ checkAnnotation(correctIndentation, annotation);
+ annotation = annotation.getNextSibling();
+ }
+ }
+
+ private void checkAnnotation(int correctIndentation, DetailAST annotation) {
+ String annotationName = getAnnotationName(annotation);
+ if (!isCorrectLocation(annotation) && !isJSpecifyAnnotation(annotationName)) {
+ log(annotation, AnnotationLocationCheck.MSG_KEY_ANNOTATION_LOCATION_ALONE, annotationName);
+ }
+ else if (annotation.getColumnNo() != correctIndentation && !hasNodeBefore(annotation)) {
+ log(annotation, AnnotationLocationCheck.MSG_KEY_ANNOTATION_LOCATION, annotationName,
+ annotation.getColumnNo(), correctIndentation);
+ }
+ }
+
+ private String getAnnotationName(DetailAST annotation) {
+ DetailAST identNode = annotation.findFirstToken(TokenTypes.IDENT);
+ if (identNode == null) {
+ identNode = annotation.findFirstToken(TokenTypes.DOT).findFirstToken(TokenTypes.IDENT);
+ }
+ return identNode.getText();
+ }
+
+ private boolean isCorrectLocation(DetailAST annotation) {
+ return !hasNodeBeside(annotation);
+ }
+
+ private boolean hasNodeBeside(DetailAST annotation) {
+ return hasNodeBefore(annotation) || hasNodeAfter(annotation);
+ }
+
+ private boolean hasNodeBefore(DetailAST annotation) {
+ int annotationLineNo = annotation.getLineNo();
+ DetailAST previousNode = annotation.getPreviousSibling();
+ return (previousNode != null) && (annotationLineNo == previousNode.getLineNo());
+ }
+
+ private boolean hasNodeAfter(DetailAST annotation) {
+ int annotationLineNo = annotation.getLineNo();
+ DetailAST nextNode = annotation.getNextSibling();
+ nextNode = (nextNode != null) ? nextNode : annotation.getParent().getNextSibling();
+ return annotationLineNo == nextNode.getLineNo();
+ }
+
+ private boolean isJSpecifyAnnotation(String annotationName) {
+ return JSPECIFY_ANNOTATION_NAMES.contains(annotationName);
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringAvoidStaticImportCheck.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringAvoidStaticImportCheck.java
index d88c11be..b9b3c3e4 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringAvoidStaticImportCheck.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringAvoidStaticImportCheck.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2022 the original author or authors.
+ * Copyright 2017-present 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.
@@ -37,6 +37,7 @@ public class SpringAvoidStaticImportCheck extends AvoidStaticImportCheck {
excludes.add("io.restassured.RestAssured.*");
excludes.add("org.assertj.core.api.Assertions.*");
excludes.add("org.assertj.core.api.Assumptions.*");
+ excludes.add("org.assertj.core.api.BDDAssertions.*");
excludes.add("org.assertj.core.api.HamcrestCondition.*");
excludes.add("org.awaitility.Awaitility.*");
excludes.add("org.hamcrest.CoreMatchers.*");
@@ -46,16 +47,15 @@ public class SpringAvoidStaticImportCheck extends AvoidStaticImportCheck {
excludes.add("org.junit.internal.matchers.ThrowableMessageMatcher.*");
excludes.add("org.junit.jupiter.api.Assertions.*");
excludes.add("org.junit.jupiter.api.Assumptions.*");
- excludes.add("org.junit.jupiter.api.Assertions.*");
+ excludes.add("org.mockito.AdditionalMatchers.*");
excludes.add("org.mockito.ArgumentMatchers.*");
excludes.add("org.mockito.BDDMockito.*");
excludes.add("org.mockito.Matchers.*");
- excludes.add("org.mockito.AdditionalMatchers.*");
excludes.add("org.mockito.Mockito.*");
excludes.add("org.springframework.boot.configurationprocessor.ConfigurationMetadataMatchers.*");
excludes.add("org.springframework.boot.configurationprocessor.TestCompiler.*");
excludes.add("org.springframework.boot.test.autoconfigure.AutoConfigurationImportedCondition.*");
- excludes.add("org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo");
+ excludes.add("org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*");
excludes.add("org.springframework.restdocs.headers.HeaderDocumentation.*");
excludes.add("org.springframework.restdocs.hypermedia.HypermediaDocumentation.*");
excludes.add("org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*");
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringCatchCheck.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringCatchCheck.java
index 638951c1..81d2144b 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringCatchCheck.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringCatchCheck.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringDeprecatedCheck.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringDeprecatedCheck.java
new file mode 100644
index 00000000..42bf0f4b
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringDeprecatedCheck.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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 io.spring.javaformat.checkstyle.check;
+
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.api.FullIdent;
+import com.puppycrawl.tools.checkstyle.api.TokenTypes;
+
+/**
+ * Checks that {@link Deprecated @Deprecated} annotations follow Spring conventions.
+ *
+ * @author Andy Wilkinson
+ * @since 0.0.35
+ */
+public class SpringDeprecatedCheck extends AbstractSpringCheck {
+
+ @Override
+ public int[] getAcceptableTokens() {
+ return new int[] { TokenTypes.ANNOTATION };
+ }
+
+ @Override
+ public void visitToken(DetailAST ast) {
+ if (ast.getType() == TokenTypes.ANNOTATION) {
+ visitAnnotation(ast);
+ }
+ }
+
+ private void visitAnnotation(DetailAST annotation) {
+ String text = FullIdent.createFullIdent(annotation.findFirstToken(TokenTypes.AT).getNextSibling()).getText();
+ if ("Deprecated".equals(text) || "java.lang.Deprecated".equals(text)) {
+ visitDeprecated(annotation);
+ }
+ }
+
+ private void visitDeprecated(DetailAST deprecated) {
+ DetailAST sinceAttribute = findSinceAttribute(deprecated);
+ if (sinceAttribute == null) {
+ log(deprecated.getLineNo(), deprecated.getColumnNo(), "deprecated.missingSince");
+ }
+ else {
+ DetailAST expr = sinceAttribute.findFirstToken(TokenTypes.EXPR);
+ DetailAST sinceLiteral = expr.findFirstToken(TokenTypes.STRING_LITERAL);
+ if ("\"\"".equals(sinceLiteral.getText())) {
+ log(deprecated.getLineNo(), deprecated.getColumnNo(), "deprecated.emptySince");
+ }
+ }
+ }
+
+ private DetailAST findSinceAttribute(DetailAST deprecated) {
+ DetailAST child = deprecated.getFirstChild();
+ while (child != null) {
+ if (child.getType() == TokenTypes.ANNOTATION_MEMBER_VALUE_PAIR) {
+ DetailAST attributeIdent = child.findFirstToken(TokenTypes.IDENT);
+ if (attributeIdent != null && ("since".equals(attributeIdent.getText()))) {
+ return child;
+ }
+ }
+ child = child.getNextSibling();
+ }
+ return null;
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringHeaderCheck.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringHeaderCheck.java
index 7820d4b3..c58e74c4 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringHeaderCheck.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringHeaderCheck.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-present 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.
@@ -61,7 +61,7 @@ public class SpringHeaderCheck extends AbstractFileSetCheck {
/**
* The default header copyright pattern.
*/
- public static final String DEFAULT_HEADER_COPYRIGHT_PATTERN = "20\\d\\d(-20\\d\\d)?";
+ public static final String DEFAULT_HEADER_COPYRIGHT_PATTERN = "20\\d\\d(-20\\d\\d|-present)?";
private static final String DEFAULT_CHARSET = System.getProperty("file.encoding", StandardCharsets.UTF_8.name());
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringHideUtilityClassConstructor.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringHideUtilityClassConstructor.java
index c7dcaab1..882b9b9a 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringHideUtilityClassConstructor.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringHideUtilityClassConstructor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
@@ -39,8 +39,9 @@ public class SpringHideUtilityClassConstructor extends HideUtilityClassConstruct
annotations.add("org.springframework.context.annotation.Configuration");
annotations.add("org.springframework.boot.autoconfigure.SpringBootApplication");
annotations.add("org.springframework.boot.autoconfigure.EnableAutoConfiguration");
- Set shortNames = annotations.stream().map((name) -> name.substring(name.lastIndexOf(".") + 1))
- .collect(Collectors.toSet());
+ Set shortNames = annotations.stream()
+ .map((name) -> name.substring(name.lastIndexOf(".") + 1))
+ .collect(Collectors.toSet());
annotations.addAll(shortNames);
BYPASS_ANNOTATIONS = Collections.unmodifiableSet(annotations);
}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringImportOrderCheck.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringImportOrderCheck.java
index 94198a8b..69f8bf31 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringImportOrderCheck.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringImportOrderCheck.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringJUnit5Check.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringJUnit5Check.java
index 9fc9251f..722c8868 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringJUnit5Check.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringJUnit5Check.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-present 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.
@@ -19,12 +19,14 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.FullIdent;
@@ -38,33 +40,35 @@
*/
public class SpringJUnit5Check extends AbstractSpringCheck {
- private static final String JUNIT4_TEST_ANNOTATION = "org.junit.Test";
+ private static final String JUNIT4_TEST_ANNOTATION_NAME = "org.junit.Test";
- private static final List TEST_ANNOTATIONS;
+ private static final List TEST_ANNOTATIONS;
static {
- Set annotations = new LinkedHashSet<>();
- annotations.add("RepeatedTest");
- annotations.add("Test");
- annotations.add("TestFactory");
- annotations.add("TestTemplate");
- annotations.add("ParameterizedTest");
+ Set annotations = new LinkedHashSet<>();
+ annotations.add(new Annotation("org.junit.jupiter.api", "RepeatedTest"));
+ annotations.add(new Annotation("org.junit.jupiter.api", "Test"));
+ annotations.add(new Annotation("org.junit.jupiter.api", "TestFactory"));
+ annotations.add(new Annotation("org.junit.jupiter.api", "TestTemplate"));
+ annotations.add(new Annotation("org.junit.jupiter.api", "ParameterizedTest"));
TEST_ANNOTATIONS = Collections.unmodifiableList(new ArrayList<>(annotations));
}
- private static final List LIFECYCLE_ANNOTATIONS;
+ private static final List LIFECYCLE_ANNOTATIONS;
static {
- Set annotations = new LinkedHashSet<>();
- annotations.add("BeforeAll");
- annotations.add("BeforeEach");
- annotations.add("AfterAll");
- annotations.add("AfterEach");
+ Set annotations = new LinkedHashSet<>();
+ annotations.add(new Annotation("org.junit.jupiter.api", "BeforeAll"));
+ annotations.add(new Annotation("org.junit.jupiter.api", "BeforeEach"));
+ annotations.add(new Annotation("org.junit.jupiter.api", "AfterAll"));
+ annotations.add(new Annotation("org.junit.jupiter.api", "AfterEach"));
LIFECYCLE_ANNOTATIONS = Collections.unmodifiableList(new ArrayList<>(annotations));
}
+ private static final Annotation NESTED_ANNOTATION = new Annotation("org.junit.jupiter.api", "Nested");
+
private static final Set BANNED_IMPORTS;
static {
Set bannedImports = new LinkedHashSet<>();
- bannedImports.add(JUNIT4_TEST_ANNOTATION);
+ bannedImports.add(JUNIT4_TEST_ANNOTATION_NAME);
bannedImports.add("org.junit.After");
bannedImports.add("org.junit.AfterClass");
bannedImports.add("org.junit.Before");
@@ -82,43 +86,84 @@ public class SpringJUnit5Check extends AbstractSpringCheck {
private final List lifecycleMethods = new ArrayList<>();
+ private final List nestedTestClasses = new ArrayList<>();
+
+ private DetailAST testClass;
+
@Override
public int[] getAcceptableTokens() {
- return new int[] { TokenTypes.METHOD_DEF, TokenTypes.IMPORT };
+ return new int[] { TokenTypes.METHOD_DEF, TokenTypes.IMPORT, TokenTypes.CLASS_DEF };
}
@Override
public void beginTree(DetailAST rootAST) {
+ this.testClass = null;
this.imports.clear();
this.testMethods.clear();
this.lifecycleMethods.clear();
+ this.nestedTestClasses.clear();
}
@Override
public void visitToken(DetailAST ast) {
switch (ast.getType()) {
- case TokenTypes.METHOD_DEF:
- visitMethodDef(ast);
- case TokenTypes.IMPORT:
- visitImport(ast);
- break;
+ case TokenTypes.METHOD_DEF:
+ visitMethodDef(ast);
+ break;
+ case TokenTypes.IMPORT:
+ visitImport(ast);
+ break;
+ case TokenTypes.CLASS_DEF:
+ visitClassDefinition(ast);
+ break;
}
}
private void visitMethodDef(DetailAST ast) {
- if (AnnotationUtil.containsAnnotation(ast, TEST_ANNOTATIONS)) {
+ if (containsAnnotation(ast, TEST_ANNOTATIONS)) {
this.testMethods.add(ast);
}
- if (AnnotationUtil.containsAnnotation(ast, LIFECYCLE_ANNOTATIONS)) {
+ if (containsAnnotation(ast, LIFECYCLE_ANNOTATIONS)) {
this.lifecycleMethods.add(ast);
}
}
+ private boolean containsAnnotation(DetailAST ast, List annotations) {
+ List annotationNames = annotations.stream()
+ .flatMap((annotation) -> Stream.of(annotation.simpleName, annotation.fullyQualifiedName()))
+ .collect(Collectors.toList());
+ try {
+ return AnnotationUtil.containsAnnotation(ast, annotationNames);
+ }
+ catch (NoSuchMethodError ex) {
+ // Checkstyle >= 10.3 (https://github.com/checkstyle/checkstyle/issues/14134)
+ Set annotationNamesSet = new HashSet<>(annotationNames);
+ try {
+ return (boolean) AnnotationUtil.class.getMethod("containsAnnotation", DetailAST.class, Set.class)
+ .invoke(null, ast, annotationNamesSet);
+ }
+ catch (Exception ex2) {
+ throw new RuntimeException("containsAnnotation failed", ex2);
+ }
+ }
+ }
+
private void visitImport(DetailAST ast) {
FullIdent ident = FullIdent.createFullIdentBelow(ast);
this.imports.put(ident.getText(), ident);
}
+ private void visitClassDefinition(DetailAST ast) {
+ if (ast.getParent().getType() == TokenTypes.COMPILATION_UNIT) {
+ this.testClass = ast;
+ }
+ else {
+ if (containsAnnotation(ast, Arrays.asList(NESTED_ANNOTATION))) {
+ this.nestedTestClasses.add(ast);
+ }
+ }
+ }
+
@Override
public void finishTree(DetailAST rootAST) {
if (shouldCheck()) {
@@ -127,7 +172,7 @@ public void finishTree(DetailAST rootAST) {
}
private boolean shouldCheck() {
- if (this.testMethods.isEmpty() && this.lifecycleMethods.isEmpty()) {
+ if (this.testMethods.isEmpty() && this.lifecycleMethods.isEmpty() && this.nestedTestClasses.isEmpty()) {
return false;
}
for (String unlessImport : this.unlessImports) {
@@ -139,6 +184,10 @@ private boolean shouldCheck() {
}
private void check() {
+ if (this.testClass != null && !isAbstract(this.testClass)) {
+ checkVisibility(Arrays.asList(this.testClass), "junit5.publicClass", null);
+ }
+ checkVisibility(this.nestedTestClasses, "junit5.publicNestedClass", "junit5.privateNestedClass");
for (String bannedImport : BANNED_IMPORTS) {
FullIdent ident = this.imports.get(bannedImport);
if (ident != null) {
@@ -146,34 +195,56 @@ private void check() {
}
}
for (DetailAST testMethod : this.testMethods) {
- if (AnnotationUtil.containsAnnotation(testMethod, JUNIT4_TEST_ANNOTATION)) {
+ if (AnnotationUtil.containsAnnotation(testMethod, JUNIT4_TEST_ANNOTATION_NAME)) {
log(testMethod, "junit5.bannedTestAnnotation");
}
}
- checkMethodVisibility(this.testMethods, "junit5.testPublicMethod", "junit5.testPrivateMethod");
- checkMethodVisibility(this.lifecycleMethods, "junit5.lifecyclePublicMethod", "junit5.lifecyclePrivateMethod");
+ checkVisibility(this.testMethods, "junit5.testPublicMethod", "junit5.testPrivateMethod");
+ checkVisibility(this.lifecycleMethods, "junit5.lifecyclePublicMethod", "junit5.lifecyclePrivateMethod");
+ }
+
+ private boolean isAbstract(DetailAST ast) {
+ DetailAST modifiers = ast.findFirstToken(TokenTypes.MODIFIERS);
+ return modifiers.findFirstToken(TokenTypes.ABSTRACT) != null;
}
- private void checkMethodVisibility(List methods, String publicMessageKey, String privateMessageKey) {
- for (DetailAST method : methods) {
- DetailAST modifiers = method.findFirstToken(TokenTypes.MODIFIERS);
+ private void checkVisibility(List asts, String publicMessageKey, String privateMessageKey) {
+ for (DetailAST ast : asts) {
+ DetailAST modifiers = ast.findFirstToken(TokenTypes.MODIFIERS);
if (modifiers.findFirstToken(TokenTypes.LITERAL_PUBLIC) != null) {
- log(method, publicMessageKey);
+ log(ast, publicMessageKey);
}
- if (modifiers.findFirstToken(TokenTypes.LITERAL_PRIVATE) != null) {
- log(method, privateMessageKey);
+ if ((privateMessageKey != null) && (modifiers.findFirstToken(TokenTypes.LITERAL_PRIVATE) != null)) {
+ log(ast, privateMessageKey);
}
}
}
- private void log(DetailAST method, String key) {
- String name = method.findFirstToken(TokenTypes.IDENT).getText();
- log(method.getLineNo(), method.getColumnNo(), key, name);
+ private void log(DetailAST ast, String key) {
+ String name = ast.findFirstToken(TokenTypes.IDENT).getText();
+ log(ast.getLineNo(), ast.getColumnNo(), key, name);
}
public void setUnlessImports(String unlessImports) {
- this.unlessImports = Collections.unmodifiableList(
- Arrays.stream(unlessImports.split(",")).map(String::trim).collect(Collectors.toList()));
+ this.unlessImports = Collections
+ .unmodifiableList(Arrays.stream(unlessImports.split(",")).map(String::trim).collect(Collectors.toList()));
+ }
+
+ private static final class Annotation {
+
+ private final String packageName;
+
+ private final String simpleName;
+
+ private Annotation(String packageName, String simpleName) {
+ this.packageName = packageName;
+ this.simpleName = simpleName;
+ }
+
+ private String fullyQualifiedName() {
+ return this.packageName + "." + this.simpleName;
+ }
+
}
}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringJavadocCheck.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringJavadocCheck.java
index 8b2edc4b..56f7ea63 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringJavadocCheck.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringJavadocCheck.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -81,7 +81,7 @@ public class SpringJavadocCheck extends AbstractSpringCheck {
@Override
public int[] getDefaultTokens() {
return new int[] { TokenTypes.INTERFACE_DEF, TokenTypes.CLASS_DEF, TokenTypes.ENUM_DEF,
- TokenTypes.ANNOTATION_DEF, TokenTypes.METHOD_DEF, TokenTypes.CTOR_DEF };
+ TokenTypes.ANNOTATION_DEF, TokenTypes.METHOD_DEF, TokenTypes.CTOR_DEF, TokenTypes.ANNOTATION_FIELD_DEF };
}
@Override
@@ -130,6 +130,7 @@ private void checkJavadoc(DetailAST ast, TextBlock javadoc) {
checkTagCase(ast, javadoc);
checkSinceTag(ast, javadoc);
checkMethodJavaDoc(ast, javadoc);
+ checkAnnotationFieldJavaDoc(ast, javadoc);
}
private void checkBannedTags(DetailAST ast, TextBlock javadoc) {
@@ -164,24 +165,56 @@ private void checkSinceTag(DetailAST ast, TextBlock javadoc) {
if (!TOP_LEVEL_TYPES.contains(ast.getType())) {
return;
}
- String[] text = javadoc.getText();
- DetailAST interfaceDef = getInterfaceDef(ast);
- boolean privateType = !isPublicOrProtected(ast) && (interfaceDef == null || !isPublicOrProtected(interfaceDef));
- boolean innerType = ast.getParent() != null && ast.getParent().getType() != TokenTypes.COMPILATION_UNIT;
- boolean found = false;
- for (int i = 0; i < text.length; i++) {
- Matcher matcher = SINCE_TAG_PATTERN.matcher(text[i]);
- if (matcher.find()) {
- found = true;
- String description = matcher.group(1).trim();
- if (this.publicOnlySinceTags && privateType) {
- log(javadoc.getStartLineNo() + i, text[i].length() - description.length(), "javadoc.publicSince");
+ DetailAST interfaceOrAnnotationDef = getInterfaceOrAnnotationDef(ast);
+ boolean privateType = !isPublicOrProtected(ast)
+ && (interfaceOrAnnotationDef == null || !isPublicOrProtected(interfaceOrAnnotationDef));
+ SinceTag sinceTag = SinceTag.find(ast, javadoc);
+ if (sinceTag != null) {
+ if (this.publicOnlySinceTags && privateType) {
+ log(sinceTag.lineNumber, sinceTag.columnNumber, "javadoc.publicSince");
+ }
+ else {
+ checkContainingSince(ast, sinceTag);
+ }
+ }
+ else {
+ boolean innerType = ast.getParent() != null && ast.getParent().getType() != TokenTypes.COMPILATION_UNIT;
+ if (this.requireSinceTag && !innerType && sinceTag == null && !(this.publicOnlySinceTags && privateType)) {
+ log(javadoc.getStartLineNo(), 0, "javadoc.missingSince");
+ }
+ }
+ }
+
+ private void checkContainingSince(DetailAST ast, SinceTag currentTag) {
+ SinceTag containingSince = findContainingSince(ast);
+ if (containingSince != null) {
+ SinceVersion current = currentTag.version;
+ SinceVersion container = containingSince.version;
+ if (current != SinceVersion.UNKNOWN && container != SinceVersion.UNKNOWN) {
+ int comparison = current.compareTo(container);
+ if (comparison < 0) {
+ log(currentTag.lineNumber, currentTag.columnNumber, "javadoc.earlierSince", current, container, containingSince.lineNumber, containingSince.columnNumber);
+ }
+ else if (comparison == 0) {
+ log(currentTag.lineNumber, currentTag.columnNumber, "javadoc.sameSince", current, containingSince.lineNumber, containingSince.columnNumber);
}
}
}
- if (this.requireSinceTag && !innerType && !found && !(this.publicOnlySinceTags && privateType)) {
- log(javadoc.getStartLineNo(), 0, "javadoc.missingSince");
+ }
+
+ private SinceTag findContainingSince(DetailAST ast) {
+ DetailAST parent = ast.getParent();
+ while (parent != null && parent.getType() != TokenTypes.COMPILATION_UNIT) {
+ TextBlock javadoc = getFileContents().getJavadocBefore(parent.getLineNo());
+ if (javadoc != null) {
+ SinceTag sinceTag = SinceTag.find(ast, javadoc);
+ if (sinceTag != null) {
+ return sinceTag;
+ }
+ }
+ parent = parent.getParent();
}
+ return null;
}
private void checkMethodJavaDoc(DetailAST ast, TextBlock javadoc) {
@@ -195,6 +228,20 @@ private void checkMethodJavaDoc(DetailAST ast, TextBlock javadoc) {
log(javadoc.getStartLineNo() + i - 1, 0, "javadoc.emptyLineBeforeTag");
}
}
+ SinceTag sinceTag = SinceTag.find(ast, javadoc);
+ if (sinceTag != null) {
+ checkContainingSince(ast, sinceTag);
+ }
+ }
+
+ private void checkAnnotationFieldJavaDoc(DetailAST ast, TextBlock javadoc) {
+ if (TokenTypes.ANNOTATION_FIELD_DEF != ast.getType()) {
+ return;
+ }
+ SinceTag sinceTag = SinceTag.find(ast, javadoc);
+ if (sinceTag != null) {
+ checkContainingSince(ast, sinceTag);
+ }
}
private boolean startsWithUppercase(String description) {
@@ -225,14 +272,16 @@ public void setAllowNonJavadocComments(boolean allowNonJavadocComments) {
this.allowNonJavadocComments = allowNonJavadocComments;
}
- private DetailAST getInterfaceDef(DetailAST ast) {
- return findParent(ast, TokenTypes.INTERFACE_DEF);
+ private DetailAST getInterfaceOrAnnotationDef(DetailAST ast) {
+ return findParent(ast, TokenTypes.INTERFACE_DEF, TokenTypes.ANNOTATION_DEF);
}
- private DetailAST findParent(DetailAST ast, int classDef) {
+ private DetailAST findParent(DetailAST ast, int... classDefs) {
while (ast != null) {
- if (ast.getType() == classDef) {
- return ast;
+ for (int classDef : classDefs) {
+ if (ast.getType() == classDef) {
+ return ast;
+ }
}
ast = ast.getParent();
}
@@ -248,4 +297,86 @@ private boolean isPublicOrProtected(DetailAST ast) {
|| modifiers.findFirstToken(TokenTypes.LITERAL_PROTECTED) != null;
}
+ private static final class SinceTag {
+
+ private final int lineNumber;
+
+ private final int columnNumber;
+
+ private final SinceVersion version;
+
+ private SinceTag(int lineNumber, int columnNumber, SinceVersion version) {
+ this.lineNumber = lineNumber;
+ this.columnNumber = columnNumber;
+ this.version = version;
+ }
+
+ private static SinceTag find(DetailAST ast, TextBlock javadoc) {
+ String[] text = javadoc.getText();
+ for (int i = 0; i < text.length; i++) {
+ Matcher matcher = SINCE_TAG_PATTERN.matcher(text[i]);
+ if (matcher.find()) {
+ String description = matcher.group(1).trim();
+ return new SinceTag(javadoc.getStartLineNo() + i, text[i].length() - description.length(), SinceVersion.of(description));
+ }
+ }
+ return null;
+ }
+ }
+
+ private static final class SinceVersion implements Comparable {
+
+ private static final SinceVersion UNKNOWN = new SinceVersion(-1, -1, -1, "unknown");
+
+ private static final Pattern DATE_PATTERN = Pattern.compile("[0-3][0-9]\\.[0-1][0-9]\\.20[0-2][0-9]");
+
+ private final int major;
+
+ private final int minor;
+
+ private final int patch;
+
+ private final String text;
+
+ private SinceVersion(int major, int minor, int patch, String text) {
+ this.major = major;
+ this.minor = minor;
+ this.patch = patch;
+ this.text = text;
+ }
+
+ private static SinceVersion of(String text) {
+ if (DATE_PATTERN.matcher(text).matches()) {
+ return UNKNOWN;
+ }
+ try {
+ String[] components = text.split("\\.");
+ int major = (components.length > 0) ? Integer.parseInt(components[0]) : 0;
+ int minor = (components.length > 1) ? Integer.parseInt(components[1]) : 0;
+ int patch = (components.length > 2) ? Integer.parseInt(components[2]) : 0;
+ return new SinceVersion(major, minor, patch, text);
+ }
+ catch (NumberFormatException ex) {
+ return UNKNOWN;
+ }
+ }
+
+ public String toString() {
+ return this.text;
+ }
+
+ @Override
+ public int compareTo(SinceVersion other) {
+ int diff = this.major - other.major;
+ if (diff == 0) {
+ diff = this.minor - other.minor;
+ if (diff == 0) {
+ diff = this.patch - other.patch;
+ }
+ }
+ return diff;
+ }
+
+ }
+
}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringLambdaCheck.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringLambdaCheck.java
index 42822761..c0f45f07 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringLambdaCheck.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringLambdaCheck.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringLeadingWhitespaceCheck.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringLeadingWhitespaceCheck.java
index 188e6781..abeba9de 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringLeadingWhitespaceCheck.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringLeadingWhitespaceCheck.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -17,7 +17,9 @@
package io.spring.javaformat.checkstyle.check;
import java.io.File;
+import java.util.ArrayDeque;
import java.util.Collections;
+import java.util.Deque;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
@@ -26,6 +28,7 @@
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.FileContents;
import com.puppycrawl.tools.checkstyle.api.FileText;
+import com.puppycrawl.tools.checkstyle.api.TokenTypes;
import io.spring.javaformat.config.IndentationStyle;
import io.spring.javaformat.config.JavaFormatConfig;
@@ -49,14 +52,32 @@ public class SpringLeadingWhitespaceCheck extends AbstractSpringCheck {
private IndentationStyle indentationStyle;
+ private final Deque textBlockPairs = new ArrayDeque<>();
+
@Override
public int[] getAcceptableTokens() {
- return NO_REQUIRED_TOKENS;
+ return new int[] { TokenTypes.TEXT_BLOCK_LITERAL_BEGIN, TokenTypes.TEXT_BLOCK_LITERAL_END };
+ }
+
+ @Override
+ public void visitToken(DetailAST ast) {
+ super.visitToken(ast);
+ if (ast.getType() == TokenTypes.TEXT_BLOCK_LITERAL_BEGIN) {
+ this.textBlockPairs.add(new TextBlockPair(ast));
+ }
+ else if (ast.getType() == TokenTypes.TEXT_BLOCK_LITERAL_END) {
+ this.textBlockPairs.getLast().end(ast);
+ }
}
@Override
public void beginTree(DetailAST rootAST) {
super.beginTree(rootAST);
+ this.textBlockPairs.clear();
+ }
+
+ @Override
+ public void finishTree(DetailAST rootAST) {
FileContents fileContents = getFileContents();
FileText fileText = fileContents.getText();
File file = fileText.getFile();
@@ -66,8 +87,11 @@ public void beginTree(DetailAST rootAST) {
IndentationStyle indentationStyle = (this.indentationStyle != null) ? this.indentationStyle
: JavaFormatConfig.findFrom(file.getParentFile()).getIndentationStyle();
for (int i = 0; i < fileText.size(); i++) {
- String line = fileText.get(i);
int lineNo = i + 1;
+ if (isInTextBlock(lineNo)) {
+ continue;
+ }
+ String line = fileText.get(i);
Matcher matcher = PATTERN.matcher(line);
boolean found = matcher.find(0);
while (found
@@ -78,6 +102,11 @@ public void beginTree(DetailAST rootAST) {
log(lineNo, "leadingwhitespace.incorrect", indentationStyle.toString().toLowerCase());
}
}
+ super.finishTree(rootAST);
+ }
+
+ private boolean isInTextBlock(int lineNo) {
+ return this.textBlockPairs.stream().anyMatch((textBlockPair) -> textBlockPair.contains(lineNo));
}
public void setIndentationStyle(String indentationStyle) {
@@ -85,4 +114,24 @@ public void setIndentationStyle(String indentationStyle) {
? IndentationStyle.valueOf(indentationStyle.toUpperCase()) : null;
}
+ private static class TextBlockPair {
+
+ private final DetailAST begin;
+
+ private DetailAST end;
+
+ TextBlockPair(DetailAST begin) {
+ this.begin = begin;
+ }
+
+ public boolean contains(int lineNo) {
+ return (lineNo > this.begin.getLineNo()) && (lineNo <= this.end.getLineNo());
+ }
+
+ void end(DetailAST end) {
+ this.end = end;
+ }
+
+ }
+
}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringMethodOrderCheck.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringMethodOrderCheck.java
index c486888f..bbb088bc 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringMethodOrderCheck.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringMethodOrderCheck.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
@@ -33,7 +33,7 @@
public class SpringMethodOrderCheck extends AbstractSpringCheck {
private static final List EXPECTED_ORDER = Collections
- .unmodifiableList(Arrays.asList("equals", "hashCode", "toString"));
+ .unmodifiableList(Arrays.asList("equals", "hashCode", "toString"));
@Override
public int[] getAcceptableTokens() {
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringMethodVisibilityCheck.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringMethodVisibilityCheck.java
index ab431020..ca5bd3ef 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringMethodVisibilityCheck.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringMethodVisibilityCheck.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
@@ -20,10 +20,17 @@
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
/**
- * Checks that protected, package-private and private classes to not have public methods
- * unless they are also annotated with {@link Override @Override}.
+ * Check for compliance with Spring-style method visibility. Checks that:
+ *
+ *
+ *
package-private and private classes do not have public methods
+ * unless they are also annotated with {@link Override @Override}
+ *
final classes do not have protected methods unless that are also
+ * annotated with {@link Override @Override}
+ *
*
* @author Phillip Webb
+ * @author Andy Wilkinson
*/
public class SpringMethodVisibilityCheck extends AbstractSpringCheck {
@@ -38,6 +45,9 @@ public void visitToken(DetailAST ast) {
if (modifiers.findFirstToken(TokenTypes.LITERAL_PUBLIC) != null) {
visitPublicMethod(modifiers, ast);
}
+ else if (modifiers.findFirstToken(TokenTypes.LITERAL_PROTECTED) != null) {
+ visitProtectedMethod(modifiers, ast);
+ }
}
private void visitPublicMethod(DetailAST modifiers, DetailAST method) {
@@ -56,6 +66,18 @@ private void visitPublicMethod(DetailAST modifiers, DetailAST method) {
log(ident.getLineNo(), ident.getColumnNo(), "methodvisibility.publicMethod", ident.getText());
}
+ private void visitProtectedMethod(DetailAST modifiers, DetailAST method) {
+ if (hasOverrideAnnotation(modifiers)) {
+ return;
+ }
+ DetailAST classDef = getClassDef(method.getParent());
+ if (classDef == null || !isFinal(classDef)) {
+ return;
+ }
+ DetailAST ident = method.findFirstToken(TokenTypes.IDENT);
+ log(ident.getLineNo(), ident.getColumnNo(), "methodvisibility.protectedMethodInFinalClass", ident.getText());
+ }
+
private boolean hasOverrideAnnotation(DetailAST modifiers) {
DetailAST candidate = modifiers.getFirstChild();
while (candidate != null) {
@@ -98,4 +120,12 @@ private boolean isPublicOrProtected(DetailAST ast) {
|| modifiers.findFirstToken(TokenTypes.LITERAL_PROTECTED) != null;
}
+ private boolean isFinal(DetailAST ast) {
+ DetailAST modifiers = ast.findFirstToken(TokenTypes.MODIFIERS);
+ if (modifiers == null) {
+ return false;
+ }
+ return modifiers.findFirstToken(TokenTypes.FINAL) != null;
+ }
+
}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringNoThisCheck.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringNoThisCheck.java
index ffeda211..1a4ee466 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringNoThisCheck.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringNoThisCheck.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringNoWhitespaceBeforeCheck.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringNoWhitespaceBeforeCheck.java
new file mode 100644
index 00000000..f06a88c5
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringNoWhitespaceBeforeCheck.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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 io.spring.javaformat.checkstyle.check;
+
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.api.TokenTypes;
+import com.puppycrawl.tools.checkstyle.checks.whitespace.NoWhitespaceBeforeCheck;
+
+/**
+ * Spring-specific customization of {@link NoWhitespaceBeforeCheck} that permits
+ * whitespace before {@code ...} when it is a separator after an annotation, for
+ * example {@code int @Nullable ...}.
+ *
+ * @author Andy Wilkinson
+ */
+public class SpringNoWhitespaceBeforeCheck extends NoWhitespaceBeforeCheck {
+
+ @Override
+ public void visitToken(DetailAST ast) {
+ if (ast.getType() != TokenTypes.ELLIPSIS) {
+ super.visitToken(ast);
+ }
+ else {
+ visitEllipsis(ast);
+ }
+ }
+
+ private void visitEllipsis(DetailAST ellipsis) {
+ DetailAST previousSibling = ellipsis.getPreviousSibling();
+ if (previousSibling.getType() == TokenTypes.TYPE &&
+ previousSibling.getChildCount() == 2 &&
+ previousSibling.getLastChild().getType() == TokenTypes.ANNOTATIONS) {
+ return;
+ }
+ super.visitToken(ellipsis);
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringNullabilityCheck.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringNullabilityCheck.java
new file mode 100644
index 00000000..4c48c381
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringNullabilityCheck.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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 io.spring.javaformat.checkstyle.check;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.api.FullIdent;
+import com.puppycrawl.tools.checkstyle.api.TokenTypes;
+
+/**
+ * Checks compliance with Spring team's nullability conventions. JSpecify annotations
+ * should be used to express nullability and type-use annotations ({@code @Nullable}
+ * and {@code @NonNull}) should appear immediately before a type.
+ *
+ * @author Andy Wilkinson
+ */
+public class SpringNullabilityCheck extends AbstractSpringCheck {
+
+ private final Set unwantedNullabilityImports = new HashSet<>();
+
+ private final List modifiers = new ArrayList<>();
+
+ @Override
+ public int[] getAcceptableTokens() {
+ return new int[] { TokenTypes.IMPORT, TokenTypes.MODIFIERS };
+ }
+
+ @Override
+ public void beginTree(DetailAST rootAST) {
+ this.modifiers.clear();
+ this.unwantedNullabilityImports.clear();
+ }
+
+ @Override
+ public void finishTree(DetailAST rootAST) {
+ this.modifiers.forEach(this::visitModifiers);
+ }
+
+ @Override
+ public void visitToken(DetailAST ast) {
+ switch (ast.getType()) {
+ case TokenTypes.IMPORT:
+ visitImport(ast);
+ break;
+ case TokenTypes.MODIFIERS:
+ this.modifiers.add(ast);
+ break;
+ }
+ }
+
+ private void visitImport(DetailAST ast) {
+ FullIdent ident = FullIdent.createFullIdentBelow(ast);
+ if (!isFullyQualifiedJSpecifyAnnotation(ident)) {
+ String simpleName = simpleNameOf(ident);
+ for (JSpecifyAnnotation annotation: JSpecifyAnnotation.values()) {
+ if (annotation.replaces.contains(simpleName)) {
+ log(ident.getLineNo(), ident.getColumnNo(), "nullability.bannedImport", ident.getText(), annotation.name);
+ this.unwantedNullabilityImports.add(simpleName);
+ }
+ }
+ }
+ }
+
+ private boolean isFullyQualifiedJSpecifyAnnotation(FullIdent ident) {
+ for (JSpecifyAnnotation annotation: JSpecifyAnnotation.values()) {
+ if (ident.getText().equals(annotation.name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private String simpleNameOf(FullIdent ident) {
+ String identText = ident.getText();
+ return identText.substring(identText.lastIndexOf(".") + 1);
+ }
+
+ private void visitModifiers(DetailAST ast) {
+ DetailAST annotation = ast.findFirstToken(TokenTypes.ANNOTATION);
+ if (annotation != null) {
+ DetailAST ident = annotation.findFirstToken(TokenTypes.IDENT);
+ if (ident != null) {
+ String identText = ident.getText();
+ DetailAST lastChild = ast.getLastChild();
+ if (isJSpecifyAnnotation(ident) && !annotation.equals(lastChild)) {
+ log(annotation.getLineNo(), annotation.getColumnNo(), "nullability.annotationLocation", identText);
+ }
+ }
+ }
+ }
+
+ private boolean isJSpecifyAnnotation(DetailAST ident) {
+ for (JSpecifyAnnotation annotation: JSpecifyAnnotation.values()) {
+ if (ident.getText().equals(annotation.simpleName) && !this.unwantedNullabilityImports.contains(ident.getText())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private enum JSpecifyAnnotation {
+
+ NULLABLE("Nullable", "Nullable"),
+
+ NON_NULL("NonNull", "NonNull", "Nonnull");
+
+ private final String simpleName;
+
+ private final String name;
+
+ private Set replaces;
+
+ JSpecifyAnnotation(String simpleName, String... replaces) {
+ this.simpleName = simpleName;
+ this.name = "org.jspecify.annotations." + simpleName;
+ this.replaces = new HashSet<>(Arrays.asList(replaces));
+ }
+
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringParenPadCheck.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringParenPadCheck.java
new file mode 100644
index 00000000..a49789b0
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringParenPadCheck.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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 io.spring.javaformat.checkstyle.check;
+
+import java.util.Locale;
+
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.checks.whitespace.PadOption;
+import com.puppycrawl.tools.checkstyle.checks.whitespace.ParenPadCheck;
+import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
+
+/**
+ * {@link ParenPadCheck} variant that allows whitespace after {@code (} if before
+ * {@code //}.
+ *
+ * @author Phillip Webb
+ */
+public class SpringParenPadCheck extends ParenPadCheck {
+
+ private static final char OPEN_PARENTHESIS = '(';
+
+ private static final char CLOSE_PARENTHESIS = ')';
+
+ private PadOption option = PadOption.NOSPACE;
+
+ @Override
+ public void setOption(String optionStr) {
+ this.option = PadOption.valueOf(optionStr.trim().toUpperCase(Locale.ENGLISH));
+ }
+
+ @Override
+ protected void processLeft(DetailAST ast) {
+ String line = getLines()[ast.getLineNo() - 1];
+ int[] codePoints = line.codePoints().toArray();
+ int after = ast.getColumnNo() + 1;
+ if (after < codePoints.length) {
+ boolean hasWhitespaceAfter = isConsideredWhitespace(codePoints, after);
+ if (this.option == PadOption.NOSPACE && hasWhitespaceAfter) {
+ log(ast, MSG_WS_FOLLOWED, OPEN_PARENTHESIS);
+ }
+ else if (this.option == PadOption.SPACE && !hasWhitespaceAfter && line.charAt(after) != CLOSE_PARENTHESIS) {
+ log(ast, MSG_WS_NOT_FOLLOWED, OPEN_PARENTHESIS);
+ }
+ }
+ }
+
+ private boolean isConsideredWhitespace(int[] codePoints, int after) {
+ if (CommonUtil.isCodePointWhitespace(codePoints, after)) {
+ return !isSlashSlash(codePoints, after + 1);
+ }
+ return false;
+ }
+
+ private boolean isSlashSlash(int[] codePoints, int index) {
+ if (index + 1 < codePoints.length) {
+ char c1 = Character.toChars(codePoints[index])[0];
+ char c2 = Character.toChars(codePoints[index + 1])[0];
+ return c1 == '/' && c2 == '/';
+ }
+ return false;
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringTernaryCheck.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringTernaryCheck.java
index 0bf7a2e9..caf82d1e 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringTernaryCheck.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringTernaryCheck.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
@@ -61,9 +61,9 @@ private void visitQuestion(DetailAST ast) {
private boolean requiresParens(DetailAST expression) {
if (expression != null && expression.getChildCount() > 1) {
switch (expression.getType()) {
- case TokenTypes.METHOD_CALL:
- case TokenTypes.DOT:
- return false;
+ case TokenTypes.METHOD_CALL:
+ case TokenTypes.DOT:
+ return false;
}
return true;
}
@@ -86,13 +86,13 @@ private boolean isSimpleEqualsExpression(DetailAST expression) {
private boolean isEqualsTestAllowed(DetailAST ast) {
switch (this.equalsTest) {
- case ANY:
- return true;
- case NEVER:
- return false;
- case NEVER_FOR_NULLS:
- DetailAST equal = ast.findFirstToken(TokenTypes.EQUAL);
- return equal.findFirstToken(TokenTypes.LITERAL_NULL) == null;
+ case ANY:
+ return true;
+ case NEVER:
+ return false;
+ case NEVER_FOR_NULLS:
+ DetailAST equal = ast.findFirstToken(TokenTypes.EQUAL);
+ return equal.findFirstToken(TokenTypes.LITERAL_NULL) == null;
}
throw new IllegalStateException("Unsupported equals test " + this.equalsTest);
}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringTestFileNameCheck.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringTestFileNameCheck.java
new file mode 100644
index 00000000..31dda6a0
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringTestFileNameCheck.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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 io.spring.javaformat.checkstyle.check;
+
+import java.io.File;
+
+import com.puppycrawl.tools.checkstyle.JavaParser;
+import com.puppycrawl.tools.checkstyle.JavaParser.Options;
+import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck;
+import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.api.FileText;
+import com.puppycrawl.tools.checkstyle.api.TokenTypes;
+
+/**
+ * Checks that test class filenames end {@literal Tests.java} and not
+ * {@literal Test.java}.
+ *
+ * @author Phillip Webb
+ * @author Andy Wilkinson
+ */
+public class SpringTestFileNameCheck extends AbstractFileSetCheck {
+
+ @Override
+ protected void processFiltered(File file, FileText fileText) throws CheckstyleException {
+ String path = file.getPath().replace('\\', '/');
+ if (path.contains("src/test/java") && file.getName().endsWith("Test.java")) {
+ visitCompilationUnit(JavaParser.parseFileText(fileText, Options.WITHOUT_COMMENTS));
+ }
+ }
+
+ private void visitCompilationUnit(DetailAST ast) {
+ DetailAST child = ast.getFirstChild();
+ while (child != null) {
+ if (child.getType() == TokenTypes.CLASS_DEF) {
+ log(1, "testfilename.wrongName");
+ return;
+ }
+ child = child.getNextSibling();
+ }
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/filter/CheckFilter.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/filter/CheckFilter.java
index 5e83fccf..5388e5bd 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/filter/CheckFilter.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/filter/CheckFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/filter/IdentCheckFilter.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/filter/IdentCheckFilter.java
index d8950d5e..6e434bcc 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/filter/IdentCheckFilter.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/filter/IdentCheckFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/filter/RequiresOuterThisFilter.java b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/filter/RequiresOuterThisFilter.java
index e12e8b4f..080bf8ec 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/filter/RequiresOuterThisFilter.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/filter/RequiresOuterThisFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/resources/io/spring/javaformat/checkstyle/check/messages.properties b/spring-javaformat/spring-javaformat-checkstyle/src/main/resources/io/spring/javaformat/checkstyle/check/messages.properties
index b32ec8a7..eaaec1f1 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/resources/io/spring/javaformat/checkstyle/check/messages.properties
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/resources/io/spring/javaformat/checkstyle/check/messages.properties
@@ -1,3 +1,6 @@
+annotation.attribute.overlyVerboseValue=Value of ''{0}'' attribute is overly verbose. Import ''{1}'' and use ''{2}'' instead.
+annotation.location=Annotation ''{0}'' have incorrect indentation level {1}, expected level should be {2}.
+annotation.location.alone=Annotation ''{0}'' should be alone on line.
catch.singleLetter=Single letter catch variable (use "ex" instead).
catch.wideEye=''o_O'' catch variable (use "ex" instead).
header.unexpected=Unexpected header.
@@ -8,7 +11,9 @@ import.avoidStatic=Using a static member import should be avoided - {0}.
import.ordering=Wrong order for ''{0}'' import.
javadoc.badCase=Javadoc element descriptions should not start with an uppercase letter.
javadoc.bannedTag=Javadoc tag ''{0}'' should not be used.
+javadoc.earlierSince=Javadoc @since version ''{0}'' is earlier than @since version ''{1}'' at {2}:{3}.
javadoc.missingSince=Missing Javadoc @since tag.
+javadoc.sameSince=Javadoc @since version ''{0}'' is unnecessary as it is the same as the @since version at {1}:{2}.
javadoc.publicSince=Javadoc @since tag should not be used on private classes.
javadoc.emptyLineBeforeTag=Method Javadoc should not have empty line before tag.
javadoc.nonJavadocComment=Comments should not include \"(non-Javadoc)\".
@@ -16,6 +21,9 @@ junit5.bannedImport=Import ''{0}'' should not be used in a JUnit 5 test.
junit5.bannedTestAnnotation=JUnit 4 @Test annotation should not be used in a JUnit 5 test.
junit5.lifecyclePrivateMethod=Lifecycle method ''{0}'' should not be private.
junit5.lifecyclePublicMethod=Lifecycle method ''{0}'' should not be public.
+junit5.publicClass=Test class ''{0}'' should not be public.
+junit5.publicNestedClass=Nested test class ''{0}'' should not be public.
+junit5.privateNestedClass=Nested test class ''{0}'' should not be private.
junit5.testPrivateMethod=Test method ''{0}'' should not be private.
junit5.testPublicMethod=Test method ''{0}'' should not be public.
lambda.missingParen=Lambda argument missing parentheses.
@@ -23,7 +31,19 @@ lambda.unnecessaryBlock=Lambda block is unnecessary.
lambda.unnecessaryParen=Lambda argument has unnecessary parentheses.
methodorder.outOfOrder=Method ''{0}'' is out of order, expected {1}.
methodvisibility.publicMethod=Method ''{0}'' in private class should not be public.
+methodvisibility.protectedMethodInFinalClass=Method ''{0}'' in final class should be package-private rather than protected.
nothis.unexpected=Reference to instance variable ''{0}'' should not use \"this.\".
+nullability.bannedImport=Nullability should be expressed using JSpecify. Replace ''{0}'' with ''{1}''.
+nullability.annotationLocation=''{0}'' should only be used immediately before a type.
ternary.equalOperator=Ternary operation should use != when testing.
-ternary.missingParen=Ternary operation missing parentheses. Use the form \"(a != b) ? y : n\"
+ternary.missingParen=Ternary operation missing parentheses. Use the form \"(a != b) ? y : n\".
+testfilename.wrongName=Test classes should have a name ending with 'Tests.java'.
leadingwhitespace.incorrect=Indentation should be performed with {0} only.
+deprecated.missingSince=@Deprecated has no since attribute.
+deprecated.emptySince=@Deprecated has an empty since attribute.
+ws.followed=''{0}'' is followed by whitespace.
+ws.illegalFollow=''{0}'' is followed by an illegal character.
+ws.notFollowed=''{0}'' is not followed by whitespace.
+ws.notPreceded=''{0}'' is not preceded with whitespace.
+ws.preceded=''{0}'' is preceded with whitespace.
+ws.typeCast=''typecast'' is not followed by whitespace.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/resources/io/spring/javaformat/checkstyle/spring-checkstyle.xml b/spring-javaformat/spring-javaformat-checkstyle/src/main/resources/io/spring/javaformat/checkstyle/spring-checkstyle.xml
index 894b78bb..829e6959 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/main/resources/io/spring/javaformat/checkstyle/spring-checkstyle.xml
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/resources/io/spring/javaformat/checkstyle/spring-checkstyle.xml
@@ -11,6 +11,7 @@
+
@@ -21,11 +22,10 @@
+
-
-
-
+
+
@@ -69,6 +69,7 @@
+
@@ -87,7 +88,7 @@
-
+
@@ -127,7 +128,7 @@
-
+
@@ -144,8 +145,7 @@
-
-
+
@@ -161,5 +161,7 @@
+
+
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/java/io/spring/javaformat/checkstyle/AssertionsAuditListener.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/java/io/spring/javaformat/checkstyle/AssertionsAuditListener.java
index 6b6daeb6..6b36f545 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/java/io/spring/javaformat/checkstyle/AssertionsAuditListener.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/java/io/spring/javaformat/checkstyle/AssertionsAuditListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -111,7 +111,7 @@ private void recordLevel(AuditEvent event) {
private void recordLocalizedMessage(String message, String... args) {
recordMessage(new Violation(0, Definitions.CHECKSTYLE_BUNDLE, message, args, null, Violation.class, null)
- .getViolation());
+ .getViolation());
}
private void recordMessage(String message) {
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/java/io/spring/javaformat/checkstyle/SpringChecksTestParameter.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/java/io/spring/javaformat/checkstyle/SpringChecksTestParameter.java
index 2cad6835..62e4a959 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/java/io/spring/javaformat/checkstyle/SpringChecksTestParameter.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/java/io/spring/javaformat/checkstyle/SpringChecksTestParameter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/java/io/spring/javaformat/checkstyle/SpringChecksTests.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/java/io/spring/javaformat/checkstyle/SpringChecksTests.java
index 311d7f50..0be6bdb9 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/java/io/spring/javaformat/checkstyle/SpringChecksTests.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/java/io/spring/javaformat/checkstyle/SpringChecksTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2022 the original author or authors.
+ * Copyright 2017-present 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.
@@ -21,6 +21,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -41,6 +42,7 @@
import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
import com.puppycrawl.tools.checkstyle.api.Configuration;
import com.puppycrawl.tools.checkstyle.api.RootModule;
+import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.xml.sax.InputSource;
@@ -62,6 +64,9 @@ public class SpringChecksTests {
private static final File DEFAULT_CONFIG = new File(CONFIGS_DIR, "default-checkstyle-configuration.xml");
+ @TempDir
+ public Path temp;
+
@ParameterizedTest
@MethodSource("paramaters")
public void processHasExpectedResults(Parameter parameter) throws Exception {
@@ -113,9 +118,15 @@ private void printDebugInfo(File file) throws CheckstyleException {
}
public static Collection paramaters() throws IOException {
- ArrayList parameters = Arrays.stream(SOURCES_DIR.listFiles(SpringChecksTests::sourceFile)).sorted()
- .map(Parameter::new).collect(Collectors.toCollection(ArrayList::new));
+ ArrayList parameters = Arrays.stream(SOURCES_DIR.listFiles(SpringChecksTests::sourceFile))
+ .sorted()
+ .map(Parameter::new)
+ .collect(Collectors.toCollection(ArrayList::new));
parameters.add(new Parameter(new File(SOURCES_DIR, "nopackageinfo/NoPackageInfo.java")));
+ Arrays.stream(new File(SOURCES_DIR, "src/test/java").listFiles(SpringChecksTests::sourceFile))
+ .sorted()
+ .map(Parameter::new)
+ .forEach(parameters::add);
return parameters;
}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/java/io/spring/javaformat/checkstyle/SpringConfigurationLoaderTests.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/java/io/spring/javaformat/checkstyle/SpringConfigurationLoaderTests.java
index bb42d4f0..2c81cdd4 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/java/io/spring/javaformat/checkstyle/SpringConfigurationLoaderTests.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/java/io/spring/javaformat/checkstyle/SpringConfigurationLoaderTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2022 the original author or authors.
+ * Copyright 2017-present 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.
@@ -16,8 +16,10 @@
package io.spring.javaformat.checkstyle;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
@@ -45,28 +47,33 @@ public class SpringConfigurationLoaderTests {
@Test
public void loadShouldLoadChecks() {
Collection checks = load(null);
- assertThat(checks).hasSize(4);
- TreeWalker treeWalker = (TreeWalker) checks.toArray()[3];
+ assertThat(checks).hasSize(5);
+ TreeWalker treeWalker = (TreeWalker) checks.toArray()[4];
Set> ordinaryChecks = (Set>) Extractors.byName("ordinaryChecks").extract(treeWalker);
- assertThat(ordinaryChecks).hasSize(60);
+ assertThat(ordinaryChecks).hasSize(63);
+ Set> commentChecks = (Set>) Extractors.byName("commentChecks").extract(treeWalker);
+ assertThat(commentChecks).hasSize(6);
}
@Test
public void loadWithExcludeShouldExcludeChecks() {
- Set excludes = Collections
- .singleton("com.puppycrawl.tools.checkstyle.checks.whitespace.MethodParamPadCheck");
+ Set excludes = new HashSet(
+ Arrays.asList("com.puppycrawl.tools.checkstyle.checks.whitespace.MethodParamPadCheck",
+ "com.puppycrawl.tools.checkstyle.checks.annotation.MissingDeprecatedCheck"));
Collection checks = load(excludes);
- assertThat(checks).hasSize(4);
- TreeWalker treeWalker = (TreeWalker) checks.toArray()[3];
+ assertThat(checks).hasSize(5);
+ TreeWalker treeWalker = (TreeWalker) checks.toArray()[4];
Set> ordinaryChecks = (Set>) Extractors.byName("ordinaryChecks").extract(treeWalker);
- assertThat(ordinaryChecks).hasSize(59);
+ assertThat(ordinaryChecks).hasSize(62);
+ Set> commentChecks = (Set>) Extractors.byName("commentChecks").extract(treeWalker);
+ assertThat(commentChecks).hasSize(5);
}
@Test
public void loadWithExcludeHeaderShouldExcludeChecks() {
Set excludes = Collections.singleton("io.spring.javaformat.checkstyle.check.SpringHeaderCheck");
Object[] checks = load(excludes).stream().toArray();
- assertThat(checks).hasSize(3);
+ assertThat(checks).hasSize(4);
}
private Collection load(Set excludes) {
@@ -75,7 +82,7 @@ private Collection load(Set excludes) {
new PackageObjectFactory(getClass().getPackage().getName(), getClass().getClassLoader()), excludes);
context.add("moduleFactory", filteredModuleFactory);
Collection checks = new SpringConfigurationLoader(context, filteredModuleFactory)
- .load(getPropertyResolver());
+ .load(getPropertyResolver());
return checks;
}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationAttributeWithValueThatHasConciseReferenceToContainedEnumValue.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationAttributeWithValueThatHasConciseReferenceToContainedEnumValue.txt
new file mode 100644
index 00000000..23435c7a
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationAttributeWithValueThatHasConciseReferenceToContainedEnumValue.txt
@@ -0,0 +1 @@
++0 errors
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationAttributeWithValueThatHasReferenceToContainedConstant.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationAttributeWithValueThatHasReferenceToContainedConstant.txt
new file mode 100644
index 00000000..23435c7a
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationAttributeWithValueThatHasReferenceToContainedConstant.txt
@@ -0,0 +1 @@
++0 errors
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationAttributeWithValueThatHasVerboseReferenceToContainedEnumValue.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationAttributeWithValueThatHasVerboseReferenceToContainedEnumValue.txt
new file mode 100644
index 00000000..17a91c25
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationAttributeWithValueThatHasVerboseReferenceToContainedEnumValue.txt
@@ -0,0 +1,2 @@
++AnnotationAttributeWithValueThatHasVerboseReferenceToContainedEnumValue.java:17:84: Value of 'value' attribute is overly verbose. Import 'ConditionalOnWebApplicationType.WebApplicationType' and use 'WebApplicationType.SERVLET' instead. [SpringAnnotationAttributeConciseValue]
++1 error
\ No newline at end of file
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationNamedAttributeWithValueThatHasConciseReferenceToContainedEnumValue.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationNamedAttributeWithValueThatHasConciseReferenceToContainedEnumValue.txt
new file mode 100644
index 00000000..23435c7a
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationNamedAttributeWithValueThatHasConciseReferenceToContainedEnumValue.txt
@@ -0,0 +1 @@
++0 errors
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationNamedAttributeWithValueThatHasNecessarilyVerboseReferenceToContainedEnumValue.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationNamedAttributeWithValueThatHasNecessarilyVerboseReferenceToContainedEnumValue.txt
new file mode 100644
index 00000000..23435c7a
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationNamedAttributeWithValueThatHasNecessarilyVerboseReferenceToContainedEnumValue.txt
@@ -0,0 +1 @@
++0 errors
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationNamedAttributeWithValueThatHasReferenceToContainedConstant.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationNamedAttributeWithValueThatHasReferenceToContainedConstant.txt
new file mode 100644
index 00000000..23435c7a
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationNamedAttributeWithValueThatHasReferenceToContainedConstant.txt
@@ -0,0 +1 @@
++0 errors
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationNamedAttributeWithValueThatHasVerboseReferenceToContainedEnumValue.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationNamedAttributeWithValueThatHasVerboseReferenceToContainedEnumValue.txt
new file mode 100644
index 00000000..2c02256f
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationNamedAttributeWithValueThatHasVerboseReferenceToContainedEnumValue.txt
@@ -0,0 +1,2 @@
++AnnotationNamedAttributeWithValueThatHasVerboseReferenceToContainedEnumValue.java:17:91: Value of 'type' attribute is overly verbose. Import 'ConditionalOnWebApplicationType.WebApplicationType' and use 'WebApplicationType.SERVLET' instead. [SpringAnnotationAttributeConciseValue]
++1 error
\ No newline at end of file
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationOnNewLine.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationOnNewLine.txt
new file mode 100644
index 00000000..69174e4c
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationOnNewLine.txt
@@ -0,0 +1 @@
++0 errors
\ No newline at end of file
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationWithFullyQualifiedNameAndNamedAttributeWithValueThatHasConciseReferenceToContainedEnumValue.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationWithFullyQualifiedNameAndNamedAttributeWithValueThatHasConciseReferenceToContainedEnumValue.txt
new file mode 100644
index 00000000..23435c7a
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AnnotationWithFullyQualifiedNameAndNamedAttributeWithValueThatHasConciseReferenceToContainedEnumValue.txt
@@ -0,0 +1 @@
++0 errors
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AsciidoctorCallout.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AsciidoctorCallout.txt
new file mode 100644
index 00000000..23435c7a
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AsciidoctorCallout.txt
@@ -0,0 +1 @@
++0 errors
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AssertJBadAssertImport.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AssertJBadAssertImport.txt
new file mode 100644
index 00000000..05108d50
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AssertJBadAssertImport.txt
@@ -0,0 +1,2 @@
++Please use AssertJ imports.
++3 errors
\ No newline at end of file
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AssertJBadAssertionsImport.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AssertJBadAssertionsImport.txt
new file mode 100644
index 00000000..05108d50
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/AssertJBadAssertionsImport.txt
@@ -0,0 +1,2 @@
++Please use AssertJ imports.
++3 errors
\ No newline at end of file
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/DeprecatedBadCase.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/DeprecatedBadCase.txt
new file mode 100644
index 00000000..96f86d18
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/DeprecatedBadCase.txt
@@ -0,0 +1,6 @@
++DeprecatedBadCase.java:22:1: @Deprecated has no since attribute. [SpringDeprecated]
++DeprecatedBadCase.java:25:9: @Deprecated has no since attribute. [SpringDeprecated]
++DeprecatedBadCase.java:28:9: @Deprecated has an empty since attribute. [SpringDeprecated]
++DeprecatedBadCase.java:33:9: @Deprecated has no since attribute. [SpringDeprecated]
++DeprecatedBadCase.java:36:17: @Deprecated has an empty since attribute. [SpringDeprecated]
++5 errors
\ No newline at end of file
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/DeprecatedValid.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/DeprecatedValid.txt
new file mode 100644
index 00000000..69174e4c
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/DeprecatedValid.txt
@@ -0,0 +1 @@
++0 errors
\ No newline at end of file
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderWithDateToPresent.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderWithDateToPresent.txt
new file mode 100644
index 00000000..23435c7a
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderWithDateToPresent.txt
@@ -0,0 +1 @@
++0 errors
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JUnit5BadModifier.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JUnit5BadModifier.txt
index 376aa13c..7ec1d4de 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JUnit5BadModifier.txt
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JUnit5BadModifier.txt
@@ -1,7 +1,11 @@
++Test class 'JUnit5BadModifier' should not be public
++Nested test class 'PublicNestedTests' should not be public
++Nested test class 'PrivateNestedTests' should not be private
+Test method 'doSomethingWorks' should not be public
+Test method 'doSomethingElseWorks' should not be private
+Test method 'doSomethingWithTemplateWorks' should not be public
+Test method 'doSomethingElseWithTemplateWorks' should not be private
++Test method 'nestedPublicTest' should not be public
+Lifecycle method 'publicBeforeAll' should not be public
+Lifecycle method 'publicBeforeEach' should not be public
+Lifecycle method 'publicAfterAll' should not be public
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JUnit5PublicAbstractIsValid.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JUnit5PublicAbstractIsValid.txt
new file mode 100644
index 00000000..69174e4c
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JUnit5PublicAbstractIsValid.txt
@@ -0,0 +1 @@
++0 errors
\ No newline at end of file
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocAnnotationFieldHasEarlierSince.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocAnnotationFieldHasEarlierSince.txt
new file mode 100644
index 00000000..e5c19bf9
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocAnnotationFieldHasEarlierSince.txt
@@ -0,0 +1,2 @@
++28:19: Javadoc @since version '1.1.0' is earlier than @since version '1.2.0' at 21:10.
++1 error
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocInnerClassHasEarlierSince.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocInnerClassHasEarlierSince.txt
new file mode 100644
index 00000000..73737acb
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocInnerClassHasEarlierSince.txt
@@ -0,0 +1,2 @@
++28:19: Javadoc @since version '1.2.3' is earlier than @since version '2.0.0' at 21:10.
++1 error
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocMethodHasEarlierSince.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocMethodHasEarlierSince.txt
new file mode 100644
index 00000000..7d3a7148
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocMethodHasEarlierSince.txt
@@ -0,0 +1,2 @@
++27:19: Javadoc @since version '1.2.3' is earlier than @since version '2.0.0' at 21:10.
++1 error
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocNonPublicSinceInsideAnnotation.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocNonPublicSinceInsideAnnotation.txt
new file mode 100644
index 00000000..69174e4c
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocNonPublicSinceInsideAnnotation.txt
@@ -0,0 +1 @@
++0 errors
\ No newline at end of file
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/LeadingWhitespaceTabsAndTextBlock.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/LeadingWhitespaceTabsAndTextBlock.txt
new file mode 100644
index 00000000..23435c7a
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/LeadingWhitespaceTabsAndTextBlock.txt
@@ -0,0 +1 @@
++0 errors
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/MethodVisibilityFinalClassWithOverride.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/MethodVisibilityFinalClassWithOverride.txt
new file mode 100644
index 00000000..23435c7a
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/MethodVisibilityFinalClassWithOverride.txt
@@ -0,0 +1 @@
++0 errors
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/MethodVisibilityFinalClassWithProtectedMethod.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/MethodVisibilityFinalClassWithProtectedMethod.txt
new file mode 100644
index 00000000..20293abd
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/MethodVisibilityFinalClassWithProtectedMethod.txt
@@ -0,0 +1,2 @@
++Method 'bad' in final class should be package-private rather than protected.
++Method 'badStatic' in final class should be package-private rather than protected.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/MethodVisibilityProtectedWithPublicMethod.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/MethodVisibilityProtectedWithPublicMethod.txt
new file mode 100644
index 00000000..23435c7a
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/MethodVisibilityProtectedWithPublicMethod.txt
@@ -0,0 +1 @@
++0 errors
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NullabilityBannedNonNull.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NullabilityBannedNonNull.txt
new file mode 100644
index 00000000..2565624c
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NullabilityBannedNonNull.txt
@@ -0,0 +1,3 @@
++NullabilityBannedNonNull.java:17:8: Nullability should be expressed using JSpecify. Replace 'javax.annotation.Nonnull' with 'org.jspecify.annotations.NonNull'. [SpringNullability]
++NullabilityBannedNonNull.java:19:8: Nullability should be expressed using JSpecify. Replace 'org.checkerframework.checker.nullness.qual.NonNull' with 'org.jspecify.annotations.NonNull'. [SpringNullability]
++2 errors
\ No newline at end of file
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NullabilityBannedNullable.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NullabilityBannedNullable.txt
new file mode 100644
index 00000000..f3829412
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NullabilityBannedNullable.txt
@@ -0,0 +1 @@
++Nullability should be expressed using JSpecify. Replace 'javax.annotation.Nullable' with 'org.jspecify.annotations.Nullable'. [SpringNullability]
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NullabilityNullableNotPrecedingFieldType.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NullabilityNullableNotPrecedingFieldType.txt
new file mode 100644
index 00000000..de4383d2
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NullabilityNullableNotPrecedingFieldType.txt
@@ -0,0 +1 @@
++NullabilityNullableNotPrecedingFieldType.java:26:17: 'Nullable' should only be used immediately before a type. [SpringNullability]
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NullabilityNullableNotPrecedingParameterType.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NullabilityNullableNotPrecedingParameterType.txt
new file mode 100644
index 00000000..7b47421a
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NullabilityNullableNotPrecedingParameterType.txt
@@ -0,0 +1 @@
+NullabilityNullableNotPrecedingParameterType.java:26:30: 'Nullable' should only be used immediately before a type. [SpringNullability]
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NullabilityNullableNotPrecedingReturnType.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NullabilityNullableNotPrecedingReturnType.txt
new file mode 100644
index 00000000..fe62aa47
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NullabilityNullableNotPrecedingReturnType.txt
@@ -0,0 +1 @@
++NullabilityNullableNotPrecedingReturnType.java:26:9: 'Nullable' should only be used immediately before a type. [SpringNullability]
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NullabilityNullableOnSeparateLine.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NullabilityNullableOnSeparateLine.txt
new file mode 100644
index 00000000..e69de29b
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NullabilityValid.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NullabilityValid.txt
new file mode 100644
index 00000000..23435c7a
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NullabilityValid.txt
@@ -0,0 +1 @@
++0 errors
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/WhitespaceNullableArray.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/WhitespaceNullableArray.txt
new file mode 100644
index 00000000..69174e4c
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/WhitespaceNullableArray.txt
@@ -0,0 +1 @@
++0 errors
\ No newline at end of file
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/WhitespaceNullableArrayElements.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/WhitespaceNullableArrayElements.txt
new file mode 100644
index 00000000..69174e4c
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/WhitespaceNullableArrayElements.txt
@@ -0,0 +1 @@
++0 errors
\ No newline at end of file
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/WhitespaceNullableVarargs.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/WhitespaceNullableVarargs.txt
new file mode 100644
index 00000000..69174e4c
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/WhitespaceNullableVarargs.txt
@@ -0,0 +1 @@
++0 errors
\ No newline at end of file
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/WhitespaceVarargs.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/WhitespaceVarargs.txt
new file mode 100644
index 00000000..1ec0d7e2
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/WhitespaceVarargs.txt
@@ -0,0 +1,2 @@
++WhitespaceVarargs.java:24:24: '...' is preceded with whitespace. [SpringNoWhitespaceBefore]
++1 error
\ No newline at end of file
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/src/test/java/AnnotationEndingInTest.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/src/test/java/AnnotationEndingInTest.txt
new file mode 100644
index 00000000..69174e4c
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/src/test/java/AnnotationEndingInTest.txt
@@ -0,0 +1 @@
++0 errors
\ No newline at end of file
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/src/test/java/InterfaceEndingInTest.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/src/test/java/InterfaceEndingInTest.txt
new file mode 100644
index 00000000..69174e4c
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/src/test/java/InterfaceEndingInTest.txt
@@ -0,0 +1 @@
++0 errors
\ No newline at end of file
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/src/test/java/NamedTest.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/src/test/java/NamedTest.txt
new file mode 100644
index 00000000..38fff433
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/src/test/java/NamedTest.txt
@@ -0,0 +1 @@
++Test classes should have a name ending with Tests.java
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/src/test/java/NamedTests.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/src/test/java/NamedTests.txt
new file mode 100644
index 00000000..69174e4c
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/src/test/java/NamedTests.txt
@@ -0,0 +1 @@
++0 errors
\ No newline at end of file
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/DeprecatedBadCase.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/DeprecatedBadCase.xml
new file mode 100644
index 00000000..0a4b92ee
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/DeprecatedBadCase.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/DeprecatedValid.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/DeprecatedValid.xml
new file mode 100644
index 00000000..0a4b92ee
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/DeprecatedValid.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JavadocNonPublicSinceInsideAnnotation.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JavadocNonPublicSinceInsideAnnotation.xml
new file mode 100644
index 00000000..c2b98905
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JavadocNonPublicSinceInsideAnnotation.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationAttributeWithValueThatHasConciseReferenceToContainedEnumValue.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationAttributeWithValueThatHasConciseReferenceToContainedEnumValue.java
new file mode 100644
index 00000000..d7ea8e09
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationAttributeWithValueThatHasConciseReferenceToContainedEnumValue.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+@ConditionalOnWebApplicationType(WebApplicationType.A.B.C.D.SERVLET)
+public class AnnotationAttributeWithValueThatHasConciseReferenceToContainedEnumValue {
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationAttributeWithValueThatHasReferenceToContainedConstant.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationAttributeWithValueThatHasReferenceToContainedConstant.java
new file mode 100644
index 00000000..edc98fb7
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationAttributeWithValueThatHasReferenceToContainedConstant.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+@ConditionalOnSomething(ConditionalOnSomething.TYPE_ONE)
+public class AnnotationAttributeWithValueThatHasReferenceToContainedConstant {
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationAttributeWithValueThatHasVerboseReferenceToContainedEnumValue.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationAttributeWithValueThatHasVerboseReferenceToContainedEnumValue.java
new file mode 100644
index 00000000..8594fc9b
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationAttributeWithValueThatHasVerboseReferenceToContainedEnumValue.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+@ConditionalOnWebApplicationType(ConditionalOnWebApplicationType.WebApplicationType.SERVLET)
+public class AnnotationAttributeWithValueThatHasVerboseReferenceToContainedEnumValue {
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationNamedAttributeWithValueThatHasConciseReferenceToContainedEnumValue.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationNamedAttributeWithValueThatHasConciseReferenceToContainedEnumValue.java
new file mode 100644
index 00000000..ea1a39cd
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationNamedAttributeWithValueThatHasConciseReferenceToContainedEnumValue.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+@ConditionalOnWebApplicationType(type = WebApplicationType.A.B.C.D.SERVLET)
+public class AnnotationNamedAttributeWithValueThatHasConciseReferenceToContainedEnumValue {
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationNamedAttributeWithValueThatHasNecessarilyVerboseReferenceToContainedEnumValue.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationNamedAttributeWithValueThatHasNecessarilyVerboseReferenceToContainedEnumValue.java
new file mode 100644
index 00000000..12557326
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationNamedAttributeWithValueThatHasNecessarilyVerboseReferenceToContainedEnumValue.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+import com.example.some.other.WebApplicationType;
+
+@ConditionalOnWebApplicationType(type = ConditionalOnWebApplicationType.WebApplicationType.SERVLET)
+public class AnnotationNamedAttributeWithValueThatHasNecessarilyVerboseReferenceToContainedEnumValue {
+
+ WebApplicationType type;
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationNamedAttributeWithValueThatHasReferenceToContainedConstant.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationNamedAttributeWithValueThatHasReferenceToContainedConstant.java
new file mode 100644
index 00000000..44d6eb5a
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationNamedAttributeWithValueThatHasReferenceToContainedConstant.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+@ConditionalOnSomething(type = ConditionalOnSomething.TYPE_ONE)
+public class AnnotationNamedAttributeWithValueThatHasReferenceToContainedConstant {
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationNamedAttributeWithValueThatHasVerboseReferenceToContainedEnumValue.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationNamedAttributeWithValueThatHasVerboseReferenceToContainedEnumValue.java
new file mode 100644
index 00000000..c652976e
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationNamedAttributeWithValueThatHasVerboseReferenceToContainedEnumValue.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+@ConditionalOnWebApplicationType(type = ConditionalOnWebApplicationType.WebApplicationType.SERVLET)
+public class AnnotationNamedAttributeWithValueThatHasVerboseReferenceToContainedEnumValue {
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationOnNewLine.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationOnNewLine.java
new file mode 100644
index 00000000..f4893731
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationOnNewLine.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+import org.jspecify.annotations.Nullable;
+
+/**
+ * This is a valid example.
+ *
+ * @author Phillip Webb
+ */
+public class AnnotationOnNewLine {
+
+ @Override
+ public String toString() {
+ return "";
+ }
+
+ @Nullable String test1() {
+ return "";
+ }
+
+ @Override
+ @Nullable String test2() {
+ return "";
+ }
+
+ @Override
+ public @Nullable String test3() {
+ return "";
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationWithFullyQualifiedNameAndNamedAttributeWithValueThatHasConciseReferenceToContainedEnumValue.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationWithFullyQualifiedNameAndNamedAttributeWithValueThatHasConciseReferenceToContainedEnumValue.java
new file mode 100644
index 00000000..614e11c0
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationWithFullyQualifiedNameAndNamedAttributeWithValueThatHasConciseReferenceToContainedEnumValue.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+@com.example.web.condition.ConditionalOnWebApplicationType(type = WebApplicationType.A.B.C.D.SERVLET)
+public class AnnotationWithFullyQualifiedNameAndNamedAttributeWithValueThatHasConciseReferenceToContainedEnumValue {
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AsciidoctorCallout.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AsciidoctorCallout.java
new file mode 100644
index 00000000..4f8a00ef
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AsciidoctorCallout.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+/**
+ * This is a valid example.
+ *
+ * @author Phillip Webb
+ */
+public class AsciidoctorCallout {
+
+ public void example() {
+ RestAssured.given(this.spec).filter(document("headers", requestHeaders( // <1>
+ )));
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AssertJBadAssertImport.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AssertJBadAssertImport.java
new file mode 100644
index 00000000..7646caff
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AssertJBadAssertImport.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+import org.junit.Assert;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Import of banned org.junit.Assert.
+ *
+ * @author Andy Wilkinson
+ */
+public class AssertJBadAssertImport {
+
+ @Test
+ void useTheImports() {
+ assertTrue(true);
+ Assert.assertFalse(false);
+ fail("oops");
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AssertJBadAssertionsImport.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AssertJBadAssertionsImport.java
new file mode 100644
index 00000000..5d877c52
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AssertJBadAssertionsImport.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+/**
+ * Import of banned org.junit.jupiter.api.Assertions.
+ *
+ * @author Andy Wilkinson
+ */
+public class AssertJBadAssertionsImport {
+
+ @Test
+ void useTheImports() {
+ assertTrue(true);
+ Assertions.assertFalse(false);
+ fail("oops");
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/CatchE.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/CatchE.java
index aedce6b2..c1e81c66 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/CatchE.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/CatchE.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/CatchEx.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/CatchEx.java
index 68bb8c00..e9739ae0 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/CatchEx.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/CatchEx.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/CatchOo.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/CatchOo.java
index 9e48ba4a..1d21cda5 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/CatchOo.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/CatchOo.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/CatchWord.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/CatchWord.java
index 50bc7af6..3c7d230b 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/CatchWord.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/CatchWord.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/DeprecatedBadCase.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/DeprecatedBadCase.java
new file mode 100644
index 00000000..b806639d
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/DeprecatedBadCase.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+/**
+ * Bad cases for use of {@link Deprecated @Deprecated}.
+ *
+ * @author Andy Wilkinson
+ */
+@Deprecated
+public class DeprecatedBadCase {
+
+ @java.lang.Deprecated
+ public static final String SOME_CONSTANT;
+
+ @Deprecated(since = "")
+ public void someMethod() {
+
+ }
+
+ @Deprecated
+ private class InnerClass {
+
+ @Deprecated(since = "")
+ private void someInnerMethod() {
+
+ }
+
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/DeprecatedValid.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/DeprecatedValid.java
new file mode 100644
index 00000000..e52e3ae1
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/DeprecatedValid.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+/**
+ * Valid cases for use of {@link Deprecated @Deprecated}.
+ *
+ * @author Andy Wilkinson
+ */
+@Deprecated(since = "2.0.0")
+public class DeprecatedValid {
+
+ @Deprecated(since = "1.2.0")
+ public static final String SOME_CONSTANT;
+
+ @Deprecated(since = "1.3.0")
+ public void someMethod() {
+
+ }
+
+ @Deprecated(since = "1.2.0")
+ private class InnerClass {
+
+ @Deprecated(since = "1.1.0")
+ private void someInnerMethod() {
+
+ }
+
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/FiltersToSkipThis.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/FiltersToSkipThis.java
index 82c0a957..e25b5cf8 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/FiltersToSkipThis.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/FiltersToSkipThis.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderDate.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderDate.java
index ecf31c47..2f23d85c 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderDate.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderDate.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderMismatch.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderMismatch.java
index d410278e..48e94313 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderMismatch.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderMismatch.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this foil except in compliance with the License.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderTooLong.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderTooLong.java
index cdf92b18..8b8a0b85 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderTooLong.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderTooLong.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderTooShort.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderTooShort.java
index 467a2381..0325be9e 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderTooShort.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderTooShort.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderWithDateToPresent.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderWithDateToPresent.java
new file mode 100644
index 00000000..5f6957b3
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderWithDateToPresent.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2019-present 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
+ *
+ * https://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.
+ */
+
+/**
+ * The header uses NNNN-present.
+ *
+ * @author Phillip Webb
+ */
+public class HeaderWithDateToPresent {
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderWithSingleDate.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderWithSingleDate.java
index a3045e8e..11600fcd 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderWithSingleDate.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderWithSingleDate.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2019 the original author or authors.
+ * Copyright 2019-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HideUtilityClassConstructorInvalid.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HideUtilityClassConstructorInvalid.java
index 414731c4..5a6b3543 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HideUtilityClassConstructorInvalid.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HideUtilityClassConstructorInvalid.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HideUtilityClassConstructorSpringApplication.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HideUtilityClassConstructorSpringApplication.java
index 23ee070d..ece74108 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HideUtilityClassConstructorSpringApplication.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HideUtilityClassConstructorSpringApplication.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HideUtilityClassConstructorSpringConfiguration.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HideUtilityClassConstructorSpringConfiguration.java
index 080feb69..cafe6164 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HideUtilityClassConstructorSpringConfiguration.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HideUtilityClassConstructorSpringConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/ImportOrderCustomPackageInvalid.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/ImportOrderCustomPackageInvalid.java
index 796175c7..7aa089cf 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/ImportOrderCustomPackageInvalid.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/ImportOrderCustomPackageInvalid.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/ImportOrderCustomPackageValid.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/ImportOrderCustomPackageValid.java
index 129348fb..427075e6 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/ImportOrderCustomPackageValid.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/ImportOrderCustomPackageValid.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5BadAnnotation.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5BadAnnotation.java
index e157a8fa..e9c41790 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5BadAnnotation.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5BadAnnotation.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5BadImport.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5BadImport.java
index 92d8f1ab..2870f5fb 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5BadImport.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5BadImport.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5BadImportWithOptOut.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5BadImportWithOptOut.java
index 668ca7c8..4b471be5 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5BadImportWithOptOut.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5BadImportWithOptOut.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5BadModifier.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5BadModifier.java
index e9b91697..0e665db0 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5BadModifier.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5BadModifier.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-present 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.
@@ -88,4 +88,19 @@ private void doSomethingElseWithTemplateWorks() {
// test here
}
+ @Nested
+ public static class PublicNestedTests {
+
+ @Test
+ public void nestedPublicTest() {
+
+ }
+
+ }
+
+ @Nested
+ private static class PrivateNestedTests {
+
+ }
+
}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5PublicAbstractIsValid.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5PublicAbstractIsValid.java
new file mode 100644
index 00000000..dee91ee2
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5PublicAbstractIsValid.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * This is a valid example. We allow abstract test classes to be
+ * public so that classes in other packages can extend them.
+ *
+ * @author Andy Wilkinson
+ */
+public abstract class JUnit5PublicAbstractIsValid {
+
+ @Test
+ void doSomethingWorks() {
+ // test here
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5Valid.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5Valid.java
index cc7b4cd0..df921319 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5Valid.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5Valid.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
@@ -21,7 +21,7 @@
*
* @author Phillip Webb
*/
-public class JUnit5Valid {
+class JUnit5Valid {
@Test
void doSomethingWorks() {
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocAnnotationFieldHasEarlierSince.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocAnnotationFieldHasEarlierSince.java
new file mode 100644
index 00000000..2ecaf03c
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocAnnotationFieldHasEarlierSince.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+/**
+ * Javadoc with a good since tag.
+ *
+ * @author Andy Wilkinson
+ * @since 1.2.0
+ */
+public @interface JavadocAnnotationFieldHasEarlierSince {
+
+ /**
+ * An attribute.
+ * @return the value
+ * @since 1.1.0
+ */
+ boolean attribute() default true;
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocAuthorWithoutSpace.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocAuthorWithoutSpace.java
index d96d4e66..8a421b44 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocAuthorWithoutSpace.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocAuthorWithoutSpace.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocBadCase.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocBadCase.java
index 8bdca2a1..4a5df596 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocBadCase.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocBadCase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocInnerClassHasEarlierSince.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocInnerClassHasEarlierSince.java
new file mode 100644
index 00000000..2ad74700
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocInnerClassHasEarlierSince.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+/**
+ * Javadoc with an earlier since tag on an inner class.
+ *
+ * @author Phillip Webb
+ * @since 2.0.0
+ */
+class JavadocInnerClassHasEarlierSince {
+
+ /**
+ * Inner class.
+ *
+ * @since 1.2.3
+ */
+ private static class Inner {
+
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocMethodEmptyLineBeforeTag.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocMethodEmptyLineBeforeTag.java
index ff292fc9..dcb778a8 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocMethodEmptyLineBeforeTag.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocMethodEmptyLineBeforeTag.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocMethodEmptyLineBeforeTagWithStarAtEnd.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocMethodEmptyLineBeforeTagWithStarAtEnd.java
index a6704c45..2d92f513 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocMethodEmptyLineBeforeTagWithStarAtEnd.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocMethodEmptyLineBeforeTagWithStarAtEnd.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocMethodHasEarlierSince.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocMethodHasEarlierSince.java
new file mode 100644
index 00000000..d23d74ee
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocMethodHasEarlierSince.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+/**
+ * Javadoc with an earlier since tag on a method.
+ *
+ * @author Andy Wilkinson
+ * @since 2.0.0
+ */
+public class JavadocMethodHasEarlierSince {
+
+ /**
+ * Some method.
+ * @since 1.2.3
+ */
+ public void someMethod() {
+
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocMissingSince.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocMissingSince.java
index 9f22ace8..c9afd407 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocMissingSince.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocMissingSince.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocNonJavadocComment.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocNonJavadocComment.java
index 8f4b66d2..047b2a05 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocNonJavadocComment.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocNonJavadocComment.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocNonPublicSince.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocNonPublicSince.java
index 58e914d3..4f0f2fde 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocNonPublicSince.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocNonPublicSince.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
@@ -25,7 +25,7 @@ class JavadocNonPublicSince {
/**
* Inner class.
*
- * @since 1.2.3
+ * @since 1.2.4
*/
private static class Inner {
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocNonPublicSinceInsideAnnotation.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocNonPublicSinceInsideAnnotation.java
new file mode 100644
index 00000000..b79a5a85
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocNonPublicSinceInsideAnnotation.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+/**
+ * Javadoc with a good since tag.
+ *
+ * @author Phillip Webb
+ * @since 1.2.3
+ */
+public @interface JavadocNonPublicSinceInsideAnnotation {
+
+ /**
+ * Inner enum.
+ *
+ * @since 1.2.4
+ */
+ enum Inner {
+
+ FOO
+
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocNonPublicSinceInsideInterface.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocNonPublicSinceInsideInterface.java
index a8fa5f47..c0e4b412 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocNonPublicSinceInsideInterface.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocNonPublicSinceInsideInterface.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
@@ -25,7 +25,7 @@ public interface JavadocNonPublicSinceInsideInterface {
/**
* Inner enum.
*
- * @since 1.2.3
+ * @since 1.2.4
*/
enum Inner {
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocSoundtrack.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocSoundtrack.java
index ea598898..846bf48d 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocSoundtrack.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocSoundtrack.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocValid.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocValid.java
index 21d30add..6584ef36 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocValid.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocValid.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
@@ -46,4 +46,34 @@ public void test2(String something) {
public String test3(String something) throws RuntimeException {
}
+ /**
+ * Class with a numeric date since.
+ * @since 28.12.2003
+ */
+ public class NumericDateSince {
+
+ /**
+ * Method with version-based since.
+ * @since 1.3.0
+ */
+ public void versionSince() {
+ }
+
+ }
+
+ /**
+ * Class with an alphanumeric date since.
+ * @since 16 April 2001
+ */
+ public class AlphanumericDateSince {
+
+ /**
+ * Method with version-based since.
+ * @since 1.3.0
+ */
+ public void versionSince() {
+ }
+
+ }
+
}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaExtraParens.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaExtraParens.java
index c4f17b30..5e82a117 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaExtraParens.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaExtraParens.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaMissingParens.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaMissingParens.java
index 4e621d28..9ab33a37 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaMissingParens.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaMissingParens.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryBlock.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryBlock.java
index 86807333..cfb42294 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryBlock.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryBlock.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryEmptyBlock.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryEmptyBlock.java
index d1f83089..b8246fee 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryEmptyBlock.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryEmptyBlock.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryIfBlock.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryIfBlock.java
index 4208b212..5468bb48 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryIfBlock.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryIfBlock.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryIfElseBlock.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryIfElseBlock.java
index 059bb564..473fa096 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryIfElseBlock.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryIfElseBlock.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryThrowBlock.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryThrowBlock.java
index 24f4da47..61350fe8 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryThrowBlock.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryThrowBlock.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryTryBlock.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryTryBlock.java
index d2f5cde9..2c874d0d 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryTryBlock.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryTryBlock.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryVoidCallable.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryVoidCallable.java
index c9cab5fa..54864d72 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryVoidCallable.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryVoidCallable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaSwitch.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaSwitch.java
index 59d213ac..55640621 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaSwitch.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaSwitch.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaUnnecessaryBlock.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaUnnecessaryBlock.java
index b5f9b616..df215545 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaUnnecessaryBlock.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaUnnecessaryBlock.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaValid.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaValid.java
index 465f92c0..768488e7 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaValid.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaValid.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LeadingWhitespaceSpaces.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LeadingWhitespaceSpaces.java
index 88621291..0e69080a 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LeadingWhitespaceSpaces.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LeadingWhitespaceSpaces.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LeadingWhitespaceTabs.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LeadingWhitespaceTabs.java
index dda09ef0..53d64c19 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LeadingWhitespaceTabs.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LeadingWhitespaceTabs.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LeadingWhitespaceTabsAndTextBlock.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LeadingWhitespaceTabsAndTextBlock.java
new file mode 100644
index 00000000..21a2311a
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LeadingWhitespaceTabsAndTextBlock.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+/**
+ * Leading whitepace with a text block.
+ *
+ * @author Phillip Webb
+ */
+public class LeadingWhitespaceTabsAndTextBlock {
+
+ /**
+ * Comments are ignored.
+ */
+ public void hello() {
+ System.out.println(""""
+ Hello
+ World!""");
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodOrderInvalid.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodOrderInvalid.java
index 9271ba92..0db3e04c 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodOrderInvalid.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodOrderInvalid.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodOrderValid.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodOrderValid.java
index 2bffbcae..b44ad87b 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodOrderValid.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodOrderValid.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityFinalClassWithOverride.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityFinalClassWithOverride.java
new file mode 100644
index 00000000..6a74b3b7
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityFinalClassWithOverride.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+/**
+ * Good visibility because, while class is final, protected methods are
+ * annotated with {@code @Override}.
+ *
+ * @author Andy Wilkinson
+ */
+public final class MethodVisibilityFinalClassWithOverride {
+
+ @Override
+ protected void good() {
+ }
+
+ @Override
+ protected static void goodStatic() {
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityFinalClassWithProtectedMethod.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityFinalClassWithProtectedMethod.java
new file mode 100644
index 00000000..7452e21f
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityFinalClassWithProtectedMethod.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+/**
+ * Bad visibility because class is final.
+ *
+ * @author Andy Wilkinson
+ */
+public final class MethodVisibilityFinalClassWithProtectedMethod {
+
+ protected void bad() {
+ }
+
+ protected static void badStatic() {
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityInnerClassesWithPublicMethod.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityInnerClassesWithPublicMethod.java
index cf10eb76..262a258f 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityInnerClassesWithPublicMethod.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityInnerClassesWithPublicMethod.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityPackagePrivateWithPublicMethod.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityPackagePrivateWithPublicMethod.java
index 75d5b080..c6377f3d 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityPackagePrivateWithPublicMethod.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityPackagePrivateWithPublicMethod.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityProtectedWithPublicMethod.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityProtectedWithPublicMethod.java
new file mode 100644
index 00000000..fe36ec8c
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityProtectedWithPublicMethod.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+/**
+ * Good visibility because class is protected.
+ *
+ * @author Phillip Webb
+ */
+protected class MethodVisibilityProtectedWithPublicMethod {
+
+ MethodVisibilityPackagePrivateWithPublicMethod() {
+ }
+
+ public void bad() {
+ }
+
+ public static void badStatic() {
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityWithOverride.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityWithOverride.java
index 2be96a19..c4b8d3b3 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityWithOverride.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityWithOverride.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
@@ -15,7 +15,7 @@
*/
/**
- * Bad visibility because of public method.
+ * Good visibility because of {@code @Override} annotation.
*
* @author Phillip Webb
*/
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NestedInterfaceItems.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NestedInterfaceItems.java
index d41dbaee..8f9bb820 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NestedInterfaceItems.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NestedInterfaceItems.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NewlineAtEndOfFile.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NewlineAtEndOfFile.java
index 2e80c229..436c72a4 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NewlineAtEndOfFile.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NewlineAtEndOfFile.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NoThis.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NoThis.java
index aa8fe05d..556214ab 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NoThis.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NoThis.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NullabilityBannedNonNull.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NullabilityBannedNonNull.java
new file mode 100644
index 00000000..870a40e9
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NullabilityBannedNonNull.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+import javax.annotation.Nonnull;
+
+import org.checkerframework.checker.nullness.qual.NonNull;
+
+/**
+ * JSpecify's NonNull annotation should be used.
+ *
+ * @author Andy Wilkinson
+ */
+public class NullabilityBannedNonNull {
+
+ public void method(@Nonnull String one, @NonNull String two) {
+
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NullabilityBannedNullable.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NullabilityBannedNullable.java
new file mode 100644
index 00000000..61d918d1
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NullabilityBannedNullable.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+import javax.annotation.Nullable;
+
+/**
+ * JSpecify's Nullable annotation should be used.
+ *
+ * @author Andy Wilkinson
+ */
+public class NullabilityBannedNullable {
+
+ public void method(@Nullable String one) {
+
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NullabilityNullableNotPrecedingFieldType.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NullabilityNullableNotPrecedingFieldType.java
new file mode 100644
index 00000000..a54069ef
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NullabilityNullableNotPrecedingFieldType.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+import org.jspecify.annotations.Nullable;
+
+/**
+ * {@code @Nullable} should appear immediately before the parameter type.
+ *
+ * @author Andy Wilkinson
+ */
+public class NullabilityNullableNotPrecedingFieldType {
+
+ private @Nullable static String field = null;
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NullabilityNullableNotPrecedingParameterType.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NullabilityNullableNotPrecedingParameterType.java
new file mode 100644
index 00000000..bd55d9d2
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NullabilityNullableNotPrecedingParameterType.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+import org.jspecify.annotations.Nullable;
+
+/**
+ * {@code @Nullable} should appear immediately before the parameter type.
+ *
+ * @author Andy Wilkinson
+ */
+public class NullabilityNullableNotPrecedingParameterType {
+
+ public String method(@Nullable final String arg) {
+ return "result";
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NullabilityNullableNotPrecedingReturnType.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NullabilityNullableNotPrecedingReturnType.java
new file mode 100644
index 00000000..9b9b8a4e
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NullabilityNullableNotPrecedingReturnType.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+import org.jspecify.annotations.Nullable;
+
+/**
+ * {@code @Nullable} should appear immediately before the return type.
+ *
+ * @author Andy Wilkinson
+ */
+public class NullabilityNullableNotPrecedingReturnType {
+
+ @Nullable public String method() {
+ return "result";
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NullabilityNullableOnSeparateLine.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NullabilityNullableOnSeparateLine.java
new file mode 100644
index 00000000..b18ee10a
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NullabilityNullableOnSeparateLine.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+import org.jspecify.annotations.Nullable;
+
+/**
+ * {@code @Nullable} should appear immediately before the return type.
+ *
+ * @author Andy Wilkinson
+ */
+public class NullabilityNullableOnSeparateLine {
+
+ @Nullable
+ public String method() {
+ return "result";
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NullabilityValid.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NullabilityValid.java
new file mode 100644
index 00000000..e0ea5cca
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NullabilityValid.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.jspecify.annotations.Nullable;
+
+/**
+ * Valid use of nullability annotations.
+ *
+ * @author Andy Wilkinson
+ */
+public class NullabilityValid {
+
+ private @Nullable String field;
+
+ public NullabilityValid(@Nullable String arg, final @Nullable String anotherArg) {
+
+ }
+
+ public @Nullable String publicMethod() {
+ return "result";
+ }
+
+ @Nullable String packagePrivateMethod() {
+ return "result";
+ }
+
+ public Map genericReturnType() {
+ return Collections.emptyMap();
+ }
+
+ void genericParameter(Map<@Nullable ? extends String, @Nullable String> arg) {
+
+ }
+
+ void parameter(@Nullable String arg) {
+
+ }
+
+ void finalParameter(final @Nullable String arg) {
+
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/OuterTypeFilenameInvalid.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/OuterTypeFilenameInvalid.java
index 0c2f80ad..59f7dc88 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/OuterTypeFilenameInvalid.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/OuterTypeFilenameInvalid.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/OuterTypeFilenameValid.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/OuterTypeFilenameValid.java
index c9ee62bc..6814ed2f 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/OuterTypeFilenameValid.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/OuterTypeFilenameValid.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/SpringApplication.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/SpringApplication.java
index 0dd10214..d72c300b 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/SpringApplication.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/SpringApplication.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryEqualsEquals.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryEqualsEquals.java
index 355cfad5..afd0926d 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryEqualsEquals.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryEqualsEquals.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryEqualsEqualsAny.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryEqualsEqualsAny.java
index bc73a067..9eb48eb9 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryEqualsEqualsAny.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryEqualsEqualsAny.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryEqualsEqualsNever.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryEqualsEqualsNever.java
index 8371a02e..3a30c31a 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryEqualsEqualsNever.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryEqualsEqualsNever.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryInArray.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryInArray.java
index 1fedecbe..99c43de5 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryInArray.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryInArray.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryInIf.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryInIf.java
index c3fc5a56..6414b748 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryInIf.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryInIf.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2022 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryInWhile.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryInWhile.java
index 84e14ac6..1bef3bee 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryInWhile.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryInWhile.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2022 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryParensAndPlus.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryParensAndPlus.java
index 942b1bce..36e22af3 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryParensAndPlus.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryParensAndPlus.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryParensInvalid.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryParensInvalid.java
index 69fc4218..cbd7ce9e 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryParensInvalid.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryParensInvalid.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryParensValid.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryParensValid.java
index 42f842c3..f9f490ee 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryParensValid.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TernaryParensValid.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TryWithResources.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TryWithResources.java
index 473889ae..c68396dc 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TryWithResources.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TryWithResources.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/Valid.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/Valid.java
index da4f0436..e14319f1 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/Valid.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/Valid.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/WhitespaceNullableArray.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/WhitespaceNullableArray.java
new file mode 100644
index 00000000..2d25cfa7
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/WhitespaceNullableArray.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+/**
+ * Whitespace is expected before {@code []} when @Nullable.
+ *
+ * @author Andy Wilkinson
+ */
+public class WhitespaceNullableArray {
+
+ void bytes(int @Nullable [] elements) {
+
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/WhitespaceNullableArrayElements.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/WhitespaceNullableArrayElements.java
new file mode 100644
index 00000000..6e23b7fb
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/WhitespaceNullableArrayElements.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+/**
+ * Whitespace is expected before {@code type[]} when @Nullable.
+ *
+ * @author Andy Wilkinson
+ */
+public class WhitespaceNullableArrayElements {
+
+ void bytes(@Nullable int[] elements) {
+
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/WhitespaceNullableVarargs.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/WhitespaceNullableVarargs.java
new file mode 100644
index 00000000..1b4eaeae
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/WhitespaceNullableVarargs.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+/**
+ * Whitespace is expected before ... when @Nullable.
+ *
+ * @author Andy Wilkinson
+ */
+public class WhitespaceNullableVarargs {
+
+ void bytes(int @Nullable ... elements) {
+
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/WhitespaceVarargs.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/WhitespaceVarargs.java
new file mode 100644
index 00000000..2a962abe
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/WhitespaceVarargs.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+/**
+ * Whitespace is not expected before {@code ...}.
+ *
+ * @author Andy Wilkinson
+ */
+public class WhitespaceVarargs {
+
+ void bytes(int ... elements) {
+
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/nopackageinfo/NoPackageInfo.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/nopackageinfo/NoPackageInfo.java
index a6f8b3ae..5ae26280 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/nopackageinfo/NoPackageInfo.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/nopackageinfo/NoPackageInfo.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2022 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/package-info-header-must-be-missing.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/package-info-header-must-be-missing.java
index b426e3ba..039f3f05 100644
--- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/package-info-header-must-be-missing.java
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/package-info-header-must-be-missing.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this foil except in compliance with the License.
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/src/test/java/AnnotationEndingInTest.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/src/test/java/AnnotationEndingInTest.java
new file mode 100644
index 00000000..cdc31f8c
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/src/test/java/AnnotationEndingInTest.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+/**
+ * This is an annotation with a legal name. Only test classes must
+ * have a name that ends with {@code Tests}.
+ *
+ * @author Andy Wilkinson
+ */
+public @interface AnnotationEndingInTest {
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/src/test/java/InterfaceEndingInTest.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/src/test/java/InterfaceEndingInTest.java
new file mode 100644
index 00000000..d79b6453
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/src/test/java/InterfaceEndingInTest.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+/**
+ * This is an interface with a legal name. Only test classes must
+ * have a name that ends with {@code Tests}.
+ *
+ * @author Andy Wilkinson
+ */
+public interface InterfaceEndingInTest {
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/src/test/java/NamedTest.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/src/test/java/NamedTest.java
new file mode 100644
index 00000000..a042f613
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/src/test/java/NamedTest.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+/**
+ * This is a test with the wrong name.
+ *
+ * @author Phillip Webb
+ */
+public class NamedTest {
+
+}
diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/src/test/java/NamedTests.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/src/test/java/NamedTests.java
new file mode 100644
index 00000000..423428e5
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/src/test/java/NamedTests.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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.
+ */
+
+/**
+ * This is a test with the correct name.
+ *
+ * @author Phillip Webb
+ */
+public class NamedTests {
+
+}
diff --git a/spring-javaformat/spring-javaformat-config/pom.xml b/spring-javaformat/spring-javaformat-config/pom.xml
index 3b622102..e984a073 100644
--- a/spring-javaformat/spring-javaformat-config/pom.xml
+++ b/spring-javaformat/spring-javaformat-config/pom.xml
@@ -5,7 +5,7 @@
io.spring.javaformatspring-javaformat
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTspring-javaformat-configSpring JavaFormat Config
diff --git a/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/DefaultJavaFormatConfig.java b/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/DefaultJavaFormatConfig.java
index 60f615ff..d2b5ee8c 100644
--- a/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/DefaultJavaFormatConfig.java
+++ b/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/DefaultJavaFormatConfig.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/IndentationStyle.java b/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/IndentationStyle.java
index 7477b099..f6e2144d 100644
--- a/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/IndentationStyle.java
+++ b/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/IndentationStyle.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/JavaBaseline.java b/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/JavaBaseline.java
index 90bde24a..a27c3df0 100644
--- a/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/JavaBaseline.java
+++ b/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/JavaBaseline.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -29,8 +29,8 @@ public enum JavaBaseline {
V8,
/**
- * Use JDK 11+ or higher compatible formatter.
+ * Use JDK 17+ or higher compatible formatter.
*/
- V11
+ V17
}
diff --git a/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/JavaFormatConfig.java b/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/JavaFormatConfig.java
index 300fcce1..23bf45c8 100644
--- a/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/JavaFormatConfig.java
+++ b/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/JavaFormatConfig.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -32,7 +32,7 @@ public interface JavaFormatConfig {
/**
* The default {@link JavaFormatConfig}.
*/
- JavaFormatConfig DEFAULT = of(JavaBaseline.V11, IndentationStyle.TABS);
+ JavaFormatConfig DEFAULT = of(JavaBaseline.V17, IndentationStyle.TABS);
/**
* Java JDK baseline version expected be used when formatting.
diff --git a/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/PropertiesJavaFormatConfig.java b/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/PropertiesJavaFormatConfig.java
index 23d87a59..d631312d 100644
--- a/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/PropertiesJavaFormatConfig.java
+++ b/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/PropertiesJavaFormatConfig.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-config/src/test/java/io/spring/javaformat/config/PropertiesJavaFormatConfigTests.java b/spring-javaformat/spring-javaformat-config/src/test/java/io/spring/javaformat/config/PropertiesJavaFormatConfigTests.java
index 135e9e0e..2c702617 100644
--- a/spring-javaformat/spring-javaformat-config/src/test/java/io/spring/javaformat/config/PropertiesJavaFormatConfigTests.java
+++ b/spring-javaformat/spring-javaformat-config/src/test/java/io/spring/javaformat/config/PropertiesJavaFormatConfigTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-present 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.
@@ -33,7 +33,7 @@ class PropertiesJavaFormatConfigTests {
void getJavaBaselineWhenNoPropertyReturnsJava11() {
Properties properties = new Properties();
PropertiesJavaFormatConfig config = new PropertiesJavaFormatConfig(properties);
- assertThat(config.getJavaBaseline()).isEqualTo(JavaBaseline.V11);
+ assertThat(config.getJavaBaseline()).isEqualTo(JavaBaseline.V17);
}
@Test
diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-jdk11/META-INF/MANIFEST.MF b/spring-javaformat/spring-javaformat-formatter-eclipse-jdk17/META-INF/MANIFEST.MF
similarity index 78%
rename from spring-javaformat/spring-javaformat-formatter-eclipse-jdk11/META-INF/MANIFEST.MF
rename to spring-javaformat/spring-javaformat-formatter-eclipse-jdk17/META-INF/MANIFEST.MF
index 60fcdafe..5e2e9099 100644
--- a/spring-javaformat/spring-javaformat-formatter-eclipse-jdk11/META-INF/MANIFEST.MF
+++ b/spring-javaformat/spring-javaformat-formatter-eclipse-jdk17/META-INF/MANIFEST.MF
@@ -1,8 +1,8 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
-Bundle-Name: Spring Formatter Eclipse Runtime JDK11
-Bundle-SymbolicName: spring-javaformat-formatter-eclipse-jdk11
-Bundle-Version: 0.0.35.qualifier
+Bundle-Name: Spring Formatter Eclipse Runtime JDK17
+Bundle-SymbolicName: spring-javaformat-formatter-eclipse-jdk17
+Bundle-Version: 0.0.48.qualifier
Require-Bundle: org.eclipse.jdt.core;bundle-version="[1.0.0,10.0.0)",
org.eclipse.jface;bundle-version="[1.0.0,10.0.0)",
org.eclipse.jdt.core.source;bundle-version="[1.0.0,10.0.0)";resolution:=optional,
diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-jdk11/build.properties b/spring-javaformat/spring-javaformat-formatter-eclipse-jdk17/build.properties
similarity index 100%
rename from spring-javaformat/spring-javaformat-formatter-eclipse-jdk11/build.properties
rename to spring-javaformat/spring-javaformat-formatter-eclipse-jdk17/build.properties
diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-jdk11/pom.xml b/spring-javaformat/spring-javaformat-formatter-eclipse-jdk17/pom.xml
similarity index 90%
rename from spring-javaformat/spring-javaformat-formatter-eclipse-jdk11/pom.xml
rename to spring-javaformat/spring-javaformat-formatter-eclipse-jdk17/pom.xml
index eb0b837a..0e73c0e4 100644
--- a/spring-javaformat/spring-javaformat-formatter-eclipse-jdk11/pom.xml
+++ b/spring-javaformat/spring-javaformat-formatter-eclipse-jdk17/pom.xml
@@ -6,11 +6,11 @@
io.spring.javaformatspring-javaformat
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOT
- spring-javaformat-formatter-eclipse-jdk11
+ spring-javaformat-formatter-eclipse-jdk17eclipse-plugin
- Spring JavaFormat Eclipse JDK-11
+ Spring JavaFormat Eclipse JDK-17${basedir}/../..org.eclipse.jdt.core.source,org.eclipse.jface.source,org.eclipse.text.source
@@ -23,13 +23,29 @@
- eclipse-jdk11
+ eclipse-jdk17p2
- ${eclipse.jdk11.repository}
+ ${eclipse.jdk17.repository}
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+ empty-javadoc-jar
+ package
+
+ jar
+
+
+ javadoc
+
+
+
+ org.apache.maven.pluginsmaven-antrun-plugin
diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-jdk8/META-INF/MANIFEST.MF b/spring-javaformat/spring-javaformat-formatter-eclipse-jdk8/META-INF/MANIFEST.MF
index bb464282..3c5dbb8b 100644
--- a/spring-javaformat/spring-javaformat-formatter-eclipse-jdk8/META-INF/MANIFEST.MF
+++ b/spring-javaformat/spring-javaformat-formatter-eclipse-jdk8/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Spring Formatter Eclipse JDK8
Bundle-SymbolicName: spring-javaformat-formatter-eclipse-jdk8
-Bundle-Version: 0.0.35.qualifier
+Bundle-Version: 0.0.48.qualifier
Require-Bundle: org.eclipse.jdt.core;bundle-version="[1.0.0,10.0.0)",
org.eclipse.jface;bundle-version="[1.0.0,10.0.0)",
org.eclipse.jdt.core.source;bundle-version="[1.0.0,10.0.0)";resolution:=optional,
diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-jdk8/pom.xml b/spring-javaformat/spring-javaformat-formatter-eclipse-jdk8/pom.xml
index 89578264..0e52bf06 100644
--- a/spring-javaformat/spring-javaformat-formatter-eclipse-jdk8/pom.xml
+++ b/spring-javaformat/spring-javaformat-formatter-eclipse-jdk8/pom.xml
@@ -6,7 +6,7 @@
io.spring.javaformatspring-javaformat
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTspring-javaformat-formatter-eclipse-jdk8eclipse-plugin
@@ -30,6 +30,22 @@
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+ empty-javadoc-jar
+ package
+
+ jar
+
+
+ javadoc
+
+
+
+ org.apache.maven.pluginsmaven-antrun-plugin
diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk11/pom.xml b/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk17/pom.xml
similarity index 85%
rename from spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk11/pom.xml
rename to spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk17/pom.xml
index f4037c17..9aef9a9a 100644
--- a/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk11/pom.xml
+++ b/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk17/pom.xml
@@ -6,17 +6,17 @@
io.spring.javaformatspring-javaformat
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOT
- spring-javaformat-formatter-eclipse-jdt-jdk11
- Spring JavaFormat Eclipse JDT JDK-11
+ spring-javaformat-formatter-eclipse-jdt-jdk17
+ Spring JavaFormat Eclipse JDT JDK-17${basedir}/../..io.spring.javaformat
- spring-javaformat-formatter-eclipse-jdk11
+ spring-javaformat-formatter-eclipse-jdk17${project.version}true
@@ -48,7 +48,7 @@
- io.spring.javaformat:spring-javaformat-formatter-eclipse-jdk11
+ io.spring.javaformat:spring-javaformat-formatter-eclipse-jdk17org/eclipse/jdt/**
@@ -57,7 +57,7 @@
org.eclipse.jdt
- io.spring.javaformat.eclipse.jdt.jdk11
+ io.spring.javaformat.eclipse.jdt.jdk17false
diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk11/src/main/java/org/eclipse/jdt/internal/formatter/ExtendedCodeFormatter.java b/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk17/src/main/java/org/eclipse/jdt/internal/formatter/ExtendedCodeFormatter.java
similarity index 94%
rename from spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk11/src/main/java/org/eclipse/jdt/internal/formatter/ExtendedCodeFormatter.java
rename to spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk17/src/main/java/org/eclipse/jdt/internal/formatter/ExtendedCodeFormatter.java
index f02bbf08..a2664b72 100644
--- a/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk11/src/main/java/org/eclipse/jdt/internal/formatter/ExtendedCodeFormatter.java
+++ b/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk17/src/main/java/org/eclipse/jdt/internal/formatter/ExtendedCodeFormatter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -107,8 +107,9 @@ protected void prepareWraps(int kind) {
}
private void applyPreparators(Phase preWrapping, int kind, ASTNode astRoot, TokenManager tokenManager) {
- this.preparators.stream().filter((preparator) -> preparator.getPhase() == preWrapping)
- .forEach((preparator) -> preparator.apply(kind, tokenManager, astRoot));
+ this.preparators.stream()
+ .filter((preparator) -> preparator.getPhase() == preWrapping)
+ .forEach((preparator) -> preparator.apply(kind, tokenManager, astRoot));
}
@SuppressWarnings("unchecked")
diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk11/src/main/java/org/eclipse/jdt/internal/formatter/Preparator.java b/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk17/src/main/java/org/eclipse/jdt/internal/formatter/Preparator.java
similarity index 95%
rename from spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk11/src/main/java/org/eclipse/jdt/internal/formatter/Preparator.java
rename to spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk17/src/main/java/org/eclipse/jdt/internal/formatter/Preparator.java
index 9873fc96..bfd16b37 100644
--- a/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk11/src/main/java/org/eclipse/jdt/internal/formatter/Preparator.java
+++ b/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk17/src/main/java/org/eclipse/jdt/internal/formatter/Preparator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -54,7 +54,7 @@ enum Phase {
/**
* Apply the preparator after wrapping.
*/
- POST_WRAPPING;
+ POST_WRAPPING
}
diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk8/pom.xml b/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk8/pom.xml
index c0573920..30a2af39 100644
--- a/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk8/pom.xml
+++ b/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk8/pom.xml
@@ -6,7 +6,7 @@
io.spring.javaformatspring-javaformat
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTspring-javaformat-formatter-eclipse-jdt-jdk8Spring JavaFormat Eclipse JDT JDK-8
diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk8/src/main/java/org/eclipse/jdt/internal/formatter/ExtendedCodeFormatter.java b/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk8/src/main/java/org/eclipse/jdt/internal/formatter/ExtendedCodeFormatter.java
index f02bbf08..a2664b72 100644
--- a/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk8/src/main/java/org/eclipse/jdt/internal/formatter/ExtendedCodeFormatter.java
+++ b/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk8/src/main/java/org/eclipse/jdt/internal/formatter/ExtendedCodeFormatter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -107,8 +107,9 @@ protected void prepareWraps(int kind) {
}
private void applyPreparators(Phase preWrapping, int kind, ASTNode astRoot, TokenManager tokenManager) {
- this.preparators.stream().filter((preparator) -> preparator.getPhase() == preWrapping)
- .forEach((preparator) -> preparator.apply(kind, tokenManager, astRoot));
+ this.preparators.stream()
+ .filter((preparator) -> preparator.getPhase() == preWrapping)
+ .forEach((preparator) -> preparator.apply(kind, tokenManager, astRoot));
}
@SuppressWarnings("unchecked")
diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk8/src/main/java/org/eclipse/jdt/internal/formatter/Preparator.java b/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk8/src/main/java/org/eclipse/jdt/internal/formatter/Preparator.java
index 9873fc96..bfd16b37 100644
--- a/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk8/src/main/java/org/eclipse/jdt/internal/formatter/Preparator.java
+++ b/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk8/src/main/java/org/eclipse/jdt/internal/formatter/Preparator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -54,7 +54,7 @@ enum Phase {
/**
* Apply the preparator after wrapping.
*/
- POST_WRAPPING;
+ POST_WRAPPING
}
diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk8/src/main/java/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java b/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk8/src/main/java/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java
new file mode 100644
index 00000000..6878ca6f
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk8/src/main/java/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java
@@ -0,0 +1,1688 @@
+/*******************************************************************************
+ * Copyright (c) 2014, 2020 Mateusz Matela and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Mateusz Matela - [formatter] Formatter does not format Java code correctly, especially when max line width is set - https://bugs.eclipse.org/303519
+ * Mateusz Matela - [formatter] follow up bug for comments - https://bugs.eclipse.org/458208
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter.linewrap;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Predicate;
+import java.util.function.ToIntFunction;
+
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.Annotation;
+import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
+import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
+import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
+import org.eclipse.jdt.core.dom.ArrayInitializer;
+import org.eclipse.jdt.core.dom.AssertStatement;
+import org.eclipse.jdt.core.dom.Assignment;
+import org.eclipse.jdt.core.dom.Block;
+import org.eclipse.jdt.core.dom.CatchClause;
+import org.eclipse.jdt.core.dom.ClassInstanceCreation;
+import org.eclipse.jdt.core.dom.ConditionalExpression;
+import org.eclipse.jdt.core.dom.ConstructorInvocation;
+import org.eclipse.jdt.core.dom.CreationReference;
+import org.eclipse.jdt.core.dom.DoStatement;
+import org.eclipse.jdt.core.dom.EnhancedForStatement;
+import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
+import org.eclipse.jdt.core.dom.EnumDeclaration;
+import org.eclipse.jdt.core.dom.ExportsDirective;
+import org.eclipse.jdt.core.dom.Expression;
+import org.eclipse.jdt.core.dom.ExpressionMethodReference;
+import org.eclipse.jdt.core.dom.FieldAccess;
+import org.eclipse.jdt.core.dom.FieldDeclaration;
+import org.eclipse.jdt.core.dom.ForStatement;
+import org.eclipse.jdt.core.dom.IExtendedModifier;
+import org.eclipse.jdt.core.dom.IfStatement;
+import org.eclipse.jdt.core.dom.InfixExpression;
+import org.eclipse.jdt.core.dom.InfixExpression.Operator;
+import org.eclipse.jdt.core.dom.LambdaExpression;
+import org.eclipse.jdt.core.dom.MemberValuePair;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.MethodInvocation;
+import org.eclipse.jdt.core.dom.Name;
+import org.eclipse.jdt.core.dom.NormalAnnotation;
+import org.eclipse.jdt.core.dom.OpensDirective;
+import org.eclipse.jdt.core.dom.PackageDeclaration;
+import org.eclipse.jdt.core.dom.ParameterizedType;
+import org.eclipse.jdt.core.dom.ProvidesDirective;
+import org.eclipse.jdt.core.dom.QualifiedName;
+import org.eclipse.jdt.core.dom.RecordDeclaration;
+import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
+import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
+import org.eclipse.jdt.core.dom.Statement;
+import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
+import org.eclipse.jdt.core.dom.SuperFieldAccess;
+import org.eclipse.jdt.core.dom.SuperMethodInvocation;
+import org.eclipse.jdt.core.dom.SuperMethodReference;
+import org.eclipse.jdt.core.dom.SwitchExpression;
+import org.eclipse.jdt.core.dom.SwitchStatement;
+import org.eclipse.jdt.core.dom.ThisExpression;
+import org.eclipse.jdt.core.dom.TryStatement;
+import org.eclipse.jdt.core.dom.Type;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.core.dom.TypeMethodReference;
+import org.eclipse.jdt.core.dom.TypeParameter;
+import org.eclipse.jdt.core.dom.UnionType;
+import org.eclipse.jdt.core.dom.VariableDeclaration;
+import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
+import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
+import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
+import org.eclipse.jdt.core.dom.WhileStatement;
+import org.eclipse.jdt.core.formatter.CodeFormatter;
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
+import org.eclipse.jdt.internal.formatter.DefaultCodeFormatterOptions;
+import org.eclipse.jdt.internal.formatter.DefaultCodeFormatterOptions.Alignment;
+import org.eclipse.jdt.internal.formatter.Token;
+import org.eclipse.jdt.internal.formatter.Token.WrapMode;
+import org.eclipse.jdt.internal.formatter.Token.WrapPolicy;
+import org.eclipse.jdt.internal.formatter.TokenManager;
+import org.eclipse.jdt.internal.formatter.TokenTraverser;
+import org.eclipse.jface.text.IRegion;
+
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOLON;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMA;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_BLOCK;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_JAVADOC;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_LINE;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameDOT;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameEQUAL;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameIdentifier;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameLBRACE;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameLESS;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameLPAREN;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameOR;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameQUESTION;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameRBRACE;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameRPAREN;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameSEMICOLON;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameStringLiteral;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameenum;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameextends;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameimplements;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNamenew;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNamesuper;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNamethis;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNamethrows;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameto;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNamewhile;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNamewith;
+
+public class WrapPreparator extends ASTVisitor {
+
+ // @formatter:off
+
+ /**
+ * Helper for common handling of all expressions that should be treated the same as
+ * {@link FieldAccess}
+ */
+ private static class FieldAccessAdapter {
+ final Expression accessExpression;
+
+ public FieldAccessAdapter(Expression expression) {
+ this.accessExpression = expression;
+ }
+
+ public static boolean isFieldAccess(ASTNode expr) {
+ return expr instanceof FieldAccess || expr instanceof QualifiedName || expr instanceof ThisExpression
+ || expr instanceof SuperFieldAccess;
+ }
+
+ public Expression getExpression() {
+ if (this.accessExpression instanceof FieldAccess) {
+ return ((FieldAccess) this.accessExpression).getExpression();
+ }
+ if (this.accessExpression instanceof QualifiedName) {
+ return ((QualifiedName) this.accessExpression).getQualifier();
+ }
+ if (this.accessExpression instanceof ThisExpression) {
+ return ((ThisExpression) this.accessExpression).getQualifier();
+ }
+ if (this.accessExpression instanceof SuperFieldAccess) {
+ return ((SuperFieldAccess) this.accessExpression).getQualifier();
+ }
+ throw new AssertionError();
+ }
+
+ public int getIdentifierIndex(TokenManager tm) {
+ if (this.accessExpression instanceof FieldAccess) {
+ return tm.firstIndexIn(((FieldAccess) this.accessExpression).getName(), TokenNameIdentifier);
+ }
+ if (this.accessExpression instanceof QualifiedName) {
+ return tm.firstIndexIn(((QualifiedName) this.accessExpression).getName(), TokenNameIdentifier);
+ }
+ if (this.accessExpression instanceof ThisExpression) {
+ return tm.lastIndexIn(this.accessExpression, TokenNamethis);
+ }
+ if (this.accessExpression instanceof SuperFieldAccess) {
+ return tm.lastIndexIn(this.accessExpression, TokenNamesuper);
+ }
+ throw new AssertionError();
+ }
+ }
+
+ private static final Map OPERATOR_PRECEDENCE;
+ private static final Map> OPERATOR_WRAPPING_OPTION;
+ private static final Map> OPERATOR_WRAP_BEFORE_OPTION;
+ static {
+ HashMap precedence = new HashMap<>();
+ HashMap> wrappingOption = new HashMap<>();
+ HashMap> wrapBeforeOption = new HashMap<>();
+ for (Operator op : Arrays.asList(Operator.TIMES, Operator.DIVIDE, Operator.REMAINDER)) {
+ precedence.put(op, 1);
+ wrappingOption.put(op, o -> o.alignment_for_multiplicative_operator);
+ wrapBeforeOption.put(op, o -> o.wrap_before_multiplicative_operator);
+ }
+ for (Operator op : Arrays.asList(Operator.PLUS, Operator.MINUS)) {
+ precedence.put(op, 2);
+ wrappingOption.put(op, o -> o.alignment_for_additive_operator);
+ wrapBeforeOption.put(op, o -> o.wrap_before_additive_operator);
+ }
+ for (Operator op : Arrays.asList(Operator.LEFT_SHIFT, Operator.RIGHT_SHIFT_SIGNED,
+ Operator.RIGHT_SHIFT_UNSIGNED)) {
+ precedence.put(op, 3);
+ wrappingOption.put(op, o -> o.alignment_for_shift_operator);
+ wrapBeforeOption.put(op, o -> o.wrap_before_shift_operator);
+ }
+ for (Operator op : Arrays.asList(Operator.LESS, Operator.GREATER, Operator.LESS_EQUALS,
+ Operator.GREATER_EQUALS)) {
+ precedence.put(op, 4);
+ wrappingOption.put(op, o -> o.alignment_for_relational_operator);
+ wrapBeforeOption.put(op, o -> o.wrap_before_relational_operator);
+ }
+ for (Operator op : Arrays.asList(Operator.EQUALS, Operator.NOT_EQUALS)) {
+ precedence.put(op, 5);
+ wrappingOption.put(op, o -> o.alignment_for_relational_operator);
+ wrapBeforeOption.put(op, o -> o.wrap_before_relational_operator);
+ }
+
+ precedence.put(Operator.AND, 6);
+ precedence.put(Operator.XOR, 7);
+ precedence.put(Operator.OR, 8);
+ for (Operator op : Arrays.asList(Operator.AND, Operator.XOR, Operator.OR)) {
+ wrappingOption.put(op, o -> o.alignment_for_bitwise_operator);
+ wrapBeforeOption.put(op, o -> o.wrap_before_bitwise_operator);
+ }
+
+ precedence.put(Operator.CONDITIONAL_AND, 9);
+ precedence.put(Operator.CONDITIONAL_OR, 10);
+ for (Operator op : Arrays.asList(Operator.CONDITIONAL_AND, Operator.CONDITIONAL_OR)) {
+ wrappingOption.put(op, o -> o.alignment_for_logical_operator);
+ wrapBeforeOption.put(op, o -> o.wrap_before_logical_operator);
+ }
+ // ternary and assignment operators not relevant to infix expressions
+
+ OPERATOR_PRECEDENCE = Collections.unmodifiableMap(precedence);
+ OPERATOR_WRAPPING_OPTION = Collections.unmodifiableMap(wrappingOption);
+ OPERATOR_WRAP_BEFORE_OPTION = Collections.unmodifiableMap(wrapBeforeOption);
+ }
+
+ /** Penalty multiplier for wraps that are preferred */
+ private final static float PREFERRED = 7f / 8;
+
+ final TokenManager tm;
+ final DefaultCodeFormatterOptions options;
+ final int kind;
+
+ final Aligner aligner;
+
+ /*
+ * temporary values used when calling {@link #handleWrap(int)} to avoid ArrayList
+ * initialization and long lists of parameters
+ */
+ private List wrapIndexes = new ArrayList<>();
+ /**
+ * Indexes for wraps that shouldn't happen but should be indented if cannot be removed
+ */
+ private List secondaryWrapIndexes = new ArrayList<>();
+ private List wrapPenalties = new ArrayList<>();
+ private int wrapParentIndex = -1;
+ private int wrapGroupEnd = -1;
+
+ private int currentDepth = 0;
+
+ public WrapPreparator(TokenManager tokenManager, DefaultCodeFormatterOptions options, int kind) {
+ this.tm = tokenManager;
+ this.options = options;
+ this.kind = kind;
+
+ this.aligner = new Aligner(this.tm, this.options);
+ }
+
+ @Override
+ public boolean preVisit2(ASTNode node) {
+ this.currentDepth++;
+
+ assert this.wrapIndexes.isEmpty() && this.secondaryWrapIndexes.isEmpty() && this.wrapPenalties.isEmpty();
+ assert this.wrapParentIndex == -1 && this.wrapGroupEnd == -1;
+
+ boolean isMalformed = (node.getFlags() & ASTNode.MALFORMED) != 0;
+ if (isMalformed) {
+ this.tm.addDisableFormatTokenPair(this.tm.firstTokenIn(node, -1), this.tm.lastTokenIn(node, -1));
+ }
+ return !isMalformed;
+ }
+
+ @Override
+ public void postVisit(ASTNode node) {
+ this.currentDepth--;
+ }
+
+ @Override
+ public boolean visit(PackageDeclaration node) {
+ handleAnnotations(node.annotations(), this.options.alignment_for_annotations_on_package);
+ return true;
+ }
+
+ @Override
+ public boolean visit(NormalAnnotation node) {
+ int lParen = this.tm.firstIndexAfter(node.getTypeName(), TokenNameLPAREN);
+ int rParen = this.tm.lastIndexIn(node, TokenNameRPAREN);
+ handleParenthesesPositions(lParen, rParen, this.options.parenthesis_positions_in_annotation);
+
+ handleArguments(node.values(), this.options.alignment_for_arguments_in_annotation);
+ return true;
+ }
+
+ @Override
+ public boolean visit(SingleMemberAnnotation node) {
+ int lParen = this.tm.firstIndexAfter(node.getTypeName(), TokenNameLPAREN);
+ int rParen = this.tm.lastIndexIn(node, TokenNameRPAREN);
+ handleParenthesesPositions(lParen, rParen, this.options.parenthesis_positions_in_annotation);
+ return true;
+ }
+
+ @Override
+ public boolean visit(TypeDeclaration node) {
+ handleAnnotations(node.modifiers(), this.options.alignment_for_annotations_on_type);
+
+ Type superclassType = node.getSuperclassType();
+ if (superclassType != null) {
+ this.wrapParentIndex = this.tm.lastIndexIn(node.getName(), -1);
+ this.wrapGroupEnd = this.tm.lastIndexIn(superclassType, -1);
+ this.wrapIndexes.add(this.tm.firstIndexBefore(superclassType, TokenNameextends));
+ this.wrapIndexes.add(this.tm.firstIndexIn(superclassType, -1));
+ handleWrap(this.options.alignment_for_superclass_in_type_declaration, PREFERRED);
+ }
+
+ List superInterfaceTypes = node.superInterfaceTypes();
+ if (!superInterfaceTypes.isEmpty()) {
+ int implementsToken = node.isInterface() ? TokenNameextends : TokenNameimplements;
+ this.wrapParentIndex = this.tm.lastIndexIn(node.getName(), -1);
+ this.wrapIndexes.add(this.tm.firstIndexBefore(superInterfaceTypes.get(0), implementsToken));
+ prepareElementsList(superInterfaceTypes, TokenNameCOMMA, -1);
+ handleWrap(this.options.alignment_for_superinterfaces_in_type_declaration, PREFERRED);
+ }
+
+ prepareElementsList(node.typeParameters(), TokenNameCOMMA, TokenNameLESS);
+ handleWrap(this.options.alignment_for_type_parameters);
+
+ this.aligner.handleAlign(node.bodyDeclarations());
+
+ return true;
+ }
+
+ @Override
+ public boolean visit(AnnotationTypeDeclaration node) {
+ handleAnnotations(node.modifiers(), this.options.alignment_for_annotations_on_type);
+ this.aligner.handleAlign(node.bodyDeclarations());
+ return true;
+ }
+
+ @Override
+ public boolean visit(AnnotationTypeMemberDeclaration node) {
+ handleAnnotations(node.modifiers(), this.options.alignment_for_annotations_on_method);
+ return true;
+ }
+
+ @Override
+ public boolean visit(AnonymousClassDeclaration node) {
+ this.aligner.handleAlign(node.bodyDeclarations());
+ return true;
+ }
+
+ @Override
+ public boolean visit(RecordDeclaration node) {
+ handleAnnotations(node.modifiers(), this.options.alignment_for_annotations_on_type);
+
+ int lParen = this.tm.firstIndexAfter(node.getName(), TokenNameLPAREN);
+ List components = node.recordComponents();
+ int rParen = this.tm.firstIndexAfter(
+ components.isEmpty() ? node.getName() : components.get(components.size() - 1), TokenNameRPAREN);
+ handleParenthesesPositions(lParen, rParen, this.options.parenthesis_positions_in_record_declaration);
+
+ if (!components.isEmpty()) {
+ int wrappingOption = this.options.alignment_for_record_components;
+ this.wrapGroupEnd = this.tm.lastIndexIn(components.get(components.size() - 1), -1);
+ handleArguments(components, wrappingOption);
+ }
+
+ List superInterfaceTypes = node.superInterfaceTypes();
+ if (!superInterfaceTypes.isEmpty()) {
+ this.wrapParentIndex = this.tm.lastIndexIn(node.getName(), -1);
+ this.wrapIndexes.add(this.tm.firstIndexBefore(superInterfaceTypes.get(0), TokenNameimplements));
+ prepareElementsList(superInterfaceTypes, TokenNameCOMMA, -1);
+ handleWrap(this.options.alignment_for_superinterfaces_in_record_declaration, PREFERRED);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean visit(MethodDeclaration node) {
+ handleAnnotations(node.modifiers(), this.options.alignment_for_annotations_on_method);
+
+ if (!node.isCompactConstructor()) {
+ int lParen = this.tm.firstIndexAfter(node.getName(), TokenNameLPAREN);
+ int rParen = node.getBody() == null ? this.tm.lastIndexIn(node, TokenNameRPAREN)
+ : this.tm.firstIndexBefore(node.getBody(), TokenNameRPAREN);
+ handleParenthesesPositions(lParen, rParen, this.options.parenthesis_positions_in_method_declaration);
+ }
+
+ List parameters = node.parameters();
+ Type receiverType = node.getReceiverType();
+ if (!parameters.isEmpty() || receiverType != null) {
+ if (receiverType != null) {
+ this.wrapIndexes.add(this.tm.firstIndexIn(receiverType, -1));
+ }
+ int wrappingOption = node.isConstructor() ? this.options.alignment_for_parameters_in_constructor_declaration
+ : this.options.alignment_for_parameters_in_method_declaration;
+ this.wrapGroupEnd = this.tm
+ .lastIndexIn(parameters.isEmpty() ? receiverType : parameters.get(parameters.size() - 1), -1);
+ handleArguments(parameters, wrappingOption);
+ }
+
+ List exceptionTypes = node.thrownExceptionTypes();
+ if (!exceptionTypes.isEmpty()) {
+ int wrappingOption = node.isConstructor()
+ ? this.options.alignment_for_throws_clause_in_constructor_declaration
+ : this.options.alignment_for_throws_clause_in_method_declaration;
+ if ((wrappingOption & Alignment.M_INDENT_ON_COLUMN) == 0) {
+ this.wrapParentIndex = this.tm.firstIndexAfter(node.getName(), TokenNameLPAREN);
+ }
+ prepareElementsList(exceptionTypes, TokenNameCOMMA, TokenNameRPAREN);
+ // instead of the first exception type, wrap the "throws" token
+ this.wrapIndexes.set(0, this.tm.firstIndexBefore(exceptionTypes.get(0), TokenNamethrows));
+ handleWrap(wrappingOption, 0.5f);
+ }
+
+ if (!node.isConstructor()) {
+ this.wrapParentIndex = this.tm.findFirstTokenInLine(this.tm.firstIndexIn(node.getName(), -1));
+ while (this.tm.get(this.wrapParentIndex).isComment()) {
+ this.wrapParentIndex++;
+ }
+ List typeParameters = node.typeParameters();
+ if (!typeParameters.isEmpty()) {
+ this.wrapIndexes.add(this.tm.firstIndexIn(typeParameters.get(0), -1));
+ }
+ if (node.getReturnType2() != null) {
+ int returTypeIndex = this.tm.firstIndexIn(node.getReturnType2(), -1);
+ if (returTypeIndex != this.wrapParentIndex) {
+ this.wrapIndexes.add(returTypeIndex);
+ }
+ }
+ this.wrapIndexes.add(this.tm.firstIndexIn(node.getName(), -1));
+ this.wrapGroupEnd = this.tm.lastIndexIn(node.getName(), -1);
+ handleWrap(this.options.alignment_for_method_declaration);
+ }
+
+ prepareElementsList(node.typeParameters(), TokenNameCOMMA, TokenNameLESS);
+ handleWrap(this.options.alignment_for_type_parameters);
+
+ return true;
+ }
+
+ @Override
+ public boolean visit(EnumDeclaration node) {
+ handleAnnotations(node.modifiers(), this.options.alignment_for_annotations_on_type);
+
+ List enumConstants = node.enumConstants();
+ int constantsEnd = -1;
+ if (!enumConstants.isEmpty()) {
+ for (EnumConstantDeclaration constant : enumConstants) {
+ this.wrapIndexes.add(this.tm.firstIndexIn(constant, -1));
+ }
+ this.wrapParentIndex = (this.options.alignment_for_enum_constants & Alignment.M_INDENT_ON_COLUMN) > 0
+ ? this.tm.firstIndexBefore(enumConstants.get(0), TokenNameLBRACE)
+ : this.tm.firstIndexIn(node, TokenNameenum);
+ this.wrapGroupEnd = constantsEnd = this.tm.lastIndexIn(enumConstants.get(enumConstants.size() - 1), -1);
+ handleWrap(this.options.alignment_for_enum_constants, node);
+ }
+
+ if (!this.options.join_wrapped_lines) {
+ // preserve a line break between the last comma and semicolon
+ int commaIndex = -1;
+ int i = constantsEnd > 0 ? constantsEnd : this.tm.firstIndexAfter(node.getName(), TokenNameLBRACE);
+ while (++i < this.tm.size()) {
+ Token t = this.tm.get(i);
+ if (t.isComment()) {
+ continue;
+ }
+ if (t.tokenType == TokenNameCOMMA) {
+ commaIndex = i;
+ continue;
+ }
+ if (t.tokenType == TokenNameSEMICOLON && commaIndex >= 0
+ && this.tm.countLineBreaksBetween(this.tm.get(commaIndex), t) == 1) {
+ t.setWrapPolicy(new WrapPolicy(WrapMode.WHERE_NECESSARY, commaIndex, 0));
+ }
+ break;
+ }
+ }
+
+ List superInterfaceTypes = node.superInterfaceTypes();
+ if (!superInterfaceTypes.isEmpty()) {
+ this.wrapParentIndex = this.tm.lastIndexIn(node.getName(), -1);
+ this.wrapIndexes.add(this.tm.firstIndexBefore(superInterfaceTypes.get(0), TokenNameimplements));
+ prepareElementsList(superInterfaceTypes, TokenNameCOMMA, -1);
+ handleWrap(this.options.alignment_for_superinterfaces_in_enum_declaration, PREFERRED);
+ }
+
+ this.aligner.handleAlign(node.bodyDeclarations());
+
+ return true;
+ }
+
+ @Override
+ public boolean visit(EnumConstantDeclaration node) {
+ handleAnnotations(node.modifiers(), this.options.alignment_for_annotations_on_enum_constant);
+
+ int lParen = this.tm.firstIndexAfter(node.getName(), -1);
+ while (this.tm.get(lParen).isComment()) {
+ lParen++;
+ }
+ if (this.tm.get(lParen).tokenType == TokenNameLPAREN) {
+ int rParen = node.getAnonymousClassDeclaration() == null ? this.tm.lastIndexIn(node, TokenNameRPAREN)
+ : this.tm.firstIndexBefore(node.getAnonymousClassDeclaration(), TokenNameRPAREN);
+ handleParenthesesPositions(lParen, rParen, this.options.parenthesis_positions_in_enum_constant_declaration);
+ }
+
+ handleArguments(node.arguments(), this.options.alignment_for_arguments_in_enum_constant);
+ AnonymousClassDeclaration anonymousClass = node.getAnonymousClassDeclaration();
+ if (anonymousClass != null) {
+ forceContinuousWrapping(anonymousClass, this.tm.firstIndexIn(node.getName(), -1));
+ }
+ return true;
+ }
+
+ @Override
+ public boolean visit(Block node) {
+ this.aligner.handleAlign(node);
+ return true;
+ }
+
+ @Override
+ public boolean visit(MethodInvocation node) {
+ // Method patched based on
+ // https://git.eclipse.org/r/c/jdt/eclipse.jdt.core/+/189391/4/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java
+ int lParen = this.tm.firstIndexAfter(node.getName(), TokenNameLPAREN);
+ int rParen = this.tm.lastIndexIn(node, TokenNameRPAREN);
+ handleParenthesesPositions(lParen, rParen, this.options.parenthesis_positions_in_method_invocation);
+
+ handleArguments(node.arguments(), this.options.alignment_for_arguments_in_method_invocation);
+ handleTypeArguments(node.typeArguments());
+
+ boolean isInvocationChainRoot = !(node.getParent() instanceof MethodInvocation)
+ || node.getLocationInParent() != MethodInvocation.EXPRESSION_PROPERTY;
+ if (isInvocationChainRoot) {
+ Expression expression = node;
+ MethodInvocation invocation = node;
+ while (expression instanceof MethodInvocation) {
+ invocation = (MethodInvocation) expression;
+ expression = invocation.getExpression();
+ if (expression != null) {
+ this.wrapIndexes.add(this.tm.firstIndexBefore(invocation.getName(), TokenNameDOT));
+ this.secondaryWrapIndexes.add(this.tm.firstIndexIn(invocation.getName(), TokenNameIdentifier));
+ }
+ }
+ Collections.reverse(this.wrapIndexes);
+ expression = (expression != null) ? expression : invocation;
+ this.wrapParentIndex = this.tm.lastIndexIn(expression, -1);
+ if ((this.options.alignment_for_selector_in_method_invocation & Alignment.M_INDENT_ON_COLUMN) == 0) {
+ this.wrapParentIndex = this.tm.firstIndexIn(expression, -1);
+ }
+ this.wrapGroupEnd = this.tm.lastIndexIn(node, -1);
+ handleWrap(this.options.alignment_for_selector_in_method_invocation);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean visit(SuperMethodInvocation node) {
+ int lParen = this.tm.firstIndexAfter(node.getName(), TokenNameLPAREN);
+ int rParen = this.tm.lastIndexIn(node, TokenNameRPAREN);
+ handleParenthesesPositions(lParen, rParen, this.options.parenthesis_positions_in_method_invocation);
+
+ handleArguments(node.arguments(), this.options.alignment_for_arguments_in_method_invocation);
+ handleTypeArguments(node.typeArguments());
+ return true;
+ }
+
+ @Override
+ public boolean visit(ClassInstanceCreation node) {
+ int lParen = this.tm.firstIndexAfter(node.getType(), TokenNameLPAREN);
+ int rParen = node.getAnonymousClassDeclaration() == null ? this.tm.lastIndexIn(node, TokenNameRPAREN)
+ : this.tm.firstIndexBefore(node.getAnonymousClassDeclaration(), TokenNameRPAREN);
+ handleParenthesesPositions(lParen, rParen, this.options.parenthesis_positions_in_method_invocation);
+
+ AnonymousClassDeclaration anonymousClass = node.getAnonymousClassDeclaration();
+ if (anonymousClass != null) {
+ forceContinuousWrapping(anonymousClass, this.tm.firstIndexIn(node, TokenNamenew));
+ }
+
+ int wrappingOption = node.getExpression() != null
+ ? this.options.alignment_for_arguments_in_qualified_allocation_expression
+ : this.options.alignment_for_arguments_in_allocation_expression;
+ handleArguments(node.arguments(), wrappingOption);
+
+ handleTypeArguments(node.typeArguments());
+ return true;
+ }
+
+ @Override
+ public boolean visit(ConstructorInvocation node) {
+ int lParen = node.arguments().isEmpty() ? this.tm.lastIndexIn(node, TokenNameLPAREN)
+ : this.tm.firstIndexBefore((ASTNode) node.arguments().get(0), TokenNameLPAREN);
+ int rParen = this.tm.lastIndexIn(node, TokenNameRPAREN);
+ handleParenthesesPositions(lParen, rParen, this.options.parenthesis_positions_in_method_invocation);
+
+ handleArguments(node.arguments(), this.options.alignment_for_arguments_in_explicit_constructor_call);
+ handleTypeArguments(node.typeArguments());
+ return true;
+ }
+
+ @Override
+ public boolean visit(SuperConstructorInvocation node) {
+ int lParen = node.arguments().isEmpty() ? this.tm.lastIndexIn(node, TokenNameLPAREN)
+ : this.tm.firstIndexBefore((ASTNode) node.arguments().get(0), TokenNameLPAREN);
+ int rParen = this.tm.lastIndexIn(node, TokenNameRPAREN);
+ handleParenthesesPositions(lParen, rParen, this.options.parenthesis_positions_in_method_invocation);
+
+ handleArguments(node.arguments(), this.options.alignment_for_arguments_in_explicit_constructor_call);
+ handleTypeArguments(node.typeArguments());
+ return true;
+ }
+
+ @Override
+ public boolean visit(FieldAccess node) {
+ handleFieldAccess(node);
+ return true;
+ }
+
+ @Override
+ public boolean visit(QualifiedName node) {
+ handleFieldAccess(node);
+ return true;
+ }
+
+ @Override
+ public boolean visit(ThisExpression node) {
+ handleFieldAccess(node);
+ return true;
+ }
+
+ @Override
+ public boolean visit(SuperFieldAccess node) {
+ handleFieldAccess(node);
+ return true;
+ }
+
+ private void handleFieldAccess(Expression node) {
+ boolean isAccessChainRoot = !FieldAccessAdapter.isFieldAccess(node.getParent());
+ if (!isAccessChainRoot) {
+ return;
+ }
+
+ Expression expression = node;
+ FieldAccessAdapter access = null;
+ while (FieldAccessAdapter.isFieldAccess(expression)) {
+ access = new FieldAccessAdapter(expression);
+ int nameIndex = access.getIdentifierIndex(this.tm);
+ // find a dot preceding the name, may not be there
+ for (int i = nameIndex - 1; i > this.tm.firstIndexIn(node, -1); i--) {
+ Token t = this.tm.get(i);
+ if (t.tokenType == TokenNameDOT) {
+ this.wrapIndexes.add(i);
+ this.secondaryWrapIndexes.add(nameIndex);
+ }
+ if (!t.isComment() && t.tokenType != TokenNamesuper) {
+ break;
+ }
+ }
+ expression = access.getExpression();
+ }
+ Collections.reverse(this.wrapIndexes);
+ this.wrapParentIndex = this.tm.lastIndexIn(expression != null ? expression : access.accessExpression, -1);
+ boolean isFollowedByInvocation = node.getParent() instanceof MethodInvocation
+ && node.getLocationInParent() == MethodInvocation.EXPRESSION_PROPERTY;
+ this.wrapGroupEnd = isFollowedByInvocation ? this.tm.lastIndexIn(node.getParent(), -1)
+ : new FieldAccessAdapter(node).getIdentifierIndex(this.tm);
+ // TODO need configuration for this, now only handles line breaks that cannot be
+ // removed
+ handleWrap(Alignment.M_NO_ALIGNMENT);
+ }
+
+ @Override
+ public boolean visit(InfixExpression node) {
+ Integer operatorPrecedence = OPERATOR_PRECEDENCE.get(node.getOperator());
+ if (operatorPrecedence == null) {
+ return true;
+ }
+ ASTNode parent = node.getParent();
+ if ((parent instanceof InfixExpression) && samePrecedence(node, (InfixExpression) parent)) {
+ return true; // this node has been handled higher in the AST
+ }
+
+ int wrappingOption = OPERATOR_WRAPPING_OPTION.get(node.getOperator()).applyAsInt(this.options);
+ boolean wrapBeforeOperator = OPERATOR_WRAP_BEFORE_OPTION.get(node.getOperator()).test(this.options);
+ if (this.tm.isStringConcatenation(node)) {
+ wrappingOption = this.options.alignment_for_string_concatenation;
+ wrapBeforeOperator = this.options.wrap_before_string_concatenation;
+ }
+
+ findTokensToWrap(node, wrapBeforeOperator, 0);
+ this.wrapParentIndex = this.wrapIndexes.remove(0);
+ this.wrapGroupEnd = this.tm.lastIndexIn(node, -1);
+ if ((wrappingOption & Alignment.M_INDENT_ON_COLUMN) != 0 && this.wrapParentIndex > 0) {
+ this.wrapParentIndex--;
+ }
+ for (int i = this.wrapParentIndex; i >= 0; i--) {
+ if (!this.tm.get(i).isComment()) {
+ this.wrapParentIndex = i;
+ break;
+ }
+ }
+ handleWrap(wrappingOption, !wrapBeforeOperator, node);
+ return true;
+ }
+
+ private void findTokensToWrap(InfixExpression node, boolean wrapBeforeOperator, int depth) {
+ Expression left = node.getLeftOperand();
+ if (left instanceof InfixExpression && samePrecedence(node, (InfixExpression) left)) {
+ findTokensToWrap((InfixExpression) left, wrapBeforeOperator, depth + 1);
+ }
+ else if (this.wrapIndexes.isEmpty() // always add first operand, it will be taken
+ // as wrap parent
+ || !wrapBeforeOperator) {
+ this.wrapIndexes.add(this.tm.firstIndexIn(left, -1));
+ }
+
+ Expression right = node.getRightOperand();
+ List extended = node.extendedOperands();
+ for (int i = -1; i < extended.size(); i++) {
+ Expression operand = (i == -1) ? right : extended.get(i);
+ if (operand instanceof InfixExpression && samePrecedence(node, (InfixExpression) operand)) {
+ findTokensToWrap((InfixExpression) operand, wrapBeforeOperator, depth + 1);
+ }
+ int indexBefore = this.tm.firstIndexBefore(operand, -1);
+ while (this.tm.get(indexBefore).isComment()) {
+ indexBefore--;
+ }
+ assert node.getOperator().toString().equals(this.tm.toString(indexBefore));
+ int indexAfter = this.tm.firstIndexIn(operand, -1);
+ this.wrapIndexes.add(wrapBeforeOperator ? indexBefore : indexAfter);
+ this.secondaryWrapIndexes.add(wrapBeforeOperator ? indexAfter : indexBefore);
+
+ if (!this.options.join_wrapped_lines) {
+ // TODO there should be an option for never joining wraps on opposite side
+ // of the operator
+ if (wrapBeforeOperator) {
+ if (this.tm.countLineBreaksBetween(this.tm.get(indexAfter - 1), this.tm.get(indexAfter)) > 0) {
+ this.wrapIndexes.add(indexAfter);
+ }
+ }
+ else {
+ if (this.tm.countLineBreaksBetween(this.tm.get(indexBefore), this.tm.get(indexBefore - 1)) > 0) {
+ this.wrapIndexes.add(indexBefore);
+ }
+ }
+ }
+ }
+ }
+
+ private boolean samePrecedence(InfixExpression expression1, InfixExpression expression2) {
+ Integer precedence1 = OPERATOR_PRECEDENCE.get(expression1.getOperator());
+ Integer precedence2 = OPERATOR_PRECEDENCE.get(expression2.getOperator());
+ if (precedence1 == null || precedence2 == null) {
+ return false;
+ }
+ return precedence1.equals(precedence2);
+ }
+
+ @Override
+ public boolean visit(ConditionalExpression node) {
+ boolean chainsMatter = (this.options.alignment_for_conditional_expression_chain
+ & Alignment.SPLIT_MASK) != Alignment.M_NO_ALIGNMENT;
+ boolean isNextInChain = node.getParent() instanceof ConditionalExpression
+ && node == ((ConditionalExpression) node.getParent()).getElseExpression();
+ boolean isFirstInChain = node.getElseExpression() instanceof ConditionalExpression && !isNextInChain;
+ boolean wrapBefore = this.options.wrap_before_conditional_operator;
+ List before = wrapBefore ? this.wrapIndexes : this.secondaryWrapIndexes;
+ List after = wrapBefore ? this.secondaryWrapIndexes : this.wrapIndexes;
+ if (!chainsMatter || (!isFirstInChain && !isNextInChain)) {
+ before.add(this.tm.firstIndexAfter(node.getExpression(), TokenNameQUESTION));
+ before.add(this.tm.firstIndexAfter(node.getThenExpression(), TokenNameCOLON));
+ after.add(this.tm.firstIndexIn(node.getThenExpression(), -1));
+ after.add(this.tm.firstIndexIn(node.getElseExpression(), -1));
+ this.wrapParentIndex = this.tm.lastIndexIn(node.getExpression(), -1);
+ this.wrapGroupEnd = this.tm.lastIndexIn(node, -1);
+ handleWrap(this.options.alignment_for_conditional_expression);
+
+ }
+ else if (isFirstInChain) {
+ List chain = new ArrayList<>();
+ chain.add(node);
+ ConditionalExpression next = node;
+ while (next.getElseExpression() instanceof ConditionalExpression) {
+ next = (ConditionalExpression) next.getElseExpression();
+ chain.add(next);
+ }
+
+ for (ConditionalExpression conditional : chain) {
+ before.add(this.tm.firstIndexAfter(conditional.getThenExpression(), TokenNameCOLON));
+ after.add(this.tm.firstIndexIn(conditional.getElseExpression(), -1));
+ }
+ this.wrapParentIndex = this.tm.firstIndexIn(node.getExpression(), -1);
+ this.wrapGroupEnd = this.tm.lastIndexIn(node, -1);
+ handleWrap(this.options.alignment_for_conditional_expression_chain);
+
+ this.currentDepth++;
+ for (ConditionalExpression conditional : chain) {
+ before.add(this.tm.firstIndexAfter(conditional.getExpression(), TokenNameQUESTION));
+ after.add(this.tm.firstIndexIn(conditional.getThenExpression(), -1));
+ this.wrapParentIndex = this.tm.firstIndexIn(conditional.getExpression(), -1);
+ this.wrapGroupEnd = this.tm.lastIndexIn(conditional.getThenExpression(), -1);
+ handleWrap(this.options.alignment_for_conditional_expression);
+ }
+ this.currentDepth--;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean visit(ArrayInitializer node) {
+ List expressions = node.expressions();
+ if (!expressions.isEmpty()) {
+ prepareElementsList(expressions, TokenNameCOMMA, TokenNameLBRACE);
+ handleWrap(this.options.alignment_for_expressions_in_array_initializer, node);
+ }
+ int openingBraceIndex = this.tm.firstIndexIn(node, TokenNameLBRACE);
+ Token openingBrace = this.tm.get(openingBraceIndex);
+ if (openingBrace.isNextLineOnWrap() && openingBrace.getWrapPolicy() == null && openingBraceIndex > 0) {
+ // add fake wrap policy to make sure the brace indentation is right
+ openingBrace.setWrapPolicy(new WrapPolicy(WrapMode.DISABLED, openingBraceIndex - 1, 0));
+ }
+ if (!this.options.join_wrapped_lines
+ && !this.options.insert_new_line_before_closing_brace_in_array_initializer) {
+ // if there is a line break before the closing brace, formatter should treat
+ // it as a valid wrap to preserve
+ int closingBraceIndex = this.tm.lastIndexIn(node, TokenNameRBRACE);
+ Token closingBrace = this.tm.get(closingBraceIndex);
+ if (this.tm.countLineBreaksBetween(this.tm.get(closingBraceIndex - 1), closingBrace) == 1) {
+ closingBrace.setWrapPolicy(new WrapPolicy(WrapMode.WHERE_NECESSARY, openingBraceIndex,
+ closingBraceIndex, 0, this.currentDepth, 1, true, false));
+ }
+ }
+ if (this.options.brace_position_for_array_initializer.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED)
+ && openingBrace.getWrapPolicy() == null && (node.getParent() instanceof SingleMemberAnnotation
+ || node.getParent() instanceof MemberValuePair)) {
+ int parentIndex = this.tm.firstIndexIn(node.getParent(), -1);
+ int indent = this.options.indentation_size;
+ openingBrace.setWrapPolicy(new WrapPolicy(WrapMode.BLOCK_INDENT, parentIndex, indent));
+ }
+ return true;
+ }
+
+ @Override
+ public boolean visit(Assignment node) {
+ int rightSideIndex = this.tm.firstIndexIn(node.getRightHandSide(), -1);
+ if (this.tm.get(rightSideIndex).getLineBreaksBefore() > 0) {
+ return true; // must be an array initializer in new line because of
+ // brace_position_for_array_initializer
+ }
+
+ int operatorIndex = this.tm.firstIndexBefore(node.getRightHandSide(), -1);
+ while (this.tm.get(operatorIndex).isComment()) {
+ operatorIndex--;
+ }
+ assert node.getOperator().toString().equals(this.tm.toString(operatorIndex));
+
+ this.wrapIndexes.add(this.options.wrap_before_assignment_operator ? operatorIndex : rightSideIndex);
+ this.secondaryWrapIndexes.add(this.options.wrap_before_assignment_operator ? rightSideIndex : operatorIndex);
+ this.wrapParentIndex = operatorIndex - 1;
+ this.wrapGroupEnd = this.tm.lastIndexIn(node.getRightHandSide(), -1);
+ handleWrap(this.options.alignment_for_assignment);
+ return true;
+ }
+
+ @Override
+ public boolean visit(VariableDeclarationFragment node) {
+ if (node.getInitializer() == null) {
+ return true;
+ }
+ int rightSideIndex = this.tm.firstIndexIn(node.getInitializer(), -1);
+ if (this.tm.get(rightSideIndex).getLineBreaksBefore() > 0) {
+ return true; // must be an array initializer in new line because of
+ // brace_position_for_array_initializer
+ }
+ int equalIndex = this.tm.firstIndexBefore(node.getInitializer(), TokenNameEQUAL);
+
+ this.wrapIndexes.add(this.options.wrap_before_assignment_operator ? equalIndex : rightSideIndex);
+ this.secondaryWrapIndexes.add(this.options.wrap_before_assignment_operator ? rightSideIndex : equalIndex);
+ this.wrapParentIndex = equalIndex - 1;
+ this.wrapGroupEnd = this.tm.lastIndexIn(node.getInitializer(), -1);
+ handleWrap(this.options.alignment_for_assignment);
+ return true;
+ }
+
+ @Override
+ public boolean visit(IfStatement node) {
+ int lParen = this.tm.firstIndexIn(node, TokenNameLPAREN);
+ int rParen = this.tm.firstIndexAfter(node.getExpression(), TokenNameRPAREN);
+ handleParenthesesPositions(lParen, rParen, this.options.parenthesis_positions_in_if_while_statement);
+
+ Statement elseStatement = node.getElseStatement();
+ boolean keepThenOnSameLine = this.options.keep_then_statement_on_same_line
+ || (this.options.keep_simple_if_on_one_line && elseStatement == null);
+ if (keepThenOnSameLine) {
+ handleSimpleLoop(node.getThenStatement(), this.options.alignment_for_compact_if);
+ }
+
+ if (this.options.keep_else_statement_on_same_line && elseStatement != null) {
+ handleSimpleLoop(elseStatement, this.options.alignment_for_compact_if);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean visit(ForStatement node) {
+ int lParen = this.tm.firstIndexIn(node, TokenNameLPAREN);
+ int rParen = this.tm.firstIndexBefore(node.getBody(), TokenNameRPAREN);
+ handleParenthesesPositions(lParen, rParen, this.options.parenthesis_positions_in_for_statement);
+
+ List initializers = node.initializers();
+ if (!initializers.isEmpty()) {
+ this.wrapIndexes.add(this.tm.firstIndexIn(initializers.get(0), -1));
+ }
+ if (node.getExpression() != null) {
+ this.wrapIndexes.add(this.tm.firstIndexIn(node.getExpression(), -1));
+ }
+ List updaters = node.updaters();
+ if (!updaters.isEmpty()) {
+ this.wrapIndexes.add(this.tm.firstIndexIn(updaters.get(0), -1));
+ }
+ if (!this.wrapIndexes.isEmpty()) {
+ this.wrapParentIndex = lParen;
+ this.wrapGroupEnd = rParen;
+ handleWrap(this.options.alignment_for_expressions_in_for_loop_header);
+ }
+ if (this.options.keep_simple_for_body_on_same_line) {
+ handleSimpleLoop(node.getBody(), this.options.alignment_for_compact_loop);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean visit(EnhancedForStatement node) {
+ int lParen = this.tm.firstIndexIn(node, TokenNameLPAREN);
+ int rParen = this.tm.firstIndexBefore(node.getBody(), TokenNameRPAREN);
+ handleParenthesesPositions(lParen, rParen, this.options.parenthesis_positions_in_for_statement);
+
+ if (this.options.keep_simple_for_body_on_same_line) {
+ handleSimpleLoop(node.getBody(), this.options.alignment_for_compact_loop);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean visit(WhileStatement node) {
+ int lParen = this.tm.firstIndexIn(node, TokenNameLPAREN);
+ int rParen = this.tm.firstIndexAfter(node.getExpression(), TokenNameRPAREN);
+ handleParenthesesPositions(lParen, rParen, this.options.parenthesis_positions_in_if_while_statement);
+
+ if (this.options.keep_simple_while_body_on_same_line) {
+ handleSimpleLoop(node.getBody(), this.options.alignment_for_compact_loop);
+ }
+ return true;
+ }
+
+ private void handleSimpleLoop(Statement body, int wrappingOption) {
+ if (!(body instanceof Block)) {
+ this.wrapIndexes.add(this.tm.firstIndexIn(body, -1));
+ this.wrapParentIndex = this.tm.firstIndexBefore(body, TokenNameRPAREN);
+ this.wrapGroupEnd = this.tm.lastIndexIn(body, -1);
+ handleWrap(wrappingOption, body.getParent());
+
+ body.accept(new ASTVisitor() {
+ @Override
+ public boolean visit(Block node) {
+ forceContinuousWrapping(node, WrapPreparator.this.tm.firstIndexIn(node, -1));
+ return false;
+ }
+ });
+ }
+ }
+
+ @Override
+ public void endVisit(DoStatement node) {
+ if (this.options.keep_simple_do_while_body_on_same_line && !(node.getBody() instanceof Block)) {
+ int whileIndex = this.tm.firstIndexAfter(node.getBody(), TokenNamewhile);
+ this.wrapIndexes.add(whileIndex);
+ this.wrapParentIndex = this.tm.lastIndexIn(node.getBody(), -1);
+ this.wrapGroupEnd = this.tm.lastIndexIn(node, -1);
+
+ int alignment = this.options.alignment_for_compact_loop;
+ for (int i = this.tm.firstIndexIn(node, -1) + 1; i < whileIndex; i++) {
+ Token token = this.tm.get(i);
+ if (token.getLineBreaksBefore() > 0 || token.getLineBreaksAfter() > 0) {
+ alignment |= Alignment.M_FORCE;
+ }
+ }
+ handleWrap(alignment, node);
+ }
+ }
+
+ @Override
+ public boolean visit(TryStatement node) {
+ if (!node.resources().isEmpty()) {
+ int lParen = this.tm.firstIndexIn(node, TokenNameLPAREN);
+ int rParen = this.tm.firstIndexBefore(node.getBody(), TokenNameRPAREN);
+ handleParenthesesPositions(lParen, rParen, this.options.parenthesis_positions_in_try_clause);
+ }
+ prepareElementsList(node.resources(), TokenNameSEMICOLON, TokenNameLPAREN);
+ handleWrap(this.options.alignment_for_resources_in_try);
+ return true;
+ }
+
+ @Override
+ public boolean visit(UnionType node) {
+ List types = node.types();
+ if (types.isEmpty()) {
+ return true;
+ }
+ if (this.options.wrap_before_or_operator_multicatch) {
+ for (Type type : types) {
+ if (this.wrapIndexes.isEmpty()) {
+ this.wrapIndexes.add(this.tm.firstIndexIn(type, -1));
+ }
+ else {
+ this.wrapIndexes.add(this.tm.firstIndexBefore(type, TokenNameOR));
+ this.secondaryWrapIndexes.add(this.tm.firstIndexIn(type, -1));
+ }
+ }
+ this.wrapParentIndex = this.tm.firstIndexBefore(node, -1);
+ while (this.tm.get(this.wrapParentIndex).isComment()) {
+ this.wrapParentIndex--;
+ }
+ this.wrapGroupEnd = this.tm.lastIndexIn(types.get(types.size() - 1), -1);
+ handleWrap(this.options.alignment_for_union_type_in_multicatch);
+ }
+ else {
+ prepareElementsList(types, TokenNameOR, TokenNameLPAREN);
+ handleWrap(this.options.alignment_for_union_type_in_multicatch);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean visit(LambdaExpression node) {
+ int lParen = this.tm.firstIndexIn(node, -1);
+ if (this.tm.get(lParen).tokenType == TokenNameLPAREN) {
+ int rParen = this.tm.firstIndexBefore(node.getBody(), TokenNameRPAREN);
+ handleParenthesesPositions(lParen, rParen, this.options.parenthesis_positions_in_lambda_declaration);
+ }
+ if (node.getBody() instanceof Block) {
+ forceContinuousWrapping(node.getBody(), this.tm.firstIndexIn(node, -1));
+
+ List statements = ((Block) node.getBody()).statements();
+ if (!statements.isEmpty()) {
+ int openBraceIndex = this.tm.firstIndexBefore(statements.get(0), TokenNameLBRACE);
+ int closeBraceIndex = this.tm.firstIndexAfter(statements.get(statements.size() - 1), TokenNameRBRACE);
+ boolean areKeptOnOneLine = this.tm.stream().skip(openBraceIndex + 1)
+ .limit(closeBraceIndex - openBraceIndex - 1)
+ .allMatch(t -> t.getLineBreaksBefore() == 0 && t.getLineBreaksAfter() == 0);
+ if (areKeptOnOneLine) {
+ for (Statement statement : statements) {
+ this.wrapIndexes.add(this.tm.firstIndexIn(statement, -1));
+ }
+ this.wrapParentIndex = openBraceIndex;
+ this.wrapGroupEnd = closeBraceIndex;
+ handleWrap(Alignment.M_ONE_PER_LINE_SPLIT, node);
+ this.tm.get(closeBraceIndex).setWrapPolicy(new WrapPolicy(WrapMode.TOP_PRIORITY, openBraceIndex,
+ closeBraceIndex, 0, this.currentDepth, 1, false, false));
+ }
+ }
+ }
+ if (node.hasParentheses()) {
+ List parameters = node.parameters();
+ // the legacy formatter didn't like wrapping lambda parameters, so neither do
+ // we
+ this.currentDepth++;
+ handleArguments(parameters, this.options.alignment_for_parameters_in_method_declaration);
+ this.currentDepth--;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean visit(FieldDeclaration node) {
+ handleAnnotations(node.modifiers(), this.options.alignment_for_annotations_on_field);
+ handleVariableDeclarations(node.fragments());
+ return true;
+ }
+
+ @Override
+ public boolean visit(VariableDeclarationStatement node) {
+ handleAnnotations(node.modifiers(), this.options.alignment_for_annotations_on_local_variable);
+ handleVariableDeclarations(node.fragments());
+ return true;
+ }
+
+ @Override
+ public boolean visit(VariableDeclarationExpression node) {
+ handleAnnotations(node.modifiers(), this.options.alignment_for_annotations_on_local_variable);
+ handleVariableDeclarations(node.fragments());
+ return true;
+ }
+
+ @Override
+ public boolean visit(SingleVariableDeclaration node) {
+ handleAnnotations(node.modifiers(),
+ node.getParent() instanceof EnhancedForStatement
+ ? this.options.alignment_for_annotations_on_local_variable
+ : this.options.alignment_for_annotations_on_parameter);
+ return true;
+ }
+
+ @Override
+ public boolean visit(ParameterizedType node) {
+ prepareElementsList(node.typeArguments(), TokenNameCOMMA, TokenNameLESS);
+ handleWrap(this.options.alignment_for_parameterized_type_references);
+ return true;
+ }
+
+ @Override
+ public boolean visit(TypeMethodReference node) {
+ handleTypeArguments(node.typeArguments());
+ return true;
+ }
+
+ @Override
+ public boolean visit(ExpressionMethodReference node) {
+ handleTypeArguments(node.typeArguments());
+ return true;
+ }
+
+ @Override
+ public boolean visit(SuperMethodReference node) {
+ handleTypeArguments(node.typeArguments());
+ return true;
+ }
+
+ @Override
+ public boolean visit(CreationReference node) {
+ handleTypeArguments(node.typeArguments());
+ return true;
+ }
+
+ private void handleTypeArguments(List typeArguments) {
+ if (typeArguments.isEmpty()) {
+ return;
+ }
+ prepareElementsList(typeArguments, TokenNameCOMMA, TokenNameLESS);
+ handleWrap(this.options.alignment_for_type_arguments);
+ }
+
+ @Override
+ public boolean visit(ExportsDirective node) {
+ handleModuleStatement(node.modules(), TokenNameto);
+ return true;
+ }
+
+ @Override
+ public boolean visit(OpensDirective node) {
+ handleModuleStatement(node.modules(), TokenNameto);
+ return true;
+ }
+
+ @Override
+ public boolean visit(ProvidesDirective node) {
+ handleModuleStatement(node.implementations(), TokenNamewith);
+ return true;
+ }
+
+ private void handleModuleStatement(List names, int joiningTokenType) {
+ if (names.isEmpty()) {
+ return;
+ }
+ int joiningTokenIndex = this.tm.firstIndexBefore(names.get(0), joiningTokenType);
+ this.wrapParentIndex = this.tm.firstIndexBefore(names.get(0), TokenNameIdentifier);
+ this.wrapIndexes.add(joiningTokenIndex);
+ prepareElementsList(names, TokenNameCOMMA, -1);
+ handleWrap(this.options.alignment_for_module_statements, PREFERRED);
+ }
+
+ @Override
+ public boolean visit(CatchClause node) {
+ int lParen = this.tm.firstIndexIn(node, TokenNameLPAREN);
+ int rParen = this.tm.firstIndexBefore(node.getBody(), TokenNameRPAREN);
+ handleParenthesesPositions(lParen, rParen, this.options.parenthesis_positions_in_catch_clause);
+ return true;
+ }
+
+ @Override
+ public boolean visit(SwitchStatement node) {
+ int lParen = this.tm.firstIndexIn(node, TokenNameLPAREN);
+ int rParen = this.tm.firstIndexAfter(node.getExpression(), TokenNameRPAREN);
+ handleParenthesesPositions(lParen, rParen, this.options.parenthesis_positions_in_switch_statement);
+ return true;
+ }
+
+ @Override
+ public boolean visit(SwitchExpression node) {
+ int lParen = this.tm.firstIndexIn(node, TokenNameLPAREN);
+ int rParen = this.tm.firstIndexAfter(node.getExpression(), TokenNameRPAREN);
+ handleParenthesesPositions(lParen, rParen, this.options.parenthesis_positions_in_switch_statement);
+ return true;
+ }
+
+ @Override
+ public boolean visit(DoStatement node) {
+ int lParen = this.tm.firstIndexBefore(node.getExpression(), TokenNameLPAREN);
+ int rParen = this.tm.firstIndexAfter(node.getExpression(), TokenNameRPAREN);
+ handleParenthesesPositions(lParen, rParen, this.options.parenthesis_positions_in_if_while_statement);
+ return true;
+ }
+
+ @Override
+ public boolean visit(AssertStatement node) {
+ Expression message = node.getMessage();
+ if (message != null) {
+ int atColon = this.tm.firstIndexBefore(message, TokenNameCOLON);
+ int afterColon = this.tm.firstIndexIn(message, -1);
+ if (this.options.wrap_before_assertion_message_operator) {
+ this.wrapIndexes.add(atColon);
+ this.secondaryWrapIndexes.add(afterColon);
+ }
+ else {
+ this.wrapIndexes.add(afterColon);
+ this.secondaryWrapIndexes.add(atColon);
+ }
+ this.wrapParentIndex = this.tm.firstIndexIn(node, -1);
+ this.wrapGroupEnd = this.tm.lastIndexIn(node, -1);
+ handleWrap(this.options.alignment_for_assertion_message);
+ }
+ return true;
+ }
+
+ /**
+ * Makes sure all new lines within given node will have wrap policy so that wrap
+ * executor will fix their indentation if necessary.
+ */
+ void forceContinuousWrapping(ASTNode node, int parentIndex) {
+ int parentIndent = this.tm.get(parentIndex).getIndent();
+ int indentChange = -parentIndent;
+ int lineStart = this.tm.findFirstTokenInLine(parentIndex);
+ for (int i = parentIndex; i >= lineStart; i--) {
+ int align = this.tm.get(i).getAlign();
+ if (align > 0) {
+ indentChange = -2 * parentIndent + align;
+ break;
+ }
+ }
+
+ Token previous = null;
+ int from = this.tm.firstIndexIn(node, -1);
+ int to = this.tm.lastIndexIn(node, -1);
+ for (int i = from; i <= to; i++) {
+ Token token = this.tm.get(i);
+ if ((token.getLineBreaksBefore() > 0 || (previous != null && previous.getLineBreaksAfter() > 0))
+ && (token.getWrapPolicy() == null || token.getWrapPolicy().wrapMode == WrapMode.BLOCK_INDENT)) {
+ int extraIndent = token.getIndent() + indentChange;
+ token.setWrapPolicy(new WrapPolicy(WrapMode.BLOCK_INDENT, parentIndex, extraIndent));
+ token.setIndent(parentIndent + extraIndent);
+ }
+ previous = token;
+ }
+ }
+
+ private void handleVariableDeclarations(List fragments) {
+ if (fragments.size() > 1) {
+ this.wrapParentIndex = this.tm.firstIndexIn(fragments.get(0), -1);
+ prepareElementsList(fragments, TokenNameCOMMA, -1);
+ this.wrapIndexes.remove(0);
+ handleWrap(this.options.alignment_for_multiple_fields);
+ }
+ }
+
+ private void handleArguments(List extends ASTNode> arguments, int wrappingOption) {
+ this.wrapPenalties.add(1 / PREFERRED);
+ prepareElementsList(arguments, TokenNameCOMMA, TokenNameLPAREN);
+ handleWrap(wrappingOption);
+ }
+
+ private void handleAnnotations(List extends IExtendedModifier> modifiers, int wrappingOption) {
+ Annotation last = null;
+ int i;
+ for (i = 0; i < modifiers.size(); i++) {
+ if (modifiers.get(i).isModifier()) {
+ break;
+ }
+ Annotation annotation = (Annotation) modifiers.get(i);
+ if (i == 0) {
+ this.wrapParentIndex = this.tm.firstIndexIn(annotation, -1);
+ }
+ else {
+ this.wrapIndexes.add(this.tm.firstIndexIn(annotation, -1));
+ this.wrapGroupEnd = this.tm.lastIndexIn(annotation, -1);
+ }
+ last = annotation;
+ }
+ handleWrap(wrappingOption, last);
+
+ if (i < modifiers.size()) {
+ // any annotations following other modifiers will be associated with
+ // declaration type
+ handleAnnotations(modifiers.subList(i + 1, modifiers.size()), this.options.alignment_for_type_annotations);
+ }
+ }
+
+ private void prepareElementsList(List extends ASTNode> elements, int separatorType, int wrapParentType) {
+ for (int i = 0; i < elements.size(); i++) {
+ ASTNode element = elements.get(i);
+ this.wrapIndexes.add(this.tm.firstIndexIn(element, -1));
+ if (i > 0) {
+ this.secondaryWrapIndexes.add(this.tm.firstIndexBefore(element, separatorType));
+ }
+ }
+ // wrapIndexes may have been filled with additional values even if arguments is
+ // empty
+ if (!this.wrapIndexes.isEmpty()) {
+ Token firstToken = this.tm.get(this.wrapIndexes.get(0));
+ if (this.wrapParentIndex < 0) {
+ this.wrapParentIndex = this.tm.findIndex(firstToken.originalStart - 1, wrapParentType, false);
+ }
+ if (!elements.isEmpty() && this.wrapGroupEnd < 0) {
+ this.wrapGroupEnd = this.tm.lastIndexIn(elements.get(elements.size() - 1), -1);
+ }
+ }
+ }
+
+ private void handleWrap(int wrappingOption) {
+ handleWrap(wrappingOption, null);
+ }
+
+ private void handleWrap(int wrappingOption, float firstPenaltyMultiplier) {
+ this.wrapPenalties.add(firstPenaltyMultiplier);
+ handleWrap(wrappingOption, null);
+ }
+
+ private void handleWrap(int wrappingOption, ASTNode parentNode) {
+ handleWrap(wrappingOption, true, parentNode);
+ }
+
+ private void handleWrap(int wrappingOption, boolean wrapPreceedingComments, ASTNode parentNode) {
+ doHandleWrap(wrappingOption, wrapPreceedingComments, parentNode);
+ this.wrapIndexes.clear();
+ this.secondaryWrapIndexes.clear();
+ this.wrapPenalties.clear();
+ this.wrapParentIndex = this.wrapGroupEnd = -1;
+ }
+
+ private void doHandleWrap(int wrappingOption, boolean wrapPreceedingComments, ASTNode parentNode) {
+ if (this.wrapIndexes.isEmpty()) {
+ return;
+ }
+ assert this.wrapParentIndex >= 0 && this.wrapParentIndex < this.wrapIndexes.get(0);
+ assert this.wrapGroupEnd >= this.wrapIndexes.get(this.wrapIndexes.size() - 1);
+
+ while (this.tm.get(this.wrapParentIndex).isComment() && this.wrapParentIndex > 0) {
+ this.wrapParentIndex--;
+ }
+
+ float penalty = this.wrapPenalties.isEmpty() ? 1 : this.wrapPenalties.get(0);
+ WrapPolicy policy = getWrapPolicy(wrappingOption, penalty, true, parentNode);
+
+ WrapPolicy existing = this.tm.get(this.wrapIndexes.get(0)).getWrapPolicy();
+ if (existing != null && existing.wrapMode == WrapMode.TOP_PRIORITY) {
+ // SEPARATE_LINES_IF_WRAPPED
+ assert existing.wrapParentIndex == this.wrapParentIndex;
+ this.wrapGroupEnd = existing.groupEndIndex;
+ policy = new WrapPolicy(WrapMode.TOP_PRIORITY, policy.wrapParentIndex, this.wrapGroupEnd,
+ policy.extraIndent, policy.structureDepth, policy.penaltyMultiplier, true, policy.indentOnColumn);
+ }
+
+ setTokenWrapPolicy(0, policy, true);
+
+ for (int i = 1; i < this.wrapIndexes.size(); i++) {
+ penalty = this.wrapPenalties.size() > i ? this.wrapPenalties.get(i) : 1;
+ if (penalty != policy.penaltyMultiplier || i == 1) {
+ policy = getWrapPolicy(wrappingOption, penalty, false, parentNode);
+ }
+ setTokenWrapPolicy(i, policy, wrapPreceedingComments);
+ }
+
+ if (!this.secondaryWrapIndexes.isEmpty()) {
+ int optionNoAlignment = (wrappingOption & ~Alignment.SPLIT_MASK) | Alignment.M_NO_ALIGNMENT;
+ policy = getWrapPolicy(optionNoAlignment, 1, false, parentNode);
+ for (int index : this.secondaryWrapIndexes) {
+ Token token = this.tm.get(index);
+ if (token.getWrapPolicy() == null) {
+ token.setWrapPolicy(policy);
+ }
+ }
+ }
+ }
+
+ private void setTokenWrapPolicy(int wrapIndexesIndex, WrapPolicy policy, boolean wrapPreceedingComments) {
+ int index = this.wrapIndexes.get(wrapIndexesIndex);
+ if (wrapPreceedingComments) {
+ for (int i = index - 1; i >= 0; i--) {
+ Token previous = this.tm.get(i);
+ if (!previous.isComment()) {
+ break;
+ }
+ if (previous.getWrapPolicy() == WrapPolicy.FORCE_FIRST_COLUMN) {
+ break;
+ }
+ if (previous.getLineBreaksAfter() == 0 && i == index - 1) {
+ index = i;
+ }
+ if (previous.getLineBreaksBefore() > 0) {
+ previous.setWrapPolicy(policy);
+ }
+ }
+ this.wrapIndexes.set(wrapIndexesIndex, index);
+ }
+
+ Token token = this.tm.get(index);
+ if (token.getWrapPolicy() == WrapPolicy.DISABLE_WRAP) {
+ return;
+ }
+
+ token.setWrapPolicy(policy);
+ if (policy.wrapMode == WrapMode.FORCE) {
+ token.breakBefore();
+ }
+ else if (this.options.join_wrapped_lines && token.tokenType == TokenNameCOMMENT_BLOCK) {
+ // allow wrap preparator to decide if this comment should be wrapped
+ token.clearLineBreaksBefore();
+ }
+ }
+
+ private WrapPolicy getWrapPolicy(int wrappingOption, float penaltyMultiplier, boolean isFirst, ASTNode parentNode) {
+ assert this.wrapParentIndex >= 0 && this.wrapGroupEnd >= 0;
+ int extraIndent = this.options.continuation_indentation;
+ boolean indentOnColumn = (wrappingOption & Alignment.M_INDENT_ON_COLUMN) != 0;
+ boolean isForceWrap = (wrappingOption & Alignment.M_FORCE) != 0;
+ boolean isAlreadyWrapped = false;
+ if (indentOnColumn) {
+ extraIndent = 0;
+ }
+ else if (parentNode instanceof Annotation) {
+ extraIndent = 0;
+ }
+ else if (parentNode instanceof EnumDeclaration) {
+ // special behavior for compatibility with legacy formatter
+ extraIndent = ((wrappingOption & Alignment.M_INDENT_BY_ONE) != 0) ? 2 : 1;
+ if (!this.options.indent_body_declarations_compare_to_enum_declaration_header) {
+ extraIndent--;
+ }
+ isAlreadyWrapped = isFirst;
+ }
+ else if (parentNode instanceof IfStatement || parentNode instanceof ForStatement
+ || parentNode instanceof EnhancedForStatement || parentNode instanceof WhileStatement) {
+ extraIndent = 1;
+ this.wrapParentIndex = this.tm.firstIndexIn(parentNode, -1); // only if
+ // !indoentOnColumn
+ }
+ else if (parentNode instanceof DoStatement) {
+ extraIndent = 0;
+ this.wrapParentIndex = this.tm.firstIndexIn(parentNode, -1); // only if
+ // !indoentOnColumn
+ }
+ else if (parentNode instanceof LambdaExpression) {
+ extraIndent = 1;
+ }
+ else if ((wrappingOption & Alignment.M_INDENT_BY_ONE) != 0) {
+ extraIndent = 1;
+ }
+ else if (parentNode instanceof ArrayInitializer) {
+ extraIndent = this.options.continuation_indentation_for_array_initializer;
+ isAlreadyWrapped = isFirst && this.options.insert_new_line_after_opening_brace_in_array_initializer;
+ }
+
+ WrapMode wrapMode = WrapMode.WHERE_NECESSARY;
+ boolean isTopPriority = false;
+ switch (wrappingOption & Alignment.SPLIT_MASK) {
+ case Alignment.M_NO_ALIGNMENT:
+ wrapMode = WrapMode.DISABLED;
+ isForceWrap = false;
+ break;
+ case Alignment.M_COMPACT_FIRST_BREAK_SPLIT:
+ isTopPriority = isFirst;
+ isForceWrap &= isFirst;
+ break;
+ case Alignment.M_ONE_PER_LINE_SPLIT:
+ isTopPriority = true;
+ break;
+ case Alignment.M_NEXT_SHIFTED_SPLIT:
+ isTopPriority = true;
+ if (!isFirst) {
+ extraIndent++;
+ }
+ break;
+ case Alignment.M_NEXT_PER_LINE_SPLIT:
+ isTopPriority = !isFirst;
+ isForceWrap &= !isFirst;
+ break;
+ }
+
+ if (isForceWrap) {
+ wrapMode = WrapMode.FORCE;
+ }
+ else if (isAlreadyWrapped) {
+ wrapMode = WrapMode.DISABLED; // to avoid triggering top priority wrapping
+ }
+ else if (isTopPriority) {
+ wrapMode = WrapMode.TOP_PRIORITY;
+ }
+ extraIndent *= this.options.indentation_size;
+ return new WrapPolicy(wrapMode, this.wrapParentIndex, this.wrapGroupEnd, extraIndent, this.currentDepth,
+ penaltyMultiplier, isFirst, indentOnColumn);
+ }
+
+ public void finishUp(ASTNode astRoot, List regions) {
+ preserveExistingLineBreaks();
+ applyBreaksOutsideRegions(regions);
+ new WrapExecutor(this.tm, this.options, regions).executeWraps();
+ this.aligner.alignComments();
+ wrapComments();
+ fixEnumConstantIndents(astRoot);
+ }
+
+ private void preserveExistingLineBreaks() {
+ // normally n empty lines = n+1 line breaks, but not at the file start and end
+ Token first = this.tm.get(0);
+ int startingBreaks = first.getLineBreaksBefore();
+ first.clearLineBreaksBefore();
+ first.putLineBreaksBefore(startingBreaks - 1);
+
+ this.tm.traverse(0, new TokenTraverser() {
+ boolean join_wrapped_lines = WrapPreparator.this.options.join_wrapped_lines;
+
+ @Override
+ protected boolean token(Token token, int index) {
+ int lineBreaks = getLineBreaksToPreserve(getPrevious(), token);
+ if (lineBreaks > 1 || (!this.join_wrapped_lines && token.isWrappable()) || index == 0) {
+ token.putLineBreaksBefore(lineBreaks);
+ }
+ return true;
+ }
+
+ });
+
+ Token last = this.tm.get(this.tm.size() - 1);
+ last.clearLineBreaksAfter();
+ int endingBreaks = getLineBreaksToPreserve(last, null);
+ if (endingBreaks > 0) {
+ last.putLineBreaksAfter(endingBreaks);
+ }
+ else if ((this.kind & (CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.K_MODULE_INFO)) != 0
+ && this.options.insert_new_line_at_end_of_file_if_missing) {
+ last.breakAfter();
+ }
+ }
+
+ int getLineBreaksToPreserve(Token token1, Token token2) {
+ if ((token1 != null && !token1.isPreserveLineBreaksAfter())
+ || (token2 != null && !token2.isPreserveLineBreaksBefore())) {
+ return 0;
+ }
+ if (token1 != null) {
+ List structure = token1.getInternalStructure();
+ if (structure != null && !structure.isEmpty()) {
+ token1 = structure.get(structure.size() - 1);
+ }
+ }
+ if (token2 != null) {
+ List structure = token2.getInternalStructure();
+ if (structure != null && !structure.isEmpty()) {
+ token2 = structure.get(0);
+ }
+ }
+ int lineBreaks = WrapPreparator.this.tm.countLineBreaksBetween(token1, token2);
+ int toPreserve = this.options.number_of_empty_lines_to_preserve;
+ if (token1 != null && token2 != null) {
+ toPreserve++; // n empty lines = n+1 line breaks, except for file start and
+ // end
+ }
+ return Math.min(lineBreaks, toPreserve);
+ }
+
+ private void applyBreaksOutsideRegions(List regions) {
+ String source = this.tm.getSource();
+ int previousRegionEnd = 0;
+ for (IRegion region : regions) {
+ int index = this.tm.findIndex(previousRegionEnd, -1, true);
+ Token token = this.tm.get(index);
+ if (this.tm.countLineBreaksBetween(source, previousRegionEnd,
+ Math.min(token.originalStart, region.getOffset())) > 0) {
+ token.breakBefore();
+ }
+ for (index++; index < this.tm.size(); index++) {
+ Token next = this.tm.get(index);
+ if (next.originalStart > region.getOffset()) {
+ if (this.tm.countLineBreaksBetween(source, token.originalEnd, region.getOffset()) > 0) {
+ next.breakBefore();
+ }
+ break;
+ }
+ if (this.tm.countLineBreaksBetween(token, next) > 0) {
+ next.breakBefore();
+ }
+ token = next;
+ }
+ previousRegionEnd = region.getOffset() + region.getLength() - 1;
+ }
+ }
+
+ private void wrapComments() {
+ CommentWrapExecutor commentWrapper = new CommentWrapExecutor(this.tm, this.options);
+ boolean isNLSTagInLine = false;
+ for (int i = 0; i < this.tm.size(); i++) {
+ Token token = this.tm.get(i);
+ if (token.getLineBreaksBefore() > 0 || token.getLineBreaksAfter() > 0) {
+ isNLSTagInLine = false;
+ }
+ if (token.hasNLSTag()) {
+ assert token.tokenType == TokenNameStringLiteral;
+ isNLSTagInLine = true;
+ }
+ List structure = token.getInternalStructure();
+ if (token.isComment() && structure != null && !structure.isEmpty() && !isNLSTagInLine) {
+ int startPosition = this.tm.getPositionInLine(i);
+ if (token.tokenType == TokenNameCOMMENT_LINE) {
+ commentWrapper.wrapLineComment(token, startPosition);
+ }
+ else {
+ assert token.tokenType == TokenNameCOMMENT_BLOCK || token.tokenType == TokenNameCOMMENT_JAVADOC;
+ commentWrapper.wrapMultiLineComment(token, startPosition, false, false);
+ }
+ }
+ }
+ }
+
+ private void fixEnumConstantIndents(ASTNode astRoot) {
+ if (this.options.use_tabs_only_for_leading_indentations) {
+ // enum constants should be indented like other declarations, not like wrapped
+ // elements
+ astRoot.accept(new ASTVisitor() {
+
+ @Override
+ public boolean visit(EnumConstantDeclaration node) {
+ WrapPreparator.this.tm.firstTokenIn(node, -1).setWrapPolicy(null);
+ return true;
+ }
+ });
+ }
+ }
+
+ private void handleParenthesesPositions(int openingParenIndex, int closingParenIndex, String positionsSetting) {
+ boolean isEmpty = openingParenIndex + 1 == closingParenIndex;
+ switch (positionsSetting) {
+ case DefaultCodeFormatterConstants.COMMON_LINES:
+ // nothing to do
+ break;
+ case DefaultCodeFormatterConstants.SEPARATE_LINES_IF_WRAPPED:
+ if (isEmpty) {
+ break;
+ }
+ this.tm.get(openingParenIndex + 1).setWrapPolicy(new WrapPolicy(WrapMode.TOP_PRIORITY, openingParenIndex,
+ closingParenIndex, this.options.indentation_size, this.currentDepth, 1, true, false));
+ this.tm.get(closingParenIndex).setWrapPolicy(new WrapPolicy(WrapMode.TOP_PRIORITY, openingParenIndex,
+ closingParenIndex, 0, this.currentDepth, 1, false, false));
+ break;
+ case DefaultCodeFormatterConstants.SEPARATE_LINES_IF_NOT_EMPTY:
+ if (isEmpty) {
+ break;
+ }
+ //$FALL-THROUGH$
+ case DefaultCodeFormatterConstants.SEPARATE_LINES:
+ case DefaultCodeFormatterConstants.PRESERVE_POSITIONS:
+ boolean always = !positionsSetting.equals(DefaultCodeFormatterConstants.PRESERVE_POSITIONS);
+ Token afterOpening = this.tm.get(openingParenIndex + 1);
+ if (always || this.tm.countLineBreaksBetween(this.tm.get(openingParenIndex), afterOpening) > 0) {
+ afterOpening.setWrapPolicy(
+ new WrapPolicy(WrapMode.WHERE_NECESSARY, openingParenIndex, this.options.indentation_size));
+ afterOpening.breakBefore();
+ }
+ Token closingParen = this.tm.get(closingParenIndex);
+ if (always || this.tm.countLineBreaksBetween(this.tm.get(closingParenIndex - 1), closingParen) > 0) {
+ closingParen.setWrapPolicy(new WrapPolicy(WrapMode.WHERE_NECESSARY, openingParenIndex, 0));
+ closingParen.breakBefore();
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Unrecognized parentheses positions setting: " + positionsSetting); //$NON-NLS-1$
+ }
+ }
+
+ // @formatter:on
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-rewriter/pom.xml b/spring-javaformat/spring-javaformat-formatter-eclipse-rewriter/pom.xml
index 9393de03..9be11ea0 100644
--- a/spring-javaformat/spring-javaformat-formatter-eclipse-rewriter/pom.xml
+++ b/spring-javaformat/spring-javaformat-formatter-eclipse-rewriter/pom.xml
@@ -5,7 +5,7 @@
io.spring.javaformatspring-javaformat
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTspring-javaformat-formatter-eclipse-rewriterSpring JavaFormat Eclipse Rewriter
diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-rewriter/src/main/java/io/spring/javaformat/formatter/eclipse/rewrite/EclipseRewriter.java b/spring-javaformat/spring-javaformat-formatter-eclipse-rewriter/src/main/java/io/spring/javaformat/formatter/eclipse/rewrite/EclipseRewriter.java
index 232f1d25..7053dc0c 100644
--- a/spring-javaformat/spring-javaformat-formatter-eclipse-rewriter/src/main/java/io/spring/javaformat/formatter/eclipse/rewrite/EclipseRewriter.java
+++ b/spring-javaformat/spring-javaformat-formatter-eclipse-rewriter/src/main/java/io/spring/javaformat/formatter/eclipse/rewrite/EclipseRewriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -77,9 +77,10 @@ private void rewrite(JdkVersion jdkVersion, FileSystem zip) throws IOException {
DefaultCodeFormatterManipulator::new);
if (jdkVersion == JdkVersion.V8) {
rewrite(zip, "org/eclipse/osgi/util/NLS$1.class", NlsJdk8Manipulator::new);
+ deleteWrapPreparator(zip);
}
else {
- rewrite(zip, "org/eclipse/osgi/util/NLS.class", NlsJdk11Manipulator::new);
+ rewrite(zip, "org/eclipse/osgi/util/NLS.class", NlsJdk17Manipulator::new);
}
}
@@ -94,6 +95,11 @@ private void rewrite(FileSystem zip, String name, Function".equals(name)) {
- return new NslJdk11MethodManipulator(super.visitMethod(access, name, desc, signature, exceptions));
+ return new NslJdk17MethodManipulator(super.visitMethod(access, name, desc, signature, exceptions));
}
return super.visitMethod(access, name, desc, signature, exceptions);
}
@@ -216,12 +222,12 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si
* {@link MethodVisitor} to update the {@code NLS} class in the JDK 8 version so it
* doesn't use a System property to disable warning messages.
*/
- private static class NslJdk11MethodManipulator extends MethodVisitor {
+ private static class NslJdk17MethodManipulator extends MethodVisitor {
private final MethodVisitor methodVisitor;
- NslJdk11MethodManipulator(MethodVisitor mv) {
- super(Opcodes.ASM7, null);
+ NslJdk17MethodManipulator(MethodVisitor mv) {
+ super(Opcodes.ASM9, null);
this.methodVisitor = mv;
}
diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/pom.xml b/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/pom.xml
index c537bd48..dab30621 100644
--- a/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/pom.xml
+++ b/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/pom.xml
@@ -6,7 +6,7 @@
io.spring.javaformatspring-javaformat
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTspring-javaformat-formatter-eclipse-runtimeSpring JavaFormat Eclipse Runtime
diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/src/main/java/org/eclipse/core/runtime/content/IContentTypeManager$ContentTypeChangeEvent.java b/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/src/main/java/org/eclipse/core/runtime/content/IContentTypeManager$ContentTypeChangeEvent.java
index 913abdea..78e9cd52 100644
--- a/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/src/main/java/org/eclipse/core/runtime/content/IContentTypeManager$ContentTypeChangeEvent.java
+++ b/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/src/main/java/org/eclipse/core/runtime/content/IContentTypeManager$ContentTypeChangeEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/src/main/java/org/eclipse/core/runtime/content/IContentTypeManager$IContentTypeChangeListener.java b/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/src/main/java/org/eclipse/core/runtime/content/IContentTypeManager$IContentTypeChangeListener.java
index 52462f79..6458ef5a 100644
--- a/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/src/main/java/org/eclipse/core/runtime/content/IContentTypeManager$IContentTypeChangeListener.java
+++ b/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/src/main/java/org/eclipse/core/runtime/content/IContentTypeManager$IContentTypeChangeListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-formatter-shaded/pom.xml b/spring-javaformat/spring-javaformat-formatter-shaded/pom.xml
index 0707ad20..330f53c9 100644
--- a/spring-javaformat/spring-javaformat-formatter-shaded/pom.xml
+++ b/spring-javaformat/spring-javaformat-formatter-shaded/pom.xml
@@ -6,7 +6,7 @@
io.spring.javaformatspring-javaformat
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTspring-javaformat-formatter-shadedSpring JavaFormat Formatter Shaded
@@ -80,6 +80,11 @@
+
+
+ ${project.version}
+
+
diff --git a/spring-javaformat/spring-javaformat-formatter-shader/.factorypath b/spring-javaformat/spring-javaformat-formatter-shader/.factorypath
deleted file mode 100644
index a157f4e2..00000000
--- a/spring-javaformat/spring-javaformat-formatter-shader/.factorypath
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-javaformat/spring-javaformat-formatter-shader/pom.xml b/spring-javaformat/spring-javaformat-formatter-shader/pom.xml
index e0c4f2dc..a07cf239 100644
--- a/spring-javaformat/spring-javaformat-formatter-shader/pom.xml
+++ b/spring-javaformat/spring-javaformat-formatter-shader/pom.xml
@@ -6,7 +6,7 @@
io.spring.javaformatspring-javaformat
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTspring-javaformat-formatter-shaderSpring JavaFormat Formatter Shader
diff --git a/spring-javaformat/spring-javaformat-formatter-shader/src/main/java/io/spring/javaformat/formatter/shader/PrefsResourceTransformer.java b/spring-javaformat/spring-javaformat-formatter-shader/src/main/java/io/spring/javaformat/formatter/shader/PrefsResourceTransformer.java
index 47ba9843..09882163 100644
--- a/spring-javaformat/spring-javaformat-formatter-shader/src/main/java/io/spring/javaformat/formatter/shader/PrefsResourceTransformer.java
+++ b/spring-javaformat/spring-javaformat-formatter-shader/src/main/java/io/spring/javaformat/formatter/shader/PrefsResourceTransformer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-formatter-test-support/pom.xml b/spring-javaformat/spring-javaformat-formatter-test-support/pom.xml
index 4f21603f..1f72a67a 100644
--- a/spring-javaformat/spring-javaformat-formatter-test-support/pom.xml
+++ b/spring-javaformat/spring-javaformat-formatter-test-support/pom.xml
@@ -6,7 +6,7 @@
io.spring.javaformatspring-javaformat
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTspring-javaformat-formatter-test-supportSpring JavaFormat Formatter Test Support
diff --git a/spring-javaformat/spring-javaformat-formatter-test-support/src/main/java/io/spring/javaformat/formatter/FormatterApp.java b/spring-javaformat/spring-javaformat-formatter-test-support/src/main/java/io/spring/javaformat/formatter/FormatterApp.java
index 9adaacc6..ca679983 100644
--- a/spring-javaformat/spring-javaformat-formatter-test-support/src/main/java/io/spring/javaformat/formatter/FormatterApp.java
+++ b/spring-javaformat/spring-javaformat-formatter-test-support/src/main/java/io/spring/javaformat/formatter/FormatterApp.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/pom.xml b/spring-javaformat/spring-javaformat-formatter-tests/pom.xml
index 3c165c98..30ea6a7e 100644
--- a/spring-javaformat/spring-javaformat-formatter-tests/pom.xml
+++ b/spring-javaformat/spring-javaformat-formatter-tests/pom.xml
@@ -6,13 +6,13 @@
io.spring.javaformatspring-javaformat
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTspring-javaformat-formatter-testsSpring JavaFormat Formatter Tests${basedir}/../..
- 11
+ 17
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/AbstractFormatterTests.java b/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/AbstractFormatterTests.java
index f039acfd..1af21b70 100644
--- a/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/AbstractFormatterTests.java
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/AbstractFormatterTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -17,10 +17,12 @@
package io.spring.javaformat.formatter;
import java.io.File;
+import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
-import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
import io.spring.javaformat.config.JavaBaseline;
import io.spring.javaformat.config.JavaFormatConfig;
@@ -47,24 +49,75 @@ protected final String read(File file) throws Exception {
}
protected static Item[] items(String expectedOverride) {
- Collection items = new ArrayList<>();
+ List items = new ArrayList<>();
File sourceDir = new File("src/test/resources/source");
File expectedDir = new File("src/test/resources/expected");
File configDir = new File("src/test/resources/config");
File expectedOverrideDir = new File("src/test/resources/" + expectedOverride);
for (File source : sourceDir.listFiles((dir, name) -> !name.startsWith("."))) {
- File expected = new File(expectedOverrideDir, source.getName());
- if (!expected.exists()) {
- expected = new File(expectedDir, source.getName());
- }
File config = new File(configDir, source.getName());
for (JavaBaseline javaBaseline : JavaBaseline.values()) {
- items.add(new Item(javaBaseline, source, expected, config));
+ File expected = getExpected(source, javaBaseline, expectedOverrideDir, expectedDir);
+ addItem(items, javaBaseline, source, expected, config);
}
}
+ items.sort(Comparator.comparing(Item::getName));
return items.toArray(new Item[0]);
}
+ private static File getExpected(File source, JavaBaseline javaBaseline, File... expectedDirs) {
+ for (File expectedDir : expectedDirs) {
+ File versionSpecificExpectedDir = new File(expectedDir, javaBaseline.toString().toLowerCase());
+ File expected = new File(versionSpecificExpectedDir, source.getName());
+ expected = (!expected.exists()) ? new File(expectedDir, source.getName()) : expected;
+ if (expected.exists()) {
+ return expected;
+ }
+ }
+ throw new IllegalStateException("Unable to find expected file");
+ }
+
+ private static void addItem(List items, JavaBaseline javaBaseline, File source, File expected, File config) {
+ if (source.getName().contains("lineendings")) {
+ items.add(new Item(javaBaseline, copy(source, LineEnding.CR), copy(expected, LineEnding.CR), config));
+ items.add(new Item(javaBaseline, copy(source, LineEnding.LF), copy(expected, LineEnding.LF), config));
+ items.add(new Item(javaBaseline, copy(source, LineEnding.CRLF), copy(expected, LineEnding.CRLF), config));
+ }
+ else {
+ items.add(new Item(javaBaseline, source, expected, config));
+ }
+ }
+
+ private static File copy(File file, LineEnding lineEnding) {
+ try {
+ String[] name = file.getName().split("\\.");
+ File result = File.createTempFile(name[0] + "_" + lineEnding + "_", "." + name[1]);
+ String content = Files.readString(file.toPath());
+ content = content.replace("\r\n", "\n").replace('\r', '\n').replace("\n", lineEnding.ending());
+ Files.writeString(result.toPath(), content);
+ return result;
+ }
+ catch (IOException ex) {
+ throw new IllegalStateException(ex);
+ }
+ }
+
+ enum LineEnding {
+
+ CR("\r"), LF("\n"), CRLF("\r\n");
+
+ private final String ending;
+
+ LineEnding(String ending) {
+ this.ending = ending;
+ }
+
+ String ending() {
+ return this.ending;
+ }
+
+ };
+
static class Item {
private final JavaBaseline javaBaseline;
@@ -88,6 +141,10 @@ private JavaFormatConfig loadConfig(JavaBaseline javaBaseline, File configFile)
return JavaFormatConfig.of(javaBaseline, config.getIndentationStyle());
}
+ String getName() {
+ return this.source.getName();
+ }
+
public File getSource() {
return this.source;
}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/FileEditTests.java b/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/FileEditTests.java
index 59c6d57a..015b9eb7 100644
--- a/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/FileEditTests.java
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/FileEditTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -51,7 +51,7 @@ public class FileEditTests {
private FileEdit fileEdit;
@BeforeEach
- public void setup() throws IOException {
+ void setup() throws IOException {
this.source = new File(this.temp, "source.txt");
this.expected = new File(this.temp, "expected.txt");
Files.copy(new File("src/test/resources/source/javadoc-top.txt").toPath(), this.source.toPath(),
@@ -64,17 +64,17 @@ public void setup() throws IOException {
}
@Test
- public void getFileShouldReturnFile() throws Exception {
+ void getFileReturnsFile() throws Exception {
assertThat(this.fileEdit.getFile()).isEqualTo(this.source);
}
@Test
- public void hasEditsWhenHasEditsShouldReturnTrue() throws Exception {
+ void hasEditsWhenHasEditsReturnsTrue() throws Exception {
assertThat(this.fileEdit.hasEdits()).isTrue();
}
@Test
- public void hasEditsWhenHasNoEditsShouldReturnFalse() throws Exception {
+ void hasEditsWhenHasNoEditsReturnsFalse() throws Exception {
String content = read(this.expected);
this.textEdit = new Formatter().format(content);
this.fileEdit = new FileEdit(this.source, UTF_8, content, this.textEdit);
@@ -82,7 +82,7 @@ public void hasEditsWhenHasNoEditsShouldReturnFalse() throws Exception {
}
@Test
- public void saveShouldSaveContent() throws Exception {
+ void saveSavesContent() throws Exception {
String expected = read(this.expected);
assertThat(read(this.source)).isNotEqualTo(expected);
this.fileEdit.save();
@@ -90,7 +90,7 @@ public void saveShouldSaveContent() throws Exception {
}
@Test
- public void getFormattedContentShouldReturnFormattedContent() throws Exception {
+ void getFormattedContentReturnsFormattedContent() throws Exception {
String expected = read(this.expected);
assertThat(this.fileEdit.getFormattedContent()).isEqualTo(expected);
}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/FileFormatterTests.java b/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/FileFormatterTests.java
index dc49c4f6..f9d14f7c 100644
--- a/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/FileFormatterTests.java
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/FileFormatterTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -36,23 +36,27 @@ public class FileFormatterTests extends AbstractFormatterTests {
@ParameterizedTest
@MethodSource("items")
- public void formatFilesFromIteratorShouldFormatFile(Item item) throws Exception {
+ void formatFilesFromIteratorFormatsFile(Item item) throws Exception {
FileEdit edit = new FileFormatter(item.getConfig())
- .formatFiles(Arrays.asList(item.getSource()), StandardCharsets.UTF_8).findFirst().get();
+ .formatFiles(Arrays.asList(item.getSource()), StandardCharsets.UTF_8)
+ .findFirst()
+ .get();
assertThat(edit.getFormattedContent()).isEqualTo(read(item.getExpected()));
}
@ParameterizedTest
@MethodSource("items")
- public void formatFilesFromStreamShouldFormatFile(Item item) throws Exception {
+ void formatFilesFromStreamFormatsFile(Item item) throws Exception {
FileEdit edit = new FileFormatter(item.getConfig())
- .formatFiles(Arrays.asList(item.getSource()).stream(), StandardCharsets.UTF_8).findFirst().get();
+ .formatFiles(Arrays.asList(item.getSource()).stream(), StandardCharsets.UTF_8)
+ .findFirst()
+ .get();
assertThat(edit.getFormattedContent()).isEqualTo(read(item.getExpected()));
}
@ParameterizedTest
@MethodSource("items")
- public void formatFileShouldFormatFile(Item item) throws Exception {
+ void formatFileFormatsFile(Item item) throws Exception {
File source = item.getSource();
FileEdit edit = new FileFormatter(item.getConfig()).formatFile(source, StandardCharsets.UTF_8);
String formattedContent = edit.getFormattedContent();
@@ -68,7 +72,7 @@ public void formatFileShouldFormatFile(Item item) throws Exception {
assertThat(formattedContent).isEqualTo(expected);
}
- public static Item[] items() {
+ static Item[] items() {
return items(null);
}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/FormatterIntegrationTests.java b/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/FormatterIntegrationTests.java
index 80abe8ef..383b07cd 100644
--- a/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/FormatterIntegrationTests.java
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/FormatterIntegrationTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -54,16 +54,16 @@ void formatCodeWithV8BaselineCanFormatOnAllVersions(String version) throws Excep
}
@ParameterizedTest
- @ValueSource(strings = { "11", "17" })
+ @ValueSource(strings = { "17" })
void formatCodeWithV11BaselineCanFormatOn11OrHigher(String version) throws Exception {
- runFormatter(JavaBaseline.V11, version);
+ runFormatter(JavaBaseline.V17, version);
}
@ParameterizedTest
@ValueSource(strings = "8")
void formatCodeWithV11BaselineCannotFormatOn8(String version) throws Exception {
assertThatExceptionOfType(ContainerLaunchException.class)
- .isThrownBy(() -> runFormatter(JavaBaseline.V11, version));
+ .isThrownBy(() -> runFormatter(JavaBaseline.V17, version));
}
private void runFormatter(JavaBaseline baseline, String version) throws IOException, Exception {
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/FormatterTests.java b/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/FormatterTests.java
index e5db7baf..cc1c8b50 100644
--- a/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/FormatterTests.java
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/FormatterTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -33,7 +33,7 @@ public class FormatterTests extends AbstractFormatterTests {
@ParameterizedTest
@MethodSource("items")
- public void format(Item item) throws Exception {
+ void format(Item item) throws Exception {
String sourceContent = read(item.getSource());
String expectedContent = read(item.getExpected());
String formattedContent = format(item.getConfig(), sourceContent);
@@ -43,8 +43,8 @@ public void format(Item item) throws Exception {
print("Expected +" + item.getExpected(), expectedContent);
print("Got", formattedContent);
System.out.println("========================================");
- assertThat(expectedContent).isEqualTo(formattedContent)
- .describedAs("Formatted content does not match for " + item.getSource());
+ assertThat(formattedContent).isEqualTo(expectedContent)
+ .describedAs("Formatted content does not match for " + item.getSource());
}
}
@@ -55,7 +55,7 @@ private String format(JavaFormatConfig config, String sourceContent) throws Exce
return document.get();
}
- public static Item[] items() {
+ static Item[] items() {
return items("FormatterTests-expected");
}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/JavaContainer.java b/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/JavaContainer.java
index 9632f95e..8f847bbb 100644
--- a/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/JavaContainer.java
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/JavaContainer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -25,7 +25,7 @@
*/
public class JavaContainer extends GenericContainer {
- public JavaContainer(String version) {
+ JavaContainer(String version) {
super("bellsoft/liberica-openjdk-debian:" + version);
}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/StreamsEditTests.java b/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/StreamsEditTests.java
new file mode 100644
index 00000000..b054f57d
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/StreamsEditTests.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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 io.spring.javaformat.formatter;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+
+import org.eclipse.text.edits.TextEdit;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for {@link StreamsEdit}.
+ *
+ * @author Phillip Webb
+ */
+public class StreamsEditTests {
+
+ private static final Charset UTF_8 = StandardCharsets.UTF_8;
+
+ @TempDir
+ public File temp;
+
+ private File source;
+
+ private File expected;
+
+ private TextEdit textEdit;
+
+ private StreamsEdit streamsEdit;
+
+ @BeforeEach
+ void setup() throws IOException {
+ this.source = new File(this.temp, "source.txt");
+ this.expected = new File(this.temp, "expected.txt");
+ Files.copy(new File("src/test/resources/source/javadoc-top.txt").toPath(), this.source.toPath(),
+ StandardCopyOption.REPLACE_EXISTING);
+ Files.copy(new File("src/test/resources/expected/javadoc-top.txt").toPath(), this.expected.toPath(),
+ StandardCopyOption.REPLACE_EXISTING);
+ String content = read(this.source);
+ this.textEdit = new Formatter().format(content);
+ this.streamsEdit = new StreamsEdit(content, this.textEdit);
+ }
+
+ @Test
+ void hasEditsWhenHasEditsReturnsTrue() throws Exception {
+ assertThat(this.streamsEdit.hasEdits()).isTrue();
+ }
+
+ @Test
+ void hasEditsWhenHasNoEditsReturnsFalse() throws Exception {
+ String content = read(this.expected);
+ this.textEdit = new Formatter().format(content);
+ this.streamsEdit = new StreamsEdit(content, this.textEdit);
+ assertThat(this.streamsEdit.hasEdits()).isFalse();
+ }
+
+ @Test
+ void writeToOutputStreamWritesContent() throws Exception {
+ String expected = read(this.expected);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ this.streamsEdit.writeTo(outputStream);
+ assertThat(outputStream.toByteArray()).isEqualTo(expected.getBytes(UTF_8));
+ }
+
+ @Test
+ void writeToOutputStreamWithCharsetWritesContent() throws IOException {
+ String expected = read(this.expected);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ this.streamsEdit.writeTo(outputStream, UTF_8);
+ assertThat(outputStream.toByteArray()).isEqualTo(expected.getBytes(UTF_8));
+ }
+
+ @Test
+ void writeToAppendableWritesContent() throws IOException {
+ String expected = read(this.expected);
+ StringBuilder output = new StringBuilder();
+ this.streamsEdit.writeTo(output);
+ assertThat(output.toString()).isEqualTo(expected);
+ }
+
+ @Test
+ void getFormattedContentReturnsFormattedContent() throws Exception {
+ String expected = read(this.expected);
+ assertThat(this.streamsEdit.getFormattedContent()).isEqualTo(expected);
+ }
+
+ private String read(File file) throws IOException {
+ return new String(Files.readAllBytes(file.toPath()), UTF_8);
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/StreamsFormatterTests.java b/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/StreamsFormatterTests.java
new file mode 100644
index 00000000..388c123c
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/StreamsFormatterTests.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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 io.spring.javaformat.formatter;
+
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for {@link StreamsFormatter}.
+ *
+ * @author Phillip Webb
+ */
+public class StreamsFormatterTests extends AbstractFormatterTests {
+
+ @ParameterizedTest
+ @MethodSource("items")
+ void formatInputStreamFormatsFile(Item item) throws Exception {
+ try (InputStream inputStream = new FileInputStream(item.getSource())) {
+ StreamsEdit edit = new StreamsFormatter(item.getConfig()).format(inputStream);
+ assertThat(edit.getFormattedContent()).isEqualTo(read(item.getExpected()));
+ }
+ }
+
+ @ParameterizedTest
+ @MethodSource("items")
+ void formatInputStreamWithCharsetFormatsFile(Item item) throws Exception {
+ try (InputStream inputStream = new FileInputStream(item.getSource())) {
+ StreamsEdit edit = new StreamsFormatter(item.getConfig()).format(inputStream, StandardCharsets.UTF_8);
+ assertThat(edit.getFormattedContent()).isEqualTo(read(item.getExpected()));
+ }
+ }
+
+ @ParameterizedTest
+ @MethodSource("items")
+ void formatReaderFormatsFile(Item item) throws Exception {
+ try (Reader reader = new InputStreamReader(new FileInputStream(item.getSource()))) {
+ StreamsEdit edit = new StreamsFormatter(item.getConfig()).format(reader);
+ assertThat(edit.getFormattedContent()).isEqualTo(read(item.getExpected()));
+ }
+ }
+
+ static Item[] items() {
+ return items(null);
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/FormatterTests-expected/record-with-param.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/FormatterTests-expected/record-with-param.txt
new file mode 100644
index 00000000..57e16f3c
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/FormatterTests-expected/record-with-param.txt
@@ -0,0 +1,16 @@
+package simple;
+
+/**
+ * Settings that can be applied when creating a {@link ClientHttpRequestFactory}.
+ *
+ * @param connectTimeout the connect timeout
+ * @param readTimeout the read timeout
+ * @param bufferRequestBody if request body buffering is used
+ * @author Andy Wilkinson
+ * @author Phillip Webb
+ * @since 3.0.0
+ * @see ClientHttpRequestFactories
+ */
+public record Simple(String name) {
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/FormatterTests-expected/simple.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/FormatterTests-expected/simple.txt
new file mode 100644
index 00000000..63ca9a5c
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/FormatterTests-expected/simple.txt
@@ -0,0 +1,15 @@
+package simple;
+
+/**
+ * Simple.
+ *
+ * @author Phillip Webb
+ * @since 1.0.0
+ */
+public class Simple {
+
+ public static void main(String[] args) throws Exception {
+ // FIXME
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/complex.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/complex.txt
index f0dc2fc9..a874b5bd 100644
--- a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/complex.txt
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/complex.txt
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2021 the original author or authors.
+ * Copyright 2012-2023 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.
@@ -557,8 +557,8 @@ public class SpringApplication {
*/
protected void postProcessApplicationContext(ConfigurableApplicationContext context) {
if (this.beanNameGenerator != null) {
- context.getBeanFactory().registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR,
- this.beanNameGenerator);
+ context.getBeanFactory()
+ .registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, this.beanNameGenerator);
}
if (this.resourceLoader != null) {
if (context instanceof GenericApplicationContext) {
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/generics.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/generics.txt
new file mode 100644
index 00000000..4c3055e0
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/generics.txt
@@ -0,0 +1,8 @@
+package simple;
+
+/**
+ * gh-363.
+ */
+class SpectatorToDoubleGauge extends AbstractMeter implements Gauge {
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/generics2.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/generics2.txt
new file mode 100644
index 00000000..da493d53
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/generics2.txt
@@ -0,0 +1,8 @@
+package simple;
+
+/**
+ * gh-363.
+ */
+public class UnresolvedGenericProperties extends AbstractGenericProperties {
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/javadoc-with-format-off.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/javadoc-with-format-off.txt
new file mode 100644
index 00000000..157ea11b
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/javadoc-with-format-off.txt
@@ -0,0 +1,8 @@
+/**
+ * This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test.
+ * @formatter:off
+ * @formatter:on
+ */
+public class Format {
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/lineendings.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/lineendings.txt
new file mode 100644
index 00000000..92ad853f
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/lineendings.txt
@@ -0,0 +1,8 @@
+package correct;
+
+public class CorrectLf {
+
+ public static void main(String[] args) throws Exception {
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/multi-line-statement-indentation.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/multi-line-statement-indentation.txt
index 7c63370c..a7946a65 100644
--- a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/multi-line-statement-indentation.txt
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/multi-line-statement-indentation.txt
@@ -12,9 +12,8 @@ public class Simple {
public String someMethod() throws MalformedURLException, IOException {
String settingsXml = new String(Files.readAllBytes(Paths.get("src", "intTest", "projects", "settings.xml")),
StandardCharsets.UTF_8)
- .replace("@localCentralUrl@",
- new File("build/int-test-maven-repository").toURI().toURL().toString())
- .replace("@localRepositoryPath@", new File("build/local-maven-repository").getAbsolutePath());
+ .replace("@localCentralUrl@", new File("build/int-test-maven-repository").toURI().toURL().toString())
+ .replace("@localRepositoryPath@", new File("build/local-maven-repository").getAbsolutePath());
return settingsXml;
}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/nullable-not-jspecify.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/nullable-not-jspecify.txt
new file mode 100644
index 00000000..dbdb1f45
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/nullable-not-jspecify.txt
@@ -0,0 +1,23 @@
+package example;
+
+import com.example.Nullable;
+
+/**
+ * Nullable.
+ *
+ * @author Phillip Webb
+ * @since 1.0.0
+ */
+public interface ExampleNullables {
+
+ @Override
+ @Nullable
+ String myMethod(String param);
+
+ @Override
+ public @Nullable String myPublicMethod(String param);
+
+ Object myArrayMethod(@Nullable String string, @Nullable String @Nullable [] array,
+ @Nullable String @Nullable... varargs);
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/nullable-wildcard-import.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/nullable-wildcard-import.txt
new file mode 100644
index 00000000..053cbc13
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/nullable-wildcard-import.txt
@@ -0,0 +1,22 @@
+package example;
+
+import org.jspecify.annotations.*;
+
+/**
+ * Nullable.
+ *
+ * @author Phillip Webb
+ * @since 1.0.0
+ */
+public interface ExampleNullables {
+
+ @Override
+ @Nullable String myMethod(String param);
+
+ @Override
+ public @Nullable String myPublicMethod(String param);
+
+ Object myArrayMethod(@Nullable String string, @Nullable String @Nullable [] array,
+ @Nullable String @Nullable ... varargs);
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/nullable.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/nullable.txt
new file mode 100644
index 00000000..aa859a6e
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/nullable.txt
@@ -0,0 +1,50 @@
+package example;
+
+import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.Nullable;
+import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.NullUnmarked;
+
+/**
+ * Nullable.
+ *
+ * @author Phillip Webb
+ * @since 1.0.0
+ */
+public interface ExampleNullables {
+
+ @Override
+ @Nullable String myMethod(String param);
+
+ @Override
+ public @Nullable String myPublicMethod(String param);
+
+ Object myArrayMethod(@Nullable String string, @Nullable String @Nullable [] array,
+ @Nullable String @Nullable ... varargs);
+
+ default Object inBody() {
+ @Nullable Object[] args = new Object[length];
+ @Nullable List<@Nullable Object> list = new Object[length];
+ Object @Nullable [] moreArgs = new Object[length];
+ return args;
+ }
+
+ @NullMarked
+ void withNullMarked(String str);
+
+ @NullUnmarked
+ void withNullUnmarked(String str);
+
+ static class Fields {
+
+ @Nullable Object one;
+
+ @NonNull Object two;
+
+ private @Nullable Object three;
+
+ private @NonNull Object four;
+
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/record-with-param.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/record-with-param.txt
new file mode 100644
index 00000000..164c5351
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/record-with-param.txt
@@ -0,0 +1,16 @@
+package simple;
+
+/**
+ * Settings that can be applied when creating a {@link ClientHttpRequestFactory}.
+ *
+ * @param connectTimeout the connect timeout
+ * @param readTimeout the read timeout
+ * @param bufferRequestBody if request body buffering is used
+ * @author Andy Wilkinson
+ * @author Phillip Webb
+ * @since 3.0.0
+ * @see ClientHttpRequestFactories
+ */
+public record Simple(String name) {
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/v17/record-with-generic.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/v17/record-with-generic.txt
new file mode 100644
index 00000000..45528043
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/v17/record-with-generic.txt
@@ -0,0 +1,11 @@
+package simple;
+
+/**
+ * Record with generic.
+ *
+ * @author Andy Wilkinson
+ * @since 1.0.0
+ */
+public record SomeRecord(T item) {
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/v8/record-with-generic.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/v8/record-with-generic.txt
new file mode 100644
index 00000000..d31ccb47
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/v8/record-with-generic.txt
@@ -0,0 +1,11 @@
+package simple;
+
+/**
+ * Record with generic.
+ *
+ * @author Andy Wilkinson
+ * @since 1.0.0
+ */
+public record SomeRecord (T item) {
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/complex.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/complex.txt
index 15283fa8..936faa1b 100644
--- a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/complex.txt
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/complex.txt
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2021 the original author or authors.
+ * Copyright 2012-2023 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.
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/generics.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/generics.txt
new file mode 100644
index 00000000..4c3055e0
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/generics.txt
@@ -0,0 +1,8 @@
+package simple;
+
+/**
+ * gh-363.
+ */
+class SpectatorToDoubleGauge extends AbstractMeter implements Gauge {
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/generics2.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/generics2.txt
new file mode 100644
index 00000000..da493d53
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/generics2.txt
@@ -0,0 +1,8 @@
+package simple;
+
+/**
+ * gh-363.
+ */
+public class UnresolvedGenericProperties extends AbstractGenericProperties {
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/javadoc-with-format-off.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/javadoc-with-format-off.txt
new file mode 100644
index 00000000..dbfef5c0
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/javadoc-with-format-off.txt
@@ -0,0 +1,7 @@
+/**
+ * This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test.
+ * @formatter:off
+ * @formatter:on
+ */
+public class Format {
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/lineendings.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/lineendings.txt
new file mode 100644
index 00000000..e56b3941
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/lineendings.txt
@@ -0,0 +1,7 @@
+package correct;
+
+public class CorrectLf {
+
+ public static void main(String[] args) throws Exception { }
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/nullable-not-jspecify.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/nullable-not-jspecify.txt
new file mode 100644
index 00000000..011a2189
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/nullable-not-jspecify.txt
@@ -0,0 +1,20 @@
+package example;
+
+import com.example.Nullable;
+
+/**
+ * Nullable.
+ *
+ * @author Phillip Webb
+ * @since 1.0.0
+ */
+public interface ExampleNullables {
+
+ @Override @Nullable String myMethod(String param);
+
+ @Override public @Nullable String myPublicMethod(String param);
+
+ Object myArrayMethod(@Nullable String string, @Nullable String @Nullable [] array, @Nullable
+ String @Nullable ... varargs);
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/nullable-wildcard-import.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/nullable-wildcard-import.txt
new file mode 100644
index 00000000..11c65198
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/nullable-wildcard-import.txt
@@ -0,0 +1,20 @@
+package example;
+
+import org.jspecify.annotations.*;
+
+/**
+ * Nullable.
+ *
+ * @author Phillip Webb
+ * @since 1.0.0
+ */
+public interface ExampleNullables {
+
+ @Override @Nullable String myMethod(String param);
+
+ @Override public @Nullable String myPublicMethod(String param);
+
+ Object myArrayMethod(@Nullable String string, @Nullable String @Nullable [] array, @Nullable
+ String @Nullable ... varargs);
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/nullable.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/nullable.txt
new file mode 100644
index 00000000..45c9c0da
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/nullable.txt
@@ -0,0 +1,48 @@
+package example;
+
+import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.Nullable;
+import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.NullUnmarked;
+
+/**
+ * Nullable.
+ *
+ * @author Phillip Webb
+ * @since 1.0.0
+ */
+public interface ExampleNullables {
+
+ @Override @Nullable String myMethod(String param);
+
+ @Override public @Nullable String myPublicMethod(String param);
+
+ Object myArrayMethod(@Nullable String string, @Nullable String @Nullable [] array, @Nullable
+ String @Nullable ... varargs);
+
+ default Object inBody() {
+ @Nullable Object[] args = new Object[length];
+ @Nullable List<@Nullable Object> list = new Object[length];
+ Object @Nullable [] moreArgs = new Object[length];
+ return args;
+ }
+
+ @NullMarked
+ void withNullMarked(String str);
+
+ @NullUnmarked
+ void withNullUnmarked(String str);
+
+ static class Fields {
+
+ @Nullable Object one;
+
+ @NonNull Object two;
+
+ private @Nullable Object three;
+
+ private @NonNull Object four;
+
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/record-with-generic.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/record-with-generic.txt
new file mode 100644
index 00000000..5a608dfe
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/record-with-generic.txt
@@ -0,0 +1,11 @@
+package simple;
+
+/**
+ * Record with generic.
+ *
+ * @author Andy Wilkinson
+ * @since 1.0.0
+ */
+public record SomeRecord ( T item) {
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/record-with-param.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/record-with-param.txt
new file mode 100644
index 00000000..37149688
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/record-with-param.txt
@@ -0,0 +1,15 @@
+package simple;
+
+/**
+ * Settings that can be applied when creating a {@link ClientHttpRequestFactory}.
+ * @param connectTimeout the connect timeout
+ * @param readTimeout the read timeout
+ * @param bufferRequestBody if request body buffering is used
+ * @author Andy Wilkinson
+ * @author Phillip Webb
+ * @since 3.0.0
+ * @see ClientHttpRequestFactories
+ */
+ public record Simple(String name) {
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/simple.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/simple.txt
index a12ac39e..62d2a493 100644
--- a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/simple.txt
+++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/simple.txt
@@ -2,7 +2,6 @@ package simple;
/**
* Simple.
- *
* @author Phillip Webb
* @since 1.0.0
*/
diff --git a/spring-javaformat/spring-javaformat-formatter/pom.xml b/spring-javaformat/spring-javaformat-formatter/pom.xml
index 3115ed45..d4642459 100644
--- a/spring-javaformat/spring-javaformat-formatter/pom.xml
+++ b/spring-javaformat/spring-javaformat-formatter/pom.xml
@@ -6,7 +6,7 @@
io.spring.javaformatspring-javaformat
- 0.0.35-SNAPSHOT
+ 0.0.48-SNAPSHOTspring-javaformat-formatterSpring JavaFormat Formatter
@@ -27,7 +27,7 @@
io.spring.javaformat
- spring-javaformat-formatter-eclipse-jdt-jdk11
+ spring-javaformat-formatter-eclipse-jdt-jdk17${project.version}
diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/Edit.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/Edit.java
new file mode 100644
index 00000000..8e6a9c4d
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/Edit.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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 io.spring.javaformat.formatter;
+
+import java.util.regex.Pattern;
+
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.text.edits.TextEdit;
+
+/**
+ * Base class for edits that can be applied to content.
+ *
+ * @author Phillip Webb
+ */
+public abstract class Edit {
+
+ private static final Pattern TRAILING_WHITESPACE = Pattern.compile(" +$", Pattern.MULTILINE);
+
+ private final String originalContent;
+
+ private final TextEdit textEdit;
+
+ protected Edit(String originalContent, TextEdit textEdit) {
+ super();
+ this.originalContent = originalContent;
+ this.textEdit = textEdit;
+ }
+
+ public boolean hasEdits() {
+ return (this.textEdit.hasChildren() || this.textEdit.getLength() > 0);
+ }
+
+ public String getFormattedContent() throws Exception {
+ IDocument document = new Document(this.originalContent);
+ this.textEdit.apply(document);
+ String formattedContent = document.get();
+ return trimTrailingWhitespace(formattedContent);
+ }
+
+ private String trimTrailingWhitespace(String content) {
+ return TRAILING_WHITESPACE.matcher(content).replaceAll("");
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/FileEdit.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/FileEdit.java
index 78604658..457fcc7c 100644
--- a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/FileEdit.java
+++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/FileEdit.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
@@ -20,44 +20,30 @@
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
-import java.util.regex.Pattern;
-import org.eclipse.jface.text.Document;
-import org.eclipse.jface.text.IDocument;
import org.eclipse.text.edits.TextEdit;
/**
- * An Edit that can be applied to a File.
+ * An {@link Edit} that can be applied to a {@link File}.
*
* @author Phillip Webb
*/
-public class FileEdit {
-
- private static final Pattern TRAILING_WHITESPACE = Pattern.compile(" +$", Pattern.MULTILINE);
+public class FileEdit extends Edit {
private final File file;
private final Charset encoding;
- private final String originalContent;
-
- private final TextEdit edit;
-
- FileEdit(File file, Charset encoding, String originalContent, TextEdit edit) {
+ FileEdit(File file, Charset encoding, String originalContent, TextEdit textEdit) {
+ super(originalContent, textEdit);
this.file = file;
this.encoding = encoding;
- this.originalContent = originalContent;
- this.edit = edit;
}
public File getFile() {
return this.file;
}
- public boolean hasEdits() {
- return (this.edit.hasChildren() || this.edit.getLength() > 0);
- }
-
public void save() {
try {
String formattedContent = getFormattedContent();
@@ -69,20 +55,14 @@ public void save() {
}
}
+ @Override
public String getFormattedContent() throws Exception {
try {
- IDocument document = new Document(this.originalContent);
- this.edit.apply(document);
- String formattedContent = document.get();
- return trimTrailingWhitespace(formattedContent);
+ return super.getFormattedContent();
}
catch (Exception ex) {
throw FileFormatterException.wrap(this.file, ex);
}
}
- private String trimTrailingWhitespace(String content) {
- return TRAILING_WHITESPACE.matcher(content).replaceAll("");
- }
-
}
diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/FileFormatter.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/FileFormatter.java
index fe93fe9a..49b05234 100644
--- a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/FileFormatter.java
+++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/FileFormatter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -55,7 +55,7 @@ public FileFormatter(Formatter formatter) {
* instances.
* @param files the files to format
* @param encoding the source encoding
- * @return a stream of formatted files that have edits
+ * @return a stream of file edits
*/
public Stream formatFiles(Iterable files, Charset encoding) {
return formatFiles(files, encoding, Formatter.DEFAULT_LINE_SEPARATOR);
@@ -67,7 +67,7 @@ public Stream formatFiles(Iterable files, Charset encoding) {
* @param files the files to format
* @param encoding the source encoding
* @param lineSeparator the line separator
- * @return a stream of formatted files that have edits
+ * @return a stream of file edits
*/
public Stream formatFiles(Iterable files, Charset encoding, String lineSeparator) {
return formatFiles(StreamSupport.stream(files.spliterator(), false), encoding, lineSeparator);
@@ -78,7 +78,7 @@ public Stream formatFiles(Iterable files, Charset encoding, Stri
* instances.
* @param files the files to format
* @param encoding the source encoding
- * @return a stream of formatted files that have edits
+ * @return a stream of file edits
*/
public Stream formatFiles(Stream files, Charset encoding) {
return formatFiles(files, encoding, Formatter.DEFAULT_LINE_SEPARATOR);
@@ -90,28 +90,28 @@ public Stream formatFiles(Stream files, Charset encoding) {
* @param files the files to format
* @param encoding the source encoding
* @param lineSeparator the line separator
- * @return a stream of formatted files that have edits
+ * @return a stream of file edits
*/
public Stream formatFiles(Stream files, Charset encoding, String lineSeparator) {
return files.map((file) -> formatFile(file, encoding, lineSeparator));
}
/**
- * Format the the given source file and return a {@link FileEdit} instance.
+ * Format the given source file and return a {@link FileEdit} instance.
* @param file the file to format
* @param encoding the source encoding
- * @return a formatted file
+ * @return a file edit
*/
public FileEdit formatFile(File file, Charset encoding) {
return formatFile(file, encoding, Formatter.DEFAULT_LINE_SEPARATOR);
}
/**
- * Format the the given source file and return a {@link FileEdit} instance.
+ * Format the given source file and return a {@link FileEdit} instance.
* @param file the file to format
* @param encoding the source encoding
* @param lineSeparator the line separator
- * @return a formatted file
+ * @return a file edit
*/
public FileEdit formatFile(File file, Charset encoding, String lineSeparator) {
try {
diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/FileFormatterException.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/FileFormatterException.java
index 09f17a5d..2d054698 100644
--- a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/FileFormatterException.java
+++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/FileFormatterException.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2019 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/Formatter.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/Formatter.java
index 83f6406c..ed6169c4 100644
--- a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/Formatter.java
+++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/Formatter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -24,7 +24,7 @@
import io.spring.javaformat.config.JavaBaseline;
import io.spring.javaformat.config.JavaFormatConfig;
import io.spring.javaformat.formatter.eclipse.EclipseCodeFormatter;
-import io.spring.javaformat.formatter.jdk11.eclipse.EclipseJdk11CodeFormatter;
+import io.spring.javaformat.formatter.jdk17.eclipse.EclipseJdk17CodeFormatter;
import io.spring.javaformat.formatter.jdk8.eclipse.EclipseJdk8CodeFormatter;
/**
@@ -76,7 +76,7 @@ public Formatter() {
*/
public Formatter(JavaFormatConfig javaFormatConfig) {
this.delegate = javaFormatConfig.getJavaBaseline() == JavaBaseline.V8
- ? new EclipseJdk8CodeFormatter(javaFormatConfig) : new EclipseJdk11CodeFormatter(javaFormatConfig);
+ ? new EclipseJdk8CodeFormatter(javaFormatConfig) : new EclipseJdk17CodeFormatter(javaFormatConfig);
}
/**
@@ -123,6 +123,7 @@ public TextEdit format(String source, int offset, int length, String lineSeparat
public TextEdit format(int kind, String source, int offset, int length, int indentationLevel,
String lineSeparator) {
+ lineSeparator = (lineSeparator != null) ? lineSeparator : detectLineSeparator(source);
return this.delegate.format(kind, source, offset, length, indentationLevel, lineSeparator);
}
@@ -148,6 +149,7 @@ public TextEdit format(String source, IRegion[] regions, String lineSeparator) {
}
public TextEdit format(int kind, String source, IRegion[] regions, int indentationLevel, String lineSeparator) {
+ lineSeparator = (lineSeparator != null) ? lineSeparator : detectLineSeparator(source);
return this.delegate.format(kind, source, regions, indentationLevel, lineSeparator);
}
@@ -159,4 +161,19 @@ public void setOptions(Map options) {
this.delegate.setOptions(options);
}
+ private String detectLineSeparator(String contents) {
+ int length = contents.length();
+ for (int i = 0; i < length; i++) {
+ char ch = contents.charAt(i);
+ boolean isLastChar = (i + 1) == length;
+ if (ch == '\r') {
+ return (isLastChar || contents.charAt(i + 1) != '\n') ? "\r" : "\r\n";
+ }
+ if (ch == '\n') {
+ return "\n";
+ }
+ }
+ return null;
+ }
+
}
diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/StreamsEdit.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/StreamsEdit.java
new file mode 100644
index 00000000..7263a5e6
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/StreamsEdit.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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 io.spring.javaformat.formatter;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
+import org.eclipse.text.edits.TextEdit;
+
+/**
+ * An {@link Edit} that can be applied to IO Streams.
+ *
+ * @author Phillip Webb
+ */
+public class StreamsEdit extends Edit {
+
+ StreamsEdit(String originalContent, TextEdit textEdit) {
+ super(originalContent, textEdit);
+ }
+
+ /**
+ * Write the edited content to the given {@link OutputStream}.
+ * @param outputStream the output stream where formatted content should be written
+ */
+ public void writeTo(OutputStream outputStream) {
+ writeTo(outputStream, StandardCharsets.UTF_8);
+ }
+
+ /**
+ * Write the edited content to the given {@link OutputStream}.
+ * @param outputStream the output stream where formatted content should be written
+ * @param encoding the source encoding
+ */
+ public void writeTo(OutputStream outputStream, Charset encoding) {
+ try (OutputStreamWriter writer = new OutputStreamWriter(outputStream, encoding)) {
+ writeTo(writer);
+ }
+ catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ /**
+ * Write the edited content to the given {@link Appendable}.
+ * @param appendable the appendable where formatted content should be written
+ */
+ public void writeTo(Appendable appendable) {
+ try {
+ appendable.append(getFormattedContent());
+ }
+ catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/StreamsFormatter.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/StreamsFormatter.java
new file mode 100644
index 00000000..fb8257d7
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/StreamsFormatter.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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 io.spring.javaformat.formatter;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.Optional;
+
+import org.eclipse.text.edits.TextEdit;
+
+import io.spring.javaformat.config.JavaFormatConfig;
+
+/**
+ * A code formatter designed to work with IO streams.
+ *
+ * @author Phillip Webb
+ * @see Formatter
+ */
+public class StreamsFormatter {
+
+ private final Formatter formatter;
+
+ public StreamsFormatter() {
+ this(new Formatter());
+ }
+
+ public StreamsFormatter(JavaFormatConfig javaFormatConfig) {
+ this(new Formatter(javaFormatConfig));
+ }
+
+ public StreamsFormatter(Formatter formatter) {
+ Optional.ofNullable(formatter).orElseThrow(() -> new IllegalArgumentException("Formatter must not be null"));
+ this.formatter = formatter;
+ }
+
+ /**
+ * Format content from the given source {@link InputStream} and return a
+ * {@link StreamsEdit} instance.
+ * @param inputStream the source input stream
+ * @return a streams edit
+ */
+ public StreamsEdit format(InputStream inputStream) {
+ return format(inputStream, StandardCharsets.UTF_8);
+ }
+
+ /**
+ * Format content from the given source {@link InputStream} and return a
+ * {@link StreamsEdit} instance.
+ * @param inputStream the source input stream
+ * @param encoding the source encoding
+ * @return a streams edit
+ */
+ public StreamsEdit format(InputStream inputStream, Charset encoding) {
+ return format(inputStream, encoding, Formatter.DEFAULT_LINE_SEPARATOR);
+ }
+
+ /**
+ * Format content from the given source {@link InputStream} and return a
+ * {@link StreamsEdit} instance.
+ * @param inputStream the source input stream
+ * @param encoding the source encoding
+ * @param lineSeparator the line separator
+ * @return a streams edit
+ */
+ public StreamsEdit format(InputStream inputStream, Charset encoding, String lineSeparator) {
+ return format(new InputStreamReader(inputStream, encoding), lineSeparator);
+ }
+
+ /**
+ * Format content from the given source {@link Reader} and return a
+ * {@link StreamsEdit} instance.
+ * @param reader the source reader
+ * @return a streams edit
+ */
+ public StreamsEdit format(Reader reader) {
+ return format(reader, Formatter.DEFAULT_LINE_SEPARATOR);
+ }
+
+ /**
+ * Format content from the given source {@link Reader} and return a
+ * {@link StreamsEdit} instance.
+ * @param reader the source reader
+ * @param lineSeparator the line separator
+ * @return a streams edit
+ */
+ public StreamsEdit format(Reader reader, String lineSeparator) {
+ try {
+ String content = readContent(reader);
+ TextEdit edit = this.formatter.format(content, lineSeparator);
+ return new StreamsEdit(content, edit);
+ }
+ catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ private String readContent(Reader reader) throws IOException {
+ StringBuilder result = new StringBuilder();
+ char[] buffer = new char[2048];
+ int numChars;
+ while ((numChars = reader.read(buffer)) >= 0) {
+ result.append(buffer, 0, numChars);
+ }
+ return result.toString();
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/eclipse/EclipseCodeFormatter.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/eclipse/EclipseCodeFormatter.java
index 4f17a95a..121ddc4a 100644
--- a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/eclipse/EclipseCodeFormatter.java
+++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/eclipse/EclipseCodeFormatter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/eclipse/Options.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/eclipse/Options.java
index 3f50237e..b80c0346 100644
--- a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/eclipse/Options.java
+++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/eclipse/Options.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -63,8 +63,9 @@ private Map loadProperties() throws IOException {
}
private void applyConfig(Map properties, JavaFormatConfig javaFormatConfig) {
+ String coreFormatter = this.prefix + ".core.formatter.";
if (javaFormatConfig.getIndentationStyle() == IndentationStyle.SPACES) {
- properties.put(this.prefix + ".core.formatter.tabulation.char", "space");
+ properties.put(coreFormatter + "tabulation.char", "space");
}
}
diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk11/eclipse/CodeLineBreakPreparator.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk17/eclipse/CodeLineBreakPreparator.java
similarity index 75%
rename from spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk11/eclipse/CodeLineBreakPreparator.java
rename to spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk17/eclipse/CodeLineBreakPreparator.java
index 6b3ee9d8..3f5a7337 100644
--- a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk11/eclipse/CodeLineBreakPreparator.java
+++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk17/eclipse/CodeLineBreakPreparator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -14,24 +14,24 @@
* limitations under the License.
*/
-package io.spring.javaformat.formatter.jdk11.eclipse;
+package io.spring.javaformat.formatter.jdk17.eclipse;
-import io.spring.javaformat.eclipse.jdt.jdk11.core.dom.ASTNode;
-import io.spring.javaformat.eclipse.jdt.jdk11.core.dom.ASTVisitor;
-import io.spring.javaformat.eclipse.jdt.jdk11.core.dom.AbstractTypeDeclaration;
-import io.spring.javaformat.eclipse.jdt.jdk11.core.dom.AnnotationTypeDeclaration;
-import io.spring.javaformat.eclipse.jdt.jdk11.core.dom.EnumDeclaration;
-import io.spring.javaformat.eclipse.jdt.jdk11.core.dom.FieldDeclaration;
-import io.spring.javaformat.eclipse.jdt.jdk11.core.dom.SimpleName;
-import io.spring.javaformat.eclipse.jdt.jdk11.core.dom.TypeDeclaration;
-import io.spring.javaformat.eclipse.jdt.jdk11.core.formatter.CodeFormatter;
-import io.spring.javaformat.eclipse.jdt.jdk11.internal.compiler.parser.TerminalTokens;
-import io.spring.javaformat.eclipse.jdt.jdk11.internal.formatter.Preparator;
-import io.spring.javaformat.eclipse.jdt.jdk11.internal.formatter.Token;
-import io.spring.javaformat.eclipse.jdt.jdk11.internal.formatter.TokenManager;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.ASTNode;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.ASTVisitor;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.AbstractTypeDeclaration;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.AnnotationTypeDeclaration;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.EnumDeclaration;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.FieldDeclaration;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.SimpleName;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.TypeDeclaration;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.formatter.CodeFormatter;
+import io.spring.javaformat.eclipse.jdt.jdk17.internal.compiler.parser.TerminalTokens;
+import io.spring.javaformat.eclipse.jdt.jdk17.internal.formatter.Preparator;
+import io.spring.javaformat.eclipse.jdt.jdk17.internal.formatter.Token;
+import io.spring.javaformat.eclipse.jdt.jdk17.internal.formatter.TokenManager;
/**
- * {@link Preparator} to fine tune curly-brace line breaks.
+ * {@link Preparator} to finetune curly-brace line breaks.
*
* @author Phillip Webb
*/
diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk11/eclipse/EclipseJdk11CodeFormatter.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk17/eclipse/EclipseJdk17CodeFormatter.java
similarity index 68%
rename from spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk11/eclipse/EclipseJdk11CodeFormatter.java
rename to spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk17/eclipse/EclipseJdk17CodeFormatter.java
index e4d57dc5..a7530156 100644
--- a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk11/eclipse/EclipseJdk11CodeFormatter.java
+++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk17/eclipse/EclipseJdk17CodeFormatter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -14,35 +14,36 @@
* limitations under the License.
*/
-package io.spring.javaformat.formatter.jdk11.eclipse;
+package io.spring.javaformat.formatter.jdk17.eclipse;
import java.util.Map;
import io.spring.javaformat.config.JavaFormatConfig;
-import io.spring.javaformat.eclipse.jdt.jdk11.internal.formatter.ExtendedCodeFormatter;
-import io.spring.javaformat.eclipse.jdt.jdk11.internal.formatter.Preparator;
+import io.spring.javaformat.eclipse.jdt.jdk17.internal.formatter.ExtendedCodeFormatter;
+import io.spring.javaformat.eclipse.jdt.jdk17.internal.formatter.Preparator;
import io.spring.javaformat.formatter.eclipse.EclipseCodeFormatter;
import io.spring.javaformat.formatter.eclipse.Options;
/**
- * Internal delegate JDK 11 baseline {@link EclipseCodeFormatter} to apply Spring
+ * Internal delegate JDK 17 baseline {@link EclipseCodeFormatter} to apply Spring
* {@literal formatter.prefs} and add {@link Preparator Preparators}.
*
* @author Phillip Webb
*/
-public class EclipseJdk11CodeFormatter extends ExtendedCodeFormatter implements EclipseCodeFormatter {
+public class EclipseJdk17CodeFormatter extends ExtendedCodeFormatter implements EclipseCodeFormatter {
private final Map appliedOptions;
- public EclipseJdk11CodeFormatter(JavaFormatConfig javaFormatConfig) {
- this(new Options("io.spring.javaformat.eclipse.jdt.jdk11").load(javaFormatConfig));
+ public EclipseJdk17CodeFormatter(JavaFormatConfig javaFormatConfig) {
+ this(new Options("io.spring.javaformat.eclipse.jdt.jdk17").load(javaFormatConfig));
}
- EclipseJdk11CodeFormatter(Map options) {
+ EclipseJdk17CodeFormatter(Map options) {
super(options);
this.appliedOptions = options;
addPreparator(new JavadocLineBreakPreparator());
addPreparator(new CodeLineBreakPreparator());
+ addPreparator(new JSpecifyPreparator());
}
@Override
diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk17/eclipse/JSpecifyPreparator.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk17/eclipse/JSpecifyPreparator.java
new file mode 100644
index 00000000..2f9b8aeb
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk17/eclipse/JSpecifyPreparator.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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 io.spring.javaformat.formatter.jdk17.eclipse;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.ASTNode;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.ASTVisitor;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.Annotation;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.CompilationUnit;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.FieldDeclaration;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.IExtendedModifier;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.ImportDeclaration;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.MethodDeclaration;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.SingleVariableDeclaration;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.VariableDeclarationStatement;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.formatter.CodeFormatter;
+import io.spring.javaformat.eclipse.jdt.jdk17.internal.formatter.Preparator;
+import io.spring.javaformat.eclipse.jdt.jdk17.internal.formatter.TokenManager;
+
+public class JSpecifyPreparator implements Preparator {
+
+ private static final String PACKAGE_NAME = "org.jspecify.annotations";
+
+ private static final Set ANNOTATION_NAMES = new HashSet<>(Arrays.asList("NonNull", "Nullable"));
+
+ private static final Set FULLY_QUALIFIED_ANNOTATION_NAMES = ANNOTATION_NAMES.stream()
+ .map((annotationName) -> PACKAGE_NAME + "." + annotationName)
+ .collect(Collectors.toSet());
+
+ @Override
+ public void apply(int kind, TokenManager tokenManager, ASTNode astRoot) {
+ if ((kind & CodeFormatter.K_COMPILATION_UNIT) != 0) {
+ ASTVisitor visitor = new Vistor(tokenManager);
+ astRoot.accept(visitor);
+ }
+ }
+
+ private static class Vistor extends ASTVisitor {
+
+ private final TokenManager tokenManager;
+
+ private final Map fullyQualified = new HashMap<>();
+
+ Vistor(TokenManager tokenManager) {
+ this.tokenManager = tokenManager;
+ }
+
+ @Override
+ public boolean visit(CompilationUnit node) {
+ this.fullyQualified.clear();
+ return super.visit(node);
+ }
+
+ @Override
+ public boolean visit(ImportDeclaration node) {
+ String name = node.getName().toString();
+ if (name.equals(PACKAGE_NAME) || name.startsWith(PACKAGE_NAME)) {
+ Set annotationNames = (node.isOnDemand()) ? ANNOTATION_NAMES
+ : Collections.singleton(name.substring(name.lastIndexOf(".") + 1));
+ for (String annotationName : annotationNames) {
+ this.fullyQualified.put(annotationName, PACKAGE_NAME + "." + annotationName);
+ }
+ }
+ return super.visit(node);
+ }
+
+ @Override
+ public boolean visit(FieldDeclaration node) {
+ clearLineBreaksIfHasJSpecifyAnnotation(node.modifiers());
+ return super.visit(node);
+ }
+
+ @Override
+ public boolean visit(MethodDeclaration node) {
+ clearLineBreaksIfHasJSpecifyAnnotation(node.modifiers());
+ return true;
+ }
+
+ @Override
+ public boolean visit(VariableDeclarationStatement node) {
+ clearLineBreaksIfHasJSpecifyAnnotation(node.modifiers());
+ return true;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void endVisit(SingleVariableDeclaration node) {
+ if (node.isVarargs()) {
+ List annotations = node.varargsAnnotations();
+ Annotation lastAnnotation = getLastAnnotation(annotations);
+ if (isJSpecifyAnnotation(lastAnnotation)) {
+ this.tokenManager.lastTokenIn(lastAnnotation, -1).spaceAfter();
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void clearLineBreaksIfHasJSpecifyAnnotation(List> modifiers) {
+ Annotation lastAnnotation = getLastAnnotation((List) modifiers);
+ if (isJSpecifyAnnotation(lastAnnotation)) {
+ this.tokenManager.lastTokenIn(lastAnnotation, -1).clearLineBreaksAfter();
+ }
+ }
+
+ private Annotation getLastAnnotation(List extends IExtendedModifier> modifiers) {
+ Annotation annotation = null;
+ for (IExtendedModifier modifier : modifiers) {
+ if (!modifier.isAnnotation()) {
+ return annotation;
+ }
+ annotation = (Annotation) modifier;
+ }
+ return annotation;
+ }
+
+ private boolean isJSpecifyAnnotation(Annotation annotation) {
+ String fullyQualifiedName = (annotation != null)
+ ? this.fullyQualified.get(annotation.getTypeName().toString()) : null;
+ return (fullyQualifiedName != null) && FULLY_QUALIFIED_ANNOTATION_NAMES.contains(fullyQualifiedName);
+ }
+
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk11/eclipse/JavadocLineBreakPreparator.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk17/eclipse/JavadocLineBreakPreparator.java
similarity index 67%
rename from spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk11/eclipse/JavadocLineBreakPreparator.java
rename to spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk17/eclipse/JavadocLineBreakPreparator.java
index 1e77a4ff..28b369c7 100644
--- a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk11/eclipse/JavadocLineBreakPreparator.java
+++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk17/eclipse/JavadocLineBreakPreparator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -14,28 +14,28 @@
* limitations under the License.
*/
-package io.spring.javaformat.formatter.jdk11.eclipse;
+package io.spring.javaformat.formatter.jdk17.eclipse;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import io.spring.javaformat.eclipse.jdt.jdk11.core.dom.ASTNode;
-import io.spring.javaformat.eclipse.jdt.jdk11.core.dom.ASTVisitor;
-import io.spring.javaformat.eclipse.jdt.jdk11.core.dom.Comment;
-import io.spring.javaformat.eclipse.jdt.jdk11.core.dom.CompilationUnit;
-import io.spring.javaformat.eclipse.jdt.jdk11.core.dom.Javadoc;
-import io.spring.javaformat.eclipse.jdt.jdk11.core.dom.TagElement;
-import io.spring.javaformat.eclipse.jdt.jdk11.core.dom.TextElement;
-import io.spring.javaformat.eclipse.jdt.jdk11.core.dom.TypeDeclaration;
-import io.spring.javaformat.eclipse.jdt.jdk11.core.formatter.CodeFormatter;
-import io.spring.javaformat.eclipse.jdt.jdk11.internal.compiler.parser.TerminalTokens;
-import io.spring.javaformat.eclipse.jdt.jdk11.internal.formatter.Preparator;
-import io.spring.javaformat.eclipse.jdt.jdk11.internal.formatter.Token;
-import io.spring.javaformat.eclipse.jdt.jdk11.internal.formatter.TokenManager;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.ASTNode;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.ASTVisitor;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.AbstractTypeDeclaration;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.Comment;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.CompilationUnit;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.Javadoc;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.TagElement;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.dom.TextElement;
+import io.spring.javaformat.eclipse.jdt.jdk17.core.formatter.CodeFormatter;
+import io.spring.javaformat.eclipse.jdt.jdk17.internal.compiler.parser.TerminalTokens;
+import io.spring.javaformat.eclipse.jdt.jdk17.internal.formatter.Preparator;
+import io.spring.javaformat.eclipse.jdt.jdk17.internal.formatter.Token;
+import io.spring.javaformat.eclipse.jdt.jdk17.internal.formatter.TokenManager;
/**
- * {@link Preparator} to fine tune Javadoc whitespace.
+ * {@link Preparator} to finetune Javadoc whitespace.
*
* @author Phillip Webb
*/
@@ -93,7 +93,8 @@ private static class Vistor extends ASTVisitor {
public boolean visit(Javadoc node) {
int commentIndex = this.tokenManager.firstIndexIn(node, TerminalTokens.TokenNameCOMMENT_JAVADOC);
Token commentToken = this.tokenManager.get(commentIndex);
- this.commentTokenManager = new TokenManager(commentToken.getInternalStructure(), this.tokenManager);
+ this.commentTokenManager = (commentToken.getInternalStructure() != null)
+ ? new TokenManager(commentToken.getInternalStructure(), this.tokenManager) : null;
this.declaration = node.getParent();
this.firstTagElement = true;
this.hasText = false;
@@ -108,19 +109,19 @@ public boolean visit(TextElement node) {
@Override
public boolean visit(TagElement node) {
- if (isSquashRequired(node, this.declaration)) {
+ if (this.commentTokenManager != null && isSquashRequired(node, this.declaration)) {
int startIndex = this.commentTokenManager.findIndex(node.getStartPosition(), -1, false);
Token token = this.commentTokenManager.get(startIndex);
token.clearLineBreaksBefore();
- token.putLineBreaksBefore(
- this.declaration instanceof TypeDeclaration && this.firstTagElement && this.hasText ? 2 : 1);
+ boolean isTypeDeclaration = this.declaration instanceof AbstractTypeDeclaration;
+ token.putLineBreaksBefore(isTypeDeclaration && this.firstTagElement && this.hasText ? 2 : 1);
this.firstTagElement = false;
}
return true;
}
private boolean isSquashRequired(TagElement node, ASTNode declaration) {
- if (declaration instanceof TypeDeclaration) {
+ if (declaration instanceof AbstractTypeDeclaration) {
String tagName = node.getTagName();
return (!node.isNested() && tagName != null && tagName.startsWith("@"));
}
diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/CodeLineBreakPreparator.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/CodeLineBreakPreparator.java
index 29d16a3d..2cb2ef68 100644
--- a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/CodeLineBreakPreparator.java
+++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/CodeLineBreakPreparator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -31,7 +31,7 @@
import io.spring.javaformat.eclipse.jdt.jdk8.internal.formatter.TokenManager;
/**
- * {@link Preparator} to fine tune curly-brace line breaks.
+ * {@link Preparator} to finetune curly-brace line breaks.
*
* @author Phillip Webb
*/
diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/EclipseJdk8CodeFormatter.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/EclipseJdk8CodeFormatter.java
index 7b747cd2..9887ccb2 100644
--- a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/EclipseJdk8CodeFormatter.java
+++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/EclipseJdk8CodeFormatter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -25,7 +25,7 @@
import io.spring.javaformat.formatter.eclipse.Options;
/**
- * Internal delegate JDK 11 baseline {@link EclipseCodeFormatter} to apply Spring
+ * Internal delegate JDK 8 baseline {@link EclipseCodeFormatter} to apply Spring
* {@literal formatter.prefs} and add {@link Preparator Preparators}.
*
* @author Phillip Webb
@@ -43,6 +43,7 @@ public EclipseJdk8CodeFormatter(JavaFormatConfig javaFormatConfig) {
this.appliedOptions = options;
addPreparator(new JavadocLineBreakPreparator());
addPreparator(new CodeLineBreakPreparator());
+ addPreparator(new JSpecifyPreparator());
}
@Override
diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/JSpecifyPreparator.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/JSpecifyPreparator.java
new file mode 100644
index 00000000..89397c6d
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/JSpecifyPreparator.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2017-present 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
+ *
+ * https://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 io.spring.javaformat.formatter.jdk8.eclipse;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.ASTNode;
+import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.ASTVisitor;
+import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.Annotation;
+import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.CompilationUnit;
+import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.FieldDeclaration;
+import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.IExtendedModifier;
+import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.ImportDeclaration;
+import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.MethodDeclaration;
+import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.SingleVariableDeclaration;
+import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.VariableDeclarationStatement;
+import io.spring.javaformat.eclipse.jdt.jdk8.core.formatter.CodeFormatter;
+import io.spring.javaformat.eclipse.jdt.jdk8.internal.formatter.Preparator;
+import io.spring.javaformat.eclipse.jdt.jdk8.internal.formatter.TokenManager;
+
+public class JSpecifyPreparator implements Preparator {
+
+ private static final String PACKAGE_NAME = "org.jspecify.annotations";
+
+ private static final Set ANNOTATION_NAMES = new HashSet<>(Arrays.asList("NonNull", "Nullable"));
+
+ private static final Set FULLY_QUALIFIED_ANNOTATION_NAMES = ANNOTATION_NAMES.stream()
+ .map((annotationName) -> PACKAGE_NAME + "." + annotationName)
+ .collect(Collectors.toSet());
+
+ @Override
+ public void apply(int kind, TokenManager tokenManager, ASTNode astRoot) {
+ if ((kind & CodeFormatter.K_COMPILATION_UNIT) != 0) {
+ ASTVisitor visitor = new Vistor(tokenManager);
+ astRoot.accept(visitor);
+ }
+ }
+
+ private static class Vistor extends ASTVisitor {
+
+ private final TokenManager tokenManager;
+
+ private final Map fullyQualified = new HashMap<>();
+
+ Vistor(TokenManager tokenManager) {
+ this.tokenManager = tokenManager;
+ }
+
+ @Override
+ public boolean visit(CompilationUnit node) {
+ this.fullyQualified.clear();
+ return super.visit(node);
+ }
+
+ @Override
+ public boolean visit(ImportDeclaration node) {
+ String name = node.getName().toString();
+ if (name.equals(PACKAGE_NAME) || name.startsWith(PACKAGE_NAME)) {
+ Set annotationNames = (node.isOnDemand()) ? ANNOTATION_NAMES
+ : Collections.singleton(name.substring(name.lastIndexOf(".") + 1));
+ for (String annotationName : annotationNames) {
+ this.fullyQualified.put(annotationName, PACKAGE_NAME + "." + annotationName);
+ }
+ }
+ return super.visit(node);
+ }
+
+ @Override
+ public boolean visit(FieldDeclaration node) {
+ clearLineBreaksIfHasJSpecifyAnnotation(node.modifiers());
+ return super.visit(node);
+ }
+
+ @Override
+ public boolean visit(MethodDeclaration node) {
+ clearLineBreaksIfHasJSpecifyAnnotation(node.modifiers());
+ return true;
+ }
+
+ @Override
+ public boolean visit(VariableDeclarationStatement node) {
+ clearLineBreaksIfHasJSpecifyAnnotation(node.modifiers());
+ return true;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void endVisit(SingleVariableDeclaration node) {
+ if (node.isVarargs()) {
+ List annotations = node.varargsAnnotations();
+ Annotation lastAnnotation = getLastAnnotation(annotations);
+ if (isJSpecifyAnnotation(lastAnnotation)) {
+ this.tokenManager.lastTokenIn(lastAnnotation, -1).spaceAfter();
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void clearLineBreaksIfHasJSpecifyAnnotation(List> modifiers) {
+ Annotation lastAnnotation = getLastAnnotation((List) modifiers);
+ if (isJSpecifyAnnotation(lastAnnotation)) {
+ this.tokenManager.lastTokenIn(lastAnnotation, -1).clearLineBreaksAfter();
+ }
+ }
+
+ private Annotation getLastAnnotation(List extends IExtendedModifier> modifiers) {
+ Annotation annotation = null;
+ for (IExtendedModifier modifier : modifiers) {
+ if (!modifier.isAnnotation()) {
+ return annotation;
+ }
+ annotation = (Annotation) modifier;
+ }
+ return annotation;
+ }
+
+ private boolean isJSpecifyAnnotation(Annotation annotation) {
+ String fullyQualifiedName = (annotation != null)
+ ? this.fullyQualified.get(annotation.getTypeName().toString()) : null;
+ return (fullyQualifiedName != null) && FULLY_QUALIFIED_ANNOTATION_NAMES.contains(fullyQualifiedName);
+ }
+
+ }
+
+}
diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/JavadocLineBreakPreparator.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/JavadocLineBreakPreparator.java
index 6a7a4752..a5b8a035 100644
--- a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/JavadocLineBreakPreparator.java
+++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/JavadocLineBreakPreparator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-present 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.
@@ -22,12 +22,12 @@
import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.ASTNode;
import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.ASTVisitor;
+import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.AbstractTypeDeclaration;
import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.Comment;
import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.CompilationUnit;
import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.Javadoc;
import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.TagElement;
import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.TextElement;
-import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.TypeDeclaration;
import io.spring.javaformat.eclipse.jdt.jdk8.core.formatter.CodeFormatter;
import io.spring.javaformat.eclipse.jdt.jdk8.internal.compiler.parser.TerminalTokens;
import io.spring.javaformat.eclipse.jdt.jdk8.internal.formatter.Preparator;
@@ -35,7 +35,7 @@
import io.spring.javaformat.eclipse.jdt.jdk8.internal.formatter.TokenManager;
/**
- * {@link Preparator} to fine tune Javadoc whitespace.
+ * {@link Preparator} to finetune Javadoc whitespace.
*
* @author Phillip Webb
*/
@@ -93,7 +93,8 @@ private static class Vistor extends ASTVisitor {
public boolean visit(Javadoc node) {
int commentIndex = this.tokenManager.firstIndexIn(node, TerminalTokens.TokenNameCOMMENT_JAVADOC);
Token commentToken = this.tokenManager.get(commentIndex);
- this.commentTokenManager = new TokenManager(commentToken.getInternalStructure(), this.tokenManager);
+ this.commentTokenManager = (commentToken.getInternalStructure() != null)
+ ? new TokenManager(commentToken.getInternalStructure(), this.tokenManager) : null;
this.declaration = node.getParent();
this.firstTagElement = true;
this.hasText = false;
@@ -108,19 +109,19 @@ public boolean visit(TextElement node) {
@Override
public boolean visit(TagElement node) {
- if (isSquashRequired(node, this.declaration)) {
+ if (this.commentTokenManager != null && isSquashRequired(node, this.declaration)) {
int startIndex = this.commentTokenManager.findIndex(node.getStartPosition(), -1, false);
Token token = this.commentTokenManager.get(startIndex);
token.clearLineBreaksBefore();
- token.putLineBreaksBefore(
- this.declaration instanceof TypeDeclaration && this.firstTagElement && this.hasText ? 2 : 1);
+ boolean isTypeDeclaration = this.declaration instanceof AbstractTypeDeclaration;
+ token.putLineBreaksBefore(isTypeDeclaration && this.firstTagElement && this.hasText ? 2 : 1);
this.firstTagElement = false;
}
return true;
}
private boolean isSquashRequired(TagElement node, ASTNode declaration) {
- if (declaration instanceof TypeDeclaration) {
+ if (declaration instanceof AbstractTypeDeclaration) {
String tagName = node.getTagName();
return (!node.isNested() && tagName != null && tagName.startsWith("@"));
}
diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/resources/io/spring/javaformat/formatter/eclipse/formatter.prefs b/spring-javaformat/spring-javaformat-formatter/src/main/resources/io/spring/javaformat/formatter/eclipse/formatter.prefs
index c5760514..46940cbe 100644
--- a/spring-javaformat/spring-javaformat-formatter/src/main/resources/io/spring/javaformat/formatter/eclipse/formatter.prefs
+++ b/spring-javaformat/spring-javaformat-formatter/src/main/resources/io/spring/javaformat/formatter/eclipse/formatter.prefs
@@ -30,7 +30,7 @@ core.formatter.alignment_for_parameters_in_constructor_declaration=16
core.formatter.alignment_for_parameters_in_method_declaration=16
core.formatter.alignment_for_relational_operator=0
core.formatter.alignment_for_resources_in_try=80
-core.formatter.alignment_for_selector_in_method_invocation=16
+core.formatter.alignment_for_selector_in_method_invocation=84
core.formatter.alignment_for_shift_operator=0
core.formatter.alignment_for_string_concatenation=16
core.formatter.alignment_for_superclass_in_type_declaration=16
@@ -41,7 +41,7 @@ core.formatter.alignment_for_throws_clause_in_method_declaration=16
core.formatter.alignment_for_type_arguments=0
core.formatter.alignment_for_type_parameters=0
core.formatter.alignment_for_union_type_in_multicatch=16
-core.formatter.align_selector_in_method_invocation_on_expression_first_line=false
+core.formatter.align_selector_in_method_invocation_on_expression_first_line=true
core.formatter.blank_lines_after_imports=1
core.formatter.blank_lines_after_package=1
core.formatter.blank_lines_before_field=0
diff --git a/src/checkstyle/checkstyle-header.txt b/src/checkstyle/checkstyle-header.txt
index 39429ee6..7e182ab3 100644
--- a/src/checkstyle/checkstyle-header.txt
+++ b/src/checkstyle/checkstyle-header.txt
@@ -1,5 +1,5 @@
^\Q/*\E$
-^\Q * Copyright \E20\d\d\-20\d\d\Q the original author or authors.\E$
+^\Q * Copyright \E20\d\d\-present\Q the original author or authors.\E$
^\Q *\E$
^\Q * Licensed under the Apache License, Version 2.0 (the "License");\E$
^\Q * you may not use this file except in compliance with the License.\E$
diff --git a/src/checkstyle/checkstyle-suppressions.xml b/src/checkstyle/checkstyle-suppressions.xml
index 75d577f2..b115d317 100644
--- a/src/checkstyle/checkstyle-suppressions.xml
+++ b/src/checkstyle/checkstyle-suppressions.xml
@@ -6,4 +6,5 @@
+
diff --git a/src/checkstyle/checkstyle.xml b/src/checkstyle/checkstyle.xml
index 0c6b5e96..c13faf85 100644
--- a/src/checkstyle/checkstyle.xml
+++ b/src/checkstyle/checkstyle.xml
@@ -65,6 +65,7 @@
+