1earner1 commited on
Commit
3428fbf
·
verified ·
1 Parent(s): 5f6de0c

Upload try_new_mutation.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. try_new_mutation.py +922 -0
try_new_mutation.py ADDED
@@ -0,0 +1,922 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # import ast
2
+ # import astor
3
+
4
+ # class dependencychecker(ast.nodevisitor):
5
+ # def __init__(self):
6
+ # self.read_vars = set()
7
+ # self.assigned_vars = set()
8
+
9
+ # def visit_name(self, node):
10
+ # if isinstance(node.ctx, ast.load):
11
+ # self.read_vars.add(node.id)
12
+ # elif isinstance(node.ctx, ast.store):
13
+ # self.assigned_vars.add(node.id)
14
+
15
+ # def are_independent(stmt1, stmt2):
16
+ # # check dependencies of stmt1
17
+ # checker1 = dependencychecker()
18
+ # checker1.visit(stmt1)
19
+
20
+ # # check dependencies of stmt2
21
+ # checker2 = dependencychecker()
22
+ # checker2.visit(stmt2)
23
+
24
+ # # check for intersection between assigned variables and read variables
25
+ # independent = (checker1.assigned_vars.isdisjoint(checker2.read_vars) and
26
+ # checker2.assigned_vars.isdisjoint(checker1.read_vars))
27
+
28
+ # return independent
29
+
30
+ # # sample source code
31
+ # source_code1 = """
32
+ # a = [1]
33
+ # b= 5-a[-1]
34
+ # e = a.append(2)
35
+ # c = 3
36
+ # d = 4
37
+ # """
38
+
39
+ # # parse the source code into an ast
40
+
41
+
42
+
43
+
44
+ # # ensure there are at least two statements to compare
45
+ # def pos_mut(source_code, v=0):
46
+ # parsed_ast = ast.parse(source_code)
47
+ # # print the original code
48
+ # if v==1:
49
+ # print("original code:")
50
+ # print(astor.to_source(parsed_ast))
51
+ # for i in range(len(parsed_ast.body) - 1):
52
+ # stmt1 = parsed_ast.body[i]
53
+ # stmt2 = parsed_ast.body[i + 1]
54
+
55
+ # if are_independent(stmt1, stmt2):
56
+ # # swap the two independent statements
57
+ # parsed_ast.body[i], parsed_ast.body[i + 1] = parsed_ast.body[i + 1], parsed_ast.body[i]
58
+ # break # swap only the first pair of independent statements
59
+
60
+ # # convert the modified ast back to source code
61
+ # modified_code = astor.to_source(parsed_ast)
62
+ # if v==1:
63
+ # print("\nmodified code:")
64
+ # print(modified_code)
65
+ # return modified_code
66
+
67
+
68
+ # pos_mut(source_code, v=1)
69
+ # def neg_mut(source_code):
70
+ # parsed_ast = ast.parse(source_code)
71
+ # for i in range(len(parsed_ast.body) - 1):
72
+ # stmt1 = parsed_ast.body[i]
73
+ # stmt2 = parsed_ast.body[i + 1]
74
+
75
+ # if not are_independent(stmt1, stmt2):
76
+ # # swap the two independent statements
77
+ # parsed_ast.body[i], parsed_ast.body[i + 1] = parsed_ast.body[i + 1], parsed_ast.body[i]
78
+ # break # swap only the first pair of independent statements
79
+
80
+ # # convert the modified ast back to source code
81
+ # modified_code = astor.to_source(parsed_ast)
82
+ # return modified_code
83
+
84
+
85
+
86
+
87
+
88
+
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+
97
+ import ast
98
+ import astor
99
+
100
+ class dependencychecker(ast.NodeVisitor):
101
+ def __init__(self):
102
+ self.read_vars = set()
103
+ self.assigned_vars = set()
104
+ self.mutated_vars = set()
105
+
106
+ def visit_name(self, node):
107
+ if isinstance(node.ctx, ast.load):
108
+ self.read_vars.add(node.id)
109
+ elif isinstance(node.ctx, ast.store):
110
+ self.assigned_vars.add(node.id)
111
+
112
+ def visit_attribute(self, node):
113
+ # handle object attributes like a.append(), a[-1], etc.
114
+ if isinstance(node.ctx, ast.load):
115
+ self.read_vars.add(node.value.id)
116
+ elif isinstance(node.ctx, ast.store):
117
+ self.assigned_vars.add(node.value.id)
118
+ self.generic_visit(node)
119
+
120
+ def visit_subscript(self, node):
121
+ # handle subscripting like a[-1]
122
+ if isinstance(node.ctx, ast.load):
123
+ self.read_vars.add(node.value.id)
124
+ elif isinstance(node.ctx, ast.store):
125
+ self.mutated_vars.add(node.value.id)
126
+ self.generic_visit(node)
127
+
128
+ def visit_call(self, node):
129
+ # handle function calls like a.append()
130
+ if isinstance(node.func, ast.attribute):
131
+ self.mutated_vars.add(node.func.value.id)
132
+ self.generic_visit(node)
133
+
134
+ def are_independent(stmt1, stmt2):
135
+ # check dependencies of stmt1
136
+ checker1 = dependencychecker()
137
+ checker1.visit(stmt1)
138
+
139
+ # check dependencies of stmt2
140
+ checker2 = dependencychecker()
141
+ checker2.visit(stmt2)
142
+
143
+ # check for intersection between assigned/mutated variables and read variables
144
+ independent = (checker1.assigned_vars.isdisjoint(checker2.read_vars | checker2.mutated_vars) and
145
+ checker2.assigned_vars.isdisjoint(checker1.read_vars | checker1.mutated_vars) and
146
+ checker1.mutated_vars.isdisjoint(checker2.read_vars | checker2.mutated_vars) and
147
+ checker2.mutated_vars.isdisjoint(checker1.read_vars | checker1.mutated_vars))
148
+
149
+ return independent
150
+
151
+ # sample source code
152
+
153
+ source_code = """
154
+ a = [1]
155
+ b = 5 - a[-1]
156
+ a[0] = a[0] + 1
157
+ c = 3
158
+ d = 4
159
+ """
160
+ def pos_mut(source_code, verbose=False):
161
+ # parse the source code into an ast
162
+ parsed_ast = ast.parse(source_code)
163
+
164
+ # print the original code
165
+ if verbose==True:
166
+ print("original code:")
167
+ print(astor.to_source(parsed_ast))
168
+
169
+ # ensure there are at least two statements to compare
170
+ for i in range(len(parsed_ast.body) - 1):
171
+ stmt1 = parsed_ast.body[i]
172
+ stmt2 = parsed_ast.body[i + 1]
173
+
174
+ if are_independent(stmt1, stmt2):
175
+ # swap the two independent statements
176
+ parsed_ast.body[i], parsed_ast.body[i + 1] = parsed_ast.body[i + 1], parsed_ast.body[i]
177
+ break # swap only the first pair of independent statements
178
+
179
+ # convert the modified ast back to source code
180
+ modified_code = astor.to_source(parsed_ast)
181
+
182
+ # print the modified code
183
+ if verbose==True:
184
+ print("\nmodified code:")
185
+ print(modified_code)
186
+
187
+ pos_mut(source_code, verbose=True)
188
+
189
+ def neg_mut(source_code, verbose=False):
190
+ # parse the source code into an ast
191
+ parsed_ast = ast.parse(source_code)
192
+
193
+ # print the original code
194
+ if verbose==True:
195
+ print("original code:")
196
+ print(astor.to_source(parsed_ast))
197
+
198
+ # ensure there are at least two statements to compare
199
+ for i in range(len(parsed_ast.body) - 1):
200
+ stmt1 = parsed_ast.body[i]
201
+ stmt2 = parsed_ast.body[i + 1]
202
+
203
+ if not are_independent(stmt1, stmt2):
204
+ # swap the two independent statements
205
+ parsed_ast.body[i], parsed_ast.body[i + 1] = parsed_ast.body[i + 1], parsed_ast.body[i]
206
+ break # swap only the first pair of independent statements
207
+
208
+ # convert the modified ast back to source code
209
+ modified_code = astor.to_source(parsed_ast)
210
+
211
+ # print the modified code
212
+ if verbose==True:
213
+ print("\nmodified code:")
214
+ print(modified_code)
215
+
216
+ neg_mut(source_code, verbose=True)
217
+
218
+ # import ast
219
+ # import astor
220
+ # import random
221
+ # import string
222
+
223
+ # class VariableRenamer(ast.NodeTransformer):
224
+ # def __init__(self, rename_map=None):
225
+ # # Mapping from original variable names to their new names
226
+ # if rename_map is None:
227
+ # self.rename_map = {}
228
+ # else:
229
+ # self.rename_map = rename_map
230
+
231
+ # def generate_new_name(self, old_name):
232
+ # # Generate a new name for the variable
233
+ # if old_name not in self.rename_map:
234
+ # new_name = ''.join(random.choices(string.ascii_lowercase, k=5))
235
+ # self.rename_map[old_name] = new_name
236
+ # return self.rename_map[old_name]
237
+
238
+ # def visit_Name(self, node):
239
+ # if isinstance(node.ctx, (ast.Load, ast.Store, ast.Del)):
240
+ # node.id = self.generate_new_name(node.id)
241
+ # return node
242
+
243
+ # def visit_FunctionDef(self, node):
244
+ # # Rename function arguments
245
+ # node.args.args = [ast.arg(arg=self.generate_new_name(arg.arg), annotation=arg.annotation) for arg in node.args.args]
246
+ # # Rename the function body
247
+ # self.generic_visit(node)
248
+ # return node
249
+
250
+ # def visit_Assign(self, node):
251
+ # # Rename variables in assignments
252
+ # self.generic_visit(node)
253
+ # return node
254
+
255
+ # def visit_Attribute(self, node):
256
+ # # Skip renaming attributes (e.g., object.method) to avoid unintended changes
257
+ # self.generic_visit(node)
258
+ # return node
259
+
260
+ # def rename_variables(source_code):
261
+ # # Parse the source code into an AST
262
+ # parsed_ast = ast.parse(source_code)
263
+
264
+ # # Create a renamer instance
265
+ # renamer = VariableRenamer()
266
+
267
+ # # Transform the AST by renaming variables
268
+ # renamed_ast = renamer.visit(parsed_ast)
269
+
270
+ # # Convert the modified AST back to source code
271
+ # renamed_code = astor.to_source(renamed_ast)
272
+
273
+ # return renamed_code
274
+
275
+ # # Sample source code
276
+ # source_code = """
277
+ # def example_function(x, y):
278
+ # a = x + y
279
+ # b = a * 2
280
+ # return b
281
+
282
+ # x = 5
283
+ # y = 10
284
+ # result = example_function(x, y)
285
+ # print(result)
286
+ # """
287
+
288
+ # # Rename variables in the source code
289
+ # renamed_code = rename_variables(source_code)
290
+
291
+ # # Print the original and modified code
292
+ # print("Original code:")
293
+ # print(source_code)
294
+ # print("\nRenamed code:")
295
+ # print(renamed_code)
296
+
297
+
298
+
299
+
300
+
301
+
302
+
303
+
304
+
305
+
306
+
307
+
308
+
309
+
310
+ # import com.github.javaparser.StaticJavaParser;
311
+ # import com.github.javaparser.ast.CompilationUnit;
312
+ # import com.github.javaparser.ast.body.MethodDeclaration;
313
+ # import com.github.javaparser.ast.body.Parameter;
314
+ # import com.github.javaparser.ast.expr.SimpleName;
315
+ # import com.github.javaparser.ast.visitor.ModifierVisitor;
316
+ # import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
317
+
318
+ # import java.io.FileInputStream;
319
+ # import java.io.FileNotFoundException;
320
+ # import java.util.HashMap;
321
+ # import java.util.Map;
322
+ # import java.util.Random;
323
+
324
+ # public class VariableRenamer {
325
+ # private static Map<String, String> renameMap = new HashMap<>();
326
+
327
+ # public static void main(String[] args) throws FileNotFoundException {
328
+ # FileInputStream in = new FileInputStream("Example.java"); // Your Java file
329
+
330
+ # CompilationUnit cu = StaticJavaParser.parse(in);
331
+
332
+ # // Rename variables
333
+ # new ModifierVisitor<Void>() {
334
+ # @Override
335
+ # public SimpleName visit(SimpleName n, Void arg) {
336
+ # String originalName = n.getIdentifier();
337
+ # if (!renameMap.containsKey(originalName)) {
338
+ # renameMap.put(originalName, generateNewName());
339
+ # }
340
+ # n.setIdentifier(renameMap.get(originalName));
341
+ # return n;
342
+ # }
343
+
344
+ # @Override
345
+ # public MethodDeclaration visit(MethodDeclaration md, Void arg) {
346
+ # for (Parameter parameter : md.getParameters()) {
347
+ # String originalName = parameter.getNameAsString();
348
+ # if (!renameMap.containsKey(originalName)) {
349
+ # renameMap.put(originalName, generateNewName());
350
+ # }
351
+ # parameter.setName(renameMap.get(originalName));
352
+ # }
353
+ # return super.visit(md, arg);
354
+ # }
355
+ # }.visit(cu, null);
356
+
357
+ # System.out.println(cu.toString());
358
+ # }
359
+
360
+ # // Generates a random 5-letter name
361
+ # private static String generateNewName() {
362
+ # int length = 5;
363
+ # String chars = "abcdefghijklmnopqrstuvwxyz";
364
+ # Random random = new Random();
365
+ # StringBuilder newName = new StringBuilder(length);
366
+ # for (int i = 0; i < length; i++) {
367
+ # newName.append(chars.charAt(random.nextInt(chars.length())));
368
+ # }
369
+ # return newName.toString();
370
+ # }
371
+ # }
372
+
373
+
374
+
375
+
376
+
377
+
378
+
379
+
380
+ # import javalang
381
+ # import random
382
+ # import string
383
+
384
+ # # Generate a consistent new name for a given old name
385
+ # def generate_new_name(existing_names):
386
+ # new_name = ''.join(random.choices(string.ascii_lowercase, k=5))
387
+ # while new_name in existing_names:
388
+ # new_name = ''.join(random.choices(string.ascii_lowercase, k=5))
389
+ # return new_name
390
+
391
+ # # Perform the variable renaming
392
+ # def rename_variables(java_code):
393
+ # tree = javalang.parse.parse(java_code)
394
+ # rename_map = {}
395
+ # existing_names = set()
396
+
397
+ # for path, node in tree:
398
+ # if isinstance(node, javalang.tree.VariableDeclarator):
399
+ # var_name = node.name
400
+ # if var_name not in rename_map:
401
+ # new_name = generate_new_name(existing_names)
402
+ # rename_map[var_name] = new_name
403
+ # existing_names.add(new_name)
404
+ # node.name = rename_map[var_name]
405
+
406
+ # elif isinstance(node, javalang.tree.MemberReference):
407
+ # var_name = node.member
408
+ # if var_name in rename_map:
409
+ # node.member = rename_map[var_name]
410
+
411
+ # elif isinstance(node, javalang.tree.FormalParameter):
412
+ # param_name = node.name
413
+ # if param_name not in rename_map:
414
+ # new_name = generate_new_name(existing_names)
415
+ # rename_map[param_name] = new_name
416
+ # existing_names.add(new_name)
417
+ # node.name = rename_map[param_name]
418
+
419
+ # return tree, rename_map
420
+
421
+ # # Convert the modified AST back to Java code
422
+ # def ast_to_code(tree):
423
+ # code = []
424
+ # for path, node in tree:
425
+ # if isinstance(node, javalang.tree.ClassDeclaration):
426
+ # code.append(f"class {node.name} " + "{\n")
427
+ # elif isinstance(node, javalang.tree.MethodDeclaration):
428
+ # modifiers = ' '.join(node.modifiers)
429
+ # return_type = node.return_type.name if node.return_type else 'void'
430
+ # params = ', '.join(f"{param.type.name} {param.name}" for param in node.parameters)
431
+ # code.append(f" {modifiers} {return_type} {node.name}({params}) " + "{\n")
432
+ # elif isinstance(node, javalang.tree.VariableDeclarator):
433
+ # code.append(f" {node.name} = {node.initializer};\n")
434
+ # elif isinstance(node, javalang.tree.Assignment):
435
+ # code.append(f" {node.expressionl.member} = {node.value.member};\n")
436
+ # elif isinstance(node, javalang.tree.MemberReference):
437
+ # code.append(f" {node.member};\n")
438
+ # elif isinstance(node, javalang.tree.Literal):
439
+ # code.append(f"{node.value}")
440
+ # elif isinstance(node, javalang.tree.MethodInvocation):
441
+ # code.append(f" {node.name}({', '.join(arg.member if isinstance(arg, javalang.tree.MemberReference) else str(arg) for arg in node.arguments)});\n")
442
+ # elif isinstance(node, javalang.tree.StatementExpression):
443
+ # code.append(f" {node.expression.member};\n")
444
+ # elif isinstance(node, javalang.tree.ReturnStatement):
445
+ # code.append(f" return {node.expression.member if isinstance(node.expression, javalang.tree.MemberReference) else str(node.expression)};\n")
446
+ # elif isinstance(node, javalang.tree.IfStatement):
447
+ # code.append(f" if ({node.condition.member if isinstance(node.condition, javalang.tree.MemberReference) else str(node.condition)}) " + "{\n")
448
+ # code.append(f" }}\n")
449
+ # elif isinstance(node, javalang.tree.ConstructorDeclaration):
450
+ # modifiers = ' '.join(node.modifiers)
451
+ # params = ', '.join(f"{param.type.name} {param.name}" for param in node.parameters)
452
+ # code.append(f" {modifiers} {node.name}({params}) " + "{\n")
453
+
454
+ # code.append("}\n")
455
+ # return ''.join(code)
456
+
457
+ # # Sample Java source code
458
+ # java_code = """
459
+ # public class Example {
460
+ # public static void main(String[] args) {
461
+ # int a = 5;
462
+ # int b = a + 10;
463
+ # System.out.println(b);
464
+ # }
465
+ # }
466
+ # """
467
+
468
+ # # Rename variables in the Java code
469
+ # ast, rename_map = rename_variables(java_code)
470
+
471
+ # # Convert the modified AST back to Java code
472
+ # modified_code = ast_to_code(ast)
473
+
474
+ # # Print the original and modified Java code
475
+ # print("Original Java code:")
476
+ # print(java_code)
477
+ # print("\nRenamed Java code:")
478
+ # print(modified_code)
479
+
480
+
481
+
482
+
483
+
484
+
485
+
486
+ # import ast
487
+ # import astor
488
+ # import random
489
+ # import string
490
+
491
+ # class DefUseBreakTransformer(ast.NodeTransformer):
492
+ # def __init__(self):
493
+ # self.def_use_count = {}
494
+ # self.rename_map = {}
495
+
496
+ # def generate_new_name(self):
497
+ # return ''.join(random.choices(string.ascii_lowercase, k=5))
498
+
499
+ # def visit_FunctionDef(self, node):
500
+ # # Reset state for each function
501
+ # self.def_use_count = {}
502
+ # self.rename_map = {}
503
+ # return self.generic_visit(node)
504
+
505
+ # def visit_Assign(self, node):
506
+ # if isinstance(node.targets[0], ast.Name):
507
+ # var_name = node.targets[0].id
508
+
509
+ # # Track the count of each variable's definition
510
+ # if var_name not in self.def_use_count:
511
+ # self.def_use_count[var_name] = 1
512
+ # else:
513
+ # self.def_use_count[var_name] += 1
514
+
515
+ # # If it's the second or later definition, rename the variable
516
+ # if self.def_use_count[var_name] == 2:
517
+ # new_name = self.generate_new_name()
518
+ # self.rename_map[var_name] = new_name
519
+ # node.targets[0].id = new_name
520
+ # elif var_name in self.rename_map:
521
+ # node.targets[0].id = self.rename_map[var_name]
522
+
523
+ # self.generic_visit(node)
524
+ # return node
525
+
526
+ # def visit_Name(self, node):
527
+ # var_name = node.id
528
+ # if var_name in self.rename_map:
529
+ # node.id = self.rename_map[var_name]
530
+ # return node
531
+
532
+ # def def_use_break(source_code):
533
+ # tree = ast.parse(source_code)
534
+ # transformer = DefUseBreakTransformer()
535
+ # new_tree = transformer.visit(tree)
536
+ # return astor.to_source(new_tree)
537
+
538
+ # # Example Python source code
539
+ # source_code = """
540
+ # def example_function():
541
+ # a = 5
542
+ # b = a + 10
543
+ # a = b + 1
544
+ # print(a)
545
+ # """
546
+
547
+ # # Apply the Def-Use Break mutation
548
+ # modified_code = def_use_break(source_code)
549
+
550
+ # # Print the original and modified code
551
+ # print("Original code:")
552
+ # print(source_code)
553
+ # print("\nModified code:")
554
+ # print(modified_code)
555
+
556
+
557
+
558
+
559
+
560
+
561
+
562
+
563
+
564
+ # import ast
565
+ # import astor
566
+
567
+ # class LineNumberStatementRemover(ast.NodeTransformer):
568
+ # def __init__(self, target_lineno):
569
+ # self.target_lineno = target_lineno
570
+ # self.found = False
571
+
572
+ # def visit(self, node):
573
+ # """
574
+ # Recursively visit each node in the AST, and if the node matches the target line number,
575
+ # remove the node and everything nested inside it.
576
+ # """
577
+ # # If we already found and removed the target node, return the node unchanged
578
+ # if self.found:
579
+ # return node
580
+
581
+ # # Check if the current node starts on the target line number
582
+ # if hasattr(node, 'lineno') and node.lineno == self.target_lineno:
583
+ # self.found = True
584
+ # return None # Removing the node
585
+
586
+ # # For compound statements, check their body to find and remove the target node
587
+ # if hasattr(node, 'body'):
588
+ # new_body = []
589
+ # for stmt in node.body:
590
+ # if hasattr(stmt, 'lineno') and stmt.lineno == self.target_lineno:
591
+ # self.found = True
592
+ # else:
593
+ # new_body.append(self.visit(stmt))
594
+ # node.body = [stmt for stmt in new_body if stmt is not None]
595
+
596
+ # return node
597
+
598
+ # def remove_statement_by_line(source_code, target_lineno):
599
+ # """
600
+ # Removes the statement at the specified line number and everything nested inside it.
601
+
602
+ # :param source_code: A string containing the Python source code.
603
+ # :param target_lineno: The line number of the statement to remove.
604
+ # :return: The transformed source code with the target statement removed.
605
+ # """
606
+ # # Parse the source code into an AST
607
+ # tree = ast.parse(source_code)
608
+
609
+ # # Create a transformer to remove the node corresponding to the target line number
610
+ # transformer = LineNumberStatementRemover(target_lineno)
611
+
612
+ # # Transform the tree by removing the target node
613
+ # transformed_tree = transformer.visit(tree)
614
+
615
+ # # Convert the transformed AST back to source code
616
+ # transformed_code = astor.to_source(transformed_tree)
617
+
618
+ # return transformed_code
619
+
620
+ # # Example Usage
621
+ # source_code = """
622
+ # def example():
623
+ # x = 1
624
+ # if x > 0:
625
+ # print("Positive")
626
+ # if x == 1:
627
+ # print("One")
628
+ # for i in range(5):
629
+ # print(i)
630
+ # """
631
+
632
+ # # Remove the statement at line 4 (the first 'if' statement) and everything nested within it
633
+ # target_lineno = 6
634
+ # transformed_code = remove_statement_by_line(source_code, target_lineno)
635
+
636
+ # print(transformed_code)
637
+
638
+
639
+
640
+
641
+
642
+
643
+ # import ast
644
+ # import astor
645
+
646
+ # class BooleanInverter(ast.NodeTransformer):
647
+ # def __init__(self, bool_var_name):
648
+ # self.bool_var_name = bool_var_name
649
+
650
+ # def visit_Assign(self, node):
651
+ # """
652
+ # Visit assignment statements and invert the boolean value if it matches the boolean variable.
653
+ # """
654
+ # if isinstance(node.targets[0], ast.Name) and node.targets[0].id == self.bool_var_name:
655
+ # if isinstance(node.value, ast.Constant) and isinstance(node.value.value, bool):
656
+ # # Invert the boolean value
657
+ # node.value.value = not node.value.value
658
+ # return self.generic_visit(node)
659
+
660
+ # def visit_Name(self, node):
661
+ # """
662
+ # Invert the usage of the boolean variable by wrapping it in a `not` expression.
663
+ # """
664
+ # if isinstance(node.ctx, ast.Load) and node.id == self.bool_var_name:
665
+ # return ast.UnaryOp(op=ast.Not(), operand=node)
666
+ # return node
667
+
668
+ # def visit_UnaryOp(self, node):
669
+ # """
670
+ # Handle double negation (`not not var`) by simplifying it.
671
+ # """
672
+ # if isinstance(node.op, ast.Not) and isinstance(node.operand, ast.UnaryOp) and isinstance(node.operand.op, ast.Not):
673
+ # return self.visit(node.operand.operand)
674
+ # return self.generic_visit(node)
675
+
676
+ # def invert_boolean_variable(source_code, bool_var_name):
677
+ # """
678
+ # Inverts the value of the specified boolean variable and propagates the change throughout the code.
679
+
680
+ # :param source_code: A string containing the Python source code.
681
+ # :param bool_var_name: The name of the boolean variable to invert.
682
+ # :return: The transformed source code with the boolean variable inverted and logic preserved.
683
+ # """
684
+ # # Parse the source code into an AST
685
+ # tree = ast.parse(source_code)
686
+
687
+ # # Create a transformer to invert the boolean variable
688
+ # transformer = BooleanInverter(bool_var_name)
689
+
690
+ # # Transform the tree by inverting the boolean variable
691
+ # transformed_tree = transformer.visit(tree)
692
+
693
+ # # Convert the transformed AST back to source code
694
+ # transformed_code = astor.to_source(transformed_tree)
695
+
696
+ # return transformed_code
697
+
698
+ # # Example Usage
699
+ # source_code = """
700
+ # def example():
701
+ # flag = True
702
+ # if flag:
703
+ # print("Flag is true")
704
+ # else:
705
+ # print("Flag is false")
706
+
707
+ # while flag:
708
+ # print("Still true")
709
+ # flag = False
710
+ # print(flag)
711
+ # """
712
+
713
+ # # Invert the boolean variable "flag"
714
+ # bool_var_name = "flag"
715
+ # transformed_code = invert_boolean_variable(source_code, bool_var_name)
716
+
717
+ # print(transformed_code)
718
+
719
+
720
+
721
+
722
+
723
+
724
+
725
+
726
+
727
+
728
+
729
+
730
+
731
+
732
+
733
+
734
+
735
+
736
+
737
+ # import ast
738
+ # import astor
739
+
740
+ # class DeadCodeEliminator(ast.NodeTransformer):
741
+ # def eliminate_dead_code(self, statements):
742
+ # """
743
+ # Eliminate dead code from a list of statements. If a return, break, continue, or raise
744
+ # statement is encountered, all following code in that block is considered dead and removed.
745
+ # """
746
+ # live_statements = []
747
+ # for stmt in statements:
748
+ # live_statements.append(stmt)
749
+
750
+ # if isinstance(stmt, (ast.Return, ast.Raise, ast.Break, ast.Continue)):
751
+ # # Any code after this is dead, so stop adding further statements
752
+ # break
753
+
754
+ # return live_statements
755
+
756
+ # def visit_FunctionDef(self, node):
757
+ # node.body = self.eliminate_dead_code(node.body)
758
+ # return node
759
+
760
+ # def visit_If(self, node):
761
+ # node.body = self.eliminate_dead_code(node.body)
762
+ # node.orelse = self.eliminate_dead_code(node.orelse)
763
+ # return node
764
+
765
+ # def visit_While(self, node):
766
+ # node.body = self.eliminate_dead_code(node.body)
767
+ # node.orelse = self.eliminate_dead_code(node.orelse)
768
+ # return node
769
+
770
+ # def visit_For(self, node):
771
+ # node.body = self.eliminate_dead_code(node.body)
772
+ # node.orelse = self.eliminate_dead_code(node.orelse)
773
+ # return node
774
+
775
+ # def eliminate_dead_code(source_code):
776
+ # """
777
+ # Eliminate dead code from the given source code.
778
+
779
+ # :param source_code: A string containing the Python source code.
780
+ # :return: The transformed source code with dead code removed.
781
+ # """
782
+ # # Parse the source code into an AST
783
+ # tree = ast.parse(source_code)
784
+
785
+ # # Create a transformer to eliminate dead code
786
+ # transformer = DeadCodeEliminator()
787
+
788
+ # # Transform the tree by eliminating dead code
789
+ # transformed_tree = transformer.visit(tree)
790
+
791
+ # # Convert the transformed AST back to source code
792
+ # transformed_code = astor.to_source(transformed_tree)
793
+
794
+ # return transformed_code
795
+
796
+ # # Example Usage
797
+ # source_code = """
798
+ # def example():
799
+ # x = 10
800
+ # if x > 5:
801
+ # return x
802
+ # print("This is dead code")
803
+ # else:
804
+ # print("This is alive")
805
+ # raise ValueError("This also makes code below dead")
806
+ # print("This is also dead code")
807
+
808
+ # print("This is unreachable")
809
+
810
+ # while x > 0:
811
+ # break
812
+ # print("Dead code after break")
813
+ # """
814
+
815
+ # # Eliminate dead code
816
+ # transformed_code = eliminate_dead_code(source_code)
817
+
818
+ # print(transformed_code)
819
+
820
+
821
+ # NOT
822
+
823
+
824
+
825
+
826
+
827
+
828
+
829
+
830
+
831
+
832
+ # import ast
833
+ # import astor
834
+ # import random
835
+
836
+ # class ExpressionRefactorer(ast.NodeTransformer):
837
+ # def visit_BinOp(self, node):
838
+ # # Reorder commutative operations: a + b -> b + a
839
+ # if isinstance(node.op, (ast.Add, ast.Mult, ast.BitOr, ast.BitAnd)):
840
+ # if isinstance(node.left, (ast.Name, ast.Constant)) and isinstance(node.right, (ast.Name, ast.Constant)):
841
+ # node.left, node.right = node.right, node.left
842
+
843
+ # # Optionally recurse into subexpressions
844
+ # self.generic_visit(node)
845
+ # return node
846
+
847
+ # def visit_Assign(self, node):
848
+ # # Check if there are multiple assignments that can be merged or split
849
+ # if isinstance(node.value, ast.BinOp):
850
+ # if random.choice([True, False]):
851
+ # # Merge adjacent assignments into a single expression
852
+ # return self.merge_expressions(node)
853
+ # else:
854
+ # # Split a complex assignment into simpler ones
855
+ # return self.split_expressions(node)
856
+
857
+ # return node
858
+
859
+ # def merge_expressions(self, node):
860
+ # """
861
+ # Merge multiple assignments into a single complex expression.
862
+ # """
863
+ # if isinstance(node.value, ast.BinOp):
864
+ # left_var = node.targets[0].id
865
+ # new_expr = ast.BinOp(
866
+ # left=ast.Name(id=left_var, ctx=ast.Load()),
867
+ # op=node.value.op,
868
+ # right=node.value.right
869
+ # )
870
+ # new_assign = ast.Assign(
871
+ # targets=[ast.Name(id=left_var, ctx=ast.Store())],
872
+ # value=new_expr
873
+ # )
874
+ # return new_assign
875
+ # return node
876
+
877
+ # def split_expressions(self, node):
878
+ # """
879
+ # Split a complex assignment into multiple simpler ones.
880
+ # """
881
+ # if isinstance(node.value, ast.BinOp):
882
+ # temp_var_name = "temp_" + node.targets[0].id
883
+ # first_assign = ast.Assign(
884
+ # targets=[ast.Name(id=temp_var_name, ctx=ast.Store())],
885
+ # value=node.value.left
886
+ # )
887
+ # second_assign = ast.Assign(
888
+ # targets=node.targets,
889
+ # value=ast.BinOp(
890
+ # left=ast.Name(id=temp_var_name, ctx=ast.Load()),
891
+ # op=node.value.op,
892
+ # right=node.value.right
893
+ # )
894
+ # )
895
+ # return [first_assign, second_assign]
896
+ # return node
897
+
898
+ # def refactor_code(code):
899
+ # # Parse the code into an AST
900
+ # tree = ast.parse(code)
901
+
902
+ # # Apply the refactoring
903
+ # refactorer = ExpressionRefactorer()
904
+ # refactored_tree = refactorer.visit(tree)
905
+
906
+ # # Convert the refactored AST back to code
907
+ # refactored_code = astor.to_source(refactored_tree)
908
+
909
+ # return refactored_code
910
+
911
+ # # Example usage
912
+ # original_code = """
913
+ # a = 5
914
+ # b = a
915
+ # x = a + b
916
+ # y = c * d
917
+
918
+ # z = (a + b) * (c + d)
919
+ # """
920
+
921
+ # refactored_code = refactor_code(original_code)
922
+ # print(refactored_code)