001    /*
002     * Copyright 2010-2014 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.resolve.java;
018    
019    import com.google.common.base.Predicate;
020    import com.google.common.collect.ImmutableList;
021    import com.intellij.openapi.project.Project;
022    import com.intellij.psi.PsiFile;
023    import org.jetbrains.annotations.NotNull;
024    import org.jetbrains.jet.analyzer.AnalyzeExhaust;
025    import org.jetbrains.jet.analyzer.AnalyzerFacade;
026    import org.jetbrains.jet.context.ContextPackage;
027    import org.jetbrains.jet.context.GlobalContext;
028    import org.jetbrains.jet.context.GlobalContextImpl;
029    import org.jetbrains.jet.descriptors.serialization.descriptors.MemberFilter;
030    import org.jetbrains.jet.di.InjectorForLazyResolveWithJava;
031    import org.jetbrains.jet.di.InjectorForTopDownAnalyzerForJvm;
032    import org.jetbrains.jet.lang.descriptors.DependencyKind;
033    import org.jetbrains.jet.lang.descriptors.ModuleDescriptorImpl;
034    import org.jetbrains.jet.lang.psi.JetFile;
035    import org.jetbrains.jet.lang.resolve.*;
036    import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap;
037    import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
038    import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFactory;
039    import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFactoryService;
040    import org.jetbrains.jet.lang.resolve.name.Name;
041    import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
042    
043    import java.util.Collection;
044    import java.util.List;
045    
046    public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
047    
048        INSTANCE;
049    
050        public static final List<ImportPath> DEFAULT_IMPORTS = ImmutableList.of(
051                new ImportPath("java.lang.*"),
052                new ImportPath("kotlin.*"),
053                new ImportPath("kotlin.io.*"),
054                new ImportPath("kotlin.reflect.*")
055        );
056    
057        public static class JvmSetup extends BasicSetup {
058    
059            private final JavaDescriptorResolver javaDescriptorResolver;
060    
061            public JvmSetup(@NotNull ResolveSession session, @NotNull JavaDescriptorResolver javaDescriptorResolver) {
062                super(session);
063                this.javaDescriptorResolver = javaDescriptorResolver;
064            }
065    
066            @NotNull
067            public JavaDescriptorResolver getJavaDescriptorResolver() {
068                return javaDescriptorResolver;
069            }
070        }
071    
072        private AnalyzerFacadeForJVM() {
073        }
074    
075        @NotNull
076        @Override
077        public JvmSetup createSetup(@NotNull Project fileProject, @NotNull Collection<JetFile> files) {
078            return createSetup(fileProject, files, new BindingTraceContext(), true);
079        }
080    
081        @NotNull
082        public static ResolveSession createLazyResolveSession(
083                @NotNull Project project,
084                @NotNull Collection<JetFile> files,
085                @NotNull BindingTrace trace,
086                boolean addBuiltIns
087        ) {
088    
089            return createSetup(project, files, trace, addBuiltIns).getLazyResolveSession();
090        }
091    
092        private static JvmSetup createSetup(
093                Project project,
094                Collection<JetFile> files,
095                BindingTrace trace,
096                boolean addBuiltIns
097        ) {
098            GlobalContextImpl globalContext = ContextPackage.GlobalContext();
099    
100            DeclarationProviderFactory declarationProviderFactory =
101                    DeclarationProviderFactoryService.createDeclarationProviderFactory(project, globalContext.getStorageManager(), files);
102    
103            InjectorForLazyResolveWithJava resolveWithJava = new InjectorForLazyResolveWithJava(
104                    project,
105                    globalContext,
106                    declarationProviderFactory,
107                    trace);
108    
109            resolveWithJava.getModule().addFragmentProvider(
110                    DependencyKind.BINARIES, resolveWithJava.getJavaDescriptorResolver().getPackageFragmentProvider());
111    
112            if (addBuiltIns) {
113                resolveWithJava.getModule().addFragmentProvider(
114                        DependencyKind.BUILT_INS,
115                        KotlinBuiltIns.getInstance().getBuiltInsModule().getPackageFragmentProvider());
116            }
117            return new JvmSetup(resolveWithJava.getResolveSession(), resolveWithJava.getJavaDescriptorResolver());
118        }
119    
120        @NotNull
121        public static AnalyzeExhaust analyzeFilesWithJavaIntegration(
122                Project project,
123                Collection<JetFile> files,
124                BindingTrace trace,
125                Predicate<PsiFile> filesToAnalyzeCompletely,
126                ModuleDescriptorImpl module,
127                MemberFilter memberFilter
128        ) {
129            GlobalContext globalContext = ContextPackage.GlobalContext();
130            TopDownAnalysisParameters topDownAnalysisParameters = TopDownAnalysisParameters.create(
131                    globalContext.getStorageManager(),
132                    globalContext.getExceptionTracker(),
133                    filesToAnalyzeCompletely,
134                    false,
135                    false
136            );
137    
138            InjectorForTopDownAnalyzerForJvm injector = new InjectorForTopDownAnalyzerForJvm(project, topDownAnalysisParameters, trace, module,
139                                                                                             memberFilter);
140            try {
141                module.addFragmentProvider(DependencyKind.BINARIES, injector.getJavaDescriptorResolver().getPackageFragmentProvider());
142                injector.getTopDownAnalyzer().analyzeFiles(topDownAnalysisParameters, files);
143                return AnalyzeExhaust.success(trace.getBindingContext(), module);
144            }
145            finally {
146                injector.destroy();
147            }
148        }
149    
150        @NotNull
151        public static ModuleDescriptorImpl createJavaModule(@NotNull String name) {
152            return new ModuleDescriptorImpl(Name.special(name), DEFAULT_IMPORTS, JavaToKotlinClassMap.getInstance());
153        }
154    }