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.di.InjectorForLazyResolveWithJava;
030    import org.jetbrains.jet.di.InjectorForTopDownAnalyzerForJvm;
031    import org.jetbrains.jet.lang.descriptors.DependencyKind;
032    import org.jetbrains.jet.lang.descriptors.ModuleDescriptorImpl;
033    import org.jetbrains.jet.lang.psi.JetFile;
034    import org.jetbrains.jet.lang.resolve.BindingTrace;
035    import org.jetbrains.jet.lang.resolve.BindingTraceContext;
036    import org.jetbrains.jet.lang.resolve.ImportPath;
037    import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters;
038    import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap;
039    import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalCache;
040    import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalCacheProvider;
041    import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalPackageFragmentProvider;
042    import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
043    import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFactory;
044    import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFactoryService;
045    import org.jetbrains.jet.lang.resolve.name.Name;
046    import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
047    
048    import java.io.File;
049    import java.util.Collection;
050    import java.util.List;
051    
052    public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
053    
054        INSTANCE;
055    
056        public static final List<ImportPath> DEFAULT_IMPORTS = ImmutableList.of(
057                new ImportPath("java.lang.*"),
058                new ImportPath("kotlin.*"),
059                new ImportPath("kotlin.jvm.*"),
060                new ImportPath("kotlin.io.*")
061        );
062    
063        public static class JvmSetup extends BasicSetup {
064    
065            private final JavaDescriptorResolver javaDescriptorResolver;
066    
067            public JvmSetup(@NotNull ResolveSession session, @NotNull JavaDescriptorResolver javaDescriptorResolver) {
068                super(session);
069                this.javaDescriptorResolver = javaDescriptorResolver;
070            }
071    
072            @NotNull
073            public JavaDescriptorResolver getJavaDescriptorResolver() {
074                return javaDescriptorResolver;
075            }
076        }
077    
078        private AnalyzerFacadeForJVM() {
079        }
080    
081        @NotNull
082        @Override
083        public JvmSetup createSetup(@NotNull Project fileProject, @NotNull Collection<JetFile> files) {
084            return createSetup(fileProject, files, new BindingTraceContext(), true);
085        }
086    
087        @NotNull
088        public static ResolveSession createLazyResolveSession(
089                @NotNull Project project,
090                @NotNull Collection<JetFile> files,
091                @NotNull BindingTrace trace,
092                boolean addBuiltIns
093        ) {
094    
095            return createSetup(project, files, trace, addBuiltIns).getLazyResolveSession();
096        }
097    
098        private static JvmSetup createSetup(
099                Project project,
100                Collection<JetFile> files,
101                BindingTrace trace,
102                boolean addBuiltIns
103        ) {
104            GlobalContextImpl globalContext = ContextPackage.GlobalContext();
105    
106            DeclarationProviderFactory declarationProviderFactory =
107                    DeclarationProviderFactoryService.createDeclarationProviderFactory(project, globalContext.getStorageManager(), files);
108    
109            InjectorForLazyResolveWithJava resolveWithJava = new InjectorForLazyResolveWithJava(
110                    project,
111                    globalContext,
112                    declarationProviderFactory,
113                    trace);
114    
115            resolveWithJava.getModule().addFragmentProvider(
116                    DependencyKind.BINARIES, resolveWithJava.getJavaDescriptorResolver().getPackageFragmentProvider());
117    
118            if (addBuiltIns) {
119                resolveWithJava.getModule().addFragmentProvider(
120                        DependencyKind.BUILT_INS,
121                        KotlinBuiltIns.getInstance().getBuiltInsModule().getPackageFragmentProvider());
122            }
123            return new JvmSetup(resolveWithJava.getResolveSession(), resolveWithJava.getJavaDescriptorResolver());
124        }
125    
126        @NotNull
127        public static AnalyzeExhaust analyzeFilesWithJavaIntegration(
128                Project project,
129                Collection<JetFile> files,
130                BindingTrace trace,
131                Predicate<PsiFile> filesToAnalyzeCompletely,
132                ModuleDescriptorImpl module,
133                List<String> moduleIds,
134                File incrementalCacheDir
135        ) {
136            GlobalContext globalContext = ContextPackage.GlobalContext();
137            TopDownAnalysisParameters topDownAnalysisParameters = TopDownAnalysisParameters.create(
138                    globalContext.getStorageManager(),
139                    globalContext.getExceptionTracker(),
140                    filesToAnalyzeCompletely,
141                    false,
142                    false
143            );
144    
145            InjectorForTopDownAnalyzerForJvm injector = new InjectorForTopDownAnalyzerForJvm(project, topDownAnalysisParameters, trace, module);
146            try {
147                module.addFragmentProvider(DependencyKind.BINARIES, injector.getJavaDescriptorResolver().getPackageFragmentProvider());
148    
149                IncrementalCacheProvider incrementalCacheProvider = IncrementalCacheProvider.object$.getInstance();
150                if (incrementalCacheDir != null && moduleIds != null && incrementalCacheProvider != null) {
151                    IncrementalCache incrementalCache = incrementalCacheProvider.getIncrementalCache(incrementalCacheDir);
152                    for (String moduleId : moduleIds) {
153                        module.addFragmentProvider(
154                                DependencyKind.SOURCES,
155                                new IncrementalPackageFragmentProvider(
156                                        files, module, globalContext.getStorageManager(), injector.getDeserializationGlobalContextForJava(),
157                                        incrementalCache, moduleId, injector.getJavaDescriptorResolver()
158                                )
159                        );
160                    }
161                }
162    
163                injector.getTopDownAnalyzer().analyzeFiles(topDownAnalysisParameters, files);
164                return AnalyzeExhaust.success(trace.getBindingContext(), module);
165            }
166            finally {
167                injector.destroy();
168            }
169        }
170    
171        @NotNull
172        public static ModuleDescriptorImpl createJavaModule(@NotNull String name) {
173            return new ModuleDescriptorImpl(Name.special(name), DEFAULT_IMPORTS, JavaToKotlinClassMap.getInstance());
174        }
175    }