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
017package org.jetbrains.jet.lang.psi;
018
019import com.intellij.extapi.psi.PsiFileBase;
020import com.intellij.lang.ASTNode;
021import com.intellij.openapi.fileTypes.FileType;
022import com.intellij.psi.FileViewProvider;
023import com.intellij.psi.PsiElementVisitor;
024import com.intellij.psi.util.PsiTreeUtil;
025import org.jetbrains.annotations.NotNull;
026import org.jetbrains.annotations.Nullable;
027import org.jetbrains.jet.JetNodeTypes;
028import org.jetbrains.jet.lang.psi.stubs.PsiJetFileStub;
029import org.jetbrains.jet.plugin.JetFileType;
030import org.jetbrains.jet.plugin.JetLanguage;
031
032import java.util.List;
033
034public class JetFile extends PsiFileBase implements JetDeclarationContainer, JetElement {
035    public JetFile(FileViewProvider viewProvider) {
036        super(viewProvider, JetLanguage.INSTANCE);
037    }
038
039    @Override
040    @NotNull
041    public FileType getFileType() {
042        return JetFileType.INSTANCE;
043    }
044
045    @Override
046    public String toString() {
047        return "JetFile: " + getName();
048    }
049
050    @NotNull
051    @Override
052    public List<JetDeclaration> getDeclarations() {
053        return PsiTreeUtil.getChildrenOfTypeAsList(this, JetDeclaration.class);
054    }
055
056    public List<JetImportDirective> getImportDirectives() {
057        return PsiTreeUtil.getChildrenOfTypeAsList(this, JetImportDirective.class);
058    }
059
060    @Nullable
061    public JetImportDirective findImportByAlias(@NotNull String name) {
062        for (JetImportDirective directive : getImportDirectives()) {
063            if (name.equals(directive.getAliasName())) {
064                return directive;
065            }
066        }
067        return null;
068    }
069
070    // scripts has no namespace header
071    @Nullable
072    public JetNamespaceHeader getNamespaceHeader() {
073        ASTNode ast = getNode().findChildByType(JetNodeTypes.NAMESPACE_HEADER);
074        return ast != null ? (JetNamespaceHeader) ast.getPsi() : null;
075    }
076
077    @Nullable
078    public String getPackageName() {
079        PsiJetFileStub stub = (PsiJetFileStub)getStub();
080        if (stub != null) {
081            return stub.getPackageName();
082        }
083
084        JetNamespaceHeader statement = getNamespaceHeader();
085        return statement != null ? statement.getQualifiedName() : null;
086    }
087
088    @Nullable
089    public JetScript getScript() {
090        return PsiTreeUtil.getChildOfType(this, JetScript.class);
091    }
092
093    public boolean isScript() {
094        PsiJetFileStub stub = (PsiJetFileStub)getStub();
095        if (stub != null) {
096            return stub.isScript();
097        }
098
099        return getScript() != null;
100    }
101
102    @NotNull
103    @Override
104    public String getName() {
105        return super.getName(); // TODO
106    }
107
108    @Override
109    public void accept(@NotNull PsiElementVisitor visitor) {
110        if (visitor instanceof JetVisitorVoid) {
111            accept((JetVisitorVoid) visitor);
112        }
113        else {
114            visitor.visitFile(this);
115        }
116    }
117
118    @Override
119    public <D> void acceptChildren(@NotNull JetTreeVisitor<D> visitor, D data) {
120        JetPsiUtil.visitChildren(this, visitor, data);
121    }
122
123    @Override
124    public void accept(@NotNull JetVisitorVoid visitor) {
125        visitor.visitJetFile(this);
126    }
127
128    @Override
129    public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
130        return visitor.visitJetFile(this, data);
131    }
132}