Skip to content

Commit a7ffd07

Browse files
committedAug 28, 2022
Fixed symbol parsing
1 parent 996bc06 commit a7ffd07

6 files changed

+73
-51
lines changed
 

‎declaration.go

+8-3
Original file line numberDiff line numberDiff line change
@@ -287,9 +287,14 @@ func ParseDecl(node *sitter.Node, source []byte, ctx Ctx) ast.Decl {
287287
}
288288

289289
// Go through the types and check to see if they differ
290-
for index, param := range d.Parameters {
291-
paramType := methodParameters.NamedChild(index).ChildByFieldName("type").Content(source)
292-
if param.OriginalType != paramType {
290+
for index, param := range nodeutil.NamedChildrenOf(methodParameters) {
291+
var paramType string
292+
if param.Type() == "spread_parameter" {
293+
paramType = param.NamedChild(0).Content(source)
294+
} else {
295+
paramType = param.ChildByFieldName("type").Content(source)
296+
}
297+
if d.Parameters[index].OriginalType != paramType {
293298
return false
294299
}
295300
}

‎expression.go

+10-9
Original file line numberDiff line numberDiff line change
@@ -169,15 +169,16 @@ func ParseExpr(node *sitter.Node, source []byte, ctx Ctx) ast.Expr {
169169
argumentTypes := make([]string, objectArguments.NamedChildCount())
170170
for ind, argument := range nodeutil.NamedChildrenOf(objectArguments) {
171171
arguments[ind] = ParseExpr(argument, source, ctx)
172+
172173
// Look up each argument and find its type
173174
if argument.Type() != "identifier" {
174175
argumentTypes[ind] = symbol.TypeOfLiteral(argument, source)
175176
} else {
176177
if localDef := ctx.localScope.FindVariable(argument.Content(source)); localDef != nil {
177178
argumentTypes[ind] = localDef.OriginalType
178179
// Otherwise, a variable may exist as a global variable
179-
} else if def := ctx.currentClass.FindField().ByOriginalName(argument.Content(source))[0]; def != nil {
180-
argumentTypes[ind] = def.OriginalType
180+
} else if def := ctx.currentFile.FindField().ByOriginalName(argument.Content(source)); len(def) > 0 {
181+
argumentTypes[ind] = def[0].OriginalType
181182
}
182183
}
183184
}
@@ -275,25 +276,25 @@ func ParseExpr(node *sitter.Node, source []byte, ctx Ctx) ast.Expr {
275276
// TODO: This probably should be a cast function, instead of an assertion
276277
return &ast.TypeAssertExpr{
277278
X: ParseExpr(node.NamedChild(1), source, ctx),
278-
Type: ParseExpr(node.NamedChild(0), source, ctx),
279+
Type: astutil.ParseType(node.NamedChild(0), source),
279280
}
280281
case "field_access":
281282
// X.Sel
282283
obj := node.ChildByFieldName("object")
283284

284285
if obj.Type() == "this" {
285-
def := ctx.currentClass.FindField().ByOriginalName(node.ChildByFieldName("field").Content(source))[0]
286-
if def == nil {
286+
def := ctx.currentClass.FindField().ByOriginalName(node.ChildByFieldName("field").Content(source))
287+
if len(def) == 0 {
287288
// TODO: This field could not be found in the current class, because it exists in the superclass
288289
// definition for the class
289-
def = &symbol.Definition{
290+
def = []*symbol.Definition{&symbol.Definition{
290291
Name: node.ChildByFieldName("field").Content(source),
291-
}
292+
}}
292293
}
293294

294295
return &ast.SelectorExpr{
295296
X: ParseExpr(node.ChildByFieldName("object"), source, ctx),
296-
Sel: &ast.Ident{Name: def.Name},
297+
Sel: &ast.Ident{Name: def[0].Name},
297298
}
298299
}
299300
return &ast.SelectorExpr{
@@ -358,5 +359,5 @@ func ParseExpr(node *sitter.Node, source []byte, ctx Ctx) ast.Expr {
358359
case "true", "false":
359360
return &ast.Ident{Name: node.Content(source)}
360361
}
361-
return nil
362+
panic("Unhandled expression: " + node.Type())
362363
}

‎statement.go

+15-15
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"go/ast"
66
"go/token"
77

8+
"github.com/NickyBoy89/java2go/astutil"
89
"github.com/NickyBoy89/java2go/nodeutil"
910
log "github.com/sirupsen/logrus"
1011
sitter "github.com/smacker/go-tree-sitter"
@@ -28,39 +29,38 @@ func TryParseStmt(node *sitter.Node, source []byte, ctx Ctx) ast.Stmt {
2829
case "comment":
2930
return &ast.BadStmt{}
3031
case "local_variable_declaration":
31-
var varTypeIndex int
32+
variableType := astutil.ParseType(node.ChildByFieldName("type"), source)
33+
variableDeclarator := node.ChildByFieldName("declarator")
3234

33-
// The first child can either be modifiers e.g `final int var = 1`, or
34-
// just the variable's type
35-
if node.NamedChild(0).Type() == "modifiers" {
36-
varTypeIndex = 1
37-
}
38-
39-
// The variable declarator does not have a value (ex: int value;)
40-
if node.NamedChild(varTypeIndex+1).NamedChildCount() == 1 {
35+
// If a variable is being declared, but not set to a value
36+
// Ex: `int value;`
37+
if variableDeclarator.NamedChildCount() == 1 {
4138
return &ast.DeclStmt{
4239
Decl: &ast.GenDecl{
4340
Tok: token.VAR,
4441
Specs: []ast.Spec{
4542
&ast.ValueSpec{
46-
Names: []*ast.Ident{ParseExpr(node.NamedChild(varTypeIndex+1).NamedChild(0), source, ctx).(*ast.Ident)},
47-
Type: ParseExpr(node.NamedChild(varTypeIndex), source, ctx),
43+
Names: []*ast.Ident{ParseExpr(variableDeclarator.ChildByFieldName("name"), source, ctx).(*ast.Ident)},
44+
Type: variableType,
4845
},
4946
},
5047
},
5148
}
5249
}
5350

54-
ctx.lastType = ParseExpr(node.NamedChild(varTypeIndex), source, ctx)
51+
ctx.lastType = variableType
5552

56-
declaration := ParseStmt(node.NamedChild(varTypeIndex+1), source, ctx).(*ast.AssignStmt)
53+
declaration := ParseStmt(variableDeclarator, source, ctx).(*ast.AssignStmt)
5754

55+
// Now, if a variable is assigned to `null`, we can't infer its type, so
56+
// don't throw out the type information associated with it
5857
var containsNull bool
5958

6059
// Go through the values and see if there is a `null_literal`
61-
for _, child := range nodeutil.NamedChildrenOf(node.NamedChild(varTypeIndex + 1)) {
60+
for _, child := range nodeutil.NamedChildrenOf(variableDeclarator) {
6261
if child.Type() == "null_literal" {
6362
containsNull = true
63+
break
6464
}
6565
}
6666

@@ -78,7 +78,7 @@ func TryParseStmt(node *sitter.Node, source []byte, ctx Ctx) ast.Stmt {
7878
Specs: []ast.Spec{
7979
&ast.ValueSpec{
8080
Names: names,
81-
Type: ParseExpr(node.NamedChild(varTypeIndex), source, ctx),
81+
Type: variableType,
8282
Values: declaration.Rhs,
8383
},
8484
},

‎symbol/class_scope.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ func (cs *ClassScope) FindMethod() Finder {
1818
return &cm
1919
}
2020

21-
// FindField searches through the immediate class's methods to find a specific method
21+
// FindField searches through the immediate class's fields to find a specific field
2222
func (cs *ClassScope) FindField() Finder {
2323
cm := classFieldFinder(*cs)
2424
return &cm

‎symbol/file_scope.go

+33
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,36 @@ func (fs *FileScope) FindClass(name string) *Definition {
2525
}
2626
return nil
2727
}
28+
29+
// FindField searches through all of the classes in a file and determines if a
30+
// field exists
31+
func (cs *FileScope) FindField() Finder {
32+
cm := fileFieldFinder(*cs)
33+
return &cm
34+
}
35+
36+
type fileFieldFinder FileScope
37+
38+
func findFieldsInClass(class *ClassScope, criteria func(d *Definition) bool) []*Definition {
39+
defs := class.FindField().By(criteria)
40+
for _, subclass := range class.Subclasses {
41+
defs = append(defs, findFieldsInClass(subclass, criteria)...)
42+
}
43+
return defs
44+
}
45+
46+
func (ff *fileFieldFinder) By(criteria func(d *Definition) bool) []*Definition {
47+
return findFieldsInClass(ff.BaseClass, criteria)
48+
}
49+
50+
func (ff *fileFieldFinder) ByName(name string) []*Definition {
51+
return ff.By(func(d *Definition) bool {
52+
return d.Name == name
53+
})
54+
}
55+
56+
func (ff *fileFieldFinder) ByOriginalName(originalName string) []*Definition {
57+
return ff.By(func(d *Definition) bool {
58+
return d.OriginalName == originalName
59+
})
60+
}

‎tree_sitter.go

+6-23
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"go/ast"
66

7+
"github.com/NickyBoy89/java2go/astutil"
78
"github.com/NickyBoy89/java2go/nodeutil"
89
"github.com/NickyBoy89/java2go/symbol"
910
log "github.com/sirupsen/logrus"
@@ -242,37 +243,19 @@ func ParseNode(node *sitter.Node, source []byte, ctx Ctx) interface{} {
242243
}
243244
return &ast.Field{
244245
Names: []*ast.Ident{ParseExpr(node.ChildByFieldName("name"), source, ctx).(*ast.Ident)},
245-
Type: ParseExpr(node.ChildByFieldName("type"), source, ctx),
246+
Type: astutil.ParseType(node.ChildByFieldName("type"), source),
246247
}
247248
case "spread_parameter":
248249
// The spread paramater takes a list and separates it into multiple elements
249250
// Ex: addElements([]int elements...)
250251

251-
switch ParseExpr(node.NamedChild(0), source, ctx).(type) {
252-
case *ast.StarExpr:
253-
// If the parameter is a reference type (ex: ...[]*Test), then the type is
254-
// a `StarExpr`, which is passed into the ellipsis
255-
return &ast.Field{
256-
Names: []*ast.Ident{ParseExpr(node.NamedChild(1).NamedChild(0), source, ctx).(*ast.Ident)},
257-
Type: &ast.Ellipsis{
258-
Elt: ParseExpr(node.NamedChild(0), source, ctx),
259-
},
260-
}
261-
case *ast.ArrayType:
262-
// Represents something such as `byte[]... name`
263-
return &ast.Field{
264-
Names: []*ast.Ident{ParseExpr(node.NamedChild(1).NamedChild(0), source, ctx).(*ast.Ident)},
265-
Type: &ast.Ellipsis{
266-
Elt: ParseExpr(node.NamedChild(0), source, ctx),
267-
},
268-
}
269-
}
252+
spreadType := node.NamedChild(0)
253+
spreadDeclarator := node.NamedChild(1)
270254

271255
return &ast.Field{
272-
Names: []*ast.Ident{ParseExpr(node.NamedChild(0), source, ctx).(*ast.Ident)},
256+
Names: []*ast.Ident{ParseExpr(spreadDeclarator.ChildByFieldName("name"), source, ctx).(*ast.Ident)},
273257
Type: &ast.Ellipsis{
274-
// This comes as a variable declarator, but we only need need the identifier for the type
275-
Elt: ParseExpr(node.NamedChild(1).NamedChild(0), source, ctx),
258+
Elt: astutil.ParseType(spreadType, source),
276259
},
277260
}
278261
case "inferred_parameters":

0 commit comments

Comments
 (0)
Please sign in to comment.