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.extapi.psi.PsiFileBase;
020 import com.intellij.lang.ASTNode;
021 import com.intellij.lang.FileASTNode;
022 import com.intellij.openapi.fileTypes.FileType;
023 import com.intellij.psi.FileViewProvider;
024 import com.intellij.psi.PsiClass;
025 import com.intellij.psi.PsiClassOwner;
026 import com.intellij.psi.PsiElementVisitor;
027 import com.intellij.psi.stubs.StubElement;
028 import com.intellij.psi.util.PsiTreeUtil;
029 import org.jetbrains.annotations.NotNull;
030 import org.jetbrains.annotations.Nullable;
031 import org.jetbrains.jet.JetNodeTypes;
032 import org.jetbrains.jet.lang.psi.stubs.PsiJetFileStub;
033 import org.jetbrains.jet.lang.psi.stubs.elements.JetStubElementTypes;
034 import org.jetbrains.jet.lang.resolve.name.FqName;
035 import org.jetbrains.jet.plugin.JetFileType;
036 import org.jetbrains.jet.plugin.JetLanguage;
037
038 import java.util.Arrays;
039 import java.util.Collections;
040 import java.util.List;
041
042 public class JetFile extends PsiFileBase implements JetDeclarationContainer, JetElement, PsiClassOwner {
043
044 private final boolean isCompiled;
045
046 public JetFile(FileViewProvider viewProvider, boolean compiled) {
047 super(viewProvider, JetLanguage.INSTANCE);
048 this.isCompiled = compiled;
049 }
050
051 @Override
052 public FileASTNode getNode() {
053 return super.getNode();
054 }
055
056 public boolean isCompiled() {
057 return isCompiled;
058 }
059
060 @Override
061 @NotNull
062 public FileType getFileType() {
063 return JetFileType.INSTANCE;
064 }
065
066 @Override
067 public String toString() {
068 return "JetFile: " + getName();
069 }
070
071 @NotNull
072 @Override
073 public List<JetDeclaration> getDeclarations() {
074 PsiJetFileStub stub = getStub();
075 if (stub != null) {
076 return Arrays.asList(stub.getChildrenByType(JetStubElementTypes.DECLARATION_TYPES, JetDeclaration.ARRAY_FACTORY));
077 }
078 return PsiTreeUtil.getChildrenOfTypeAsList(this, JetDeclaration.class);
079 }
080
081 @Nullable
082 public JetImportList getImportList() {
083 PsiJetFileStub stub = getStub();
084 if (stub != null) {
085 StubElement<JetImportList> importListStub = stub.findChildStubByType(JetStubElementTypes.IMPORT_LIST);
086 return importListStub != null ? importListStub.getPsi() : null;
087 }
088 return findChildByClass(JetImportList.class);
089 }
090
091 @NotNull
092 public List<JetImportDirective> getImportDirectives() {
093 JetImportList importList = getImportList();
094 return importList != null ? importList.getImports() : Collections.<JetImportDirective>emptyList();
095 }
096
097 @Nullable
098 public JetImportDirective findImportByAlias(@NotNull String name) {
099 for (JetImportDirective directive : getImportDirectives()) {
100 if (name.equals(directive.getAliasName())) {
101 return directive;
102 }
103 }
104 return null;
105 }
106
107 // scripts have no package directive, all other files must have package directives
108 @Nullable
109 public JetPackageDirective getPackageDirective() {
110 PsiJetFileStub stub = getStub();
111 if (stub != null) {
112 StubElement<JetPackageDirective> packageDirectiveStub = stub.findChildStubByType(JetStubElementTypes.PACKAGE_DIRECTIVE);
113 return packageDirectiveStub != null ? packageDirectiveStub.getPsi() : null;
114 }
115 ASTNode ast = getNode().findChildByType(JetNodeTypes.PACKAGE_DIRECTIVE);
116 return ast != null ? (JetPackageDirective) ast.getPsi() : null;
117 }
118
119 @Deprecated // getPackageFqName should be used instead
120 @Override
121 @NotNull
122 public String getPackageName() {
123 return getPackageFqName().asString();
124 }
125
126 @NotNull
127 public FqName getPackageFqName() {
128 PsiJetFileStub stub = getStub();
129 if (stub != null) {
130 return stub.getPackageFqName();
131 }
132 return getPackageFqNameByTree();
133 }
134
135 @NotNull
136 public FqName getPackageFqNameByTree() {
137 JetPackageDirective packageDirective = getPackageDirective();
138 if (packageDirective == null) {
139 return FqName.ROOT;
140 }
141 return packageDirective.getFqName();
142 }
143
144 @Override
145 @Nullable
146 public PsiJetFileStub getStub() {
147 return (PsiJetFileStub) super.getStub();
148 }
149
150 @NotNull
151 @Override
152 public PsiClass[] getClasses() {
153 return PsiClass.EMPTY_ARRAY;
154 }
155
156 @Override
157 public void setPackageName(String packageName) { }
158
159 // SCRIPT: find script in file
160 @Nullable
161 public JetScript getScript() {
162 return PsiTreeUtil.getChildOfType(this, JetScript.class);
163 }
164
165 public boolean isScript() {
166 PsiJetFileStub stub = getStub();
167 if (stub != null) {
168 return stub.isScript();
169 }
170 return isScriptByTree();
171 }
172
173 public boolean isScriptByTree() {
174 return getScript() != null;
175 }
176
177 @NotNull
178 @Override
179 public String getName() {
180 return super.getName(); // TODO
181 }
182
183 @Override
184 public void accept(@NotNull PsiElementVisitor visitor) {
185 if (visitor instanceof JetVisitor) {
186 accept((JetVisitor) visitor, null);
187 }
188 else {
189 visitor.visitFile(this);
190 }
191 }
192
193 @NotNull
194 @Override
195 public JetFile getContainingJetFile() {
196 return this;
197 }
198
199 @Override
200 public <D> void acceptChildren(@NotNull JetTreeVisitor<D> visitor, D data) {
201 JetPsiUtil.visitChildren(this, visitor, data);
202 }
203
204 @Override
205 public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
206 return visitor.visitJetFile(this, data);
207 }
208 }