/* * Copyright 2003-2013 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 jetbrains.mps.idea.java.psi.impl; import com.intellij.navigation.ColoredItemPresentation; import com.intellij.navigation.ItemPresentation; import com.intellij.openapi.editor.colors.CodeInsightColors; import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Iconable; import com.intellij.psi.EmptySubstitutor; import com.intellij.psi.HierarchicalMethodSignature; import com.intellij.psi.PsiBundle; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiCodeBlock; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiIdentifier; import com.intellij.psi.PsiManager; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiModifier.ModifierConstant; import com.intellij.psi.PsiModifierList; import com.intellij.psi.PsiParameterList; import com.intellij.psi.PsiReferenceList; import com.intellij.psi.PsiReferenceList.Role; import com.intellij.psi.PsiSubstitutor; import com.intellij.psi.PsiType; import com.intellij.psi.PsiTypeElement; import com.intellij.psi.PsiTypeParameter; import com.intellij.psi.PsiTypeParameterList; import com.intellij.psi.impl.ElementPresentationUtil; import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.impl.PsiSuperMethodImplUtil; import com.intellij.psi.impl.light.JavaIdentifier; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.util.MethodSignature; import com.intellij.psi.util.MethodSignatureBackedByPsiMethod; import com.intellij.psi.util.PsiFormatUtil; import com.intellij.ui.RowIcon; import com.intellij.util.IncorrectOperationException; import com.intellij.util.PlatformIcons; import jetbrains.mps.idea.core.psi.impl.MPSPsiNode; import jetbrains.mps.idea.core.psi.impl.MPSPsiNodeBase; import jetbrains.mps.idea.java.refactoring.MoveRenameBatch; import jetbrains.mps.project.MPSProject; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.mps.openapi.model.SNode; import org.jetbrains.mps.openapi.model.SNodeId; import org.jetbrains.mps.openapi.model.SNodeReference; import javax.swing.Icon; import java.util.List; /** * danilla 2/1/13 */ public class MPSPsiMethod extends MPSPsiNode implements PsiMethod { // used during java refactorings private boolean isCopy = false; public MPSPsiMethod(SNodeId id, String concept, String containingRole, PsiManager manager) { super(id, concept, containingRole, manager); addChildLast(new MPSPsiMethodModifierList(manager)); addChildLast(new MPSPsiParameterList(manager)); } @Nullable @Override public PsiType getReturnType() { MPSPsiNode returnTypeNode = getChildOfType("returnType", MPSPsiNode.class); if (returnTypeNode instanceof ComputesPsiType) { return ((ComputesPsiType) returnTypeNode).getPsiType(); } return null; } @Nullable @Override public PsiTypeElement getReturnTypeElement() { return null; //To change body of implemented methods use File | Settings | File Templates. } @NotNull @Override public PsiParameterList getParameterList() { return getChildOfType(MPSPsiParameterList.class); } @Nullable @Override protected MPSPsiNodeBase getParentFor(MPSPsiNode child) { if (child instanceof MPSPsiParameter) { return getChildOfType(MPSPsiParameterList.class); } return super.getParentFor(child); } @NotNull @Override public PsiReferenceList getThrowsList() { MPSPsiClassifierType[] classes = getChildrenOfType("throwsItem", MPSPsiClassifierType.class); return new MPSPsiRefList(this, Role.THROWS_LIST, classes, getManager()); } @Nullable @Override public PsiCodeBlock getBody() { return null; //To change body of implemented methods use File | Settings | File Templates. } @Override public boolean isConstructor() { return false; } @Override public boolean isVarArgs() { return PsiImplUtil.isVarArgs(this); } @NotNull @Override public MethodSignature getSignature(@NotNull PsiSubstitutor substitutor) { return MethodSignatureBackedByPsiMethod.create(this, EmptySubstitutor.getInstance()); } @Nullable @Override public PsiIdentifier getNameIdentifier() { return new JavaIdentifier(getManager(), this); } @NotNull @Override public PsiMethod[] findSuperMethods() { return PsiSuperMethodImplUtil.findSuperMethods(this); } @NotNull @Override public PsiMethod[] findSuperMethods(boolean checkAccess) { return PsiSuperMethodImplUtil.findSuperMethods(this, checkAccess); } @NotNull @Override public PsiMethod[] findSuperMethods(PsiClass parentClass) { return PsiSuperMethodImplUtil.findSuperMethods(this, parentClass); } @NotNull @Override public List<MethodSignatureBackedByPsiMethod> findSuperMethodSignaturesIncludingStatic(boolean checkAccess) { return PsiSuperMethodImplUtil.findSuperMethodSignaturesIncludingStatic(this, checkAccess); } @Nullable @Override public PsiMethod findDeepestSuperMethod() { return PsiSuperMethodImplUtil.findDeepestSuperMethod(this); } @NotNull @Override public PsiMethod[] findDeepestSuperMethods() { return PsiSuperMethodImplUtil.findDeepestSuperMethods(this); } @NotNull @Override public PsiModifierList getModifierList() { return getChildOfType(MPSPsiMethodModifierList.class); } @Override public boolean hasModifierProperty(@ModifierConstant @NonNls @NotNull String name) { return getModifierList().hasModifierProperty(name); } // java refactoring support @Override public MPSPsiMethod copy() { MPSPsiMethod clone = (MPSPsiMethod) clone(); clone.isCopy = true; return clone; } @Override public PsiElement setName(@NonNls @NotNull final String name) throws IncorrectOperationException { // todo: assert that we're in idea command setNameProperty(name); if (isCopy) return this; Project project = getProject(); final MPSProject mpsProject = project.getComponent(MPSProject.class); MoveRenameBatch batch = project.getComponent(MoveRenameBatch.class); final SNodeReference nodeRef = getSNodeReference(); batch.scheduleNodeUpdate(new Runnable() { @Override public void run() { SNode node = nodeRef.resolve(mpsProject.getRepository()); if (node == null) return; node.setProperty("name", name); } }); return this; } @NotNull @Override public HierarchicalMethodSignature getHierarchicalMethodSignature() { return PsiSuperMethodImplUtil.getHierarchicalMethodSignature(this); } @Nullable @Override public PsiDocComment getDocComment() { return null; //To change body of implemented methods use File | Settings | File Templates. } @Override public boolean isDeprecated() { return false; //To change body of implemented methods use File | Settings | File Templates. } @Override public boolean hasTypeParameters() { return false; //To change body of implemented methods use File | Settings | File Templates. } @Nullable @Override public PsiTypeParameterList getTypeParameterList() { return null; //To change body of implemented methods use File | Settings | File Templates. } @NotNull @Override public PsiTypeParameter[] getTypeParameters() { return new PsiTypeParameter[0]; //To change body of implemented methods use File | Settings | File Templates. } @Nullable @Override public PsiClass getContainingClass() { PsiElement node = getParent(); if (node instanceof MPSPsiClassifier) { return (MPSPsiClassifier) node; } else { return null; } } public boolean isStatic() { return "jetbrains.mps.baseLanguage.structure.StaticMethodDeclaration".equals(getConcept()); } @Override public Icon getElementIcon(final int flags) { Icon methodIcon = hasModifierProperty(PsiModifier.ABSTRACT) ? PlatformIcons.ABSTRACT_METHOD_ICON : PlatformIcons.METHOD_ICON; RowIcon baseIcon = ElementPresentationUtil.createLayeredIcon(methodIcon, this, false); return ElementPresentationUtil.addVisibilityIcon(this, flags, baseIcon); } @Override public ItemPresentation getPresentation() { return new ColoredItemPresentation() { @Override public String getPresentableText() { return PsiFormatUtil.formatMethod( MPSPsiMethod.this, PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS, PsiFormatUtil.SHOW_TYPE ); } @Override public TextAttributesKey getTextAttributesKey() { if (isDeprecated()) { return CodeInsightColors.DEPRECATED_ATTRIBUTES; } return null; } @Override public String getLocationString() { PsiClass psiClass = getContainingClass(); if (psiClass != null) { String container = psiClass.getQualifiedName(); if (container != null) { return PsiBundle.message("aux.context.display", container); } } return null; } @Override public Icon getIcon(boolean open) { return MPSPsiMethod.this.getIcon(Iconable.ICON_FLAG_VISIBILITY); } }; } }