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