def rule_graph_for_usage_with_variables()

in plugins/zap-transformation/__main__.py [0:0]


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])",
        holes = {"zap"}
    )
    rules =[usage_with_var]
    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])",
                replace_node="*",
                replace=f"logger.With(zap.{api}(@f, &@var_name)).Info(@i)",
                holes = {"var_name"},
                is_seed_rule=False
            )
            # 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])

    return rules, edges