Skip to content

Commit ace1cdf

Browse files
committed
GumTree Edit script computation
1 parent 514b9f4 commit ace1cdf

File tree

6 files changed

+413
-61
lines changed

6 files changed

+413
-61
lines changed

code_diff/__init__.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,27 @@ def sstub_pattern(self):
8585
return classify_sstub(*diff_search(self.source_ast, self.target_ast))
8686

8787
def edit_script(self):
88-
return compute_edit_script(self.source_ast, self.target_ast)
88+
89+
source_ast, target_ast = self.source_ast, self.target_ast
90+
91+
def is_statement_type(node_type):
92+
return any(match_type(r, node_type) for r in self.config.statement_types)
93+
94+
if not is_statement_type(source_ast.type) or not is_statement_type(target_ast.type):
95+
# We need something where we can add to (root)
96+
if source_ast.parent is not None:
97+
source_ast = source_ast.parent
98+
99+
if target_ast.parent is not None:
100+
target_ast = target_ast.parent
101+
102+
return compute_edit_script(source_ast, target_ast)
89103

90104
def __repr__(self):
91105
return "%s -> %s" % (self.source_text, self.target_text)
92106

93107

94-
108+
95109

96110
# AST Utils -----------------------------------------------------------
97111

code_diff/ast.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77

88
class ASTNode(object):
99

10-
def __init__(self, type, text = None, parent = None, children = None):
10+
def __init__(self, type, text = None, position = None, parent = None, children = None):
1111

1212
# Basic node attributes
1313
self.type = type
1414
self.children = children if children is not None else []
1515
self.parent = parent
1616
self.text = text # If text is not None, then leaf node
17+
self.position = position
1718

1819
# Tree based attributes
1920
self.subtree_hash = None
@@ -56,8 +57,8 @@ def __repr__(self):
5657
return "ASTNode(%s)" % (", ".join(["%s=%s" % (k, v) for k, v in attrs.items() if v is not None]))
5758

5859

59-
def default_create_node(type, children, text = None):
60-
new_node = ASTNode(type, text = text, children = children)
60+
def default_create_node(type, children, text = None, position = None):
61+
new_node = ASTNode(type, text = text, position = position, children = children)
6162

6263
# Subtree metrics
6364
height = 1
@@ -101,7 +102,8 @@ def _create_node(self, ast_node, text = None):
101102
children = [self.node_index[_node_key(c)] for c in ast_node.children
102103
if _node_key(c) in self.node_index]
103104

104-
current_node = self.create_node_fn(ast_node.type, children, text = text)
105+
position = (ast_node.start_point, ast_node.end_point)
106+
current_node = self.create_node_fn(ast_node.type, children, text = text, position = position)
105107
self.node_index[node_key] = current_node
106108

107109
# Add parent if ready

code_diff/gumtree/__init__.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,29 @@
1-
from .isomap import gumtree_isomap
2-
from .editmap import gumtree_editmap
1+
from .isomap import gumtree_isomap
2+
from .editmap import gumtree_editmap
3+
from .chawathe import compute_chawathe_edit_script
4+
from .ops import (Update, Insert, Delete, Move)
35

46
# Edit script ----------------------------------------------------------------
57

6-
def compute_edit_script(source_ast, target_ast):
7-
8-
isomap = gumtree_isomap(source_ast, target_ast)
9-
print(isomap)
10-
print("----------------------------------------------------------------")
8+
def compute_edit_script(source_ast, target_ast, min_height = 1):
9+
10+
# If source_ast and target_ast only leaves
11+
if len(source_ast.children) == 0 and len(target_ast.children) == 0:
12+
return [_update_leaf(source_ast, target_ast)]
13+
14+
isomap = gumtree_isomap(source_ast, target_ast, min_height)
15+
16+
while len(isomap) == 0 and min_height > 0:
17+
min_height -= 1
18+
isomap = gumtree_isomap(source_ast, target_ast, min_height)
1119

1220
editmap = gumtree_editmap(isomap, source_ast, target_ast)
21+
editscript = compute_chawathe_edit_script(editmap, source_ast, target_ast)
22+
23+
return editscript
24+
25+
26+
# Update leaf ----------------------------------------------------------------
1327

14-
print(editmap)
15-
28+
def _update_leaf(source_ast, target_ast):
29+
return Update(source_ast, target_ast.text)

0 commit comments

Comments
 (0)