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    
055        public static class JvmSetup extends BasicSetup {
056    
057            private final JavaDescriptorResolver javaDescriptorResolver;
058    
059            public JvmSetup(@NotNull ResolveSession session, @NotNull JavaDescriptorResolver javaDescriptorResolver) {
060                super(session);
061                this.javaDescriptorResolver = javaDescriptorResolver;
062            }
063    
064            @NotNull
065            public JavaDescriptorResolver getJavaDescriptorResolver() {
066                return javaDescriptorResolver;
067            }
068        }
069    
070        private AnalyzerFacadeForJVM() {
071        }
072    
073        @NotNull
074        @Override
075        public JvmSetup createSetup(@NotNull Project fileProject, @NotNull Collection<JetFile> files) {
076            return createSetup(fileProject, files, new BindingTraceContext(), true);
077        }
078    
079        @NotNull
080        public static ResolveSession createLazyResolveSession(
081                @NotNull Project project,
082                @NotNull Collection<JetFile> files,
083                @NotNull BindingTrace trace,
084                boolean addBuiltIns
085        ) {
086    
087            return createSetup(project, files, trace, addBuiltIns).getLazyResolveSession();
088        }
089    
090        private static JvmSetup createSetup(
091                Project project,
092                Collection<JetFile> files,
093                BindingTrace trace,
094                boolean addBuiltIns
095        ) {
096            GlobalContextImpl globalContext = ContextPackage.GlobalContext();
097    
098            DeclarationProviderFactory declarationProviderFactory =
099                    DeclarationProviderFactoryService.createDeclarationProviderFactory(project, globalContext.getStorageManager(), files);
100    
101            InjectorForLazyResolveWithJava resolveWithJava = new InjectorForLazyResolveWithJava(
102                    project,
103                    globalContext,
104                    declarationProviderFactory,
105                    trace);
106    
107            resolveWithJava.getModule().addFragmentProvider(
108                    DependencyKind.BINARIES, resolveWithJava.getJavaDescriptorResolver().getPackageFragmentProvider());
109    
110            if (addBuiltIns) {
111                resolveWithJava.getModule().addFragmentProvider(
112                        DependencyKind.BUILT_INS,
113                        KotlinBuiltIns.getInstance().getBuiltInsModule().getPackageFragmentProvider());
114            }
115            return new JvmSetup(resolveWithJava.getResolveSession(), resolveWithJava.getJavaDescriptorResolver());
116        }
117    
118        @NotNull
119        public static AnalyzeExhaust analyzeFilesWithJavaIntegration(
120                Project project,
121                Collection<JetFile> files,
122                BindingTrace trace,
123                Predicate<PsiFile> filesToAnalyzeCompletely,
124                ModuleDescriptorImpl module,
125                MemberFilter memberFilter
126        ) {
127            GlobalContext globalContext = ContextPackage.GlobalContext();
128            TopDownAnalysisParameters topDownAnalysisParameters = TopDownAnalysisParameters.create(
129                    globalContext.getStorageManager(),
130                    globalContext.getExceptionTracker(),
131                    filesToAnalyzeCompletely,
132                    false,
133                    false
134            );
135    
136            InjectorForTopDownAnalyzerForJvm injector = new InjectorForTopDownAnalyzerForJvm(project, topDownAnalysisParameters, trace, module,
137                                                                                             memberFilter);
138            try {
139                module.addFragmentProvider(DependencyKind.BINARIES, injector.getJavaDescriptorResolver().getPackageFragmentProvider());
140                injector.getTopDownAnalyzer().analyzeFiles(topDownAnalysisParameters, files);
141                return AnalyzeExhaust.success(trace.getBindingContext(), module);
142            }
143            finally {
144                injector.destroy();
145            }
146        }
147    
148        @NotNull
149        public static ModuleDescriptorImpl createJavaModule(@NotNull String name) {
150            return new ModuleDescriptorImpl(Name.special(name), DEFAULT_IMPORTS, JavaToKotlinClassMap.getInstance());
151        }
152    }