ReadClassDataTest: extension properties
This commit is contained in:
@@ -91,17 +91,24 @@ public class FunctionCodegen {
|
|||||||
if(v.generateCode()) {
|
if(v.generateCode()) {
|
||||||
int start = 0;
|
int start = 0;
|
||||||
if(kind != OwnerKind.TRAIT_IMPL) {
|
if(kind != OwnerKind.TRAIT_IMPL) {
|
||||||
AnnotationVisitor av = mv.visitAnnotation(JvmStdlibNames.JET_METHOD.getDescriptor(), true);
|
if (functionDescriptor instanceof PropertyAccessorDescriptor) {
|
||||||
if(functionDescriptor.getReturnType().isNullable()) {
|
AnnotationVisitor av = mv.visitAnnotation(JvmStdlibNames.JET_PROPERTY.getDescriptor(), true);
|
||||||
av.visit(JvmStdlibNames.JET_METHOD_NULLABLE_RETURN_TYPE_FIELD, true);
|
av.visitEnd();
|
||||||
|
} else if (functionDescriptor instanceof NamedFunctionDescriptor) {
|
||||||
|
AnnotationVisitor av = mv.visitAnnotation(JvmStdlibNames.JET_METHOD.getDescriptor(), true);
|
||||||
|
if(functionDescriptor.getReturnType().isNullable()) {
|
||||||
|
av.visit(JvmStdlibNames.JET_METHOD_NULLABLE_RETURN_TYPE_FIELD, true);
|
||||||
|
}
|
||||||
|
if (jvmSignature.getKotlinReturnType() != null) {
|
||||||
|
av.visit(JvmStdlibNames.JET_METHOD_RETURN_TYPE_FIELD, jvmSignature.getKotlinReturnType());
|
||||||
|
}
|
||||||
|
if (jvmSignature.getKotlinTypeParameter() != null) {
|
||||||
|
av.visit(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD, jvmSignature.getKotlinTypeParameter());
|
||||||
|
}
|
||||||
|
av.visitEnd();
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
if (jvmSignature.getKotlinReturnType() != null) {
|
|
||||||
av.visit(JvmStdlibNames.JET_METHOD_RETURN_TYPE_FIELD, jvmSignature.getKotlinReturnType());
|
|
||||||
}
|
|
||||||
if (jvmSignature.getKotlinTypeParameter() != null) {
|
|
||||||
av.visit(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD, jvmSignature.getKotlinTypeParameter());
|
|
||||||
}
|
|
||||||
av.visitEnd();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(kind == OwnerKind.TRAIT_IMPL) {
|
if(kind == OwnerKind.TRAIT_IMPL) {
|
||||||
|
|||||||
+91
-38
@@ -740,10 +740,7 @@ public class JavaDescriptorResolver {
|
|||||||
receiver = (Boolean) receiverExpression.getValue();
|
receiver = (Boolean) receiverExpression.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
PsiLiteralExpression hasDefaultValueExpression = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_VALUE_PARAMETER_HAS_DEFAULT_VALUE_FIELD);
|
hasDefaultValue = getBooleanAnnotationAttributeValue(annotation, JvmStdlibNames.JET_VALUE_PARAMETER_HAS_DEFAULT_VALUE_FIELD, false);
|
||||||
if (hasDefaultValueExpression != null) {
|
|
||||||
hasDefaultValue = (Boolean) hasDefaultValueExpression.getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} else if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_TYPE_PARAMETER.getFqName())) {
|
} else if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_TYPE_PARAMETER.getFqName())) {
|
||||||
@@ -773,6 +770,15 @@ public class JavaDescriptorResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean getBooleanAnnotationAttributeValue(PsiAnnotation annotation, String parameterName, boolean defaultValue) {
|
||||||
|
PsiLiteralExpression receiverExpression = (PsiLiteralExpression) annotation.findAttributeValue(parameterName);
|
||||||
|
if (receiverExpression != null) {
|
||||||
|
return (Boolean) receiverExpression.getValue();
|
||||||
|
} else {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
public VariableDescriptor resolveFieldToVariableDescriptor(DeclarationDescriptor containingDeclaration, PsiField field) {
|
public VariableDescriptor resolveFieldToVariableDescriptor(DeclarationDescriptor containingDeclaration, PsiField field) {
|
||||||
VariableDescriptor variableDescriptor = fieldDescriptorCache.get(field);
|
VariableDescriptor variableDescriptor = fieldDescriptorCache.get(field);
|
||||||
@@ -802,21 +808,25 @@ public class JavaDescriptorResolver {
|
|||||||
private final String name;
|
private final String name;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final PsiType type;
|
private final PsiType type;
|
||||||
|
@Nullable
|
||||||
|
private final PsiType receiverType;
|
||||||
|
|
||||||
private PropertyKey(String name, PsiType type) {
|
private PropertyKey(@NotNull String name, @NotNull PsiType type, @Nullable PsiType receiverType) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
this.receiverType = receiverType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
// generated by Idea
|
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
PropertyKey that = (PropertyKey) o;
|
PropertyKey that = (PropertyKey) o;
|
||||||
|
|
||||||
if (!name.equals(that.name)) return false;
|
if (!name.equals(that.name)) return false;
|
||||||
|
if (receiverType != null ? !receiverType.equals(that.receiverType) : that.receiverType != null)
|
||||||
|
return false;
|
||||||
if (!type.equals(that.type)) return false;
|
if (!type.equals(that.type)) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -826,6 +836,7 @@ public class JavaDescriptorResolver {
|
|||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = name.hashCode();
|
int result = name.hashCode();
|
||||||
result = 31 * result + type.hashCode();
|
result = 31 * result + type.hashCode();
|
||||||
|
result = 31 * result + (receiverType != null ? receiverType.hashCode() : 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -850,7 +861,7 @@ public class JavaDescriptorResolver {
|
|||||||
|
|
||||||
MembersForProperty members = new MembersForProperty();
|
MembersForProperty members = new MembersForProperty();
|
||||||
members.field = field;
|
members.field = field;
|
||||||
membersMap.put(new PropertyKey(field.getName(), field.getType()), members);
|
membersMap.put(new PropertyKey(field.getName(), field.getType(), null), members);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -864,36 +875,77 @@ public class JavaDescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: "is" prefix
|
// TODO: "is" prefix
|
||||||
|
// TODO: remove getJavaClass
|
||||||
if (method.getName().startsWith(JvmAbi.GETTER_PREFIX)) {
|
if (method.getName().startsWith(JvmAbi.GETTER_PREFIX)) {
|
||||||
// TODO: some java properties too
|
// TODO: some java properties too
|
||||||
if (method.getModifierList().findAnnotation(JvmStdlibNames.JET_PROPERTY.getFqName()) != null) {
|
if (method.getModifierList().findAnnotation(JvmStdlibNames.JET_PROPERTY.getFqName()) != null) {
|
||||||
|
PsiType receiverType;
|
||||||
if (method.getParameterList().getParametersCount() == 0) {
|
if (method.getParameterList().getParametersCount() == 0) {
|
||||||
if (method.getName().equals(JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD)) {
|
receiverType = null;
|
||||||
continue;
|
} else if (method.getParameterList().getParametersCount() == 1) {
|
||||||
|
if (method.getParameterList().getParameters()[0].getModifierList().findAnnotation(JvmStdlibNames.JET_TYPE_PARAMETER.getFqName()) != null) {
|
||||||
|
receiverType = null;
|
||||||
|
} else {
|
||||||
|
receiverType = method.getParameterList().getParameters()[0].getType();
|
||||||
}
|
}
|
||||||
|
} else if (method.getParameterList().getParametersCount() == 2) {
|
||||||
String propertyName = StringUtil.decapitalize(method.getName().substring(JvmAbi.GETTER_PREFIX.length()));
|
if (method.getParameterList().getParameters()[1].getModifierList().findAnnotation(JvmStdlibNames.JET_TYPE_PARAMETER.getFqName()) == null) {
|
||||||
PropertyKey key = new PropertyKey(propertyName, method.getReturnType());
|
throw new IllegalStateException();
|
||||||
MembersForProperty members = membersMap.get(key);
|
|
||||||
if (members == null) {
|
|
||||||
members = new MembersForProperty();
|
|
||||||
membersMap.put(key, members);
|
|
||||||
}
|
}
|
||||||
members.getter = method;
|
receiverType = method.getParameterList().getParameters()[0].getType();
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (method.getName().equals(JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String propertyName = StringUtil.decapitalize(method.getName().substring(JvmAbi.GETTER_PREFIX.length()));
|
||||||
|
PropertyKey key = new PropertyKey(propertyName, method.getReturnType(), receiverType);
|
||||||
|
MembersForProperty members = membersMap.get(key);
|
||||||
|
if (members == null) {
|
||||||
|
members = new MembersForProperty();
|
||||||
|
membersMap.put(key, members);
|
||||||
|
}
|
||||||
|
members.getter = method;
|
||||||
}
|
}
|
||||||
} else if (method.getName().startsWith(JvmAbi.SETTER_PREFIX)) {
|
} else if (method.getName().startsWith(JvmAbi.SETTER_PREFIX)) {
|
||||||
if (method.getModifierList().findAnnotation(JvmStdlibNames.JET_PROPERTY.getFqName()) != null) {
|
if (method.getModifierList().findAnnotation(JvmStdlibNames.JET_PROPERTY.getFqName()) != null) {
|
||||||
if (method.getParameterList().getParametersCount() == 1) {
|
if (method.getParameterList().getParametersCount() == 0) {
|
||||||
String propertyName = StringUtil.decapitalize(method.getName().substring(JvmAbi.SETTER_PREFIX.length()));
|
throw new IllegalStateException();
|
||||||
PropertyKey key = new PropertyKey(propertyName, method.getParameterList().getParameters()[0].getType());
|
|
||||||
MembersForProperty members = membersMap.get(key);
|
|
||||||
if (members == null) {
|
|
||||||
members = new MembersForProperty();
|
|
||||||
membersMap.put(key, members);
|
|
||||||
}
|
|
||||||
members.setter = method;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
PsiType receiverType = null;
|
||||||
|
PsiParameter p1 = method.getParameterList().getParameters()[0];
|
||||||
|
PsiAnnotation p1a = p1.getModifierList().findAnnotation(JvmStdlibNames.JET_VALUE_PARAMETER.getFqName());
|
||||||
|
if (p1a != null) {
|
||||||
|
if (getBooleanAnnotationAttributeValue(p1a, JvmStdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD, false)) {
|
||||||
|
receiverType = p1.getType();
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i < method.getParameterList().getParametersCount() && method.getParameterList().getParameters()[i].getModifierList().findAnnotation(JvmStdlibNames.JET_TYPE_PARAMETER.getFqName()) != null) {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i + 1 != method.getParameterList().getParametersCount()) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
|
PsiType propertyType = method.getParameterList().getParameters()[i].getType();
|
||||||
|
|
||||||
|
String propertyName = StringUtil.decapitalize(method.getName().substring(JvmAbi.SETTER_PREFIX.length()));
|
||||||
|
PropertyKey key = new PropertyKey(propertyName, propertyType, receiverType);
|
||||||
|
MembersForProperty members = membersMap.get(key);
|
||||||
|
if (members == null) {
|
||||||
|
members = new MembersForProperty();
|
||||||
|
membersMap.put(key, members);
|
||||||
|
}
|
||||||
|
members.setter = method;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -940,6 +992,7 @@ public class JavaDescriptorResolver {
|
|||||||
//}
|
//}
|
||||||
String propertyName = entry.getKey().name;
|
String propertyName = entry.getKey().name;
|
||||||
PsiType propertyType = entry.getKey().type;
|
PsiType propertyType = entry.getKey().type;
|
||||||
|
PsiType receiverType = entry.getKey().receiverType;
|
||||||
MembersForProperty members = entry.getValue();
|
MembersForProperty members = entry.getValue();
|
||||||
|
|
||||||
JetType type = semanticServices.getTypeTransformer().transformToType(propertyType);
|
JetType type = semanticServices.getTypeTransformer().transformToType(propertyType);
|
||||||
@@ -972,6 +1025,13 @@ public class JavaDescriptorResolver {
|
|||||||
isVar = members.setter != null;
|
isVar = members.setter != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JetType receiverJetType;
|
||||||
|
if (receiverType == null) {
|
||||||
|
receiverJetType = null;
|
||||||
|
} else {
|
||||||
|
receiverJetType = semanticServices.getTypeTransformer().transformToType(receiverType);
|
||||||
|
}
|
||||||
|
|
||||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
|
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
|
||||||
owner,
|
owner,
|
||||||
Collections.<AnnotationDescriptor>emptyList(),
|
Collections.<AnnotationDescriptor>emptyList(),
|
||||||
@@ -979,7 +1039,7 @@ public class JavaDescriptorResolver {
|
|||||||
resolveVisibilityFromPsiModifiers(anyMember),
|
resolveVisibilityFromPsiModifiers(anyMember),
|
||||||
isVar,
|
isVar,
|
||||||
false,
|
false,
|
||||||
null,
|
receiverJetType,
|
||||||
DescriptorUtils.getExpectedThisObjectIfNeeded(owner),
|
DescriptorUtils.getExpectedThisObjectIfNeeded(owner),
|
||||||
propertyName,
|
propertyName,
|
||||||
type);
|
type);
|
||||||
@@ -1085,18 +1145,11 @@ public class JavaDescriptorResolver {
|
|||||||
kotlin = classData.kotlin;
|
kotlin = classData.kotlin;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: hide getters and setters properly
|
// TODO: ugly
|
||||||
if (kotlin) {
|
if (method.getModifierList().findAnnotation(JvmStdlibNames.JET_PROPERTY.getFqName()) != null) {
|
||||||
if (method.getName().startsWith(JvmAbi.GETTER_PREFIX) && method.getParameterList().getParametersCount() == 0) {
|
return null;
|
||||||
if (method.getModifierList().findAnnotation(JvmStdlibNames.JET_PROPERTY.getFqName()) != null)
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (method.getName().startsWith(JvmAbi.SETTER_PREFIX) && method.getParameterList().getParametersCount() == 1) {
|
|
||||||
if (method.getModifierList().findAnnotation(JvmStdlibNames.JET_PROPERTY.getFqName()) != null)
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DeclarationDescriptor classDescriptor;
|
DeclarationDescriptor classDescriptor;
|
||||||
final List<TypeParameterDescriptor> classTypeParameters;
|
final List<TypeParameterDescriptor> classTypeParameters;
|
||||||
if (method.hasModifierProperty(PsiModifier.STATIC)) {
|
if (method.hasModifierProperty(PsiModifier.STATIC)) {
|
||||||
|
|||||||
@@ -86,14 +86,6 @@ public class JavaPackageScope extends JetScopeImpl {
|
|||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
PsiField field = psiClassForPackage.findFieldByName(name, true);
|
|
||||||
if (field == null) {
|
|
||||||
return Collections.emptySet();
|
|
||||||
}
|
|
||||||
if (!field.hasModifierProperty(PsiModifier.STATIC)) {
|
|
||||||
return Collections.emptySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: cache
|
// TODO: cache
|
||||||
return semanticServices.getDescriptorResolver().resolveFieldGroupByName(containingDescriptor, psiClassForPackage, name, true);
|
return semanticServices.getDescriptorResolver().resolveFieldGroupByName(containingDescriptor, psiClassForPackage, name, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
val Int.itIs: Int
|
||||||
|
get() = this
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class ExtPropInClass {
|
||||||
|
val Int.itIs: Int
|
||||||
|
get() = this
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
var Int.ggg: Int
|
||||||
|
get() = throw Exception()
|
||||||
|
set(p) = throw Exception()
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class ExtPropInClass {
|
||||||
|
var Int.itIs: Int
|
||||||
|
get() = throw Exception()
|
||||||
|
set(p: Int) = throw Exception()
|
||||||
|
}
|
||||||
@@ -282,6 +282,10 @@ public class ReadClassDataTest extends TestCaseWithTmpdir {
|
|||||||
} else {
|
} else {
|
||||||
sb.append("val ");
|
sb.append("val ");
|
||||||
}
|
}
|
||||||
|
if (prop.getReceiverParameter().exists()) {
|
||||||
|
serialize(prop.getReceiverParameter().getType());
|
||||||
|
sb.append(".");
|
||||||
|
}
|
||||||
sb.append(prop.getName());
|
sb.append(prop.getName());
|
||||||
sb.append(": ");
|
sb.append(": ");
|
||||||
serialize(prop.getOutType());
|
serialize(prop.getOutType());
|
||||||
|
|||||||
Reference in New Issue
Block a user