Kapt3: As javac now reads stubs from Java files, not from AST, we should provide the valid names for all identifiers (at least names should not clash with Java keywords).
Rename identifiers if it clashes with Java keywords. (KT-15838)
This commit is contained in:
+18
-4
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.kapt3.stubs
|
||||
import com.sun.tools.javac.code.Flags
|
||||
import com.sun.tools.javac.code.TypeTag
|
||||
import com.sun.tools.javac.file.JavacFileManager
|
||||
import com.sun.tools.javac.parser.Tokens
|
||||
import com.sun.tools.javac.tree.JCTree
|
||||
import com.sun.tools.javac.tree.JCTree.*
|
||||
import com.sun.tools.javac.tree.TreeMaker
|
||||
@@ -27,6 +28,7 @@ import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.kapt3.*
|
||||
import org.jetbrains.kotlin.kapt3.javac.KaptTreeMaker
|
||||
import org.jetbrains.kotlin.kapt3.javac.KaptJavaFileObject
|
||||
import org.jetbrains.kotlin.kapt3.stubs.Kapt3StubUtils.*
|
||||
import org.jetbrains.kotlin.kapt3.util.*
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
@@ -69,6 +71,12 @@ class ClassFileToSourceStubConverter(
|
||||
"org.jetbrains.annotations.", // Nullable/NotNull, ReadOnly, Mutable
|
||||
"kotlin.jvm.", "kotlin.Metadata" // Kotlin annotations from runtime
|
||||
)
|
||||
|
||||
private val JAVA_KEYWORD_FILTER_REGEX = "[a-z]+".toRegex()
|
||||
|
||||
private val JAVA_KEYWORDS = Tokens.TokenKind.values()
|
||||
.filter { JAVA_KEYWORD_FILTER_REGEX.matches(getTokenName(it)) }
|
||||
.mapTo(hashSetOf(), ::getTokenName)
|
||||
}
|
||||
|
||||
private val _bindings = mutableMapOf<String, KaptJavaFileObject>()
|
||||
@@ -210,7 +218,7 @@ class ClassFileToSourceStubConverter(
|
||||
|
||||
return treeMaker.ClassDef(
|
||||
modifiers,
|
||||
treeMaker.name(simpleName),
|
||||
treeMaker.name(getNonKeywordName(simpleName)),
|
||||
genericType.typeParameters,
|
||||
if (hasSuperClass) genericType.superClass else null,
|
||||
genericType.interfaces,
|
||||
@@ -222,7 +230,7 @@ class ClassFileToSourceStubConverter(
|
||||
val descriptor = kaptContext.origins[field]?.descriptor
|
||||
|
||||
val modifiers = convertModifiers(field.access, ElementKind.FIELD, packageFqName, field.visibleAnnotations, field.invisibleAnnotations)
|
||||
val name = treeMaker.name(field.name)
|
||||
val name = treeMaker.name(getNonKeywordName(field.name))
|
||||
val type = Type.getType(field.desc)
|
||||
|
||||
// Enum type must be an identifier (Javac requirement)
|
||||
@@ -260,7 +268,7 @@ class ClassFileToSourceStubConverter(
|
||||
}
|
||||
|
||||
val isConstructor = method.name == "<init>"
|
||||
val name = treeMaker.name(method.name)
|
||||
val name = treeMaker.name(getNonKeywordName(method.name))
|
||||
|
||||
val modifiers = convertModifiers(
|
||||
if (containingClass.isEnum() && isConstructor)
|
||||
@@ -286,7 +294,7 @@ class ClassFileToSourceStubConverter(
|
||||
info.visibleAnnotations,
|
||||
info.invisibleAnnotations)
|
||||
|
||||
val name = treeMaker.name(info.name)
|
||||
val name = treeMaker.name(getNonKeywordName(info.name))
|
||||
val type = treeMaker.Type(info.type)
|
||||
treeMaker.VarDef(modifiers, name, type, null)
|
||||
}
|
||||
@@ -394,6 +402,12 @@ class ClassFileToSourceStubConverter(
|
||||
return ifNonError()
|
||||
}
|
||||
|
||||
private fun getNonKeywordName(name: String): String {
|
||||
// In theory, this could lead to member/parameter name clashes, though it's supposed to be extremely rare.
|
||||
if (name in JAVA_KEYWORDS) return '_' + name + '_'
|
||||
return name
|
||||
}
|
||||
|
||||
private inline fun <T : JCExpression?> getNotAnonymousType(descriptor: DeclarationDescriptor?, f: () -> T): T {
|
||||
if (descriptor is CallableDescriptor) {
|
||||
val returnTypeDescriptor = descriptor.returnType?.constructor?.declarationDescriptor
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.sun.tools.javac.parser.Tokens;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class Kapt3StubUtils {
|
||||
@NotNull
|
||||
public static String getTokenName(@NotNull Tokens.TokenKind kind) {
|
||||
// This is a work-around. `name` can't be called from Kotlin, as it clashes with the `name` enum property.
|
||||
String name = kind.name;
|
||||
return (name == null) ? "" : name;
|
||||
}
|
||||
}
|
||||
+6
@@ -108,6 +108,12 @@ public class ClassFileToSourceStubConverterTestGenerated extends AbstractClassFi
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("javaKeywords.kt")
|
||||
public void testJavaKeywords() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/javaKeywords.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("jvmOverloads.kt")
|
||||
public void testJvmOverloads() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/jvmOverloads.kt");
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
class default {
|
||||
lateinit val extends: String
|
||||
fun implements(instanceof: Int) {}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
public final class _default_ {
|
||||
public java.lang.String _extends_;
|
||||
|
||||
public final java.lang.String getExtends() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public final void _implements_(int _instanceof_) {
|
||||
}
|
||||
|
||||
public _default_() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -3,7 +3,7 @@ public final class Outer {
|
||||
public final void nonAbstract(java.lang.String s, int i) {
|
||||
}
|
||||
|
||||
public abstract void abstract(java.lang.String p0, int p1);
|
||||
public abstract void _abstract_(java.lang.String p0, int p1);
|
||||
|
||||
public Outer() {
|
||||
super();
|
||||
|
||||
Reference in New Issue
Block a user