Skip to content

Commit c06680a

Browse files
authored
Merge pull request github#3470 from asger-semmle/js/cache-module-import
Approved by esbena
2 parents fe68255 + e491431 commit c06680a

File tree

11 files changed

+43
-33
lines changed

11 files changed

+43
-33
lines changed

javascript/ql/src/semmle/javascript/AMD.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ private class AmdDependencyPath extends PathExprCandidate {
192192
}
193193

194194
/** A constant path element appearing in an AMD dependency expression. */
195-
private class ConstantAmdDependencyPathElement extends PathExprInModule, ConstantString {
195+
private class ConstantAmdDependencyPathElement extends PathExpr, ConstantString {
196196
ConstantAmdDependencyPathElement() { this = any(AmdDependencyPath amd).getAPart() }
197197

198198
override string getValue() { result = getStringValue() }

javascript/ql/src/semmle/javascript/ES2015Modules.qll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class ES2015Module extends Module {
5353
class ImportDeclaration extends Stmt, Import, @importdeclaration {
5454
override ES2015Module getEnclosingModule() { result = getTopLevel() }
5555

56-
override PathExprInModule getImportedPath() { result = getChildExpr(-1) }
56+
override PathExpr getImportedPath() { result = getChildExpr(-1) }
5757

5858
/** Gets the `i`th import specifier of this import declaration. */
5959
ImportSpecifier getSpecifier(int i) { result = getChildExpr(i) }
@@ -82,7 +82,7 @@ class ImportDeclaration extends Stmt, Import, @importdeclaration {
8282
}
8383

8484
/** A literal path expression appearing in an `import` declaration. */
85-
private class LiteralImportPath extends PathExprInModule, ConstantString {
85+
private class LiteralImportPath extends PathExpr, ConstantString {
8686
LiteralImportPath() { exists(ImportDeclaration req | this = req.getChildExpr(-1)) }
8787

8888
override string getValue() { result = getStringValue() }
@@ -622,7 +622,7 @@ abstract class ReExportDeclaration extends ExportDeclaration {
622622
}
623623

624624
/** A literal path expression appearing in a re-export declaration. */
625-
private class LiteralReExportPath extends PathExprInModule, ConstantString {
625+
private class LiteralReExportPath extends PathExpr, ConstantString {
626626
LiteralReExportPath() { exists(ReExportDeclaration bred | this = bred.getImportedPath()) }
627627

628628
override string getValue() { result = getStringValue() }

javascript/ql/src/semmle/javascript/Expr.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2614,7 +2614,7 @@ class DynamicImportExpr extends @dynamicimport, Expr, Import {
26142614
}
26152615

26162616
/** A literal path expression appearing in a dynamic import. */
2617-
private class LiteralDynamicImportPath extends PathExprInModule, ConstantString {
2617+
private class LiteralDynamicImportPath extends PathExpr, ConstantString {
26182618
LiteralDynamicImportPath() {
26192619
exists(DynamicImportExpr di | this.getParentExpr*() = di.getSource())
26202620
}

javascript/ql/src/semmle/javascript/Modules.qll

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,14 @@ abstract class Import extends ASTNode {
185185
}
186186

187187
/**
188+
* DEPRECATED. Use `PathExpr` instead.
189+
*
188190
* A path expression that appears in a module and is resolved relative to it.
189191
*/
190-
abstract class PathExprInModule extends PathExpr {
191-
PathExprInModule() { exists(getEnclosingModule()) }
192-
193-
override Folder getSearchRoot(int priority) {
194-
getEnclosingModule().searchRoot(this, result, priority)
192+
abstract deprecated class PathExprInModule extends PathExpr {
193+
PathExprInModule() {
194+
this.(Expr).getTopLevel() instanceof Module
195+
or
196+
this.(Comment).getTopLevel() instanceof Module
195197
}
196198
}

javascript/ql/src/semmle/javascript/NodeJS.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -266,14 +266,14 @@ private class RequirePath extends PathExprCandidate {
266266
}
267267

268268
/** A constant path element appearing in a call to `require` or `require.resolve`. */
269-
private class ConstantRequirePathElement extends PathExprInModule, ConstantString {
269+
private class ConstantRequirePathElement extends PathExpr, ConstantString {
270270
ConstantRequirePathElement() { this = any(RequirePath rp).getAPart() }
271271

272272
override string getValue() { result = getStringValue() }
273273
}
274274

275275
/** A `__dirname` path expression. */
276-
private class DirNamePath extends PathExprInModule, VarAccess {
276+
private class DirNamePath extends PathExpr, VarAccess {
277277
DirNamePath() {
278278
getName() = "__dirname" and
279279
getVariable().getScope() instanceof ModuleScope
@@ -283,7 +283,7 @@ private class DirNamePath extends PathExprInModule, VarAccess {
283283
}
284284

285285
/** A `__filename` path expression. */
286-
private class FileNamePath extends PathExprInModule, VarAccess {
286+
private class FileNamePath extends PathExpr, VarAccess {
287287
FileNamePath() {
288288
getName() = "__filename" and
289289
getVariable().getScope() instanceof ModuleScope
@@ -296,7 +296,7 @@ private class FileNamePath extends PathExprInModule, VarAccess {
296296
* A path expression of the form `path.join(p, "...")` where
297297
* `p` is also a path expression.
298298
*/
299-
private class JoinedPath extends PathExprInModule, @callexpr {
299+
private class JoinedPath extends PathExpr, @callexpr {
300300
JoinedPath() {
301301
exists(MethodCallExpr call | call = this |
302302
call.getReceiver().(VarAccess).getName() = "path" and

javascript/ql/src/semmle/javascript/NodeModuleResolutionImpl.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class MainModulePath extends PathExpr, @json_string {
112112

113113
override string getValue() { result = this.(JSONString).getValue() }
114114

115-
override Folder getSearchRoot(int priority) {
115+
override Folder getAdditionalSearchRoot(int priority) {
116116
priority = 0 and
117117
result = pkg.getFile().getParentContainer()
118118
}

javascript/ql/src/semmle/javascript/Paths.qll

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -174,17 +174,6 @@ abstract class PathString extends string {
174174
Path resolve(Folder root) { result = resolveUpTo(getNumComponent(), root) }
175175
}
176176

177-
/**
178-
* Non-abstract base class for path expressions.
179-
*/
180-
private class PathExprBase extends Locatable {
181-
// We must put getEnclosingModule here for it to be usable in the characteristic predicate of PathExprInModule
182-
/** Gets the module containing this path expression, if any. */
183-
Module getEnclosingModule() {
184-
result = this.(Expr).getTopLevel() or result = this.(Comment).getTopLevel()
185-
}
186-
}
187-
188177
/**
189178
* An expression whose value represents a (relative or absolute) file system path.
190179
*
@@ -197,12 +186,25 @@ private class PathExprBase extends Locatable {
197186
* as their highest-priority root, with default library paths as additional roots
198187
* of lower priority.
199188
*/
200-
abstract class PathExpr extends PathExprBase {
189+
abstract class PathExpr extends Locatable {
201190
/** Gets the (unresolved) path represented by this expression. */
202191
abstract string getValue();
203192

204193
/** Gets the root folder of priority `priority` associated with this path expression. */
205-
abstract Folder getSearchRoot(int priority);
194+
Folder getSearchRoot(int priority) {
195+
// We default to the enclosing module's search root, though this may be overridden.
196+
getEnclosingModule().searchRoot(this, result, priority)
197+
or
198+
result = getAdditionalSearchRoot(priority)
199+
}
200+
201+
/**
202+
* INTERNAL. Use `getSearchRoot` instead.
203+
*
204+
* Can be overridden by subclasses of `PathExpr` to provide additional search roots
205+
* without overriding `getSearchRoot`.
206+
*/
207+
Folder getAdditionalSearchRoot(int priority) { none() }
206208

207209
/** Gets the `i`th component of this path. */
208210
string getComponent(int i) { result = getValue().(PathString).getComponent(i) }
@@ -246,6 +248,11 @@ abstract class PathExpr extends PathExprBase {
246248

247249
/** Gets the file or folder that this path refers to. */
248250
Container resolve() { result = resolveUpTo(getNumComponent()) }
251+
252+
/** Gets the module containing this path expression, if any. */
253+
Module getEnclosingModule() {
254+
result = this.(Expr).getTopLevel() or result = this.(Comment).getTopLevel()
255+
}
249256
}
250257

251258
/** A path string derived from a path expression. */
@@ -279,8 +286,8 @@ private class ConcatPath extends PathExpr {
279286
)
280287
}
281288

282-
override Folder getSearchRoot(int priority) {
283-
result = this.(AddExpr).getAnOperand().(PathExpr).getSearchRoot(priority)
289+
override Folder getAdditionalSearchRoot(int priority) {
290+
result = this.(AddExpr).getAnOperand().(PathExpr).getAdditionalSearchRoot(priority)
284291
}
285292
}
286293

javascript/ql/src/semmle/javascript/TypeScript.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ class ExternalModuleReference extends Expr, Import, @externalmodulereference {
213213
}
214214

215215
/** A literal path expression appearing in an external module reference. */
216-
private class LiteralExternalModulePath extends PathExprInModule, ConstantString {
216+
private class LiteralExternalModulePath extends PathExpr, ConstantString {
217217
LiteralExternalModulePath() {
218218
exists(ExternalModuleReference emr | this.getParentExpr*() = emr.getExpression())
219219
}

javascript/ql/src/semmle/javascript/dataflow/Nodes.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,7 @@ module ModuleImportNode {
697697
*
698698
* This predicate can be extended by subclassing `ModuleImportNode::Range`.
699699
*/
700+
cached
700701
ModuleImportNode moduleImport(string path) { result.getPath() = path }
701702

702703
/**

javascript/ql/src/semmle/javascript/frameworks/LazyCache.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ module LazyCache {
7474
}
7575

7676
/** A constant path element appearing in a call to a lazy-cache object. */
77-
private class LazyCachePathExpr extends PathExprInModule, ConstantString {
77+
private class LazyCachePathExpr extends PathExpr, ConstantString {
7878
LazyCachePathExpr() { this = any(LazyCacheImport rp).getArgument(0) }
7979

8080
override string getValue() { result = getStringValue() }

0 commit comments

Comments
 (0)