From 597d8e7d9446e25fb1e208c51a098402f96b205f Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 21 Jan 2020 11:59:08 +0100 Subject: [PATCH 1/5] Java: Update dbscheme for ParExpr removal. --- java/ql/src/config/semmlecode.dbscheme | 7 ++- java/ql/src/config/semmlecode.dbscheme.stats | 53 ++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/java/ql/src/config/semmlecode.dbscheme b/java/ql/src/config/semmlecode.dbscheme index e7706df98aa..054d7e823b2 100755 --- a/java/ql/src/config/semmlecode.dbscheme +++ b/java/ql/src/config/semmlecode.dbscheme @@ -516,6 +516,11 @@ statementEnclosingExpr( int statement_id: @stmt ref ); +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + case @expr.kind of 1 = @arrayaccess | 2 = @arraycreationexpr @@ -570,7 +575,7 @@ case @expr.kind of | 51 = @castexpr | 52 = @newexpr | 53 = @conditionalexpr -| 54 = @parexpr +| 54 = @parexpr // deprecated | 55 = @instanceofexpr | 56 = @localvariabledeclexpr | 57 = @typeliteral diff --git a/java/ql/src/config/semmlecode.dbscheme.stats b/java/ql/src/config/semmlecode.dbscheme.stats index 22e7ff7e830..165db4674b5 100644 --- a/java/ql/src/config/semmlecode.dbscheme.stats +++ b/java/ql/src/config/semmlecode.dbscheme.stats @@ -18307,6 +18307,59 @@ +isParenthesized +76010 + + +id +76010 + + +parentheses +2 + + + + +id +parentheses + + +12 + + +1 +2 +76010 + + + + + + +parentheses +id + + +12 + + +30 +31 +1 + + +75980 +75981 +1 + + + + + + + + callableBinding 1437798 From 4bd332ddca8c733f4cb5559e1c2cc745e20887be Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 21 Jan 2020 15:52:09 +0100 Subject: [PATCH 2/5] Java: Add Expr.isParenthesized, adjust VarAccess.toString, and fix tests. --- java/ql/src/Complexity/ComplexCondition.ql | 5 ++++- java/ql/src/semmle/code/java/Expr.qll | 9 ++++++++- .../constants/CompileTimeConstantExpr.expected | 2 -- .../ql/test/library-tests/constants/getIntValue.expected | 2 +- java/ql/test/query-tests/Nullness/NullExprDeref.expected | 2 +- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/java/ql/src/Complexity/ComplexCondition.ql b/java/ql/src/Complexity/ComplexCondition.ql index e8f7b67f35e..0a03abb0adb 100644 --- a/java/ql/src/Complexity/ComplexCondition.ql +++ b/java/ql/src/Complexity/ComplexCondition.ql @@ -13,7 +13,10 @@ import java predicate nontrivialLogicalOperator(BinaryExpr e) { e instanceof LogicExpr and - not e.getParent().(Expr).getKind() = e.getKind() + ( + not e.getParent().(Expr).getKind() = e.getKind() or + e.isParenthesized() + ) } Expr getSimpleParent(Expr e) { diff --git a/java/ql/src/semmle/code/java/Expr.qll b/java/ql/src/semmle/code/java/Expr.qll index 313a8eb6aa8..3b95094e46e 100755 --- a/java/ql/src/semmle/code/java/Expr.qll +++ b/java/ql/src/semmle/code/java/Expr.qll @@ -95,6 +95,9 @@ class Expr extends ExprParent, @expr { or exists(LambdaExpr lam | lam.asMethod() = getEnclosingCallable() and lam.isInStaticContext()) } + + /** Holds if this expression is parenthesized. */ + predicate isParenthesized() { isParenthesized(this, _) } } /** @@ -1330,7 +1333,11 @@ class VarAccess extends Expr, @varaccess { /** Gets a printable representation of this expression. */ override string toString() { - result = this.getQualifier().toString() + "." + this.getVariable().getName() + exists(Expr q | q = this.getQualifier() | + if q.isParenthesized() + then result = "(...)." + this.getVariable().getName() + else result = q.toString() + "." + this.getVariable().getName() + ) or not this.hasQualifier() and result = this.getVariable().getName() } diff --git a/java/ql/test/library-tests/constants/CompileTimeConstantExpr.expected b/java/ql/test/library-tests/constants/CompileTimeConstantExpr.expected index 49a0c2285d4..f5e508b4a3c 100644 --- a/java/ql/test/library-tests/constants/CompileTimeConstantExpr.expected +++ b/java/ql/test/library-tests/constants/CompileTimeConstantExpr.expected @@ -7,10 +7,8 @@ | constants/Constants.java:15:15:15:37 | ... + ... | | constants/Constants.java:15:37:15:37 | 1 | | constants/Constants.java:16:23:16:41 | Initializers.SFIELD | -| constants/Constants.java:18:15:18:18 | (...) | | constants/Constants.java:18:16:18:17 | 12 | | constants/Constants.java:19:19:19:28 | "a string" | -| constants/Constants.java:20:17:20:23 | (...) | | constants/Constants.java:20:17:20:31 | ...?...:... | | constants/Constants.java:20:18:20:18 | 3 | | constants/Constants.java:20:18:20:22 | ... < ... | diff --git a/java/ql/test/library-tests/constants/getIntValue.expected b/java/ql/test/library-tests/constants/getIntValue.expected index acf4117a0ac..bee36f5122b 100644 --- a/java/ql/test/library-tests/constants/getIntValue.expected +++ b/java/ql/test/library-tests/constants/getIntValue.expected @@ -31,7 +31,7 @@ | constants/Values.java:67:27:67:33 | ... & ... | 42 | | constants/Values.java:68:26:68:32 | ... \| ... | 42 | | constants/Values.java:69:27:69:33 | ... ^ ... | 42 | -| constants/Values.java:83:19:83:22 | (...) | 42 | +| constants/Values.java:83:20:83:21 | 42 | 42 | | constants/Values.java:86:25:86:35 | final_field | 42 | | constants/Values.java:87:33:87:34 | 42 | 42 | | constants/Values.java:88:25:88:35 | final_local | 42 | diff --git a/java/ql/test/query-tests/Nullness/NullExprDeref.expected b/java/ql/test/query-tests/Nullness/NullExprDeref.expected index c8177626302..00aec204617 100644 --- a/java/ql/test/query-tests/Nullness/NullExprDeref.expected +++ b/java/ql/test/query-tests/Nullness/NullExprDeref.expected @@ -1 +1 @@ -| ExprDeref.java:7:12:7:34 | (...) | This expression is dereferenced and may be null. | +| ExprDeref.java:7:13:7:33 | ...?...:... | This expression is dereferenced and may be null. | From f8805ebb2423b1d65d4a861763acafd90dcb45f1 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Fri, 24 Jan 2020 13:42:59 +0100 Subject: [PATCH 3/5] Java: Update 2 queries. --- .../Likely Bugs/Arithmetic/MultiplyRemainder.ql | 5 +++-- .../WhitespaceContradictsPrecedence.ql | 16 ++++++++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/java/ql/src/Likely Bugs/Arithmetic/MultiplyRemainder.ql b/java/ql/src/Likely Bugs/Arithmetic/MultiplyRemainder.ql index 8653f9cc8d5..8992d1753d9 100644 --- a/java/ql/src/Likely Bugs/Arithmetic/MultiplyRemainder.ql +++ b/java/ql/src/Likely Bugs/Arithmetic/MultiplyRemainder.ql @@ -12,8 +12,9 @@ import java -from MulExpr e +from MulExpr e, RemExpr lhs where - e.getLeftOperand() instanceof RemExpr and + e.getLeftOperand() = lhs and + not lhs.isParenthesized() and e.getRightOperand().getType().hasName("int") select e, "Result of a remainder operation multiplied by an integer." diff --git a/java/ql/src/Likely Bugs/Arithmetic/WhitespaceContradictsPrecedence.ql b/java/ql/src/Likely Bugs/Arithmetic/WhitespaceContradictsPrecedence.ql index 12218a0ac49..ca31630ea22 100644 --- a/java/ql/src/Likely Bugs/Arithmetic/WhitespaceContradictsPrecedence.ql +++ b/java/ql/src/Likely Bugs/Arithmetic/WhitespaceContradictsPrecedence.ql @@ -120,12 +120,24 @@ predicate endOfBinaryLhs(BinaryExpr expr, int line, int col) { ) } +/** Compute the number of parenthesis characters next to the operator. */ +int getParensNextToOp(BinaryExpr expr) { + exists(Expr left, Expr right, int pleft, int pright | + left = expr.getLeftOperand() and + right = expr.getRightOperand() and + (if left.isParenthesized() then isParenthesized(left, pleft) else pleft = 0) and + (if right.isParenthesized() then isParenthesized(right, pright) else pright = 0) and + result = pleft + pright + ) +} + /** Compute whitespace around the operator. */ int operatorWS(BinaryExpr expr) { - exists(int line, int lcol, int rcol | + exists(int line, int lcol, int rcol, int parens | endOfBinaryLhs(expr, line, lcol) and startOfBinaryRhs(expr, line, rcol) and - result = rcol - lcol + 1 - expr.getOp().length() + parens = getParensNextToOp(expr) and + result = rcol - lcol + 1 - expr.getOp().length() - parens ) } From 34e6679afd5e2a610cb208cccfc01e126b8dd057 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Fri, 24 Jan 2020 13:46:58 +0100 Subject: [PATCH 4/5] Java: Add upgrade script. --- .../annotValue.ql | 27 + .../callableEnclosingExpr.ql | 17 + .../exprs.ql | 38 + .../hasLocation.ql | 17 + .../isParenthesized.ql | 29 + .../numlines.ql | 13 + .../old.dbscheme | 945 +++++++++++++++++ .../semmlecode.dbscheme | 950 ++++++++++++++++++ .../statementEnclosingExpr.ql | 17 + .../upgrade.properties | 9 + 10 files changed, 2062 insertions(+) create mode 100644 java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/annotValue.ql create mode 100644 java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/callableEnclosingExpr.ql create mode 100644 java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/exprs.ql create mode 100644 java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/hasLocation.ql create mode 100644 java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/isParenthesized.ql create mode 100644 java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/numlines.ql create mode 100755 java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/old.dbscheme create mode 100755 java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/semmlecode.dbscheme create mode 100644 java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/statementEnclosingExpr.ql create mode 100644 java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/upgrade.properties diff --git a/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/annotValue.ql b/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/annotValue.ql new file mode 100644 index 00000000000..60836f7f418 --- /dev/null +++ b/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/annotValue.ql @@ -0,0 +1,27 @@ +class Annotation extends @annotation { + string toString() { result = "annotation" } +} + +class Method extends @method { + string toString() { result = "method" } +} + +class Expr extends @expr { + string toString() { result = "expr" } +} + +class ParExpr extends Expr, @parexpr { + override string toString() { result = "(...)" } +} + +predicate parExprGetExpr(ParExpr pe, Expr e) { exprs(e, _, _, pe, _) } + +from Annotation parentid, Method id2, Expr oldvalue, Expr value +where + annotValue(parentid, id2, oldvalue) and + if oldvalue instanceof ParExpr + then + parExprGetExpr+(oldvalue, value) and + not value instanceof ParExpr + else value = oldvalue +select parentid, id2, value diff --git a/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/callableEnclosingExpr.ql b/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/callableEnclosingExpr.ql new file mode 100644 index 00000000000..ba1e29ef8e4 --- /dev/null +++ b/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/callableEnclosingExpr.ql @@ -0,0 +1,17 @@ +class Expr extends @expr { + string toString() { result = "expr" } +} + +class ParExpr extends Expr, @parexpr { + override string toString() { result = "(...)" } +} + +class Callable extends @callable { + string toString() { result = "callable" } +} + +from Expr id, Callable c +where + callableEnclosingExpr(id, c) and + not id instanceof ParExpr +select id, c diff --git a/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/exprs.ql b/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/exprs.ql new file mode 100644 index 00000000000..9c3fffdc99e --- /dev/null +++ b/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/exprs.ql @@ -0,0 +1,38 @@ +class ExprParent extends @exprparent { + string toString() { result = "exprparent" } +} + +class Expr extends ExprParent, @expr { + override string toString() { result = "expr" } +} + +class ParExpr extends Expr, @parexpr { + override string toString() { result = "(...)" } +} + +class Type extends @type { + string toString() { result = "type" } +} + +predicate astlink(ExprParent parent, Expr e, int idx, int parens) { + exprs(e, _, _, parent, idx) and + parens = 0 and + not parent instanceof ParExpr and + e instanceof ParExpr + or + exists(ParExpr pe | + exprs(e, _, _, pe, _) and + astlink(parent, pe, idx, parens - 1) + ) +} + +from Expr id, int kind, Type typeid, ExprParent oldparent, ExprParent parent, int oldidx, int idx +where + exprs(id, kind, typeid, oldparent, oldidx) and + not id instanceof ParExpr and + if oldparent instanceof ParExpr + then astlink(parent, id, idx, _) + else ( + parent = oldparent and idx = oldidx + ) +select id, kind, typeid, parent, idx diff --git a/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/hasLocation.ql b/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/hasLocation.ql new file mode 100644 index 00000000000..704c355f5d3 --- /dev/null +++ b/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/hasLocation.ql @@ -0,0 +1,17 @@ +class Locatable extends @locatable { + string toString() { result = "locatable" } +} + +class Location extends @location { + string toString() { result = "location" } +} + +class ParExpr extends Locatable, @parexpr { + override string toString() { result = "(...)" } +} + +from Locatable locatable, Location location +where + hasLocation(locatable, location) and + not locatable instanceof ParExpr +select locatable, location diff --git a/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/isParenthesized.ql b/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/isParenthesized.ql new file mode 100644 index 00000000000..5fce41b94e8 --- /dev/null +++ b/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/isParenthesized.ql @@ -0,0 +1,29 @@ +class ExprParent extends @exprparent { + string toString() { result = "exprparent" } +} + +class Expr extends ExprParent, @expr { + override string toString() { result = "expr" } +} + +class ParExpr extends Expr, @parexpr { + override string toString() { result = "(...)" } +} + +predicate astlink(ExprParent parent, Expr e, int idx, int parens) { + exprs(e, _, _, parent, idx) and + parens = 0 and + not parent instanceof ParExpr and + e instanceof ParExpr + or + exists(ParExpr pe | + exprs(e, _, _, pe, _) and + astlink(parent, pe, idx, parens - 1) + ) +} + +from Expr e, int parentheses +where + astlink(_, e, _, parentheses) and + not e instanceof ParExpr +select e, parentheses diff --git a/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/numlines.ql b/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/numlines.ql new file mode 100644 index 00000000000..716e940cfb5 --- /dev/null +++ b/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/numlines.ql @@ -0,0 +1,13 @@ +class Sourceline extends @sourceline { + string toString() { result = "sourceline" } +} + +class ParExpr extends Sourceline, @parexpr { + override string toString() { result = "(...)" } +} + +from Sourceline id, int l, int code, int comm +where + numlines(id, l, code, comm) and + not id instanceof ParExpr +select id, l, code, comm diff --git a/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/old.dbscheme b/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/old.dbscheme new file mode 100755 index 00000000000..e7706df98aa --- /dev/null +++ b/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/old.dbscheme @@ -0,0 +1,945 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref // deprecated +); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +classes( + unique int id: @class, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @class ref +); + +interfaces( + unique int id: @interface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @interface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @interface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @class ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @typeorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @typeorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @class ref, + int parent: @classinstancexpr ref +); + +#keyset[classid] #keyset[parent] +isLocalClass( + int classid: @class ref, + int parent: @localclassdeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @interface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @typeorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localclassdeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +; + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +@exprparent = @stmt | @expr | @callable | @field | @fielddecl | @class | @interface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@typeorpackage = @type | @package; + +@typeorcallable = @type | @callable; +@classorinterface = @interface | @class; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype; +@classorarray = @class | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; +@element = @file | @package | @primitive | @class | @interface | @method | @constructor | @modifier | @param | @exception | @field | + @annotation | @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl; + +@modifiable = @member_modifiable| @param | @localvar ; + +@member_modifiable = @class | @interface | @method | @constructor | @field ; + +@member = @method | @constructor | @field | @reftype ; + +@locatable = @file | @class | @interface | @fielddecl | @field | @constructor | @method | @param | @exception + | @boundedtype | @typebound | @array | @primitive + | @import | @stmt | @expr | @localvar | @javadoc | @javadocTag | @javadocText + | @xmllocatable; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; diff --git a/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/semmlecode.dbscheme b/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/semmlecode.dbscheme new file mode 100755 index 00000000000..054d7e823b2 --- /dev/null +++ b/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/semmlecode.dbscheme @@ -0,0 +1,950 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref // deprecated +); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +classes( + unique int id: @class, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @class ref +); + +interfaces( + unique int id: @interface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @interface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @interface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @class ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @typeorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @typeorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @class ref, + int parent: @classinstancexpr ref +); + +#keyset[classid] #keyset[parent] +isLocalClass( + int classid: @class ref, + int parent: @localclassdeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @interface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @typeorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localclassdeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +; + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +@exprparent = @stmt | @expr | @callable | @field | @fielddecl | @class | @interface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@typeorpackage = @type | @package; + +@typeorcallable = @type | @callable; +@classorinterface = @interface | @class; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype; +@classorarray = @class | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; +@element = @file | @package | @primitive | @class | @interface | @method | @constructor | @modifier | @param | @exception | @field | + @annotation | @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl; + +@modifiable = @member_modifiable| @param | @localvar ; + +@member_modifiable = @class | @interface | @method | @constructor | @field ; + +@member = @method | @constructor | @field | @reftype ; + +@locatable = @file | @class | @interface | @fielddecl | @field | @constructor | @method | @param | @exception + | @boundedtype | @typebound | @array | @primitive + | @import | @stmt | @expr | @localvar | @javadoc | @javadocTag | @javadocText + | @xmllocatable; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; diff --git a/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/statementEnclosingExpr.ql b/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/statementEnclosingExpr.ql new file mode 100644 index 00000000000..f5823b7794d --- /dev/null +++ b/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/statementEnclosingExpr.ql @@ -0,0 +1,17 @@ +class Expr extends @expr { + string toString() { result = "expr" } +} + +class ParExpr extends Expr, @parexpr { + override string toString() { result = "(...)" } +} + +class Statement extends @stmt { + string toString() { result = "stmt" } +} + +from Expr id, Statement s +where + statementEnclosingExpr(id, s) and + not id instanceof ParExpr +select id, s diff --git a/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/upgrade.properties b/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/upgrade.properties new file mode 100644 index 00000000000..679092fa830 --- /dev/null +++ b/java/upgrades/e7706df98aaefcf055f35f50582f2686f41c23bb/upgrade.properties @@ -0,0 +1,9 @@ +description: Refactor extraction of parentheses +compatibility: full +isParenthesized.rel: run isParenthesized.qlo +exprs.rel: run exprs.qlo +callableEnclosingExpr.rel: run callableEnclosingExpr.qlo +statementEnclosingExpr.rel: run statementEnclosingExpr.qlo +annotValue.rel: run annotValue.qlo +hasLocation.rel: run hasLocation.qlo +numlines.rel: run numlines.qlo From 0b3c90b526852be95075ee2cd052ac533724c63a Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Mon, 27 Jan 2020 09:27:00 +0100 Subject: [PATCH 5/5] Java: Fix whitespace query. --- .../Likely Bugs/Arithmetic/WhitespaceContradictsPrecedence.ql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/ql/src/Likely Bugs/Arithmetic/WhitespaceContradictsPrecedence.ql b/java/ql/src/Likely Bugs/Arithmetic/WhitespaceContradictsPrecedence.ql index ca31630ea22..db806ef760c 100644 --- a/java/ql/src/Likely Bugs/Arithmetic/WhitespaceContradictsPrecedence.ql +++ b/java/ql/src/Likely Bugs/Arithmetic/WhitespaceContradictsPrecedence.ql @@ -145,7 +145,8 @@ int operatorWS(BinaryExpr expr) { predicate interestingNesting(BinaryExpr inner, BinaryExpr outer) { inner = outer.getAChildExpr() and not inner instanceof AssocNestedExpr and - not inner instanceof HarmlessNestedExpr + not inner instanceof HarmlessNestedExpr and + not inner.isParenthesized() } from BinaryExpr inner, BinaryExpr outer, int wsouter, int wsinner