• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download

<lambda>null1 package org.jetbrains.dokka
2 
3 import com.google.common.collect.ImmutableMap
4 import com.intellij.core.CoreApplicationEnvironment
5 import com.intellij.core.CoreModuleManager
6 import com.intellij.mock.MockComponentManager
7 import com.intellij.openapi.Disposable
8 import com.intellij.openapi.extensions.Extensions
9 import com.intellij.openapi.module.Module
10 import com.intellij.openapi.module.ModuleManager
11 import com.intellij.openapi.project.Project
12 import com.intellij.openapi.roots.OrderEnumerationHandler
13 import com.intellij.openapi.roots.ProjectFileIndex
14 import com.intellij.openapi.roots.ProjectRootManager
15 import com.intellij.openapi.util.Disposer
16 import com.intellij.openapi.vfs.StandardFileSystems
17 import com.intellij.psi.PsiElement
18 import com.intellij.psi.impl.source.javadoc.JavadocManagerImpl
19 import com.intellij.psi.javadoc.CustomJavadocTagProvider
20 import com.intellij.psi.javadoc.JavadocManager
21 import com.intellij.psi.javadoc.JavadocTagInfo
22 import com.intellij.psi.search.GlobalSearchScope
23 import org.jetbrains.kotlin.analyzer.*
24 import org.jetbrains.kotlin.builtins.KotlinBuiltIns
25 import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
26 import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
27 import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
28 import org.jetbrains.kotlin.cli.common.config.ContentRoot
29 import org.jetbrains.kotlin.cli.common.config.KotlinSourceRoot
30 import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot
31 import org.jetbrains.kotlin.cli.common.messages.MessageCollector
32 import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
33 import org.jetbrains.kotlin.cli.jvm.compiler.JvmPackagePartProvider
34 import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
35 import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
36 import org.jetbrains.kotlin.cli.jvm.config.*
37 import org.jetbrains.kotlin.cli.jvm.index.JavaRoot
38 import org.jetbrains.kotlin.config.*
39 import org.jetbrains.kotlin.container.getService
40 import org.jetbrains.kotlin.container.tryGetService
41 import org.jetbrains.kotlin.context.ProjectContext
42 import org.jetbrains.kotlin.context.withModule
43 import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
44 import org.jetbrains.kotlin.descriptors.ModuleDescriptor
45 import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
46 import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
47 import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
48 import org.jetbrains.kotlin.name.Name
49 import org.jetbrains.kotlin.platform.TargetPlatform
50 import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
51 import org.jetbrains.kotlin.platform.konan.KonanPlatforms
52 import org.jetbrains.kotlin.psi.*
53 import org.jetbrains.kotlin.resolve.BindingContext
54 import org.jetbrains.kotlin.resolve.BindingTrace
55 import org.jetbrains.kotlin.resolve.CompilerEnvironment
56 import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
57 import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
58 import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters
59 import org.jetbrains.kotlin.resolve.jvm.JvmResolverForModuleFactory
60 import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
61 import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
62 import org.jetbrains.kotlin.resolve.lazy.ResolveSession
63 import org.jetbrains.kotlin.types.KotlinType
64 import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice
65 import org.jetbrains.kotlin.util.slicedMap.WritableSlice
66 import java.io.File
67 
68 /**
69  * Kotlin as a service entry point
70  *
71  * Configures environment, analyses files and provides facilities to perform code processing without emitting bytecode
72  *
73  * $messageCollector: required by compiler infrastructure and will receive all compiler messages
74  * $body: optional and can be used to configure environment without creating local variable
75  */
76 class AnalysisEnvironment(val messageCollector: MessageCollector) : Disposable {
77     val configuration = CompilerConfiguration()
78 
79     init {
80         configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
81     }
82 
83     fun createCoreEnvironment(): KotlinCoreEnvironment {
84         System.setProperty("idea.io.use.fallback", "true")
85         val environment = KotlinCoreEnvironment.createForProduction(this, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
86         val projectComponentManager = environment.project as MockComponentManager
87 
88         val projectFileIndex = CoreProjectFileIndex(environment.project,
89                 environment.configuration.getList(CLIConfigurationKeys.CONTENT_ROOTS))
90 
91         val moduleManager = object : CoreModuleManager(environment.project, this) {
92             override fun getModules(): Array<out Module> = arrayOf(projectFileIndex.module)
93         }
94 
95         CoreApplicationEnvironment.registerComponentInstance(projectComponentManager.picoContainer,
96                 ModuleManager::class.java, moduleManager)
97 
98         Extensions.registerAreaClass("IDEA_MODULE", null)
99         CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(),
100                 OrderEnumerationHandler.EP_NAME, OrderEnumerationHandler.Factory::class.java)
101 
102         CoreApplicationEnvironment.registerExtensionPoint(Extensions.getArea(environment.project),
103             JavadocTagInfo.EP_NAME, JavadocTagInfo::class.java)
104         CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(),
105             CustomJavadocTagProvider.EP_NAME, CustomJavadocTagProvider::class.java)
106 
107         projectComponentManager.registerService(ProjectFileIndex::class.java,
108                 projectFileIndex)
109         projectComponentManager.registerService(ProjectRootManager::class.java,
110                 CoreProjectRootManager(projectFileIndex))
111         projectComponentManager.registerService(JavadocManager::class.java,
112             JavadocManagerImpl(environment.project))
113         projectComponentManager.registerService(CustomJavadocTagProvider::class.java,
114             CustomJavadocTagProvider { emptyList() })
115         return environment
116     }
117 
118     fun createSourceModuleSearchScope(project: Project, sourceFiles: List<KtFile>): GlobalSearchScope {
119         // TODO: Fix when going to implement dokka for JS
120         return TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, sourceFiles)
121     }
122 
123 
124     fun createResolutionFacade(environment: KotlinCoreEnvironment): Pair<DokkaResolutionFacade, DokkaResolutionFacade> {
125 
126         val projectContext = ProjectContext(environment.project, "Dokka")
127         val sourceFiles = environment.getSourceFiles()
128 
129 
130         val library = object : ModuleInfo {
131             override val name: Name = Name.special("<library>")
132             override val platform: TargetPlatform
133                 get() = JvmPlatforms.defaultJvmPlatform
134             override val analyzerServices: PlatformDependentAnalyzerServices =
135                 JvmPlatformAnalyzerServices
136             override fun dependencies(): List<ModuleInfo> = listOf(this)
137         }
138         val module = object : ModuleInfo {
139             override val name: Name = Name.special("<module>")
140             override val platform: TargetPlatform
141                 get() = JvmPlatforms.defaultJvmPlatform
142             override val analyzerServices: PlatformDependentAnalyzerServices =
143                 JvmPlatformAnalyzerServices
144             override fun dependencies(): List<ModuleInfo> = listOf(this, library)
145         }
146 
147         val sourcesScope = createSourceModuleSearchScope(environment.project, sourceFiles)
148 
149         val builtIns = JvmBuiltIns(
150             projectContext.storageManager,
151             JvmBuiltIns.Kind.FROM_CLASS_LOADER
152         )
153 
154 
155         val javaRoots = classpath
156                 .mapNotNull {
157                     val rootFile = when {
158                         it.extension == "jar" ->
159                             StandardFileSystems.jar().findFileByPath("${it.absolutePath}${"!/"}")
160                         else ->
161                             StandardFileSystems.local().findFileByPath(it.absolutePath)
162                     }
163 
164                     rootFile?.let { JavaRoot(it, JavaRoot.RootType.BINARY) }
165                 }
166 
167         val resolverForProject =  object : AbstractResolverForProject<ModuleInfo>(
168             "Dokka",
169             projectContext,
170             modules = listOf(module, library)
171         ) {
172             override fun modulesContent(module: ModuleInfo): ModuleContent<ModuleInfo> =
173                 when (module) {
174                     library -> ModuleContent(module, emptyList(), GlobalSearchScope.notScope(sourcesScope))
175                     module -> ModuleContent(module, emptyList(), sourcesScope)
176                     else -> throw IllegalArgumentException("Unexpected module info")
177                 }
178 
179             override fun builtInsForModule(module: ModuleInfo): KotlinBuiltIns = builtIns
180 
181             override fun createResolverForModule(
182                 descriptor: ModuleDescriptor,
183                 moduleInfo: ModuleInfo
184             ): ResolverForModule = JvmResolverForModuleFactory(
185                 JvmPlatformParameters({ content ->
186                     JvmPackagePartProvider(
187                         configuration.languageVersionSettings,
188                         content.moduleContentScope
189                     )
190                         .apply {
191                             addRoots(javaRoots, messageCollector)
192                         }
193                 }, {
194                     val file = (it as JavaClassImpl).psi.containingFile.virtualFile
195                     if (file in sourcesScope)
196                         module
197                     else
198                         library
199                 }),
200                 CompilerEnvironment,
201                 KonanPlatforms.defaultKonanPlatform
202             ).createResolverForModule(
203                 descriptor as ModuleDescriptorImpl,
204                 projectContext.withModule(descriptor),
205                 modulesContent(moduleInfo),
206                 this,
207                 LanguageVersionSettingsImpl.DEFAULT
208             )
209 
210             override fun sdkDependency(module: ModuleInfo): ModuleInfo? = null
211         }
212 
213         val resolverForLibrary = resolverForProject.resolverForModule(library) // Required before module to initialize library properly
214         val resolverForModule = resolverForProject.resolverForModule(module)
215         val libraryModuleDescriptor = resolverForProject.descriptorForModule(library)
216         val moduleDescriptor = resolverForProject.descriptorForModule(module)
217         builtIns.initialize(moduleDescriptor, true)
218         val libraryResolutionFacade = DokkaResolutionFacade(environment.project, libraryModuleDescriptor, resolverForLibrary)
219         val created = DokkaResolutionFacade(environment.project, moduleDescriptor, resolverForModule)
220         val projectComponentManager = environment.project as MockComponentManager
221         projectComponentManager.registerService(KotlinCacheService::class.java, CoreKotlinCacheService(created))
222 
223         return created to libraryResolutionFacade
224     }
225 
226     fun loadLanguageVersionSettings(languageVersionString: String?, apiVersionString: String?) {
227         val languageVersion = LanguageVersion.fromVersionString(languageVersionString) ?: LanguageVersion.LATEST_STABLE
228         val apiVersion = apiVersionString?.let { ApiVersion.parse(it) } ?: ApiVersion.createByLanguageVersion(languageVersion)
229         configuration.languageVersionSettings = LanguageVersionSettingsImpl(languageVersion, apiVersion)
230     }
231 
232     /**
233      * Classpath for this environment.
234      */
235     val classpath: List<File>
236         get() = configuration.jvmClasspathRoots
237 
238     /**
239      * Adds list of paths to classpath.
240      * $paths: collection of files to add
241      */
242     fun addClasspath(paths: List<File>) {
243         configuration.addJvmClasspathRoots(paths)
244     }
245 
246     /**
247      * Adds path to classpath.
248      * $path: path to add
249      */
250     fun addClasspath(path: File) {
251         configuration.addJvmClasspathRoot(path)
252     }
253 
254     /**
255      * List of source roots for this environment.
256      */
257     val sources: List<String>
258         get() = configuration.get(CLIConfigurationKeys.CONTENT_ROOTS)
259                 ?.filterIsInstance<KotlinSourceRoot>()
260                 ?.map { it.path } ?: emptyList()
261 
262     /**
263      * Adds list of paths to source roots.
264      * $list: collection of files to add
265      */
266     fun addSources(list: List<String>) {
267         list.forEach {
268             configuration.addKotlinSourceRoot(it)
269             val file = File(it)
270             if (file.isDirectory || file.extension == ".java") {
271                 configuration.addJavaSourceRoot(file)
272             }
273         }
274     }
275 
276     fun addRoots(list: List<ContentRoot>) {
277         configuration.addAll(CLIConfigurationKeys.CONTENT_ROOTS, list)
278     }
279 
280     /**
281      * Disposes the environment and frees all associated resources.
282      */
283     override fun dispose() {
284         Disposer.dispose(this)
285     }
286 }
287 
contentRootFromPathnull288 fun contentRootFromPath(path: String): ContentRoot {
289     val file = File(path)
290     return if (file.extension == "java") JavaSourceRoot(file, null) else KotlinSourceRoot(path, false)
291 }
292 
293 
294 class DokkaResolutionFacade(override val project: Project,
295                             override val moduleDescriptor: ModuleDescriptor,
296                             val resolverForModule: ResolverForModule) : ResolutionFacade {
analyzeWithAllCompilerChecksnull297     override fun analyzeWithAllCompilerChecks(elements: Collection<KtElement>): AnalysisResult {
298         throw UnsupportedOperationException()
299     }
300 
tryGetFrontendServicenull301     override fun <T : Any> tryGetFrontendService(element: PsiElement, serviceClass: Class<T>): T? {
302         return resolverForModule.componentProvider.tryGetService(serviceClass)
303     }
304 
resolveToDescriptornull305     override fun resolveToDescriptor(declaration: KtDeclaration, bodyResolveMode: BodyResolveMode): DeclarationDescriptor {
306         return resolveSession.resolveToDescriptor(declaration)
307     }
308 
analyzenull309     override fun analyze(elements: Collection<KtElement>, bodyResolveMode: BodyResolveMode): BindingContext {
310         throw UnsupportedOperationException()
311     }
312 
313     val resolveSession: ResolveSession get() = getFrontendService(ResolveSession::class.java)
314 
analyzenull315     override fun analyze(element: KtElement, bodyResolveMode: BodyResolveMode): BindingContext {
316         if (element is KtDeclaration) {
317             val descriptor = resolveToDescriptor(element)
318             return object : BindingContext {
319                 override fun <K : Any?, V : Any?> getKeys(p0: WritableSlice<K, V>?): Collection<K> {
320                     throw UnsupportedOperationException()
321                 }
322 
323                 override fun getType(p0: KtExpression): KotlinType? {
324                     throw UnsupportedOperationException()
325                 }
326 
327                 override fun <K : Any?, V : Any?> get(slice: ReadOnlySlice<K, V>?, key: K): V? {
328                     if (key != element) {
329                         throw UnsupportedOperationException()
330                     }
331                     return when {
332                         slice == BindingContext.DECLARATION_TO_DESCRIPTOR -> descriptor as V
333                         slice == BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER && (element as KtParameter).hasValOrVar() -> descriptor as V
334                         else -> null
335                     }
336                 }
337 
338                 override fun getDiagnostics(): Diagnostics {
339                     throw UnsupportedOperationException()
340                 }
341 
342                 override fun addOwnDataTo(p0: BindingTrace, p1: Boolean) {
343                     throw UnsupportedOperationException()
344                 }
345 
346                 override fun <K : Any?, V : Any?> getSliceContents(p0: ReadOnlySlice<K, V>): ImmutableMap<K, V> {
347                     throw UnsupportedOperationException()
348                 }
349 
350             }
351         }
352         throw UnsupportedOperationException()
353     }
354 
getFrontendServicenull355     override fun <T : Any> getFrontendService(element: PsiElement, serviceClass: Class<T>): T {
356         throw UnsupportedOperationException()
357     }
358 
getFrontendServicenull359     override fun <T : Any> getFrontendService(serviceClass: Class<T>): T {
360         return resolverForModule.componentProvider.getService(serviceClass)
361     }
362 
getFrontendServicenull363     override fun <T : Any> getFrontendService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T {
364         return resolverForModule.componentProvider.getService(serviceClass)
365     }
366 
getIdeServicenull367     override fun <T : Any> getIdeService(serviceClass: Class<T>): T {
368         throw UnsupportedOperationException()
369     }
370 
371 }
372