Merge branch 'master' of git.labs.intellij.net:idea/community

This commit is contained in:
Bas Leijdekkers
2011-03-10 15:27:48 +01:00
133 changed files with 4086 additions and 470 deletions
+1 -1
View File
@@ -59,7 +59,7 @@
<module fileurl="file://$PROJECT_DIR$/platform/lang-impl/lang-impl.iml" filepath="$PROJECT_DIR$/platform/lang-impl/lang-impl.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/platform/lvcs-api/lvcs-api.iml" filepath="$PROJECT_DIR$/platform/lvcs-api/lvcs-api.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/platform/lvcs-impl/lvcs-impl.iml" filepath="$PROJECT_DIR$/platform/lvcs-impl/lvcs-impl.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/maven.iml" filepath="$PROJECT_DIR$/community/plugins/maven/maven.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/maven.iml" filepath="$PROJECT_DIR$/plugins/maven/maven.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/maven-server-api/maven-server-api.iml" filepath="$PROJECT_DIR$/plugins/maven/maven-server-api/maven-server-api.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/maven2-server-impl/maven2-server-impl.iml" filepath="$PROJECT_DIR$/plugins/maven/maven2-server-impl/maven2-server-impl.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/maven3-server-impl/maven3-server-impl.iml" filepath="$PROJECT_DIR$/plugins/maven/maven3-server-impl/maven3-server-impl.iml" group="plugins" />
@@ -24,10 +24,13 @@
*/
package com.intellij.refactoring.introduceParameter;
import com.intellij.psi.*;
import com.intellij.psi.PsiElement;
class ChangedMethodCallInfo extends InternalUsageInfo {
ChangedMethodCallInfo(PsiElement e) {
/**
* recursive call usages inside method
*/
public class ChangedMethodCallInfo extends InternalUsageInfo {
public ChangedMethodCallInfo(PsiElement e) {
super(e);
}
}
@@ -0,0 +1,41 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.refactoring.introduceParameter;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageExtension;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.Nullable;
/**
* @author Maxim.Medvedev
*/
public abstract class ExpressionConverter {
public static final LanguageExtension<ExpressionConverter> EP =
new LanguageExtension<ExpressionConverter>("com.intellij.expressionConverter");
protected abstract PsiElement convert(PsiElement expression, Project project);
@Nullable
public static PsiElement getExpression(PsiElement expression, Language language, Project project) {
if (expression.getLanguage() == language) return expression;
final ExpressionConverter converter = EP.forLanguage(language);
if (converter == null) return null;
return converter.convert(expression, project);
}
}
@@ -31,7 +31,7 @@ import com.intellij.usageView.UsageInfo;
* Usage of an expression in method
*/
public class InternalUsageInfo extends UsageInfo {
InternalUsageInfo(PsiElement e) {
public InternalUsageInfo(PsiElement e) {
super(e);
}
}
@@ -15,13 +15,13 @@
*/
package com.intellij.refactoring.introduceParameter;
import org.jetbrains.annotations.NotNull;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiLocalVariable;
import com.intellij.psi.PsiType;
import gnu.trove.TIntArrayList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface IntroduceParameterData {
@NotNull
@@ -32,27 +32,35 @@ public interface IntroduceParameterData {
@NotNull
PsiMethod getMethodToSearchFor();
PsiExpression getParameterInitializer();
PsiExpression getExpressionToSearch();
PsiLocalVariable getLocalVariable();
boolean isRemoveLocalVariable();
ExpressionWrapper getParameterInitializer();
@NotNull
String getParameterName();
boolean isReplaceAllOccurences();
/**
* @see com.intellij.refactoring.IntroduceParameterRefactoring
*/
int getReplaceFieldsWithGetters();
boolean isDeclareFinal();
boolean isGenerateDelegate();
@NotNull
PsiType getForcedType();
@NotNull
TIntArrayList getParametersToRemove();
interface ExpressionWrapper<RealExpression extends PsiElement> {
@NotNull
String getText();
@Nullable
PsiType getType();
@NotNull
RealExpression getExpression();
}
}
@@ -78,6 +78,7 @@ public class IntroduceParameterProcessor extends BaseRefactoringProcessor implem
private PsiType myForcedType;
private final TIntArrayList myParametersToRemove;
private final PsiManager myManager;
private JavaExpressionWrapper myInitializerWrapper;
/**
* if expressionToSearch is null, search for localVariable
@@ -114,12 +115,15 @@ public class IntroduceParameterProcessor extends BaseRefactoringProcessor implem
myManager = PsiManager.getInstance(project);
myParametersToRemove = parametersToRemove;
myInitializerWrapper = expressionToSearch == null ? null : new JavaExpressionWrapper(expressionToSearch);
}
protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) {
return new IntroduceParameterViewDescriptor(myMethodToSearchFor);
}
@NotNull
public PsiType getForcedType() {
return myForcedType;
}
@@ -160,7 +164,7 @@ public class IntroduceParameterProcessor extends BaseRefactoringProcessor implem
else if (ref instanceof PsiClass) {
result.add(new NoConstructorClassUsageInfo((PsiClass)ref));
}
else if (!insideMethodToBeReplaced(ref)) {
else if (!IntroduceParameterUtil.insideMethodToBeReplaced(ref, myMethodToReplaceIn)) {
result.add(new ExternalUsageInfo(ref));
}
else {
@@ -256,7 +260,7 @@ public class IntroduceParameterProcessor extends BaseRefactoringProcessor implem
final Set<PsiElement> result = collector.myResult;
if (!result.isEmpty()) {
for (final UsageInfo usageInfo : usageArray) {
if (usageInfo instanceof ExternalUsageInfo && isMethodUsage(usageInfo)) {
if (usageInfo instanceof ExternalUsageInfo && IntroduceParameterUtil.isMethodUsage(usageInfo)) {
final PsiElement place = usageInfo.getElement();
for (PsiElement element : result) {
if (element instanceof PsiField && myReplaceFieldsWithGetters != IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE) { //check getter access instead
@@ -283,13 +287,6 @@ public class IntroduceParameterProcessor extends BaseRefactoringProcessor implem
}
}
private static boolean isMethodUsage(UsageInfo usageInfo) {
for (IntroduceParameterMethodUsagesProcessor processor : IntroduceParameterMethodUsagesProcessor.EP_NAME.getExtensions()) {
if (processor.isMethodUsage(usageInfo)) return true;
}
return false;
}
public static class AnySupers extends JavaRecursiveElementWalkingVisitor {
private boolean myResult = false;
@Override public void visitSuperExpression(PsiSuperExpression expression) {
@@ -331,20 +328,6 @@ public class IntroduceParameterProcessor extends BaseRefactoringProcessor implem
}
}
private boolean insideMethodToBeReplaced(PsiElement methodUsage) {
PsiElement parent = methodUsage.getParent();
while(parent != null) {
if (parent.equals(myMethodToReplaceIn)) {
return true;
}
parent = parent.getParent();
}
return false;
}
protected void refreshElements(PsiElement[] elements) {
}
protected void performRefactoring(UsageInfo[] usages) {
try {
PsiElementFactory factory = JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory();
@@ -360,29 +343,11 @@ public class IntroduceParameterProcessor extends BaseRefactoringProcessor implem
myParameterInitializer = RefactoringUtil.convertInitializerToNormalExpression(myParameterInitializer, initializerType);
}
myInitializerWrapper = new JavaExpressionWrapper(myParameterInitializer);
// Changing external occurences (the tricky part)
for (UsageInfo usage : usages) {
if (!(usage instanceof InternalUsageInfo)) {
if (usage instanceof DefaultConstructorImplicitUsageInfo) {
addSuperCall(usage, usages);
}
else if (usage instanceof NoConstructorClassUsageInfo) {
addDefaultConstructor(usage, usages);
}
else {
PsiElement element = usage.getElement();
if (element instanceof PsiMethod) {
if (!myManager.areElementsEquivalent(element, myMethodToReplaceIn)) {
changeMethodSignatureAndResolveFieldConflicts(usage, usages);
}
}
else if (!myGenerateDelegate) {
changeExternalUsage(usage, usages);
}
}
}
}
IntroduceParameterUtil.processUsages(usages, this);
if (myGenerateDelegate) {
generateDelegate(myMethodToReplaceIn);
@@ -401,9 +366,9 @@ public class IntroduceParameterProcessor extends BaseRefactoringProcessor implem
// (signature of myMethodToReplaceIn will be either changed now or have already been changed)
LOG.assertTrue(initializerType.isValid());
final FieldConflictsResolver fieldConflictsResolver = new FieldConflictsResolver(myParameterName, myMethodToReplaceIn.getBody());
changeMethodSignatureAndResolveFieldConflicts(new UsageInfo(myMethodToReplaceIn), usages);
IntroduceParameterUtil.changeMethodSignatureAndResolveFieldConflicts(new UsageInfo(myMethodToReplaceIn), usages, this);
if (myMethodToSearchFor != myMethodToReplaceIn) {
changeMethodSignatureAndResolveFieldConflicts(new UsageInfo(myMethodToSearchFor), usages);
IntroduceParameterUtil.changeMethodSignatureAndResolveFieldConflicts(new UsageInfo(myMethodToSearchFor), usages, this);
}
ChangeContextUtil.clearContextInfo(myParameterInitializer);
@@ -469,18 +434,6 @@ public class IntroduceParameterProcessor extends BaseRefactoringProcessor implem
return (PsiMethod)methodToReplaceIn.getContainingClass().addBefore(delegate, methodToReplaceIn);
}
private void addDefaultConstructor(UsageInfo usage, UsageInfo[] usages) throws IncorrectOperationException {
for (IntroduceParameterMethodUsagesProcessor processor : IntroduceParameterMethodUsagesProcessor.EP_NAME.getExtensions()) {
if (!processor.processAddDefaultConstructor(this, usage, usages)) break;
}
}
private void addSuperCall(UsageInfo usage, UsageInfo[] usages) throws IncorrectOperationException {
for (IntroduceParameterMethodUsagesProcessor processor : IntroduceParameterMethodUsagesProcessor.EP_NAME.getExtensions()) {
if (!processor.processAddSuperCall(this, usage, usages)) break;
}
}
static PsiType getInitializerType(PsiType forcedType, PsiExpression parameterInitializer, PsiLocalVariable localVariable) {
final PsiType initializerType;
if (forcedType == null) {
@@ -542,22 +495,10 @@ public class IntroduceParameterProcessor extends BaseRefactoringProcessor implem
});
}
private void changeExternalUsage(UsageInfo usage, UsageInfo[] usages) throws IncorrectOperationException {
for (IntroduceParameterMethodUsagesProcessor processor: IntroduceParameterMethodUsagesProcessor.EP_NAME.getExtensions()) {
if (!processor.processChangeMethodUsage(this, usage, usages)) break;
}
}
protected String getCommandName() {
return RefactoringBundle.message("introduce.parameter.command", UsageViewUtil.getDescriptiveName(myMethodToReplaceIn));
}
private void changeMethodSignatureAndResolveFieldConflicts(UsageInfo usage, UsageInfo[] usages) throws IncorrectOperationException {
for (IntroduceParameterMethodUsagesProcessor processor : IntroduceParameterMethodUsagesProcessor.EP_NAME.getExtensions()) {
if (!processor.processChangeMethodSignature(this, usage, usages)) break;
}
}
@Nullable
private static PsiParameter getAnchorParameter(PsiMethod methodToReplaceIn) {
PsiParameterList parameterList = methodToReplaceIn.getParameterList();
@@ -584,20 +525,8 @@ public class IntroduceParameterProcessor extends BaseRefactoringProcessor implem
return myMethodToSearchFor;
}
public PsiExpression getParameterInitializer() {
return myParameterInitializer;
}
public PsiExpression getExpressionToSearch() {
return myExpressionToSearch;
}
public PsiLocalVariable getLocalVariable() {
return myLocalVariable;
}
public boolean isRemoveLocalVariable() {
return myRemoveLocalVariable;
public JavaExpressionWrapper getParameterInitializer() {
return myInitializerWrapper;
}
@NotNull
@@ -605,10 +534,6 @@ public class IntroduceParameterProcessor extends BaseRefactoringProcessor implem
return myParameterName;
}
public boolean isReplaceAllOccurences() {
return myReplaceAllOccurences;
}
public boolean isDeclareFinal() {
return myDeclareFinal;
}
@@ -622,10 +547,6 @@ public class IntroduceParameterProcessor extends BaseRefactoringProcessor implem
return myParametersToRemove;
}
public PsiManager getManager() {
return myManager;
}
@NotNull
public Project getProject() {
return myProject;
@@ -0,0 +1,126 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.refactoring.introduceParameter;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiMethod;
import com.intellij.refactoring.util.usageInfo.DefaultConstructorImplicitUsageInfo;
import com.intellij.refactoring.util.usageInfo.NoConstructorClassUsageInfo;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.IncorrectOperationException;
import java.util.ArrayList;
import java.util.List;
/**
* @author Maxim.Medvedev
*/
public class IntroduceParameterUtil {
private IntroduceParameterUtil() {
}
public static boolean insideMethodToBeReplaced(PsiElement methodUsage, final PsiMethod methodToReplaceIn) {
PsiElement parent = methodUsage.getParent();
while (parent != null) {
if (parent.equals(methodToReplaceIn)) {
return true;
}
parent = parent.getParent();
}
return false;
}
public static boolean isMethodUsage(UsageInfo usageInfo) {
for (IntroduceParameterMethodUsagesProcessor processor : IntroduceParameterMethodUsagesProcessor.EP_NAME.getExtensions()) {
if (processor.isMethodUsage(usageInfo)) return true;
}
return false;
}
public static void addSuperCall(UsageInfo usage, UsageInfo[] usages, final IntroduceParameterData data)
throws IncorrectOperationException {
for (IntroduceParameterMethodUsagesProcessor processor : IntroduceParameterMethodUsagesProcessor.EP_NAME.getExtensions()) {
if (!processor.processAddSuperCall(data, usage, usages)) break;
}
}
public static void addDefaultConstructor(UsageInfo usage, UsageInfo[] usages, final IntroduceParameterData data)
throws IncorrectOperationException {
for (IntroduceParameterMethodUsagesProcessor processor : IntroduceParameterMethodUsagesProcessor.EP_NAME.getExtensions()) {
if (!processor.processAddDefaultConstructor(data, usage, usages)) break;
}
}
public static void changeExternalUsage(UsageInfo usage, UsageInfo[] usages, final IntroduceParameterData data)
throws IncorrectOperationException {
for (IntroduceParameterMethodUsagesProcessor processor : IntroduceParameterMethodUsagesProcessor.EP_NAME.getExtensions()) {
if (!processor.processChangeMethodUsage(data, usage, usages)) break;
}
}
public static void changeMethodSignatureAndResolveFieldConflicts(UsageInfo usage,
UsageInfo[] usages,
final IntroduceParameterData data)
throws IncorrectOperationException {
for (IntroduceParameterMethodUsagesProcessor processor : IntroduceParameterMethodUsagesProcessor.EP_NAME.getExtensions()) {
if (!processor.processChangeMethodSignature(data, usage, usages)) break;
}
}
public static void processUsages(UsageInfo[] usages, IntroduceParameterData data) {
PsiManager manager = PsiManager.getInstance(data.getProject());
List<UsageInfo> methodUsages = new ArrayList<UsageInfo>();
for (UsageInfo usage : usages) {
if (usage instanceof InternalUsageInfo) continue;
if (usage instanceof DefaultConstructorImplicitUsageInfo) {
addSuperCall(usage, usages, data);
}
else if (usage instanceof NoConstructorClassUsageInfo) {
addDefaultConstructor(usage, usages, data);
}
else {
PsiElement element = usage.getElement();
if (element instanceof PsiMethod) {
if (!manager.areElementsEquivalent(element, data.getMethodToReplaceIn())) {
methodUsages.add(usage);
}
}
else if (!data.isGenerateDelegate()) {
changeExternalUsage(usage, usages, data);
}
}
}
for (UsageInfo usage : methodUsages) {
changeMethodSignatureAndResolveFieldConflicts(usage, usages, data);
}
}
public static boolean isMethodInUsages(IntroduceParameterData data, PsiMethod method, UsageInfo[] usages) {
PsiManager manager = PsiManager.getInstance(data.getProject());
for (UsageInfo info : usages) {
if (!(info instanceof DefaultConstructorImplicitUsageInfo) && manager.areElementsEquivalent(info.getElement(), method)) {
return true;
}
}
return false;
}
}
@@ -0,0 +1,30 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.refactoring.introduceParameter;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiElement;
/**
* @author Maxim.Medvedev
*/
public class JavaExpressionConverter extends ExpressionConverter {
@Override
protected PsiElement convert(PsiElement expression, Project project) {
return JavaPsiFacade.getElementFactory(project).createExpressionFromText(expression.getText(), expression);
}
}
@@ -0,0 +1,49 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.refactoring.introduceParameter;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiType;
import org.jetbrains.annotations.NotNull;
/**
* @author Maxim.Medvedev
*/
public class JavaExpressionWrapper implements IntroduceParameterData.ExpressionWrapper {
private final PsiExpression myExpression;
public JavaExpressionWrapper(@NotNull PsiExpression expression) {
myExpression = expression;
}
@NotNull
@Override
public String getText() {
return myExpression.getText();
}
@Override
public PsiType getType() {
return myExpression.getType();
}
@NotNull
@Override
public PsiElement getExpression() {
return myExpression;
}
}
@@ -17,6 +17,7 @@ package com.intellij.refactoring.introduceParameter;
import com.intellij.codeInsight.ChangeContextUtil;
import com.intellij.lang.Language;
import com.intellij.lang.StdLanguages;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
@@ -28,7 +29,6 @@ import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.util.FieldConflictsResolver;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.refactoring.util.javadoc.MethodJavaDocHelper;
import com.intellij.refactoring.util.usageInfo.DefaultConstructorImplicitUsageInfo;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.VisibilityUtil;
@@ -81,18 +81,22 @@ public class JavaIntroduceParameterMethodUsagesProcessor implements IntroducePar
//if we insert parameter in method usage which is contained in method in which we insert this parameter too, we must insert parameter name instead of its initializer
PsiMethod method = PsiTreeUtil.getParentOfType(argList, PsiMethod.class);
if (method != null && isMethodInUsages(data, method, usages)) {
if (method != null && IntroduceParameterUtil.isMethodInUsages(data, method, usages)) {
argList
.addAfter(JavaPsiFacade.getElementFactory(data.getProject()).createExpressionFromText(data.getParameterName(), argList), anchor);
}
else {
ChangeContextUtil.encodeContextInfo(data.getParameterInitializer(), true);
PsiExpression newArg = (PsiExpression)argList.addAfter(data.getParameterInitializer(), anchor);
PsiElement initializer =
ExpressionConverter.getExpression(data.getParameterInitializer().getExpression(), StdLanguages.JAVA, data.getProject());
assert initializer instanceof PsiExpression;
ChangeContextUtil.encodeContextInfo(initializer, true);
PsiExpression newArg = (PsiExpression)argList.addAfter(initializer, anchor);
ChangeContextUtil.decodeContextInfo(newArg, null, null);
ChangeContextUtil.clearContextInfo(data.getParameterInitializer());
ChangeContextUtil.clearContextInfo(initializer);
// here comes some postprocessing...
new OldReferenceResolver(callExpression, newArg, data.getMethodToReplaceIn(), data.getReplaceFieldsWithGetters(),
data.getParameterInitializer()).resolve();
new OldReferenceResolver(callExpression, newArg, data.getMethodToReplaceIn(), data.getReplaceFieldsWithGetters(), initializer)
.resolve();
}
@@ -102,16 +106,6 @@ public class JavaIntroduceParameterMethodUsagesProcessor implements IntroducePar
return false;
}
private static boolean isMethodInUsages(IntroduceParameterData data, PsiMethod method, UsageInfo[] usages) {
PsiManager manager = PsiManager.getInstance(data.getProject());
for (UsageInfo info : usages) {
if (!(info instanceof DefaultConstructorImplicitUsageInfo) && manager.areElementsEquivalent(info.getElement(), method)) {
return true;
}
}
return false;
}
private static void removeParametersFromCall(@NotNull final PsiExpressionList argList, TIntArrayList parametersToRemove) {
final PsiExpression[] exprs = argList.getExpressions();
parametersToRemove.forEachDescending(new TIntProcedure() {
@@ -35,7 +35,7 @@ import java.util.Set;
* Date: Apr 29, 2009 2:03:38 PM
*/
public class OldReferenceResolver {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.introduceParameter.OldRefernceResolver");
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.introduceParameter.OldReferenceResolver");
private final PsiCall myContext;
private final PsiExpression myExpr;
@@ -46,13 +46,13 @@ public class OldReferenceResolver {
private final Project myProject;
private final PsiManager myManager;
private final int myReplaceFieldsWithGetters;
private final PsiExpression myParameterInitializer;
private final PsiElement myParameterInitializer;
public OldReferenceResolver(PsiCall context,
PsiExpression expr,
PsiMethod methodToReplaceIn,
int replaceFieldsWithGetters,
PsiExpression parameterInitializer) throws IncorrectOperationException {
PsiElement parameterInitializer) throws IncorrectOperationException {
myContext = context;
myExpr = expr;
myReplaceFieldsWithGetters = replaceFieldsWithGetters;
@@ -15,8 +15,10 @@
*/
package com.intellij.codeInsight.completion
import com.intellij.codeInsight.completion.impl.CompletionServiceImpl
import com.intellij.codeInsight.lookup.Lookup
import com.intellij.codeInsight.lookup.LookupManager
import com.intellij.codeInsight.lookup.impl.LookupImpl
import com.intellij.ide.DataManager
import com.intellij.ide.ui.UISettings
import com.intellij.openapi.actionSystem.IdeActions
@@ -30,7 +32,7 @@ import com.intellij.openapi.extensions.LoadingOrder
import com.intellij.openapi.progress.ProgressManager
import com.intellij.psi.PsiFile
/**
/**
* @author peter
*/
class JavaAutoPopupTest extends CompletionAutoPopupTestCase {
@@ -593,6 +595,7 @@ public interface Test {
try {
edt {
assert !lookup.calculating
lookup.hide()
def file = myFixture.addFileToProject("b.java", "")
another = EditorFactory.instance.createEditor(file.viewProvider.document, project)
@@ -601,9 +604,14 @@ public interface Test {
}
joinAlarm()
joinCompletion()
joinAlarm()
def l1 = LookupManager.getActiveLookup(another)
LookupImpl l1 = LookupManager.getActiveLookup(another)
if (l1) {
printThreadDump()
println l1.items
println l1.calculating
println myFixture.editor
println another
println CompletionServiceImpl.completionPhase
assert false : l1.items
}
type 'l'
Binary file not shown.

After

Width:  |  Height:  |  Size: 817 B

@@ -296,6 +296,11 @@ public abstract class CompletionPhase implements Disposable {
CompletionServiceImpl.setCompletionPhase(NoCompletion);
}
@Override
public String toString() {
return "EmptyAutoPopup,editor=" + editor;
}
@Override
public CompletionProgressIndicator newCompletionStarted() {
return null;
@@ -31,6 +31,8 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiUtilBase;
import java.awt.event.InputEvent;
/**
* @author peter
*/
@@ -53,7 +55,8 @@ public abstract class BaseCodeCompletionAction extends AnAction implements HintM
case CLASS_NAME: FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.EDITING_COMPLETION_CLASSNAME);
}
new CodeCompletionHandlerBase(myCompletionType).invokeCompletion(project, editor, 1, e.getInputEvent().getModifiers() != 0);
final InputEvent inputEvent = e.getInputEvent();
new CodeCompletionHandlerBase(myCompletionType).invokeCompletion(project, editor, 1, inputEvent != null && inputEvent.getModifiers() != 0);
}
@Override
@@ -19,14 +19,13 @@ package com.intellij.find.impl.livePreview;
import com.intellij.codeInsight.highlighting.HighlightManager;
import com.intellij.ide.IdeTooltipManager;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.editor.VisualPosition;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.VisibleAreaEvent;
import com.intellij.openapi.editor.event.VisibleAreaListener;
import com.intellij.openapi.editor.markup.CustomHighlighterRenderer;
import com.intellij.openapi.editor.markup.EffectType;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.editor.markup.TextAttributes;
@@ -34,12 +33,10 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.BalloonBuilder;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Segment;
import com.intellij.openapi.util.TextRange;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.containers.HashSet;
import com.intellij.util.ui.PositionTracker;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
@@ -68,13 +65,15 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele
private RangeHighlighter myCursorHighlighter;
private final List<VisibleAreaListener> myVisibleAreaListenersToRemove = new ArrayList<VisibleAreaListener>();
private static final TextAttributes EXCLUDED_TARGET_ATTRIBUTES = new TextAttributes(Color.BLACK, Color.YELLOW,
Color.BLACK, EffectType.STRIKEOUT, 0);
private static TextAttributes strikout(TextAttributes attributes) {
TextAttributes textAttributes = attributes.clone();
textAttributes.setEffectColor(Color.BLACK);
textAttributes.setEffectType(EffectType.STRIKEOUT);
return textAttributes;
}
private static final TextAttributes OTHER_TARGETS_ATTRIBUTES = new TextAttributes(Color.BLACK, Color.GREEN, null, null, 0);
private static final TextAttributes MAIN_TARGET_ATTRIBUTES = new TextAttributes(Color.BLACK, Color.YELLOW, null, null, 0);
private Delegate myDelegate;
private SearchResults mySearchResults;
@@ -206,10 +205,13 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele
for (TextRange textRange : o.getSecondaryRanges()) {
highlightRange(textRange, OTHER_TARGETS_ATTRIBUTES, myHighlighters);
}
TextAttributes attrs = EditorColorsManager.getInstance().
getGlobalScheme().getAttributes(EditorColors.TEXT_SEARCH_RESULT_ATTRIBUTES);
if (mySearchResults.isExcluded(o)) {
highlightRange(o.getPrimaryRange(), EXCLUDED_TARGET_ATTRIBUTES, myHighlighters);
highlightRange(o.getPrimaryRange(), strikout(attrs), myHighlighters);
} else {
highlightRange(o.getPrimaryRange(), MAIN_TARGET_ATTRIBUTES, myHighlighters);
highlightRange(o.getPrimaryRange(), attrs, myHighlighters);
}
}
}
@@ -205,7 +205,7 @@ public class NavBarPanel extends OpaquePanel.List implements DataProvider, Popup
return false;
}
private static Object optimizeTarget(Object target) {
static Object optimizeTarget(Object target) {
if (target instanceof PsiDirectory && ((PsiDirectory)target).getFiles().length == 0) {
final PsiDirectory[] subDir = ((PsiDirectory)target).getSubdirectories();
if (subDir.length == 1) {
@@ -487,7 +487,7 @@ public class NavBarPanel extends OpaquePanel.List implements DataProvider, Popup
|| (myNodeHint != null && myNodeHint.isVisible());
}
private void navigateInsideBar(final Object object) {
void navigateInsideBar(final Object object) {
myContextObject = null;
myUpdateQueue.cancelAllUpdates();
@@ -16,6 +16,7 @@
package com.intellij.ide.navigationToolbar;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.ui.HintHint;
@@ -30,7 +31,10 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/**
* @author Konstantin Bulenkov
@@ -68,9 +72,22 @@ public class NavBarPopup extends LightweightHint {
}
public void show(final NavBarItem item) {
show(item, true);
}
private void show(final NavBarItem item, boolean checkRepaint) {
final RelativePoint point = new RelativePoint(item, new Point(0, item.getHeight()));
final Point p = point.getPoint(myPanel);
show(myPanel, p.x, p.y, myPanel, new HintHint(myPanel, p));
if (p.x == 0 && p.y == 0 && checkRepaint) { // need repaint of nav bar panel
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
show(item, false); // end-less loop protection
}
});
} else {
show(myPanel, p.x, p.y, myPanel, new HintHint(myPanel, p));
}
}
private static JBList createPopupContent(final NavBarPanel panel, Object[] siblings, int selectedIndex) {
@@ -90,25 +107,28 @@ public class NavBarPopup extends LightweightHint {
});
list.setBorder(IdeBorderFactory.createEmptyBorder(5,5,5,5));
list.setSelectedIndex(selectedIndex);
list.registerKeyboardAction(createMoveAction(panel, -1), KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), JComponent.WHEN_FOCUSED);
list.registerKeyboardAction(createMoveAction(panel, 1), KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), JComponent.WHEN_FOCUSED);
list.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
panel.cancelPopup();
}
});
installMoveAction(list, panel, -1, KeyEvent.VK_LEFT);
installMoveAction(list, panel, 1, KeyEvent.VK_RIGHT);
installEnterAction(list, panel, KeyEvent.VK_ENTER);
return list;
}
private static void installEnterAction(final JBList list, final NavBarPanel panel, int keyCode) {
final AbstractAction action = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
panel.navigateInsideBar(NavBarPanel.optimizeTarget(list.getSelectedValue()));
}
};
list.registerKeyboardAction(action, KeyStroke.getKeyStroke(keyCode, 0), JComponent.WHEN_FOCUSED);
}
public Object getSelectedValue() {
return ((JBList)getComponent()).getSelectedValue();
}
private static Action createMoveAction(final NavBarPanel panel, final int direction) {
return new AbstractAction() {
private static void installMoveAction(JBList list, final NavBarPanel panel, final int direction, final int keyCode) {
final AbstractAction action = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
panel.cancelPopup();
@@ -116,31 +136,6 @@ public class NavBarPopup extends LightweightHint {
panel.restorePopup();
}
};
}
private static class CancelNavBarPopup extends AbstractAction implements FocusListener {
private final NavBarPanel myPanel;
private CancelNavBarPopup(NavBarPanel panel) {
myPanel = panel;
}
@Override
public void actionPerformed(ActionEvent e) {
cancelPopup();
}
@Override
public void focusGained(FocusEvent e) {
}
@Override
public void focusLost(FocusEvent e) {
cancelPopup();
}
private void cancelPopup() {
myPanel.cancelPopup();
}
list.registerKeyboardAction(action, KeyStroke.getKeyStroke(keyCode, 0), JComponent.WHEN_FOCUSED);
}
}
@@ -363,7 +363,6 @@ public class SearchableOptionsRegistrarImpl extends SearchableOptionsRegistrar {
for (String opt : options) {
if (isStopWord(opt)) continue;
final String processed = PorterStemmerUtil.stem(opt);
assert processed != null;
if (isStopWord(processed)) continue;
result.add(opt);
}
@@ -377,7 +376,7 @@ public class SearchableOptionsRegistrarImpl extends SearchableOptionsRegistrar {
for (String opt : options) {
if (isStopWord(opt)) continue;
opt = PorterStemmerUtil.stem(opt);
assert opt != null;
if (opt == null) continue;
result.add(opt);
}
return result;
@@ -121,8 +121,8 @@ public class LightweightHint extends UserDataHolderBase implements Hint {
LOG.assertTrue(myParentComponent.isShowing());
myEscListener = new MyEscListener();
myComponent.registerKeyboardAction(myEscListener, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
JComponent.WHEN_IN_FOCUSED_WINDOW);
myComponent.registerKeyboardAction(myEscListener, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);
myComponent.registerKeyboardAction(myEscListener, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_FOCUSED);
final JLayeredPane layeredPane = parentComponent.getRootPane().getLayeredPane();
myComponent.validate();
@@ -104,6 +104,7 @@ public class RemoteObject implements Remote, Unreferenced {
if (foreignException) {
final RuntimeException wrapper = new RuntimeException(ex.toString());
wrapper.setStackTrace(ex.getStackTrace());
wrapper.initCause(wrapException(ex.getCause()));
ex = wrapper;
}
return ex;
@@ -15,11 +15,19 @@
*/
package com.intellij.execution.rmi;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.naming.spi.InitialContextFactory;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.rmi.Remote;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.ExportException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Hashtable;
import java.util.Random;
public class RemoteServer {
@@ -28,6 +36,7 @@ public class RemoteServer {
protected static void start(Remote remote) throws Exception {
setupRMI();
banJNDI();
if (ourRemote != null) throw new AssertionError("Already started");
@@ -71,4 +80,23 @@ public class RemoteServer {
// do not use http tunnelling
System.setProperty("java.rmi.server.disableHttp", "true");
}
private static void banJNDI() {
if (System.getProperty(InitialContext.INITIAL_CONTEXT_FACTORY) == null) {
System.setProperty(InitialContext.INITIAL_CONTEXT_FACTORY, "com.intellij.execution.rmi.RemoteServer$Jndi");
}
}
public static class Jndi implements InitialContextFactory, InvocationHandler {
@Override
public Context getInitialContext(final Hashtable<?, ?> environment) throws NamingException {
return (Context) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { Context.class}, this );
}
@Override
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
return null;
}
}
}
+2
View File
@@ -105,6 +105,8 @@
<constantExpressionEvaluator language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.psi.util.GroovyConstantExpressionEvaluator"/>
<annotationSupport language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.annotation.GroovyAnnotationSupport"/>
<expressionConverter language="Groovy" implementationClass="org.jetbrains.plugins.groovy.refactoring.introduce.parameter.GroovyExpressionConverter"/>
<errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
<fileTypeFactory implementation="org.jetbrains.plugins.groovy.GroovyFileTypeLoader"/>
@@ -104,6 +104,13 @@ public class SwitchStatement implements GroovyElementTypes {
parser.parseSwitchCaseList(builder);
}
sectionMarker.done(CASE_SECTION);
if (builder.getTokenType() != kCASE && builder.getTokenType() != kDEFAULT && builder.getTokenType() != mRCURLY) {
builder.error("case, default or } expected");
while (!builder.eof() && builder.getTokenType() != kCASE && builder.getTokenType() != kDEFAULT && builder.getTokenType() != mRCURLY) {
builder.advanceLexer();
}
}
}
ParserUtils.getToken(builder, mRCURLY, GroovyBundle.message("rcurly.expected"));
}
@@ -27,4 +27,7 @@ public interface GrQualifiedReference<Qualifier extends PsiElement> extends PsiQ
Qualifier getQualifier();
void setQualifier(@Nullable Qualifier qualifier);
@Nullable
PsiElement getReferenceNameElement();
}
@@ -31,9 +31,6 @@ public interface GrReferenceElement<Q extends PsiElement> extends GroovyPsiEleme
@Nullable
String getReferenceName();
@Nullable
PsiElement getReferenceNameElement();
PsiElement resolve();
GroovyResolveResult advancedResolve();
@@ -138,4 +138,8 @@ public abstract class GrReferenceElementImpl<Q extends PsiElement> extends Groov
public GrTypeArgumentList getTypeArgumentList() {
return (GrTypeArgumentList)findChildByType(GroovyElementTypes.TYPE_ARGUMENTS);
}
public void setQualifier(@Nullable Q newQualifier) {
PsiImplUtil.setQualifier(this, newQualifier);
}
}
@@ -33,7 +33,9 @@ import com.intellij.psi.util.MethodSignatureUtil;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.GrNamedElement;
import org.jetbrains.plugins.groovy.lang.psi.GrQualifiedReference;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
@@ -399,4 +401,26 @@ public class PsiImplUtil {
}
}
}
public static <T extends PsiElement> void setQualifier(GrQualifiedReference<T> ref, T newQualifier) {
final T oldQualifier = ref.getQualifier();
final ASTNode node = ref.getNode();
final PsiElement refNameElement = ref.getReferenceNameElement();
if (newQualifier == null) {
if (oldQualifier != null && refNameElement != null) {
ref.deleteChildRange(ref.getFirstChild(), refNameElement.getPrevSibling());
}
} else {
if (oldQualifier == null) {
if (refNameElement != null) {
ref.addBefore(newQualifier, refNameElement);
node.addLeaf(GroovyTokenTypes.mDOT, ".", refNameElement.getNode());
}
}
else {
oldQualifier.replace(newQualifier);
}
}
}
}
@@ -129,7 +129,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
final PsiElement element = candidate.getElement();
if (element instanceof PsiField) {
final PsiClass containingClass = ((PsiField)element).getContainingClass();
if (containingClass != null && PsiTreeUtil.isAncestor(containingClass, this, true)) return fieldCandidates;
if (containingClass != null && PsiTreeUtil.isContextAncestor(containingClass, this, true)) return fieldCandidates;
}
else {
return fieldCandidates;
@@ -227,7 +227,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
final PsiElement element = candidate.getElement();
if (element instanceof GrField) {
final PsiClass containingClass = ((PsiField)element).getContainingClass();
if (containingClass != null && PsiTreeUtil.isAncestor(containingClass, this, true)) return propertyCandidates;
if (containingClass != null && PsiTreeUtil.isContextAncestor(containingClass, this, true)) return propertyCandidates;
}
}
}
@@ -883,29 +883,6 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
return RESOLVER.resolve(this, true);
}
public void setQualifier(GrExpression newQualifier) {
final GrExpression oldQualifier = getQualifierExpression();
final ASTNode node = getNode();
final PsiElement refNameElement = getReferenceNameElement();
if (newQualifier == null) {
if (oldQualifier != null) {
if (refNameElement != null) {
node.removeRange(node.getFirstChildNode(), refNameElement.getNode());
}
}
} else {
if (oldQualifier != null) {
node.replaceChild(oldQualifier.getNode(), newQualifier.getNode());
} else {
if (refNameElement != null) {
node.addChild(newQualifier.getNode(), refNameElement.getNode());
node.addLeaf(GroovyTokenTypes.mDOT, ".", refNameElement.getNode());
}
}
}
}
public GrReferenceExpression bindToElementViaStaticImport(@NotNull PsiClass qualifierClass) {
if (getQualifier() != null) {
throw new IncorrectOperationException("Reference has qualifier");
@@ -36,7 +36,7 @@ public class GrThisReferenceExpressionImpl extends GrThisSuperReferenceExpressio
public PsiType getType() {
final GrReferenceExpression qualifier = getQualifier();
if (qualifier == null) {
GroovyPsiElement context = PsiTreeUtil.getParentOfType(this, GrTypeDefinition.class, GroovyFile.class);
GroovyPsiElement context = PsiTreeUtil.getContextOfType(this, GrTypeDefinition.class, GroovyFile.class);
if (context instanceof GrTypeDefinition) {
return createType((PsiClass)context);
}
@@ -86,7 +86,7 @@ public class GrThisReferenceExpressionImpl extends GrThisSuperReferenceExpressio
return qualifier.resolve();
}
final GrTypeDefinition containingClass = PsiTreeUtil.getParentOfType(this, GrTypeDefinition.class, true, GroovyFile.class);
final GrTypeDefinition containingClass = PsiTreeUtil.getContextOfType(this, GrTypeDefinition.class, true, GroovyFile.class);
if (containingClass != null) return containingClass;
final PsiFile containingFile = getContainingFile();
if (containingFile instanceof GroovyFile) {
@@ -11,13 +11,12 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
/**
* @author Maxim.Medvedev
@@ -36,24 +35,12 @@ public abstract class GrThisSuperReferenceExpressionBase extends GrExpressionImp
@Override
public void setQualifier(@Nullable GrReferenceExpression newQualifier) {
final GrExpression oldQualifier = getQualifier();
final ASTNode node = getNode();
final PsiElement refNameElement = getLastChild();
assert refNameElement != null;
if (newQualifier == null) {
if (oldQualifier != null) {
node.removeRange(node.getFirstChildNode(), refNameElement.getNode());
}
}
else {
if (oldQualifier != null) {
node.replaceChild(oldQualifier.getNode(), newQualifier.getNode());
}
else {
node.addChild(newQualifier.getNode(), refNameElement.getNode());
node.addLeaf(GroovyTokenTypes.mDOT, ".", refNameElement.getNode());
}
}
PsiImplUtil.setQualifier(this, newQualifier);
}
@Override
public PsiElement getReferenceNameElement() {
return getLastChild();
}
@Override
@@ -30,7 +30,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
@@ -53,31 +56,16 @@ public class GrClosureSignatureUtil {
public static GrClosureSignature createSignature(GrCall call) {
if (call instanceof GrMethodCall) {
final GrExpression invokedExpression = ((GrMethodCall)call).getInvokedExpression();
return getSignatureByInvokedExpression(invokedExpression);
final PsiType type = invokedExpression.getType();
if (type instanceof GrClosureType) return ((GrClosureType)type).getSignature();
}
if (call instanceof GrConstructorCall) {
final GroovyResolveResult resolveResult = ((GrConstructorCall)call).resolveConstructorGenerics();
final PsiElement element = resolveResult.getElement();
if (element instanceof PsiMethod) {
return createSignature(((PsiMethod)element), resolveResult.getSubstitutor());
}
final GroovyResolveResult resolveResult = call.advancedResolve();
final PsiElement element = resolveResult.getElement();
if (element instanceof PsiMethod) {
return createSignature((PsiMethod)element, resolveResult.getSubstitutor());
}
return null;
}
@Nullable
private static GrClosureSignature getSignatureByInvokedExpression(GrExpression invokedExpression) {
final PsiType type = invokedExpression.getType();
if (type instanceof GrClosureType) return ((GrClosureType)type).getSignature();
if (invokedExpression instanceof GrReferenceExpression) {
final GroovyResolveResult resolveResult = ((GrReferenceExpression)invokedExpression).advancedResolve();
final PsiElement element = resolveResult.getElement();
if (element instanceof PsiMethod) {
return createSignature((PsiMethod)element, resolveResult.getSubstitutor());
}
}
return null;
}
@@ -28,7 +28,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.completion.GroovyCompletionUtil;
import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocReferenceElement;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
@@ -88,22 +87,6 @@ public class GrCodeReferenceElementImpl extends GrReferenceElementImpl<GrCodeRef
return (GrCodeReferenceElement) findChildByType(GroovyElementTypes.REFERENCE_ELEMENT);
}
public void setQualifier(@Nullable GrCodeReferenceElement newQualifier) {
final GrCodeReferenceElement qualifier = getQualifier();
if (newQualifier == null) {
if (qualifier == null) return;
getNode().removeRange(getNode().getFirstChildNode(), getReferenceNameElement().getNode());
} else {
if (qualifier == null) {
final ASTNode refNameNode = getReferenceNameElement().getNode();
getNode().addChild(newQualifier.getNode(), refNameNode);
getNode().addLeaf(GroovyTokenTypes.mDOT, ".", refNameNode);
} else {
getNode().replaceChild(qualifier.getNode(), newQualifier.getNode());
}
}
}
enum ReferenceKind {
CLASS,
CLASS_OR_PACKAGE,
@@ -313,30 +313,30 @@ public class PsiUtil {
final PsiElement resolved = ref.resolve();
if (resolved == null) return false;
ref.setQualifier(null);
if (ref.isReferenceTo(resolved)) return true;
final GrQualifiedReference<Qualifier> copy = (GrQualifiedReference<Qualifier>)ref.copy();
if (resolved instanceof PsiClass) {
final GroovyFileBase file = (GroovyFileBase)ref.getContainingFile();
final PsiClass clazz = (PsiClass)resolved;
final String qName = clazz.getQualifiedName();
if (qName != null) {
if (mayInsertImport(ref)) {
final GrImportStatement added = file.addImportForClass(clazz);
if (!ref.isReferenceTo(resolved)) {
file.removeImport(added);
copy.setQualifier(null);
if (!copy.isReferenceTo(resolved)) {
if (resolved instanceof PsiClass) {
final GroovyFileBase file = (GroovyFileBase)ref.getContainingFile();
final PsiClass clazz = (PsiClass)resolved;
final String qName = clazz.getQualifiedName();
if (qName != null) {
if (mayInsertImport(ref)) {
final GrImportStatement added = file.addImportForClass(clazz);
if (!copy.isReferenceTo(resolved)) {
file.removeImport(added);
return false;
}
}
}
}
else {
return false;
}
}
if (!ref.isReferenceTo(resolved)) {
ref.setQualifier((Qualifier)qualifier.copy());
return false;
}
else {
return true;
}
ref.setQualifier(null);
return true;
}
private static <Qualifier extends PsiElement> boolean canShorten(Qualifier qualifier) {
@@ -70,6 +70,12 @@ public class ResolverProcessor implements PsiScopeProcessor, NameHint, ClassHint
}
if (myResolveTargetKinds.contains(getResolveKind(element))) {
//hack for resolve of java local vars and parameters
//don't check field for name because they can be aliased imported
if (element instanceof PsiVariable && !(element instanceof PsiField) &&
myName != null && !myName.equals(((PsiVariable)element).getName())) {
return true;
}
PsiNamedElement namedElement = (PsiNamedElement)element;
PsiSubstitutor substitutor = state.get(PsiSubstitutor.KEY);
if (substitutor == null) substitutor = PsiSubstitutor.EMPTY;
@@ -154,3 +154,5 @@ Field.cannot.be.final.because.replaced.variable.has.lhs.usages=Selected variable
field.cannot.be.initialized.in.field.declaration=Field cannot be initialized in declaration
field.cannot.be.initialized.in.constructor(s)=Field cannot be initialized in constructor(s)
selected.variable.is.used.for.write=Selected variable is used for write
there.is.no.method=There is no containing method
remove.parameter.0.no.longer.used=Remove parameter ''{0}'' no longer used
@@ -31,6 +31,7 @@ import org.jetbrains.plugins.groovy.refactoring.changeSignature.GrChangeSignatur
import org.jetbrains.plugins.groovy.refactoring.extractMethod.GroovyExtractMethodHandler;
import org.jetbrains.plugins.groovy.refactoring.introduce.constant.GrIntroduceConstantHandler;
import org.jetbrains.plugins.groovy.refactoring.introduce.field.GrIntroduceFieldHandler;
import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.GrIntroduceParameterHandler;
import org.jetbrains.plugins.groovy.refactoring.introduce.variable.GroovyIntroduceVariableHandler;
/**
@@ -80,6 +81,11 @@ public class GroovyRefactoringSupportProvider extends RefactoringSupportProvider
return new GrIntroduceFieldHandler();
}
@Override
public RefactoringActionHandler getIntroduceParameterHandler() {
return new GrIntroduceParameterHandler();
}
@Override
public RefactoringActionHandler getIntroduceConstantHandler() {
return new GrIntroduceConstantHandler();
@@ -59,6 +59,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefini
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.util.GrDeclarationHolder;
import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner;
import java.util.*;
@@ -469,7 +470,7 @@ public abstract class GroovyRefactoringUtil {
/* if (declareFinal) {
com.intellij.psi.util.PsiUtil.setModifierProperty((decl.getMembers()[0]), PsiModifier.FINAL, true);
}*/
((GrCodeBlock)anchorStatement.getParent()).addStatementBefore(decl, anchorStatement);
((GrStatementOwner)anchorStatement.getParent()).addStatementBefore(decl, anchorStatement);
return id;
}
@@ -632,4 +633,26 @@ public abstract class GroovyRefactoringUtil {
}
return true;
}
public static GrExpression generateArgFromMultiArg(PsiSubstitutor substitutor,
List<PsiElement> arguments,
PsiType type,
final Project project) {
StringBuilder argText = new StringBuilder();
argText.append("[");
for (PsiElement argument : arguments) {
argText.append(argument.getText()).append(", ");
argument.delete();
}
argText.replace(argText.length() - 2, argText.length(), "]");
if (type instanceof PsiArrayType) {
type = substitutor.substitute(type);
String typeText = type.getCanonicalText();
if (type instanceof PsiEllipsisType) {
typeText = typeText.replace("...", "[]");
}
argText.append(" as ").append(typeText);
}
return GroovyPsiElementFactory.getInstance(project).createExpressionFromText(argText.toString());
}
}
@@ -455,23 +455,9 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
if (argInfo.isMultiArg) { //arguments for Map and varArg
if ((i != 0 || !(arguments.size() > 0 && arguments.iterator().next() instanceof GrNamedArgument)) &&
(i != parameters.length - 1 || !parameter.isVarargType())) {
StringBuilder argText = new StringBuilder();
argText.append("[");
for (PsiElement argument : arguments) {
argText.append(argument.getText()).append(", ");
argument.delete();
}
argText.replace(argText.length() - 2, argText.length(), "]");
PsiType type = parameter.createType(changeInfo.getMethod().getParameterList(), argumentList.getManager());
if (type instanceof PsiArrayType) {
type = substitutor.substitute(type);
String typeText = type.getCanonicalText();
if (type instanceof PsiEllipsisType) {
typeText = typeText.replace("...", "[]");
}
argText.append(" as ").append(typeText);
}
anchor = argumentList.addAfter(factory.createExpressionFromText(argText.toString()), anchor);
final PsiType type = parameter.createType(changeInfo.getMethod().getParameterList(), argumentList.getManager());
final GrExpression arg = GroovyRefactoringUtil.generateArgFromMultiArg(substitutor, arguments, type, element.getProject());
anchor = argumentList.addAfter(arg, anchor);
PsiUtil.shortenReferences((GroovyPsiElement)anchor);
}
}
@@ -0,0 +1,148 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.refactoring.introduce.parameter;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import java.util.ArrayList;
import java.util.List;
/**
* @author Maxim.Medvedev
*/
public class FieldConflictsResolver {
private static final Logger LOG =
Logger.getInstance("#org.jetbrains.plugins.groovy.refactoring.introduce.parameter.FieldConflictsResolver");
private final GrCodeBlock myScope;
private PsiField myField = null;
private List<GrReferenceExpression> myReferenceExpressions = null;
private PsiClass myQualifyingClass;
public FieldConflictsResolver(String name, GrCodeBlock scope) {
myScope = scope;
if (myScope == null) return;
final GroovyPsiElement resolved = ResolveUtil.resolveProperty(myScope, name);
if (resolved instanceof GrReferenceExpression || resolved == null) return;
assert resolved instanceof PsiVariable;
final PsiVariable oldVariable = (PsiVariable)resolved;
myField = oldVariable instanceof PsiField ? (PsiField) oldVariable : null;
if (!(oldVariable instanceof PsiField)) return;
myReferenceExpressions = new ArrayList<GrReferenceExpression>();
for (PsiReference reference : ReferencesSearch.search(myField, new LocalSearchScope(myScope), false)) {
final PsiElement element = reference.getElement();
if (element instanceof GrReferenceExpression) {
final GrReferenceExpression referenceExpression = (GrReferenceExpression)element;
if (referenceExpression.getQualifier() == null) {
myReferenceExpressions.add(referenceExpression);
}
}
}
if (myField.hasModifierProperty(PsiModifier.STATIC)) {
myQualifyingClass = myField.getContainingClass();
}
}
public GrExpression fixInitializer(GrExpression initializer) {
if (myField == null) return initializer;
final GrReferenceExpression[] replacedRef = {null};
initializer.accept(new GroovyRecursiveElementVisitor() {
@Override
public void visitReferenceExpression(GrReferenceExpression expression) {
final GrExpression qualifierExpression = expression.getQualifier();
if (qualifierExpression != null) {
qualifierExpression.accept(this);
}
else {
final PsiElement result = expression.resolve();
if (expression.getManager().areElementsEquivalent(result, myField)) {
try {
replacedRef[0] = qualifyReference(expression, myField, myQualifyingClass);
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
}
}
});
if (!initializer.isValid()) return replacedRef[0];
return initializer;
}
public void fix() throws IncorrectOperationException {
if (myField == null) return;
final PsiManager manager = myScope.getManager();
for (GrReferenceExpression referenceExpression : myReferenceExpressions) {
if (!referenceExpression.isValid()) continue;
final PsiElement newlyResolved = referenceExpression.resolve();
if (!manager.areElementsEquivalent(newlyResolved, myField)) {
qualifyReference(referenceExpression, myField, myQualifyingClass);
}
}
}
public static GrReferenceExpression qualifyReference(GrReferenceExpression referenceExpression,
final PsiMember member,
@Nullable final PsiClass qualifyingClass) throws IncorrectOperationException {
PsiManager manager = referenceExpression.getManager();
GrReferenceExpression expressionFromText;
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(referenceExpression.getProject());
if (qualifyingClass == null) {
PsiClass parentClass = PsiTreeUtil.getParentOfType(referenceExpression, PsiClass.class);
final PsiClass containingClass = member.getContainingClass();
if (parentClass != null && !InheritanceUtil.isInheritorOrSelf(parentClass, containingClass, true)) {
while (parentClass != null && !InheritanceUtil.isInheritorOrSelf(parentClass, containingClass, true)) {
parentClass = PsiTreeUtil.getParentOfType(parentClass, PsiClass.class, true);
}
LOG.assertTrue(parentClass != null);
expressionFromText = factory.createReferenceExpressionFromText("A.this." + member.getName());
//noinspection ConstantConditions
((GrThisReferenceExpression)expressionFromText.getQualifier()).getQualifier().replace(
factory.createReferenceElementForClass(parentClass));
}
else {
expressionFromText = (GrReferenceExpression)factory.createExpressionFromText("this." + member.getName());
}
}
else {
expressionFromText = (GrReferenceExpression)factory.createExpressionFromText("A." + member.getName());
expressionFromText.setQualifier(factory.createReferenceElementForClass(qualifyingClass));
}
CodeStyleManager codeStyleManager = manager.getCodeStyleManager();
expressionFromText = (GrReferenceExpression)codeStyleManager.reformat(expressionFromText);
return (GrReferenceExpression)referenceExpression.replace(expressionFromText);
}
}
@@ -0,0 +1,50 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.refactoring.introduce.parameter;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiType;
import com.intellij.refactoring.introduceParameter.IntroduceParameterData;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
/**
* @author Maxim.Medvedev
*/
public class GrExpressionWrapper implements IntroduceParameterData.ExpressionWrapper {
private final GrExpression myExpression;
public GrExpressionWrapper(GrExpression expression) {
myExpression = expression;
}
@NotNull
@Override
public String getText() {
return myExpression.getText();
}
@Override
public PsiType getType() {
return myExpression.getType();
}
@NotNull
@Override
public PsiElement getExpression() {
return myExpression;
}
}
@@ -0,0 +1,34 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.refactoring.introduce.parameter;
import com.intellij.psi.PsiMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContext;
/**
* @author Maxim.Medvedev
*/
public class GrIntroduceParameterContext extends GrIntroduceContext {
public final PsiMethod methodToSearchFor;
public final GrMethod methodToReplaceIn;
public GrIntroduceParameterContext(GrIntroduceContext context, GrMethod methodToReplaceIn, PsiMethod methodToSearchFor) {
super(context.project, context.editor, context.expression, context.occurrences, context.scope, context.var);
this.methodToReplaceIn = methodToReplaceIn;
this.methodToSearchFor = methodToSearchFor;
}
}
@@ -0,0 +1,144 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.plugins.groovy.refactoring.introduce.parameter.GrIntroduceParameterDialog">
<grid id="cbd77" binding="myContentPane" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="10" left="10" bottom="10" right="10"/>
<constraints>
<xy x="48" y="54" width="595" height="340"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<grid id="ad8bd" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="a9bd6" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Parameter of &amp;type:"/>
</properties>
</component>
<component id="eeb4" class="org.jetbrains.plugins.groovy.refactoring.ui.GrTypeComboBox" binding="myTypeComboBox" custom-create="true" default-binding="true">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="7aff5" class="javax.swing.JLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&amp;Name:"/>
</properties>
</component>
<component id="d934b" class="com.intellij.refactoring.ui.NameSuggestionsField" binding="myNameSuggestionsField" custom-create="true" default-binding="true">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
</children>
</grid>
<grid id="a8cf9" binding="myCheckBoxContainer" layout-manager="GridBagLayout">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="62ec5" class="javax.swing.JCheckBox" binding="myDeclareFinalCheckBox" default-binding="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
<gridbag weightx="1.0" weighty="1.0"/>
</constraints>
<properties>
<text value="Declare &amp;final"/>
</properties>
</component>
<component id="33f30" class="javax.swing.JCheckBox" binding="myDelegateViaOverloadingMethodCheckBox" default-binding="true">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
<gridbag weightx="1.0" weighty="1.0"/>
</constraints>
<properties>
<text value="De&amp;legate via overloading method"/>
</properties>
</component>
<component id="e1dc5" class="javax.swing.JCheckBox" binding="myReplaceAllOccurrencesCheckBox" default-binding="true">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="1.0" weighty="1.0"/>
</constraints>
<properties>
<text value="Replace &amp;all occurrences"/>
</properties>
</component>
<component id="a952e" class="javax.swing.JCheckBox" binding="myRemoveLocalVariableCheckBox" default-binding="true">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="1.0" weighty="1.0"/>
</constraints>
<properties>
<text value="Remove local variable"/>
</properties>
</component>
</children>
</grid>
<grid id="537d" binding="myGetterPanel" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none" title="Peplace fields used in expressions with their getters"/>
<children>
<component id="5cbea" class="javax.swing.JRadioButton" binding="myDoNotReplaceRadioButton" default-binding="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<selected value="true"/>
<text value="Do n&amp;ot replace"/>
</properties>
</component>
<component id="621e5" class="javax.swing.JRadioButton" binding="myReplaceFieldsInaccessibleInRadioButton" default-binding="true">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<selected value="false"/>
<text value="Replace fields &amp;inaccessible in usage context"/>
</properties>
</component>
<component id="9d2ba" class="javax.swing.JRadioButton" binding="myReplaceAllFieldsRadioButton" default-binding="true">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&amp;Replace all fields"/>
</properties>
</component>
</children>
</grid>
<vspacer id="14a96">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
</children>
</grid>
<buttonGroups>
<group name="replaceFieldsGroup">
<member id="5cbea"/>
<member id="621e5"/>
<member id="9d2ba"/>
</group>
</buttonGroups>
</form>
@@ -0,0 +1,252 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.refactoring.introduce.parameter;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiType;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.refactoring.JavaRefactoringSettings;
import com.intellij.refactoring.ui.NameSuggestionsField;
import com.intellij.refactoring.ui.RefactoringDialog;
import com.intellij.util.ui.GridBag;
import gnu.trove.TIntArrayList;
import gnu.trove.TObjectIntHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.GroovyFileType;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.refactoring.GroovyNameSuggestionUtil;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle;
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceDialog;
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceRefactoringError;
import org.jetbrains.plugins.groovy.refactoring.introduce.field.GroovyFieldValidator;
import org.jetbrains.plugins.groovy.refactoring.ui.GrTypeComboBox;
import javax.swing.*;
import java.awt.*;
import static com.intellij.refactoring.IntroduceParameterRefactoring.*;
public class GrIntroduceParameterDialog extends RefactoringDialog implements GrIntroduceDialog<GrIntroduceParameterSettings> {
private JPanel myContentPane;
private GrTypeComboBox myTypeComboBox;
private NameSuggestionsField myNameSuggestionsField;
private JCheckBox myDeclareFinalCheckBox;
private JCheckBox myDelegateViaOverloadingMethodCheckBox;
private JPanel myCheckBoxContainer;
private JCheckBox myReplaceAllOccurrencesCheckBox;
private JRadioButton myDoNotReplaceRadioButton;
private JRadioButton myReplaceFieldsInaccessibleInRadioButton;
private JRadioButton myReplaceAllFieldsRadioButton;
private JCheckBox myRemoveLocalVariableCheckBox;
private JPanel myGetterPanel;
private GrIntroduceParameterContext myContext;
TObjectIntHashMap<JCheckBox> toRemoveCBs;
public GrIntroduceParameterDialog(GrIntroduceParameterContext context, TObjectIntHashMap<GrParameter> parametersToRemove) {
super(context.project, true);
myContext = context;
toRemoveCBs = new TObjectIntHashMap<JCheckBox>(parametersToRemove.size());
for (Object p : parametersToRemove.keys()) {
JCheckBox cb = new JCheckBox(GroovyRefactoringBundle.message("remove.parameter.0.no.longer.used", ((GrParameter)p).getName()));
toRemoveCBs.put(cb, parametersToRemove.get((GrParameter)p));
cb.setSelected(true);
}
JavaRefactoringSettings settings = JavaRefactoringSettings.getInstance();
final PsiElement[] occurrences = context.occurrences;
if (occurrences.length < 2) {
myReplaceAllOccurrencesCheckBox.setSelected(true);
myReplaceAllOccurrencesCheckBox.setVisible(false);
}
if (myContext.var == null) {
myRemoveLocalVariableCheckBox.setSelected(false);
myRemoveLocalVariableCheckBox.setVisible(false);
}
else {
myRemoveLocalVariableCheckBox.setSelected(settings.INTRODUCE_PARAMETER_DELETE_LOCAL_VARIABLE);
}
initReplaceFieldsWithGetters(settings);
myDeclareFinalCheckBox.setSelected(hasFinalModifier());
init();
}
private void initReplaceFieldsWithGetters(JavaRefactoringSettings settings) {
final GrExpression expression = myContext.expression;
GroovyIntroduceParameterUtil.findUsedFieldsWithGetters(expression, myContext.methodToReplaceIn.getContainingClass());
switch (settings.INTRODUCE_PARAMETER_REPLACE_FIELDS_WITH_GETTERS) {
case REPLACE_FIELDS_WITH_GETTERS_ALL:
myReplaceAllFieldsRadioButton.setSelected(true);
break;
case REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE:
myReplaceFieldsInaccessibleInRadioButton.setSelected(true);
break;
case REPLACE_FIELDS_WITH_GETTERS_NONE:
myDoNotReplaceRadioButton.setSelected(true);
break;
}
}
private boolean hasFinalModifier() {
final Boolean createFinals = JavaRefactoringSettings.getInstance().INTRODUCE_PARAMETER_CREATE_FINALS;
return createFinals == null ? CodeStyleSettingsManager.getSettings(myProject).GENERATE_FINAL_PARAMETERS : createFinals.booleanValue();
}
@Override
protected void doAction() {
saveSettings();
GrIntroduceParameterSettings settings = new GrIntroduceParameterSettingsImpl(
myNameSuggestionsField.getEnteredName(),
myReplaceAllOccurrencesCheckBox.isSelected(),
myTypeComboBox.getSelectedType(),
myDeclareFinalCheckBox.isSelected(),
myDelegateViaOverloadingMethodCheckBox.isSelected(),
getParametersToRemove(),
getReplaceFieldsWithGetter(),
myRemoveLocalVariableCheckBox.isSelected());
invokeRefactoring(new GrIntroduceParameterProcessor(settings, myContext));
}
private void saveSettings() {
final JavaRefactoringSettings settings = JavaRefactoringSettings.getInstance();
settings.INTRODUCE_PARAMETER_CREATE_FINALS = myDeclareFinalCheckBox.isSelected();
if (myRemoveLocalVariableCheckBox.isVisible()) {
settings.INTRODUCE_PARAMETER_DELETE_LOCAL_VARIABLE = myRemoveLocalVariableCheckBox.isSelected();
}
if (myGetterPanel.isVisible()) {
settings.INTRODUCE_PARAMETER_REPLACE_FIELDS_WITH_GETTERS = getReplaceFieldsWithGetter();
}
}
@Override
protected JComponent createCenterPanel() {
final GridBag c = new GridBag().setDefaultAnchor(GridBagConstraints.WEST).setLine(3);
for (Object o : toRemoveCBs.keys()) {
c.nextLine();
myCheckBoxContainer.add(((JCheckBox)o), c);
}
return myContentPane;
}
@Override
public GrIntroduceParameterSettings getSettings() {
return null;
}
private int getReplaceFieldsWithGetter() {
if (myDoNotReplaceRadioButton.isSelected()) return REPLACE_FIELDS_WITH_GETTERS_NONE;
if (myReplaceFieldsInaccessibleInRadioButton.isSelected()) return REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE;
if (myReplaceAllFieldsRadioButton.isSelected()) return REPLACE_FIELDS_WITH_GETTERS_ALL;
throw new GrIntroduceRefactoringError("no check box selected");
}
private TIntArrayList getParametersToRemove() {
TIntArrayList list = new TIntArrayList();
for (Object o : toRemoveCBs.keys()) {
if (((JCheckBox)o).isSelected()) {
list.add(toRemoveCBs.get((JCheckBox)o));
}
}
return list;
}
private void createUIComponents() {
myTypeComboBox = new GrTypeComboBox(myContext.var != null ? myContext.var.getDeclaredType() : myContext.expression.getType());
String[] possibleNames = GroovyNameSuggestionUtil.suggestVariableNames(myContext.expression, new GroovyFieldValidator(myContext), true);
if (myContext.var != null) {
String[] arr = new String[possibleNames.length + 1];
arr[0] = myContext.var.getName();
System.arraycopy(possibleNames, 0, arr, 1, possibleNames.length);
possibleNames = arr;
}
myNameSuggestionsField = new NameSuggestionsField(possibleNames, myContext.project, GroovyFileType.GROOVY_FILE_TYPE);
}
static class GrIntroduceParameterSettingsImpl implements GrIntroduceParameterSettings {
private String myName;
private boolean myReplaceAllOccurrences;
private PsiType mySelectedType;
private boolean myDeclareFinal;
private boolean myIsGenerateDelegate;
private TIntArrayList myParameterToRemove;
private int myReplaceFieldWithGetters;
private boolean myRemoveLocalVariable;
GrIntroduceParameterSettingsImpl(String name,
boolean replaceAllOccurrences,
PsiType selectedType,
boolean declareFinal,
boolean isGenerateDelegate,
TIntArrayList parameterToRemove,
int replaceFieldWithGetters,
boolean removeLocalVariable) {
myName = name;
myReplaceAllOccurrences = replaceAllOccurrences;
mySelectedType = selectedType;
myDeclareFinal = declareFinal;
myIsGenerateDelegate = isGenerateDelegate;
myParameterToRemove = parameterToRemove;
myReplaceFieldWithGetters = replaceFieldWithGetters;
myRemoveLocalVariable = removeLocalVariable;
}
@Override
public String getName() {
return myName;
}
@Override
public boolean replaceAllOccurrences() {
return myReplaceAllOccurrences;
}
@Override
public PsiType getSelectedType() {
return mySelectedType;
}
@Override
public boolean declareFinal() {
return myDeclareFinal;
}
@Override
public boolean removeLocalVariable() {
return myRemoveLocalVariable;
}
@Override
public boolean generateDelegate() {
return myIsGenerateDelegate;
}
@NotNull
@Override
public TIntArrayList parametersToRemove() {
return myParameterToRemove;
}
@Override
public int replaceFieldsWithGetters() {
return myReplaceFieldWithGetters;
}
}
}
@@ -0,0 +1,103 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.refactoring.introduce.parameter;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.introduceParameter.IntroduceParameterHandler;
import gnu.trove.TObjectIntHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle;
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContext;
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceDialog;
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceHandlerBase;
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceRefactoringError;
/**
* @author Maxim.Medvedev
*/
public class GrIntroduceParameterHandler extends GrIntroduceHandlerBase<GrIntroduceParameterSettings> {
@Override
protected String getRefactoringName() {
return RefactoringBundle.message("introduce.parameter.title");
}
@Override
protected String getHelpID() {
return HelpID.INTRODUCE_PARAMETER;
}
@NotNull
@Override
protected PsiElement findScope(GrExpression expression, GrVariable variable) {
@NotNull PsiElement place = expression == null ? variable : expression;
final PsiMethod method = PsiTreeUtil.getParentOfType(place, PsiMethod.class, true, PsiClass.class);
if (method == null) throw new GrIntroduceRefactoringError(GroovyRefactoringBundle.message("there.is.no.method"));
return method;
}
@Override
public GrIntroduceContext getContext(Project project, Editor editor, GrExpression expression, @Nullable GrVariable variable) {
final GrIntroduceContext context = super.getContext(project, editor, expression, variable);
assert context.scope instanceof GrMethod;
GrMethod curMethod = (GrMethod)context.scope;
final PsiMethod methodToSearchFor = IntroduceParameterHandler.chooseEnclosingMethod(curMethod);
return new GrIntroduceParameterContext(context, curMethod, methodToSearchFor);
}
@Override
protected void checkExpression(GrExpression selectedExpr) throws GrIntroduceRefactoringError {
//nothing to do
}
@Override
protected void checkVariable(GrVariable variable) throws GrIntroduceRefactoringError {
//nothing to do
}
@Override
protected void checkOccurrences(PsiElement[] occurrences) {
//nothing to do
}
@Override
protected GrIntroduceDialog<GrIntroduceParameterSettings> getDialog(GrIntroduceContext context) {
assert context instanceof GrIntroduceParameterContext;
TObjectIntHashMap<GrParameter> toRemove = GroovyIntroduceParameterUtil.findParametersToRemove(context);
return new GrIntroduceParameterDialog((GrIntroduceParameterContext)context, toRemove);
}
@Override
public GrVariable runRefactoring(GrIntroduceContext context, GrIntroduceParameterSettings settings) {
return null;
}
}
@@ -0,0 +1,472 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.refactoring.introduce.parameter;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.MethodReferencesSearch;
import com.intellij.psi.search.searches.OverridingMethodsSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.IntroduceParameterRefactoring;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.introduceParameter.*;
import com.intellij.refactoring.ui.UsageViewDescriptorAdapter;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.refactoring.util.ConflictsUtil;
import com.intellij.refactoring.util.RefactoringUIUtil;
import com.intellij.refactoring.util.usageInfo.DefaultConstructorImplicitUsageInfo;
import com.intellij.refactoring.util.usageInfo.NoConstructorClassUsageInfo;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.containers.MultiMap;
import gnu.trove.TIntArrayList;
import gnu.trove.TIntProcedure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* @author Maxim.Medvedev
*/
public class GrIntroduceParameterProcessor extends BaseRefactoringProcessor implements IntroduceParameterData {
private static final Logger LOG =
Logger.getInstance("#org.jetbrains.plugins.groovy.refactoring.introduce.parameter.GrIntroduceParameterProcessor");
private final GrIntroduceParameterSettings mySettings;
private final GrIntroduceParameterContext myContext;
private IntroduceParameterData.ExpressionWrapper myParameterInitializer;
public GrIntroduceParameterProcessor(GrIntroduceParameterSettings settings, GrIntroduceParameterContext context) {
super(context.project);
this.mySettings = settings;
this.myContext = context;
myParameterInitializer = new GrExpressionWrapper(this.myContext.expression);
}
@Override
protected UsageViewDescriptor createUsageViewDescriptor(final UsageInfo[] usages) {
return new UsageViewDescriptorAdapter() {
@NotNull
@Override
public PsiElement[] getElements() {
return new PsiElement[]{myContext.methodToSearchFor};
}
@Override
public String getProcessedElementsHeader() {
return RefactoringBundle.message("introduce.parameter.elements.header");
}
};
}
@Override
protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) {
UsageInfo[] usagesIn = refUsages.get();
MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
/*AnySameNameVariables anySameNameVariables = new AnySameNameVariables();
myMethodToReplaceIn.accept(anySameNameVariables);
final Pair<PsiElement, String> conflictPair = anySameNameVariables.getConflict();
if (conflictPair != null) {
conflicts.putValue(conflictPair.first, conflictPair.second);
}*/
if (!mySettings.generateDelegate()) {
detectAccessibilityConflicts(usagesIn, conflicts);
}
if (myContext.expression != null && !myContext.methodToReplaceIn.hasModifierProperty(PsiModifier.PRIVATE)) {
final AnySupers anySupers = new AnySupers();
myContext.expression.accept(anySupers);
if (anySupers.isResult()) {
for (UsageInfo usageInfo : usagesIn) {
if (!(usageInfo.getElement() instanceof PsiMethod) && !(usageInfo instanceof InternalUsageInfo)) {
if (!PsiTreeUtil.isAncestor(myContext.methodToReplaceIn.getContainingClass(), usageInfo.getElement(), false)) {
conflicts.putValue(myContext.expression,
RefactoringBundle.message("parameter.initializer.contains.0.but.not.all.calls.to.method.are.in.its.class",
CommonRefactoringUtil.htmlEmphasize(PsiKeyword.SUPER)));
break;
}
}
}
}
}
for (IntroduceParameterMethodUsagesProcessor processor : IntroduceParameterMethodUsagesProcessor.EP_NAME.getExtensions()) {
processor.findConflicts(this, refUsages.get(), conflicts);
}
return showConflicts(conflicts, usagesIn);
}
private void detectAccessibilityConflicts(final UsageInfo[] usageArray, MultiMap<PsiElement, String> conflicts) {
if (myContext.expression == null) return;
final ReferencedElementsCollector collector = new ReferencedElementsCollector();
myContext.expression.accept(collector);
final List<PsiElement> result = collector.getResult();
if (result.isEmpty()) return;
for (final UsageInfo usageInfo : usageArray) {
if (!(usageInfo instanceof ExternalUsageInfo) || !IntroduceParameterUtil.isMethodUsage(usageInfo)) continue;
final PsiElement place = usageInfo.getElement();
for (PsiElement element : result) {
if (element instanceof PsiField &&
mySettings.replaceFieldsWithGetters() != IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE) {
//check getter access instead
final PsiClass psiClass = ((PsiField)element).getContainingClass();
LOG.assertTrue(psiClass != null);
final PsiMethod method = GroovyPropertyUtils.findGetterForField((PsiField)element);
if (method != null) {
element = method;
}
}
if (element instanceof PsiMember &&
!JavaPsiFacade.getInstance(myProject).getResolveHelper().isAccessible((PsiMember)element, place, null)) {
String message = RefactoringBundle.message(
"0.is.not.accessible.from.1.value.for.introduced.parameter.in.that.method.call.will.be.incorrect",
RefactoringUIUtil.getDescription(element, true),
RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(place), true));
conflicts.putValue(element, message);
}
}
}
}
private static class AnySupers extends GroovyRecursiveElementVisitor {
boolean myContainsSupers = false;
@Override
public void visitSuperExpression(GrSuperReferenceExpression superExpression) {
super.visitSuperExpression(superExpression);
myContainsSupers = true;
}
boolean isResult() {
return myContainsSupers;
}
}
private static class ReferencedElementsCollector extends GroovyRecursiveElementVisitor {
private List<PsiElement> myResult = new ArrayList<PsiElement>();
@Override
public void visitReferenceExpression(GrReferenceExpression referenceExpression) {
add(referenceExpression);
}
private void add(GrReferenceElement referenceExpression) {
final PsiElement resolved = referenceExpression.resolve();
if (resolved != null) {
myResult.add(resolved);
}
}
@Override
public void visitCodeReferenceElement(GrCodeReferenceElement refElement) {
add(refElement);
}
public List<PsiElement> getResult() {
return myResult;
}
}
@NotNull
@Override
protected UsageInfo[] findUsages() {
ArrayList<UsageInfo> result = new ArrayList<UsageInfo>();
final PsiMethod methodToSearchFor = myContext.methodToSearchFor;
if (!mySettings.generateDelegate()) {
Collection<PsiReference> refs =
MethodReferencesSearch.search(methodToSearchFor, GlobalSearchScope.projectScope(myProject), true).findAll();
for (PsiReference ref1 : refs) {
PsiElement ref = ref1.getElement();
if (ref instanceof PsiMethod && ((PsiMethod)ref).isConstructor()) {
DefaultConstructorImplicitUsageInfo implicitUsageInfo =
new DefaultConstructorImplicitUsageInfo((PsiMethod)ref, ((PsiMethod)ref).getContainingClass(), methodToSearchFor);
result.add(implicitUsageInfo);
}
else if (ref instanceof PsiClass) {
result.add(new NoConstructorClassUsageInfo((PsiClass)ref));
}
else if (!IntroduceParameterUtil.insideMethodToBeReplaced(ref, myContext.methodToReplaceIn)) {
result.add(new ExternalUsageInfo(ref));
}
else {
result.add(new ChangedMethodCallInfo(ref));
}
}
}
if (mySettings.replaceAllOccurrences()) {
PsiElement[] exprs = myContext.occurrences;
for (PsiElement expr : exprs) {
result.add(new InternalUsageInfo(expr));
}
}
else {
if (myContext.expression != null) {
result.add(new InternalUsageInfo(myContext.expression));
}
}
Collection<PsiMethod> overridingMethods =
OverridingMethodsSearch.search(methodToSearchFor, methodToSearchFor.getUseScope(), true).findAll();
for (PsiMethod overridingMethod : overridingMethods) {
result.add(new UsageInfo(overridingMethod));
}
final UsageInfo[] usageInfos = result.toArray(new UsageInfo[result.size()]);
return UsageViewUtil.removeDuplicatedUsages(usageInfos);
}
@Override
protected void performRefactoring(UsageInfo[] usages) {
GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
PsiType initializerType = mySettings.getSelectedType();
// Changing external occurences (the tricky part)
IntroduceParameterUtil.processUsages(usages, this);
final boolean methodsToProcessAreDifferent = myContext.methodToReplaceIn != myContext.methodToSearchFor;
if (mySettings.generateDelegate()) {
generateDelegate(myContext.methodToReplaceIn);
if (methodsToProcessAreDifferent) {
final GrMethod method = generateDelegate(myContext.methodToSearchFor);
final PsiClass containingClass = method.getContainingClass();
if (containingClass != null && containingClass.isInterface()) {
final GrOpenBlock block = method.getBlock();
if (block != null) {
block.delete();
}
}
}
}
// Changing signature of initial method
// (signature of myMethodToReplaceIn will be either changed now or have already been changed)
LOG.assertTrue(initializerType == null || initializerType.isValid());
final FieldConflictsResolver fieldConflictsResolver =
new FieldConflictsResolver(mySettings.getName(), myContext.methodToReplaceIn.getBlock());
IntroduceParameterUtil.changeMethodSignatureAndResolveFieldConflicts(new UsageInfo(myContext.methodToReplaceIn), usages, this);
if (methodsToProcessAreDifferent) {
IntroduceParameterUtil.changeMethodSignatureAndResolveFieldConflicts(new UsageInfo(myContext.methodToSearchFor), usages, this);
}
// Replacing expression occurences
for (UsageInfo usage : usages) {
if (usage instanceof ChangedMethodCallInfo) {
PsiElement element = usage.getElement();
processChangedMethodCall(element);
}
else if (usage instanceof InternalUsageInfo) {
PsiElement element = usage.getElement();
if (element instanceof GrExpression) {
element = PsiUtil.skipParentheses(element, true);
}
GrExpression newExpr = factory.createExpressionFromText(mySettings.getName());
element.replace(newExpr);
}
}
if (myContext.var != null && mySettings.removeLocalVariable()) {
myContext.var.delete();
}
fieldConflictsResolver.fix();
}
private GrMethod generateDelegate(PsiMethod prototype) {
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
GrMethod result;
if (prototype instanceof GrMethod) {
result = (GrMethod)prototype.copy();
}
else {
StringBuilder builder = new StringBuilder();
builder.append(prototype.getModifierList().getText()).append(' ');
if (prototype.getReturnTypeElement() != null) {
builder.append(prototype.getReturnTypeElement().getText());
}
builder.append(' ').append(prototype.getName());
builder.append(prototype.getParameterList().getText());
builder.append("{}");
result = factory.createMethodFromText(builder.toString());
}
StringBuilder call = new StringBuilder();
call.append("def foo(){\n").append(prototype.getName()).append('(');
final GrParameter[] parameters = result.getParameters();
for (GrParameter parameter : parameters) {
call.append(parameter.getName()).append(", ");
}
call.delete(call.length() - 2, call.length());
call.append(myParameterInitializer.getText());
call.append(");\n}");
final GrOpenBlock block = factory.createMethodFromText(call.toString()).getBlock();
result.getBlock().replace(block);
final PsiElement parent = myContext.methodToReplaceIn.getParent();
return (GrMethod)parent.addBefore(result, myContext.methodToReplaceIn);
}
private void processChangedMethodCall(PsiElement element) {
if (element.getParent() instanceof GrMethodCallExpression) {
GrMethodCallExpression methodCall = (GrMethodCallExpression)element.getParent();
GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
GrExpression expression = factory.createExpressionFromText(mySettings.getName(), null);
final GrArgumentList argList = methodCall.getArgumentList();
final PsiElement[] exprs = argList.getAllArguments();
if (exprs.length > 0) {
argList.addAfter(expression, exprs[exprs.length - 1]);
}
else {
argList.add(expression);
}
removeParametersFromCall(methodCall, argList);
}
else {
LOG.error(element.getParent());
}
}
private void removeParametersFromCall(GrMethodCallExpression methodCall, GrArgumentList argList) {
final GroovyResolveResult resolveResult = methodCall.advancedResolve();
final PsiElement resolved = resolveResult.getElement();
LOG.assertTrue(resolved instanceof PsiMethod);
final GrClosureSignature signature = GrClosureSignatureUtil.createSignature((PsiMethod)resolved, resolveResult.getSubstitutor());
final GrClosureSignatureUtil.ArgInfo<PsiElement>[] argInfos =
GrClosureSignatureUtil.mapParametersToArguments(signature, argList, methodCall, methodCall.getClosureArguments());
LOG.assertTrue(argInfos != null);
mySettings.parametersToRemove().forEach(new TIntProcedure() {
@Override
public boolean execute(int value) {
final List<PsiElement> args = argInfos[value].args;
for (PsiElement arg : args) {
arg.delete();
}
return true;
}
});
}
@Override
protected String getCommandName() {
return RefactoringBundle.message("introduce.parameter.command", UsageViewUtil.getDescriptiveName(myContext.methodToReplaceIn));
}
@NotNull
@Override
public Project getProject() {
return myContext.project;
}
@Override
public PsiMethod getMethodToReplaceIn() {
return myContext.methodToReplaceIn;
}
@NotNull
@Override
public PsiMethod getMethodToSearchFor() {
return myContext.methodToSearchFor;
}
@Override
public IntroduceParameterData.ExpressionWrapper getParameterInitializer() {
return myParameterInitializer;
}
@NotNull
@Override
public String getParameterName() {
return mySettings.getName();
}
@Override
public int getReplaceFieldsWithGetters() {
return mySettings.replaceFieldsWithGetters();
}
@Override
public boolean isDeclareFinal() {
return mySettings.declareFinal();
}
@Override
public boolean isGenerateDelegate() {
return mySettings.generateDelegate();
}
@NotNull
@Override
public PsiType getForcedType() {
final PsiType selectedType = mySettings.getSelectedType();
if (selectedType != null) return selectedType;
final PsiManager manager = PsiManager.getInstance(myProject);
final GlobalSearchScope resolveScope = myContext.methodToReplaceIn.getResolveScope();
return PsiType.getJavaLangObject(manager, resolveScope);
}
@NotNull
@Override
public TIntArrayList getParametersToRemove() {
return mySettings.parametersToRemove();
}
}
@@ -0,0 +1,36 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.refactoring.introduce.parameter;
import gnu.trove.TIntArrayList;
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceSettings;
/**
* @author Maxim.Medvedev
*/
public interface GrIntroduceParameterSettings extends GrIntroduceSettings {
boolean generateDelegate();
TIntArrayList parametersToRemove();
/**
* @see com.intellij.refactoring.IntroduceParameterRefactoring
*/
int replaceFieldsWithGetters();
boolean declareFinal();
boolean removeLocalVariable();
}
@@ -0,0 +1,31 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.refactoring.introduce.parameter;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.refactoring.introduceParameter.ExpressionConverter;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
/**
* @author Maxim.Medvedev
*/
public class GroovyExpressionConverter extends ExpressionConverter {
@Override
protected PsiElement convert(PsiElement expression, Project project) {
return GroovyPsiElementFactory.getInstance(project).createExpressionFromText(expression.getText(), expression);
}
}
@@ -0,0 +1,99 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.refactoring.introduce.parameter;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.TObjectIntHashMap;
import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContext;
import java.util.ArrayList;
import java.util.List;
/**
* @author Maxim.Medvedev
*/
public class GroovyIntroduceParameterUtil {
private GroovyIntroduceParameterUtil() {
}
public static PsiField[] findUsedFieldsWithGetters(GrExpression expression, PsiClass containingClass) {
final FieldSearcher searcher = new FieldSearcher(containingClass);
expression.accept(searcher);
return searcher.getResult();
}
public static TObjectIntHashMap<GrParameter> findParametersToRemove(GrIntroduceContext context) {
TObjectIntHashMap<GrParameter> toRemove = new TObjectIntHashMap<GrParameter>();
if (context.var == null) {
final GrMethod method = (GrMethod)context.scope;
final GrParameter[] parameters = method.getParameters();
final GrExpression expr = context.expression;
for (int i = 0; i < parameters.length; i++) {
GrParameter parameter = parameters[i];
final boolean shouldRemove = ReferencesSearch.search(parameter).forEach(new Processor<PsiReference>() {
@Override
public boolean process(PsiReference ref) {
final PsiElement element = ref.getElement();
if (element == null) return false;
return PsiTreeUtil.isAncestor(expr, element, false);
}
});
if (shouldRemove) {
toRemove.put(parameter, i);
}
}
}
return toRemove;
}
private static class FieldSearcher extends GroovyRecursiveElementVisitor {
PsiClass myClass;
private final List<PsiField> result = new ArrayList<PsiField>();
private FieldSearcher(PsiClass aClass) {
myClass = aClass;
}
public PsiField[] getResult() {
return ContainerUtil.toArray(result, new PsiField[result.size()]);
}
@Override
public void visitReferenceExpression(GrReferenceExpression ref) {
super.visitReferenceExpression(ref);
final GrExpression qualifier = ref.getQualifier();
if (qualifier != null && !(qualifier instanceof GrThisReferenceExpression)) return;
final PsiElement resolved = ref.resolve();
if (!(resolved instanceof PsiField)) return;
final PsiMethod getter = GroovyPropertyUtils.findGetterForField((PsiField)resolved);
if (getter != null) {
result.add((PsiField)resolved);
}
}
}
}
@@ -17,16 +17,16 @@
package org.jetbrains.plugins.groovy.refactoring.introduce.parameter.java2groovy;
import com.intellij.codeInsight.ChangeContextUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.javadoc.PsiDocTag;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.introduceParameter.ExpressionConverter;
import com.intellij.refactoring.introduceParameter.IntroduceParameterData;
import com.intellij.refactoring.introduceParameter.IntroduceParameterMethodUsagesProcessor;
import com.intellij.refactoring.introduceParameter.IntroduceParameterUtil;
import com.intellij.refactoring.util.javadoc.MethodJavaDocHelper;
import com.intellij.refactoring.util.usageInfo.DefaultConstructorImplicitUsageInfo;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
@@ -37,25 +37,30 @@ import gnu.trove.TIntProcedure;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.GroovyFileType;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
import java.util.HashSet;
import java.util.Set;
/**
* @author Maxim.Medvedev
* Date: Apr 18, 2009 3:16:24 PM
*/
public class GroovyIntroduceParameterMethodUsagesProcessor implements IntroduceParameterMethodUsagesProcessor {
private static final Logger LOG = Logger
.getInstance("#org.jetbrains.plugins.groovy.refactoring.introduce.parameter.java2groovy.GroovyIntroduceParameterMethodUsagesProcessor");
private static boolean isGroovyUsage(UsageInfo usage) {
final PsiElement el = usage.getElement();
@@ -67,33 +72,6 @@ public class GroovyIntroduceParameterMethodUsagesProcessor implements IntroduceP
}
public void findConflicts(IntroduceParameterData data, UsageInfo[] usages, MultiMap<PsiElement, String> conflicts) {
Set<UsageInfo> groovyUsages = new HashSet<UsageInfo>();
for (UsageInfo usage : usages) {
if (isMethodUsage(usage)) groovyUsages.add(usage);
}
if (groovyUsages.size() == 0) return;
data.getParameterInitializer().accept(new InitializerVisitor(conflicts));
}
private static class InitializerVisitor extends JavaRecursiveElementWalkingVisitor {
private final MultiMap<PsiElement, String> conflicts;
private InitializerVisitor(MultiMap<PsiElement, String> conflicts) {
this.conflicts = conflicts;
}
@Override
public void visitNewExpression(PsiNewExpression expression) {
super.visitNewExpression(expression);
final PsiExpression qualifier = expression.getQualifier();
if (qualifier != null) {
conflicts.putValue(qualifier, GroovyRefactoringBundle.message("groovy.does.not.support.inner.classes.but.it.is.used.in.parameter.initializer"));
}
final PsiAnonymousClass anonymousClass = expression.getAnonymousClass();
if (anonymousClass != null) {
conflicts.putValue(anonymousClass, GroovyRefactoringBundle.message("groovy.does.not.support.anonymous.classes.but.it.is.used.in.parameter.initializer"));
}
}
}
public boolean processChangeMethodUsage(IntroduceParameterData data, UsageInfo usage, UsageInfo[] usages) throws IncorrectOperationException {
@@ -117,29 +95,33 @@ public class GroovyIntroduceParameterMethodUsagesProcessor implements IntroduceP
}
}
PsiMethod method = PsiTreeUtil.getParentOfType(argList, PsiMethod.class);
if (method!=null && isMethodInUsages(method, usages, data)) {
GrClosureSignature signature = GrClosureSignatureUtil.createSignature(callExpression);
if (signature == null) signature = GrClosureSignatureUtil.createSignature(data.getMethodToSearchFor(), PsiSubstitutor.EMPTY);
final GrClosureSignatureUtil.ArgInfo<PsiElement>[] actualArgs =
GrClosureSignatureUtil.mapParametersToArguments(signature, argList, callExpression, callExpression.getClosureArguments(), true);
if (method != null && IntroduceParameterUtil.isMethodInUsages(data, method, usages)) {
argList.addAfter(GroovyPsiElementFactory.getInstance(data.getProject()).createExpressionFromText(data.getParameterName()), anchor);
}
else {
ChangeContextUtil.encodeContextInfo(data.getParameterInitializer(), true);
final GrExpression grInitializer = GroovyRefactoringUtil.convertJavaExpr2GroovyExpr(data.getParameterInitializer());
GrExpression newArg = (GrExpression)argList.addAfter(grInitializer, anchor);
new OldReferencesResolver(callExpression, newArg, data.getMethodToReplaceIn(), data.getReplaceFieldsWithGetters(),
data.getParameterInitializer()).resolve();
ChangeContextUtil.clearContextInfo(data.getParameterInitializer());
PsiElement initializer = ExpressionConverter
.getExpression(data.getParameterInitializer().getExpression(), GroovyFileType.GROOVY_LANGUAGE, data.getProject());
LOG.assertTrue(initializer instanceof GrExpression);
GrExpression newArg = (GrExpression)argList.addAfter(initializer, anchor);
new OldReferencesResolver(callExpression, newArg, data.getMethodToReplaceIn(), data.getReplaceFieldsWithGetters(), initializer,
signature, actualArgs).resolve();
ChangeContextUtil.clearContextInfo(initializer);
}
removeParametersFromCall(callExpression.getArgumentList(), data.getParametersToRemove());
return false;
}
private static boolean isMethodInUsages(PsiMethod method, UsageInfo[] usages, IntroduceParameterData data) {
PsiManager manager=PsiManager.getInstance(data.getProject());
for (UsageInfo info : usages) {
if (!(info instanceof DefaultConstructorImplicitUsageInfo) && manager.areElementsEquivalent(info.getElement(), method)) return true;
if (actualArgs == null) {
removeParamsFromUnresolvedCall(callExpression, data);
}
else {
removeParametersFromCall(actualArgs, data.getParametersToRemove());
}
return false;
}
@@ -156,16 +138,64 @@ public class GroovyIntroduceParameterMethodUsagesProcessor implements IntroduceP
return anchor;
}
private static void removeParametersFromCall(final GrArgumentList argList, TIntArrayList parametersToRemove) {
final GrExpression[] exprs = argList.getExpressionArguments();
parametersToRemove.forEachDescending(new TIntProcedure() {
private static void removeParametersFromCall(final GrClosureSignatureUtil.ArgInfo<PsiElement>[] actualArgs,final TIntArrayList parametersToRemove) {
parametersToRemove.forEach(new TIntProcedure() {
public boolean execute(final int paramNum) {
try {
exprs[paramNum].delete();
final GrClosureSignatureUtil.ArgInfo<PsiElement> actualArg = actualArgs[paramNum];
for (PsiElement arg : actualArg.args) {
arg.delete();
}
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
return true;
}
});
}
private static void removeParamsFromUnresolvedCall(GrCall callExpression, IntroduceParameterData data) {
final GrExpression[] arguments = callExpression.getExpressionArguments();
final GrClosableBlock[] closureArguments = callExpression.getClosureArguments();
final GrNamedArgument[] namedArguments = callExpression.getNamedArguments();
final boolean hasNamedArgs;
if (namedArguments.length > 0) {
final PsiMethod method = data.getMethodToSearchFor();
final PsiParameter[] parameters = method.getParameterList().getParameters();
if (parameters.length > 0) {
final PsiType type = parameters[0].getType();
hasNamedArgs = InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_MAP);
}
else {
hasNamedArgs = false;
}
}
else {
hasNamedArgs = false;
}
data.getParametersToRemove().forEachDescending(new TIntProcedure() {
public boolean execute(int paramNum) {
try {
if (paramNum == 0 && hasNamedArgs) {
for (GrNamedArgument namedArgument : namedArguments) {
namedArgument.delete();
}
}
else {
if (hasNamedArgs) paramNum--;
if (paramNum < arguments.length) {
arguments[paramNum].delete();
}
else if (paramNum < arguments.length + closureArguments.length) {
closureArguments[paramNum - arguments.length].delete();
}
}
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
return true;
}
@@ -178,7 +208,6 @@ public class GroovyIntroduceParameterMethodUsagesProcessor implements IntroduceP
final FieldConflictsResolver fieldConflictsResolver = new FieldConflictsResolver(data.getParameterName(), method.getBlock());
final MethodJavaDocHelper javaDocHelper = new MethodJavaDocHelper(method);
PsiManager manager = method.getManager();
GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(method.getProject());
final PsiParameter[] parameters = method.getParameterList().getParameters();
@@ -193,18 +222,21 @@ public class GroovyIntroduceParameterMethodUsagesProcessor implements IntroduceP
param.delete();
}
catch (IncorrectOperationException e) {
// LOG.error(e);
LOG.error(e);
}
return true;
}
});
PsiParameter parameter = factory.createParameter(data.getParameterName(), data.getForcedType().getCanonicalText(), method);
PsiUtil.setModifierProperty(parameter, PsiModifier.FINAL, data.isDeclareFinal());
final PsiType forcedType = data.getForcedType();
final String typeText = forcedType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) ? null : forcedType.getCanonicalText();
GrParameter parameter = factory.createParameter(data.getParameterName(), typeText, method);
parameter.getModifierList().setModifierProperty(GrModifier.FINAL, data.isDeclareFinal());
final PsiParameter anchorParameter = getAnchorParameter(method);
final GrParameterList parameterList = method.getParameterList();
parameter = (PsiParameter)parameterList.addAfter(parameter, anchorParameter);
JavaCodeStyleManager.getInstance(manager.getProject()).shortenClassReferences(parameter);
parameter = (GrParameter)parameterList.addAfter(parameter, anchorParameter);
PsiUtil.shortenReferences(parameter);
final PsiDocTag tagForAnchorParameter = javaDocHelper.getTagForParameter(anchorParameter);
javaDocHelper.addParameterAfter(data.getParameterName(), tagForAnchorParameter);
@@ -224,8 +256,6 @@ public class GroovyIntroduceParameterMethodUsagesProcessor implements IntroduceP
anchorParameter = length > 0 ? parameters[length - 1] : null;
}
else {
// LOG.assertTrue(length > 0);
// LOG.assertTrue(parameters[length - 1].isVarArgs());
anchorParameter = length > 1 ? parameters[length - 2] : null;
}
return anchorParameter;
@@ -238,9 +268,8 @@ public class GroovyIntroduceParameterMethodUsagesProcessor implements IntroduceP
GrMethod constructor =
factory.createConstructorFromText(aClass.getName(), ArrayUtil.EMPTY_STRING_ARRAY, ArrayUtil.EMPTY_STRING_ARRAY, "{}");
constructor = (GrMethod)aClass.add(constructor);
PsiUtil.setModifierProperty(constructor, VisibilityUtil.getVisibilityModifier(aClass.getModifierList()), true);
constructor.getModifierList().setModifierProperty(VisibilityUtil.getVisibilityModifier(aClass.getModifierList()), true);
processAddSuperCall(data, new UsageInfo(constructor), usages);
// constructor = (GrMethod)CodeStyleManager.getInstance(data.getProject()).reformat(constructor);
return false;
}
@@ -252,17 +281,16 @@ public class GroovyIntroduceParameterMethodUsagesProcessor implements IntroduceP
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(data.getProject());
GrExpression superCall = (GrExpression)factory.createStatementFromText("super();");
superCall = (GrExpression)CodeStyleManager.getInstance(data.getProject()).reformat(superCall);
GrConstructorInvocation superCall = factory.createConstructorInvocation("super();");
GrOpenBlock body = constructor.getBlock();
final GrStatement[] statements = body.getStatements();
if (statements.length > 0) {
superCall = (GrExpression)body.addStatementBefore(superCall, statements[0]);
superCall = (GrConstructorInvocation)body.addStatementBefore(superCall, statements[0]);
}
else {
superCall = (GrExpression)body.addStatementBefore(superCall, null);
superCall = (GrConstructorInvocation)body.addStatementBefore(superCall, null);
}
processChangeMethodUsage(data, new UsageInfo(((GrMethodCallExpression)superCall).getInvokedExpression()), usages);
processChangeMethodUsage(data, new UsageInfo(superCall), usages);
return false;
}
@@ -16,22 +16,28 @@
package org.jetbrains.plugins.groovy.refactoring.introduce.parameter.java2groovy;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.impl.source.tree.CompositePsiElement;
import com.intellij.psi.util.PropertyUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.IntroduceParameterRefactoring;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -43,28 +49,36 @@ import static com.intellij.codeInsight.ChangeContextUtil.*;
*/
public class OldReferencesResolver {
private static final Logger LOG =
Logger.getInstance("#org.jetbrains.plugins.groovy.refactoring.introduce.parameter.java2groovy.OldReferencesResolver");
private final GrCall myContext;
private final GrExpression myExpr;
private final HashMap<GrExpression, String> myTempVars;
private final GrExpression myInstanceRef;
private final GrExpression[] myActualArgs;
private final GrClosureSignatureUtil.ArgInfo<PsiElement>[] myActualArgs;
private final PsiMethod myMethodToReplaceIn;
private final Project myProject;
private final int myReplaceFieldsWithGetters;
private final PsiExpression myParameterInitializer;
private final PsiElement myParameterInitializer;
private final PsiManager myManager;
private final PsiParameter[] myParameters;
private final GrClosureSignature mySignature;
public OldReferencesResolver(GrCall context,
GrExpression expr,
PsiMethod methodToReplaceIn,
int replaceFieldsWithGetters,
PsiExpression parameterInitializer) throws IncorrectOperationException {
PsiElement parameterInitializer,
final GrClosureSignature signature,
final GrClosureSignatureUtil.ArgInfo<PsiElement>[] actualArgs) throws IncorrectOperationException {
myContext = context;
myExpr = expr;
myReplaceFieldsWithGetters = replaceFieldsWithGetters;
myParameterInitializer = parameterInitializer;
myTempVars = new HashMap<GrExpression, String>();
myActualArgs = myContext.getArgumentList().getExpressionArguments();
mySignature = signature;
myActualArgs = actualArgs;
myMethodToReplaceIn = methodToReplaceIn;
myProject = myContext.getProject();
myManager = myContext.getManager();
@@ -82,6 +96,7 @@ public class OldReferencesResolver {
else {
myInstanceRef = null;
}
myParameters = myMethodToReplaceIn.getParameterList().getParameters();
}
public void resolve() throws IncorrectOperationException {
@@ -104,15 +119,15 @@ public class OldReferencesResolver {
GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
PsiElement newExpr = expr; // references continue being resolved in the children of newExpr
if (oldExpr instanceof PsiReferenceExpression) {
final PsiReferenceExpression oldRef = (PsiReferenceExpression)oldExpr;
if (oldExpr instanceof GrReferenceExpression) {
final GrReferenceExpression oldRef = (GrReferenceExpression)oldExpr;
newExpr = newExpr.replace(decodeReferenceExpression((GrReferenceExpression)newExpr, oldRef));
//newExpr = ((GrReferenceExpression)newExpr).getReferenceNameElement();
final JavaResolveResult adv = oldRef.advancedResolve(false);
final GroovyResolveResult adv = oldRef.advancedResolve();
final PsiElement scope = getClassContainingResolve(adv);
final PsiElement owner = PsiTreeUtil.getParentOfType(oldExpr, PsiClass.class);
final PsiElement owner = PsiTreeUtil.getContextOfType(oldExpr, PsiClass.class);
if (owner != null && scope != null && PsiTreeUtil.isAncestor(owner, scope, false)) {
if (owner != null && scope != null && PsiTreeUtil.isContextAncestor(owner, scope, false)) {
final PsiElement subj = adv.getElement();
@@ -125,7 +140,7 @@ public class OldReferencesResolver {
int index = parameterList.getParameterIndex((PsiParameter)subj);
if (index < 0) return;
if (index < parameters.length) {
GrExpression actualArg = myActualArgs[index];
GrExpression actualArg = getActualArg(index);
int copyingSafetyLevel = GroovyRefactoringUtil.verifySafeCopyExpression(actualArg);
if (copyingSafetyLevel == RefactoringUtil.EXPR_COPY_PROHIBITED) {
actualArg = factory.createExpressionFromText(getTempVar(actualArg));
@@ -139,15 +154,24 @@ public class OldReferencesResolver {
boolean isStatic = subj instanceof PsiField && ((PsiField)subj).hasModifierProperty(PsiModifier.STATIC) ||
subj instanceof PsiMethod && ((PsiMethod)subj).hasModifierProperty(PsiModifier.STATIC);
if (myInstanceRef != null && !isStatic) {
String name = ((PsiNamedElement)subj).getName();
GrReferenceExpression newRef = (GrReferenceExpression)factory.createExpressionFromText("a." + name);
GrExpression instanceRef = getInstanceRef(factory);
newRef.getQualifierExpression().replace(instanceRef);
newRef = (GrReferenceExpression)CodeStyleManager.getInstance(myProject).reformat(newRef);
newRef = (GrReferenceExpression)newExpr.replace(newRef);
newExpr = newRef.getReferenceNameElement();
String name = ((PsiNamedElement)subj).getName();
boolean shouldBeAt = subj instanceof PsiField &&
!PsiTreeUtil.isAncestor(((PsiMember)subj).getContainingClass(), newExpr, true) &&
GroovyPropertyUtils.findGetterForField((PsiField)subj) != null;
final GrReferenceExpression fromText = factory.createReferenceExpressionFromText("qualifier." + (shouldBeAt ? "@" : "") + name);
if (isStatic) {
final GrReferenceExpression qualifier = factory.createReferenceElementForClass(((PsiMember)subj).getContainingClass());
newExpr = newExpr.replace(fromText);
((GrReferenceExpression)newExpr).setQualifier(qualifier);
newExpr = ((GrReferenceExpression)newExpr).getReferenceNameElement();
}
else {
if (myInstanceRef != null) {
GrExpression instanceRef = getInstanceRef(factory);
fromText.setQualifier(instanceRef);
newExpr = newExpr.replace(fromText);
newExpr = ((GrReferenceExpression)newExpr).getReferenceNameElement();
}
}
}
@@ -163,16 +187,15 @@ public class OldReferencesResolver {
}
}
}
else if (oldExpr instanceof PsiThisExpression &&
(((PsiThisExpression)oldExpr).getQualifier() == null ||
myManager
.areElementsEquivalent(((PsiThisExpression)oldExpr).getQualifier().resolve(), myMethodToReplaceIn.getContainingClass()))) {
else if (oldExpr instanceof GrThisReferenceExpression &&
(((GrThisReferenceExpression)oldExpr).getQualifier() == null || myManager.areElementsEquivalent(
((GrThisReferenceExpression)oldExpr).getQualifier().resolve(), myMethodToReplaceIn.getContainingClass()))) {
if (myInstanceRef != null) {
newExpr.replace(getInstanceRef(factory));
}
return;
}
else if (oldExpr instanceof PsiSuperExpression && ((PsiSuperExpression)oldExpr).getQualifier() == null) {
else if (oldExpr instanceof GrSuperReferenceExpression && ((GrSuperReferenceExpression)oldExpr).getQualifier() == null) {
if (myInstanceRef != null) {
newExpr.replace(getInstanceRef(factory));
}
@@ -197,23 +220,20 @@ public class OldReferencesResolver {
PsiElement[] oldChildren = oldExpr.getChildren();
PsiElement[] newChildren = newExpr.getChildren();
if (oldExpr instanceof PsiNewExpression && newExpr instanceof GrNewExpression) { //special new-expression case
if (oldExpr instanceof GrNewExpression && newExpr instanceof GrNewExpression) { //special new-expression case
resolveOldReferences(((GrNewExpression)newExpr).getReferenceElement(),
((PsiNewExpression)oldExpr).getClassOrAnonymousClassReference());
((GrNewExpression)oldExpr).getReferenceElement());
resolveOldReferences(((GrNewExpression)newExpr).getArgumentList(), ((PsiNewExpression)oldExpr).getArgumentList());
resolveOldReferences(((GrNewExpression)newExpr).getArgumentList(), ((GrNewExpression)oldExpr).getArgumentList());
if (newChildren[1] instanceof GrArrayDeclaration) {
int j = 3; //array dimension expressions may occur since 3 position
for (GrExpression expression : ((GrArrayDeclaration)newChildren[1]).getBoundExpressions()) {
while (!(oldChildren[j] instanceof CompositePsiElement)) j++;
resolveOldReferences(expression, oldChildren[j]);
j++;
resolveOldReferences(expression, oldChildren[1]);
}
}
}
else {
if (oldExpr instanceof PsiReferenceExpression && newExpr instanceof GrReferenceExpression) {
final PsiExpression oldQualifier = ((PsiReferenceExpression)oldExpr).getQualifierExpression();
if (oldExpr instanceof GrReferenceExpression && newExpr instanceof GrReferenceExpression) {
final GrExpression oldQualifier = ((GrReferenceExpression)oldExpr).getQualifierExpression();
final GrExpression newQualifier = ((GrReferenceExpression)newExpr).getQualifierExpression();
if (oldQualifier != null && newQualifier != null) {
resolveOldReferences(newQualifier, oldQualifier);
@@ -221,25 +241,41 @@ public class OldReferencesResolver {
}
}
int oldCount = countOldChildren(oldChildren);
if (oldCount == newChildren.length) {
int j = 0;
if (oldChildren.length == newChildren.length) {
for (int i = 0; i < newChildren.length; i++) {
while (!(oldChildren[j] instanceof CompositePsiElement)) j++;
resolveOldReferences(newChildren[i], oldChildren[j]);
j++;
resolveOldReferences(newChildren[i], oldChildren[i]);
}
}
}
}
private static int countOldChildren(PsiElement[] children) {
int count = 0;
for (PsiElement child : children) {
if (child instanceof CompositePsiElement) count++;
@NotNull
private GrExpression getActualArg(int index) {
if (myActualArgs == null) {
final GrExpression[] arguments = myContext.getArgumentList().getExpressionArguments();
if (index < arguments.length) return arguments[index];
index -= arguments.length;
final GrClosableBlock[] closureArguments = myContext.getClosureArguments();
if (index < closureArguments.length) return closureArguments[index];
throw new IncorrectOperationException("fail :(");
}
final GrClosureSignatureUtil.ArgInfo<PsiElement> argInfo = myActualArgs[index];
final List<PsiElement> args = argInfo.args;
if (argInfo.isMultiArg) {
return GroovyRefactoringUtil.generateArgFromMultiArg(mySignature.getSubstitutor(), args, myParameters[index].getType(),
myContext.getProject());
}
else if (args.size() == 0) {
final PsiParameter parameter = myParameters[index];
LOG.assertTrue(parameter instanceof GrParameter);
final GrExpression initializer = ((GrParameter)parameter).getInitializerGroovy();
LOG.assertTrue(initializer != null);
return (GrExpression)initializer.copy();
}
else {
return (GrExpression)args.get(0);
}
return count;
}
private GrExpression getInstanceRef(GroovyPsiElementFactory factory) throws IncorrectOperationException {
@@ -264,19 +300,18 @@ public class OldReferencesResolver {
}
}
private PsiElement replaceFieldWithGetter(PsiElement expr, PsiField psiField) throws IncorrectOperationException {
private static PsiElement replaceFieldWithGetter(PsiElement expr, PsiField psiField) throws IncorrectOperationException {
if (RefactoringUtil.isAssignmentLHS(expr)) {
// todo: warning
return expr;
}
PsiElement newExpr = expr;
PsiMethod getterPrototype = PropertyUtil.generateGetterPrototype(psiField);
PsiMethod getter = psiField.getContainingClass().findMethodBySignature(getterPrototype, true);
PsiMethod getter = GroovyPropertyUtils.findGetterForField(psiField);
if (getter != null) {
if (JavaPsiFacade.getInstance(psiField.getProject()).getResolveHelper().isAccessible(getter, newExpr, null)) {
GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(newExpr.getProject());
String id = getter.getName();
final PsiElement parent = newExpr.getParent();
@@ -287,14 +322,18 @@ public class OldReferencesResolver {
qualifier = qualifierExpression.getText();
}
}
GrMethodCallExpression getterCall =
(GrMethodCallExpression)factory.createExpressionFromText((qualifier != null ? qualifier + "." : "") + id + "()");
getterCall = (GrMethodCallExpression)CodeStyleManager.getInstance(myProject).reformat(getterCall);
GrExpression getterCall;
if (PsiTreeUtil.isAncestor(psiField.getContainingClass(), expr, true)) {
getterCall = factory.createExpressionFromText((qualifier != null ? qualifier + "." : "") + id + "()");
}
else {
getterCall = factory.createExpressionFromText((qualifier != null ? qualifier + "." : "") + psiField.getName());
}
if (parent != null) {
newExpr = parent.replace(getterCall);
}
else {
newExpr = getterCall;
newExpr = expr.replace(getterCall);
}
}
else {
@@ -306,25 +345,25 @@ public class OldReferencesResolver {
}
@Nullable
private static PsiElement getClassContainingResolve(final JavaResolveResult result) {
private static PsiElement getClassContainingResolve(final GroovyResolveResult result) {
final PsiElement elem = result.getElement();
if (elem != null) {
if (elem instanceof PsiLocalVariable || elem instanceof PsiParameter) {
return PsiTreeUtil.getParentOfType(elem, PsiClass.class);
if (elem instanceof PsiMember) {
return ((PsiMember)elem).getContainingClass();
}
else {
return result.getCurrentFileResolveScope();
return PsiTreeUtil.getParentOfType(elem, PsiClass.class);
}
}
return null;
}
private static GrReferenceExpression decodeReferenceExpression(GrReferenceExpression newExpr, PsiReferenceExpression refExpr)
private static GrReferenceExpression decodeReferenceExpression(GrReferenceExpression newExpr, GrReferenceExpression refExpr)
throws IncorrectOperationException {
PsiManager manager = refExpr.getManager();
GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(manager.getProject());
PsiExpression qualifier = refExpr.getQualifierExpression();
GrExpression qualifier = refExpr.getQualifier();
if (qualifier == null) {
PsiMember refMember = refExpr.getCopyableUserData(REF_MEMBER_KEY);
refExpr.putCopyableUserData(REF_MEMBER_KEY, null);
@@ -358,29 +397,29 @@ public class OldReferencesResolver {
return newExpr;
}
private static boolean canRemoveQualifier(PsiReferenceExpression refExpr) {
private static boolean canRemoveQualifier(GrReferenceExpression refExpr) {
try {
PsiExpression qualifier = refExpr.getQualifierExpression();
if (!(qualifier instanceof PsiReferenceExpression)) return false;
GrExpression qualifier = refExpr.getQualifier();
if (!(qualifier instanceof GrReferenceExpression)) return false;
PsiElement qualifierRefElement = ((PsiReferenceExpression)qualifier).resolve();
PsiElement qualifierRefElement = ((GrReferenceExpression)qualifier).resolve();
if (!(qualifierRefElement instanceof PsiClass)) return false;
PsiElement refElement = refExpr.resolve();
if (refElement == null) return false;
PsiElementFactory factory = JavaPsiFacade.getInstance(refExpr.getProject()).getElementFactory();
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(refExpr.getProject());
if (refExpr.getParent() instanceof PsiMethodCallExpression) {
PsiMethodCallExpression methodCall = (PsiMethodCallExpression)refExpr.getParent();
PsiMethodCallExpression newMethodCall =
(PsiMethodCallExpression)factory.createExpressionFromText(refExpr.getReferenceName() + "()", refExpr);
if (refExpr.getParent() instanceof GrMethodCallExpression) {
GrMethodCallExpression methodCall = (GrMethodCallExpression)refExpr.getParent();
GrMethodCallExpression newMethodCall =
(GrMethodCallExpression)factory.createExpressionFromText(refExpr.getReferenceName() + "()", refExpr);
newMethodCall.getArgumentList().replace(methodCall.getArgumentList());
PsiElement newRefElement = newMethodCall.getMethodExpression().resolve();
PsiElement newRefElement = ((GrReferenceExpression)newMethodCall.getInvokedExpression()).resolve();
return refElement.equals(newRefElement);
}
else {
PsiReferenceExpression newRefExpr = (PsiReferenceExpression)factory.createExpressionFromText(refExpr.getReferenceName(), refExpr);
GrReferenceExpression newRefExpr = (GrReferenceExpression)factory.createExpressionFromText(refExpr.getReferenceName(), refExpr);
PsiElement newRefElement = newRefExpr.resolve();
return refElement.equals(newRefElement);
}
@@ -389,4 +428,4 @@ public class OldReferencesResolver {
return false;
}
}
}
}
@@ -98,5 +98,20 @@ class GroovyReparseTest extends LightCodeInsightFixtureTestCase {
""", "switch "
}
public void testSwitchCaseDot() throws Exception {
checkReparse """
def foo() {
switch(x) {
case 2:
return <caret>
case 3:
return false
case 4:
return false
}
}
""", "foo."
}
}
@@ -0,0 +1,292 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.refactoring.introduceParameter;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.psi.PsiType;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
import com.intellij.refactoring.IntroduceParameterRefactoring;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import gnu.trove.TIntArrayList;
import gnu.trove.TObjectIntHashMap;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContext;
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceDialog;
import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.*;
import org.jetbrains.plugins.groovy.util.TestUtils;
/**
* @author Maxim.Medvedev
*/
public class GrIntroduceParameterTest extends LightCodeInsightFixtureTestCase {
protected String getBasePath() {
return TestUtils.getTestDataPath() + "refactoring/introduceParameterGroovy/" + getTestName(true) + '/';
}
private boolean doTest(int replaceFieldsWithGetters, boolean removeUnusedParameters, boolean searchForSuper, boolean declareFinal) {
return doTest(replaceFieldsWithGetters, removeUnusedParameters, searchForSuper, declareFinal, null);
}
private boolean doTest(final int replaceFieldsWithGetters,
final boolean removeUnusedParameters,
boolean searchForSuper,
final boolean declareFinal,
final String conflicts) {
final String beforeGroovy = getTestName(false)+"Before.groovy";
final String afterGroovy = getTestName(false) + "After.groovy";
final String clazz = getTestName(false) + "MyClass.groovy";
myFixture.configureByFiles(clazz, beforeGroovy);
execute(replaceFieldsWithGetters, removeUnusedParameters, declareFinal, conflicts);
PostprocessReformattingAspect.getInstance(getProject()).doPostponedFormatting();
myFixture.getEditor().getSelectionModel().removeSelection();
myFixture.checkResultByFile(beforeGroovy, afterGroovy, true);
return true;
}
private void execute(final int replaceFieldsWithGetters,
final boolean removeUnusedParameters,
final boolean declareFinal,
final String conflicts) {
CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
@Override
public void run() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
try {
final GrIntroduceParameterHandler hackedHandler = new GrIntroduceParameterHandler() {
@Override
protected GrIntroduceDialog<GrIntroduceParameterSettings> getDialog(final GrIntroduceContext context) {
final GrIntroduceParameterSettings hackedSettings =
getSettings(context, removeUnusedParameters, replaceFieldsWithGetters, declareFinal);
return new GrIntroduceDialog<GrIntroduceParameterSettings>() {
@Override
public GrIntroduceParameterSettings getSettings() {
return null;
}
@Override
public void show() {
new GrIntroduceParameterProcessor(hackedSettings, (GrIntroduceParameterContext)context).run();
}
@Override
public boolean isOK() {
return false;
}
};
}
};
hackedHandler.invoke(myFixture.getProject(), myFixture.getEditor(), myFixture.getFile(), null);
if (conflicts != null) fail("Conflicts were expected");
}
catch (Exception e) {
if (conflicts == null) {
e.printStackTrace();
fail("Conflicts were not expected");
}
assertEquals(conflicts, e.getMessage());
}
}
});
}
}, "introduce Parameter", null);
}
private GrIntroduceParameterSettings getSettings(final GrIntroduceContext context,
final boolean removeUnusedParameters,
final int replaceFieldsWithGetters,
final boolean declareFinal) {
return new GrIntroduceParameterSettings() {
@Override
public boolean generateDelegate() {
return false;
}
@Override
public TIntArrayList parametersToRemove() {
if (removeUnusedParameters) {
final TObjectIntHashMap<GrParameter> parametersToRemove = GroovyIntroduceParameterUtil.findParametersToRemove(context);
TIntArrayList list = new TIntArrayList(parametersToRemove.size());
for (Object o : parametersToRemove.keys()) {
list.add(parametersToRemove.get((GrParameter)o));
}
return list;
}
return new TIntArrayList(0);
}
@Override
public int replaceFieldsWithGetters() {
return replaceFieldsWithGetters;
}
@Override
public boolean declareFinal() {
return declareFinal;
}
@Override
public boolean removeLocalVariable() {
return false;
}
@Override
public String getName() {
return "anObject";
}
@Override
public boolean replaceAllOccurrences() {
return true;
}
@Override
public PsiType getSelectedType() {
PsiType type = context.var == null ? context.expression.getType() : context.var.getDeclaredType();
return TypesUtil.unboxPrimitiveTypeWrapper(type);
}
};
}
public void testSimpleOverridedMethod() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, false);
}
public void testOverridedMethodWithRemoveUnusedParameters() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, true, false, false);
}
public void testSimpleUsage() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, false);
}
public void testMethodWithoutParams() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, false);
}
public void testParameterSubstitution() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, false);
}
public void testThisSubstitution() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, false);
}
public void testThisSubstitutionInQualifier() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, false, "field <b><code>Test.i</code></b> is not accessible from method <b><code>XTest.n()</code></b>. Value for introduced parameter in that method call will be incorrect.");
}
public void testFieldAccess() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, false);
}
public void testMethodAccess() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, false);
}
public void testStaticFieldAccess() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, false);
}
public void testFieldWithGetterReplacement() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_ALL, false, false, false);
}
public void testFieldWithInaccessibleGetterReplacement() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false);
}
public void testWeirdQualifier() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false);
}
public void testSuperInExpression() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class.");
}
public void testWeirdQualifierAndParameter() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false);
}
public void testImplicitSuperCall() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false);
}
public void testImplicitDefaultConstructor() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false);
}
public void testInternalSideEffect() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false);
}
/* public void testAnonymousClass() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false);
}*/
public void testSuperWithSideEffect() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class.");
}
public void testConflictingField() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, true, false);
}
/*public void testParameterJavaDoc1() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, true);
}
public void testParameterJavaDoc2() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, true);
}
public void testParameterJavaDoc3() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, true);
}
public void testParameterJavaDocBeforeVararg() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, true);
}*/
public void testRemoveParameterInHierarchy() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, true, false, false);
}
/*public void testRemoveParameterWithJavadoc() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, true, false, false);
}*/
public void testVarargs() { // IDEADEV-16828
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, false);
}
public void testMethodUsageInThisMethodInheritor() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, false);
}
public void testIncorrectArgumentList() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, true, false, true);
}
}
@@ -1,6 +1,6 @@
class A {
def foo() {
print Other.<selection>CONST</selection>
print <selection>Other.CONST</selection>
}
}
@@ -4,4 +4,4 @@ interface MyInterface {
def foo(String s);
}
def a = MyInterface.<selection>CONST</selection>;
def a = <selection>MyInterface.CONST</selection>;
@@ -4,6 +4,6 @@ class Bar {
def foo() {
def f = 5
print f
print this.<selection>f</selection>
print <selection>this.f</selection>
}
}
@@ -1,6 +1,6 @@
class XXX {
public int m() {
Test t;
return t.method(1, 1 + t.getI());
return t.method(1, 1 + t.i);
}
}
@@ -1,6 +1,6 @@
class XXX {
public int m() {
Test t;
return t.method(1, 1 + t.i);
return t.method(1, 1 + t.@i);
}
}
@@ -0,0 +1,27 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class Test2 extends Test1 {
public void method(int anObject) {
System.out.println(this.anObject);
}
}
public class Usage {
{
Test t = new Test2();
t.method(1 + 2);
}
}
@@ -0,0 +1,27 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class Test2 extends Test1 {
public void method() {
System.out.println(anObject);
}
}
public class Usage {
{
Test t = new Test2();
t.method();
}
}
@@ -0,0 +1,27 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class Test {
public int anObject;
public void method() {
}
}
public class Test1 extends Test {
public void method() {
System.out.println(<selection>1 + 2</selection>);
System.out.println(anObject);
}
}
@@ -0,0 +1,22 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class XTest {
int n() {
Test t;
return t.method(1, 2, t.i);
}
}
@@ -0,0 +1,22 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class XTest {
int n() {
Test t;
return t.method(1, 2);
}
}
@@ -0,0 +1,21 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class Test {
int method(int a, int b) {
return <selection>i</selection>;
}
public int i;
}
@@ -0,0 +1,21 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class XXX {
public int m() {
Test t;
return t.method(1, 1 + t.i);
}
}
@@ -0,0 +1,21 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class XXX {
public int m() {
Test t;
return t.method(1);
}
}
@@ -0,0 +1,24 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class Test {
int i;
public int getI() { return i; }
int method(int a) {
return <selection>a + i</selection>;
}
}
@@ -0,0 +1,21 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class XXX {
public int m() {
Test t;
return t.method(1, 1 + t.@i);
}
}
@@ -0,0 +1,21 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class XXX {
public int m() {
Test t;
return t.method(1);
}
}
@@ -0,0 +1,24 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class Test {
public int i;
public int getI() { return i; }
int method(int a) {
return <selection>a + i</selection>;
}
}
@@ -0,0 +1,24 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class B extends A {
B() {
super(27)
}
}
class Usage {
A a = new B();
}
@@ -0,0 +1,20 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class B extends A {}
class Usage {
A a = new B();
}
@@ -0,0 +1,21 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class A {
int i;
public A() {
i = <selection>27</selection>;
}
}
@@ -0,0 +1,27 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class B extends A {
int k;
public B() {
super(27)
k = 10;
}
}
class Usage {
A a = new B();
}
@@ -0,0 +1,26 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class B extends A {
int k;
public B() {
k = 10;
}
}
class Usage {
A a = new B();
}
@@ -0,0 +1,6 @@
class A {
int i;
public A() {
i = <selection>27</selection>;
}
}
@@ -0,0 +1,6 @@
class A {
int i;
def foo(int x, double y) {
i = <selection>27+y</selection>;
}
}
@@ -0,0 +1,32 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class Usage {
int usage(Test[] tests) {
int sum = 0;
int i = 0;
while (i < tests.length) {
final Test test = tests[i++]
sum += test.method(test.field);
}
List list = Arrays.asList(tests);
i = 0;
while (i < list.size()) {
final Test test = (Test) list.get(i++)
sum += test.method(test.field);
}
}
}
@@ -0,0 +1,30 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class Usage {
int usage(Test[] tests) {
int sum = 0;
int i = 0;
while (i < tests.length) {
sum += tests[i++].method();
}
List list = Arrays.asList(tests);
i = 0;
while (i < list.size()) {
sum += ((Test) list.get(i++)).method();
}
}
}
@@ -0,0 +1,22 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class Test {
int field;
int method() {
return <selection>field</selection>;
}
}
@@ -0,0 +1,22 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class XTest {
int n() {
Test t;
return t.method(1, 2, t.anotherMethod(1 + 2));
}
}
@@ -0,0 +1,22 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class XTest {
int n() {
Test t;
return t.method(1, 2);
}
}
@@ -0,0 +1,25 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class Test {
int method(int a, int b) {
return <selection>anotherMethod(a + b)</selection>;
}
int i;
int anotherMethod(int x) {
return x;
}
}
@@ -0,0 +1,20 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class D extends C {
int foo(int x, int anObject) {
return super.foo(x, anObject);
}
}
@@ -0,0 +1,20 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class D extends C {
int foo(int x) {
return super.foo(x);
}
}
@@ -0,0 +1,20 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class C {
int foo(int x) {
return <selection>x+1</selection>;
}
}
@@ -0,0 +1,21 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class X3 {
int n() {
Test t;
return t.m(0);
}
}
@@ -0,0 +1,21 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class X3 {
int n() {
Test t;
return t.m();
}
}
@@ -0,0 +1,20 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class Test {
int m() {
return <selection>0</selection>;
}
}
@@ -0,0 +1,20 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class GrClass extends MyClass {
public int m(int y, int anObject) {
return 1;
}
}
@@ -0,0 +1,20 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class GrClass extends MyClass {
public int m(int x, int y) {
return 1;
}
}
@@ -0,0 +1,20 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class MyClass {
public int m(int x, int y) {
return <selection>x+1</selection>+y;
}
}
@@ -0,0 +1,22 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class XTest {
int n() {
Test t;
return t.method(1, 2, 1 + 2);
}
}
@@ -0,0 +1,22 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class XTest {
int n() {
Test t;
return t.method(1, 2);
}
}
@@ -0,0 +1,20 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class Test {
int method(int a, int b) {
return <selection>a + b</selection>;
}
}
@@ -0,0 +1,20 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class S extends Bar {
public int baz(int anObject) {
return super.baz(anObject); //To change body of overridden methods use File | Settings | File Templates.
}
}
@@ -0,0 +1,20 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class S extends Bar {
public int baz(byte blah) {
return super.baz((byte) 0); //To change body of overridden methods use File | Settings | File Templates.
}
}
@@ -0,0 +1,20 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class Bar {
public int baz(byte blah) {
return <selection>blah + 3</selection>;
}
}

Some files were not shown because too many files have changed in this diff Show More