From 741635e1ab40c5d4aa38ccd75c56715301b2c247 Mon Sep 17 00:00:00 2001 From: Ameya Ketkar <94497232+ketkarameya@users.noreply.github.com> Date: Wed, 8 Nov 2023 22:02:48 -0800 Subject: [PATCH 1/2] Starter kit code for zap transformation --- plugins/zap-transformation/__main__.py | 88 +++++++++++++++++++ plugins/zap-transformation/resource/sample.go | 7 ++ 2 files changed, 95 insertions(+) create mode 100644 plugins/zap-transformation/__main__.py create mode 100644 plugins/zap-transformation/resource/sample.go diff --git a/plugins/zap-transformation/__main__.py b/plugins/zap-transformation/__main__.py new file mode 100644 index 000000000..fd083dc06 --- /dev/null +++ b/plugins/zap-transformation/__main__.py @@ -0,0 +1,88 @@ +import re +from polyglot_piranha import OutgoingEdges, Rule, RuleGraph, execute_piranha, PiranhaArguments + + +mapping = { + "Bool": ["true", "false"], + "Complex128": ["complex128(:[x])"], + "Float64": ["float64(:[x])"], +} + + +def convert_hole_style(s): + pattern = re.compile(r':\[(\w+)\]') + return pattern.sub(r'@\1', s) + + + +def get_simple_rule(mapping): + return [ + Rule( + f"simple_{api}_usage_{pattern}", # Create a unique name for the rule + query=f"cs logger.With(zap.Any(:[f], {pattern})).Info(:[i])", # The query to match + replace_node="*", + replace="logger.With(zap.{}(@f, {})).Info(@i)".format(api, convert_hole_style(pattern)), # The replacement (the replacement is a bit awkward because we need to convert the hole style) + holes = {"zap"} + ) + for api, patterns in mapping.items() + for pattern in patterns + ] + + +def get_complex_rule_graph(mapping): + + # Make a rule that matches the usage of zap.Any with a variable + usage_with_var = Rule( + f"usage_of_zap_any_with_var", + query=f"cs logger.With(zap.Any(:[f], &:[var_name])).Info(:[i])", + holes = {"zap"} + ) + rules =[usage_with_var] + edges = [] + for api, patterns in mapping.items(): + for pattern in patterns: + var_decl_pattern = Rule( + name=f"var_decl_{api}_usage_{pattern}", + query=f"cs :[var_name] = {pattern}", + holes = {"var_name"}, + is_seed_rule=False + ) + update_zap_usage = Rule( + name=f"update_zap_usage_{api}_usage_{pattern}", + query=f"cs logger.With(zap.Any(:[f], &:[var_name])).Info(:[i])", + replace_node="*", + replace=f"logger.With(zap.{api}(@f, &@var_name)).Info(@i)", + holes = {"var_name"}, + is_seed_rule=False + ) + edge1 = OutgoingEdges( + var_decl_pattern.name, + to = [ update_zap_usage.name ], + scope= "Function-Method" + ) + + edge2 = OutgoingEdges( + usage_with_var.name, + to = [ var_decl_pattern.name ], + scope= "Function-Method" + ) + rules.extend([var_decl_pattern, update_zap_usage]) + edges.extend([edge1, edge2]) + + return rules, edges + + +simple_rules = get_simple_rule(mapping) +complex_rules, edges = get_complex_rule_graph(mapping) + +rule_graph = RuleGraph(rules=simple_rules + complex_rules, edges=edges) +args = PiranhaArguments( + "go", + paths_to_codebase=["/Users/ketkara/repositories/open-source/piranha/plugins/zap-transformation/resource"], + substitutions={"zap": "zap"}, + rule_graph=rule_graph, +) + +summary = execute_piranha(args) + +print(summary) diff --git a/plugins/zap-transformation/resource/sample.go b/plugins/zap-transformation/resource/sample.go new file mode 100644 index 000000000..533948559 --- /dev/null +++ b/plugins/zap-transformation/resource/sample.go @@ -0,0 +1,7 @@ +func logTestMessage() { + + logger.With(zap.Any("field", complex128(0))).Info("test") + c1 = float64(0) + c = complex128(0) + logger.With(zap.Any("field", &c1)).Info("test") +} From aa6ff5d3cf1713a5a31673cef5f8ea01035f7ba9 Mon Sep 17 00:00:00 2001 From: Ameya Ketkar <94497232+ketkarameya@users.noreply.github.com> Date: Wed, 8 Nov 2023 22:09:40 -0800 Subject: [PATCH 2/2] . --- plugins/zap-transformation/__main__.py | 35 +++++++++++++++----------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/plugins/zap-transformation/__main__.py b/plugins/zap-transformation/__main__.py index fd083dc06..25d9a3908 100644 --- a/plugins/zap-transformation/__main__.py +++ b/plugins/zap-transformation/__main__.py @@ -14,7 +14,8 @@ def convert_hole_style(s): return pattern.sub(r'@\1', s) - +# This function creates a list of simple rules for the following scenario: +# - zap.Any is used with a pattern from the mapping def get_simple_rule(mapping): return [ Rule( @@ -28,10 +29,12 @@ def get_simple_rule(mapping): for pattern in patterns ] - -def get_complex_rule_graph(mapping): - - # Make a rule that matches the usage of zap.Any with a variable +# This function creates a rule graph for the following scenario: +# - zap.Any is used with a variable (e.g., zap.Any("key", &value)) +# - The variable is declared within the enclosing function +# - The variable is initialized to a pattern from the mapping +def rule_graph_for_usage_with_variables(mapping): + # Matches the usage of zap.Any with a variable usage_with_var = Rule( f"usage_of_zap_any_with_var", query=f"cs logger.With(zap.Any(:[f], &:[var_name])).Info(:[i])", @@ -41,12 +44,14 @@ def get_complex_rule_graph(mapping): edges = [] for api, patterns in mapping.items(): for pattern in patterns: + # Matches the declaration of a variable initialized to the pattern var_decl_pattern = Rule( name=f"var_decl_{api}_usage_{pattern}", query=f"cs :[var_name] = {pattern}", holes = {"var_name"}, is_seed_rule=False ) + # Update the zap any usage update_zap_usage = Rule( name=f"update_zap_usage_{api}_usage_{pattern}", query=f"cs logger.With(zap.Any(:[f], &:[var_name])).Info(:[i])", @@ -55,25 +60,25 @@ def get_complex_rule_graph(mapping): holes = {"var_name"}, is_seed_rule=False ) - edge1 = OutgoingEdges( - var_decl_pattern.name, - to = [ update_zap_usage.name ], - scope= "Function-Method" - ) - - edge2 = OutgoingEdges( + # When zap usage with a variable is found, we find the declaration of the variable within the enclosing function + edges.append(OutgoingEdges( usage_with_var.name, to = [ var_decl_pattern.name ], scope= "Function-Method" - ) + )) + # If the variable declaration is found for that variable, and it is initialized to the pattern, we update the zap usage + edges.append(OutgoingEdges( + var_decl_pattern.name, + to = [ update_zap_usage.name ], + scope= "Function-Method" + )) rules.extend([var_decl_pattern, update_zap_usage]) - edges.extend([edge1, edge2]) return rules, edges simple_rules = get_simple_rule(mapping) -complex_rules, edges = get_complex_rule_graph(mapping) +complex_rules, edges = rule_graph_for_usage_with_variables(mapping) rule_graph = RuleGraph(rules=simple_rules + complex_rules, edges=edges) args = PiranhaArguments(