Merge pull request #5461 from erik-krogh/moreOutDir

Approved by asgerf
This commit is contained in:
CodeQL CI
2021-03-22 13:27:14 +00:00
committed by GitHub
9 changed files with 98 additions and 43 deletions

View File

@@ -407,7 +407,7 @@ public class AutoBuild {
// codeql-javascript-*.json files
patterns.add("**/.eslintrc*");
patterns.add("**/package.json");
patterns.add("**/tsconfig.json");
patterns.add("**/tsconfig*.json");
patterns.add("**/codeql-javascript-*.json");
// include any explicitly specified extensions

View File

@@ -43,7 +43,7 @@ public class Main {
* A version identifier that should be updated every time the extractor changes in such a way that
* it may produce different tuples for the same file under the same {@link ExtractorConfig}.
*/
public static final String EXTRACTOR_VERSION = "2021-03-08";
public static final String EXTRACTOR_VERSION = "2021-03-19";
public static final Pattern NEWLINE = Pattern.compile("\n");

View File

@@ -141,29 +141,7 @@ abstract class PathString extends string {
* components of this path refers to when resolved relative to the
* given `root` folder.
*/
Path resolveUpTo(int n, Folder root) {
n = 0 and result.getContainer() = root and root = getARootFolder()
or
exists(Path base, string next | next = getComponent(this, n - 1, base, root) |
// handle empty components and the special "." folder
(next = "" or next = ".") and
result = base
or
// handle the special ".." folder
next = ".." and result = base.(ConsPath).getParent()
or
// special handling for Windows drive letters when resolving absolute path:
// the extractor populates "C:/" as a folder that has path "C:/" but name ""
n = 1 and
next.regexpMatch("[A-Za-z]:") and
root.getBaseName() = "" and
root.toString() = next.toUpperCase() + "/" and
result = base
or
// default case
result = TConsPath(base, next)
)
}
Path resolveUpTo(int n, Folder root) { result = resolveUpTo(this, n, root, _) }
/**
* Gets the absolute path that this path refers to when resolved relative to
@@ -172,16 +150,57 @@ abstract class PathString extends string {
Path resolve(Folder root) { result = resolveUpTo(getNumComponent(), root) }
}
/**
* Gets the absolute path that the sub-path consisting of the first `n`
* components of this path refers to when resolved relative to the
* given `root` folder.
*/
private Path resolveUpTo(PathString p, int n, Folder root, boolean inTS) {
n = 0 and result.getContainer() = root and root = p.getARootFolder() and inTS = false
or
exists(Path base, string next | next = getComponent(p, n - 1, base, root, inTS) |
// handle empty components and the special "." folder
(next = "" or next = ".") and
result = base
or
// handle the special ".." folder
next = ".." and result = base.(ConsPath).getParent()
or
// special handling for Windows drive letters when resolving absolute path:
// the extractor populates "C:/" as a folder that has path "C:/" but name ""
n = 1 and
next.regexpMatch("[A-Za-z]:") and
root.getBaseName() = "" and
root.toString() = next.toUpperCase() + "/" and
result = base
or
// default case
result = TConsPath(base, next)
)
}
/**
* Gets the `i`th component of the path `str`, where `base` is the resolved path one level up.
* Supports that the root directory might be compiled output from TypeScript.
* `inTS` is true if the result is TypeScript that is compiled into the path specified by `str`.
*/
private string getComponent(PathString str, int n, Path base, Folder root) {
base = str.resolveUpTo(n, root) and
(
result = str.getComponent(n)
or
result = TypeScriptOutDir::getOriginalTypeScriptFolder(str.getComponent(n), base.getContainer())
private string getComponent(PathString str, int n, Path base, Folder root, boolean inTS) {
exists(boolean prevTS |
base = resolveUpTo(str, n, root, prevTS) and
(
result = str.getComponent(n) and prevTS = inTS
or
// If we are in a TypeScript source folder, try to replace file endings with ".ts" or ".tsx"
n = str.getNumComponent() - 1 and
prevTS = true and
inTS = prevTS and
result = str.getComponent(n).regexpCapture("^(.*)\\.js$", 1) + "." + ["ts", "tsx"]
or
prevTS = false and
inTS = true and
result =
TypeScriptOutDir::getOriginalTypeScriptFolder(str.getComponent(n), base.getContainer())
)
)
}
@@ -194,21 +213,35 @@ private module TypeScriptOutDir {
*/
string getOriginalTypeScriptFolder(string outdir, Folder parent) {
exists(JSONObject tsconfig |
tsconfig.getFile().getBaseName() = "tsconfig.json" and
tsconfig.isTopLevel() and
tsconfig.getFile().getParentContainer() = parent
|
outdir =
tsconfig
.getPropValue("compilerOptions")
.(JSONObject)
.getPropValue("outDir")
.(JSONString)
.getValue() and
result = getEffectiveRootDirFromTSConfig(tsconfig)
outdir = removeLeadingSlash(getOutDir(tsconfig, parent)) and
result = removeLeadingSlash(getEffectiveRootDirFromTSConfig(tsconfig))
)
}
/**
* Removes a leading dot and/or slash from `raw`.
*/
bindingset[raw]
private string removeLeadingSlash(string raw) {
result = raw.regexpCapture("^\\.?/?([\\w.\\-]+)$", 1)
}
/**
* Gets the `outDir` option from a tsconfig file from the folder `parent`.
*/
private string getOutDir(JSONObject tsconfig, Folder parent) {
tsconfig.getFile().getBaseName().regexpMatch("tsconfig.*\\.json") and
tsconfig.isTopLevel() and
tsconfig.getFile().getParentContainer() = parent and
result =
tsconfig
.getPropValue("compilerOptions")
.(JSONObject)
.getPropValue("outDir")
.(JSONString)
.getValue()
}
/**
* Gets the directory that contains the TypeScript source files.
* Based on the tsconfig.json file `tsconfig`.

View File

@@ -0,0 +1,2 @@
var foo1 = require('./lib/index.js');
var foo2 = require('./src/index.ts');

View File

@@ -0,0 +1,4 @@
{
"name": "foo",
"main": "./lib/index.js"
}

View File

@@ -0,0 +1 @@
export default class Foo {}

View File

@@ -0,0 +1,8 @@
{
"extends": "./tsconfig",
"compilerOptions": {
"module": "commonjs",
"rootDir": "./src",
"outDir": "./lib"
}
}

View File

@@ -1,3 +1,4 @@
resolveableImport
| nonUniqueInclude/index.js:1:12:1:38 | require ... oo.js') | nonUniqueInclude/src/foo.ts:1:1:1:27 | <toplevel> |
| nonUniqueInclude/index.js:2:12:2:39 | require ... oo.js') | nonUniqueInclude/src2/foo.ts:1:1:1:27 | <toplevel> |
| nonUniqueInclude/index.js:3:12:3:34 | require ... oo.ts') | nonUniqueInclude/src/foo.ts:1:1:1:27 | <toplevel> |
@@ -10,3 +11,7 @@
| simpleOutDir/index.js:2:12:2:36 | require ... ex.ts') | simpleOutDir/src/index.ts:1:1:1:27 | <toplevel> |
| simpleOutDir/index.js:4:12:4:33 | require ... index') | simpleOutDir/src/index.ts:1:1:1:27 | <toplevel> |
| simpleOutDir/index.js:5:12:5:33 | require ... index') | simpleOutDir/src/index.ts:1:1:1:27 | <toplevel> |
| slashAndExtension/index.js:1:12:1:36 | require ... ex.js') | slashAndExtension/src/index.ts:1:1:1:27 | <toplevel> |
| slashAndExtension/index.js:2:12:2:36 | require ... ex.ts') | slashAndExtension/src/index.ts:1:1:1:27 | <toplevel> |
getMain
| slashAndExtension/package.json:1:1:4:1 | {\\n " ... x.js"\\n} | slashAndExtension/src/index.ts:1:1:1:27 | <toplevel> |

View File

@@ -5,3 +5,5 @@ query predicate resolveableImport(Import imp, Module mod) {
not imp.getTopLevel().isExterns() and
not mod.getTopLevel().isExterns()
}
query Module getMain(PackageJSON json) { result = json.getMainModule() }