Skip to content

Commit

Permalink
overhaul symbol analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
nedpals committed Nov 13, 2023
1 parent ff75f00 commit 12ae6be
Show file tree
Hide file tree
Showing 18 changed files with 500 additions and 486 deletions.
8 changes: 4 additions & 4 deletions errgoengine.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,13 @@ func (e *ErrgoEngine) Analyze(workingPath, msg string) (*CompiledErrorTemplate,
// get nearest node
doc := contextData.Documents[mainTraceNode.DocumentPath]
nearest := doc.Tree.RootNode().NamedDescendantForPointRange(
sitter.Point{Row: uint32(mainTraceNode.Line)},
sitter.Point{Row: uint32(mainTraceNode.Line)},
sitter.Point{Row: uint32(mainTraceNode.StartPos.Line)},
sitter.Point{Row: uint32(mainTraceNode.EndPos.Line)},
)

if nearest.StartPoint().Row != uint32(mainTraceNode.Line) {
if nearest.StartPoint().Row != uint32(mainTraceNode.StartPos.Line) {
cursor := sitter.NewTreeCursor(nearest)
nearest = nearestNodeFromPos(cursor, mainTraceNode.Position)
nearest = nearestNodeFromPos(cursor, mainTraceNode.StartPos)
}

// further analyze main error
Expand Down
7 changes: 6 additions & 1 deletion error_template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import (

type TestAnalyzer struct{}

func (TestAnalyzer) FallbackSymbol() lib.Symbol {
return nil
}

func (TestAnalyzer) AnalyzeNode(lib.SyntaxNode) lib.Symbol {
return nil
}
Expand All @@ -24,7 +28,8 @@ var testLanguage = &lib.Language{
LocationConverter: func(path, pos string) lib.Location {
return lib.Location{
DocumentPath: path,
Position: lib.Position{0, 0, 0},
StartPos: lib.Position{0, 0, 0},
EndPos: lib.Position{0, 0, 0},
}
},
AnalyzerFactory: func(cd *lib.ContextData) lib.LanguageAnalyzer {
Expand Down
6 changes: 4 additions & 2 deletions language.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type NodeValueAnalyzer interface {
}

type LanguageAnalyzer interface {
FallbackSymbol() Symbol
AnalyzeNode(SyntaxNode) Symbol
AnalyzeImport(ImportParams) ResolvedImport
}
Expand All @@ -26,7 +27,7 @@ type Language struct {
SitterLanguage *sitter.Language
StackTracePattern string
ErrorPattern string
SymbolsToCapture ISymbolCaptureList
SymbolsToCapture string
LocationConverter func(path, pos string) Location
AnalyzerFactory func(cd *ContextData) LanguageAnalyzer
}
Expand Down Expand Up @@ -72,6 +73,7 @@ func DefaultLocationConverter(path, pos string) Location {
}
return Location{
DocumentPath: path,
Position: Position{Line: trueLine},
StartPos: Position{Line: trueLine},
EndPos: Position{Line: trueLine},
}
}
12 changes: 6 additions & 6 deletions languages/java/java_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ public class Test {
}
`,
Expected: `
(tree [0,0]-[0,0]
(class Test [0,0]
(tree [0,18]-[1,1]
(function main [1,1]
(tree [1,40]-[2,2]
(variable a [2,2]))))))
(tree [0,0 | 0]-[4,1 | 79]
(class Test [0,0 | 0]-[4,1 | 79]
(tree [0,18 | 18]-[4,1 | 79]
(function main [1,1 | 21]-[3,2 | 77]
(tree [1,1 | 21]-[3,2 | 77]
(variable a [2,6 | 68]-[2,11 | 73]))))))
`,
},
}
Expand Down
90 changes: 9 additions & 81 deletions languages/java/language.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package java

import (
_ "embed"
"fmt"

lib "github.com/nedpals/errgoengine"
"github.com/smacker/go-tree-sitter/java"
)

//go:embed symbols.txt
var symbols string

var Language = &lib.Language{
Name: "Java",
FilePatterns: []string{".java"},
Expand All @@ -15,93 +19,17 @@ var Language = &lib.Language{
AnalyzerFactory: func(cd *lib.ContextData) lib.LanguageAnalyzer {
return &javaAnalyzer{cd}
},
SymbolsToCapture: lib.ISymbolCaptureList{
lib.SymbolCapture{
Query: "import_declaration",
Kind: lib.SymbolKindImport,
NameNode: &lib.SymbolCapture{
Query: `(_) ("." (asterisk))*`,
},
},
lib.SymbolCapture{
Query: "class_declaration",
Kind: lib.SymbolKindClass,
NameNode: &lib.SymbolCapture{
Field: "name",
Query: "identifier",
},
BodyNode: &lib.SymbolCapture{
Field: "body",
Query: "class_body",
Children: []*lib.SymbolCapture{
{
Query: "field_declaration (variable_declarator)",
Kind: lib.SymbolKindVariable,
NameNode: &lib.SymbolCapture{
Field: "name",
Query: "identifier",
},
},
{
Query: "method_declaration",
Kind: lib.SymbolKindFunction,
NameNode: &lib.SymbolCapture{
Field: "name",
Query: "identifier",
},
// TODO: make return type node work
ReturnTypeNode: &lib.SymbolCapture{
Field: "type",
Query: "_",
},
ContentNode: &lib.SymbolCapture{
Query: "return_statement (expression)?",
Optional: true,
},
ParameterNodes: &lib.SymbolCapture{
Field: "parameters",
Query: "formal_parameters",
Children: []*lib.SymbolCapture{
{
Kind: lib.SymbolKindVariable,
Query: "formal_parameter",
NameNode: &lib.SymbolCapture{
Field: "name",
Query: "identifier",
},
},
},
},
BodyNode: &lib.SymbolCapture{
Field: "body",
Query: "block",
Children: []*lib.SymbolCapture{
// FIXME: figure out return type of variables
{
Query: "local_variable_declaration (variable_declarator)",
Kind: lib.SymbolKindVariable,
NameNode: &lib.SymbolCapture{
Field: "name",
Query: "identifier",
},
ContentNode: &lib.SymbolCapture{
Field: "value",
Query: "_",
},
},
},
},
},
},
},
},
},
SymbolsToCapture: symbols,
}

type javaAnalyzer struct {
*lib.ContextData
}

func (an *javaAnalyzer) FallbackSymbol() lib.Symbol {
return BuiltinTypes.VoidSymbol
}

func (an *javaAnalyzer) AnalyzeNode(n lib.SyntaxNode) lib.Symbol {
switch n.Type() {
// types first
Expand Down
43 changes: 43 additions & 0 deletions languages/java/symbols.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
(import_declaration
(scoped_identifier) @import.path
.
(asterisk) @import.symbol) @import

(import_declaration
(scoped_identifier
scope: (scoped_identifier) @import.path
name: (identifier) @import.symbol)
.) @import

(class_declaration
name: (identifier) @class.name
body: (class_body
[
(field_declaration
type: (_) @variable.return-type
declarator: (variable_declarator
name: (identifier) @variable.name
value: (_)? @variable.content) @variable.declaration) @variable
(method_declaration
type: (void_type) @method.return-type
name: (identifier) @method.name
parameters: (formal_parameters
(formal_parameter
type: (_) @parameter.return-type
name: (identifier) @parameter.name)* @parameter) @parameters) @method
]) @class.body) @class

(block
[
(local_variable_declaration
type: (_) @variable.return-type
declarator: (variable_declarator
name: (identifier) @variable.name
value: (_)? @variable.content)) @variable
(expression_statement
(assignment_expression
left: (identifier) @assignment.name
right: (_) @assignment.content)) @assignment
]?
(return_statement
(_) @block.content)?) @block
77 changes: 10 additions & 67 deletions languages/python/language.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package python

import (
_ "embed"

lib "github.com/nedpals/errgoengine"
"github.com/smacker/go-tree-sitter/python"
)

//go:embed symbols.txt
var symbols string

var Language = &lib.Language{
Name: "Python",
FilePatterns: []string{".py"},
Expand All @@ -14,79 +19,17 @@ var Language = &lib.Language{
AnalyzerFactory: func(cd *lib.ContextData) lib.LanguageAnalyzer {
return &pyAnalyzer{cd}
},
SymbolsToCapture: lib.ISymbolCaptureList{
lib.SymbolCapture{
Query: "import_statement",
Kind: lib.SymbolKindImport,
NameNode: &lib.SymbolCapture{
Query: "_",
Field: "name",
},
},
lib.SymbolCapture{
Query: "import_from_statement",
Kind: lib.SymbolKindImport,
NameNode: &lib.SymbolCapture{
Query: "_",
Field: "module_name",
},
// TODO: include symbol names?
},
lib.SymbolCapture{
Query: "function_definition",
Kind: lib.SymbolKindFunction,
NameNode: &lib.SymbolCapture{
Query: "identifier",
Field: "name",
},
ParameterNodes: &lib.SymbolCapture{
Field: "parameters",
Query: "parameters",
Children: []*lib.SymbolCapture{
{
Kind: lib.SymbolKindVariable,
Query: "parameter",
NameNode: &lib.SymbolCapture{
Query: "identifier",
},
},
{
Kind: lib.SymbolKindVariable,
Query: "parameter",
NameNode: &lib.SymbolCapture{
Query: "_",
Field: "name",
},
},
},
},
BodyNode: &lib.SymbolCapture{
Field: "body",
Query: "block",
Children: []*lib.SymbolCapture{
// FIXME: figure out return type of variables
{
Query: "expression_statement (assignment)",
Kind: lib.SymbolKindVariable,
NameNode: &lib.SymbolCapture{
Field: "left",
Query: "identifier",
},
ContentNode: &lib.SymbolCapture{
Field: "right",
Query: "_",
},
},
},
},
},
},
SymbolsToCapture: symbols,
}

type pyAnalyzer struct {
*lib.ContextData
}

func (an *pyAnalyzer) FallbackSymbol() lib.Symbol {
return lib.Builtin("any")
}

func (an *pyAnalyzer) AnalyzeNode(n lib.SyntaxNode) lib.Symbol {
// TODO:
return lib.Builtin("void")
Expand Down
8 changes: 4 additions & 4 deletions languages/python/python_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ def main():
a = 1
`,
Expected: `
(tree [0,0]-[0,0]
(function main [0,0]
(tree [1,1]-[1,6]
(variable a [1,1]))))
(tree [0,0 | 0]-[1,6 | 18]
(function [0,0 | 0]-[1,6 | 18]
(tree [0,0 | 0]-[1,6 | 18]
(assignment a [1,1 | 13]-[1,2 | 14]))))
`,
},
}
Expand Down
23 changes: 23 additions & 0 deletions languages/python/symbols.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
(import_statement
name: (_) @import.path) @import

(expression_statement
(assignment
left: (identifier) @assignment.name
right: (_) @assignment.content)) @assignment

(function_definition
parameters: (parameters
[
(identifier) @parameter.name
(typed_parameter
((identifier) @parameter.name)
type: (_) @parameter.return-type)
]? @parameter) @parameters) @function
(return_statement
(_) @block.content)?

(expression_statement
(assignment
left: (identifier) @assignment.name
right: (identifier) @assignment.content) @assignment)
Loading

0 comments on commit 12ae6be

Please sign in to comment.