Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: 🍺 Support for BreakStmt #174

Merged
merged 2 commits into from
Nov 4, 2024
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: 18 additions & 0 deletions sourcecode-parser/graph/construct.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"sync"
"time"

javalang "github.com/shivasurya/code-pathfinder/sourcecode-parser/graph/java"

"github.com/shivasurya/code-pathfinder/sourcecode-parser/model"
"github.com/smacker/go-tree-sitter/java"

Expand Down Expand Up @@ -48,6 +50,7 @@ type Node struct {
WhileStmt *model.WhileStmt
DoStmt *model.DoStmt
ForStmt *model.ForStmt
BreakStmt *model.BreakStmt
}

type Edge struct {
Expand Down Expand Up @@ -176,6 +179,21 @@ func parseJavadocTags(commentContent string) *model.Javadoc {
func buildGraphFromAST(node *sitter.Node, sourceCode []byte, graph *CodeGraph, currentContext *Node, file string) {
isJavaSourceFile := isJavaSourceFile(file)
switch node.Type() {
case "break_statement":
breakNode := javalang.ParseBreakStatement(node, sourceCode)
uniquebreakstmtID := fmt.Sprintf("breakstmt_%d_%d_%s", node.StartPoint().Row+1, node.StartPoint().Column+1, file)
breakStmtNode := &Node{
ID: GenerateSha256(uniquebreakstmtID),
Type: "BreakStmt",
LineNumber: node.StartPoint().Row + 1,
Name: "BreakStmt",
IsExternal: true,
CodeSnippet: node.Content(sourceCode),
File: file,
isJavaSourceFile: isJavaSourceFile,
BreakStmt: breakNode,
}
graph.AddNode(breakStmtNode)
case "if_statement":
ifNode := model.IfStmt{}
// get the condition of the if statement
Expand Down
9 changes: 7 additions & 2 deletions sourcecode-parser/graph/construct_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -753,11 +753,16 @@ func TestBuildGraphFromAST(t *testing.T) {
int i = 1 | 1;
int j = 1 ^ 1;
int l = 1 >>> 1;
outerlabel:
while (a > 0) {
a--;
if (a == 0) {
break outerlabel;
}
}
for (int i = 0; i < 10; i++) {
System.out.println(i);
break;
}
do {
System.out.println("Hello, World!");
Expand All @@ -771,9 +776,9 @@ func TestBuildGraphFromAST(t *testing.T) {
}
}
`,
expectedNodes: 63,
expectedNodes: 68,
expectedEdges: 4,
expectedTypes: []string{"class_declaration", "method_declaration", "binary_expression", "comp_expression", "and_expression", "or_expression", "IfStmt", "ForStmt", "WhileStmt", "DoStmt"},
expectedTypes: []string{"class_declaration", "method_declaration", "binary_expression", "comp_expression", "and_expression", "or_expression", "IfStmt", "ForStmt", "WhileStmt", "DoStmt", "BreakStmt"},
unexpectedTypes: []string{""},
},
{
Expand Down
17 changes: 17 additions & 0 deletions sourcecode-parser/graph/java/parse_statement.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package java

import (
"github.com/shivasurya/code-pathfinder/sourcecode-parser/model"
sitter "github.com/smacker/go-tree-sitter"
)

func ParseBreakStatement(node *sitter.Node, sourcecode []byte) *model.BreakStmt {
breakStmt := &model.BreakStmt{}
// get identifier if present child
for i := 0; i < int(node.ChildCount()); i++ {
if node.Child(i).Type() == "identifier" {
breakStmt.Label = node.Child(i).Content(sourcecode)
}
}
return breakStmt
}
41 changes: 41 additions & 0 deletions sourcecode-parser/graph/java/parse_statement_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package java

import (
"github.com/smacker/go-tree-sitter/java"
"testing"

"github.com/shivasurya/code-pathfinder/sourcecode-parser/model"
sitter "github.com/smacker/go-tree-sitter"
"github.com/stretchr/testify/assert"
)

func TestParseBreakStatement(t *testing.T) {
tests := []struct {
name string
input string
expected *model.BreakStmt
}{
{
name: "Simple break statement without label",
input: "break;",
expected: &model.BreakStmt{Label: ""},
},
{
name: "Break statement with label",
input: "break myLabel;",
expected: &model.BreakStmt{Label: "myLabel"},
},
}

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 := ParseBreakStatement(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 @@ -135,6 +135,10 @@ func (env *Env) GetForStmt() *model.ForStmt {
return env.Node.ForStmt
}

func (env *Env) GetBreakStmt() *model.BreakStmt {
return env.Node.BreakStmt
}

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

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

// print query select list
for _, entity := range query.SelectList {
Expand Down Expand Up @@ -366,6 +371,8 @@ func generateProxyEnv(node *Node, query parser.Query) map[string]interface{} {
doStmt = entity.Alias
case "ForStmt":
forStmt = entity.Alias
case "BreakStmt":
breakStmt = entity.Alias
}
}
env := map[string]interface{}{
Expand Down Expand Up @@ -512,6 +519,10 @@ func generateProxyEnv(node *Node, query parser.Query) map[string]interface{} {
"getForStmt": proxyenv.GetForStmt,
"toString": proxyenv.ToString,
},
breakStmt: map[string]interface{}{
"toString": proxyenv.ToString,
"getBreakStmt": proxyenv.GetBreakStmt,
},
}
return env
}
Expand Down
61 changes: 61 additions & 0 deletions sourcecode-parser/model/stmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,64 @@ func (whileStmt *WhileStmt) GetPP() string {
func (whileStmt *WhileStmt) ToString() string {
return fmt.Sprintf("while (%s) %s", whileStmt.Condition.NodeString, whileStmt.Stmt.NodeString)
}

type ILabeledStmt interface {
GetAPrimaryQlClass() string
GetHalsteadID() int
GetLabel() *LabeledStmt
GetPP() string
ToString() string
}

type LabeledStmt struct {
Stmt
Label *LabeledStmt
}

type JumpStmt struct {
Stmt
}

type IJumpStmt interface {
GetTarget() *StmtParent
GetTargetLabel() *LabeledStmt
}

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

type BreakStmt struct {
JumpStmt
Label string
}

func (breakStmt *BreakStmt) GetAPrimaryQlClass() string {
return "BreakStmt"
}

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

func (breakStmt *BreakStmt) GetPP() string {
return fmt.Sprintf("break (%s)", breakStmt.Label)
}

func (breakStmt *BreakStmt) ToString() string {
return fmt.Sprintf("break (%s)", breakStmt.Label)
}

func (breakStmt *BreakStmt) hasLabel() bool {
return breakStmt.Label != ""
}

func (breakStmt *BreakStmt) GetLabel() string {
return breakStmt.Label
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,11 @@ protected void onCreate(Bundle savedInstanceState) {
ServerSocket serverSocket = new ServerSocket(80);

movieGeneralModal moviegeneralModal = (movieGeneralModal) intent.getSerializableExtra("DATA_MOVIE");

outlabel:
if (savedInstanceState == null) {

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