/* * 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 com.intellij.psi.impl.source; import com.intellij.lang.ASTNode; import com.intellij.navigation.ItemPresentation; import com.intellij.navigation.ItemPresentationProviders; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.impl.PsiClassImplUtil; import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.impl.java.stubs.JavaStubElementTypes; import com.intellij.psi.impl.java.stubs.PsiFieldStub; import com.intellij.psi.impl.source.tree.ChildRole; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import javax.swing.*; /** * @author dsl */ public class PsiEnumConstantImpl extends JavaStubPsiElement<PsiFieldStub> implements PsiEnumConstant { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiEnumConstantImpl"); private final MyReference myReference = new MyReference(); public PsiEnumConstantImpl(final PsiFieldStub stub) { super(stub, JavaStubElementTypes.ENUM_CONSTANT); } public PsiEnumConstantImpl(final ASTNode node) { super(node); } public String toString() { return "PsiEnumConstant:" + getName(); } @Override public void accept(@NotNull PsiElementVisitor visitor) { if (visitor instanceof JavaElementVisitor) { ((JavaElementVisitor)visitor).visitEnumConstant(this); } else { visitor.visitElement(this); } } @Override public PsiExpressionList getArgumentList() { return (PsiExpressionList)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.ARGUMENT_LIST); } @Override public PsiEnumConstantInitializer getInitializingClass() { return (PsiEnumConstantInitializer)getStubOrPsiChild(JavaStubElementTypes.ENUM_CONSTANT_INITIALIZER); } @NotNull @Override public PsiEnumConstantInitializer getOrCreateInitializingClass() { final PsiEnumConstantInitializer initializingClass = getInitializingClass(); if (initializingClass != null) return initializingClass; final PsiElementFactory factory = JavaPsiFacade.getElementFactory(getProject()); final PsiEnumConstantInitializer initializer = factory.createEnumConstantFromText("foo{}", null).getInitializingClass(); LOG.assertTrue(initializer != null); final PsiExpressionList argumentList = getArgumentList(); if (argumentList != null) { return (PsiEnumConstantInitializer)addAfter(initializer, argumentList); } else { return (PsiEnumConstantInitializer)addAfter(initializer, getNameIdentifier()); } } @Override public PsiClass getContainingClass() { PsiElement parent = getParent(); return parent instanceof PsiClass ? (PsiClass)parent : null; } @Override public PsiElement getContext() { final PsiClass cc = getContainingClass(); return cc != null ? cc : super.getContext(); } @Override public PsiModifierList getModifierList() { return getStubOrPsiChild(JavaStubElementTypes.MODIFIER_LIST); } @Override public boolean hasModifierProperty(@NotNull String name) { return PsiModifier.PUBLIC.equals(name) || PsiModifier.STATIC.equals(name) || PsiModifier.FINAL.equals(name); } @Override @NotNull public PsiType getType() { return JavaPsiFacade.getInstance(getProject()).getElementFactory().createType(getContainingClass()); } @Override public PsiTypeElement getTypeElement() { return null; } @Override public PsiExpression getInitializer() { return null; } @Override public boolean hasInitializer() { return true; } @Override public void normalizeDeclaration() throws IncorrectOperationException { } @Override public Object computeConstantValue() { return this; } @Override public PsiMethod resolveMethod() { PsiClass containingClass = getContainingClass(); LOG.assertTrue(containingClass != null); final JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject()); JavaResolveResult resolveResult = facade.getResolveHelper() .resolveConstructor(facade.getElementFactory().createType(containingClass), getArgumentList(), this); return (PsiMethod)resolveResult.getElement(); } @Override @NotNull public JavaResolveResult resolveMethodGenerics() { PsiClass containingClass = getContainingClass(); LOG.assertTrue(containingClass != null); final JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject()); return facade.getResolveHelper().resolveConstructor(facade.getElementFactory().createType(containingClass), getArgumentList(), this); } @Override @NotNull public PsiIdentifier getNameIdentifier() { return (PsiIdentifier)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.NAME); } @Override @NotNull public String getName() { final PsiFieldStub stub = getStub(); if (stub != null) { return stub.getName(); } return getNameIdentifier().getText(); } @Override public PsiElement setName(@NotNull String name) throws IncorrectOperationException { PsiImplUtil.setName(getNameIdentifier(), name); return this; } @Override public PsiDocComment getDocComment() { return (PsiDocComment)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.DOC_COMMENT); } @Override public boolean isDeprecated() { final PsiFieldStub stub = getStub(); if (stub != null) { return stub.isDeprecated(); } PsiDocComment docComment = getDocComment(); return docComment != null && docComment.findTagByName("deprecated") != null || getModifierList().findAnnotation("java.lang.Deprecated") != null; } @Override public PsiReference getReference() { return myReference; } @Override public PsiMethod resolveConstructor() { return resolveMethod(); } @Override protected boolean isVisibilitySupported() { return true; } private class MyReference implements PsiJavaReference { @Override public PsiElement getElement() { return PsiEnumConstantImpl.this; } @Override public TextRange getRangeInElement() { PsiIdentifier nameIdentifier = getNameIdentifier(); int startOffsetInParent = nameIdentifier.getStartOffsetInParent(); return new TextRange(startOffsetInParent, startOffsetInParent + nameIdentifier.getTextLength()); } @Override public boolean isSoft() { return false; } @Override public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { return getElement(); } @Override public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { throw new IncorrectOperationException("Invalid operation"); } @Override @NotNull public Object[] getVariants() { return ArrayUtil.EMPTY_OBJECT_ARRAY; } @Override public void processVariants(@NotNull PsiScopeProcessor processor) { } @Override @NotNull public JavaResolveResult[] multiResolve(boolean incompleteCode) { final JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject()); PsiClassType type = facade.getElementFactory().createType(getContainingClass()); return facade.getResolveHelper().multiResolveConstructor(type, getArgumentList(), getElement()); } @Override @NotNull public JavaResolveResult advancedResolve(boolean incompleteCode) { final JavaResolveResult[] results = multiResolve(incompleteCode); if (results.length == 1) return results[0]; return JavaResolveResult.EMPTY; } @Override public PsiElement resolve() { return advancedResolve(false).getElement(); } @Override @NotNull public String getCanonicalText() { return getContainingClass().getName(); } @Override public boolean isReferenceTo(PsiElement element) { return element instanceof PsiMethod && ((PsiMethod)element).isConstructor() && ((PsiMethod)element).getContainingClass() == getContainingClass() && getManager().areElementsEquivalent(resolve(), element); } } @Override public ItemPresentation getPresentation() { return ItemPresentationProviders.getItemPresentation(this); } @Override public void setInitializer(PsiExpression initializer) throws IncorrectOperationException { throw new IncorrectOperationException(); } @Override public boolean isEquivalentTo(final PsiElement another) { return PsiClassImplUtil.isFieldEquivalentTo(this, another); } @Override public PsiType getTypeNoResolve() { return getType(); } }