001    /*
002     * Copyright 2010-2013 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.jet.lang.psi;
018    
019    import com.intellij.lang.ASTNode;
020    import com.intellij.psi.PsiElement;
021    import org.jetbrains.annotations.NotNull;
022    import org.jetbrains.annotations.Nullable;
023    import org.jetbrains.jet.JetNodeTypes;
024    import org.jetbrains.jet.lexer.JetToken;
025    import org.jetbrains.jet.lexer.JetTokens;
026    
027    import java.util.Collections;
028    import java.util.List;
029    
030    public class JetTypeProjection extends JetElementImpl implements JetModifierListOwner {
031        public JetTypeProjection(@NotNull ASTNode node) {
032            super(node);
033        }
034    
035        @Override
036        public JetModifierList getModifierList() {
037            return (JetModifierList) findChildByType(JetNodeTypes.MODIFIER_LIST);
038        }
039    
040        @Override
041        public boolean hasModifier(JetToken modifier) {
042            JetModifierList modifierList = getModifierList();
043            return modifierList != null && modifierList.hasModifier(modifier);
044        }
045    
046        @NotNull
047        public JetProjectionKind getProjectionKind() {
048            ASTNode projectionNode = getProjectionNode();
049            if (projectionNode == null) return JetProjectionKind.NONE;
050    
051            if (projectionNode.getElementType() == JetTokens.IN_KEYWORD) return JetProjectionKind.IN;
052            if (projectionNode.getElementType() == JetTokens.OUT_KEYWORD) return JetProjectionKind.OUT;
053            if (projectionNode.getElementType() == JetTokens.MUL) return JetProjectionKind.STAR;
054    
055            throw new IllegalStateException(projectionNode.getText());
056        }
057    
058        @Override
059        public void accept(@NotNull JetVisitorVoid visitor) {
060            visitor.visitTypeProjection(this);
061        }
062    
063        @Override
064        public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
065            return visitor.visitTypeProjection(this, data);
066        }
067    
068        @Nullable
069        public JetTypeReference getTypeReference() {
070            return (JetTypeReference) findChildByType(JetNodeTypes.TYPE_REFERENCE);
071        }
072    
073        @Nullable
074        public ASTNode getProjectionNode() {
075            JetModifierList modifierList = getModifierList();
076            if (modifierList != null) {
077                ASTNode node = modifierList.getModifierNode(JetTokens.IN_KEYWORD);
078                if (node != null) {
079                    return node;
080                }
081                node = modifierList.getModifierNode(JetTokens.OUT_KEYWORD);
082                if (node != null) {
083                    return node;
084                }
085            }
086            PsiElement star = findChildByType(JetTokens.MUL);
087            if (star != null) {
088                return star.getNode();
089            }
090    
091            return null;
092        }
093    
094        @NotNull
095        @Override
096        public List<JetAnnotationEntry> getAnnotationEntries() {
097            JetModifierList modifierList = getModifierList();
098            if (modifierList == null) return Collections.emptyList();
099            return modifierList.getAnnotationEntries();
100        }
101    
102        @NotNull
103        @Override
104        public List<JetAnnotation> getAnnotations() {
105            JetModifierList modifierList = getModifierList();
106            if (modifierList == null) return Collections.emptyList();
107            return modifierList.getAnnotations();
108        }
109    }