From f8373c1f19fa2ba3ebde7ff272860a3931016a2b Mon Sep 17 00:00:00 2001 From: Kasper Svendsen Date: Thu, 9 Jan 2025 09:35:56 +0100 Subject: [PATCH] Define entity discard predicates for Java --- java/ql/lib/java.qll | 1 + java/ql/lib/semmle/code/Location.qll | 14 +++++++++ java/ql/lib/semmle/code/java/Expr.qll | 13 +++++++++ java/ql/lib/semmle/code/java/Javadoc.qll | 13 +++++++++ java/ql/lib/semmle/code/java/Member.qll | 33 ++++++++++++++++++++++ java/ql/lib/semmle/code/java/Overlay.qll | 29 +++++++++++++++++++ java/ql/lib/semmle/code/java/Statement.qll | 13 +++++++++ java/ql/lib/semmle/code/java/Variable.qll | 13 +++++++++ 8 files changed, 129 insertions(+) create mode 100644 java/ql/lib/semmle/code/java/Overlay.qll diff --git a/java/ql/lib/java.qll b/java/ql/lib/java.qll index 9644343e93b..82c37282379 100644 --- a/java/ql/lib/java.qll +++ b/java/ql/lib/java.qll @@ -26,6 +26,7 @@ import semmle.code.java.KotlinType import semmle.code.java.Member import semmle.code.java.Modifier import semmle.code.java.Modules +import semmle.code.java.Overlay import semmle.code.java.Package import semmle.code.java.Statement import semmle.code.java.Type diff --git a/java/ql/lib/semmle/code/Location.qll b/java/ql/lib/semmle/code/Location.qll index 14fc7a99532..cd5b41ca749 100644 --- a/java/ql/lib/semmle/code/Location.qll +++ b/java/ql/lib/semmle/code/Location.qll @@ -221,3 +221,17 @@ private predicate fixedHasLocation(Top l, Location loc, File f) { not hasSourceLocation(l, _, _) and locations_default(loc, f, _, _, _, _) } + +overlay[local] +pragma[nomagic] +predicate discardableLocation(string file, @location l) { + not hasOverlay() and + file = getRawFileForLoc(l) and + not exists(@file f | hasLocation(f, l)) +} + +overlay[discard_entity] +pragma[nomagic] +predicate discardLocation(@location l) { + exists(string file | discardableLocation(file, l) and discardFile(file)) +} diff --git a/java/ql/lib/semmle/code/java/Expr.qll b/java/ql/lib/semmle/code/java/Expr.qll index 182bf5b7001..814da6ce1c8 100644 --- a/java/ql/lib/semmle/code/java/Expr.qll +++ b/java/ql/lib/semmle/code/java/Expr.qll @@ -2701,3 +2701,16 @@ class RecordPatternExpr extends Expr, @recordpatternexpr { ) } } + +overlay[local] +pragma[nomagic] +predicate discardableExpr(string file, @expr e) { + not hasOverlay() and + file = getRawFile(e) +} + +overlay[discard_entity] +pragma[nomagic] +predicate discardExpr(@expr e) { + exists(string file | discardableExpr(file, e) and discardFile(file)) +} diff --git a/java/ql/lib/semmle/code/java/Javadoc.qll b/java/ql/lib/semmle/code/java/Javadoc.qll index ef8f77bf9ba..f9132e7ad05 100644 --- a/java/ql/lib/semmle/code/java/Javadoc.qll +++ b/java/ql/lib/semmle/code/java/Javadoc.qll @@ -196,3 +196,16 @@ class KtCommentSection extends @ktcommentsection { /** Gets the string representation of this section. */ string toString() { result = this.getContent() } } + +overlay[local] +pragma[nomagic] +predicate discardableJavadoc(string file, @javadoc d) { + not hasOverlay() and + exists(@member m | file = getRawFile(m) and hasJavadoc(m, d)) +} + +overlay[discard_entity] +pragma[nomagic] +predicate discardJavadoc(@javadoc d) { + exists(string file | discardableJavadoc(file, d) and discardFile(file)) +} diff --git a/java/ql/lib/semmle/code/java/Member.qll b/java/ql/lib/semmle/code/java/Member.qll index 662eab06bd1..e3ea0605e1f 100644 --- a/java/ql/lib/semmle/code/java/Member.qll +++ b/java/ql/lib/semmle/code/java/Member.qll @@ -897,3 +897,36 @@ class ExtensionMethod extends Method { else result = 0 } } + +overlay[local] +pragma[nomagic] +predicate discardableMethod(string file, @method m) { + not hasOverlay() and + file = getRawFile(m) and + exists(@classorinterface c | methods(m, _, _, _, c, _) and isAnonymClass(c, _)) +} + +overlay[discard_entity] +pragma[nomagic] +predicate discardAnonMethod(@method m) { + exists(string file | discardableMethod(file, m) and discardFile(file)) +} + +overlay[local] +pragma[nomagic] +predicate discardableBaseMethod(string file, @method m) { + not hasOverlay() and + file = getRawFile(m) +} + +overlay[local] +pragma[nomagic] +predicate usedOverlayMethod(@method m) { hasOverlay() and methods(m, _, _, _, _, _) } + +overlay[discard_entity] +pragma[nomagic] +predicate discardMethod(@method m) { + exists(string file | + discardableBaseMethod(file, m) and discardFile(file) and not usedOverlayMethod(m) + ) +} diff --git a/java/ql/lib/semmle/code/java/Overlay.qll b/java/ql/lib/semmle/code/java/Overlay.qll new file mode 100644 index 00000000000..caeb2f0ddee --- /dev/null +++ b/java/ql/lib/semmle/code/java/Overlay.qll @@ -0,0 +1,29 @@ +overlay[local?] +module; + +import java + +overlay[local] +pragma[nomagic] +predicate hasOverlay() { databaseMetadata("isOverlay", "true") } + +overlay[local] +string getRawFile(@locatable el) { + exists(@location loc, @file file | + hasLocation(el, loc) and + locations_default(loc, file, _, _, _, _) and + files(file, result) + ) +} + +overlay[local] +string getRawFileForLoc(@location l) { + exists(@file f | locations_default(l, f, _, _, _, _) and files(f, result)) +} + +overlay[local] +pragma[nomagic] +predicate discardFile(string file) { + hasOverlay() and + exists(@expr e | callableEnclosingExpr(e, _) and file = getRawFile(e)) +} diff --git a/java/ql/lib/semmle/code/java/Statement.qll b/java/ql/lib/semmle/code/java/Statement.qll index 73b0aac5cbd..0591155037f 100644 --- a/java/ql/lib/semmle/code/java/Statement.qll +++ b/java/ql/lib/semmle/code/java/Statement.qll @@ -987,3 +987,16 @@ class SuperConstructorInvocationStmt extends Stmt, ConstructorCall, @superconstr override string getAPrimaryQlClass() { result = "SuperConstructorInvocationStmt" } } + +overlay[local] +pragma[nomagic] +predicate discardableStmt(string file, @stmt s) { + not hasOverlay() and + file = getRawFile(s) +} + +overlay[discard_entity] +pragma[nomagic] +predicate discardStmt(@stmt s) { + exists(string file | discardableStmt(file, s) and discardFile(file)) +} diff --git a/java/ql/lib/semmle/code/java/Variable.qll b/java/ql/lib/semmle/code/java/Variable.qll index 50fd7a06484..875c39d8443 100644 --- a/java/ql/lib/semmle/code/java/Variable.qll +++ b/java/ql/lib/semmle/code/java/Variable.qll @@ -133,3 +133,16 @@ class Parameter extends Element, @param, LocalScopeVariable { /** Holds if this is an anonymous parameter, `_` */ predicate isAnonymous() { this.getName() = "" } } + +overlay[local] +pragma[nomagic] +predicate discardableLocalVarDecl(string file, @localscopevariable l) { + not hasOverlay() and + file = getRawFile(l) +} + +overlay[discard_entity] +pragma[nomagic] +predicate discardLocalVarDecl(@localscopevariable l) { + exists(string file | discardableLocalVarDecl(file, l) and discardFile(file)) +}