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 InitializeSkipComments(analyzers []*Analyzer)
- func WalkTree(node *sitter.Node, walker Walker)
- type Analyzer
- func (ana *Analyzer) AddChecker(checker Checker)
- func (ana *Analyzer) Analyze() []*Issue
- func (ana *Analyzer) ContainsSkipcq(skipLines []*SkipComment, issue *Issue) bool
- func (ana *Analyzer) OnEnterNode(node *sitter.Node) bool
- func (ana *Analyzer) OnLeaveNode(node *sitter.Node)
- func (ana *Analyzer) Report(issue *Issue)
- type Checker
- type Issue
- type Language
- type NodeFilter
- type ParseResult
- type PathFilter
- type PatternCheckerFile
- type Reference
- type Scope
- type ScopeBuilder
- type ScopeTree
- type SkipComment
- 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 VisitFn
- type Walker
- type YamlChecker
Constants ¶
This section is empty.
Variables ¶
var ScopeNodes = []string{
"statement_block",
"function_declaration",
"function_expression",
"for_statement",
"for_in_statement",
"for_of_statement",
}
Functions ¶
func ChildrenWithFieldName ¶
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 ¶
FindMatchingChild iterates over all children of a node—both named and unnamed—and returns the first child that matches the predicate function.
func GetEscapedCommentIdentifierFromPath ¶ added in v0.7.0
func GetExtFromLanguage ¶
func InitializeSkipComments ¶ added in v0.7.0
func InitializeSkipComments(analyzers []*Analyzer)
Types ¶
type Analyzer ¶
type Analyzer struct {
Language Language
// WorkDir is the directory in which the analysis is being run.
WorkDir string
// ParseResult is the result of parsing a file with a tree-sitter parser,
// along with some extra appendages (e.g: scope information).
ParseResult *ParseResult
// patternCheckers is a list of all checkers that run after a query is run on the AST.
// Usually, these are written in a DSL (which, for now, is the tree-sitter S-Expression query language)
YamlCheckers []YamlChecker
// contains filtered or unexported fields
}
func NewAnalyzer ¶
func NewAnalyzer(file *ParseResult, checkers []Checker) *Analyzer
func (*Analyzer) AddChecker ¶ added in v0.4.0
func (*Analyzer) ContainsSkipcq ¶ added in v0.7.0
func (ana *Analyzer) ContainsSkipcq(skipLines []*SkipComment, issue *Issue) bool
func (*Analyzer) OnLeaveNode ¶
type Checker ¶ added in v0.4.0
type Issue ¶
type Issue struct {
// The category of the issue
Category config.Category
// The severity of the issue
Severity config.Severity
// The message to display to the user
Message string
// The file path of the file that the issue was found in
Filepath string
// The range of the issue in the source code
Range sitter.Range
// (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 RunYamlCheckers ¶ added in v0.4.0
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 DecodeLanguage ¶
DecodeLanguage converts a stringified language name to its corresponding Language enum
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 NodeFilter ¶
type NodeFilter struct {
// contains filtered or unexported fields
}
NodeFilter is a filter that can be applied to a PatternChecker to restrict the the nodes that the checker is applied to. The checker is only applied to nodes that have a parent matching (or not matching) the query.
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)
ParseFile parses the file at the given path using the appropriate tree-sitter grammar.
type PathFilter ¶
PathFilter is a glob that can be applied to a PatternChecker to restrict the files that the checker is applied to.
type PatternCheckerFile ¶ added in v0.4.0
type PatternCheckerFile struct {
Language string `yaml:"language"`
Code string `yaml:"name"`
Message string `yaml:"message"`
Category config.Category `yaml:"category"`
Severity config.Severity `yaml:"severity"`
// Pattern is a single pattern in the form of:
// pattern: (some_pattern)
// in the YAML file
Pattern string `yaml:"pattern,omitempty"`
// Patterns are ultiple patterns in the form of:
// pattern: (something)
// in the YAML file
Patterns []string `yaml:"patterns,omitempty"`
Description string `yaml:"description,omitempty"`
Filters []filterYAML `yaml:"filters,omitempty"`
Exclude []string `yaml:"exclude,omitempty"`
Include []string `yaml:"include,omitempty"`
}
type Reference ¶
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 ¶
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 ¶
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 ¶
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 ¶
func BuildScopeTree(builder ScopeBuilder, ast *sitter.Node, source []byte) *ScopeTree
BuildScopeTree constructs a scope tree from the AST for a program
type SkipComment ¶ added in v0.7.0
type SkipComment struct {
// the line number for the skipcq comment
CommentLine int
// the entire text of the skipcq comment
CommentText string
// (optional) name of the checker for targetted skip
CheckerIds []string
}
func GatherSkipInfo ¶ added in v0.7.0
func GatherSkipInfo(fileContext *ParseResult) []*SkipComment
type TsScopeBuilder ¶
type TsScopeBuilder struct {
// contains filtered or unexported fields
}
func (*TsScopeBuilder) CollectVariables ¶
func (ts *TsScopeBuilder) CollectVariables(node *sitter.Node) []*Variable
func (*TsScopeBuilder) DeclaresVariable ¶
func (ts *TsScopeBuilder) DeclaresVariable(node *sitter.Node) bool
func (*TsScopeBuilder) GetLanguage ¶
func (j *TsScopeBuilder) GetLanguage() Language
func (*TsScopeBuilder) NodeCreatesScope ¶
func (ts *TsScopeBuilder) NodeCreatesScope(node *sitter.Node) bool
func (*TsScopeBuilder) OnNodeEnter ¶
func (ts *TsScopeBuilder) OnNodeEnter(node *sitter.Node, scope *Scope)
func (*TsScopeBuilder) OnNodeExit ¶
func (ts *TsScopeBuilder) OnNodeExit(node *sitter.Node, scope *Scope)
type UnresolvedRef ¶
type UnresolvedRef struct {
// contains filtered or unexported fields
}
type Walker ¶
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.
type YamlChecker ¶ added in v0.4.0
type YamlChecker interface {
Name() string
Patterns() []*sitter.Query
Language() Language
Category() config.Category
Severity() config.Severity
OnMatch(
ana *Analyzer,
matchedQuery *sitter.Query,
matchedNode *sitter.Node,
captures []sitter.QueryCapture,
)
PathFilter() *PathFilter
NodeFilters() []NodeFilter
}
A YamlChecker is a checker that matches a tree-sitter query pattern and reports an issue when the pattern is found. Unlike regular issues, PatternCheckers are not associated with a specific node type, rather they are invoked for *every* node that matches the pattern.
func CreatePatternChecker ¶ added in v0.4.0
func CreatePatternChecker( patterns []*sitter.Query, language Language, issueMessage string, issueId string, pathFilter *PathFilter, ) YamlChecker
func ReadFromBytes ¶
func ReadFromBytes(fileContent []byte) (YamlChecker, error)
ReadFromBytes reads a pattern checker definition from bytes array
func ReadFromFile ¶
func ReadFromFile(filePath string) (YamlChecker, error)
ReadFromFile reads a pattern checker definition from a YAML config file.