This repository was archived by the owner on Jan 25, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 41
improved unbound identifier detection #95
Open
symphorien
wants to merge
11
commits into
nix-community:master
Choose a base branch
from
symphorien:static
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 10 commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
3a66e76
some support for let ... in
symphorien 66a1458
add some function support
symphorien 25d0341
parse lists
symphorien d5c0155
parse support for string
symphorien 0709138
add support for parsing with
symphorien 7a5adb5
add support for parsing `a.b or c`
symphorien cae18e3
ExprSource: add support for assert
symphorien dd0a4cc
ExprSource: add support for if then else
symphorien 3601da7
more tests for static analysis
symphorien 29494db
explicitly spell all possible node kinds
symphorien c9d1231
keep the range of @foo in ExprSource
symphorien File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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 | ||||
|---|---|---|---|---|---|---|
|
|
@@ -8,6 +8,17 @@ use rnix::TextRange; | |||||
| use std::borrow::Borrow; | ||||||
| use std::collections::HashMap; | ||||||
|
|
||||||
| /// A string part | ||||||
| /// | ||||||
| /// in `"foo${bar}baz"`, parts are `Literal("foo")`, `Expression(bar)` and `Literal("baz")` | ||||||
| #[derive(Debug, Trace, Finalize)] | ||||||
| pub enum StringPartSource { | ||||||
| /// Literal string | ||||||
| Literal(String), | ||||||
| /// Interpolated expression | ||||||
| Expression(ExprResultBox), | ||||||
| } | ||||||
|
|
||||||
| // Expressions like BinOp have the only copy of their Expr children, | ||||||
| // so they use ExprResultBox. Expressions like Map, which may have | ||||||
| // contents copied in multiple places, need ExprResultGc. | ||||||
|
|
@@ -36,6 +47,18 @@ pub enum ExprSource { | |||||
| /// ``` | ||||||
| definitions: Vec<ExprResultGc>, | ||||||
| }, | ||||||
| LetIn { | ||||||
| /// We use a list because the user might define the same top-level | ||||||
| /// attribute in multiple places via path syntax. For example: | ||||||
| /// ```nix | ||||||
| /// { | ||||||
| /// xyz.foo = true; | ||||||
| /// xyz.bar = false; | ||||||
| /// } | ||||||
| /// ``` | ||||||
| definitions: Vec<ExprResultGc>, | ||||||
| body: ExprResultBox, | ||||||
| }, | ||||||
| /// See the AttrSet handling in Expr::parse for more details. | ||||||
| /// Note that this syntax is the exact opposite of Expr::Select. | ||||||
| KeyValuePair { | ||||||
|
|
@@ -50,19 +73,76 @@ pub enum ExprSource { | |||||
| from: ExprResultGc, | ||||||
| index: ExprResultBox, | ||||||
| }, | ||||||
| /// `assert condition; body` | ||||||
| Assert { | ||||||
| /// the asserted condition | ||||||
| condition: ExprResultBox, | ||||||
| /// the body which is only evaluated if the assertion is true | ||||||
| body: ExprResultBox, | ||||||
| }, | ||||||
| /// Dynamic attribute, such as the curly braces in `foo.${toString (1+1)}` | ||||||
| Dynamic { | ||||||
| inner: ExprResultBox, | ||||||
| }, | ||||||
| /// `with inner; body` | ||||||
| With { | ||||||
| /// the expression used to provide bindings | ||||||
| inner: ExprResultGc, | ||||||
| /// the body evaluated with the new bindings | ||||||
| body: ExprResultBox, | ||||||
| }, | ||||||
| Ident { | ||||||
| name: String, | ||||||
| }, | ||||||
| Literal { | ||||||
| value: NixValue, | ||||||
| }, | ||||||
| /// `if condition then body else else_body` | ||||||
| IfElse { | ||||||
| /// the condition evaluated | ||||||
| condition: ExprResultBox, | ||||||
| /// the body evaluated when the condition is true | ||||||
| body: ExprResultBox, | ||||||
| /// the body evaluated when the condition is false | ||||||
| else_body: ExprResultBox, | ||||||
| }, | ||||||
| /// A string, possibly interpolated | ||||||
| String { | ||||||
| /// interpolated and literal parts of this string | ||||||
| parts: Vec<StringPartSource>, | ||||||
| }, | ||||||
| /// `a.b or c` | ||||||
| OrDefault { | ||||||
| /// `a.b`, of type `Select` | ||||||
| index: ExprResultBox, | ||||||
| /// `c` | ||||||
| default: ExprResultBox, | ||||||
| }, | ||||||
| Paren { | ||||||
| inner: ExprResultBox, | ||||||
| }, | ||||||
| /// `{ arg1, ... } @ args` in a lambda definition `{ arg1, ... } @ args: body` | ||||||
| Pattern { | ||||||
| /// for `{ arg1, arg2 ? default }: body`, a map `"arg1" => None, "arg2" => default` | ||||||
| entries: HashMap<String, Option<ExprResultGc>>, | ||||||
| /// whether the patter is incomplete (contains `...`) | ||||||
| ellipsis: bool, | ||||||
| /// the identifier bound by `@` | ||||||
| at: Option<String>, | ||||||
|
||||||
| at: Option<String>, | |
| at: Option<ExprResultGc>, |
This would let us put the identifier in a Scope, and the Expression struct would also give us more info about where the identifier is located.
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.
I made it an ExprResultBox as there is no need for sharing as far as I can see
aaronjanse marked this conversation as resolved.
Show resolved
Hide resolved
aaronjanse marked this conversation as resolved.
Show resolved
Hide resolved
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.