Skip to content

Commit 1aba111

Browse files
committed
JS: Use ::Range pattern for abstract classes
1 parent c8823fa commit 1aba111

File tree

2 files changed

+69
-13
lines changed

2 files changed

+69
-13
lines changed

javascript/ql/src/semmle/javascript/Closure.qll

Lines changed: 66 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,52 @@ module Closure {
88
/**
99
* A reference to a Closure namespace.
1010
*/
11-
abstract class ClosureNamespaceRef extends DataFlow::Node {
11+
class ClosureNamespaceRef extends DataFlow::Node {
12+
ClosureNamespaceRef::Range range;
13+
14+
ClosureNamespaceRef() { this = range }
15+
1216
/**
1317
* Gets the namespace being referenced.
1418
*/
15-
abstract string getClosureNamespace();
19+
string getClosureNamespace() { result = range.getClosureNamespace() }
20+
}
21+
22+
module ClosureNamespaceRef {
23+
/**
24+
* A reference to a Closure namespace.
25+
*
26+
* Can be subclassed to classify additional nodes as namespace references.
27+
*/
28+
abstract class Range extends DataFlow::Node {
29+
/**
30+
* Gets the namespace being referenced.
31+
*/
32+
abstract string getClosureNamespace();
33+
}
1634
}
1735

1836
/**
1937
* A data flow node that returns the value of a closure namespace.
2038
*/
21-
abstract class ClosureNamespaceAccess extends ClosureNamespaceRef { }
39+
class ClosureNamespaceAccess extends ClosureNamespaceRef {
40+
override ClosureNamespaceAccess::Range range;
41+
}
42+
43+
module ClosureNamespaceAccess {
44+
/**
45+
* A data flow node that returns the value of a closure namespace.
46+
*
47+
* Can be subclassed to classify additional nodes as namespace accesses.
48+
*/
49+
abstract class Range extends ClosureNamespaceRef::Range { }
50+
}
2251

2352
/**
2453
* A call to a method on the `goog.` namespace, as a closure reference.
2554
*/
26-
abstract private class DefaultNamespaceRef extends DataFlow::MethodCallNode, ClosureNamespaceRef {
55+
abstract private class DefaultNamespaceRef extends DataFlow::MethodCallNode,
56+
ClosureNamespaceRef::Range {
2757
DefaultNamespaceRef() { this = DataFlow::globalVarRef("goog").getAMethodCall() }
2858

2959
override string getClosureNamespace() { result = getArgument(0).asExpr().getStringValue() }
@@ -40,30 +70,51 @@ module Closure {
4070
/**
4171
* A top-level call to `goog.provide`.
4272
*/
43-
class ClosureProvideCall extends DefaultNamespaceRef {
44-
ClosureProvideCall() {
73+
private class DefaultClosureProvideCall extends DefaultNamespaceRef {
74+
DefaultClosureProvideCall() {
4575
getMethodName() = "provide" and
4676
isTopLevelExpr(this)
4777
}
4878
}
4979

80+
/**
81+
* A top-level call to `goog.provide`.
82+
*/
83+
class ClosureProvideCall extends ClosureNamespaceRef, DataFlow::MethodCallNode {
84+
override DefaultClosureProvideCall range;
85+
}
86+
5087
/**
5188
* A call to `goog.require`.
5289
*/
53-
class ClosureRequireCall extends DefaultNamespaceRef, ClosureNamespaceAccess {
54-
ClosureRequireCall() { getMethodName() = "require" }
90+
private class DefaultClosureRequireCall extends DefaultNamespaceRef, ClosureNamespaceAccess::Range {
91+
DefaultClosureRequireCall() { getMethodName() = "require" }
92+
}
93+
94+
/**
95+
* A call to `goog.require`.
96+
*/
97+
class ClosureRequireCall extends ClosureNamespaceAccess, DataFlow::MethodCallNode {
98+
override DefaultClosureRequireCall range;
5599
}
56100

57101
/**
58102
* A top-level call to `goog.module` or `goog.declareModuleId`.
59103
*/
60-
class ClosureModuleDeclaration extends DefaultNamespaceRef {
61-
ClosureModuleDeclaration() {
104+
private class DefaultClosureModuleDeclaration extends DefaultNamespaceRef {
105+
DefaultClosureModuleDeclaration() {
62106
(getMethodName() = "module" or getMethodName() = "declareModuleId") and
63107
isTopLevelExpr(this)
64108
}
65109
}
66110

111+
/**
112+
* A top-level call to `goog.module` or `goog.declareModuleId`.
113+
*/
114+
class ClosureModuleDeclaration extends ClosureNamespaceRef, DataFlow::MethodCallNode {
115+
override DefaultClosureModuleDeclaration range;
116+
}
117+
67118
/**
68119
* A module using the Closure module system, declared using `goog.module()` or `goog.declareModuleId()`.
69120
*/
@@ -192,11 +243,14 @@ module Closure {
192243
* Gets the closure namespace path written to by the given property write, if any.
193244
*/
194245
string getWrittenClosureNamespace(DataFlow::PropWrite node) {
195-
result = getClosureNamespaceFromSourceNode(node.getBase().getALocalSource()) + "." + node.getPropertyName()
246+
result = getClosureNamespaceFromSourceNode(node.getBase().getALocalSource()) + "." +
247+
node.getPropertyName()
196248
}
197249

198250
/**
199251
* Gets a data flow node that refers to the given value exported from a Closure module.
200252
*/
201-
DataFlow::SourceNode moduleImport(string moduleName) { getClosureNamespaceFromSourceNode(result) = moduleName }
253+
DataFlow::SourceNode moduleImport(string moduleName) {
254+
getClosureNamespaceFromSourceNode(result) = moduleName
255+
}
202256
}

javascript/ql/src/semmle/javascript/dataflow/internal/InterModuleTypeInference.qll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,9 @@ private class AnalyzedClosureExportAssign extends AnalyzedPropertyWrite, DataFlo
358358
private class AnalyzedClosureGlobalAccessPath extends AnalyzedNode, AnalyzedPropertyRead {
359359
string accessPath;
360360

361-
AnalyzedClosureGlobalAccessPath() { accessPath = Closure::getClosureNamespaceFromSourceNode(this) }
361+
AnalyzedClosureGlobalAccessPath() {
362+
accessPath = Closure::getClosureNamespaceFromSourceNode(this)
363+
}
362364

363365
override AnalyzedNode localFlowPred() {
364366
exists(DataFlow::PropWrite write |

0 commit comments

Comments
 (0)