Changed naming algorithm of accessor name generation: "isXXX" and "kClass" cases affected

This commit is contained in:
Valentin Kipyatkov
2015-09-23 21:29:07 +03:00
parent 98da621ab3
commit 420c6856be
13 changed files with 101 additions and 43 deletions
@@ -2758,7 +2758,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
JetType type = bindingContext.getType(expression); JetType type = bindingContext.getType(expression);
assert type != null; assert type != null;
assert state.getReflectionTypes().getkClass().getTypeConstructor().equals(type.getConstructor()) assert state.getReflectionTypes().getTEMP_kClass().getTypeConstructor().equals(type.getConstructor())
: "::class expression should be type checked to a KClass: " + type; : "::class expression should be type checked to a KClass: " + type;
return generateClassLiteralReference(typeMapper, KotlinPackage.single(type.getArguments()).getType()); return generateClassLiteralReference(typeMapper, KotlinPackage.single(type.getArguments()).getType());
@@ -336,7 +336,7 @@ public class JetFlowInformationProvider {
} }
if (!(instruction instanceof WriteValueInstruction)) return; if (!(instruction instanceof WriteValueInstruction)) return;
WriteValueInstruction writeValueInstruction = (WriteValueInstruction) instruction; WriteValueInstruction writeValueInstruction = (WriteValueInstruction) instruction;
JetElement element = writeValueInstruction.getlValue(); JetElement element = writeValueInstruction.getTEMP_lValue();
boolean error = checkBackingField(ctxt, element); boolean error = checkBackingField(ctxt, element);
if (!(element instanceof JetExpression)) return; if (!(element instanceof JetExpression)) return;
if (!error) { if (!error) {
@@ -89,7 +89,7 @@ public class PseudocodeUtil {
element = ((ReadValueInstruction) instruction).getElement(); element = ((ReadValueInstruction) instruction).getElement();
} }
else if (instruction instanceof WriteValueInstruction) { else if (instruction instanceof WriteValueInstruction) {
element = ((WriteValueInstruction) instruction).getlValue(); element = ((WriteValueInstruction) instruction).getTEMP_lValue();
} }
else if (instruction instanceof VariableDeclarationInstruction) { else if (instruction instanceof VariableDeclarationInstruction) {
element = ((VariableDeclarationInstruction) instruction).getVariableDeclarationElement(); element = ((VariableDeclarationInstruction) instruction).getVariableDeclarationElement();
@@ -16,18 +16,14 @@
package org.jetbrains.kotlin.cfg.pseudocode.instructions.eval package org.jetbrains.kotlin.cfg.pseudocode.instructions.eval
import org.jetbrains.kotlin.psi.JetElement
import org.jetbrains.kotlin.cfg.pseudocode.PseudoValue import org.jetbrains.kotlin.cfg.pseudocode.PseudoValue
import org.jetbrains.kotlin.cfg.pseudocode.instructions.LexicalScope
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionWithNext
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.cfg.pseudocode.PseudoValueFactory import org.jetbrains.kotlin.cfg.pseudocode.PseudoValueFactory
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor import org.jetbrains.kotlin.cfg.pseudocode.instructions.*
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionImpl import org.jetbrains.kotlin.psi.JetElement
import org.jetbrains.kotlin.psi.JetNamedDeclaration import org.jetbrains.kotlin.psi.JetNamedDeclaration
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
public sealed class AccessTarget { public sealed class AccessTarget {
public data class Declaration(val descriptor: VariableDescriptor): AccessTarget() public data class Declaration(val descriptor: VariableDescriptor): AccessTarget()
@@ -95,7 +91,7 @@ public class WriteValueInstruction(
lexicalScope: LexicalScope, lexicalScope: LexicalScope,
target: AccessTarget, target: AccessTarget,
receiverValues: Map<PseudoValue, ReceiverValue>, receiverValues: Map<PseudoValue, ReceiverValue>,
public val lValue: JetElement, public val TEMP_lValue: JetElement,
public val rValue: PseudoValue public val rValue: PseudoValue
) : AccessValueInstruction(assignment, lexicalScope, target, receiverValues) { ) : AccessValueInstruction(assignment, lexicalScope, target, receiverValues) {
override val inputValues: List<PseudoValue> override val inputValues: List<PseudoValue>
@@ -110,10 +106,10 @@ public class WriteValueInstruction(
} }
override fun toString(): String { override fun toString(): String {
val lhs = (lValue as? JetNamedDeclaration)?.getName() ?: render(lValue) val lhs = (TEMP_lValue as? JetNamedDeclaration)?.getName() ?: render(TEMP_lValue)
return "w($lhs|${inputValues.joinToString(", ")})" return "w($lhs|${inputValues.joinToString(", ")})"
} }
override fun createCopy(): InstructionImpl = override fun createCopy(): InstructionImpl =
WriteValueInstruction(element, lexicalScope, target, receiverValues, lValue, rValue) WriteValueInstruction(element, lexicalScope, target, receiverValues, TEMP_lValue, rValue)
} }
@@ -136,8 +136,8 @@ public object LightClassUtil {
public fun getLightClassAccessorMethods(accessor: JetPropertyAccessor): List<PsiMethod> { public fun getLightClassAccessorMethods(accessor: JetPropertyAccessor): List<PsiMethod> {
val property = accessor.getNonStrictParentOfType<JetProperty>() ?: return emptyList() val property = accessor.getNonStrictParentOfType<JetProperty>() ?: return emptyList()
val wrappers = getPsiMethodWrappers(property, true) val wrappers = getPsiMethodWrappers(property, true)
return wrappers.filter { wrapper -> (accessor.isGetter && !wrapper.name.startsWith(JvmAbi.SETTER_PREFIX)) || return wrappers.filter { wrapper -> (accessor.isGetter && !JvmAbi.isSetterName(wrapper.name)) ||
(accessor.isSetter && wrapper.name.startsWith(JvmAbi.SETTER_PREFIX)) } (accessor.isSetter && JvmAbi.isSetterName(wrapper.name)) }
} }
public fun getLightFieldForCompanionObject(companionObject: JetClassOrObject): PsiField? { public fun getLightFieldForCompanionObject(companionObject: JetClassOrObject): PsiField? {
@@ -296,11 +296,11 @@ public object LightClassUtil {
val additionalAccessors = arrayListOf<PsiMethod>() val additionalAccessors = arrayListOf<PsiMethod>()
val wrappers = getPsiMethodWrappers(jetDeclaration, true).filter { val wrappers = getPsiMethodWrappers(jetDeclaration, true).filter {
it.name.startsWith(JvmAbi.GETTER_PREFIX) || it.name.startsWith(JvmAbi.SETTER_PREFIX) JvmAbi.isGetterName(it.name) || JvmAbi.isSetterName(it.name)
} }
for (wrapper in wrappers) { for (wrapper in wrappers) {
if (wrapper.getName().startsWith(JvmAbi.SETTER_PREFIX)) { if (JvmAbi.isSetterName(wrapper.getName())) {
if (setterWrapper == null || setterWrapper === specialSetter) { if (setterWrapper == null || setterWrapper === specialSetter) {
setterWrapper = wrapper setterWrapper = wrapper
} }
@@ -0,0 +1,41 @@
package a
interface I {
var simpleFoo: Int
var isSomething1: Boolean
var isSomethingNullable: Boolean?
var isSomethingNonBoolean: String
var isHTML: Boolean
var is1: Boolean
var `is`: Boolean
var kClassName: String
var URL: String
var HTTPProtocol: String
var issueFlag: Boolean
}
// 1 getSimpleFoo
// 1 setSimpleFoo
// 1 isSomething1
// 1 setSomething1
// 1 isSomethingNullable
// 1 setSomethingNullable
// 1 isSomethingNonBoolean
// 1 setSomethingNonBoolean
// 1 isHTML
// 1 setHTML
// 1 is1
// 1 set1
// 2 getIs
// 2 setIs
// 1 getKClassName
// 1 setKClassName
// 1 getURL
// 1 setURL
// 1 getHTTPProtocol
// 1 setHTTPProtocol
// 1 getIssueFlag
// 1 setIssueFlag
@@ -37,6 +37,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("accessorNaming.kt")
public void testAccessorNaming() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/accessorNaming.kt");
doTest(fileName);
}
public void testAllFilesPresentInBytecodeText() throws Exception { public void testAllFilesPresentInBytecodeText() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText"), Pattern.compile("^(.+)\\.kt$"), true); JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText"), Pattern.compile("^(.+)\\.kt$"), true);
} }
@@ -40,8 +40,10 @@ public final class JvmAbi {
public static final String TRAIT_IMPL_SUFFIX = "$" + TRAIT_IMPL_CLASS_NAME; public static final String TRAIT_IMPL_SUFFIX = "$" + TRAIT_IMPL_CLASS_NAME;
public static final String DEFAULT_PARAMS_IMPL_SUFFIX = "$default"; public static final String DEFAULT_PARAMS_IMPL_SUFFIX = "$default";
public static final String GETTER_PREFIX = "get";
public static final String SETTER_PREFIX = "set"; private static final String GET_PREFIX = "get";
private static final String IS_PREFIX = "is";
private static final String SET_PREFIX = "set";
public static final String DELEGATED_PROPERTY_NAME_SUFFIX = "$delegate"; public static final String DELEGATED_PROPERTY_NAME_SUFFIX = "$delegate";
public static final String PROPERTY_METADATA_ARRAY_NAME = "$propertyMetadata"; public static final String PROPERTY_METADATA_ARRAY_NAME = "$propertyMetadata";
@@ -65,21 +67,34 @@ public final class JvmAbi {
return isDelegated ? propertyName.asString() + DELEGATED_PROPERTY_NAME_SUFFIX : propertyName.asString(); return isDelegated ? propertyName.asString() + DELEGATED_PROPERTY_NAME_SUFFIX : propertyName.asString();
} }
public static boolean isGetterName(@NotNull String name) {
return name.startsWith(GET_PREFIX) || name.startsWith(IS_PREFIX);
}
public static boolean isSetterName(@NotNull String name) {
return name.startsWith(SET_PREFIX);
}
@NotNull @NotNull
public static String getterName(@NotNull String propertyName) { public static String getterName(@NotNull String propertyName) {
return GETTER_PREFIX + capitalizeWithJavaBeanConvention(propertyName); return startsWithIsPrefix(propertyName)
? propertyName
: GET_PREFIX + KotlinPackage.capitalize(propertyName);
} }
@NotNull @NotNull
public static String setterName(@NotNull String propertyName) { public static String setterName(@NotNull String propertyName) {
return SETTER_PREFIX + capitalizeWithJavaBeanConvention(propertyName); return startsWithIsPrefix(propertyName)
? SET_PREFIX + propertyName.substring(IS_PREFIX.length())
: SET_PREFIX + KotlinPackage.capitalize(propertyName);
} }
/** private static boolean startsWithIsPrefix(String name) {
* @see com.intellij.openapi.util.text.StringUtil#capitalizeWithJavaBeanConvention(String) if (!name.startsWith(IS_PREFIX)) return false;
*/ if (name.length() == IS_PREFIX.length()) return false;
@NotNull char c = name.charAt(IS_PREFIX.length());
private static String capitalizeWithJavaBeanConvention(@NotNull String s) { return !Character.isLowerCase(c);
return s.length() > 1 && Character.isUpperCase(s.charAt(1)) ? s : KotlinPackage.capitalize(s);
} }
} }
@@ -134,7 +134,7 @@ class LazyJavaTypeResolver(
private fun mapKotlinClass(fqName: FqName): ClassDescriptor? { private fun mapKotlinClass(fqName: FqName): ClassDescriptor? {
if (attr.isForAnnotationParameter && fqName == JAVA_LANG_CLASS_FQ_NAME) { if (attr.isForAnnotationParameter && fqName == JAVA_LANG_CLASS_FQ_NAME) {
return c.reflectionTypes.kClass return c.reflectionTypes.TEMP_kClass
} }
val javaToKotlin = JavaToKotlinClassMap.INSTANCE val javaToKotlin = JavaToKotlinClassMap.INSTANCE
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.scopes.JetScope import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import java.util.ArrayList import java.util.*
val KOTLIN_REFLECT_FQ_NAME = FqName("kotlin.reflect") val KOTLIN_REFLECT_FQ_NAME = FqName("kotlin.reflect")
@@ -49,7 +49,11 @@ public class ReflectionTypes(private val module: ModuleDescriptor) {
public fun getKFunction(n: Int): ClassDescriptor = find("KFunction$n") public fun getKFunction(n: Int): ClassDescriptor = find("KFunction$n")
public val kClass: ClassDescriptor by ClassLookup // public val TEMP_kClass: ClassDescriptor by ClassLookup
//TODO: temporary
public val TEMP_kClass: ClassDescriptor
get() = find("KClass")
public val kProperty0: ClassDescriptor by ClassLookup public val kProperty0: ClassDescriptor by ClassLookup
public val kProperty1: ClassDescriptor by ClassLookup public val kProperty1: ClassDescriptor by ClassLookup
public val kProperty2: ClassDescriptor by ClassLookup public val kProperty2: ClassDescriptor by ClassLookup
@@ -57,7 +61,7 @@ public class ReflectionTypes(private val module: ModuleDescriptor) {
public val kMutableProperty1: ClassDescriptor by ClassLookup public val kMutableProperty1: ClassDescriptor by ClassLookup
public fun getKClassType(annotations: Annotations, type: JetType): JetType { public fun getKClassType(annotations: Annotations, type: JetType): JetType {
val descriptor = kClass val descriptor = TEMP_kClass
if (ErrorUtils.isError(descriptor)) { if (ErrorUtils.isError(descriptor)) {
return descriptor.getDefaultType() return descriptor.getDefaultType()
} }
@@ -369,9 +369,9 @@ public open class JetChangeInfo(
is JetProperty, is JetParameter -> { is JetProperty, is JetParameter -> {
val accessorName = originalPsiMethod.getName() val accessorName = originalPsiMethod.getName()
when { when {
accessorName.startsWith(JvmAbi.GETTER_PREFIX) -> JvmAbi.isGetterName(accessorName) ->
createJavaChangeInfoForFunctionOrGetter(originalPsiMethod, currentPsiMethod, true) createJavaChangeInfoForFunctionOrGetter(originalPsiMethod, currentPsiMethod, true)
accessorName.startsWith(JvmAbi.SETTER_PREFIX) -> JvmAbi.isSetterName(accessorName) ->
createJavaChangeInfoForSetter(originalPsiMethod, currentPsiMethod) createJavaChangeInfoForSetter(originalPsiMethod, currentPsiMethod)
else -> null else -> null
} }
@@ -151,8 +151,8 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
String newName = changeInfo.getNewName(); String newName = changeInfo.getNewName();
if (isPropertyJavaUsage()) { if (isPropertyJavaUsage()) {
String currentName = ((JetSimpleNameExpression) callee).getReferencedName(); String currentName = ((JetSimpleNameExpression) callee).getReferencedName();
if (currentName.startsWith(JvmAbi.GETTER_PREFIX)) newName = JvmAbi.getterName(newName); if (JvmAbi.isGetterName(currentName)) newName = JvmAbi.getterName(newName);
else if (currentName.startsWith(JvmAbi.SETTER_PREFIX)) newName = JvmAbi.setterName(newName); else if (JvmAbi.isSetterName(currentName)) newName = JvmAbi.setterName(newName);
} }
callee.replace(JetPsiFactory(getProject()).createSimpleName(newName)); callee.replace(JetPsiFactory(getProject()).createSimpleName(newName));
+2 -6
View File
@@ -29,7 +29,7 @@ public var Element.childrenText: String
while (i < size) { while (i < size) {
val node = nodeList.item(i) val node = nodeList.item(i)
if (node != null) { if (node != null) {
if (node.isText()) { if (node.isText) {
buffer.append(node.nodeValue) buffer.append(node.nodeValue)
} }
} }
@@ -41,7 +41,7 @@ public var Element.childrenText: String
val element = this val element = this
// lets remove all the previous text nodes first // lets remove all the previous text nodes first
for (node in element.children()) { for (node in element.children()) {
if (node.isText()) { if (node.isText) {
removeChild(node) removeChild(node)
} }
} }
@@ -269,10 +269,6 @@ private class PreviousSiblings(private var node: Node) : Iterable<Node> {
} }
} }
/** Returns true if this node is a Text node or a CDATA node */
@Deprecated("use property isText instead", ReplaceWith("isText"))
public fun Node.isText() : Boolean = isText
/** /**
* it is *true* when [Node.nodeType] is TEXT_NODE or CDATA_SECTION_NODE * it is *true* when [Node.nodeType] is TEXT_NODE or CDATA_SECTION_NODE
*/ */