KT-60821 [KAPT] Generate stubs without KaptTreeMaker
Merge-request: KT-MR-12979 Merged-by: Pavel Mikhailovskii <Pavel.Mikhailovskii@jetbrains.com>
This commit is contained in:
committed by
Space Team
parent
0fba58eee7
commit
9c2ce475e2
@@ -29,6 +29,12 @@ import kotlin.collections.List
|
||||
import kotlin.system.measureTimeMillis
|
||||
import com.sun.tools.javac.util.List as JavacList
|
||||
|
||||
fun KaptContext.doAnnotationProcessing(
|
||||
javaSourceFiles: List<File>,
|
||||
processors: List<IncrementalProcessor>,
|
||||
binaryTypesToReprocess: List<String> = emptyList()
|
||||
) = doAnnotationProcessing(javaSourceFiles, processors, JavacList.nil(), binaryTypesToReprocess)
|
||||
|
||||
fun KaptContext.doAnnotationProcessing(
|
||||
javaSourceFiles: List<File>,
|
||||
processors: List<IncrementalProcessor>,
|
||||
|
||||
-152
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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.kapt3.stubs
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiRecursiveElementVisitor
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import com.sun.tools.javac.parser.Tokens
|
||||
import com.sun.tools.javac.tree.DCTree
|
||||
import com.sun.tools.javac.tree.DocCommentTable
|
||||
import com.sun.tools.javac.tree.JCTree
|
||||
import com.sun.tools.javac.tree.TreeScanner
|
||||
import org.jetbrains.kotlin.kapt3.base.KaptContext
|
||||
import org.jetbrains.kotlin.kdoc.lexer.KDocTokens
|
||||
import org.jetbrains.kotlin.kdoc.psi.api.KDoc
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
|
||||
abstract class AbstractKDocCommentKeeper<T: KaptContext>(protected val kaptContext: T) {
|
||||
private val docCommentTable = KaptDocCommentTable()
|
||||
|
||||
fun getDocTable(file: JCTree.JCCompilationUnit): DocCommentTable {
|
||||
val map = docCommentTable.takeIf { it.map.isNotEmpty() } ?: return docCommentTable
|
||||
|
||||
// Enum values with doc comments are rendered incorrectly in javac pretty print,
|
||||
// so we delete the comments.
|
||||
file.accept(object : TreeScanner() {
|
||||
var removeComments = false
|
||||
|
||||
override fun visitVarDef(def: JCTree.JCVariableDecl) {
|
||||
if (!removeComments && (def.modifiers.flags and Opcodes.ACC_ENUM.toLong()) != 0L) {
|
||||
map.removeComment(def)
|
||||
|
||||
removeComments = true
|
||||
super.visitVarDef(def)
|
||||
removeComments = false
|
||||
return
|
||||
}
|
||||
|
||||
super.visitVarDef(def)
|
||||
}
|
||||
|
||||
override fun scan(tree: JCTree?) {
|
||||
if (removeComments && tree != null) {
|
||||
map.removeComment(tree)
|
||||
}
|
||||
|
||||
super.scan(tree)
|
||||
}
|
||||
})
|
||||
|
||||
return docCommentTable
|
||||
}
|
||||
|
||||
protected fun saveKDocComment(tree: JCTree, comment: KDoc) {
|
||||
docCommentTable.putComment(tree, KDocComment(escapeNestedComments(extractCommentText(comment))))
|
||||
}
|
||||
|
||||
private fun escapeNestedComments(text: String): String {
|
||||
val result = StringBuilder()
|
||||
|
||||
var index = 0
|
||||
var commentLevel = 0
|
||||
|
||||
while (index < text.length) {
|
||||
val currentChar = text[index]
|
||||
fun nextChar() = text.getOrNull(index + 1)
|
||||
|
||||
if (currentChar == '/' && nextChar() == '*') {
|
||||
commentLevel++
|
||||
index++
|
||||
result.append("/ *")
|
||||
} else if (currentChar == '*' && nextChar() == '/') {
|
||||
commentLevel = maxOf(0, commentLevel - 1)
|
||||
index++
|
||||
result.append("* /")
|
||||
} else {
|
||||
result.append(currentChar)
|
||||
}
|
||||
|
||||
index++
|
||||
}
|
||||
|
||||
return result.toString()
|
||||
}
|
||||
|
||||
private fun extractCommentText(docComment: KDoc): String {
|
||||
return buildString {
|
||||
docComment.accept(object : PsiRecursiveElementVisitor() {
|
||||
override fun visitElement(element: PsiElement) {
|
||||
if (element is LeafPsiElement) {
|
||||
if (element.isKDocLeadingAsterisk()) {
|
||||
val indent = takeLastWhile { it == ' ' || it == '\t' }.length
|
||||
if (indent > 0) {
|
||||
delete(length - indent, length)
|
||||
}
|
||||
} else if (!element.isKDocStart() && !element.isKDocEnd()) {
|
||||
append(element.text)
|
||||
}
|
||||
}
|
||||
|
||||
super.visitElement(element)
|
||||
}
|
||||
})
|
||||
}.trimIndent().trim()
|
||||
}
|
||||
|
||||
private fun LeafPsiElement.isKDocStart() = elementType == KDocTokens.START
|
||||
private fun LeafPsiElement.isKDocEnd() = elementType == KDocTokens.END
|
||||
private fun LeafPsiElement.isKDocLeadingAsterisk() = elementType == KDocTokens.LEADING_ASTERISK
|
||||
}
|
||||
|
||||
private class KDocComment(val body: String) : Tokens.Comment {
|
||||
override fun getSourcePos(index: Int) = -1
|
||||
override fun getStyle() = Tokens.Comment.CommentStyle.JAVADOC
|
||||
override fun getText() = body
|
||||
override fun isDeprecated() = false
|
||||
}
|
||||
|
||||
private class KaptDocCommentTable(map: Map<JCTree, Tokens.Comment> = emptyMap()) : DocCommentTable {
|
||||
private val table = map.toMutableMap()
|
||||
|
||||
val map: Map<JCTree, Tokens.Comment>
|
||||
get() = table
|
||||
|
||||
override fun hasComment(tree: JCTree) = tree in table
|
||||
override fun getComment(tree: JCTree) = table[tree]
|
||||
override fun getCommentText(tree: JCTree) = getComment(tree)?.text
|
||||
|
||||
override fun getCommentTree(tree: JCTree): DCTree.DCDocComment? = null
|
||||
|
||||
override fun putComment(tree: JCTree, c: Tokens.Comment) {
|
||||
table[tree] = c
|
||||
}
|
||||
|
||||
fun removeComment(tree: JCTree) {
|
||||
table.remove(tree)
|
||||
}
|
||||
}
|
||||
+135
-2
@@ -5,19 +5,31 @@
|
||||
|
||||
package org.jetbrains.kotlin.kapt3.stubs
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiRecursiveElementVisitor
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import com.sun.tools.javac.parser.Tokens
|
||||
import com.sun.tools.javac.tree.DCTree
|
||||
import com.sun.tools.javac.tree.DocCommentTable
|
||||
import com.sun.tools.javac.tree.JCTree
|
||||
import com.sun.tools.javac.tree.TreeScanner
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
||||
import org.jetbrains.kotlin.kapt3.KaptContextForStubGeneration
|
||||
import org.jetbrains.kotlin.kdoc.lexer.KDocTokens
|
||||
import org.jetbrains.kotlin.kdoc.psi.api.KDoc
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.tree.FieldNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
|
||||
class Kapt3DocCommentKeeper(kaptContext: KaptContextForStubGeneration) : AbstractKDocCommentKeeper<KaptContextForStubGeneration>(kaptContext) {
|
||||
internal class Kapt3DocCommentKeeper(private val kaptContext: KaptContextForStubGeneration) {
|
||||
private val docCommentTable = KaptDocCommentTable()
|
||||
|
||||
fun saveKDocComment(tree: JCTree, node: Any) {
|
||||
val origin = kaptContext.origins[node] ?: return
|
||||
val psiElement = origin.element as? KtDeclaration ?: return
|
||||
@@ -45,4 +57,125 @@ class Kapt3DocCommentKeeper(kaptContext: KaptContextForStubGeneration) : Abstrac
|
||||
|
||||
saveKDocComment(tree, docComment)
|
||||
}
|
||||
}
|
||||
|
||||
fun getDocTable(file: JCTree.JCCompilationUnit): DocCommentTable {
|
||||
val map = docCommentTable.takeIf { it.map.isNotEmpty() } ?: return docCommentTable
|
||||
|
||||
// Enum values with doc comments are rendered incorrectly in javac pretty print,
|
||||
// so we delete the comments.
|
||||
file.accept(object : TreeScanner() {
|
||||
var removeComments = false
|
||||
|
||||
override fun visitVarDef(def: JCTree.JCVariableDecl) {
|
||||
if (!removeComments && (def.modifiers.flags and Opcodes.ACC_ENUM.toLong()) != 0L) {
|
||||
map.removeComment(def)
|
||||
|
||||
removeComments = true
|
||||
super.visitVarDef(def)
|
||||
removeComments = false
|
||||
return
|
||||
}
|
||||
|
||||
super.visitVarDef(def)
|
||||
}
|
||||
|
||||
override fun scan(tree: JCTree?) {
|
||||
if (removeComments && tree != null) {
|
||||
map.removeComment(tree)
|
||||
}
|
||||
|
||||
super.scan(tree)
|
||||
}
|
||||
})
|
||||
|
||||
return docCommentTable
|
||||
}
|
||||
|
||||
protected fun saveKDocComment(tree: JCTree, comment: KDoc) {
|
||||
docCommentTable.putComment(tree, KDocComment(extractComment(comment)))
|
||||
}
|
||||
}
|
||||
|
||||
private class KDocComment(val body: String) : Tokens.Comment {
|
||||
override fun getSourcePos(index: Int) = -1
|
||||
override fun getStyle() = Tokens.Comment.CommentStyle.JAVADOC
|
||||
override fun getText() = body
|
||||
override fun isDeprecated() = false
|
||||
}
|
||||
|
||||
private class KaptDocCommentTable(map: Map<JCTree, Tokens.Comment> = emptyMap()) : DocCommentTable {
|
||||
private val table = map.toMutableMap()
|
||||
|
||||
val map: Map<JCTree, Tokens.Comment>
|
||||
get() = table
|
||||
|
||||
override fun hasComment(tree: JCTree) = tree in table
|
||||
override fun getComment(tree: JCTree) = table[tree]
|
||||
override fun getCommentText(tree: JCTree) = getComment(tree)?.text
|
||||
|
||||
override fun getCommentTree(tree: JCTree): DCTree.DCDocComment? = null
|
||||
|
||||
override fun putComment(tree: JCTree, c: Tokens.Comment) {
|
||||
table[tree] = c
|
||||
}
|
||||
|
||||
fun removeComment(tree: JCTree) {
|
||||
table.remove(tree)
|
||||
}
|
||||
}
|
||||
|
||||
fun extractComment(comment: KDoc) = escapeNestedComments(extractCommentText(comment))
|
||||
|
||||
|
||||
private fun escapeNestedComments(text: String): String {
|
||||
val result = StringBuilder()
|
||||
|
||||
var index = 0
|
||||
var commentLevel = 0
|
||||
|
||||
while (index < text.length) {
|
||||
val currentChar = text[index]
|
||||
fun nextChar() = text.getOrNull(index + 1)
|
||||
|
||||
if (currentChar == '/' && nextChar() == '*') {
|
||||
commentLevel++
|
||||
index++
|
||||
result.append("/ *")
|
||||
} else if (currentChar == '*' && nextChar() == '/') {
|
||||
commentLevel = maxOf(0, commentLevel - 1)
|
||||
index++
|
||||
result.append("* /")
|
||||
} else {
|
||||
result.append(currentChar)
|
||||
}
|
||||
|
||||
index++
|
||||
}
|
||||
|
||||
return result.toString()
|
||||
}
|
||||
|
||||
private fun extractCommentText(docComment: KDoc): String {
|
||||
return buildString {
|
||||
docComment.accept(object : PsiRecursiveElementVisitor() {
|
||||
override fun visitElement(element: PsiElement) {
|
||||
if (element is LeafPsiElement) {
|
||||
if (element.isKDocLeadingAsterisk()) {
|
||||
val indent = takeLastWhile { it == ' ' || it == '\t' }.length
|
||||
if (indent > 0) {
|
||||
delete(length - indent, length)
|
||||
}
|
||||
} else if (!element.isKDocStart() && !element.isKDocEnd()) {
|
||||
append(element.text)
|
||||
}
|
||||
}
|
||||
|
||||
super.visitElement(element)
|
||||
}
|
||||
})
|
||||
}.trimIndent().trim()
|
||||
}
|
||||
|
||||
private fun LeafPsiElement.isKDocStart() = elementType == KDocTokens.START
|
||||
private fun LeafPsiElement.isKDocEnd() = elementType == KDocTokens.END
|
||||
private fun LeafPsiElement.isKDocLeadingAsterisk() = elementType == KDocTokens.LEADING_ASTERISK
|
||||
+4
-5
@@ -5,7 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.kapt3.stubs
|
||||
|
||||
import com.sun.tools.javac.tree.JCTree
|
||||
import org.jetbrains.kotlin.kapt3.base.stubs.KotlinPosition
|
||||
|
||||
/**
|
||||
@@ -20,9 +19,9 @@ import org.jetbrains.kotlin.kapt3.base.stubs.KotlinPosition
|
||||
* The consequence is that the contents of the generated stub files may not be consistent across a clean build and an incremental
|
||||
* build, making the build non-deterministic and dependent tasks run unnecessarily (see KT-40882).
|
||||
*/
|
||||
class MembersPositionComparator(val classSource: KotlinPosition?, val memberData: Map<JCTree, MemberData>) :
|
||||
Comparator<JCTree> {
|
||||
override fun compare(o1: JCTree, o2: JCTree): Int {
|
||||
class MembersPositionComparator<T>(val classSource: KotlinPosition?, val memberData: Map<T, MemberData>) :
|
||||
Comparator<T> {
|
||||
override fun compare(o1: T, o2: T): Int {
|
||||
val data1 = memberData.getValue(o1)
|
||||
val data2 = memberData.getValue(o2)
|
||||
classSource ?: return compareDescriptors(data1, data2)
|
||||
@@ -51,4 +50,4 @@ class MembersPositionComparator(val classSource: KotlinPosition?, val memberData
|
||||
return m1.descriptor.compareTo(m2.descriptor)
|
||||
}
|
||||
}
|
||||
class MemberData(val name: String, val descriptor: String, val position: KotlinPosition?)
|
||||
class MemberData(val name: String, val descriptor: String, val position: KotlinPosition?)
|
||||
|
||||
@@ -44,6 +44,7 @@ class Test4 {
|
||||
}
|
||||
|
||||
enum class EnumError {
|
||||
/** This is the one */
|
||||
One {
|
||||
override fun doIt() = ""
|
||||
|
||||
|
||||
+2
-2
@@ -135,10 +135,10 @@ public enum Em {
|
||||
@kotlin.Metadata()
|
||||
public final class Foo {
|
||||
private final boolean z = true;
|
||||
private final byte b = (byte)0;
|
||||
private final byte b = 0;
|
||||
private final char c = 'c';
|
||||
private final char c2 = '\n';
|
||||
private final short sh = (short)10;
|
||||
private final short sh = 10;
|
||||
private final int i = 10;
|
||||
private final long l = -10L;
|
||||
private final float f = 1.0F;
|
||||
|
||||
@@ -79,7 +79,7 @@ public final class JvmStaticTest {
|
||||
private static final int one = 1;
|
||||
public static final int two = 2;
|
||||
public static final char c = 'C';
|
||||
public final byte three = (byte)3;
|
||||
public final byte three = 3;
|
||||
public final char d = 'D';
|
||||
|
||||
public JvmStaticTest() {
|
||||
|
||||
@@ -150,9 +150,9 @@ public final class PrimitiveTypes {
|
||||
public static final int intMinValue = -2147483648;
|
||||
public static final int intMaxValue = 2147483647;
|
||||
public static final int intHex = -1;
|
||||
public static final byte byte0 = (byte)0;
|
||||
public static final byte byte50 = (byte)50;
|
||||
public static final short short5 = (short)5;
|
||||
public static final byte byte0 = 0;
|
||||
public static final byte byte50 = 50;
|
||||
public static final short short5 = 5;
|
||||
public static final char charC = 'C';
|
||||
public static final char char0 = '\u0000';
|
||||
public static final char char10 = '\n';
|
||||
|
||||
Reference in New Issue
Block a user