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.psi.PsiElement;
021    import org.jetbrains.annotations.Contract;
022    import org.jetbrains.annotations.NotNull;
023    import org.jetbrains.annotations.Nullable;
024    import org.jetbrains.kotlin.psi.stubs.KotlinTypeParameterStub;
025    import org.jetbrains.kotlin.psi.stubs.elements.JetStubElementTypes;
026    import org.jetbrains.kotlin.types.Variance;
027    import org.jetbrains.kotlin.lexer.JetTokens;
028    
029    public class JetTypeParameter extends JetNamedDeclarationStub<KotlinTypeParameterStub> {
030    
031        public JetTypeParameter(@NotNull ASTNode node) {
032            super(node);
033        }
034    
035        public JetTypeParameter(@NotNull KotlinTypeParameterStub stub) {
036            super(stub, JetStubElementTypes.TYPE_PARAMETER);
037        }
038    
039        @Override
040        public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
041            return visitor.visitTypeParameter(this, data);
042        }
043    
044        @NotNull
045        public Variance getVariance() {
046            KotlinTypeParameterStub stub = getStub();
047            if (stub != null) {
048                if (stub.isOutVariance()) return Variance.OUT_VARIANCE;
049                if (stub.isInVariance()) return Variance.IN_VARIANCE;
050                return Variance.INVARIANT;
051            }
052    
053            JetModifierList modifierList = getModifierList();
054            if (modifierList == null) return Variance.INVARIANT;
055    
056            if (modifierList.hasModifier(JetTokens.OUT_KEYWORD)) return Variance.OUT_VARIANCE;
057            if (modifierList.hasModifier(JetTokens.IN_KEYWORD)) return Variance.IN_VARIANCE;
058            return Variance.INVARIANT;
059        }
060    
061        @Nullable
062        public JetTypeReference setExtendsBound(@Nullable JetTypeReference typeReference) {
063            JetTypeReference currentExtendsBound = getExtendsBound();
064            if (currentExtendsBound != null) {
065                if (typeReference == null) {
066                    PsiElement colon = findChildByType(JetTokens.COLON);
067                    if (colon != null) colon.delete();
068                    currentExtendsBound.delete();
069                    return null;
070                }
071                return (JetTypeReference) currentExtendsBound.replace(typeReference);
072            }
073    
074            if (typeReference != null) {
075                PsiElement colon = addAfter(new JetPsiFactory(getProject()).createColon(), getNameIdentifier());
076                return (JetTypeReference) addAfter(typeReference, colon);
077            }
078    
079            return null;
080        }
081    
082        @Nullable
083        public JetTypeReference getExtendsBound() {
084            return getStubOrPsiChild(JetStubElementTypes.TYPE_REFERENCE);
085        }
086    }