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 }