aboutsummaryrefslogtreecommitdiff
path: root/src/Analysis
diff options
context:
space:
mode:
Diffstat (limited to 'src/Analysis')
-rw-r--r--src/Analysis/AnalysisEnvironment.kt70
-rw-r--r--src/Analysis/CommentsAPI.kt30
-rw-r--r--src/Analysis/CompilerAPI.kt62
-rw-r--r--src/Analysis/PsiAPI.kt19
4 files changed, 181 insertions, 0 deletions
diff --git a/src/Analysis/AnalysisEnvironment.kt b/src/Analysis/AnalysisEnvironment.kt
new file mode 100644
index 00000000..346367ee
--- /dev/null
+++ b/src/Analysis/AnalysisEnvironment.kt
@@ -0,0 +1,70 @@
+package org.jetbrains.dokka
+
+import org.jetbrains.jet.cli.common.messages.*
+import com.intellij.openapi.*
+import org.jetbrains.jet.cli.jvm.compiler.*
+import org.jetbrains.jet.lang.resolve.*
+import org.jetbrains.jet.lang.psi.*
+import java.io.File
+import org.jetbrains.jet.config.*
+import org.jetbrains.jet.cli.common.*
+import org.jetbrains.jet.cli.jvm.*
+import com.intellij.openapi.util.*
+
+public class AnalysisEnvironment(val messageCollector: MessageCollector, body: AnalysisEnvironment.() -> Unit = {}) : Disposable {
+ val configuration = CompilerConfiguration();
+
+ {
+ configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
+ body()
+ }
+
+ private fun withContext<T>(processor: (JetCoreEnvironment, BindingContext) -> T): T {
+ val environment = JetCoreEnvironment.createForProduction(this, configuration)
+ val result = environment.analyze(messageCollector)
+ return processor(environment, result)
+ }
+
+ public fun withContext<T>(processor: (BindingContext) -> T): T {
+ return withContext { environment, context -> processor(context) }
+ }
+
+ public fun streamFiles<T>(processor: (BindingContext, JetFile) -> T): Stream<T> {
+ return withContext { environment, context ->
+ environment.getSourceFiles().stream().map { file -> processor(context, file) }
+ }
+ }
+
+ public fun processFiles<T>(processor: (BindingContext, JetFile) -> T): List<T> {
+ return withContext { environment, context ->
+ environment.getSourceFiles().map { file -> processor(context, file) }
+ }
+ }
+
+ public fun processFilesFlat<T>(processor: (BindingContext, JetFile) -> List<T>): List<T> {
+ return withContext { environment, context ->
+ environment.getSourceFiles().flatMap { file -> processor(context, file) }
+ }
+ }
+
+ public val classpath: List<File>
+ get() = configuration.get(JVMConfigurationKeys.CLASSPATH_KEY) ?: listOf()
+
+ public fun addClasspath(list: List<File>) {
+ configuration.addAll(JVMConfigurationKeys.CLASSPATH_KEY, list)
+ }
+
+ public fun addClasspath(file: File) {
+ configuration.add(JVMConfigurationKeys.CLASSPATH_KEY, file)
+ }
+
+ public val sources: List<String>
+ get() = configuration.get(CommonConfigurationKeys.SOURCE_ROOTS_KEY) ?: listOf()
+ public fun addSources(list: List<String>) {
+ configuration.addAll(CommonConfigurationKeys.SOURCE_ROOTS_KEY, list)
+ }
+
+ public override fun dispose() {
+ Disposer.dispose(this)
+ }
+} \ No newline at end of file
diff --git a/src/Analysis/CommentsAPI.kt b/src/Analysis/CommentsAPI.kt
new file mode 100644
index 00000000..a32ee734
--- /dev/null
+++ b/src/Analysis/CommentsAPI.kt
@@ -0,0 +1,30 @@
+package org.jetbrains.dokka
+
+import org.jetbrains.jet.lang.descriptors.*
+import org.jetbrains.jet.lang.resolve.*
+import org.jetbrains.jet.kdoc.psi.api.*
+import org.jetbrains.jet.lang.psi.*
+
+fun BindingContext.getDocumentation(descriptor: DeclarationDescriptor): KDoc? {
+ val psiElement = DescriptorToSourceUtils.descriptorToDeclaration(descriptor)
+ if (psiElement == null)
+ throw IllegalArgumentException("$descriptor doesn't have connection to source code, is it synthetic?")
+
+ return psiElement.previousSiblings().takeWhile { it !is JetDeclaration }.firstOrNull { it is KDoc } as KDoc?
+}
+
+fun KDoc?.extractText(): String {
+ if (this == null)
+ return ""
+ val text = getText()
+ if (text == null)
+ return ""
+ val lines = text.replace("\r", "").split("\n")
+ return lines.map {
+ it.dropWhile { java.lang.Character.isWhitespace(it) }
+ .dropWhile { it == '/' }
+ .dropWhile { it == '*' }
+ .dropWhile { it == '/' }
+ .dropWhile { java.lang.Character.isWhitespace(it) }
+ }.filter { it.any() }.join("\n")
+} \ No newline at end of file
diff --git a/src/Analysis/CompilerAPI.kt b/src/Analysis/CompilerAPI.kt
new file mode 100644
index 00000000..bf77a7d4
--- /dev/null
+++ b/src/Analysis/CompilerAPI.kt
@@ -0,0 +1,62 @@
+package org.jetbrains.dokka
+
+import org.jetbrains.jet.cli.common.arguments.*
+import org.jetbrains.jet.cli.common.messages.*
+import org.jetbrains.jet.cli.jvm.*
+import org.jetbrains.jet.cli.jvm.compiler.*
+import org.jetbrains.jet.utils.*
+import java.io.*
+import org.jetbrains.jet.lang.resolve.java.*
+import com.google.common.base.*
+import com.intellij.psi.*
+import org.jetbrains.jet.lang.resolve.*
+import org.jetbrains.jet.lang.psi.*
+import org.jetbrains.jet.analyzer.*
+import org.jetbrains.jet.lang.descriptors.*
+
+private fun getAnnotationsPath(paths: KotlinPaths, arguments: K2JVMCompilerArguments): MutableList<File> {
+ val annotationsPath = arrayListOf<File>()
+ annotationsPath.add(paths.getJdkAnnotationsPath())
+ val annotationPaths = arguments.annotations
+ if (annotationPaths != null) {
+ for (element in annotationPaths.split(File.pathSeparatorChar)) {
+ annotationsPath.add(File(element))
+ }
+ }
+ return annotationsPath
+}
+
+fun JetCoreEnvironment.analyze(messageCollector: MessageCollector): BindingContext {
+ val project = getProject()
+ val sourceFiles = getSourceFiles()
+
+ val analyzerWithCompilerReport = AnalyzerWithCompilerReport(messageCollector)
+ analyzerWithCompilerReport.analyzeAndReport(sourceFiles) {
+ val support = CliLightClassGenerationSupport.getInstanceForCli(project)!!
+ val sharedTrace = support.getTrace()
+ val sharedModule = support.getModule()
+ val compilerConfiguration = getConfiguration()!!
+ AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(project, sourceFiles, sharedTrace,
+ Predicates.alwaysTrue<PsiFile>(),
+ sharedModule,
+ compilerConfiguration.get(JVMConfigurationKeys.MODULE_IDS),
+ compilerConfiguration.get(JVMConfigurationKeys.INCREMENTAL_CACHE_BASE_DIR))
+ }
+
+ val exhaust = analyzerWithCompilerReport.getAnalyzeExhaust()
+ assert(exhaust != null) { "AnalyzeExhaust should be non-null, compiling: " + sourceFiles }
+
+ return exhaust!!.getBindingContext()
+}
+
+fun AnalyzerWithCompilerReport.analyzeAndReport(files: List<JetFile>, analyser: () -> AnalyzeExhaust) = analyzeAndReport(analyser, files)
+
+fun BindingContext.getPackageFragment(file: JetFile) = get(BindingContext.FILE_TO_PACKAGE_FRAGMENT, file)
+
+fun DeclarationDescriptor.isUserCode() =
+ when (this) {
+ is PackageFragmentDescriptor -> false
+ is PropertyAccessorDescriptor -> !isDefault()
+ is CallableMemberDescriptor -> getKind() == CallableMemberDescriptor.Kind.DECLARATION
+ else -> true
+ }
diff --git a/src/Analysis/PsiAPI.kt b/src/Analysis/PsiAPI.kt
new file mode 100644
index 00000000..2282cd1d
--- /dev/null
+++ b/src/Analysis/PsiAPI.kt
@@ -0,0 +1,19 @@
+package org.jetbrains.dokka
+
+import com.intellij.psi.*
+import kotlin.support.*
+
+fun PsiElement.previousSiblings(): Stream<PsiElement> {
+ var element: PsiElement? = this
+ return object : Stream<PsiElement> {
+ override fun iterator(): Iterator<PsiElement> = object : AbstractIterator<PsiElement>() {
+ override fun computeNext() {
+ element = element?.getPrevSibling()
+ if (element == null)
+ done()
+ else
+ setNext(element!!)
+ }
+ }
+ }
+}