1
1
mirror of https://github.com/oxalica/nil.git synced 2024-11-22 19:49:20 +03:00

Handle builtin names

This commit is contained in:
oxalica 2022-07-31 21:28:14 +08:00
parent 76a27d724a
commit 7e36f8a81b
6 changed files with 250 additions and 7 deletions

102
Cargo.lock generated
View File

@ -78,6 +78,17 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "getrandom"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
@ -229,6 +240,7 @@ dependencies = [
"indexmap",
"la-arena",
"ordered-float",
"phf",
"rowan",
"salsa",
"smol_str",
@ -296,6 +308,54 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
name = "phf"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4724fa946c8d1e7cd881bd3dbee63ce32fc1e9e191e35786b3dc1320a3f68131"
dependencies = [
"phf_macros",
"phf_shared",
]
[[package]]
name = "phf_generator"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b450720b6f75cfbfabc195814bd3765f337a4f9a83186f8537297cac12f6705"
dependencies = [
"phf_shared",
"rand",
]
[[package]]
name = "phf_macros"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd94351ac44e70e56b59883e15029a5135f902a8a3020f9c18d580a420e526aa"
dependencies = [
"phf_generator",
"phf_shared",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "phf_shared"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dd5609d4b2df87167f908a32e1b146ce309c16cf35df76bc11f440b756048e4"
dependencies = [
"siphasher",
]
[[package]]
name = "ppv-lite86"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
[[package]]
name = "proc-macro2"
version = "1.0.40"
@ -314,6 +374,36 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
"getrandom",
]
[[package]]
name = "redox_syscall"
version = "0.2.13"
@ -441,6 +531,12 @@ dependencies = [
"syn",
]
[[package]]
name = "siphasher"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
[[package]]
name = "smallvec"
version = "1.9.0"
@ -538,6 +634,12 @@ dependencies = [
"serde",
]
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "winapi"
version = "0.3.9"

View File

@ -7,6 +7,7 @@ edition = "2021"
indexmap = "1.9.1"
la-arena = "0.2.1"
ordered-float = "3.0.0"
phf = { version = "0.11.0", features = ["macros"] }
rowan = "0.15.6"
salsa = "0.17.0-pre.2"
smol_str = "0.1.23"

113
src/builtin.rs Normal file
View File

@ -0,0 +1,113 @@
pub static NAMES: phf::Set<&'static str> = phf::phf_set! {
"__addErrorContext",
"__all",
"__any",
"__appendContext",
"__attrNames",
"__attrValues",
"__bitAnd",
"__bitOr",
"__bitXor",
"__catAttrs",
"__ceil",
"__compareVersions",
"__concatLists",
"__concatMap",
"__concatStringsSep",
"__currentSystem",
"__currentTime",
"__deepSeq",
"__div",
"__elem",
"__elemAt",
"__fetchurl",
"__filter",
"__filterSource",
"__findFile",
"__floor",
"__foldl'",
"__fromJSON",
"__functionArgs",
"__genList",
"__genericClosure",
"__getAttr",
"__getContext",
"__getEnv",
"__getFlake",
"__groupBy",
"__hasAttr",
"__hasContext",
"__hashFile",
"__hashString",
"__head",
"__intersectAttrs",
"__isAttrs",
"__isBool",
"__isFloat",
"__isFunction",
"__isInt",
"__isList",
"__isPath",
"__isString",
"__langVersion",
"__length",
"__lessThan",
"__listToAttrs",
"__mapAttrs",
"__match",
"__mul",
"__nixPath",
"__nixVersion",
"__parseDrvName",
"__partition",
"__path",
"__pathExists",
"__readDir",
"__readFile",
"__replaceStrings",
"__seq",
"__sort",
"__split",
"__splitVersion",
"__storeDir",
"__storePath",
"__stringLength",
"__sub",
"__substring",
"__tail",
"__toFile",
"__toJSON",
"__toPath",
"__toXML",
"__trace",
"__traceVerbose",
"__tryEval",
"__typeOf",
"__unsafeDiscardOutputDependency",
"__unsafeDiscardStringContext",
"__unsafeGetAttrPos",
"__zipAttrsWith",
"abort",
"baseNameOf",
"break",
"builtins",
"derivation",
"derivationStrict",
"dirOf",
"false",
"fetchGit",
"fetchMercurial",
"fetchTarball",
"fetchTree",
"fromTOML",
"import",
"isNull",
"map",
"null",
"placeholder",
"removeAttrs",
"scopedImport",
"throw",
"toString",
"true",
};

View File

@ -1,5 +1,5 @@
use super::{BindingKey, BindingValue, Bindings, DefDatabase, Expr, ExprId, Module, NameDefId};
use crate::base::FileId;
use crate::{builtin, FileId};
use la_arena::{Arena, ArenaMap, Idx};
use smol_str::SmolStr;
use std::{collections::HashMap, iter, ops, sync::Arc};
@ -53,17 +53,25 @@ impl ModuleScopes {
}
pub fn resolve_name(&self, expr_id: ExprId, name: &SmolStr) -> Option<ResolveResult> {
let mut inner_env = None;
self.ancestors(self.scope_by_expr(expr_id)?)
let mut innermost_env = None;
let scope = self.scope_by_expr(expr_id)?;
// 1. Local defs.
self.ancestors(scope)
.find_map(|data| match &data.kind {
ScopeKind::NameDefs(defs) => defs.get(name).copied(),
ScopeKind::NameDefs(defs) => Some(ResolveResult::NameDef(*defs.get(name)?)),
ScopeKind::WithEnv(env) => {
inner_env = inner_env.or(Some(*env));
innermost_env = innermost_env.or(Some(*env));
None
}
})
.map(ResolveResult::NameDef)
.or_else(|| inner_env.map(ResolveResult::WithEnv))
// 2. Builtin names.
.or_else(|| {
builtin::NAMES
.get_key(name)
.map(|s| ResolveResult::Builtin(s))
})
// 3. Innermost "with" expr.
.or_else(|| innermost_env.map(ResolveResult::WithEnv))
}
fn traverse_expr(&mut self, module: &Module, expr: ExprId, scope: ScopeId) {
@ -164,6 +172,7 @@ impl ModuleScopes {
pub enum ResolveResult {
NameDef(NameDefId),
WithEnv(ExprId),
Builtin(&'static str),
}
#[derive(Debug, Clone, PartialEq, Eq)]
@ -270,6 +279,8 @@ mod tests {
.to_node(&parse.syntax_node())
.text_range()
.start(),
// Same pos for builtin names.
ResolveResult::Builtin(_) => pos,
});
assert_eq!(got, Some(def_pos));
}
@ -350,4 +361,11 @@ mod tests {
check_resolve("let a = 1; $1b = 2; in let a = 2; inherit $0b; in b");
check_resolve("let a = 1; in let $1a = $0a; in a");
}
#[test]
fn builtin() {
check_resolve("let $1true = 1; in with x; $0true + false + falsie");
check_resolve("let true = 1; in with x; true + $0$1false + falsie");
check_resolve("let true = 1; in with $1x; true + false + $0falsie");
}
}

View File

@ -53,6 +53,8 @@ pub(crate) fn goto_definition(
let with_header = with_token_range.cover(with_header_end);
(with_token_range, with_header)
}
// Currently builtin names cannot "goto-definition".
ResolveResult::Builtin(_) => return None,
};
Some(NavigationTarget {
@ -120,4 +122,10 @@ mod tests {
expect!["<a> = a;"],
);
}
#[test]
fn builtin() {
check("let true = 1; in $0true && false", expect!["<true> = 1;"]);
check("let true = 1; in true && $0false", expect![""]);
}
}

View File

@ -1,4 +1,5 @@
mod base;
mod builtin;
mod def;
mod diagnostic;
mod ide;