-
Notifications
You must be signed in to change notification settings - Fork 22
/
NonTerminalProgramElement.java
130 lines (115 loc) · 4.71 KB
/
NonTerminalProgramElement.java
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// This file is part of the RECODER library and protected by the LGPL.
package recoder.java;
import recoder.ModelException;
/**
* Non terminal program element.
*
* @author <TT>AutoDoc</TT>
*/
public interface NonTerminalProgramElement extends ProgramElement {
/**
* Returns the number of children of this node.
*
* @return an int giving the number of children of this node
*/
int getChildCount();
/**
* Returns the child at the specified index in this node's "virtual" child array.
*
* @param index an index into this node's "virtual" child array
* @return the program element at the given position
* @throws ArrayIndexOutOfBoundsException if <tt>index</tt> is out of bounds
*/
ProgramElement getChildAt(int index);
/**
* Returns the index of the given child, or <CODE>-1</CODE> if there is no such child. The child
* is searched for by identity: <CODE>
* getChildAt(getIndexOfChild(x)) == x</CODE>.
*
* @param child the exact child to look for.
* @return the index of the given child, or <CODE>-1</CODE>.
*/
int getIndexOfChild(ProgramElement child);
/**
* Returns the positional code of the given child, or <CODE>-1</CODE> if there is no such child.
* The result contains an encoding of the relative position of the child as well as the role it
* has been playing in this parent element. This information is required internally for proper
* undo of transformations and is to be delivered to the detached method of the ChangeHistory.
*
* @param child the exact child to look for.
* @return the positional code of the given child, or <CODE>-1</CODE>.
* @see recoder.service.ChangeHistory#detached
*/
int getChildPositionCode(ProgramElement child);
/**
* Extracts the index of a child from its position code.
* <p>
* This method does not return the child index as received by getIndexOfChild(), but rather the
* index within internal data structure representation.
* <p>
* Therefore it is common that <code>getIndexOfChild(getChildPositionCode(aChild))
* != getIndexOfChild(aChild)</code>
* <p>
* This method is deprecated as of 0.75
*
* @param positionCode the position code.
* @return the index of the given position code.
* @see NonTerminalProgramElement#getChildPositionCode(ProgramElement)
* @deprecated
*/
@Deprecated
int getIndexOfChild(int positionCode);
/**
* Extracts the role of a child from its position code. This information is required internally
* for proper undo of transformations.
*
* @param positionCode the position code.
* @return the role code of the given position code.
* @see NonTerminalProgramElement#getChildPositionCode(ProgramElement)
*/
int getRoleOfChild(int positionCode);
/**
* Ensures that each child has "this" as syntactical parent. Any class should define this method
* for added attributes, and delegate to super.makeParentRoleValid() to ensure that inherited
* attributes are made valid as well (e.g. comments from {@link SourceElement}). Any constructor
* of a concrete class should call this method before returning if it shall leave a consistent
* state.
*/
void makeParentRoleValid();
/**
* Calls {@link #makeParentRoleValid}for each non terminal in the subtree with the current
* element as root. If this instanceof TerminalProgramElement, nothing happens.
*/
void makeAllParentRolesValid();
/**
* Calls {@link #validate}for each for the entire subtree with the current element as root.
*
* @since 0.80
*/
void validateAll() throws ModelException;
/**
* Replace a single non-null child in the current node. The child to replace is matched by
* identity and hence must be known exactly. The replacement element can be null - in that case,
* the child is effectively removed. The parent role of the new child is validated, while the
* parent link of the replaced child is left untouched.
*
* @param p the old child.
* @param q the new child.
* @return true if a replacement has occured, false otherwise.
* @throws ClassCastException if the new child cannot take over the role of the old one.
*/
boolean replaceChild(ProgramElement p, ProgramElement q);
/**
* Get the compilation unit that contains this program element.
*
* @return the compilation unit
*/
default CompilationUnit compilationUnit() {
NonTerminalProgramElement parent = getASTParent();
if (parent != null) {
return parent.compilationUnit();
} else {
return null;
}
}
}