Remove logic in JavaPropertyResolver related to kotlin properties

Make logic in MembersCache clearer
Remove useless helper classes
This commit is contained in:
Pavel V. Talanov
2013-07-05 20:55:35 +04:00
parent f5c4075837
commit 9be16bf94c
12 changed files with 93 additions and 931 deletions
@@ -170,7 +170,6 @@ public class InjectorForJavaDescriptorResolver {
javaInnerClassResolver.setClassResolver(javaClassResolver);
javaPropertyResolver.setAnnotationResolver(javaAnnotationResolver);
javaPropertyResolver.setJavaSignatureResolver(javaSignatureResolver);
javaPropertyResolver.setSemanticServices(javaSemanticServices);
javaPropertyResolver.setTrace(bindingTrace);
@@ -170,7 +170,6 @@ public class InjectorForJavaSemanticServices {
javaInnerClassResolver.setClassResolver(javaClassResolver);
javaPropertyResolver.setAnnotationResolver(javaAnnotationResolver);
javaPropertyResolver.setJavaSignatureResolver(javaSignatureResolver);
javaPropertyResolver.setSemanticServices(javaSemanticServices);
javaPropertyResolver.setTrace(bindingTrace);
@@ -348,7 +348,6 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
javaInnerClassResolver.setClassResolver(javaClassResolver);
javaPropertyResolver.setAnnotationResolver(javaAnnotationResolver);
javaPropertyResolver.setJavaSignatureResolver(javaSignatureResolver);
javaPropertyResolver.setSemanticServices(javaSemanticServices);
javaPropertyResolver.setTrace(bindingTrace);
@@ -1,52 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java;
import com.intellij.psi.PsiModifierListOwner;
import com.intellij.psi.PsiType;
import org.jetbrains.annotations.NotNull;
public class TypeSource {
@NotNull
private final String typeString;
@NotNull
private final PsiType psiType;
@NotNull
private final PsiModifierListOwner psiNotNullOwner;
public TypeSource(@NotNull String typeString, @NotNull PsiType psiType, @NotNull PsiModifierListOwner psiNotNullOwner) {
this.typeString = typeString;
this.psiType = psiType;
this.psiNotNullOwner = psiNotNullOwner;
}
@NotNull
public String getTypeString() {
return typeString;
}
@NotNull
public PsiType getPsiType() {
return psiType;
}
@NotNull
public PsiModifierListOwner getPsiNotNullOwner() {
return psiNotNullOwner;
}
}
@@ -1,45 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.prop;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
public class PropertyNameUtils {
private PropertyNameUtils() {
}
@Nullable
public static PropertyParseResult parseMethodToProperty(@NotNull String methodName) {
// TODO: support is properties
if (methodName.startsWith(JvmAbi.GETTER_PREFIX) && methodName.length() > JvmAbi.GETTER_PREFIX.length()) {
String propertyName = StringUtil.decapitalize(methodName.substring(JvmAbi.GETTER_PREFIX.length()));
return new PropertyParseResult(propertyName, true);
}
else if (methodName.startsWith(JvmAbi.SETTER_PREFIX) && methodName.length() > JvmAbi.SETTER_PREFIX.length()) {
String propertyName = StringUtil.decapitalize(methodName.substring(JvmAbi.SETTER_PREFIX.length()));
return new PropertyParseResult(propertyName, false);
}
else {
return null;
}
}
}
@@ -1,39 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.prop;
import org.jetbrains.annotations.NotNull;
public class PropertyParseResult {
@NotNull
private final String propertyName;
private final boolean getter;
public PropertyParseResult(@NotNull String propertyName, boolean getter) {
this.propertyName = propertyName;
this.getter = getter;
}
@NotNull
public String getPropertyName() {
return propertyName;
}
public boolean isGetter() {
return getter;
}
}
@@ -27,10 +27,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.JetJavaMirrorMarker;
import org.jetbrains.jet.lang.resolve.java.PsiClassFinder;
import org.jetbrains.jet.lang.resolve.java.TypeSource;
import org.jetbrains.jet.lang.resolve.java.prop.PropertyNameUtils;
import org.jetbrains.jet.lang.resolve.java.prop.PropertyParseResult;
import org.jetbrains.jet.lang.resolve.java.wrapper.*;
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiFieldWrapper;
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMemberWrapper;
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
@@ -168,35 +167,24 @@ public final class MembersCache {
}
private void processMethods() {
parseAllMethodsAsProperties();
createEntriesForAllMethods();
processOwnMethods();
}
private void createEntriesForAllMethods() {
for (PsiMethod method : psiClass.getAllMethods()) {
getOrCreateEmpty(Name.identifier(method.getName()));
}
}
private void processOwnMethods() {
for (final PsiMethod method : psiClass.getMethods()) {
RunOnce task = new RunOnce() {
addTask(method, new RunOnce() {
@Override
public void doRun() {
processOwnMethod(method);
}
};
addTask(method, task);
PropertyParseResult propertyParseResult = PropertyNameUtils.parseMethodToProperty(method.getName());
if (propertyParseResult != null) {
addTask(propertyParseResult.getPropertyName(), task);
}
}
}
private void parseAllMethodsAsProperties() {
for (PsiMethod method : psiClass.getAllMethods()) {
createEmptyEntry(Name.identifier(method.getName()));
PropertyParseResult propertyParseResult = PropertyNameUtils.parseMethodToProperty(method.getName());
if (propertyParseResult != null) {
createEmptyEntry(Name.identifier(propertyParseResult.getPropertyName()));
}
});
}
}
@@ -248,8 +236,7 @@ public final class MembersCache {
return;
}
TypeSource type = new TypeSource("", fieldWrapper.getType(), field);
namedMembers.addPropertyAccessor(new PropertyPsiDataElement(fieldWrapper, type, null));
namedMembers.addField(fieldWrapper);
}
private void processOwnMethod(PsiMethod ownMethod) {
@@ -259,37 +246,10 @@ public final class MembersCache {
return;
}
PropertyParseResult propertyParseResult = PropertyNameUtils.parseMethodToProperty(method.getName());
// TODO: remove getJavaClass
if (propertyParseResult != null && propertyParseResult.isGetter()) {
processGetter(ownMethod, method, propertyParseResult);
}
else if (propertyParseResult != null) {
processSetter(method, propertyParseResult);
}
NamedMembers namedMembers = getOrCreateEmpty(Name.identifier(method.getName()));
namedMembers.addMethod(method);
}
//TODO: manually!!!!
private void processSetter(PsiMethodWrapper method, PropertyParseResult propertyParseResult) {
//TODO
String propertyName = propertyParseResult.getPropertyName();
getOrCreateEmpty(Name.identifier(propertyName));
}
private void processGetter(PsiMethod ownMethod, PsiMethodWrapper method, PropertyParseResult propertyParseResult) {
//TODO:
String propertyName = propertyParseResult.getPropertyName();
getOrCreateEmpty(Name.identifier(propertyName));
}
private void createEmptyEntry(@NotNull Name identifier) {
getOrCreateEmpty(identifier);
}
private void processNestedClass(PsiClass nested) {
if (isSamInterface(nested)) {
NamedMembers namedMembers = getOrCreateEmpty(Name.identifier(nested.getName()));
@@ -20,7 +20,7 @@ import com.google.common.collect.Lists;
import com.intellij.psi.PsiClass;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.wrapper.PropertyPsiDataElement;
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiFieldWrapper;
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper;
import org.jetbrains.jet.lang.resolve.name.Name;
@@ -39,7 +39,7 @@ public final class NamedMembers {
private final List<PsiMethodWrapper> methods = Lists.newArrayList();
@NotNull
private final List<PropertyPsiDataElement> propertyPsiDataElements = Lists.newArrayList();
private final List<PsiFieldWrapper> fields = Lists.newArrayList();
@Nullable
private PsiClass samInterface;
@@ -48,8 +48,8 @@ public final class NamedMembers {
methods.add(method);
}
void addPropertyAccessor(@NotNull PropertyPsiDataElement propertyPsiDataElement) {
propertyPsiDataElements.add(propertyPsiDataElement);
void addField(@NotNull PsiFieldWrapper field) {
fields.add(field);
}
void setSamInterface(@NotNull PsiClass samInterface) {
@@ -67,8 +67,8 @@ public final class NamedMembers {
}
@NotNull
public List<PropertyPsiDataElement> getPropertyPsiDataElements() {
return propertyPsiDataElements;
public List<PsiFieldWrapper> getFields() {
return fields;
}
@Nullable
@@ -17,35 +17,36 @@
package org.jetbrains.jet.lang.resolve.java.resolver;
import com.google.common.collect.Sets;
import com.intellij.psi.*;
import com.intellij.psi.PsiEnumConstant;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiLiteralExpression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.*;
import org.jetbrains.jet.lang.descriptors.impl.ClassDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.impl.PropertyDescriptorForObjectImpl;
import org.jetbrains.jet.lang.descriptors.impl.PropertyDescriptorImpl;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.java.*;
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeFieldSignatureData;
import org.jetbrains.jet.lang.resolve.java.provider.NamedMembers;
import org.jetbrains.jet.lang.resolve.java.provider.PsiDeclarationProvider;
import org.jetbrains.jet.lang.resolve.java.wrapper.PropertyPsiData;
import org.jetbrains.jet.lang.resolve.java.wrapper.PropertyPsiDataElement;
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiFieldWrapper;
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import javax.inject.Inject;
import java.util.*;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
//TODO: getters and setter are not working
public final class JavaPropertyResolver {
private JavaSemanticServices semanticServices;
private JavaSignatureResolver javaSignatureResolver;
private BindingTrace trace;
private JavaAnnotationResolver annotationResolver;
@@ -62,11 +63,6 @@ public final class JavaPropertyResolver {
this.trace = trace;
}
@Inject
public void setJavaSignatureResolver(JavaSignatureResolver javaSignatureResolver) {
this.javaSignatureResolver = javaSignatureResolver;
}
@Inject
public void setAnnotationResolver(JavaAnnotationResolver annotationResolver) {
this.annotationResolver = annotationResolver;
@@ -94,26 +90,15 @@ public final class JavaPropertyResolver {
@NotNull Name propertyName,
@NotNull String context
) {
Collection<PropertyPsiData> psiDataCollection = PropertyPsiData.assemblePropertyPsiDataFromElements(
namedMembers.getPropertyPsiDataElements());
List<PsiFieldWrapper> fields = namedMembers.getFields();
Set<PropertyDescriptor> propertiesFromCurrent = new HashSet<PropertyDescriptor>(1);
int regularPropertiesCount = getNumberOfNonExtensionProperties(psiDataCollection);
for (PropertyPsiData propertyPsiData : psiDataCollection) {
// we cannot have more then one property with given name even if java code
// has several fields, getters and setter of different types
if (!propertyPsiData.isExtension() && regularPropertiesCount > 1) {
continue;
assert fields.size() <= 1;
if (fields.size() == 1) {
PsiFieldWrapper field = fields.iterator().next();
if (DescriptorResolverUtils.isCorrectOwnerForEnumMember(ownerDescriptor, field.getPsiField())) {
propertiesFromCurrent.add(resolveProperty(ownerDescriptor, propertyName, context, field));
}
if (!DescriptorResolverUtils.isCorrectOwnerForEnumMember(ownerDescriptor, propertyPsiData.getCharacteristicPsi())) {
continue;
}
propertiesFromCurrent.add(resolveProperty(ownerDescriptor, propertyName, context, propertyPsiData));
}
Set<PropertyDescriptor> propertiesFromSupertypes = getPropertiesFromSupertypes(propertyName, ownerDescriptor);
@@ -162,51 +147,36 @@ public final class JavaPropertyResolver {
@NotNull ClassOrNamespaceDescriptor owner,
@NotNull Name propertyName,
@NotNull String context,
@NotNull PropertyPsiData psiData
@NotNull PsiFieldWrapper field
) {
boolean isVar = psiData.isVar();
boolean isVar = !field.isFinal();
PropertyPsiDataElement characteristicMember = psiData.getCharacteristicMember();
Visibility visibility = DescriptorResolverUtils.resolveVisibility(psiData.getCharacteristicPsi());
CallableMemberDescriptor.Kind kind = CallableMemberDescriptor.Kind.DECLARATION;
PropertyPsiDataElement getter = psiData.getGetter();
if (getter != null) {
visibility = DescriptorResolverUtils.resolveVisibility(psiData.getCharacteristicPsi());
}
Visibility visibility = DescriptorResolverUtils.resolveVisibility(field.getPsiField());
PropertyDescriptorImpl propertyDescriptor =
createPropertyDescriptor(owner, propertyName, psiData, true, isVar, visibility, kind);
createPropertyDescriptor(owner, propertyName, field, isVar, visibility);
PropertyGetterDescriptorImpl getterDescriptor = resolveGetter(visibility, kind, getter, propertyDescriptor);
PropertySetterDescriptorImpl setterDescriptor = resolveSetter(psiData, kind, propertyDescriptor);
propertyDescriptor.initialize(getterDescriptor, setterDescriptor);
List<TypeParameterDescriptor> typeParameters = resolvePropertyTypeParameters(psiData, characteristicMember, propertyDescriptor);
propertyDescriptor.initialize(null, null);
TypeVariableResolver typeVariableResolverForPropertyInternals = TypeVariableResolvers.typeVariableResolverFromTypeParameters(
typeParameters, propertyDescriptor, "property " + propertyName + " in " + context);
Collections.<TypeParameterDescriptor>emptyList(), propertyDescriptor, "property " + propertyName + " in " + context);
JetType propertyType = getPropertyType(psiData, characteristicMember, typeVariableResolverForPropertyInternals);
JetType receiverType = getReceiverType(characteristicMember, typeVariableResolverForPropertyInternals);
JetType propertyType = getPropertyType(field, typeVariableResolverForPropertyInternals);
propertyType = getAlternativeSignatureData(isVar, characteristicMember, propertyDescriptor, propertyType);
propertyType = getAlternativeSignatureData(isVar, field, propertyDescriptor, propertyType);
propertyDescriptor.setType(
propertyType,
typeParameters,
Collections.<TypeParameterDescriptor>emptyList(),
DescriptorUtils.getExpectedThisObjectIfNeeded(owner),
receiverType
(JetType) null
);
initializeSetterAndGetter(propertyDescriptor, getterDescriptor, setterDescriptor, propertyType, psiData);
trace.record(BindingContext.VARIABLE, psiData.getCharacteristicPsi(), propertyDescriptor);
trace.record(BindingContext.VARIABLE, field.getPsiField(), propertyDescriptor);
trace.record(JavaBindingContext.IS_DECLARED_IN_JAVA, propertyDescriptor);
if (AnnotationUtils.isPropertyAcceptableAsAnnotationParameter(propertyDescriptor) && psiData.getCharacteristicPsi() instanceof PsiField) {
PsiExpression initializer = ((PsiField) psiData.getCharacteristicPsi()).getInitializer();
if (AnnotationUtils.isPropertyAcceptableAsAnnotationParameter(propertyDescriptor)) {
PsiExpression initializer = field.getPsiField().getInitializer();
if (initializer instanceof PsiLiteralExpression) {
CompileTimeConstant<?> constant = JavaCompileTimeConstResolver
.resolveCompileTimeConstantValue(((PsiLiteralExpression) initializer).getValue(), propertyType);
@@ -222,15 +192,13 @@ public final class JavaPropertyResolver {
private PropertyDescriptorImpl createPropertyDescriptor(
@NotNull ClassOrNamespaceDescriptor owner,
@NotNull Name propertyName,
@NotNull PropertyPsiData psiData,
boolean isFinal,
@NotNull PsiFieldWrapper field,
boolean isVar,
@NotNull Visibility visibility,
@NotNull CallableMemberDescriptor.Kind kind
@NotNull Visibility visibility
) {
boolean isEnumEntry = psiData.getCharacteristicPsi() instanceof PsiEnumConstant;
boolean isEnumEntry = field.getPsiField() instanceof PsiEnumConstant;
if (isEnumEntry) {
assert !isVar && isFinal : "Enum entries should be final and immutable.";
assert !isVar : "Enum entries should be immutable.";
assert DescriptorUtils.isEnumClassObject(owner) : "Enum entries should be put into class object of enum only: " + owner;
//TODO: this is a hack to indicate that this enum entry is an object
// class descriptor for enum entries is not used by backends so for now this should be safe to use
@@ -244,196 +212,57 @@ public final class JavaPropertyResolver {
false);
return new PropertyDescriptorForObjectImpl(
owner,
annotationResolver.resolveAnnotations(psiData.getCharacteristicPsi()),
annotationResolver.resolveAnnotations(field.getPsiField()),
visibility,
propertyName,
dummyClassDescriptorForEnumEntryObject);
}
else if (psiData.isPropertyForNamedObject() && owner instanceof NamespaceDescriptor) {
//TODO: support nested classes and objects
assert !isVar && isFinal : "Objects should be final and immutable.";
ClassDescriptor objectClass = ((NamespaceDescriptor) owner).getMemberScope().getObjectDescriptor(propertyName);
assert objectClass != null;
return new PropertyDescriptorForObjectImpl(
owner,
annotationResolver.resolveAnnotations(psiData.getCharacteristicPsi()),
visibility,
propertyName,
objectClass);
}
else {
return new PropertyDescriptorImpl(
owner,
annotationResolver.resolveAnnotations(psiData.getCharacteristicPsi()),
Modality.convertFromFlags(psiData.getCharacteristicMember().getMember().isAbstract(),
!(isFinal || psiData.isPropertyForNamedObject())),
visibility,
isVar,
propertyName,
kind);
}
return new PropertyDescriptorImpl(
owner,
annotationResolver.resolveAnnotations(field.getPsiField()),
Modality.FINAL,
visibility,
isVar,
propertyName,
CallableMemberDescriptor.Kind.DECLARATION);
}
@NotNull
private JetType getAlternativeSignatureData(
boolean isVar,
PropertyPsiDataElement characteristicMember,
PsiFieldWrapper field,
PropertyDescriptor propertyDescriptor,
JetType propertyType
) {
if (!characteristicMember.isField()) {
return propertyType;
}
AlternativeFieldSignatureData signatureData =
new AlternativeFieldSignatureData((PsiFieldWrapper) characteristicMember.getMember(), propertyType, isVar);
if (!signatureData.hasErrors()) {
if (signatureData.isAnnotated()) {
return signatureData.getReturnType();
}
}
else {
AlternativeFieldSignatureData signatureData = new AlternativeFieldSignatureData(field, propertyType, isVar);
if (signatureData.hasErrors()) {
trace.record(JavaBindingContext.LOAD_FROM_JAVA_SIGNATURE_ERRORS, propertyDescriptor,
Collections.singletonList(signatureData.getError()));
}
else if (signatureData.isAnnotated()) {
return signatureData.getReturnType();
}
return propertyType;
}
//TODO: doesn't work
private static void initializeSetterAndGetter(
@NotNull PropertyDescriptor propertyDescriptor,
@Nullable PropertyGetterDescriptorImpl getterDescriptor,
@Nullable PropertySetterDescriptorImpl setterDescriptor,
@NotNull JetType propertyType,
@NotNull PropertyPsiData data
) {
if (getterDescriptor != null) {
getterDescriptor.initialize(propertyType);
}
if (setterDescriptor != null) {
PropertyPsiDataElement setter = data.getSetter();
assert setter != null;
List<PsiParameter> parameters = ((PsiMethodWrapper) setter.getMember()).getParameters();
assert parameters.size() != 0;
setterDescriptor.initialize(new ValueParameterDescriptorImpl(
setterDescriptor,
0,
Collections.<AnnotationDescriptor>emptyList(),
Name.identifierNoValidate(""),
propertyDescriptor.getType(),
false,
null));
}
}
@Nullable
private PropertyGetterDescriptorImpl resolveGetter(
Visibility visibility,
CallableMemberDescriptor.Kind kind,
PropertyPsiDataElement getter,
PropertyDescriptor propertyDescriptor
) {
if (getter == null) {
return null;
}
return new PropertyGetterDescriptorImpl(
propertyDescriptor,
annotationResolver.resolveAnnotations(getter.getMember().getPsiMember()),
propertyDescriptor.getModality(),
visibility,
true,
false,
kind);
}
@Nullable
private PropertySetterDescriptorImpl resolveSetter(
PropertyPsiData psiData,
CallableMemberDescriptor.Kind kind,
PropertyDescriptor propertyDescriptor
) {
PropertyPsiDataElement setter = psiData.getSetter();
if (setter == null) {
return null;
}
Visibility setterVisibility = DescriptorResolverUtils.resolveVisibility(setter.getMember().getPsiMember());
if (setter.getMember() instanceof PsiMethodWrapper) {
setterVisibility = DescriptorResolverUtils.resolveVisibility(
setter.getMember().getPsiMember()
);
}
return new PropertySetterDescriptorImpl(
propertyDescriptor,
annotationResolver.resolveAnnotations(setter.getMember().getPsiMember()),
propertyDescriptor.getModality(),
setterVisibility,
true,
false,
kind);
}
private List<TypeParameterDescriptor> resolvePropertyTypeParameters(
@NotNull PropertyPsiData members,
@NotNull PropertyPsiDataElement characteristicMember,
@NotNull PropertyDescriptor propertyDescriptor
) {
// TODO: Can't get type parameters from field - only from accessors
if (characteristicMember == members.getSetter() || characteristicMember == members.getGetter()) {
PsiMethodWrapper method = (PsiMethodWrapper) characteristicMember.getMember();
return javaSignatureResolver.resolveMethodTypeParameters(method, propertyDescriptor);
}
return Collections.emptyList();
}
@NotNull
private JetType getPropertyType(
PropertyPsiData members,
PropertyPsiDataElement characteristicMember,
PsiFieldWrapper field,
TypeVariableResolver typeVariableResolverForPropertyInternals
) {
if (!characteristicMember.getType().getTypeString().isEmpty()) {
return semanticServices.getTypeTransformer().transformToType(
characteristicMember.getType().getTypeString(), typeVariableResolverForPropertyInternals);
}
JetType propertyType = semanticServices.getTypeTransformer().transformToType(
characteristicMember.getType().getPsiType(), typeVariableResolverForPropertyInternals);
field.getType(), typeVariableResolverForPropertyInternals);
boolean hasNotNullAnnotation = JavaAnnotationResolver.findAnnotationWithExternal(
characteristicMember.getType().getPsiNotNullOwner(),
field.getPsiField(),
JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().asString()) != null;
if (hasNotNullAnnotation || members.isStaticFinalField()) {
if (hasNotNullAnnotation || isStaticFinalField(field)) {
propertyType = TypeUtils.makeNotNullable(propertyType);
}
return propertyType;
}
@Nullable
private JetType getReceiverType(
PropertyPsiDataElement characteristicMember,
TypeVariableResolver typeVariableResolverForPropertyInternals
) {
if (characteristicMember.getReceiverType() == null) {
return null;
}
if (!characteristicMember.getReceiverType().getTypeString().isEmpty()) {
return semanticServices.getTypeTransformer()
.transformToType(characteristicMember.getReceiverType().getTypeString(), typeVariableResolverForPropertyInternals);
}
return semanticServices.getTypeTransformer()
.transformToType(characteristicMember.getReceiverType().getPsiType(), typeVariableResolverForPropertyInternals);
}
private static int getNumberOfNonExtensionProperties(@NotNull Collection<PropertyPsiData> propertyPsiDataCollection) {
int regularPropertiesCount = 0;
for (PropertyPsiData members : propertyPsiDataCollection) {
if (!members.isExtension()) {
++regularPropertiesCount;
}
}
return regularPropertiesCount;
}
@NotNull
private static Set<PropertyDescriptor> getPropertiesFromSupertypes(
@NotNull Name propertyName, @NotNull ClassOrNamespaceDescriptor ownerDescriptor
@@ -446,4 +275,8 @@ public final class JavaPropertyResolver {
}
return r;
}
private static boolean isStaticFinalField(@NotNull PsiFieldWrapper wrapper) {
return wrapper.isFinal() && wrapper.isStatic();
}
}
@@ -17,30 +17,26 @@
package org.jetbrains.jet.lang.resolve.java.resolver;
import com.google.common.collect.Lists;
import com.intellij.psi.*;
import jet.typeinfo.TypeInfoVariance;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiTypeParameter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.*;
import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices;
import org.jetbrains.jet.lang.resolve.java.TypeUsage;
import org.jetbrains.jet.lang.resolve.java.TypeVariableResolver;
import org.jetbrains.jet.lang.resolve.java.TypeVariableResolvers;
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.Variance;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.rt.signature.JetSignatureAdapter;
import org.jetbrains.jet.rt.signature.JetSignatureExceptionsAdapter;
import org.jetbrains.jet.rt.signature.JetSignatureReader;
import org.jetbrains.jet.rt.signature.JetSignatureVisitor;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -54,44 +50,17 @@ public final class JavaSignatureResolver {
this.semanticServices = javaSemanticServices;
}
private static boolean isJavaLangObject(@NotNull JetType type) {
ClassifierDescriptor classifierDescriptor = type.getConstructor().getDeclarationDescriptor();
return classifierDescriptor instanceof ClassDescriptor &&
DescriptorUtils.getFQName(classifierDescriptor).equalsTo(DescriptorResolverUtils.OBJECT_FQ_NAME);
}
private enum TypeParameterDescriptorOrigin {
JAVA,
KOTLIN,
}
public static class TypeParameterDescriptorInitialization {
@NotNull
private final TypeParameterDescriptorOrigin origin;
@NotNull
private final TypeParameterDescriptorImpl descriptor;
private final PsiTypeParameter psiTypeParameter;
@Nullable
private final List<JetType> upperBoundsForKotlin;
private TypeParameterDescriptorInitialization(
@NotNull TypeParameterDescriptorImpl descriptor,
@NotNull PsiTypeParameter psiTypeParameter
) {
this.origin = TypeParameterDescriptorOrigin.JAVA;
this.descriptor = descriptor;
this.psiTypeParameter = psiTypeParameter;
this.upperBoundsForKotlin = null;
}
private TypeParameterDescriptorInitialization(
@NotNull TypeParameterDescriptorImpl descriptor, @NotNull PsiTypeParameter psiTypeParameter,
@Nullable List<JetType> upperBoundsForKotlin
) {
this.origin = TypeParameterDescriptorOrigin.KOTLIN;
this.descriptor = descriptor;
this.psiTypeParameter = psiTypeParameter;
this.upperBoundsForKotlin = upperBoundsForKotlin;
}
@NotNull
@@ -101,159 +70,6 @@ public final class JavaSignatureResolver {
}
@NotNull
private static PsiTypeParameter getPsiTypeParameterByName(PsiTypeParameterListOwner clazz, String name) {
for (PsiTypeParameter typeParameter : clazz.getTypeParameters()) {
if (typeParameter.getName().equals(name)) {
return typeParameter;
}
}
throw new IllegalStateException("PsiTypeParameter '" + name + "' is not found");
}
private abstract class JetSignatureTypeParameterVisitor extends JetSignatureExceptionsAdapter {
@NotNull
private final PsiTypeParameterListOwner psiOwner;
@NotNull
private final String name;
@NotNull
private final TypeVariableResolver typeVariableResolver;
@NotNull
private final TypeParameterDescriptorImpl typeParameterDescriptor;
protected JetSignatureTypeParameterVisitor(
@NotNull PsiTypeParameterListOwner psiOwner,
@NotNull String name,
@NotNull TypeVariableResolver typeVariableResolver,
@NotNull TypeParameterDescriptorImpl typeParameterDescriptor
) {
if (name.isEmpty()) {
throw new IllegalStateException();
}
this.psiOwner = psiOwner;
this.name = name;
this.typeVariableResolver = typeVariableResolver;
this.typeParameterDescriptor = typeParameterDescriptor;
}
List<JetType> upperBounds = new ArrayList<JetType>();
@Override
public JetSignatureVisitor visitClassBound() {
return new JetTypeJetSignatureReader(semanticServices, KotlinBuiltIns.getInstance(), typeVariableResolver) {
@Override
protected void done(@NotNull JetType jetType) {
if (isJavaLangObject(jetType)) {
return;
}
upperBounds.add(jetType);
}
};
}
@Override
public JetSignatureVisitor visitInterfaceBound() {
return new JetTypeJetSignatureReader(semanticServices, KotlinBuiltIns.getInstance(), typeVariableResolver) {
@Override
protected void done(@NotNull JetType jetType) {
upperBounds.add(jetType);
}
};
}
@Override
public void visitFormalTypeParameterEnd() {
PsiTypeParameter psiTypeParameter = getPsiTypeParameterByName(psiOwner, name);
TypeParameterDescriptorInitialization typeParameterDescriptorInitialization =
new TypeParameterDescriptorInitialization(typeParameterDescriptor, psiTypeParameter, upperBounds);
done(typeParameterDescriptorInitialization);
}
protected abstract void done(@NotNull TypeParameterDescriptorInitialization typeParameterDescriptor);
}
private class JetSignatureTypeParametersVisitor extends JetSignatureExceptionsAdapter {
@NotNull
private final DeclarationDescriptor containingDeclaration;
@NotNull
private final PsiTypeParameterListOwner psiOwner;
private final List<TypeParameterDescriptor> previousTypeParameters = new ArrayList<TypeParameterDescriptor>();
// note changes state in this method
private final TypeVariableResolver typeVariableResolver;
private JetSignatureTypeParametersVisitor(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull PsiTypeParameterListOwner psiOwner,
@NotNull String context
) {
this.containingDeclaration = containingDeclaration;
this.psiOwner = psiOwner;
this.typeVariableResolver = TypeVariableResolvers.typeVariableResolverFromTypeParameters(
previousTypeParameters,
containingDeclaration,
context);
}
private int formalTypeParameterIndex = 0;
List<TypeParameterDescriptorInitialization> r = new ArrayList<TypeParameterDescriptorInitialization>();
@Override
public JetSignatureVisitor visitFormalTypeParameter(final String name, TypeInfoVariance variance, boolean reified) {
TypeParameterDescriptorImpl typeParameter = TypeParameterDescriptorImpl.createForFurtherModification(
containingDeclaration,
Collections.<AnnotationDescriptor>emptyList(), // TODO: wrong
reified,
JetSignatureUtils.translateVariance(variance),
Name.identifier(name),
formalTypeParameterIndex++);
previousTypeParameters.add(typeParameter);
return new JetSignatureTypeParameterVisitor(psiOwner, name, typeVariableResolver, typeParameter) {
@Override
protected void done(@NotNull TypeParameterDescriptorInitialization typeParameterDescriptor) {
r.add(typeParameterDescriptor);
previousTypeParameters.add(typeParameterDescriptor.descriptor);
}
};
}
}
/**
* @see #resolveMethodTypeParametersFromJetSignature(String, PsiMethod, DeclarationDescriptor)
*/
private List<TypeParameterDescriptorInitialization> resolveClassTypeParametersFromJetSignature(
String jetSignature,
final PsiClass clazz, final ClassDescriptor classDescriptor
) {
String context = "class " + clazz.getQualifiedName();
JetSignatureTypeParametersVisitor jetSignatureTypeParametersVisitor =
new JetSignatureTypeParametersVisitor(classDescriptor, clazz, context) {
@Override
public JetSignatureVisitor visitSuperclass() {
// TODO
return new JetSignatureAdapter();
}
@Override
public JetSignatureVisitor visitInterface() {
// TODO
return new JetSignatureAdapter();
}
};
new JetSignatureReader(jetSignature).accept(jetSignatureTypeParametersVisitor);
return jetSignatureTypeParametersVisitor.r;
}
private static List<TypeParameterDescriptorInitialization> makeUninitializedTypeParameters(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull PsiTypeParameter[] typeParameters
@@ -288,37 +104,21 @@ public final class JavaSignatureResolver {
TypeVariableResolver typeVariableByPsiResolver
) {
TypeParameterDescriptorImpl typeParameterDescriptor = typeParameter.descriptor;
if (typeParameter.origin == TypeParameterDescriptorOrigin.KOTLIN) {
List<JetType> upperBoundsForKotlin = typeParameter.upperBoundsForKotlin;
assert upperBoundsForKotlin != null;
if (upperBoundsForKotlin.size() == 0) {
typeParameterDescriptor.addUpperBound(KotlinBuiltIns.getInstance().getNullableAnyType());
}
else {
for (JetType upperBound : upperBoundsForKotlin) {
typeParameterDescriptor.addUpperBound(upperBound);
}
}
// TODO: lower bounds
PsiClassType[] referencedTypes = typeParameter.psiTypeParameter.getExtendsList().getReferencedTypes();
if (referencedTypes.length == 0) {
typeParameterDescriptor.addUpperBound(KotlinBuiltIns.getInstance().getNullableAnyType());
}
else if (referencedTypes.length == 1) {
typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer()
.transformToType(referencedTypes[0], TypeUsage.UPPER_BOUND,
typeVariableByPsiResolver));
}
else {
PsiClassType[] referencedTypes = typeParameter.psiTypeParameter.getExtendsList().getReferencedTypes();
if (referencedTypes.length == 0) {
typeParameterDescriptor.addUpperBound(KotlinBuiltIns.getInstance().getNullableAnyType());
}
else if (referencedTypes.length == 1) {
for (PsiClassType referencedType : referencedTypes) {
typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer()
.transformToType(referencedTypes[0], TypeUsage.UPPER_BOUND,
.transformToType(referencedType, TypeUsage.UPPER_BOUND,
typeVariableByPsiResolver));
}
else {
for (PsiClassType referencedType : referencedTypes) {
typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer()
.transformToType(referencedType, TypeUsage.UPPER_BOUND,
typeVariableByPsiResolver));
}
}
}
typeParameterDescriptor.setInitialized();
}
@@ -379,20 +179,4 @@ public final class JavaSignatureResolver {
return typeParameters;
}
/**
* @see #resolveClassTypeParametersFromJetSignature(String, PsiClass, ClassDescriptor)
*/
private List<TypeParameterDescriptorInitialization> resolveMethodTypeParametersFromJetSignature(
String jetSignature,
PsiMethod method, DeclarationDescriptor functionDescriptor
) {
PsiClass methodContainingClass = method.getContainingClass();
assert methodContainingClass != null;
String context = "method " + method.getName() + " in class " + methodContainingClass.getQualifiedName();
JetSignatureTypeParametersVisitor jetSignatureTypeParametersVisitor =
new JetSignatureTypeParametersVisitor(functionDescriptor, method, context);
new JetSignatureReader(jetSignature).acceptFormalTypeParametersOnly(jetSignatureTypeParametersVisitor);
return jetSignatureTypeParametersVisitor.r;
}
}
@@ -1,200 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.wrapper;
import com.google.common.collect.Lists;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMember;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.TypeSource;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/*
* Data from PSI related to one property used to resolve this property.
*/
public final class PropertyPsiData {
@NotNull
public static Collection<PropertyPsiData> assemblePropertyPsiDataFromElements(@NotNull List<PropertyPsiDataElement> elements) {
Map<String, PropertyPsiData> map = new HashMap<String, PropertyPsiData>();
for (PropertyPsiDataElement element : elements) {
String key = propertyKeyForGrouping(element);
PropertyPsiData value = map.get(key);
if (value == null) {
value = new PropertyPsiData();
map.put(key, value);
}
if (element.isGetter()) {
checkDuplicatePropertyComponent(element, "getter", value.getter);
value.getter = element;
}
else if (element.isSetter()) {
checkDuplicatePropertyComponent(element, "setter", value.setter);
value.setter = element;
}
else if (element.isField()) {
checkDuplicatePropertyComponent(element, "field", value.field);
value.field = element;
}
else {
throw new IllegalStateException();
}
}
return map.values();
}
private static void checkDuplicatePropertyComponent(
@NotNull PropertyPsiDataElement checked, @NotNull String componentTypeName, @Nullable PropertyPsiDataElement existent
) {
if (existent != null) {
PsiClass checkedElementClass = checked.getMember().getPsiMember().getContainingClass();
PsiClass existentElementClass = existent.getMember().getPsiMember().getContainingClass();
throw new IllegalStateException(
String.format("Psi element '%s' in class '%s' overwrites '%s' in class '%s' while generating %s component for property",
checked.getMember().getPsiMember(),
checkedElementClass != null ? checkedElementClass.getQualifiedName() : "<no-class>",
existent.getMember().getPsiMember(),
existentElementClass != null ? existentElementClass.getQualifiedName() : "<no-class>",
componentTypeName));
}
}
@NotNull
private static String propertyKeyForGrouping(@NotNull PropertyPsiDataElement propertyAccessor) {
String type = key(propertyAccessor.getType());
String receiverType = key(propertyAccessor.getReceiverType());
return Pair.create(type, receiverType).toString();
}
@NotNull
private static String key(@Nullable TypeSource typeSource) {
if (typeSource == null) {
return "";
}
else if (typeSource.getTypeString().length() > 0) {
return typeSource.getTypeString();
}
else {
return typeSource.getPsiType().getPresentableText();
}
}
@Nullable
private PropertyPsiDataElement getter = null;
@Nullable
private PropertyPsiDataElement setter = null;
@Nullable
private PropertyPsiDataElement field = null;
@Nullable
private Collection<PropertyPsiDataElement> elements = null;
@Nullable
public PropertyPsiDataElement getGetter() {
return getter;
}
@Nullable
public PropertyPsiDataElement getSetter() {
return setter;
}
@SuppressWarnings("ConstantConditions")
@NotNull
private Collection<PropertyPsiDataElement> getElements() {
if (elements == null) {
elements = Lists.newArrayList();
if (getter != null) {
elements.add(getter);
}
if (setter != null) {
elements.add(setter);
}
if (field != null) {
elements.add(field);
}
assert !elements.isEmpty();
}
return elements;
}
public boolean isExtension() {
boolean isExtension = getCharacteristicMember().isExtension();
for (PropertyPsiDataElement element : getElements()) {
assert (element.isExtension() == isExtension);
}
return isExtension;
}
public boolean isStatic() {
boolean isStatic = getCharacteristicMember().getMember().isStatic();
for (PropertyPsiDataElement element : getElements()) {
assert (element.getMember().isStatic() == isStatic);
}
return isStatic;
}
@NotNull
public PropertyPsiDataElement getCharacteristicMember() {
if (getter != null) {
return getter;
}
if (field != null) {
return field;
}
if (setter != null) {
return setter;
}
throw new IllegalStateException();
}
@NotNull
public PsiMember getCharacteristicPsi() {
return getCharacteristicMember().getMember().getPsiMember();
}
public boolean isVar() {
if (getter == null && setter == null) {
assert field != null;
return !field.getMember().isFinal();
}
return setter != null;
}
public boolean isStaticFinalField() {
if (getter != null || setter != null) {
return false;
}
assert field != null;
return field.getMember().isFinal() && field.getMember().isStatic();
}
public boolean isPropertyForNamedObject() {
return field != null && JvmAbi.INSTANCE_FIELD.equals(field.getMember().getName());
}
}
@@ -1,76 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.wrapper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.TypeSource;
/**
* Some PSI corresponding to a property: getter, setter or field.
*/
public final class PropertyPsiDataElement {
@NotNull
private final PsiMemberWrapper member;
// for methods
private final boolean getter;
@NotNull
private final TypeSource type;
@Nullable
private final TypeSource receiverType;
public PropertyPsiDataElement(@NotNull PsiFieldWrapper field, @NotNull TypeSource type, @Nullable TypeSource receiverType) {
this.member = field;
this.type = type;
this.receiverType = receiverType;
this.getter = false;
}
@NotNull
public PsiMemberWrapper getMember() {
return member;
}
@NotNull
public TypeSource getType() {
return type;
}
@Nullable
public TypeSource getReceiverType() {
return receiverType;
}
boolean isExtension() {
return getReceiverType() != null;
}
public boolean isGetter() {
return member instanceof PsiMethodWrapper && getter;
}
public boolean isSetter() {
return member instanceof PsiMethodWrapper && !getter;
}
public boolean isField() {
return member instanceof PsiFieldWrapper;
}
}