A type used before its declaration, in a file shared by two independent source sets, resolves to the other source set's copy
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 58/100
Línea de trabajo
Start with the reproducing test in maddi-inspection-openjdk/src/test/java/io/codelaser/maddi/inspection/openjdk/TestSharedSourceFileInTwoSourceSets.java and run ./gradlew :maddi-inspection-openjdk:test --tests 'TestSharedSourceFileInTwoSourceSets'. Trace how JavaInspector.parseMultiSourceSet resolves the nested type used before its declaration, then inspect InfoByFqn.getType and computeDistance as suggested by the issue. Done means both test cases pass and each source set's reference resolves to its own class.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
What happens
When one Java source file is compiled into two source sets that do not depend on each other, maddi parses one copy of the file per source set — correct. But in the second copy, a use of a type that is declared further down the same file resolves to the first source set's copy of that type.
javac compiles each source set on its own, so the second copy can only ever mean its own type. The first source set is not even a dependency of the second.
Minimal shape (the file is in both source sets):
public final class ClassificationMetadataResolver {
private static void checkStatus(HttpURLConnection connection, URI uri) throws IOException {
if ( connection.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND ) {
throw new MissingMetadataException( uri ); // <-- in the 2nd source set, this links to the 1st set's class
}
}
private static final class MissingMetadataException extends IOException { // declared AFTER its use
...
}
}
With the nested class declared before checkStatus, both copies resolve correctly.
Reproducing test
Branch test/shared-source-file-in-two-source-sets (one commit on top of main), file
maddi-inspection-openjdk/src/test/java/io/codelaser/maddi/inspection/openjdk/TestSharedSourceFileInTwoSourceSets.java.
It only uses maddi: two source sets depending on java.base only, the same in-memory source in both, parsed with JavaInspector.parseMultiSourceSet (the same setup as TestStubMeetsItsOwnSource).
./gradlew :maddi-inspection-openjdk:test --tests '*TestSharedSourceFileInTwoSourceSets*'
| Test | Result on main (527709bb6) |
|---|---|
typeUsedBeforeItsDeclaration — nested class declared after its use |
fails |
typeDeclaredBeforeItsUse — control, nested class declared before its use |
passes |
Failure:
the copy of checkStatus in source set 'test-protocolB' does `new MissingMetadataException( uri )`; the list is
the source set of the MissingMetadataException that call resolved to, and it must be the same source set
==> expected: <[test-protocolB]> but was: <[test-protocol]>
Probable cause (not verified in the code path)
The second scan meets new MissingMetadataException( uri ) before it has registered its own copy of the nested class, asks InfoByFqn.getType(fqn, sourceSetOfCurrentTask), and gets the only copy registered so far:
getTypereturns an entry ofsingleTypeByFqndirectly, without looking at its source set;- with several entries,
computeDistancegives an unreachable source setInteger.MAX_VALUE, and the choice sorts rather than excludes, so an unreachable copy still wins when it is the only candidate.
Where it was found, and what it costs
hibernate-orm d6c1a87f14 compiles shared/classification/src/main/java into two Gradle projects:
local-build-plugins/build.gradle: sourceSets.main.java.srcDir("../shared/classification/src/main/java")
tooling/hibernate-dialect-provider/hibernate-dialect-provider-tooling.gradle: main.java.srcDir rootProject.file("shared/classification/src/main/java")
The CodeLaser dead-code analysis then saw nothing creating the tooling/hibernate-dialect-provider/main copy of ClassificationMetadataResolver.MissingMetadataException, reported its constructor and its field uri dead while the checkStatus that creates it (correctly) stayed alive, and the removal refused the whole hibernate-orm run.
Any project that compiles one source folder into several modules, with a type used before its declaration, gets the same wrong link: the copy that is really used looks unused, and the other copy looks used.
- Lenguaje dominante
- Java
- Estrellas
- 1
- Forks
- 1
- Merge medio
- 1 h 55 min
- PR fusionados (30 d)
- 8
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de CodeLaser/maddi
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
CodeLaser/maddi#166 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
build/ci good first issue
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 3/5 1-2 días Aptitud para principiantes 67/100
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 3/5 1-2 días Aptitud para principiantes 68/100
Los mantenedores suelen responder en 1 día
-
Java printer: a nested type prints by simple name when the unit imports another type of that nameAbiertobug
Dificultad 3/5 1-2 días Aptitud para principiantes 57/100
Los mantenedores suelen responder en 1 día
Todos los issues de CodeLaser/maddi
Issues similares
-
status: waiting-for-triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
spring-projects/spring-framework#37614 ·
Los mantenedores suelen responder en 1 día
-
azure-spring azure-spring-aad Client
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Azure/azure-sdk-for-java#51046 · 1 reacción ·
Los mantenedores suelen responder en 1 día
-
helm-knative-apply.sh fails with Helm 4Posiblemente ocupada Un pull request vinculado a esta issue está abierto o ya se fusionó. Abiertoarea: triage theme: undefined
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
jhipster/generator-jhipster#35895 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
oracle/graalvm-reachability-metadata#11659 ·
Los mantenedores suelen responder en 1 día