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 com.intellij.psi.tree.IElementType;
022    import com.intellij.psi.tree.TokenSet;
023    import org.jetbrains.annotations.NotNull;
024    import org.jetbrains.annotations.Nullable;
025    import org.jetbrains.jet.lang.parsing.JetExpressionParsing;
026    import org.jetbrains.jet.lang.resolve.name.Name;
027    import org.jetbrains.jet.lexer.JetTokens;
028    
029    import static org.jetbrains.jet.lexer.JetTokens.*;
030    
031    public class JetSimpleNameExpression extends JetReferenceExpression {
032        public static final TokenSet REFERENCE_TOKENS = TokenSet.orSet(LABELS, TokenSet.create(IDENTIFIER, FIELD_IDENTIFIER, THIS_KEYWORD, SUPER_KEYWORD));
033    
034        public JetSimpleNameExpression(@NotNull ASTNode node) {
035            super(node);
036        }
037    
038        @Nullable
039        public JetExpression getReceiverExpression() {
040            PsiElement parent = getParent();
041            if (parent instanceof JetQualifiedExpression && !isImportDirectiveExpression()) {
042                JetExpression receiverExpression = ((JetQualifiedExpression) parent).getReceiverExpression();
043                // Name expression can't be receiver for itself
044                if (receiverExpression != this) {
045                    return receiverExpression;
046                }
047            }
048            else if (parent instanceof JetCallExpression) {
049                //This is in case `a().b()`
050                JetCallExpression callExpression = (JetCallExpression) parent;
051                parent = callExpression.getParent();
052                if (parent instanceof JetQualifiedExpression) {
053                    JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) parent;
054                    JetExpression parentsReceiver = qualifiedExpression.getReceiverExpression();
055                    if (parentsReceiver != callExpression) {
056                        return parentsReceiver;
057                    }
058                }
059            }
060            else if (parent instanceof JetBinaryExpression && ((JetBinaryExpression) parent).getOperationReference() == this) {
061                return ((JetBinaryExpression) parent).getLeft();
062            }
063            else if (parent instanceof JetUnaryExpression && ((JetUnaryExpression) parent).getOperationReference() == this) {
064                return ((JetUnaryExpression) parent).getBaseExpression();
065            }
066            else if (parent instanceof JetUserType) {
067                JetUserType qualifier = ((JetUserType) parent).getQualifier();
068                if (qualifier != null) {
069                    return qualifier.getReferenceExpression();
070                }
071            }
072            return null;
073        }
074    
075        public boolean isImportDirectiveExpression() {
076            PsiElement parent = getParent();
077            if (parent == null) return false;
078            else return parent instanceof JetImportDirective ||
079                        parent.getParent() instanceof JetImportDirective;
080        }
081    
082        @NotNull
083        public String getReferencedName() {
084            String text = getReferencedNameElement().getNode().getText();
085            return JetPsiUtil.unquoteIdentifierOrFieldReference(text);
086        }
087    
088        @NotNull
089        public Name getReferencedNameAsName() {
090            String name = getReferencedName();
091            return Name.identifierNoValidate(name);
092        }
093    
094        @NotNull
095        public PsiElement getReferencedNameElement() {
096            PsiElement element = findChildByType(REFERENCE_TOKENS);
097            if (element == null) {
098                element = findChildByType(JetExpressionParsing.ALL_OPERATIONS);
099            }
100    
101            if (element != null) {
102                return element;
103            }
104    
105            return this;
106        }
107    
108        @Nullable
109        public PsiElement getIdentifier() {
110            return findChildByType(JetTokens.IDENTIFIER);
111        }
112    
113        @Nullable @IfNotParsed
114        public IElementType getReferencedNameElementType() {
115            return getReferencedNameElement().getNode().getElementType();
116        }
117    
118        @Override
119        public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
120            return visitor.visitSimpleNameExpression(this, data);
121        }
122    }