Documentation
¶
Overview ¶
scope resolution implementation for JS and TS files
Index ¶
- Variables
- func ChildWithFieldName(node *sitter.Node, fieldName string) *sitter.Node
- func ChildrenOfType(node *sitter.Node, nodeType string) []*sitter.Node
- func ChildrenWithFieldName(node *sitter.Node, fieldName string) []*sitter.Node
- func FindMatchingChild(node *sitter.Node, predicate func(*sitter.Node) bool) *sitter.Node
- func FirstChildOfType(node *sitter.Node, nodeType string) *sitter.Node
- func GetEscapedCommentIdentifierFromPath(path string) string
- func GetExtFromLanguage(lang Language) string
- func IssueAsTextFromJson(jsonData []byte) ([]byte, error)
- func Preorder(pass *Pass, fn func(*sitter.Node))
- func ReportIssues(issues []*Issue, format string) ([]byte, error)
- func RunAnalyzerTests(testDir string, analyzers []*Analyzer) (string, string, bool, error)
- func WalkTree(node *sitter.Node, walker Walker)
- type Analyzer
- type Category
- type Issue
- type Language
- type ParseResult
- type Pass
- type Reference
- type Scope
- type ScopeBuilder
- type ScopeTree
- type Severity
- type TsScopeBuilder
- func (ts *TsScopeBuilder) CollectVariables(node *sitter.Node) []*Variable
- func (ts *TsScopeBuilder) DeclaresVariable(node *sitter.Node) bool
- func (j *TsScopeBuilder) GetLanguage() Language
- func (ts *TsScopeBuilder) NodeCreatesScope(node *sitter.Node) bool
- func (ts *TsScopeBuilder) OnNodeEnter(node *sitter.Node, scope *Scope)
- func (ts *TsScopeBuilder) OnNodeExit(node *sitter.Node, scope *Scope)
- type UnresolvedRef
- type VarKind
- type Variable
- type Walker
Constants ¶
This section is empty.
Variables ¶
var ErrUnsupportedLanguage = fmt.Errorf("unsupported language")
ParseFile parses the file at the given path using the appropriate tree-sitter grammar.
var ScopeNodes = []string{
"statement_block",
"function_declaration",
"function_expression",
"for_statement",
"for_in_statement",
"for_of_statement",
"program",
}
Functions ¶
func ChildWithFieldName ¶ added in v0.4.0
func ChildrenOfType ¶ added in v0.4.0
func ChildrenWithFieldName ¶ added in v0.4.0
ChildrenWithFieldName returns all the children of a node with a specific field name. Tree-sitter can have multiple children with the same field name.
func FindMatchingChild ¶ added in v0.4.0
FindMatchingChild iterates over all children of a node—both named and unnamed—and returns the first child that matches the predicate function.
func FirstChildOfType ¶ added in v0.4.0
func GetEscapedCommentIdentifierFromPath ¶ added in v0.3.0
func GetExtFromLanguage ¶ added in v0.4.0
func IssueAsTextFromJson ¶ added in v0.3.0
func RunAnalyzerTests ¶ added in v0.3.0
Types ¶
type Issue ¶
type Issue struct {
// The category of the issue
Category Category
// The severity of the issue
Severity Severity
// The message to display to the user
Message string
// The file path of the file that the issue was found in
Filepath string
// (optional) The AST node that caused the issue
Node *sitter.Node
// Id is a unique ID for the issue.
// Issue that have 'Id's can be explained using the `globstar desc` command.
Id *string
}
func IssueFromJson ¶ added in v0.3.0
func RunAnalyzers ¶
type Language ¶
type Language int
const ( LangUnknown Language = iota LangPy LangJs // vanilla JS and JSX LangTs // TypeScript (not TSX) LangTsx // TypeScript with JSX extension LangJava LangRuby LangRust LangYaml LangCss LangDockerfile LangMarkdown LangSql LangKotlin LangOCaml LangLua LangBash LangCsharp LangElixir LangElm LangGo LangGroovy LangHcl LangHtml LangPhp LangScala LangSwift )
func LanguageFromFilePath ¶
LanguageFromFilePath returns the Language of the file at the given path returns `LangUnkown` if the language is not recognized (e.g: `.txt` files).
type ParseResult ¶
type ParseResult struct {
// Ast is the root node of the tree-sitter parse-tree
// representing this file
Ast *sitter.Node
// Source is the raw source code of the file
Source []byte
// FilePath is the path to the file that was parsed
FilePath string
// Language is the tree-sitter language used to parse the file
TsLanguage *sitter.Language
// Language is the language of the file
Language Language
// ScopeTree represents the scope hierarchy of the file.
// Can be nil if scope support for this language has not been implemented yet.
ScopeTree *ScopeTree
}
ParseResult is the result of parsing a file.
func ParseFile ¶
func ParseFile(filePath string) (*ParseResult, error)
type Pass ¶
type Pass struct {
Analyzer *Analyzer
FileContext *ParseResult
Files []*ParseResult
ResultOf map[*Analyzer]any
Report func(*Pass, *sitter.Node, string)
// TODO (opt): the cache should ideally not be stored in-memory
ResultCache map[*Analyzer]map[*ParseResult]any
}
type Reference ¶ added in v0.4.0
type Reference struct {
// IsWriteRef determines if this reference is a write reference.
// For write refs, only the expression being assigned is stored.
// i.e: for `a = 3`, this list will store the `3` node, not the assignment node
IsWriteRef bool
// Variable stores the variable being referenced
Variable *Variable
// Node stores the node that references the variable
Node *sitter.Node
}
Reference represents a variable reference inside a source file Cross-file references like those in Golang and C++ (macros/extern) are NOT supported, so this shouldn't be used for checkers like "unused-variable", but is safe to use for checkers like "unused-import"
type Scope ¶ added in v0.4.0
type Scope struct {
// AstNode is the AST node that introduces this scope into the scope tree
AstNode *sitter.Node
// Variables is a map of variable name to an object representing it
Variables map[string]*Variable
// Upper is the parent scope of this scope
Upper *Scope
// Children is a list of scopes that are children of this scope
Children []*Scope
}
type ScopeBuilder ¶ added in v0.4.0
type ScopeBuilder interface {
GetLanguage() Language
// NodeCreatesScope returns true if the node introduces a new scope
// into the scope tree
NodeCreatesScope(node *sitter.Node) bool
// DeclaresVariable determines if we can extract new variables out of this AST node
DeclaresVariable(node *sitter.Node) bool
// CollectVariables extracts variables from the node and adds them to the scope
CollectVariables(node *sitter.Node) []*Variable
// OnNodeEnter is called when the scope builder enters a node
// for the first time, and hasn't scanned its children decls just yet
// can be used to handle language specific scoping rules, if any
// If `node` is smth like a block statement, `currentScope` corresponds
// to the scope introduced by the block statement.
OnNodeEnter(node *sitter.Node, currentScope *Scope)
// OnNodeExit is called when the scope builder exits a node
// can be used to handle language specific scoping rules, if any
// If `node` is smth like a block statement, `currentScope` corresponds
// to the scope introduced by the block statement.
OnNodeExit(node *sitter.Node, currentScope *Scope)
}
ScopeBuilder is an interface that has to be implemented once for every supported language. Languages that don't implement a `ScopeBuilder` can still have checkers, just not any that require scope resolution.
type ScopeTree ¶ added in v0.4.0
type ScopeTree struct {
Language Language
// ScopeOfNode maps every scope-having node to its corresponding scope.
// E.g: a block statement is mapped to the scope it introduces.
ScopeOfNode map[*sitter.Node]*Scope
// Root is the top-level scope in the program,
// usually associated with the `program` or `module` node
Root *Scope
}
func BuildScopeTree ¶ added in v0.4.0
func BuildScopeTree(builder ScopeBuilder, ast *sitter.Node, source []byte) *ScopeTree
BuildScopeTree constructs a scope tree from the AST for a program
func MakeScopeTree ¶ added in v0.4.0
type TsScopeBuilder ¶ added in v0.4.0
type TsScopeBuilder struct {
// contains filtered or unexported fields
}
func (*TsScopeBuilder) CollectVariables ¶ added in v0.4.0
func (ts *TsScopeBuilder) CollectVariables(node *sitter.Node) []*Variable
func (*TsScopeBuilder) DeclaresVariable ¶ added in v0.4.0
func (ts *TsScopeBuilder) DeclaresVariable(node *sitter.Node) bool
func (*TsScopeBuilder) GetLanguage ¶ added in v0.4.0
func (j *TsScopeBuilder) GetLanguage() Language
func (*TsScopeBuilder) NodeCreatesScope ¶ added in v0.4.0
func (ts *TsScopeBuilder) NodeCreatesScope(node *sitter.Node) bool
func (*TsScopeBuilder) OnNodeEnter ¶ added in v0.4.0
func (ts *TsScopeBuilder) OnNodeEnter(node *sitter.Node, scope *Scope)
func (*TsScopeBuilder) OnNodeExit ¶ added in v0.4.0
func (ts *TsScopeBuilder) OnNodeExit(node *sitter.Node, scope *Scope)
type UnresolvedRef ¶ added in v0.4.0
type UnresolvedRef struct {
// contains filtered or unexported fields
}
type Walker ¶ added in v0.4.0
type Walker interface {
// OnEnterNode is called when the walker enters a node.
// The boolean return value indicates whether the walker should
// continue walking the sub-tree of this node.
OnEnterNode(node *sitter.Node) bool
// OnLeaveNode is called when the walker leaves a node.
// This is called after all the children of the node have been visited and explored.
OnLeaveNode(node *sitter.Node)
}
Walker is an interface that dictates what to do when entering and leaving each node during the pre-order traversal of a tree. To traverse post-order, use the `OnLeaveNode` callback.