001 /*
002 * Copyright 2010-2015 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.kotlin.psi;
018
019 import com.intellij.lang.ASTNode;
020 import com.intellij.psi.tree.IElementType;
021 import com.intellij.psi.util.PsiTreeUtil;
022 import org.jetbrains.annotations.NotNull;
023 import org.jetbrains.annotations.Nullable;
024 import org.jetbrains.kotlin.lexer.JetTokens;
025 import org.jetbrains.kotlin.name.FqName;
026 import org.jetbrains.kotlin.name.Name;
027 import org.jetbrains.kotlin.psi.stubs.KotlinImportDirectiveStub;
028 import org.jetbrains.kotlin.psi.stubs.elements.JetStubElementTypes;
029 import org.jetbrains.kotlin.resolve.ImportPath;
030
031 public class JetImportDirective extends JetElementImplStub<KotlinImportDirectiveStub> {
032
033 public JetImportDirective(@NotNull ASTNode node) {
034 super(node);
035 }
036
037 public JetImportDirective(@NotNull KotlinImportDirectiveStub stub) {
038 super(stub, JetStubElementTypes.IMPORT_DIRECTIVE);
039 }
040
041 @Override
042 public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
043 return visitor.visitImportDirective(this, data);
044 }
045
046 public boolean isAbsoluteInRootPackage() {
047 KotlinImportDirectiveStub stub = getStub();
048 if (stub != null) {
049 return stub.isAbsoluteInRootPackage();
050 }
051 return findChildByType(JetTokens.PACKAGE_KEYWORD) != null;
052 }
053
054 @Nullable @IfNotParsed
055 public JetExpression getImportedReference() {
056 JetExpression[] references = getStubOrPsiChildren(JetStubElementTypes.INSIDE_DIRECTIVE_EXPRESSIONS, JetExpression.ARRAY_FACTORY);
057 if (references.length > 0) {
058 return references[0];
059 }
060 return null;
061 }
062
063 @Nullable
064 public ASTNode getAliasNameNode() {
065 boolean asPassed = false;
066 ASTNode childNode = getNode().getFirstChildNode();
067 while (childNode != null) {
068 IElementType tt = childNode.getElementType();
069 if (tt == JetTokens.AS_KEYWORD) asPassed = true;
070 if (asPassed && tt == JetTokens.IDENTIFIER) {
071 return childNode;
072 }
073
074 childNode = childNode.getTreeNext();
075 }
076 return null;
077 }
078
079 @Nullable
080 public String getAliasName() {
081 KotlinImportDirectiveStub stub = getStub();
082 if (stub != null) {
083 return stub.getAliasName();
084 }
085 ASTNode aliasNameNode = getAliasNameNode();
086 if (aliasNameNode == null) {
087 return null;
088 }
089 return aliasNameNode.getText();
090 }
091
092 public boolean isAllUnder() {
093 KotlinImportDirectiveStub stub = getStub();
094 if (stub != null) {
095 return stub.isAllUnder();
096 }
097 return getNode().findChildByType(JetTokens.MUL) != null;
098 }
099
100 @Nullable
101 @IfNotParsed
102 public FqName getImportedFqName() {
103 KotlinImportDirectiveStub stub = getStub();
104 if (stub != null) {
105 return stub.getImportedFqName();
106 }
107 return fqNameFromExpression(getImportedReference());
108 }
109
110 @Nullable
111 @IfNotParsed
112 public ImportPath getImportPath() {
113 FqName importFqn = getImportedFqName();
114 if (importFqn == null) {
115 return null;
116 }
117
118 Name alias = null;
119 String aliasName = getAliasName();
120 if (aliasName != null) {
121 alias = Name.identifier(aliasName);
122 }
123
124 return new ImportPath(importFqn, isAllUnder(), alias);
125 }
126
127 public boolean isValidImport() {
128 KotlinImportDirectiveStub stub = getStub();
129 if (stub != null) {
130 return stub.isValid();
131 }
132 return !PsiTreeUtil.hasErrorElements(this);
133 }
134
135 @Nullable
136 private static FqName fqNameFromExpression(@Nullable JetExpression expression) {
137 if (expression == null) {
138 return null;
139 }
140
141 if (expression instanceof JetDotQualifiedExpression) {
142 JetDotQualifiedExpression dotQualifiedExpression = (JetDotQualifiedExpression) expression;
143 FqName parentFqn = fqNameFromExpression(dotQualifiedExpression.getReceiverExpression());
144 Name child = nameFromExpression(dotQualifiedExpression.getSelectorExpression());
145 if (child == null) {
146 return parentFqn;
147 }
148 if (parentFqn != null) {
149 return parentFqn.child(child);
150 }
151 return null;
152 }
153 else if (expression instanceof JetSimpleNameExpression) {
154 JetSimpleNameExpression simpleNameExpression = (JetSimpleNameExpression) expression;
155 return FqName.topLevel(simpleNameExpression.getReferencedNameAsName());
156 }
157 else {
158 throw new IllegalArgumentException("Can't construct fqn for: " + expression.getClass().toString());
159 }
160 }
161
162 @Nullable
163 private static Name nameFromExpression(@Nullable JetExpression expression) {
164 if (expression == null) {
165 return null;
166 }
167
168 if (expression instanceof JetSimpleNameExpression) {
169 return ((JetSimpleNameExpression) expression).getReferencedNameAsName();
170 }
171 else {
172 throw new IllegalArgumentException("Can't construct name for: " + expression.getClass().toString());
173 }
174 }
175 }