github / github/codeql

Java: `hasSubtype` / `getASubtype` does not work correctly for generic types

Offen
#8,339 2 Kommentare 0 Reaktionen 1 zugewiesene Person Beansprucht von @aschackmull Auf GitHub ansehen
question
Vorherrschende Sprache
CodeQL
Sterne
10.1k
Forks
2.1k
Ø Merge
2 T. 15 Std.
Gemergte PRs (30 T.)
141

Beschreibung

Based on https://github.com/github/codeql/pull/8241#discussion_r815508557

The predicate `hasSubtype(RefType, Type)` and predicates which are based on it, such as `RefType.getASubtype()` do not work correctly for generic types. For example for the generic type `java.util.List`, the type `java.util.ArrayList` is not found ([example query](https://lgtm.com/query/5617555852827933522/)).

The underlying issue is most likely related to how CodeQL in general handles type hierarchies of generic, parameterized and raw types, and which is likely the reason why `getASourceSupertype()` exists. Generic types simply seem to have no subtypes ([example query](https://lgtm.com/query/4703394327948888047/)), which therefore affects all predicates based on `hasSubtype`; this is closely related to #5521.

I am not sure what the Java Language Specification says about this, or whether it says anything about this situation at all. Because generic types do not appear in type usage (as far as I know); type usage either references parameterized or raw types.
The current issue with the CodeQL predicates is that there are a lot predicates for navigating the hierarchy (`hasSubtype`, `getASubtype`, `getASupertype`, ...), but all of them do not work correctly for generic types. This will likely be confusing (and maybe even frustrating) for new users.

If possible, without violating any constraints and without negatively affecting performance too much, would it be possible to consider generic types in the type hierarchy related predicates by default (possibly rendering `getASourceSupertype` redundant)?

---

Also, to avoid any misunderstanding, here is how CodeQL currently represents the types (with their name):
- Generic type: `List`; represents the class or interface declared in the source file, or in a third party class file
- Raw type: `List<>`; represents usage of a raw type, e.g. `List strings = ...`
- Parameterized type: `List`

Beitragsleitfaden

Beitragsleitfaden öffnen

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.