Skip to content

Commit 308ca88

Browse files
committed
Work on successfully parsing more parts of classes and static blocks
1 parent 379ad37 commit 308ca88

6 files changed

Lines changed: 93 additions & 33 deletions

File tree

codeparser/parselines.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
)
88

99
func ParseLine(source string) LineTyper {
10+
source = strings.Trim(source, " \n")
1011
currentWords := []LineType{}
1112

1213
lastLine, ci := 0, 0
@@ -43,8 +44,11 @@ func ParseLine(source string) LineTyper {
4344
},
4445
}
4546
default:
46-
currentWords = append(currentWords, ParseExpression(strings.Trim(source[lastLine:ci], " "))[0])
47-
lastLine = ci + 1
47+
curWord := ParseExpression(strings.Trim(source[lastLine:ci], " "))
48+
if len(curWord) > 0 {
49+
currentWords = append(currentWords, curWord[0])
50+
lastLine = ci + 1
51+
}
4852
}
4953
case '(':
5054
closingParenths := parsetools.IndexOfMatchingParenths(source, ci)
@@ -80,6 +84,10 @@ func ParseLine(source string) LineTyper {
8084
}
8185
return ParseControlFlow("if", source[ci + 1:closingParenths], source[startingBrace + 1:closingBrace])
8286
case "while":
87+
// If the while is part of a do-while loop, then there won't be a closing brace
88+
if closingBrace == -1 {
89+
return ParseControlFlow("doWhileCondition", source[ci + 1:closingParenths], "")
90+
}
8391
return ParseControlFlow("while", source[ci + 1:closingParenths], source[startingBrace + 1:closingBrace])
8492
case "catch":
8593
return ParseControlFlow("catch", source[ci + 1:closingParenths], "")
@@ -356,9 +364,7 @@ func ParseControlFlow(controlBlockname, parameters, source string) LineBlock {
356364
case "do-while":
357365
return LineBlock{
358366
Name: "DoWhileStatement",
359-
Words: map[string]interface{}{
360-
"Statement": ParseExpression(parameters),
361-
},
367+
Words: make(map[string]interface{}),
362368
Lines: ParseContent(strings.Trim(source, " \n")),
363369
}
364370
case "synchronized":
@@ -386,6 +392,13 @@ func ParseControlFlow(controlBlockname, parameters, source string) LineBlock {
386392
Name: "FinallyBlock",
387393
Words: make(map[string]interface{}),
388394
Lines: ParseContent(strings.Trim(source, " \n")),
395+
}
396+
case "doWhileCondition":
397+
return LineBlock{
398+
Name: "DoWhileCondition",
399+
Words: map[string]interface{}{
400+
"Condition": ParseExpression(parameters),
401+
},
389402
}
390403
default:
391404
panic("Unknown control flow [" + controlBlockname + "]")

goparser/goparser.go

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,27 @@ const indentNum = 2
1515
// A list of in-scope variables, for type-checking reasons
1616
var inScopeVariables = make(map[string]string)
1717

18+
// For do-while loops, where the location of the "while" condition occurs after the "do" block
19+
var lastWhileCondition codeparser.LineTyper
20+
1821
func ClearInScopeVariables() {
1922
inScopeVariables = make(map[string]string)
2023
}
2124

2225
// NewClass is set to true if the class is a nested class
23-
func ParseFile(sourceFile parsing.ParsedClasses, newClass bool) string {
26+
func ParseFile(sourceFile parsing.ParsedClasses, newClass bool, filename string) string {
2427
var generated string
2528
if newClass {
26-
generated += fmt.Sprintf("package main\n\n")
29+
generated += fmt.Sprintf("package %s\n\n", filename)
2730
generated += "func NewAssertionError(err string) error {\n return errors.New(err)\n}\n\n"
2831
}
29-
fmt.Printf("Generated %s\n", sourceFile.GetType())
3032
switch sourceFile.GetType() {
3133
case "class":
32-
generated += ParseClass(sourceFile.(parsing.ParsedClass)) // Parse the class into one struct
34+
generated += ParseClass(sourceFile.(parsing.ParsedClass), filename) // Parse the class into one struct
3335
case "interface":
34-
generated += ParseInterface(sourceFile.(parsing.ParsedInterface))
36+
generated += ParseInterface(sourceFile.(parsing.ParsedInterface), filename)
3537
case "enum":
36-
generated += ParseEnum(sourceFile.(parsing.ParsedEnum))
38+
generated += ParseEnum(sourceFile.(parsing.ParsedEnum), filename)
3739
default:
3840
panic("Unknown class type: " + sourceFile.GetType())
3941
}
@@ -47,7 +49,7 @@ func ParseFile(sourceFile parsing.ParsedClasses, newClass bool) string {
4749
}
4850

4951
// Parse a given class
50-
func ParseClass(source parsing.ParsedClass) string {
52+
func ParseClass(source parsing.ParsedClass, filename string) string {
5153
var generated string
5254

5355
// Create a context for the class, so that the methods have some frame of reference
@@ -66,6 +68,19 @@ func ParseClass(source parsing.ParsedClass) string {
6668
// classContext.Name = ToPrivate(source.Name)
6769
// }
6870

71+
72+
// Add the implements as a comment
73+
generated += fmt.Sprintf("//%v\n", source.Implements)
74+
75+
// Add the extends as a comment
76+
generated += fmt.Sprintf("//%v\n", source.Extends)
77+
78+
// If the class has any static blocks, then generated them
79+
for _, staticBlock := range source.StaticBlocks {
80+
generated += CreateStaticBlock(staticBlock, classContext, 0)
81+
generated += "\n\n"
82+
}
83+
6984
// Parse the class itself as a struct
7085
// If the class is static, don't generate a struct for it
7186
if !parsetools.Contains("static", source.Modifiers) {
@@ -82,13 +97,13 @@ func ParseClass(source parsing.ParsedClass) string {
8297

8398
// Parse the nested classes
8499
for _, nested := range source.NestedClasses {
85-
generated += ParseFile(nested, false)
100+
generated += ParseFile(nested, false, filename)
86101
}
87102

88103
return generated
89104
}
90105

91-
func ParseEnum(source parsing.ParsedEnum) string {
106+
func ParseEnum(source parsing.ParsedEnum, filename string) string {
92107
var generated string
93108

94109
classContext := new(ClassContext)
@@ -103,6 +118,15 @@ func ParseEnum(source parsing.ParsedEnum) string {
103118
parsedEnums = append(parsedEnums, CreateEnumField(field, classContext))
104119
}
105120

121+
// Add the implements as a comment
122+
generated += fmt.Sprintf("//%v\n", source.Implements)
123+
124+
// If the class has any static blocks, then generated them
125+
for _, staticBlock := range source.StaticBlocks {
126+
generated += CreateStaticBlock(staticBlock, classContext, 0)
127+
generated += "\n\n"
128+
}
129+
106130
if !parsetools.Contains("static", source.Modifiers) {
107131
generated += CreateStruct(classContext, source.ClassVariables)
108132
}
@@ -147,10 +171,15 @@ func ParseEnum(source parsing.ParsedEnum) string {
147171
generated += "\n\n" // Add some spacing in between the methods
148172
}
149173

174+
// Parse the nested classes
175+
for _, nested := range source.NestedClasses {
176+
generated += ParseFile(nested, false, filename)
177+
}
178+
150179
return generated
151180
}
152181

153-
func ParseInterface(source parsing.ParsedInterface) string {
182+
func ParseInterface(source parsing.ParsedInterface, filename string) string {
154183
var generated string
155184

156185
// Create a context for the class, so that the methods have some frame of reference
@@ -175,7 +204,7 @@ func ParseInterface(source parsing.ParsedInterface) string {
175204

176205
// Parse the nested classes
177206
for _, nested := range source.NestedClasses {
178-
generated += ParseFile(nested, false)
207+
generated += ParseFile(nested, false, filename)
179208
}
180209

181210
return generated
@@ -301,6 +330,13 @@ func CreateMethod(classContext *ClassContext, methodSource parsing.ParsedMethod)
301330
return result
302331
}
303332

333+
func CreateStaticBlock(lines []codeparser.LineTyper, classContext *ClassContext, indentation int) string {
334+
block := fmt.Sprintf("func init() {\n")
335+
block += CreateBody(lines, classContext, indentation + 2)
336+
block += fmt.Sprintf("\n%s}", strings.Repeat(" ", indentation))
337+
return block
338+
}
339+
304340
// Parses the lines of the body
305341
func CreateBody(body []codeparser.LineTyper, classContext *ClassContext, indentation int) string {
306342
var result string
@@ -556,17 +592,15 @@ func CreateLine(line codeparser.LineTyper, classContext *ClassContext, indentati
556592
CreateBody(line.(codeparser.LineBlock).Lines, classContext, indentation + 2),
557593
strings.Repeat(" ", indentation),
558594
)
595+
case "DoWhileCondition": // The while condition for a do-while, comes after the do block
596+
lastWhileCondition = line // Global
559597
case "DoWhileStatement":
560-
var body string
561-
for _, line := range line.(codeparser.LineBlock).Words["Statement"].([]codeparser.LineType) {
562-
body += CreateLine(line, classContext, 0, false) + " "
563-
}
564598
result += strings.Repeat(" ", indentation) + fmt.Sprintf(
565599
"for {%s\n%s\n%sif %s {\nbreak\n%s}}",
566600
CreateBody(line.(codeparser.LineBlock).Lines, classContext, indentation + 2),
567601
strings.Repeat(" ", indentation),
568602
strings.Repeat(" ", indentation),
569-
body,
603+
lastWhileCondition,
570604
strings.Repeat(" ", indentation),
571605
)
572606
case "TypeAssertion":

java2go.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func main() {
5252
if err != nil {
5353
log.Fatal(err)
5454
}
55-
generated := goparser.ParseFile(parsing.ParseFile(string(jsonFile)), true)
55+
generated := goparser.ParseFile(parsing.ParseFile(string(jsonFile)), true, "main")
5656
fmt.Println(generated)
5757

5858
formatted, err := json.MarshalIndent(parsing.ParseFile(string(jsonFile)), "", " ")
@@ -112,8 +112,12 @@ func ParseFile(path string, verbose, writeFlag, skipImports *bool, outputDir *st
112112
return err
113113
}
114114

115-
// Gets the directory of the current file by stripping out the filename from the filepath
116-
fileDirectory := path[:strings.LastIndex(path, "/")]
115+
// Gets the current path of directories to the file
116+
lastSlashInd := strings.LastIndex(path, "/")
117+
filePath := path[:lastSlashInd]
118+
119+
// Gets the current relative directory that the file is in
120+
fileDirectory := path[strings.LastIndex(path[:lastSlashInd], "/") + 1:lastSlashInd]
117121

118122
// If writing is enabled through the -w tag
119123
if *writeFlag {
@@ -122,14 +126,14 @@ func ParseFile(path string, verbose, writeFlag, skipImports *bool, outputDir *st
122126
// Add a slash to the output directory to make it a valid directory
123127
*outputDir = *outputDir + "/"
124128
// If a folder does not exist for the output files, then create one
125-
if _, err := os.Stat(*outputDir + fileDirectory); os.IsNotExist(err) {
126-
os.MkdirAll(*outputDir + fileDirectory, 0775)
129+
if _, err := os.Stat(*outputDir + filePath); os.IsNotExist(err) {
130+
os.MkdirAll(*outputDir + filePath, 0775)
127131
}
128132
}
129133

130134
ioutil.WriteFile(
131135
*outputDir + ChangeFileExtension(path, ".go"), // Change the output file to .go
132-
[]byte(goparser.ParseFile(parsing.ParseFile(string(contents)), true)), // Parse the contents of the file
136+
[]byte(goparser.ParseFile(parsing.ParseFile(string(contents)), true, fileDirectory)), // Parse the contents of the file
133137
0775,
134138
)
135139

parsing/datatypes.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ type ParsedClass struct {
2424
ClassVariables []ParsedVariable
2525
Methods []ParsedMethod
2626
NestedClasses []ParsedClasses
27-
StaticBlocks []string
27+
StaticBlocks [][]codeparser.LineTyper
2828
}
2929

3030
func (c ParsedClass) GetType() string {
@@ -88,7 +88,7 @@ type ParsedEnum struct {
8888
Methods []ParsedMethod
8989
EnumFields []EnumField
9090
NestedClasses []ParsedClasses
91-
StaticBlocks []string
91+
StaticBlocks [][]codeparser.LineTyper
9292
}
9393

9494
func (e ParsedEnum) GetType() string {
@@ -101,6 +101,7 @@ func (e ParsedEnum) MethodContext() map[string][]string {
101101
for _, method := range e.Methods {
102102
methods[method.Name] = method.ParameterTypes()
103103
}
104+
104105
// Get the names of all the methods in the nested classes
105106
for _, nested := range e.NestedClasses {
106107
for nestedMethodName, nestedMethodParams := range nested.MethodContext() {

parsing/parseclass.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"strings"
55

66
"gitlab.nicholasnovak.io/snapdragon/java2go/parsetools"
7+
"gitlab.nicholasnovak.io/snapdragon/java2go/codeparser"
78
)
89

910
func ParseClass(sourceString string) ParsedClass {
@@ -39,7 +40,7 @@ func ParseClass(sourceString string) ParsedClass {
3940
result.Modifiers = words[:len(words) - 2]
4041
result.ClassVariables = []ParsedVariable{}
4142
result.NestedClasses = []ParsedClasses{}
42-
result.StaticBlocks = []string{}
43+
result.StaticBlocks = [][]codeparser.LineTyper{}
4344

4445
classBody := sourceString[bodyDivider + 1:parsetools.IndexOfMatchingBrace(sourceString, bodyDivider)]
4546

@@ -81,7 +82,10 @@ func ParseClass(sourceString string) ParsedClass {
8182
lastInterest = ci + 1
8283
} else if char == '{' {
8384
if strings.Trim(classBody[lastInterest:ci], " \n") == "static" { // Handle static block
84-
result.StaticBlocks = append(result.StaticBlocks, strings.Trim(classBody[strings.IndexRune(classBody[lastInterest:], '{') + lastInterest + 1:parsetools.IndexOfMatchingBrace(classBody, ci)], " \n"))
85+
result.StaticBlocks = append(
86+
result.StaticBlocks,
87+
codeparser.ParseContent(parsetools.RemoveIndentation(strings.Trim(classBody[strings.IndexRune(classBody[lastInterest:], '{') + lastInterest + 1:parsetools.IndexOfMatchingBrace(classBody, ci)], " \n"))),
88+
)
8589
ci = parsetools.IndexOfMatchingBrace(classBody, ci) + 1// Cut out the remaining brace
8690
lastInterest = ci
8791
} else if strings.Contains(classBody[lastInterest:ci], "class") { // Nested class

parsing/parseenum.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ package parsing
22

33
import (
44
"strings"
5-
// "fmt"
65

6+
"gitlab.nicholasnovak.io/snapdragon/java2go/codeparser"
77
"gitlab.nicholasnovak.io/snapdragon/java2go/parsetools"
88
)
99

@@ -44,6 +44,7 @@ func ParseEnum(sourceString string) ParsedEnum {
4444
result.Modifiers = words[:len(words) - 2]
4545
result.ClassVariables = []ParsedVariable{}
4646
result.NestedClasses = []ParsedClasses{}
47+
result.StaticBlocks = [][]codeparser.LineTyper{}
4748

4849
classBody := sourceString[bodyDivider + 1:parsetools.IndexOfMatchingBrace(sourceString, bodyDivider)]
4950

@@ -104,7 +105,10 @@ func ParseEnum(sourceString string) ParsedEnum {
104105
lastInterest = ci
105106
} else if char == '{' {
106107
if strings.Trim(classBody[lastInterest:ci], " \n") == "static" { // Handle static block
107-
result.StaticBlocks = append(result.StaticBlocks, strings.Trim(classBody[strings.IndexRune(classBody[lastInterest:], '{') + lastInterest + 1:parsetools.IndexOfMatchingBrace(classBody, ci)], " \n"))
108+
result.StaticBlocks = append(
109+
result.StaticBlocks,
110+
codeparser.ParseContent(strings.Trim(classBody[strings.IndexRune(classBody[lastInterest:], '{') + lastInterest + 1:parsetools.IndexOfMatchingBrace(classBody, ci)], " \n")),
111+
)
108112
ci = parsetools.IndexOfMatchingBrace(classBody, ci) + 1// Cut out the remaining brace
109113
lastInterest = ci
110114
} else if strings.Contains(classBody[lastInterest:ci], "class") { // Nested class

0 commit comments

Comments
 (0)