@aws/fully-qualified-names
v2.1.4
Published
For extracting def use statements from code.
Downloads
106,328
Readme
Fully Qualified Names
A name cannot be dissected any further by means of a definition: it is a primitive sign -- Ludwig Wittgenstein
Powered by tree-sitter
, fully-qualified-names
lets you extract simple and fully qualified names from code written in JavaScript, TypeScript, Python or Java. Those names are further split into declarations and usages which provides a convenient simplification of more complex ASTs for static analysis.
How to use
The package offers a Rust and a JS API, the latter based on WASM. To get names from a Python code snippet in Rust you would use something like the following.
use fully-qualified-names::Python;
let code = r#"class Person:
def __init__(self, name):
self.name = name
def hello(self):
return f"Hello, {self.name}"
"#;
let names = Python::find_names(code).unwrap();
println!("{names:?}");
The same in JS would look as follows.
import { Python } from '@aws/fully-qualified-names';
const code = `class Person:
def __init__(self, name):
self.name = name
def hello(self):
return f"Hello, {self.name}"
`;
const names = await Python.findNames(code);
console.log(JSON.stringify(names));
Background
In programming, identifers are used to refer to values, types and code passages.
Names
Those all have simple names which are context-specific, and fully qualified names (subsequently abbreviated as FQNs), which are unambiguous and unique across projects.
Take e.g. the following Rust code snippet.
let list = std::vec::Vec::new();
Here we have several simple names (list
, std
, vec
, Vec
, new
),
which include variable (list
), module (std
, vec
), type (Vec
) and method (new
) names.
All of those have FQNs as well, the new
method's FQN is explicitly stated as std::vec::Vec::new
,
the list
variable's FQN can only be determined with knowledge of the surrounding package
and module structure.
Declaration -- Usage
The names introduced above can be furthermore be separated into declarations (list
) and usages (std::vec::Vec::new
)
Declaration: A declaration is a statement which introduces a name into a scope.
Value Usage: A symbol name is used in an expression which requires evaluating (i.e. looking up) the symbol’s definition.
Type Usage: A type name is used by the compiler in a left-hand-side context to
- ensure a value in a right-right-hand side context has the required type
- avoid type propagation/inference across scopes
Security
See CONTRIBUTING for more information.
License
This project is licensed under the Apache-2.0 License.