-
Notifications
You must be signed in to change notification settings - Fork 2k
Rust: Handle path attributes in path resolution #19216
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -655,6 +655,11 @@ private predicate fileModule(SourceFile f, string name, Folder folder) { | |
| ) | ||
| } | ||
|
|
||
| private Meta getPathAttrMeta(Module m) { | ||
| result = m.getAnAttr().getMeta() and | ||
| result.getPath().getText() = "path" | ||
| } | ||
|
|
||
| /** | ||
| * Holds if `m` is a `mod name;` module declaration, where the corresponding | ||
| * module file needs to be looked up in `lookup` or one of its descandants. | ||
|
|
@@ -663,12 +668,7 @@ private predicate modImport0(Module m, string name, Folder lookup) { | |
| exists(File f, Folder parent, string fileName | | ||
| f = m.getFile() and | ||
| not m.hasItemList() and | ||
| // TODO: handle | ||
| // ``` | ||
| // #[path = "foo.rs"] | ||
| // mod bar; | ||
| // ``` | ||
| not m.getAnAttr().getMeta().getPath().getText() = "path" and | ||
| not exists(getPathAttrMeta(m)) and | ||
| name = m.getName().getText() and | ||
| parent = f.getParentContainer() and | ||
| fileName = f.getStem() | ||
|
|
@@ -717,6 +717,16 @@ private predicate modImportNestedLookup(Module m, ModuleItemNode ancestor, Folde | |
| ) | ||
| } | ||
|
|
||
| private predicate pathAttrImport(Folder f, Module m, string relativePath) { | ||
| exists(Meta meta | | ||
| f = m.getFile().getParentContainer() and | ||
| meta = getPathAttrMeta(m) and | ||
| relativePath = meta.getExpr().(LiteralExpr).getTextValue().regexpCapture("\"(.+)\"", 1) | ||
| ) | ||
| } | ||
|
|
||
| private predicate append(Folder f, string relativePath) { pathAttrImport(f, _, relativePath) } | ||
|
||
|
|
||
| /** Holds if `m` is a `mod name;` item importing file `f`. */ | ||
| private predicate fileImport(Module m, SourceFile f) { | ||
| exists(string name, Folder parent | | ||
|
|
@@ -730,6 +740,11 @@ private predicate fileImport(Module m, SourceFile f) { | |
| // `m` is inside a nested module | ||
| modImportNestedLookup(m, m, parent) | ||
| ) | ||
| or | ||
| exists(Folder folder, string relativePath | | ||
| pathAttrImport(folder, m, relativePath) and | ||
| f.getFile() = Folder::Append<append/2>::append(folder, relativePath) | ||
| ) | ||
| } | ||
|
|
||
| /** | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| pub fn f() {} // I1001 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -218,6 +218,53 @@ module Make<InputSig Input> { | |
| /** Gets the URL of this file. */ | ||
| override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" } | ||
| } | ||
|
|
||
| /** Provides logic related to `Folder`s. */ | ||
| module Folder { | ||
| /** Holds if `relativePath` needs to be appended to `f`. */ | ||
| signature predicate appendSig(Folder f, string relativePath); | ||
|
|
||
| /** Provides the `append` predicate for appending a relative path onto a folder. */ | ||
| module Append<appendSig/2 app> { | ||
| pragma[nomagic] | ||
| private string getComponent(string relativePath, int i) { | ||
| app(_, relativePath) and | ||
| result = relativePath.replaceAll("\\", "/").regexpFind("[^/]+", i, _) | ||
| } | ||
|
|
||
| pragma[nomagic] | ||
| private Container appendStep(Folder f, string relativePath, int i) { | ||
| i = -1 and | ||
| app(f, relativePath) and | ||
| result = f | ||
| or | ||
| exists(Container mid, string comp | | ||
| mid = appendStep(f, relativePath, i - 1) and | ||
| comp = getComponent(relativePath, i) and | ||
| if comp = ".." | ||
| then result = mid.getParentContainer() | ||
| else | ||
| if comp = "." | ||
| then result = mid | ||
| else ( | ||
| result = mid.getAChildContainer() and | ||
| result.getBaseName() = comp | ||
| ) | ||
| ) | ||
| } | ||
|
|
||
| /** | ||
| * Gets the file or folder obtained by appending `relativePath` onto `f`. | ||
| */ | ||
| pragma[nomagic] | ||
| Container append(Folder f, string relativePath) { | ||
| exists(int components | | ||
| components = (-1).maximum(max(int comp | exists(getComponent(relativePath, comp)) | comp)) and | ||
| result = appendStep(f, relativePath, components) | ||
| ) | ||
|
||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /** A file. */ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.