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