Skip to content

Commit fc282f8

Browse files
committed
Fix for #1079: support StaticMethodCallExpression in convert to property
1 parent 7d14e8a commit fc282f8

File tree

2 files changed

+115
-52
lines changed

2 files changed

+115
-52
lines changed

ide-test/org.codehaus.groovy.eclipse.quickfix.test/src/org/codehaus/groovy/eclipse/quickfix/test/QuickAssistTests.groovy

+68-14
Original file line numberDiff line numberDiff line change
@@ -226,37 +226,51 @@ final class QuickAssistTests extends QuickFixTestSuite {
226226

227227
@Test
228228
void testConvertToProperty1() {
229+
assertProposalNotOffered(
230+
'"".length()',
231+
4, 0, new ConvertAccessorToPropertyProposal())
232+
}
233+
234+
@Test
235+
void testConvertToProperty2() {
236+
assertProposalNotOffered(
237+
'[].set(1, null)',
238+
4, 0, new ConvertAccessorToPropertyProposal())
239+
}
240+
241+
@Test
242+
void testConvertToProperty3() {
229243
assertConversion(
230244
'"".isEmpty()',
231245
'"".empty',
232246
4, 0, new ConvertAccessorToPropertyProposal())
233247
}
234248

235249
@Test
236-
void testConvertToProperty2() {
250+
void testConvertToProperty4() {
237251
assertConversion(
238252
'"".getBytes()',
239253
'"".bytes',
240254
4, 0, new ConvertAccessorToPropertyProposal())
241255
}
242256

243257
@Test
244-
void testConvertToProperty3() {
258+
void testConvertToProperty5() {
245259
assertProposalNotOffered(
246260
'"".getBytes("UTF-8")',
247261
4, 0, new ConvertAccessorToPropertyProposal())
248262
}
249263

250264
@Test
251-
void testConvertToProperty4() {
265+
void testConvertToProperty6() {
252266
assertConversion(
253267
'new Date().setTime(1L);',
254268
'new Date().time = 1L;',
255269
'set', new ConvertAccessorToPropertyProposal())
256270
}
257271

258272
@Test
259-
void testConvertToProperty4a() {
273+
void testConvertToProperty6a() {
260274
setJavaPreference(FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR, JavaCore.DO_NOT_INSERT)
261275
try {
262276
assertConversion(
@@ -269,17 +283,57 @@ final class QuickAssistTests extends QuickFixTestSuite {
269283
}
270284

271285
@Test
272-
void testConvertToProperty5() {
273-
assertProposalNotOffered(
274-
'[].set(1, null)',
275-
4, 0, new ConvertAccessorToPropertyProposal())
286+
void testConvertToProperty7() {
287+
assertConversion('''\
288+
|class Foo {
289+
| def bar
290+
| void test() {
291+
| getBar()
292+
| }
293+
|}
294+
|'''.stripMargin(), '''\
295+
|class Foo {
296+
| def bar
297+
| void test() {
298+
| bar
299+
| }
300+
|}
301+
|'''.stripMargin(),
302+
'getBar', new ConvertAccessorToPropertyProposal())
276303
}
277304

278305
@Test
279-
void testConvertToProperty6() {
280-
assertProposalNotOffered(
281-
'"".length()',
282-
4, 0, new ConvertAccessorToPropertyProposal())
306+
void testConvertToProperty8() {
307+
assertConversion('''\
308+
|class Foo {
309+
| static getBar() {}
310+
| static test() {
311+
| getBar()
312+
| }
313+
|}
314+
|'''.stripMargin(), '''\
315+
|class Foo {
316+
| static getBar() {}
317+
| static test() {
318+
| bar
319+
| }
320+
|}
321+
|'''.stripMargin(),
322+
'getBar', new ConvertAccessorToPropertyProposal())
323+
}
324+
325+
@Test
326+
void testConvertToProperty9() {
327+
addGroovySource '''\
328+
|class Bar {
329+
| static getBaz() {}
330+
|}
331+
|'''.stripMargin(), 'foo', 'Bar'
332+
333+
assertConversion(
334+
'import static foo.Bar.getBaz\ngetBaz().hashCode()',
335+
'import static foo.Bar.getBaz\nbaz.hashCode()',
336+
'getBaz', new ConvertAccessorToPropertyProposal())
283337
}
284338

285339
@Test
@@ -513,7 +567,7 @@ final class QuickAssistTests extends QuickFixTestSuite {
513567
assertConversion(
514568
'v && g && a',
515569
'g && v && a',
516-
'&&', new SwapLeftAndRightOperandsProposal())
570+
' &&', new SwapLeftAndRightOperandsProposal())
517571
}
518572

519573
@Test
@@ -1964,7 +2018,7 @@ final class QuickAssistTests extends QuickFixTestSuite {
19642018
//
19652019

19662020
private void assertConversion(String original, String expected, String target, GroovyQuickAssistProposal proposal) {
1967-
int offset = (target == null ? 0 : original.indexOf(target)),
2021+
int offset = (target == null ? 0 : original.lastIndexOf(target)),
19682022
length = (target == null ? 0 : target.length())
19692023
assertConversion(original, expected, offset, length, proposal)
19702024
}

ide/org.codehaus.groovy.eclipse.ui/src/org/codehaus/groovy/eclipse/refactoring/actions/ConvertToPropertyAction.java

+47-38
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2009-2018 the original author or authors.
2+
* Copyright 2009-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* https://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -27,7 +27,9 @@
2727
import org.codehaus.groovy.ast.ASTNode;
2828
import org.codehaus.groovy.ast.expr.ArgumentListExpression;
2929
import org.codehaus.groovy.ast.expr.ConstantExpression;
30+
import org.codehaus.groovy.ast.expr.MethodCall;
3031
import org.codehaus.groovy.ast.expr.MethodCallExpression;
32+
import org.codehaus.groovy.ast.expr.StaticMethodCallExpression;
3133
import org.codehaus.groovy.eclipse.GroovyPlugin;
3234
import org.codehaus.groovy.eclipse.codebrowsing.fragments.ASTFragmentKind;
3335
import org.codehaus.groovy.eclipse.codebrowsing.fragments.IASTFragment;
@@ -52,7 +54,7 @@ public class ConvertToPropertyAction extends Action {
5254

5355
private final GroovyEditor editor;
5456

55-
public ConvertToPropertyAction(GroovyEditor editor) {
57+
public ConvertToPropertyAction(final GroovyEditor editor) {
5658
this.editor = editor;
5759
setText("Replace Accessor call with Property read/write");
5860
setActionDefinitionId("org.codehaus.groovy.eclipse.ui.convertToProperty");
@@ -78,49 +80,56 @@ public void run() {
7880
}
7981
}
8082

81-
public static TextEdit createEdit(GroovyCompilationUnit gcu, int pos, int len) {
83+
public static TextEdit createEdit(final GroovyCompilationUnit gcu, final int pos, final int len) {
8284
ModuleNodeInfo info = gcu.getModuleInfo(true);
8385
if (!info.isEmpty()) {
86+
MethodCall call = null;
87+
8488
ASTNode node = new ASTNodeFinder(new Region(pos, len)).doVisit(info.module);
8589
if (node instanceof ConstantExpression) {
8690
IASTFragment fragment = new FindSurroundingNode(new Region(node)).doVisitSurroundingNode(info.module);
8791
if (fragment.kind() == ASTFragmentKind.METHOD_CALL) {
88-
MethodCallExpression call = (MethodCallExpression) fragment.getAssociatedNode();
89-
if (call != null && !call.isUsingGenerics() && call.getArguments() instanceof ArgumentListExpression) {
90-
ArgumentListExpression args = (ArgumentListExpression) call.getArguments();
91-
92-
Matcher match; // check for accessor or mutator
93-
if (args.getExpressions().isEmpty() && (match = compile("(?:get|is)(\\p{javaJavaIdentifierPart}+)").matcher(call.getMethodAsString())).matches()) {
94-
int offset = node.getStart(),
95-
length = (args.getEnd() + 1) - offset;
96-
String propertyName = match.group(1);
97-
98-
// replace "getPropertyName()" with "propertyName"
99-
return new ReplaceEdit(offset, length, decapitalize(propertyName));
100-
101-
} else if (args.getExpressions().size() == 1 && (match = compile("set(\\p{javaJavaIdentifierPart}+)").matcher(call.getMethodAsString())).matches()) {
102-
int offset = node.getStart(),
103-
length = args.getStart() - offset;
104-
String propertyName = match.group(1);
105-
106-
// replace "setPropertyName(value_expression)" or "setPropertyName value_expression"
107-
// with "propertyName = value_expression" (check prefs for spaces around assignment)
108-
MultiTextEdit edits = new MultiTextEdit();
109-
Map<String, String> options = gcu.getJavaProject().getOptions(true);
110-
StringBuilder replacement = new StringBuilder(decapitalize(propertyName));
111-
if (JavaCore.INSERT.equals(options.get(FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR)))
112-
replacement.append(' ');
113-
replacement.append('=');
114-
if (JavaCore.INSERT.equals(options.get(FORMATTER_INSERT_SPACE_AFTER_ASSIGNMENT_OPERATOR)))
115-
replacement.append(' ');
116-
117-
edits.addChild(new ReplaceEdit(offset, length, replacement.toString()));
118-
if (gcu.getContents()[args.getEnd()] == ')') edits.addChild(new DeleteEdit(args.getEnd(), 1));
119-
120-
return edits;
121-
}
92+
MethodCallExpression expr = (MethodCallExpression) fragment.getAssociatedNode();
93+
if (expr != null && !expr.isUsingGenerics()) {
94+
call = expr;
12295
}
12396
}
97+
} else if (node instanceof StaticMethodCallExpression) {
98+
call = (StaticMethodCallExpression) node;
99+
}
100+
101+
if (call != null && call.getArguments() instanceof ArgumentListExpression) {
102+
ArgumentListExpression args = (ArgumentListExpression) call.getArguments();
103+
104+
Matcher match; // check for accessor or mutator
105+
if (args.getExpressions().isEmpty() && (match = compile("(?:get|is)(\\p{javaJavaIdentifierPart}+)").matcher(call.getMethodAsString())).matches()) {
106+
int offset = node.getStart(), length = (args.getEnd() + 1) - offset;
107+
String propertyName = match.group(1);
108+
109+
// replace "getPropertyName()" with "propertyName"
110+
return new ReplaceEdit(offset, length, decapitalize(propertyName));
111+
112+
} else if (args.getExpressions().size() == 1 && (match = compile("set(\\p{javaJavaIdentifierPart}+)").matcher(call.getMethodAsString())).matches()) {
113+
int offset = node.getStart(), length = args.getStart() - offset;
114+
String propertyName = match.group(1);
115+
116+
// replace "setPropertyName(value_expression)" or "setPropertyName value_expression"
117+
// with "propertyName = value_expression" (check prefs for spaces around assignment)
118+
MultiTextEdit edits = new MultiTextEdit();
119+
Map<String, String> options = gcu.getJavaProject().getOptions(true);
120+
StringBuilder replacement = new StringBuilder(decapitalize(propertyName));
121+
if (JavaCore.INSERT.equals(options.get(FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR))) {
122+
replacement.append(' ');
123+
}
124+
replacement.append('=');
125+
if (JavaCore.INSERT.equals(options.get(FORMATTER_INSERT_SPACE_AFTER_ASSIGNMENT_OPERATOR))) {
126+
replacement.append(' ');
127+
}
128+
edits.addChild(new ReplaceEdit(offset, length, replacement.toString()));
129+
if (gcu.getContents()[args.getEnd()] == ')') edits.addChild(new DeleteEdit(args.getEnd(), 1));
130+
131+
return edits;
132+
}
124133
}
125134
}
126135
return null;

0 commit comments

Comments
 (0)