diff options
-rw-r--r-- | src/Analysis/CompilerAPI.kt | 57 | ||||
-rw-r--r-- | src/Model/DocumentationBuilder.kt | 4 | ||||
-rw-r--r-- | src/Model/DocumentationBuildingVisitor.kt | 48 | ||||
-rw-r--r-- | src/Model/DocumentationResolver.kt | 12 | ||||
-rw-r--r-- | src/main.kt | 2 | ||||
-rw-r--r-- | test/src/TestAPI.kt | 2 |
6 files changed, 96 insertions, 29 deletions
diff --git a/src/Analysis/CompilerAPI.kt b/src/Analysis/CompilerAPI.kt index bf77a7d4..039ad799 100644 --- a/src/Analysis/CompilerAPI.kt +++ b/src/Analysis/CompilerAPI.kt @@ -13,6 +13,11 @@ import org.jetbrains.jet.lang.resolve.* import org.jetbrains.jet.lang.psi.* import org.jetbrains.jet.analyzer.* import org.jetbrains.jet.lang.descriptors.* +import org.jetbrains.jet.lang.resolve.scopes.JetScope +import com.intellij.psi.impl.source.tree.LeafPsiElement +import org.jetbrains.jet.lang.resolve.scopes.WritableScope +import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl +import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler private fun getAnnotationsPath(paths: KotlinPaths, arguments: K2JVMCompilerArguments): MutableList<File> { val annotationsPath = arrayListOf<File>() @@ -60,3 +65,55 @@ fun DeclarationDescriptor.isUserCode() = is CallableMemberDescriptor -> getKind() == CallableMemberDescriptor.Kind.DECLARATION else -> true } + +public fun getFunctionInnerScope(outerScope: JetScope, descriptor: FunctionDescriptor): JetScope { + val redeclarationHandler = object : RedeclarationHandler { + override fun handleRedeclaration(first: DeclarationDescriptor, second: DeclarationDescriptor) { + // TODO: check if we can ignore redeclarations + } + } + + val parameterScope = WritableScopeImpl(outerScope, descriptor, redeclarationHandler, "Function KDoc scope") + val receiver = descriptor.getReceiverParameter() + if (receiver != null) { + parameterScope.setImplicitReceiver(receiver) + } + for (typeParameter in descriptor.getTypeParameters()) { + parameterScope.addTypeParameterDescriptor(typeParameter) + } + for (valueParameterDescriptor in descriptor.getValueParameters()) { + parameterScope.addVariableDescriptor(valueParameterDescriptor) + } + parameterScope.addLabeledDeclaration(descriptor) + parameterScope.changeLockLevel(WritableScope.LockLevel.READING) + return parameterScope +} + +fun BindingContext.getResolutionScope(descriptor: DeclarationDescriptor): JetScope { + when (descriptor) { + is PackageFragmentDescriptor -> return descriptor.getMemberScope() + is PackageViewDescriptor -> return descriptor.getMemberScope() + + is ClassDescriptor -> return descriptor.getUnsubstitutedInnerClassesScope() + is PropertyAccessorDescriptor -> return getResolutionScope(descriptor.getCorrespondingProperty()) + is FunctionDescriptor -> { + val container = getFunctionInnerScope(getResolutionScope(descriptor.getContainingDeclaration()), descriptor) + if (container is JetFunction) + return getFunctionBodyScope(container) + } + } + + if (descriptor is DeclarationDescriptorNonRoot) + return getResolutionScope(descriptor.getContainingDeclaration()) + + throw IllegalArgumentException("Cannot find resolution scope for root $descriptor") +} + +fun BindingContext.getFunctionBodyScope(element: JetFunction): JetScope { + val body = element.getBodyExpression() + val scope = get(BindingContext.RESOLUTION_SCOPE, body) + if (scope != null) + return scope + throw IllegalArgumentException("Cannot find resolution scope for function $element") +} + diff --git a/src/Model/DocumentationBuilder.kt b/src/Model/DocumentationBuilder.kt index 464a5ab2..353e839e 100644 --- a/src/Model/DocumentationBuilder.kt +++ b/src/Model/DocumentationBuilder.kt @@ -6,13 +6,13 @@ import org.jetbrains.jet.lang.descriptors.* import org.jetbrains.jet.lang.descriptors.impl.* import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns -fun BindingContext.createSourceModel(file: JetFile): DocumentationModel { +fun BindingContext.createDocumentationModel(file: JetFile): DocumentationModel { val model = DocumentationModel() val packageFragment = getPackageFragment(file) if (packageFragment == null) throw IllegalArgumentException("File $file should have package fragment") val visitor = DocumentationBuilderVisitor(this) - visitDescriptor(packageFragment, model, visitor) + packageFragment.accept(DocumentationBuildingVisitor(this, visitor), model) return model } diff --git a/src/Model/DocumentationBuildingVisitor.kt b/src/Model/DocumentationBuildingVisitor.kt index e7b3fc09..81a6474c 100644 --- a/src/Model/DocumentationBuildingVisitor.kt +++ b/src/Model/DocumentationBuildingVisitor.kt @@ -1,9 +1,10 @@ package org.jetbrains.dokka import org.jetbrains.jet.lang.descriptors.* -import org.jetbrains.jet.lang.resolve.name.FqName +import org.jetbrains.jet.lang.resolve.name.* +import org.jetbrains.jet.lang.resolve.* -class DocumentationBuildingVisitor(private val worker: DeclarationDescriptorVisitor<DocumentationNode, DocumentationNode>) +class DocumentationBuildingVisitor(val context: BindingContext, private val worker: DeclarationDescriptorVisitor<DocumentationNode, DocumentationNode>) : DeclarationDescriptorVisitor<DocumentationNode, DocumentationNode> { private fun visitChildren(descriptors: Collection<DeclarationDescriptor>, data: DocumentationNode) { @@ -27,19 +28,19 @@ class DocumentationBuildingVisitor(private val worker: DeclarationDescriptorVisi visitChildren(descriptor.getTypeParameters(), node) visitChild(descriptor.getReceiverParameter(), node) visitChildren(descriptor.getValueParameters(), node) - return node + return node.resolve(context.getResolutionScope(descriptor)) } public override fun visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor?, data: DocumentationNode?): DocumentationNode? { val node = createDocumentation(descriptor!!, data!!) visitChildren(descriptor.getMemberScope().getAllDescriptors(), node) - return node + return node.resolve(context.getResolutionScope(descriptor)) } public override fun visitPackageViewDescriptor(descriptor: PackageViewDescriptor?, data: DocumentationNode?): DocumentationNode? { val node = createDocumentation(descriptor!!, data!!) visitChildren(descriptor.getMemberScope().getAllDescriptors(), node) - return node + return node.resolve(context.getResolutionScope(descriptor)) } public override fun visitVariableDescriptor(descriptor: VariableDescriptor?, data: DocumentationNode?): DocumentationNode? { @@ -56,12 +57,12 @@ class DocumentationBuildingVisitor(private val worker: DeclarationDescriptorVisi public override fun visitFunctionDescriptor(descriptor: FunctionDescriptor?, data: DocumentationNode?): DocumentationNode? { val node = processCallable(descriptor!!, data!!) - return node + return node.resolve(context.getResolutionScope(descriptor)) } public override fun visitTypeParameterDescriptor(descriptor: TypeParameterDescriptor?, data: DocumentationNode?): DocumentationNode? { val node = createDocumentation(descriptor!!, data!!) - return node + return node.resolve(context.getResolutionScope(descriptor)) } public override fun visitClassDescriptor(descriptor: ClassDescriptor?, data: DocumentationNode?): DocumentationNode? { @@ -76,46 +77,43 @@ class DocumentationBuildingVisitor(private val worker: DeclarationDescriptorVisi it !is CallableMemberDescriptor || it.isUserCode() } visitChildren(members, node) - return node + return node.resolve(context.getResolutionScope(descriptor)) } public override fun visitModuleDeclaration(descriptor: ModuleDescriptor?, data: DocumentationNode?): DocumentationNode? { val node = createDocumentation(descriptor!!, data!!) visitChild(descriptor.getPackage(FqName.ROOT), node) - return node + return node.resolve(context.getResolutionScope(descriptor)) } - public override fun visitConstructorDescriptor(constructorDescriptor: ConstructorDescriptor?, data: DocumentationNode?): DocumentationNode? { - val node = visitFunctionDescriptor(constructorDescriptor, data) - return node + public override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor?, data: DocumentationNode?): DocumentationNode? { + val node = visitFunctionDescriptor(descriptor!!, data) + return node?.resolve(context.getResolutionScope(descriptor)) } public override fun visitScriptDescriptor(scriptDescriptor: ScriptDescriptor?, data: DocumentationNode?): DocumentationNode? { - val node = visitClassDescriptor(scriptDescriptor!!.getClassDescriptor(), data) - return node + val classDescriptor = scriptDescriptor!!.getClassDescriptor() + val node = visitClassDescriptor(classDescriptor, data) + return node?.resolve(context.getResolutionScope(classDescriptor)) } public override fun visitValueParameterDescriptor(descriptor: ValueParameterDescriptor?, data: DocumentationNode?): DocumentationNode? { - val node = visitVariableDescriptor(descriptor, data) - return node + val node = visitVariableDescriptor(descriptor!!, data) + return node?.resolve(context.getResolutionScope(descriptor)) } public override fun visitPropertyGetterDescriptor(descriptor: PropertyGetterDescriptor?, data: DocumentationNode?): DocumentationNode? { - val node = visitFunctionDescriptor(descriptor, data) - return node + val node = visitFunctionDescriptor(descriptor!!, data) + return node?.resolve(context.getResolutionScope(descriptor)) } public override fun visitPropertySetterDescriptor(descriptor: PropertySetterDescriptor?, data: DocumentationNode?): DocumentationNode? { - val node = visitFunctionDescriptor(descriptor, data) - return node + val node = visitFunctionDescriptor(descriptor!!, data) + return node?.resolve(context.getResolutionScope(descriptor)) } public override fun visitReceiverParameterDescriptor(descriptor: ReceiverParameterDescriptor?, data: DocumentationNode?): DocumentationNode? { val node = createDocumentation(descriptor!!, data!!) - return node + return node.resolve(context.getResolutionScope(descriptor)) } } - -public fun visitDescriptor(descriptor: DeclarationDescriptor, data: DocumentationNode, visitor: DeclarationDescriptorVisitor<DocumentationNode, DocumentationNode>): DocumentationNode { - return descriptor.accept(DocumentationBuildingVisitor(visitor), data) -} diff --git a/src/Model/DocumentationResolver.kt b/src/Model/DocumentationResolver.kt new file mode 100644 index 00000000..70ee4aae --- /dev/null +++ b/src/Model/DocumentationResolver.kt @@ -0,0 +1,12 @@ +package org.jetbrains.dokka + +import org.jetbrains.jet.lang.resolve.scopes.* + + +fun DocumentationNode.resolve(): DocumentationNode { + return this +} + +fun DocumentationNode.resolve(scope: JetScope): DocumentationNode { + return this +}
\ No newline at end of file diff --git a/src/main.kt b/src/main.kt index 30c3a737..1ed3e625 100644 --- a/src/main.kt +++ b/src/main.kt @@ -37,7 +37,7 @@ public fun main(args: Array<String>) { val model = environment.processFiles { context, file -> println("Processing: ${file.getName()}") - context.createSourceModel(file) + context.createDocumentationModel(file) }.fold(DocumentationModel()) {(aggregate, item) -> aggregate.merge(item) } ConsoleGenerator().generate(model) diff --git a/test/src/TestAPI.kt b/test/src/TestAPI.kt index e5669569..282697da 100644 --- a/test/src/TestAPI.kt +++ b/test/src/TestAPI.kt @@ -28,7 +28,7 @@ public fun verifyModel(vararg files: String, verifier: (DocumentationModel) -> U } val result = environment.processFiles { context, file -> - context.createSourceModel(file) + context.createDocumentationModel(file) }.fold(DocumentationModel()) {(aggregate, item) -> aggregate.merge(item) } verifier(result) Disposer.dispose(environment) |