-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathAbstractNode.java
More file actions
111 lines (95 loc) · 3.63 KB
/
AbstractNode.java
File metadata and controls
111 lines (95 loc) · 3.63 KB
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package org.perlonjava.astnode;
import org.perlonjava.astvisitor.PrintVisitor;
import java.util.HashMap;
import java.util.Map;
/**
* Abstract base class for AST nodes that includes an tokenIndex pointing
* back to the token list. This tokenIndex is used for providing better
* error messages by pointing to the exact location in the source code.
* <p>
* It also provides deep toString() formatting using PrintVisitor
*/
public abstract class AbstractNode implements Node {
public int tokenIndex;
// Lazy initialization - only created when first annotation is set
public Map<String, Object> annotations;
private int internalAnnotationFlags;
private static final int FLAG_BLOCK_ALREADY_REFACTORED = 1;
private static final int FLAG_QUEUED_FOR_REFACTOR = 2;
private static final int FLAG_CHUNK_ALREADY_REFACTORED = 4;
private int cachedBytecodeSize = Integer.MIN_VALUE;
private byte cachedHasAnyControlFlow = -1;
@Override
public int getIndex() {
return tokenIndex;
}
@Override
public void setIndex(int tokenIndex) {
this.tokenIndex = tokenIndex;
}
/**
* Returns a string representation of the syntax tree.
* The string representation includes the type and text of the syntax tree.
*
* @return a string representation of the syntax tree
*/
@Override
public String toString() {
try {
PrintVisitor printVisitor = new PrintVisitor();
this.accept(printVisitor);
return printVisitor.getResult();
} catch (Exception e) {
e.printStackTrace(); // Print any exceptions that occur during the process
return e.toString();
}
}
public void setAnnotation(String key, Object value) {
if (value instanceof Boolean boolVal && boolVal) {
if ("blockAlreadyRefactored".equals(key)) {
internalAnnotationFlags |= FLAG_BLOCK_ALREADY_REFACTORED;
return;
}
if ("queuedForRefactor".equals(key)) {
internalAnnotationFlags |= FLAG_QUEUED_FOR_REFACTOR;
return;
}
if ("chunkAlreadyRefactored".equals(key)) {
internalAnnotationFlags |= FLAG_CHUNK_ALREADY_REFACTORED;
return;
}
}
if (annotations == null) {
annotations = new HashMap<>();
}
annotations.put(key, value);
}
public Integer getCachedBytecodeSize() {
return cachedBytecodeSize == Integer.MIN_VALUE ? null : cachedBytecodeSize;
}
public void setCachedBytecodeSize(int size) {
this.cachedBytecodeSize = size;
}
public Boolean getCachedHasAnyControlFlow() {
return cachedHasAnyControlFlow < 0 ? null : cachedHasAnyControlFlow != 0;
}
public void setCachedHasAnyControlFlow(boolean hasAnyControlFlow) {
this.cachedHasAnyControlFlow = (byte) (hasAnyControlFlow ? 1 : 0);
}
public Object getAnnotation(String key) {
if ("blockAlreadyRefactored".equals(key)) {
return (internalAnnotationFlags & FLAG_BLOCK_ALREADY_REFACTORED) != 0;
}
if ("queuedForRefactor".equals(key)) {
return (internalAnnotationFlags & FLAG_QUEUED_FOR_REFACTOR) != 0;
}
if ("chunkAlreadyRefactored".equals(key)) {
return (internalAnnotationFlags & FLAG_CHUNK_ALREADY_REFACTORED) != 0;
}
return annotations == null ? null : annotations.get(key);
}
public boolean getBooleanAnnotation(String key) {
Object value = getAnnotation(key);
return value instanceof Boolean && (Boolean) value;
}
}