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