Do not run ExtractExplicitConstructorInvocationArguments on non-Java sources - #1235
Open
knutwannheden wants to merge 1 commit into
Open
Do not run ExtractExplicitConstructorInvocationArguments on non-Java sources#1235knutwannheden wants to merge 1 commit into
ExtractExplicitConstructorInvocationArguments on non-Java sources#1235knutwannheden wants to merge 1 commit into
Conversation
…a sources The recipe's `JavaIsoVisitor` accepted any `JavaSourceFile`, so it also ran on Groovy compilation units. There it reached `JavaTemplate`, which generates its stub from the Groovy LST and parses it as Java, and `JavaTemplateParser.parseMethodArguments` threw on the result. Narrow the visitor to `J.CompilationUnit`. JEP 513 is a Java language feature, so Groovy and Kotlin sources are out of scope for this recipe.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Running
ExtractExplicitConstructorInvocationArgumentsover a corpus of open-source repositories throws onspring-cloud/spring-cloud-contract, inspring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/util/SyntaxChecker.groovy:How a Groovy file gets here
The visitor is a
JavaIsoVisitor, whoseisAcceptabletakes anyJavaSourceFile, and that includesG.CompilationUnit. TheUsesJavaVersion<>(25)precondition does not narrow it either: theJavaVersionmarker on a Groovy source carries the module's Java version, so it matches.Groovy attributes a method type to
super(..)only under@CompileStatic, taken fromStaticTypesMarker.DIRECT_METHOD_CALL_TARGET.SyntaxChecker.groovyannotates its nested classes that way, so thegetMethodType() == nullbail-out does not catch them and the recipe builds aJavaTemplatewhose stub, generated from the Groovy LST, is parsed as Java.JavaTemplateParser.parseMethodArgumentsthen casts the result:For the two-argument
super(URI.create(…), Kind.SOURCE)in that file the parse yields aJ.FieldAccess. For a one-argument call the list comes back empty and the same line throwsIndexOutOfBoundsExceptioninstead.Fix
isAcceptablenow returnssourceFile instanceof J.CompilationUnit. JEP 513 is a Java language feature and the transformation is written as aJavaTemplate, so Groovy and Kotlin are out of scope for this recipe whatever the LST happens to allow.The cast in
parseMethodArgumentsis unsound in general, but hardening it upstream would only trade one exception for another: a Java template applied to a non-Java LST has no correct result. The guard belongs at the recipe. Nothing about the shape is specific to this recipe, though — anyJavaTemplate-based recipe without a source-file guard can reach the same line.Tests
doNotRunOnGroovySourcespins the guard with a minimal@CompileStaticGroovy source; without the fix it fails atJavaTemplateParser.java:223. TheSimpleJavaFileObjectsubclass fromSyntaxChecker.groovyreproduces the reported cast verbatim, but a two-linesuper(name.trim())defends the same guard, so that is what the suite keeps.main, which is Preserve Java 25 constructor extraction statements #1206. This change adds no failures and its own test passes.