Perf improvements

This commit is contained in:
Asger F
2025-04-10 14:35:10 +02:00
parent 81c7b4a9f1
commit ca75ee161a
2 changed files with 21 additions and 9 deletions

View File

@@ -6,6 +6,7 @@ private import semmle.javascript.internal.paths.PackageJsonEx
final private class FinalPathExpr = PathExpr; final private class FinalPathExpr = PathExpr;
private class RelevantPathExpr extends FinalPathExpr { private class RelevantPathExpr extends FinalPathExpr {
pragma[nomagic]
RelevantPathExpr() { this = any(Import imprt).getImportedPath() } RelevantPathExpr() { this = any(Import imprt).getImportedPath() }
} }
@@ -38,6 +39,7 @@ private TSConfig getTSConfigFromPathExpr(RelevantPathExpr expr) {
* Holds if `path` is relative, in the sense that it should be resolved relative to its enclosing folder. * Holds if `path` is relative, in the sense that it should be resolved relative to its enclosing folder.
*/ */
bindingset[path] bindingset[path]
pragma[inline_late]
predicate isRelativePath(string path) { path.regexpMatch("\\.\\.?(?:[/\\\\].*)?") } predicate isRelativePath(string path) { path.regexpMatch("\\.\\.?(?:[/\\\\].*)?") }
/** /**
@@ -106,14 +108,11 @@ module JSPaths {
} }
} }
/** private Variable dirname() { result.getName() = "__dirname" }
* Gets an access to `__dirname`.
*/
private VarAccess dirname() { result.getName() = "__dirname" }
/** Holds if `add` is a relevant path expression of form `__dirname + expr`. */ /** Holds if `add` is a relevant path expression of form `__dirname + expr`. */
private predicate prefixedByDirname(PathExpr expr) { private predicate prefixedByDirname(PathExpr expr) {
expr = dirname() expr = dirname().getAnAccess()
or or
prefixedByDirname(expr.(AddExpr).getLeftOperand()) prefixedByDirname(expr.(AddExpr).getLeftOperand())
or or
@@ -163,15 +162,24 @@ private predicate resolveViaPathMapping(RelevantPathExpr expr, Container base, s
) )
} }
pragma[noopt]
private predicate relativePathExpr(RelevantPathExpr expr, Container base, string path) {
expr instanceof RelevantPathExpr and
path = expr.getValue() and
isRelativePath(path) and
exists(File file |
file = expr.getFile() and
base = file.getParentContainer()
)
}
/** /**
* Holds if `expr` should be resolved as `path` relative to `base`. * Holds if `expr` should be resolved as `path` relative to `base`.
*/ */
pragma[nomagic] pragma[nomagic]
private predicate shouldResolve(RelevantPathExpr expr, Container base, string path) { private predicate shouldResolve(RelevantPathExpr expr, Container base, string path) {
// Relative paths are resolved from their enclosing folder // Relative paths are resolved from their enclosing folder
path = expr.getValue() and relativePathExpr(expr, base, path)
isRelativePath(path) and
base = expr.getFile().getParentContainer()
or or
// Paths prefixed by __dirname should be resolved from the root dir, because __dirname // Paths prefixed by __dirname should be resolved from the root dir, because __dirname
// currently has a getValue() that returns its absolute path. // currently has a getValue() that returns its absolute path.
@@ -194,7 +202,7 @@ private predicate shouldResolve(RelevantPathExpr expr, Container base, string pa
packageName = getPackagePrefixFromPathExpr(expr) and packageName = getPackagePrefixFromPathExpr(expr) and
pkg.getDeclaredPackageName() = packageName and pkg.getDeclaredPackageName() = packageName and
path = expr.getValue().suffix(packageName.length()).regexpReplaceAll("^[/\\\\]", "") and path = expr.getValue().suffix(packageName.length()).regexpReplaceAll("^[/\\\\]", "") and
base = pkg.getJsonFile().getParentContainer() base = pkg.getFolder()
) )
} }

View File

@@ -36,6 +36,7 @@ signature module PathResolverSig {
module PathResolver<PathResolverSig Config> { module PathResolver<PathResolverSig Config> {
private import Config private import Config
pragma[nomagic]
private string getPathSegment(string path, int n) { private string getPathSegment(string path, int n) {
shouldResolve(_, path) and shouldResolve(_, path) and
result = path.replaceAll("\\", "/").splitAt("/", n) result = path.replaceAll("\\", "/").splitAt("/", n)
@@ -50,6 +51,7 @@ module PathResolver<PathResolverSig Config> {
result = segment.regexpReplaceAll("[^a-zA-Z0-9*]", "\\\\$0").replaceAll("*", ".*") result = segment.regexpReplaceAll("[^a-zA-Z0-9*]", "\\\\$0").replaceAll("*", ".*")
} }
pragma[nomagic]
private int getNumPathSegment(string path) { private int getNumPathSegment(string path) {
result = strictcount(int n | exists(getPathSegment(path, n))) result = strictcount(int n | exists(getPathSegment(path, n)))
} }
@@ -60,6 +62,7 @@ module PathResolver<PathResolverSig Config> {
result = getAnAdditionalChild(base, name) result = getAnAdditionalChild(base, name)
} }
pragma[nomagic]
private Container resolve(Container base, string path, int n) { private Container resolve(Container base, string path, int n) {
shouldResolve(base, path) and n = 0 and result = base shouldResolve(base, path) and n = 0 and result = base
or or
@@ -111,6 +114,7 @@ module PathResolver<PathResolverSig Config> {
* Only has results for the `(base, path)` pairs provided by `shouldResolve` * Only has results for the `(base, path)` pairs provided by `shouldResolve`
* in the instantiation of this module. * in the instantiation of this module.
*/ */
pragma[nomagic]
Container resolve(Container base, string path) { Container resolve(Container base, string path) {
result = resolve(base, path, getNumPathSegment(path)) result = resolve(base, path, getNumPathSegment(path))
} }