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.lexer.KtTokens;
030    import org.jetbrains.kotlin.psi.stubs.KotlinParameterStub;
031    import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes;
032    import org.jetbrains.kotlin.psi.typeRefHelpers.TypeRefHelpersKt;
033    
034    import java.util.Collections;
035    import java.util.List;
036    
037    public class KtParameter extends KtNamedDeclarationStub<KotlinParameterStub> implements KtCallableDeclaration, KtValVarKeywordOwner {
038    
039        public KtParameter(@NotNull ASTNode node) {
040            super(node);
041        }
042    
043        public KtParameter(@NotNull KotlinParameterStub stub) {
044            super(stub, KtStubElementTypes.VALUE_PARAMETER);
045        }
046    
047        @Override
048        public <R, D> R accept(@NotNull KtVisitor<R, D> visitor, D data) {
049            return visitor.visitParameter(this, data);
050        }
051    
052        @Override
053        @Nullable
054        public KtTypeReference getTypeReference() {
055            return getStubOrPsiChild(KtStubElementTypes.TYPE_REFERENCE);
056        }
057    
058        @Override
059        @Nullable
060        public KtTypeReference setTypeReference(@Nullable KtTypeReference typeRef) {
061            return TypeRefHelpersKt.setTypeReference(this, getNameIdentifier(), typeRef);
062        }
063    
064        @Nullable
065        @Override
066        public PsiElement getColon() {
067            return findChildByType(KtTokens.COLON);
068        }
069    
070        @Nullable
071        public PsiElement getEqualsToken() {
072            return findChildByType(KtTokens.EQ);
073        }
074    
075        public boolean hasDefaultValue() {
076            KotlinParameterStub stub = getStub();
077            if (stub != null) {
078                return stub.hasDefaultValue();
079            }
080            return getDefaultValue() != null;
081        }
082    
083        @Nullable
084        public KtExpression getDefaultValue() {
085            KotlinParameterStub stub = getStub();
086            if (stub != null && !stub.hasDefaultValue()) return null;
087    
088            PsiElement equalsToken = getEqualsToken();
089            return equalsToken != null ? PsiTreeUtil.getNextSiblingOfType(equalsToken, KtExpression.class) : null;
090        }
091    
092        public boolean isMutable() {
093            KotlinParameterStub stub = getStub();
094            if (stub != null) {
095                return stub.isMutable();
096            }
097    
098            return findChildByType(KtTokens.VAR_KEYWORD) != null;
099        }
100    
101        public boolean isVarArg() {
102            KtModifierList modifierList = getModifierList();
103            return modifierList != null && modifierList.hasModifier(KtTokens.VARARG_KEYWORD);
104        }
105    
106        public boolean hasValOrVar() {
107            KotlinParameterStub stub = getStub();
108            if (stub != null) {
109                return stub.hasValOrVar();
110            }
111            return getValOrVarKeyword() != null;
112        }
113    
114        @Nullable
115        public PsiElement getValOrVarKeyword() {
116            KotlinParameterStub stub = getStub();
117            if (stub != null && !stub.hasValOrVar()) {
118                return null;
119            }
120            return findChildByType(VAL_VAR_TOKEN_SET);
121        }
122    
123        private static final TokenSet VAL_VAR_TOKEN_SET = TokenSet.create(KtTokens.VAL_KEYWORD, KtTokens.VAR_KEYWORD);
124    
125        @Override
126        public ItemPresentation getPresentation() {
127            return ItemPresentationProviders.getItemPresentation(this);
128        }
129    
130        public boolean isLoopParameter() {
131            return getParent() instanceof KtForExpression;
132        }
133    
134        @Nullable
135        @Override
136        public KtParameterList getValueParameterList() {
137            return null;
138        }
139    
140        @NotNull
141        @Override
142        public List<KtParameter> getValueParameters() {
143            return Collections.emptyList();
144        }
145    
146        @Nullable
147        @Override
148        public KtTypeReference getReceiverTypeReference() {
149            return null;
150        }
151    
152        @Nullable
153        @Override
154        public KtTypeParameterList getTypeParameterList() {
155            return null;
156        }
157    
158        @Nullable
159        @Override
160        public KtTypeConstraintList getTypeConstraintList() {
161            return null;
162        }
163    
164        @NotNull
165        @Override
166        public List<KtTypeConstraint> getTypeConstraints() {
167            return Collections.emptyList();
168        }
169    
170        @NotNull
171        @Override
172        public List<KtTypeParameter> getTypeParameters() {
173            return Collections.emptyList();
174        }
175    
176        @Nullable
177        public KtFunction getOwnerFunction() {
178            PsiElement parent = getParentByStub();
179            if (!(parent instanceof KtParameterList)) return null;
180            return ((KtParameterList) parent).getOwnerFunction();
181        }
182    
183        @NotNull
184        @Override
185        public SearchScope getUseScope() {
186            KtExpression owner = getOwnerFunction();
187            if (owner instanceof KtPrimaryConstructor) {
188                if (hasValOrVar()) return super.getUseScope();
189                owner = ((KtPrimaryConstructor) owner).getContainingClassOrObject();
190            }
191            if (owner == null) {
192                owner = PsiTreeUtil.getParentOfType(this, KtExpression.class);
193            }
194            return new LocalSearchScope(owner != null ? owner : this);
195        }
196    }