Skip to content

Commit

Permalink
- Change JSON AST structure.
Browse files Browse the repository at this point in the history
- Converting AST: support chain call of properties.
  • Loading branch information
pherrymason committed Nov 25, 2024
1 parent f444d33 commit 767ffe8
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 36 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ assets
tree-sitter-c3
parser/chumsky
server/internal/parser
server/internal/lsp/ast/ast.json
server/bin
dist/
4 changes: 2 additions & 2 deletions server/internal/lsp/ast/ast_visitors.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type ASTVisitor interface {
VisitFunctionParameter(node *FunctionParameter)
VisitFunctionCall(node *FunctionCall)
VisitInterfaceDecl(node *InterfaceDecl)
VisitCompounStatement(node *CompoundStmt)
VisitCompoundStatement(node *CompoundStmt)
VisitType(node *TypeInfo)
VisitIdentifier(node *Ident)
VisitBinaryExpression(node *BinaryExpression)
Expand Down Expand Up @@ -55,7 +55,7 @@ func Visit(node Node, v ASTVisitor) {
v.VisitLambdaDeclaration(node.(*LambdaDeclarationExpr))

case *CompoundStmt:
v.VisitCompounStatement(node.(*CompoundStmt))
v.VisitCompoundStatement(node.(*CompoundStmt))

case *TypeInfo:
v.VisitType(node.(*TypeInfo))
Expand Down
2 changes: 1 addition & 1 deletion server/internal/lsp/ast/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -1167,7 +1167,7 @@ func convert_field_expr(node *sitter.Node, source []byte) Expression {
WithSitterPos(argument).
Build()
} else {

argumentNode = convert_field_expr(argument, source)
}
field := node.ChildByFieldName("field")

Expand Down
26 changes: 23 additions & 3 deletions server/internal/lsp/ast/convert_expression_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,28 @@ func TestConvertToAST_function_statements_call_chain(t *testing.T) {
EndPos: Position{Line: 3, Column: 16},
},
Identifier: &SelectorExpr{
X: Ident{Name: "object"},
Sel: Ident{Name: "call"},
X: NewIdentifierBuilder().WithName("object").WithStartEnd(3, 2, 3, 8).Build(),
Sel: NewIdentifierBuilder().WithName("call").WithStartEnd(3, 9, 3, 13).Build(),
},
Arguments: []Expression{
&IntegerLiteral{Value: "1"},
},
},
},
{
skip: false,
input: "object.prop.call(1);",
expected: &FunctionCall{
NodeAttributes: NodeAttributes{
StartPos: Position{Line: 3, Column: 2},
EndPos: Position{Line: 3, Column: 21},
},
Identifier: &SelectorExpr{
X: &SelectorExpr{
X: NewIdentifierBuilder().WithName("object").WithStartEnd(3, 2, 3, 8).Build(),
Sel: NewIdentifierBuilder().WithName("prop").WithStartEnd(3, 9, 3, 13).Build(),
},
Sel: NewIdentifierBuilder().WithName("call").WithStartEnd(3, 14, 3, 18).Build(),
},
Arguments: []Expression{
&IntegerLiteral{Value: "1"},
Expand All @@ -356,7 +376,7 @@ func TestConvertToAST_function_statements_call_chain(t *testing.T) {
if tt.skip {
continue
}
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
t.Run(fmt.Sprintf("function_statements_call_chain[%d]", i), func(t *testing.T) {
source := `
module foo;
fn void main() {
Expand Down
70 changes: 41 additions & 29 deletions server/internal/lsp/ast/json_visitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@ package ast

import "encoding/json"

// ---------------------------------------------------------------
// Visitor that generates a JSON representation of the AST program
//
// Schema ---------
// All objects representing a node have following properties
// - "node_type": string.
// - "doc_pos": array[uint,uint]. Represents start and end positions in the file.
//
// FileObject
// - "modules": [ModuleObject]
// - "name": string
// - "node_type": "File"

const PNodeType = "node_type"
const PDocPos = "doc_pos"

type JSONObject map[string]interface{}

type JSONVisitor struct {
Expand All @@ -26,50 +42,46 @@ func (v *JSONVisitor) VisitFile(node *File) {
}

v.Result = map[string]interface{}{
"type": "File",
PNodeType: "File",
"name": node.Name,
"modules": jsonModules,
}
}

func (v *JSONVisitor) VisitModule(node *Module) {
declarationsV := JSONVisitor{}
declarations := []interface{}{}
var declarations []interface{}
for _, decl := range node.Declarations {
Visit(decl, &declarationsV)
if declarationsV.Result != nil {
declarations = append(declarations, declarationsV.Result)
}
}

functionsV := JSONVisitor{}
functions := []interface{}{}
for _, fun := range node.Declarations {
Visit(fun, &functionsV)
if functionsV.Result != nil {
functions = append(functions, functionsV.Result)
}
v.VisitDeclaration(decl)
declarations = append(declarations, v.Result)
}

v.Result = map[string]interface{}{
"type": "Module",
PNodeType: "Module",
"name": node.Name,
"pos": serialize_pos(node),
PDocPos: serialize_pos(node),
"declarations": declarations,
"functions": functions,
}
}

func (v *JSONVisitor) VisitImport(node *Import) {

}

func (v *JSONVisitor) VisitDeclaration(node Declaration) {
switch node.(type) {
case *VariableDecl:
v.VisitVariableDeclaration(node.(*VariableDecl))
case *FunctionDecl:
v.VisitFunctionDecl(node.(*FunctionDecl))
}
}

func (v *JSONVisitor) VisitVariableDeclaration(node *VariableDecl) {
names := []map[string]interface{}{}
for _, name := range node.Names {
names = append(names, map[string]interface{}{
"name": name.Name,
"pos": serialize_pos(name),
"name": name.Name,
PDocPos: serialize_pos(name),
})
}

Expand All @@ -80,9 +92,9 @@ func (v *JSONVisitor) VisitVariableDeclaration(node *VariableDecl) {
Visit(node.Initializer, &initV)

v.Result = map[string]interface{}{
"type": "VariableDeclaration",
PNodeType: "VariableDeclaration",
"names": names,
"kind": typeV.Result,
"variable_type": typeV.Result,
"initialization": initV.Result,
}
}
Expand Down Expand Up @@ -132,7 +144,7 @@ func (v *JSONVisitor) VisitFunctionDecl(node *FunctionDecl) {
Visit(node.Body, &bodyV)

v.Result = map[string]interface{}{
"type": "FunctionDecl",
PNodeType: "FunctionDecl",
"name": node.Signature.Name.Name,
"returnType": returnType,
"parameters": parameters,
Expand All @@ -146,7 +158,7 @@ func (v *JSONVisitor) VisitFunctionParameter(node *FunctionParameter) {

func VisitFunctionParameter(node *FunctionParameter) JSONObject {
return map[string]interface{}{
"type": "FunctionParameter",
PNodeType: "FunctionParameter",
"name": node.Name.Name,
"parameterType": VisitType(&node.Type),
}
Expand All @@ -160,7 +172,7 @@ func (v *JSONVisitor) VisitInterfaceDecl(node *InterfaceDecl) {

}

func (v *JSONVisitor) VisitCompounStatement(node *CompoundStmt) {
func (v *JSONVisitor) VisitCompoundStatement(node *CompoundStmt) {
visitor := JSONVisitor{}
statements := []JSONObject{}
for _, s := range node.Statements {
Expand All @@ -183,7 +195,7 @@ func VisitType(node *TypeInfo) JSONObject {
}

return map[string]interface{}{
"type": "Type",
PNodeType: "Type",
"name": node.Identifier.Name,
"builtin": node.BuiltIn,
"optional": node.Optional,
Expand All @@ -205,8 +217,8 @@ func (v *JSONVisitor) VisitIfStatement(node *IfStmt) {

func (v *JSONVisitor) VisitIntegerLiteral(node *IntegerLiteral) {
v.Result = map[string]interface{}{
"type": "IntegerLiteral",
"value": node.Value,
PNodeType: "IntegerLiteral",
"value": node.Value,
}
}

Expand Down
10 changes: 9 additions & 1 deletion server/pkg/featureflags/feature_flags.go
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
package utils
package featureflags

var features = map[string]bool{
"UseGeneratedAST": false,
}

func IsActive(feature string) bool {
return features[feature]
}

0 comments on commit 767ffe8

Please sign in to comment.