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