diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GrMethodOverrideCompletionProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GrMethodOverrideCompletionProvider.java new file mode 100644 index 000000000000..0496728972c3 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GrMethodOverrideCompletionProvider.java @@ -0,0 +1,101 @@ +/* + * Copyright 2000-2015 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.completion; + +import com.intellij.codeInsight.completion.*; +import com.intellij.codeInsight.generation.OverrideImplementExploreUtil; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.icons.AllIcons; +import com.intellij.psi.*; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.psi.util.PsiFormatUtilBase; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.ui.RowIcon; +import com.intellij.util.ProcessingContext; +import com.intellij.util.VisibilityUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.completion.handlers.GroovyMethodOverrideHandler; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinitionBody; + +import javax.swing.*; +import java.util.Collection; + +import static com.intellij.patterns.PlatformPatterns.psiElement; + +/** + * Created by Arasthel on 29/01/15. + */ + +class GrMethodOverrideCompletionProvider extends CompletionProvider { + + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, @NotNull CompletionResultSet result) { + PsiElement position = parameters.getPosition(); + + PsiClass currentClass = PsiTreeUtil.getParentOfType(position, PsiClass.class); + + if (currentClass != null) { + addSuperMethods(currentClass, result, false); + addSuperMethods(currentClass, result, true); + } + } + + public static void register(CompletionContributor contributor) { + contributor.extend(CompletionType.BASIC, psiElement().withParent(GrTypeDefinitionBody.class), new GrMethodOverrideCompletionProvider()); + } + + private void addSuperMethods(final PsiClass psiClass, CompletionResultSet completionResultSet, boolean implement) { + Collection candidates = OverrideImplementExploreUtil.getMethodsToOverrideImplement(psiClass, implement); + for(CandidateInfo candidateInfo : candidates) { + final PsiMethod method = (PsiMethod) candidateInfo.getElement(); + PsiSubstitutor substitutor = candidateInfo.getSubstitutor(); + + RowIcon icon = new RowIcon(2); + icon.setIcon(method.getIcon(0), 0); + icon.setIcon(implement ? AllIcons.Gutter.ImplementingMethod : AllIcons.Gutter.OverridingMethod, 1); + + if(!method.isConstructor()) { + completionResultSet.addElement(createLookUpElement(method, substitutor, psiClass, icon, new GroovyMethodOverrideHandler(psiClass))); + } + } + } + + private LookupElementBuilder createLookUpElement(final PsiMethod method, PsiSubstitutor substitutor, PsiClass currentClass, Icon icon, + InsertHandler insertHandler) { + String parameters = PsiFormatUtil.formatMethod(method, substitutor, PsiFormatUtilBase.SHOW_PARAMETERS, PsiFormatUtilBase.SHOW_NAME); + + String visibility = VisibilityUtil.getVisibilityModifier(method.getModifierList()); + String modifiers = (visibility == PsiModifier.PACKAGE_LOCAL ? "" : visibility + " "); + + PsiType type = substitutor.substitute(method.getReturnType()); + + String parentClassName = currentClass == null ? "" : currentClass.getName(); + + String signature = modifiers + (type == null ? "" : type.getPresentableText() + " ") + method.getName(); + + LookupElementBuilder elementBuilder = LookupElementBuilder.create(method, signature) + .withLookupString(signature) + .appendTailText(parameters, false) + .appendTailText("{...}", true) + .withTypeText(parentClassName) + .withIcon(icon) + .withInsertHandler(insertHandler); + + return elementBuilder; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java index 4c0c342030fb..05b5611339eb 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java @@ -44,6 +44,7 @@ public class GroovyCompletionContributor extends CompletionContributor { public GroovyCompletionContributor() { + GrMethodOverrideCompletionProvider.register(this); GrThisSuperCompletionProvider.register(this); MapArgumentCompletionProvider.register(this); GroovyConfigSlurperCompletionProvider.register(this); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/GroovyMethodOverrideHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/GroovyMethodOverrideHandler.java new file mode 100644 index 000000000000..252e87672a30 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/GroovyMethodOverrideHandler.java @@ -0,0 +1,48 @@ +/* + * Copyright 2000-2015 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.completion.handlers; + +import com.intellij.codeInsight.completion.InsertHandler; +import com.intellij.codeInsight.completion.InsertionContext; +import com.intellij.codeInsight.generation.GenerateMembersUtil; +import com.intellij.codeInsight.generation.OverrideImplementUtil; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; + +import java.util.List; + +/** + * Created by Arasthel on 29/01/15. + */ +public class GroovyMethodOverrideHandler implements InsertHandler { + + private PsiClass myPsiClass; + + public GroovyMethodOverrideHandler(PsiClass aClass) { + this.myPsiClass = aClass; + } + + @Override + public void handleInsert(InsertionContext context, LookupElement item) { + context.getDocument().deleteString(context.getStartOffset(), context.getTailOffset()); + PsiMethod method = (PsiMethod) item.getObject(); + List prototypes = OverrideImplementUtil.overrideOrImplementMethod(myPsiClass, method, false); + context.commitDocument(); + GenerateMembersUtil.insertMembersAtOffset(context.getFile(), context.getStartOffset(), + OverrideImplementUtil.convert2GenerationInfos(prototypes)); + } +}