diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
index 4a5e3fbde661..87abba067121 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
@@ -895,7 +895,7 @@ public class ExtractMethodProcessor implements MatchProvider {
protected PsiElement addToMethodCallLocation(PsiStatement statement) throws IncorrectOperationException {
if (myEnclosingBlockStatement == null) {
- PsiElement containingStatement = PsiTreeUtil.getParentOfType(myExpression != null ? myExpression : myElements[0], PsiStatement.class, false);
+ PsiElement containingStatement = myElements[0] instanceof PsiComment ? myElements[0] : PsiTreeUtil.getParentOfType(myExpression != null ? myExpression : myElements[0], PsiStatement.class, false);
if (containingStatement == null) {
containingStatement = PsiTreeUtil.getParentOfType(myExpression != null ? myExpression : myElements[0], PsiComment.class, false);
}
diff --git a/java/java-tests/testData/refactoring/extractMethod/ExtractWithLeadingComment.java b/java/java-tests/testData/refactoring/extractMethod/ExtractWithLeadingComment.java
new file mode 100644
index 000000000000..a2519de1d143
--- /dev/null
+++ b/java/java-tests/testData/refactoring/extractMethod/ExtractWithLeadingComment.java
@@ -0,0 +1,12 @@
+class Test {
+ public void method2() {
+ if (true) {
+
+ // add to list2
+ list2.add(true);
+
+ } else {
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/extractMethod/ExtractWithLeadingComment_after.java b/java/java-tests/testData/refactoring/extractMethod/ExtractWithLeadingComment_after.java
new file mode 100644
index 000000000000..8833a288035d
--- /dev/null
+++ b/java/java-tests/testData/refactoring/extractMethod/ExtractWithLeadingComment_after.java
@@ -0,0 +1,16 @@
+class Test {
+ public void method2() {
+ if (true) {
+ newMethod();
+
+
+ } else {
+
+ }
+ }
+
+ private void newMethod() {
+ // add to list2
+ list2.add(true);
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java
index 9d632414afb4..f6ad0d3b6b46 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java
@@ -482,6 +482,10 @@ public class ExtractMethodTest extends LightCodeInsightTestCase {
doTest();
}
+ public void testExtractWithLeadingComment() throws Exception {
+ doTest();
+ }
+
private void doPrepareErrorTest(final String expectedMessage) throws Exception {
String expectedError = null;
try {
diff --git a/platform/lang-api/src/com/intellij/refactoring/util/MoveRenameUsageInfo.java b/platform/lang-api/src/com/intellij/refactoring/util/MoveRenameUsageInfo.java
index 29a9ad83bc44..8015da154fff 100644
--- a/platform/lang-api/src/com/intellij/refactoring/util/MoveRenameUsageInfo.java
+++ b/platform/lang-api/src/com/intellij/refactoring/util/MoveRenameUsageInfo.java
@@ -29,7 +29,6 @@ public class MoveRenameUsageInfo extends UsageInfo{
private PsiReference myReference;
private RangeMarker myReferenceRangeMarker = null;
- private boolean myDynamicUsage;
public MoveRenameUsageInfo(PsiReference reference, PsiElement referencedElement){
this(reference.getElement(), reference, referencedElement);
@@ -46,12 +45,6 @@ public class MoveRenameUsageInfo extends UsageInfo{
init(element, reference, referencedElement);
}
- public MoveRenameUsageInfo(PsiElement element, PsiReference reference, int startOffset, int endOffset, PsiElement referencedElement, boolean nonCodeUsage, boolean isDynamicUsage){
- super(element, startOffset, endOffset, nonCodeUsage);
- myDynamicUsage = isDynamicUsage;
- init(element, reference, referencedElement);
- }
-
private void init(final PsiElement element, PsiReference reference, final PsiElement referencedElement) {
final Project project = element.getProject();
myReferencedElement = referencedElement;
@@ -68,6 +61,7 @@ public class MoveRenameUsageInfo extends UsageInfo{
int elementStart = reference.getElement().getTextRange().getStartOffset();
myReferenceRangeMarker = document.createRangeMarker(elementStart + reference.getRangeInElement().getStartOffset(),
elementStart + reference.getRangeInElement().getEndOffset());
+ myDynamicUsage = reference.resolve() == null;
}
}
@@ -99,8 +93,4 @@ public class MoveRenameUsageInfo extends UsageInfo{
if (rangeInElement.getStartOffset() != start || rangeInElement.getEndOffset() != end) return null;
return reference;
}
-
- public boolean isDynamicUsage() {
- return myDynamicUsage;
- }
}
diff --git a/platform/lang-api/src/com/intellij/usageView/UsageInfo.java b/platform/lang-api/src/com/intellij/usageView/UsageInfo.java
index 425b01cc2929..23c9adee35b6 100644
--- a/platform/lang-api/src/com/intellij/usageView/UsageInfo.java
+++ b/platform/lang-api/src/com/intellij/usageView/UsageInfo.java
@@ -37,6 +37,7 @@ public class UsageInfo {
private final int endOffset; // in navigation element
public final boolean isNonCodeUsage;
+ protected boolean myDynamicUsage = false;
public UsageInfo(@NotNull PsiElement element, int startOffset, int endOffset, boolean isNonCodeUsage) {
LOG.assertTrue(element.isValid(), element);
@@ -80,6 +81,7 @@ public class UsageInfo {
public UsageInfo(@NotNull PsiReference reference) {
this(reference.getElement(), reference.getRangeInElement().getStartOffset(), reference.getRangeInElement().getEndOffset());
+ myDynamicUsage = reference.resolve() == null;
}
public UsageInfo(@NotNull PsiQualifiedReference reference) {
@@ -206,4 +208,8 @@ public class UsageInfo {
public void dispose() {
((Disposable)mySmartPointer).dispose();
}
+
+ public boolean isDynamicUsage() {
+ return myDynamicUsage;
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java
index 57f760abbde8..5bff937c484d 100644
--- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java
+++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java
@@ -389,8 +389,7 @@ public class FindUsagesManager implements JDOMExternalizable {
});
PsiManager.getInstance(project).getSearchHelper().processRequests(options.fastTrack, new ReadActionProcessor() {
public boolean processInReadAction(final PsiReference ref) {
- TextRange rangeInElement = ref.getRangeInElement();
- return usageInfoProcessor.process(new UsageInfo(ref.getElement(), rangeInElement.getStartOffset(), rangeInElement.getEndOffset(), false));
+ return usageInfoProcessor.process(new UsageInfo(ref));
}
});
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorPsiDataProvider.java b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorPsiDataProvider.java
index a4d2f5012b6f..0238e016a128 100644
--- a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorPsiDataProvider.java
+++ b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorPsiDataProvider.java
@@ -117,18 +117,29 @@ public class TextEditorPsiDataProvider implements EditorDataProvider {
}
private static Language getLanguageAtCurrentPositionInEditor(final Editor editor, final PsiFile psiFile) {
- int mostProbablyCorrectLanguageOffset = getOffset(editor);
+ final SelectionModel selectionModel = editor.getSelectionModel();
+ int caretOffset = editor.getCaretModel().getOffset();
+ int mostProbablyCorrectLanguageOffset = caretOffset == selectionModel.getSelectionStart() ||
+ caretOffset == selectionModel.getSelectionEnd()
+ ? selectionModel.getSelectionStart()
+ : caretOffset;
+ if (selectionModel.hasSelection()) {
+ return getLanguageAtOffset(psiFile, mostProbablyCorrectLanguageOffset, selectionModel.getSelectionEnd());
+ }
return PsiUtilBase.getLanguageAtOffset(psiFile, mostProbablyCorrectLanguageOffset);
}
- private static int getOffset(Editor editor) {
- final SelectionModel selectionModel = editor.getSelectionModel();
- int caretOffset = editor.getCaretModel().getOffset();
- return caretOffset == selectionModel.getSelectionStart() ||
- caretOffset == selectionModel.getSelectionEnd()
- ? selectionModel.getSelectionStart()
- : caretOffset;
+ private static Language getLanguageAtOffset(PsiFile psiFile, int mostProbablyCorrectLanguageOffset, int end) {
+ final PsiElement elt = psiFile.findElementAt(mostProbablyCorrectLanguageOffset);
+ if (elt == null) return psiFile.getLanguage();
+ if (elt instanceof PsiWhiteSpace) {
+ final int incremented = elt.getTextRange().getEndOffset() + 1;
+ if (incremented <= end) {
+ return getLanguageAtOffset(psiFile, incremented, end);
+ }
+ }
+ return PsiUtilBase.findLanguageFromElement(elt);
}
@Nullable
diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameUtil.java b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameUtil.java
index a942123ce3d8..ee01fe58425c 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameUtil.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameUtil.java
@@ -71,10 +71,9 @@ public class RenameUtil {
continue;
}
PsiElement referenceElement = ref.getElement();
- final boolean isDynamic = ref.resolve() == null;
result.add(new MoveRenameUsageInfo(referenceElement, ref, ref.getRangeInElement().getStartOffset(),
ref.getRangeInElement().getEndOffset(), element,
- isDynamic, isDynamic));
+ ref.resolve() == null));
}
processor.findCollisions(element, newName, allRenames, result);
diff --git a/platform/usageView/src/com/intellij/usages/impl/rules/NonCodeUsageGroupingRule.java b/platform/usageView/src/com/intellij/usages/impl/rules/NonCodeUsageGroupingRule.java
index 9663d13c773a..15cb1337d60f 100644
--- a/platform/usageView/src/com/intellij/usages/impl/rules/NonCodeUsageGroupingRule.java
+++ b/platform/usageView/src/com/intellij/usages/impl/rules/NonCodeUsageGroupingRule.java
@@ -18,6 +18,7 @@ package com.intellij.usages.impl.rules;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.refactoring.util.MoveRenameUsageInfo;
+import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewBundle;
import com.intellij.usages.Usage;
import com.intellij.usages.UsageGroup;
@@ -25,6 +26,7 @@ import com.intellij.usages.UsageInfo2UsageAdapter;
import com.intellij.usages.UsageView;
import com.intellij.usages.rules.PsiElementUsage;
import com.intellij.usages.rules.UsageGroupingRule;
+import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -90,10 +92,17 @@ public class NonCodeUsageGroupingRule implements UsageGroupingRule {
private static class DynamicUsageGroup implements UsageGroup {
public static final UsageGroup INSTANCE = new DynamicUsageGroup();
+ @NonNls private static final String DYNAMIC_CAPTION = "Dynamic usages";
@NotNull
public String getText(UsageView view) {
- return view == null ? "Dynamic usages" : view.getPresentation().getDynamicCodeUsagesString();
+ if (view == null) {
+ return DYNAMIC_CAPTION;
+ }
+ else {
+ final String dynamicCodeUsagesString = view.getPresentation().getDynamicCodeUsagesString();
+ return dynamicCodeUsagesString == null ? DYNAMIC_CAPTION : dynamicCodeUsagesString;
+ }
}
public void update() {
@@ -117,15 +126,13 @@ public class NonCodeUsageGroupingRule implements UsageGroupingRule {
public UsageGroup groupUsage(Usage usage) {
if (usage instanceof PsiElementUsage) {
- if (((PsiElementUsage)usage).isNonCodeUsage()) {
- if (usage instanceof UsageInfo2UsageAdapter) {
- if (((UsageInfo2UsageAdapter)usage).getUsageInfo() instanceof MoveRenameUsageInfo) {
- final MoveRenameUsageInfo usageInfo = (MoveRenameUsageInfo)((UsageInfo2UsageAdapter)usage).getUsageInfo();
- if (usageInfo.isDynamicUsage()) {
- return DynamicUsageGroup.INSTANCE;
- }
- }
+ if (usage instanceof UsageInfo2UsageAdapter) {
+ final UsageInfo usageInfo = ((UsageInfo2UsageAdapter)usage).getUsageInfo();
+ if (usageInfo.isDynamicUsage()) {
+ return DynamicUsageGroup.INSTANCE;
}
+ }
+ if (((PsiElementUsage)usage).isNonCodeUsage()) {
return NonCodeUsageGroup.INSTANCE;
}
else {
diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml
index 3c69d065228d..d90bdad173ef 100644
--- a/plugins/groovy/src/META-INF/plugin.xml
+++ b/plugins/groovy/src/META-INF/plugin.xml
@@ -260,7 +260,6 @@
-
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyUsageViewGroupingRuleProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyUsageViewGroupingRuleProvider.java
deleted file mode 100644
index cbdb3eee86ca..000000000000
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyUsageViewGroupingRuleProvider.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2000-2009 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.findUsages;
-
-import com.intellij.openapi.actionSystem.AnAction;
-import com.intellij.openapi.project.Project;
-import com.intellij.usages.UsageView;
-import com.intellij.usages.rules.UsageGroupingRule;
-import com.intellij.usages.rules.UsageGroupingRuleProvider;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * @author ven
- */
-public class GroovyUsageViewGroupingRuleProvider implements UsageGroupingRuleProvider {
- @NotNull
- public UsageGroupingRule[] getActiveRules(Project project) {
- return new UsageGroupingRule[] {new LateBoundUsageGroupingRule()};
- }
-
- @NotNull
- public AnAction[] createGroupingActions(UsageView view) {
- return AnAction.EMPTY_ARRAY;
- }
-}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/LateBoundUsageGroupingRule.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/LateBoundUsageGroupingRule.java
deleted file mode 100644
index 5d02dfed9ca6..000000000000
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/LateBoundUsageGroupingRule.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2000-2009 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.findUsages;
-
-import com.intellij.openapi.vcs.FileStatus;
-import com.intellij.psi.PsiElement;
-import com.intellij.usages.Usage;
-import com.intellij.usages.UsageGroup;
-import com.intellij.usages.UsageView;
-import com.intellij.usages.rules.OrderableUsageGroupingRule;
-import com.intellij.usages.rules.PsiElementUsage;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
-
-import javax.swing.*;
-
-/**
- * @author ven
- */
-public class LateBoundUsageGroupingRule implements OrderableUsageGroupingRule {
- private final LateBoundGroup INSTANCE = new LateBoundGroup();
-
- private class LateBoundGroup implements UsageGroup {
-
- public Icon getIcon(boolean isOpen) {
- return null;
- }
-
- @NotNull
- public String getText(UsageView view) {
- return "Dynamically typed usages";
- }
-
- public FileStatus getFileStatus() {
- return null;
- }
-
- public boolean isValid() {
- return true;
- }
-
- public void update() {
- }
-
- public int compareTo(UsageGroup usageGroup) {
- return getText(null).compareTo(usageGroup.getText(null));
- }
-
- public void navigate(boolean b) {
- }
-
- public boolean canNavigate() {
- return false;
- }
-
- public boolean canNavigateToSource() {
- return false;
- }
- }
-
- public UsageGroup groupUsage(Usage usage) {
- if (usage instanceof PsiElementUsage) {
- final PsiElement element = ((PsiElementUsage) usage).getElement();
- if (element instanceof GrReferenceExpression && ((GrReferenceExpression) element).resolve() == null) {
- return INSTANCE;
- }
- }
-
- return null;
- }
-
- public int getRank() {
- return 0;
- }
-}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parameterInfo/GroovyParameterInfoHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parameterInfo/GroovyParameterInfoHandler.java
index 8f3d84c4894e..f2449cd6e89f 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parameterInfo/GroovyParameterInfoHandler.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parameterInfo/GroovyParameterInfoHandler.java
@@ -440,12 +440,16 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandler im
return findChildByType(TokenSets.VISIBILITY_MODIFIERS) != null;
}
- public boolean hasModifierProperty(@NotNull @NonNls String modifier) {
- final PsiElement parent = getParent();
+ public static boolean checkModifierProperty(@NotNull GrModifierList modifierList, @NotNull String modifier) {
+ final PsiElement parent = modifierList.getParent();
if (parent instanceof GrVariableDeclaration &&
parent.getParent() instanceof GrTypeDefinitionBody) {
PsiElement pParent = parent.getParent().getParent();
- if (!hasExplicitVisibilityModifiers()) { //properties are backed by private fields
+ if (!modifierList.hasExplicitVisibilityModifiers()) { //properties are backed by private fields
if (!(pParent instanceof PsiClass) || !((PsiClass)pParent).isInterface()) {
if (modifier.equals(GrModifier.PRIVATE)) return true;
if (modifier.equals(GrModifier.PROTECTED)) return false;
@@ -161,20 +161,20 @@ public class GrModifierListImpl extends GrStubElementBase im
if (modifier.equals(GrModifier.FINAL)) return true;
}
if (pParent instanceof GrTypeDefinition) {
- PsiModifierList modifierList = ((GrTypeDefinition)pParent).getModifierList();
- if (modifierList != null && modifierList.findAnnotation(GroovyImmutableAnnotationInspection.IMMUTABLE) != null) {
+ PsiModifierList pModifierList = ((GrTypeDefinition)pParent).getModifierList();
+ if (pModifierList != null && pModifierList.findAnnotation(GroovyImmutableAnnotationInspection.IMMUTABLE) != null) {
if (modifier.equals(GrModifier.FINAL)) return true;
}
}
}
- if (hasExplicitModifier(modifier)) {
+ if (modifierList.hasExplicitModifier(modifier)) {
return true;
}
if (modifier.equals(GrModifier.PUBLIC)) {
//groovy type definitions and methods are public by default
- return !hasExplicitModifier(GrModifier.PRIVATE) && !hasExplicitModifier(GrModifier.PROTECTED);
+ return !modifierList.hasExplicitModifier(GrModifier.PRIVATE) && !modifierList.hasExplicitModifier(GrModifier.PROTECTED);
}
if (parent instanceof GrTypeDefinition) {
@@ -190,6 +190,10 @@ public class GrModifierListImpl extends GrStubElementBase im
return false;
}
+ public boolean hasModifierProperty(@NotNull @NonNls String modifier) {
+ return checkModifierProperty(this, modifier);
+ }
+
public boolean hasExplicitModifier(@NotNull @NonNls String name) {
final GrModifierListStub stub = getStub();
if (stub != null) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/params/GrParameterListImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/params/GrParameterListImpl.java
index 0299e6dfcd5d..a3f465a9c8c0 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/params/GrParameterListImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/params/GrParameterListImpl.java
@@ -98,8 +98,9 @@ public class GrParameterListImpl extends GrStubElementBase implements
}
public int getParameterNumber(final GrParameter parameter) {
- for (int i = 0; i < getParameters().length; i++) {
- GrParameter param = getParameters()[i];
+ GrParameter[] parameters = getParameters();
+ for (int i = 0; i < parameters.length; i++) {
+ GrParameter param = parameters[i];
if (param == parameter) {
return i;
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightMethodBuilder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightMethodBuilder.java
new file mode 100644
index 000000000000..d5deb15634a9
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightMethodBuilder.java
@@ -0,0 +1,379 @@
+/*
+ * 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.lang.psi.impl.synthetic;
+
+import com.intellij.navigation.ItemPresentation;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.ElementPresentationUtil;
+import com.intellij.psi.impl.PsiClassImplUtil;
+import com.intellij.psi.impl.PsiImplUtil;
+import com.intellij.psi.impl.PsiSuperMethodImplUtil;
+import com.intellij.psi.impl.light.LightElement;
+import com.intellij.psi.impl.light.LightEmptyImplementsList;
+import com.intellij.psi.impl.light.LightIdentifier;
+import com.intellij.psi.presentation.java.JavaPresentationUtil;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.util.MethodSignature;
+import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
+import com.intellij.ui.RowIcon;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Icons;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.GroovyFileType;
+import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocComment;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
+import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
+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.GrMember;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
+import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
+
+import javax.swing.*;
+import java.util.List;
+
+/**
+ * @author Sergey Evdokimov
+ */
+public class GrLightMethodBuilder extends LightElement implements GrMethod {
+ private final String myName;
+ private PsiType myReturnType;
+ private final GrModifierList myModifierList;
+ private GrParameterList myParameterList;
+ private Icon myBaseIcon;
+ private PsiClass myContainingClass;
+ private Object myMethodKind;
+ private String[] namedParametersArray = ArrayUtil.EMPTY_STRING_ARRAY;
+
+ public GrLightMethodBuilder(PsiManager manager, String name) {
+ this(manager, name, new GrLightParameterListBuilder(manager, GroovyFileType.GROOVY_LANGUAGE), null);
+ }
+
+ public GrLightMethodBuilder(PsiManager manager,
+ String name,
+ GrParameterList parameterList,
+ GrModifierList modifierList) {
+ super(manager, GroovyFileType.GROOVY_LANGUAGE);
+ myName = name;
+ myParameterList = parameterList;
+ myModifierList = modifierList == null ? new GrLightModifierList(this, ArrayUtil.EMPTY_STRING_ARRAY) : modifierList;
+ }
+
+ public void setNamedParametersArray(@NotNull String[] namedParametersArray) {
+ this.namedParametersArray = namedParametersArray;
+ }
+
+ @Override
+ public ItemPresentation getPresentation() {
+ return JavaPresentationUtil.getMethodPresentation(this);
+ }
+
+ public boolean hasTypeParameters() {
+ return false;
+ }
+
+ @NotNull
+ public PsiTypeParameter[] getTypeParameters() {
+ return PsiTypeParameter.EMPTY_ARRAY;
+ }
+
+ public PsiTypeParameterList getTypeParameterList() {
+ //todo
+ return null;
+ }
+
+ public GrDocComment getDocComment() {
+ //todo
+ return null;
+ }
+
+ public boolean isDeprecated() {
+ //todo
+ return false;
+ }
+
+ public PsiElement setName(@NotNull String name) throws IncorrectOperationException {
+ throw new IncorrectOperationException("Please don't rename light methods");
+ }
+
+ @NotNull
+ public String getName() {
+ return myName;
+ }
+
+ @NotNull
+ public HierarchicalMethodSignature getHierarchicalMethodSignature() {
+ return PsiSuperMethodImplUtil.getHierarchicalMethodSignature(this);
+ }
+
+ public boolean hasModifierProperty(@NotNull String name) {
+ return getModifierList().hasModifierProperty(name);
+ }
+
+ @Override
+ public GrMember[] getMembers() {
+ return GrMember.EMPTY_ARRAY;
+ }
+
+ @NotNull
+ public GrModifierList getModifierList() {
+ return myModifierList;
+ }
+
+ @NotNull
+ @Override
+ public String[] getNamedParametersArray() {
+ return namedParametersArray;
+ }
+
+ public GrLightMethodBuilder addModifiers(String... modifiers) {
+ for (String modifier : modifiers) {
+ addModifier(modifier);
+ }
+ return this;
+ }
+
+ public GrLightMethodBuilder addModifier(String modifier) {
+ ((GrLightModifierList)myModifierList).addModifier(modifier);
+ return this;
+ }
+
+ public GrLightMethodBuilder setModifiers(String[] modifiers) {
+ ((GrLightModifierList)myModifierList).clearModifiers();
+ addModifiers(modifiers);
+ return this;
+ }
+
+ @Override
+ public GrOpenBlock getBlock() {
+ return null;
+ }
+
+ @Override
+ public void setBlock(GrCodeBlock newBlock) {
+ throw new IncorrectOperationException();
+ }
+
+ @Override
+ public GrTypeElement getReturnTypeElementGroovy() {
+ return null;
+ }
+
+ @Override
+ public PsiType getInferredReturnType() {
+ return getReturnType();
+ }
+
+ public PsiType getReturnType() {
+ return myReturnType;
+ }
+
+ public GrTypeElement setReturnType(PsiType returnType) {
+ myReturnType = returnType;
+ return null;
+ }
+
+ public PsiTypeElement getReturnTypeElement() {
+ return null;
+ }
+
+ @Override
+ public GrParameter[] getParameters() {
+ return myParameterList.getParameters();
+ }
+
+ @NotNull
+ public GrParameterList getParameterList() {
+ return myParameterList;
+ }
+
+ public GrLightMethodBuilder addParameter(@NotNull GrParameter parameter) {
+ ((GrLightParameterListBuilder)myParameterList).addParameter(parameter);
+ return this;
+ }
+
+ public GrLightMethodBuilder addParameter(@NotNull String name, @NotNull String type, boolean isOptional) {
+ return addParameter(name, JavaPsiFacade.getElementFactory(getProject()).createTypeFromText(type, this), isOptional);
+ }
+
+ public GrLightMethodBuilder addParameter(@NotNull String name, @NotNull PsiType type, boolean isOptional) {
+ GrLightParameter param = new GrLightParameter(name, type, this).setOptional(isOptional);
+ return addParameter(param);
+ }
+
+ @NotNull
+ public PsiReferenceList getThrowsList() {
+ //todo
+ return new LightEmptyImplementsList(getManager());
+ }
+
+ public PsiCodeBlock getBody() {
+ return null;
+ }
+
+ @Override
+ public boolean isConstructor() {
+ return false;
+ }
+
+ public boolean isVarArgs() {
+ //todo
+ return false;
+ }
+
+ @NotNull
+ public MethodSignature getSignature(@NotNull PsiSubstitutor substitutor) {
+ return MethodSignatureBackedByPsiMethod.create(this, substitutor);
+ }
+
+ public PsiIdentifier getNameIdentifier() {
+ return null;
+ }
+
+ @NotNull
+ public PsiMethod[] findSuperMethods() {
+ return PsiSuperMethodImplUtil.findSuperMethods(this);
+ }
+
+ @NotNull
+ public PsiMethod[] findSuperMethods(boolean checkAccess) {
+ return PsiSuperMethodImplUtil.findSuperMethods(this, checkAccess);
+ }
+
+ @NotNull
+ public PsiMethod[] findSuperMethods(PsiClass parentClass) {
+ return PsiSuperMethodImplUtil.findSuperMethods(this, parentClass);
+ }
+
+ @NotNull
+ public List findSuperMethodSignaturesIncludingStatic(boolean checkAccess) {
+ return PsiSuperMethodImplUtil.findSuperMethodSignaturesIncludingStatic(this, checkAccess);
+ }
+
+ public PsiMethod findDeepestSuperMethod() {
+ return PsiSuperMethodImplUtil.findDeepestSuperMethod(this);
+ }
+
+ @NotNull
+ public PsiMethod[] findDeepestSuperMethods() {
+ return PsiSuperMethodImplUtil.findDeepestSuperMethods(this);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof JavaElementVisitor) {
+ ((JavaElementVisitor)visitor).visitMethod(this);
+ }
+ }
+
+ public GrLightMethodBuilder setNavigationElement(PsiElement navigationElement) {
+ super.setNavigationElement(navigationElement);
+ return this;
+ }
+
+ public PsiClass getContainingClass() {
+ return myContainingClass;
+ }
+
+ public GrLightMethodBuilder setContainingClass(PsiClass containingClass) {
+ myContainingClass = containingClass;
+ return this;
+ }
+
+ public GrLightMethodBuilder setMethodKind(@Nullable Object debugKindName) {
+ myMethodKind = debugKindName;
+ return this;
+ }
+
+ @NotNull
+ @Override
+ public PsiElement getNameIdentifierGroovy() {
+ return new LightIdentifier(getManager(), getName());
+ }
+
+ @Override
+ public void accept(GroovyElementVisitor visitor) {
+
+ }
+
+ @Override
+ public void acceptChildren(GroovyElementVisitor visitor) {
+
+ }
+
+ public static boolean checkKind(@Nullable PsiElement method, @NotNull Object kind) {
+ return method instanceof GrLightMethodBuilder && kind.equals(((GrLightMethodBuilder)method).myMethodKind);
+ }
+
+ public String toString() {
+ return myMethodKind + ":" + getName();
+ }
+
+ public Icon getElementIcon(final int flags) {
+ Icon methodIcon = myBaseIcon != null ? myBaseIcon :
+ hasModifierProperty(PsiModifier.ABSTRACT) ? Icons.ABSTRACT_METHOD_ICON : Icons.METHOD_ICON;
+ RowIcon baseIcon = createLayeredIcon(methodIcon, ElementPresentationUtil.getFlags(this, false));
+ return ElementPresentationUtil.addVisibilityIcon(this, flags, baseIcon);
+ }
+
+ public GrLightMethodBuilder setBaseIcon(Icon baseIcon) {
+ myBaseIcon = baseIcon;
+ return this;
+ }
+
+ @Override
+ public boolean isEquivalentTo(final PsiElement another) {
+ return PsiClassImplUtil.isMethodEquivalentTo(this, another);
+ }
+
+ @NotNull
+ public SearchScope getUseScope() {
+ return PsiImplUtil.getMemberUseScope(this);
+ }
+
+ @Override
+ @Nullable
+ public PsiFile getContainingFile() {
+ final PsiClass containingClass = getContainingClass();
+ return containingClass == null ? null : containingClass.getContainingFile();
+ }
+
+ @Override
+ public PsiElement getContext() {
+ final PsiElement navElement = getNavigationElement();
+ if (navElement != this) {
+ return navElement;
+ }
+
+ final PsiClass cls = getContainingClass();
+ if (cls != null) {
+ return cls;
+ }
+
+ return getContainingFile();
+ }
+
+ public PsiMethodReceiver getMethodReceiver() {
+ return null;
+ }
+ public PsiType getReturnTypeNoResolve() {
+ return getReturnType();
+ }
+
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightModifierList.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightModifierList.java
new file mode 100644
index 000000000000..214690a93918
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightModifierList.java
@@ -0,0 +1,125 @@
+/*
+ * 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.lang.psi.impl.synthetic;
+
+import com.intellij.psi.*;
+import com.intellij.psi.impl.light.LightElement;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
+import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierFlags;
+import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList;
+import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation;
+import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.modifiers.GrModifierListImpl;
+
+public class GrLightModifierList extends LightElement implements GrModifierList {
+
+ private String[] myModifiers;
+
+ private final PsiElement myParent;
+
+ public GrLightModifierList(@NotNull PsiElement parent, String[] modifiers) {
+ super(parent.getManager(), parent.getLanguage());
+ myModifiers = modifiers;
+ myParent = parent;
+ }
+
+ @Override
+ public PsiElement getParent() {
+ return myParent;
+ }
+
+ public void addModifier(String modifier) {
+ myModifiers = ArrayUtil.append(myModifiers, modifier, ArrayUtil.STRING_ARRAY_FACTORY);
+ }
+
+ public void clearModifiers() {
+ myModifiers = ArrayUtil.EMPTY_STRING_ARRAY;
+ }
+
+ public boolean hasModifierProperty(@NotNull String name){
+ return GrModifierListImpl.checkModifierProperty(this, name);
+ }
+
+ public boolean hasExplicitModifier(@NotNull String name) {
+ return ArrayUtil.contains(name, myModifiers);
+ }
+
+ public void setModifierProperty(@NotNull String name, boolean value) throws IncorrectOperationException{
+ throw new IncorrectOperationException();
+ }
+
+ public void checkSetModifierProperty(@NotNull String name, boolean value) throws IncorrectOperationException{
+ throw new IncorrectOperationException();
+ }
+
+ @NotNull
+ public GrAnnotation[] getAnnotations() {
+ return GrAnnotation.EMPTY_ARRAY;
+ }
+
+ @NotNull
+ public PsiAnnotation[] getApplicableAnnotations() {
+ return getAnnotations();
+ }
+
+ public PsiAnnotation findAnnotation(@NotNull String qualifiedName) {
+ return null;
+ }
+
+ @NotNull
+ public PsiAnnotation addAnnotation(@NotNull @NonNls String qualifiedName) {
+ throw new IncorrectOperationException("Method addAnnotation is not yet implemented in " + getClass().getName());
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof JavaElementVisitor) {
+ ((JavaElementVisitor)visitor).visitModifierList(this);
+ }
+ else {
+ visitor.visitElement(this);
+ }
+ }
+
+ public String toString() {
+ return "GrModifierList";
+ }
+
+ @NotNull
+ public PsiElement[] getModifiers() {
+ return PsiElement.EMPTY_ARRAY;
+ }
+
+ @Override
+ public boolean hasExplicitVisibilityModifiers() {
+ for (String modifier : myModifiers) {
+ if (modifier.equals(PsiModifier.PRIVATE) || modifier.equals(PsiModifier.PUBLIC) || modifier.equals(PsiModifier.PROTECTED)) return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void accept(GroovyElementVisitor visitor) {
+ visitor.visitModifierList(this);
+ }
+
+ @Override
+ public void acceptChildren(GroovyElementVisitor visitor) {
+
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightParameterListBuilder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightParameterListBuilder.java
new file mode 100644
index 000000000000..b883720ecf0a
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightParameterListBuilder.java
@@ -0,0 +1,108 @@
+/*
+ * 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.lang.psi.impl.synthetic;
+
+import com.intellij.lang.Language;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.light.LightElement;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Sergey Evdokimov
+ */
+public class GrLightParameterListBuilder extends LightElement implements GrParameterList {
+ private final List myParameters = new ArrayList();
+ private GrParameter[] myCachedParameters;
+
+ public GrLightParameterListBuilder(PsiManager manager, Language language) {
+ super(manager, language);
+ }
+
+ public void addParameter(GrParameter parameter) {
+ myParameters.add(parameter);
+ myCachedParameters = null;
+ }
+
+ @Override
+ public String toString() {
+ return "GrLightParameterListBuilder";
+ }
+
+ @NotNull
+ @Override
+ public GrParameter[] getParameters() {
+ if (myCachedParameters == null) {
+ if (myParameters.isEmpty()) {
+ myCachedParameters = GrParameter.EMPTY_ARRAY;
+ }
+ else {
+ myCachedParameters = myParameters.toArray(new GrParameter[myParameters.size()]);
+ }
+ }
+
+ return myCachedParameters;
+ }
+
+ @Override
+ public void addParameterToEnd(GrParameter parameter) {
+
+ }
+
+ @Override
+ public void addParameterToHead(GrParameter parameter) {
+ throw new IncorrectOperationException("GrLightParameterListBuilder is unmodifiable");
+ }
+
+ @Override
+ public int getParameterNumber(GrParameter parameter) {
+ return getParameterIndex(parameter);
+ }
+
+ @Override
+ public int getParameterIndex(PsiParameter parameter) {
+ //noinspection SuspiciousMethodCalls
+ return myParameters.indexOf(parameter);
+ }
+
+ @Override
+ public int getParametersCount() {
+ return myParameters.size();
+ }
+
+ @Override
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof JavaElementVisitor) {
+ ((JavaElementVisitor) visitor).visitParameterList(this);
+ }
+ }
+
+ @Override
+ public void accept(GroovyElementVisitor visitor) {
+ visitor.visitParameterList(this);
+ }
+
+ @Override
+ public void acceptChildren(GroovyElementVisitor visitor) {
+
+ }
+}