-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathextractor.py
50 lines (46 loc) · 2.15 KB
/
extractor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import subprocess
class Extractor:
def __init__(self, config, jar_path, max_path_length, max_path_width):
self.config = config
self.max_path_length = max_path_length
self.max_path_width = max_path_width
self.jar_path = jar_path
def extract_paths(self, path):
command = ['node', './TSExtractor/TSExtractor/out/main.js', '--max_path_length', str(args.max_path_length),
'--max_path_width', str(args.max_path_width), '--file', path, '--no_hash']
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = process.communicate()
output = out.decode().splitlines()
if len(output) == 0:
err = err.decode()
raise ValueError(err)
hash_to_string_dict = {}
result = []
for i, line in enumerate(output):
parts = line.rstrip().split(' ')
# method_name = parts[0]
identifier_type = parts[0]
current_result_line_parts = [identifier_type]
contexts = parts[1:self.config.MAX_CONTEXTS]
for context in contexts:
context_parts = context.split(',')
context_word1 = context_parts[0]
context_path = context_parts[1]
context_word2 = context_parts[2]
hashed_path = str(self.java_string_hashcode(context_path))
hash_to_string_dict[hashed_path] = context_path
current_result_line_parts += ['%s,%s,%s' % (context_word1, hashed_path, context_word2)]
space_padding = ' ' * (self.config.MAX_CONTEXTS - len(contexts))
result_line = ' '.join(current_result_line_parts) + space_padding
result.append(result_line)
return result, hash_to_string_dict
@staticmethod
def java_string_hashcode(s):
"""
Imitating Java's String#hashCode, because the model is trained on hashed paths but we wish to
Present the path attention on un-hashed paths.
"""
h = 0
for c in s:
h = (31 * h + ord(c)) & 0xFFFFFFFF
return ((h + 0x80000000) & 0xFFFFFFFF) - 0x80000000