45
45
import org .netbeans .api .java .source .*;
46
46
import org .netbeans .api .java .source .JavaSource .Phase ;
47
47
import org .netbeans .api .java .source .ModificationResult .Difference ;
48
- import org .netbeans .api .progress .ProgressUtils ;
48
+ import org .netbeans .api .progress .BaseProgressUtils ;
49
49
import org .netbeans .editor .BaseAction ;
50
50
import org .netbeans .editor .BaseDocument ;
51
51
import org .netbeans .editor .GuardedDocument ;
73
73
@ Hint (displayName = "#DN_org.netbeans.modules.java.hints.OrganizeMembers" , description = "#DESC_org.netbeans.modules.java.hints.OrganizeMembers" , category = "class_structure" , enabled = false )
74
74
public class OrganizeMembers {
75
75
76
- @ TriggerTreeKind (Kind .CLASS )
76
+ @ TriggerTreeKind ({ Kind .CLASS , Kind . RECORD , Kind . ENUM } )
77
77
public static ErrorDescription checkMembers (final HintContext context ) {
78
78
for (Diagnostic <?> d : context .getInfo ().getDiagnostics ()) {
79
79
if (Hacks .isSyntaxError (d )) {
@@ -122,49 +122,44 @@ private static void doOrganizeMembers(WorkingCopy copy, TreePath path) {
122
122
ClassTree clazz = (ClassTree ) path .getLeaf ();
123
123
clazz = gu .importComments (clazz , copy .getCompilationUnit ());
124
124
TreeMaker maker = copy .getTreeMaker ();
125
+
125
126
ClassTree nue = maker .Class (clazz .getModifiers (), clazz .getSimpleName (), clazz .getTypeParameters (), clazz .getExtendsClause (), clazz .getImplementsClause (), clazz .getPermitsClause (), Collections .<Tree >emptyList ());
126
- List <Tree > members = new ArrayList <>(clazz . getMembers (). size () );
127
- Map <Tree , Tree > memberMap = new HashMap <>(clazz . getMembers (). size () );
127
+ List <Tree > members = new ArrayList <>();
128
+ Map <Tree , Tree > memberMap = new HashMap <>();
128
129
129
- List <Tree > enumValues = new ArrayList <>();
130
+ List <Tree > fixedMembers = new ArrayList <>();
130
131
for (Tree tree : clazz .getMembers ()) {
131
- if (copy .getTreeUtilities ().isSynthetic (new TreePath (path , tree ))) {
132
+ // isSynthetic does not consider record components to be synthetic
133
+ if (copy .getTreeUtilities ().isSynthetic (new TreePath (path , tree ))
134
+ && !(tree .getKind () == Kind .VARIABLE && copy .getTreeUtilities ().isRecordComponent ((VariableTree )tree ))) {
132
135
continue ;
133
136
}
134
- Tree member ;
135
- switch (tree .getKind ()) {
136
- case CLASS :
137
- case INTERFACE :
138
- case ENUM :
139
- case ANNOTATION_TYPE :
140
- member = maker .setLabel (tree , ((ClassTree )tree ).getSimpleName ());
141
- break ;
142
- case VARIABLE :
143
- member = maker .setLabel (tree , ((VariableTree )tree ).getName ());
144
- if (copy .getTreeUtilities ().isEnumConstant ((VariableTree )tree )) {
145
- enumValues .add (member );
137
+ Tree member = switch (tree .getKind ()) {
138
+ case CLASS , INTERFACE , ENUM , RECORD , ANNOTATION_TYPE ->
139
+ maker .setLabel (tree , ((ClassTree )tree ).getSimpleName ());
140
+ case VARIABLE -> {
141
+ VariableTree vt = (VariableTree )tree ;
142
+ Tree mem = maker .setLabel (tree , vt .getName ());
143
+ if (copy .getTreeUtilities ().isEnumConstant (vt ) || copy .getTreeUtilities ().isRecordComponent (vt )) {
144
+ fixedMembers .add (mem );
146
145
}
147
- break ;
148
- case METHOD :
149
- member = maker .setLabel (tree , ((MethodTree )tree ).getName ());
150
- break ;
151
- case BLOCK :
152
- member = maker .asReplacementOf (maker .Block (((BlockTree )tree ).getStatements (), ((BlockTree )tree ).isStatic ()), tree , true );
153
- break ;
154
- default :
155
- member = tree ;
156
- }
146
+ yield mem ;
147
+ }
148
+ case METHOD -> maker .setLabel (tree , ((MethodTree )tree ).getName ());
149
+ case BLOCK -> maker .asReplacementOf (maker .Block (((BlockTree )tree ).getStatements (), ((BlockTree )tree ).isStatic ()), tree , true );
150
+ default -> tree ;
151
+ };
157
152
members .add (member );
158
153
memberMap .put (member , tree );
159
154
}
160
155
// fool the generator utilities with cloned members, so it does not take positions into account
161
- if (enumValues .isEmpty ()) {
156
+ if (fixedMembers .isEmpty ()) {
162
157
nue = GeneratorUtilities .get (copy ).insertClassMembers (nue , members );
163
158
} else {
164
- members .removeAll (enumValues );
159
+ members .removeAll (fixedMembers );
165
160
int max = nue .getMembers ().size ();
166
- // insert the enum values in the original order
167
- for (Tree t : enumValues ) {
161
+ // insert the enum values or record components in the original order
162
+ for (Tree t : fixedMembers ) {
168
163
nue = maker .insertClassMember (nue , max ++, t );
169
164
}
170
165
nue = GeneratorUtilities .get (copy ).insertClassMembers (nue , members );
@@ -181,8 +176,8 @@ private static void doOrganizeMembers(WorkingCopy copy, TreePath path) {
181
176
}
182
177
183
178
private static boolean checkGuarded (Document doc , List <? extends Difference > diffs ) {
184
- if (doc instanceof GuardedDocument ) {
185
- MarkBlockChain chain = (( GuardedDocument ) doc ) .getGuardedBlockChain ();
179
+ if (doc instanceof GuardedDocument guardedDocument ) {
180
+ MarkBlockChain chain = guardedDocument .getGuardedBlockChain ();
186
181
for (Difference diff : diffs ) {
187
182
if ((chain .compareBlock (diff .getStartPosition ().getOffset (), diff .getEndPosition ().getOffset ()) & MarkBlock .OVERLAP ) != 0 ) {
188
183
return true ;
@@ -226,7 +221,7 @@ public void actionPerformed(final ActionEvent evt, final JTextComponent componen
226
221
final Source source = Source .create (doc );
227
222
if (source != null ) {
228
223
final AtomicBoolean cancel = new AtomicBoolean ();
229
- ProgressUtils .runOffEventDispatchThread (new Runnable () {
224
+ BaseProgressUtils .runOffEventDispatchThread (new Runnable () {
230
225
@ Override
231
226
public void run () {
232
227
try {
0 commit comments