Skip to content

Commit 01eeebc

Browse files
committed
Java: Refactor definitions query, add queries for ide search
This enables jump-to-definition and find-references in the VS Code extension, for Java source archives.
1 parent 48e4079 commit 01eeebc

File tree

5 files changed

+251
-188
lines changed

5 files changed

+251
-188
lines changed

java/ql/src/codeql-suites/java-lgtm-full.qls

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,8 @@
22
- qlpack: codeql-java
33
- apply: lgtm-selectors.yml
44
from: codeql-suite-helpers
5+
# These are only for IDE use.
6+
- exclude:
7+
tags contain:
8+
- ide-contextual-queries/local-definitions
9+
- ide-contextual-queries/local-references

java/ql/src/definitions.ql

Lines changed: 2 additions & 188 deletions
Original file line numberDiff line numberDiff line change
@@ -6,194 +6,8 @@
66
* @id java/jump-to-definition
77
*/
88

9-
import java
10-
11-
/**
12-
* Restricts the location of a method access to the method identifier only,
13-
* excluding its qualifier, type arguments and arguments.
14-
*
15-
* If there is any whitespace between the method identifier and its first argument,
16-
* or between the method identifier and its qualifier (or last type argument, if any),
17-
* the location may be slightly inaccurate and include such whitespace,
18-
* but it should suffice for the purpose of avoiding overlapping definitions.
19-
*/
20-
class LocationOverridingMethodAccess extends MethodAccess {
21-
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
22-
exists(MemberRefExpr e | e.getReferencedCallable() = getMethod() |
23-
exists(int elRef, int ecRef | e.hasLocationInfo(path, _, _, elRef, ecRef) |
24-
sl = elRef and
25-
sc = ecRef - getMethod().getName().length() + 1 and
26-
el = elRef and
27-
ec = ecRef
28-
)
29-
)
30-
or
31-
not exists(MemberRefExpr e | e.getReferencedCallable() = getMethod()) and
32-
exists(int slSuper, int scSuper, int elSuper, int ecSuper |
33-
super.hasLocationInfo(path, slSuper, scSuper, elSuper, ecSuper)
34-
|
35-
(
36-
if exists(getTypeArgument(_))
37-
then
38-
exists(Location locTypeArg |
39-
locTypeArg = getTypeArgument(count(getTypeArgument(_)) - 1).getLocation()
40-
|
41-
sl = locTypeArg.getEndLine() and
42-
sc = locTypeArg.getEndColumn() + 2
43-
)
44-
else (
45-
if exists(getQualifier())
46-
then
47-
// Note: this needs to be the original (full) location of the qualifier, not the modified one.
48-
exists(Location locQual | locQual = getQualifier().getLocation() |
49-
sl = locQual.getEndLine() and
50-
sc = locQual.getEndColumn() + 2
51-
)
52-
else (
53-
sl = slSuper and
54-
sc = scSuper
55-
)
56-
)
57-
) and
58-
(
59-
if getNumArgument() > 0
60-
then
61-
// Note: this needs to be the original (full) location of the first argument, not the modified one.
62-
exists(Location locArg | locArg = getArgument(0).getLocation() |
63-
el = locArg.getStartLine() and
64-
ec = locArg.getStartColumn() - 2
65-
)
66-
else (
67-
el = elSuper and
68-
ec = ecSuper - 2
69-
)
70-
)
71-
)
72-
}
73-
}
74-
75-
/**
76-
* Restricts the location of a type access to exclude
77-
* the type arguments and qualifier, if any.
78-
*/
79-
class LocationOverridingTypeAccess extends TypeAccess {
80-
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
81-
exists(int slSuper, int scSuper, int elSuper, int ecSuper |
82-
super.hasLocationInfo(path, slSuper, scSuper, elSuper, ecSuper)
83-
|
84-
(
85-
if exists(getQualifier())
86-
then
87-
// Note: this needs to be the original (full) location of the qualifier, not the modified one.
88-
exists(Location locQual | locQual = getQualifier().getLocation() |
89-
sl = locQual.getEndLine() and
90-
sc = locQual.getEndColumn() + 2
91-
)
92-
else (
93-
sl = slSuper and
94-
sc = scSuper
95-
)
96-
) and
97-
(
98-
if exists(getTypeArgument(_))
99-
then
100-
// Note: this needs to be the original (full) location of the first type argument, not the modified one.
101-
exists(Location locArg | locArg = getTypeArgument(0).getLocation() |
102-
el = locArg.getStartLine() and
103-
ec = locArg.getStartColumn() - 2
104-
)
105-
else (
106-
el = elSuper and
107-
ec = ecSuper
108-
)
109-
)
110-
)
111-
}
112-
}
113-
114-
/**
115-
* Restricts the location of a field access to the name of the accessed field only,
116-
* excluding its qualifier.
117-
*/
118-
class LocationOverridingFieldAccess extends FieldAccess {
119-
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
120-
super.hasLocationInfo(path, _, _, el, ec) and
121-
sl = el and
122-
sc = ec - getField().getName().length() + 1
123-
}
124-
}
125-
126-
/**
127-
* Restricts the location of a single-type-import declaration to the name of the imported type only,
128-
* excluding the `import` keyword and the package name.
129-
*/
130-
class LocationOverridingImportType extends ImportType {
131-
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
132-
exists(int slSuper, int scSuper, int elSuper, int ecSuper |
133-
super.hasLocationInfo(path, slSuper, scSuper, elSuper, ecSuper)
134-
|
135-
el = elSuper and
136-
ec = ecSuper - 1 and
137-
sl = el and
138-
sc = ecSuper - getImportedType().getName().length()
139-
)
140-
}
141-
}
142-
143-
/**
144-
* Restricts the location of a single-static-import declaration to the name of the imported member(s) only,
145-
* excluding the `import` keyword and the package name.
146-
*/
147-
class LocationOverridingImportStaticTypeMember extends ImportStaticTypeMember {
148-
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
149-
exists(int slSuper, int scSuper, int elSuper, int ecSuper |
150-
super.hasLocationInfo(path, slSuper, scSuper, elSuper, ecSuper)
151-
|
152-
el = elSuper and
153-
ec = ecSuper - 1 and
154-
sl = el and
155-
sc = ecSuper - getName().length()
156-
)
157-
}
158-
}
159-
160-
Element definition(Element e, string kind) {
161-
e.(MethodAccess).getMethod().getSourceDeclaration() = result and
162-
kind = "M" and
163-
not result instanceof InitializerMethod
164-
or
165-
e.(TypeAccess).getType().(RefType).getSourceDeclaration() = result and kind = "T"
166-
or
167-
exists(Variable v | v = e.(VarAccess).getVariable() |
168-
result = v.(Field).getSourceDeclaration() or
169-
result = v.(Parameter).getSourceDeclaration() or
170-
result = v.(LocalVariableDecl)
171-
) and
172-
kind = "V"
173-
or
174-
e.(ImportType).getImportedType() = result and kind = "I"
175-
or
176-
e.(ImportStaticTypeMember).getAMemberImport() = result and kind = "I"
177-
}
178-
179-
predicate dummyVarAccess(VarAccess va) {
180-
exists(AssignExpr ae, InitializerMethod im |
181-
ae.getDest() = va and
182-
ae.getParent() = im.getBody().getAChild()
183-
)
184-
}
185-
186-
predicate dummyTypeAccess(TypeAccess ta) {
187-
exists(FunctionalExpr e |
188-
e.getAnonymousClass().getClassInstanceExpr().getTypeName() = ta.getParent*()
189-
)
190-
}
9+
import definitions
19110

19211
from Element e, Element def, string kind
193-
where
194-
def = definition(e, kind) and
195-
def.fromSource() and
196-
e.fromSource() and
197-
not dummyVarAccess(e) and
198-
not dummyTypeAccess(e)
12+
where def = definitionOf(e, kind)
19913
select e, def, kind

0 commit comments

Comments
 (0)