Skip to content

Commit caea621

Browse files
author
Esben Sparre Andreasen
committed
JS: use inheritance in js/mixed-static-instance-this-access
1 parent 26a248b commit caea621

File tree

5 files changed

+41
-3
lines changed

5 files changed

+41
-3
lines changed

change-notes/1.19/analysis-javascript.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
| Unused variable, import, function or class | Fewer results | This rule now flags import statements with multiple unused imports once. |
5757
| Useless assignment to local variable | Fewer false-positive results | This rule now recognizes additional ways default values can be set. |
5858
| Whitespace contradicts operator precedence | Fewer false-positive results | This rule no longer flags operators with asymmetric whitespace. |
59+
| Wrong use of 'this' for static method | More results, fewer false-positive results | This rule now recognizes inherited methods. |
5960

6061
## Changes to QL libraries
6162

javascript/ql/src/Declarations/MixedStaticInstanceThisAccess.ql

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,19 @@
1010
*/
1111
import javascript
1212

13+
/** Holds if `base` declares or inherits method `m` with the given `name`. */
14+
predicate hasMethod(ClassDefinition base, string name, MethodDefinition m) {
15+
m = base.getMethod(name) or
16+
hasMethod(base.getSuperClassDefinition(), name, m)
17+
}
1318

1419
/**
1520
* Holds if `access` is in`fromMethod`, and it references `toMethod` through `this`.
1621
*/
1722
predicate isLocalMethodAccess(PropAccess access, MethodDefinition fromMethod, MethodDefinition toMethod) {
18-
fromMethod.getDeclaringClass() = toMethod.getDeclaringClass() and
23+
hasMethod(fromMethod.getDeclaringClass(), access.getPropertyName(), toMethod) and
1924
access.getEnclosingFunction() = fromMethod.getBody() and
20-
access.getBase() instanceof ThisExpr and
21-
access.getPropertyName() = toMethod.getName()
25+
access.getBase() instanceof ThisExpr
2226
}
2327

2428
string getKind(MethodDefinition m) {

javascript/ql/src/semmle/javascript/Classes.qll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,13 @@ class ClassDefinition extends @classdefinition, ClassOrInterface, AST::ValueNode
216216
)
217217
}
218218

219+
/**
220+
* Gets the definition of the super class of this class, if it can be determined.
221+
*/
222+
ClassDefinition getSuperClassDefinition() {
223+
result = getSuperClass().analyze().getAValue().(AbstractClass).getClass()
224+
}
225+
219226
}
220227

221228
/**
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
| instanceStatic.js:3:9:3:16 | this.baz | Access to instance method $@ from static method $@ is not possible through `this`. | instanceStatic.js:5:5:7:5 | baz(){\\n\\n } | baz | instanceStatic.js:2:5:4:5 | static ... K\\n } | bar |
22
| staticInstance.js:3:9:3:16 | this.baz | Access to static method $@ from instance method $@ is not possible through `this`. | staticInstance.js:5:5:6:5 | static baz(){\\n } | baz | staticInstance.js:2:5:4:5 | bar(){\\n ... K\\n } | bar |
3+
| tst.js:66:9:66:14 | this.f | Access to instance method $@ from static method $@ is not possible through `this`. | tst.js:60:5:62:5 | f() {\\n\\n } | f | tst.js:65:5:67:5 | static ... K\\n } | test |

javascript/ql/test/query-tests/Declarations/MixedStaticInstanceThisAccess/tst.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,28 @@ class C4 {
4141
}
4242
}
4343
C4.f = x;
44+
45+
class C5_super {
46+
f() {
47+
48+
}
49+
}
50+
class C5 extends C5_super{
51+
static f() {
52+
53+
}
54+
test() {
55+
this.f; // OK
56+
}
57+
}
58+
59+
class C6_super {
60+
f() {
61+
62+
}
63+
}
64+
class C6 extends C6_super{
65+
static test() {
66+
this.f; // NOT OK
67+
}
68+
}

0 commit comments

Comments
 (0)