-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreach.ql
More file actions
116 lines (103 loc) · 4.3 KB
/
reach.ql
File metadata and controls
116 lines (103 loc) · 4.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import javascript
/**
* Find the file referenced in an "import" statement. We do this by first computing the absolute path of the
* referenced file, and then finding a File object corresponding to that path.
*/
File getImportedFile(ImportDeclaration id){
exists(File file, string importPath, string prefix |
importPath = id.getImportedPath().getValue() and
prefix = id.getFile().getAbsolutePath().substring(0, id.getFile().getAbsolutePath().indexOf(id.getFile().getBaseName())) and
( file.getAbsolutePath() = importPath.replaceAll("./", prefix) or
file.getAbsolutePath() = importPath.replaceAll("./", prefix) + ".js") and
result = file
)
}
File getReExportedFile(ReExportDeclaration be){
exists(File file, string importPath, string prefix |
importPath = be.getImportedPath().toString() and
prefix = be.getFile().getAbsolutePath().substring(0, be.getFile().getAbsolutePath().indexOf(be.getFile().getBaseName())) and
(file.getAbsolutePath() = importPath.replaceAll("./", prefix).substring(1,importPath.replaceAll("./", prefix).length()-1) or
file.getAbsolutePath() = importPath.replaceAll("./", prefix).substring(1,importPath.replaceAll("./", prefix).length()-1) + ".js"
)
and
result = file
)
}
/**
* Find the file referenced in a "require" expression. We do this by first computing the absolute path of the
* referenced file, and then finding a File object corresponding to that path.
*/
File getRequiredFile(InvokeExpr ie){
// require a .js file
ie.getCalleeName() = "require" and
(exists(File file, string importPath, string prefix |
importPath = ((StringLiteral)ie.getChild(0)).getStringValue() and
prefix = ie.getFile().getAbsolutePath().substring(0, ie.getFile().getAbsolutePath().indexOf(ie.getFile().getBaseName())) and
file.getAbsolutePath() = importPath.replaceAll("./", prefix) and
result = file
)
or
// require a directory relative to "."; in this case we look for an index.js file within that directory
exists(File file, string importPath, string prefix |
importPath = ((StringLiteral)ie.getChild(0)).getStringValue() and
prefix = ie.getFile().getAbsolutePath().substring(0, ie.getFile().getAbsolutePath().indexOf(ie.getFile().getBaseName())) and
file.getAbsolutePath().indexOf(importPath.replaceAll("./", prefix)) = 0 and
file.getBaseName() = "index.js" and
result = file
)
or
// require a directory relative to ".."; in this case we look for an index.js file within that directory
exists(File file, string importPath, string prefix, Container parent |
parent = ie.getFile().getParentContainer().getParentContainer() and
importPath = ((StringLiteral)ie.getChild(0)).getStringValue() and
prefix = parent.getAbsolutePath() and
file.getAbsolutePath().indexOf(importPath.replaceAll("../", prefix + "/")) = 0 and
file.getBaseName() = "index.js" and
result = file
))
}
predicate isMainFile(File file){
file.getBaseName() = "MemoryFileSystem.js"
or
file.getBaseName() = "MemoryFileSystemError.js"
}
/*
boolean isExcluded(File file){
if (file.getAbsolutePath().indexOf("node_modules") != -1) then
result = true
else
result = false
}*/
predicate findInvokeExpr(File file, InvokeExpr ie){
ie.getFile() = file
}
predicate findImportDeclaration(File file, ImportDeclaration id){
id.getFile() = file
}
predicate findReExportDeclaration(File file, ReExportDeclaration rd){
rd.getFile() = file
}
predicate reachable(File file){
//isExcluded(file) = false
//and
(isMainFile(file)
or
// a file is reachable if it is required by a reachable file
exists(File f, InvokeExpr ie | reachable(f) and findInvokeExpr(f, ie) and file = getRequiredFile(ie) )
or
// a file is reachable if it is imported by a reachable file
exists(File f, ImportDeclaration id | reachable(f) and findImportDeclaration(f, id) and file = getImportedFile(id) )
or
// a file is reachable if a reachable file re-exports from it
exists(File f, ReExportDeclaration rd | reachable(f) and findReExportDeclaration(f, rd) and file = getReExportedFile(rd) )
)
}
//from File s
// where reachable(s)
//select s.getAbsolutePath()
from File s, ASTNode a
where
a.getFile() = s and
a instanceof InvokeExpr or a instanceof ImportDeclaration or a instanceof ReExportDeclaration
select
s, s.getAbsolutePath()