diff options
Diffstat (limited to 'src/Analysis')
-rw-r--r-- | src/Analysis/AnalysisEnvironment.kt | 70 | ||||
-rw-r--r-- | src/Analysis/CommentsAPI.kt | 30 | ||||
-rw-r--r-- | src/Analysis/CompilerAPI.kt | 62 | ||||
-rw-r--r-- | src/Analysis/PsiAPI.kt | 19 |
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!!) + } + } + } +} |