Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion sourcecode-parser/graph/construct.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ type Node struct {
DoStmt *model.DoStmt
ForStmt *model.ForStmt
BreakStmt *model.BreakStmt
}
ContinueStmt *model.ContinueStmt
} //

type Edge struct {
From *Node
Expand Down Expand Up @@ -194,6 +195,21 @@ func buildGraphFromAST(node *sitter.Node, sourceCode []byte, graph *CodeGraph, c
BreakStmt: breakNode,
}
graph.AddNode(breakStmtNode)
case "continue_statement":
continueNode := javalang.ParseContinueStatement(node, sourceCode)
uniquecontinueID := fmt.Sprintf("continuestmt_%d_%d_%s", node.StartPoint().Row+1, node.StartPoint().Column+1, file)
continueStmtNode := &Node{
ID: GenerateSha256(uniquecontinueID),
Type: "ContinueStmt",
LineNumber: node.StartPoint().Row + 1,
Name: "ContinueStmt",
IsExternal: true,
CodeSnippet: node.Content(sourceCode),
File: file,
isJavaSourceFile: isJavaSourceFile,
ContinueStmt: continueNode,
}
graph.AddNode(continueStmtNode)
case "if_statement":
ifNode := model.IfStmt{}
// get the condition of the if statement
Expand Down
6 changes: 4 additions & 2 deletions sourcecode-parser/graph/construct_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,8 @@ func TestBuildGraphFromAST(t *testing.T) {
a--;
if (a == 0) {
break outerlabel;
} else {
continue outerlabel;
}
}
for (int i = 0; i < 10; i++) {
Expand All @@ -776,9 +778,9 @@ func TestBuildGraphFromAST(t *testing.T) {
}
}
`,
expectedNodes: 68,
expectedNodes: 69,
expectedEdges: 4,
expectedTypes: []string{"class_declaration", "method_declaration", "binary_expression", "comp_expression", "and_expression", "or_expression", "IfStmt", "ForStmt", "WhileStmt", "DoStmt", "BreakStmt"},
expectedTypes: []string{"class_declaration", "method_declaration", "binary_expression", "comp_expression", "and_expression", "or_expression", "IfStmt", "ForStmt", "WhileStmt", "DoStmt", "BreakStmt", "ContinueStmt"},
unexpectedTypes: []string{""},
},
{
Expand Down
11 changes: 11 additions & 0 deletions sourcecode-parser/graph/java/parse_statement.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,14 @@ func ParseBreakStatement(node *sitter.Node, sourcecode []byte) *model.BreakStmt
}
return breakStmt
}

func ParseContinueStatement(node *sitter.Node, sourcecode []byte) *model.ContinueStmt {
continueStmt := &model.ContinueStmt{}
// get identifier if present child
for i := 0; i < int(node.ChildCount()); i++ {
if node.Child(i).Type() == "identifier" {
continueStmt.Label = node.Child(i).Content(sourcecode)
}
}
return continueStmt
}
41 changes: 41 additions & 0 deletions sourcecode-parser/graph/java/parse_statement_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,44 @@ func TestParseBreakStatement(t *testing.T) {
})
}
}

func TestParseContinueStatement(t *testing.T) {
tests := []struct {
name string
input string
expected *model.ContinueStmt
}{
{
name: "Simple continue statement without label",
input: "continue;",
expected: &model.ContinueStmt{Label: ""},
},
{
name: "Continue statement with label",
input: "continue outerLoop;",
expected: &model.ContinueStmt{Label: "outerLoop"},
},
{
name: "Continue statement with complex label",
input: "continue COMPLEX_LABEL_123;",
expected: &model.ContinueStmt{Label: "COMPLEX_LABEL_123"},
},
{
name: "Continue statement with underscore label",
input: "continue outer_loop_label;",
expected: &model.ContinueStmt{Label: "outer_loop_label"},
},
}

parser := sitter.NewParser()
parser.SetLanguage(java.GetLanguage())

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tree := parser.Parse(nil, []byte(tt.input))
node := tree.RootNode().Child(0)
result := ParseContinueStatement(node, []byte(tt.input))
assert.Equal(t, tt.expected, result)
})
}
}
11 changes: 11 additions & 0 deletions sourcecode-parser/graph/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ func (env *Env) GetBreakStmt() *model.BreakStmt {
return env.Node.BreakStmt
}

func (env *Env) GetContinueStmt() *model.ContinueStmt {
return env.Node.ContinueStmt
}

func QueryEntities(graph *CodeGraph, query parser.Query) (nodes [][]*Node, output [][]interface{}) {
result := make([][]*Node, 0)

Expand Down Expand Up @@ -315,6 +319,7 @@ func generateProxyEnv(node *Node, query parser.Query) map[string]interface{} {
doStmt := "DoStmt"
forStmt := "ForStmt"
breakStmt := "BreakStmt"
continueStmt := "ContinueStmt"

// print query select list
for _, entity := range query.SelectList {
Expand Down Expand Up @@ -373,6 +378,8 @@ func generateProxyEnv(node *Node, query parser.Query) map[string]interface{} {
forStmt = entity.Alias
case "BreakStmt":
breakStmt = entity.Alias
case "ContinueStmt":
continueStmt = entity.Alias
}
}
env := map[string]interface{}{
Expand Down Expand Up @@ -523,6 +530,10 @@ func generateProxyEnv(node *Node, query parser.Query) map[string]interface{} {
"toString": proxyenv.ToString,
"getBreakStmt": proxyenv.GetBreakStmt,
},
continueStmt: map[string]interface{}{
"toString": proxyenv.ToString,
"getContinueStmt": proxyenv.GetContinueStmt,
},
}
return env
}
Expand Down
39 changes: 39 additions & 0 deletions sourcecode-parser/model/stmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,42 @@ func (breakStmt *BreakStmt) hasLabel() bool {
func (breakStmt *BreakStmt) GetLabel() string {
return breakStmt.Label
}

type IContinueStmt interface {
GetAPrimaryQlClass() string
GetHalsteadID() int
GetLabel() string
hasLabel() bool
GetPP() string
ToString() string
}

type ContinueStmt struct {
JumpStmt
Label string
}

func (continueStmt *ContinueStmt) GetAPrimaryQlClass() string {
return "ContinueStmt"
}

func (continueStmt *ContinueStmt) GetHalsteadID() int {
// TODO: Implement Halstead ID calculation for ContinueStmt
return 0
}

func (continueStmt *ContinueStmt) GetPP() string {
return fmt.Sprintf("continue (%s)", continueStmt.Label)
}

func (continueStmt *ContinueStmt) ToString() string {
return fmt.Sprintf("continue (%s)", continueStmt.Label)
}

func (continueStmt *ContinueStmt) hasLabel() bool {
return continueStmt.Label != ""
}

func (continueStmt *ContinueStmt) GetLabel() string {
return continueStmt.Label
}
72 changes: 72 additions & 0 deletions sourcecode-parser/model/stmt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,75 @@ func TestIfStmt(t *testing.T) {
assert.Equal(t, expected, ifStmt.ToString())
})
}

func TestContinueStmt(t *testing.T) {
t.Run("GetAPrimaryQlClass", func(t *testing.T) {
continueStmt := &ContinueStmt{}
assert.Equal(t, "ContinueStmt", continueStmt.GetAPrimaryQlClass())
})

t.Run("GetHalsteadID", func(t *testing.T) {
continueStmt := &ContinueStmt{}
assert.Equal(t, 0, continueStmt.GetHalsteadID())
})

t.Run("GetPP with label", func(t *testing.T) {
continueStmt := &ContinueStmt{
Label: "outerLoop",
}
expected := "continue (outerLoop)"
assert.Equal(t, expected, continueStmt.GetPP())
})

t.Run("GetPP without label", func(t *testing.T) {
continueStmt := &ContinueStmt{
Label: "",
}
expected := "continue ()"
assert.Equal(t, expected, continueStmt.GetPP())
})

t.Run("ToString with label", func(t *testing.T) {
continueStmt := &ContinueStmt{
Label: "innerLoop",
}
expected := "continue (innerLoop)"
assert.Equal(t, expected, continueStmt.ToString())
})

t.Run("ToString without label", func(t *testing.T) {
continueStmt := &ContinueStmt{
Label: "",
}
expected := "continue ()"
assert.Equal(t, expected, continueStmt.ToString())
})

t.Run("hasLabel with label", func(t *testing.T) {
continueStmt := &ContinueStmt{
Label: "loop1",
}
assert.True(t, continueStmt.hasLabel())
})

t.Run("hasLabel without label", func(t *testing.T) {
continueStmt := &ContinueStmt{
Label: "",
}
assert.False(t, continueStmt.hasLabel())
})

t.Run("GetLabel with label", func(t *testing.T) {
continueStmt := &ContinueStmt{
Label: "loop2",
}
assert.Equal(t, "loop2", continueStmt.GetLabel())
})

t.Run("GetLabel without label", func(t *testing.T) {
continueStmt := &ContinueStmt{
Label: "",
}
assert.Equal(t, "", continueStmt.GetLabel())
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ protected void onCreate(Bundle savedInstanceState) {
if (savedInstanceState == null) {

movieDetailFragment fragment = new movieDetailFragment();
break outlabel;
continue outlabel;
fragment.setMovieData(moviegeneralModal);
getSupportFragmentManager().beginTransaction()
.add(R.id.movie_detail_container, fragment)
Expand Down