2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.psi.impl.source;
18 import com.intellij.lang.ASTNode;
19 import com.intellij.navigation.ItemPresentation;
20 import com.intellij.openapi.diagnostic.Logger;
21 import com.intellij.psi.*;
22 import com.intellij.psi.impl.CheckUtil;
23 import com.intellij.psi.impl.ElementPresentationUtil;
24 import com.intellij.psi.impl.PsiImplUtil;
25 import com.intellij.psi.impl.cache.TypeInfo;
26 import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
27 import com.intellij.psi.impl.java.stubs.PsiParameterStub;
28 import com.intellij.psi.impl.source.tree.ChildRole;
29 import com.intellij.psi.impl.source.tree.CompositeElement;
30 import com.intellij.psi.impl.source.tree.JavaSharedImplUtil;
31 import com.intellij.psi.presentation.java.JavaPresentationUtil;
32 import com.intellij.psi.search.LocalSearchScope;
33 import com.intellij.psi.search.SearchScope;
34 import com.intellij.ui.RowIcon;
35 import com.intellij.util.Icons;
36 import com.intellij.util.IncorrectOperationException;
37 import com.intellij.util.PatchedSoftReference;
38 import org.jetbrains.annotations.NotNull;
41 import java.util.Arrays;
43 public class PsiParameterImpl extends JavaStubPsiElement<PsiParameterStub> implements PsiParameter {
44 private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiParameterImpl");
45 private volatile PatchedSoftReference<PsiType> myCachedType = null;
47 public PsiParameterImpl(final PsiParameterStub stub) {
48 super(stub, JavaStubElementTypes.PARAMETER);
51 public PsiParameterImpl(final ASTNode node) {
55 public void subtreeChanged() {
56 super.subtreeChanged();
60 protected Object clone() {
61 PsiParameterImpl clone = (PsiParameterImpl)super.clone();
62 clone.myCachedType = null;
68 public final String getName() {
69 final PsiParameterStub stub = getStub();
71 return stub.getName();
73 return getNameIdentifier().getText();
76 public PsiElement setName(@NotNull String name) throws IncorrectOperationException {
77 PsiImplUtil.setName(getNameIdentifier(), name);
82 public final PsiIdentifier getNameIdentifier() {
83 return (PsiIdentifier)getNode().findChildByRoleAsPsiElement(ChildRole.NAME);
87 public CompositeElement getNode() {
88 return (CompositeElement)super.getNode();
92 public PsiType getType() {
93 final PsiParameterStub stub = getStub();
95 PatchedSoftReference<PsiType> cachedType = myCachedType;
96 if (cachedType != null) {
97 PsiType type = cachedType.get();
98 if (type != null) return type;
101 String typeText = TypeInfo.createTypeText(stub.getType(true));
103 final PsiType type = JavaPsiFacade.getInstance(getProject()).getParserFacade().createTypeFromText(typeText, this);
104 myCachedType = new PatchedSoftReference<PsiType>(type);
107 catch (IncorrectOperationException e) {
114 return JavaSharedImplUtil.getType(this);
117 public PsiType getTypeNoResolve() {
118 final PsiParameterStub stub = getStub();
120 String typeText = TypeInfo.createTypeText(stub.getType(false));
122 return JavaPsiFacade.getInstance(getProject()).getParserFacade().createTypeFromText(typeText, this);
124 catch (IncorrectOperationException e) {
129 PsiTypeElement typeElement = getTypeElement();
130 PsiIdentifier nameIdentifier = getNameIdentifier();
131 return JavaSharedImplUtil.getTypeNoResolve(typeElement, nameIdentifier, this);
135 public PsiTypeElement getTypeElement() {
136 return (PsiTypeElement)getNode().findChildByRoleAsPsiElement(ChildRole.TYPE);
140 public PsiModifierList getModifierList() {
141 return getStubOrPsiChild(JavaStubElementTypes.MODIFIER_LIST);
144 public boolean hasModifierProperty(@NotNull String name) {
145 return getModifierList().hasModifierProperty(name);
148 public PsiExpression getInitializer() {
152 public boolean hasInitializer() {
156 public Object computeConstantValue() {
160 public void normalizeDeclaration() throws IncorrectOperationException {
161 CheckUtil.checkWritable(this);
162 JavaSharedImplUtil.normalizeBrackets(this);
165 public void accept(@NotNull PsiElementVisitor visitor) {
166 if (visitor instanceof JavaElementVisitor) {
167 ((JavaElementVisitor)visitor).visitParameter(this);
170 visitor.visitElement(this);
174 public String toString() {
175 return "PsiParameter:" + getName();
179 public PsiElement getDeclarationScope() {
180 final PsiElement parent = getParent();
181 if (parent == null) return this;
182 if (parent instanceof PsiParameterList){
183 return parent.getParent();
185 if (parent instanceof PsiForeachStatement) {
188 if (parent instanceof PsiCatchSection) {
191 PsiElement[] children = parent.getChildren();
192 //noinspection ConstantConditions
193 if (children != null) {
194 for(int i = 0; i < children.length; i++){
195 if (children[i].equals(this)){
196 while(!(children[i] instanceof PsiCodeBlock)){
203 LOG.error("codeblock not found among parameter' "+this+" parents children: "+ Arrays.asList(children));
207 public boolean isVarArgs() {
208 final PsiParameterStub stub = getStub();
210 return stub.isParameterTypeEllipsis();
214 return SourceTreeToPsiMap.psiElementToTree(getTypeElement()).findChildByType(JavaTokenType.ELLIPSIS) != null;
218 public PsiAnnotation[] getAnnotations() {
219 return getModifierList().getAnnotations();
222 public ItemPresentation getPresentation() {
223 return JavaPresentationUtil.getVariablePresentation(this);
226 public Icon getElementIcon(final int flags) {
227 final RowIcon baseIcon = createLayeredIcon(Icons.PARAMETER_ICON, 0);
228 return ElementPresentationUtil.addVisibilityIcon(this, flags, baseIcon);
232 public SearchScope getUseScope() {
233 final PsiElement declarationScope = getDeclarationScope();
234 return new LocalSearchScope(declarationScope);