001    /*
002     * Copyright 2010-2015 JetBrains s.r.o.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jetbrains.kotlin.psi;
018    
019    import com.intellij.lang.ASTNode;
020    import com.intellij.navigation.ItemPresentation;
021    import com.intellij.navigation.ItemPresentationProviders;
022    import com.intellij.psi.PsiElement;
023    import com.intellij.psi.search.LocalSearchScope;
024    import com.intellij.psi.search.SearchScope;
025    import com.intellij.psi.tree.TokenSet;
026    import com.intellij.psi.util.PsiTreeUtil;
027    import org.jetbrains.annotations.NotNull;
028    import org.jetbrains.annotations.Nullable;
029    import org.jetbrains.kotlin.KtNodeTypes;
030    import org.jetbrains.kotlin.lexer.KtTokens;
031    import org.jetbrains.kotlin.psi.stubs.KotlinParameterStub;
032    import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes;
033    import org.jetbrains.kotlin.psi.typeRefHelpers.TypeRefHelpersKt;
034    
035    import java.util.Collections;
036    import java.util.List;
037    
038    public class KtParameter extends KtNamedDeclarationStub<KotlinParameterStub> implements KtCallableDeclaration, KtValVarKeywordOwner {
039    
040        public KtParameter(@NotNull ASTNode node) {
041            super(node);
042        }
043    
044        public KtParameter(@NotNull KotlinParameterStub stub) {
045            super(stub, KtStubElementTypes.VALUE_PARAMETER);
046        }
047    
048        @Override
049        public <R, D> R accept(@NotNull KtVisitor<R, D> visitor, D data) {
050            return visitor.visitParameter(this, data);
051        }
052    
053        @Override
054        @Nullable
055        public KtTypeReference getTypeReference() {
056            return getStubOrPsiChild(KtStubElementTypes.TYPE_REFERENCE);
057        }
058    
059        @Override
060        @Nullable
061        public KtTypeReference setTypeReference(@Nullable KtTypeReference typeRef) {
062            return TypeRefHelpersKt.setTypeReference(this, getNameIdentifier(), typeRef);
063        }
064    
065        @Nullable
066        @Override
067        public PsiElement getColon() {
068            return findChildByType(KtTokens.COLON);
069        }
070    
071        @Nullable
072        public PsiElement getEqualsToken() {
073            return findChildByType(KtTokens.EQ);
074        }
075    
076        public boolean hasDefaultValue() {
077            KotlinParameterStub stub = getStub();
078            if (stub != null) {
079                return stub.hasDefaultValue();
080            }
081            return getDefaultValue() != null;
082        }
083    
084        @Nullable
085        public KtExpression getDefaultValue() {
086            KotlinParameterStub stub = getStub();
087            if (stub != null && !stub.hasDefaultValue()) return null;
088    
089            PsiElement equalsToken = getEqualsToken();
090            return equalsToken != null ? PsiTreeUtil.getNextSiblingOfType(equalsToken, KtExpression.class) : null;
091        }
092    
093        public boolean isMutable() {
094            KotlinParameterStub stub = getStub();
095            if (stub != null) {
096                return stub.isMutable();
097            }
098    
099            return findChildByType(KtTokens.VAR_KEYWORD) != null;
100        }
101    
102        public boolean isVarArg() {
103            KtModifierList modifierList = getModifierList();
104            return modifierList != null && modifierList.hasModifier(KtTokens.VARARG_KEYWORD);
105        }
106    
107        public boolean hasValOrVar() {
108            KotlinParameterStub stub = getStub();
109            if (stub != null) {
110                return stub.hasValOrVar();
111            }
112            return getValOrVarKeyword() != null;
113        }
114    
115        @Nullable
116        public PsiElement getValOrVarKeyword() {
117            KotlinParameterStub stub = getStub();
118            if (stub != null && !stub.hasValOrVar()) {
119                return null;
120            }
121            return findChildByType(VAL_VAR_TOKEN_SET);
122        }
123    
124        @Nullable
125        public KtDestructuringDeclaration getDestructuringDeclaration() {
126            // No destructuring declaration in stubs
127            if (getStub() != null) return null;
128    
129            return findChildByType(KtNodeTypes.DESTRUCTURING_DECLARATION);
130        }
131    
132        private static final TokenSet VAL_VAR_TOKEN_SET = TokenSet.create(KtTokens.VAL_KEYWORD, KtTokens.VAR_KEYWORD);
133    
134        @Override
135        public ItemPresentation getPresentation() {
136            return ItemPresentationProviders.getItemPresentation(this);
137        }
138    
139        public boolean isLoopParameter() {
140            return getParent() instanceof KtForExpression;
141        }
142    
143        @Nullable
144        @Override
145        public KtParameterList getValueParameterList() {
146            return null;
147        }
148    
149        @NotNull
150        @Override
151        public List<KtParameter> getValueParameters() {
152            return Collections.emptyList();
153        }
154    
155        @Nullable
156        @Override
157        public KtTypeReference getReceiverTypeReference() {
158            return null;
159        }
160    
161        @Nullable
162        @Override
163        public KtTypeParameterList getTypeParameterList() {
164            return null;
165        }
166    
167        @Nullable
168        @Override
169        public KtTypeConstraintList getTypeConstraintList() {
170            return null;
171        }
172    
173        @NotNull
174        @Override
175        public List<KtTypeConstraint> getTypeConstraints() {
176            return Collections.emptyList();
177        }
178    
179        @NotNull
180        @Override
181        public List<KtTypeParameter> getTypeParameters() {
182            return Collections.emptyList();
183        }
184    
185        @Nullable
186        public KtFunction getOwnerFunction() {
187            PsiElement parent = getParentByStub();
188            if (!(parent instanceof KtParameterList)) return null;
189            return ((KtParameterList) parent).getOwnerFunction();
190        }
191    
192        @NotNull
193        @Override
194        public SearchScope getUseScope() {
195            KtExpression owner = getOwnerFunction();
196            if (owner instanceof KtPrimaryConstructor) {
197                if (hasValOrVar()) return super.getUseScope();
198                owner = ((KtPrimaryConstructor) owner).getContainingClassOrObject();
199            }
200            if (owner == null) {
201                owner = PsiTreeUtil.getParentOfType(this, KtExpression.class);
202            }
203            return new LocalSearchScope(owner != null ? owner : this);
204        }
205    }