From 159eea1f3a6334b36f24103ba7489ec5e09afd87 Mon Sep 17 00:00:00 2001 From: Shivasurya Date: Tue, 23 Apr 2024 23:49:19 -0400 Subject: [PATCH] Added method arguments type and argument value - Added support for filtering based on argument type and argument value --- sourcecode-parser/construct.go | 52 ++++++++++++++----------- sourcecode-parser/queryparser/parser.go | 4 +- sourcecode-parser/source_sink.go | 27 ++++++++++--- 3 files changed, 54 insertions(+), 29 deletions(-) diff --git a/sourcecode-parser/construct.go b/sourcecode-parser/construct.go index b4253ec..6cd7794 100644 --- a/sourcecode-parser/construct.go +++ b/sourcecode-parser/construct.go @@ -16,16 +16,17 @@ import ( ) type GraphNode struct { - ID string - Type string - Name string - CodeSnippet string - LineNumber uint32 - OutgoingEdges []*GraphEdge - IsExternal bool - Modifier string - ReturnType string - MethodArguments []string + ID string + Type string + Name string + CodeSnippet string + LineNumber uint32 + OutgoingEdges []*GraphEdge + IsExternal bool + Modifier string + ReturnType string + MethodArgumentsType []string + MethodArgumentsValue []string } type GraphEdge struct { @@ -88,33 +89,40 @@ func buildGraphFromAST(node *sitter.Node, sourceCode []byte, graph *CodeGraph, c methodName, methodId := extractMethodName(node, sourceCode, packageName, className) invokedNode, exists := graph.Nodes[methodId] modifiers := "" - ReturnType := "" - MethodArguments := []string{} + returnType := "" + methodArgumentType := []string{} + methodArgumentValue := []string{} + for i := 0; i < int(node.ChildCount()); i++ { if node.Child(i).Type() == "modifiers" { modifiers = node.Child(i).Content(sourceCode) } else if node.Child(i).Type() == "void_type" || node.Child(i).Type() == "type_identifier" { // get return type of method - ReturnType = node.Child(i).Content(sourceCode) + returnType = node.Child(i).Content(sourceCode) } else if node.Child(i).Type() == "formal_parameters" { // get method arguments for j := 0; j < int(node.Child(i).NamedChildCount()); j++ { param := node.Child(i).NamedChild(j) - MethodArguments = append(MethodArguments, param.Content(sourceCode)) + // get type of argument and add to method arguments + paramType := param.Child(0).Content(sourceCode) + paramValue := param.Child(1).Content(sourceCode) + methodArgumentType = append(methodArgumentType, paramType) + methodArgumentValue = append(methodArgumentValue, paramValue) } } } if !exists || (exists && invokedNode.ID != methodId) { invokedNode = &GraphNode{ - ID: methodId, // In a real scenario, you would construct a unique ID, possibly using the method signature - Type: "method_declaration", - Name: methodName, - CodeSnippet: string(node.Content(sourceCode)), - LineNumber: node.StartPoint().Row + 1, // Lines start from 0 in the AST - Modifier: extractVisibilityModifier(modifiers), - ReturnType: ReturnType, - MethodArguments: MethodArguments, + ID: methodId, // In a real scenario, you would construct a unique ID, possibly using the method signature + Type: "method_declaration", + Name: methodName, + CodeSnippet: string(node.Content(sourceCode)), + LineNumber: node.StartPoint().Row + 1, // Lines start from 0 in the AST + Modifier: extractVisibilityModifier(modifiers), + ReturnType: returnType, + MethodArgumentsType: methodArgumentType, + MethodArgumentsValue: methodArgumentValue, // CodeSnippet and LineNumber are skipped as per the requirement } } diff --git a/sourcecode-parser/queryparser/parser.go b/sourcecode-parser/queryparser/parser.go index 2fbab40..4470fbb 100644 --- a/sourcecode-parser/queryparser/parser.go +++ b/sourcecode-parser/queryparser/parser.go @@ -106,7 +106,7 @@ func (p *Parser) parseCondition() *Condition { } type EvalContext interface { - GetValue(key string) string // Retrieves a value based on a key, which helps in condition evaluation. + GetValue(key string, val string) string // Retrieves a value based on a key, which helps in condition evaluation. } type Expr interface { @@ -167,7 +167,7 @@ func (b *BinaryExpr) Evaluate(ctx EvalContext) bool { } func (c *Condition) Evaluate(ctx EvalContext) bool { - fieldValue := ctx.GetValue(c.Field) + fieldValue := ctx.GetValue(c.Field, c.Value) switch c.Operator { case "=": return fieldValue == c.Value diff --git a/sourcecode-parser/source_sink.go b/sourcecode-parser/source_sink.go index bece90b..2e95dbc 100644 --- a/sourcecode-parser/source_sink.go +++ b/sourcecode-parser/source_sink.go @@ -12,9 +12,11 @@ type SourceSinkPath struct { } var MethodAttribute = map[string]int{ - "name": 0, - "visibility": 1, - "returntype": 2, + "name": 0, + "visibility": 1, + "returntype": 2, + "argumentype": 3, + "argumentname": 4, // Add more attributes as needed } @@ -82,7 +84,7 @@ type GraphNodeContext struct { } // GetValue returns the value of a field in a GraphNode based on the key. -func (gnc *GraphNodeContext) GetValue(key string) string { +func (gnc *GraphNodeContext) GetValue(key string, val string) string { switch key { case "visibility": return gnc.Node.Modifier @@ -90,7 +92,22 @@ func (gnc *GraphNodeContext) GetValue(key string) string { return gnc.Node.ReturnType case "name": return gnc.Node.Name - // add other cases as necessary for your application + case "argumentype": + // check value in MethodArgumentsType array + for i, arg := range gnc.Node.MethodArgumentsType { + if arg == val { + return gnc.Node.MethodArgumentsType[i] + } + } + return "" + case "argumentname": + // check value in MethodArgumentsValue array + for i, arg := range gnc.Node.MethodArgumentsValue { + if arg == val { + return gnc.Node.MethodArgumentsValue[i] + } + } + return "" default: fmt.Printf("Unsupported attribute key: %s\n", key) return ""