Make j2k depends on idea-core instead of idea-full

This commit is contained in:
Natalia Ukhorskaya
2015-07-27 18:32:12 +03:00
parent 22ee063269
commit c86b25b1dc
18 changed files with 450 additions and 291 deletions
@@ -32,11 +32,12 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileVisitor
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.PsiManager
import org.jetbrains.kotlin.idea.j2k.IdeaResolverForConverter
import org.jetbrains.kotlin.idea.j2k.IdeaJavaToKotlinServices
import org.jetbrains.kotlin.idea.j2k.J2kPostProcessor
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.j2k.*
import org.jetbrains.kotlin.j2k.ConverterSettings
import org.jetbrains.kotlin.j2k.JavaToKotlinConverter
import java.io.File
import java.io.IOException
import java.util.ArrayList
@@ -50,7 +51,7 @@ public class JavaToKotlinAction : AnAction() {
var converterResult: JavaToKotlinConverter.FilesResult? = null
fun convert() {
val converter = JavaToKotlinConverter(project, ConverterSettings.defaultSettings, IdeaReferenceSearcher, IdeaResolverForConverter, IdeaDocCommentConverter)
val converter = JavaToKotlinConverter(project, ConverterSettings.defaultSettings, IdeaJavaToKotlinServices)
converterResult = converter.filesToKotlin(javaFiles, J2kPostProcessor(formatCode = true), ProgressManager.getInstance().getProgressIndicator())
}
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
import org.jetbrains.kotlin.idea.codeInsight.KotlinCopyPasteReferenceProcessor
import org.jetbrains.kotlin.idea.codeInsight.KotlinReferenceData
import org.jetbrains.kotlin.idea.editor.JetEditorOptions
import org.jetbrains.kotlin.idea.j2k.IdeaJavaToKotlinServices
import org.jetbrains.kotlin.idea.j2k.IdeaResolverForConverter
import org.jetbrains.kotlin.idea.j2k.J2kPostProcessor
import org.jetbrains.kotlin.idea.util.ImportInsertHelper
@@ -159,9 +160,7 @@ public class ConvertJavaCopyPastePostProcessor : CopyPastePostProcessor<TextBloc
val converter = JavaToKotlinConverter(
project,
ConverterSettings.defaultSettings,
IdeaReferenceSearcher,
IdeaResolverForConverter,
IdeaDocCommentConverter
IdeaJavaToKotlinServices
)
val inputElements = elementsAndTexts.filterIsInstance<PsiElement>()
@@ -0,0 +1,217 @@
/*
* 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.j2k
import com.intellij.ide.highlighter.HtmlFileType
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFileFactory
import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.XmlRecursiveElementVisitor
import com.intellij.psi.javadoc.PsiDocComment
import com.intellij.psi.javadoc.PsiDocTag
import com.intellij.psi.javadoc.PsiDocToken
import com.intellij.psi.javadoc.PsiInlineDocTag
import com.intellij.psi.xml.XmlFile
import com.intellij.psi.xml.XmlTag
import com.intellij.psi.xml.XmlText
import com.intellij.psi.xml.XmlTokenType
import org.jetbrains.kotlin.j2k.DocCommentConverter
import org.jetbrains.kotlin.j2k.content
object IdeaDocCommentConverter : DocCommentConverter {
override fun convertDocComment(docComment: PsiDocComment): String {
val html = StringBuilder {
appendJavadocElements(docComment.getDescriptionElements())
tagsLoop@
for (tag in docComment.getTags()) {
when (tag.getName()) {
"deprecated" -> continue@tagsLoop
"see" -> append("@see ${convertJavadocLink(tag.content())}\n")
else -> appendJavadocElements(tag.getChildren()).append("\n")
}
}
}.toString()
if (html.trim().isEmpty() && docComment.findTagByName("deprecated") != null) {
// @deprecated was the only content of the doc comment; we can drop the comment
return ""
}
val htmlFile = PsiFileFactory.getInstance(docComment.getProject()).createFileFromText(
"javadoc.html", HtmlFileType.INSTANCE, html)
val htmlToMarkdownConverter = HtmlToMarkdownConverter()
htmlFile.accept(htmlToMarkdownConverter)
return htmlToMarkdownConverter.result
}
private fun StringBuilder.appendJavadocElements(elements: Array<PsiElement>): StringBuilder {
elements.forEach {
if (it is PsiInlineDocTag) {
append(convertInlineDocTag(it))
}
else {
append(it.getText())
}
}
return this
}
private fun convertInlineDocTag(tag: PsiInlineDocTag) = when(tag.getName()) {
"code", "literal" -> {
val text = tag.getDataElements().map { it.getText() }.join("")
val escaped = StringUtil.escapeXml(text.trimStart())
if (tag.getName() == "code") "<code>$escaped</code>" else escaped
}
"link", "linkplain" -> {
val valueElement = tag.linkElement()
val labelText = tag.getDataElements().firstOrNull { it is PsiDocToken }?.getText() ?: ""
val kdocLink = convertJavadocLink(valueElement?.getText())
val linkText = if (labelText.isEmpty()) kdocLink else StringUtil.escapeXml(labelText)
"<a docref=\"$kdocLink\">$linkText</a>"
}
else -> tag.getText()
}
private fun convertJavadocLink(link: String?): String =
if (link != null) link.substringBefore('(').replace('#', '.') else ""
private fun PsiDocTag.linkElement(): PsiElement? =
getValueElement() ?: getDataElements().firstOrNull { it !is PsiWhiteSpace }
private class HtmlToMarkdownConverter() : XmlRecursiveElementVisitor() {
private enum class ListType { Ordered, Unordered; }
data class MarkdownSpan(val prefix: String, val suffix: String) {
companion object {
val Empty = MarkdownSpan("", "")
fun wrap(text: String) = MarkdownSpan(text, text)
fun prefix(text: String) = MarkdownSpan(text, "")
}
}
val result: String
get() = markdownBuilder.toString()
private val markdownBuilder = StringBuilder("/**")
private var afterLineBreak = false
private var whitespaceIsPartOfText = true
private var currentListType = ListType.Unordered
override fun visitWhiteSpace(space: PsiWhiteSpace) {
super.visitWhiteSpace(space)
if (whitespaceIsPartOfText) {
appendPendingText()
markdownBuilder.append(space.getText())
if (space.textContains('\n')) {
afterLineBreak = true
}
}
}
override fun visitElement(element: PsiElement) {
super.visitElement(element)
val tokenType = element.getNode().getElementType()
if (tokenType == XmlTokenType.XML_DATA_CHARACTERS || tokenType == XmlTokenType.XML_CHAR_ENTITY_REF) {
appendPendingText()
markdownBuilder.append(element.getText())
}
}
override fun visitXmlTag(tag: XmlTag) {
withWhitespaceAsPartOfText(false) {
val oldListType = currentListType
val atLineStart = afterLineBreak
appendPendingText()
val (openingMarkdown, closingMarkdown) = getMarkdownForTag(tag, atLineStart)
markdownBuilder.append(openingMarkdown)
super.visitXmlTag(tag)
markdownBuilder.append(closingMarkdown)
currentListType = oldListType
}
}
override fun visitXmlText(text: XmlText) {
withWhitespaceAsPartOfText(true) {
super.visitXmlText(text)
}
}
private inline fun withWhitespaceAsPartOfText(newValue: Boolean, block: () -> Unit) {
val oldValue = whitespaceIsPartOfText
whitespaceIsPartOfText = newValue
try {
block()
}
finally {
whitespaceIsPartOfText = oldValue
}
}
private fun getMarkdownForTag(tag: XmlTag, atLineStart: Boolean): MarkdownSpan = when(tag.getName()) {
"b", "strong" -> MarkdownSpan.wrap("**")
"p" -> if (atLineStart) MarkdownSpan.prefix("\n * ") else MarkdownSpan.prefix("\n *\n *")
"i", "em" -> MarkdownSpan.wrap("*")
"s", "del" -> MarkdownSpan.wrap("~~")
"code" -> MarkdownSpan.wrap("`")
"a" -> {
if (tag.getAttributeValue("docref") != null) {
val docRef = tag.getAttributeValue("docref")
val innerText = tag.getValue().getText()
if (docRef == innerText) MarkdownSpan("[", "]") else MarkdownSpan("[", "][$docRef]")
}
else {
MarkdownSpan("[", "](${tag.getAttributeValue("href")})")
}
}
"ul" -> { currentListType = ListType.Unordered; MarkdownSpan.Empty }
"ol" -> { currentListType = ListType.Ordered; MarkdownSpan.Empty }
"li" -> if (currentListType == ListType.Unordered) MarkdownSpan.prefix(" * ") else MarkdownSpan.prefix(" 1. ")
else -> MarkdownSpan.Empty
}
private fun appendPendingText() {
if (afterLineBreak ) {
markdownBuilder.append(" * ")
afterLineBreak = false
}
}
override fun visitXmlFile(file: XmlFile) {
super.visitXmlFile(file)
markdownBuilder.append(" */")
}
}
}
@@ -0,0 +1,28 @@
/*
* 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.j2k
import org.jetbrains.kotlin.j2k.*
object IdeaJavaToKotlinServices: JavaToKotlinConverterServices {
override val referenceSearcher: ReferenceSearcher
get() = IdeaReferenceSearcher
override val resolverForConverter: ResolverForConverter
get() = IdeaResolverForConverter
override val docCommentConverter: DocCommentConverter
get() = IdeaDocCommentConverter
}
@@ -0,0 +1,52 @@
/*
* 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.j2k
import com.intellij.lang.java.JavaLanguage
import com.intellij.openapi.fileTypes.FileType
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiReference
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.LocalSearchScope
import com.intellij.psi.search.searches.ClassInheritorsSearch
import com.intellij.psi.search.searches.OverridingMethodsSearch
import com.intellij.psi.search.searches.ReferencesSearch
import org.jetbrains.kotlin.idea.JetLanguage
import org.jetbrains.kotlin.j2k.ReferenceSearcher
import java.util.*
public object IdeaReferenceSearcher: ReferenceSearcher {
override fun findLocalUsages(element: PsiElement, scope: PsiElement) = ReferencesSearch.search(element, LocalSearchScope(scope)).findAll()
override fun hasInheritors(`class`: PsiClass) = ClassInheritorsSearch.search(`class`, false).any()
override fun hasOverrides(method: PsiMethod) = OverridingMethodsSearch.search(method, false).any()
override fun findUsagesForExternalCodeProcessing(element: PsiElement, searchJava: Boolean, searchKotlin: Boolean): Collection<PsiReference> {
val fileTypes = ArrayList<FileType>()
if (searchJava) {
fileTypes.add(JavaLanguage.INSTANCE.getAssociatedFileType()!!)
}
if (searchKotlin) {
fileTypes.add(JetLanguage.INSTANCE.getAssociatedFileType()!!)
}
val searchScope = GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.projectScope(element.getProject()), *fileTypes.toTypedArray())
return ReferencesSearch.search(element, searchScope).findAll()
}
}
@@ -16,8 +16,6 @@
package org.jetbrains.kotlin.idea.refactoring.introduce.introduceParameter
import com.intellij.lang.java.JavaLanguage
import com.intellij.openapi.util.Ref
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiExpression
import com.intellij.psi.PsiMethod
@@ -25,10 +23,7 @@ import com.intellij.psi.search.GlobalSearchScope
import com.intellij.refactoring.introduceParameter.IntroduceParameterData
import com.intellij.refactoring.introduceParameter.IntroduceParameterMethodUsagesProcessor
import com.intellij.usageView.UsageInfo
import com.intellij.util.ArrayUtil
import com.intellij.util.containers.MultiMap
import gnu.trove.TIntArrayList
import org.jetbrains.kotlin.asJava.KotlinLightMethod
import org.jetbrains.kotlin.asJava.unwrapped
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
@@ -36,24 +31,20 @@ import org.jetbrains.kotlin.idea.JetFileType
import org.jetbrains.kotlin.idea.caches.resolve.getJavaMethodDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
import org.jetbrains.kotlin.idea.core.refactoring.j2k
import org.jetbrains.kotlin.idea.j2k.IdeaResolverForConverter
import org.jetbrains.kotlin.idea.j2k.J2kPostProcessor
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetChangeInfo
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetChangeSignatureData
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetParameterInfo
import org.jetbrains.kotlin.idea.refactoring.changeSignature.originalBaseFunctionDescriptor
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.*
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.JetCallableDefinitionUsage
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.JetConstructorDelegationCallUsage
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.JetFunctionCallUsage
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.JetUsageInfo
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
import org.jetbrains.kotlin.idea.search.declarationsSearch.searchOverriders
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import org.jetbrains.kotlin.j2k.ConverterSettings
import org.jetbrains.kotlin.j2k.IdeaReferenceSearcher
import org.jetbrains.kotlin.j2k.JavaToKotlinConverter
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
import org.jetbrains.kotlin.types.JetType
import java.util.Arrays
import java.util.Collections
import org.jetbrains.kotlin.idea.search.declarationsSearch.searchOverriders
public class KotlinIntroduceParameterMethodUsageProcessor : IntroduceParameterMethodUsagesProcessor {
override fun isMethodUsage(usage: UsageInfo): Boolean = (usage.getElement() as? JetElement)?.let {
@@ -63,12 +63,10 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.getJavaMemberDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
import org.jetbrains.kotlin.idea.core.getPackage
import org.jetbrains.kotlin.idea.j2k.IdeaResolverForConverter
import org.jetbrains.kotlin.idea.j2k.IdeaJavaToKotlinServices
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
import org.jetbrains.kotlin.idea.util.string.collapseSpaces
import org.jetbrains.kotlin.j2k.ConverterSettings
import org.jetbrains.kotlin.j2k.IdeaDocCommentConverter
import org.jetbrains.kotlin.j2k.IdeaReferenceSearcher
import org.jetbrains.kotlin.j2k.JavaToKotlinConverter
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.codeFragmentUtil.suppressDiagnosticsInDebugMode
@@ -77,10 +75,10 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.AnalyzingUtils
import org.jetbrains.kotlin.resolve.BindingContext
import java.io.File
import java.lang.annotation.Retention
import java.util.ArrayList
import java.util.Collections
import javax.swing.Icon
import java.lang.annotation.Retention
fun <T: Any> PsiElement.getAndRemoveCopyableUserData(key: Key<T>): T? {
val data = getCopyableUserData(key)
@@ -572,9 +570,7 @@ fun PsiExpression.j2k(): JetExpression? {
val project = getProject()
val j2kConverter = JavaToKotlinConverter(project,
ConverterSettings.defaultSettings,
IdeaReferenceSearcher,
IdeaResolverForConverter,
IdeaDocCommentConverter)
IdeaJavaToKotlinServices)
val text = j2kConverter.elementsToKotlin(listOf(this)).results.single()?.text ?: return null //TODO: insert imports
return JetPsiFactory(getProject()).createExpression(text)
}