Skip to content

Commit 93daaf5

Browse files
authored
Merge pull request github#6174 from joefarebrother/guava-collections
Java: Model Guava collections package
2 parents 27c45d8 + 522c6e0 commit 93daaf5

File tree

91 files changed

+11334
-1095
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+11334
-1095
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
lgtm,codescanning
2+
* Improved modelling for the `com.google.common.collect` package of the Guava framework.

java/ql/lib/semmle/code/java/frameworks/guava/Collections.qll

Lines changed: 564 additions & 292 deletions
Large diffs are not rendered by default.

java/ql/src/utils/FlowTestCase.qll

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,15 @@ class TestCase extends TTestCase {
257257
if componentStack = baseOutput
258258
then result = "out"
259259
else
260-
result =
261-
SupportMethod::getMethodForContent(componentStack)
262-
.getCall(this.getOutput(componentStack.tail()))
260+
if componentStack.tail() = baseOutput
261+
then
262+
result =
263+
SupportMethod::getMethodFor(this.getOutputType(), componentStack)
264+
.getCall(this.getOutput(componentStack.tail()))
265+
else
266+
result =
267+
SupportMethod::getMethodForContent(componentStack)
268+
.getCall(this.getOutput(componentStack.tail()))
263269
)
264270
}
265271

java/ql/src/utils/FlowTestCaseSupportMethods.qll

Lines changed: 120 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ private class DefaultGetMethod extends GetMethod {
145145

146146
DefaultGetMethod() { this = "DefaultGet" + contentToken(c) }
147147

148-
string getName() { result = "get" + contentToken(c) }
148+
string getName() { result = "get" + contentToken(c) + "Default" }
149149

150150
override int getPriority() { result = 999 }
151151

@@ -159,12 +159,12 @@ private class DefaultGetMethod extends GetMethod {
159159
override string getCall(string arg) { result = this.getName() + "(" + arg + ")" }
160160

161161
override string getDefinition() {
162-
result = "Object get" + contentToken(c) + "(Object container) { return null; }"
162+
result = "Object get" + contentToken(c) + "Default(Object container) { return null; }"
163163
}
164164

165165
override string getCsvModel() {
166166
result =
167-
"generatedtest;Test;false;" + this.getName() + ";;;" +
167+
"generatedtest;Test;false;" + this.getName() + ";(Object);;" +
168168
getComponentSpec(SummaryComponent::content(c)) + " of Argument[0];ReturnValue;value"
169169
}
170170
}
@@ -201,6 +201,22 @@ private class IteratorGetMethod extends GetMethod {
201201
override string getCall(string arg) { result = "getElement(" + arg + ")" }
202202
}
203203

204+
private class EnumerationGetMethod extends GetMethod {
205+
EnumerationGetMethod() { this = "enumerationgetmethod" }
206+
207+
override predicate appliesTo(Type t, Content c) {
208+
t.(RefType).getASourceSupertype*().hasQualifiedName("java.util", "Enumeration") and
209+
c instanceof CollectionContent
210+
}
211+
212+
override string getDefinition() {
213+
result = "<T> T getElement(Enumeration<T> it) { return it.nextElement(); }"
214+
}
215+
216+
bindingset[arg]
217+
override string getCall(string arg) { result = "getElement(" + arg + ")" }
218+
}
219+
204220
private class OptionalGetMethod extends GetMethod {
205221
OptionalGetMethod() { this = "optionalgetmethod" }
206222

@@ -215,8 +231,8 @@ private class OptionalGetMethod extends GetMethod {
215231
override string getCall(string arg) { result = "getElement(" + arg + ")" }
216232
}
217233

218-
private class MapGetKeyMethod extends GetMethod {
219-
MapGetKeyMethod() { this = "mapgetkeymethod" }
234+
private class MapGetKeytMethod extends GetMethod {
235+
MapGetKeytMethod() { this = "mapgetkeymethod" }
220236

221237
override predicate appliesTo(Type t, Content c) {
222238
t.(RefType).getASourceSupertype*().hasQualifiedName("java.util", "Map") and
@@ -231,8 +247,20 @@ private class MapGetKeyMethod extends GetMethod {
231247
override string getCall(string arg) { result = "getMapKey(" + arg + ")" }
232248
}
233249

234-
private class MapValueGetMethod extends GetMethod {
235-
MapValueGetMethod() { this = "MapValueGetMethod" }
250+
private class MapEntryGetKeyMethod extends GetMethod {
251+
MapEntryGetKeyMethod() { this = "mapentrygetkeymethod" }
252+
253+
override predicate appliesTo(Type t, Content c) {
254+
t.(RefType).getASourceSupertype*().hasQualifiedName("java.util", "Map$Entry") and
255+
c instanceof MapKeyContent
256+
}
257+
258+
bindingset[arg]
259+
override string getCall(string arg) { result = arg + ".getKey()" }
260+
}
261+
262+
private class MapGetValueMethod extends GetMethod {
263+
MapGetValueMethod() { this = "MapGetValueMethod" }
236264

237265
override predicate appliesTo(Type t, Content c) {
238266
t.(RefType).getASourceSupertype*().hasQualifiedName("java.util", "Map") and
@@ -247,6 +275,18 @@ private class MapValueGetMethod extends GetMethod {
247275
override string getCall(string arg) { result = "getMapValue(" + arg + ")" }
248276
}
249277

278+
private class MapEntryGetValueMethod extends GetMethod {
279+
MapEntryGetValueMethod() { this = "mapentrygetvaluemethod" }
280+
281+
override predicate appliesTo(Type t, Content c) {
282+
t.(RefType).getASourceSupertype*().hasQualifiedName("java.util", "Map$Entry") and
283+
c instanceof MapValueContent
284+
}
285+
286+
bindingset[arg]
287+
override string getCall(string arg) { result = arg + ".getValue()" }
288+
}
289+
250290
private class ArrayGetMethod extends GetMethod {
251291
ArrayGetMethod() { this = "arraygetmethod" }
252292

@@ -285,7 +325,7 @@ private class DefaultGenMethod extends GenMethod {
285325

286326
DefaultGenMethod() { this = "DefaultGen" + contentToken(c) }
287327

288-
string getName() { result = "newWith" + contentToken(c) }
328+
string getName() { result = "newWith" + contentToken(c) + "Default" }
289329

290330
override int getPriority() { result = 999 }
291331

@@ -299,12 +339,12 @@ private class DefaultGenMethod extends GenMethod {
299339
override string getCall(string arg) { result = this.getName() + "(" + arg + ")" }
300340

301341
override string getDefinition() {
302-
result = "Object newWith" + contentToken(c) + "(Object element) { return null; }"
342+
result = "Object newWith" + contentToken(c) + "Default(Object element) { return null; }"
303343
}
304344

305345
override string getCsvModel() {
306346
result =
307-
"generatedtest;Test;false;" + this.getName() + ";;;Argument[0];" +
347+
"generatedtest;Test;false;" + this.getName() + ";(Object);;Argument[0];" +
308348
getComponentSpec(SummaryComponent::content(c)) + " of ReturnValue;value"
309349
}
310350
}
@@ -314,7 +354,8 @@ private class ListGenMethod extends GenMethod {
314354

315355
override predicate appliesTo(Type t, Content c) {
316356
exists(GenericType list | list.hasQualifiedName("java.util", "List") |
317-
t = list or list.getAParameterizedType().getASupertype*() = t
357+
t.getErasure() = list.getASourceSupertype*().getErasure() or // cover things like Iterable and Collection
358+
list.getAParameterizedType().getASupertype*() = t
318359
) and
319360
c instanceof CollectionContent
320361
}
@@ -323,12 +364,40 @@ private class ListGenMethod extends GenMethod {
323364
override string getCall(string arg) { result = "List.of(" + arg + ")" }
324365
}
325366

367+
private class SetGenMethod extends GenMethod {
368+
SetGenMethod() { this = "SetGenMethod" }
369+
370+
override predicate appliesTo(Type t, Content c) {
371+
exists(GenericType set | set.hasQualifiedName("java.util", "Set") |
372+
t.getErasure() = set.getErasure()
373+
) and
374+
c instanceof CollectionContent
375+
}
376+
377+
bindingset[arg]
378+
override string getCall(string arg) { result = "Set.of(" + arg + ")" }
379+
}
380+
381+
private class IteratorGenMethod extends GenMethod {
382+
IteratorGenMethod() { this = "IteratorGenMethod" }
383+
384+
override predicate appliesTo(Type t, Content c) {
385+
exists(GenericType set | set.hasQualifiedName("java.util", "Iterator") |
386+
t.getErasure() = set.getErasure()
387+
) and
388+
c instanceof CollectionContent
389+
}
390+
391+
bindingset[arg]
392+
override string getCall(string arg) { result = "List.of(" + arg + ").iterator()" }
393+
}
394+
326395
private class OptionalGenMethod extends GenMethod {
327396
OptionalGenMethod() { this = "optionalgenmethod" }
328397

329398
override predicate appliesTo(Type t, Content c) {
330-
exists(GenericType list | list.hasQualifiedName("java.util", "List") |
331-
list.getAParameterizedType().getASupertype*() = t
399+
exists(GenericType op | op.hasQualifiedName("java.util", "Optional") |
400+
op.getAParameterizedType().getASupertype*() = t
332401
) and
333402
c instanceof CollectionContent
334403
}
@@ -351,6 +420,25 @@ private class MapGenKeyMethod extends GenMethod {
351420
override string getCall(string arg) { result = "Map.of(" + arg + ", null)" }
352421
}
353422

423+
private class MapEntryGenKeyMethod extends GenMethod {
424+
MapEntryGenKeyMethod() { this = "mapentrygenkeymethod" }
425+
426+
override predicate appliesTo(Type t, Content c) {
427+
exists(GenericType map | map.hasQualifiedName("java.util", "Map$Entry") |
428+
map.getAParameterizedType().getASupertype*() = t
429+
) and
430+
c instanceof MapKeyContent
431+
}
432+
433+
override string getDefinition() {
434+
result =
435+
"<K> Map.Entry<K,?> newEntryWithMapKey(K key) { return Map.of(key, null).entrySet().iterator().next(); }"
436+
}
437+
438+
bindingset[arg]
439+
override string getCall(string arg) { result = "newEntryWithMapKey(" + arg + ")" }
440+
}
441+
354442
private class MapGenValueMethod extends GenMethod {
355443
MapGenValueMethod() { this = "mapvaluegenmethod" }
356444

@@ -365,6 +453,25 @@ private class MapGenValueMethod extends GenMethod {
365453
override string getCall(string arg) { result = "Map.of(null, " + arg + ")" }
366454
}
367455

456+
private class MapEntryGenValueMethod extends GenMethod {
457+
MapEntryGenValueMethod() { this = "mapentrygenvaluemethod" }
458+
459+
override predicate appliesTo(Type t, Content c) {
460+
exists(GenericType map | map.hasQualifiedName("java.util", "Map$Entry") |
461+
map.getAParameterizedType().getASupertype*() = t
462+
) and
463+
c instanceof MapValueContent
464+
}
465+
466+
override string getDefinition() {
467+
result =
468+
"<V> Map.Entry<?,V> newEntryWithMapValue(V value) { return Map.of(null, value).entrySet().iterator().next(); }"
469+
}
470+
471+
bindingset[arg]
472+
override string getCall(string arg) { result = "newEntryWithMapValue(" + arg + ")" }
473+
}
474+
368475
/**
369476
* Returns a cast to type `t` if `t` is not `java.lang.Object`, or an empty string otherwise.
370477
*/

java/ql/test/library-tests/frameworks/guava/TestCollect.java

Lines changed: 0 additions & 122 deletions
This file was deleted.

0 commit comments

Comments
 (0)