Corrections on code review
This commit is contained in:
@@ -33,10 +33,10 @@ class AnnotationConverter(private val converter: Converter) {
|
|||||||
|
|
||||||
private fun convertAnnotationsOnly(owner: PsiModifierListOwner): Annotations {
|
private fun convertAnnotationsOnly(owner: PsiModifierListOwner): Annotations {
|
||||||
val modifierList = owner.getModifierList()
|
val modifierList = owner.getModifierList()
|
||||||
val annotations = modifierList?.getAnnotations()?.filter { it.getQualifiedName() !in annotationsToRemove }.orEmpty()
|
val annotations = modifierList?.getAnnotations()?.filter { it.getQualifiedName() !in annotationsToRemove }
|
||||||
|
|
||||||
val newLines = run {
|
var convertedAnnotations: List<Annotation> = if (annotations != null && annotations.isNotEmpty()) {
|
||||||
if (!modifierList!!.isInSingleLine()) {
|
val newLines = if (!modifierList!!.isInSingleLine()) {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -47,30 +47,31 @@ class AnnotationConverter(private val converter: Converter) {
|
|||||||
}
|
}
|
||||||
if (child is PsiWhiteSpace) !child!!.isInSingleLine() else false
|
if (child is PsiWhiteSpace) !child!!.isInSingleLine() else false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
annotations.map { convertAnnotation(it, owner is PsiLocalVariable, newLines) }.filterNotNull() //TODO: brackets are also needed for local classes
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
listOf()
|
||||||
}
|
}
|
||||||
|
|
||||||
var list = annotations.map { convertAnnotation(it, owner is PsiLocalVariable, newLines) }.filterNotNull() //TODO: brackets are also needed for local classes
|
|
||||||
if (owner is PsiDocCommentOwner) {
|
if (owner is PsiDocCommentOwner) {
|
||||||
val deprecatedAnnotation = convertDeprecatedJavadocTag(owner)
|
val deprecatedAnnotation = convertDeprecatedJavadocTag(owner)
|
||||||
if (deprecatedAnnotation != null) {
|
if (deprecatedAnnotation != null) {
|
||||||
list += deprecatedAnnotation
|
convertedAnnotations += deprecatedAnnotation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (list.isEmpty()) Annotations.Empty else Annotations(list).assignNoPrototype()
|
return Annotations(convertedAnnotations).assignNoPrototype()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun convertDeprecatedJavadocTag(element: PsiDocCommentOwner): Annotation? {
|
private fun convertDeprecatedJavadocTag(element: PsiDocCommentOwner): Annotation? {
|
||||||
val deprecatedTag = element.getDocComment()?.findTagByName("deprecated")
|
val deprecatedTag = element.getDocComment()?.findTagByName("deprecated") ?: return null
|
||||||
if (deprecatedTag != null) {
|
val deferredExpression = converter.deferredElement<Expression> {
|
||||||
val deferredExpression = converter.deferredElement<Expression> {
|
LiteralExpression("\"" + StringUtil.escapeStringCharacters(deprecatedTag.content()) + "\"").assignNoPrototype()
|
||||||
LiteralExpression("\"${StringUtil.escapeStringCharacters(deprecatedTag.content())}\"").assignNoPrototype()
|
|
||||||
}
|
|
||||||
return Annotation(Identifier("deprecated").assignPrototype(deprecatedTag.getNameElement()),
|
|
||||||
listOf(null to deferredExpression), false, true)
|
|
||||||
.assignPrototype(deprecatedTag)
|
|
||||||
}
|
}
|
||||||
return null
|
return Annotation(Identifier("deprecated").assignPrototype(deprecatedTag.getNameElement()),
|
||||||
|
listOf(null to deferredExpression), false, true)
|
||||||
|
.assignPrototype(deprecatedTag)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun convertModifiersToAnnotations(owner: PsiModifierListOwner): Annotations {
|
private fun convertModifiersToAnnotations(owner: PsiModifierListOwner): Annotations {
|
||||||
|
|||||||
@@ -61,7 +61,8 @@ class CodeBuilder(private val topElement: PsiElement?) {
|
|||||||
private fun appendCommentOrWhiteSpace(element: PsiElement) {
|
private fun appendCommentOrWhiteSpace(element: PsiElement) {
|
||||||
if (element is PsiDocComment) {
|
if (element is PsiDocComment) {
|
||||||
append(DocCommentConverter.convertDocComment(element), false)
|
append(DocCommentConverter.convertDocComment(element), false)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
append(element.getText()!!, element.isEndOfLineComment())
|
append(element.getText()!!, element.isEndOfLineComment())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,45 +31,49 @@ import java.util.Stack
|
|||||||
|
|
||||||
object DocCommentConverter {
|
object DocCommentConverter {
|
||||||
fun convertDocComment(docComment: PsiDocComment): String {
|
fun convertDocComment(docComment: PsiDocComment): String {
|
||||||
val htmlTextBuilder = StringBuilder()
|
val html = StringBuilder {
|
||||||
htmlTextBuilder.appendJavadocElements(docComment.getDescriptionElements())
|
appendJavadocElements(docComment.getDescriptionElements())
|
||||||
docComment.getTags().filter { it.getName() != "deprecated" }.forEach {
|
|
||||||
if (it.getName() == "see") {
|
for (tag in docComment.getTags()) {
|
||||||
htmlTextBuilder.append("@see ${convertJavadocLink(it.content())}\n")
|
when (tag.getName()) {
|
||||||
} else {
|
"deprecated" -> continue
|
||||||
htmlTextBuilder.appendJavadocElements(it.getChildren()).append("\n")
|
"see" -> append("@see ${convertJavadocLink(tag.content())}\n")
|
||||||
|
else -> appendJavadocElements(tag.getChildren()).append("\n")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}.toString()
|
||||||
val html = htmlTextBuilder.toString()
|
|
||||||
if (html.trim().isEmpty() && docComment.findTagByName("deprecated") != null) {
|
if (html.trim().isEmpty() && docComment.findTagByName("deprecated") != null) {
|
||||||
// @deprecated was the only content of the doc comment; we can drop the comment
|
// @deprecated was the only content of the doc comment; we can drop the comment
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
val htmlFile = PsiFileFactory.getInstance(docComment.getProject()).createFileFromText(
|
val htmlFile = PsiFileFactory.getInstance(docComment.getProject()).createFileFromText(
|
||||||
"javadoc.html", HtmlFileType.INSTANCE, html)
|
"javadoc.html", HtmlFileType.INSTANCE, html)
|
||||||
val htmlToMarkdownConverter = HtmlToMarkdownConverter()
|
val htmlToMarkdownConverter = HtmlToMarkdownConverter()
|
||||||
htmlFile.accept(htmlToMarkdownConverter)
|
htmlFile.accept(htmlToMarkdownConverter)
|
||||||
return htmlToMarkdownConverter.markdownBuilder.toString()
|
return htmlToMarkdownConverter.result
|
||||||
}
|
}
|
||||||
|
|
||||||
fun StringBuilder.appendJavadocElements(elements: Array<PsiElement>): StringBuilder {
|
private fun StringBuilder.appendJavadocElements(elements: Array<PsiElement>): StringBuilder {
|
||||||
elements.forEach {
|
elements.forEach {
|
||||||
if (it is PsiInlineDocTag) {
|
if (it is PsiInlineDocTag) {
|
||||||
append(convertInlineDocTag(it))
|
append(convertInlineDocTag(it))
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
append(it.getText())
|
append(it.getText())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
fun convertInlineDocTag(tag: PsiInlineDocTag) = when(tag.getName()) {
|
private fun convertInlineDocTag(tag: PsiInlineDocTag) = when(tag.getName()) {
|
||||||
"code", "literal" -> {
|
"code", "literal" -> {
|
||||||
val text = StringBuilder()
|
val text = tag.getDataElements().map { it.getText() }.join()
|
||||||
tag.getDataElements().forEach { text.append(it.getText()) }
|
val escaped = StringUtil.escapeXml(text.trimLeading())
|
||||||
val escaped = StringUtil.escapeXml(text.toString().trimLeading())
|
|
||||||
if (tag.getName() == "code") "<code>$escaped</code>" else escaped
|
if (tag.getName() == "code") "<code>$escaped</code>" else escaped
|
||||||
}
|
}
|
||||||
|
|
||||||
"link", "linkplain" -> {
|
"link", "linkplain" -> {
|
||||||
val valueElement = tag.linkElement()
|
val valueElement = tag.linkElement()
|
||||||
val labelText = tag.getDataElements().firstOrNull { it is PsiDocToken }?.getText() ?: ""
|
val labelText = tag.getDataElements().firstOrNull { it is PsiDocToken }?.getText() ?: ""
|
||||||
@@ -77,25 +81,30 @@ object DocCommentConverter {
|
|||||||
val linkText = if (labelText.isEmpty()) kdocLink else StringUtil.escapeXml(labelText)
|
val linkText = if (labelText.isEmpty()) kdocLink else StringUtil.escapeXml(labelText)
|
||||||
"<a docref=\"$kdocLink\">$linkText</a>"
|
"<a docref=\"$kdocLink\">$linkText</a>"
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> tag.getText()
|
else -> tag.getText()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun convertJavadocLink(link: String?): String =
|
private fun convertJavadocLink(link: String?): String =
|
||||||
if (link != null) link.substringBefore('(').replace('#', '.') else ""
|
if (link != null) link.substringBefore('(').replace('#', '.') else ""
|
||||||
|
|
||||||
private fun PsiDocTag.linkElement(): PsiElement? =
|
private fun PsiDocTag.linkElement(): PsiElement? =
|
||||||
getValueElement() ?: getDataElements().firstOrNull { it !is PsiWhiteSpace }
|
getValueElement() ?: getDataElements().firstOrNull { it !is PsiWhiteSpace }
|
||||||
|
|
||||||
class HtmlToMarkdownConverter() : XmlRecursiveElementVisitor() {
|
private class HtmlToMarkdownConverter() : XmlRecursiveElementVisitor() {
|
||||||
enum class ListType { Ordered; Unordered }
|
private enum class ListType { Ordered; Unordered }
|
||||||
|
|
||||||
val markdownBuilder = StringBuilder("/**")
|
val result: String
|
||||||
var afterLineBreak: Boolean = false
|
get() = markdownBuilder.toString()
|
||||||
var whitespaceIsPartOfText: Boolean = true
|
|
||||||
var currentListType = ListType.Unordered
|
private val markdownBuilder = StringBuilder("/**")
|
||||||
|
private var afterLineBreak = false
|
||||||
|
private var whitespaceIsPartOfText = true
|
||||||
|
private var currentListType = ListType.Unordered
|
||||||
|
|
||||||
override fun visitWhiteSpace(space: PsiWhiteSpace) {
|
override fun visitWhiteSpace(space: PsiWhiteSpace) {
|
||||||
super.visitWhiteSpace(space)
|
super.visitWhiteSpace(space)
|
||||||
|
|
||||||
if (whitespaceIsPartOfText) {
|
if (whitespaceIsPartOfText) {
|
||||||
appendPendingText()
|
appendPendingText()
|
||||||
markdownBuilder.append(space.getText())
|
markdownBuilder.append(space.getText())
|
||||||
@@ -107,6 +116,7 @@ object DocCommentConverter {
|
|||||||
|
|
||||||
override fun visitElement(element: PsiElement) {
|
override fun visitElement(element: PsiElement) {
|
||||||
super.visitElement(element)
|
super.visitElement(element)
|
||||||
|
|
||||||
val tokenType = element.getNode().getElementType()
|
val tokenType = element.getNode().getElementType()
|
||||||
if (tokenType == XmlTokenType.XML_DATA_CHARACTERS || tokenType == XmlTokenType.XML_CHAR_ENTITY_REF) {
|
if (tokenType == XmlTokenType.XML_DATA_CHARACTERS || tokenType == XmlTokenType.XML_CHAR_ENTITY_REF) {
|
||||||
appendPendingText()
|
appendPendingText()
|
||||||
@@ -121,13 +131,15 @@ object DocCommentConverter {
|
|||||||
appendPendingText()
|
appendPendingText()
|
||||||
val (openingMarkdown, closingMarkdown) = getMarkdownForTag(tag, atLineStart)
|
val (openingMarkdown, closingMarkdown) = getMarkdownForTag(tag, atLineStart)
|
||||||
markdownBuilder.append(openingMarkdown)
|
markdownBuilder.append(openingMarkdown)
|
||||||
|
|
||||||
super.visitXmlTag(tag)
|
super.visitXmlTag(tag)
|
||||||
|
|
||||||
markdownBuilder.append(closingMarkdown)
|
markdownBuilder.append(closingMarkdown)
|
||||||
currentListType = oldListType
|
currentListType = oldListType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitXmlText(text: XmlText?) {
|
override fun visitXmlText(text: XmlText) {
|
||||||
withWhitespaceAsPartOfText(true) {
|
withWhitespaceAsPartOfText(true) {
|
||||||
super.visitXmlText(text)
|
super.visitXmlText(text)
|
||||||
}
|
}
|
||||||
@@ -138,27 +150,40 @@ object DocCommentConverter {
|
|||||||
whitespaceIsPartOfText = newValue
|
whitespaceIsPartOfText = newValue
|
||||||
try {
|
try {
|
||||||
block()
|
block()
|
||||||
} finally {
|
}
|
||||||
|
finally {
|
||||||
whitespaceIsPartOfText = oldValue
|
whitespaceIsPartOfText = oldValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getMarkdownForTag(tag: XmlTag, atLineStart: Boolean): Pair<String, String> = when(tag.getName()) {
|
private fun getMarkdownForTag(tag: XmlTag, atLineStart: Boolean): Pair<String, String> = when(tag.getName()) {
|
||||||
"b", "strong" -> "**" to "**"
|
"b", "strong" -> "**" to "**"
|
||||||
|
|
||||||
"p" -> if (atLineStart) "\n * " to "" else "\n *\n *" to ""
|
"p" -> if (atLineStart) "\n * " to "" else "\n *\n *" to ""
|
||||||
|
|
||||||
"i", "em" -> "*" to "*"
|
"i", "em" -> "*" to "*"
|
||||||
|
|
||||||
"s", "del" -> "~~" to "~~"
|
"s", "del" -> "~~" to "~~"
|
||||||
|
|
||||||
"code" -> "`" to "`"
|
"code" -> "`" to "`"
|
||||||
"a" -> if (tag.getAttributeValue("docref") != null) {
|
|
||||||
val docRef = tag.getAttributeValue("docref")
|
"a" -> {
|
||||||
val innerText = tag.getValue().getText()
|
if (tag.getAttributeValue("docref") != null) {
|
||||||
if (docRef == innerText) "[" to "]" else "[" to "][$docRef]"
|
val docRef = tag.getAttributeValue("docref")
|
||||||
} else {
|
val innerText = tag.getValue().getText()
|
||||||
"[" to "](${tag.getAttributeValue("href")})"
|
if (docRef == innerText) "[" to "]" else "[" to "][$docRef]"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
"[" to "](${tag.getAttributeValue("href")})"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"ul" -> { currentListType = ListType.Unordered; "" to "" }
|
"ul" -> { currentListType = ListType.Unordered; "" to "" }
|
||||||
|
|
||||||
"ol" -> { currentListType = ListType.Ordered; "" to "" }
|
"ol" -> { currentListType = ListType.Ordered; "" to "" }
|
||||||
|
|
||||||
"li" -> if (currentListType == ListType.Unordered) " * " to "" else " 1. " to ""
|
"li" -> if (currentListType == ListType.Unordered) " * " to "" else " 1. " to ""
|
||||||
|
|
||||||
else -> "" to ""
|
else -> "" to ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,8 +194,9 @@ object DocCommentConverter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitXmlFile(file: XmlFile?) {
|
override fun visitXmlFile(file: XmlFile) {
|
||||||
super.visitXmlFile(file)
|
super.visitXmlFile(file)
|
||||||
|
|
||||||
markdownBuilder.append(" */")
|
markdownBuilder.append(" */")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user