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