AnalyzerFacadeForJS.java 7.0 KB
Newer Older
P
Pavel Talanov 已提交
1
/*
A
Andrey Breslav 已提交
2
 * Copyright 2010-2012 JetBrains s.r.o.
P
Pavel Talanov 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jetbrains.k2js.analyze;

import com.google.common.base.Predicate;
P
pTalanov 已提交
20
import com.google.common.base.Predicates;
P
Pavel Talanov 已提交
21 22 23 24
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
25 26
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.analyzer.AnalyzerFacade;
S
Stepan Koltsov 已提交
27
import org.jetbrains.jet.di.InjectorForTopDownAnalyzerForJs;
S
Stepan Koltsov 已提交
28
import org.jetbrains.jet.lang.DefaultModuleConfiguration;
29
import org.jetbrains.jet.lang.ModuleConfiguration;
P
Pavel Talanov 已提交
30
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
S
Stepan Koltsov 已提交
31
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
P
Pavel Talanov 已提交
32 33
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
34
import org.jetbrains.jet.lang.psi.JetImportDirective;
P
Pavel Talanov 已提交
35 36 37
import org.jetbrains.jet.lang.psi.JetPsiFactory;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
S
Stepan Koltsov 已提交
38
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
39
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
P
Pavel Talanov 已提交
40
import org.jetbrains.k2js.config.Config;
41
import org.jetbrains.k2js.config.IDEAConfig;
P
Pavel Talanov 已提交
42 43

import java.util.ArrayList;
44
import java.util.Collection;
P
pTalanov 已提交
45
import java.util.Collections;
P
Pavel Talanov 已提交
46 47 48 49 50
import java.util.List;

/**
 * @author Pavel Talanov
 */
51 52 53
public enum AnalyzerFacadeForJS implements AnalyzerFacade {

    INSTANCE;
P
Pavel Talanov 已提交
54

55
    private AnalyzerFacadeForJS() {
P
Pavel Talanov 已提交
56 57
    }

58 59 60 61 62 63 64 65 66 67
    @NotNull
    @Override
    public AnalyzeExhaust analyzeFiles(@NotNull Project project,
                                       @NotNull Collection<JetFile> files,
                                       @NotNull Predicate<PsiFile> filesToAnalyzeCompletely,
                                       @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
        BindingContext context = analyzeFiles(files, new IDEAConfig(project));
        return new AnalyzeExhaust(context, JetStandardLibrary.getInstance());
    }

P
Pavel Talanov 已提交
68 69 70 71 72 73 74 75 76
    @NotNull
    public static BindingContext analyzeFilesAndCheckErrors(@NotNull List<JetFile> files,
                                                            @NotNull Config config) {
        BindingContext bindingContext = analyzeFiles(files, config);
        checkForErrors(withJsLibAdded(files, config), bindingContext);
        return bindingContext;
    }

    @NotNull
77
    public static BindingContext analyzeFiles(@NotNull Collection<JetFile> files,
P
Pavel Talanov 已提交
78 79
                                              @NotNull Config config) {
        Project project = config.getProject();
S
Stepan Koltsov 已提交
80 81 82 83 84
        BindingTraceContext bindingTraceContext = new BindingTraceContext();

        final ModuleDescriptor owner = new ModuleDescriptor("<module>");

        TopDownAnalysisParameters topDownAnalysisParameters = new TopDownAnalysisParameters(
85
            notLibFiles(config.getLibFiles()), false, false);
S
Stepan Koltsov 已提交
86 87

        InjectorForTopDownAnalyzerForJs injector = new InjectorForTopDownAnalyzerForJs(
88 89
            project, topDownAnalysisParameters, new ObservableBindingTrace(bindingTraceContext), owner,
            JetControlFlowDataTraceFactory.EMPTY, JsConfiguration.jsLibConfiguration(project));
S
Stepan Koltsov 已提交
90

S
Stepan Koltsov 已提交
91
        injector.getTopDownAnalyzer().analyzeFiles(withJsLibAdded(files, config));
S
Stepan Koltsov 已提交
92
        return bindingTraceContext.getBindingContext();
P
Pavel Talanov 已提交
93 94
    }

95
    private static void checkForErrors(@NotNull Collection<JetFile> allFiles, @NotNull BindingContext bindingContext) {
P
Pavel Talanov 已提交
96 97 98 99 100 101 102
        AnalyzingUtils.throwExceptionOnErrors(bindingContext);
        for (JetFile file : allFiles) {
            AnalyzingUtils.checkForSyntacticErrors(file);
        }
    }

    @NotNull
103
    public static Collection<JetFile> withJsLibAdded(@NotNull Collection<JetFile> files, @NotNull Config config) {
P
Pavel Talanov 已提交
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
        List<JetFile> allFiles = new ArrayList<JetFile>();
        allFiles.addAll(files);
        allFiles.addAll(config.getLibFiles());
        return allFiles;
    }

    @NotNull
    private static Predicate<PsiFile> notLibFiles(@NotNull final List<JetFile> jsLibFiles) {
        return new Predicate<PsiFile>() {
            @Override
            public boolean apply(@Nullable PsiFile file) {
                assert file instanceof JetFile;
                @SuppressWarnings("UnnecessaryLocalVariable") boolean notLibFile = !jsLibFiles.contains(file);
                return notLibFile;
            }
        };
    }

122 123
    //TODO: exclude?
    @NotNull
P
pTalanov 已提交
124 125 126
    public static BindingContext analyzeNamespace(@NotNull JetFile file) {
        BindingTraceContext bindingTraceContext = new BindingTraceContext();
        Project project = file.getProject();
S
Stepan Koltsov 已提交
127 128 129 130

        final ModuleDescriptor owner = new ModuleDescriptor("<module>");

        TopDownAnalysisParameters topDownAnalysisParameters = new TopDownAnalysisParameters(
131
            Predicates.<PsiFile>alwaysTrue(), false, false);
S
Stepan Koltsov 已提交
132 133

        InjectorForTopDownAnalyzerForJs injector = new InjectorForTopDownAnalyzerForJs(
134 135
            project, topDownAnalysisParameters, new ObservableBindingTrace(bindingTraceContext), owner,
            JetControlFlowDataTraceFactory.EMPTY, JsConfiguration.jsLibConfiguration(project));
S
Stepan Koltsov 已提交
136

S
Stepan Koltsov 已提交
137
        injector.getTopDownAnalyzer().analyzeFiles(Collections.singletonList(file));
S
Stepan Koltsov 已提交
138
        return bindingTraceContext.getBindingContext();
P
pTalanov 已提交
139 140
    }

141
    private static final class JsConfiguration implements ModuleConfiguration {
P
Pavel Talanov 已提交
142 143

        @NotNull
P
pTalanov 已提交
144
        private final Project project;
P
Pavel Talanov 已提交
145 146 147 148 149 150 151 152 153 154

        public static JsConfiguration jsLibConfiguration(@NotNull Project project) {
            return new JsConfiguration(project);
        }

        private JsConfiguration(@NotNull Project project) {
            this.project = project;
        }

        @Override
155
        public void addDefaultImports(@NotNull Collection<JetImportDirective> directives) {
156
            //TODO: these thing should not be hard-coded like that
S
Stepan Koltsov 已提交
157
            directives.add(JetPsiFactory.createImportDirective(project, new ImportPath("js.*")));
S
Stepan Koltsov 已提交
158
            directives.add(JetPsiFactory.createImportDirective(project, new ImportPath(JetStandardClasses.STANDARD_CLASSES_FQNAME, true)));
159
            directives.add(JetPsiFactory.createImportDirective(project, new ImportPath("kotlin.*")));
P
Pavel Talanov 已提交
160 161 162 163 164
        }

        @Override
        public void extendNamespaceScope(@NotNull BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor,
                                         @NotNull WritableScope namespaceMemberScope) {
165 166
            DefaultModuleConfiguration.createStandardConfiguration(project, true)
                .extendNamespaceScope(trace, namespaceDescriptor, namespaceMemberScope);
P
Pavel Talanov 已提交
167 168 169
        }
    }
}