-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
QL4QL: Improvements to
RedundantImport
query
- Loading branch information
Showing
9 changed files
with
42 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,68 +1,64 @@ | ||
import ql | ||
private import YAML | ||
private import codeql_ql.ast.internal.Module | ||
|
||
Import imports(Import imp) { | ||
private FileOrModule getResolvedModule(Import imp) { | ||
result = imp.getResolvedModule() and | ||
// skip the top-level language files | ||
not result.asFile() = any(QLPack p).getLanguageLib() | ||
} | ||
|
||
private Import imports(Import imp) { | ||
( | ||
exists(File file, TopLevel top | | ||
imp.getResolvedModule().asFile() = file and | ||
getResolvedModule(imp).asFile() = file and | ||
top.getLocation().getFile() = file and | ||
result = top.getAMember() | ||
) | ||
or | ||
exists(Module mod | | ||
imp.getResolvedModule().asModule() = mod and | ||
getResolvedModule(imp).asModule() = mod and | ||
result = mod.getAMember() | ||
) | ||
) | ||
} | ||
|
||
Import getAnImport(AstNode parent) { | ||
private Import getAnImport(AstNode parent) { | ||
result = parent.(TopLevel).getAMember() | ||
or | ||
result = parent.(Module).getAMember() | ||
} | ||
|
||
pragma[inline] | ||
predicate importsFromSameFolder(Import a, Import b) { | ||
exists(string base | | ||
a.getImportString().regexpCapture("(.*)\\.[^\\.]*", 1) = base and | ||
b.getImportString().regexpCapture("(.*)\\.[^\\.]*", 1) = base | ||
) | ||
or | ||
not a.getImportString().matches("%.%") and | ||
not b.getImportString().matches("%.%") | ||
} | ||
|
||
predicate problem(Import imp, Import redundant, string message) { | ||
not exists(imp.importedAs()) and | ||
not exists(redundant.importedAs()) and | ||
not exists(imp.getModuleExpr().getQualifier*().getArgument(_)) and // any type-arguments, and we ignore, they might be different. | ||
// skip the top-level language files, they have redundant imports, and that's fine. | ||
not exists(imp.getLocation().getFile().getParentContainer().getFile("qlpack.yml")) and | ||
not imp.getLocation().getFile() = any(QLPack p).getLanguageLib() and | ||
// skip the DataFlowImpl.qll and similar, they have redundant imports in some copies. | ||
not imp.getLocation() | ||
.getFile() | ||
.getBaseName() | ||
.regexpMatch([".*Impl\\d?\\.qll", "DataFlowImpl.*\\.qll"]) and | ||
// skip two imports that imports different things from the same folder. | ||
not importsFromSameFolder(imp, redundant) and | ||
// if the redundant is public, and the imp is private, then the redundant might add things that are exported. | ||
not (imp.isPrivate() and not redundant.isPrivate()) and | ||
// Actually checking if the import is redundant: | ||
exists(AstNode parent | | ||
imp = getAnImport(parent) and | ||
redundant = getAnImport(parent) and | ||
redundant.getLocation().getStartLine() > imp.getLocation().getStartLine() | ||
redundant = getAnImport(parent) | ||
| | ||
message = "Redundant import, the module is already imported inside $@." and | ||
// only looking for things directly imported one level down. Otherwise things gets complicated (lots of cycles). | ||
exists(Import inner | inner = imports(imp) | | ||
redundant.getResolvedModule() = inner.getResolvedModule() and | ||
getResolvedModule(redundant) = getResolvedModule(inner) and | ||
not inner.isPrivate() and // if the inner is private, then it's not propagated out. | ||
not inner.isDeprecated() and | ||
not exists(inner.importedAs()) | ||
) | ||
or | ||
message = "Duplicate import, the module is already imported by $@." and | ||
// two different import statements, that import the same thing | ||
imp.getResolvedModule() = redundant.getResolvedModule() | ||
getResolvedModule(imp) = getResolvedModule(redundant) and | ||
redundant.getLocation().getStartLine() > imp.getLocation().getStartLine() | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
import folder.A | ||
import folder.B |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
import folder.A | ||
import folder.C |
1 change: 1 addition & 0 deletions
1
ql/ql/test/queries/style/RedundantImport/RedundantImport.expected
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
| D.qll:1:1:1:15 | Import | Redundant import, the module is already imported inside $@. | D.qll:2:1:2:15 | Import | folder.B | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
queries/style/RedundantImport.ql |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
predicate p() { any() } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
import A |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
deprecated import A |