173: Revert changes for IDEA < 181

This commit is contained in:
Simon Ogorodnik
2018-07-17 18:03:23 +03:00
parent c2e27a3c46
commit b58e35a3e5
48 changed files with 1272 additions and 0 deletions
@@ -0,0 +1,366 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea
import com.google.common.html.HtmlEscapers
import com.intellij.codeInsight.documentation.DocumentationManagerUtil
import com.intellij.codeInsight.javadoc.JavaDocInfoGeneratorFactory
import com.intellij.lang.documentation.AbstractDocumentationProvider
import com.intellij.lang.java.JavaDocumentationProvider
import com.intellij.openapi.diagnostic.Logger
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiManager
import com.intellij.psi.PsiWhiteSpace
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.elements.KtLightDeclaration
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.idea.core.completion.DeclarationLookupObject
import org.jetbrains.kotlin.idea.decompiler.navigation.SourceNavigationHelper
import org.jetbrains.kotlin.idea.kdoc.KDocRenderer
import org.jetbrains.kotlin.idea.kdoc.findKDoc
import org.jetbrains.kotlin.idea.kdoc.isBoringBuiltinClass
import org.jetbrains.kotlin.idea.kdoc.resolveKDocLink
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.idea.resolve.frontendService
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
import org.jetbrains.kotlin.kdoc.psi.api.KDoc
import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.renderer.ClassifierNamePolicy
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DeprecationResolver
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.deprecatedByAnnotationReplaceWithExpression
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.utils.addToStdlib.constant
class HtmlClassifierNamePolicy(val base: ClassifierNamePolicy) : ClassifierNamePolicy {
override fun renderClassifier(classifier: ClassifierDescriptor, renderer: DescriptorRenderer): String {
if (DescriptorUtils.isAnonymousObject(classifier)) {
val supertypes = classifier.typeConstructor.supertypes
return buildString {
append("&lt;anonymous object")
if (supertypes.isNotEmpty()) {
append(" : ")
supertypes.joinTo(this) {
val ref = it.constructor.declarationDescriptor
if (ref != null)
renderClassifier(ref, renderer)
else
"&lt;ERROR CLASS&gt;"
}
}
append("&gt;")
}
}
val name = base.renderClassifier(classifier, renderer)
if (classifier.isBoringBuiltinClass())
return name
return buildString {
val ref = classifier.fqNameUnsafe.toString()
DocumentationManagerUtil.createHyperlink(this, ref, name, true)
}
}
}
class KotlinQuickDocumentationProvider : AbstractDocumentationProvider() {
override fun getQuickNavigateInfo(element: PsiElement?, originalElement: PsiElement?): String? {
return if (element == null) null else getText(element, originalElement, true)
}
override fun generateDoc(element: PsiElement, originalElement: PsiElement?): String? {
return getText(element, originalElement, false)
}
override fun getDocumentationElementForLink(psiManager: PsiManager, link: String, context: PsiElement?): PsiElement? {
val navElement = context?.navigationElement as? KtElement ?: return null
val bindingContext = navElement.analyze(BodyResolveMode.PARTIAL)
val contextDescriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, navElement] ?: return null
val descriptors = resolveKDocLink(bindingContext, navElement.getResolutionFacade(),
contextDescriptor, null, link.split('.'))
val target = descriptors.firstOrNull() ?: return null
return DescriptorToSourceUtilsIde.getAnyDeclaration(psiManager.project, target)
}
override fun getDocumentationElementForLookupItem(psiManager: PsiManager, `object`: Any?, element: PsiElement?): PsiElement? {
if (`object` is DeclarationLookupObject) {
`object`.psiElement?.let { return it }
`object`.descriptor?.let { descriptor ->
return DescriptorToSourceUtilsIde.getAnyDeclaration(psiManager.project, descriptor)
}
}
return null
}
companion object {
private val LOG = Logger.getInstance(KotlinQuickDocumentationProvider::class.java)
private val DESCRIPTOR_RENDERER = DescriptorRenderer.HTML.withOptions {
classifierNamePolicy = HtmlClassifierNamePolicy(ClassifierNamePolicy.SHORT)
renderCompanionObjectName = true
}
private fun renderEnumSpecialFunction(element: KtClass, functionDescriptor: FunctionDescriptor, quickNavigation: Boolean): String {
var renderedDecl = DESCRIPTOR_RENDERER.render(functionDescriptor)
if (quickNavigation) return renderedDecl
val declarationDescriptor = element.resolveToDescriptorIfAny()
val enumDescriptor = declarationDescriptor?.getSuperClassNotAny() ?: return renderedDecl
val enumDeclaration =
DescriptorToSourceUtilsIde.getAnyDeclaration(element.project, enumDescriptor) as? KtDeclaration ?: return renderedDecl
val enumSource = SourceNavigationHelper.getNavigationElement(enumDeclaration)
val functionName = functionDescriptor.fqNameSafe.shortName().asString()
val kdoc = enumSource.findDescendantOfType<KDoc> {
it.getChildrenOfType<KDocSection>().any { it.findTagByName(functionName) != null }
}
if (kdoc != null) {
val renderedComment = KDocRenderer.renderKDoc(kdoc.getDefaultSection())
if (renderedComment.startsWith("<p>")) {
renderedDecl += renderedComment
}
else {
renderedDecl = "$renderedDecl<br/>$renderedComment"
}
}
return renderedDecl
}
private fun renderEnum(element: KtClass, originalElement: PsiElement?, quickNavigation: Boolean): String? {
val referenceExpression = originalElement?.getNonStrictParentOfType<KtReferenceExpression>()
if (referenceExpression != null) {
// When caret on special enum function (e.g SomeEnum.values<caret>())
// element is not an KtReferenceExpression, but KtClass of enum
// so reference extracted from originalElement
val context = referenceExpression.analyze(BodyResolveMode.PARTIAL)
(context[BindingContext.REFERENCE_TARGET, referenceExpression] ?:
context[BindingContext.REFERENCE_TARGET, referenceExpression.getChildOfType<KtReferenceExpression>()])?.let {
if (it is FunctionDescriptor) // To protect from Some<caret>Enum.values()
return renderEnumSpecialFunction(element, it, quickNavigation)
}
}
return renderKotlinDeclaration(element, quickNavigation)
}
private fun getText(element: PsiElement, originalElement: PsiElement?, quickNavigation: Boolean): String? {
if (element is PsiWhiteSpace) {
val itElement = findElementWithText(originalElement, "it")
val itReference = itElement?.getParentOfType<KtNameReferenceExpression>(false)
if (itReference != null) {
return getText(itReference, originalElement, quickNavigation)
}
}
if (element is KtTypeReference) {
val declaration = element.parent
if (declaration is KtCallableDeclaration && declaration.receiverTypeReference == element) {
val thisElement = findElementWithText(originalElement, "this")
if (thisElement != null) {
return getText(declaration, originalElement, quickNavigation)
}
}
}
if (element is KtClass && element.isEnum()) {
// When caret on special enum function (e.g SomeEnum.values<caret>())
// element is not an KtReferenceExpression, but KtClass of enum
return renderEnum(element, originalElement, quickNavigation)
}
else if (element is KtEnumEntry && !quickNavigation) {
val ordinal = element.containingClassOrObject?.getBody()?.run { getChildrenOfType<KtEnumEntry>().indexOf(element) }
return buildString {
append(renderKotlinDeclaration(element, quickNavigation))
ordinal?.let {
wrapTag("b") {
append("Enum constant ordinal: $ordinal")
}
}
}
}
else if (element is KtDeclaration) {
return renderKotlinDeclaration(element, quickNavigation)
}
else if (element is KtNameReferenceExpression && element.getReferencedName() == "it") {
return renderKotlinImplicitLambdaParameter(element, quickNavigation)
}
else if (element is KtLightDeclaration<*, *>) {
val origin = element.kotlinOrigin ?: return null
return renderKotlinDeclaration(origin, quickNavigation)
}
if (quickNavigation) {
val referenceExpression = originalElement?.getNonStrictParentOfType<KtReferenceExpression>()
if (referenceExpression != null) {
val context = referenceExpression.analyze(BodyResolveMode.PARTIAL)
val declarationDescriptor = context[BindingContext.REFERENCE_TARGET, referenceExpression]
if (declarationDescriptor != null) {
return mixKotlinToJava(declarationDescriptor, element, originalElement)
}
}
}
else {
// This element was resolved to non-kotlin element, it will be rendered with own provider
}
return null
}
private fun renderKotlinDeclaration(declaration: KtExpression, quickNavigation: Boolean): String {
val context = declaration.analyze(BodyResolveMode.PARTIAL)
val declarationDescriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration]
if (declarationDescriptor == null) {
LOG.info("Failed to find descriptor for declaration " + declaration.getElementTextWithContext())
return "No documentation available"
}
return renderKotlin(context, declarationDescriptor, quickNavigation, declaration)
}
private fun renderKotlinImplicitLambdaParameter(element: KtReferenceExpression, quickNavigation: Boolean): String? {
val context = element.analyze(BodyResolveMode.PARTIAL)
val target = element.mainReference.resolveToDescriptors(context).singleOrNull() as? ValueParameterDescriptor? ?: return null
return renderKotlin(context, target, quickNavigation, element)
}
private fun renderKotlin(
context: BindingContext,
declarationDescriptor: DeclarationDescriptor,
quickNavigation: Boolean,
ktElement: KtElement
): String {
@Suppress("NAME_SHADOWING")
var declarationDescriptor = declarationDescriptor
if (declarationDescriptor is ValueParameterDescriptor) {
val property = context[BindingContext.VALUE_PARAMETER_AS_PROPERTY, declarationDescriptor]
if (property != null) {
declarationDescriptor = property
}
}
var renderedDecl = DESCRIPTOR_RENDERER.withOptions {
withDefinedIn = !DescriptorUtils.isLocal(declarationDescriptor)
}.render(declarationDescriptor)
if (!quickNavigation) {
renderedDecl = "<pre>$renderedDecl</pre>"
}
val deprecationProvider = ktElement.getResolutionFacade().frontendService<DeprecationResolver>()
renderedDecl += renderDeprecationInfo(declarationDescriptor, deprecationProvider)
if (!quickNavigation) {
val comment = declarationDescriptor.findKDoc { DescriptorToSourceUtilsIde.getAnyDeclaration(ktElement.project, it) }
if (comment != null) {
val renderedComment = KDocRenderer.renderKDoc(comment)
if (renderedComment.startsWith("<p>")) {
renderedDecl += renderedComment
}
else {
renderedDecl = "$renderedDecl<br/>$renderedComment"
}
}
else {
if (declarationDescriptor is CallableDescriptor) { // If we couldn't find KDoc, try to find javadoc in one of super's
val psi = declarationDescriptor.findPsi() as? KtFunction
if (psi != null) {
val lightElement = LightClassUtil.getLightClassMethod(psi) // Light method for super's scan in javadoc info gen
val javaDocInfoGenerator = JavaDocInfoGeneratorFactory.create(psi.project, lightElement)
val builder = StringBuilder()
if (javaDocInfoGenerator.generateDocInfoCore(builder, false))
renderedDecl += builder.toString().substringAfter("</PRE>") // Cut off light method signature
}
}
}
}
return renderedDecl
}
private fun renderDeprecationInfo(
declarationDescriptor: DeclarationDescriptor,
deprecationResolver: DeprecationResolver
): String {
val deprecation = deprecationResolver.getDeprecations(declarationDescriptor).firstOrNull() ?: return ""
return buildString {
wrapTag("DL") {
deprecation.message?.let { message ->
wrapTag("DT") { wrapTag("b") { append("Deprecated:") } }
wrapTag("DD") {
append(message.htmlEscape())
}
}
deprecation.deprecatedByAnnotationReplaceWithExpression()?.let { replaceWith ->
wrapTag("DT") { wrapTag("b") { append("Replace with:") } }
wrapTag("DD") {
wrapTag("code") { append(replaceWith.htmlEscape()) }
}
}
}
}
}
private fun String.htmlEscape(): String = HtmlEscapers.htmlEscaper().escape(this)
private inline fun StringBuilder.wrap(prefix: String, postfix: String, crossinline body: () -> Unit) {
this.append(prefix)
body()
this.append(postfix)
}
private inline fun StringBuilder.wrapTag(tag: String, crossinline body: () -> Unit) {
wrap("<$tag>", "</$tag>", body)
}
private fun mixKotlinToJava(declarationDescriptor: DeclarationDescriptor, element: PsiElement, originalElement: PsiElement?): String? {
val originalInfo = JavaDocumentationProvider().getQuickNavigateInfo(element, originalElement)
if (originalInfo != null) {
val renderedDecl = constant { DESCRIPTOR_RENDERER.withOptions { withDefinedIn = false } }.render(declarationDescriptor)
return renderedDecl + "<br/>Java declaration:<br/>" + originalInfo
}
return null
}
private fun findElementWithText(element: PsiElement?, text: String): PsiElement? {
return when {
element == null -> null
element.text == text -> element
element.prevLeaf()?.text == text -> element.prevLeaf()
else -> null
}
}
}
}
@@ -0,0 +1,323 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.kdoc
import com.intellij.codeInsight.documentation.DocumentationManagerUtil
import com.intellij.psi.PsiElement
import org.intellij.markdown.IElementType
import org.intellij.markdown.MarkdownElementTypes
import org.intellij.markdown.MarkdownTokenTypes
import org.intellij.markdown.ast.ASTNode
import org.intellij.markdown.flavours.commonmark.CommonMarkFlavourDescriptor
import org.intellij.markdown.parser.MarkdownParser
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.idea.util.wrapTag
import org.jetbrains.kotlin.kdoc.psi.impl.KDocLink
import org.jetbrains.kotlin.kdoc.psi.impl.KDocName
import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection
import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag
import org.jetbrains.kotlin.psi.KtBlockExpression
import org.jetbrains.kotlin.psi.KtDeclarationWithBody
import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType
object KDocRenderer {
fun renderKDoc(docComment: KDocTag): String {
val content = docComment.getContent()
val result = StringBuilder()
result.append(markdownToHtml(content, allowSingleParagraph = true))
if (docComment is KDocSection) {
result.append("\n")
renderTag(docComment.findTagByName("receiver"), "Receiver", result)
val paramTags = docComment.findTagsByName("param").filter { it.getSubjectName() != null }
renderTagList(paramTags, "Parameters", result)
renderTag(docComment.findTagByName("return"), "Returns", result)
val throwsTags = (docComment.findTagsByName("exception").union(docComment.findTagsByName("throws")))
.filter { it.getSubjectName() != null }
renderTagList(throwsTags, "Throws", result)
renderTag(docComment.findTagByName("author"), "Author", result)
renderTag(docComment.findTagByName("since"), "Since", result)
renderSeeAlso(docComment, result)
val sampleTags = docComment.findTagsByName("sample").filter { it.getSubjectLink() != null }
renderSamplesList(sampleTags, result)
}
return result.toString()
}
private fun KDocLink.createHyperlink(to: StringBuilder) {
DocumentationManagerUtil.createHyperlink(to, getLinkText(), getLinkText(), false)
}
private fun KDocLink.getTargetElement(): PsiElement? {
return this.getChildrenOfType<KDocName>().last().mainReference.resolve()
}
private fun PsiElement.extractExampleText() = when (this) {
is KtDeclarationWithBody -> {
val bodyExpression = bodyExpression
when (bodyExpression) {
is KtBlockExpression -> bodyExpression.text.removeSurrounding("{", "}")
else -> bodyExpression!!.text
}
}
else -> text
}
private fun trimCommonIndent(text: String): String {
fun String.leadingIndent() = indexOfFirst { !it.isWhitespace() }
val lines = text.split('\n')
val minIndent = lines.filter { it.trim().isNotEmpty() }.map(String::leadingIndent).min() ?: 0
return lines.joinToString("\n") { it.drop(minIndent) }
}
private fun renderSamplesList(sampleTags: List<KDocTag>, to: StringBuilder) {
if (sampleTags.isEmpty()) return
to.apply {
wrapTag("dl") {
append("<dt><b>Samples:</b></dt>")
sampleTags.forEach {
wrapTag("dd") {
it.getSubjectLink()?.let { subjectLink ->
subjectLink.createHyperlink(to)
val target = subjectLink.getTargetElement()
wrapTag("pre") {
wrapTag("code") {
if (target == null)
to.append("// Unresolved")
else {
to.append(trimCommonIndent(target.extractExampleText()))
}
}
}
}
}
}
}
}
}
private fun renderSeeAlso(docComment: KDocSection, to: StringBuilder) {
val seeTags = docComment.findTagsByName("see")
if (seeTags.isEmpty()) return
to.append("<DD><DL>")
to.append("<DT><b>").append("See Also:").append("</b>")
to.append("<DD>")
seeTags.forEachIndexed { index, tag ->
val subjectName = tag.getSubjectName()
if (subjectName != null) {
DocumentationManagerUtil.createHyperlink(to, subjectName, subjectName, false)
}
else {
to.append(tag.getContent())
}
if (index < seeTags.size - 1) {
to.append(", ")
}
}
to.append("</DD></DL></DD>")
}
private fun renderTagList(tags: List<KDocTag>, title: String, to: StringBuilder) {
if (tags.isEmpty()) {
return
}
to.append("<dl><dt><b>$title:</b></dt>")
tags.forEach {
to.append("<dd><code>${it.getSubjectName()}</code> - ${markdownToHtml(it.getContent().trimStart())}</dd>")
}
to.append("</dl>\n")
}
private fun renderTag(tag: KDocTag?, title: String, to: StringBuilder) {
if (tag != null) {
to.append("<dl><dt><b>$title:</b></dt>")
to.append("<dd>${markdownToHtml(tag.getContent())}</dd>")
to.append("</dl>\n")
}
}
fun markdownToHtml(markdown: String, allowSingleParagraph: Boolean = false): String {
val markdownTree = MarkdownParser(CommonMarkFlavourDescriptor()).buildMarkdownTreeFromString(markdown)
val markdownNode = MarkdownNode(markdownTree, null, markdown)
// Avoid wrapping the entire converted contents in a <p> tag if it's just a single paragraph
val maybeSingleParagraph = markdownNode.children.singleOrNull { it.type != MarkdownTokenTypes.EOL }
return if (maybeSingleParagraph != null && !allowSingleParagraph) {
maybeSingleParagraph.children.joinToString("") {
if (it.text == "\n") " " else it.toHtml()
}
}
else {
markdownNode.toHtml()
}
}
class MarkdownNode(val node: ASTNode, val parent: MarkdownNode?, val markdown: String) {
val children: List<MarkdownNode> = node.children.map { MarkdownNode(it, this, markdown) }
val endOffset: Int get() = node.endOffset
val startOffset: Int get() = node.startOffset
val type: IElementType get() = node.type
val text: String get() = markdown.substring(startOffset, endOffset)
fun child(type: IElementType): MarkdownNode? = children.firstOrNull { it.type == type }
}
private fun MarkdownNode.visit(action: (MarkdownNode, () -> Unit) -> Unit) {
action(this) {
for (child in children) {
child.visit(action)
}
}
}
private fun MarkdownNode.toHtml(): String {
if (node.type == MarkdownTokenTypes.WHITE_SPACE) {
return text // do not trim trailing whitespace
}
val sb = StringBuilder()
visit { node, processChildren ->
fun wrapChildren(tag: String, newline: Boolean = false) {
sb.append("<$tag>")
processChildren()
sb.append("</$tag>")
if (newline) sb.appendln()
}
val nodeType = node.type
val nodeText = node.text
when (nodeType) {
MarkdownElementTypes.UNORDERED_LIST -> wrapChildren("ul", newline = true)
MarkdownElementTypes.ORDERED_LIST -> wrapChildren("ol", newline = true)
MarkdownElementTypes.LIST_ITEM -> wrapChildren("li")
MarkdownElementTypes.EMPH -> wrapChildren("em")
MarkdownElementTypes.STRONG -> wrapChildren("strong")
MarkdownElementTypes.ATX_1 -> wrapChildren("h1")
MarkdownElementTypes.ATX_2 -> wrapChildren("h2")
MarkdownElementTypes.ATX_3 -> wrapChildren("h3")
MarkdownElementTypes.ATX_4 -> wrapChildren("h4")
MarkdownElementTypes.ATX_5 -> wrapChildren("h5")
MarkdownElementTypes.ATX_6 -> wrapChildren("h6")
MarkdownElementTypes.BLOCK_QUOTE -> wrapChildren("blockquote")
MarkdownElementTypes.PARAGRAPH -> {
sb.trimEnd()
wrapChildren("p", newline = true)
}
MarkdownElementTypes.CODE_SPAN -> {
val startDelimiter = node.child(MarkdownTokenTypes.BACKTICK)?.text
if (startDelimiter != null) {
val text = node.text.substring(startDelimiter.length).removeSuffix(startDelimiter)
sb.append("<code>").append(text.htmlEscape()).append("</code>")
}
}
MarkdownElementTypes.CODE_BLOCK,
MarkdownElementTypes.CODE_FENCE -> {
sb.trimEnd()
sb.append("<pre><code>")
processChildren()
sb.append("</code></pre>")
}
MarkdownElementTypes.SHORT_REFERENCE_LINK,
MarkdownElementTypes.FULL_REFERENCE_LINK -> {
val linkLabelNode = node.child(MarkdownElementTypes.LINK_LABEL)
val linkLabelContent = linkLabelNode?.children
?.dropWhile { it.type == MarkdownTokenTypes.LBRACKET }
?.dropLastWhile { it.type == MarkdownTokenTypes.RBRACKET }
if (linkLabelContent != null) {
val label = linkLabelContent.joinToString(separator = "") { it.text }
val linkText = node.child(MarkdownElementTypes.LINK_TEXT)?.toHtml() ?: label
DocumentationManagerUtil.createHyperlink(sb, label, linkText, true)
}
else {
sb.append(node.text)
}
}
MarkdownElementTypes.INLINE_LINK -> {
val label = node.child(MarkdownElementTypes.LINK_TEXT)?.toHtml()
val destination = node.child(MarkdownElementTypes.LINK_DESTINATION)?.text
if (label != null && destination != null) {
sb.append("<a href=\"$destination\">$label</a>")
}
else {
sb.append(node.text)
}
}
MarkdownTokenTypes.TEXT,
MarkdownTokenTypes.WHITE_SPACE,
MarkdownTokenTypes.COLON,
MarkdownTokenTypes.SINGLE_QUOTE,
MarkdownTokenTypes.DOUBLE_QUOTE,
MarkdownTokenTypes.LPAREN,
MarkdownTokenTypes.RPAREN,
MarkdownTokenTypes.LBRACKET,
MarkdownTokenTypes.RBRACKET,
MarkdownTokenTypes.EXCLAMATION_MARK -> {
sb.append(nodeText)
}
MarkdownTokenTypes.CODE_LINE -> {
sb.append(nodeText.removePrefix(KDocTag.indentationWhiteSpaces).htmlEscape())
}
MarkdownTokenTypes.CODE_FENCE_CONTENT -> {
sb.append(nodeText.htmlEscape())
}
MarkdownTokenTypes.EOL -> {
val parentType = node.parent?.type
if (parentType == MarkdownElementTypes.CODE_BLOCK || parentType == MarkdownElementTypes.CODE_FENCE) {
sb.append("\n")
}
else {
sb.append(" ")
}
}
MarkdownTokenTypes.GT -> sb.append("&gt;")
MarkdownTokenTypes.LT -> sb.append("&lt;")
MarkdownElementTypes.LINK_TEXT -> {
val childrenWithoutBrackets = node.children.drop(1).dropLast(1)
for (child in childrenWithoutBrackets) {
sb.append(child.toHtml())
}
}
MarkdownTokenTypes.EMPH -> {
val parentNodeType = node.parent?.type
if (parentNodeType != MarkdownElementTypes.EMPH && parentNodeType != MarkdownElementTypes.STRONG) {
sb.append(node.text)
}
}
else -> {
processChildren()
}
}
}
return sb.toString().trimEnd()
}
private fun StringBuilder.trimEnd() {
while (length > 0 && this[length - 1] == ' ') {
deleteCharAt(length - 1)
}
}
private fun String.htmlEscape(): String = replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
}
@@ -0,0 +1,9 @@
interface OurFace
open class OurClass
fun context() {
val v = object : OurClass(), OurFace {}
v<caret>
}
//INFO: <pre><b>val</b> v: &lt;anonymous object : <a href="psi_element://OurClass">OurClass</a>, <a href="psi_element://OurFace">OurFace</a>&gt;</pre>
@@ -0,0 +1,12 @@
class C {
/** Use [SOME_REFERENCED_VAL] to do something */
fun fo<caret>o() {
}
companion object {
val SOME_REFERENCED_VAL = 1
}
}
//INFO: <pre><b>public</b> <b>final</b> <b>fun</b> foo(): Unit <i>defined in</i> C</pre><p>Use <a href="psi_element://SOME_REFERENCED_VAL">SOME_REFERENCED_VAL</a> to do something</p>
@@ -0,0 +1,3 @@
fun some(<caret>f: (Int) -> String) : String? = null
//INFO: <pre><b>value-parameter</b> f: (Int) &rarr; String</pre>
@@ -0,0 +1,7 @@
fun foo() {
listOf(1).forEach {
println(it<caret>)
}
}
//INFO: <pre><b>value-parameter</b> it: Int</pre>
@@ -0,0 +1,7 @@
fun foo() {
listOf(1).forEach {
println(i<caret>t)
}
}
//INFO: <pre><b>value-parameter</b> it: Int</pre>
+9
View File
@@ -0,0 +1,9 @@
fun context() {
fun local() {
}
<caret>local()
}
//INFO: <pre><b>local</b> <b>final</b> <b>fun</b> local(): Unit</pre>
+5
View File
@@ -0,0 +1,5 @@
interface Base
class Some<<caret>T: Base>
//INFO: <pre>&lt;T : <a href="psi_element://Base">Base</a>&gt; <i>defined in</i> Some</pre>
@@ -0,0 +1,8 @@
fun some() : String? = null
fun test() {
val <caret>test = some()
}
//INFO: <pre><b>val</b> test: String?</pre>
@@ -0,0 +1,7 @@
class C(var v: Int) {
fun foo() {
print(<caret>v)
}
}
//INFO: <pre><b>public</b> <b>final</b> <b>var</b> v: Int <i>defined in</i> C</pre>
@@ -0,0 +1,14 @@
/**
* Code block:
* ``` kotlin
* A<T>
* ```
* Code span:
* `<T>` is type parameter
*/
class <caret>A<T>
//INFO: <pre><b>public</b> <b>final</b> <b>class</b> A&lt;T&gt; <i>defined in</i> root package <i>in file</i> EscapeHtmlInsideCodeBlocks.kt</pre><p>Code block:</p>
//INFO: <pre><code>
//INFO: A&lt;T&gt;
//INFO: </code></pre><p>Code span: <code>&lt;T&gt;</code> is type parameter</p>
+10
View File
@@ -0,0 +1,10 @@
interface Foo
fun foo(a: Any) {}
fun Foo.bar() {
foo(th<caret>is)
}
//INFO: <pre><b>public</b> <b>fun</b> <a href="psi_element://Foo">Foo</a>.bar(): Unit <i>defined in</i> root package <i>in file</i> ExtensionReceiver.kt</pre>
@@ -0,0 +1,10 @@
interface Foo
fun foo(a: Any) {}
fun Foo.bar() {
foo(this<caret>)
}
//INFO: <pre><b>public</b> <b>fun</b> <a href="psi_element://Foo">Foo</a>.bar(): Unit <i>defined in</i> root package <i>in file</i> ExtensionReceiverEnd.kt</pre>
+22
View File
@@ -0,0 +1,22 @@
/**
* val a = A()
* println(a) // comment
* ```
* <fenced>Code_block</fenced>
* ```
* val b = B()
* println(b)
* some text content
*
* Indented code block with tab
* Second line
*/
class <caret>A
//INFO: <pre><b>public</b> <b>final</b> <b>class</b> A <i>defined in</i> root package <i>in file</i> IndentedCodeBlock.kt</pre><br/><pre><code>val a = A()
//INFO: println(a) // comment</code></pre><pre><code>
//INFO: &lt;fenced&gt;Code_block&lt;/fenced&gt;
//INFO: </code></pre><pre><code>val b = B()
//INFO: println(b)</code></pre><p>some text content</p>
//INFO: <pre><code>Indented code block with tab
//INFO: Second line</code></pre>
@@ -0,0 +1,8 @@
fun testing() {
<caret>SomeClass<List<String>>()
}
//INFO: <html><head> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } p { margin: 5px 0; } </style></head><body><PRE>public class <b>SomeClass</b>&lt;T extends <a href="psi_element://java.util.List"><code>List</code></a>&gt;
//INFO: extends <a href="psi_element://java.lang.Object"><code>Object</code></a></PRE>
//INFO: Some Java Class
//INFO: <DD><DL><DT><b>Type parameters:</b><DD><code>&lt;T&gt;</code> - </DD></DL></DD></body></html>
@@ -0,0 +1,9 @@
class A : OverrideMe() {
override fun <caret>overrideMe() {
}
}
//INFO: <pre><b>protected</b> <b>open</b> <b>fun</b> overrideMe(): Unit <i>defined in</i> A</pre><DD><DL><DT><b>Description copied from class:</b>&nbsp;<a href="psi_element://OverrideMe"><code>OverrideMe</code></a><br>
//INFO: Some comment
//INFO: </DD></DL></DD><DD><DL><DT><b>Overrides:</b><DD><a href="psi_element://OverrideMe#overrideMe()"><code>overrideMe</code></a> in class <a href="psi_element://OverrideMe"><code>OverrideMe</code></a></DD></DL></DD>
@@ -0,0 +1,9 @@
class A : OverrideMe {
override fun <caret>overrideMe() {
}
}
//INFO: <pre><b>public</b> <b>open</b> <b>fun</b> overrideMe(): Unit <i>defined in</i> A</pre><DD><DL><DT><b>Description copied from interface:</b>&nbsp;<a href="psi_element://OverrideMe"><code>OverrideMe</code></a><br>
//INFO: Some comment
//INFO: </DD></DL></DD><DD><DL><DT><b>Specified by:</b><DD><a href="psi_element://OverrideMe#overrideMe()"><code>overrideMe</code></a> in interface <a href="psi_element://OverrideMe"><code>OverrideMe</code></a></DD></DL></DD>
@@ -0,0 +1,13 @@
fun ktTest() {
Test.<caret>foo("SomeTest")
}
//INFO: <html><head> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } p { margin: 5px 0; } </style></head><body><small><b><a href="psi_element://Test"><code>Test</code></a></b></small><PRE><i>@Contract(pure = true)</i>&nbsp;
//INFO: <i>@<a href="psi_element://org.jetbrains.annotations.NotNull"><code>NotNull</code></a></i>&nbsp;
//INFO: public static&nbsp;<a href="psi_element://java.lang.Object"><code>Object</code></a>[]&nbsp;<b>foo</b>(<a href="psi_element://java.lang.String"><code>String</code></a>&nbsp;param)</PRE>
//INFO: Java Method
//INFO:
//INFO: <i>Inferred</i> annotations available:<br>
//INFO: <ul>
//INFO: <li><i>@org.jetbrains.annotations.Contract(pure = true)</i> <i>@<a href="psi_element://org.jetbrains.annotations.NotNull"><code>org.jetbrains.annotations.NotNull</code></a></i></li>
//INFO: </ul></body></html>
@@ -0,0 +1,9 @@
import testing.Test;
class KotlinClassUsedFromJava {
void test() {
<caret>Test();
}
}
//INFO: <pre><b>public</b> <b>final</b> <b>class</b> Test <i>defined in</i> testing <i>in file</i> KotlinClassUsedFromJava_Data.kt</pre><p>Some comment</p>
@@ -0,0 +1,10 @@
import testing.KotlinPackageClassUsedFromJava_DataKt;
class KotlinPackageClassUsedFromJava {
void test() {
<caret>KotlinPackageClassUsedFromJava_DataKt.foo();
}
}
//INFO: <html><head> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } p { margin: 5px 0; } </style></head><body><small><b>testing</b></small><PRE>public final class <b>testing.KotlinPackageClassUsedFromJava_DataKt</b>
//INFO: extends <a href="psi_element://java.lang.Object"><code>Object</code></a></PRE></body></html>
+5
View File
@@ -0,0 +1,5 @@
fun test() {
listOf(1, 2, 4).<caret>filter { it > 0 }
}
//INFO: <pre><b>public</b> <b>inline</b> <b>fun</b> &lt;T&gt; <a href="psi_element://kotlin.collections.Iterable">Iterable</a>&lt;<a href="psi_element://kotlin.collections.filter.T">T</a>&gt;.filter(predicate: (<a href="psi_element://kotlin.collections.filter.T">T</a>) &rarr; Boolean): <a href="psi_element://kotlin.collections.List">List</a>&lt;<a href="psi_element://kotlin.collections.filter.T">T</a>&gt; <i>defined in</i> kotlin.collections <i>in file</i> CollectionsKt.class</pre><p>Returns a list containing only elements matching the given <a href="psi_element://predicate">predicate</a>.</p>
@@ -0,0 +1,6 @@
/**
* Usefull comment
*/
class <caret>Some
//INFO: <pre><b>public</b> <b>final</b> <b>class</b> Some <i>defined in</i> root package <i>in file</i> OnClassDeclarationWithNoPackage.kt</pre><p>Usefull comment</p>
@@ -0,0 +1,10 @@
/**
* Useless one
*/
enum class SomeEnum
fun use() {
Some<caret>Enum::class
}
//INFO: <pre><b>public</b> <b>final</b> <b>enum class</b> SomeEnum : <a href="psi_element://kotlin.Enum">Enum</a>&lt;<a href="psi_element://SomeEnum">SomeEnum</a>&gt; <i>defined in</i> root package <i>in file</i> OnEnumClassReference.kt</pre><p>Useless one</p>
@@ -0,0 +1,6 @@
/**
* Useless one
*/
enum class SomeEnum<caret>
//INFO: <pre><b>public</b> <b>final</b> <b>enum class</b> SomeEnum : <a href="psi_element://kotlin.Enum">Enum</a>&lt;<a href="psi_element://SomeEnum">SomeEnum</a>&gt; <i>defined in</i> root package <i>in file</i> OnEnumDeclaration.kt</pre><p>Useless one</p>
+7
View File
@@ -0,0 +1,7 @@
enum class TestEnum{
A, B, <caret>C
}
//INFO: <pre><b>enum entry</b> C <i>defined in</i> TestEnum</pre><b>Enum constant ordinal: 2</b>
+9
View File
@@ -0,0 +1,9 @@
enum class TestEnum{
A, B, C
}
fun test() {
TestEnum.<caret>C
}
//INFO: <pre><b>enum entry</b> C <i>defined in</i> TestEnum</pre><b>Enum constant ordinal: 2</b>
+12
View File
@@ -0,0 +1,12 @@
/**
* Enum of 1, 2
*/
enum class SomeEnum(val i: Int) {
One(1), Two(2);
}
fun use() {
Some<caret>Enum.One
}
//INFO: <pre><b>public</b> <b>final</b> <b>enum class</b> SomeEnum : <a href="psi_element://kotlin.Enum">Enum</a>&lt;<a href="psi_element://SomeEnum">SomeEnum</a>&gt; <i>defined in</i> root package <i>in file</i> OnEnumUsage.kt</pre><p>Enum of 1, 2</p>
@@ -0,0 +1,11 @@
enum class E {
A
}
fun use() {
E.valueOf<caret>("A")
}
//INFO: <b>public</b> <b>final</b> <b>fun</b> valueOf(value: String): <a href="psi_element://E">E</a> <i>defined in</i> E<p>Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)</p>
//INFO: <dl><dt><b>Throws:</b></dt><dd><code>IllegalArgumentException</code> - if this enum type has no constant with the specified name</dd></dl>
@@ -0,0 +1,9 @@
enum class E {
}
fun use() {
E.values<caret>()
}
//INFO: <b>public</b> <b>final</b> <b>fun</b> values(): Array&lt;<a href="psi_element://E">E</a>&gt; <i>defined in</i> E<p>Returns an array containing the constants of this enum type, in the order they're declared. This method may be used to iterate over the constants.</p>
@@ -0,0 +1,16 @@
package test
/**
*
*
* Test function
*
* @param first Some
* @param second Other
*/
fun <caret>testFun(first: String, second: Int) = 12
//INFO: <pre><b>public</b> <b>fun</b> testFun(first: String, second: Int): Int <i>defined in</i> test <i>in file</i> OnFunctionDeclarationWithPackage.kt</pre><p>Test function</p>
//INFO: <dl><dt><b>Parameters:</b></dt><dd><code>first</code> - Some</dd><dd><code>second</code> - Other</dd></dl>
@@ -0,0 +1,17 @@
open class C() {
/**
* This method returns zero.
*/
open fun foo(): Int = 0
}
class D(): C() {
override fun foo(): Int = 1
}
fun test() {
D().f<caret>oo()
}
//INFO: <pre><b>public</b> <b>open</b> <b>fun</b> foo(): Int <i>defined in</i> D</pre><p>This method returns zero.</p>
@@ -0,0 +1,17 @@
open class C() {
/**
* This property returns zero.
*/
open val foo: Int get() = 0
}
class D(): C() {
override val foo: Int get() = 1
}
fun test() {
D().f<caret>oo
}
//INFO: <pre><b>public</b> <b>open</b> <b>val</b> foo: Int <i>defined in</i> D</pre><p>This property returns zero.</p>
+16
View File
@@ -0,0 +1,16 @@
/**
Some documentation
* @param a Some int
* @param b String
*/
fun testMethod(a: Int, b: String) {
}
fun test() {
<caret>testMethod(1, "value")
}
//INFO: <pre><b>public</b> <b>fun</b> testMethod(a: Int, b: String): Unit <i>defined in</i> root package <i>in file</i> OnMethodUsage.kt</pre><p>Some documentation</p>
//INFO: <dl><dt><b>Parameters:</b></dt><dd><code>a</code> - Some int</dd><dd><code>b</code> - String</dd></dl>
@@ -0,0 +1,13 @@
/**
* Some documentation
* on two lines.
*/
fun testMethod() {
}
fun test() {
<caret>testMethod()
}
//INFO: <pre><b>public</b> <b>fun</b> testMethod(): Unit <i>defined in</i> root package <i>in file</i> OnMethodUsageMultiline.kt</pre><p>Some documentation on two lines.</p>
@@ -0,0 +1,16 @@
/**
Some documentation
* @param[a] Some int
* @param[b] String
*/
fun testMethod(a: Int, b: String) {
}
fun test() {
<caret>testMethod(1, "value")
}
//INFO: <pre><b>public</b> <b>fun</b> testMethod(a: Int, b: String): Unit <i>defined in</i> root package <i>in file</i> OnMethodUsageWithBracketsInParam.kt</pre><p>Some documentation</p>
//INFO: <dl><dt><b>Parameters:</b></dt><dd><code>a</code> - Some int</dd><dd><code>b</code> - String</dd></dl>
@@ -0,0 +1,35 @@
/**
* Some documentation.
*
* ```
* Code block
* Second line
*
* Third line
* ```
*
* Text between code blocks.
* ```
* ```
* Text after code block.
*/
fun testMethod() {
}
class C {
}
fun test() {
<caret>testMethod(1, "value")
}
//INFO: <pre><b>public</b> <b>fun</b> testMethod(): Unit <i>defined in</i> root package <i>in file</i> OnMethodUsageWithCodeBlock.kt</pre><p>Some documentation.</p>
//INFO: <pre><code>
//INFO: Code block
//INFO: Second line
//INFO:
//INFO: Third line
//INFO: </code></pre><p>Text between code blocks.</p>
//INFO: <pre><code>
//INFO: </code></pre><p>Text after code block.</p>
@@ -0,0 +1,36 @@
/**
* Some documentation. **Bold** *underline* `code` foo: bar (baz) [quux] <xyzzy> 'apos'
*
* [Kotlin](http://www.kotlinlang.org)
* [a**b**__d__ kas ](http://www.ibm.com)
*
* [C]
*
* [See **this** class][C]
*
* This is _emphasized text_ but text_with_underscores has to preserve the underscores.
* Single stars embedded in a word like Embedded*Star have to be preserved as well.
*
* Exclamation marks are also important! Also in `code blocks!`
*
* bt+ : ``prefix ` postfix``
* backslash: `\`
*/
fun testMethod() {
}
class C {
}
fun test() {
<caret>testMethod(1, "value")
}
//INFO: <pre><b>public</b> <b>fun</b> testMethod(): Unit <i>defined in</i> root package <i>in file</i> OnMethodUsageWithMarkdown.kt</pre><p>Some documentation. <strong>Bold</strong> <em>underline</em> <code>code</code> foo: bar (baz) <a href="psi_element://quux">quux</a> 'apos'</p>
//INFO: <p><a href="http://www.kotlinlang.org">Kotlin</a> <a href="http://www.ibm.com">a<strong>b</strong><strong>d</strong> kas</a></p>
//INFO: <p><a href="psi_element://C">C</a></p>
//INFO: <p><a href="psi_element://C">See <strong>this</strong> class</a></p>
//INFO: <p>This is <em>emphasized text</em> but text_with_underscores has to preserve the underscores. Single stars embedded in a word like Embedded*Star have to be preserved as well.</p>
//INFO: <p>Exclamation marks are also important! Also in <code>code blocks!</code></p>
//INFO: <p>bt+ : <code>prefix ` postfix</code> backslash: <code>\</code></p>
@@ -0,0 +1,16 @@
/**
* Some documentation
* on two lines.
*
* @param test String
* on two lines
*/
fun testMethod(test: String) {
}
fun test() {
<caret>testMethod("")
}
//INFO: <pre><b>public</b> <b>fun</b> testMethod(test: String): Unit <i>defined in</i> root package <i>in file</i> OnMethodUsageWithMultilineParam.kt</pre><p>Some documentation on two lines.</p>
//INFO: <dl><dt><b>Parameters:</b></dt><dd><code>test</code> - String on two lines</dd></dl>
@@ -0,0 +1,19 @@
/**
Some documentation
* @receiver Some int
* @param b String
* @return Return [a] and nothing else
*/
fun Int.testMethod(b: String) {
}
fun test() {
1.<caret>testMethod("value")
}
//INFO: <pre><b>public</b> <b>fun</b> Int.testMethod(b: String): Unit <i>defined in</i> root package <i>in file</i> OnMethodUsageWithReceiver.kt</pre><p>Some documentation</p>
//INFO: <dl><dt><b>Receiver:</b></dt><dd>Some int</dd></dl>
//INFO: <dl><dt><b>Parameters:</b></dt><dd><code>b</code> - String</dd></dl>
//INFO: <dl><dt><b>Returns:</b></dt><dd>Return <a href="psi_element://a">a</a> and nothing else</dd></dl>
@@ -0,0 +1,18 @@
/**
Some documentation
* @param a Some int
* @param b String
* @return Return [a] and nothing else
*/
fun testMethod(a: Int, b: String) {
}
fun test() {
<caret>testMethod(1, "value")
}
//INFO: <pre><b>public</b> <b>fun</b> testMethod(a: Int, b: String): Unit <i>defined in</i> root package <i>in file</i> OnMethodUsageWithReturnAndLink.kt</pre><p>Some documentation</p>
//INFO: <dl><dt><b>Parameters:</b></dt><dd><code>a</code> - Some int</dd><dd><code>b</code> - String</dd></dl>
//INFO: <dl><dt><b>Returns:</b></dt><dd>Return <a href="psi_element://a">a</a> and nothing else</dd></dl>
@@ -0,0 +1,20 @@
/**
Some documentation
* @param a Some int
* @param b String
* @return Return value
* @throws IllegalArgumentException if the weather is bad
*/
fun testMethod(a: Int, b: String) {
}
fun test() {
<caret>testMethod(1, "value")
}
//INFO: <pre><b>public</b> <b>fun</b> testMethod(a: Int, b: String): Unit <i>defined in</i> root package <i>in file</i> OnMethodUsageWithReturnAndThrows.kt</pre><p>Some documentation</p>
//INFO: <dl><dt><b>Parameters:</b></dt><dd><code>a</code> - Some int</dd><dd><code>b</code> - String</dd></dl>
//INFO: <dl><dt><b>Returns:</b></dt><dd>Return value</dd></dl>
//INFO: <dl><dt><b>Throws:</b></dt><dd><code>IllegalArgumentException</code> - if the weather is bad</dd></dl>
@@ -0,0 +1,21 @@
/**
* @see C
* @see D
* @see <a href="http://kotl.in">kotlin</a>
*/
fun testMethod() {
}
class C {
}
class D {
}
fun test() {
<caret>testMethod(1, "value")
}
//INFO: <pre><b>public</b> <b>fun</b> testMethod(): Unit <i>defined in</i> root package <i>in file</i> OnMethodUsageWithSee.kt</pre><br/>
//INFO: <DD><DL><DT><b>See Also:</b><DD><a href="psi_element://C"><code>C</code></a>, <a href="psi_element://D"><code>D</code></a>, <a href="http://kotl.in">kotlin</a></DD></DL></DD>
@@ -0,0 +1,17 @@
/**
Some documentation
* @param T the type parameter
* @param a Some int
* @param b String
*/
fun <T> testMethod(a: Int, b: String) {
}
fun test() {
<caret>testMethod(1, "value")
}
//INFO: <pre><b>public</b> <b>fun</b> &lt;T&gt; testMethod(a: Int, b: String): Unit <i>defined in</i> root package <i>in file</i> OnMethodUsageWithTypeParameter.kt</pre><p>Some documentation</p>
//INFO: <dl><dt><b>Parameters:</b></dt><dd><code>T</code> - the type parameter</dd><dd><code>a</code> - Some int</dd><dd><code>b</code> - String</dd></dl>
+28
View File
@@ -0,0 +1,28 @@
package magic
object Samples {
fun sampleMagic() {
castTextSpell("[asd] [dse] [asz]")
}
}
fun sampleScroll() {
val reader = Scroll("[asd] [dse] [asz]").reader()
castTextSpell(reader.readAll())
}
/**
* @sample Samples.sampleMagic
* @sample sampleScroll
*/
fun <caret>castTextSpell(spell: String) {
throw SecurityException("Magic prohibited outside Hogwarts")
}
//INFO: <pre><b>public</b> <b>fun</b> castTextSpell(spell: String): Unit <i>defined in</i> magic <i>in file</i> Samples.kt</pre><br/>
//INFO: <dl><dt><b>Samples:</b></dt><dd><a href="psi_element://Samples.sampleMagic"><code>Samples.sampleMagic</code></a><pre><code>
//INFO: castTextSpell("[asd] [dse] [asz]")
//INFO: </code></pre></dd><dd><a href="psi_element://sampleScroll"><code>sampleScroll</code></a><pre><code>
//INFO: val reader = Scroll("[asd] [dse] [asz]").reader()
//INFO: castTextSpell(reader.readAll())
//INFO: </code></pre></dd></dl>
@@ -0,0 +1,11 @@
package server
import some.TopLevelMethodFromJava_DataKt
class Testing {
void test() {
TopLevelMethodFromJava_DataKt.<caret>foo(12);
}
}
//INFO: <pre><b>public</b> <b>fun</b> foo(bar: Int): Unit <i>defined in</i> some <i>in file</i> TopLevelMethodFromJava_Data.kt</pre><p>KDoc foo</p>
@@ -0,0 +1,11 @@
class A {
}
fun foo(x : A) { }
fun main(args: Array<String>) {
<caret>foo()
}
//INFO: <pre><b>public</b> <b>fun</b> foo(x: <a href="psi_element://A">A</a>): Unit <i>defined in</i> root package <i>in file</i> TypeNamesFromStdLibNavigation.kt</pre>