提交 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(
containingDeclaration,
psiClass,
staticMembers ? null : (ClassDescriptor) containingDeclaration,
name,
staticMembers);
functionGroups.put(name, functionGroup);
}
return functionGroup;
return semanticServices.getDescriptorResolver().resolveFunctionGroup(
containingDeclaration,
psiClass,
staticMembers ? null : (ClassDescriptor) containingDeclaration,
name,
staticMembers);
}
@Override
......
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.
先完成此消息的编辑!
想要评论请 注册