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.JetModifierKeywordToken;
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(JetModifierKeywordToken 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 <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
060            return visitor.visitTypeProjection(this, data);
061        }
062    
063        @Nullable
064        public JetTypeReference getTypeReference() {
065            return (JetTypeReference) findChildByType(JetNodeTypes.TYPE_REFERENCE);
066        }
067    
068        @Nullable
069        public ASTNode getProjectionNode() {
070            JetModifierList modifierList = getModifierList();
071            if (modifierList != null) {
072                ASTNode node = modifierList.getModifierNode(JetTokens.IN_KEYWORD);
073                if (node != null) {
074                    return node;
075                }
076                node = modifierList.getModifierNode(JetTokens.OUT_KEYWORD);
077                if (node != null) {
078                    return node;
079                }
080            }
081            PsiElement star = findChildByType(JetTokens.MUL);
082            if (star != null) {
083                return star.getNode();
084            }
085    
086            return null;
087        }
088    
089        @NotNull
090        @Override
091        public List<JetAnnotationEntry> getAnnotationEntries() {
092            JetModifierList modifierList = getModifierList();
093            if (modifierList == null) return Collections.emptyList();
094            return modifierList.getAnnotationEntries();
095        }
096    
097        @NotNull
098        @Override
099        public List<JetAnnotation> getAnnotations() {
100            JetModifierList modifierList = getModifierList();
101            if (modifierList == null) return Collections.emptyList();
102            return modifierList.getAnnotations();
103        }
104    }