提交 4ded2e79 编写于 作者: S Stepan Koltsov

refactor java descriptor resolver

上级 c18a5009
......@@ -2,15 +2,26 @@ package org.jetbrains.jet.lang.resolve.java;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.intellij.psi.*;
import com.intellij.psi.HierarchicalMethodSignature;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
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.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
import java.util.*;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author abreslav
......@@ -20,8 +31,6 @@ public class JavaClassMembersScope implements JetScope {
private final JavaSemanticServices semanticServices;
private final boolean staticMembers;
private final DeclarationDescriptor containingDeclaration;
private final Map<String, Set<FunctionDescriptor>> functionGroups = Maps.newHashMap();
private final Map<String, Set<VariableDescriptor>> variables = Maps.newHashMap();
private final Map<String, ClassifierDescriptor> classifiers = Maps.newHashMap();
private Collection<DeclarationDescriptor> allDescriptors;
......@@ -76,7 +85,7 @@ public class JavaClassMembersScope implements JetScope {
if (method.hasModifierProperty(PsiModifier.STATIC) != staticMembers) {
continue;
}
FunctionDescriptor functionDescriptor = semanticServices.getDescriptorResolver().resolveMethodToFunctionDescriptor(containingDeclaration, psiClass, substitutorForGenericSupertypes, method);
FunctionDescriptor functionDescriptor = semanticServices.getDescriptorResolver().resolveMethodToFunctionDescriptor(containingDeclaration, psiClass, substitutorForGenericSupertypes, new PsiMethodWrapper(method));
if (functionDescriptor != null) {
allDescriptors.add(functionDescriptor);
}
......@@ -117,14 +126,7 @@ public class JavaClassMembersScope implements JetScope {
@NotNull
@Override
public Set<VariableDescriptor> getProperties(@NotNull String name) {
Set<VariableDescriptor> variableDescriptor = variables.get(name);
if (variableDescriptor == null) {
variableDescriptor = doGetVariable(name);
if (variableDescriptor != null) {
variables.put(name, variableDescriptor);
}
}
return variableDescriptor != null ? variableDescriptor : Collections.<VariableDescriptor>emptySet();
return semanticServices.getDescriptorResolver().resolveFieldGroupByName(containingDeclaration, psiClass, name, staticMembers);
}
@Override
......@@ -132,32 +134,15 @@ public class JavaClassMembersScope implements JetScope {
return null;
}
@Nullable
private Set<VariableDescriptor> doGetVariable(String name) {
PsiField field = psiClass.findFieldByName(name, true);
if (field == null) return null;
if (field.hasModifierProperty(PsiModifier.STATIC) != staticMembers) {
return null;
}
//return semanticServices.getDescriptorResolver().resolveFieldToVariableDescriptor(containingDeclaration, field);
return semanticServices.getDescriptorResolver().resolveFieldGroupByName(containingDeclaration, psiClass, name, staticMembers);
}
@NotNull
@Override
public Set<FunctionDescriptor> getFunctions(@NotNull String name) {
Set<FunctionDescriptor> functionGroup = functionGroups.get(name);
if (functionGroup == null) {
functionGroup = semanticServices.getDescriptorResolver().resolveFunctionGroup(
return semanticServices.getDescriptorResolver().resolveFunctionGroup(
containingDeclaration,
psiClass,
staticMembers ? null : (ClassDescriptor) containingDeclaration,
name,
staticMembers);
functionGroups.put(name, functionGroup);
}
return functionGroup;
}
@Override
......
......@@ -4,15 +4,12 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.HierarchicalMethodSignature;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiEllipsisType;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiJavaFile;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
......@@ -63,6 +60,7 @@ import org.jetbrains.jet.rt.signature.JetSignatureVisitor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
......@@ -129,10 +127,11 @@ public class JavaDescriptorResolver {
}
}
private static abstract class ResolverScopeData {
@Nullable
private Set<VariableDescriptor> properties;
protected boolean kotlin;
private Map<String, NamedMembers> namedMembersMap;
}
private static class ResolverClassData extends ResolverScopeData {
......@@ -159,7 +158,6 @@ public class JavaDescriptorResolver {
private final Map<PsiTypeParameter, TypeParameterDescriptorInitialization> typeParameterDescriptorCache = Maps.newHashMap();
protected final Map<PsiMethod, FunctionDescriptor> methodDescriptorCache = Maps.newHashMap();
protected final Map<PsiField, VariableDescriptor> fieldDescriptorCache = Maps.newHashMap();
protected final JavaPsiFacade javaFacade;
protected final GlobalSearchScope javaSearchScope;
protected final JavaSemanticServices semanticServices;
......@@ -781,239 +779,53 @@ public class JavaDescriptorResolver {
}
}
/*
public VariableDescriptor resolveFieldToVariableDescriptor(DeclarationDescriptor containingDeclaration, PsiField field) {
VariableDescriptor variableDescriptor = fieldDescriptorCache.get(field);
if (variableDescriptor != null) {
return variableDescriptor;
}
JetType type = semanticServices.getTypeTransformer().transformToType(field.getType());
boolean isFinal = field.hasModifierProperty(PsiModifier.FINAL);
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
containingDeclaration,
Collections.<AnnotationDescriptor>emptyList(),
Modality.FINAL,
resolveVisibilityFromPsiModifiers(field),
!isFinal,
null,
DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration),
field.getName(),
type);
semanticServices.getTrace().record(BindingContext.VARIABLE, field, propertyDescriptor);
fieldDescriptorCache.put(field, propertyDescriptor);
return propertyDescriptor;
}
*/
private static class PropertyKey {
@NotNull
private final String name;
//@NotNull
//private final PsiType type;
//@Nullable
//private final PsiType receiverType;
private PropertyKey(@NotNull String name /*, @NotNull PsiType type, @Nullable PsiType receiverType */) {
this.name = name;
//this.type = type;
//this.receiverType = receiverType;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PropertyKey that = (PropertyKey) o;
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;
return true;
}
@Override
public int hashCode() {
int result = name.hashCode();
//result = 31 * result + type.hashCode();
//result = 31 * result + (receiverType != null ? receiverType.hashCode() : 0);
return result;
}
}
private static class MembersForProperty {
private PsiFieldWrapper field;
private PsiMethodWrapper setter;
private PsiMethodWrapper getter;
private PsiType type;
private PsiType receiverType;
}
private Map<PropertyKey, MembersForProperty> getMembersForProperties(@NotNull PsiClass clazz, boolean staticMembers, boolean kotlin) {
Map<PropertyKey, MembersForProperty> membersMap = Maps.newHashMap();
if (!kotlin) {
for (PsiField field : clazz.getFields()) {
if (field.getModifierList().hasExplicitModifier(PsiModifier.STATIC) != staticMembers) {
continue;
}
if (field.hasModifierProperty(PsiModifier.PRIVATE)) {
continue;
}
public Set<VariableDescriptor> resolveFieldGroupByName(@NotNull DeclarationDescriptor owner, PsiClass psiClass, String fieldName, boolean staticMembers) {
ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass));
MembersForProperty members = new MembersForProperty();
members.field = new PsiFieldWrapper(field);
members.type = field.getType();
membersMap.put(new PropertyKey(field.getName() /*, field.getType(), null*/), members);
}
NamedMembers namedMembers = scopeData.namedMembersMap.get(fieldName);
if (namedMembers == null) {
return Collections.emptySet();
}
for (PsiMethod psiMethod : clazz.getMethods()) {
PsiMethodWrapper method = new PsiMethodWrapper(psiMethod);
resolveNamedGroupProperties(owner, staticMembers, namedMembers, fieldName);
if (method.isStatic() != staticMembers) {
continue;
return namedMembers.propertyDescriptors;
}
if (method.isPrivate()) {
continue;
}
// TODO: "is" prefix
// TODO: remove getJavaClass
if (psiMethod.getName().startsWith(JvmAbi.GETTER_PREFIX)) {
@NotNull
public Set<VariableDescriptor> resolveFieldGroup(@NotNull DeclarationDescriptor owner, PsiClass psiClass, boolean staticMembers) {
// TODO: some java properties too
if (method.getJetMethod().kind() == JvmStdlibNames.JET_METHOD_KIND_PROPERTY) {
ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass));
if (psiMethod.getName().equals(JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD)) {
Set<VariableDescriptor> descriptors = Sets.newHashSet();
Map<String, NamedMembers> membersForProperties = scopeData.namedMembersMap;
for (Map.Entry<String, NamedMembers> entry : membersForProperties.entrySet()) {
NamedMembers namedMembers = entry.getValue();
if (namedMembers.properties == null) {
continue;
}
int i = 0;
PsiType receiverType;
if (i < method.getParameters().size() && method.getParameter(i).getJetValueParameter().receiver()) {
receiverType = method.getParameter(i).getPsiParameter().getType();
++i;
} else {
receiverType = null;
}
while (i < method.getParameters().size() && method.getParameter(i).getJetTypeParameter().isDefined()) {
// TODO: store is reified
++i;
}
if (i != method.getParameters().size()) {
// TODO: report error properly
throw new IllegalStateException();
}
String propertyName = StringUtil.decapitalize(psiMethod.getName().substring(JvmAbi.GETTER_PREFIX.length()));
PropertyKey key = new PropertyKey(propertyName /*, psiMethod.getReturnType(), receiverType*/);
MembersForProperty members = membersMap.get(key);
if (members == null) {
members = new MembersForProperty();
membersMap.put(key, members);
}
members.getter = new PsiMethodWrapper(psiMethod);
// TODO: check conflicts with setter
members.type = psiMethod.getReturnType();
members.receiverType = receiverType;
}
} else if (psiMethod.getName().startsWith(JvmAbi.SETTER_PREFIX)) {
if (method.getJetMethod().kind() == JvmStdlibNames.JET_METHOD_KIND_PROPERTY) {
if (psiMethod.getParameterList().getParametersCount() == 0) {
// TODO: report error properly
throw new IllegalStateException();
}
int i = 0;
PsiType receiverType = null;
PsiParameterWrapper p1 = method.getParameter(0);
if (p1.getJetValueParameter().receiver()) {
receiverType = p1.getPsiParameter().getType();
++i;
}
while (i < method.getParameters().size() && method.getParameter(i).getJetTypeParameter().isDefined()) {
++i;
}
if (i + 1 != psiMethod.getParameterList().getParametersCount()) {
throw new IllegalStateException();
}
String propertyName = entry.getKey();
PsiType propertyType = psiMethod.getParameterList().getParameters()[i].getType();
String propertyName = StringUtil.decapitalize(psiMethod.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);
resolveNamedGroupProperties(owner, staticMembers, namedMembers, propertyName);
descriptors.addAll(namedMembers.propertyDescriptors);
}
members.setter = new PsiMethodWrapper(psiMethod);
// TODO: check conflicts with getter
members.type = propertyType;
members.receiverType = receiverType;
}
}
}
return membersMap;
}
public Set<VariableDescriptor> resolveFieldGroupByName(@NotNull DeclarationDescriptor owner, PsiClass psiClass, String fieldName, boolean staticMembers) {
Set<VariableDescriptor> r = Sets.newHashSet();
// TODO: slow
Set<VariableDescriptor> variables = resolveFieldGroup(owner, psiClass, staticMembers);
for (VariableDescriptor variable : variables) {
if (variable.getName().equals(fieldName)) {
r.add(variable);
}
}
return r;
return descriptors;
}
@NotNull
public Set<VariableDescriptor> resolveFieldGroup(@NotNull DeclarationDescriptor owner, PsiClass psiClass, boolean staticMembers) {
ResolverScopeData scopeData;
if (owner instanceof JavaNamespaceDescriptor) {
scopeData = namespaceDescriptorCacheByFqn.get(((JavaNamespaceDescriptor) owner).getQualifiedName());
} else if (owner instanceof ClassDescriptor) {
scopeData = classDescriptorCache.get(psiClass.getQualifiedName());
} else {
throw new IllegalStateException();
}
if (scopeData == null) {
throw new IllegalStateException();
private void resolveNamedGroupProperties(DeclarationDescriptor owner, boolean staticMembers, NamedMembers namedMembers, String propertyName) {
if (namedMembers.propertyDescriptors != null) {
return;
}
if (scopeData.properties != null) {
return scopeData.properties;
if (namedMembers.properties == null) {
namedMembers.propertyDescriptors = Collections.emptySet();
return;
}
Set<VariableDescriptor> descriptors = Sets.newHashSet();
Map<PropertyKey, MembersForProperty> membersForProperties = getMembersForProperties(psiClass, staticMembers, scopeData.kotlin);
for (Map.Entry<PropertyKey, MembersForProperty> entry : membersForProperties.entrySet()) {
//VariableDescriptor variableDescriptor = fieldDescriptorCache.get(field);
//if (variableDescriptor != null) {
// return variableDescriptor;
//}
String propertyName = entry.getKey().name;
PsiType propertyType = entry.getValue().type;
PsiType receiverType = entry.getValue().receiverType;
MembersForProperty members = entry.getValue();
PsiType propertyType = namedMembers.properties.type;
PsiType receiverType = namedMembers.properties.receiverType;
MembersForProperty members = namedMembers.properties;
boolean isFinal;
if (members.setter == null && members.getter == null) {
......@@ -1106,44 +918,65 @@ public class JavaDescriptorResolver {
}
semanticServices.getTrace().record(BindingContext.VARIABLE, anyMember.psiMember, propertyDescriptor);
//fieldDescriptorCache.put(field, propertyDescriptor);
descriptors.add(propertyDescriptor);
namedMembers.propertyDescriptors = Collections.<VariableDescriptor>singleton(propertyDescriptor);
}
scopeData.properties = descriptors;
return descriptors;
private void resolveNamedGroupFunctions(DeclarationDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, boolean staticMembers, NamedMembers namedMembers, String functionName) {
if (namedMembers.functionDescriptors != null) {
return;
}
@NotNull
public Set<FunctionDescriptor> resolveFunctionGroup(@NotNull DeclarationDescriptor owner, @NotNull PsiClass psiClass, @Nullable ClassDescriptor classDescriptor, @NotNull String methodName, boolean staticMembers) {
Set<FunctionDescriptor> writableFunctionGroup = Sets.newLinkedHashSet();
final Collection<HierarchicalMethodSignature> signatures = psiClass.getVisibleSignatures();
TypeSubstitutor typeSubstitutor = createSubstitutorForGenericSupertypes(classDescriptor);
for (HierarchicalMethodSignature signature: signatures) {
if (!methodName.equals(signature.getName())) {
continue;
if (namedMembers.methods == null) {
namedMembers.functionDescriptors = Collections.emptySet();
return;
}
FunctionDescriptor substitutedFunctionDescriptor = resolveHierarchicalSignatureToFunction(owner, psiClass, staticMembers, typeSubstitutor, signature);
if (substitutedFunctionDescriptor != null) {
writableFunctionGroup.add(substitutedFunctionDescriptor);
Set<FunctionDescriptor> functionDescriptors = new HashSet<FunctionDescriptor>(namedMembers.methods.size());
for (PsiMethodWrapper method : namedMembers.methods) {
functionDescriptors.add(resolveMethodToFunctionDescriptor(owner, psiClass, typeSubstitutorForGenericSuperclasses, method));
}
namedMembers.functionDescriptors = functionDescriptors;
}
return writableFunctionGroup;
private ResolverScopeData getResolverScopeData(DeclarationDescriptor owner, PsiClassWrapper psiClass) {
ResolverScopeData scopeData;
boolean staticMembers;
if (owner instanceof JavaNamespaceDescriptor) {
scopeData = namespaceDescriptorCacheByFqn.get(((JavaNamespaceDescriptor) owner).getQualifiedName());
staticMembers = true;
} else if (owner instanceof ClassDescriptor) {
scopeData = classDescriptorCache.get(psiClass.getQualifiedName());
staticMembers = false;
} else {
throw new IllegalStateException();
}
if (scopeData == null) {
throw new IllegalStateException();
}
@Nullable
private FunctionDescriptor resolveHierarchicalSignatureToFunction(DeclarationDescriptor owner, PsiClass psiClass, boolean staticMembers, TypeSubstitutor typeSubstitutor, HierarchicalMethodSignature signature) {
PsiMethod method = signature.getMethod();
if (method.hasModifierProperty(PsiModifier.STATIC) != staticMembers) {
return null;
if (scopeData.namedMembersMap == null) {
scopeData.namedMembersMap = JavaDescriptorResolverHelper.getNamedMembers(psiClass, staticMembers, scopeData.kotlin);
}
FunctionDescriptor functionDescriptor = resolveMethodToFunctionDescriptor(owner, psiClass, typeSubstitutor, method);
// if (functionDescriptor != null && !staticMembers) {
// for (HierarchicalMethodSignature superSignature : signature.getSuperSignatures()) {
// ((FunctionDescriptorImpl) functionDescriptor).addOverriddenFunction(resolveHierarchicalSignatureToFunction(owner, superSignature.getMethod().getContainingClass(), false, typeSubstitutor, superSignature));
// }
// }
return functionDescriptor;
return scopeData;
}
@NotNull
public Set<FunctionDescriptor> resolveFunctionGroup(@NotNull DeclarationDescriptor owner, @NotNull PsiClass psiClass, @Nullable ClassDescriptor classDescriptor, @NotNull String methodName, boolean staticMembers) {
ResolverScopeData resolverScopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass));
Map<String, NamedMembers> namedMembersMap = resolverScopeData.namedMembersMap;
NamedMembers namedMembers = namedMembersMap.get(methodName);
if (namedMembers == null || namedMembers.methods == null) {
return Collections.emptySet();
}
TypeSubstitutor typeSubstitutor = createSubstitutorForGenericSupertypes(classDescriptor);
resolveNamedGroupFunctions(owner, psiClass, typeSubstitutor, staticMembers, namedMembers, methodName);
return namedMembers.functionDescriptors;
}
public TypeSubstitutor createSubstitutorForGenericSupertypes(ClassDescriptor classDescriptor) {
......@@ -1178,16 +1011,15 @@ public class JavaDescriptorResolver {
}
@Nullable
public FunctionDescriptor resolveMethodToFunctionDescriptor(DeclarationDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, PsiMethod psiMethod) {
PsiMethodWrapper method = new PsiMethodWrapper(psiMethod);
public FunctionDescriptor resolveMethodToFunctionDescriptor(DeclarationDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, PsiMethodWrapper method) {
PsiType returnType = psiMethod.getReturnType();
PsiType returnType = method.getReturnType();
if (returnType == null) {
return null;
}
FunctionDescriptor functionDescriptor = methodDescriptorCache.get(psiMethod);
FunctionDescriptor functionDescriptor = methodDescriptorCache.get(method.getPsiMethod());
if (functionDescriptor != null) {
if (psiMethod.getContainingClass() != psiClass) {
if (method.getPsiMethod().getContainingClass() != psiClass) {
functionDescriptor = functionDescriptor.substitute(typeSubstitutorForGenericSuperclasses);
}
return functionDescriptor;
......@@ -1238,11 +1070,11 @@ public class JavaDescriptorResolver {
DeclarationDescriptor classDescriptor;
final List<TypeParameterDescriptor> classTypeParameters;
if (method.isStatic()) {
classDescriptor = resolveNamespace(psiMethod.getContainingClass());
classDescriptor = resolveNamespace(method.getPsiMethod().getContainingClass());
classTypeParameters = Collections.emptyList();
}
else {
ClassDescriptor classClassDescriptor = resolveClass(psiMethod.getContainingClass());
ClassDescriptor classClassDescriptor = resolveClass(method.getPsiMethod().getContainingClass());
classDescriptor = classClassDescriptor;
classTypeParameters = classClassDescriptor.getTypeConstructor().getParameters();
}
......@@ -1252,14 +1084,14 @@ public class JavaDescriptorResolver {
NamedFunctionDescriptorImpl functionDescriptorImpl = new NamedFunctionDescriptorImpl(
owner,
Collections.<AnnotationDescriptor>emptyList(), // TODO
psiMethod.getName()
method.getName()
);
methodDescriptorCache.put(psiMethod, functionDescriptorImpl);
methodDescriptorCache.put(method.getPsiMethod(), functionDescriptorImpl);
// TODO: add outer classes
TypeParameterListTypeVariableResolver typeVariableResolverForParameters = new TypeParameterListTypeVariableResolver(classTypeParameters);
final List<TypeParameterDescriptor> methodTypeParameters = resolveMethodTypeParameters(new PsiMethodWrapper(psiMethod), functionDescriptorImpl, typeVariableResolverForParameters);
final List<TypeParameterDescriptor> methodTypeParameters = resolveMethodTypeParameters(method, functionDescriptorImpl, typeVariableResolverForParameters);
class MethodTypeVariableResolver implements TypeVariableResolver {
......@@ -1288,12 +1120,12 @@ public class JavaDescriptorResolver {
methodTypeParameters,
valueParameterDescriptors.descriptors,
makeReturnType(returnType, method, new MethodTypeVariableResolver()),
Modality.convertFromFlags(psiMethod.hasModifierProperty(PsiModifier.ABSTRACT), !psiMethod.hasModifierProperty(PsiModifier.FINAL)),
resolveVisibilityFromPsiModifiers(psiMethod)
Modality.convertFromFlags(method.getPsiMethod().hasModifierProperty(PsiModifier.ABSTRACT), !method.isFinal()),
resolveVisibilityFromPsiModifiers(method.getPsiMethod())
);
semanticServices.getTrace().record(BindingContext.FUNCTION, psiMethod, functionDescriptorImpl);
semanticServices.getTrace().record(BindingContext.FUNCTION, method.getPsiMethod(), functionDescriptorImpl);
FunctionDescriptor substitutedFunctionDescriptor = functionDescriptorImpl;
if (psiMethod.getContainingClass() != psiClass) {
if (method.getPsiMethod().getContainingClass() != psiClass) {
substitutedFunctionDescriptor = functionDescriptorImpl.substitute(typeSubstitutorForGenericSuperclasses);
}
return substitutedFunctionDescriptor;
......@@ -1400,7 +1232,7 @@ public class JavaDescriptorResolver {
ownerOwner = classDescriptor;
substitutorForGenericSupertypes = semanticServices.getDescriptorResolver().createSubstitutorForGenericSupertypes(classDescriptor);
}
FunctionDescriptor functionDescriptor = resolveMethodToFunctionDescriptor(ownerOwner, containingClass, substitutorForGenericSupertypes, psiMethod);
FunctionDescriptor functionDescriptor = resolveMethodToFunctionDescriptor(ownerOwner, containingClass, substitutorForGenericSupertypes, new PsiMethodWrapper(psiMethod));
return resolveTypeParameter(functionDescriptor, typeParameter);
}
throw new IllegalStateException("Unknown parent type: " + owner);
......
package org.jetbrains.jet.lang.resolve.java;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.HierarchicalMethodSignature;
import com.intellij.psi.PsiType;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
/**
* @author Stepan Koltsov
*/
class JavaDescriptorResolverHelper {
private static class Builder {
private final PsiClassWrapper psiClass;
private final boolean staticMembers;
private final boolean kotlin;
private Map<String, NamedMembers> namedMembersMap = new HashMap<String, NamedMembers>();
private Builder(PsiClassWrapper psiClass, boolean staticMembers, boolean kotlin) {
this.psiClass = psiClass;
this.staticMembers = staticMembers;
this.kotlin = kotlin;
}
public void run() {
processFields();
processMethods();
}
private NamedMembers getNamedMembers(String name) {
NamedMembers r = namedMembersMap.get(name);
if (r == null) {
r = new NamedMembers();
r.name = name;
namedMembersMap.put(name, r);
}
return r;
}
private void processFields() {
if (!kotlin) {
for (PsiFieldWrapper field : psiClass.getFields()) {
if (field.isStatic() != staticMembers) {
continue;
}
if (field.isPrivate()) {
continue;
}
NamedMembers namedMembers = getNamedMembers(field.getName());
MembersForProperty members = new MembersForProperty();
members.field = field;
members.type = field.getType();
namedMembers.properties = members;
}
}
}
private void processMethods() {
for (HierarchicalMethodSignature method0 : psiClass.getPsiClass().getVisibleSignatures()) {
PsiMethodWrapper method = new PsiMethodWrapper(method0.getMethod());
if (method.isStatic() != staticMembers) {
continue;
}
if (method.isPrivate()) {
continue;
}
// TODO: "is" prefix
// TODO: remove getJavaClass
if (method.getName().startsWith(JvmAbi.GETTER_PREFIX)) {
// TODO: some java properties too
if (method.getJetMethod().kind() == JvmStdlibNames.JET_METHOD_KIND_PROPERTY) {
if (method.getName().equals(JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD)) {
continue;
}
int i = 0;
PsiType receiverType;
if (i < method.getParameters().size() && method.getParameter(i).getJetValueParameter().receiver()) {
receiverType = method.getParameter(i).getPsiParameter().getType();
++i;
} else {
receiverType = null;
}
while (i < method.getParameters().size() && method.getParameter(i).getJetTypeParameter().isDefined()) {
// TODO: store is reified
++i;
}
if (i != method.getParameters().size()) {
// TODO: report error properly
throw new IllegalStateException();
}
String propertyName = StringUtil.decapitalize(method.getName().substring(JvmAbi.GETTER_PREFIX.length()));
NamedMembers members = getNamedMembers(propertyName);
members.getForProperty().getter = method;
// TODO: check conflicts with setter
// TODO: what if returnType == null?
members.getForProperty().type = method.getReturnType();
members.getForProperty().receiverType = receiverType;
}
} else if (method.getName().startsWith(JvmAbi.SETTER_PREFIX)) {
if (method.getJetMethod().kind() == JvmStdlibNames.JET_METHOD_KIND_PROPERTY) {
if (method.getParameters().size() == 0) {
// TODO: report error properly
throw new IllegalStateException();
}
int i = 0;
PsiType receiverType = null;
PsiParameterWrapper p1 = method.getParameter(0);
if (p1.getJetValueParameter().receiver()) {
receiverType = p1.getPsiParameter().getType();
++i;
}
while (i < method.getParameters().size() && method.getParameter(i).getJetTypeParameter().isDefined()) {
++i;
}
if (i + 1 != method.getParameters().size()) {
throw new IllegalStateException();
}
PsiType propertyType = method.getParameter(i).getPsiParameter().getType();
String propertyName = StringUtil.decapitalize(method.getName().substring(JvmAbi.SETTER_PREFIX.length()));
NamedMembers members = getNamedMembers(propertyName);
members.getForProperty().setter = method;
// TODO: check conflicts with getter
members.getForProperty().type = propertyType;
members.getForProperty().receiverType = receiverType;
}
}
if (method.getJetMethod().kind() != JvmStdlibNames.JET_METHOD_KIND_PROPERTY) {
NamedMembers namedMembers = getNamedMembers(method.getName());
namedMembers.addMethod(method);
}
}
}
}
static Map<String, NamedMembers> getNamedMembers(@NotNull PsiClassWrapper psiClass, boolean staticMembers, boolean kotlin) {
Builder builder = new Builder(psiClass, staticMembers, kotlin);
builder.run();
return builder.namedMembersMap;
}
}
package org.jetbrains.jet.lang.resolve.java;
import com.intellij.psi.PsiType;
/**
* @author Stepan Koltsov
*/
class MembersForProperty {
PsiFieldWrapper field;
PsiMethodWrapper setter;
PsiMethodWrapper getter;
PsiType type;
PsiType receiverType;
}
package org.jetbrains.jet.lang.resolve.java;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* @author Stepan Koltsov
*/
class NamedMembers {
String name;
List<PsiMethodWrapper> methods;
@Nullable
MembersForProperty properties;
@Nullable
private PsiClass nestedClasses;
Set<VariableDescriptor> propertyDescriptors;
Set<FunctionDescriptor> functionDescriptors;
MembersForProperty getForProperty() {
if (properties == null) {
properties = new MembersForProperty();
}
return properties;
}
void addMethod(PsiMethodWrapper method) {
if (methods == null) {
methods = new ArrayList<PsiMethodWrapper>();
}
methods.add(method);
}
}
package org.jetbrains.jet.lang.resolve.java;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiMethod;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* @author Stepan Koltsov
*/
public class PsiClassWrapper {
@NotNull
private final PsiClass psiClass;
public PsiClassWrapper(@NotNull PsiClass psiClass) {
this.psiClass = psiClass;
}
private List<PsiMethodWrapper> methods;
@NotNull
public List<PsiMethodWrapper> getMethods() {
if (methods == null) {
PsiMethod[] psiMethods = psiClass.getMethods();
List<PsiMethodWrapper> methods = new ArrayList<PsiMethodWrapper>(psiMethods.length);
for (PsiMethod psiMethod : psiMethods) {
methods.add(new PsiMethodWrapper(psiMethod));
}
this.methods = methods;
}
return methods;
}
private List<PsiFieldWrapper> fields;
@NotNull
public List<PsiFieldWrapper> getFields() {
if (fields == null) {
PsiField[] psiFields = psiClass.getFields();
List<PsiFieldWrapper> fields = new ArrayList<PsiFieldWrapper>(psiFields.length);
for (PsiField psiField : psiFields) {
fields.add(new PsiFieldWrapper(psiField));
}
this.fields = fields;
}
return fields;
}
public String getQualifiedName() {
return psiClass.getQualifiedName();
}
@NotNull
public PsiClass getPsiClass() {
return psiClass;
}
}
package org.jetbrains.jet.lang.resolve.java;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiMember;
import com.intellij.psi.PsiType;
import org.jetbrains.annotations.NotNull;
/**
......@@ -10,4 +12,12 @@ public class PsiFieldWrapper extends PsiMemberWrapper {
public PsiFieldWrapper(@NotNull PsiMember psiMember) {
super(psiMember);
}
public PsiField getPsiField() {
return (PsiField) psiMember;
}
public PsiType getType() {
return getPsiField().getType();
}
}
......@@ -3,7 +3,9 @@ package org.jetbrains.jet.lang.resolve.java;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiParameter;
import com.intellij.psi.PsiType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.kt.JetConstructorAnnotation;
import org.jetbrains.jet.lang.resolve.java.kt.JetMethodAnnotation;
......@@ -55,8 +57,17 @@ public class PsiMethodWrapper extends PsiMemberWrapper {
return jetConstructor;
}
public boolean isAbstract() {
return psiMember.hasModifierProperty(PsiModifier.ABSTRACT);
}
@NotNull
public PsiMethod getPsiMethod() {
return (PsiMethod) psiMember;
}
@Nullable
public PsiType getReturnType() {
return getPsiMethod().getReturnType();
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册