diff --git a/.eclipse/org.eclipse.jdt.core.prefs b/.eclipse/org.eclipse.jdt.core.prefs index fd349833..cc3e405e 100644 --- a/.eclipse/org.eclipse.jdt.core.prefs +++ b/.eclipse/org.eclipse.jdt.core.prefs @@ -25,7 +25,7 @@ org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning org.eclipse.jdt.core.compiler.problem.deadCode=warning org.eclipse.jdt.core.compiler.problem.deprecation=warning org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled org.eclipse.jdt.core.compiler.problem.discouragedReference=warning org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore org.eclipse.jdt.core.compiler.problem.enumIdentifier=error @@ -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,6 +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=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 @@ -384,7 +385,7 @@ org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=90 +org.eclipse.jdt.core.formatter.lineSplit=120 org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 diff --git a/.eclipse/org.eclipse.jdt.ui.prefs b/.eclipse/org.eclipse.jdt.ui.prefs index ebacdff2..ccf98e6a 100644 --- a/.eclipse/org.eclipse.jdt.ui.prefs +++ b/.eclipse/org.eclipse.jdt.ui.prefs @@ -64,13 +64,13 @@ formatter_settings_version=13 org.eclipse.jdt.ui.exception.name=e org.eclipse.jdt.ui.gettersetter.use.is=true org.eclipse.jdt.ui.ignorelowercasenames=true -org.eclipse.jdt.ui.importorder=java;javax;;org.springframework;\#; +org.eclipse.jdt.ui.importorder=java;javax;;io.spring;\#; org.eclipse.jdt.ui.javadoc=true org.eclipse.jdt.ui.keywordthis=false org.eclipse.jdt.ui.ondemandthreshold=9999 org.eclipse.jdt.ui.overrideannotation=true org.eclipse.jdt.ui.staticondemandthreshold=9999 -org.eclipse.jdt.ui.text.custom_code_templates= +org.eclipse.jdt.ui.text.custom_code_templates= sp_cleanup.add_default_serial_version_id=true sp_cleanup.add_generated_serial_version_id=false sp_cleanup.add_missing_annotations=true 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 94% 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 index 0ce880e7..6ee635e0 100755 --- a/ci/scripts/publish-eclipse-update-site-pom-template.xml +++ b/.github/actions/publish-eclipse-update-site/publish-eclipse-update-site-pom-template.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.eclipse.m2e.maveneclipse m2eclipse-maveneclipse-publish @@ -25,7 +25,7 @@ -##respositories## +##repositories## ${project.build.directory}/repository true diff --git a/.github/actions/publish-eclipse-update-site/publish-eclipse-update-site.sh b/.github/actions/publish-eclipse-update-site/publish-eclipse-update-site.sh new file mode 100644 index 00000000..9ddcee29 --- /dev/null +++ b/.github/actions/publish-eclipse-update-site/publish-eclipse-update-site.sh @@ -0,0 +1,51 @@ +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/' ) + +echo "Publishing ${buildName}/${buildNumber} (${groupId}:${version}) to Eclipse Update Site" + +jfrog rt dl --build spring-javaformat-${VERSION}/${BUILD_NUMBER} '**/io.spring.javaformat.eclipse.site*.zip' + +curl \ + -s \ + --connect-timeout 240 \ + --max-time 2700 \ + -u ${ARTIFACTORY_USERNAME}:${ARTIFACTORY_PASSWORD} \ + -f \ + -H "X-Explode-Archive: true" \ + -X PUT \ + -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 ) + +repositories="" +while read -r releasedVersion; do + echo "Adding repository for ${releasedVersion}" + repositories="${repositories}https://repo.spring.io/javaformat-eclipse-update-site/${releasedVersion}p2" +done <<< "${releasedVersions}" + +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 \ + --connect-timeout 240 \ + --max-time 2700 \ + -u ${ARTIFACTORY_USERNAME}:${ARTIFACTORY_PASSWORD} \ + -f \ + -X PUT \ + -T "target/repository/content.jar" \ + "https://repo.spring.io/javaformat-eclipse-update-site/" > /dev/null || { echo "Failed to publish" >&2; exit 1; } + +curl \ + -s \ + --connect-timeout 240 \ + --max-time 2700 \ + -u ${ARTIFACTORY_USERNAME}:${ARTIFACTORY_PASSWORD} \ + -f \ + -X PUT \ + -T "target/repository/artifacts.jar" \ + "https://repo.spring.io/javaformat-eclipse-update-site/" > /dev/null || { echo "Failed to publish" >&2; exit 1; } + +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/images/setup-idea-dependency.png b/.github/images/setup-idea-dependency.png new file mode 100644 index 00000000..06958617 Binary files /dev/null and b/.github/images/setup-idea-dependency.png differ diff --git a/.github/images/setup-idea-library.png b/.github/images/setup-idea-library.png new file mode 100644 index 00000000..d3563c7c Binary files /dev/null and b/.github/images/setup-idea-library.png differ diff --git a/.github/images/setup-idea-plugin-module.png b/.github/images/setup-idea-plugin-module.png new file mode 100644 index 00000000..694a1370 Binary files /dev/null and b/.github/images/setup-idea-plugin-module.png differ diff --git a/.github/images/setup-idea-plugin-sdk.png b/.github/images/setup-idea-plugin-sdk.png new file mode 100644 index 00000000..3766bdb0 Binary files /dev/null and b/.github/images/setup-idea-plugin-sdk.png differ 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/jvm.config b/.mvn/jvm.config index 9b109f37..629555a1 100644 --- a/.mvn/jvm.config +++ b/.mvn/jvm.config @@ -1 +1,2 @@ --Xmx1024m \ No newline at end of file +-Xmx1536m +-Dtycho.disableP2Mirrors=true diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar old mode 100755 new mode 100644 index 9cc84ea9..bf82ff01 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 old mode 100755 new mode 100644 index 71793467..6686a643 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1 +1,18 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip +# 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 new file mode 100644 index 00000000..83ec5a0a --- /dev/null +++ b/.sdkmanrc @@ -0,0 +1,3 @@ +# Enable auto-env through the sdkman_auto_env config +# Add key=value pairs of SDKs to use below +java=17.0.14-librca diff --git a/CODE_OF_CONDUCT.adoc b/CODE_OF_CONDUCT.adoc index f013d6f3..17783c7c 100644 --- a/CODE_OF_CONDUCT.adoc +++ b/CODE_OF_CONDUCT.adoc @@ -40,5 +40,5 @@ appropriate to the circumstances. Maintainers are obligated to maintain confiden with regard to the reporter of an incident. This Code of Conduct is adapted from the -http://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at -http://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/] +https://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at +https://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/] diff --git a/CONTRIBUTING.adoc b/CONTRIBUTING.adoc index e5619989..a7e07f62 100644 --- a/CONTRIBUTING.adoc +++ b/CONTRIBUTING.adoc @@ -3,27 +3,36 @@ Spring Java Format is released under the Apache 2.0 license. If you would like to contribute something, or simply want to hack on the code this document should help you get started. + + == Code of Conduct This project adheres to the Contributor Covenant link:CODE_OF_CONDUCT.adoc[code of conduct]. By participating, you are expected to uphold this code. 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. -== Working with the code + +== 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]. + + + +== Working With the Code If you don't have an IDE preference we would recommend that you use https://spring.io/tools/sts[Spring Tools Suite] or -http://eclipse.org[Eclipse] when working with the code. We use the -http://eclipse.org/m2e/[M2Eclipse] eclipse plugin for maven support. Other IDEs and tools +https://eclipse.org[Eclipse] when working with the code. We use the +https://eclipse.org/m2e/[M2Eclipse] eclipse plugin for maven support. Other IDEs and tools should also work without issue. -=== Building from source -To build the source you will need to install JDK 1.8. -==== Default build + +=== Building From Source +To build the source you will need to install JDK 17. + + + +==== Default Build The project can be built from the root directory using the standard maven command: [indent=0] @@ -33,30 +42,172 @@ The project can be built from the root directory using the standard maven comman NOTE: You may need to increase the amount of memory available to Maven by setting a `MAVEN_OPTS` environment variable with the value `-Xmx512m` -=== Importing into eclipse -You can import the code into any Eclipse based distribution as long as it had the http://eclipse.org/m2e/[M2Eclipse] eclipse plugin. + + +=== Importing Into Eclipse +You can import the code into any Eclipse based distribution as long as it had the https://eclipse.org/m2e/[M2Eclipse] eclipse plugin. If you don't already have m2eclipse installed it is available from the "Eclipse marketplace". +Once imported, you can apply eclipse settings by running: + +[indent=0] +---- + $ ./mvnw -Peclipse validate +---- + NOTE: You'll need to close the `spring-javaformat-formatter-eclipse` and `spring-javaformat-formatter-eclipse-runtime` projects following import since they contain rewritten packages that aren't supported by the IDE -=== Importing into other IDEs + + +=== Importing Into IntelliJ IDEA +You can import the code as a maven project into IntelliJ IDEA. + + + +==== Module Dependencies +When IntelliJ IDEA parses `pom.xml`, it automatically creates inter-module dependencies if dependent libraries are coming from other modules within the project. +However, when dependent modules perform repackaging (e.g. `spring-javaformat-formatter-eclipse-runtime` module), the current module cannot resolve all classes by module dependencies because repackaging (shade & binary manipulation) moves around classes. +Therefore, you need to manually update the dependencies from the module to the produced jars. + +Following modules perform repackaging. + +* `spring-javaformat-formatter-eclipse` +* `spring-javaformat-formatter-eclipse-runtime` + +Modules that depend on these modules need jar dependencies instead of module dependencies. + + + +===== Setting up Jar Dependencies +The following steps define jar-based project libraries on IDE and add them to the modules that need jar dependencies. + +*Add a jar file-based project library* + +* "Project Settings" -> "Libraries" +* Click "+" sign, then select "Java" +* Specify the jar file + +For example, you can specify the jar file in the target directory(`/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/target/spring-javaformat-formatter-eclipse-runtime-0.0.28-SNAPSHOT.jar`) +or one in the local maven repository(`~/.m2/repository/io/spring/javaformat/spring-javaformat-formatter-eclipse-runtime/0.0.28-SNAPSHOT/spring-javaformat-formatter-eclipse-runtime-0.0.28-SNAPSHOT.jar`). + +image::.github/images/setup-idea-library.png[Setup IntelliJ IDEA library] + +*Add library dependencies to modules* + +* "Project Settings" -> "Modules" +* Select a module that depends on repackaging modules +* Click "+" sign and "2 Library" +* "Choose Libraries" and select necessary libraries that have added in the previous step +* Move up the added libraries higher than the module dependencies (or remove the module dependencies) + +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. + +* Open the `pom.xml` in `spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-runtime`. +* Check `intellij.binary` and `intellij.source` properties to find out the appropriate IntelliJ IDEA version. +* Download the binary from the url in `intellij.binary`. +(For OSX, replace the `.tar.gz` to `.dmg` to download the image file.) +* Install the image to the local machine +* Download the source files from github specified in `intellij.source` and unzip it. + + + +==== Setup SDK +* Open "Project Structure" - "Platform Settings" - "SDKs" +* Click "+" sign, "Add Intellij Platform Plugin SDK..." +* Specify the installed intellij image. (`/applications/IntelliJ IDEA CE` for OSX) +* On the right panel, "Sourcepath", Click "+" sign, specify unzipped intellij source directory +* Specify "Sandbox Home" directory + +image::.github/images/setup-idea-plugin-sdk.png[Setup IntelliJ IDEA Plugin SDK] + +Please see the https://plugins.jetbrains.com/docs/intellij/setting-up-environment.html[IntelliJ IDEA reference] for how to setup a plugin development in details. + + + +==== Convert to Plugin Module +The imported `spring-javaformat-intellij-idea-plugin` module is recognized as a java module. +This needs to be converted to a plugin module. + +* Open `spring-javaformat-intellij-idea-plugin.iml` in `spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin` +* Change `type="JAVA_MODULE"` to `type="PLUGIN_MODULE"` + +[source,xml] +---- + +---- + +Reference https://stackoverflow.com/questions/18278440/how-to-import-and-run-existing-plugins-from-intellij-community-edition-repo[how to convert existing module to a plugin module] + +* Open "Project Structure" - "Modules" +* Check `spring-javaformat-intellij-idea-plugin` icon turns to a plugin icon +* "Plugin Deployment" - "Path to META-INF/plugin.xml" +* Specify `spring-javaformat/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/resources` + +image::.github/images/setup-idea-plugin-module.png[Setup IntelliJ IDEA Plugin Module] + + + +=== Setting up Gradle Plugin Development +`spring-javaformat-gradle-plugin` module is a gradle plugin and requires gradle related classes. + +To add gradle classes, convert this module to a gradle project. + +* On the project pain, right-click `build.gradle` in `spring-javaformat-gradle-plugin` module +* Select "Import 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. -== Understanding the code + + +== 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 6ba3ae8c..907d9a2c 100644 --- a/README.adoc +++ b/README.adoc @@ -1,22 +1,27 @@ -:release-version: 0.0.6 -:checkstyle-version: 8.11 -## Spring Java Format +:release-version: 0.0.47 +:checkstyle-version: 9.3 +== Spring Java Format -### What is this? + + +=== What is This? A set of plugins that can be applied to any Java project to provide a consistent "`Spring`" style. 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. You can't configure the plugin conventions to match your style! -### Maven -#### Source Formatting +=== Maven + + + +==== Source Formatting For source formatting, add the `spring-javaformat-maven-plugin` to your `build` plugins as follows: [source,xml,indent=0,subs="normal"] @@ -67,9 +72,17 @@ If you want to enforce that all code matches the required style, add the followi ---- -#### Checkstyle +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`. + + -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"] ---- @@ -78,7 +91,7 @@ To enforce checksyle conventions add the checkstyle plugin and include a depende org.apache.maven.plugins maven-checkstyle-plugin - 3.0.0 + 3.1.1 com.puppycrawl.tools @@ -110,63 +123,114 @@ 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: + +=== Gradle +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. -#### Checkstyle -To enforce checksyle conventions add the checkstyle plugin and include a dependency on `spring-javaformat-checkstyle`: +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"] ---- -apply plugin: 'checkstyle' +tasks.withType(io.spring.javaformat.gradle.tasks.CheckFormat) { + exclude "package/to/exclude" +} +---- + + + +==== Checkstyle +To enforce Checkstyle conventions, apply the Checkstyle plugin in addition to the `io.spring.javaformat` plugin: + +[source,groovy,indent=0,subs="normal"] +---- +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}" } +---- + +To configure Checkstyle to use the default Spring checks, add the following configuration: -dependencies { - checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:{release-version}") +[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 + } +} ---- -### Eclipse + +=== Java 8 Support +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: + +[source,properties] +---- +java-baseline=8 +---- + + + +=== Eclipse 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: @@ -176,62 +240,178 @@ 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 http://repo.spring.io/release/io/spring/javaformat/io.spring.javaformat.eclipse.site/{release-version}[repo.spring.io] or use the https://dl.bintray.com/spring/javaformat-eclipse/[update site]. +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/` 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 plugin provides custom formatter support for IDEA. -The plugin is automatically activated whenever the Maven or Gradle plugins are discovered in a project build script. -A Spring Java Format icon (image:spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/main/resources/spring-javaformat/formatOn.png[title="Icon"]) will also be displayed in the status bar to indicate the formatter is active. + + +=== 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 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-plugin` jar file. -You can download the latest version from http://repo.spring.io/release/io/spring/javaformat/spring-javaformat-intellij-plugin/{release-version}[repo.spring.io]. +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]. + + + +==== Enable the Plugin +The plugin is automatically enabled when one or more of the following conditions match: + +* `.springjavaformatconfig` file exists +* 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 -### 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. -### Tips + +==== CheckStyle-IDEA plugin +The https://plugins.jetbrains.com/plugin/1065-checkstyle-idea[CheckStyle-IDEA plugin] provides Checkstyle integration for IntelliJ IDEA. + +To configure the plugin, create your own Checkstyle configuration file with the following content: + +[source,xml,indent=0] +---- + + + + + +---- + +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 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 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. +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, 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: + +[source,properties] +---- +indentation-style=spaces +---- + + + +=== Tips Formatting and Checkstyle alone are not enough to produce truly consistent code. Here are some tips that we've found useful when developing Spring Boot. -#### Wrapping -The source formatter intentionally uses a low character count of 90 chars for wrapping. -If you're used to longer lines, this 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 "`extract method`" refactor. -Extracting small private methods will improve formatting and it helps when reading the code and debugging. -#### Whitespace -Keeping whitespace lines out 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. +==== Excluding Specific Checks +If you want most `SpringChecks` but need to exclude one or two, you can do something like this in your `checkstyle.xml`: -#### Comments +[source,xml,indent=0] +---- + + + + + + + +---- + + + +==== Disabling Formatting For Blocks of Code +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: + +[source,java] +---- +// @formatter:off + +... code not be formatted + +// @formatter:on +---- + + + +==== Wrapping +The source formatter uses 120 chars for wrapping. This aims to strike a balance between +making use of available horizontal space in your IDE and avoiding unwanted additional +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 +"`extract method`" refactor. Extracting small private methods will improve formatting and +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 whether extracting a private method might give a better result. + + + +==== Comments 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 + + +==== 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 +==== 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 e78d45bf..00000000 --- a/ci/README.adoc +++ /dev/null @@ -1,37 +0,0 @@ -== Concourse pipeline - -The pipeline can be deployed using the following command: - -[source] ----- -$ fly -t spring 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. - -=== Release - -To release a milestone: - -[source] ----- -$ fly -t spring trigger-job -j spring-javaformat/stage-milestone -$ fly -t spring trigger-job -j spring-javaformat/promote-milestone ----- - -To release an RC: - -[source] ----- -$ fly -t spring trigger-job -j spring-javaformat/stage-rc -$ fly -t spring trigger-job -j spring-javaformat/promote-rc ----- - -To release a GA: - -[source] ----- -$ fly -t spring trigger-job -j spring-javaformat/stage-release -$ fly -t spring trigger-job -j spring-javaformat/promote-release ----- diff --git a/ci/images/spring-javaformat-ci-image/Dockerfile b/ci/images/spring-javaformat-ci-image/Dockerfile deleted file mode 100644 index 45512c3f..00000000 --- a/ci/images/spring-javaformat-ci-image/Dockerfile +++ /dev/null @@ -1,33 +0,0 @@ -FROM openjdk:8u141-jdk - -RUN apt-get update && \ - apt-get install -y git && \ - apt-get install -y libxml2-utils && \ - apt-get install -y jq - -ADD https://raw.githubusercontent.com/spring-io/concourse-java-scripts/v0.0.2/concourse-java.sh /opt/ - -ENV DOCKER_VERSION=17.05.0-ce \ - ENTRYKIT_VERSION=0.4.0 - -RUN apt-get update && \ - apt-get install -y curl && \ - apt-get install -y libudev1 && \ - apt-get install -y iptables && \ - curl https://get.docker.com/builds/Linux/x86_64/docker-${DOCKER_VERSION}.tgz | tar zx && \ - mv /docker/* /bin/ && chmod +x /bin/docker* - -# Install entrykit -RUN 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 - -ADD https://raw.githubusercontent.com/spring-projects/spring-boot/master/ci/images/docker-lib.sh /docker-lib.sh - -ENTRYPOINT [ \ - "switch", \ - "shell=/bin/sh", "--", \ - "codep", \ - "/bin/docker daemon" \ -] \ No newline at end of file diff --git a/ci/parameters.yml b/ci/parameters.yml deleted file mode 100644 index 1c908148..00000000 --- a/ci/parameters.yml +++ /dev/null @@ -1,8 +0,0 @@ -github-repo: "https://github.com/spring-io/spring-javaformat.git" -github-repo-name: "spring-io/spring-javaformat" -docker-hub-organization: "springci" -artifactory-server: "https://repo.spring.io" -branch: "master" -build-name: "spring-javaformat" -bintray-subject: "spring" -bintray-repo: "jars" diff --git a/ci/pipeline.yml b/ci/pipeline.yml deleted file mode 100644 index 3da5043a..00000000 --- a/ci/pipeline.yml +++ /dev/null @@ -1,193 +0,0 @@ -resource_types: -- name: artifactory-resource - type: docker-image - source: - repository: springio/artifactory-resource - tag: 0.0.3 -- name: pull-request - type: docker-image - source: - repository: jtarchie/pr -resources: -- name: git-repo - type: git - source: - uri: ((github-repo)) - username: ((github-username)) - password: ((github-password)) - branch: ((branch)) - ignore_paths: ["ci/images/*"] -- name: git-pull-request - type: pull-request - source: - access_token: ((github-access-token)) - repo: ((github-repo-name)) - base: ((branch)) - ignore_paths: ["ci/*"] -- name: ci-images-git-repo - type: git - source: - uri: ((github-repo)) - branch: ((branch)) - paths: ["ci/images/*"] -- name: spring-javaformat-ci-image - type: docker-image - source: - repository: ((docker-hub-organization))/spring-javaformat-ci-image - username: ((docker-hub-username)) - password: ((docker-hub-password)) - tag: ((branch)) -- name: artifactory-repo - type: artifactory-resource - source: - uri: ((artifactory-server)) - username: ((artifactory-username)) - password: ((artifactory-password)) - build_name: ((build-name)) -jobs: -- name: build-spring-javaformat-ci-images - plan: - - get: ci-images-git-repo - trigger: true - - put: spring-javaformat-ci-image - params: - build: ci-images-git-repo/ci/images/spring-javaformat-ci-image -- name: build - serial: true - public: true - plan: - - get: spring-javaformat-ci-image - - get: git-repo - trigger: true - - do: - - task: build-project - privileged: true - timeout: 1h30m - image: spring-javaformat-ci-image - file: git-repo/ci/tasks/build-project.yml - - put: artifactory-repo - params: &artifactory-params - repo: libs-snapshot-local - build_number: "${BUILD_ID}" - 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 -- name: build-pull-requests - serial: true - public: true - plan: - - get: spring-javaformat-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 - timeout: 1h30m - image: spring-javaformat-ci-image - file: git-repo/ci/tasks/build-pr-project.yml - 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-release - serial: true - plan: - - get: spring-javaformat-ci-image - - get: git-repo - trigger: false - - task: stage - image: spring-javaformat-ci-image - file: git-repo/ci/tasks/stage.yml - params: - RELEASE_TYPE: RELEASE - - put: artifactory-repo - params: - <<: *artifactory-params - repo: libs-staging-local - - put: git-repo - params: - repository: stage-git-repo -- name: promote-release - serial: true - plan: - - get: spring-javaformat-ci-image - - get: git-repo - trigger: false - - get: artifactory-repo - trigger: false - passed: [stage-release] - params: - save_build_info: true - - task: promote - image: spring-javaformat-ci-image - file: git-repo/ci/tasks/promote.yml - params: - RELEASE_TYPE: RELEASE - ARTIFACTORY_SERVER: ((artifactory-server)) - ARTIFACTORY_USERNAME: ((artifactory-username)) - ARTIFACTORY_PASSWORD: ((artifactory-password)) - BINTRAY_SUBJECT: ((bintray-subject)) - BINTRAY_REPO: ((bintray-repo)) -- name: sync-to-maven-central - serial: true - plan: - - get: spring-javaformat-ci-image - - get: git-repo - trigger: false - - get: artifactory-repo - trigger: false - passed: [promote-release] - params: - save_build_info: true - - task: sync-to-maven-central - image: spring-javaformat-ci-image - file: git-repo/ci/tasks/sync-to-maven-central.yml - params: - BINTRAY_USERNAME: ((bintray-username)) - BINTRAY_PASSWORD: ((bintray-password)) - SONATYPE_USERNAME: ((sonatype-username)) - SONATYPE_PASSWORD: ((sonatype-password)) - BINTRAY_SUBJECT: ((bintray-subject)) - BINTRAY_REPO: ((bintray-repo)) -- name: publish-eclipse-update-site - serial: true - plan: - - get: spring-javaformat-ci-image - - get: git-repo - trigger: false - - get: artifactory-repo - trigger: false - passed: [sync-to-maven-central] - params: - save_build_info: true - - task: publish-eclipse-update-site - image: spring-javaformat-ci-image - file: git-repo/ci/tasks/publish-eclipse-update-site.yml - params: - BINTRAY_USERNAME: ((bintray-username)) - BINTRAY_PASSWORD: ((bintray-password)) - SONATYPE_USERNAME: ((sonatype-username)) - SONATYPE_PASSWORD: ((sonatype-password)) - BINTRAY_SUBJECT: ((bintray-subject)) - BINTRAY_REPO: ((bintray-repo)) -groups: -- name: "Build" - jobs: ["build"] -- name: "Release" - jobs: ["stage-release", "promote-release", "sync-to-maven-central", "publish-eclipse-update-site"] -- name: "CI Images" - jobs: ["build-spring-javaformat-ci-images"] -- name: "Build 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 0198d39a..00000000 --- a/ci/scripts/common.sh +++ /dev/null @@ -1,4 +0,0 @@ -source /opt/concourse-java.sh - -setup_symlinks -cleanup_maven_repo "io.spring.javaformat" diff --git a/ci/scripts/promote.sh b/ci/scripts/promote.sh deleted file mode 100755 index 2d9fdec1..00000000 --- a/ci/scripts/promote.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/bash -set -e - -source $(dirname $0)/common.sh - -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/' ) - - -if [[ $RELEASE_TYPE = "M" ]]; then - targetRepo="libs-milestone-local" -elif [[ $RELEASE_TYPE = "RC" ]]; then - targetRepo="libs-milestone-local" -elif [[ $RELEASE_TYPE = "RELEASE" ]]; then - targetRepo="libs-release-local" -else - echo "Unknown release type $RELEASE_TYPE" >&2; exit 1; -fi - -echo "Promoting ${buildName}/${buildNumber} to ${targetRepo}" - -curl \ - -s \ - --connect-timeout 240 \ - --max-time 900 \ - -u ${ARTIFACTORY_USERNAME}:${ARTIFACTORY_PASSWORD} \ - -H "Content-type:application/json" \ - -d "{\"status\": \"staged\", \"sourceRepo\": \"libs-staging-local\", \"targetRepo\": \"${targetRepo}\"}" \ - -f \ - -X \ - POST "${ARTIFACTORY_SERVER}/api/build/promote/${buildName}/${buildNumber}" > /dev/null || { echo "Failed to promote" >&2; exit 1; } - -if [[ $RELEASE_TYPE = "RELEASE" ]]; then - curl \ - -s \ - --connect-timeout 240 \ - --max-time 2700 \ - -u ${ARTIFACTORY_USERNAME}:${ARTIFACTORY_PASSWORD} \ - -H "Content-type:application/json" \ - -d "{\"sourceRepos\": [\"libs-release-local\"], \"targetRepo\" : \"spring-distributions\", \"async\":\"true\"}" \ - -f \ - -X \ - POST "${ARTIFACTORY_SERVER}/api/build/distribute/${buildName}/${buildNumber}" > /dev/null || { echo "Failed to distribute" >&2; exit 1; } - - echo "Waiting for artifacts to be published" - ARTIFACTS_PUBLISHED=false - WAIT_TIME=5 - COUNTER=0 - while [ $ARTIFACTS_PUBLISHED == "false" ] && [ $COUNTER -lt 60 ]; do - result=$( curl -s https://api.bintray.com/packages/"${BINTRAY_SUBJECT}"/"${BINTRAY_REPO}"/"${groupId}" ) - versions=$( echo "$result" | jq -r '.versions' ) - exists=$( echo "$versions" | grep "$version" -o || true ) - if [ "$exists" = "$version" ]; then - ARTIFACTS_PUBLISHED=true - fi - COUNTER=$(( COUNTER + 1 )) - sleep $WAIT_TIME - done - if [[ $ARTIFACTS_PUBLISHED = "false" ]]; then - echo "Failed to publish" - exit 1 - fi -fi - - -echo "Promotion complete" diff --git a/ci/scripts/publish-eclipse-update-site.sh b/ci/scripts/publish-eclipse-update-site.sh deleted file mode 100755 index 923b3bf5..00000000 --- a/ci/scripts/publish-eclipse-update-site.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash -set -e - -source $(dirname $0)/common.sh - -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/' ) - -echo "Publishing ${buildName}/${buildNumber} to Eclipse Update Site" -curl \ - -s \ - --connect-timeout 240 \ - --max-time 2700 \ - -u ${BINTRAY_USERNAME}:${BINTRAY_PASSWORD} \ - -f \ - -X PUT \ - -T "artifactory-repo/io/spring/javaformat/io.spring.javaformat.eclipse.site/${version}/io.spring.javaformat.eclipse.site-${version}.zip" \ - "https://api.bintray.com/content/spring/javaformat-eclipse/update-site/${version}/${version}/site.zip?explode=1&publish=1" > /dev/null || { echo "Failed to publish" >&2; exit 1; } - -releasedVersions=$( curl -f -X GET https://api.bintray.com/packages/spring/javaformat-eclipse/update-site | jq -r '.versions[]' ) -respositories="" -while read -r releasedVersion; do - respositories="${respositories}https://dl.bintray.com/spring/javaformat-eclipse/${releasedVersion}p2" -done <<< "${releasedVersions}" - -pushd git-repo > /dev/null -sed "s|##respositories##|${respositories}|" 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; } - -curl \ - -s \ - --connect-timeout 240 \ - --max-time 2700 \ - -u ${BINTRAY_USERNAME}:${BINTRAY_PASSWORD} \ - -f \ - -X PUT \ - -T "target/repository/content.jar" \ - "https://api.bintray.com/content/spring/javaformat-eclipse/content.jar" > /dev/null || { echo "Failed to publish" >&2; exit 1; } - -curl \ - -s \ - --connect-timeout 240 \ - --max-time 2700 \ - -u ${BINTRAY_USERNAME}:${BINTRAY_PASSWORD} \ - -f \ - -X PUT \ - -T "target/repository/artifacts.jar" \ - "https://api.bintray.com/content/spring/javaformat-eclipse/artifacts.jar" > /dev/null || { echo "Failed to publish" >&2; exit 1; } - -popd > /dev/null - -echo "Publish complete" diff --git a/ci/scripts/stage.sh b/ci/scripts/stage.sh deleted file mode 100755 index 4b36ed7d..00000000 --- a/ci/scripts/stage.sh +++ /dev/null @@ -1,45 +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 = "RELEASE" ]]; then - stageVersion=$( strip_snapshot_suffix $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 Buildmaster" > /dev/null -git config user.email "buildmaster@springframework.org" > /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 -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 -git add . > /dev/null -git commit -m"Next development version (v$nextVersion)" > /dev/null - -echo "DONE" - -popd > /dev/null diff --git a/ci/scripts/sync-to-maven-central.sh b/ci/scripts/sync-to-maven-central.sh deleted file mode 100755 index d644c3bf..00000000 --- a/ci/scripts/sync-to-maven-central.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -set -e - -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/' ) - -echo "Syncing ${buildName}/${buildNumber} to Maven Central" - curl \ - -s \ - --connect-timeout 240 \ - --max-time 2700 \ - -u ${BINTRAY_USERNAME}:${BINTRAY_PASSWORD} \ - -H "Content-Type: application/json" -d "{\"username\": \"${SONATYPE_USERNAME}\", \"password\": \"${SONATYPE_PASSWORD}\"}" \ - -f \ - -X \ - POST "https://api.bintray.com/maven_central_sync/${BINTRAY_SUBJECT}/${BINTRAY_REPO}/${groupId}/versions/${version}" > /dev/null || { echo "Failed to sync" >&2; exit 1; } -echo "Sync complete" \ No newline at end of file diff --git a/ci/tasks/build-pr-project.yml b/ci/tasks/build-pr-project.yml deleted file mode 100644 index 9430bc00..00000000 --- a/ci/tasks/build-pr-project.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -platform: linux -inputs: -- name: git-repo -outputs: -- name: distribution-repository -caches: -- path: maven -- path: gradle -run: - path: git-repo/ci/scripts/build-project.sh \ No newline at end of file diff --git a/ci/tasks/build-project.yml b/ci/tasks/build-project.yml deleted file mode 100644 index 649e2e4b..00000000 --- a/ci/tasks/build-project.yml +++ /dev/null @@ -1,18 +0,0 @@ ---- -platform: linux -inputs: -- name: git-repo -outputs: -- name: distribution-repository -caches: -- path: maven -- path: gradle -run: - path: bash - args: - - -ec - - | - source /docker-lib.sh - start_docker - ${PWD}/git-repo/ci/scripts/build-project.sh - diff --git a/ci/tasks/promote.yml b/ci/tasks/promote.yml deleted file mode 100644 index 92b92c34..00000000 --- a/ci/tasks/promote.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -platform: linux -inputs: -- name: git-repo -- name: artifactory-repo -run: - path: git-repo/ci/scripts/promote.sh diff --git a/ci/tasks/publish-eclipse-update-site.yml b/ci/tasks/publish-eclipse-update-site.yml deleted file mode 100644 index 78b15b72..00000000 --- a/ci/tasks/publish-eclipse-update-site.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -platform: linux -inputs: -- name: git-repo -- name: artifactory-repo -run: - path: git-repo/ci/scripts/publish-eclipse-update-site.sh diff --git a/ci/tasks/stage.yml b/ci/tasks/stage.yml deleted file mode 100644 index 1cbcc1fa..00000000 --- a/ci/tasks/stage.yml +++ /dev/null @@ -1,12 +0,0 @@ ---- -platform: linux -inputs: -- name: git-repo -outputs: -- name: stage-git-repo -- name: distribution-repository -caches: -- path: maven -- path: gradle -run: - path: git-repo/ci/scripts/stage.sh diff --git a/ci/tasks/sync-to-maven-central.yml b/ci/tasks/sync-to-maven-central.yml deleted file mode 100644 index e267c673..00000000 --- a/ci/tasks/sync-to-maven-central.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -platform: linux -inputs: -- name: git-repo -- name: artifactory-repo -run: - path: git-repo/ci/scripts/sync-to-maven-central.sh diff --git a/license.txt b/license.txt index 427417b6..ff773796 100644 --- a/license.txt +++ b/license.txt @@ -1,7 +1,7 @@ Apache License Version 2.0, January 2004 - http://www.apache.org/licenses/ + https://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION @@ -193,7 +193,7 @@ 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 + 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, diff --git a/mvnw b/mvnw index 5bf251c0..b7f06462 100755 --- a/mvnw +++ b/mvnw @@ -19,7 +19,7 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Maven2 Start Up Batch script +# Apache Maven Wrapper startup batch script, version 3.1.1 # # Required ENV vars: # ------------------ @@ -27,7 +27,6 @@ # # Optional ENV vars # ----------------- -# M2_HOME - location of maven2's installed home dir # MAVEN_OPTS - parameters passed to the Java VM when running Maven # e.g. to debug Maven itself, use # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 @@ -36,6 +35,10 @@ if [ -z "$MAVEN_SKIP_RC" ] ; then + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + if [ -f /etc/mavenrc ] ; then . /etc/mavenrc fi @@ -58,9 +61,9 @@ case "`uname`" in # See https://developer.apple.com/library/mac/qa/qa1170/_index.html if [ -z "$JAVA_HOME" ]; then if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" + JAVA_HOME="`/usr/libexec/java_home`"; export JAVA_HOME else - export JAVA_HOME="/Library/Java/Home" + JAVA_HOME="/Library/Java/Home"; export JAVA_HOME fi fi ;; @@ -72,49 +75,18 @@ if [ -z "$JAVA_HOME" ] ; then fi fi -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - 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" ] && CLASSPATH=`cygpath --path --unix "$CLASSPATH"` fi -# For Migwn, ensure paths are in UNIX format before anything is touched +# 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)`" - # TODO classpath? fi if [ -z "$JAVA_HOME" ]; then @@ -146,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 @@ -160,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" @@ -185,7 +154,7 @@ find_maven_basedir() { fi # end of workaround done - echo "${basedir}" + printf '%s' "$(cd "$basedir"; pwd)" } # concatenates all lines of a file @@ -195,19 +164,106 @@ concat_lines() { fi } -BASE_DIR=`find_maven_basedir "$(pwd)"` +BASE_DIR=$(find_maven_basedir "$(dirname $0)") if [ -z "$BASE_DIR" ]; then exit 1; fi -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -echo $MAVEN_PROJECTBASEDIR +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. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" + else + 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) wrapperUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $wrapperUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + 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 $QUIET "$wrapperUrl" -O "$wrapperJarPath" + else + 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 $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L + else + 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 + 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 "$javaSource" ]; then + if [ ! -e "$javaClass" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaSource") + fi + if [ -e "$javaClass" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + 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" ] && @@ -216,10 +272,16 @@ if $cygwin; then MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` fi +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + 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 old mode 100755 new mode 100644 index 019bd74d..cba1f040 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -1,143 +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 Maven2 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 key stroke 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 enable echoing my 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 - -%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 8578e8b1..c07e765a 100644 --- a/pom.xml +++ b/pom.xml @@ -1,19 +1,19 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat spring-javaformat-build - 0.0.7-SNAPSHOT + 0.0.48-SNAPSHOT pom Spring JavaFormat Build Spring JavaFormat - https://github.com/spring-io/spring-javaformat/# + https://github.com/spring-io/spring-javaformat/ Apache License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0 + https://www.apache.org/licenses/LICENSE-2.0 @@ -24,44 +24,55 @@ Pivotal info@pivotal.io Pivotal Software, Inc. - http://www.spring.io + https://www.spring.io ${basedir} UTF-8 1.8 - http://download.eclipse.org/releases/oxygen + https://download.eclipse.org/releases/2021-03/202103171000/ + https://download.eclipse.org/releases/2024-03/202403131000/ + https://checkstyle.org/eclipse-cs-update-site/ + true 1.8.1 1.0b3 - 5.2 + 9.6 3.8.0 - 3.4 - 2.4.7 - 3.5.0 + 9.3 + 2.4.21 + 2.17.1 + 3.8.8 ${maven-core.version} - 3.5 - 2.8.47 - 4.12 + 3.8.2 + 3.6.28 + 5.8.1 3.21.0-GA 1.2 + 4.0.3 1.16.0 + 1.16.0 3.0.3 - 1.1.0 - 1.1.0 + 4.0.4 + 4.0.4 + + com.github.eirslett + frontend-maven-plugin + 1.12.1 + com.github.wvengen proguard-maven-plugin - 2.0.14 + 2.6.0 - net.sf.proguard - proguard-base - 5.3 + com.guardsquare + proguard-core + 9.0.7 runtime @@ -69,54 +80,49 @@ com.googlecode.maven-download-plugin download-maven-plugin - 1.3.0 + 1.6.8 org.apache.maven.plugins maven-antrun-plugin - 1.8 + 3.1.0 org.apache.maven.plugins maven-checkstyle-plugin - 2.17 + 3.2.1 com.puppycrawl.tools checkstyle - 8.11 + ${checkstyle.version} org.apache.maven.plugins maven-clean-plugin - 3.0.0 + 3.2.0 org.apache.maven.plugins maven-compiler-plugin - 3.6.1 + 3.10.1 org.apache.maven.plugins maven-deploy-plugin - 2.8.2 + 3.0.0 org.apache.maven.plugins maven-dependency-plugin - 3.0.1 - - - org.apache.maven.plugins - maven-eclipse-plugin - 2.10 + 3.5.0 org.apache.maven.plugins maven-failsafe-plugin - 2.20 + 2.22.2 @@ -129,37 +135,37 @@ org.apache.maven.plugins maven-install-plugin - 2.5.2 + 3.1.0 org.apache.maven.plugins maven-invoker-plugin - 3.0.0 + 3.4.0 org.apache.maven.plugins maven-jar-plugin - 3.0.2 + 3.3.0 org.apache.maven.plugins maven-plugin-plugin - 3.5 + 3.7.1 org.apache.maven.plugins maven-shade-plugin - 3.0.0 + 3.4.1 org.apache.maven.plugins maven-site-plugin - 3.6 + 3.12.1 org.apache.maven.plugins maven-surefire-plugin - 2.20 + 2.22.2 **/*Tests.java @@ -173,32 +179,36 @@ org.apache.maven.plugins maven-source-plugin - 3.0.1 + 3.2.1 org.apache.maven.plugins maven-javadoc-plugin - 3.0.0 + 3.4.1 + + 8 + -Xdoclint:none + org.apache.maven.plugins maven-resources-plugin - 3.0.2 + 3.3.0 org.codehaus.mojo versions-maven-plugin - 2.3 + 2.14.2 org.codehaus.mojo exec-maven-plugin - 1.6.0 + 3.1.0 org.codehaus.mojo build-helper-maven-plugin - 3.0.0 + 3.3.0 org.eclipse.tycho @@ -214,7 +224,8 @@ **/Abstract*.java ${ui.test.vmargs} - 7200 + 7200 + false @@ -224,16 +235,14 @@ ${tycho.version} - org.eclipse.tycho.extras + org.eclipse.tycho tycho-buildtimestamp-jgit - ${tycho-extras.version} + ${tycho.version} jgit - - pom.xml - + pom.xml warning @@ -266,6 +275,11 @@ win32 x86 + + win32 + win32 + x86_64 + linux gtk @@ -276,6 +290,11 @@ cocoa x86_64 + + macosx + cocoa + aarch64 + @@ -301,53 +320,35 @@ - - org.apache.maven.plugins - - - maven-checkstyle-plugin - - - [2.17,) - + org.apache.maven.plugins + maven-checkstyle-plugin + [2.17,) check - + - - org.codehaus.mojo - - - flatten-maven-plugin - - - [1.0.0,) - + org.codehaus.mojo + flatten-maven-plugin + [1.0.0,) flatten - + - - org.eclipse.tycho - - - tycho-versions-plugin - - - [1.1.0,) - + org.eclipse.tycho + tycho-versions-plugin + [1.1.0,) update-eclipse-metadata @@ -355,22 +356,35 @@ - + + + + + + org.apache.maven.plugins + maven-antrun-plugin + [1.8,) + + run + + + + - org.apache.maven.plugins + com.github.eirslett - maven-antrun-plugin + frontend-maven-plugin - [1.8,) + [1.12.1,) - run + npx @@ -390,6 +404,11 @@ ${java.version} ${java.version} + -Werror + -Xlint:deprecation + -Xlint:rawtypes + -Xlint:unchecked + -Xlint:varargs @@ -447,7 +466,6 @@ src/checkstyle/checkstyle-suppressions.xml src/checkstyle/checkstyle-header.txt checkstyle.build.directory=${project.build.directory} - UTF-8 true true true @@ -463,14 +481,31 @@ - junit - junit - ${junit.version} + org.apache.logging.log4j + log4j-api + ${log4j.version} + + + org.apache.logging.log4j + log4j-core + ${log4j.version} + + + org.apache.logging.log4j + log4j-slf4j-impl + ${log4j.version} + + + org.junit + junit-bom + 5.8.1 + pom + import com.puppycrawl.tools checkstyle - 8.11 + ${checkstyle.version} net.sf.trove4j @@ -503,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.javassist javassist @@ -563,13 +558,28 @@ picocontainer ${picocontainer.version} + + org.codehaus.plexus + plexus-utils + ${plexus-utils.version} + + + org.testcontainers + testcontainers + ${testcontainers.version} + + + org.testcontainers + junit-jupiter + ${testcontainers.version} + - junit - junit + org.junit.jupiter + junit-jupiter test @@ -583,19 +593,13 @@ test - - - eclipse - p2 - ${eclipse.repository} - - spring-javaformat - spring-javaformat-maven - spring-javaformat-gradle spring-javaformat-eclipse - spring-javaformat-intellij + spring-javaformat-gradle + spring-javaformat-intellij-idea + spring-javaformat-maven + spring-javaformat-vscode @@ -607,7 +611,7 @@ - -Xmx512m -XX:MaxPermSize=256m -XstartOnFirstThread + -Xmx512m -XstartOnFirstThread @@ -619,7 +623,7 @@ - -Xmx512m -XX:MaxPermSize=256m + -Xmx512m diff --git a/samples/spring-javaformat-gradle-sample/.eclipse/eclipse.properties b/samples/spring-javaformat-gradle-sample/.eclipse/eclipse.properties new file mode 100644 index 00000000..217686f5 --- /dev/null +++ b/samples/spring-javaformat-gradle-sample/.eclipse/eclipse.properties @@ -0,0 +1 @@ +copyright-year=2017-2019 \ No newline at end of file diff --git a/samples/spring-javaformat-gradle-sample/build.gradle b/samples/spring-javaformat-gradle-sample/build.gradle index 93df30ee..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.6-SNAPSHOT") + classpath("io.spring.javaformat:spring-javaformat-gradle-plugin:0.0.48-SNAPSHOT") } } @@ -21,9 +21,9 @@ repositories { } checkstyle { - toolVersion = "8.9" + toolVersion = "8.29" } dependencies { - checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:0.0.6-SNAPSHOT") + checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:0.0.48-SNAPSHOT") } diff --git a/samples/spring-javaformat-gradle-sample/config/checkstyle/checkstyle.xml b/samples/spring-javaformat-gradle-sample/config/checkstyle/checkstyle.xml index b1231c9b..886a68d2 100644 --- a/samples/spring-javaformat-gradle-sample/config/checkstyle/checkstyle.xml +++ b/samples/spring-javaformat-gradle-sample/config/checkstyle/checkstyle.xml @@ -1,5 +1,7 @@ - + diff --git a/samples/spring-javaformat-gradle-sample/gradle/wrapper/gradle-wrapper.properties b/samples/spring-javaformat-gradle-sample/gradle/wrapper/gradle-wrapper.properties index a452b450..4d9ca164 100644 --- a/samples/spring-javaformat-gradle-sample/gradle/wrapper/gradle-wrapper.properties +++ b/samples/spring-javaformat-gradle-sample/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Thu Apr 26 21:27:14 PDT 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-all.zip diff --git a/samples/spring-javaformat-gradle-sample/src/checkstyle/checkstyle.xml b/samples/spring-javaformat-gradle-sample/src/checkstyle/checkstyle.xml index 3c433aee..284595fc 100644 --- a/samples/spring-javaformat-gradle-sample/src/checkstyle/checkstyle.xml +++ b/samples/spring-javaformat-gradle-sample/src/checkstyle/checkstyle.xml @@ -1,5 +1,7 @@ - + \ No newline at end of file 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 ed240148..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, diff --git a/samples/spring-javaformat-maven-sample/.checkstyle b/samples/spring-javaformat-maven-sample/.checkstyle new file mode 100644 index 00000000..5783bc0d --- /dev/null +++ b/samples/spring-javaformat-maven-sample/.checkstyle @@ -0,0 +1,7 @@ + + + + + + + diff --git a/samples/spring-javaformat-maven-sample/.eclipse/eclipse.properties b/samples/spring-javaformat-maven-sample/.eclipse/eclipse.properties index f3b95ce3..217686f5 100644 --- a/samples/spring-javaformat-maven-sample/.eclipse/eclipse.properties +++ b/samples/spring-javaformat-maven-sample/.eclipse/eclipse.properties @@ -1 +1 @@ -copyright-year=2017-2018 \ No newline at end of file +copyright-year=2017-2019 \ No newline at end of file diff --git a/samples/spring-javaformat-maven-sample/pom.xml b/samples/spring-javaformat-maven-sample/pom.xml index b2891b3d..9354db42 100644 --- a/samples/spring-javaformat-maven-sample/pom.xml +++ b/samples/spring-javaformat-maven-sample/pom.xml @@ -1,17 +1,21 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat.sample spring-javaformat-maven-sample 0.0.1-SNAPSHOT + + UTF-8 + 0.0.48-SNAPSHOT + io.spring.javaformat spring-javaformat-maven-plugin - 0.0.6-SNAPSHOT + ${spring-javaformat.version} @@ -28,12 +32,12 @@ com.puppycrawl.tools checkstyle - 8.8 + 8.29 io.spring.javaformat spring-javaformat-checkstyle - ${project.version} + 0.0.20-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 ed240148..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.feature/feature.properties b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.feature/feature.properties index 2fb1fe2a..12c7b165 100755 --- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.feature/feature.properties +++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.feature/feature.properties @@ -1,14 +1,15 @@ featureName=Spring Java Format providerName=Spring +vendorName=Pivotal description=Spring Java Format Eclipse Plugin copyright=\ -Copyright 2000-2014 the original author or authors.\n\ +Copyright 2000-2019 the original author or authors.\n\ All rights reserved. This program and the accompanying materials\n\ are made available under the terms of the Apache License v2.0\n\ which accompanies this distribution, and is available at\n\ -http://www.apache.org/licenses/LICENSE-2.0\n\ +https://www.apache.org/licenses/LICENSE-2.0\n\ \n licenseURL=license.html @@ -20,7 +21,7 @@ Licensed under the Apache License, Version 2.0 (the "License");\n\ you may not use this file except in compliance with the License.\n\ You may obtain a copy of the License at\n\ \n\ - http://www.apache.org/licenses/LICENSE-2.0\n\ + https://www.apache.org/licenses/LICENSE-2.0\n\ \n\ Unless required by applicable law or agreed to in writing, software\n\ distributed under the License is distributed on an "AS IS" BASIS,\n\ 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 92815e82..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.7.qualifier" + version="0.0.48.qualifier" unpack="false"/> diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.feature/license.html b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.feature/license.html index 65825a7a..6810f277 100755 --- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.feature/license.html +++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.feature/license.html @@ -1,5 +1,5 @@ - + @@ -30,7 +30,7 @@

Apache License Version 2.0

-Copyright 2017-2018 the original author or authors. +Copyright 2017-2019 the original author or authors.

@@ -39,7 +39,7 @@

Apache License Version 2.0

You may obtain a copy of the License at

-http://www.apache.org/licenses/LICENSE-2.0 +https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software 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 5bad3f8f..7b294c42 100755 --- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.feature/pom.xml +++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.feature/pom.xml @@ -1,17 +1,18 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat spring-javaformat-eclipse - 0.0.7-SNAPSHOT + 0.0.48-SNAPSHOT io.spring.javaformat.eclipse.feature eclipse-feature - Spring JavaFormat Eclipse Feature + Spring JavaFormat Eclipse Plugin Feature ${basedir}/../.. + 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 a92e1f32..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 608bfc9a..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 516f3220..5d4e2f97 100755 --- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.site/pom.xml +++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.site/pom.xml @@ -1,18 +1,19 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat spring-javaformat-eclipse - 0.0.7-SNAPSHOT + 0.0.48-SNAPSHOT io.spring.javaformat.eclipse.site eclipse-repository - Spring JavaFormat Eclipse Site + Spring JavaFormat Eclipse Plugin Site ${basedir}/../.. + 17 @@ -21,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 3c8c5f4a..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,15 +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 Tests +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.7.qualifier -Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Require-Bundle: org.junit;bundle-version="4.12" +Bundle-Version: 0.0.48.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-11 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/lib/.gitignore b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/lib/.gitignore new file mode 100644 index 00000000..72e8ffc0 --- /dev/null +++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/lib/.gitignore @@ -0,0 +1 @@ +* diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/lib/assertj-core.jar b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/lib/assertj-core.jar deleted file mode 100644 index 49976cdd..00000000 Binary files a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/lib/assertj-core.jar and /dev/null differ diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/lib/byte-buddy-agent.jar b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/lib/byte-buddy-agent.jar deleted file mode 100644 index 350e6cc9..00000000 Binary files a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/lib/byte-buddy-agent.jar and /dev/null differ diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/lib/byte-buddy.jar b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/lib/byte-buddy.jar deleted file mode 100644 index 04c0f847..00000000 Binary files a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/lib/byte-buddy.jar and /dev/null differ diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/lib/mockito-core.jar b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/lib/mockito-core.jar deleted file mode 100644 index 2e10d748..00000000 Binary files a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/lib/mockito-core.jar and /dev/null differ diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/lib/objenesis.jar b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/lib/objenesis.jar deleted file mode 100644 index 7b60a8b4..00000000 Binary files a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/lib/objenesis.jar and /dev/null differ 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 569e1f05..532aefb8 100644 --- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/pom.xml +++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse.tests/pom.xml @@ -1,18 +1,20 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat spring-javaformat-eclipse - 0.0.7-SNAPSHOT + 0.0.48-SNAPSHOT io.spring.javaformat.eclipse.tests eclipse-test-plugin Spring JavaFormat Eclipse Test ${basedir}/../.. + 17 + true @@ -26,4 +28,36 @@ runtime + + + + org.apache.maven.plugins + 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 6a5bbfaa..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -17,7 +17,7 @@ package io.spring.javaformat.eclipse; import org.eclipse.osgi.util.NLS; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -29,10 +29,9 @@ 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"); + 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 d1e188d5..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,11 +1,11 @@ /* - * Copyright 2012-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -22,12 +22,14 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.time.LocalDate; import java.util.Properties; import java.util.stream.Collectors; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import io.spring.javaformat.config.JavaFormatConfig; import static org.assertj.core.api.Assertions.assertThat; @@ -38,53 +40,51 @@ */ public class ProjectPropertiesTests { - @Rule - public TemporaryFolder temp = new TemporaryFolder(); + @TempDir + public File temp; @Test - public void addFromFolderAddsEclipseProperties() throws IOException { - File folder = this.temp.newFolder(); - File file = new File(folder, "eclipse.properties"); + void addFromFolderAddsEclipseProperties() throws IOException { + File file = new File(this.temp, "eclipse.properties"); writeProperties(file, "2018"); ProjectProperties properties = new ProjectProperties(); - properties.addFromFolder(folder); + properties.addFromFolder(this.temp); assertThat(properties.get("copyright-year")).isEqualTo("2018"); } @Test - public void addFromFolderWhenAlreadySetDoesNotOverwrite() throws IOException { + void addFromFolderWhenAlreadySetDoesNotOverwrite() throws IOException { ProjectProperties properties = new ProjectProperties(); - File folder = this.temp.newFolder(); - writeProperties(new File(folder, "eclipse.properties"), "2018"); - properties.addFromFolder(folder); - folder = this.temp.newFolder(); - writeProperties(new File(folder, "eclipse.properties"), "2017"); - properties.addFromFolder(folder); + File folder1 = new File(this.temp, "1"); + folder1.mkdirs(); + writeProperties(new File(folder1, "eclipse.properties"), "2018"); + properties.addFromFolder(folder1); + File folder2 = new File(this.temp, "2"); + folder2.mkdirs(); + writeProperties(new File(folder2, "eclipse.properties"), "2017"); + properties.addFromFolder(folder2); assertThat(properties.get("copyright-year")).isEqualTo("2018"); } @Test - public void addFromEmptyFolderUsesDefaults() throws IOException { + void addFromEmptyFolderUsesDefaults() throws IOException { ProjectProperties properties = new ProjectProperties(); - File folder = this.temp.newFolder(); - properties.addFromFolder(folder); - assertThat(properties.get("copyright-year")).isEqualTo("2018"); + properties.addFromFolder(this.temp); + String currentYear = String.valueOf(LocalDate.now().getYear()); + assertThat(properties.get("copyright-year")).isEqualTo(currentYear); } @Test - public void getModifiedContentReplacesCopyrightYear() throws IOException { - File folder = this.temp.newFolder(); - File file = new File(folder, "eclipse.properties"); - writeProperties(file, "2016-2020"); + void getModifiedContentReplacesCopyrightYear() throws IOException { + String year = "2016-2020"; + File file = new File(this.temp, "eclipse.properties"); + writeProperties(file, year); ProjectProperties properties = new ProjectProperties(); - properties.addFromFolder(folder); - ProjectSettingsFiles files = new ProjectSettingsFilesLocator() - .locateSettingsFiles(); + properties.addFromFolder(this.temp); + ProjectSettingsFiles files = new ProjectSettingsFilesLocator().locateSettingsFiles(); ProjectSettingsFile prefs = getFile(files, "org.eclipse.jdt.ui.prefs"); - String content = loadContent(properties.getModifiedContent(prefs)); - assertThat(content) - .contains("Copyright 2016-2020 the original author or authors"); - + String content = loadContent(properties.getModifiedContent(prefs).getContent(JavaFormatConfig.DEFAULT)); + assertThat(content).contains("Copyright " + year + " the original author or authors"); } private ProjectSettingsFile getFile(ProjectSettingsFiles files, String name) { 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 3237d0a3..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -21,9 +21,10 @@ import java.io.FileNotFoundException; import java.io.PrintWriter; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import io.spring.javaformat.config.JavaFormatConfig; import static org.assertj.core.api.Assertions.assertThat; @@ -34,26 +35,25 @@ */ public class ProjectSettingsFileTests { - @Rule - public TemporaryFolder temp = new TemporaryFolder(); + @TempDir + public File temp; @Test - public void fromFileAdaptsFile() throws Exception { - File file = this.temp.newFile(); + 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()) - .hasSameContentAs(new ByteArrayInputStream("test".getBytes())); + assertThat(projectSettingsFile.getContent(JavaFormatConfig.DEFAULT)) + .hasSameContentAs(new ByteArrayInputStream("test".getBytes())); } @Test - public void fromClasspathResourceAdaptsResource() throws Exception { - ProjectSettingsFile projectSettingsFile = ProjectSettingsFile - .fromClasspath(getClass(), "test.txt"); + void fromClasspathResourceAdaptsResource() throws Exception { + ProjectSettingsFile projectSettingsFile = ProjectSettingsFile.fromClasspath(getClass(), "test.txt"); assertThat(projectSettingsFile.getName()).isEqualTo("test.txt"); - assertThat(projectSettingsFile.getContent()) - .hasSameContentAs(new ByteArrayInputStream("test".getBytes())); + assertThat(projectSettingsFile.getContent(JavaFormatConfig.DEFAULT)) + .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 24e831ad..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -19,13 +19,18 @@ import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.io.PrintWriter; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Properties; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import io.spring.javaformat.config.IndentationStyle; +import io.spring.javaformat.config.JavaBaseline; +import io.spring.javaformat.config.JavaFormatConfig; import static org.assertj.core.api.Assertions.assertThat; @@ -36,44 +41,72 @@ */ public class ProjectSettingsFilesLocatorTests { - @Rule - public TemporaryFolder temp = new TemporaryFolder(); + @TempDir + public File temp; @Test - public void locateSettingsFilesWhenNoFoldersShouldReturnDefault() throws IOException { - ProjectSettingsFiles files = new ProjectSettingsFilesLocator() - .locateSettingsFiles(); + 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"); + .containsOnly("org.eclipse.jdt.core.prefs", "org.eclipse.jdt.ui.prefs"); } @Test - public void locateSettingsFilesOnlyFindPrefs() throws Exception { - File folder = this.temp.newFolder(); - writeFile(folder, "foo.prefs"); - writeFile(folder, "bar.notprefs"); - ProjectSettingsFiles files = new ProjectSettingsFilesLocator(folder) - .locateSettingsFiles(); + 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"); + .containsOnly("org.eclipse.jdt.core.prefs", "org.eclipse.jdt.ui.prefs", "foo.prefs"); } @Test - public void locateSettingsFilesWhenMultipleFoldersFindsInEarliest() throws Exception { - File folder1 = this.temp.newFolder(); + void locateSettingsFilesWhenMultipleFoldersFindsInEarliest() throws Exception { + File folder1 = new File(this.temp, "1"); writeFile(folder1, "foo.prefs", "foo1"); - File folder2 = this.temp.newFolder(); + File folder2 = new File(this.temp, "2"); writeFile(folder2, "foo.prefs", "foo2"); writeFile(folder2, "org.eclipse.jdt.core.prefs", "core2"); - ProjectSettingsFiles files = new ProjectSettingsFilesLocator(folder1, folder2) - .locateSettingsFiles(); + ProjectSettingsFiles files = new ProjectSettingsFilesLocator(folder1, folder2).locateSettingsFiles(); Map found = new LinkedHashMap<>(); files.iterator().forEachRemaining((f) -> found.put(f.getName(), f)); - assertThat(found.get("foo.prefs").getContent()) - .hasSameContentAs(new ByteArrayInputStream("foo1".getBytes())); - assertThat(found.get("org.eclipse.jdt.core.prefs").getContent()) - .hasSameContentAs(new ByteArrayInputStream("core2".getBytes())); + assertThat(found.get("foo.prefs").getContent(JavaFormatConfig.DEFAULT)) + .hasSameContentAs(new ByteArrayInputStream("foo1".getBytes())); + assertThat(found.get("org.eclipse.jdt.core.prefs").getContent(JavaFormatConfig.DEFAULT)) + .hasSameContentAs(new ByteArrayInputStream("core2".getBytes())); + } + + @Test + 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.jdk17.tabs"); + } + } + + @Test + 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"); + } + } + + private ProjectSettingsFile get(ProjectSettingsFiles files, String name) { + for (ProjectSettingsFile file : files) { + if (file.getName().equals(name)) { + return file; + } + } + return null; } private void writeFile(File folder, String name) throws IOException { 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 78770981..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -16,19 +16,28 @@ package io.spring.javaformat.eclipse.projectsettings; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.Collections; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IProgressMonitor; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.will; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -39,31 +48,62 @@ */ public class ProjectSettingsFilesTests { - @Rule - public TemporaryFolder temp = new TemporaryFolder(); + @TempDir + public File temp; @Test - public void iteratorIteratesFiles() throws Exception { - ProjectSettingsFile file = ProjectSettingsFile.fromFile(this.temp.newFile()); - ProjectSettingsFiles files = new ProjectSettingsFiles(Collections.singleton(file), - new ProjectProperties()); + 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 applyToProjectCopiesToDotSettings() throws Exception { - ProjectSettingsFile file = ProjectSettingsFile - .fromFile(this.temp.newFile("foo.prefs")); - ProjectSettingsFiles files = new ProjectSettingsFiles(Collections.singleton(file), - new ProjectProperties()); + void applyToProjectWithoutFileCopiesToDotSettings() throws Exception { + ProjectSettingsFile file = createPrefsFile(); + ProjectSettingsFiles files = new ProjectSettingsFiles(Collections.singleton(file), new ProjectProperties()); + IProject project = mock(IProject.class); + IProgressMonitor monitor = mock(IProgressMonitor.class); + IFile projectFile = mock(IFile.class); + given(project.getFile(".settings/foo.prefs")).willReturn(projectFile); + given(projectFile.exists()).willReturn(false); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + will((invocation) -> { + invocation.getArgument(0, InputStream.class).transferTo(out); + return null; + }).given(projectFile).create(any(), anyBoolean(), any()); + files.applyToProject(project, monitor); + verify(projectFile).create(any(), eq(true), any()); + assertThat(out.toString(StandardCharsets.UTF_8)).isEqualTo("y=z\n"); + } + + @Test + void applyToProjectWithFileMergesToDotSettings() throws Exception { + ProjectSettingsFile file = createPrefsFile(); + ProjectSettingsFiles files = new ProjectSettingsFiles(Collections.singleton(file), new ProjectProperties()); IProject project = mock(IProject.class); IProgressMonitor monitor = mock(IProgressMonitor.class); IFile projectFile = mock(IFile.class); 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))); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + will((invocation) -> { + invocation.getArgument(0, InputStream.class).transferTo(out); + return null; + }).given(projectFile).setContents((InputStream) any(), anyInt(), any()); files.applyToProject(project, monitor); - verify(projectFile).delete(true, monitor); - verify(projectFile).create(any(), eq(true), eq(monitor)); + verify(projectFile).setContents((InputStream) any(), eq(1), eq(monitor)); + assertThat(out.toString(StandardCharsets.UTF_8)) + .isEqualToNormalizingNewlines("a=b\ny=z\n"); + } + + private ProjectSettingsFile createPrefsFile() throws IOException { + File prefsFile = new File(this.temp, "foo.prefs"); + Files.copy(new ByteArrayInputStream("y=z\n".getBytes(StandardCharsets.UTF_8)), prefsFile.toPath()); + ProjectSettingsFile file = ProjectSettingsFile.fromFile(prefsFile); + return file; } } 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 747d18bf..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 @@ -1,23 +1,26 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: Spring Java Format +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.7.qualifier +Bundle-Version: 0.0.48.qualifier Bundle-Activator: io.spring.javaformat.eclipse.Activator -Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Bundle-RequiredExecutionEnvironment: JavaSE-11 Require-Bundle: org.eclipse.ui, org.eclipse.core.resources, org.eclipse.core.runtime, + org.eclipse.ui.ide, org.eclipse.jdt.core, org.eclipse.jface.text, org.eclipse.m2e.jdt;resolution:=optional, org.eclipse.m2e.core;resolution:=optional, org.eclipse.m2e.maven.runtime;resolution:=optional, org.eclipse.buildship.core;resolution:=optional, - com.gradleware.tooling.model;resolution:=optional, - org.slf4j.api;bundle-version="1.7.0" + net.sf.eclipsecs.core;resolution:=optional Bundle-ClassPath: ., - lib/spring-javaformat-formatter-eclipse.jar, - lib/spring-javaformat-formatter.jar + lib/spring-javaformat-config.jar, + lib/spring-javaformat-formatter.jar, + lib/spring-javaformat-checkstyle.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/bin/META-INF/MANIFEST.MF b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/bin/META-INF/MANIFEST.MF deleted file mode 100644 index 753e0f61..00000000 --- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/bin/META-INF/MANIFEST.MF +++ /dev/null @@ -1,7 +0,0 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Spring Javaformat -Bundle-SymbolicName: io.spring.javaformat.eclipse.plugin;singleton:=true -Bundle-Version: 0.0.1.qualifier -Automatic-Module-Name: test -Bundle-RequiredExecutionEnvironment: JavaSE-1.8 diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/bin/build.properties b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/bin/build.properties deleted file mode 100644 index 34d2e4d2..00000000 --- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/bin/build.properties +++ /dev/null @@ -1,4 +0,0 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/bin/plugin.xml b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/bin/plugin.xml deleted file mode 100644 index 5db0254f..00000000 --- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/bin/plugin.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/bin/pom.xml b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/bin/pom.xml deleted file mode 100644 index 178b0b40..00000000 --- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/bin/pom.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - 4.0.0 - - io.spring.javaformat - spring-javaformat-eclipse - 0.0.1-SNAPSHOT - - spring-javaformat-eclipse-plugin - eclipse-plugin - - ${basedir}/../../.. - - - - - org.eclipse.tycho - tycho-maven-plugin - - - org.eclipse.tycho - target-platform-configuration - - - - diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/build.properties b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/build.properties index a9ce579d..9bd6565a 100644 --- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/build.properties +++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/build.properties @@ -3,6 +3,8 @@ bin.includes = META-INF/,\ .,\ plugin.xml,\ lifecycle-mapping-metadata.xml,\ - lib/spring-javaformat-formatter-eclipse.jar,\ - lib/spring-javaformat-formatter.jar - + lib/spring-javaformat-checkstyle.jar,\ + lib/spring-javaformat-config.jar,\ + lib/spring-javaformat-formatter.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 723871df..f9864bd4 100644 --- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/plugin.xml +++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/plugin.xml @@ -3,26 +3,48 @@ + class="io.spring.javaformat.eclipse.formatter.SpringCodeFormatterJdk17Tabs" + id="io.spring.javaformat.eclipse.formatter.jdk17.tabs" + name="Spring (tabs)"> + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/pom.xml b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/pom.xml index ee9f0837..3ccfe109 100644 --- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/pom.xml +++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/pom.xml @@ -1,26 +1,83 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat spring-javaformat-eclipse - 0.0.7-SNAPSHOT + 0.0.48-SNAPSHOT io.spring.javaformat.eclipse eclipse-plugin - Spring JavaFormat Eclipse Parent + Spring JavaFormat Eclipse Plugin ${basedir}/../.. + 17 + + io.spring.javaformat + spring-javaformat-config + runtime + ${project.version} + io.spring.javaformat spring-javaformat-formatter runtime ${project.version} + + io.spring.javaformat + spring-javaformat-checkstyle + runtime + ${project.version} + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + io.spring.javaformat + spring-javaformat-config + ${project.version} + + + io.spring.javaformat + spring-javaformat-formatter + ${project.version} + + + io.spring.javaformat + spring-javaformat-formatter-eclipse-jdt-jdk8 + ${project.version} + + + io.spring.javaformat + 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 ee7e6122..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -16,7 +16,10 @@ package io.spring.javaformat.eclipse; -import io.spring.javaformat.eclipse.gradle.RefreshProjectSettingsListeners; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.Plugin; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; @@ -34,18 +37,27 @@ public class Activator extends AbstractUIPlugin { private static Activator plugin; + private final List javaCorePlugins = new ArrayList<>(); + public Activator() { + this.javaCorePlugins.add(new io.spring.javaformat.eclipse.jdt.jdk8.core.JavaCore()); + this.javaCorePlugins.add(new io.spring.javaformat.eclipse.jdt.jdk17.core.JavaCore()); } @Override public void start(BundleContext context) throws Exception { super.start(context); - RefreshProjectSettingsListeners.attach(); plugin = this; + for (Plugin javaCorePlugin : this.javaCorePlugins) { + javaCorePlugin.start(context); + } } @Override public void stop(BundleContext context) throws Exception { + for (Plugin javaCorePlugin : this.javaCorePlugins) { + javaCorePlugin.stop(context); + } plugin = null; super.stop(context); } 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 27f1065e..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -52,8 +52,7 @@ public void run(Command command) throws CoreException { throw (CoreException) ex; } String msg = NLS.bind(this.failureMessage, ex.getMessage()); - throw new CoreException( - new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, msg, ex)); + throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, msg, ex)); } } 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 05f4fe5f..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -25,8 +25,7 @@ */ public final class Messages extends NLS { - private static final String BUNDLE_NAME = Messages.class.getPackage().getName() - + ".messages"; //$NON-NLS-1$ + private static final String BUNDLE_NAME = Messages.class.getPackage().getName() + ".messages"; //$NON-NLS-1$ /** * General error message. 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 fc9b14e8..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 74129974..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -18,32 +18,35 @@ import java.util.Map; -import io.spring.javaformat.formatter.Formatter; import org.eclipse.jdt.core.formatter.CodeFormatter; import org.eclipse.jface.text.IRegion; import org.eclipse.text.edits.TextEdit; +import io.spring.javaformat.config.JavaFormatConfig; +import io.spring.javaformat.formatter.Formatter; + /** - * Eclipse {@link CodeFormatter} for Spring formatting. + * Eclipse {@link CodeFormatter} base class for Spring formatting. * * @author Phillip Webb */ -public class SpringCodeFormatter extends CodeFormatter { +public abstract class SpringCodeFormatter extends CodeFormatter { - private Formatter delegate = new Formatter(); + private final Formatter delegate; + + public SpringCodeFormatter(JavaFormatConfig javaFormatConfig) { + this.delegate = new Formatter(javaFormatConfig); + } @Override - public TextEdit format(int kind, String source, int offset, int length, - int indentationLevel, String lineSeparator) { - return this.delegate.format(kind, source, offset, length, indentationLevel, - lineSeparator); + public TextEdit format(int kind, String source, int offset, int length, int indentationLevel, + String lineSeparator) { + return this.delegate.format(kind, source, offset, length, indentationLevel, lineSeparator); } @Override - public TextEdit format(int kind, String source, IRegion[] regions, - int indentationLevel, String lineSeparator) { - return this.delegate.format(kind, source, regions, indentationLevel, - lineSeparator); + public TextEdit format(int kind, String source, IRegion[] regions, int indentationLevel, String lineSeparator) { + return this.delegate.format(kind, source, regions, indentationLevel, lineSeparator); } @Override diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk17Spaces.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk17Spaces.java new file mode 100644 index 00000000..d0682ff2 --- /dev/null +++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk17Spaces.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. + */ + +package io.spring.javaformat.eclipse.formatter; + +import org.eclipse.jdt.core.formatter.CodeFormatter; + +import io.spring.javaformat.config.IndentationStyle; +import io.spring.javaformat.config.JavaBaseline; +import io.spring.javaformat.config.JavaFormatConfig; + +/** + * Eclipse {@link CodeFormatter} for Spring formatting with spaces. + * + * @author Phillip Webb + */ +public class SpringCodeFormatterJdk17Spaces extends SpringCodeFormatter { + + 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/SpringCodeFormatterJdk17Tabs.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk17Tabs.java new file mode 100644 index 00000000..718e9846 --- /dev/null +++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk17Tabs.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. + */ + +package io.spring.javaformat.eclipse.formatter; + +import org.eclipse.jdt.core.formatter.CodeFormatter; + +import io.spring.javaformat.config.IndentationStyle; +import io.spring.javaformat.config.JavaBaseline; +import io.spring.javaformat.config.JavaFormatConfig; + +/** + * Eclipse {@link CodeFormatter} for Spring formatting with tabs. + * + * @author Phillip Webb + */ +public class SpringCodeFormatterJdk17Tabs extends SpringCodeFormatter { + + 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 new file mode 100644 index 00000000..536c85ef --- /dev/null +++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk8Spaces.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. + */ + +package io.spring.javaformat.eclipse.formatter; + +import org.eclipse.jdt.core.formatter.CodeFormatter; + +import io.spring.javaformat.config.IndentationStyle; +import io.spring.javaformat.config.JavaBaseline; +import io.spring.javaformat.config.JavaFormatConfig; + +/** + * Eclipse {@link CodeFormatter} for Spring formatting with spaces. + * + * @author Phillip Webb + */ +public class SpringCodeFormatterJdk8Spaces extends SpringCodeFormatter { + + public SpringCodeFormatterJdk8Spaces() { + super(JavaFormatConfig.of(JavaBaseline.V8, IndentationStyle.SPACES)); + } + +} 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 new file mode 100644 index 00000000..0750be23 --- /dev/null +++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/formatter/SpringCodeFormatterJdk8Tabs.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. + */ + +package io.spring.javaformat.eclipse.formatter; + +import org.eclipse.jdt.core.formatter.CodeFormatter; + +import io.spring.javaformat.config.IndentationStyle; +import io.spring.javaformat.config.JavaBaseline; +import io.spring.javaformat.config.JavaFormatConfig; + +/** + * Eclipse {@link CodeFormatter} for Spring formatting with tabs. + * + * @author Phillip Webb + */ +public class SpringCodeFormatterJdk8Tabs extends SpringCodeFormatter { + + public SpringCodeFormatterJdk8Tabs() { + super(JavaFormatConfig.of(JavaBaseline.V8, IndentationStyle.TABS)); + } + +} 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 new file mode 100644 index 00000000..9ab4bb69 --- /dev/null +++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/gradle/GradleProjectSettingsConfigurator.java @@ -0,0 +1,139 @@ +/* + * 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.eclipse.gradle; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import org.eclipse.buildship.core.GradleBuild; +import org.eclipse.buildship.core.InitializationContext; +import org.eclipse.buildship.core.ProjectConfigurator; +import org.eclipse.buildship.core.ProjectContext; +import org.eclipse.buildship.core.internal.CorePlugin; +import org.eclipse.buildship.core.internal.workspace.FetchStrategy; +import org.eclipse.buildship.core.internal.workspace.InternalGradleBuild; +import org.eclipse.buildship.core.internal.workspace.InternalGradleWorkspace; +import org.eclipse.buildship.core.internal.workspace.ModelProvider; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.gradle.tooling.CancellationTokenSource; +import org.gradle.tooling.GradleConnector; +import org.gradle.tooling.model.GradleTask; +import org.gradle.tooling.model.eclipse.EclipseProject; + +import io.spring.javaformat.eclipse.projectsettings.ProjectSettingsFilesLocator; + +/** + * {@link ProjectConfigurator} to apply project-specific settings to Gradle projects. + * + * @author Andy Wilkinson + * @author Phillip Webb + */ +@SuppressWarnings("restriction") +public class GradleProjectSettingsConfigurator implements ProjectConfigurator { + + private static final Object TASK_NAME = "checkFormatMain"; + + private CancellationTokenSource tokenSource; + + @Override + public void init(InitializationContext context, IProgressMonitor monitor) { + this.tokenSource = GradleConnector.newCancellationTokenSource(); + + } + + @Override + public void configure(ProjectContext context, IProgressMonitor monitor) { + try { + configureProject(context.getProject(), monitor); + } + catch (Exception ex) { + context.error("Failed to apply project settings", ex); + } + } + + private void configureProject(IProject project, IProgressMonitor monitor) throws CoreException, IOException { + InternalGradleWorkspace workspace = CorePlugin.internalGradleWorkspace(); + Optional build = workspace.getBuild(project); + if (build.isPresent()) { + ModelProvider modelProvider = ((InternalGradleBuild) build.get()).getModelProvider(); + Collection rootProjects = getRootProjects(monitor, modelProvider); + EclipseProject eclipseProject = findProjectByName(rootProjects, project.getName()); + if (hasSpringFormatPlugin(eclipseProject)) { + ProjectSettingsFilesLocator locator = new ProjectSettingsFilesLocator(getSearchFolders(rootProjects)); + locator.locateSettingsFiles().applyToProject(project, monitor); + } + } + } + + @SuppressWarnings("unchecked") + private Collection getRootProjects(IProgressMonitor monitor, ModelProvider modelProvider) { + Object models = modelProvider.fetchModels(EclipseProject.class, FetchStrategy.FORCE_RELOAD, this.tokenSource, + monitor); + return (Collection) ((models instanceof Map) ? ((Map) models).values() : models); + } + + private EclipseProject findProjectByName(Iterable candidates, String name) { + for (EclipseProject candidate : candidates) { + if (name.equals(candidate.getName())) { + return candidate; + } + EclipseProject childResult = findProjectByName(candidate.getChildren(), name); + if (childResult != null) { + return childResult; + } + } + return null; + } + + private boolean hasSpringFormatPlugin(EclipseProject eclipseProject) { + if (eclipseProject != null) { + for (GradleTask task : eclipseProject.getGradleProject().getTasks()) { + if (isSpringFormatPlugin(task)) { + return true; + } + } + } + return false; + } + + private boolean isSpringFormatPlugin(GradleTask task) { + return TASK_NAME.equals(task.getName()); + } + + private Set getSearchFolders(Collection projects) { + Set searchFolders = new LinkedHashSet<>(); + for (EclipseProject project : projects) { + while (project != null) { + searchFolders.add(project.getProjectDirectory()); + project = project.getParent(); + } + } + return searchFolders; + } + + @Override + public void unconfigure(ProjectContext context, IProgressMonitor monitor) { + } + +} diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/gradle/RefreshProjectSettingsListeners.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/gradle/RefreshProjectSettingsListeners.java deleted file mode 100644 index 7c122d77..00000000 --- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/gradle/RefreshProjectSettingsListeners.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2017-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.spring.javaformat.eclipse.gradle; - -import org.eclipse.buildship.core.CorePlugin; -import org.eclipse.buildship.core.event.Event; -import org.eclipse.buildship.core.event.EventListener; -import org.eclipse.buildship.core.workspace.GradleNatureAddedEvent; -import org.eclipse.buildship.core.workspace.ProjectCreatedEvent; -import org.eclipse.core.commands.Command; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.commands.IExecutionListener; -import org.eclipse.core.commands.NotHandledException; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.commands.ICommandService; - -/** - * Listeners used to trigger the {@link RefreshProjectsSettingsJob}. - * - * @author Phillip Webb - */ -@SuppressWarnings("restriction") -public final class RefreshProjectSettingsListeners { - - private RefreshProjectSettingsListeners() { - } - - /** - * Attach listeners to trigger the {@link RefreshProjectsSettingsJob}. - */ - public static void attach() { - try { - ProjectListener.attach(); - CommandListener.attach(); - } - catch (NoClassDefFoundError ex) { - } - } - - /** - * Command listener that triggers an update after the "Refresh Gradle Project". - */ - private static class CommandListener implements IExecutionListener { - - private static final String COMMAND_NAME = "org.eclipse.buildship.ui.commands.refreshproject"; //$NON-NLS-1$ - - @Override - public void notHandled(String commandId, NotHandledException exception) { - } - - @Override - public void postExecuteFailure(String commandId, ExecutionException exception) { - } - - @Override - public void postExecuteSuccess(String commandId, Object returnValue) { - new RefreshProjectsSettingsJob().schedule(); - } - - @Override - public void preExecute(String commandId, ExecutionEvent event) { - } - - static void attach() { - if (PlatformUI.isWorkbenchRunning()) { - ICommandService commandService = PlatformUI.getWorkbench() - .getAdapter(ICommandService.class); - Command command = commandService.getCommand(COMMAND_NAME); - if (command != null) { - command.addExecutionListener(new CommandListener()); - } - } - } - - } - - /** - * Event Listener to triger an update after a project import or gradle nature change. - */ - private static class ProjectListener implements EventListener { - - @Override - public void onEvent(Event event) { - if (event instanceof ProjectCreatedEvent - || event instanceof GradleNatureAddedEvent) { - new RefreshProjectsSettingsJob().schedule(); - } - } - - static void attach() { - CorePlugin.listenerRegistry().addEventListener(new ProjectListener()); - } - - } - -} diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/gradle/RefreshProjectsSettingsJob.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/gradle/RefreshProjectsSettingsJob.java deleted file mode 100644 index 198006c2..00000000 --- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/gradle/RefreshProjectsSettingsJob.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2017-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.spring.javaformat.eclipse.gradle; - -import java.io.File; -import java.io.IOException; -import java.util.LinkedHashSet; -import java.util.Set; - -import com.google.common.base.Optional; -import com.gradleware.tooling.toolingmodel.OmniEclipseProject; -import com.gradleware.tooling.toolingmodel.OmniProjectTask; -import com.gradleware.tooling.toolingmodel.repository.FetchStrategy; -import io.spring.javaformat.eclipse.Executor; -import io.spring.javaformat.eclipse.Messages; -import io.spring.javaformat.eclipse.projectsettings.ProjectSettingsFilesLocator; -import org.eclipse.buildship.core.CorePlugin; -import org.eclipse.buildship.core.workspace.GradleBuild; -import org.eclipse.buildship.core.workspace.GradleWorkspaceManager; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.gradle.tooling.CancellationTokenSource; -import org.gradle.tooling.GradleConnector; - -/** - * Job to trigger refresh of project specific settings when the gradle plugin is used. - * - * @author Phillip Webb - */ -@SuppressWarnings("restriction") -public class RefreshProjectsSettingsJob extends Job { - - private static final Object TASK_NAME = "checkFormatMain"; - - private final CancellationTokenSource tokenSource; - - public RefreshProjectsSettingsJob() { - super("Refresh spring-javaformat project settings"); - this.tokenSource = GradleConnector.newCancellationTokenSource(); - } - - @Override - protected IStatus run(IProgressMonitor monitor) { - try { - new Executor(Messages.springFormatSettingsImportError).run(() -> { - configureProjects(monitor); - }); - } - catch (CoreException ex) { - return ex.getStatus(); - } - return Status.OK_STATUS; - } - - private void configureProjects(IProgressMonitor monitor) - throws CoreException, IOException { - GradleWorkspaceManager manager = CorePlugin.gradleWorkspaceManager(); - for (IProject project : ResourcesPlugin.getWorkspace().getRoot().getProjects()) { - Optional build = manager.getGradleBuild(project); - if (build.isPresent()) { - configureProject(project, build.get(), monitor); - } - } - } - - private void configureProject(IProject project, GradleBuild build, - IProgressMonitor monitor) throws CoreException, IOException { - Set projects = build.getModelProvider() - .fetchEclipseGradleProjects(FetchStrategy.FORCE_RELOAD, - this.tokenSource.token(), monitor); - if (hasSpringFormatPlugin(projects)) { - ProjectSettingsFilesLocator locator = new ProjectSettingsFilesLocator( - getSearchFolders(projects)); - locator.locateSettingsFiles().applyToProject(project, monitor); - } - } - - private boolean hasSpringFormatPlugin(Set projects) { - for (OmniEclipseProject project : projects) { - for (OmniProjectTask task : project.getGradleProject().getProjectTasks()) { - if (isSpringFormatPlugin(task)) { - return true; - } - } - } - return false; - } - - private boolean isSpringFormatPlugin(OmniProjectTask task) { - return TASK_NAME.equals(task.getName()); - } - - private Set getSearchFolders(Set projects) { - Set searchFolders = new LinkedHashSet<>(); - for (OmniEclipseProject project : projects) { - searchFolders.add(project.getProjectDirectory()); - searchFolders.add(project.getRoot().getProjectDirectory()); - } - return searchFolders; - } - -} diff --git a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/m2e/ProjectSettingsConfigurator.java b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/m2e/MavenProjectSettingsConfigurator.java similarity index 78% rename from spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/m2e/ProjectSettingsConfigurator.java rename to spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/m2e/MavenProjectSettingsConfigurator.java index 69aca233..62e94e26 100644 --- a/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/m2e/ProjectSettingsConfigurator.java +++ b/spring-javaformat-eclipse/io.spring.javaformat.eclipse/src/io/spring/javaformat/eclipse/m2e/MavenProjectSettingsConfigurator.java @@ -1,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -20,37 +20,36 @@ import java.util.ArrayList; import java.util.List; -import io.spring.javaformat.eclipse.Executor; -import io.spring.javaformat.eclipse.Messages; -import io.spring.javaformat.eclipse.projectsettings.ProjectSettingsFiles; -import io.spring.javaformat.eclipse.projectsettings.ProjectSettingsFilesLocator; import org.apache.maven.project.MavenProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.m2e.core.project.configurator.AbstractProjectConfigurator; import org.eclipse.m2e.core.project.configurator.ProjectConfigurationRequest; +import io.spring.javaformat.eclipse.Executor; +import io.spring.javaformat.eclipse.Messages; +import io.spring.javaformat.eclipse.projectsettings.ProjectSettingsFiles; +import io.spring.javaformat.eclipse.projectsettings.ProjectSettingsFilesLocator; + /** - * Configurator to apply project specific settings. + * Configurator to apply project-specific settings to Maven projects. * * @author Phillip Webb */ -public class ProjectSettingsConfigurator extends AbstractProjectConfigurator { +public class MavenProjectSettingsConfigurator extends AbstractProjectConfigurator { @Override - public void configure(ProjectConfigurationRequest request, IProgressMonitor monitor) - throws CoreException { + public void configure(ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException { new Executor(Messages.springFormatSettingsImportError).run(() -> { List searchFolders = getSearchFolders(request); - ProjectSettingsFiles settingsFiles = new ProjectSettingsFilesLocator( - searchFolders).locateSettingsFiles(); - settingsFiles.applyToProject(request.getProject(), monitor); + ProjectSettingsFiles settingsFiles = new ProjectSettingsFilesLocator(searchFolders).locateSettingsFiles(); + 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 880f8b2e..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,11 +1,11 @@ /* - * Copyright 2012-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -16,14 +16,9 @@ package io.spring.javaformat.eclipse.projectsettings; -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Collections; @@ -31,7 +26,6 @@ import java.util.Map; import java.util.Properties; import java.util.function.Supplier; -import java.util.stream.Collectors; /** * Eclipse properties used to modify setting files content. @@ -42,8 +36,7 @@ class ProjectProperties { private static final String COPYRIGHT_YEAR = "copyright-year"; - private static final DateTimeFormatter YEAR_FORMATTER = DateTimeFormatter - .ofPattern("yyyy"); + private static final DateTimeFormatter YEAR_FORMATTER = DateTimeFormatter.ofPattern("yyyy"); private static final Map> DEFAULTS; static { @@ -75,22 +68,13 @@ private void addFromProperties(Properties properties) { }); } - public InputStream getModifiedContent(ProjectSettingsFile file) throws IOException { + public ProjectSettingsFile getModifiedContent(ProjectSettingsFile file) throws IOException { if (file.getName().equals("org.eclipse.jdt.ui.prefs")) { - String content = loadContent(file); - content = content.replace("Copyright the original author or authors", - "Copyright " + get(COPYRIGHT_YEAR) - + " the original author or authors"); - return new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)); - } - return file.getContent(); - } - - private String loadContent(ProjectSettingsFile file) throws IOException { - try (BufferedReader reader = new BufferedReader( - new InputStreamReader(file.getContent()))) { - return reader.lines().collect(Collectors.joining("\n")); + return file.withUpdatedContent( + (javaFormatConfig, content) -> content.replace("Copyright the original author or authors", + "Copyright " + get(COPYRIGHT_YEAR) + " the original author or authors")); } + return file; } String get(String name) { 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 75ea5790..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -16,10 +16,18 @@ package io.spring.javaformat.eclipse.projectsettings; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringWriter; +import java.nio.charset.StandardCharsets; +import java.util.function.BiFunction; + +import io.spring.javaformat.config.JavaFormatConfig; /** * A project settings file that can be copied to the project {@code .settings} folder. @@ -32,7 +40,7 @@ final class ProjectSettingsFile { private final ContentSupplier contentSupplier; - private ProjectSettingsFile(String name, ContentSupplier contentSupplier) { + ProjectSettingsFile(String name, ContentSupplier contentSupplier) { this.name = name; this.contentSupplier = contentSupplier; } @@ -48,11 +56,34 @@ public String getName() { /** * Return a new {@link InputStream} that can be used to access the content of the * file. + * @param javaFormatConfig the java format config to apply * @return the file contents * @throws IOException if the file cannot be opened */ - public InputStream getContent() throws IOException { - return this.contentSupplier.getContent(); + public InputStream getContent(JavaFormatConfig javaFormatConfig) throws IOException { + return this.contentSupplier.getContent(javaFormatConfig); + } + + /** + * Return a new {@link ProjectSettingsFile} where the original content is updated by + * the given operation. + * @param operation the operation to update the content + * @return a new {@link ProjectSettingsFile} instance + */ + public ProjectSettingsFile withUpdatedContent(BiFunction operation) { + return new ProjectSettingsFile(this.name, (javaFormatConfig) -> { + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(this.contentSupplier.getContent(javaFormatConfig)))) { + StringWriter writer = new StringWriter(); + char[] buffer = new char[4096]; + int read = 0; + while ((read = reader.read(buffer)) >= 0) { + writer.write(buffer, 0, read); + } + String content = operation.apply(javaFormatConfig, writer.toString()); + return new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)); + } + }); } /** @@ -61,7 +92,7 @@ public InputStream getContent() throws IOException { * @return a new {@link ProjectSettingsFile} */ public static ProjectSettingsFile fromFile(File file) { - return new ProjectSettingsFile(file.getName(), () -> new FileInputStream(file)); + return new ProjectSettingsFile(file.getName(), (javaFormatConfig) -> new FileInputStream(file)); } /** @@ -71,13 +102,13 @@ public static ProjectSettingsFile fromFile(File file) { * @return a new {@link ProjectSettingsFile} */ public static ProjectSettingsFile fromClasspath(Class sourceClass, String name) { - return new ProjectSettingsFile(name, () -> sourceClass.getResourceAsStream(name)); + return new ProjectSettingsFile(name, (javaFormatConfig) -> sourceClass.getResourceAsStream(name)); } @FunctionalInterface - private interface ContentSupplier { + interface ContentSupplier { - InputStream getContent() throws IOException; + InputStream getContent(JavaFormatConfig javaFormatConfig) throws IOException; } 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 9338fa54..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -17,18 +17,32 @@ package io.spring.javaformat.eclipse.projectsettings; import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; +import java.util.Comparator; import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; +import java.util.Set; +import java.util.TreeSet; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; +import io.spring.javaformat.config.JavaFormatConfig; + /** * A collection of {@link ProjectSettingsFile project setting files}. * @@ -45,8 +59,7 @@ public class ProjectSettingsFiles implements Iterable { * @param files the project settings files * @param projectProperties project properties */ - public ProjectSettingsFiles(Collection files, - ProjectProperties projectProperties) { + public ProjectSettingsFiles(Collection files, ProjectProperties projectProperties) { this.files = new ArrayList<>(files); this.projectProperties = projectProperties; } @@ -63,21 +76,73 @@ public Iterator iterator() { * @throws IOException on IO error * @throws CoreException on eclipse file creation failure */ - public void applyToProject(IProject project, IProgressMonitor monitor) - throws IOException, CoreException { + public void applyToProject(IProject project, IProgressMonitor monitor) throws IOException, CoreException { + JavaFormatConfig javaFormatConfig = getJavaFormatConfig(project); for (ProjectSettingsFile file : this) { + file = this.projectProperties.getModifiedContent(file); IFile destination = project.getFile(".settings/" + file.getName()); - if (destination.exists()) { - try { - destination.delete(true, monitor); + try (InputStream content = file.getContent(javaFormatConfig)) { + if (!destination.exists()) { + destination.create(new BufferedInputStream(content), true, monitor); } - catch (CoreException ex) { + else { + Properties properties = new OrderedProperties(); + try (InputStream existingContent = destination.getContents(true)) { + if (existingContent != null) { + properties.load(existingContent); + } + } + properties.load(content); + destination.setContents( + new ByteArrayInputStream(stripTimestamp(properties).getBytes(StandardCharsets.UTF_8)), + IResource.FORCE, monitor); } } - try (InputStream content = this.projectProperties.getModifiedContent(file)) { - destination.create(new BufferedInputStream(content), true, monitor); - } } } + private String stripTimestamp(Properties properties) throws IOException { + try (ByteArrayOutputStream output = new ByteArrayOutputStream()) { + properties.store(output, null); + String string = output.toString(StandardCharsets.UTF_8); + String separator = System.getProperty("line.separator"); + return string.substring(string.indexOf(separator) + separator.length()); + } + } + + private JavaFormatConfig getJavaFormatConfig(IProject project) { + try { + IPath location = project.getLocation(); + File file = (location != null) ? location.toFile() : null; + return JavaFormatConfig.findFrom(file); + } + catch (Exception ex) { + return JavaFormatConfig.DEFAULT; + } + } + + static class OrderedProperties extends Properties { + + private static final long serialVersionUID = 1L; + + @Override + public Set> entrySet() { + Set> set = new TreeSet>(new MapEntryKeyComparator()); + set.addAll(super.entrySet()); + return set; + }; + + } + + private static class MapEntryKeyComparator implements Comparator> { + + @Override + public int compare(Entry o1, Entry o2) { + Object k1 = o1.getKey(); + Object k2 = o2.getKey(); + return String.valueOf(k1).compareTo(String.valueOf(k2)); + } + + } + } 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 a89cea94..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -22,6 +22,8 @@ import java.util.LinkedHashMap; import java.util.Map; +import io.spring.javaformat.config.JavaFormatConfig; + /** * Locates project settings files to be applied to projects. * @@ -29,10 +31,11 @@ */ public class ProjectSettingsFilesLocator { + private static final String JDT_CORE_PREFS = "org.eclipse.jdt.core.prefs"; + private static final String[] SOURCE_FOLDERS = { "eclipse", ".eclipse" }; - private static final String[] DEFAULT_FILES = { "org.eclipse.jdt.core.prefs", - "org.eclipse.jdt.ui.prefs" }; + private static final String[] DEFAULT_FILES = { JDT_CORE_PREFS, "org.eclipse.jdt.ui.prefs" }; private final File[] searchFolders; @@ -53,13 +56,38 @@ public ProjectSettingsFiles locateSettingsFiles() throws IOException { } } for (String file : DEFAULT_FILES) { - putIfAbsent(files, ProjectSettingsFile.fromClasspath(getClass(), file)); + putIfAbsent(files, getDefaultSettingsFile(file)); } return new ProjectSettingsFiles(files.values(), projectProperties); } - private void add(ProjectProperties projectProperties, - Map files, File folder) throws IOException { + private ProjectSettingsFile getDefaultSettingsFile(String file) { + ProjectSettingsFile settingsFile = ProjectSettingsFile.fromClasspath(getClass(), file); + if (settingsFile.getName().equals(JDT_CORE_PREFS)) { + settingsFile = settingsFile.withUpdatedContent(this::updateFormatter); + } + return settingsFile; + } + + 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.jdk17.tabs", + "org.eclipse.jdt.core.javaFormatter=" + formatterId); + } + return 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; + } + + private void add(ProjectProperties projectProperties, Map files, File folder) + throws IOException { if (folder.exists() && folder.isDirectory()) { for (File file : folder.listFiles(this::isPrefsFile)) { putIfAbsent(files, ProjectSettingsFile.fromFile(file)); @@ -72,8 +100,7 @@ private boolean isPrefsFile(File file) { return file.getName().toLowerCase().endsWith(".prefs"); } - private void putIfAbsent(Map files, - ProjectSettingsFile candidate) { + private void putIfAbsent(Map files, ProjectSettingsFile candidate) { files.putIfAbsent(candidate.getName(), candidate); } 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 0a505b83..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 @@ -11,9 +11,7 @@ org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes= org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes= org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -25,7 +23,7 @@ org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning org.eclipse.jdt.core.compiler.problem.deadCode=warning org.eclipse.jdt.core.compiler.problem.deprecation=warning org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled org.eclipse.jdt.core.compiler.problem.discouragedReference=warning org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore org.eclipse.jdt.core.compiler.problem.enumIdentifier=error @@ -47,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 @@ -84,12 +82,12 @@ 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 -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=disabled org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled org.eclipse.jdt.core.compiler.problem.unusedImport=warning @@ -101,312 +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.compiler.source=1.8 -org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_module_statements=16 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -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_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 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -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.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 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false -org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=false -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=true -org.eclipse.jdt.core.formatter.comment.format_source_code=false -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=false -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=do not insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert -org.eclipse.jdt.core.formatter.comment.line_length=90 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=90 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=tab -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=true -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true -org.eclipse.jdt.core.javaFormatter=io.spring.javaformat.eclipse.formatter +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 edc0fff0..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 @@ -70,7 +71,7 @@ org.eclipse.jdt.ui.keywordthis=false org.eclipse.jdt.ui.ondemandthreshold=9999 org.eclipse.jdt.ui.overrideannotation=true org.eclipse.jdt.ui.staticondemandthreshold=9999 -org.eclipse.jdt.ui.text.custom_code_templates= +org.eclipse.jdt.ui.text.custom_code_templates= sp_cleanup.add_default_serial_version_id=true sp_cleanup.add_generated_serial_version_id=false sp_cleanup.add_missing_annotations=true @@ -103,6 +104,9 @@ sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class= sp_cleanup.qualify_static_member_accesses_with_declaring_class=true sp_cleanup.qualify_static_method_accesses_with_declaring_class=false sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_redundant_modifiers=true +sp_cleanup.remove_redundant_semicolons=true +sp_cleanup.remove_redundant_type_arguments=true sp_cleanup.remove_trailing_whitespaces=true sp_cleanup.remove_trailing_whitespaces_all=true sp_cleanup.remove_trailing_whitespaces_ignore_empty=false diff --git a/spring-javaformat-eclipse/pom.xml b/spring-javaformat-eclipse/pom.xml index 8c0fc90e..7bed9c79 100644 --- a/spring-javaformat-eclipse/pom.xml +++ b/spring-javaformat-eclipse/pom.xml @@ -1,21 +1,43 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat spring-javaformat-build - 0.0.7-SNAPSHOT + 0.0.48-SNAPSHOT spring-javaformat-eclipse pom - Spring JavaFormat Eclipse + Spring JavaFormat Eclipse Parent ${basedir}/.. + 17 + + + eclipse-jdk17 + p2 + ${eclipse.jdk17.repository} + + + eclipse-checkstyle + p2 + ${eclipse.checkstyle.repository} + + + + org.apache.maven.plugins + maven-javadoc-plugin + + 8 + -Xdoclint:none + false + + org.eclipse.tycho tycho-maven-plugin @@ -62,7 +84,6 @@ - diff --git a/spring-javaformat-gradle/io.spring.javaformat.gradle.plugin/pom.xml b/spring-javaformat-gradle/io.spring.javaformat.gradle.plugin/pom.xml new file mode 100644 index 00000000..1c2e0383 --- /dev/null +++ b/spring-javaformat-gradle/io.spring.javaformat.gradle.plugin/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + + io.spring.javaformat + spring-javaformat-gradle + 0.0.48-SNAPSHOT + + io.spring.javaformat + io.spring.javaformat.gradle.plugin + pom + Spring JavaFormat Gradle Plugin Marker Artifact + + ${basedir}/../.. + + + + io.spring.javaformat + spring-javaformat-gradle-plugin + ${project.version} + + + diff --git a/spring-javaformat-gradle/pom.xml b/spring-javaformat-gradle/pom.xml index 94fb6c76..681a1645 100644 --- a/spring-javaformat-gradle/pom.xml +++ b/spring-javaformat-gradle/pom.xml @@ -1,12 +1,12 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat spring-javaformat-build - 0.0.7-SNAPSHOT + 0.0.48-SNAPSHOT spring-javaformat-gradle pom @@ -32,5 +32,6 @@ spring-javaformat-gradle-plugin + io.spring.javaformat.gradle.plugin diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/build.gradle b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/build.gradle index 062d9ec7..e088814b 100644 --- a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/build.gradle +++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'java' + id 'java-gradle-plugin' id 'eclipse' } @@ -8,11 +8,9 @@ repositories { } dependencies { - compile localGroovy() - compile gradleApi() - 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 { @@ -22,11 +20,15 @@ jar { } test { + useJUnitPlatform() testLogging { events "passed", "skipped", "failed" } } +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + eclipseJdt { inputFile = rootProject.file('../../.eclipse/org.eclipse.jdt.core.prefs') doLast { @@ -59,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.jar b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/gradle/wrapper/gradle-wrapper.jar index 91ca28c8..e708b1c0 100644 Binary files a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/gradle/wrapper/gradle-wrapper.jar and b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/gradle/wrapper/gradle-wrapper.jar differ 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 16d28051..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-4.7-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 cccdd3d5..22cf4de8 100755 --- a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/gradlew +++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/gradlew @@ -1,5 +1,21 @@ #!/usr/bin/env sh +# +# 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. +# 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. +# + ############################################################################## ## ## Gradle start up script for UN*X @@ -28,7 +44,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -66,6 +82,7 @@ esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then @@ -109,10 +126,11 @@ if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath @@ -138,19 +156,19 @@ if $cygwin ; then else eval `echo args$i`="\"$arg\"" fi - i=$((i+1)) + i=`expr $i + 1` done case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi @@ -159,14 +177,9 @@ save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } -APP_ARGS=$(save "$@") +APP_ARGS=`save "$@"` # Collect all arguments for the java command, following the shell quoting and substitution rules eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - exec "$JAVACMD" "$@" diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/gradlew.bat b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/gradlew.bat index e95643d6..18a320c0 100755 --- a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/gradlew.bat +++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@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. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -35,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -45,28 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/pom.xml b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/pom.xml index 41381e09..3170b015 100644 --- a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/pom.xml +++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/pom.xml @@ -1,12 +1,12 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat spring-javaformat-gradle - 0.0.7-SNAPSHOT + 0.0.48-SNAPSHOT spring-javaformat-gradle-plugin pom @@ -32,6 +32,7 @@ false compile + true ${project.build.directory}/dependencies/compile @@ -111,19 +112,14 @@ io.spring.javaformat - spring-javaformat-formatter + spring-javaformat-formatter-shaded ${project.version} + io.spring.javaformat - spring-javaformat-formatter-eclipse-runtime + spring-javaformat-checkstyle ${project.version} - - - * - * - - diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/FormatterTask.java b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/FormatterTask.java deleted file mode 100644 index 3388fe46..00000000 --- a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/FormatterTask.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2017-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.spring.javaformat.gradle; - -import java.nio.charset.Charset; -import java.util.stream.Stream; - -import io.spring.javaformat.formatter.FileEdit; -import io.spring.javaformat.formatter.FileFormatter; -import org.gradle.api.tasks.Input; -import org.gradle.api.tasks.Optional; -import org.gradle.api.tasks.SourceTask; - -/** - * Abstract base class for formatter tasks. - * - * @author Phillip Webb - */ -abstract class FormatterTask extends SourceTask { - - private String encoding; - - /** - * Get the file encoding in use. - * @return the encoding the file encoding - */ - @Input - @Optional - public String getEncoding() { - return this.encoding; - } - - /** - * Set the file encoding in use. - * @param encoding the encoding to set - */ - public void setEncoding(String encoding) { - this.encoding = encoding; - } - - /** - * Format the source files and provide a {@link Stream} of {@link FileEdit} instances. - * @return the file edits - */ - protected final Stream formatFiles() { - FileFormatter formatter = new FileFormatter(); - Charset encoding = (getEncoding() != null ? Charset.forName(getEncoding()) - : Charset.defaultCharset()); - return formatter.formatFiles(getSource().getFiles(), encoding); - } - -} 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 98f802d0..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -16,17 +16,34 @@ 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; /** * Spring Format Gradle Plugin. * * @author Phillip Webb + * @author Andy Wilkinson */ public class SpringJavaFormatPlugin implements Plugin { @@ -36,39 +53,90 @@ 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() { this.project.getPlugins().withType(JavaBasePlugin.class, (plugin) -> { - Task formatAll = this.project.task(FormatTask.NAME); - formatAll.setDescription(FormatTask.DESCRIPTION); - Task checkAll = this.project.task(CheckTask.NAME); - checkAll.setDescription(CheckTask.DESCRIPTION); - this.project.getTasks().getByName(JavaBasePlugin.CHECK_TASK_NAME) - .dependsOn(checkAll); - this.project.getConvention().getPlugin(JavaPluginConvention.class) - .getSourceSets() - .all((sourceSet) -> addSourceTasks(sourceSet, checkAll, formatAll)); + TaskContainer tasks = this.project.getTasks(); + TaskProvider formatAllProvider = tasks.register(Format.NAME); + formatAllProvider.configure((formatAll) -> formatAll.setDescription(Format.DESCRIPTION)); + 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.getExtensions() + .getByType(JavaPluginExtension.class) + .getSourceSets() + .all((sourceSet) -> addSourceTasks(sourceSet, checkAllProvider, formatAllProvider)); }); } - private void addSourceTasks(SourceSet sourceSet, Task checkAll, Task formatAll) { - CheckTask checkTask = addSourceTask(sourceSet, CheckTask.class, CheckTask.NAME, - CheckTask.DESCRIPTION); - checkAll.dependsOn(checkTask); - FormatTask formatSourceSet = addSourceTask(sourceSet, FormatTask.class, - FormatTask.NAME, FormatTask.DESCRIPTION); - formatSourceSet.conventionMapping("encoding", () -> "UTF-8"); - formatAll.dependsOn(formatSourceSet); + 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); + formatTaskProvider.configure((format) -> format.conventionMapping("encoding", () -> "UTF-8")); + formatAllProvider.configure((formatAll) -> formatAll.dependsOn(formatTaskProvider)); } - private T addSourceTask(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); - T task = this.project.getTasks().create(taskName, taskType); - task.setDescription(desc + " for " + sourceSet.getName()); - task.setSource(sourceSet.getAllJava()); - return task; + TaskProvider provider = this.project.getTasks().register(taskName, taskType); + provider.configure((task) -> { + task.setDescription(desc + " for " + sourceSet.getName()); + task.setSource(sourceSet.getAllJava()); + JavaFormatConfig config = JavaFormatConfig.findFrom(this.project.getProjectDir()); + task.getIndentationStyle().convention(config.getIndentationStyle()); + task.getJavaBaseline().convention(config.getJavaBaseline()); + }); + 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/CheckTask.java b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/tasks/CheckFormat.java similarity index 50% rename from spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/CheckTask.java rename to spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/tasks/CheckFormat.java index 34817517..d6504edf 100644 --- a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/CheckTask.java +++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/tasks/CheckFormat.java @@ -1,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,23 +14,30 @@ * limitations under the License. */ -package io.spring.javaformat.gradle; +package io.spring.javaformat.gradle.tasks; import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.util.Collections; import java.util.List; import java.util.stream.Collectors; -import io.spring.javaformat.formatter.FileEdit; -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; /** * {@link FormatterTask} to check formatting. * * @author Phillip Webb */ -public class CheckTask extends FormatterTask { +@CacheableTask +public class CheckFormat extends FormatterTask { /** * The name of the task. @@ -42,17 +49,34 @@ public class CheckTask extends FormatterTask { */ public static final String DESCRIPTION = "Run Spring Java formatting checks"; + private File reportLocation; + @TaskAction public void checkFormatting() throws IOException, InterruptedException { List problems = formatFiles().filter(FileEdit::hasEdits) - .map(FileEdit::getFile).collect(Collectors.toList()); + .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"); - problems.stream().forEach((f) -> message.append(" * " + f + "\n")); + StringBuilder message = new StringBuilder("Formatting violations found in the following files:\n"); + problems.stream().forEach((f) -> message.append(" * " + getProject().relativePath(f) + "\n")); message.append("\nRun `format` to fix."); - throw new GradleException(message.toString()); + Files.write(this.reportLocation.toPath(), Collections.singletonList(message.toString()), + StandardOpenOption.CREATE); + throw new VerificationException(message.toString()); + } + else { + this.reportLocation.createNewFile(); } } + @OutputFile + public File getReportLocation() { + return this.reportLocation; + } + + public void setReportLocation(File reportLocation) { + this.reportLocation = reportLocation; + } + } diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/FormatTask.java b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/tasks/Format.java similarity index 78% rename from spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/FormatTask.java rename to spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/tasks/Format.java index 038289d9..b1f6b312 100644 --- a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/FormatTask.java +++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/tasks/Format.java @@ -1,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,21 +14,24 @@ * limitations under the License. */ -package io.spring.javaformat.gradle; +package io.spring.javaformat.gradle.tasks; import java.io.IOException; -import io.spring.javaformat.formatter.FileEdit; -import io.spring.javaformat.formatter.FileFormatterException; import org.gradle.api.GradleException; +import org.gradle.api.file.FileTree; +import org.gradle.api.tasks.OutputFiles; import org.gradle.api.tasks.TaskAction; +import io.spring.javaformat.formatter.FileEdit; +import io.spring.javaformat.formatter.FileFormatterException; + /** * {@link FormatterTask} to apply formatting. * * @author Phillip Webb */ -public class FormatTask extends FormatterTask { +public class Format extends FormatterTask { /** * The name of the task. @@ -50,4 +53,9 @@ public void format() throws IOException, InterruptedException { } } + @OutputFiles + public FileTree getOutputFiles() { + return super.getSource(); + } + } 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 new file mode 100644 index 00000000..b99ded44 --- /dev/null +++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/tasks/FormatterTask.java @@ -0,0 +1,109 @@ +/* + * 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.tasks; + +import java.nio.charset.Charset; +import java.util.stream.Stream; + +import org.gradle.api.file.FileTree; +import org.gradle.api.provider.Property; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.InputFiles; +import org.gradle.api.tasks.Optional; +import org.gradle.api.tasks.PathSensitive; +import org.gradle.api.tasks.PathSensitivity; +import org.gradle.api.tasks.SourceTask; + +import io.spring.javaformat.config.IndentationStyle; +import io.spring.javaformat.config.JavaBaseline; +import io.spring.javaformat.config.JavaFormatConfig; +import io.spring.javaformat.formatter.FileEdit; +import io.spring.javaformat.formatter.FileFormatter; + +/** + * Abstract base class for formatter tasks. + * + * @author Phillip Webb + */ +public abstract class FormatterTask extends SourceTask { + + private String encoding; + + private final Property indentationStyle; + + private final Property javaBaseline; + + FormatterTask() { + this.indentationStyle = getProject().getObjects().property(IndentationStyle.class); + this.javaBaseline = getProject().getObjects().property(JavaBaseline.class); + } + + /** + * Get the file encoding in use. + * @return the encoding the file encoding + */ + @Input + @Optional + public String getEncoding() { + return this.encoding; + } + + /** + * Set the file encoding in use. + * @param encoding the encoding to set + */ + public void setEncoding(String encoding) { + this.encoding = encoding; + } + + /** + * The indentation style used for formatting. + * @return the indentation style + */ + @Input + public Property getIndentationStyle() { + return this.indentationStyle; + } + + /** + * The Java baseline used for formatting. + * @return the Java baseline + */ + @Input + public Property getJavaBaseline() { + return this.javaBaseline; + } + + @Override + @InputFiles + @PathSensitive(PathSensitivity.RELATIVE) + public FileTree getSource() { + return super.getSource(); + } + + /** + * Format the source files and provide a {@link Stream} of {@link FileEdit} instances. + * @return the file edits + */ + protected final Stream formatFiles() { + JavaFormatConfig javaFormatConfig = JavaFormatConfig.of(this.javaBaseline.get(), this.indentationStyle.get()); + FileFormatter formatter = new FileFormatter(javaFormatConfig); + Charset encoding = (getEncoding() != null ? Charset.forName(getEncoding()) : Charset.defaultCharset()); + return formatter.formatFiles(getSource().getFiles(), encoding); + } + +} 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 0d7a1949..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -16,40 +16,136 @@ package io.spring.javaformat.gradle; +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.StandardOpenOption; +import java.util.Arrays; +import java.util.stream.Stream; -import io.spring.javaformat.gradle.testkit.GradleBuild; import org.gradle.testkit.runner.BuildResult; import org.gradle.testkit.runner.TaskOutcome; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.io.TempDir; + +import io.spring.javaformat.gradle.tasks.CheckFormat; +import io.spring.javaformat.gradle.testkit.GradleBuild; +import io.spring.javaformat.gradle.testkit.GradleBuildExtension; import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link CheckTask}. + * Tests for {@link CheckFormat}. * * @author Phillip Webb */ +@ExtendWith(GradleBuildExtension.class) public class CheckTaskTests { - @Rule - public final GradleBuild gradleBuild = new GradleBuild(); + private final GradleBuild gradleBuild = new GradleBuild(); + + @TempDir + public File temp; + + @Test + 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 + 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); + result = gradleBuild.build("check"); + assertThat(result.task(":checkFormatMain").getOutcome()).isEqualTo(TaskOutcome.UP_TO_DATE); + } + + @Test + 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(), + "// 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 + 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); + Files.write(new File(this.gradleBuild.getProjectDir(), ".springjavaformatconfig").toPath(), + Arrays.asList("indentation-style=spaces")); + result = gradleBuild.buildAndFail("check"); + assertThat(result.task(":checkFormatMain").getOutcome()).isEqualTo(TaskOutcome.FAILED); + } + + @Test + 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); + Files.write(new File(this.gradleBuild.getProjectDir(), ".springjavaformatconfig").toPath(), + Arrays.asList("indentation-style=spaces")); + result = gradleBuild.build("check"); + assertThat(result.task(":checkFormatMain").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); + } + + @Test + 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); + Files.write(new File(this.gradleBuild.getProjectDir(), ".springjavaformatconfig").toPath(), + Arrays.asList("java-baseline=8")); + result = gradleBuild.build("check"); + assertThat(result.task(":checkFormatMain").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); + result = gradleBuild.build("check"); + assertThat(result.task(":checkFormatMain").getOutcome()).isEqualTo(TaskOutcome.UP_TO_DATE); + } @Test - public void checkOk() throws IOException { - BuildResult result = this.gradleBuild.source("src/test/resources/check-ok") - .build("check"); - assertThat(result.task(":checkFormatMain").getOutcome()) - .isEqualTo(TaskOutcome.SUCCESS); + 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 checkBad() throws IOException { - BuildResult result = this.gradleBuild.source("src/test/resources/check-bad") - .buildAndFail("check"); - assertThat(result.task(":checkFormatMain").getOutcome()) - .isEqualTo(TaskOutcome.FAILED); + 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); + result = gradleBuild.buildAndFail("check"); + assertThat(result.task(":checkFormatMain").getOutcome()).isEqualTo(TaskOutcome.FAILED); + } + + 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 (!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) { + throw new IllegalStateException(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 dc752dc0..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -19,35 +19,85 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.util.Arrays; -import io.spring.javaformat.gradle.testkit.GradleBuild; import org.gradle.testkit.runner.BuildResult; +import org.gradle.testkit.runner.GradleRunner; import org.gradle.testkit.runner.TaskOutcome; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import io.spring.javaformat.gradle.tasks.Format; +import io.spring.javaformat.gradle.testkit.GradleBuild; +import io.spring.javaformat.gradle.testkit.GradleBuildExtension; import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link FormatTask}. + * Tests for {@link Format}. * * @author Phillip Webb */ +@ExtendWith(GradleBuildExtension.class) public class FormatTaskTests { - @Rule - public final GradleBuild gradleBuild = new GradleBuild(); + private final GradleBuild gradleBuild = new GradleBuild(); + + @Test + 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"); + String formattedContent = new String(Files.readAllBytes(formattedFile.toPath())); + assertThat(formattedContent).contains("class Simple {").contains(" public static void main"); + } + + @Test + 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); + // Format of already formatted files + assertThat(runner.build().task(":formatMain").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); + // Up-to-date + assertThat(runner.build().task(":formatMain").getOutcome()).isEqualTo(TaskOutcome.UP_TO_DATE); + } + + @Test + 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); + // Format of already formatted files + assertThat(runner.build().task(":formatMain").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); + // Up-to-date + assertThat(runner.build().task(":formatMain").getOutcome()).isEqualTo(TaskOutcome.UP_TO_DATE); + Files.write(new File(this.gradleBuild.getProjectDir(), ".springjavaformatconfig").toPath(), + Arrays.asList("java-baseline=8")); + assertThat(runner.build().task(":formatMain").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); + } + + @Test + 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); + // Format of already formatted files + assertThat(runner.build().task(":formatMain").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); + // Up-to-date + assertThat(runner.build().task(":formatMain").getOutcome()).isEqualTo(TaskOutcome.UP_TO_DATE); + Files.write(new File(this.gradleBuild.getProjectDir(), ".springjavaformatconfig").toPath(), + Arrays.asList("indentation-style=spaces")); + assertThat(runner.build().task(":formatMain").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); + } @Test - public 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"); + 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"); String formattedContent = new String(Files.readAllBytes(formattedFile.toPath())); - assertThat(formattedContent).contains("class Simple {"); + assertThat(formattedContent).contains("class Simple {").contains(" public static void main"); } } 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 3403ddb4..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -19,11 +19,13 @@ import java.io.File; import java.io.FileReader; 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.util.ArrayList; import java.util.Arrays; +import java.util.Comparator; import java.util.List; import java.util.stream.Stream; @@ -31,27 +33,23 @@ import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathFactory; -import io.spring.javaformat.formatter.Formatter; -import io.spring.javaformat.formatter.eclipse.Preparator; -import org.eclipse.jdt.core.formatter.CodeFormatter; -import org.gradle.internal.impldep.com.google.common.base.Charsets; import org.gradle.testkit.runner.BuildResult; import org.gradle.testkit.runner.GradleRunner; -import org.junit.rules.TemporaryFolder; -import org.junit.rules.TestRule; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; +import org.gradle.util.GradleVersion; import org.xml.sax.InputSource; +import io.spring.javaformat.formatter.Formatter; + +import static org.assertj.core.api.Assertions.assertThat; + /** - * A {@link TestRule} for running a Gradle build using {@link GradleRunner}. + * A {@code GradleBuild} is used to run a Gradle build using {@link GradleRunner}. * * @author Andy Wilkinson + * @author Scott Frederick * @author Phillip Webb */ -public class GradleBuild implements TestRule { - - private final TemporaryFolder temp = new TemporaryFolder(); +public class GradleBuild { private File source; @@ -59,46 +57,15 @@ public class GradleBuild implements TestRule { private String gradleVersion; - @Override - public Statement apply(Statement base, Description description) { - return this.temp.apply(new Statement() { - - @Override - public void evaluate() throws Throwable { - before(); - try { - base.evaluate(); - } - finally { - after(); - } - } - - }, description); - } + private GradleVersion expectDeprecationWarnings; - private void before() throws IOException { - this.projectDir = this.temp.newFolder(); + void before() throws IOException { + this.projectDir = Files.createTempDirectory("gradle-").toFile(); } - private void after() { - GradleBuild.this.source = null; - } - - private String getPluginClasspath() { - return absolutePath("build/classes/java/main") + "," - + absolutePath("build/resources/main") + "," - + pathOfJarContaining(Formatter.class) + "," - + pathOfJarContaining(Preparator.class) + "," - + pathOfJarContaining(CodeFormatter.class); - } - - private String absolutePath(String path) { - return new File(path).getAbsolutePath(); - } - - private String pathOfJarContaining(Class type) { - return type.getProtectionDomain().getCodeSource().getLocation().getPath(); + void after() throws IOException { + this.source = null; + Files.walk(this.projectDir.toPath()).sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete); } public GradleBuild source(String source) { @@ -115,7 +82,12 @@ public GradleBuild source(File source) { public BuildResult build(String... arguments) { try { - return prepareRunner(arguments).build(); + BuildResult result = prepareRunner(arguments).build(); + if (this.expectDeprecationWarnings == null || (this.gradleVersion != null + && this.expectDeprecationWarnings.compareTo(GradleVersion.version(this.gradleVersion)) > 0)) { + assertThat(result.getOutput()).doesNotContain("Deprecated").doesNotContain("deprecated"); + } + return result; } catch (Exception ex) { throw new RuntimeException(ex); @@ -134,11 +106,10 @@ public BuildResult buildAndFail(String... arguments) { public GradleRunner prepareRunner(String... arguments) throws IOException { copyFolder(this.source.getAbsoluteFile().toPath(), this.projectDir.toPath()); File buildFile = new File(this.projectDir, "build.gradle"); - String scriptContent = new String(Files.readAllBytes(buildFile.toPath())) - .replace("{version}", getSpringFormatVersion()); - Files.write(buildFile.toPath(), scriptContent.getBytes(Charsets.UTF_8)); - GradleRunner gradleRunner = GradleRunner.create().withProjectDir(this.projectDir) - .withDebug(true); + String scriptContent = new String(Files.readAllBytes(buildFile.toPath())).replace("{version}", + getSpringFormatVersion()); + Files.write(buildFile.toPath(), scriptContent.getBytes(StandardCharsets.UTF_8)); + GradleRunner gradleRunner = GradleRunner.create().withProjectDir(this.projectDir).withDebug(true); if (this.gradleVersion != null) { gradleRunner.withGradleVersion(this.gradleVersion); } @@ -150,13 +121,28 @@ public GradleRunner prepareRunner(String... arguments) throws IOException { return gradleRunner.withArguments(allArguments); } + private String getPluginClasspath() { + return absolutePath("build/classes/java/main") + "," + absolutePath("build/resources/main") + "," + + pathOfJarContaining(Formatter.class); + } + + private String absolutePath(String path) { + return new File(path).getAbsolutePath(); + } + + private String pathOfJarContaining(Class type) { + return type.getProtectionDomain().getCodeSource().getLocation().getPath(); + } + private void copyFolder(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); - Files.copy(child, destination, StandardCopyOption.REPLACE_EXISTING); + if (!destination.toFile().isDirectory()) { + Files.copy(child, destination, StandardCopyOption.REPLACE_EXISTING); + } } catch (Exception ex) { throw new IllegalStateException(ex); @@ -184,8 +170,7 @@ public String getGradleVersion() { private String getSpringFormatVersion() { return evaluateExpression( - "/*[local-name()='project']/*[local-name()='parent']/*[local-name()='version']" - + "/text()"); + "/*[local-name()='project']/*[local-name()='parent']/*[local-name()='version']" + "/text()"); } private String evaluateExpression(String expression) { 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 new file mode 100644 index 00000000..bb5b8a6d --- /dev/null +++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/java/io/spring/javaformat/gradle/testkit/GradleBuildExtension.java @@ -0,0 +1,54 @@ +/* + * 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.testkit; + +import java.lang.reflect.Field; + +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.Extension; +import org.junit.jupiter.api.extension.ExtensionContext; + +/** + * An {@link Extension} for managing the lifecycle of a {@link GradleBuild} stored in a + * field named {@code gradleBuild}. + * + * @author Andy Wilkinson + * @author Scott Frederick + * @author Phillip Webb + */ +public class GradleBuildExtension implements BeforeEachCallback, AfterEachCallback { + + @Override + public void beforeEach(ExtensionContext context) throws Exception { + extractGradleBuild(context).before(); + } + + @Override + public void afterEach(ExtensionContext context) throws Exception { + extractGradleBuild(context).after(); + } + + private GradleBuild extractGradleBuild(ExtensionContext context) throws Exception { + Object testInstance = context.getRequiredTestInstance(); + Field gradleBuildField = testInstance.getClass().getDeclaredField("gradleBuild"); + gradleBuildField.setAccessible(true); + GradleBuild gradleBuild = (GradleBuild) gradleBuildField.get(testInstance); + return gradleBuild; + } + +} diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/check-ok/src/main/java/simple/package-info.java b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/check-ok/src/main/java/simple/package-info.java new file mode 100644 index 00000000..35b32be0 --- /dev/null +++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/check-ok/src/main/java/simple/package-info.java @@ -0,0 +1 @@ +package simple; \ No newline at end of file diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/check-spaces/build.gradle b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/check-spaces/build.gradle new file mode 100644 index 00000000..d6ca2f32 --- /dev/null +++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/check-spaces/build.gradle @@ -0,0 +1,10 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'java' +apply plugin: 'io.spring.javaformat' + +sourceCompatibility = 1.8 diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/check-spaces/src/main/java/simple/Simple.java b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/check-spaces/src/main/java/simple/Simple.java new file mode 100644 index 00000000..cd5523a6 --- /dev/null +++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/check-spaces/src/main/java/simple/Simple.java @@ -0,0 +1,15 @@ +package simple; + +/** + * Simple indented with spaces. + * + * @author Andy Wilkinson + * @since 1.0.0 + */ +public class Simple { + + public static void main(String[] args) throws Exception { + // Main method + } + +} 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-gradle/spring-javaformat-gradle-plugin/src/test/resources/format-spaces/.springjavaformatconfig b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/format-spaces/.springjavaformatconfig new file mode 100644 index 00000000..881903b2 --- /dev/null +++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/format-spaces/.springjavaformatconfig @@ -0,0 +1 @@ +indentation-style=spaces diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/format-spaces/build.gradle b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/format-spaces/build.gradle new file mode 100644 index 00000000..d6ca2f32 --- /dev/null +++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/format-spaces/build.gradle @@ -0,0 +1,10 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'java' +apply plugin: 'io.spring.javaformat' + +sourceCompatibility = 1.8 diff --git a/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/format-spaces/src/main/java/simple/Simple.java b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/format-spaces/src/main/java/simple/Simple.java new file mode 100644 index 00000000..83b618ce --- /dev/null +++ b/spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/test/resources/format-spaces/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-intellij/pom.xml b/spring-javaformat-intellij-idea/pom.xml similarity index 67% rename from spring-javaformat-intellij/pom.xml rename to spring-javaformat-intellij-idea/pom.xml index c05c2a24..9de7cec6 100644 --- a/spring-javaformat-intellij/pom.xml +++ b/spring-javaformat-intellij-idea/pom.xml @@ -1,15 +1,15 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat spring-javaformat-build - 0.0.7-SNAPSHOT + 0.0.48-SNAPSHOT - spring-javaformat-intellij + spring-javaformat-intellij-idea pom - Spring JavaFormat IntelliJ + Spring JavaFormat IntelliJ IDEA ${basedir}/.. @@ -30,7 +30,7 @@ - spring-javaformat-intellij-runtime - spring-javaformat-intellij-plugin + spring-javaformat-intellij-idea-runtime + spring-javaformat-intellij-idea-plugin diff --git a/spring-javaformat-intellij/spring-javaformat-intellij-plugin/pom.xml b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/pom.xml similarity index 54% rename from spring-javaformat-intellij/spring-javaformat-intellij-plugin/pom.xml rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/pom.xml index f3ceee80..7915af9f 100644 --- a/spring-javaformat-intellij/spring-javaformat-intellij-plugin/pom.xml +++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/pom.xml @@ -1,24 +1,21 @@ - + 4.0.0 io.spring.javaformat - spring-javaformat-intellij - 0.0.7-SNAPSHOT + spring-javaformat-intellij-idea + 0.0.48-SNAPSHOT - spring-javaformat-intellij-plugin - Spring JavaFormat IntelliJ Plugin + spring-javaformat-intellij-idea-plugin + Spring JavaFormat IntelliJ IDEA Plugin ${basedir}/../.. + 17 - - io.spring.javaformat - spring-javaformat-formatter - ${project.version} - io.spring.javaformat spring-javaformat-formatter-eclipse-runtime @@ -30,64 +27,75 @@ + + io.spring.javaformat + spring-javaformat-formatter + ${project.version} + io.spring.javaformat - spring-javaformat-intellij-runtime + spring-javaformat-intellij-idea-runtime ${project.version} pom provided - io.spring.javaformat.intellij - extensions + org.jetbrains + annotations + 13.0 + provided + + + io.spring.javaformat.intellij.idea + app ${project.version} provided - io.spring.javaformat.intellij - platform-api + io.spring.javaformat.intellij.idea + jps-model ${project.version} provided - io.spring.javaformat.intellij + io.spring.javaformat.intellij.idea util ${project.version} provided - io.spring.javaformat.intellij - idea + io.spring.javaformat.intellij.idea + util_rt ${project.version} provided - io.spring.javaformat.intellij + io.spring.javaformat.intellij.idea maven ${project.version} provided - io.spring.javaformat.intellij - maven-server-api + io.spring.javaformat.intellij.idea + maven-server ${project.version} provided - io.spring.javaformat.intellij + io.spring.javaformat.intellij.idea gradle ${project.version} provided - io.spring.javaformat.intellij + io.spring.javaformat.intellij.idea gradle-tooling-extension-api ${project.version} provided - io.spring.javaformat.intellij + io.spring.javaformat.intellij.idea gradle-tooling-extension-impl ${project.version} provided @@ -102,9 +110,45 @@ picocontainer provided + + org.jetbrains.kotlinx + kotlinx-coroutines-core + 1.6.4 + provided + + + it.unimi.dsi + fastutil + 8.5.11 + provided + + + + ${basedir}/src/main/resources + true + + META-INF/plugin.xml + + + + ${basedir}/src/main/resources + + META-INF/plugin.xml + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + 11 + false + -Xdoclint:none + + org.apache.maven.plugins maven-shade-plugin diff --git a/spring-javaformat-intellij/spring-javaformat-intellij-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 85% rename from spring-javaformat-intellij/spring-javaformat-intellij-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 5363413f..255a72f1 100644 --- a/spring-javaformat-intellij/spring-javaformat-intellij-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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -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; @@ -35,8 +35,7 @@ class EclipseDocumentAdapter extends Document { } @Override - public void replace(int pos, int length, String text, long modificationStamp) - throws BadLocationException { + public void replace(int pos, int length, String text, long modificationStamp) throws BadLocationException { super.replace(pos, length, text, modificationStamp); this.intellijDocument.replaceString(pos, pos + length, text); } diff --git a/spring-javaformat-intellij/spring-javaformat-intellij-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 76% rename from spring-javaformat-intellij/spring-javaformat-intellij-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 53428476..1b1fdc9e 100644 --- a/spring-javaformat-intellij/spring-javaformat-intellij-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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -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 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/spring-javaformat-intellij-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 81% rename from spring-javaformat-intellij/spring-javaformat-intellij-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 372b8742..84128c15 100644 --- a/spring-javaformat-intellij/spring-javaformat-intellij-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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -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; @@ -23,16 +23,17 @@ import com.intellij.openapi.vfs.VirtualFileManager; 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; @@ -55,8 +56,7 @@ public void stop() { private void check() { VirtualFile baseDir = getProject().getBaseDir(); - VirtualFile triggerFile = (baseDir == null ? null - : baseDir.findChild(TRIGGER_FILE)); + VirtualFile triggerFile = (baseDir == null ? null : baseDir.findChild(TRIGGER_FILE)); State currentState = (triggerFile == null ? State.NOT_ACTIVE : State.ACTIVE); if (!currentState.equals(this.state)) { getTrigger().updateState(currentState); @@ -65,8 +65,7 @@ private void check() { } public static Factory factory() { - return (project, trigger) -> new FileMonitor(project, trigger, - VirtualFileManager.getInstance()); + return (project, trigger) -> new FileMonitor(project, trigger, VirtualFileManager.getInstance()); } /** diff --git a/spring-javaformat-intellij/spring-javaformat-intellij-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 71% rename from spring-javaformat-intellij/spring-javaformat-intellij-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 050596af..8a41e441 100644 --- a/spring-javaformat-intellij/spring-javaformat-intellij-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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,11 +14,11 @@ * 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; import com.intellij.openapi.externalSystem.model.task.TaskData; @@ -26,9 +26,11 @@ import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataImportListener; import com.intellij.openapi.project.Project; import com.intellij.util.messages.MessageBusConnection; -import io.spring.format.formatter.intellij.codestyle.monitor.Trigger.State; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.util.GradleConstants; +import io.spring.format.formatter.intellij.state.State; + /** * {@link Monitor} that looks for a {@code spring-javaformat-gradle-plugin} declaration in * the build.gradle file. @@ -37,25 +39,35 @@ */ public class GradleMonitor extends Monitor { - private static final String FORMAT_TASK = "io.spring.javaformat.gradle.FormatTask"; + private static final Logger logger = Logger.getInstance(GradleMonitor.class); + + private static final String FORMAT_TASK = "io.spring.javaformat.gradle.tasks.Format"; 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() { - ProjectDataManager projectDataManager = ServiceManager - .getService(ProjectDataManager.class); - boolean hasFormatPlugin = hasFormatPlugin(projectDataManager - .getExternalProjectsData(getProject(), GradleConstants.SYSTEM_ID)); + logger.info("Checking " + getProject().getName() + " for use of Spring Java Format"); + ProjectDataManager projectDataManager = ProjectDataManager.getInstance(); + boolean hasFormatPlugin = hasFormatPlugin( + projectDataManager.getExternalProjectsData(getProject(), GradleConstants.SYSTEM_ID)); getTrigger().updateState(hasFormatPlugin ? State.ACTIVE : State.NOT_ACTIVE); } private boolean hasFormatPlugin(Collection projectInfos) { for (ExternalProjectInfo projectInfo : projectInfos) { if (hasFormatPlugin(projectInfo.getExternalProjectStructure())) { + logger.info(projectInfo + " uses Spring Java Format"); return true; } } diff --git a/spring-javaformat-intellij/spring-javaformat-intellij-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 78% rename from spring-javaformat-intellij/spring-javaformat-intellij-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 bf358518..6ddb20e8 100644 --- a/spring-javaformat-intellij/spring-javaformat-intellij-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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,19 +14,20 @@ * limitations under the License. */ -package io.spring.format.formatter.intellij.codestyle.monitor; +package io.spring.format.formatter.intellij.monitor; import java.util.List; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; -import io.spring.format.formatter.intellij.codestyle.monitor.Trigger.State; import org.jetbrains.idea.maven.project.MavenProject; import org.jetbrains.idea.maven.project.MavenProjectChanges; import org.jetbrains.idea.maven.project.MavenProjectsManager; import org.jetbrains.idea.maven.project.MavenProjectsTree.Listener; import org.jetbrains.idea.maven.server.NativeMavenProjectHolder; +import io.spring.format.formatter.intellij.state.State; + /** * {@link Monitor} that looks for a {@code spring-javaformat-maven-plugin} declaration in * the POM.xml file. @@ -41,8 +42,7 @@ public class MavenMonitor extends Monitor { private final MavenProjectsManager mavenProjectsManager; - public MavenMonitor(Project project, Trigger trigger, - MavenProjectsManager mavenProjectsManager) { + public MavenMonitor(Project project, Trigger trigger, MavenProjectsManager mavenProjectsManager) { super(project, trigger); this.mavenProjectsManager = mavenProjectsManager; attachListener(mavenProjectsManager); @@ -53,15 +53,13 @@ private void attachListener(MavenProjectsManager mavenProjectsManager) { mavenProjectsManager.addProjectsTreeListener(new Listener() { @Override - public void projectsUpdated( - List> updated, + public void projectsUpdated(List> updated, List deleted) { check(); } @Override - public void projectResolved( - Pair projectWithChanges, + public void projectResolved(Pair projectWithChanges, NativeMavenProjectHolder nativeMavenProject) { check(); } @@ -94,10 +92,8 @@ private boolean hasSpringFormatPlugin(List projects) { public static Factory factory() { return (project, trigger) -> { - MavenProjectsManager mavenProjectsManager = MavenProjectsManager - .getInstance(project); - return (mavenProjectsManager == null ? null - : new MavenMonitor(project, trigger, mavenProjectsManager)); + MavenProjectsManager mavenProjectsManager = MavenProjectsManager.getInstance(project); + return (mavenProjectsManager == null ? null : new MavenMonitor(project, trigger, mavenProjectsManager)); }; } diff --git a/spring-javaformat-intellij/spring-javaformat-intellij-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 90% rename from spring-javaformat-intellij/spring-javaformat-intellij-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 527e6a75..d0663c86 100644 --- a/spring-javaformat-intellij/spring-javaformat-intellij-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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -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/spring-javaformat-intellij-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 86% rename from spring-javaformat-intellij/spring-javaformat-intellij-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 4faf26d0..cfe8dc4a 100644 --- a/spring-javaformat-intellij/spring-javaformat-intellij-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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -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; @@ -23,7 +23,8 @@ import java.util.function.Consumer; 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 @@ -46,8 +47,7 @@ public class Monitors { * @param stateChangeConsumer consumer called whenever the ultimate state changes * @param monitorFactories factories used to create the monitors */ - public Monitors(Project project, Consumer stateChangeConsumer, - Monitor.Factory... monitorFactories) { + public Monitors(Project project, Consumer stateChangeConsumer, Monitor.Factory... monitorFactories) { this(project, stateChangeConsumer, Arrays.asList(monitorFactories)); } @@ -57,8 +57,7 @@ public Monitors(Project project, Consumer stateChangeConsumer, * @param stateChangeConsumer consumer called whenever the ultimate state changes * @param monitorFactories factories used to create the monitors */ - public Monitors(Project project, Consumer stateChangeConsumer, - List monitorFactories) { + public Monitors(Project project, Consumer stateChangeConsumer, List monitorFactories) { this.stateChangeConsumer = stateChangeConsumer; List monitors = new ArrayList<>(monitorFactories.size()); for (Monitor.Factory factory : monitorFactories) { @@ -81,8 +80,7 @@ private Trigger addTrigger() { activeAfter = containsActiveState(this.states); } if (activeBefore != activeAfter) { - this.stateChangeConsumer - .accept(activeAfter ? State.ACTIVE : State.NOT_ACTIVE); + this.stateChangeConsumer.accept(activeAfter ? State.ACTIVE : State.NOT_ACTIVE); } }; } diff --git a/spring-javaformat-intellij/spring-javaformat-intellij-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 69% rename from spring-javaformat-intellij/spring-javaformat-intellij-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 ab68bc0b..f1c7d223 100644 --- a/spring-javaformat-intellij/spring-javaformat-intellij-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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -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/startup/SpringJavaFormatStartupActivity.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/startup/SpringJavaFormatStartupActivity.java new file mode 100644 index 00000000..f11e345c --- /dev/null +++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/startup/SpringJavaFormatStartupActivity.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. + */ + +package io.spring.format.formatter.intellij.startup; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.startup.StartupActivity; + +/** + * {@link StartupActivity} hook for {@link ManagedSpringJavaFormatProject}. + * + * @author Phillip Webb + */ +public class SpringJavaFormatStartupActivity implements StartupActivity { + + @Override + public void runActivity(Project 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/spring-javaformat-intellij-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 63% rename from spring-javaformat-intellij/spring-javaformat-intellij-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 c6b53547..935b738e 100644 --- a/spring-javaformat-intellij/spring-javaformat-intellij-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,11 +1,11 @@ /* - * Copyright 2012-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,43 +14,44 @@ * 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; import javax.swing.Icon; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.IconLoader; -import com.intellij.openapi.wm.IdeFrame; import com.intellij.openapi.wm.StatusBar; import com.intellij.openapi.wm.StatusBarWidget; import com.intellij.openapi.wm.WindowManager; -import com.intellij.openapi.wm.WindowManagerListener; import com.intellij.util.Consumer; -import io.spring.format.formatter.intellij.codestyle.monitor.Trigger.State; +import com.intellij.util.concurrency.AppExecutorUtil; + +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) { - windowManager.addListener(new UpdateOnFrameCreateListener(state)); + AppExecutorUtil.getAppScheduledExecutorService().schedule(() -> retryUpdate(state), 1, TimeUnit.SECONDS); return; } if (state == State.ACTIVE) { @@ -61,6 +62,10 @@ public void update(State state) { } } + private void retryUpdate(State state) { + ApplicationManager.getApplication().invokeLater(() -> update(state)); + } + private void show(StatusBar statusBar) { if (this.widget == null) { this.widget = new Widget(); @@ -75,38 +80,12 @@ private void hide(final StatusBar statusBar) { } } - /** - * {@link WindowManagerListener} used to defer setting the status if the IDE frame - * isn't available. - */ - private class UpdateOnFrameCreateListener implements WindowManagerListener { - - private final State state; - - UpdateOnFrameCreateListener(State state) { - this.state = state; - } - - @Override - public void frameCreated(IdeFrame frame) { - WindowManager.getInstance().removeListener(this); - ApplicationManager.getApplication().invokeLater(() -> update(this.state)); - } - - @Override - public void beforeFrameReleased(IdeFrame frame) { - } - - } - /** * The {@link StatusBarWidget} component for the status. */ - private static class Widget - implements StatusBarWidget, StatusBarWidget.IconPresentation { + private static class Widget implements StatusBarWidget, StatusBarWidget.IconPresentation { - public static final Icon ICON = IconLoader - .getIcon("/spring-javaformat/formatOn.png"); + public static final Icon ICON = IconLoader.getIcon("/spring-javaformat/formatOn.png"); @Override public String ID() { 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 new file mode 100644 index 00000000..21c74b0f --- /dev/null +++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/resources/META-INF/plugin.xml @@ -0,0 +1,15 @@ + + spring-javaformat + Spring Javaformat + A source formatter that applies wrapping and whitespace conventions to + provide a consistent “Spring” style. + + ${project.version} + Spring Team + org.jetbrains.idea.maven + org.jetbrains.plugins.gradle + + + + + diff --git a/spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/main/resources/spring-javaformat/formatOn.png b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/resources/spring-javaformat/formatOn.png similarity index 100% rename from spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/main/resources/spring-javaformat/formatOn.png rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/resources/spring-javaformat/formatOn.png diff --git a/spring-javaformat-intellij/spring-javaformat-intellij-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 79% rename from spring-javaformat-intellij/spring-javaformat-intellij-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 9d9cb1b6..4fe90665 100644 --- a/spring-javaformat-intellij/spring-javaformat-intellij-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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,10 +14,10 @@ * 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.Test; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; @@ -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/spring-javaformat-intellij-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 73% rename from spring-javaformat-intellij/spring-javaformat-intellij-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 a56ebaaa..f4c2d2a4 100644 --- a/spring-javaformat-intellij/spring-javaformat-intellij-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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,14 +14,14 @@ * 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; import com.intellij.openapi.util.TextRange; import org.eclipse.jface.text.IRegion; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -33,27 +33,26 @@ 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 { - List ranges = Arrays.asList(new TextRange(10, 20), - new TextRange(30, 35)); + 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); assertThat(regions[0].getOffset()).isEqualTo(10); 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 new file mode 100644 index 00000000..b6202b0d --- /dev/null +++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-runtime/pom.xml @@ -0,0 +1,301 @@ + + + 4.0.0 + + io.spring.javaformat + spring-javaformat-intellij-idea + 0.0.48-SNAPSHOT + + spring-javaformat-intellij-idea-runtime + pom + Spring JavaFormat IntelliJ IDEA Runtime + + ${basedir}/../.. + 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 + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + com.googlecode.maven-download-plugin + download-maven-plugin + + + download-intellij-binary + validate + + wget + + + ${intellij.binary} + intellij.tar.gz + + + + download-intellij-source + install + + wget + + + ${intellij.source} + intellij-source.zip + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + prepare-intellij + install + + run + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.apache.maven.plugins + maven-install-plugin + + + install-intellij-util + install + false + + install-file + + + ${project.build.directory}/intellij/util.jar + ${intellij.source.directory}/util-sources.zip + io.spring.javaformat.intellij.idea + util + ${project.version} + jar + true + + + + install-intellij-util_rt + install + false + + install-file + + + ${project.build.directory}/intellij/util_rt.jar + ${intellij.source.directory}/util_rt-sources.zip + io.spring.javaformat.intellij.idea + util_rt + ${project.version} + jar + true + + + + install-intellij-app + install + false + + install-file + + + ${project.build.directory}/intellij/app.jar + ${intellij.source.directory}/app-sources.zip + io.spring.javaformat.intellij.idea + app + ${project.version} + jar + true + + + + install-intellij-maven + install + false + + install-file + + + ${project.build.directory}/intellij/maven.jar + ${intellij.source.directory}/maven-sources.zip + io.spring.javaformat.intellij.idea + maven + ${project.version} + jar + true + + + + install-intellij-maven-server + install + false + + install-file + + + ${project.build.directory}/intellij/maven-server.jar + ${intellij.source.directory}/maven-server-sources.zip + io.spring.javaformat.intellij.idea + maven-server + ${project.version} + jar + true + + + + install-intellij-gradle + install + false + + install-file + + + ${project.build.directory}/intellij/gradle.jar + ${intellij.source.directory}/gradle-sources.zip + io.spring.javaformat.intellij.idea + gradle + ${project.version} + jar + true + + + + install-intellij-gradle-tooling-extension-api + install + false + + install-file + + + ${project.build.directory}/intellij/gradle-tooling-extension-api.jar + ${intellij.source.directory}/gradle-tooling-extension-api-sources.zip + io.spring.javaformat.intellij.idea + gradle-tooling-extension-api + ${project.version} + jar + true + + + + install-intellij-jps-model + install + false + + install-file + + + ${project.build.directory}/intellij/jps-model.jar + ${intellij.source.directory}/jps-model-sources.zip + io.spring.javaformat.intellij.idea + jps-model + ${project.version} + jar + true + + + + install-intellij-gradle-tooling-extension-impl + install + false + + install-file + + + ${project.build.directory}/intellij/gradle-tooling-extension-impl.jar + ${intellij.source.directory}/gradle-tooling-extension-impl-sources.zip + io.spring.javaformat.intellij.idea + gradle-tooling-extension-impl + ${project.version} + jar + true + + + + + + + diff --git a/spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/main/java/io/spring/format/formatter/intellij/SpringFormatComponent.java b/spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/main/java/io/spring/format/formatter/intellij/SpringFormatComponent.java deleted file mode 100644 index 3afb96e8..00000000 --- a/spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/main/java/io/spring/format/formatter/intellij/SpringFormatComponent.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2017-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.spring.format.formatter.intellij; - -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -import com.intellij.designer.designSurface.ScalableComponent; -import com.intellij.ide.util.PropertiesComponent; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.AbstractProjectComponent; -import com.intellij.openapi.components.ProjectComponent; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import com.intellij.psi.codeStyle.CodeStyleManager; -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; -import org.picocontainer.MutablePicoContainer; - -/** - * {@link ProjectComponent} to add Spring Java Format IntelliJ support. - * - * @author Phillip Webb - */ -public class SpringFormatComponent extends AbstractProjectComponent { - - private static final String CODE_STYLE_MANAGER_KEY = CodeStyleManager.class.getName(); - - private static final String ACTIVE_PROPERTY = ScalableComponent.class.getName() - + ".ACTIVE"; - - private final StatusIndicator statusIndicator; - - private final Lock lock = new ReentrantLock(); - - private Monitors monitors; - - private static final Logger logger = Logger.getInstance(SpringFormatComponent.class); - - private PropertiesComponent properties; - - protected SpringFormatComponent(Project project) { - super(project); - this.statusIndicator = new StatusIndicator(project); - this.properties = PropertiesComponent.getInstance(project); - } - - @Override - public void initComponent() { - if (this.properties.getBoolean(ACTIVE_PROPERTY, false)) { - update(State.ACTIVE); - } - this.monitors = new Monitors(this.myProject, this::update, FileMonitor.factory(), - MavenMonitor.factory(), GradleMonitor.factory()); - } - - @Override - public void disposeComponent() { - if (this.monitors != null) { - this.monitors.stop(); - this.monitors = null; - } - } - - private void update(State state) { - this.lock.lock(); - try { - CodeStyleManager manager = CodeStyleManager.getInstance(this.myProject); - if (manager == null) { - logger.warn("Unable to find exiting CodeStyleManager"); - return; - } - if (state == State.ACTIVE && !(manager instanceof SpringCodeStyleManager)) { - logger.debug("Enabling SpringCodeStyleManager"); - reregisterComponent(new SpringCodeStyleManager(manager)); - this.properties.setValue(ACTIVE_PROPERTY, true); - } - if (state == State.NOT_ACTIVE - && (manager instanceof SpringCodeStyleManager)) { - logger.debug("Disabling SpringCodeStyleManager"); - reregisterComponent(((SpringCodeStyleManager) manager).getDelegate()); - this.properties.setValue(ACTIVE_PROPERTY, false); - } - ApplicationManager.getApplication() - .invokeLater(() -> this.statusIndicator.update(state)); - } - finally { - this.lock.unlock(); - } - } - - private void reregisterComponent(CodeStyleManager manager) { - MutablePicoContainer container = (MutablePicoContainer) this.myProject - .getPicoContainer(); - container.unregisterComponent(CODE_STYLE_MANAGER_KEY); - container.registerComponentInstance(CODE_STYLE_MANAGER_KEY, manager); - } - -} diff --git a/spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/DelegatingCodeStyleManager.java b/spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/DelegatingCodeStyleManager.java deleted file mode 100644 index 98035623..00000000 --- a/spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/DelegatingCodeStyleManager.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright 2017-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package 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 ranges) - throws IncorrectOperationException { - this.delegate.reformatText(file, ranges); - } - - @Override - public void reformatTextWithContext(PsiFile file, Collection ranges) - throws IncorrectOperationException { - this.delegate.reformatTextWithContext(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 - @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; - } - -} diff --git a/spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/SpringCodeStyleManager.java b/spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/SpringCodeStyleManager.java deleted file mode 100644 index 7b4d0919..00000000 --- a/spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/SpringCodeStyleManager.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2017-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package 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.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 ranges) - throws IncorrectOperationException { - reformat(file, () -> ranges, () -> super.reformatText(file, ranges)); - } - - @Override - public void reformatTextWithContext(PsiFile file, Collection ranges) - throws IncorrectOperationException { - reformat(file, () -> ranges, () -> super.reformatTextWithContext(file, ranges)); - } - - 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/spring-javaformat-intellij-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/SpringReformatter.java b/spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/SpringReformatter.java deleted file mode 100644 index cb40baa7..00000000 --- a/spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/SpringReformatter.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2017-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.spring.format.formatter.intellij.codestyle; - -import java.util.Collection; -import java.util.function.Supplier; - -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.StdFileTypes; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiBundle; -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 io.spring.javaformat.formatter.Formatter; -import org.eclipse.jface.text.IRegion; -import org.eclipse.text.edits.TextEdit; - -/** - * Reformatter used by {@link SpringCodeStyleManager} to determine when formatting can - * apply and to perform the actual formatting. - * - * @author Phillip Webb - */ -class SpringReformatter { - - 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 StdFileTypes.JAVA.equals(file.getFileType()); - } - - public void reformat(PsiFile file, Collection 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( - PsiBundle.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(PsiBundle.message( - "cannot.modify.a.read.only.file", virtualFile.getPresentableUrl())); - } - - private void reformat(PsiFile file, Collection ranges, Document document) { - if (document != null) { - Formatter formatter = new Formatter(); - String source = document.getText(); - IRegion[] regions = EclipseRegionAdapter.asArray(ranges); - TextEdit edit = formatter.format(source, regions); - 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/spring-javaformat-intellij-plugin/src/main/resources/META-INF/plugin.xml b/spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/main/resources/META-INF/plugin.xml deleted file mode 100644 index 5f8225c8..00000000 --- a/spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/main/resources/META-INF/plugin.xml +++ /dev/null @@ -1,16 +0,0 @@ - - spring-javaformat - spring-javaformat - 1.0 - Spring - - - org.jetbrains.idea.maven - org.jetbrains.plugins.gradle - - - io.spring.format.formatter.intellij.SpringFormatComponent - - - - diff --git a/spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/DelegatingCodeStyleManagerTests.java b/spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/DelegatingCodeStyleManagerTests.java deleted file mode 100644 index 11d03da5..00000000 --- a/spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/DelegatingCodeStyleManagerTests.java +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright 2017-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package 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.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import static org.assertj.core.api.Assertions.assertThat; -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; - - @Before - @Test - 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); - verify(this.delegate).reformatTextWithContext(this.file, 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/spring-javaformat-intellij-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/SpringCodeStyleManagerTests.java b/spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/SpringCodeStyleManagerTests.java deleted file mode 100644 index 9efa32a1..00000000 --- a/spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/SpringCodeStyleManagerTests.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2017-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package 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.CodeStyleManager; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; -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; - - @Before - 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); - verify(this.delegate).reformatTextWithContext(this.file, 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/spring-javaformat-intellij-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/SpringReformatterTests.java b/spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/SpringReformatterTests.java deleted file mode 100644 index c2896c6f..00000000 --- a/spring-javaformat-intellij/spring-javaformat-intellij-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/SpringReformatterTests.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2017-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package 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.psi.PsiDocumentManager; -import com.intellij.psi.PsiFile; -import com.intellij.util.IncorrectOperationException; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -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 { - - @Rule - public ExpectedException thrown = ExpectedException.none(); - - @Mock - private Project project; - - @Mock - private Application application; - - @Mock - private PsiDocumentManager documentManager; - - private SpringReformatter reformatter; - - @Mock - private PsiFile file; - - private Collection ranges = Arrays.asList(new TextRange(10, 20)); - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - 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 { - this.thrown.expect(IncorrectOperationException.class); - 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/spring-javaformat-intellij-runtime/pom.xml b/spring-javaformat-intellij/spring-javaformat-intellij-runtime/pom.xml deleted file mode 100644 index dfab70ae..00000000 --- a/spring-javaformat-intellij/spring-javaformat-intellij-runtime/pom.xml +++ /dev/null @@ -1,285 +0,0 @@ - - - 4.0.0 - - io.spring.javaformat - spring-javaformat-intellij - 0.0.7-SNAPSHOT - - spring-javaformat-intellij-runtime - pom - Spring JavaFormat IntelliJ Runtime - - ${basedir}/../.. - https://download.jetbrains.com/idea/ideaIC-2018.2-no-jdk.tar.gz - 528c3e895fb1d20a5fef2a212667d00861204ff9 - https://github.com/JetBrains/intellij-community/archive/182.3684.zip - intellij-community-182.3684 - - - - - org.apache.maven.plugins - maven-deploy-plugin - - true - - - - com.googlecode.maven-download-plugin - download-maven-plugin - - - download-intellij-binary - validate - - wget - - - ${intellij.binary} - ${intellij.binary.sha1} - intellij.tgz - - - - download-intellij-source - install - - wget - - - ${intellij.source} - intellij-source.zip - - - - - - org.apache.maven.plugins - maven-antrun-plugin - - - prepare-intellij - install - - run - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.apache.maven.plugins - maven-install-plugin - - - install-intellij-platform-api - install - false - - install-file - - - ${project.build.directory}/intellij/platform-api.jar - ${project.build.directory}/intellij-source/platform-api-sources.zip - io.spring.javaformat.intellij - platform-api - ${project.version} - jar - true - - - - install-intellij-util - install - false - - install-file - - - ${project.build.directory}/intellij/util.jar - ${project.build.directory}/intellij-source/util-sources.zip - io.spring.javaformat.intellij - util - ${project.version} - jar - true - - - - install-intellij-extensions - install - false - - install-file - - - ${project.build.directory}/intellij/extensions.jar - ${project.build.directory}/intellij-source/extensions-sources.zip - io.spring.javaformat.intellij - extensions - ${project.version} - jar - true - - - - install-intellij-idea - install - false - - install-file - - - ${project.build.directory}/intellij/idea.jar - io.spring.javaformat.intellij - idea - ${project.version} - jar - true - - - - install-intellij-maven - install - false - - install-file - - - ${project.build.directory}/intellij/maven.jar - ${project.build.directory}/intellij-source/maven-sources.zip - io.spring.javaformat.intellij - maven - ${project.version} - jar - true - - - - install-intellij-maven-server-api - install - false - - install-file - - - ${project.build.directory}/intellij/maven-server-api.jar - io.spring.javaformat.intellij - maven-server-api - ${project.version} - jar - true - - - - install-intellij-gradle - install - false - - install-file - - - ${project.build.directory}/intellij/gradle-common.jar - ${project.build.directory}/intellij-source/gradle-sources.zip - io.spring.javaformat.intellij - gradle - ${project.version} - jar - true - - - - install-intellij-gradle-tooling-extension-api - install - false - - install-file - - - ${project.build.directory}/intellij/gradle-tooling-extension-api.jar - ${project.build.directory}/intellij-source/gradle-tooling-extension-api-sources.zip - io.spring.javaformat.intellij - gradle-tooling-extension-api - ${project.version} - jar - true - - - - install-intellij-gradle-tooling-extension-impl - install - false - - install-file - - - ${project.build.directory}/intellij/gradle-tooling-extension-impl.jar - ${project.build.directory}/intellij-source/gradle-tooling-extension-impl-sources.zip - io.spring.javaformat.intellij - gradle-tooling-extension-impl - ${project.version} - jar - true - - - - - - - diff --git a/spring-javaformat-maven/pom.xml b/spring-javaformat-maven/pom.xml index 44014f42..61cb5d27 100644 --- a/spring-javaformat-maven/pom.xml +++ b/spring-javaformat-maven/pom.xml @@ -1,12 +1,12 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat spring-javaformat-build - 0.0.7-SNAPSHOT + 0.0.48-SNAPSHOT spring-javaformat-maven pom diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/pom.xml b/spring-javaformat-maven/spring-javaformat-maven-plugin/pom.xml index 5354af86..af8474d3 100644 --- a/spring-javaformat-maven/spring-javaformat-maven-plugin/pom.xml +++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/pom.xml @@ -1,11 +1,11 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat spring-javaformat-maven - 0.0.7-SNAPSHOT + 0.0.48-SNAPSHOT spring-javaformat-maven-plugin maven-plugin @@ -15,6 +15,16 @@ + + maven-clean-plugin + + + + out + + + + org.apache.maven.plugins maven-invoker-plugin @@ -91,15 +101,21 @@ + + org.codehaus.plexus + plexus-utils + + org.apache.maven maven-core + provided org.apache.maven maven-plugin-api + provided - org.apache.maven.plugin-tools maven-plugin-annotations diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-line-separator/pom.xml b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-line-separator/pom.xml new file mode 100644 index 00000000..b71be82c --- /dev/null +++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-line-separator/pom.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + io.spring.javaformat + apply-line-separator + 0.0.1.BUILD-SNAPSHOT + + UTF-8 + 1.8 + 1.8 + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + + apply + + + CR + + + + + + + diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-line-separator/src/main/java/simple/Simple.java b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-line-separator/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-line-separator/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-line-separator/verify.groovy b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-line-separator/verify.groovy new file mode 100644 index 00000000..21927be4 --- /dev/null +++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-line-separator/verify.groovy @@ -0,0 +1 @@ +new io.spring.format.maven.VerifyApply().verify(basedir, "\r") 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/apply-spaces/.springjavaformatconfig b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-spaces/.springjavaformatconfig new file mode 100644 index 00000000..881903b2 --- /dev/null +++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-spaces/.springjavaformatconfig @@ -0,0 +1 @@ +indentation-style=spaces diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-spaces/pom.xml b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-spaces/pom.xml new file mode 100644 index 00000000..252e99b8 --- /dev/null +++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-spaces/pom.xml @@ -0,0 +1,29 @@ + + + 4.0.0 + io.spring.javaformat + apply + 0.0.1.BUILD-SNAPSHOT + + UTF-8 + 1.8 + 1.8 + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + + apply + + + + + + + diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-spaces/src/main/java/simple/Simple.java b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-spaces/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-spaces/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-spaces/verify.groovy b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-spaces/verify.groovy new file mode 100644 index 00000000..644be98b --- /dev/null +++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply-spaces/verify.groovy @@ -0,0 +1 @@ +new io.spring.format.maven.VerifyApply().verify(basedir, true) diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply/pom.xml b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply/pom.xml index 8d63de00..252e99b8 100644 --- a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply/pom.xml +++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/apply/pom.xml @@ -1,12 +1,14 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat apply 0.0.1.BUILD-SNAPSHOT UTF-8 + 1.8 + 1.8 diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-bad/pom.xml b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-bad/pom.xml index 3cefcbad..7c23eaf4 100644 --- a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-bad/pom.xml +++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-bad/pom.xml @@ -1,12 +1,15 @@ - + 4.0.0 io.spring.javaformat validate-bad 0.0.1.BUILD-SNAPSHOT UTF-8 + 1.8 + 1.8 diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-gensource-exclude/pom.xml b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-gensource-exclude/pom.xml index 4d3a011a..d213bc7b 100644 --- a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-gensource-exclude/pom.xml +++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-gensource-exclude/pom.xml @@ -1,13 +1,15 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat validate-gensource-exclude 0.0.1.BUILD-SNAPSHOT UTF-8 + 1.8 + 1.8 diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-gensource-include/pom.xml b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-gensource-include/pom.xml index ee8948fb..820f2c24 100644 --- a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-gensource-include/pom.xml +++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-gensource-include/pom.xml @@ -1,13 +1,15 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat validate-gensource-include 0.0.1.BUILD-SNAPSHOT UTF-8 + 1.8 + 1.8 diff --git a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-ok/pom.xml b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-ok/pom.xml index af50bc98..61fde7ba 100644 --- a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-ok/pom.xml +++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-ok/pom.xml @@ -1,12 +1,14 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat validate-ok 0.0.1.BUILD-SNAPSHOT UTF-8 + 1.8 + 1.8 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/spring-javaformat-formatter/bin/src/test/resources/source/simple.txt b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-skip-global-property/src/main/java/simple/Simple.java similarity index 78% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/simple.txt rename to spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-skip-global-property/src/main/java/simple/Simple.java index a12ac39e..14f14516 100644 --- a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/simple.txt +++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-skip-global-property/src/main/java/simple/Simple.java @@ -6,10 +6,10 @@ * @author Phillip Webb * @since 1.0.0 */ -public class Simple { +public class Simple { public static void main(String[] args) throws Exception { - // FIXME + // 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/it/validate-skip/pom.xml b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-skip/pom.xml index 4da63f70..84c27feb 100644 --- a/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-skip/pom.xml +++ b/spring-javaformat-maven/spring-javaformat-maven-plugin/src/it/validate-skip/pom.xml @@ -1,12 +1,14 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat validate-skip 0.0.1.BUILD-SNAPSHOT UTF-8 + 1.8 + 1.8 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 d8de0e5a..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -20,29 +20,38 @@ import java.nio.charset.Charset; import java.util.List; -import io.spring.javaformat.formatter.FileEdit; -import io.spring.javaformat.formatter.FileFormatter; -import io.spring.javaformat.formatter.FileFormatterException; import org.apache.maven.plugin.MojoExecutionException; 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; /** * Applies source formatting to the codebase. * * @author Phillip Webb */ -@Mojo(name = "apply", defaultPhase = LifecyclePhase.PROCESS_SOURCES) +@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) + 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 { - FileFormatter formatter = new FileFormatter(); - formatter.formatFiles(files, encoding).filter(FileEdit::hasEdits) - .forEach(this::save); + getFormatter().formatFiles(files, encoding, lineSeparator).filter(FileEdit::hasEdits).forEach(this::save); } catch (FileFormatterException ex) { throw new MojoExecutionException("Unable to format file " + ex.getFile(), ex); 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 7bd528dd..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -22,10 +22,15 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +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; @@ -34,6 +39,9 @@ import org.codehaus.plexus.util.DirectoryScanner; import org.codehaus.plexus.util.FileUtils; +import io.spring.javaformat.config.JavaFormatConfig; +import io.spring.javaformat.formatter.FileFormatter; + /** * Base class for formatter Mojo. * @@ -43,8 +51,18 @@ public abstract class FormatMojo extends AbstractMojo { private static final String[] DEFAULT_INCLUDES = new String[] { "**/*.java" }; - private static final String GENERATED_SOURCE = File.separator + "generated-sources" - + File.separator; + private static final String GENERATED_SOURCES = File.separator + "generated-sources" + File.separator; + + private static final String GENERATED_TEST_SOURCES = File.separator + "generated-test-sources" + File.separator; + + private static final Map LINE_SEPARATOR; + static { + Map lineSeparator = new LinkedHashMap<>(); + lineSeparator.put("cr", "\r"); + lineSeparator.put("lf", "\n"); + lineSeparator.put("crlf", "\r\n"); + LINE_SEPARATOR = Collections.unmodifiableMap(lineSeparator); + } /** * The Maven Project Object. @@ -52,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. */ @@ -87,6 +111,12 @@ public abstract class FormatMojo extends AbstractMojo { @Parameter(property = "spring-javaformat.includeGeneratedSource", defaultValue = "false") private boolean includeGeneratedSource; + /** + * Specifies the line separator to use when formatting. + */ + @Parameter(property = "spring-javaformat.lineSeparator") + private String lineSeparator; + @Override public final void execute() throws MojoExecutionException, MojoFailureException { List directories = new ArrayList<>(); @@ -96,15 +126,21 @@ public final void execute() throws MojoExecutionException, MojoFailureException for (File directory : directories) { files.addAll(scan(directory)); } - Charset encoding = (this.encoding == null ? StandardCharsets.UTF_8 - : Charset.forName(this.encoding)); - execute(files, encoding); + Charset encoding = (this.encoding == null ? StandardCharsets.UTF_8 : Charset.forName(this.encoding)); + String lineSeparator = null; + if (this.lineSeparator != null) { + lineSeparator = LINE_SEPARATOR.get(this.lineSeparator.toLowerCase()); + if (lineSeparator == null) { + throw new MojoExecutionException("Unknown lineSeparator " + this.lineSeparator); + } + } + execute(files, encoding, this.lineSeparator != null ? lineSeparator : null); } 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) { @@ -124,7 +160,8 @@ private boolean isGeneratedSource(File file) { try { String path = file.getCanonicalPath() + File.separator; String projectPath = this.project.getBasedir().getCanonicalPath(); - return path.startsWith(projectPath) && path.contains(GENERATED_SOURCE); + return path.startsWith(projectPath) + && (path.contains(GENERATED_SOURCES) || path.contains(GENERATED_TEST_SOURCES)); } catch (IOException ex) { return false; @@ -140,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) { @@ -152,10 +191,28 @@ private boolean hasLength(Object[] array) { * Perform the formatting build-process behavior this {@code Mojo} implements. * @param files the files to process * @param encoding the encoding + * @param lineSeparator the line separator * @throws MojoExecutionException on execution error * @throws MojoFailureException on failure */ - protected abstract void execute(List files, Charset encoding) + protected abstract void execute(List files, Charset encoding, String lineSeparator) throws MojoExecutionException, MojoFailureException; + protected final FileFormatter getFormatter() { + JavaFormatConfig javaFormatConfig = JavaFormatConfig.findFrom(this.project.getBasedir()); + 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 1cc1e64d..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -21,42 +21,41 @@ import java.util.List; import java.util.stream.Collectors; -import io.spring.javaformat.formatter.FileEdit; -import io.spring.javaformat.formatter.FileFormatter; import org.apache.maven.plugin.MojoExecutionException; 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; + /** * Validates that source formatting matches the required style. * * @author Phillip Webb */ -@Mojo(name = "validate", defaultPhase = LifecyclePhase.VALIDATE) +@Mojo(name = "validate", defaultPhase = LifecyclePhase.VALIDATE, threadSafe = true) 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) + 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; } - FileFormatter formatter = new FileFormatter(); - List problems = formatter.formatFiles(files, encoding) - .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"); + StringBuilder message = new StringBuilder("Formatting violations found in the following files:\n"); problems.stream().forEach((f) -> message.append(" * " + f + "\n")); message.append("\nRun `spring-javaformat:apply` to fix."); throw new MojoFailureException(message.toString()); 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 d857633b..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -33,10 +33,33 @@ public class VerifyApply { private static final String JAVA_FILE = "src/main/java/simple/Simple.java"; public void verify(File base) throws IOException { - String formated = new String(Files.readAllBytes(base.toPath().resolve(JAVA_FILE)), - StandardCharsets.UTF_8); - assertThat(formated).contains("Simple.\n *\n * @author") - .contains("public class Simple {"); + verify(base, null); + } + + public void verify(File base, boolean spaces) throws IOException { + verify(base, null, spaces); + } + + public void verify(File base, String lineSeparator) throws IOException { + verify(base, lineSeparator, false); + } + + 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"); + } + + 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. + +![](./format.gif) + +## 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/samples/spring-javaformat-maven-sample/.springformat b/spring-javaformat-vscode/spring-javaformat-vscode-extension/test-workspace/Test.java similarity index 100% rename from samples/spring-javaformat-maven-sample/.springformat rename to spring-javaformat-vscode/spring-javaformat-vscode-extension/test-workspace/Test.java 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 0e0b747c..849cefc1 100644 --- a/spring-javaformat/pom.xml +++ b/spring-javaformat/pom.xml @@ -1,12 +1,12 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat spring-javaformat-build - 0.0.7-SNAPSHOT + 0.0.48-SNAPSHOT spring-javaformat pom @@ -31,10 +31,18 @@ + spring-javaformat-config spring-javaformat-checkstyle + spring-javaformat-formatter + spring-javaformat-formatter-test-support + spring-javaformat-formatter-tests spring-javaformat-formatter-eclipse-rewriter + spring-javaformat-formatter-eclipse-jdk8 + spring-javaformat-formatter-eclipse-jdk17 + spring-javaformat-formatter-eclipse-jdt-jdk8 + spring-javaformat-formatter-eclipse-jdt-jdk17 spring-javaformat-formatter-eclipse-runtime - spring-javaformat-formatter-eclipse - spring-javaformat-formatter + spring-javaformat-formatter-shader + spring-javaformat-formatter-shaded diff --git a/spring-javaformat/spring-javaformat-checkstyle/pom.xml b/spring-javaformat/spring-javaformat-checkstyle/pom.xml index 53820f79..5605577e 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/pom.xml +++ b/spring-javaformat/spring-javaformat-checkstyle/pom.xml @@ -1,11 +1,11 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat spring-javaformat - 0.0.7-SNAPSHOT + 0.0.48-SNAPSHOT spring-javaformat-checkstyle Spring JavaFormat CheckStyle @@ -14,6 +14,11 @@ + + io.spring.javaformat + spring-javaformat-config + ${project.version} + com.puppycrawl.tools 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 new file mode 100644 index 00000000..e595863f --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/FilteredModuleFactory.java @@ -0,0 +1,72 @@ +/* + * 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; + +import java.util.Set; + +import com.puppycrawl.tools.checkstyle.ModuleFactory; +import com.puppycrawl.tools.checkstyle.TreeWalkerAuditEvent; +import com.puppycrawl.tools.checkstyle.TreeWalkerFilter; +import com.puppycrawl.tools.checkstyle.api.AbstractCheck; +import com.puppycrawl.tools.checkstyle.api.CheckstyleException; +import com.puppycrawl.tools.checkstyle.api.Configuration; + +class FilteredModuleFactory implements ModuleFactory { + + static final TreeWalkerFilter FILTERED = new TreeWalkerFilter() { + + @Override + public boolean accept(TreeWalkerAuditEvent treeWalkerAuditEvent) { + return true; + } + + }; + + private final ModuleFactory moduleFactory; + + private final Set excludes; + + FilteredModuleFactory(ModuleFactory moduleFactory, Set excludes) { + this.moduleFactory = moduleFactory; + this.excludes = excludes; + } + + @Override + public Object createModule(String name) throws CheckstyleException { + Object module = this.moduleFactory.createModule(name); + if (isFiltered(module)) { + if (module instanceof AbstractCheck) { + return FILTERED; + } + throw new IllegalStateException("Unable to filter module " + module.getClass().getName()); + } + return module; + } + + boolean nonFiltered(Configuration configuration) { + return !isFiltered(configuration.getName()); + } + + private boolean isFiltered(Object module) { + return isFiltered(module.getClass().getName()); + } + + private boolean isFiltered(String name) { + return this.excludes != null && this.excludes.contains(name); + } + +} 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 dff22639..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -17,12 +17,16 @@ package io.spring.javaformat.checkstyle; import java.io.File; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Properties; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; +import java.util.stream.Collectors; import com.puppycrawl.tools.checkstyle.Checker; import com.puppycrawl.tools.checkstyle.DefaultContext; @@ -34,9 +38,11 @@ import com.puppycrawl.tools.checkstyle.api.ExternalResourceHolder; import com.puppycrawl.tools.checkstyle.api.FileSetCheck; import com.puppycrawl.tools.checkstyle.api.FileText; -import com.puppycrawl.tools.checkstyle.api.LocalizedMessage; -import com.puppycrawl.tools.checkstyle.filters.SuppressElement; +import com.puppycrawl.tools.checkstyle.api.Violation; +import com.puppycrawl.tools.checkstyle.filters.SuppressFilterElement; + import io.spring.javaformat.checkstyle.check.SpringHeaderCheck; +import io.spring.javaformat.checkstyle.check.SpringImportOrderCheck; /** * {@link FileSetCheck} that applies Spring checkstype rules. @@ -45,10 +51,6 @@ */ public class SpringChecks extends AbstractFileSetCheck implements ExternalResourceHolder { - private static final int DEFAULT_TAB_WIDTH = 8; - - private int tabWidth = DEFAULT_TAB_WIDTH; - private ClassLoader classLoader; private ModuleFactory moduleFactory; @@ -59,13 +61,13 @@ public class SpringChecks extends AbstractFileSetCheck implements ExternalResour private String headerCopyrightPattern = SpringHeaderCheck.DEFAULT_HEADER_COPYRIGHT_PATTERN; - /** - * Sets tab width. - * @param tabWidth the distance between tab stops - */ - public void setTabWidth(int tabWidth) { - this.tabWidth = tabWidth; - } + private String headerFile; + + private Set avoidStaticImportExcludes = Collections.emptySet(); + + private String projectRootPackage = SpringImportOrderCheck.DEFAULT_PROJECT_ROOT_PACKAGE; + + private Set excludes; /** * Sets classLoader to load class. @@ -85,16 +87,26 @@ public void setModuleFactory(ModuleFactory moduleFactory) { @Override public void finishLocalSetup() { + FilteredModuleFactory moduleFactory = new FilteredModuleFactory(this.moduleFactory, this.excludes); DefaultContext context = new DefaultContext(); context.add("classLoader", this.classLoader); context.add("severity", getSeverity()); - context.add("tabWidth", String.valueOf(this.tabWidth)); - context.add("moduleFactory", this.moduleFactory); + context.add("tabWidth", String.valueOf(getTabWidth())); + context.add("moduleFactory", moduleFactory); Properties properties = new Properties(); - properties.put("headerType", this.headerType); - properties.put("headerCopyrightPattern", this.headerCopyrightPattern); - this.checks = new SpringConfigurationLoader(context, this.moduleFactory) - .load(new PropertiesExpander(properties)); + put(properties, "headerType", this.headerType); + put(properties, "headerCopyrightPattern", this.headerCopyrightPattern); + put(properties, "headerFile", this.headerFile); + put(properties, "projectRootPackage", this.projectRootPackage); + put(properties, "avoidStaticImportExcludes", + this.avoidStaticImportExcludes.stream().collect(Collectors.joining(","))); + this.checks = new SpringConfigurationLoader(context, moduleFactory).load(new PropertiesExpander(properties)); + } + + private void put(Properties properties, String name, Object value) { + if (value != null) { + properties.put(name, value); + } } @Override @@ -102,8 +114,7 @@ public Set getExternalResourceLocations() { Set locations = new LinkedHashSet<>(); for (FileSetCheck check : this.checks) { if (check instanceof ExternalResourceHolder) { - locations.addAll( - ((ExternalResourceHolder) check).getExternalResourceLocations()); + locations.addAll(((ExternalResourceHolder) check).getExternalResourceLocations()); } } return locations; @@ -113,9 +124,8 @@ public Set getExternalResourceLocations() { public void beginProcessing(String charset) { super.beginProcessing(charset); try { - SuppressElement filter = new SuppressElement( - "[\\\\/]src[\\\\/]test[\\\\/]java[\\\\/]", "Javadoc*", null, null, - null, null); + SuppressFilterElement filter = new SuppressFilterElement("[\\\\/]src[\\\\/]test[\\\\/]java[\\\\/]", + "Javadoc*", null, null, null, null); ((Checker) getMessageDispatcher()).addFilter(filter); } catch (Exception ex) { @@ -124,19 +134,17 @@ public void beginProcessing(String charset) { } @Override - protected void processFiltered(File file, FileText fileText) - throws CheckstyleException { - SortedSet messages = new TreeSet<>(); + protected void processFiltered(File file, FileText fileText) throws CheckstyleException { + SortedSet violations = new TreeSet<>(); for (FileSetCheck check : this.checks) { - messages.addAll(check.process(file, fileText)); + violations.addAll(check.process(file, fileText)); } - addMessages(messages); + addViolations(violations); } @Override public void setupChild(Configuration configuration) throws CheckstyleException { - throw new CheckstyleException( - "SpringChecks is not allowed as a parent of " + configuration.getName()); + throw new CheckstyleException("SpringChecks is not allowed as a parent of " + configuration.getName()); } public void setHeaderType(String headerType) { @@ -147,4 +155,20 @@ public void setHeaderCopyrightPattern(String headerCopyrightPattern) { this.headerCopyrightPattern = headerCopyrightPattern; } + public void setHeaderFile(String headerFile) { + this.headerFile = headerFile; + } + + public void setAvoidStaticImportExcludes(String[] avoidStaticImportExcludes) { + this.avoidStaticImportExcludes = new LinkedHashSet<>(Arrays.asList(avoidStaticImportExcludes)); + } + + public void setProjectRootPackage(String projectRootPackage) { + this.projectRootPackage = projectRootPackage; + } + + public void setExcludes(String... excludes) { + this.excludes = new HashSet<>(Arrays.asList(excludes)); + } + } 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 f2d7eb89..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -16,20 +16,26 @@ 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; import com.puppycrawl.tools.checkstyle.ConfigurationLoader; import com.puppycrawl.tools.checkstyle.ConfigurationLoader.IgnoredModulesOptions; -import com.puppycrawl.tools.checkstyle.ModuleFactory; 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; /** @@ -42,27 +48,54 @@ class SpringConfigurationLoader { private final Context context; - private final ModuleFactory moduleFactory; + private final FilteredModuleFactory moduleFactory; - SpringConfigurationLoader(Context context, ModuleFactory moduleFactory) { + SpringConfigurationLoader(Context context, FilteredModuleFactory moduleFactory) { this.context = context; this.moduleFactory = moduleFactory; } public Collection load(PropertyResolver propertyResolver) { - Configuration config = loadConfiguration( - getClass().getResourceAsStream("spring-checkstyle.xml"), - propertyResolver); - return Arrays.stream(config.getChildren()).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); - return ConfigurationLoader.loadConfiguration(inputSource, propertyResolver, - IgnoredModulesOptions.EXECUTE); + 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) { throw new IllegalStateException(ex); @@ -81,21 +114,21 @@ 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) { - throw new IllegalStateException( - "cannot initialize module " + name + " - " + ex.getMessage(), ex); + throw new IllegalStateException("cannot initialize module " + name + " - " + ex.getMessage(), ex); } } - 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 0f0743d0..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -36,4 +36,5 @@ public int[] getDefaultTokens() { public int[] getRequiredTokens() { return NO_REQUIRED_TOKENS; } + } 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 new file mode 100644 index 00000000..b9b3c3e4 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringAvoidStaticImportCheck.java @@ -0,0 +1,106 @@ +/* + * 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.Collections; +import java.util.LinkedHashSet; +import java.util.Set; + +import com.puppycrawl.tools.checkstyle.checks.imports.AvoidStarImportCheck; +import com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheck; + +/** + * Spring variant of {@link AvoidStarImportCheck}. + * + * @author Phillip Webb + */ +public class SpringAvoidStaticImportCheck extends AvoidStaticImportCheck { + + private static final Set ALWAYS_EXCLUDED; + static { + Set excludes = new LinkedHashSet<>(); + 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.*"); + excludes.add("org.hamcrest.Matchers.*"); + excludes.add("org.junit.Assert.*"); + excludes.add("org.junit.Assume.*"); + excludes.add("org.junit.internal.matchers.ThrowableMessageMatcher.*"); + excludes.add("org.junit.jupiter.api.Assertions.*"); + excludes.add("org.junit.jupiter.api.Assumptions.*"); + excludes.add("org.mockito.AdditionalMatchers.*"); + excludes.add("org.mockito.ArgumentMatchers.*"); + excludes.add("org.mockito.BDDMockito.*"); + excludes.add("org.mockito.Matchers.*"); + 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.server.mvc.WebMvcLinkBuilder.*"); + excludes.add("org.springframework.restdocs.headers.HeaderDocumentation.*"); + excludes.add("org.springframework.restdocs.hypermedia.HypermediaDocumentation.*"); + excludes.add("org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*"); + excludes.add("org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*"); + excludes.add("org.springframework.restdocs.operation.preprocess.Preprocessors.*"); + excludes.add("org.springframework.restdocs.payload.PayloadDocumentation.*"); + excludes.add("org.springframework.restdocs.request.RequestDocumentation.*"); + excludes.add("org.springframework.restdocs.restassured.operation.preprocess.RestAssuredPreprocessors.*"); + excludes.add("org.springframework.restdocs.restassured.RestAssuredRestDocumentation.*"); + excludes.add("org.springframework.restdocs.restassured3.operation.preprocess.RestAssuredPreprocessors.*"); + excludes.add("org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.*"); + excludes.add("org.springframework.restdocs.snippet.Attributes.*"); + excludes.add("org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation.*"); + excludes.add("org.springframework.security.config.Customizer.*"); + excludes.add("org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers.*"); + excludes.add("org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.*"); + excludes.add("org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*"); + excludes.add("org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.*"); + excludes.add("org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*"); + excludes.add("org.springframework.test.web.client.ExpectedCount.*"); + excludes.add("org.springframework.test.web.client.match.MockRestRequestMatchers.*"); + excludes.add("org.springframework.test.web.client.response.MockRestResponseCreators.*"); + excludes.add("org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*"); + excludes.add("org.springframework.test.web.servlet.result.MockMvcResultHandlers.*"); + excludes.add("org.springframework.test.web.servlet.result.MockMvcResultMatchers.*"); + excludes.add("org.springframework.test.web.servlet.setup.MockMvcBuilders.*"); + excludes.add("org.springframework.web.reactive.function.BodyInserters.*"); + excludes.add("org.springframework.web.reactive.function.server.RequestPredicates.*"); + excludes.add("org.springframework.web.reactive.function.server.RouterFunctions.*"); + excludes.add("org.springframework.web.servlet.function.RequestPredicates.*"); + excludes.add("org.springframework.web.servlet.function.RouterFunctions.*"); + excludes.add("org.springframework.ws.test.client.RequestMatchers.*"); + excludes.add("org.springframework.ws.test.client.ResponseCreators.*"); + ALWAYS_EXCLUDED = Collections.unmodifiableSet(excludes); + } + + public SpringAvoidStaticImportCheck() { + setExcludes(ALWAYS_EXCLUDED.toArray(new String[0])); + } + + @Override + public void setExcludes(String... excludes) { + Set merged = new LinkedHashSet<>(ALWAYS_EXCLUDED); + merged.addAll(Arrays.asList(excludes)); + super.setExcludes(merged.toArray(new String[0])); + } + +} 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 b0725cde..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -60,6 +60,9 @@ private void checkIdent(DetailAST ast) { if (text.length() == 1) { log(ast.getLineNo(), ast.getColumnNo(), "catch.singleLetter"); } + if (text.toLowerCase().equals("o_o")) { + log(ast.getLineNo(), ast.getColumnNo(), "catch.wideEye"); + } } } 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 086eab26..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -23,6 +23,10 @@ import java.io.InputStreamReader; import java.io.LineNumberReader; import java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; @@ -57,14 +61,24 @@ 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()); + + private String charset = DEFAULT_CHARSET; private String headerType = DEFAULT_HEADER_TYPE; + private URI headerFile; + private String headerCopyrightPattern = DEFAULT_HEADER_COPYRIGHT_PATTERN; private String packageInfoHeaderType; + private URI packageInfoHeaderFile; + + private boolean blankLineAfter = true; + private HeaderCheck check; private HeaderCheck packageInfoCheck; @@ -72,29 +86,31 @@ public class SpringHeaderCheck extends AbstractFileSetCheck { @Override protected void finishLocalSetup() throws CheckstyleException { try { - this.check = createCheck(this.headerType); - this.packageInfoCheck = createCheck(this.packageInfoHeaderType != null - ? this.packageInfoHeaderType : this.headerType); + this.check = createCheck(this.headerType, this.headerFile); + String packageInfoHeaderType = this.packageInfoHeaderType != null ? this.packageInfoHeaderType + : this.headerType; + URI packageInfoHeaderFile = this.packageInfoHeaderFile != null ? this.packageInfoHeaderFile + : this.headerFile; + this.packageInfoCheck = createCheck(packageInfoHeaderType, packageInfoHeaderFile); } catch (IOException ex) { throw new IllegalStateException(ex); } } - private HeaderCheck createCheck(String headerType) throws IOException { + private HeaderCheck createCheck(String headerType, URI headerFile) throws IOException { if (UNCHECKED.equals(headerType)) { return HeaderCheck.NONE; } if (NONE.equals(headerType)) { return new NoHeaderCheck(); } - return new RegexHeaderCheck(headerType, this.headerCopyrightPattern); + return new RegexHeaderCheck(headerType, headerFile); } @Override - protected void processFiltered(File file, FileText fileText) - throws CheckstyleException { - getCheck(file).run(fileText); + protected void processFiltered(File file, FileText fileText) throws CheckstyleException { + getCheck(file).run(fileText, this.blankLineAfter); } private HeaderCheck getCheck(File file) { @@ -104,10 +120,21 @@ private HeaderCheck getCheck(File file) { return this.check; } + public void setCharset(String charset) throws UnsupportedEncodingException { + if (!Charset.isSupported(charset)) { + throw new UnsupportedEncodingException("unsupported charset: '" + charset + "'"); + } + this.charset = charset; + } + public void setHeaderType(String headerType) { this.headerType = headerType; } + public void setHeaderFile(URI headerFile) throws CheckstyleException { + this.headerFile = headerFile; + } + public void setHeaderCopyrightPattern(String headerCopyrightPattern) { this.headerCopyrightPattern = headerCopyrightPattern; } @@ -116,6 +143,14 @@ public void setPackageInfoHeaderType(String packageInfoHeaderType) { this.packageInfoHeaderType = packageInfoHeaderType; } + public void setPackageInfoHeaderFile(URI packageInfoHeaderFile) { + this.packageInfoHeaderFile = packageInfoHeaderFile; + } + + public void setBlankLineAfter(boolean blankLineAfter) { + this.blankLineAfter = blankLineAfter; + } + /** * Interface used to check for a header. */ @@ -124,14 +159,15 @@ private interface HeaderCheck { /** * Don't run any checks. */ - HeaderCheck NONE = (fileText) -> true; + HeaderCheck NONE = (fileText, blankLineAfter) -> true; /** * Run the check. * @param fileText the text to check + * @param blankLineAfter if a blank line should be after the header * @return {@code true} if the header is valid */ - boolean run(FileText fileText); + boolean run(FileText fileText, boolean blankLineAfter); } @@ -142,19 +178,25 @@ private class RegexHeaderCheck implements HeaderCheck { private final List lines; - RegexHeaderCheck(String type, String copyrightPattern) throws IOException { + RegexHeaderCheck(String type, URI file) throws IOException { + this.lines = loadLines(openInputStream(type, file)); + } + + private InputStream openInputStream(String type, URI file) throws IOException { + if (file != null) { + return file.toURL().openStream(); + } String name = "header-" + type + ".txt"; InputStream inputStream = SpringHeaderCheck.class.getResourceAsStream(name); if (inputStream == null) { throw new IllegalStateException("Unknown header type " + type); } - this.lines = loadLines(inputStream, copyrightPattern); + return inputStream; } - private List loadLines(InputStream inputStream, String copyrightPattern) - throws IOException { + private List loadLines(InputStream inputStream) throws IOException { inputStream = new BufferedInputStream(inputStream); - try (Reader reader = new InputStreamReader(inputStream, "UTF-8")) { + try (Reader reader = new InputStreamReader(inputStream, SpringHeaderCheck.this.charset)) { LineNumberReader lineReader = new LineNumberReader(reader); List lines = new ArrayList<>(); while (true) { @@ -162,7 +204,7 @@ private List loadLines(InputStream inputStream, String copyrightPattern if (line == null) { return lines; } - lines.add(loadLine(line, copyrightPattern)); + lines.add(loadLine(line, SpringHeaderCheck.this.headerCopyrightPattern)); } } } @@ -174,7 +216,7 @@ private Pattern loadLine(String line, String copyrightPattern) { } @Override - public boolean run(FileText fileText) { + public boolean run(FileText fileText, boolean blankLineAfter) { if (this.lines.size() > fileText.size()) { log(1, RegexpHeaderCheck.MSG_HEADER_MISSING); return false; @@ -187,6 +229,11 @@ public boolean run(FileText fileText) { return false; } } + if (blankLineAfter) { + if (fileText.size() <= this.lines.size() || !"".equals(fileText.get(this.lines.size()))) { + log(this.lines.size() + 1, "header.blankLine"); + } + } return true; } @@ -198,7 +245,7 @@ public boolean run(FileText fileText) { private class NoHeaderCheck implements HeaderCheck { @Override - public boolean run(FileText fileText) { + public boolean run(FileText fileText, boolean blankLineAfter) { for (int i = 0; i < fileText.size(); i++) { String fileLine = fileText.get(i); if (fileLine.trim().isEmpty()) { @@ -214,8 +261,7 @@ public boolean run(FileText fileText) { } private boolean isHeaderComment(String fileLine) { - return (fileLine.contains("/*") || fileLine.contains("//")) - && !fileLine.contains("/**"); + return (fileLine.contains("/*") || fileLine.contains("//")) && !fileLine.contains("/**"); } } 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 new file mode 100644 index 00000000..882b9b9a --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringHideUtilityClassConstructor.java @@ -0,0 +1,65 @@ +/* + * 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.Collections; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.stream.Collectors; + +import com.puppycrawl.tools.checkstyle.api.DetailAST; +import com.puppycrawl.tools.checkstyle.checks.design.HideUtilityClassConstructorCheck; +import com.puppycrawl.tools.checkstyle.utils.AnnotationUtil; + +/** + * Extension to {@link HideUtilityClassConstructorCheck} that doesn't fail certain common + * Spring patterns. + * + * @author Phillip Webb + */ +public class SpringHideUtilityClassConstructor extends HideUtilityClassConstructorCheck { + + private static final Set BYPASS_ANNOTATIONS; + static { + Set annotations = new LinkedHashSet<>(); + 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()); + annotations.addAll(shortNames); + BYPASS_ANNOTATIONS = Collections.unmodifiableSet(annotations); + } + + @Override + public void visitToken(DetailAST ast) { + if (!isBypassed(ast)) { + super.visitToken(ast); + } + } + + private boolean isBypassed(DetailAST ast) { + for (String bypassAnnotation : BYPASS_ANNOTATIONS) { + if (AnnotationUtil.containsAnnotation(ast, bypassAnnotation)) { + return true; + } + } + return false; + } + +} 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 new file mode 100644 index 00000000..69f8bf31 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringImportOrderCheck.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. + */ + +package io.spring.javaformat.checkstyle.check; + +import com.puppycrawl.tools.checkstyle.checks.imports.ImportOrderCheck; + +/** + * Checks that the order of imports follow Spring conventions. + * + * @author Vedran Pavic + */ +public class SpringImportOrderCheck extends ImportOrderCheck { + + /** + * The default root package. + */ + public static final String DEFAULT_PROJECT_ROOT_PACKAGE = "org.springframework"; + + public SpringImportOrderCheck() { + setProjectRootPackage(DEFAULT_PROJECT_ROOT_PACKAGE); + setOrdered(true); + setSeparated(true); + setOption("bottom"); + setSortStaticImportsAlphabetically(true); + } + + public void setProjectRootPackage(String projectRootPackage) { + setGroups("java", "/^javax?\\./", "*", projectRootPackage); + } + +} 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 new file mode 100644 index 00000000..722c8868 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringJUnit5Check.java @@ -0,0 +1,250 @@ +/* + * 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.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; +import com.puppycrawl.tools.checkstyle.api.TokenTypes; +import com.puppycrawl.tools.checkstyle.utils.AnnotationUtil; + +/** + * Checks that JUnit 5 conventions are followed and that JUnit 4 is not accidentally used. + * + * @author Phillip Webb + */ +public class SpringJUnit5Check extends AbstractSpringCheck { + + private static final String JUNIT4_TEST_ANNOTATION_NAME = "org.junit.Test"; + + private static final List TEST_ANNOTATIONS; + static { + 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; + static { + 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_NAME); + bannedImports.add("org.junit.After"); + bannedImports.add("org.junit.AfterClass"); + bannedImports.add("org.junit.Before"); + bannedImports.add("org.junit.BeforeClass"); + bannedImports.add("org.junit.Rule"); + bannedImports.add("org.junit.ClassRule"); + BANNED_IMPORTS = Collections.unmodifiableSet(bannedImports); + } + + private List unlessImports = new ArrayList<>(); + + private final List testMethods = new ArrayList<>(); + + private final Map imports = new LinkedHashMap<>(); + + 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, 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); + break; + case TokenTypes.IMPORT: + visitImport(ast); + break; + case TokenTypes.CLASS_DEF: + visitClassDefinition(ast); + break; + } + } + + private void visitMethodDef(DetailAST ast) { + if (containsAnnotation(ast, TEST_ANNOTATIONS)) { + this.testMethods.add(ast); + } + 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()) { + check(); + } + } + + private boolean shouldCheck() { + if (this.testMethods.isEmpty() && this.lifecycleMethods.isEmpty() && this.nestedTestClasses.isEmpty()) { + return false; + } + for (String unlessImport : this.unlessImports) { + if (this.imports.containsKey(unlessImport)) { + return false; + } + } + return true; + } + + 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) { + log(ident.getLineNo(), ident.getColumnNo(), "junit5.bannedImport", bannedImport); + } + } + for (DetailAST testMethod : this.testMethods) { + if (AnnotationUtil.containsAnnotation(testMethod, JUNIT4_TEST_ANNOTATION_NAME)) { + log(testMethod, "junit5.bannedTestAnnotation"); + } + } + 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 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(ast, publicMessageKey); + } + if ((privateMessageKey != null) && (modifiers.findFirstToken(TokenTypes.LITERAL_PRIVATE) != null)) { + log(ast, privateMessageKey); + } + } + } + + 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())); + } + + 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 0e9d9a65..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -16,10 +16,18 @@ package io.spring.javaformat.checkstyle.check; +import java.util.ArrayList; +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.regex.Matcher; import java.util.regex.Pattern; import com.puppycrawl.tools.checkstyle.api.DetailAST; +import com.puppycrawl.tools.checkstyle.api.FileContents; import com.puppycrawl.tools.checkstyle.api.TextBlock; import com.puppycrawl.tools.checkstyle.api.TokenTypes; @@ -30,53 +38,345 @@ */ public class SpringJavadocCheck extends AbstractSpringCheck { - private static final Pattern[] PATTERNS = { Pattern.compile("@param\\s+\\S+\\s+(.*)"), - Pattern.compile("@throws\\s+\\S+\\s+(.*)"), - Pattern.compile("@return\\s+(.*)") }; + private static final List CASE_CHECKED_TAG_PATTERNS; + static { + List patterns = new ArrayList<>(); + patterns.add(Pattern.compile("@param\\s+\\S+\\s+(.*)")); + patterns.add(Pattern.compile("@throws\\s+\\S+\\s+(.*)")); + patterns.add(Pattern.compile("@return\\s+(.*)")); + CASE_CHECKED_TAG_PATTERNS = Collections.unmodifiableList(patterns); + } + + private static final List BANNED_TAGS; + static { + List patterns = new ArrayList<>(); + patterns.add(Pattern.compile("(@soundtrack)\\s+.*")); + BANNED_TAGS = Collections.unmodifiableList(patterns); + } + + private static final Pattern SINCE_TAG_PATTERN = Pattern.compile("@since\\s+(.*)"); + + private static final Pattern AT_TAG_PATTERN = Pattern.compile("[^{]@\\w+\\s+.*"); + + private static final Pattern NON_JAVADOC_COMMENT = Pattern.compile("\\(non-Javadoc\\)", Pattern.CASE_INSENSITIVE); + + private static final Set TOP_LEVEL_TYPES; + static { + Set topLevelTypes = new HashSet(); + topLevelTypes.add(TokenTypes.INTERFACE_DEF); + topLevelTypes.add(TokenTypes.CLASS_DEF); + topLevelTypes.add(TokenTypes.ENUM_DEF); + topLevelTypes.add(TokenTypes.ANNOTATION_DEF); + TOP_LEVEL_TYPES = Collections.unmodifiableSet(topLevelTypes); + } + + private boolean requireSinceTag; + + private boolean publicOnlySinceTags; + + private boolean allowNonJavadocComments; + + private Map blockComments; @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 }; + return new int[] { TokenTypes.INTERFACE_DEF, TokenTypes.CLASS_DEF, TokenTypes.ENUM_DEF, + TokenTypes.ANNOTATION_DEF, TokenTypes.METHOD_DEF, TokenTypes.CTOR_DEF, TokenTypes.ANNOTATION_FIELD_DEF }; } @Override public int[] getAcceptableTokens() { - return new int[] { TokenTypes.INTERFACE_DEF, TokenTypes.CLASS_DEF, - TokenTypes.ENUM_DEF, TokenTypes.ANNOTATION_DEF, TokenTypes.METHOD_DEF, - TokenTypes.CTOR_DEF, TokenTypes.ENUM_CONSTANT_DEF, + return new int[] { TokenTypes.INTERFACE_DEF, TokenTypes.CLASS_DEF, TokenTypes.ENUM_DEF, + TokenTypes.ANNOTATION_DEF, TokenTypes.METHOD_DEF, TokenTypes.CTOR_DEF, TokenTypes.ENUM_CONSTANT_DEF, TokenTypes.ANNOTATION_FIELD_DEF }; } + @Override + public void beginTree(DetailAST rootAST) { + super.beginTree(rootAST); + this.blockComments = new HashMap<>(); + FileContents contents = getFileContents(); + for (List blockComments : contents.getBlockComments().values()) { + for (TextBlock blockComment : blockComments) { + this.blockComments.put(blockComment.getEndLineNo(), blockComment); + } + } + } + @Override public void visitToken(DetailAST ast) { int lineNumber = ast.getLineNo(); TextBlock javadoc = getFileContents().getJavadocBefore(lineNumber); if (javadoc != null) { - checkParamTags(javadoc); + checkJavadoc(ast, javadoc); + } + if (!this.allowNonJavadocComments) { + checkForNonJavadocComments(javadoc); + checkForNonJavadocComments(getBlockCommentBefore(lineNumber)); + } + } + + public TextBlock getBlockCommentBefore(int lineNoBefore) { + FileContents contents = getFileContents(); + int lineNo = lineNoBefore - 1; + while (lineNo > 0 && (contents.lineIsBlank(lineNo) || contents.lineIsComment(lineNo))) { + lineNo--; + } + return this.blockComments.get(lineNo); + } + + private void checkJavadoc(DetailAST ast, TextBlock javadoc) { + checkBannedTags(ast, javadoc); + checkTagCase(ast, javadoc); + checkSinceTag(ast, javadoc); + checkMethodJavaDoc(ast, javadoc); + checkAnnotationFieldJavaDoc(ast, javadoc); + } + + private void checkBannedTags(DetailAST ast, TextBlock javadoc) { + String[] text = javadoc.getText(); + for (int i = 0; i < text.length; i++) { + for (Pattern pattern : BANNED_TAGS) { + Matcher matcher = pattern.matcher(text[i]); + if (matcher.find()) { + String tagName = matcher.group(1).trim(); + log(javadoc.getStartLineNo() + i, tagName.length(), "javadoc.bannedTag", tagName); + } + } } } - private void checkParamTags(TextBlock javadoc) { + private void checkTagCase(DetailAST ast, TextBlock javadoc) { String[] text = javadoc.getText(); for (int i = 0; i < text.length; i++) { - for (Pattern pattern : PATTERNS) { + for (Pattern pattern : CASE_CHECKED_TAG_PATTERNS) { Matcher matcher = pattern.matcher(text[i]); if (matcher.find()) { String description = matcher.group(1).trim(); if (startsWithUppercase(description)) { - log(javadoc.getStartLineNo() + i, - text[i].length() - description.length(), - "javadoc.badCase"); + log(javadoc.getStartLineNo() + i, text[i].length() - description.length(), "javadoc.badCase"); } } } } } + private void checkSinceTag(DetailAST ast, TextBlock javadoc) { + if (!TOP_LEVEL_TYPES.contains(ast.getType())) { + return; + } + 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); + } + } + } + } + + 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) { + if (TokenTypes.METHOD_DEF != ast.getType()) { + return; + } + String[] text = javadoc.getText(); + for (int i = 0; i < text.length; i++) { + Matcher matcher = AT_TAG_PATTERN.matcher(text[i]); + if (matcher.find() && i > 0 && text[i - 1].trim().equals("*")) { + 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) { return description.length() > 0 && Character.isUpperCase(description.charAt(0)); } + private void checkForNonJavadocComments(TextBlock block) { + if (block == null) { + return; + } + String[] text = block.getText(); + for (int i = 0; i < text.length; i++) { + if (NON_JAVADOC_COMMENT.matcher(text[i]).find()) { + log(block.getStartLineNo() + i - 1, 0, "javadoc.nonJavadocComment"); + } + } + } + + public void setRequireSinceTag(boolean requireSinceTag) { + this.requireSinceTag = requireSinceTag; + } + + public void setPublicOnlySinceTags(boolean publicOnlySinceTags) { + this.publicOnlySinceTags = publicOnlySinceTags; + } + + public void setAllowNonJavadocComments(boolean allowNonJavadocComments) { + this.allowNonJavadocComments = allowNonJavadocComments; + } + + private DetailAST getInterfaceOrAnnotationDef(DetailAST ast) { + return findParent(ast, TokenTypes.INTERFACE_DEF, TokenTypes.ANNOTATION_DEF); + } + + private DetailAST findParent(DetailAST ast, int... classDefs) { + while (ast != null) { + for (int classDef : classDefs) { + if (ast.getType() == classDef) { + return ast; + } + } + ast = ast.getParent(); + } + return null; + } + + private boolean isPublicOrProtected(DetailAST ast) { + DetailAST modifiers = ast.findFirstToken(TokenTypes.MODIFIERS); + if (modifiers == null) { + return false; + } + return modifiers.findFirstToken(TokenTypes.LITERAL_PUBLIC) != null + || 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 ea88c887..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -38,7 +38,8 @@ public int[] getAcceptableTokens() { @Override public void visitToken(DetailAST ast) { - if (ast.getType() == TokenTypes.LAMBDA) { + if (ast.getType() == TokenTypes.LAMBDA && ast.getParent() != null + && ast.getParent().getType() != TokenTypes.SWITCH_RULE) { visitLambda(ast); } } @@ -51,22 +52,34 @@ private void visitLambda(DetailAST lambda) { } else if (!this.singleArgumentParentheses && hasParentheses) { if (!isUsingParametersToDefineType(lambda)) { - log(lambda.getLineNo(), lambda.getColumnNo(), - "lambda.unnecessaryParen"); + log(lambda.getLineNo(), lambda.getColumnNo(), "lambda.unnecessaryParen"); } } } DetailAST block = lambda.getLastChild(); - if (isStatementList(block) && block.getChildCount(TokenTypes.SEMI) <= 1 - && !isNecessaryBlock(block)) { + int statements = countDescendantsOfType(block, TokenTypes.SEMI); + int requireBlock = countDescendantsOfType(block, TokenTypes.LCURLY, TokenTypes.LITERAL_THROW, TokenTypes.SLIST); + if (statements == 1 && requireBlock == 0) { log(block.getLineNo(), block.getColumnNo(), "lambda.unnecessaryBlock"); } } + private int countDescendantsOfType(DetailAST ast, int... types) { + int count = 0; + for (int type : types) { + count += ast.getChildCount(type); + } + DetailAST child = ast.getFirstChild(); + while (child != null) { + count += countDescendantsOfType(child, types); + child = child.getNextSibling(); + } + return count; + } + private boolean hasSingleParameter(DetailAST lambda) { DetailAST parameters = lambda.findFirstToken(TokenTypes.PARAMETERS); - return (parameters == null) - || (parameters.getChildCount(TokenTypes.PARAMETER_DEF) == 1); + return (parameters == null) || (parameters.getChildCount(TokenTypes.PARAMETER_DEF) == 1); } private boolean isUsingParametersToDefineType(DetailAST lambda) { @@ -77,31 +90,6 @@ private boolean isUsingParametersToDefineType(DetailAST lambda) { return ast != null; } - private boolean isNecessaryBlock(DetailAST block) { - DetailAST firstChild = block.getFirstChild(); - if (firstChild == null) { - return false; - } - if (firstChild.getType() == TokenTypes.LITERAL_THROW) { - return true; - } - if (block.getChildCount() == 1 && firstChild.getType() == TokenTypes.RCURLY) { - return true; - } - DetailAST candidate = firstChild.getFirstChild(); - while (candidate != null) { - if (isStatementList(candidate)) { - return true; - } - candidate = candidate.getNextSibling(); - } - return false; - } - - private boolean isStatementList(DetailAST ast) { - return ast != null && ast.getType() == TokenTypes.SLIST; - } - private boolean hasToken(DetailAST ast, int type) { return ast.findFirstToken(type) != null; } 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 new file mode 100644 index 00000000..abeba9de --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringLeadingWhitespaceCheck.java @@ -0,0 +1,137 @@ +/* + * 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 java.util.ArrayDeque; +import java.util.Collections; +import java.util.Deque; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +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; + +/** + * Checks that leading whitespace matches the expected indentation style. + * + * @author Phillip Webb + */ +public class SpringLeadingWhitespaceCheck extends AbstractSpringCheck { + + private static final Pattern PATTERN = Pattern.compile("^([\\ \\t]+)\\S"); + + private static final Map INDENTATION_STYLE_PATTERN; + static { + Map indentationStylePatterns = new HashMap<>(); + indentationStylePatterns.put(IndentationStyle.TABS, Pattern.compile("\\t*")); + indentationStylePatterns.put(IndentationStyle.SPACES, Pattern.compile("\\ *")); + INDENTATION_STYLE_PATTERN = Collections.unmodifiableMap(indentationStylePatterns); + } + + private IndentationStyle indentationStyle; + + private final Deque textBlockPairs = new ArrayDeque<>(); + + @Override + public int[] getAcceptableTokens() { + 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(); + if (file == null) { + return; + } + IndentationStyle indentationStyle = (this.indentationStyle != null) ? this.indentationStyle + : JavaFormatConfig.findFrom(file.getParentFile()).getIndentationStyle(); + for (int i = 0; i < fileText.size(); 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 + && fileContents.hasIntersectionWithComment(lineNo, matcher.start(0), lineNo, matcher.end(0) - 1)) { + found = matcher.find(matcher.end(0)); + } + if (found && !INDENTATION_STYLE_PATTERN.get(indentationStyle).matcher(matcher.group(1)).matches()) { + 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) { + this.indentationStyle = (indentationStyle != null && !"".equals(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 d9ee57ff..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -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() { @@ -59,15 +59,13 @@ public void visitToken(DetailAST ast) { } private void checkOrder(List methods) { - List methodsNames = methods.stream().map(DetailAST::getText) - .collect(Collectors.toList()); + List methodsNames = methods.stream().map(DetailAST::getText).collect(Collectors.toList()); List expected = new ArrayList<>(EXPECTED_ORDER); expected.retainAll(methodsNames); for (int i = 0; i < methods.size(); i++) { DetailAST method = methods.get(i); if (!method.getText().equals(expected.get(i))) { - log(method.getLineNo(), method.getColumnNo(), "methodorder.outOfOrder", - method.getText(), expected); + log(method.getLineNo(), method.getColumnNo(), "methodorder.outOfOrder", method.getText(), expected); } } } 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 new file mode 100644 index 00000000..ca5bd3ef --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/check/SpringMethodVisibilityCheck.java @@ -0,0 +1,131 @@ +/* + * 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; + +/** + * 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 { + + @Override + public int[] getAcceptableTokens() { + return new int[] { TokenTypes.METHOD_DEF }; + } + + @Override + public void visitToken(DetailAST ast) { + DetailAST modifiers = ast.findFirstToken(TokenTypes.MODIFIERS); + 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) { + if (hasOverrideAnnotation(modifiers)) { + return; + } + DetailAST classDef = getClassDef(method.getParent()); + if (classDef == null || isPublicOrProtected(classDef)) { + return; + } + DetailAST interfaceDef = getInterfaceDef(classDef.getParent()); + if (interfaceDef != null && isPublicOrProtected(interfaceDef)) { + return; + } + DetailAST ident = method.findFirstToken(TokenTypes.IDENT); + 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) { + if (candidate.getType() == TokenTypes.ANNOTATION) { + DetailAST dot = candidate.findFirstToken(TokenTypes.DOT); + String name = (dot != null ? dot : candidate).findFirstToken(TokenTypes.IDENT).getText(); + if ("Override".equals(name)) { + return true; + } + } + candidate = candidate.getNextSibling(); + } + return false; + } + + private DetailAST getClassDef(DetailAST ast) { + return findParent(ast, TokenTypes.CLASS_DEF); + } + + private DetailAST getInterfaceDef(DetailAST ast) { + return findParent(ast, TokenTypes.INTERFACE_DEF); + } + + private DetailAST findParent(DetailAST ast, int classDef) { + while (ast != null) { + if (ast.getType() == classDef) { + return ast; + } + ast = ast.getParent(); + } + return null; + } + + private boolean isPublicOrProtected(DetailAST ast) { + DetailAST modifiers = ast.findFirstToken(TokenTypes.MODIFIERS); + if (modifiers == null) { + return false; + } + return modifiers.findFirstToken(TokenTypes.LITERAL_PUBLIC) != null + || 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 d4d3f478..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -53,8 +53,7 @@ private void visitIdent(DetailAST ast) { DetailAST sibling = ast.getPreviousSibling(); if (sibling != null && sibling.getType() == TokenTypes.LITERAL_THIS) { DetailAST parent = getFirstNonDotParent(ast); - if (!(this.allowAssignement && parent != null - && parent.getType() == TokenTypes.ASSIGN)) { + if (!(this.allowAssignement && parent != null && parent.getType() == TokenTypes.ASSIGN)) { log(ast.getLineNo(), ast.getColumnNo(), "nothis.unexpected", name); } } 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 b57bde47..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -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); } @@ -103,8 +103,7 @@ private boolean hasType(DetailAST ast, int type) { public void setEqualsTest(String equalsTest) { try { - this.equalsTest = Enum.valueOf(EqualsTest.class, - equalsTest.trim().toUpperCase(Locale.ENGLISH)); + this.equalsTest = Enum.valueOf(EqualsTest.class, equalsTest.trim().toUpperCase(Locale.ENGLISH)); } catch (final IllegalArgumentException ex) { throw new IllegalArgumentException("unable to parse " + equalsTest, ex); 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 bb178221..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -28,7 +28,7 @@ import com.puppycrawl.tools.checkstyle.api.Configuration; import com.puppycrawl.tools.checkstyle.api.Context; import com.puppycrawl.tools.checkstyle.api.DetailAST; -import com.puppycrawl.tools.checkstyle.api.LocalizedMessage; +import com.puppycrawl.tools.checkstyle.api.Violation; /** * Base class for {@link AbstractCheck checks} that act as a filter for a single child. @@ -44,7 +44,6 @@ public class CheckFilter extends AbstractCheck { @Override public void finishLocalSetup() { DefaultContext context = new DefaultContext(); - context.add("classLoader", getClassLoader()); context.add("severity", getSeverity()); context.add("tabWidth", String.valueOf(getTabWidth())); this.childContext = context; @@ -56,8 +55,8 @@ public void setupChild(Configuration childConf) throws CheckstyleException { String name = childConf.getName(); Object module = moduleFactory.createModule(name); if (!(module instanceof AbstractCheck)) { - throw new CheckstyleException("OptionalCheck is not allowed as a parent of " - + name + " Please review 'Parent Module' section for this Check."); + throw new CheckstyleException("OptionalCheck is not allowed as a parent of " + name + + " Please review 'Parent Module' section for this Check."); } if (this.check != null) { throw new CheckstyleException("Can only make a single check optional"); @@ -101,14 +100,14 @@ public boolean isCommentNodesRequired() { } @Override - public SortedSet getMessages() { - return this.check.getMessages(); + public SortedSet getViolations() { + return this.check.getViolations(); } @Override public void beginTree(DetailAST rootAST) { this.check.setFileContents(getFileContents()); - this.check.clearMessages(); + this.check.clearViolations(); this.check.beginTree(rootAST); } @@ -127,6 +126,4 @@ public void leaveToken(DetailAST ast) { this.check.leaveToken(ast); } - - } 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 79fab14a..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 86405424..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -21,7 +21,7 @@ import com.puppycrawl.tools.checkstyle.TreeWalkerAuditEvent; import com.puppycrawl.tools.checkstyle.TreeWalkerFilter; -import com.puppycrawl.tools.checkstyle.api.LocalizedMessage; +import com.puppycrawl.tools.checkstyle.api.Violation; /** * {@link TreeWalkerFilter} that can used to relax the {@code 'this.'} requirement when @@ -35,9 +35,9 @@ public class RequiresOuterThisFilter implements TreeWalkerFilter { @Override public boolean accept(TreeWalkerAuditEvent event) { - LocalizedMessage message = event.getLocalizedMessage(); - if ("require.this.variable".equals(message.getKey())) { - Object[] args = getArgs(message); + Violation violation = event.getViolation(); + if ("require.this.variable".equals(violation.getKey())) { + Object[] args = getArgs(violation); String prefex = (args.length > 1 ? Objects.toString(args[1]) : null); if (prefex != null && prefex.length() > 0) { return false; @@ -46,12 +46,12 @@ public boolean accept(TreeWalkerAuditEvent event) { return true; } - private Object[] getArgs(LocalizedMessage message) { + private Object[] getArgs(Violation violation) { if (ARGS_FIELD == null) { throw new IllegalStateException("Unable to extract message args"); } try { - return (Object[]) ARGS_FIELD.get(message); + return (Object[]) ARGS_FIELD.get(violation); } catch (Exception ex) { return null; @@ -60,7 +60,7 @@ private Object[] getArgs(LocalizedMessage message) { private static Field getArgsField() { try { - Field field = LocalizedMessage.class.getDeclaredField("args"); + Field field = Violation.class.getDeclaredField("args"); field.setAccessible(true); return field; } diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/resources/io/spring/javaformat/checkstyle/check/header-apache2.txt b/spring-javaformat/spring-javaformat-checkstyle/src/main/resources/io/spring/javaformat/checkstyle/check/header-apache2.txt index 3f5d4761..dd9f9cce 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/src/main/resources/io/spring/javaformat/checkstyle/check/header-apache2.txt +++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/resources/io/spring/javaformat/checkstyle/check/header-apache2.txt @@ -5,7 +5,7 @@ * 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 + * 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, 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 5d82007e..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,10 +1,49 @@ -lambda.missingParen=Lambda argument missing parentheses. -lambda.unnecessaryParen=Lambda argument has unnecessary parentheses. -lambda.unnecessaryBlock=Lambda block is unnecessary. -ternary.missingParen=Ternary operation missing parentheses. -ternary.equalOperator=Ternary operation should use != when testing. +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). -javadoc.badCase=Javadoc element descriptions should not start with an uppercase letter. +catch.wideEye=''o_O'' catch variable (use "ex" instead). header.unexpected=Unexpected header. -nothis.unexpected=Reference to instance variable ''{0}'' should not use \"this.\". +header.mismatch=Line does not match expected header line of ''{0}''. +header.blankLine=Blank line expected after header. +hide.utility.class=Utility classes should not have a public or default constructor. +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)\". +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. +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\". +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/checkstyle.xml b/spring-javaformat/spring-javaformat-checkstyle/src/main/resources/io/spring/javaformat/checkstyle/checkstyle.xml index b1231c9b..886a68d2 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/src/main/resources/io/spring/javaformat/checkstyle/checkstyle.xml +++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/resources/io/spring/javaformat/checkstyle/checkstyle.xml @@ -1,5 +1,7 @@ - + diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/main/resources/io/spring/javaformat/checkstyle/spring-checkstyle-suppressions.xml b/spring-javaformat/spring-javaformat-checkstyle/src/main/resources/io/spring/javaformat/checkstyle/spring-checkstyle-suppressions.xml index 5ebc0a4b..0c736d01 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/src/main/resources/io/spring/javaformat/checkstyle/spring-checkstyle-suppressions.xml +++ b/spring-javaformat/spring-javaformat-checkstyle/src/main/resources/io/spring/javaformat/checkstyle/spring-checkstyle-suppressions.xml @@ -1,7 +1,7 @@ + "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN" + "https://checkstyle.org/dtds/suppressions_1_2.dtd"> 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 e09c3622..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 @@ -1,16 +1,19 @@ - + - - - - - + + + + + + @@ -19,11 +22,10 @@ + - - - + + @@ -39,7 +41,7 @@ - + @@ -67,23 +69,16 @@ + - - - - - - - - - + + @@ -91,11 +86,9 @@ - - - + - + @@ -106,11 +99,11 @@ - + - + - + @@ -126,22 +119,16 @@ - - + + + + value="Please use BDD-style (given, when, then) using BDDMockito imports." /> - - - - - - - - - + + + @@ -158,17 +145,23 @@ - - + + + + + - + + + + 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 b69ab3ec..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -27,8 +27,8 @@ import com.puppycrawl.tools.checkstyle.Definitions; import com.puppycrawl.tools.checkstyle.api.AuditEvent; import com.puppycrawl.tools.checkstyle.api.AuditListener; -import com.puppycrawl.tools.checkstyle.api.LocalizedMessage; import com.puppycrawl.tools.checkstyle.api.SeverityLevel; +import com.puppycrawl.tools.checkstyle.api.Violation; import static org.assertj.core.api.Assertions.assertThat; @@ -75,10 +75,10 @@ public void auditFinished(AuditEvent event) { private void runCheck(String check) { String description = this.filenames.toString(); if (check.startsWith("+")) { - assertThat(this.message).as(description).contains(check.substring(1)); + assertThat(this.message.toString()).as(description).contains(check.substring(1)); } else if (check.startsWith("-")) { - assertThat(this.message).as(description).doesNotContain(check.substring(1)); + assertThat(this.message.toString()).as(description).doesNotContain(check.substring(1)); } } @@ -106,13 +106,12 @@ public void addException(AuditEvent event, Throwable throwable) { } private void recordLevel(AuditEvent event) { - this.severityCounts.compute(event.getSeverityLevel(), - (level, count) -> (count == null ? 1 : count + 1)); + this.severityCounts.compute(event.getSeverityLevel(), (level, count) -> (count == null ? 1 : count + 1)); } private void recordLocalizedMessage(String message, String... args) { - recordMessage(new LocalizedMessage(0, Definitions.CHECKSTYLE_BUNDLE, message, - args, null, LocalizedMessage.class, null).getMessage()); + recordMessage(new Violation(0, Definitions.CHECKSTYLE_BUNDLE, message, args, null, Violation.class, null) + .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 34b3d69c..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 120ca04a..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -21,9 +21,12 @@ 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; import java.util.List; +import java.util.Locale; import java.util.Properties; import java.util.stream.Collectors; @@ -39,10 +42,9 @@ import com.puppycrawl.tools.checkstyle.api.CheckstyleException; import com.puppycrawl.tools.checkstyle.api.Configuration; import com.puppycrawl.tools.checkstyle.api.RootModule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; +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; /** @@ -50,79 +52,86 @@ * * @author Phillip Webb */ -@RunWith(Parameterized.class) public class SpringChecksTests { + private static final boolean RUNNING_ON_WINDOWS = System.getProperty("os.name").toLowerCase().contains("win"); + private static final File SOURCES_DIR = new File("src/test/resources/source"); private static final File CHECKS_DIR = new File("src/test/resources/check"); private static final File CONFIGS_DIR = new File("src/test/resources/config"); - private static final File DEFAULT_CONFIG = new File(CONFIGS_DIR, - "default-checkstyle-configuration.xml"); - - private final Parameter parameter; + private static final File DEFAULT_CONFIG = new File(CONFIGS_DIR, "default-checkstyle-configuration.xml"); - public SpringChecksTests(Parameter parameter) throws Exception { - this.parameter = parameter; - } + @TempDir + public Path temp; - @Test - public void processHasExpectedResults() throws Exception { - Configuration configuration = loadConfiguration(); + @ParameterizedTest + @MethodSource("paramaters") + public void processHasExpectedResults(Parameter parameter) throws Exception { + Locale previousLocale = Locale.getDefault(); + Locale.setDefault(Locale.ENGLISH); + Configuration configuration = loadConfiguration(parameter); RootModule rootModule = createRootModule(configuration); try { - processAndCheckResults(rootModule); + processAndCheckResults(parameter, rootModule); } finally { rootModule.destroy(); + Locale.setDefault(previousLocale); } } - private Configuration loadConfiguration() throws Exception { - try (InputStream inputStream = new FileInputStream( - this.parameter.getConfigFile())) { - Configuration configuration = ConfigurationLoader.loadConfiguration( - new InputSource(inputStream), - new PropertiesExpander(new Properties()), - IgnoredModulesOptions.EXECUTE, + private Configuration loadConfiguration(Parameter parameter) throws Exception { + try (InputStream inputStream = new FileInputStream(parameter.getConfigFile())) { + Configuration configuration = ConfigurationLoader.loadConfiguration(new InputSource(inputStream), + new PropertiesExpander(new Properties()), IgnoredModulesOptions.EXECUTE, ThreadModeSettings.SINGLE_THREAD_MODE_INSTANCE); return configuration; } } - private RootModule createRootModule(Configuration configuration) - throws CheckstyleException { - ModuleFactory factory = new PackageObjectFactory( - Checker.class.getPackage().getName(), getClass().getClassLoader()); - RootModule rootModule = (RootModule) factory - .createModule(configuration.getName()); + private RootModule createRootModule(Configuration configuration) throws CheckstyleException { + ModuleFactory factory = new PackageObjectFactory(Checker.class.getPackage().getName(), + getClass().getClassLoader()); + RootModule rootModule = (RootModule) factory.createModule(configuration.getName()); rootModule.setModuleClassLoader(getClass().getClassLoader()); rootModule.configure(configuration); return rootModule; } - private void processAndCheckResults(RootModule rootModule) - throws CheckstyleException { - rootModule.addListener(this.parameter.getAssersionsListener()); - printDebugInfo(this.parameter.getSourceFile()); - rootModule.process(Arrays.asList(this.parameter.getSourceFile())); + private void processAndCheckResults(Parameter parameter, RootModule rootModule) throws CheckstyleException { + rootModule.addListener(parameter.getAssertionsListener()); + if (!RUNNING_ON_WINDOWS) { + printDebugInfo(parameter.getSourceFile()); + } + rootModule.process(Arrays.asList(parameter.getSourceFile())); } private void printDebugInfo(File file) throws CheckstyleException { try { - System.out.println(AstTreeStringPrinter.printFileAst(file, - JavaParser.Options.WITHOUT_COMMENTS)); + System.out.println(AstTreeStringPrinter.printFileAst(file, JavaParser.Options.WITHOUT_COMMENTS)); } catch (IOException ex) { } } - @Parameters(name = "{0}") - public static Collection files() throws IOException { - return Arrays.stream(SOURCES_DIR.list((dir, name) -> !name.startsWith("."))) - .map(Parameter::new).collect(Collectors.toList()); + public static Collection paramaters() throws IOException { + 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; + } + + private static boolean sourceFile(File file) { + return file.isFile() && !file.getName().startsWith(".") && !file.getName().equals("package-info.java"); } private static class Parameter { @@ -131,17 +140,17 @@ private static class Parameter { private final File sourceFile; - private final AssertionsAuditListener assersionsListener; + private final AssertionsAuditListener assertionsListener; private final File configFile; - Parameter(String sourceName) { + Parameter(File sourceFile) { + String sourceName = sourceFile.getAbsolutePath().substring(SOURCES_DIR.getAbsolutePath().length() + 1); this.name = sourceName.replace(".java", ""); this.sourceFile = new File(SOURCES_DIR, sourceName); File configFile = new File(CONFIGS_DIR, this.name + ".xml"); this.configFile = (configFile.exists() ? configFile : DEFAULT_CONFIG); - this.assersionsListener = new AssertionsAuditListener( - readChecks(this.name + ".txt")); + this.assertionsListener = new AssertionsAuditListener(readChecks(this.name + ".txt")); } private List readChecks(String name) { @@ -161,8 +170,8 @@ public File getConfigFile() { return this.configFile; } - public AssertionsAuditListener getAssersionsListener() { - return this.assersionsListener; + public AssertionsAuditListener getAssertionsListener() { + return this.assertionsListener; } @Override 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 962e74cf..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -16,17 +16,24 @@ 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; import com.puppycrawl.tools.checkstyle.DefaultContext; -import com.puppycrawl.tools.checkstyle.ModuleFactory; import com.puppycrawl.tools.checkstyle.PackageObjectFactory; import com.puppycrawl.tools.checkstyle.PropertiesExpander; import com.puppycrawl.tools.checkstyle.PropertyResolver; +import com.puppycrawl.tools.checkstyle.TreeWalker; import com.puppycrawl.tools.checkstyle.api.FileSetCheck; +import org.assertj.core.extractor.Extractors; +import org.junit.jupiter.api.Test; + import io.spring.javaformat.checkstyle.check.SpringHeaderCheck; -import org.junit.Test; +import io.spring.javaformat.checkstyle.check.SpringImportOrderCheck; import static org.assertj.core.api.Assertions.assertThat; @@ -39,21 +46,53 @@ public class SpringConfigurationLoaderTests { @Test public void loadShouldLoadChecks() { + Collection checks = load(null); + assertThat(checks).hasSize(5); + TreeWalker treeWalker = (TreeWalker) checks.toArray()[4]; + Set ordinaryChecks = (Set) Extractors.byName("ordinaryChecks").extract(treeWalker); + assertThat(ordinaryChecks).hasSize(63); + Set commentChecks = (Set) Extractors.byName("commentChecks").extract(treeWalker); + assertThat(commentChecks).hasSize(6); + } + + @Test + public void loadWithExcludeShouldExcludeChecks() { + 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(5); + TreeWalker treeWalker = (TreeWalker) checks.toArray()[4]; + Set ordinaryChecks = (Set) Extractors.byName("ordinaryChecks").extract(treeWalker); + 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(4); + } + + private Collection load(Set excludes) { DefaultContext context = new DefaultContext(); - context.add("moduleFactory", new PackageObjectFactory( - getClass().getPackage().getName(), getClass().getClassLoader())); - ModuleFactory moduleFactory = new PackageObjectFactory( - getClass().getPackage().getName(), getClass().getClassLoader()); - Collection checks = new SpringConfigurationLoader(context, - moduleFactory).load(getPropertyResolver()); - assertThat(checks).hasSize(3); + FilteredModuleFactory filteredModuleFactory = new FilteredModuleFactory( + new PackageObjectFactory(getClass().getPackage().getName(), getClass().getClassLoader()), excludes); + context.add("moduleFactory", filteredModuleFactory); + Collection checks = new SpringConfigurationLoader(context, filteredModuleFactory) + .load(getPropertyResolver()); + return checks; } private PropertyResolver getPropertyResolver() { Properties properties = new Properties(); properties.put("headerType", SpringHeaderCheck.DEFAULT_HEADER_TYPE); - properties.put("headerCopyrightPattern", - SpringHeaderCheck.DEFAULT_HEADER_COPYRIGHT_PATTERN); + properties.put("headerFile", ""); + properties.put("headerCopyrightPattern", SpringHeaderCheck.DEFAULT_HEADER_COPYRIGHT_PATTERN); + properties.put("projectRootPackage", SpringImportOrderCheck.DEFAULT_PROJECT_ROOT_PACKAGE); + properties.put("avoidStaticImportExcludes", ""); return new PropertiesExpander(properties); } 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/CatchOo.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/CatchOo.txt new file mode 100644 index 00000000..dba33895 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/CatchOo.txt @@ -0,0 +1 @@ ++'o_O' catch variable (use "ex" instead) 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/HeaderDate.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderDate.txt index cb61a4b8..3d109568 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderDate.txt +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderDate.txt @@ -1 +1,3 @@ -+HeaderDate.java:2: header.mismatch [SpringHeader] ++HeaderDate.java:2 ++Line does not match expected header ++[SpringHeader] diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderFile.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderFile.txt new file mode 100644 index 00000000..69174e4c --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderFile.txt @@ -0,0 +1 @@ ++0 errors \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderMismatch.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderMismatch.txt index 49868389..186d6aed 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderMismatch.txt +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderMismatch.txt @@ -1 +1,3 @@ -+HeaderMismatch.java:5: header.mismatch [SpringHeader] \ No newline at end of file ++HeaderMismatch.java:5 ++Line does not match expected header ++[SpringHeader] diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderMissingBlankLine.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderMissingBlankLine.txt new file mode 100644 index 00000000..7ffa25dc --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderMissingBlankLine.txt @@ -0,0 +1,2 @@ ++Blank line expected after header ++1 error \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderTooLong.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderTooLong.txt index 1c85c9e3..02c7a81b 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderTooLong.txt +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderTooLong.txt @@ -1 +1,3 @@ -+HeaderTooLong.java:15: header.mismatch [SpringHeader] ++HeaderTooLong.java:15: ++Line does not match expected header ++[SpringHeader] diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderTooShort.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderTooShort.txt index 856886e8..4c47c177 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderTooShort.txt +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderTooShort.txt @@ -1 +1,3 @@ -+HeaderTooShort.java:14: header.mismatch [SpringHeader] ++HeaderTooShort.java:14 ++Line does not match expected header ++[SpringHeader] 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/HeaderWithSingleDate.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderWithSingleDate.txt new file mode 100644 index 00000000..23435c7a --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HeaderWithSingleDate.txt @@ -0,0 +1 @@ ++0 errors diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HideUtilityClassConstructorInvalid.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HideUtilityClassConstructorInvalid.txt new file mode 100644 index 00000000..dc14dcd3 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HideUtilityClassConstructorInvalid.txt @@ -0,0 +1 @@ ++HideUtilityClassConstructorInvalid.java:22:1: Utility classes should not have a public or default constructor. [SpringHideUtilityClassConstructor] diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HideUtilityClassConstructorSpringApplication.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HideUtilityClassConstructorSpringApplication.txt new file mode 100644 index 00000000..69174e4c --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HideUtilityClassConstructorSpringApplication.txt @@ -0,0 +1 @@ ++0 errors \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HideUtilityClassConstructorSpringConfiguration.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HideUtilityClassConstructorSpringConfiguration.txt new file mode 100644 index 00000000..69174e4c --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/HideUtilityClassConstructorSpringConfiguration.txt @@ -0,0 +1 @@ ++0 errors \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/ImportOrderCustomPackageInvalid.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/ImportOrderCustomPackageInvalid.txt new file mode 100644 index 00000000..37a1d385 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/ImportOrderCustomPackageInvalid.txt @@ -0,0 +1 @@ ++ImportOrderCustomPackageInvalid.java:21:1: Wrong order for 'java.util.Objects' import. [SpringImportOrder] diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/ImportOrderCustomPackageValid.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/ImportOrderCustomPackageValid.txt new file mode 100644 index 00000000..69174e4c --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/ImportOrderCustomPackageValid.txt @@ -0,0 +1 @@ ++0 errors \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JUnit5BadAnnotation.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JUnit5BadAnnotation.txt new file mode 100644 index 00000000..ee903496 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JUnit5BadAnnotation.txt @@ -0,0 +1 @@ ++JUnit 4 @Test annotation should not be used in a JUnit 5 test. \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JUnit5BadImport.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JUnit5BadImport.txt new file mode 100644 index 00000000..75e3c05b --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JUnit5BadImport.txt @@ -0,0 +1 @@ ++Import 'org.junit.Before' should not be used in a JUnit 5 test. \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JUnit5BadImportWithOptOut.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JUnit5BadImportWithOptOut.txt new file mode 100644 index 00000000..69174e4c --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JUnit5BadImportWithOptOut.txt @@ -0,0 +1 @@ ++0 errors \ No newline at end of file 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 new file mode 100644 index 00000000..7ec1d4de --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JUnit5BadModifier.txt @@ -0,0 +1,16 @@ ++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 ++Lifecycle method 'publicAfterEach' should not be public ++Lifecycle method 'privateBeforeAll' should not be private ++Lifecycle method 'privateBeforeEach' should not be private ++Lifecycle method 'privateAfterAll' should not be private ++Lifecycle method 'privateAfterEach' should not be private \ No newline at end of file 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/JUnit5Valid.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JUnit5Valid.txt new file mode 100644 index 00000000..69174e4c --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JUnit5Valid.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/JavadocMethodEmptyLineBeforeTag.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocMethodEmptyLineBeforeTag.txt new file mode 100644 index 00000000..efa9ef2f --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocMethodEmptyLineBeforeTag.txt @@ -0,0 +1,2 @@ ++Method Javadoc should not have empty line before tag. ++1 error \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocMethodEmptyLineBeforeTagWithStarAtEnd.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocMethodEmptyLineBeforeTagWithStarAtEnd.txt new file mode 100644 index 00000000..69174e4c --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocMethodEmptyLineBeforeTagWithStarAtEnd.txt @@ -0,0 +1 @@ ++0 errors \ No newline at end of file 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/JavadocMissingSince.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocMissingSince.txt new file mode 100644 index 00000000..914724b7 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocMissingSince.txt @@ -0,0 +1,2 @@ ++Missing Javadoc @since tag. ++1 error \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocNonJavadocComment.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocNonJavadocComment.txt new file mode 100644 index 00000000..7ba1b19a --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocNonJavadocComment.txt @@ -0,0 +1,3 @@ ++23:1: Comments should not include "(non-Javadoc)" ++30:1: Comments should not include "(non-Javadoc)" ++2 errors \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocNonPublicSince.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocNonPublicSince.txt new file mode 100644 index 00000000..ecb8dbc3 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocNonPublicSince.txt @@ -0,0 +1,3 @@ ++JavadocNonPublicSince.java:21:11: Javadoc @since tag should not be used on private classes. [SpringJavadoc] ++JavadocNonPublicSince.java:28:19: Javadoc @since tag should not be used on private classes. [SpringJavadoc] ++2 errors \ No newline at end of file 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/JavadocNonPublicSinceInsideInterface.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocNonPublicSinceInsideInterface.txt new file mode 100644 index 00000000..69174e4c --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocNonPublicSinceInsideInterface.txt @@ -0,0 +1 @@ ++0 errors \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocSoundtrack.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocSoundtrack.txt new file mode 100644 index 00000000..20ea9833 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/JavadocSoundtrack.txt @@ -0,0 +1 @@ ++Javadoc tag '@soundtrack' should not be used. [SpringJavadoc] diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/LambdaNecessaryVoidCallable.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/LambdaNecessaryVoidCallable.txt new file mode 100644 index 00000000..69174e4c --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/LambdaNecessaryVoidCallable.txt @@ -0,0 +1 @@ ++0 errors \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/LambdaSwitch.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/LambdaSwitch.txt new file mode 100644 index 00000000..69174e4c --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/LambdaSwitch.txt @@ -0,0 +1 @@ ++0 errors \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/LeadingWhitespaceSpaces.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/LeadingWhitespaceSpaces.txt new file mode 100644 index 00000000..23d7767e --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/LeadingWhitespaceSpaces.txt @@ -0,0 +1,2 @@ ++Indentation should be performed with spaces only. [SpringLeadingWhitespace] ++1 error diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/LeadingWhitespaceTabs.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/LeadingWhitespaceTabs.txt new file mode 100644 index 00000000..3a32b527 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/LeadingWhitespaceTabs.txt @@ -0,0 +1,2 @@ ++Indentation should be performed with tabs only. [SpringLeadingWhitespace] ++1 error 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/MethodVisibilityInnerClassesWithPublicMethod.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/MethodVisibilityInnerClassesWithPublicMethod.txt new file mode 100644 index 00000000..e66b5bd9 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/MethodVisibilityInnerClassesWithPublicMethod.txt @@ -0,0 +1,3 @@ ++Method 'badPrivateInner' in private class should not be public. ++Method 'badDefaultInner' in private class should not be public. ++2 errors diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/MethodVisibilityPackagePrivateWithPublicMethod.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/MethodVisibilityPackagePrivateWithPublicMethod.txt new file mode 100644 index 00000000..4d1363b7 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/MethodVisibilityPackagePrivateWithPublicMethod.txt @@ -0,0 +1,3 @@ ++Method 'bad' in private class should not be public. ++Method 'badStatic' in private class should not be public. ++2 errors 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/MethodVisibilityWithOverride.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/MethodVisibilityWithOverride.txt new file mode 100644 index 00000000..23435c7a --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/MethodVisibilityWithOverride.txt @@ -0,0 +1 @@ ++0 errors diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NestedInterfaceItems.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NestedInterfaceItems.txt new file mode 100644 index 00000000..69174e4c --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/NestedInterfaceItems.txt @@ -0,0 +1 @@ ++0 errors \ No newline at end of file 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/OuterTypeFilenameInvalid.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/OuterTypeFilenameInvalid.txt new file mode 100644 index 00000000..c242222d --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/OuterTypeFilenameInvalid.txt @@ -0,0 +1 @@ ++The name of the outer type and the file do not match \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/OuterTypeFilenameValid.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/OuterTypeFilenameValid.txt new file mode 100644 index 00000000..69174e4c --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/OuterTypeFilenameValid.txt @@ -0,0 +1 @@ ++0 errors \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/TernaryParensInvalid.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/TernaryParensInvalid.txt index bd07621a..0c329c35 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/TernaryParensInvalid.txt +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/TernaryParensInvalid.txt @@ -1,2 +1,2 @@ -+Ternary operation missing parentheses ++Ternary operation missing parentheses. Use the form "(a != b) ? y : n" +3 errors \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/TryWithResources.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/TryWithResources.txt new file mode 100644 index 00000000..69174e4c --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/TryWithResources.txt @@ -0,0 +1 @@ ++0 errors \ No newline at end of file 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/nopackageinfo/NoPackageInfo.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/nopackageinfo/NoPackageInfo.txt new file mode 100644 index 00000000..a19759c0 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/check/nopackageinfo/NoPackageInfo.txt @@ -0,0 +1 @@ ++Missing package-info.java file \ 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/FiltersToSkipThis.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/FiltersToSkipThis.xml index 5cefa3a5..d12a0f37 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/FiltersToSkipThis.xml +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/FiltersToSkipThis.xml @@ -1,5 +1,7 @@ - + diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderDate.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderDate.xml index 2ec372e9..dde28701 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderDate.xml +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderDate.xml @@ -1,5 +1,7 @@ - + diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderFile.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderFile.xml new file mode 100644 index 00000000..1f3c7efa --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderFile.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderMissingBlankLine.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderMissingBlankLine.xml new file mode 100644 index 00000000..1f3c7efa --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderMissingBlankLine.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderMustBeMissing.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderMustBeMissing.xml index f03eb43e..79567613 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderMustBeMissing.xml +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderMustBeMissing.xml @@ -1,5 +1,7 @@ - + diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderMustBeMissingButIsNot.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderMustBeMissingButIsNot.xml index f03eb43e..79567613 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderMustBeMissingButIsNot.xml +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderMustBeMissingButIsNot.xml @@ -1,5 +1,7 @@ - + diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderUnchecked.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderUnchecked.xml index 6731bd0a..df9ccdac 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderUnchecked.xml +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/HeaderUnchecked.xml @@ -1,5 +1,7 @@ - + diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/ImportOrderCustomPackageInvalid.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/ImportOrderCustomPackageInvalid.xml new file mode 100644 index 00000000..dca7c768 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/ImportOrderCustomPackageInvalid.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/ImportOrderCustomPackageValid.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/ImportOrderCustomPackageValid.xml new file mode 100644 index 00000000..dca7c768 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/ImportOrderCustomPackageValid.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JUnit5BadAnnotation.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JUnit5BadAnnotation.xml new file mode 100644 index 00000000..1f9cd714 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JUnit5BadAnnotation.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JUnit5BadImport.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JUnit5BadImport.xml new file mode 100644 index 00000000..1f9cd714 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JUnit5BadImport.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JUnit5BadImportWithOptOut.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JUnit5BadImportWithOptOut.xml new file mode 100644 index 00000000..6d672900 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JUnit5BadImportWithOptOut.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JUnit5BadModifier.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JUnit5BadModifier.xml new file mode 100644 index 00000000..1f9cd714 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JUnit5BadModifier.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JUnit5Valid.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JUnit5Valid.xml new file mode 100644 index 00000000..1f9cd714 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JUnit5Valid.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JavadocMissingSince.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JavadocMissingSince.xml new file mode 100644 index 00000000..c13dc89d --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JavadocMissingSince.xml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JavadocNonPublicSince.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JavadocNonPublicSince.xml new file mode 100644 index 00000000..c2b98905 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JavadocNonPublicSince.xml @@ -0,0 +1,11 @@ + + + + + + + + + \ 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/config/JavadocNonPublicSinceInsideInterface.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JavadocNonPublicSinceInsideInterface.xml new file mode 100644 index 00000000..c2b98905 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/JavadocNonPublicSinceInsideInterface.xml @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/LambdaExtraParens.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/LambdaExtraParens.xml index 497832ff..0daf80c8 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/LambdaExtraParens.xml +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/LambdaExtraParens.xml @@ -1,5 +1,7 @@ - + diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/LeadingWhitespaceSpaces.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/LeadingWhitespaceSpaces.xml new file mode 100644 index 00000000..0070d582 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/LeadingWhitespaceSpaces.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/NoThis.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/NoThis.xml index 9b402015..ec09684f 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/NoThis.xml +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/NoThis.xml @@ -1,5 +1,7 @@ - + diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/TernaryEqualsEqualsAny.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/TernaryEqualsEqualsAny.xml index 7611428a..e155786e 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/TernaryEqualsEqualsAny.xml +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/TernaryEqualsEqualsAny.xml @@ -1,5 +1,7 @@ - + diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/TernaryEqualsEqualsNever.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/TernaryEqualsEqualsNever.xml index dafbee0c..14306d10 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/TernaryEqualsEqualsNever.xml +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/TernaryEqualsEqualsNever.xml @@ -1,5 +1,7 @@ - + diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/default-checkstyle-configuration.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/default-checkstyle-configuration.xml index 5f9503d2..f8fd854f 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/default-checkstyle-configuration.xml +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/default-checkstyle-configuration.xml @@ -1,5 +1,7 @@ - + \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/package-info-header-must-be-missing-but-is-not.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/package-info-header-must-be-missing-but-is-not.xml index a6e6df59..6b1603c3 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/package-info-header-must-be-missing-but-is-not.xml +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/package-info-header-must-be-missing-but-is-not.xml @@ -1,5 +1,7 @@ - + diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/package-info-header-must-be-missing.xml b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/package-info-header-must-be-missing.xml index a6e6df59..6b1603c3 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/package-info-header-must-be-missing.xml +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/config/package-info-header-must-be-missing.xml @@ -1,5 +1,7 @@ - + diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/customHeaderFile.txt b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/customHeaderFile.txt new file mode 100644 index 00000000..b96355a3 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/customHeaderFile.txt @@ -0,0 +1 @@ +// (c) Somebody ${copyright-pattern} \ 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-formatter/src/main/java/io/spring/javaformat/formatter/preparator/Preparators.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationOnNewLine.java similarity index 51% rename from spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/preparator/Preparators.java rename to spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationOnNewLine.java index 811b7857..f4893731 100644 --- a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/preparator/Preparators.java +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/AnnotationOnNewLine.java @@ -1,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,25 +14,32 @@ * limitations under the License. */ -package io.spring.javaformat.formatter.preparator; - -import java.util.function.Consumer; - -import io.spring.javaformat.formatter.eclipse.Preparator; +import org.jspecify.annotations.Nullable; /** - * {@link Preparator} instances that can be added. + * This is a valid example. * * @author Phillip Webb */ -public final class Preparators { +public class AnnotationOnNewLine { + + @Override + public String toString() { + return ""; + } + + @Nullable String test1() { + return ""; + } - private Preparators() { + @Override + @Nullable String test2() { + return ""; } - public static void forEach(Consumer consumer) { - consumer.accept(new JavadocLineBreakPreparator()); - consumer.accept(new CodeLineBreakPreparator()); + @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 79aaa40a..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 29d62ba0..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 new file mode 100644 index 00000000..1d21cda5 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/CatchOo.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. + */ + +/** + * A invalid catch with o_O as the variable. + * + * @author Phillip Webb + */ +public class CatchOo { + + public void test() { + try { + new String("foo"); + } + catch (IllegalStateException o_O) { + // Ignore + } + } + +} 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 6a77e525..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 d765b047..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 be1cc5c4..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderFile.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderFile.java new file mode 100644 index 00000000..6737309e --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderFile.java @@ -0,0 +1,10 @@ +// (c) Somebody 2017-2019 + +/** + * A custom header file. + * + * @author Phillip Webb + */ +public class HeaderFile { + +} 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 bc256fbb..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderMissingBlankLine.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderMissingBlankLine.java new file mode 100644 index 00000000..a12b1152 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderMissingBlankLine.java @@ -0,0 +1,9 @@ +// (c) Somebody 2017-2019 +/** + * A custom header file. + * + * @author Phillip Webb + */ +public class HeaderMissingBlankLine { + +} 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 6520e32b..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 8c10e592..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 new file mode 100644 index 00000000..11600fcd --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HeaderWithSingleDate.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 doesn't use a date range. + * + * @author Phillip Webb + */ +public class HeaderWithSingleDate { + +} 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 new file mode 100644 index 00000000..5a6b3543 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HideUtilityClassConstructorInvalid.java @@ -0,0 +1,27 @@ +/* + * 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. + */ + +/** + * Invlid utility class. + * + * @author Phillip Webb + */ +public class HideUtilityClassConstructorInvalid { + + public static void main(String[] args) { + } + +} 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 new file mode 100644 index 00000000..ece74108 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HideUtilityClassConstructorSpringApplication.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.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Usually invalid utility class but OK because it's a Spring Application. + * + * @author Phillip Webb + */ +@SpringBootApplication +public class HideUtilityClassConstructorSpringApplication { + + public static void main(String[] args) { + } + +} 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 new file mode 100644 index 00000000..cafe6164 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/HideUtilityClassConstructorSpringConfiguration.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. + */ + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Usually invalid utility class but OK because it's a Spring Configuration. + * + * @author Phillip Webb + */ +@Configuration +public class HideUtilityClassConstructorSpringConfiguration { + + @Bean + public static String myBean() { + return "foo"; + } + +} 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 new file mode 100644 index 00000000..7aa089cf --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/ImportOrderCustomPackageInvalid.java @@ -0,0 +1,40 @@ +/* + * 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 com.example; + +import com.example.util.MyUtils1; +import com.example.util.MyUtils2; +import java.util.Objects; + +/** + * Custom pacakge with valid imports. + * + * @author Phillip Webb + */ +public final class ImportOrderCustomPackageInvalid { + + private ImportOrderCustomPackageValid() { + } + + public static void main(String[] args) { + if (Objects.nonNull(args)) { + MyUtils1.sort(args); + MyUtils2.find(args); + } + } + +} 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 new file mode 100644 index 00000000..427075e6 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/ImportOrderCustomPackageValid.java @@ -0,0 +1,41 @@ +/* + * 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 com.example; + +import java.util.Objects; + +import com.example.util.MyUtils1; +import com.example.util.MyUtils2; + +/** + * Custom pacakge with valid imports. + * + * @author Phillip Webb + */ +public final class ImportOrderCustomPackageValid { + + private ImportOrderCustomPackageValid() { + } + + public static void main(String[] args) { + if (Objects.nonNull(args)) { + MyUtils1.sort(args); + MyUtils2.find(args); + } + } + +} 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 new file mode 100644 index 00000000..e9c41790 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5BadAnnotation.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. + */ + +/** + * Test with bad full qualified annotation. + * + * @author Phillip Webb + */ +public class JUnit5BadAnnotation { + + @org.junit.Test + void doSomethingWorks() { + // test here + } + +} 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 new file mode 100644 index 00000000..2870f5fb --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5BadImport.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. + */ + +import org.junit.jupiter.api.Test; +import org.junit.Before; + +/** + * Test with banned import. + * + * @author Phillip Webb + */ +public class JUnit5BadImport { + + @Before + public void bad() { + } + + @Test + void doSomethingWorks() { + // test here + } + +} 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 new file mode 100644 index 00000000..4b471be5 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5BadImportWithOptOut.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. + */ + +import com.example.OptOutRunner; +import org.junit.RunWith; +import org.junit.Test; + +/** + * Test with banned import but also opt-out trigger. + * + * @author Phillip Webb + */ +@RunWith(OptOutRunner.class) +public class JUnit5BadImportWithOptOut { + + @Test + void doSomethingWorks() { + // test here + } + +} 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 new file mode 100644 index 00000000..0e665db0 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5BadModifier.java @@ -0,0 +1,106 @@ +/* + * 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.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestTemplate; + +/** + * Test with bad modifiers. + * + * @author Phillip Webb + */ +public class JUnit5BadModifier { + + @BeforeAll + public static void publicBeforeAll() { + + } + + @BeforeEach + public void publicBeforeEach() { + + } + + @AfterAll + public static void publicAfterAll() { + + } + + @AfterEach + public void publicAfterEach() { + + } + + @BeforeAll + private static void privateBeforeAll() { + + } + + @BeforeEach + private void privateBeforeEach() { + + } + + @AfterAll + private static void privateAfterAll() { + + } + + @AfterEach + private void privateAfterEach() { + + } + + @Test + public void doSomethingWorks() { + // test here + } + + @Test + private void doSomethingElseWorks() { + // test here + } + + @TestTemplate + public void doSomethingWithTemplateWorks() { + // test here + } + + @TestTemplate + 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 new file mode 100644 index 00000000..df921319 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JUnit5Valid.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.junit.jupiter.api.Test; + +/** + * This is a valid example. + * + * @author Phillip Webb + */ +class JUnit5Valid { + + @Test + void doSomethingWorks() { + // test here + } + +} 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 0aba7142..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 41382834..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 new file mode 100644 index 00000000..dcb778a8 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocMethodEmptyLineBeforeTag.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 white space. + * @param this is a valid param + * @author Sushant Kumar Singh + */ +public class JavadocMethodEmptyLineBeforeTag { + + /** + * Do something. + * + * @param something a lovely thing + */ + public void test(String something) { + } + +} 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 new file mode 100644 index 00000000..2d92f513 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocMethodEmptyLineBeforeTagWithStarAtEnd.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 white space. + * @param this is a valid param + * @author Sushant Kumar Singh + */ +public class JavadocMethodEmptyLineBeforeTagWithStarAtEnd { + + /** + * First paragraph. + * + *

Second paragraph contains an asterisk in a code element: {@code *}. + * @since 1.0 + */ + public void test() { + } + +} 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-formatter/src/main/java/io/spring/javaformat/formatter/FormatterOption.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocMissingSince.java similarity index 66% rename from spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/FormatterOption.java rename to spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocMissingSince.java index 0c04a23d..c9afd407 100644 --- a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/FormatterOption.java +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocMissingSince.java @@ -1,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,18 +14,18 @@ * limitations under the License. */ -package io.spring.javaformat.formatter; - /** - * Options that can be used to configure a {@link Formatter}. + * Javadoc with a bad since tag. * * @author Phillip Webb */ -public enum FormatterOption { +public class JavadocMissingSince { /** - * Show Eclipse NLS warnings. + * Inner class. */ - SHOW_NLS_WARNINGS + private static class Inner { + + } } 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 new file mode 100644 index 00000000..047b2a05 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocNonJavadocComment.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. + */ + +/** + * Example with non javadoc comments. + * + * @author Phillip Webb + */ +public class JavadocNonJavadocComment { + + /* (non-Javadoc) + * Example. + */ + public void one() { + } + + /** + * (non-Javadoc). + */ + public void two() { + } + +} 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 new file mode 100644 index 00000000..4f0f2fde --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocNonPublicSince.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 a bad since tag. + * + * @author Phillip Webb + * @since 1.2.3 + */ +class JavadocNonPublicSince { + + /** + * Inner class. + * + * @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 new file mode 100644 index 00000000..c0e4b412 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocNonPublicSinceInsideInterface.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 JavadocNonPublicSinceInsideInterface { + + /** + * Inner enum. + * + * @since 1.2.4 + */ + enum Inner { + + FOO + + } + +} 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 new file mode 100644 index 00000000..846bf48d --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/JavadocSoundtrack.java @@ -0,0 +1,26 @@ +/* + * 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 Javadoc. + * + * @param this is a valid param + * @author Phillip Webb + * @soundtrack Gina G - Ooh Aah Just A Little Bit + */ +public class JavadocSoundtrack { + +} 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 6b925542..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -15,7 +15,7 @@ */ /** - * Javadoc with a bad author tag. + * Valid Javadoc. * * @param this is a valid param * @author Phillip Webb @@ -43,7 +43,37 @@ public void test2(String something) { * @return the thing * @throws RuntimeException on the error */ - public String test3(String something) throw RuntimeException { + 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 b638608a..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,12 +1,12 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 77775604..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 f1c47d40..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 62f736f3..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 01ff0754..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 f0e58f8e..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 18ada5f4..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 1884c28f..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 new file mode 100644 index 00000000..54864d72 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaNecessaryVoidCallable.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. + */ + +import java.util.concurrent.Callable; + +/** + * This is a valid example of a lambda where the block is required. + * + * @author Andy Wilkinson + */ +public class LambdaNecessaryVoidCallable { + + public Callable test() { + return () -> { + new String("test"); + return null; + }; + } + +} 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 new file mode 100644 index 00000000..55640621 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LambdaSwitch.java @@ -0,0 +1,35 @@ +/* + * 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.function.Function; + +/** + * Lambda in a switch statement. + * + * @author Josef Reichardt + */ +public class LambdaSwitch { + + private void sayHello(String[] args) { + Function getText = (cnt) -> "Number of args: " + cnt; + String message = switch (args.length) { + case 0 -> "No arg"; + case 1 -> "One arg"; + default -> getText.apply(args.length); + }; + System.out.println(message); + } +} 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 1c983775..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,6 +14,7 @@ * limitations under the License. */ +import java.util.function.Consumer; import java.util.function.Function; /** @@ -30,7 +31,7 @@ public Function test() { }; } - public Consimer test() { + public Consumer test() { return (string) -> { new StringBuilder() .append("foo"); 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 bd198b42..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 new file mode 100644 index 00000000..0e69080a --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LeadingWhitespaceSpaces.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. + */ + +/** + * Leading whitepace expects only tabs. + * + * @author Phillip Webb + */ +public class LeadingWhitespaceSpaces { + + /** + * Comments are ignored. + */ + public void hello() { + System.out.println("World"); + } + +} 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 new file mode 100644 index 00000000..53d64c19 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/LeadingWhitespaceTabs.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. + */ + +/** + * Leading whitepace expects only tabs. + * + * @author Phillip Webb + */ +public class LeadingWhitespaceTabs { + + /** + * Comments are ignored. + */ + public void hello() { + System.out.println("World"); + } + +} 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 0f4e6ec2..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 df0feb0d..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 new file mode 100644 index 00000000..262a258f --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityInnerClassesWithPublicMethod.java @@ -0,0 +1,51 @@ +/* + * 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 of public method. + * + * @author Phillip Webb + */ +public class MethodVisibilityInnerClassesWithPublicMethod { + + private static class PrivateInnerClass { + + public void badPrivateInner() { + } + + } + + protected static class ProtectedInnerClass { + + public void okProtectedInner() { + } + + } + + static class DefaultInnerClass { + + public void badDefaultInner() { + } + + } + + public static class PublicInnerClass { + + public void okPublicInner() { + } + + } +} 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 new file mode 100644 index 00000000..c6377f3d --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityPackagePrivateWithPublicMethod.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. + */ + +/** + * Bad visibility because of public method. + * + * @author Phillip Webb + */ +class MethodVisibilityPackagePrivateWithPublicMethod { + + MethodVisibilityPackagePrivateWithPublicMethod() { + } + + public void bad() { + } + + public static void badStatic() { + } + +} 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 new file mode 100644 index 00000000..c4b8d3b3 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/MethodVisibilityWithOverride.java @@ -0,0 +1,48 @@ +/* + * 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 of {@code @Override} annotation. + * + * @author Phillip Webb + */ +public class MethodVisibilityWithOverride { + + private static class PrivateInnerClass { + + @Override + public void okPrivateInner() { + } + + } + + protected static class ProtectedInnerClass { + + @Override + public void okProtectedInner() { + } + + } + + static class DefaultInnerClass { + + @Override + public void okDefaultInner() { + } + + } + +} 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 new file mode 100644 index 00000000..8f9bb820 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/NestedInterfaceItems.java @@ -0,0 +1,40 @@ +/* + * 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; + +/** + * Interface with implicit public elements. + * + * @author Phillip Webb + */ +public interface NestedInterfaceItems { + + /** + * A nested class class. + */ + class NestedClass { + + public NestedClass(String arg) { + // This is valid because nested class is implicitly public + } + + public void thisIsFine() { + } + + } + +} 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 7c583197..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,6 +14,6 @@ * limitations under the License. */ -public class MissingNewLine { +public class NewlineAtEndOfFile { } \ No newline at end of file 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 3a40b334..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 new file mode 100644 index 00000000..59f7dc88 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/OuterTypeFilenameInvalid.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 an example of a class name not matching its filename. + * + * @author Christoph Dreis + */ +public class NameNotMatching { + +} 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 new file mode 100644 index 00000000..6814ed2f --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/OuterTypeFilenameValid.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 valid example of a class name matching its filename. + * + * @author Christoph Dreis + */ +public class OuterTypeFilenameValid { + +} 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 33a838f0..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -935,8 +935,8 @@ public void setMainApplicationClass(Class mainApplicationClass) { /** * Returns whether this {@link SpringApplication} is running within a web environment. * @return {@code true} if running within a web environment, otherwise {@code false}. - * @see #setWebEnvironment(boolean) * @deprecated since 2.0.0 in favor of {@link #getWebApplicationType()} + * @see #setWebEnvironment(boolean) */ @Deprecated public boolean isWebEnvironment() { 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 08a42aed..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 d818405e..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 83df865c..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 b5472d6d..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 71c157aa..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -24,7 +24,9 @@ public class TernaryInIf { public void test() { boolean a = true; boolean b = false; - if ((a != b) ? true : false) { + int c = 1; + int d = 2; + if ((a != b) ? d < c : c >= d) { System.out.println("OK"); } } 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 ddc333cf..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -24,7 +24,9 @@ public class TernaryInWhile { public void test() { boolean a = true; boolean b = false; - while ((a != b) ? true : false) { + int c = 1; + int d = 2; + while ((a != b) ? d < c : c >= d) { System.out.println("OK"); } } 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 06303fb2..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 bca4d7ea..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 bda2d180..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 new file mode 100644 index 00000000..c68396dc --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/TryWithResources.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. + */ + +/** + * This is a valid example. + * + * @author Phillip Webb + */ +public class TryWithResources { + + public void test() { + try (Session session = this.driver.session(); Transaction tx = session.beginTransaction()) { + System.out.println(session); + } + } + +} 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 eb199261..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 new file mode 100644 index 00000000..5ae26280 --- /dev/null +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/nopackageinfo/NoPackageInfo.java @@ -0,0 +1,26 @@ +/* + * 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 nopackageinfo; + +/** + * A class in a package with no {@code package-info.java} file. + * + * @author Andy Wilkinson + */ +class NoPackageInfo { + +} diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/package-info-header-must-be-missing-but-is-not.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/package-info-header-must-be-missing-but-is-not.java index 3850a9ec..a7f468eb 100644 --- a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/package-info-header-must-be-missing-but-is-not.java +++ b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/package-info-header-must-be-missing-but-is-not.java @@ -1,4 +1,4 @@ /** * Something. */ -package com.example +package com.example; 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 2f645a7d..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,4 +14,4 @@ * limitations under the License. */ -package com.example +package com.example; diff --git a/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/package-info.java b/spring-javaformat/spring-javaformat-checkstyle/src/test/resources/source/package-info.java new file mode 100644 index 00000000..e69de29b 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 new file mode 100644 index 00000000..e984a073 --- /dev/null +++ b/spring-javaformat/spring-javaformat-config/pom.xml @@ -0,0 +1,15 @@ + + + 4.0.0 + + io.spring.javaformat + spring-javaformat + 0.0.48-SNAPSHOT + + spring-javaformat-config + Spring JavaFormat Config + + ${basedir}/../.. + + 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 new file mode 100644 index 00000000..d2b5ee8c --- /dev/null +++ b/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/DefaultJavaFormatConfig.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. + */ + +package io.spring.javaformat.config; + +/** + * Default {@link JavaFormatConfig} implementation used when no config file is found. + * + * @author Phillip Webb + */ +class DefaultJavaFormatConfig implements JavaFormatConfig { + + private final JavaBaseline javaBaseline; + + private final IndentationStyle indentationStyle; + + DefaultJavaFormatConfig(JavaBaseline javaBaseline, IndentationStyle indentationStyle) { + this.javaBaseline = javaBaseline; + this.indentationStyle = indentationStyle; + } + + @Override + public JavaBaseline getJavaBaseline() { + return this.javaBaseline; + } + + @Override + public IndentationStyle getIndentationStyle() { + return this.indentationStyle; + } + +} 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 new file mode 100644 index 00000000..f6e2144d --- /dev/null +++ b/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/IndentationStyle.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. + */ + +package io.spring.javaformat.config; + +/** + * Indentation styles that can be used. + * + * @author Phillip Webb + */ +public enum IndentationStyle { + + /** + * Indent with tabs. + */ + TABS, + + /** + * Indent with spaces. + */ + SPACES + +} 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 new file mode 100644 index 00000000..a27c3df0 --- /dev/null +++ b/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/JavaBaseline.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. + */ + +package io.spring.javaformat.config; + +/** + * Java JDK baseline version expected be used when formatting. + * + * @author Phillip Webb + */ +public enum JavaBaseline { + + /** + * Use JDK 8+ compatible formatter. + */ + V8, + + /** + * Use JDK 17+ or higher compatible formatter. + */ + 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 new file mode 100644 index 00000000..23bf45c8 --- /dev/null +++ b/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/JavaFormatConfig.java @@ -0,0 +1,121 @@ +/* + * 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.config; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Path; + +/** + * Support for the {@code .springjavaformatconfig} file that can be used to apply settings + * on a per-project basis. + * + * @author Phillip Webb + */ +public interface JavaFormatConfig { + + /** + * The default {@link JavaFormatConfig}. + */ + JavaFormatConfig DEFAULT = of(JavaBaseline.V17, IndentationStyle.TABS); + + /** + * Java JDK baseline version expected be used when formatting. + * @return the JDK version + */ + JavaBaseline getJavaBaseline(); + + /** + * Return the indentation style that should be used with the project. + * @return the indentation style + */ + IndentationStyle getIndentationStyle(); + + /** + * Find and load a {@code .springjavaformatconfig} by searching from the given file. + * @param path the file or directory to search from + * @return a loaded {@link JavaFormatConfig} or {@link #DEFAULT} if no + * {@code .springjavaformatconfig} file is found + */ + static JavaFormatConfig findFrom(Path path) { + return findFrom((path != null) ? path.toFile() : (File) null); + } + + /** + * Find and load a {@code .springjavaformatconfig} by searching from the given file. + * @param file the file or directory to search from + * @return a loaded {@link JavaFormatConfig} or {@link #DEFAULT} if no + * {@code .springjavaformatconfig} file is found + */ + static JavaFormatConfig findFrom(File file) { + if (file != null && file.isFile()) { + return findFrom(file.getParentFile()); + } + try { + while (file != null) { + File candidate = new File(file, ".springjavaformatconfig"); + if (candidate.exists() && candidate.isFile()) { + return load(candidate); + } + file = file.getParentFile(); + } + } + catch (Exception ex) { + } + return DEFAULT; + } + + /** + * Load a {@link JavaFormatConfig} from the given file. + * @param file the file to load + * @return the loaded config + */ + static JavaFormatConfig load(File file) { + try { + return PropertiesJavaFormatConfig.load(file); + } + catch (IOException ex) { + throw new IllegalStateException(ex); + } + } + + /** + * Load a {@link JavaFormatConfig} from the given input stream. + * @param inputStream the input stream to load + * @return the loaded config + */ + static JavaFormatConfig load(InputStream inputStream) { + try { + return PropertiesJavaFormatConfig.load(inputStream); + } + catch (IOException ex) { + throw new IllegalStateException(ex); + } + } + + /** + * Factory method to create a {@link JavaFormatConfig} with specific settings. + * @param javaBaseline The baseline JDK version + * @param indentationStyle the indentation style + * @return a {@link JavaFormatConfig} instance + */ + static JavaFormatConfig of(JavaBaseline javaBaseline, IndentationStyle indentationStyle) { + return new DefaultJavaFormatConfig(javaBaseline, indentationStyle); + } + +} 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 new file mode 100644 index 00000000..d631312d --- /dev/null +++ b/spring-javaformat/spring-javaformat-config/src/main/java/io/spring/javaformat/config/PropertiesJavaFormatConfig.java @@ -0,0 +1,64 @@ +/* + * 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.config; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +/** + * {@link JavaFormatConfig} backed by a properties file. + * + * @author Phillip Webb + */ +class PropertiesJavaFormatConfig implements JavaFormatConfig { + + private final Properties properties; + + PropertiesJavaFormatConfig(Properties properties) { + this.properties = properties; + } + + @Override + public JavaBaseline getJavaBaseline() { + Object value = this.properties.get("java-baseline"); + return (value != null) ? JavaBaseline.valueOf("V" + value.toString().toUpperCase().trim()) + : DEFAULT.getJavaBaseline(); + } + + @Override + public IndentationStyle getIndentationStyle() { + Object value = this.properties.get("indentation-style"); + return (value != null) ? IndentationStyle.valueOf(value.toString().toUpperCase().trim()) + : DEFAULT.getIndentationStyle(); + } + + static JavaFormatConfig load(File file) throws IOException { + try (InputStream inputStream = new FileInputStream(file)) { + return load(inputStream); + } + } + + static JavaFormatConfig load(InputStream inputStream) throws IOException { + Properties properties = new Properties(); + properties.load(inputStream); + return new PropertiesJavaFormatConfig(properties); + } + +} 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 new file mode 100644 index 00000000..2c702617 --- /dev/null +++ b/spring-javaformat/spring-javaformat-config/src/test/java/io/spring/javaformat/config/PropertiesJavaFormatConfigTests.java @@ -0,0 +1,62 @@ +/* + * 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.config; + +import java.util.Properties; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link PropertiesJavaFormatConfig}. + * + * @author Phillip Webb + */ +class PropertiesJavaFormatConfigTests { + + @Test + void getJavaBaselineWhenNoPropertyReturnsJava11() { + Properties properties = new Properties(); + PropertiesJavaFormatConfig config = new PropertiesJavaFormatConfig(properties); + assertThat(config.getJavaBaseline()).isEqualTo(JavaBaseline.V17); + } + + @Test + void getJavaBaselineWhenPropertyReturnsPropertyValue() { + Properties properties = new Properties(); + properties.setProperty("java-baseline", "8"); + PropertiesJavaFormatConfig config = new PropertiesJavaFormatConfig(properties); + assertThat(config.getJavaBaseline()).isEqualTo(JavaBaseline.V8); + } + + @Test + void getIndentationStyleWhenNoPropertyReturnsJava11() { + Properties properties = new Properties(); + PropertiesJavaFormatConfig config = new PropertiesJavaFormatConfig(properties); + assertThat(config.getIndentationStyle()).isEqualTo(IndentationStyle.TABS); + } + + @Test + void getIndentationStyleWhenPropertyReturnsPropertyValue() { + Properties properties = new Properties(); + properties.setProperty("indentation-style", "spaces"); + PropertiesJavaFormatConfig config = new PropertiesJavaFormatConfig(properties); + assertThat(config.getIndentationStyle()).isEqualTo(IndentationStyle.SPACES); + } + +} diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-jdk17/META-INF/MANIFEST.MF b/spring-javaformat/spring-javaformat-formatter-eclipse-jdk17/META-INF/MANIFEST.MF new file mode 100644 index 00000000..5e2e9099 --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-eclipse-jdk17/META-INF/MANIFEST.MF @@ -0,0 +1,12 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +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, + org.eclipse.jface.source;bundle-version="[1.0.0,10.0.0)";resolution:=optional, + org.eclipse.jface.text.source;bundle-version="[1.0.0,10.0.0)";resolution:=optional, + org.eclipse.text.source;bundle-version="[1.0.0,10.0.0)";resolution:=optional +Bundle-RequiredExecutionEnvironment: JavaSE-11 diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/build.properties b/spring-javaformat/spring-javaformat-formatter-eclipse-jdk17/build.properties similarity index 100% rename from spring-javaformat/spring-javaformat-formatter-eclipse-runtime/build.properties rename to spring-javaformat/spring-javaformat-formatter-eclipse-jdk17/build.properties diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-jdk17/pom.xml b/spring-javaformat/spring-javaformat-formatter-eclipse-jdk17/pom.xml new file mode 100644 index 00000000..0e73c0e4 --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-eclipse-jdk17/pom.xml @@ -0,0 +1,213 @@ + + + 4.0.0 + + io.spring.javaformat + spring-javaformat + 0.0.48-SNAPSHOT + + spring-javaformat-formatter-eclipse-jdk17 + eclipse-plugin + Spring JavaFormat Eclipse JDK-17 + + ${basedir}/../.. + org.eclipse.jdt.core.source,org.eclipse.jface.source,org.eclipse.text.source + + + + Eclipse Public License, Version 1.0 + https://www.eclipse.org/legal/epl-v10.html + + + + + eclipse-jdk17 + p2 + ${eclipse.jdk17.repository} + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + empty-javadoc-jar + package + + jar + + + javadoc + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + io.spring.javaformat + spring-javaformat-formatter-eclipse-rewriter + ${project.version} + + + ant-contrib + ant-contrib + ${ant-contrib.version} + + + ant + ant + + + + + org.apache.ant + ant-nodeps + ${ant.version} + + + + + rewrite-bytecode + package + + run + + + + + + + + + + + + repackage-source + package + + run + + + + + + + + + + + + org.eclipse.tycho + tycho-packaging-plugin + + false + + + + org.eclipse.tycho + tycho-maven-plugin + + + org.eclipse.tycho + target-platform-configuration + + + org.eclipse.tycho + tycho-versions-plugin + + + update-eclipse-version + initialize + + update-eclipse-metadata + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + unpack-dependencies + + unpack-dependencies + + prepare-package + + ${project.build.outputDirectory} + META-INF/*,**.dll,**.so,**.java + ${sourceartifacts} + + + + unpack-source-dependencies + + unpack-dependencies + + prepare-package + + ${project.build.directory}/sources + ${sourceartifacts} + + + + + + com.github.wvengen + proguard-maven-plugin + + + reduce-eclipse-runtime + package + + proguard + + + false + + ${java.home}/jmods + + + + + + + + + + + + + + + + + + + + + + + io.spring.javaformat + spring-javaformat-formatter-eclipse-rewriter + ${project.version} + provided + + + diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/META-INF/MANIFEST.MF b/spring-javaformat/spring-javaformat-formatter-eclipse-jdk8/META-INF/MANIFEST.MF similarity index 72% rename from spring-javaformat/spring-javaformat-formatter-eclipse-runtime/META-INF/MANIFEST.MF rename to spring-javaformat/spring-javaformat-formatter-eclipse-jdk8/META-INF/MANIFEST.MF index a7ad4746..3c5dbb8b 100644 --- a/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/META-INF/MANIFEST.MF +++ b/spring-javaformat/spring-javaformat-formatter-eclipse-jdk8/META-INF/MANIFEST.MF @@ -1,12 +1,12 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: Spring Formatter Eclipse Runtime -Bundle-SymbolicName: spring-javaformat-formatter-eclipse-runtime -Bundle-Version: 0.0.7.qualifier +Bundle-Name: Spring Formatter Eclipse JDK8 +Bundle-SymbolicName: spring-javaformat-formatter-eclipse-jdk8 +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, org.eclipse.jface.source;bundle-version="[1.0.0,10.0.0)";resolution:=optional, org.eclipse.jface.text.source;bundle-version="[1.0.0,10.0.0)";resolution:=optional, org.eclipse.text.source;bundle-version="[1.0.0,10.0.0)";resolution:=optional -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-RequiredExecutionEnvironment: JavaSE-11 diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-jdk8/build.properties b/spring-javaformat/spring-javaformat-formatter-eclipse-jdk8/build.properties new file mode 100755 index 00000000..45d47043 --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-eclipse-jdk8/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = target/classes +bin.includes = META-INF/,\ + .,\ diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-jdk8/pom.xml b/spring-javaformat/spring-javaformat-formatter-eclipse-jdk8/pom.xml new file mode 100644 index 00000000..0e52bf06 --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-eclipse-jdk8/pom.xml @@ -0,0 +1,213 @@ + + + 4.0.0 + + io.spring.javaformat + spring-javaformat + 0.0.48-SNAPSHOT + + spring-javaformat-formatter-eclipse-jdk8 + eclipse-plugin + Spring JavaFormat Eclipse JDK-8 + + ${basedir}/../.. + org.eclipse.jdt.core.source,org.eclipse.jface.source,org.eclipse.text.source + + + + Eclipse Public License, Version 1.0 + https://www.eclipse.org/legal/epl-v10.html + + + + + eclipse-jdk8 + p2 + ${eclipse.jdk8.repository} + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + empty-javadoc-jar + package + + jar + + + javadoc + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + io.spring.javaformat + spring-javaformat-formatter-eclipse-rewriter + ${project.version} + + + ant-contrib + ant-contrib + ${ant-contrib.version} + + + ant + ant + + + + + org.apache.ant + ant-nodeps + ${ant.version} + + + + + rewrite-bytecode + package + + run + + + + + + + + + + + + repackage-source + package + + run + + + + + + + + + + + + org.eclipse.tycho + tycho-packaging-plugin + + false + + + + org.eclipse.tycho + tycho-maven-plugin + + + org.eclipse.tycho + target-platform-configuration + + + org.eclipse.tycho + tycho-versions-plugin + + + update-eclipse-version + initialize + + update-eclipse-metadata + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + unpack-dependencies + + unpack-dependencies + + prepare-package + + ${project.build.outputDirectory} + META-INF/*,**.dll,**.so,**.java + ${sourceartifacts} + + + + unpack-source-dependencies + + unpack-dependencies + + prepare-package + + ${project.build.directory}/sources + ${sourceartifacts} + + + + + + com.github.wvengen + proguard-maven-plugin + + + reduce-eclipse-runtime + package + + proguard + + + false + + ${java.home}/jmods + + + + + + + + + + + + + + + + + + + + + + + io.spring.javaformat + spring-javaformat-formatter-eclipse-rewriter + ${project.version} + provided + + + diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse/pom.xml b/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk17/pom.xml similarity index 74% rename from spring-javaformat/spring-javaformat-formatter-eclipse/pom.xml rename to spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk17/pom.xml index 6f9e13b0..9aef9a9a 100644 --- a/spring-javaformat/spring-javaformat-formatter-eclipse/pom.xml +++ b/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk17/pom.xml @@ -1,23 +1,23 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat spring-javaformat - 0.0.7-SNAPSHOT + 0.0.48-SNAPSHOT - spring-javaformat-formatter-eclipse - Spring JavaFormat Eclipse + spring-javaformat-formatter-eclipse-jdt-jdk17 + Spring JavaFormat Eclipse JDT JDK-17 ${basedir}/../.. io.spring.javaformat - spring-javaformat-formatter-eclipse-runtime - 0.0.7-SNAPSHOT + spring-javaformat-formatter-eclipse-jdk17 + ${project.version} true @@ -48,16 +48,16 @@ - io.spring.javaformat:spring-javaformat-formatter-eclipse-runtime + io.spring.javaformat:spring-javaformat-formatter-eclipse-jdk17 - org/eclipse/jdt/internal/formatter/** + org/eclipse/jdt/** - org.eclipse.jdt.internal.formatter - io.spring.javaformat.formatter.eclipse + org.eclipse.jdt + io.spring.javaformat.eclipse.jdt.jdk17 false diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse/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 57% rename from spring-javaformat/spring-javaformat-formatter-eclipse/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 5caf3e37..a2664b72 100644 --- a/spring-javaformat/spring-javaformat-formatter-eclipse/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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -21,7 +21,11 @@ import java.util.List; import java.util.Map; +import org.eclipse.jdt.core.compiler.InvalidInputException; import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; +import org.eclipse.jdt.internal.compiler.parser.Scanner; +import org.eclipse.jdt.internal.compiler.parser.TerminalTokens; import org.eclipse.jdt.internal.formatter.Preparator.Phase; /** @@ -32,14 +36,15 @@ */ public class ExtendedCodeFormatter extends DefaultCodeFormatter { + private static boolean useLegacyTokenize = false; + private final List preparators = new ArrayList<>(); public ExtendedCodeFormatter() { super(); } - public ExtendedCodeFormatter(DefaultCodeFormatterOptions defaultCodeFormatterOptions, - Map options) { + public ExtendedCodeFormatter(DefaultCodeFormatterOptions defaultCodeFormatterOptions, Map options) { super(defaultCodeFormatterOptions, options); } @@ -55,6 +60,43 @@ protected void addPreparator(Preparator preparator) { this.preparators.add(preparator); } + @Override + protected void tokenizeSource(int kind) { + if (useLegacyTokenize) { + legacyTokenizeSource(kind); + return; + } + try { + super.tokenizeSource(kind); + } + catch (NoSuchMethodError ex) { + useLegacyTokenize = true; + legacyTokenizeSource(kind); + } + } + + private void legacyTokenizeSource(int kind) { + this.tokens.clear(); + long sourceLevel = CompilerOptions.versionToJdkLevel(this.sourceLevel); + Scanner scanner = new Scanner(true, false, false, sourceLevel, null, null, false); + scanner.setSource(this.sourceArray); + scanner.fakeInModule = (kind & K_MODULE_INFO) != 0; + while (true) { + try { + int tokenType = scanner.getNextToken(); + if (tokenType == TerminalTokens.TokenNameEOF) { + break; + } + Token token = Token.fromCurrent(scanner, tokenType); + this.tokens.add(token); + } + catch (InvalidInputException ex) { + Token token = Token.fromCurrent(scanner, TerminalTokens.TokenNameNotAToken); + this.tokens.add(token); + } + } + } + @Override protected void prepareWraps(int kind) { ASTNode astRoot = getField("astRoot", ASTNode.class); @@ -64,11 +106,10 @@ protected void prepareWraps(int kind) { applyPreparators(Phase.POST_WRAPPING, kind, astRoot, tokenManager); } - private void applyPreparators(Phase preWrapping, int kind, ASTNode astRoot, - TokenManager tokenManager) { + 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)); + .filter((preparator) -> preparator.getPhase() == preWrapping) + .forEach((preparator) -> preparator.apply(kind, tokenManager, astRoot)); } @SuppressWarnings("unchecked") diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse/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 92% rename from spring-javaformat/spring-javaformat-formatter-eclipse/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 e0a8d12d..bfd16b37 100644 --- a/spring-javaformat/spring-javaformat-formatter-eclipse/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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -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 new file mode 100644 index 00000000..30a2af39 --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk8/pom.xml @@ -0,0 +1,72 @@ + + + 4.0.0 + + io.spring.javaformat + spring-javaformat + 0.0.48-SNAPSHOT + + spring-javaformat-formatter-eclipse-jdt-jdk8 + Spring JavaFormat Eclipse JDT JDK-8 + + ${basedir}/../.. + + + + io.spring.javaformat + spring-javaformat-formatter-eclipse-jdk8 + ${project.version} + true + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-source + package + + jar + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + + + io.spring.javaformat:spring-javaformat-formatter-eclipse-jdk8 + + org/eclipse/jdt/** + + + + + + org.eclipse.jdt + io.spring.javaformat.eclipse.jdt.jdk8 + + + false + true + true + + + + + + + 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 new file mode 100644 index 00000000..a2664b72 --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk8/src/main/java/org/eclipse/jdt/internal/formatter/ExtendedCodeFormatter.java @@ -0,0 +1,127 @@ +/* + * 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 org.eclipse.jdt.internal.formatter; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.eclipse.jdt.core.compiler.InvalidInputException; +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; +import org.eclipse.jdt.internal.compiler.parser.Scanner; +import org.eclipse.jdt.internal.compiler.parser.TerminalTokens; +import org.eclipse.jdt.internal.formatter.Preparator.Phase; + +/** + * Extended version of {@link DefaultCodeFormatter} that allows additional + * {@link Preparator preparators} to be used. + * + * @author Phillip Webb + */ +public class ExtendedCodeFormatter extends DefaultCodeFormatter { + + private static boolean useLegacyTokenize = false; + + private final List preparators = new ArrayList<>(); + + public ExtendedCodeFormatter() { + super(); + } + + public ExtendedCodeFormatter(DefaultCodeFormatterOptions defaultCodeFormatterOptions, Map options) { + super(defaultCodeFormatterOptions, options); + } + + public ExtendedCodeFormatter(DefaultCodeFormatterOptions options) { + super(options); + } + + public ExtendedCodeFormatter(Map options) { + super(options); + } + + protected void addPreparator(Preparator preparator) { + this.preparators.add(preparator); + } + + @Override + protected void tokenizeSource(int kind) { + if (useLegacyTokenize) { + legacyTokenizeSource(kind); + return; + } + try { + super.tokenizeSource(kind); + } + catch (NoSuchMethodError ex) { + useLegacyTokenize = true; + legacyTokenizeSource(kind); + } + } + + private void legacyTokenizeSource(int kind) { + this.tokens.clear(); + long sourceLevel = CompilerOptions.versionToJdkLevel(this.sourceLevel); + Scanner scanner = new Scanner(true, false, false, sourceLevel, null, null, false); + scanner.setSource(this.sourceArray); + scanner.fakeInModule = (kind & K_MODULE_INFO) != 0; + while (true) { + try { + int tokenType = scanner.getNextToken(); + if (tokenType == TerminalTokens.TokenNameEOF) { + break; + } + Token token = Token.fromCurrent(scanner, tokenType); + this.tokens.add(token); + } + catch (InvalidInputException ex) { + Token token = Token.fromCurrent(scanner, TerminalTokens.TokenNameNotAToken); + this.tokens.add(token); + } + } + } + + @Override + protected void prepareWraps(int kind) { + ASTNode astRoot = getField("astRoot", ASTNode.class); + TokenManager tokenManager = getField("tokenManager", TokenManager.class); + applyPreparators(Phase.PRE_WRAPPING, kind, astRoot, tokenManager); + super.prepareWraps(kind); + applyPreparators(Phase.POST_WRAPPING, kind, astRoot, tokenManager); + } + + 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)); + } + + @SuppressWarnings("unchecked") + private T getField(String name, Class type) { + try { + Field field = DefaultCodeFormatter.class.getDeclaredField(name); + field.setAccessible(true); + return (T) field.get(this); + } + catch (Exception ex) { + throw new IllegalStateException(ex); + } + } + +} 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 new file mode 100644 index 00000000..bfd16b37 --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-eclipse-jdt-jdk8/src/main/java/org/eclipse/jdt/internal/formatter/Preparator.java @@ -0,0 +1,61 @@ +/* + * 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 org.eclipse.jdt.internal.formatter; + +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.formatter.CodeFormatter; + +/** + * Strategy interface used by {@link ExtendedCodeFormatter} to allow additional code + * formatting before wrapping. + * + * @author Phillip Webb + */ +public interface Preparator { + + default Phase getPhase() { + return Phase.POST_WRAPPING; + } + + /** + * Apply the preparator. + * @param kind the format kind (see + * {@link CodeFormatter#format(int, String, org.eclipse.jface.text.IRegion[], int, String)} + * for details) + * @param tokenManager the token manager + * @param astRoot the AST root node + */ + void apply(int kind, TokenManager tokenManager, ASTNode astRoot); + + /** + * The phase where the {@link Preparator} should be applied. + */ + enum Phase { + + /** + * Apply the preparator before wrapping. + */ + PRE_WRAPPING, + + /** + * Apply the preparator after 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 arguments, int wrappingOption) { + this.wrapPenalties.add(1 / PREFERRED); + prepareElementsList(arguments, TokenNameCOMMA, TokenNameLPAREN); + handleWrap(wrappingOption); + } + + private void handleAnnotations(List 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 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 2e7c1713..9be11ea0 100644 --- a/spring-javaformat/spring-javaformat-formatter-eclipse-rewriter/pom.xml +++ b/spring-javaformat/spring-javaformat-formatter-eclipse-rewriter/pom.xml @@ -1,11 +1,11 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat spring-javaformat - 0.0.7-SNAPSHOT + 0.0.48-SNAPSHOT spring-javaformat-formatter-eclipse-rewriter Spring 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 41586fb7..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -24,12 +24,17 @@ import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.function.Function; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; @@ -40,48 +45,87 @@ */ public final class EclipseRewriter { + private static final Set UPDATED_METHODS; + static { + Set updatedMethods = new LinkedHashSet(); + updatedMethods.add("prepareWraps"); + updatedMethods.add("tokenizeSource"); + UPDATED_METHODS = Collections.unmodifiableSet(updatedMethods); + } + + private static final Set UPDATED_FIELDS; + static { + Set updatedFields = new LinkedHashSet(); + updatedFields.add("sourceLevel"); + updatedFields.add("tokens"); + UPDATED_FIELDS = Collections.unmodifiableSet(updatedFields); + } + private EclipseRewriter() { } - public void rewrite(String file) throws IOException { + public void rewrite(JdkVersion jdkVersion, String file) throws IOException { System.out.println("Rewriting classes in " + file); - URI uri = URI.create("jar:file:" + file); - try (FileSystem zip = FileSystems.newFileSystem(uri, - Collections.singletonMap("create", "true"))) { - rewrite(zip); + URI uri = URI.create("jar:file:" + Paths.get(file).toUri().getPath()); + try (FileSystem zip = FileSystems.newFileSystem(uri, Collections.singletonMap("create", "true"))) { + rewrite(jdkVersion, zip); + } + } + + private void rewrite(JdkVersion jdkVersion, FileSystem zip) throws IOException { + rewrite(zip, "org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.class", + 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", NlsJdk17Manipulator::new); } } - private void rewrite(FileSystem zip) throws IOException { - Path path = zip - .getPath("org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.class"); - ClassWriter writer = new ClassWriter(0); + private void rewrite(FileSystem zip, String name, Function manipulator) + throws IOException { + ClassWriter classWriter = new ClassWriter(0); + Path path = zip.getPath(name); try (InputStream in = Files.newInputStream(path)) { - DefaultCodeFormatterManipulator manipulator = new DefaultCodeFormatterManipulator( - writer); ClassReader reader = new ClassReader(in); - reader.accept(manipulator, 0); + reader.accept(manipulator.apply(classWriter), 0); } - Files.copy(new ByteArrayInputStream(writer.toByteArray()), path, - StandardCopyOption.REPLACE_EXISTING); + Files.copy(new ByteArrayInputStream(classWriter.toByteArray()), path, StandardCopyOption.REPLACE_EXISTING); + } + + private void deleteWrapPreparator(FileSystem zip) throws IOException { + Path path = zip.getPath("org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.class"); + Files.delete(path); } public static void main(String[] args) throws Exception { - new EclipseRewriter().rewrite(args[0]); + new EclipseRewriter().rewrite(JdkVersion.valueOf("V" + args[0]), args[1]); } + /** + * {@link ClassVisitor} to make some fields and methods from + * {@code DefaultCodeFormatter} public. + */ private static class DefaultCodeFormatterManipulator extends ClassVisitor { DefaultCodeFormatterManipulator(ClassVisitor visitor) { - super(Opcodes.ASM5, visitor); + super(Opcodes.ASM9, visitor); + } + + @Override + public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { + if ((access & Opcodes.ACC_PRIVATE) != 0 && UPDATED_FIELDS.contains(name)) { + access = Opcodes.ACC_PROTECTED; + } + return super.visitField(access, name, desc, signature, value); } @Override - public MethodVisitor visitMethod(int access, String name, String desc, - String signature, String[] exceptions) { - if ("prepareWraps".equals(name) && Opcodes.ACC_PRIVATE == access) { - return super.visitMethod(Opcodes.ACC_PROTECTED, name, desc, signature, - exceptions); + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + if ((access & Opcodes.ACC_PRIVATE) != 0 && UPDATED_METHODS.contains(name)) { + access = Opcodes.ACC_PROTECTED; } return new DefaultCodeFormatterMethodManipulator( super.visitMethod(access, name, desc, signature, exceptions)); @@ -89,22 +133,129 @@ public MethodVisitor visitMethod(int access, String name, String desc, } + /** + * {@link MethodVisitor} to make some fields and methods from + * {@code DefaultCodeFormatter} public. + */ private static class DefaultCodeFormatterMethodManipulator extends MethodVisitor { DefaultCodeFormatterMethodManipulator(MethodVisitor mv) { - super(Opcodes.ASM5, mv); + super(Opcodes.ASM9, mv); } @Override - public void visitMethodInsn(int opcode, String owner, String name, String desc, - boolean itf) { - if ("prepareWraps".equals(name) && opcode == Opcodes.INVOKESPECIAL) { - super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, name, desc, itf); - return; + public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { + if (opcode == Opcodes.INVOKESPECIAL && UPDATED_METHODS.contains(name)) { + opcode = Opcodes.INVOKEVIRTUAL; } super.visitMethodInsn(opcode, owner, name, desc, itf); } } + /** + * {@link ClassVisitor} 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 NlsJdk8Manipulator extends ClassVisitor { + + NlsJdk8Manipulator(ClassVisitor visitor) { + super(Opcodes.ASM9, visitor); + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + if ("run".equals(name) && desc.contains("Boolean")) { + return new NslJdk8MethodManipulator(super.visitMethod(access, name, desc, signature, exceptions)); + } + return super.visitMethod(access, name, desc, signature, exceptions); + } + + } + + /** + * {@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 NslJdk8MethodManipulator extends MethodVisitor { + + private final MethodVisitor methodVisitor; + + NslJdk8MethodManipulator(MethodVisitor mv) { + super(Opcodes.ASM9, null); + this.methodVisitor = mv; + } + + @Override + public void visitEnd() { + MethodVisitor mv = this.methodVisitor; + mv.visitCode(); + mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Boolean", "TRUE", "Ljava/lang/Boolean;"); + mv.visitInsn(Opcodes.ARETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + } + + } + + /** + * {@link ClassVisitor} 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 NlsJdk17Manipulator extends ClassVisitor { + + NlsJdk17Manipulator(ClassVisitor visitor) { + super(Opcodes.ASM9, visitor); + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + if ("".equals(name)) { + return new NslJdk17MethodManipulator(super.visitMethod(access, name, desc, signature, exceptions)); + } + return super.visitMethod(access, name, desc, signature, exceptions); + } + + } + + /** + * {@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 NslJdk17MethodManipulator extends MethodVisitor { + + private final MethodVisitor methodVisitor; + + NslJdk17MethodManipulator(MethodVisitor mv) { + super(Opcodes.ASM9, null); + this.methodVisitor = mv; + } + + @Override + public void visitEnd() { + MethodVisitor mv = this.methodVisitor; + mv.visitCode(); + mv.visitInsn(Opcodes.ICONST_0); + mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object"); + mv.visitFieldInsn(Opcodes.PUTSTATIC, "org/eclipse/osgi/util/NLS", "EMPTY_ARGS", "[Ljava/lang/Object;"); + mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Boolean", "TRUE", "Ljava/lang/Boolean;"); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false); + mv.visitFieldInsn(Opcodes.PUTSTATIC, "org/eclipse/osgi/util/NLS", "ignoreWarnings", "Z"); + mv.visitTypeInsn(Opcodes.NEW, "java/lang/Object"); + mv.visitInsn(Opcodes.DUP); + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "", "()V", false); + mv.visitFieldInsn(Opcodes.PUTSTATIC, "org/eclipse/osgi/util/NLS", "ASSIGNED", "Ljava/lang/Object;"); + mv.visitInsn(Opcodes.RETURN); + mv.visitMaxs(2, 0); + mv.visitEnd(); + } + + } + + enum JdkVersion { + + V8, V11 + + } + } diff --git a/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/pom.xml b/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/pom.xml index a9042a0e..dab30621 100644 --- a/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/pom.xml +++ b/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/pom.xml @@ -1,189 +1,84 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat spring-javaformat - 0.0.7-SNAPSHOT + 0.0.48-SNAPSHOT spring-javaformat-formatter-eclipse-runtime - eclipse-plugin Spring JavaFormat Eclipse Runtime ${basedir}/../.. - org.eclipse.jdt.core.source,org.eclipse.jface.source,org.eclipse.text.source - - - Eclipse Public License, Version 1.0 - https://www.eclipse.org/legal/epl-v10.html - - + + + io.spring.javaformat + spring-javaformat-formatter-eclipse-jdk8 + ${project.version} + true + + + org.apache.maven.plugins - maven-antrun-plugin - - - io.spring.javaformat - spring-javaformat-formatter-eclipse-rewriter - ${project.version} - - - ant-contrib - ant-contrib - ${ant-contrib.version} - - - ant - ant - - - - - org.apache.ant - ant-nodeps - ${ant.version} - - + maven-jar-plugin - rewrite-bytecode - package - - run - - - - - - - - - - - repackage-source + empty-javadoc-jar package - run + jar - - - - + javadoc - - org.eclipse.tycho - tycho-packaging-plugin - - false - - - - org.eclipse.tycho - tycho-maven-plugin - - - org.eclipse.tycho - target-platform-configuration - - - org.eclipse.tycho - tycho-versions-plugin - - - update-eclipse-version - initialize - - update-eclipse-metadata - - - - org.apache.maven.plugins - maven-dependency-plugin + maven-source-plugin - unpack-dependencies - - unpack-dependencies - - prepare-package - - ${project.build.outputDirectory} - META-INF/*,**.dll,**.so,**.java - ${sourceartifacts} - - - - unpack-source-dependencies + attach-source + package - unpack-dependencies + jar - prepare-package - - ${project.build.directory}/sources - ${sourceartifacts} - - com.github.wvengen - proguard-maven-plugin + org.apache.maven.plugins + maven-shade-plugin - reduce-eclipse-runtime package - proguard + shade - false - - ${java.home}/lib/rt.jar - ${java.home}/lib/jsse.jar - - - - - - - - - - - - - - + + + io.spring.javaformat:spring-javaformat-formatter-eclipse-jdk8 + + org/eclipse/jdt/** + META-INF/ECLIPSE_.SF + META-INF/ECLIPSE_.RSA + + + + false + true + true - - - io.spring.javaformat - spring-javaformat-formatter-eclipse-rewriter - ${project.version} - provided - - 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 new file mode 100644 index 00000000..78e9cd52 --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/src/main/java/org/eclipse/core/runtime/content/IContentTypeManager$ContentTypeChangeEvent.java @@ -0,0 +1,21 @@ +/* + * 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 org.eclipse.core.runtime.content; + +public class IContentTypeManager$ContentTypeChangeEvent { + +} 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 new file mode 100644 index 00000000..6458ef5a --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-eclipse-runtime/src/main/java/org/eclipse/core/runtime/content/IContentTypeManager$IContentTypeChangeListener.java @@ -0,0 +1,23 @@ +/* + * 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 org.eclipse.core.runtime.content; + +public interface IContentTypeManager$IContentTypeChangeListener { + + void contentTypeChanged(IContentTypeManager$ContentTypeChangeEvent event); + +} diff --git a/spring-javaformat/spring-javaformat-formatter-shaded/pom.xml b/spring-javaformat/spring-javaformat-formatter-shaded/pom.xml new file mode 100644 index 00000000..330f53c9 --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-shaded/pom.xml @@ -0,0 +1,124 @@ + + + 4.0.0 + + io.spring.javaformat + spring-javaformat + 0.0.48-SNAPSHOT + + spring-javaformat-formatter-shaded + Spring JavaFormat Formatter Shaded + + ${basedir}/../.. + + + + + org.apache.maven.plugins + maven-jar-plugin + + + empty-javadoc-jar + package + + jar + + + javadoc + + + + + + org.codehaus.mojo + flatten-maven-plugin + + true + oss + + expand + remove + remove + remove + + + + + org.apache.maven.plugins + maven-shade-plugin + + + ${project.groupId} + spring-javaformat-formatter-shader + ${project.version} + + + + true + true + false + + + io.spring.javaformat:* + + + + + org.eclipse + io.spring.javaformat.org.eclipse + + + com.ibm + io.spring.javaformat.com.ibm + + + org.osgi + io.spring.javaformat.org.osgi + + + + + + + ${project.version} + + + + + + + package + + shade + + + + + + + + + io.spring.javaformat + spring-javaformat-config + ${project.version} + + + io.spring.javaformat + spring-javaformat-formatter + ${project.version} + + + io.spring.javaformat + spring-javaformat-formatter-eclipse-runtime + ${project.version} + + + * + * + + + + + diff --git a/spring-javaformat/spring-javaformat-formatter-shader/pom.xml b/spring-javaformat/spring-javaformat-formatter-shader/pom.xml new file mode 100644 index 00000000..a07cf239 --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-shader/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + + io.spring.javaformat + spring-javaformat + 0.0.48-SNAPSHOT + + spring-javaformat-formatter-shader + Spring JavaFormat Formatter Shader + + ${basedir}/../.. + + + + org.apache.maven.plugins + maven-shade-plugin + 3.1.0 + maven-plugin + + + 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 new file mode 100644 index 00000000..09882163 --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-shader/src/main/java/io/spring/javaformat/formatter/shader/PrefsResourceTransformer.java @@ -0,0 +1,102 @@ +/* + * 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.shader; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; + +import org.apache.maven.plugins.shade.relocation.Relocator; +import org.apache.maven.plugins.shade.resource.ResourceTransformer; + +/** + * {@link ResourceTransformer} to fix formatter preference files. + * + * @author Phillip Webb + */ +public class PrefsResourceTransformer implements ResourceTransformer { + + private final Map> transformedResources = new LinkedHashMap<>(); + + @Override + public boolean canTransformResource(String resource) { + return resource.endsWith("formatter.prefs"); + } + + @Override + public void processResource(String resource, InputStream is, List relocators) throws IOException { + List trandformedLines = new ArrayList<>(); + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + String line = reader.readLine(); + while (line != null) { + trandformedLines.add(transformLine(line, relocators)); + line = reader.readLine(); + } + this.transformedResources.put(resource, trandformedLines); + } + + private String transformLine(String line, List relocators) { + int splitIndex = line.lastIndexOf('='); + if (splitIndex == -1) { + return line; + } + String key = line.substring(0, splitIndex); + String value = line.substring(splitIndex + 1); + return relocateKey(key, relocators) + "=" + value; + } + + private String relocateKey(String key, List relocators) { + for (Relocator relocator : relocators) { + if (relocator.canRelocateClass(key)) { + return relocator.relocateClass(key); + } + } + return key; + } + + @Override + public boolean hasTransformedResource() { + return true; + } + + @Override + public void modifyOutputStream(JarOutputStream os) throws IOException { + for (Map.Entry> entry : this.transformedResources.entrySet()) { + write(os, entry.getKey(), entry.getValue()); + } + } + + private void write(JarOutputStream os, String resource, List lines) throws IOException { + os.putNextEntry(new JarEntry(resource)); + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os)); + for (String line : lines) { + writer.write(line); + writer.write("\n"); + } + writer.flush(); + } + +} diff --git a/spring-javaformat/spring-javaformat-formatter-test-support/pom.xml b/spring-javaformat/spring-javaformat-formatter-test-support/pom.xml new file mode 100644 index 00000000..1f72a67a --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-test-support/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + + io.spring.javaformat + spring-javaformat + 0.0.48-SNAPSHOT + + spring-javaformat-formatter-test-support + Spring JavaFormat Formatter Test Support + + ${basedir}/../.. + + + + + io.spring.javaformat + spring-javaformat-formatter + ${project.version} + + + + io.spring.javaformat + spring-javaformat-formatter-eclipse-runtime + ${project.version} + provided + + + 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 new file mode 100644 index 00000000..ca679983 --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-test-support/src/main/java/io/spring/javaformat/formatter/FormatterApp.java @@ -0,0 +1,49 @@ +/* + * 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 org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; +import org.eclipse.text.edits.TextEdit; + +import io.spring.javaformat.config.IndentationStyle; +import io.spring.javaformat.config.JavaBaseline; +import io.spring.javaformat.config.JavaFormatConfig; + +/** + * Test app used to format something in a test container. + * + * @author Phillip Webb + */ +public final class FormatterApp { + + private FormatterApp() { + } + + public static void main(String[] args) throws Exception, BadLocationException { + JavaBaseline javaBaseline = JavaBaseline.valueOf(args[0]); + Formatter formatter = new Formatter(JavaFormatConfig.of(javaBaseline, IndentationStyle.TABS)); + String source = "public class Test {}"; + TextEdit edit = formatter.format(source); + IDocument document = new Document(source); + edit.apply(document); + String formatted = document.get(); + System.out.println(formatted); + } + +} diff --git a/spring-javaformat/spring-javaformat-formatter-tests/pom.xml b/spring-javaformat/spring-javaformat-formatter-tests/pom.xml new file mode 100644 index 00000000..30ea6a7e --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-tests/pom.xml @@ -0,0 +1,64 @@ + + + 4.0.0 + + io.spring.javaformat + spring-javaformat + 0.0.48-SNAPSHOT + + spring-javaformat-formatter-tests + Spring JavaFormat Formatter Tests + + ${basedir}/../.. + 17 + + + + + io.spring.javaformat + spring-javaformat-formatter + ${project.version} + + + + io.spring.javaformat + spring-javaformat-formatter-eclipse-runtime + ${project.version} + provided + + + + io.spring.javaformat + spring-javaformat-formatter-test-support + ${project.version} + test + + + org.apache.logging.log4j + log4j-api + test + + + org.apache.logging.log4j + log4j-core + test + + + org.apache.logging.log4j + log4j-slf4j-impl + test + + + org.testcontainers + testcontainers + test + + + org.testcontainers + junit-jupiter + test + + + 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 new file mode 100644 index 00000000..1af21b70 --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/AbstractFormatterTests.java @@ -0,0 +1,167 @@ +/* + * 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.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +import io.spring.javaformat.config.JavaBaseline; +import io.spring.javaformat.config.JavaFormatConfig; + +/** + * Base class for formatter tests. + * + * @author Phillip Webb + */ +public abstract class AbstractFormatterTests { + + protected final void print(String name, String content) { + System.out.println(name + ":"); + System.out.println(); + System.out.println("----------------------------------------"); + System.out.println(content); + System.out.println("----------------------------------------"); + System.out.println(); + System.out.println(); + } + + protected final String read(File file) throws Exception { + return new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8); + } + + protected static Item[] items(String expectedOverride) { + 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 config = new File(configDir, source.getName()); + for (JavaBaseline javaBaseline : JavaBaseline.values()) { + 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; + + private final File source; + + private final File expected; + + private final JavaFormatConfig config; + + Item(JavaBaseline javaBaseline, File source, File expected, File config) { + this.javaBaseline = javaBaseline; + this.source = source; + this.expected = expected; + this.config = loadConfig(javaBaseline, config); + } + + private JavaFormatConfig loadConfig(JavaBaseline javaBaseline, File configFile) { + JavaFormatConfig config = (!configFile.exists()) ? JavaFormatConfig.DEFAULT + : JavaFormatConfig.load(configFile); + return JavaFormatConfig.of(javaBaseline, config.getIndentationStyle()); + } + + String getName() { + return this.source.getName(); + } + + public File getSource() { + return this.source; + } + + public File getExpected() { + return this.expected; + } + + public JavaFormatConfig getConfig() { + return this.config; + } + + @Override + public String toString() { + return this.javaBaseline + " " + this.source.getName(); + } + + } + +} diff --git a/spring-javaformat/spring-javaformat-formatter/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 similarity index 70% rename from spring-javaformat/spring-javaformat-formatter/src/test/java/io/spring/javaformat/formatter/FileEditTests.java rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/FileEditTests.java index ac53f345..015b9eb7 100644 --- a/spring-javaformat/spring-javaformat-formatter/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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -24,10 +24,9 @@ import java.nio.file.StandardCopyOption; import org.eclipse.text.edits.TextEdit; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; +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; @@ -40,8 +39,8 @@ public class FileEditTests { private static final Charset UTF_8 = StandardCharsets.UTF_8; - @Rule - public TemporaryFolder temp = new TemporaryFolder(); + @TempDir + public File temp; private File source; @@ -51,31 +50,31 @@ public class FileEditTests { private FileEdit fileEdit; - @Before - public void setup() throws IOException { - this.source = this.temp.newFile("source.txt"); - this.expected = this.temp.newFile("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); + @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.fileEdit = new FileEdit(this.source, UTF_8, content, this.textEdit); } @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); @@ -83,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(); @@ -91,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 new file mode 100644 index 00000000..f9d14f7c --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/FileFormatterTests.java @@ -0,0 +1,79 @@ +/* + * 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.File; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link FileFormatter}. + * + * @author Phillip Webb + */ +public class FileFormatterTests extends AbstractFormatterTests { + + private static final boolean RUNNING_ON_WINDOWS = System.getProperty("os.name").toLowerCase().contains("win"); + + @ParameterizedTest + @MethodSource("items") + void formatFilesFromIteratorFormatsFile(Item item) throws Exception { + FileEdit edit = new FileFormatter(item.getConfig()) + .formatFiles(Arrays.asList(item.getSource()), StandardCharsets.UTF_8) + .findFirst() + .get(); + assertThat(edit.getFormattedContent()).isEqualTo(read(item.getExpected())); + } + + @ParameterizedTest + @MethodSource("items") + void formatFilesFromStreamFormatsFile(Item item) throws Exception { + FileEdit edit = new FileFormatter(item.getConfig()) + .formatFiles(Arrays.asList(item.getSource()).stream(), StandardCharsets.UTF_8) + .findFirst() + .get(); + assertThat(edit.getFormattedContent()).isEqualTo(read(item.getExpected())); + } + + @ParameterizedTest + @MethodSource("items") + 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(); + String expected = read(item.getExpected()); + if (!RUNNING_ON_WINDOWS) { + System.out.println(source); + System.out.println("----- got"); + System.out.println(formattedContent); + System.out.println("----- expected"); + System.out.println(expected); + System.out.println("-----"); + } + assertThat(formattedContent).isEqualTo(expected); + } + + 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 new file mode 100644 index 00000000..383b07cd --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/FormatterIntegrationTests.java @@ -0,0 +1,130 @@ +/* + * 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.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.testcontainers.containers.ContainerLaunchException; +import org.testcontainers.containers.output.ToStringConsumer; +import org.testcontainers.containers.startupcheck.OneShotStartupCheckStrategy; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.MountableFile; + +import io.spring.javaformat.config.JavaBaseline; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +/** + * Tests to ensure the formatter can run in different JVM versions. + * + * @author Phillip Webb + */ +@Testcontainers(disabledWithoutDocker = true) +public class FormatterIntegrationTests { + + @ParameterizedTest + @ValueSource(strings = { "8", "11", "17" }) + void formatCodeWithV8BaselineCanFormatOnAllVersions(String version) throws Exception { + runFormatter(JavaBaseline.V8, version); + } + + @ParameterizedTest + @ValueSource(strings = { "17" }) + void formatCodeWithV11BaselineCanFormatOn11OrHigher(String version) throws Exception { + runFormatter(JavaBaseline.V17, version); + } + + @ParameterizedTest + @ValueSource(strings = "8") + void formatCodeWithV11BaselineCannotFormatOn8(String version) throws Exception { + assertThatExceptionOfType(ContainerLaunchException.class) + .isThrownBy(() -> runFormatter(JavaBaseline.V17, version)); + } + + private void runFormatter(JavaBaseline baseline, String version) throws IOException, Exception { + try (JavaContainer container = new JavaContainer(version)) { + ToStringConsumer output = new ToStringConsumer(); + container.withStartupCheckStrategy(new OneShotStartupCheckStrategy().withTimeout(Duration.ofMinutes(5))); + container.withLogConsumer(output); + String classpath = withCopyClasspathToContainer(container); + container.withCommand( + "java -cp " + classpath + " " + "io.spring.javaformat.formatter.FormatterApp" + " " + baseline); + container.start(); + assertThat(output.toUtf8String()).isEqualTo("public class Test {\n\n}\n"); + } + } + + private String withCopyClasspathToContainer(JavaContainer container) throws IOException { + List classpath = new ArrayList<>(); + for (String entry : System.getProperty("java.class.path").split(File.pathSeparator)) { + if (entry.contains("spring-javaformat")) { + String classpathEntry = withCopyClasspathEntryToContainer(container, entry); + if (classpathEntry != null) { + classpath.add(classpathEntry); + } + } + } + return classpath.stream().collect(Collectors.joining(":")); + } + + private String withCopyClasspathEntryToContainer(JavaContainer container, String entry) throws IOException { + if (entry.endsWith(".jar")) { + return withCopyClasspathJarToContainer(container, new File(entry)); + } + return withCopyClasspathFolderToContainer(container, new File(entry)); + } + + private String withCopyClasspathJarToContainer(JavaContainer container, File jarFile) { + container.withCopyFileToContainer(MountableFile.forHostPath(jarFile.toPath()), "/app/" + jarFile.getName()); + return "/app/" + jarFile.getName(); + } + + private String withCopyClasspathFolderToContainer(JavaContainer container, File classesFolder) throws IOException { + String name = classesFolder.getName(); + Path source = classesFolder.toPath(); + if (!Files.exists(source)) { + return null; + } + try (Stream stream = Files.walk(source)) { + stream.forEach((child) -> { + try { + Path relative = source.relativize(child); + if (!child.toFile().isDirectory()) { + String containerPath = "/app/" + name + "/" + relative; + container.withCopyFileToContainer(MountableFile.forHostPath(child), containerPath); + } + } + catch (Exception ex) { + throw new IllegalStateException(ex); + } + }); + } + return "/app/" + name; + } + +} diff --git a/spring-javaformat/spring-javaformat-formatter/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 similarity index 50% rename from spring-javaformat/spring-javaformat-formatter/src/test/java/io/spring/javaformat/formatter/FormatterTests.java rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/FormatterTests.java index 7c4cdfa7..cc1c8b50 100644 --- a/spring-javaformat/spring-javaformat-formatter/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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -16,14 +16,13 @@ package io.spring.javaformat.formatter; -import java.io.File; -import java.util.Collection; - import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.text.edits.TextEdit; -import org.junit.Test; -import org.junit.runners.Parameterized.Parameters; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import io.spring.javaformat.config.JavaFormatConfig; import static org.assertj.core.api.Assertions.assertThat; @@ -32,37 +31,32 @@ */ public class FormatterTests extends AbstractFormatterTests { - public FormatterTests(File source, File expected) { - super(source, expected); - } - - @Test - public void format() throws Exception { - String sourceContent = read(getSource()); - String expectedContent = read(getExpected()); - String formattedContent = format(sourceContent); + @ParameterizedTest + @MethodSource("items") + void format(Item item) throws Exception { + String sourceContent = read(item.getSource()); + String expectedContent = read(item.getExpected()); + String formattedContent = format(item.getConfig(), sourceContent); if (!expectedContent.equals(formattedContent)) { - System.out.println( - "Formatted " + getSource() + " does not match " + getExpected()); - print("Source " + getSource(), sourceContent); - print("Expected +" + getExpected(), expectedContent); + System.out.println("Formatted " + item.getSource() + " does not match " + item.getExpected()); + print("Source " + item.getSource(), sourceContent); + print("Expected +" + item.getExpected(), expectedContent); print("Got", formattedContent); System.out.println("========================================"); - assertThat(expectedContent).isEqualTo(formattedContent) - .describedAs("Formatted content does not match for " + getSource()); + assertThat(formattedContent).isEqualTo(expectedContent) + .describedAs("Formatted content does not match for " + item.getSource()); } } - private String format(String sourceContent) throws Exception { + private String format(JavaFormatConfig config, String sourceContent) throws Exception { IDocument document = new Document(sourceContent); - TextEdit textEdit = new Formatter().format(sourceContent); + TextEdit textEdit = new Formatter(config).format(sourceContent); textEdit.apply(document); return document.get(); } - @Parameters(name = "{0}") - public static Collection files() { - return AbstractFormatterTests.files("FormatterTests-expected"); + 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 new file mode 100644 index 00000000..8f847bbb --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/java/io/spring/javaformat/formatter/JavaContainer.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. + */ + +package io.spring.javaformat.formatter; + +import org.testcontainers.containers.GenericContainer; + +/** + * {@link GenericContainer} for Java. + * + * @author Phillip Webb + */ +public class JavaContainer extends GenericContainer { + + 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/bin/src/test/resources/expected/javadoc-top-add.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/FormatterTests-expected/javadoc-top-add.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/javadoc-top-add.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/FormatterTests-expected/javadoc-top-add.txt 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/src/test/resources/source/simple.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/FormatterTests-expected/simple.txt similarity index 97% rename from spring-javaformat/spring-javaformat-formatter/src/test/resources/source/simple.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/FormatterTests-expected/simple.txt index a12ac39e..63ca9a5c 100644 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/simple.txt +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/FormatterTests-expected/simple.txt @@ -2,7 +2,7 @@ package simple; /** * Simple. - * + * * @author Phillip Webb * @since 1.0.0 */ diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/config/spaces.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/config/spaces.txt new file mode 100644 index 00000000..2588c596 --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/config/spaces.txt @@ -0,0 +1 @@ +indentation-style=spaces \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/annotation-attributes.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/annotation-attributes.txt new file mode 100644 index 00000000..7dc4da2d --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/annotation-attributes.txt @@ -0,0 +1,15 @@ +class MyTest { + + @SpringBootTest(properties = "spring.main.web-application-type=reactive", classes = { + WebTestClientSpringBootTestIntegrationTests.TestConfiguration.class, ExampleWebFluxApplication.class }) + static class One { + + } + + @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = { "spring.jersey.type=filter", + "server.servlet.context-path=/app", "server.servlet.register-default-servlet=true" }) + static class Two { + + } + +} \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/complex-annotation-gh-78.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/complex-annotation-gh-78.txt new file mode 100644 index 00000000..f6b0421d --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/complex-annotation-gh-78.txt @@ -0,0 +1,9 @@ +package sample; + +import sample.SpringBootTest.WebEnvironment; + +@SpringBootTest(classes = RibbonClientConfigurationIntegrationTests.TestLBConfig.class, + properties = "test.ribbon.ServerListRefreshInterval=999") +public class SampleApplication { + +} diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/complex-annotation.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/complex-annotation.txt new file mode 100644 index 00000000..3d055ddf --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/complex-annotation.txt @@ -0,0 +1,9 @@ +package sample; + +import sample.SpringBootTest.WebEnvironment; + +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = { "management.server.port=0", + "management.server.address=127.0.0.1", "management.server.servlet.context-path:/admin" }) +public class SampleApplication { + +} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/complex.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/complex.txt similarity index 91% rename from spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/complex.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/complex.txt index b66b83f8..a874b5bd 100644 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/complex.txt +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/complex.txt @@ -1,11 +1,11 @@ /* - * Copyright 2012-2016 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -256,8 +256,7 @@ public class SpringApplication { this.sources.addAll(Arrays.asList(sources)); } this.webEnvironment = deduceWebEnvironment(); - setInitializers((Collection) getSpringFactoriesInstances( - ApplicationContextInitializer.class)); + setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)); setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass = deduceMainApplicationClass(); } @@ -301,22 +300,18 @@ public class SpringApplication { SpringApplicationRunListeners listeners = getRunListeners(args); listeners.starting(); try { - ApplicationArguments applicationArguments = new DefaultApplicationArguments( - args); - ConfigurableEnvironment environment = prepareEnvironment(listeners, - applicationArguments); + ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); + ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); Banner printedBanner = printBanner(environment); context = createApplicationContext(); analyzers = new FailureAnalyzers(context); - prepareContext(context, environment, listeners, applicationArguments, - printedBanner); + prepareContext(context, environment, listeners, applicationArguments, printedBanner); refreshContext(context); afterRefresh(context, applicationArguments); listeners.finished(context, null); stopWatch.stop(); if (this.logStartupInfo) { - new StartupInfoLogger(this.mainApplicationClass) - .logStarted(getApplicationLog(), stopWatch); + new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch); } return context; } @@ -326,8 +321,7 @@ public class SpringApplication { } } - private ConfigurableEnvironment prepareEnvironment( - SpringApplicationRunListeners listeners, + private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) { // Create and configure the environment ConfigurableEnvironment environment = getOrCreateEnvironment(); @@ -339,9 +333,8 @@ public class SpringApplication { return environment; } - private void prepareContext(ConfigurableApplicationContext context, - ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, - ApplicationArguments applicationArguments, Banner printedBanner) { + private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, + SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) { context.setEnvironment(environment); postProcessApplicationContext(context); applyInitializers(context); @@ -352,8 +345,7 @@ public class SpringApplication { } // Add boot specific singleton beans - context.getBeanFactory().registerSingleton("springApplicationArguments", - applicationArguments); + context.getBeanFactory().registerSingleton("springApplicationArguments", applicationArguments); if (printedBanner != null) { context.getBeanFactory().registerSingleton("springBootBanner", printedBanner); } @@ -378,49 +370,44 @@ public class SpringApplication { } private void configureHeadlessProperty() { - System.setProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, System.getProperty( - SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, Boolean.toString(this.headless))); + System.setProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, + System.getProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, Boolean.toString(this.headless))); } private SpringApplicationRunListeners getRunListeners(String[] args) { Class[] types = new Class[] { SpringApplication.class, String[].class }; - return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances( - SpringApplicationRunListener.class, types, this, args)); + return new SpringApplicationRunListeners(logger, + getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args)); } private Collection getSpringFactoriesInstances(Class type) { return getSpringFactoriesInstances(type, new Class[] {}); } - private Collection getSpringFactoriesInstances(Class type, - Class[] parameterTypes, Object... args) { + private Collection getSpringFactoriesInstances(Class type, Class[] parameterTypes, + Object... args) { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // Use names and ensure unique to protect against duplicates - Set names = new LinkedHashSet( - SpringFactoriesLoader.loadFactoryNames(type, classLoader)); - List instances = createSpringFactoriesInstances(type, parameterTypes, - classLoader, args, names); + Set names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader)); + List instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names); AnnotationAwareOrderComparator.sort(instances); return instances; } @SuppressWarnings("unchecked") - private List createSpringFactoriesInstances(Class type, - Class[] parameterTypes, ClassLoader classLoader, Object[] args, - Set names) { + private List createSpringFactoriesInstances(Class type, Class[] parameterTypes, + ClassLoader classLoader, Object[] args, Set names) { List instances = new ArrayList(names.size()); for (String name : names) { try { Class instanceClass = ClassUtils.forName(name, classLoader); Assert.isAssignable(type, instanceClass); - Constructor constructor = instanceClass - .getDeclaredConstructor(parameterTypes); + Constructor constructor = instanceClass.getDeclaredConstructor(parameterTypes); T instance = (T) BeanUtils.instantiateClass(constructor, args); instances.add(instance); } catch (Throwable ex) { - throw new IllegalArgumentException( - "Cannot instantiate " + type + " : " + name, ex); + throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, ex); } } return instances; @@ -447,16 +434,14 @@ public class SpringApplication { * @see #configureProfiles(ConfigurableEnvironment, String[]) * @see #configurePropertySources(ConfigurableEnvironment, String[]) */ - protected void configureEnvironment(ConfigurableEnvironment environment, - String[] args) { + protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) { configurePropertySources(environment, args); configureProfiles(environment, args); } private boolean isWebEnvironment(ConfigurableEnvironment environment) { try { - Class webEnvironmentClass = ClassUtils - .forName(CONFIGURABLE_WEB_ENVIRONMENT_CLASS, getClassLoader()); + Class webEnvironmentClass = ClassUtils.forName(CONFIGURABLE_WEB_ENVIRONMENT_CLASS, getClassLoader()); return (webEnvironmentClass.isInstance(environment)); } catch (Throwable ex) { @@ -464,8 +449,7 @@ public class SpringApplication { } } - private ConfigurableEnvironment convertToStandardEnvironment( - ConfigurableEnvironment environment) { + private ConfigurableEnvironment convertToStandardEnvironment(ConfigurableEnvironment environment) { StandardEnvironment result = new StandardEnvironment(); removeAllPropertySources(result.getPropertySources()); result.setActiveProfiles(environment.getActiveProfiles()); @@ -494,20 +478,17 @@ public class SpringApplication { * @param args arguments passed to the {@code run} method * @see #configureEnvironment(ConfigurableEnvironment, String[]) */ - protected void configurePropertySources(ConfigurableEnvironment environment, - String[] args) { + protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) { MutablePropertySources sources = environment.getPropertySources(); if (this.defaultProperties != null && !this.defaultProperties.isEmpty()) { - sources.addLast( - new MapPropertySource("defaultProperties", this.defaultProperties)); + sources.addLast(new MapPropertySource("defaultProperties", this.defaultProperties)); } if (this.addCommandLineProperties && args.length > 0) { String name = CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME; if (sources.contains(name)) { PropertySource source = sources.get(name); CompositePropertySource composite = new CompositePropertySource(name); - composite.addPropertySource(new SimpleCommandLinePropertySource( - name + "-" + args.hashCode(), args)); + composite.addPropertySource(new SimpleCommandLinePropertySource(name + "-" + args.hashCode(), args)); composite.addPropertySource(source); sources.replace(name, composite); } @@ -540,8 +521,7 @@ public class SpringApplication { } ResourceLoader resourceLoader = this.resourceLoader != null ? this.resourceLoader : new DefaultResourceLoader(getClassLoader()); - SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter( - resourceLoader, this.banner); + SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter(resourceLoader, this.banner); if (this.bannerMode == Mode.LOG) { return bannerPrinter.print(environment, this.mainApplicationClass, logger); } @@ -559,13 +539,11 @@ public class SpringApplication { Class contextClass = this.applicationContextClass; if (contextClass == null) { try { - contextClass = Class.forName(this.webEnvironment - ? DEFAULT_WEB_CONTEXT_CLASS : DEFAULT_CONTEXT_CLASS); + contextClass = Class.forName(this.webEnvironment ? DEFAULT_WEB_CONTEXT_CLASS : DEFAULT_CONTEXT_CLASS); } catch (ClassNotFoundException ex) { throw new IllegalStateException( - "Unable create a default ApplicationContext, " - + "please specify an ApplicationContextClass", + "Unable create a default ApplicationContext, " + "please specify an ApplicationContextClass", ex); } } @@ -579,18 +557,15 @@ 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) { - ((GenericApplicationContext) context) - .setResourceLoader(this.resourceLoader); + ((GenericApplicationContext) context).setResourceLoader(this.resourceLoader); } if (context instanceof DefaultResourceLoader) { - ((DefaultResourceLoader) context) - .setClassLoader(this.resourceLoader.getClassLoader()); + ((DefaultResourceLoader) context).setClassLoader(this.resourceLoader.getClassLoader()); } } } @@ -604,8 +579,8 @@ public class SpringApplication { @SuppressWarnings({ "rawtypes", "unchecked" }) protected void applyInitializers(ConfigurableApplicationContext context) { for (ApplicationContextInitializer initializer : getInitializers()) { - Class requiredType = GenericTypeResolver.resolveTypeArgument( - initializer.getClass(), ApplicationContextInitializer.class); + Class requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(), + ApplicationContextInitializer.class); Assert.isInstanceOf(requiredType, context, "Unable to call initializer."); initializer.initialize(context); } @@ -618,8 +593,7 @@ public class SpringApplication { */ protected void logStartupInfo(boolean isRoot) { if (isRoot) { - new StartupInfoLogger(this.mainApplicationClass) - .logStarting(getApplicationLog()); + new StartupInfoLogger(this.mainApplicationClass).logStarting(getApplicationLog()); } } @@ -661,11 +635,9 @@ public class SpringApplication { */ protected void load(ApplicationContext context, Object[] sources) { if (logger.isDebugEnabled()) { - logger.debug( - "Loading source " + StringUtils.arrayToCommaDelimitedString(sources)); + logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources)); } - BeanDefinitionLoader loader = createBeanDefinitionLoader( - getBeanDefinitionRegistry(context), sources); + BeanDefinitionLoader loader = createBeanDefinitionLoader(getBeanDefinitionRegistry(context), sources); if (this.beanNameGenerator != null) { loader.setBeanNameGenerator(this.beanNameGenerator); } @@ -710,8 +682,7 @@ public class SpringApplication { return (BeanDefinitionRegistry) context; } if (context instanceof AbstractApplicationContext) { - return (BeanDefinitionRegistry) ((AbstractApplicationContext) context) - .getBeanFactory(); + return (BeanDefinitionRegistry) ((AbstractApplicationContext) context).getBeanFactory(); } throw new IllegalStateException("Could not locate BeanDefinitionRegistry"); } @@ -722,8 +693,7 @@ public class SpringApplication { * @param sources the sources to load * @return the {@link BeanDefinitionLoader} that will be used to load beans */ - protected BeanDefinitionLoader createBeanDefinitionLoader( - BeanDefinitionRegistry registry, Object[] sources) { + protected BeanDefinitionLoader createBeanDefinitionLoader(BeanDefinitionRegistry registry, Object[] sources) { return new BeanDefinitionLoader(registry, sources); } @@ -741,8 +711,7 @@ public class SpringApplication { * @param context the application context * @param args the application arguments */ - protected void afterRefresh(ConfigurableApplicationContext context, - ApplicationArguments args) { + protected void afterRefresh(ConfigurableApplicationContext context, ApplicationArguments args) { callRunners(context, args); } @@ -779,9 +748,8 @@ public class SpringApplication { } } - private void handleRunFailure(ConfigurableApplicationContext context, - SpringApplicationRunListeners listeners, FailureAnalyzers analyzers, - Throwable exception) { + private void handleRunFailure(ConfigurableApplicationContext context, SpringApplicationRunListeners listeners, + FailureAnalyzers analyzers, Throwable exception) { try { try { handleExitCode(context, exception); @@ -828,8 +796,7 @@ public class SpringApplication { } } - private void handleExitCode(ConfigurableApplicationContext context, - Throwable exception) { + private void handleExitCode(ConfigurableApplicationContext context, Throwable exception) { int exitCode = getExitCodeFromException(context, exception); if (exitCode != 0) { if (context != null) { @@ -842,8 +809,7 @@ public class SpringApplication { } } - private int getExitCodeFromException(ConfigurableApplicationContext context, - Throwable exception) { + private int getExitCodeFromException(ConfigurableApplicationContext context, Throwable exception) { int exitCode = getExitCodeFromMappedException(context, exception); if (exitCode == 0) { exitCode = getExitCodeFromExitCodeGeneratorException(exception); @@ -851,14 +817,12 @@ public class SpringApplication { return exitCode; } - private int getExitCodeFromMappedException(ConfigurableApplicationContext context, - Throwable exception) { + private int getExitCodeFromMappedException(ConfigurableApplicationContext context, Throwable exception) { if (context == null || !context.isActive()) { return 0; } ExitCodeGenerators generators = new ExitCodeGenerators(); - Collection beans = context - .getBeansOfType(ExitCodeExceptionMapper.class).values(); + Collection beans = context.getBeansOfType(ExitCodeExceptionMapper.class).values(); generators.addAll(exception, beans); return generators.getExitCode(); } @@ -881,8 +845,7 @@ public class SpringApplication { } private boolean isMainThread(Thread currentThread) { - return ("main".equals(currentThread.getName()) - || "restartedMain".equals(currentThread.getName())) + return ("main".equals(currentThread.getName()) || "restartedMain".equals(currentThread.getName())) && "main".equals(currentThread.getThreadGroup().getName()); } @@ -1064,8 +1027,7 @@ public class SpringApplication { * or {@link AnnotationConfigApplicationContext} for non web based applications. * @param applicationContextClass the context class to set */ - public void setApplicationContextClass( - Class applicationContextClass) { + public void setApplicationContextClass(Class applicationContextClass) { this.applicationContextClass = applicationContextClass; if (!isWebApplicationContext(applicationContextClass)) { this.webEnvironment = false; @@ -1086,8 +1048,7 @@ public class SpringApplication { * {@link ApplicationContext}. * @param initializers the initializers to set */ - public void setInitializers( - Collection> initializers) { + public void setInitializers(Collection> initializers) { this.initializers = new ArrayList>(); this.initializers.addAll(initializers); } @@ -1188,15 +1149,13 @@ public class SpringApplication { * @param exitCodeGenerators exist code generators * @return the outcome (0 if successful) */ - public static int exit(ApplicationContext context, - ExitCodeGenerator... exitCodeGenerators) { + public static int exit(ApplicationContext context, ExitCodeGenerator... exitCodeGenerators) { Assert.notNull(context, "Context must not be null"); int exitCode = 0; try { try { ExitCodeGenerators generators = new ExitCodeGenerators(); - Collection beans = context - .getBeansOfType(ExitCodeGenerator.class).values(); + Collection beans = context.getBeansOfType(ExitCodeGenerator.class).values(); generators.addAll(exitCodeGenerators); generators.addAll(beans); exitCode = generators.getExitCode(); diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/enum-constructor.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/enum-constructor.txt similarity index 63% rename from spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/enum-constructor.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/enum-constructor.txt index 5d6495d2..533ceb90 100644 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/enum-constructor.txt +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/enum-constructor.txt @@ -2,14 +2,14 @@ package sample; public enum ExampleEnum { - ONE("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", - "eleven", "twelve", "thirteen", "fourteen"), + ONE("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", + "fourteen"), /** * Two */ - TWO("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", - "eleven", "twelve", "thirteen", "fourteen"); + TWO("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", + "fourteen"); private ExampleEnum(String... args) { diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/enum-with-many-uncommented-values.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/enum-with-many-uncommented-values.txt new file mode 100644 index 00000000..b92ba57c --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/enum-with-many-uncommented-values.txt @@ -0,0 +1,18 @@ +package io.spring.javaformat.formatter; + +public enum EnumWithManyUncommentedValues { + + ONE("Long text value to force formatting of the enum's values across multiple lines"), + TWO("Long text value to force formatting of the enum's values across multiple lines"), + THREE("Long text value to force formatting of the enum's values across multiple lines"), + FOUR("Long text value to force formatting of the enum's values across multiple lines"), + FIVE("Long text value to force formatting of the enum's values across multiple lines"), + SIX("Long text value to force formatting of the enum's values across multiple lines"); + + private String text; + + EnumWithManyUncommentedValues(String text) { + this.text = text; + } + +} 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/bin/src/test/resources/expected/javadoc-nested.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/javadoc-nested.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/javadoc-nested.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/javadoc-nested.txt diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/javadoc-param.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/javadoc-param.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/javadoc-param.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/javadoc-param.txt diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/javadoc-top-add.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/javadoc-top-add.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/javadoc-top-add.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/javadoc-top-add.txt diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/javadoc-top-empty.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/javadoc-top-empty.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/javadoc-top-empty.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/javadoc-top-empty.txt diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/javadoc-top.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/javadoc-top.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/javadoc-top.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/javadoc-top.txt 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/bin/src/test/resources/expected/linebreak-classbraces.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/linebreak-classbraces.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/linebreak-classbraces.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/linebreak-classbraces.txt diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/linebreak-fields-comment-above.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/linebreak-fields-comment-above.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/linebreak-fields-comment-above.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/linebreak-fields-comment-above.txt diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/linebreak-fields-comments.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/linebreak-fields-comments.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/linebreak-fields-comments.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/linebreak-fields-comments.txt diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/linebreak-fields.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/linebreak-fields.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/linebreak-fields.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/linebreak-fields.txt diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/linebreak-interface.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/linebreak-interface.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/linebreak-interface.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/linebreak-interface.txt diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/linebreak-trailing.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/linebreak-trailing.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/linebreak-trailing.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/linebreak-trailing.txt 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/src/test/resources/source/method-wrap.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/method-wrap.txt similarity index 57% rename from spring-javaformat/spring-javaformat-formatter/src/test/resources/source/method-wrap.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/method-wrap.txt index 4cf0e2bd..482d03a0 100644 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/method-wrap.txt +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/method-wrap.txt @@ -3,7 +3,8 @@ package simple; public class Simple { @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) + throws ServletException, IOException { } } \ No newline at end of file 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 new file mode 100644 index 00000000..a7946a65 --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/multi-line-statement-indentation.txt @@ -0,0 +1,20 @@ +package simple; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; + +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()); + return settingsXml; + } + +} \ No newline at end of file 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/bin/src/test/resources/expected/simple.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/simple.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/simple.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/simple.txt diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/typical.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/spaces.txt similarity index 58% rename from spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/typical.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/spaces.txt index 20052873..f2133b38 100644 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/typical.txt +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/spaces.txt @@ -1,11 +1,11 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-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 * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -52,39 +52,39 @@ import org.springframework.core.annotation.AliasFor; @ComponentScan(excludeFilters = @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class)) public @interface SpringBootApplication { - /** - * Exclude specific auto-configuration classes such that they will never be applied. - * @return the classes to exclude - */ - Class[] exclude() default {}; + /** + * Exclude specific auto-configuration classes such that they will never be applied. + * @return the classes to exclude + */ + Class[] exclude() default {}; - /** - * Exclude specific auto-configuration class names such that they will never be - * applied. - * @return the class names to exclude - * @since 1.3.0 - */ - String[] excludeName() default {}; + /** + * Exclude specific auto-configuration class names such that they will never be + * applied. + * @return the class names to exclude + * @since 1.3.0 + */ + String[] excludeName() default {}; - /** - * Base packages to scan for annotated components. Use {@link #scanBasePackageClasses} - * for a type-safe alternative to String-based package names. - * @return base packages to scan - * @since 1.3.0 - */ - @AliasFor(annotation = ComponentScan.class, attribute = "basePackages") - String[] scanBasePackages() default {}; + /** + * Base packages to scan for annotated components. Use {@link #scanBasePackageClasses} + * for a type-safe alternative to String-based package names. + * @return base packages to scan + * @since 1.3.0 + */ + @AliasFor(annotation = ComponentScan.class, attribute = "basePackages") + String[] scanBasePackages() default {}; - /** - * Type-safe alternative to {@link #scanBasePackages} for specifying the packages to - * scan for annotated components. The package of each class specified will be scanned. - *

- * Consider creating a special no-op marker class or interface in each package that - * serves no purpose other than being referenced by this attribute. - * @return base packages to scan - * @since 1.3.0 - */ - @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses") - Class[] scanBasePackageClasses() default {}; + /** + * Type-safe alternative to {@link #scanBasePackages} for specifying the packages to + * scan for annotated components. The package of each class specified will be scanned. + *

+ * Consider creating a special no-op marker class or interface in each package that + * serves no purpose other than being referenced by this attribute. + * @return base packages to scan + * @since 1.3.0 + */ + @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses") + Class[] scanBasePackageClasses() default {}; } diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/static-initializer.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/static-initializer.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/static-initializer.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/static-initializer.txt diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/switch.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/switch.txt new file mode 100644 index 00000000..87ae995d --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/switch.txt @@ -0,0 +1,14 @@ +public class SwitchExample { + + protected boolean isIncludeBindingErrors(HttpServletRequest request, MediaType produces) { + switch (getErrorProperties().getIncludeBindingErrors()) { + case ALWAYS: + return true; + case ON_PARAM: + return getErrorsParameter(request); + default: + return false; + } + } + +} \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/typical.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/typical.txt similarity index 96% rename from spring-javaformat/spring-javaformat-formatter/src/test/resources/source/typical.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/typical.txt index 20052873..e370bf0e 100644 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/typical.txt +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/expected/typical.txt @@ -1,11 +1,11 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-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 * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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/annotation-attributes.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/annotation-attributes.txt new file mode 100644 index 00000000..19ae7f4d --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/annotation-attributes.txt @@ -0,0 +1,9 @@ +class MyTest { + + @SpringBootTest(properties = "spring.main.web-application-type=reactive", classes = { WebTestClientSpringBootTestIntegrationTests.TestConfiguration.class, ExampleWebFluxApplication.class }) + static class One {} + + @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = { "spring.jersey.type=filter", "server.servlet.context-path=/app", "server.servlet.register-default-servlet=true" }) + static class Two {} + +} \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/complex-annotation-gh-78.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/complex-annotation-gh-78.txt new file mode 100644 index 00000000..abe6a5e1 --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/complex-annotation-gh-78.txt @@ -0,0 +1,8 @@ +package sample; + +import sample.SpringBootTest.WebEnvironment; + +@SpringBootTest(classes = RibbonClientConfigurationIntegrationTests.TestLBConfig.class, properties = "test.ribbon.ServerListRefreshInterval=999") +public class SampleApplication { + +} diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/complex-annotation.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/complex-annotation.txt new file mode 100644 index 00000000..29a633ae --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/complex-annotation.txt @@ -0,0 +1,10 @@ +package sample; + +import sample.SpringBootTest.WebEnvironment; + +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = { + "management.server.port=0", "management.server.address=127.0.0.1", + "management.server.servlet.context-path:/admin" }) +public class SampleApplication { + +} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/complex.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/complex.txt similarity index 99% rename from spring-javaformat/spring-javaformat-formatter/src/test/resources/source/complex.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/complex.txt index b66b83f8..936faa1b 100644 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/complex.txt +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/complex.txt @@ -1,11 +1,11 @@ /* - * Copyright 2012-2016 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/enum-constructor.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/enum-constructor.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/enum-constructor.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/enum-constructor.txt diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/enum-with-many-uncommented-values.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/enum-with-many-uncommented-values.txt new file mode 100644 index 00000000..b92ba57c --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/enum-with-many-uncommented-values.txt @@ -0,0 +1,18 @@ +package io.spring.javaformat.formatter; + +public enum EnumWithManyUncommentedValues { + + ONE("Long text value to force formatting of the enum's values across multiple lines"), + TWO("Long text value to force formatting of the enum's values across multiple lines"), + THREE("Long text value to force formatting of the enum's values across multiple lines"), + FOUR("Long text value to force formatting of the enum's values across multiple lines"), + FIVE("Long text value to force formatting of the enum's values across multiple lines"), + SIX("Long text value to force formatting of the enum's values across multiple lines"); + + private String text; + + EnumWithManyUncommentedValues(String text) { + this.text = text; + } + +} 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/bin/src/test/resources/source/javadoc-nested.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/javadoc-nested.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/javadoc-nested.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/javadoc-nested.txt diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/javadoc-param.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/javadoc-param.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/javadoc-param.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/javadoc-param.txt diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/javadoc-top-add.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/javadoc-top-add.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/javadoc-top-add.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/javadoc-top-add.txt diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/javadoc-top-empty.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/javadoc-top-empty.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/javadoc-top-empty.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/javadoc-top-empty.txt diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/javadoc-top.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/javadoc-top.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/javadoc-top.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/javadoc-top.txt 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/bin/src/test/resources/source/linebreak-classbraces.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/linebreak-classbraces.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/linebreak-classbraces.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/linebreak-classbraces.txt diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/linebreak-fields-comment-above.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/linebreak-fields-comment-above.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/linebreak-fields-comment-above.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/linebreak-fields-comment-above.txt diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/linebreak-fields-comments.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/linebreak-fields-comments.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/linebreak-fields-comments.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/linebreak-fields-comments.txt diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/linebreak-fields.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/linebreak-fields.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/linebreak-fields.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/linebreak-fields.txt diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/linebreak-interface.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/linebreak-interface.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/linebreak-interface.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/linebreak-interface.txt diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/linebreak-trailing.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/linebreak-trailing.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/linebreak-trailing.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/linebreak-trailing.txt 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/bin/src/test/resources/source/method-wrap.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/method-wrap.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/method-wrap.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/method-wrap.txt diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/multi-line-statement-indentation.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/multi-line-statement-indentation.txt new file mode 100644 index 00000000..7c63370c --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/multi-line-statement-indentation.txt @@ -0,0 +1,21 @@ +package simple; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; + +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()); + return settingsXml; + } + +} \ No newline at end of file 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/src/test/resources/expected/simple.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/simple.txt similarity index 98% rename from spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/simple.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/simple.txt index a12ac39e..62d2a493 100644 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/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/bin/src/test/resources/source/typical.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/spaces.txt similarity index 96% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/typical.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/spaces.txt index 20052873..e370bf0e 100644 --- a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/typical.txt +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/spaces.txt @@ -1,11 +1,11 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-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 * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/static-initializer.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/static-initializer.txt similarity index 100% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/static-initializer.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/static-initializer.txt diff --git a/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/switch.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/switch.txt new file mode 100644 index 00000000..2f58321f --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/switch.txt @@ -0,0 +1,12 @@ +public class SwitchExample { + protected boolean isIncludeBindingErrors(HttpServletRequest request, MediaType produces) { + switch (getErrorProperties().getIncludeBindingErrors()) { + case ALWAYS: + return true; + case ON_PARAM: + return getErrorsParameter(request); + default: + return false; + } + } +} \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/typical.txt b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/typical.txt similarity index 96% rename from spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/typical.txt rename to spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/typical.txt index 20052873..e370bf0e 100644 --- a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/typical.txt +++ b/spring-javaformat/spring-javaformat-formatter-tests/src/test/resources/source/typical.txt @@ -1,11 +1,11 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-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 * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, diff --git a/spring-javaformat/spring-javaformat-formatter/bin/pom.xml b/spring-javaformat/spring-javaformat-formatter/bin/pom.xml deleted file mode 100644 index eec03e0c..00000000 --- a/spring-javaformat/spring-javaformat-formatter/bin/pom.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - 4.0.0 - - io.spring.javaformat - spring-javaformat - 0.0.1-SNAPSHOT - - spring-javaformat-formatter - - ${basedir}/.. - - - - io.spring.javaformat - spring-javaformat-eclipse-formatter - ${project.version} - - - io.spring.javaformat - spring-javaformat-eclipse-runtime - ${project.version} - provided - - - junit - junit - test - - - org.assertj - assertj-core - test - - - diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/FileEdit.class b/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/FileEdit.class deleted file mode 100644 index 194c9e51..00000000 Binary files a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/FileEdit.class and /dev/null differ diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/FileFormatter.class b/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/FileFormatter.class deleted file mode 100644 index c630af6e..00000000 Binary files a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/FileFormatter.class and /dev/null differ diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/FileFormatterException.class b/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/FileFormatterException.class deleted file mode 100644 index 38be8621..00000000 Binary files a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/FileFormatterException.class and /dev/null differ diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/Formatter$DelegateCodeFormatter.class b/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/Formatter$DelegateCodeFormatter.class deleted file mode 100644 index d95745c6..00000000 Binary files a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/Formatter$DelegateCodeFormatter.class and /dev/null differ diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/Formatter.class b/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/Formatter.class deleted file mode 100644 index 8c9aee98..00000000 Binary files a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/Formatter.class and /dev/null differ diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/FormatterOption.class b/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/FormatterOption.class deleted file mode 100644 index d6af86c3..00000000 Binary files a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/FormatterOption.class and /dev/null differ diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/preparator/CodeLineBreakPreparator$Vistor.class b/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/preparator/CodeLineBreakPreparator$Vistor.class deleted file mode 100644 index fff26e7b..00000000 Binary files a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/preparator/CodeLineBreakPreparator$Vistor.class and /dev/null differ diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/preparator/CodeLineBreakPreparator.class b/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/preparator/CodeLineBreakPreparator.class deleted file mode 100644 index da6be261..00000000 Binary files a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/preparator/CodeLineBreakPreparator.class and /dev/null differ diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/preparator/JavadocLineBreakPreparator$Vistor.class b/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/preparator/JavadocLineBreakPreparator$Vistor.class deleted file mode 100644 index b537fa1f..00000000 Binary files a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/preparator/JavadocLineBreakPreparator$Vistor.class and /dev/null differ diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/preparator/JavadocLineBreakPreparator.class b/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/preparator/JavadocLineBreakPreparator.class deleted file mode 100644 index 8f72a7e9..00000000 Binary files a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/preparator/JavadocLineBreakPreparator.class and /dev/null differ diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/preparator/Preparators.class b/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/preparator/Preparators.class deleted file mode 100644 index dc7b8d42..00000000 Binary files a/spring-javaformat/spring-javaformat-formatter/bin/src/main/java/io/spring/javaformat/formatter/preparator/Preparators.class and /dev/null differ diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/main/resources/io/spring/javaformat/formatter/formatter.prefs b/spring-javaformat/spring-javaformat-formatter/bin/src/main/resources/io/spring/javaformat/formatter/formatter.prefs deleted file mode 100644 index 21617429..00000000 --- a/spring-javaformat/spring-javaformat-formatter/bin/src/main/resources/io/spring/javaformat/formatter/formatter.prefs +++ /dev/null @@ -1,285 +0,0 @@ -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -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_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 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -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 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false -org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=false -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=true -org.eclipse.jdt.core.formatter.comment.format_source_code=false -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=false -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=do not insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert -org.eclipse.jdt.core.formatter.comment.line_length=90 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=90 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=tab -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=true -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/java/io/spring/javaformat/formatter/AbstractFormatterTests.class b/spring-javaformat/spring-javaformat-formatter/bin/src/test/java/io/spring/javaformat/formatter/AbstractFormatterTests.class deleted file mode 100644 index 7b0b7f8d..00000000 Binary files a/spring-javaformat/spring-javaformat-formatter/bin/src/test/java/io/spring/javaformat/formatter/AbstractFormatterTests.class and /dev/null differ diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/java/io/spring/javaformat/formatter/FileEditTests.class b/spring-javaformat/spring-javaformat-formatter/bin/src/test/java/io/spring/javaformat/formatter/FileEditTests.class deleted file mode 100644 index cc5b7bbe..00000000 Binary files a/spring-javaformat/spring-javaformat-formatter/bin/src/test/java/io/spring/javaformat/formatter/FileEditTests.class and /dev/null differ diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/java/io/spring/javaformat/formatter/FileFormatterTests.class b/spring-javaformat/spring-javaformat-formatter/bin/src/test/java/io/spring/javaformat/formatter/FileFormatterTests.class deleted file mode 100644 index 46b253c3..00000000 Binary files a/spring-javaformat/spring-javaformat-formatter/bin/src/test/java/io/spring/javaformat/formatter/FileFormatterTests.class and /dev/null differ diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/java/io/spring/javaformat/formatter/FormatterTests.class b/spring-javaformat/spring-javaformat-formatter/bin/src/test/java/io/spring/javaformat/formatter/FormatterTests.class deleted file mode 100644 index 76e99d1f..00000000 Binary files a/spring-javaformat/spring-javaformat-formatter/bin/src/test/java/io/spring/javaformat/formatter/FormatterTests.class and /dev/null differ diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/complex.txt b/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/complex.txt deleted file mode 100644 index 6241cdc3..00000000 --- a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/complex.txt +++ /dev/null @@ -1,1234 +0,0 @@ -/* - * Copyright 2012-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot; - -import java.lang.reflect.Constructor; -import java.security.AccessControlException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.BeanUtils; -import org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.BeanNameGenerator; -import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; -import org.springframework.boot.Banner.Mode; -import org.springframework.boot.diagnostics.FailureAnalyzers; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ApplicationListener; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.AnnotatedBeanDefinitionReader; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.AnnotationConfigUtils; -import org.springframework.context.annotation.ClassPathBeanDefinitionScanner; -import org.springframework.context.support.AbstractApplicationContext; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.core.GenericTypeResolver; -import org.springframework.core.annotation.AnnotationAwareOrderComparator; -import org.springframework.core.env.CommandLinePropertySource; -import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.Environment; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; -import org.springframework.core.env.SimpleCommandLinePropertySource; -import org.springframework.core.env.StandardEnvironment; -import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.core.io.Resource; -import org.springframework.core.io.ResourceLoader; -import org.springframework.core.io.support.SpringFactoriesLoader; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.ObjectUtils; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StopWatch; -import org.springframework.util.StringUtils; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.context.support.StandardServletEnvironment; - -/** - * Classes that can be used to bootstrap and launch a Spring application from a Java main - * method. By default class will perform the following steps to bootstrap your - * application: - * - *

    - *
  • Create an appropriate {@link ApplicationContext} instance (depending on your - * classpath)
  • - *
  • Register a {@link CommandLinePropertySource} to expose command line arguments as - * Spring properties
  • - *
  • Refresh the application context, loading all singleton beans
  • - *
  • Trigger any {@link CommandLineRunner} beans
  • - *
- * - * In most circumstances the static {@link #run(Object, String[])} method can be called - * directly from your {@literal main} method to bootstrap your application: - * - *
- * @Configuration
- * @EnableAutoConfiguration
- * public class MyApplication  {
- *
- * // ... Bean definitions
- *
- * public static void main(String[] args) throws Exception {
- *   SpringApplication.run(MyApplication.class, args);
- * }
- * 
- * - *

- * For more advanced configuration a {@link SpringApplication} instance can be created and - * customized before being run: - * - *

- * public static void main(String[] args) throws Exception {
- *   SpringApplication app = new SpringApplication(MyApplication.class);
- *   // ... customize app settings here
- *   app.run(args)
- * }
- * 
- * - * {@link SpringApplication}s can read beans from a variety of different sources. It is - * generally recommended that a single {@code @Configuration} class is used to bootstrap - * your application, however, any of the following sources can also be used: - * - *
    - *
  • {@link Class} - A Java class to be loaded by {@link AnnotatedBeanDefinitionReader} - *
  • - *
  • {@link Resource} - An XML resource to be loaded by {@link XmlBeanDefinitionReader}, - * or a groovy script to be loaded by {@link GroovyBeanDefinitionReader}
  • - *
  • {@link Package} - A Java package to be scanned by - * {@link ClassPathBeanDefinitionScanner}
  • - *
  • {@link CharSequence} - A class name, resource handle or package name to loaded as - * appropriate. If the {@link CharSequence} cannot be resolved to class and does not - * resolve to a {@link Resource} that exists it will be considered a {@link Package}.
  • - *
- * - * @author Phillip Webb - * @author Dave Syer - * @author Andy Wilkinson - * @author Christian Dupuis - * @author Stephane Nicoll - * @author Jeremy Rickard - * @author Craig Burke - * @author Michael Simons - * @see #run(Object, String[]) - * @see #run(Object[], String[]) - * @see #SpringApplication(Object...) - */ -public class SpringApplication { - - /** - * The class name of application context that will be used by default for non-web - * environments. - */ - public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context." - + "annotation.AnnotationConfigApplicationContext"; - - /** - * The class name of application context that will be used by default for web - * environments. - */ - public static final String DEFAULT_WEB_CONTEXT_CLASS = "org.springframework." - + "boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext"; - - private static final String[] WEB_ENVIRONMENT_CLASSES = { "javax.servlet.Servlet", - "org.springframework.web.context.ConfigurableWebApplicationContext" }; - - /** - * Default banner location. - */ - public static final String BANNER_LOCATION_PROPERTY_VALUE = SpringApplicationBannerPrinter.DEFAULT_BANNER_LOCATION; - - /** - * Banner location property key. - */ - public static final String BANNER_LOCATION_PROPERTY = SpringApplicationBannerPrinter.BANNER_LOCATION_PROPERTY; - - private static final String CONFIGURABLE_WEB_ENVIRONMENT_CLASS = "org.springframework.web.context.ConfigurableWebEnvironment"; - - private static final String SYSTEM_PROPERTY_JAVA_AWT_HEADLESS = "java.awt.headless"; - - private static final Set SERVLET_ENVIRONMENT_SOURCE_NAMES; - - static { - Set names = new HashSet(); - names.add(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME); - names.add(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME); - names.add(StandardServletEnvironment.JNDI_PROPERTY_SOURCE_NAME); - SERVLET_ENVIRONMENT_SOURCE_NAMES = Collections.unmodifiableSet(names); - } - - private static final Log logger = LogFactory.getLog(SpringApplication.class); - - private final Set sources = new LinkedHashSet(); - - private Class mainApplicationClass; - - private Banner.Mode bannerMode = Banner.Mode.CONSOLE; - - private boolean logStartupInfo = true; - - private boolean addCommandLineProperties = true; - - private Banner banner; - - private ResourceLoader resourceLoader; - - private BeanNameGenerator beanNameGenerator; - - private ConfigurableEnvironment environment; - - private Class applicationContextClass; - - private boolean webEnvironment; - - private boolean headless = true; - - private boolean registerShutdownHook = true; - - private List> initializers; - - private List> listeners; - - private Map defaultProperties; - - private Set additionalProfiles = new HashSet(); - - /** - * Create a new {@link SpringApplication} instance. The application context will load - * beans from the specified sources (see {@link SpringApplication class-level} - * documentation for details. The instance can be customized before calling - * {@link #run(String...)}. - * @param sources the bean sources - * @see #run(Object, String[]) - * @see #SpringApplication(ResourceLoader, Object...) - */ - public SpringApplication(Object... sources) { - initialize(sources); - } - - /** - * Create a new {@link SpringApplication} instance. The application context will load - * beans from the specified sources (see {@link SpringApplication class-level} - * documentation for details. The instance can be customized before calling - * {@link #run(String...)}. - * @param resourceLoader the resource loader to use - * @param sources the bean sources - * @see #run(Object, String[]) - * @see #SpringApplication(ResourceLoader, Object...) - */ - public SpringApplication(ResourceLoader resourceLoader, Object... sources) { - this.resourceLoader = resourceLoader; - initialize(sources); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private void initialize(Object[] sources) { - if (sources != null && sources.length > 0) { - this.sources.addAll(Arrays.asList(sources)); - } - this.webEnvironment = deduceWebEnvironment(); - setInitializers((Collection) getSpringFactoriesInstances( - ApplicationContextInitializer.class)); - setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); - this.mainApplicationClass = deduceMainApplicationClass(); - } - - private boolean deduceWebEnvironment() { - for (String className : WEB_ENVIRONMENT_CLASSES) { - if (!ClassUtils.isPresent(className, null)) { - return false; - } - } - return true; - } - - private Class deduceMainApplicationClass() { - try { - StackTraceElement[] stackTrace = new RuntimeException().getStackTrace(); - for (StackTraceElement stackTraceElement : stackTrace) { - if ("main".equals(stackTraceElement.getMethodName())) { - return Class.forName(stackTraceElement.getClassName()); - } - } - } - catch (ClassNotFoundException ex) { - // Swallow and continue - } - return null; - } - - /** - * Run the Spring application, creating and refreshing a new - * {@link ApplicationContext}. - * @param args the application arguments (usually passed from a Java main method) - * @return a running {@link ApplicationContext} - */ - public ConfigurableApplicationContext run(String... args) { - StopWatch stopWatch = new StopWatch(); - stopWatch.start(); - ConfigurableApplicationContext context = null; - FailureAnalyzers analyzers = null; - configureHeadlessProperty(); - SpringApplicationRunListeners listeners = getRunListeners(args); - listeners.starting(); - try { - ApplicationArguments applicationArguments = new DefaultApplicationArguments( - args); - ConfigurableEnvironment environment = prepareEnvironment(listeners, - applicationArguments); - Banner printedBanner = printBanner(environment); - context = createApplicationContext(); - analyzers = new FailureAnalyzers(context); - prepareContext(context, environment, listeners, applicationArguments, - printedBanner); - refreshContext(context); - afterRefresh(context, applicationArguments); - listeners.finished(context, null); - stopWatch.stop(); - if (this.logStartupInfo) { - new StartupInfoLogger(this.mainApplicationClass) - .logStarted(getApplicationLog(), stopWatch); - } - return context; - } - catch (Throwable ex) { - handleRunFailure(context, listeners, analyzers, ex); - throw new IllegalStateException(ex); - } - } - - private ConfigurableEnvironment prepareEnvironment( - SpringApplicationRunListeners listeners, - ApplicationArguments applicationArguments) { - // Create and configure the environment - ConfigurableEnvironment environment = getOrCreateEnvironment(); - configureEnvironment(environment, applicationArguments.getSourceArgs()); - listeners.environmentPrepared(environment); - if (isWebEnvironment(environment) && !this.webEnvironment) { - environment = convertToStandardEnvironment(environment); - } - return environment; - } - - private void prepareContext(ConfigurableApplicationContext context, - ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, - ApplicationArguments applicationArguments, Banner printedBanner) { - context.setEnvironment(environment); - postProcessApplicationContext(context); - applyInitializers(context); - listeners.contextPrepared(context); - if (this.logStartupInfo) { - logStartupInfo(context.getParent() == null); - logStartupProfileInfo(context); - } - - // Add boot specific singleton beans - context.getBeanFactory().registerSingleton("springApplicationArguments", - applicationArguments); - if (printedBanner != null) { - context.getBeanFactory().registerSingleton("springBootBanner", printedBanner); - } - - // Load the sources - Set sources = getSources(); - Assert.notEmpty(sources, "Sources must not be empty"); - load(context, sources.toArray(new Object[sources.size()])); - listeners.contextLoaded(context); - } - - private void refreshContext(ConfigurableApplicationContext context) { - refresh(context); - if (this.registerShutdownHook) { - try { - context.registerShutdownHook(); - } - catch (AccessControlException ex) { - // Not allowed in some environments. - } - } - } - - private void configureHeadlessProperty() { - System.setProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, System.getProperty( - SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, Boolean.toString(this.headless))); - } - - private SpringApplicationRunListeners getRunListeners(String[] args) { - Class[] types = new Class[] { SpringApplication.class, String[].class }; - return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances( - SpringApplicationRunListener.class, types, this, args)); - } - - private Collection getSpringFactoriesInstances(Class type) { - return getSpringFactoriesInstances(type, new Class[] {}); - } - - private Collection getSpringFactoriesInstances(Class type, - Class[] parameterTypes, Object... args) { - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - // Use names and ensure unique to protect against duplicates - Set names = new LinkedHashSet( - SpringFactoriesLoader.loadFactoryNames(type, classLoader)); - List instances = createSpringFactoriesInstances(type, parameterTypes, - classLoader, args, names); - AnnotationAwareOrderComparator.sort(instances); - return instances; - } - - @SuppressWarnings("unchecked") - private List createSpringFactoriesInstances(Class type, - Class[] parameterTypes, ClassLoader classLoader, Object[] args, - Set names) { - List instances = new ArrayList(names.size()); - for (String name : names) { - try { - Class instanceClass = ClassUtils.forName(name, classLoader); - Assert.isAssignable(type, instanceClass); - Constructor constructor = instanceClass - .getDeclaredConstructor(parameterTypes); - T instance = (T) BeanUtils.instantiateClass(constructor, args); - instances.add(instance); - } - catch (Throwable ex) { - throw new IllegalArgumentException( - "Cannot instantiate " + type + " : " + name, ex); - } - } - return instances; - } - - private ConfigurableEnvironment getOrCreateEnvironment() { - if (this.environment != null) { - return this.environment; - } - if (this.webEnvironment) { - return new StandardServletEnvironment(); - } - return new StandardEnvironment(); - } - - /** - * Template method delegating to - * {@link #configurePropertySources(ConfigurableEnvironment, String[])} and - * {@link #configureProfiles(ConfigurableEnvironment, String[])} in that order. - * Override this method for complete control over Environment customization, or one of - * the above for fine-grained control over property sources or profiles, respectively. - * @param environment this application's environment - * @param args arguments passed to the {@code run} method - * @see #configureProfiles(ConfigurableEnvironment, String[]) - * @see #configurePropertySources(ConfigurableEnvironment, String[]) - */ - protected void configureEnvironment(ConfigurableEnvironment environment, - String[] args) { - configurePropertySources(environment, args); - configureProfiles(environment, args); - } - - private boolean isWebEnvironment(ConfigurableEnvironment environment) { - try { - Class webEnvironmentClass = ClassUtils - .forName(CONFIGURABLE_WEB_ENVIRONMENT_CLASS, getClassLoader()); - return (webEnvironmentClass.isInstance(environment)); - } - catch (Throwable ex) { - return false; - } - } - - private ConfigurableEnvironment convertToStandardEnvironment( - ConfigurableEnvironment environment) { - StandardEnvironment result = new StandardEnvironment(); - removeAllPropertySources(result.getPropertySources()); - result.setActiveProfiles(environment.getActiveProfiles()); - for (PropertySource propertySource : environment.getPropertySources()) { - if (!SERVLET_ENVIRONMENT_SOURCE_NAMES.contains(propertySource.getName())) { - result.getPropertySources().addLast(propertySource); - } - } - return result; - } - - private void removeAllPropertySources(MutablePropertySources propertySources) { - Set names = new HashSet(); - for (PropertySource propertySource : propertySources) { - names.add(propertySource.getName()); - } - for (String name : names) { - propertySources.remove(name); - } - } - - /** - * Add, remove or re-order any {@link PropertySource}s in this application's - * environment. - * @param environment this application's environment - * @param args arguments passed to the {@code run} method - * @see #configureEnvironment(ConfigurableEnvironment, String[]) - */ - protected void configurePropertySources(ConfigurableEnvironment environment, - String[] args) { - MutablePropertySources sources = environment.getPropertySources(); - if (this.defaultProperties != null && !this.defaultProperties.isEmpty()) { - sources.addLast( - new MapPropertySource("defaultProperties", this.defaultProperties)); - } - if (this.addCommandLineProperties && args.length > 0) { - String name = CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME; - if (sources.contains(name)) { - PropertySource source = sources.get(name); - CompositePropertySource composite = new CompositePropertySource(name); - composite.addPropertySource(new SimpleCommandLinePropertySource( - name + "-" + args.hashCode(), args)); - composite.addPropertySource(source); - sources.replace(name, composite); - } - else { - sources.addFirst(new SimpleCommandLinePropertySource(args)); - } - } - } - - /** - * Configure which profiles are active (or active by default) for this application - * environment. Additional profiles may be activated during configuration file - * processing via the {@code spring.profiles.active} property. - * @param environment this application's environment - * @param args arguments passed to the {@code run} method - * @see #configureEnvironment(ConfigurableEnvironment, String[]) - * @see org.springframework.boot.context.config.ConfigFileApplicationListener - */ - protected void configureProfiles(ConfigurableEnvironment environment, String[] args) { - environment.getActiveProfiles(); // ensure they are initialized - // But these ones should go first (last wins in a property key clash) - Set profiles = new LinkedHashSet(this.additionalProfiles); - profiles.addAll(Arrays.asList(environment.getActiveProfiles())); - environment.setActiveProfiles(profiles.toArray(new String[profiles.size()])); - } - - private Banner printBanner(ConfigurableEnvironment environment) { - if (this.bannerMode == Banner.Mode.OFF) { - return null; - } - ResourceLoader resourceLoader = this.resourceLoader != null ? this.resourceLoader - : new DefaultResourceLoader(getClassLoader()); - SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter( - resourceLoader, this.banner); - if (this.bannerMode == Mode.LOG) { - return bannerPrinter.print(environment, this.mainApplicationClass, logger); - } - return bannerPrinter.print(environment, this.mainApplicationClass, System.out); - } - - /** - * Strategy method used to create the {@link ApplicationContext}. By default this - * method will respect any explicitly set application context or application context - * class before falling back to a suitable default. - * @return the application context (not yet refreshed) - * @see #setApplicationContextClass(Class) - */ - protected ConfigurableApplicationContext createApplicationContext() { - Class contextClass = this.applicationContextClass; - if (contextClass == null) { - try { - contextClass = Class - .forName(this.webEnvironment ? DEFAULT_WEB_CONTEXT_CLASS - : DEFAULT_CONTEXT_CLASS); - } - catch (ClassNotFoundException ex) { - throw new IllegalStateException( - "Unable create a default ApplicationContext, " - + "please specify an ApplicationContextClass", - ex); - } - } - return (ConfigurableApplicationContext) BeanUtils.instantiate(contextClass); - } - - /** - * Apply any relevant post processing the {@link ApplicationContext}. Subclasses can - * apply additional processing as required. - * @param context the application context - */ - protected void postProcessApplicationContext(ConfigurableApplicationContext context) { - if (this.beanNameGenerator != null) { - context.getBeanFactory().registerSingleton( - AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, - this.beanNameGenerator); - } - if (this.resourceLoader != null) { - if (context instanceof GenericApplicationContext) { - ((GenericApplicationContext) context) - .setResourceLoader(this.resourceLoader); - } - if (context instanceof DefaultResourceLoader) { - ((DefaultResourceLoader) context) - .setClassLoader(this.resourceLoader.getClassLoader()); - } - } - } - - /** - * Apply any {@link ApplicationContextInitializer}s to the context before it is - * refreshed. - * @param context the configured ApplicationContext (not refreshed yet) - * @see ConfigurableApplicationContext#refresh() - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - protected void applyInitializers(ConfigurableApplicationContext context) { - for (ApplicationContextInitializer initializer : getInitializers()) { - Class requiredType = GenericTypeResolver.resolveTypeArgument( - initializer.getClass(), ApplicationContextInitializer.class); - Assert.isInstanceOf(requiredType, context, "Unable to call initializer."); - initializer.initialize(context); - } - } - - /** - * Called to log startup information, subclasses may override to add additional - * logging. - * @param isRoot true if this application is the root of a context hierarchy - */ - protected void logStartupInfo(boolean isRoot) { - if (isRoot) { - new StartupInfoLogger(this.mainApplicationClass) - .logStarting(getApplicationLog()); - } - } - - /** - * Called to log active profile information. - * @param context the application context - */ - protected void logStartupProfileInfo(ConfigurableApplicationContext context) { - Log log = getApplicationLog(); - if (log.isInfoEnabled()) { - String[] activeProfiles = context.getEnvironment().getActiveProfiles(); - if (ObjectUtils.isEmpty(activeProfiles)) { - String[] defaultProfiles = context.getEnvironment().getDefaultProfiles(); - log.info("No active profile set, falling back to default profiles: " - + StringUtils.arrayToCommaDelimitedString(defaultProfiles)); - } - else { - log.info("The following profiles are active: " - + StringUtils.arrayToCommaDelimitedString(activeProfiles)); - } - } - } - - /** - * Returns the {@link Log} for the application. By default will be deduced. - * @return the application log - */ - protected Log getApplicationLog() { - if (this.mainApplicationClass == null) { - return logger; - } - return LogFactory.getLog(this.mainApplicationClass); - } - - /** - * Load beans into the application context. - * @param context the context to load beans into - * @param sources the sources to load - */ - protected void load(ApplicationContext context, Object[] sources) { - if (logger.isDebugEnabled()) { - logger.debug( - "Loading source " + StringUtils.arrayToCommaDelimitedString(sources)); - } - BeanDefinitionLoader loader = createBeanDefinitionLoader( - getBeanDefinitionRegistry(context), sources); - if (this.beanNameGenerator != null) { - loader.setBeanNameGenerator(this.beanNameGenerator); - } - if (this.resourceLoader != null) { - loader.setResourceLoader(this.resourceLoader); - } - if (this.environment != null) { - loader.setEnvironment(this.environment); - } - loader.load(); - } - - /** - * The ResourceLoader that will be used in the ApplicationContext. - * @return the resourceLoader the resource loader that will be used in the - * ApplicationContext (or null if the default) - */ - public ResourceLoader getResourceLoader() { - return this.resourceLoader; - } - - /** - * Either the ClassLoader that will be used in the ApplicationContext (if - * {@link #setResourceLoader(ResourceLoader) resourceLoader} is set, or the context - * class loader (if not null), or the loader of the Spring {@link ClassUtils} class. - * @return a ClassLoader (never null) - */ - public ClassLoader getClassLoader() { - if (this.resourceLoader != null) { - return this.resourceLoader.getClassLoader(); - } - return ClassUtils.getDefaultClassLoader(); - } - - /** - * Get the bean definition registry. - * @param context the application context - * @return the BeanDefinitionRegistry if it can be determined - */ - private BeanDefinitionRegistry getBeanDefinitionRegistry(ApplicationContext context) { - if (context instanceof BeanDefinitionRegistry) { - return (BeanDefinitionRegistry) context; - } - if (context instanceof AbstractApplicationContext) { - return (BeanDefinitionRegistry) ((AbstractApplicationContext) context) - .getBeanFactory(); - } - throw new IllegalStateException("Could not locate BeanDefinitionRegistry"); - } - - /** - * Factory method used to create the {@link BeanDefinitionLoader}. - * @param registry the bean definition registry - * @param sources the sources to load - * @return the {@link BeanDefinitionLoader} that will be used to load beans - */ - protected BeanDefinitionLoader createBeanDefinitionLoader( - BeanDefinitionRegistry registry, Object[] sources) { - return new BeanDefinitionLoader(registry, sources); - } - - /** - * Refresh the underlying {@link ApplicationContext}. - * @param applicationContext the application context to refresh - */ - protected void refresh(ApplicationContext applicationContext) { - Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext); - ((AbstractApplicationContext) applicationContext).refresh(); - } - - /** - * Called after the context has been refreshed. - * @param context the application context - * @param args the application arguments - */ - protected void afterRefresh(ConfigurableApplicationContext context, - ApplicationArguments args) { - callRunners(context, args); - } - - private void callRunners(ApplicationContext context, ApplicationArguments args) { - List runners = new ArrayList(); - runners.addAll(context.getBeansOfType(ApplicationRunner.class).values()); - runners.addAll(context.getBeansOfType(CommandLineRunner.class).values()); - AnnotationAwareOrderComparator.sort(runners); - for (Object runner : new LinkedHashSet(runners)) { - if (runner instanceof ApplicationRunner) { - callRunner((ApplicationRunner) runner, args); - } - if (runner instanceof CommandLineRunner) { - callRunner((CommandLineRunner) runner, args); - } - } - } - - private void callRunner(ApplicationRunner runner, ApplicationArguments args) { - try { - (runner).run(args); - } - catch (Exception ex) { - throw new IllegalStateException("Failed to execute ApplicationRunner", ex); - } - } - - private void callRunner(CommandLineRunner runner, ApplicationArguments args) { - try { - (runner).run(args.getSourceArgs()); - } - catch (Exception ex) { - throw new IllegalStateException("Failed to execute CommandLineRunner", ex); - } - } - - private void handleRunFailure(ConfigurableApplicationContext context, - SpringApplicationRunListeners listeners, FailureAnalyzers analyzers, - Throwable exception) { - try { - try { - handleExitCode(context, exception); - listeners.finished(context, exception); - } - finally { - reportFailure(analyzers, exception); - if (context != null) { - context.close(); - } - } - } - catch (Exception ex) { - logger.warn("Unable to close ApplicationContext", ex); - } - ReflectionUtils.rethrowRuntimeException(exception); - } - - private void reportFailure(FailureAnalyzers analyzers, Throwable failure) { - try { - if (analyzers != null && analyzers.analyzeAndReport(failure)) { - registerLoggedException(failure); - return; - } - } - catch (Throwable ex) { - // Continue with normal handling of the original failure - } - if (logger.isErrorEnabled()) { - logger.error("Application startup failed", failure); - registerLoggedException(failure); - } - } - - /** - * Register that the given exception has been logged. By default, if the running in - * the main thread, this method will suppress additional printing of the stacktrace. - * @param exception the exception that was logged - */ - protected void registerLoggedException(Throwable exception) { - SpringBootExceptionHandler handler = getSpringBootExceptionHandler(); - if (handler != null) { - handler.registerLoggedException(exception); - } - } - - private void handleExitCode(ConfigurableApplicationContext context, - Throwable exception) { - int exitCode = getExitCodeFromException(context, exception); - if (exitCode != 0) { - if (context != null) { - context.publishEvent(new ExitCodeEvent(context, exitCode)); - } - SpringBootExceptionHandler handler = getSpringBootExceptionHandler(); - if (handler != null) { - handler.registerExitCode(exitCode); - } - } - } - - private int getExitCodeFromException(ConfigurableApplicationContext context, - Throwable exception) { - int exitCode = getExitCodeFromMappedException(context, exception); - if (exitCode == 0) { - exitCode = getExitCodeFromExitCodeGeneratorException(exception); - } - return exitCode; - } - - private int getExitCodeFromMappedException(ConfigurableApplicationContext context, - Throwable exception) { - if (context == null || !context.isActive()) { - return 0; - } - ExitCodeGenerators generators = new ExitCodeGenerators(); - Collection beans = context - .getBeansOfType(ExitCodeExceptionMapper.class).values(); - generators.addAll(exception, beans); - return generators.getExitCode(); - } - - private int getExitCodeFromExitCodeGeneratorException(Throwable exception) { - if (exception == null) { - return 0; - } - if (exception instanceof ExitCodeGenerator) { - return ((ExitCodeGenerator) exception).getExitCode(); - } - return getExitCodeFromExitCodeGeneratorException(exception.getCause()); - } - - SpringBootExceptionHandler getSpringBootExceptionHandler() { - if (isMainThread(Thread.currentThread())) { - return SpringBootExceptionHandler.forCurrentThread(); - } - return null; - } - - private boolean isMainThread(Thread currentThread) { - return ("main".equals(currentThread.getName()) - || "restartedMain".equals(currentThread.getName())) - && "main".equals(currentThread.getThreadGroup().getName()); - } - - /** - * Returns the main application class that has been deduced or explicitly configured. - * @return the main application class or {@code null} - */ - public Class getMainApplicationClass() { - return this.mainApplicationClass; - } - - /** - * Set a specific main application class that will be used as a log source and to - * obtain version information. By default the main application class will be deduced. - * Can be set to {@code null} if there is no explicit application class. - * @param mainApplicationClass the mainApplicationClass to set or {@code null} - */ - public void setMainApplicationClass(Class mainApplicationClass) { - this.mainApplicationClass = mainApplicationClass; - } - - /** - * Returns whether this {@link SpringApplication} is running within a web environment. - * @return {@code true} if running within a web environment, otherwise {@code false}. - * @see #setWebEnvironment(boolean) - */ - public boolean isWebEnvironment() { - return this.webEnvironment; - } - - /** - * Sets if this application is running within a web environment. If not specified will - * attempt to deduce the environment based on the classpath. - * @param webEnvironment if the application is running in a web environment - */ - public void setWebEnvironment(boolean webEnvironment) { - this.webEnvironment = webEnvironment; - } - - /** - * Sets if the application is headless and should not instantiate AWT. Defaults to - * {@code true} to prevent java icons appearing. - * @param headless if the application is headless - */ - public void setHeadless(boolean headless) { - this.headless = headless; - } - - /** - * Sets if the created {@link ApplicationContext} should have a shutdown hook - * registered. Defaults to {@code true} to ensure that JVM shutdowns are handled - * gracefully. - * @param registerShutdownHook if the shutdown hook should be registered - */ - public void setRegisterShutdownHook(boolean registerShutdownHook) { - this.registerShutdownHook = registerShutdownHook; - } - - /** - * Sets the {@link Banner} instance which will be used to print the banner when no - * static banner file is provided. - * @param banner The Banner instance to use - */ - public void setBanner(Banner banner) { - this.banner = banner; - } - - /** - * Sets the mode used to display the banner when the application runs. Defaults to - * {@code Banner.Mode.CONSOLE}. - * @param bannerMode the mode used to display the banner - */ - public void setBannerMode(Banner.Mode bannerMode) { - this.bannerMode = bannerMode; - } - - /** - * Sets if the application information should be logged when the application starts. - * Defaults to {@code true}. - * @param logStartupInfo if startup info should be logged. - */ - public void setLogStartupInfo(boolean logStartupInfo) { - this.logStartupInfo = logStartupInfo; - } - - /** - * Sets if a {@link CommandLinePropertySource} should be added to the application - * context in order to expose arguments. Defaults to {@code true}. - * @param addCommandLineProperties if command line arguments should be exposed - */ - public void setAddCommandLineProperties(boolean addCommandLineProperties) { - this.addCommandLineProperties = addCommandLineProperties; - } - - /** - * Set default environment properties which will be used in addition to those in the - * existing {@link Environment}. - * @param defaultProperties the additional properties to set - */ - public void setDefaultProperties(Map defaultProperties) { - this.defaultProperties = defaultProperties; - } - - /** - * Convenient alternative to {@link #setDefaultProperties(Map)}. - * @param defaultProperties some {@link Properties} - */ - public void setDefaultProperties(Properties defaultProperties) { - this.defaultProperties = new HashMap(); - for (Object key : Collections.list(defaultProperties.propertyNames())) { - this.defaultProperties.put((String) key, defaultProperties.get(key)); - } - } - - /** - * Set additional profile values to use (on top of those set in system or command line - * properties). - * @param profiles the additional profiles to set - */ - public void setAdditionalProfiles(String... profiles) { - this.additionalProfiles = new LinkedHashSet(Arrays.asList(profiles)); - } - - /** - * Sets the bean name generator that should be used when generating bean names. - * @param beanNameGenerator the bean name generator - */ - public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) { - this.beanNameGenerator = beanNameGenerator; - } - - /** - * Sets the underlying environment that should be used with the created application - * context. - * @param environment the environment - */ - public void setEnvironment(ConfigurableEnvironment environment) { - this.environment = environment; - } - - /** - * Returns a mutable set of the sources that will be added to an ApplicationContext - * when {@link #run(String...)} is called. - * @return the sources the application sources. - * @see #SpringApplication(Object...) - */ - public Set getSources() { - return this.sources; - } - - /** - * The sources that will be used to create an ApplicationContext. A valid source is - * one of: a class, class name, package, package name, or an XML resource location. - * Can also be set using constructors and static convenience methods (e.g. - * {@link #run(Object[], String[])}). - *

- * NOTE: sources defined here will be used in addition to any sources specified on - * construction. - * @param sources the sources to set - * @see #SpringApplication(Object...) - */ - public void setSources(Set sources) { - Assert.notNull(sources, "Sources must not be null"); - this.sources.addAll(sources); - } - - /** - * Sets the {@link ResourceLoader} that should be used when loading resources. - * @param resourceLoader the resource loader - */ - public void setResourceLoader(ResourceLoader resourceLoader) { - Assert.notNull(resourceLoader, "ResourceLoader must not be null"); - this.resourceLoader = resourceLoader; - } - - /** - * Sets the type of Spring {@link ApplicationContext} that will be created. If not - * specified defaults to {@link #DEFAULT_WEB_CONTEXT_CLASS} for web based applications - * or {@link AnnotationConfigApplicationContext} for non web based applications. - * @param applicationContextClass the context class to set - */ - public void setApplicationContextClass( - Class applicationContextClass) { - this.applicationContextClass = applicationContextClass; - if (!isWebApplicationContext(applicationContextClass)) { - this.webEnvironment = false; - } - } - - private boolean isWebApplicationContext(Class applicationContextClass) { - try { - return WebApplicationContext.class.isAssignableFrom(applicationContextClass); - } - catch (NoClassDefFoundError ex) { - return false; - } - } - - /** - * Sets the {@link ApplicationContextInitializer} that will be applied to the Spring - * {@link ApplicationContext}. - * @param initializers the initializers to set - */ - public void setInitializers( - Collection> initializers) { - this.initializers = new ArrayList>(); - this.initializers.addAll(initializers); - } - - /** - * Add {@link ApplicationContextInitializer}s to be applied to the Spring - * {@link ApplicationContext}. - * @param initializers the initializers to add - */ - public void addInitializers(ApplicationContextInitializer... initializers) { - this.initializers.addAll(Arrays.asList(initializers)); - } - - /** - * Returns read-only ordered Set of the {@link ApplicationContextInitializer}s that - * will be applied to the Spring {@link ApplicationContext}. - * @return the initializers - */ - public Set> getInitializers() { - return asUnmodifiableOrderedSet(this.initializers); - } - - /** - * Sets the {@link ApplicationListener}s that will be applied to the SpringApplication - * and registered with the {@link ApplicationContext}. - * @param listeners the listeners to set - */ - public void setListeners(Collection> listeners) { - this.listeners = new ArrayList>(); - this.listeners.addAll(listeners); - } - - /** - * Add {@link ApplicationListener}s to be applied to the SpringApplication and - * registered with the {@link ApplicationContext}. - * @param listeners the listeners to add - */ - public void addListeners(ApplicationListener... listeners) { - this.listeners.addAll(Arrays.asList(listeners)); - } - - /** - * Returns read-only ordered Set of the {@link ApplicationListener}s that will be - * applied to the SpringApplication and registered with the {@link ApplicationContext} - * . - * @return the listeners - */ - public Set> getListeners() { - return asUnmodifiableOrderedSet(this.listeners); - } - - /** - * Static helper that can be used to run a {@link SpringApplication} from the - * specified source using default settings. - * @param source the source to load - * @param args the application arguments (usually passed from a Java main method) - * @return the running {@link ApplicationContext} - */ - public static ConfigurableApplicationContext run(Object source, String... args) { - return run(new Object[] { source }, args); - } - - /** - * Static helper that can be used to run a {@link SpringApplication} from the - * specified sources using default settings and user supplied arguments. - * @param sources the sources to load - * @param args the application arguments (usually passed from a Java main method) - * @return the running {@link ApplicationContext} - */ - public static ConfigurableApplicationContext run(Object[] sources, String[] args) { - return new SpringApplication(sources).run(args); - } - - /** - * A basic main that can be used to launch an application. This method is useful when - * application sources are defined via a {@literal --spring.main.sources} command line - * argument. - *

- * Most developers will want to define their own main method can call the - * {@link #run(Object, String...) run} method instead. - * @param args command line arguments - * @throws Exception if the application cannot be started - * @see SpringApplication#run(Object[], String[]) - * @see SpringApplication#run(Object, String...) - */ - public static void main(String[] args) throws Exception { - SpringApplication.run(new Object[0], args); - } - - /** - * Static helper that can be used to exit a {@link SpringApplication} and obtain a - * code indicating success (0) or otherwise. Does not throw exceptions but should - * print stack traces of any encountered. Applies the specified - * {@link ExitCodeGenerator} in addition to any Spring beans that implement - * {@link ExitCodeGenerator}. In the case of multiple exit codes the highest value - * will be used (or if all values are negative, the lowest value will be used) - * @param context the context to close if possible - * @param exitCodeGenerators exist code generators - * @return the outcome (0 if successful) - */ - public static int exit(ApplicationContext context, - ExitCodeGenerator... exitCodeGenerators) { - Assert.notNull(context, "Context must not be null"); - int exitCode = 0; - try { - try { - ExitCodeGenerators generators = new ExitCodeGenerators(); - Collection beans = context - .getBeansOfType(ExitCodeGenerator.class).values(); - generators.addAll(exitCodeGenerators); - generators.addAll(beans); - exitCode = generators.getExitCode(); - if (exitCode != 0) { - context.publishEvent(new ExitCodeEvent(context, exitCode)); - } - } - finally { - close(context); - } - - } - catch (Exception ex) { - ex.printStackTrace(); - exitCode = (exitCode == 0 ? 1 : exitCode); - } - return exitCode; - } - - private static void close(ApplicationContext context) { - if (context instanceof ConfigurableApplicationContext) { - ConfigurableApplicationContext closable = (ConfigurableApplicationContext) context; - closable.close(); - } - } - - private static Set asUnmodifiableOrderedSet(Collection elements) { - List list = new ArrayList(); - list.addAll(elements); - Collections.sort(list, AnnotationAwareOrderComparator.INSTANCE); - return new LinkedHashSet(list); - } - -} diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/enum-constructor.txt b/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/enum-constructor.txt deleted file mode 100644 index 5d6495d2..00000000 --- a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/enum-constructor.txt +++ /dev/null @@ -1,18 +0,0 @@ -package sample; - -public enum ExampleEnum { - - ONE("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", - "eleven", "twelve", "thirteen", "fourteen"), - - /** - * Two - */ - TWO("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", - "eleven", "twelve", "thirteen", "fourteen"); - - private ExampleEnum(String... args) { - - } - -} diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/method-wrap.txt b/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/method-wrap.txt deleted file mode 100644 index c1dde7af..00000000 --- a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/expected/method-wrap.txt +++ /dev/null @@ -1,11 +0,0 @@ -package simple; - -public class Simple { - - @Override - protected void doFilterInternal(HttpServletRequest request, - HttpServletResponse response, FilterChain chain) - throws ServletException, IOException { - } - -} \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/complex.txt b/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/complex.txt deleted file mode 100644 index b66b83f8..00000000 --- a/spring-javaformat/spring-javaformat-formatter/bin/src/test/resources/source/complex.txt +++ /dev/null @@ -1,1233 +0,0 @@ -/* - * Copyright 2012-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot; - -import java.lang.reflect.Constructor; -import java.security.AccessControlException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.BeanUtils; -import org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.BeanNameGenerator; -import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; -import org.springframework.boot.Banner.Mode; -import org.springframework.boot.diagnostics.FailureAnalyzers; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ApplicationListener; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.AnnotatedBeanDefinitionReader; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.AnnotationConfigUtils; -import org.springframework.context.annotation.ClassPathBeanDefinitionScanner; -import org.springframework.context.support.AbstractApplicationContext; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.core.GenericTypeResolver; -import org.springframework.core.annotation.AnnotationAwareOrderComparator; -import org.springframework.core.env.CommandLinePropertySource; -import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.Environment; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; -import org.springframework.core.env.SimpleCommandLinePropertySource; -import org.springframework.core.env.StandardEnvironment; -import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.core.io.Resource; -import org.springframework.core.io.ResourceLoader; -import org.springframework.core.io.support.SpringFactoriesLoader; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.ObjectUtils; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StopWatch; -import org.springframework.util.StringUtils; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.context.support.StandardServletEnvironment; - -/** - * Classes that can be used to bootstrap and launch a Spring application from a Java main - * method. By default class will perform the following steps to bootstrap your - * application: - * - *

    - *
  • Create an appropriate {@link ApplicationContext} instance (depending on your - * classpath)
  • - *
  • Register a {@link CommandLinePropertySource} to expose command line arguments as - * Spring properties
  • - *
  • Refresh the application context, loading all singleton beans
  • - *
  • Trigger any {@link CommandLineRunner} beans
  • - *
- * - * In most circumstances the static {@link #run(Object, String[])} method can be called - * directly from your {@literal main} method to bootstrap your application: - * - *
- * @Configuration
- * @EnableAutoConfiguration
- * public class MyApplication  {
- *
- * // ... Bean definitions
- *
- * public static void main(String[] args) throws Exception {
- *   SpringApplication.run(MyApplication.class, args);
- * }
- * 
- * - *

- * For more advanced configuration a {@link SpringApplication} instance can be created and - * customized before being run: - * - *

- * public static void main(String[] args) throws Exception {
- *   SpringApplication app = new SpringApplication(MyApplication.class);
- *   // ... customize app settings here
- *   app.run(args)
- * }
- * 
- * - * {@link SpringApplication}s can read beans from a variety of different sources. It is - * generally recommended that a single {@code @Configuration} class is used to bootstrap - * your application, however, any of the following sources can also be used: - * - *
    - *
  • {@link Class} - A Java class to be loaded by {@link AnnotatedBeanDefinitionReader} - *
  • - *
  • {@link Resource} - An XML resource to be loaded by {@link XmlBeanDefinitionReader}, - * or a groovy script to be loaded by {@link GroovyBeanDefinitionReader}
  • - *
  • {@link Package} - A Java package to be scanned by - * {@link ClassPathBeanDefinitionScanner}
  • - *
  • {@link CharSequence} - A class name, resource handle or package name to loaded as - * appropriate. If the {@link CharSequence} cannot be resolved to class and does not - * resolve to a {@link Resource} that exists it will be considered a {@link Package}.
  • - *
- * - * @author Phillip Webb - * @author Dave Syer - * @author Andy Wilkinson - * @author Christian Dupuis - * @author Stephane Nicoll - * @author Jeremy Rickard - * @author Craig Burke - * @author Michael Simons - * @see #run(Object, String[]) - * @see #run(Object[], String[]) - * @see #SpringApplication(Object...) - */ -public class SpringApplication { - - /** - * The class name of application context that will be used by default for non-web - * environments. - */ - public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context." - + "annotation.AnnotationConfigApplicationContext"; - - /** - * The class name of application context that will be used by default for web - * environments. - */ - public static final String DEFAULT_WEB_CONTEXT_CLASS = "org.springframework." - + "boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext"; - - private static final String[] WEB_ENVIRONMENT_CLASSES = { "javax.servlet.Servlet", - "org.springframework.web.context.ConfigurableWebApplicationContext" }; - - /** - * Default banner location. - */ - public static final String BANNER_LOCATION_PROPERTY_VALUE = SpringApplicationBannerPrinter.DEFAULT_BANNER_LOCATION; - - /** - * Banner location property key. - */ - public static final String BANNER_LOCATION_PROPERTY = SpringApplicationBannerPrinter.BANNER_LOCATION_PROPERTY; - - private static final String CONFIGURABLE_WEB_ENVIRONMENT_CLASS = "org.springframework.web.context.ConfigurableWebEnvironment"; - - private static final String SYSTEM_PROPERTY_JAVA_AWT_HEADLESS = "java.awt.headless"; - - private static final Set SERVLET_ENVIRONMENT_SOURCE_NAMES; - - static { - Set names = new HashSet(); - names.add(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME); - names.add(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME); - names.add(StandardServletEnvironment.JNDI_PROPERTY_SOURCE_NAME); - SERVLET_ENVIRONMENT_SOURCE_NAMES = Collections.unmodifiableSet(names); - } - - private static final Log logger = LogFactory.getLog(SpringApplication.class); - - private final Set sources = new LinkedHashSet(); - - private Class mainApplicationClass; - - private Banner.Mode bannerMode = Banner.Mode.CONSOLE; - - private boolean logStartupInfo = true; - - private boolean addCommandLineProperties = true; - - private Banner banner; - - private ResourceLoader resourceLoader; - - private BeanNameGenerator beanNameGenerator; - - private ConfigurableEnvironment environment; - - private Class applicationContextClass; - - private boolean webEnvironment; - - private boolean headless = true; - - private boolean registerShutdownHook = true; - - private List> initializers; - - private List> listeners; - - private Map defaultProperties; - - private Set additionalProfiles = new HashSet(); - - /** - * Create a new {@link SpringApplication} instance. The application context will load - * beans from the specified sources (see {@link SpringApplication class-level} - * documentation for details. The instance can be customized before calling - * {@link #run(String...)}. - * @param sources the bean sources - * @see #run(Object, String[]) - * @see #SpringApplication(ResourceLoader, Object...) - */ - public SpringApplication(Object... sources) { - initialize(sources); - } - - /** - * Create a new {@link SpringApplication} instance. The application context will load - * beans from the specified sources (see {@link SpringApplication class-level} - * documentation for details. The instance can be customized before calling - * {@link #run(String...)}. - * @param resourceLoader the resource loader to use - * @param sources the bean sources - * @see #run(Object, String[]) - * @see #SpringApplication(ResourceLoader, Object...) - */ - public SpringApplication(ResourceLoader resourceLoader, Object... sources) { - this.resourceLoader = resourceLoader; - initialize(sources); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private void initialize(Object[] sources) { - if (sources != null && sources.length > 0) { - this.sources.addAll(Arrays.asList(sources)); - } - this.webEnvironment = deduceWebEnvironment(); - setInitializers((Collection) getSpringFactoriesInstances( - ApplicationContextInitializer.class)); - setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); - this.mainApplicationClass = deduceMainApplicationClass(); - } - - private boolean deduceWebEnvironment() { - for (String className : WEB_ENVIRONMENT_CLASSES) { - if (!ClassUtils.isPresent(className, null)) { - return false; - } - } - return true; - } - - private Class deduceMainApplicationClass() { - try { - StackTraceElement[] stackTrace = new RuntimeException().getStackTrace(); - for (StackTraceElement stackTraceElement : stackTrace) { - if ("main".equals(stackTraceElement.getMethodName())) { - return Class.forName(stackTraceElement.getClassName()); - } - } - } - catch (ClassNotFoundException ex) { - // Swallow and continue - } - return null; - } - - /** - * Run the Spring application, creating and refreshing a new - * {@link ApplicationContext}. - * @param args the application arguments (usually passed from a Java main method) - * @return a running {@link ApplicationContext} - */ - public ConfigurableApplicationContext run(String... args) { - StopWatch stopWatch = new StopWatch(); - stopWatch.start(); - ConfigurableApplicationContext context = null; - FailureAnalyzers analyzers = null; - configureHeadlessProperty(); - SpringApplicationRunListeners listeners = getRunListeners(args); - listeners.starting(); - try { - ApplicationArguments applicationArguments = new DefaultApplicationArguments( - args); - ConfigurableEnvironment environment = prepareEnvironment(listeners, - applicationArguments); - Banner printedBanner = printBanner(environment); - context = createApplicationContext(); - analyzers = new FailureAnalyzers(context); - prepareContext(context, environment, listeners, applicationArguments, - printedBanner); - refreshContext(context); - afterRefresh(context, applicationArguments); - listeners.finished(context, null); - stopWatch.stop(); - if (this.logStartupInfo) { - new StartupInfoLogger(this.mainApplicationClass) - .logStarted(getApplicationLog(), stopWatch); - } - return context; - } - catch (Throwable ex) { - handleRunFailure(context, listeners, analyzers, ex); - throw new IllegalStateException(ex); - } - } - - private ConfigurableEnvironment prepareEnvironment( - SpringApplicationRunListeners listeners, - ApplicationArguments applicationArguments) { - // Create and configure the environment - ConfigurableEnvironment environment = getOrCreateEnvironment(); - configureEnvironment(environment, applicationArguments.getSourceArgs()); - listeners.environmentPrepared(environment); - if (isWebEnvironment(environment) && !this.webEnvironment) { - environment = convertToStandardEnvironment(environment); - } - return environment; - } - - private void prepareContext(ConfigurableApplicationContext context, - ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, - ApplicationArguments applicationArguments, Banner printedBanner) { - context.setEnvironment(environment); - postProcessApplicationContext(context); - applyInitializers(context); - listeners.contextPrepared(context); - if (this.logStartupInfo) { - logStartupInfo(context.getParent() == null); - logStartupProfileInfo(context); - } - - // Add boot specific singleton beans - context.getBeanFactory().registerSingleton("springApplicationArguments", - applicationArguments); - if (printedBanner != null) { - context.getBeanFactory().registerSingleton("springBootBanner", printedBanner); - } - - // Load the sources - Set sources = getSources(); - Assert.notEmpty(sources, "Sources must not be empty"); - load(context, sources.toArray(new Object[sources.size()])); - listeners.contextLoaded(context); - } - - private void refreshContext(ConfigurableApplicationContext context) { - refresh(context); - if (this.registerShutdownHook) { - try { - context.registerShutdownHook(); - } - catch (AccessControlException ex) { - // Not allowed in some environments. - } - } - } - - private void configureHeadlessProperty() { - System.setProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, System.getProperty( - SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, Boolean.toString(this.headless))); - } - - private SpringApplicationRunListeners getRunListeners(String[] args) { - Class[] types = new Class[] { SpringApplication.class, String[].class }; - return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances( - SpringApplicationRunListener.class, types, this, args)); - } - - private Collection getSpringFactoriesInstances(Class type) { - return getSpringFactoriesInstances(type, new Class[] {}); - } - - private Collection getSpringFactoriesInstances(Class type, - Class[] parameterTypes, Object... args) { - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - // Use names and ensure unique to protect against duplicates - Set names = new LinkedHashSet( - SpringFactoriesLoader.loadFactoryNames(type, classLoader)); - List instances = createSpringFactoriesInstances(type, parameterTypes, - classLoader, args, names); - AnnotationAwareOrderComparator.sort(instances); - return instances; - } - - @SuppressWarnings("unchecked") - private List createSpringFactoriesInstances(Class type, - Class[] parameterTypes, ClassLoader classLoader, Object[] args, - Set names) { - List instances = new ArrayList(names.size()); - for (String name : names) { - try { - Class instanceClass = ClassUtils.forName(name, classLoader); - Assert.isAssignable(type, instanceClass); - Constructor constructor = instanceClass - .getDeclaredConstructor(parameterTypes); - T instance = (T) BeanUtils.instantiateClass(constructor, args); - instances.add(instance); - } - catch (Throwable ex) { - throw new IllegalArgumentException( - "Cannot instantiate " + type + " : " + name, ex); - } - } - return instances; - } - - private ConfigurableEnvironment getOrCreateEnvironment() { - if (this.environment != null) { - return this.environment; - } - if (this.webEnvironment) { - return new StandardServletEnvironment(); - } - return new StandardEnvironment(); - } - - /** - * Template method delegating to - * {@link #configurePropertySources(ConfigurableEnvironment, String[])} and - * {@link #configureProfiles(ConfigurableEnvironment, String[])} in that order. - * Override this method for complete control over Environment customization, or one of - * the above for fine-grained control over property sources or profiles, respectively. - * @param environment this application's environment - * @param args arguments passed to the {@code run} method - * @see #configureProfiles(ConfigurableEnvironment, String[]) - * @see #configurePropertySources(ConfigurableEnvironment, String[]) - */ - protected void configureEnvironment(ConfigurableEnvironment environment, - String[] args) { - configurePropertySources(environment, args); - configureProfiles(environment, args); - } - - private boolean isWebEnvironment(ConfigurableEnvironment environment) { - try { - Class webEnvironmentClass = ClassUtils - .forName(CONFIGURABLE_WEB_ENVIRONMENT_CLASS, getClassLoader()); - return (webEnvironmentClass.isInstance(environment)); - } - catch (Throwable ex) { - return false; - } - } - - private ConfigurableEnvironment convertToStandardEnvironment( - ConfigurableEnvironment environment) { - StandardEnvironment result = new StandardEnvironment(); - removeAllPropertySources(result.getPropertySources()); - result.setActiveProfiles(environment.getActiveProfiles()); - for (PropertySource propertySource : environment.getPropertySources()) { - if (!SERVLET_ENVIRONMENT_SOURCE_NAMES.contains(propertySource.getName())) { - result.getPropertySources().addLast(propertySource); - } - } - return result; - } - - private void removeAllPropertySources(MutablePropertySources propertySources) { - Set names = new HashSet(); - for (PropertySource propertySource : propertySources) { - names.add(propertySource.getName()); - } - for (String name : names) { - propertySources.remove(name); - } - } - - /** - * Add, remove or re-order any {@link PropertySource}s in this application's - * environment. - * @param environment this application's environment - * @param args arguments passed to the {@code run} method - * @see #configureEnvironment(ConfigurableEnvironment, String[]) - */ - protected void configurePropertySources(ConfigurableEnvironment environment, - String[] args) { - MutablePropertySources sources = environment.getPropertySources(); - if (this.defaultProperties != null && !this.defaultProperties.isEmpty()) { - sources.addLast( - new MapPropertySource("defaultProperties", this.defaultProperties)); - } - if (this.addCommandLineProperties && args.length > 0) { - String name = CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME; - if (sources.contains(name)) { - PropertySource source = sources.get(name); - CompositePropertySource composite = new CompositePropertySource(name); - composite.addPropertySource(new SimpleCommandLinePropertySource( - name + "-" + args.hashCode(), args)); - composite.addPropertySource(source); - sources.replace(name, composite); - } - else { - sources.addFirst(new SimpleCommandLinePropertySource(args)); - } - } - } - - /** - * Configure which profiles are active (or active by default) for this application - * environment. Additional profiles may be activated during configuration file - * processing via the {@code spring.profiles.active} property. - * @param environment this application's environment - * @param args arguments passed to the {@code run} method - * @see #configureEnvironment(ConfigurableEnvironment, String[]) - * @see org.springframework.boot.context.config.ConfigFileApplicationListener - */ - protected void configureProfiles(ConfigurableEnvironment environment, String[] args) { - environment.getActiveProfiles(); // ensure they are initialized - // But these ones should go first (last wins in a property key clash) - Set profiles = new LinkedHashSet(this.additionalProfiles); - profiles.addAll(Arrays.asList(environment.getActiveProfiles())); - environment.setActiveProfiles(profiles.toArray(new String[profiles.size()])); - } - - private Banner printBanner(ConfigurableEnvironment environment) { - if (this.bannerMode == Banner.Mode.OFF) { - return null; - } - ResourceLoader resourceLoader = this.resourceLoader != null ? this.resourceLoader - : new DefaultResourceLoader(getClassLoader()); - SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter( - resourceLoader, this.banner); - if (this.bannerMode == Mode.LOG) { - return bannerPrinter.print(environment, this.mainApplicationClass, logger); - } - return bannerPrinter.print(environment, this.mainApplicationClass, System.out); - } - - /** - * Strategy method used to create the {@link ApplicationContext}. By default this - * method will respect any explicitly set application context or application context - * class before falling back to a suitable default. - * @return the application context (not yet refreshed) - * @see #setApplicationContextClass(Class) - */ - protected ConfigurableApplicationContext createApplicationContext() { - Class contextClass = this.applicationContextClass; - if (contextClass == null) { - try { - contextClass = Class.forName(this.webEnvironment - ? DEFAULT_WEB_CONTEXT_CLASS : DEFAULT_CONTEXT_CLASS); - } - catch (ClassNotFoundException ex) { - throw new IllegalStateException( - "Unable create a default ApplicationContext, " - + "please specify an ApplicationContextClass", - ex); - } - } - return (ConfigurableApplicationContext) BeanUtils.instantiate(contextClass); - } - - /** - * Apply any relevant post processing the {@link ApplicationContext}. Subclasses can - * apply additional processing as required. - * @param context the application context - */ - protected void postProcessApplicationContext(ConfigurableApplicationContext context) { - if (this.beanNameGenerator != null) { - context.getBeanFactory().registerSingleton( - AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, - this.beanNameGenerator); - } - if (this.resourceLoader != null) { - if (context instanceof GenericApplicationContext) { - ((GenericApplicationContext) context) - .setResourceLoader(this.resourceLoader); - } - if (context instanceof DefaultResourceLoader) { - ((DefaultResourceLoader) context) - .setClassLoader(this.resourceLoader.getClassLoader()); - } - } - } - - /** - * Apply any {@link ApplicationContextInitializer}s to the context before it is - * refreshed. - * @param context the configured ApplicationContext (not refreshed yet) - * @see ConfigurableApplicationContext#refresh() - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - protected void applyInitializers(ConfigurableApplicationContext context) { - for (ApplicationContextInitializer initializer : getInitializers()) { - Class requiredType = GenericTypeResolver.resolveTypeArgument( - initializer.getClass(), ApplicationContextInitializer.class); - Assert.isInstanceOf(requiredType, context, "Unable to call initializer."); - initializer.initialize(context); - } - } - - /** - * Called to log startup information, subclasses may override to add additional - * logging. - * @param isRoot true if this application is the root of a context hierarchy - */ - protected void logStartupInfo(boolean isRoot) { - if (isRoot) { - new StartupInfoLogger(this.mainApplicationClass) - .logStarting(getApplicationLog()); - } - } - - /** - * Called to log active profile information. - * @param context the application context - */ - protected void logStartupProfileInfo(ConfigurableApplicationContext context) { - Log log = getApplicationLog(); - if (log.isInfoEnabled()) { - String[] activeProfiles = context.getEnvironment().getActiveProfiles(); - if (ObjectUtils.isEmpty(activeProfiles)) { - String[] defaultProfiles = context.getEnvironment().getDefaultProfiles(); - log.info("No active profile set, falling back to default profiles: " - + StringUtils.arrayToCommaDelimitedString(defaultProfiles)); - } - else { - log.info("The following profiles are active: " - + StringUtils.arrayToCommaDelimitedString(activeProfiles)); - } - } - } - - /** - * Returns the {@link Log} for the application. By default will be deduced. - * @return the application log - */ - protected Log getApplicationLog() { - if (this.mainApplicationClass == null) { - return logger; - } - return LogFactory.getLog(this.mainApplicationClass); - } - - /** - * Load beans into the application context. - * @param context the context to load beans into - * @param sources the sources to load - */ - protected void load(ApplicationContext context, Object[] sources) { - if (logger.isDebugEnabled()) { - logger.debug( - "Loading source " + StringUtils.arrayToCommaDelimitedString(sources)); - } - BeanDefinitionLoader loader = createBeanDefinitionLoader( - getBeanDefinitionRegistry(context), sources); - if (this.beanNameGenerator != null) { - loader.setBeanNameGenerator(this.beanNameGenerator); - } - if (this.resourceLoader != null) { - loader.setResourceLoader(this.resourceLoader); - } - if (this.environment != null) { - loader.setEnvironment(this.environment); - } - loader.load(); - } - - /** - * The ResourceLoader that will be used in the ApplicationContext. - * @return the resourceLoader the resource loader that will be used in the - * ApplicationContext (or null if the default) - */ - public ResourceLoader getResourceLoader() { - return this.resourceLoader; - } - - /** - * Either the ClassLoader that will be used in the ApplicationContext (if - * {@link #setResourceLoader(ResourceLoader) resourceLoader} is set, or the context - * class loader (if not null), or the loader of the Spring {@link ClassUtils} class. - * @return a ClassLoader (never null) - */ - public ClassLoader getClassLoader() { - if (this.resourceLoader != null) { - return this.resourceLoader.getClassLoader(); - } - return ClassUtils.getDefaultClassLoader(); - } - - /** - * Get the bean definition registry. - * @param context the application context - * @return the BeanDefinitionRegistry if it can be determined - */ - private BeanDefinitionRegistry getBeanDefinitionRegistry(ApplicationContext context) { - if (context instanceof BeanDefinitionRegistry) { - return (BeanDefinitionRegistry) context; - } - if (context instanceof AbstractApplicationContext) { - return (BeanDefinitionRegistry) ((AbstractApplicationContext) context) - .getBeanFactory(); - } - throw new IllegalStateException("Could not locate BeanDefinitionRegistry"); - } - - /** - * Factory method used to create the {@link BeanDefinitionLoader}. - * @param registry the bean definition registry - * @param sources the sources to load - * @return the {@link BeanDefinitionLoader} that will be used to load beans - */ - protected BeanDefinitionLoader createBeanDefinitionLoader( - BeanDefinitionRegistry registry, Object[] sources) { - return new BeanDefinitionLoader(registry, sources); - } - - /** - * Refresh the underlying {@link ApplicationContext}. - * @param applicationContext the application context to refresh - */ - protected void refresh(ApplicationContext applicationContext) { - Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext); - ((AbstractApplicationContext) applicationContext).refresh(); - } - - /** - * Called after the context has been refreshed. - * @param context the application context - * @param args the application arguments - */ - protected void afterRefresh(ConfigurableApplicationContext context, - ApplicationArguments args) { - callRunners(context, args); - } - - private void callRunners(ApplicationContext context, ApplicationArguments args) { - List runners = new ArrayList(); - runners.addAll(context.getBeansOfType(ApplicationRunner.class).values()); - runners.addAll(context.getBeansOfType(CommandLineRunner.class).values()); - AnnotationAwareOrderComparator.sort(runners); - for (Object runner : new LinkedHashSet(runners)) { - if (runner instanceof ApplicationRunner) { - callRunner((ApplicationRunner) runner, args); - } - if (runner instanceof CommandLineRunner) { - callRunner((CommandLineRunner) runner, args); - } - } - } - - private void callRunner(ApplicationRunner runner, ApplicationArguments args) { - try { - (runner).run(args); - } - catch (Exception ex) { - throw new IllegalStateException("Failed to execute ApplicationRunner", ex); - } - } - - private void callRunner(CommandLineRunner runner, ApplicationArguments args) { - try { - (runner).run(args.getSourceArgs()); - } - catch (Exception ex) { - throw new IllegalStateException("Failed to execute CommandLineRunner", ex); - } - } - - private void handleRunFailure(ConfigurableApplicationContext context, - SpringApplicationRunListeners listeners, FailureAnalyzers analyzers, - Throwable exception) { - try { - try { - handleExitCode(context, exception); - listeners.finished(context, exception); - } - finally { - reportFailure(analyzers, exception); - if (context != null) { - context.close(); - } - } - } - catch (Exception ex) { - logger.warn("Unable to close ApplicationContext", ex); - } - ReflectionUtils.rethrowRuntimeException(exception); - } - - private void reportFailure(FailureAnalyzers analyzers, Throwable failure) { - try { - if (analyzers != null && analyzers.analyzeAndReport(failure)) { - registerLoggedException(failure); - return; - } - } - catch (Throwable ex) { - // Continue with normal handling of the original failure - } - if (logger.isErrorEnabled()) { - logger.error("Application startup failed", failure); - registerLoggedException(failure); - } - } - - /** - * Register that the given exception has been logged. By default, if the running in - * the main thread, this method will suppress additional printing of the stacktrace. - * @param exception the exception that was logged - */ - protected void registerLoggedException(Throwable exception) { - SpringBootExceptionHandler handler = getSpringBootExceptionHandler(); - if (handler != null) { - handler.registerLoggedException(exception); - } - } - - private void handleExitCode(ConfigurableApplicationContext context, - Throwable exception) { - int exitCode = getExitCodeFromException(context, exception); - if (exitCode != 0) { - if (context != null) { - context.publishEvent(new ExitCodeEvent(context, exitCode)); - } - SpringBootExceptionHandler handler = getSpringBootExceptionHandler(); - if (handler != null) { - handler.registerExitCode(exitCode); - } - } - } - - private int getExitCodeFromException(ConfigurableApplicationContext context, - Throwable exception) { - int exitCode = getExitCodeFromMappedException(context, exception); - if (exitCode == 0) { - exitCode = getExitCodeFromExitCodeGeneratorException(exception); - } - return exitCode; - } - - private int getExitCodeFromMappedException(ConfigurableApplicationContext context, - Throwable exception) { - if (context == null || !context.isActive()) { - return 0; - } - ExitCodeGenerators generators = new ExitCodeGenerators(); - Collection beans = context - .getBeansOfType(ExitCodeExceptionMapper.class).values(); - generators.addAll(exception, beans); - return generators.getExitCode(); - } - - private int getExitCodeFromExitCodeGeneratorException(Throwable exception) { - if (exception == null) { - return 0; - } - if (exception instanceof ExitCodeGenerator) { - return ((ExitCodeGenerator) exception).getExitCode(); - } - return getExitCodeFromExitCodeGeneratorException(exception.getCause()); - } - - SpringBootExceptionHandler getSpringBootExceptionHandler() { - if (isMainThread(Thread.currentThread())) { - return SpringBootExceptionHandler.forCurrentThread(); - } - return null; - } - - private boolean isMainThread(Thread currentThread) { - return ("main".equals(currentThread.getName()) - || "restartedMain".equals(currentThread.getName())) - && "main".equals(currentThread.getThreadGroup().getName()); - } - - /** - * Returns the main application class that has been deduced or explicitly configured. - * @return the main application class or {@code null} - */ - public Class getMainApplicationClass() { - return this.mainApplicationClass; - } - - /** - * Set a specific main application class that will be used as a log source and to - * obtain version information. By default the main application class will be deduced. - * Can be set to {@code null} if there is no explicit application class. - * @param mainApplicationClass the mainApplicationClass to set or {@code null} - */ - public void setMainApplicationClass(Class mainApplicationClass) { - this.mainApplicationClass = mainApplicationClass; - } - - /** - * Returns whether this {@link SpringApplication} is running within a web environment. - * @return {@code true} if running within a web environment, otherwise {@code false}. - * @see #setWebEnvironment(boolean) - */ - public boolean isWebEnvironment() { - return this.webEnvironment; - } - - /** - * Sets if this application is running within a web environment. If not specified will - * attempt to deduce the environment based on the classpath. - * @param webEnvironment if the application is running in a web environment - */ - public void setWebEnvironment(boolean webEnvironment) { - this.webEnvironment = webEnvironment; - } - - /** - * Sets if the application is headless and should not instantiate AWT. Defaults to - * {@code true} to prevent java icons appearing. - * @param headless if the application is headless - */ - public void setHeadless(boolean headless) { - this.headless = headless; - } - - /** - * Sets if the created {@link ApplicationContext} should have a shutdown hook - * registered. Defaults to {@code true} to ensure that JVM shutdowns are handled - * gracefully. - * @param registerShutdownHook if the shutdown hook should be registered - */ - public void setRegisterShutdownHook(boolean registerShutdownHook) { - this.registerShutdownHook = registerShutdownHook; - } - - /** - * Sets the {@link Banner} instance which will be used to print the banner when no - * static banner file is provided. - * @param banner The Banner instance to use - */ - public void setBanner(Banner banner) { - this.banner = banner; - } - - /** - * Sets the mode used to display the banner when the application runs. Defaults to - * {@code Banner.Mode.CONSOLE}. - * @param bannerMode the mode used to display the banner - */ - public void setBannerMode(Banner.Mode bannerMode) { - this.bannerMode = bannerMode; - } - - /** - * Sets if the application information should be logged when the application starts. - * Defaults to {@code true}. - * @param logStartupInfo if startup info should be logged. - */ - public void setLogStartupInfo(boolean logStartupInfo) { - this.logStartupInfo = logStartupInfo; - } - - /** - * Sets if a {@link CommandLinePropertySource} should be added to the application - * context in order to expose arguments. Defaults to {@code true}. - * @param addCommandLineProperties if command line arguments should be exposed - */ - public void setAddCommandLineProperties(boolean addCommandLineProperties) { - this.addCommandLineProperties = addCommandLineProperties; - } - - /** - * Set default environment properties which will be used in addition to those in the - * existing {@link Environment}. - * @param defaultProperties the additional properties to set - */ - public void setDefaultProperties(Map defaultProperties) { - this.defaultProperties = defaultProperties; - } - - /** - * Convenient alternative to {@link #setDefaultProperties(Map)}. - * @param defaultProperties some {@link Properties} - */ - public void setDefaultProperties(Properties defaultProperties) { - this.defaultProperties = new HashMap(); - for (Object key : Collections.list(defaultProperties.propertyNames())) { - this.defaultProperties.put((String) key, defaultProperties.get(key)); - } - } - - /** - * Set additional profile values to use (on top of those set in system or command line - * properties). - * @param profiles the additional profiles to set - */ - public void setAdditionalProfiles(String... profiles) { - this.additionalProfiles = new LinkedHashSet(Arrays.asList(profiles)); - } - - /** - * Sets the bean name generator that should be used when generating bean names. - * @param beanNameGenerator the bean name generator - */ - public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) { - this.beanNameGenerator = beanNameGenerator; - } - - /** - * Sets the underlying environment that should be used with the created application - * context. - * @param environment the environment - */ - public void setEnvironment(ConfigurableEnvironment environment) { - this.environment = environment; - } - - /** - * Returns a mutable set of the sources that will be added to an ApplicationContext - * when {@link #run(String...)} is called. - * @return the sources the application sources. - * @see #SpringApplication(Object...) - */ - public Set getSources() { - return this.sources; - } - - /** - * The sources that will be used to create an ApplicationContext. A valid source is - * one of: a class, class name, package, package name, or an XML resource location. - * Can also be set using constructors and static convenience methods (e.g. - * {@link #run(Object[], String[])}). - *

- * NOTE: sources defined here will be used in addition to any sources specified on - * construction. - * @param sources the sources to set - * @see #SpringApplication(Object...) - */ - public void setSources(Set sources) { - Assert.notNull(sources, "Sources must not be null"); - this.sources.addAll(sources); - } - - /** - * Sets the {@link ResourceLoader} that should be used when loading resources. - * @param resourceLoader the resource loader - */ - public void setResourceLoader(ResourceLoader resourceLoader) { - Assert.notNull(resourceLoader, "ResourceLoader must not be null"); - this.resourceLoader = resourceLoader; - } - - /** - * Sets the type of Spring {@link ApplicationContext} that will be created. If not - * specified defaults to {@link #DEFAULT_WEB_CONTEXT_CLASS} for web based applications - * or {@link AnnotationConfigApplicationContext} for non web based applications. - * @param applicationContextClass the context class to set - */ - public void setApplicationContextClass( - Class applicationContextClass) { - this.applicationContextClass = applicationContextClass; - if (!isWebApplicationContext(applicationContextClass)) { - this.webEnvironment = false; - } - } - - private boolean isWebApplicationContext(Class applicationContextClass) { - try { - return WebApplicationContext.class.isAssignableFrom(applicationContextClass); - } - catch (NoClassDefFoundError ex) { - return false; - } - } - - /** - * Sets the {@link ApplicationContextInitializer} that will be applied to the Spring - * {@link ApplicationContext}. - * @param initializers the initializers to set - */ - public void setInitializers( - Collection> initializers) { - this.initializers = new ArrayList>(); - this.initializers.addAll(initializers); - } - - /** - * Add {@link ApplicationContextInitializer}s to be applied to the Spring - * {@link ApplicationContext}. - * @param initializers the initializers to add - */ - public void addInitializers(ApplicationContextInitializer... initializers) { - this.initializers.addAll(Arrays.asList(initializers)); - } - - /** - * Returns read-only ordered Set of the {@link ApplicationContextInitializer}s that - * will be applied to the Spring {@link ApplicationContext}. - * @return the initializers - */ - public Set> getInitializers() { - return asUnmodifiableOrderedSet(this.initializers); - } - - /** - * Sets the {@link ApplicationListener}s that will be applied to the SpringApplication - * and registered with the {@link ApplicationContext}. - * @param listeners the listeners to set - */ - public void setListeners(Collection> listeners) { - this.listeners = new ArrayList>(); - this.listeners.addAll(listeners); - } - - /** - * Add {@link ApplicationListener}s to be applied to the SpringApplication and - * registered with the {@link ApplicationContext}. - * @param listeners the listeners to add - */ - public void addListeners(ApplicationListener... listeners) { - this.listeners.addAll(Arrays.asList(listeners)); - } - - /** - * Returns read-only ordered Set of the {@link ApplicationListener}s that will be - * applied to the SpringApplication and registered with the {@link ApplicationContext} - * . - * @return the listeners - */ - public Set> getListeners() { - return asUnmodifiableOrderedSet(this.listeners); - } - - /** - * Static helper that can be used to run a {@link SpringApplication} from the - * specified source using default settings. - * @param source the source to load - * @param args the application arguments (usually passed from a Java main method) - * @return the running {@link ApplicationContext} - */ - public static ConfigurableApplicationContext run(Object source, String... args) { - return run(new Object[] { source }, args); - } - - /** - * Static helper that can be used to run a {@link SpringApplication} from the - * specified sources using default settings and user supplied arguments. - * @param sources the sources to load - * @param args the application arguments (usually passed from a Java main method) - * @return the running {@link ApplicationContext} - */ - public static ConfigurableApplicationContext run(Object[] sources, String[] args) { - return new SpringApplication(sources).run(args); - } - - /** - * A basic main that can be used to launch an application. This method is useful when - * application sources are defined via a {@literal --spring.main.sources} command line - * argument. - *

- * Most developers will want to define their own main method can call the - * {@link #run(Object, String...) run} method instead. - * @param args command line arguments - * @throws Exception if the application cannot be started - * @see SpringApplication#run(Object[], String[]) - * @see SpringApplication#run(Object, String...) - */ - public static void main(String[] args) throws Exception { - SpringApplication.run(new Object[0], args); - } - - /** - * Static helper that can be used to exit a {@link SpringApplication} and obtain a - * code indicating success (0) or otherwise. Does not throw exceptions but should - * print stack traces of any encountered. Applies the specified - * {@link ExitCodeGenerator} in addition to any Spring beans that implement - * {@link ExitCodeGenerator}. In the case of multiple exit codes the highest value - * will be used (or if all values are negative, the lowest value will be used) - * @param context the context to close if possible - * @param exitCodeGenerators exist code generators - * @return the outcome (0 if successful) - */ - public static int exit(ApplicationContext context, - ExitCodeGenerator... exitCodeGenerators) { - Assert.notNull(context, "Context must not be null"); - int exitCode = 0; - try { - try { - ExitCodeGenerators generators = new ExitCodeGenerators(); - Collection beans = context - .getBeansOfType(ExitCodeGenerator.class).values(); - generators.addAll(exitCodeGenerators); - generators.addAll(beans); - exitCode = generators.getExitCode(); - if (exitCode != 0) { - context.publishEvent(new ExitCodeEvent(context, exitCode)); - } - } - finally { - close(context); - } - - } - catch (Exception ex) { - ex.printStackTrace(); - exitCode = (exitCode == 0 ? 1 : exitCode); - } - return exitCode; - } - - private static void close(ApplicationContext context) { - if (context instanceof ConfigurableApplicationContext) { - ConfigurableApplicationContext closable = (ConfigurableApplicationContext) context; - closable.close(); - } - } - - private static Set asUnmodifiableOrderedSet(Collection elements) { - List list = new ArrayList(); - list.addAll(elements); - Collections.sort(list, AnnotationAwareOrderComparator.INSTANCE); - return new LinkedHashSet(list); - } - -} diff --git a/spring-javaformat/spring-javaformat-formatter/pom.xml b/spring-javaformat/spring-javaformat-formatter/pom.xml index f4c0dfa2..d4642459 100644 --- a/spring-javaformat/spring-javaformat-formatter/pom.xml +++ b/spring-javaformat/spring-javaformat-formatter/pom.xml @@ -1,12 +1,12 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.spring.javaformat spring-javaformat - 0.0.7-SNAPSHOT + 0.0.48-SNAPSHOT spring-javaformat-formatter Spring JavaFormat Formatter @@ -17,7 +17,17 @@ io.spring.javaformat - spring-javaformat-formatter-eclipse + spring-javaformat-config + ${project.version} + + + io.spring.javaformat + spring-javaformat-formatter-eclipse-jdt-jdk8 + ${project.version} + + + io.spring.javaformat + 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 433332ad..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -20,45 +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(); @@ -70,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 c55dccb4..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -25,6 +25,8 @@ import org.eclipse.text.edits.TextEdit; +import io.spring.javaformat.config.JavaFormatConfig; + /** * A code formatter designed to work with {@link File Files}. * @@ -39,13 +41,12 @@ public FileFormatter() { this(new Formatter()); } - public FileFormatter(FormatterOption... options) { - this(new Formatter(options)); + public FileFormatter(JavaFormatConfig javaFormatConfig) { + this(new Formatter(javaFormatConfig)); } public FileFormatter(Formatter formatter) { - Optional.ofNullable(formatter).orElseThrow( - () -> new IllegalArgumentException("Formatter must not be null")); + Optional.ofNullable(formatter).orElseThrow(() -> new IllegalArgumentException("Formatter must not be null")); this.formatter = formatter; } @@ -54,10 +55,22 @@ 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(StreamSupport.stream(files.spliterator(), false), encoding); + return formatFiles(files, encoding, Formatter.DEFAULT_LINE_SEPARATOR); + } + + /** + * Format the given source files and provide a {@link Stream} of {@link FileEdit} + * instances. + * @param files the files to format + * @param encoding the source encoding + * @param lineSeparator the line separator + * @return a stream of file edits + */ + public Stream formatFiles(Iterable files, Charset encoding, String lineSeparator) { + return formatFiles(StreamSupport.stream(files.spliterator(), false), encoding, lineSeparator); } /** @@ -65,22 +78,45 @@ public Stream formatFiles(Iterable files, Charset encoding) { * 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 files.map((file) -> formatFile(file, encoding)); + return formatFiles(files, encoding, Formatter.DEFAULT_LINE_SEPARATOR); } /** - * Format the the given source file and return a {@link FileEdit} instance. + * Format the given source files and provide a {@link Stream} of {@link FileEdit} + * instances. + * @param files the files to format + * @param encoding the source encoding + * @param lineSeparator the line separator + * @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 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 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 file edit + */ + public FileEdit formatFile(File file, Charset encoding, String lineSeparator) { try { String content = new String(Files.readAllBytes(file.toPath()), encoding); - TextEdit edit = this.formatter.format(content); + TextEdit edit = this.formatter.format(content, lineSeparator); return new FileEdit(file, encoding, content, edit); } catch (Exception ex) { 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 267e3ff4..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, 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 25140e34..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,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -16,35 +16,40 @@ package io.spring.javaformat.formatter; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.function.Supplier; - -import io.spring.javaformat.formatter.eclipse.ExtendedCodeFormatter; -import io.spring.javaformat.formatter.eclipse.Preparator; -import io.spring.javaformat.formatter.preparator.Preparators; -import org.eclipse.jdt.core.formatter.CodeFormatter; + import org.eclipse.jface.text.IRegion; import org.eclipse.text.edits.TextEdit; +import io.spring.javaformat.config.JavaBaseline; +import io.spring.javaformat.config.JavaFormatConfig; +import io.spring.javaformat.formatter.eclipse.EclipseCodeFormatter; +import io.spring.javaformat.formatter.jdk17.eclipse.EclipseJdk17CodeFormatter; +import io.spring.javaformat.formatter.jdk8.eclipse.EclipseJdk8CodeFormatter; + /** - * A {@link CodeFormatter} that applies Spring formatting conventions. + * A code formatter that applies Spring formatting conventions. * * @author Phillip Webb */ -public class Formatter extends CodeFormatter { +public class Formatter { + + /** + * Kind used to format a compilation unit. See Eclipse {@code CodeFormatter} + * constants. + */ + private static final int K_COMPILATION_UNIT = 0x08; + + /** + * Flag used to include the comments during the formatting of the code snippet. See + * Eclipse {@code CodeFormatter} constants. + */ + private static final int F_INCLUDE_COMMENTS = 0x1000; /** * The components that will be formatted by default. */ - private static final int DEFAULT_COMPONENTS = CodeFormatter.K_COMPILATION_UNIT - | CodeFormatter.F_INCLUDE_COMMENTS; + private static final int DEFAULT_COMPONENTS = K_COMPILATION_UNIT | F_INCLUDE_COMMENTS; /** * The default indentation level. @@ -54,25 +59,24 @@ public class Formatter extends CodeFormatter { /** * The default line separator. */ - private static final String DEFAULT_LINE_SEPARATOR = null; - - private final Set options; + public static final String DEFAULT_LINE_SEPARATOR = null; - private CodeFormatter delegate = new DelegateCodeFormatter(); + private final EclipseCodeFormatter delegate; /** * Create a new formatter instance. */ public Formatter() { - this.options = Collections.emptySet(); + this(JavaFormatConfig.DEFAULT); } /** * Create a new formatter instance. - * @param options formatter options + * @param javaFormatConfig the java format config to use */ - public Formatter(FormatterOption... options) { - this.options = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(options))); + public Formatter(JavaFormatConfig javaFormatConfig) { + this.delegate = javaFormatConfig.getJavaBaseline() == JavaBaseline.V8 + ? new EclipseJdk8CodeFormatter(javaFormatConfig) : new EclipseJdk17CodeFormatter(javaFormatConfig); } /** @@ -81,7 +85,17 @@ public Formatter(FormatterOption... options) { * @return the text edit */ public TextEdit format(String source) { - return format(source, 0, source.length()); + return format(source, DEFAULT_LINE_SEPARATOR); + } + + /** + * Format the given source content. + * @param source the source content to format + * @param lineSeparator the line separator + * @return the text edit + */ + public TextEdit format(String source, String lineSeparator) { + return format(source, 0, source.length(), lineSeparator); } /** @@ -92,17 +106,25 @@ public TextEdit format(String source) { * @return the text edit */ public TextEdit format(String source, int offset, int length) { - return format(DEFAULT_COMPONENTS, source, offset, length, - DEFAULT_INDENTATION_LEVEL, DEFAULT_LINE_SEPARATOR); + return format(source, offset, length, DEFAULT_LINE_SEPARATOR); } - @Override - public TextEdit format(int kind, String source, int offset, int length, - int indentationLevel, String lineSeparator) { - return nlsSafe(() -> { - return this.delegate.format(kind, source, offset, length, indentationLevel, - lineSeparator); - }); + /** + * Format a specific subsection of the given source content. + * @param source the source content to format + * @param offset the offset to start formatting + * @param length the length to format + * @param lineSeparator the line separator + * @return the text edit + */ + public TextEdit format(String source, int offset, int length, String lineSeparator) { + return format(DEFAULT_COMPONENTS, source, offset, length, DEFAULT_INDENTATION_LEVEL, lineSeparator); + } + + 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); } /** @@ -112,72 +134,46 @@ public TextEdit format(int kind, String source, int offset, int length, * @return the text edit */ public TextEdit format(String source, IRegion[] regions) { - return format(DEFAULT_COMPONENTS, source, regions, DEFAULT_INDENTATION_LEVEL, - DEFAULT_LINE_SEPARATOR); + return format(source, regions, DEFAULT_LINE_SEPARATOR); } - @Override - public TextEdit format(int kind, String source, IRegion[] regions, - int indentationLevel, String lineSeparator) { - return nlsSafe(() -> this.delegate.format(kind, source, regions, indentationLevel, - lineSeparator)); + /** + * Format specific subsections of the given source content. + * @param source the source content to format + * @param regions the regions to format + * @param lineSeparator the line separator + * @return the text edit + */ + public TextEdit format(String source, IRegion[] regions, String lineSeparator) { + return format(DEFAULT_COMPONENTS, source, regions, DEFAULT_INDENTATION_LEVEL, 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); } - @Override public String createIndentationString(int indentationLevel) { return this.delegate.createIndentationString(indentationLevel); } - @Override public void setOptions(Map options) { this.delegate.setOptions(options); } - private T nlsSafe(Supplier formatted) { - if (this.options.contains(FormatterOption.SHOW_NLS_WARNINGS)) { - return formatted.get(); - } - String nlsWarnings = System.getProperty("osgi.nls.warnings"); - try { - System.setProperty("osgi.nls.warnings", "ignore"); - return formatted.get(); - } - finally { - if (nlsWarnings != null) { - System.setProperty("osgi.nls.warnings", nlsWarnings); - } - } - - } - - /** - * Internal delegate code formatter to apply Spring {@literal formatter.prefs} and add - * {@link Preparator Preparators}. - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - private static class DelegateCodeFormatter extends ExtendedCodeFormatter { - - static Map OPTIONS; - - static { - try { - Properties properties = new Properties(); - try (InputStream inputStream = Formatter.class - .getResourceAsStream("formatter.prefs")) { - properties.load(inputStream); - OPTIONS = (Map) Collections.unmodifiableMap(properties); - } + 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"; } - catch (IOException ex) { - throw new IllegalStateException(ex); + if (ch == '\n') { + return "\n"; } } - - DelegateCodeFormatter() { - super(OPTIONS); - Preparators.forEach(this::addPreparator); - } - + 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 new file mode 100644 index 00000000..121ddc4a --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/eclipse/EclipseCodeFormatter.java @@ -0,0 +1,39 @@ +/* + * 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.eclipse; + +import java.util.Map; + +import org.eclipse.jface.text.IRegion; +import org.eclipse.text.edits.TextEdit; + +/** + * Internal interface used to access an Eclipse {@code CodeFormatter} implementation. + * + * @author Phillip Webb + */ +public interface EclipseCodeFormatter { + + TextEdit format(int kind, String source, int offset, int length, int indentationLevel, String lineSeparator); + + TextEdit format(int kind, String source, IRegion[] regions, int indentationLevel, String lineSeparator); + + String createIndentationString(int indentationLevel); + + void setOptions(Map options); + +} 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 new file mode 100644 index 00000000..b80c0346 --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/eclipse/Options.java @@ -0,0 +1,72 @@ +/* + * 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.eclipse; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Properties; + +import io.spring.javaformat.config.IndentationStyle; +import io.spring.javaformat.config.JavaFormatConfig; + +/** + * Utility class used to load formatter options. + * + * @author Phillip Webb + */ +public class Options { + + private final String prefix; + + public Options(String prefix) { + this.prefix = prefix; + } + + public Map load(JavaFormatConfig javaFormatConfig) { + try { + Map properties = loadProperties(); + applyConfig(properties, javaFormatConfig); + return Collections.unmodifiableMap(properties); + } + catch (IOException ex) { + throw new IllegalStateException(ex); + } + } + + private Map loadProperties() throws IOException { + Properties properties = new Properties(); + try (InputStream inputStream = getClass().getResourceAsStream("formatter.prefs")) { + properties.load(inputStream); + } + Map prefixedProperties = new LinkedHashMap<>(); + for (Map.Entry entry : properties.entrySet()) { + prefixedProperties.put(this.prefix + "." + entry.getKey(), (String) entry.getValue()); + } + return prefixedProperties; + } + + private void applyConfig(Map properties, JavaFormatConfig javaFormatConfig) { + String coreFormatter = this.prefix + ".core.formatter."; + if (javaFormatConfig.getIndentationStyle() == IndentationStyle.SPACES) { + properties.put(coreFormatter + "tabulation.char", "space"); + } + } + +} diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk17/eclipse/CodeLineBreakPreparator.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk17/eclipse/CodeLineBreakPreparator.java new file mode 100644 index 00000000..3f5a7337 --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk17/eclipse/CodeLineBreakPreparator.java @@ -0,0 +1,121 @@ +/* + * 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 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 finetune curly-brace line breaks. + * + * @author Phillip Webb + */ +class CodeLineBreakPreparator implements Preparator { + + @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; + + Vistor(TokenManager tokenManager) { + this.tokenManager = tokenManager; + } + + @Override + public boolean visit(TypeDeclaration node) { + visitType(node); + return true; + } + + @Override + public boolean visit(AnnotationTypeDeclaration node) { + visitType(node); + return true; + } + + @Override + public boolean visit(EnumDeclaration node) { + visitType(node); + return true; + } + + private void visitType(AbstractTypeDeclaration node) { + SimpleName name = node.getName(); + int openBraceIndex = (name == null ? this.tokenManager.firstIndexIn(node, TerminalTokens.TokenNameLBRACE) + : this.tokenManager.firstIndexAfter(name, TerminalTokens.TokenNameLBRACE)); + Token openBraceToken = this.tokenManager.get(openBraceIndex); + openBraceToken.clearLineBreaksAfter(); + openBraceToken.putLineBreaksAfter(2); + int closeBraceIndex = this.tokenManager.lastIndexIn(node, TerminalTokens.TokenNameRBRACE); + Token closeBraceToken = this.tokenManager.get(closeBraceIndex); + closeBraceToken.clearLineBreaksBefore(); + closeBraceToken.putLineBreaksBefore(2); + } + + @Override + public boolean visit(FieldDeclaration node) { + int index = this.tokenManager.lastIndexIn(node, TerminalTokens.TokenNameSEMICOLON); + while (tokenIsOfType(index + 1, TerminalTokens.TokenNameCOMMENT_LINE, + TerminalTokens.TokenNameCOMMENT_BLOCK)) { + if (this.tokenManager.get(index).getLineBreaksAfter() > 0 + || this.tokenManager.get(index + 1).getLineBreaksBefore() > 0) { + break; + } + index++; + } + Token token = this.tokenManager.get(index); + if (tokenIsOfType(index + 1, TerminalTokens.TokenNamestatic)) { + return true; + } + token.clearLineBreaksAfter(); + token.putLineBreaksAfter(2); + return true; + } + + private boolean tokenIsOfType(int index, int... types) { + if (index < this.tokenManager.size()) { + Token token = this.tokenManager.get(index); + for (int type : types) { + if (token.tokenType == type) { + return true; + } + } + } + return false; + } + + } + +} diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk17/eclipse/EclipseJdk17CodeFormatter.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk17/eclipse/EclipseJdk17CodeFormatter.java new file mode 100644 index 00000000..a7530156 --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk17/eclipse/EclipseJdk17CodeFormatter.java @@ -0,0 +1,54 @@ +/* + * 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.Map; + +import io.spring.javaformat.config.JavaFormatConfig; +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 17 baseline {@link EclipseCodeFormatter} to apply Spring + * {@literal formatter.prefs} and add {@link Preparator Preparators}. + * + * @author Phillip Webb + */ +public class EclipseJdk17CodeFormatter extends ExtendedCodeFormatter implements EclipseCodeFormatter { + + private final Map appliedOptions; + + public EclipseJdk17CodeFormatter(JavaFormatConfig javaFormatConfig) { + this(new Options("io.spring.javaformat.eclipse.jdt.jdk17").load(javaFormatConfig)); + } + + EclipseJdk17CodeFormatter(Map options) { + super(options); + this.appliedOptions = options; + addPreparator(new JavadocLineBreakPreparator()); + addPreparator(new CodeLineBreakPreparator()); + addPreparator(new JSpecifyPreparator()); + } + + @Override + public void setOptions(Map options) { + super.setOptions(this.appliedOptions); + } + +} 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 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/jdk17/eclipse/JavadocLineBreakPreparator.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk17/eclipse/JavadocLineBreakPreparator.java new file mode 100644 index 00000000..28b369c7 --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk17/eclipse/JavadocLineBreakPreparator.java @@ -0,0 +1,133 @@ +/* + * 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.ArrayList; +import java.util.Collections; +import java.util.List; + +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 finetune Javadoc whitespace. + * + * @author Phillip Webb + */ +class JavadocLineBreakPreparator implements Preparator { + + private final static List PARAM_TAGS; + + static { + List paramTags = new ArrayList(); + paramTags.add(TagElement.TAG_PARAM); + paramTags.add(TagElement.TAG_EXCEPTION); + paramTags.add(TagElement.TAG_SERIALFIELD); + paramTags.add(TagElement.TAG_THROWS); + paramTags.add(TagElement.TAG_RETURN); + paramTags.add(TagElement.TAG_DEPRECATED); + PARAM_TAGS = Collections.unmodifiableList(paramTags); + } + + @Override + public void apply(int kind, TokenManager tokenManager, ASTNode astRoot) { + if ((kind & CodeFormatter.F_INCLUDE_COMMENTS) != 0) { + ASTVisitor visitor = new Vistor(tokenManager); + for (Comment comment : getComments(astRoot)) { + comment.accept(visitor); + } + } + } + + @SuppressWarnings("unchecked") + private List getComments(ASTNode astRoot) { + if (astRoot.getRoot() instanceof CompilationUnit) { + CompilationUnit compilationUnit = (CompilationUnit) astRoot.getRoot(); + return compilationUnit.getCommentList(); + } + return Collections.emptyList(); + } + + private static class Vistor extends ASTVisitor { + + private final TokenManager tokenManager; + + private TokenManager commentTokenManager; + + private ASTNode declaration; + + private boolean firstTagElement; + + private boolean hasText; + + Vistor(TokenManager tokenManager) { + this.tokenManager = tokenManager; + } + + @Override + public boolean visit(Javadoc node) { + int commentIndex = this.tokenManager.firstIndexIn(node, TerminalTokens.TokenNameCOMMENT_JAVADOC); + Token commentToken = this.tokenManager.get(commentIndex); + this.commentTokenManager = (commentToken.getInternalStructure() != null) + ? new TokenManager(commentToken.getInternalStructure(), this.tokenManager) : null; + this.declaration = node.getParent(); + this.firstTagElement = true; + this.hasText = false; + return true; + } + + @Override + public boolean visit(TextElement node) { + this.hasText = true; + return true; + } + + @Override + public boolean visit(TagElement node) { + 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(); + 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 AbstractTypeDeclaration) { + String tagName = node.getTagName(); + return (!node.isNested() && tagName != null && tagName.startsWith("@")); + } + return PARAM_TAGS.contains(node.getTagName()); + } + + } + +} diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/preparator/CodeLineBreakPreparator.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/CodeLineBreakPreparator.java similarity index 62% rename from spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/preparator/CodeLineBreakPreparator.java rename to spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/CodeLineBreakPreparator.java index fbb5a38e..2cb2ef68 100644 --- a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/preparator/CodeLineBreakPreparator.java +++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/CodeLineBreakPreparator.java @@ -1,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,24 +14,24 @@ * limitations under the License. */ -package io.spring.javaformat.formatter.preparator; +package io.spring.javaformat.formatter.jdk8.eclipse; -import io.spring.javaformat.formatter.eclipse.Preparator; -import io.spring.javaformat.formatter.eclipse.Token; -import io.spring.javaformat.formatter.eclipse.TokenManager; -import org.eclipse.jdt.core.dom.ASTNode; -import org.eclipse.jdt.core.dom.ASTVisitor; -import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; -import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration; -import org.eclipse.jdt.core.dom.EnumDeclaration; -import org.eclipse.jdt.core.dom.FieldDeclaration; -import org.eclipse.jdt.core.dom.SimpleName; -import org.eclipse.jdt.core.dom.TypeDeclaration; -import org.eclipse.jdt.core.formatter.CodeFormatter; -import org.eclipse.jdt.internal.compiler.parser.TerminalTokens; +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.AnnotationTypeDeclaration; +import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.EnumDeclaration; +import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.FieldDeclaration; +import io.spring.javaformat.eclipse.jdt.jdk8.core.dom.SimpleName; +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; +import io.spring.javaformat.eclipse.jdt.jdk8.internal.formatter.Token; +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 */ @@ -73,15 +73,12 @@ public boolean visit(EnumDeclaration node) { private void visitType(AbstractTypeDeclaration node) { SimpleName name = node.getName(); - int openBraceIndex = (name == null - ? this.tokenManager.firstIndexIn(node, TerminalTokens.TokenNameLBRACE) - : this.tokenManager.firstIndexAfter(name, - TerminalTokens.TokenNameLBRACE)); + int openBraceIndex = (name == null ? this.tokenManager.firstIndexIn(node, TerminalTokens.TokenNameLBRACE) + : this.tokenManager.firstIndexAfter(name, TerminalTokens.TokenNameLBRACE)); Token openBraceToken = this.tokenManager.get(openBraceIndex); openBraceToken.clearLineBreaksAfter(); openBraceToken.putLineBreaksAfter(2); - int closeBraceIndex = this.tokenManager.lastIndexIn(node, - TerminalTokens.TokenNameRBRACE); + int closeBraceIndex = this.tokenManager.lastIndexIn(node, TerminalTokens.TokenNameRBRACE); Token closeBraceToken = this.tokenManager.get(closeBraceIndex); closeBraceToken.clearLineBreaksBefore(); closeBraceToken.putLineBreaksBefore(2); @@ -89,8 +86,7 @@ private void visitType(AbstractTypeDeclaration node) { @Override public boolean visit(FieldDeclaration node) { - int index = this.tokenManager.lastIndexIn(node, - TerminalTokens.TokenNameSEMICOLON); + int index = this.tokenManager.lastIndexIn(node, TerminalTokens.TokenNameSEMICOLON); while (tokenIsOfType(index + 1, TerminalTokens.TokenNameCOMMENT_LINE, TerminalTokens.TokenNameCOMMENT_BLOCK)) { if (this.tokenManager.get(index).getLineBreaksAfter() > 0 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 new file mode 100644 index 00000000..9887ccb2 --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/EclipseJdk8CodeFormatter.java @@ -0,0 +1,54 @@ +/* + * 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.Map; + +import io.spring.javaformat.config.JavaFormatConfig; +import io.spring.javaformat.eclipse.jdt.jdk8.internal.formatter.ExtendedCodeFormatter; +import io.spring.javaformat.eclipse.jdt.jdk8.internal.formatter.Preparator; +import io.spring.javaformat.formatter.eclipse.EclipseCodeFormatter; +import io.spring.javaformat.formatter.eclipse.Options; + +/** + * Internal delegate JDK 8 baseline {@link EclipseCodeFormatter} to apply Spring + * {@literal formatter.prefs} and add {@link Preparator Preparators}. + * + * @author Phillip Webb + */ +public class EclipseJdk8CodeFormatter extends ExtendedCodeFormatter implements EclipseCodeFormatter { + + private final Map appliedOptions; + + public EclipseJdk8CodeFormatter(JavaFormatConfig javaFormatConfig) { + this(new Options("io.spring.javaformat.eclipse.jdt.jdk8").load(javaFormatConfig)); + } + + EclipseJdk8CodeFormatter(Map options) { + super(options); + this.appliedOptions = options; + addPreparator(new JavadocLineBreakPreparator()); + addPreparator(new CodeLineBreakPreparator()); + addPreparator(new JSpecifyPreparator()); + } + + @Override + public void setOptions(Map options) { + super.setOptions(this.appliedOptions); + } + +} 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 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/preparator/JavadocLineBreakPreparator.java b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/JavadocLineBreakPreparator.java similarity index 60% rename from spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/preparator/JavadocLineBreakPreparator.java rename to spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/JavadocLineBreakPreparator.java index f89b4b5e..a5b8a035 100644 --- a/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/preparator/JavadocLineBreakPreparator.java +++ b/spring-javaformat/spring-javaformat-formatter/src/main/java/io/spring/javaformat/formatter/jdk8/eclipse/JavadocLineBreakPreparator.java @@ -1,11 +1,11 @@ /* - * Copyright 2017-2018 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,28 +14,28 @@ * limitations under the License. */ -package io.spring.javaformat.formatter.preparator; +package io.spring.javaformat.formatter.jdk8.eclipse; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import io.spring.javaformat.formatter.eclipse.Preparator; -import io.spring.javaformat.formatter.eclipse.Token; -import io.spring.javaformat.formatter.eclipse.TokenManager; -import org.eclipse.jdt.core.dom.ASTNode; -import org.eclipse.jdt.core.dom.ASTVisitor; -import org.eclipse.jdt.core.dom.Comment; -import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.dom.Javadoc; -import org.eclipse.jdt.core.dom.TagElement; -import org.eclipse.jdt.core.dom.TextElement; -import org.eclipse.jdt.core.dom.TypeDeclaration; -import org.eclipse.jdt.core.formatter.CodeFormatter; -import org.eclipse.jdt.internal.compiler.parser.TerminalTokens; +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.formatter.CodeFormatter; +import io.spring.javaformat.eclipse.jdt.jdk8.internal.compiler.parser.TerminalTokens; +import io.spring.javaformat.eclipse.jdt.jdk8.internal.formatter.Preparator; +import io.spring.javaformat.eclipse.jdt.jdk8.internal.formatter.Token; +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 */ @@ -91,11 +91,10 @@ private static class Vistor extends ASTVisitor { @Override public boolean visit(Javadoc node) { - int commentIndex = this.tokenManager.firstIndexIn(node, - TerminalTokens.TokenNameCOMMENT_JAVADOC); + 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; @@ -110,20 +109,19 @@ public boolean visit(TextElement node) { @Override public boolean visit(TagElement node) { - if (isSquashRequired(node, this.declaration)) { - int startIndex = this.commentTokenManager - .findIndex(node.getStartPosition(), -1, false); + 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 new file mode 100644 index 00000000..46940cbe --- /dev/null +++ b/spring-javaformat/spring-javaformat-formatter/src/main/resources/io/spring/javaformat/formatter/eclipse/formatter.prefs @@ -0,0 +1,355 @@ +core.formatter.align_assignment_statements_on_columns=false +core.formatter.align_fields_grouping_blank_lines=2147483647 +core.formatter.align_type_members_on_columns=false +core.formatter.align_variable_declarations_on_columns=false +core.formatter.align_with_spaces=false +core.formatter.alignment_for_additive_operator=16 +core.formatter.alignment_for_arguments_in_allocation_expression=16 +core.formatter.alignment_for_arguments_in_annotation=16 +core.formatter.alignment_for_arguments_in_enum_constant=16 +core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +core.formatter.alignment_for_arguments_in_method_invocation=16 +core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +core.formatter.alignment_for_assignment=0 +core.formatter.alignment_for_binary_expression=16 +core.formatter.alignment_for_bitwise_operator=16 +core.formatter.alignment_for_compact_if=16 +core.formatter.alignment_for_compact_loops=16 +core.formatter.alignment_for_conditional_expression=16 +core.formatter.alignment_for_conditional_expression_chain=0 +core.formatter.alignment_for_enum_constants=16 +core.formatter.alignment_for_expressions_in_array_initializer=16 +core.formatter.alignment_for_expressions_in_for_loop_header=0 +core.formatter.alignment_for_logical_operator=16 +core.formatter.alignment_for_method_declaration=0 +core.formatter.alignment_for_module_statements=16 +core.formatter.alignment_for_multiple_fields=16 +core.formatter.alignment_for_multiplicative_operator=16 +core.formatter.alignment_for_parameterized_type_references=0 +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=84 +core.formatter.alignment_for_shift_operator=0 +core.formatter.alignment_for_string_concatenation=16 +core.formatter.alignment_for_superclass_in_type_declaration=16 +core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +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=true +core.formatter.blank_lines_after_imports=1 +core.formatter.blank_lines_after_package=1 +core.formatter.blank_lines_before_field=0 +core.formatter.blank_lines_before_first_class_body_declaration=0 +core.formatter.blank_lines_before_imports=1 +core.formatter.blank_lines_before_member_type=1 +core.formatter.blank_lines_before_method=1 +core.formatter.blank_lines_before_new_chunk=1 +core.formatter.blank_lines_before_package=0 +core.formatter.blank_lines_between_import_groups=1 +core.formatter.blank_lines_between_type_declarations=1 +core.formatter.brace_position_for_annotation_type_declaration=end_of_line +core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +core.formatter.brace_position_for_array_initializer=end_of_line +core.formatter.brace_position_for_block=end_of_line +core.formatter.brace_position_for_block_in_case=end_of_line +core.formatter.brace_position_for_constructor_declaration=end_of_line +core.formatter.brace_position_for_enum_constant=end_of_line +core.formatter.brace_position_for_enum_declaration=end_of_line +core.formatter.brace_position_for_lambda_body=end_of_line +core.formatter.brace_position_for_method_declaration=end_of_line +core.formatter.brace_position_for_switch=end_of_line +core.formatter.brace_position_for_type_declaration=end_of_line +core.formatter.comment.align_tags_descriptions_grouped=false +core.formatter.comment.align_tags_names_descriptions=false +core.formatter.comment.clear_blank_lines_in_block_comment=false +core.formatter.comment.clear_blank_lines_in_javadoc_comment=false +core.formatter.comment.count_line_length_from_starting_position=false +core.formatter.comment.format_block_comments=true +core.formatter.comment.format_header=false +core.formatter.comment.format_html=true +core.formatter.comment.format_javadoc_comments=true +core.formatter.comment.format_line_comments=true +core.formatter.comment.format_source_code=false +core.formatter.comment.indent_parameter_description=false +core.formatter.comment.indent_root_tags=false +core.formatter.comment.indent_tag_description=false +core.formatter.comment.insert_new_line_before_root_tags=do not insert +core.formatter.comment.insert_new_line_for_parameter=do not insert +core.formatter.comment.line_length=90 +core.formatter.comment.new_lines_at_block_boundaries=true +core.formatter.comment.new_lines_at_javadoc_boundaries=true +core.formatter.comment.preserve_white_space_between_code_and_line_comments=false +core.formatter.compact_else_if=true +core.formatter.continuation_indentation=2 +core.formatter.continuation_indentation_for_array_initializer=2 +core.formatter.disabling_tag=@formatter\:off +core.formatter.enabling_tag=@formatter\:on +core.formatter.format_guardian_clause_on_one_line=false +core.formatter.format_line_comment_starting_on_first_column=true +core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +core.formatter.indent_body_declarations_compare_to_type_header=true +core.formatter.indent_breaks_compare_to_cases=true +core.formatter.indent_empty_lines=false +core.formatter.indent_statements_compare_to_block=true +core.formatter.indent_statements_compare_to_body=true +core.formatter.indent_switchstatements_compare_to_cases=true +core.formatter.indent_switchstatements_compare_to_switch=true +core.formatter.indentation.size=4 +core.formatter.insert_new_line_after_annotation_on_enum_constant=insert +core.formatter.insert_new_line_after_annotation_on_field=insert +core.formatter.insert_new_line_after_annotation_on_local_variable=insert +core.formatter.insert_new_line_after_annotation_on_method=insert +core.formatter.insert_new_line_after_annotation_on_package=insert +core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +core.formatter.insert_new_line_after_annotation_on_type=insert +core.formatter.insert_new_line_after_label=do not insert +core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +core.formatter.insert_new_line_after_type_annotation=do not insert +core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert +core.formatter.insert_new_line_before_catch_in_try_statement=insert +core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +core.formatter.insert_new_line_before_else_in_if_statement=insert +core.formatter.insert_new_line_before_finally_in_try_statement=insert +core.formatter.insert_new_line_before_while_in_do_statement=insert +core.formatter.insert_new_line_in_empty_annotation_declaration=insert +core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +core.formatter.insert_new_line_in_empty_block=insert +core.formatter.insert_new_line_in_empty_enum_constant=insert +core.formatter.insert_new_line_in_empty_enum_declaration=insert +core.formatter.insert_new_line_in_empty_method_body=insert +core.formatter.insert_new_line_in_empty_type_declaration=insert +core.formatter.insert_space_after_additive_operator=insert +core.formatter.insert_space_after_and_in_type_parameter=insert +core.formatter.insert_space_after_assignment_operator=insert +core.formatter.insert_space_after_at_in_annotation=do not insert +core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +core.formatter.insert_space_after_binary_operator=insert +core.formatter.insert_space_after_bitwise_operator=insert +core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=do not insert +core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +core.formatter.insert_space_after_closing_brace_in_block=insert +core.formatter.insert_space_after_closing_paren_in_cast=insert +core.formatter.insert_space_after_colon_in_assert=insert +core.formatter.insert_space_after_colon_in_case=insert +core.formatter.insert_space_after_colon_in_conditional=insert +core.formatter.insert_space_after_colon_in_for=insert +core.formatter.insert_space_after_colon_in_labeled_statement=insert +core.formatter.insert_space_after_comma_in_allocation_expression=insert +core.formatter.insert_space_after_comma_in_annotation=insert +core.formatter.insert_space_after_comma_in_array_initializer=insert +core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +core.formatter.insert_space_after_comma_in_enum_declarations=insert +core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +core.formatter.insert_space_after_comma_in_for_increments=insert +core.formatter.insert_space_after_comma_in_for_inits=insert +core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +core.formatter.insert_space_after_comma_in_superinterfaces=insert +core.formatter.insert_space_after_comma_in_type_arguments=insert +core.formatter.insert_space_after_comma_in_type_parameters=insert +core.formatter.insert_space_after_ellipsis=insert +core.formatter.insert_space_after_lambda_arrow=insert +core.formatter.insert_space_after_logical_operator=insert +core.formatter.insert_space_after_multiplicative_operator=insert +core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +core.formatter.insert_space_after_opening_paren_in_cast=do not insert +core.formatter.insert_space_after_opening_paren_in_catch=do not insert +core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +core.formatter.insert_space_after_opening_paren_in_for=do not insert +core.formatter.insert_space_after_opening_paren_in_if=do not insert +core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +core.formatter.insert_space_after_opening_paren_in_switch=do not insert +core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +core.formatter.insert_space_after_opening_paren_in_try=do not insert +core.formatter.insert_space_after_opening_paren_in_while=do not insert +core.formatter.insert_space_after_postfix_operator=do not insert +core.formatter.insert_space_after_prefix_operator=do not insert +core.formatter.insert_space_after_question_in_conditional=insert +core.formatter.insert_space_after_question_in_wildcard=do not insert +core.formatter.insert_space_after_relational_operator=insert +core.formatter.insert_space_after_semicolon_in_for=insert +core.formatter.insert_space_after_semicolon_in_try_resources=insert +core.formatter.insert_space_after_shift_operator=insert +core.formatter.insert_space_after_string_concatenation=insert +core.formatter.insert_space_after_unary_operator=do not insert +core.formatter.insert_space_before_additive_operator=insert +core.formatter.insert_space_before_and_in_type_parameter=insert +core.formatter.insert_space_before_assignment_operator=insert +core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +core.formatter.insert_space_before_binary_operator=insert +core.formatter.insert_space_before_bitwise_operator=insert +core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +core.formatter.insert_space_before_closing_paren_in_cast=do not insert +core.formatter.insert_space_before_closing_paren_in_catch=do not insert +core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +core.formatter.insert_space_before_closing_paren_in_for=do not insert +core.formatter.insert_space_before_closing_paren_in_if=do not insert +core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +core.formatter.insert_space_before_closing_paren_in_switch=do not insert +core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +core.formatter.insert_space_before_closing_paren_in_try=do not insert +core.formatter.insert_space_before_closing_paren_in_while=do not insert +core.formatter.insert_space_before_colon_in_assert=insert +core.formatter.insert_space_before_colon_in_case=do not insert +core.formatter.insert_space_before_colon_in_conditional=insert +core.formatter.insert_space_before_colon_in_default=do not insert +core.formatter.insert_space_before_colon_in_for=insert +core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +core.formatter.insert_space_before_comma_in_annotation=do not insert +core.formatter.insert_space_before_comma_in_array_initializer=do not insert +core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +core.formatter.insert_space_before_comma_in_for_increments=do not insert +core.formatter.insert_space_before_comma_in_for_inits=do not insert +core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +core.formatter.insert_space_before_comma_in_type_arguments=do not insert +core.formatter.insert_space_before_comma_in_type_parameters=do not insert +core.formatter.insert_space_before_ellipsis=do not insert +core.formatter.insert_space_before_lambda_arrow=insert +core.formatter.insert_space_before_logical_operator=insert +core.formatter.insert_space_before_multiplicative_operator=insert +core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +core.formatter.insert_space_before_opening_brace_in_block=insert +core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +core.formatter.insert_space_before_opening_brace_in_switch=insert +core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +core.formatter.insert_space_before_opening_paren_in_catch=insert +core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +core.formatter.insert_space_before_opening_paren_in_for=insert +core.formatter.insert_space_before_opening_paren_in_if=insert +core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +core.formatter.insert_space_before_opening_paren_in_switch=insert +core.formatter.insert_space_before_opening_paren_in_synchronized=insert +core.formatter.insert_space_before_opening_paren_in_try=insert +core.formatter.insert_space_before_opening_paren_in_while=insert +core.formatter.insert_space_before_parenthesized_expression_in_return=insert +core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +core.formatter.insert_space_before_postfix_operator=do not insert +core.formatter.insert_space_before_prefix_operator=do not insert +core.formatter.insert_space_before_question_in_conditional=insert +core.formatter.insert_space_before_question_in_wildcard=do not insert +core.formatter.insert_space_before_relational_operator=insert +core.formatter.insert_space_before_semicolon=do not insert +core.formatter.insert_space_before_semicolon_in_for=do not insert +core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +core.formatter.insert_space_before_shift_operator=insert +core.formatter.insert_space_before_string_concatenation=insert +core.formatter.insert_space_before_unary_operator=do not insert +core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +core.formatter.join_lines_in_comments=true +core.formatter.join_wrapped_lines=true +core.formatter.keep_annotation_declaration_on_one_line=one_line_never +core.formatter.keep_anonymous_type_declaration_on_one_line=one_line_never +core.formatter.keep_code_block_on_one_line=one_line_never +core.formatter.keep_else_statement_on_same_line=false +core.formatter.keep_empty_array_initializer_on_one_line=false +core.formatter.keep_enum_constant_declaration_on_one_line=one_line_never +core.formatter.keep_enum_declaration_on_one_line=one_line_never +core.formatter.keep_if_then_body_block_on_one_line=one_line_never +core.formatter.keep_imple_if_on_one_line=false +core.formatter.keep_lambda_body_block_on_one_line=one_line_never +core.formatter.keep_loop_body_block_on_one_line=one_line_never +core.formatter.keep_method_body_on_one_line=one_line_never +core.formatter.keep_simple_do_while_body_on_same_line=false +core.formatter.keep_simple_for_body_on_same_line=false +core.formatter.keep_simple_getter_setter_on_one_line=false +core.formatter.keep_simple_while_body_on_same_line=false +core.formatter.keep_then_statement_on_same_line=false +core.formatter.keep_type_declaration_on_one_line=one_line_never +core.formatter.lineSplit=120 +core.formatter.never_indent_block_comments_on_first_column=false +core.formatter.never_indent_line_comments_on_first_column=false +core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +core.formatter.number_of_empty_lines_to_preserve=1 +core.formatter.parentheses_positions_in_annotation=common_lines +core.formatter.parentheses_positions_in_catch_clause=common_lines +core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines +core.formatter.parentheses_positions_in_for_statment=common_lines +core.formatter.parentheses_positions_in_if_while_statement=common_lines +core.formatter.parentheses_positions_in_lambda_declaration=common_lines +core.formatter.parentheses_positions_in_method_delcaration=common_lines +core.formatter.parentheses_positions_in_method_invocation=common_lines +core.formatter.parentheses_positions_in_switch_statement=common_lines +core.formatter.parentheses_positions_in_try_clause=common_lines +core.formatter.put_empty_statement_on_new_line=true +core.formatter.tabulation.char=tab +core.formatter.tabulation.size=4 +core.formatter.use_on_off_tags=true +core.formatter.use_tabs_only_for_leading_indentations=false +core.formatter.wrap_before_additive_operator=true +core.formatter.wrap_before_assignment_operator=false +core.formatter.wrap_before_binary_operator=true +core.formatter.wrap_before_bitwise_operator=true +core.formatter.wrap_before_conditional_operator=true +core.formatter.wrap_before_logical_operator=true +core.formatter.wrap_before_multiplicative_operator=true +core.formatter.wrap_before_or_operator_multicatch=true +core.formatter.wrap_before_relational_operator=true +core.formatter.wrap_before_shift_operator=true +core.formatter.wrap_before_string_concatenation=true +core.formatter.wrap_outer_expressions_when_nested=true diff --git a/spring-javaformat/spring-javaformat-formatter/src/main/resources/io/spring/javaformat/formatter/formatter.prefs b/spring-javaformat/spring-javaformat-formatter/src/main/resources/io/spring/javaformat/formatter/formatter.prefs deleted file mode 100644 index 25716aaa..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/main/resources/io/spring/javaformat/formatter/formatter.prefs +++ /dev/null @@ -1,304 +0,0 @@ -org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_module_statements=16 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -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_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 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -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.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 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false -org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=false -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=true -org.eclipse.jdt.core.formatter.comment.format_source_code=false -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=false -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=do not insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert -org.eclipse.jdt.core.formatter.comment.line_length=90 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=90 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=tab -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=true -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/java/io/spring/javaformat/formatter/AbstractFormatterTests.java b/spring-javaformat/spring-javaformat-formatter/src/test/java/io/spring/javaformat/formatter/AbstractFormatterTests.java deleted file mode 100644 index 22df9f99..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/java/io/spring/javaformat/formatter/AbstractFormatterTests.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2017-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.spring.javaformat.formatter; - -import java.io.File; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.Collection; - -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -/** - * @author Phillip Webb - */ -@RunWith(Parameterized.class) -public abstract class AbstractFormatterTests { - - private final File source; - - private final File expected; - - public AbstractFormatterTests(File source, File expected) { - this.source = source; - this.expected = expected; - } - - protected final File getSource() { - return this.source; - } - - protected final File getExpected() { - return this.expected; - } - - protected final void print(String name, String content) { - System.out.println(name + ":"); - System.out.println(); - System.out.println("----------------------------------------"); - System.out.println(content); - System.out.println("----------------------------------------"); - System.out.println(); - System.out.println(); - } - - protected final String read(File file) throws Exception { - return new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8); - } - - protected static Collection files(String expectedOverride) { - Collection files = new ArrayList<>(); - File sourceDir = new File("src/test/resources/source"); - File expectedDir = new File("src/test/resources/expected"); - 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()); - } - files.add(new Object[] { source, expected }); - } - return files; - } - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/java/io/spring/javaformat/formatter/FileFormatterTests.java b/spring-javaformat/spring-javaformat-formatter/src/test/java/io/spring/javaformat/formatter/FileFormatterTests.java deleted file mode 100644 index cbd31ddb..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/java/io/spring/javaformat/formatter/FileFormatterTests.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2017-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.spring.javaformat.formatter; - -import java.io.File; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Collection; - -import org.junit.Test; -import org.junit.runners.Parameterized.Parameters; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for FileFormatter. - * - * @author Phillip Webb - */ -public class FileFormatterTests extends AbstractFormatterTests { - - public FileFormatterTests(File source, File expected) { - super(source, expected); - } - - @Test - public void formatFilesFromIteratorShouldFormatFile() throws Exception { - FileEdit edit = new FileFormatter() - .formatFiles(Arrays.asList(getSource()), StandardCharsets.UTF_8) - .findFirst().get(); - assertThat(edit.getFormattedContent()).isEqualTo(read(getExpected())); - } - - @Test - public void formatFilesFromStreamShouldFormatFile() throws Exception { - FileEdit edit = new FileFormatter() - .formatFiles(Arrays.asList(getSource()).stream(), StandardCharsets.UTF_8) - .findFirst().get(); - assertThat(edit.getFormattedContent()).isEqualTo(read(getExpected())); - } - - @Test - public void formatFileShouldFormatFile() throws Exception { - File source = getSource(); - FileEdit edit = new FileFormatter().formatFile(source, StandardCharsets.UTF_8); - String formattedContent = edit.getFormattedContent(); - String expected = read(getExpected()); - System.out.println(source); - System.out.println("----- got"); - System.out.println(formattedContent); - System.out.println("----- expected"); - System.out.println(expected); - System.out.println("-----"); - assertThat(formattedContent).isEqualTo(expected); - } - - @Parameters(name = "{0}") - public static Collection files() { - return AbstractFormatterTests.files(null); - } - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/FormatterTests-expected/javadoc-top-add.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/FormatterTests-expected/javadoc-top-add.txt deleted file mode 100644 index 95922ff6..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/FormatterTests-expected/javadoc-top-add.txt +++ /dev/null @@ -1,10 +0,0 @@ -package demo; - -/** - * Whitespace test. - * - * @author Phillip Webb - */ -public interface Whitespace { - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/javadoc-nested.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/javadoc-nested.txt deleted file mode 100644 index 4dbd5cb9..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/javadoc-nested.txt +++ /dev/null @@ -1,8 +0,0 @@ -package demo; - -/** - * Hello {@link String}. - */ -public class ClassBraces { - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/javadoc-param.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/javadoc-param.txt deleted file mode 100644 index d41a0dc7..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/javadoc-param.txt +++ /dev/null @@ -1,31 +0,0 @@ -package demo; - -public interface Whitespace { - - /** - * There should be no whitespace. - * @return the classes to exclude - */ - String[] whitespace1(); - - /** - * There should be no whitespace. - * @return the classes to exclude - */ - String[] whitespace2(); - - /** - * There should be no whitespace. - * @return the classes to exclude - */ - String[] whitespace3(); - - /** - * There should be no whitespace. - * @param a the classes to exclude - * @param b the classes to exclude - * @return the classes to exclude - */ - String[] whitespace4(String a, String b); - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/javadoc-top-empty.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/javadoc-top-empty.txt deleted file mode 100644 index e326722b..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/javadoc-top-empty.txt +++ /dev/null @@ -1,8 +0,0 @@ -package demo; - -/** - * @author Phillip Webb - */ -public interface Whitespace { - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/javadoc-top.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/javadoc-top.txt deleted file mode 100644 index 6f91a00d..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/javadoc-top.txt +++ /dev/null @@ -1,13 +0,0 @@ -package demo; - -/** - * Whitespace test. - * - * @param T test - * @author Phillip Webb - * @since 1.4.0 - * @deprecated - */ -public interface Whitespace { - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/linebreak-classbraces.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/linebreak-classbraces.txt deleted file mode 100644 index ebdefbc7..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/linebreak-classbraces.txt +++ /dev/null @@ -1,15 +0,0 @@ -package demo; - -public class ClassBraces { - - public void hello() { - } - - public static class Hello { - - public void hello() { - } - - } - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/linebreak-fields-comment-above.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/linebreak-fields-comment-above.txt deleted file mode 100644 index d3e0a6de..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/linebreak-fields-comment-above.txt +++ /dev/null @@ -1,12 +0,0 @@ -package demo; - -public class Fields { - - private int x; - - // This is an a - private int a; - - private int b; - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/linebreak-fields-comments.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/linebreak-fields-comments.txt deleted file mode 100644 index 1897d54d..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/linebreak-fields-comments.txt +++ /dev/null @@ -1,11 +0,0 @@ -package demo; - -public class Fields { - - private int a; // a - - private int b; /* hello */ - - private String x; // x - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/linebreak-fields.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/linebreak-fields.txt deleted file mode 100644 index df74bdea..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/linebreak-fields.txt +++ /dev/null @@ -1,11 +0,0 @@ -package demo; - -public class Fields { - - private int a; - - private int b; - - private String x; - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/linebreak-interface.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/linebreak-interface.txt deleted file mode 100644 index 06c5d50e..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/linebreak-interface.txt +++ /dev/null @@ -1,7 +0,0 @@ -package demo; - -public @interface InterfaceBraces { - - String value(); - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/linebreak-trailing.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/linebreak-trailing.txt deleted file mode 100644 index fd0a6078..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/linebreak-trailing.txt +++ /dev/null @@ -1,5 +0,0 @@ -package demo; - -public class Fields { - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/method-wrap.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/method-wrap.txt deleted file mode 100644 index c1dde7af..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/method-wrap.txt +++ /dev/null @@ -1,11 +0,0 @@ -package simple; - -public class Simple { - - @Override - protected void doFilterInternal(HttpServletRequest request, - HttpServletResponse response, FilterChain chain) - throws ServletException, IOException { - } - -} \ No newline at end of file diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/static-initializer.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/static-initializer.txt deleted file mode 100644 index 1f40d2b4..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/expected/static-initializer.txt +++ /dev/null @@ -1,10 +0,0 @@ -package simple; - -public class Simple { - - public static final String FOO; - static { - FOO = "bar"; - } - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/enum-constructor.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/enum-constructor.txt deleted file mode 100644 index f3f156b7..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/enum-constructor.txt +++ /dev/null @@ -1,16 +0,0 @@ -package sample; - -public enum ExampleEnum { - - ONE("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen"), - - /** - * Two - */ - TWO("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen"); - - private ExampleEnum(String... args) { - - } - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/javadoc-nested.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/javadoc-nested.txt deleted file mode 100644 index bae4300c..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/javadoc-nested.txt +++ /dev/null @@ -1,7 +0,0 @@ -package demo; - -/** - * Hello {@link String}. - */ -public class ClassBraces { -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/javadoc-param.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/javadoc-param.txt deleted file mode 100644 index cdb35d3e..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/javadoc-param.txt +++ /dev/null @@ -1,37 +0,0 @@ -package demo; - -public interface Whitespace { - - /** - * There should be no whitespace. - * @return the classes to exclude - */ - String[] whitespace1(); - - /** - * There should be no whitespace. - * - * @return the classes to exclude - */ - String[] whitespace2(); - - /** - * There should be no whitespace. - * - * - * @return the classes to exclude - */ - String[] whitespace3(); - - /** - * There should be no whitespace. - - * @param a the classes to exclude - * - * @param b the classes to exclude - * - * @return the classes to exclude - */ - String[] whitespace4(String a, String b); - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/javadoc-top-add.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/javadoc-top-add.txt deleted file mode 100644 index b6983b8c..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/javadoc-top-add.txt +++ /dev/null @@ -1,9 +0,0 @@ -package demo; - -/** - * Whitespace test. - * @author Phillip Webb - */ -public interface Whitespace { - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/javadoc-top-empty.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/javadoc-top-empty.txt deleted file mode 100644 index e326722b..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/javadoc-top-empty.txt +++ /dev/null @@ -1,8 +0,0 @@ -package demo; - -/** - * @author Phillip Webb - */ -public interface Whitespace { - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/javadoc-top.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/javadoc-top.txt deleted file mode 100644 index f9cea248..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/javadoc-top.txt +++ /dev/null @@ -1,18 +0,0 @@ -package demo; - -/** - * Whitespace test. - * - * - * @param T test - * - * @author Phillip Webb - * - * - * @since 1.4.0 - * - * @deprecated - */ -public interface Whitespace { - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/linebreak-classbraces.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/linebreak-classbraces.txt deleted file mode 100644 index 97ce5447..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/linebreak-classbraces.txt +++ /dev/null @@ -1,12 +0,0 @@ -package demo; - -public class ClassBraces { - - public void hello() { - } - - public static class Hello { - public void hello() { - } - } -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/linebreak-fields-comment-above.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/linebreak-fields-comment-above.txt deleted file mode 100644 index d3e0a6de..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/linebreak-fields-comment-above.txt +++ /dev/null @@ -1,12 +0,0 @@ -package demo; - -public class Fields { - - private int x; - - // This is an a - private int a; - - private int b; - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/linebreak-fields-comments.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/linebreak-fields-comments.txt deleted file mode 100644 index a6e8fc6d..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/linebreak-fields-comments.txt +++ /dev/null @@ -1,9 +0,0 @@ -package demo; - -public class Fields { - - private int a; // a - private int b; /* hello */ - private String x; // x - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/linebreak-fields.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/linebreak-fields.txt deleted file mode 100644 index be9c0c2a..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/linebreak-fields.txt +++ /dev/null @@ -1,9 +0,0 @@ -package demo; - -public class Fields { - - private int a; - private int b; - private String x; - -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/linebreak-interface.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/linebreak-interface.txt deleted file mode 100644 index 1bd47364..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/linebreak-interface.txt +++ /dev/null @@ -1,6 +0,0 @@ -package demo; - -public @interface InterfaceBraces { - - String value(); -} diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/linebreak-trailing.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/linebreak-trailing.txt deleted file mode 100644 index 6c03b4de..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/linebreak-trailing.txt +++ /dev/null @@ -1,8 +0,0 @@ -package demo; - -public class Fields { - - -} - - diff --git a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/static-initializer.txt b/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/static-initializer.txt deleted file mode 100644 index 1f40d2b4..00000000 --- a/spring-javaformat/spring-javaformat-formatter/src/test/resources/source/static-initializer.txt +++ /dev/null @@ -1,10 +0,0 @@ -package simple; - -public class Simple { - - public static final String FOO; - static { - FOO = "bar"; - } - -} diff --git a/src/checkstyle/checkstyle-header.txt b/src/checkstyle/checkstyle-header.txt index 154aaa1a..7e182ab3 100644 --- a/src/checkstyle/checkstyle-header.txt +++ b/src/checkstyle/checkstyle-header.txt @@ -1,11 +1,11 @@ ^\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$ ^\Q * You may obtain a copy of the License at\E$ ^\Q *\E$ -^\Q * http://www.apache.org/licenses/LICENSE-2.0\E$ +^\Q * https://www.apache.org/licenses/LICENSE-2.0\E$ ^\Q *\E$ ^\Q * Unless required by applicable law or agreed to in writing, software\E$ ^\Q * distributed under the License is distributed on an "AS IS" BASIS,\E$ diff --git a/src/checkstyle/checkstyle-suppressions.xml b/src/checkstyle/checkstyle-suppressions.xml index 8e7715f6..b115d317 100644 --- a/src/checkstyle/checkstyle-suppressions.xml +++ b/src/checkstyle/checkstyle-suppressions.xml @@ -1,9 +1,10 @@ + "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN" + "https://checkstyle.org/dtds/suppressions_1_2.dtd"> + diff --git a/src/checkstyle/checkstyle.xml b/src/checkstyle/checkstyle.xml index bc7b18bd..c13faf85 100644 --- a/src/checkstyle/checkstyle.xml +++ b/src/checkstyle/checkstyle.xml @@ -1,14 +1,14 @@ - + - - - + @@ -65,6 +65,7 @@ + @@ -78,7 +79,7 @@ - + @@ -90,9 +91,7 @@ - - - + @@ -105,11 +104,11 @@ - + - + - + @@ -124,21 +123,21 @@ - + - - + + - - + + @@ -161,5 +160,5 @@ - +