Created
January 17, 2012 18:58
-
-
Save stepancheg/1628144 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 41b6b4ef0ec11fdd9adec8fde73f176b938e865d | |
Author: Stepan Koltsov <[email protected]> | |
Date: Mon Jan 16 16:55:00 2012 +0400 | |
refactor java descriptor resolver | |
diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java | |
index 80c8b72..636682c 100644 | |
--- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java | |
+++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java | |
@@ -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 | |
diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java | |
index 55480be..f5b85af 100644 | |
--- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java | |
+++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java | |
@@ -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; | |
@@ -128,11 +126,12 @@ public class JavaDescriptorResolver { | |
this.lowerBoundsForKotlin = lowerBoundsForKotlin; | |
} | |
} | |
- | |
+ | |
+ | |
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,217 +779,174 @@ 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; | |
+ public Set<VariableDescriptor> resolveFieldGroupByName(@NotNull DeclarationDescriptor owner, PsiClass psiClass, String fieldName, boolean staticMembers) { | |
+ ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass)); | |
- private PropertyKey(@NotNull String name /*, @NotNull PsiType type, @Nullable PsiType receiverType */) { | |
- this.name = name; | |
- //this.type = type; | |
- //this.receiverType = receiverType; | |
+ NamedMembers namedMembers = scopeData.namedMembersMap.get(fieldName); | |
+ if (namedMembers == null) { | |
+ return Collections.emptySet(); | |
} | |
- @Override | |
- public boolean equals(Object o) { | |
- if (this == o) return true; | |
- if (o == null || getClass() != o.getClass()) return false; | |
- | |
- PropertyKey that = (PropertyKey) o; | |
+ resolveNamedGroupProperties(owner, staticMembers, namedMembers, fieldName); | |
- 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 namedMembers.propertyDescriptors; | |
+ } | |
+ | |
+ @NotNull | |
+ public Set<VariableDescriptor> resolveFieldGroup(@NotNull DeclarationDescriptor owner, PsiClass psiClass, boolean staticMembers) { | |
- return true; | |
- } | |
+ ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass)); | |
+ | |
+ 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; | |
+ } | |
+ | |
+ String propertyName = entry.getKey(); | |
- @Override | |
- public int hashCode() { | |
- int result = name.hashCode(); | |
- //result = 31 * result + type.hashCode(); | |
- //result = 31 * result + (receiverType != null ? receiverType.hashCode() : 0); | |
- return result; | |
+ resolveNamedGroupProperties(owner, staticMembers, namedMembers, propertyName); | |
+ descriptors.addAll(namedMembers.propertyDescriptors); | |
} | |
+ return descriptors; | |
} | |
- 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; | |
- } | |
+ private void resolveNamedGroupProperties(DeclarationDescriptor owner, boolean staticMembers, NamedMembers namedMembers, String propertyName) { | |
+ if (namedMembers.propertyDescriptors != null) { | |
+ return; | |
+ } | |
+ | |
+ if (namedMembers.properties == null) { | |
+ namedMembers.propertyDescriptors = Collections.emptySet(); | |
+ return; | |
+ } | |
+ | |
+ PsiType propertyType = namedMembers.properties.type; | |
+ PsiType receiverType = namedMembers.properties.receiverType; | |
+ MembersForProperty members = namedMembers.properties; | |
+ | |
+ boolean isFinal; | |
+ if (members.setter == null && members.getter == null) { | |
+ isFinal = false; | |
+ } else if (members.getter != null) { | |
+ isFinal = members.getter.isFinal(); | |
+ } else if (members.setter != null) { | |
+ isFinal = members.setter.isFinal(); | |
+ } else { | |
+ isFinal = false; | |
+ } | |
- if (field.hasModifierProperty(PsiModifier.PRIVATE)) { | |
- continue; | |
- } | |
+ PsiMemberWrapper anyMember; | |
+ if (members.getter != null) { | |
+ anyMember = members.getter; | |
+ } else if (members.field != null) { | |
+ anyMember = members.field; | |
+ } else if (members.setter != null) { | |
+ anyMember = members.setter; | |
+ } else { | |
+ throw new IllegalStateException(); | |
+ } | |
- MembersForProperty members = new MembersForProperty(); | |
- members.field = new PsiFieldWrapper(field); | |
- members.type = field.getType(); | |
- membersMap.put(new PropertyKey(field.getName() /*, field.getType(), null*/), members); | |
- } | |
+ boolean isVar; | |
+ if (members.getter == null && members.setter == null) { | |
+ isVar = !members.field.isFinal(); | |
+ } else { | |
+ isVar = members.setter != null; | |
} | |
- | |
- for (PsiMethod psiMethod : clazz.getMethods()) { | |
- PsiMethodWrapper method = new PsiMethodWrapper(psiMethod); | |
- if (method.isStatic() != staticMembers) { | |
- continue; | |
- } | |
+ PropertyDescriptor propertyDescriptor = new PropertyDescriptor( | |
+ owner, | |
+ Collections.<AnnotationDescriptor>emptyList(), | |
+ isFinal && !staticMembers ? Modality.FINAL : Modality.OPEN, // TODO: abstract | |
+ resolveVisibilityFromPsiModifiers(anyMember.psiMember), | |
+ isVar, | |
+ false, | |
+ propertyName); | |
- if (method.isPrivate()) { | |
- continue; | |
- } | |
+ PropertyGetterDescriptor getterDescriptor = null; | |
+ PropertySetterDescriptor setterDescriptor = null; | |
+ if (members.getter != null) { | |
+ getterDescriptor = new PropertyGetterDescriptor(propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.OPEN, Visibility.PUBLIC, true, false); | |
+ } | |
+ if (members.setter != null) { | |
+ setterDescriptor = new PropertySetterDescriptor(propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.OPEN, Visibility.PUBLIC, true, false); | |
+ } | |
- // TODO: "is" prefix | |
- // TODO: remove getJavaClass | |
- if (psiMethod.getName().startsWith(JvmAbi.GETTER_PREFIX)) { | |
+ propertyDescriptor.initialize(getterDescriptor, setterDescriptor); | |
- // TODO: some java properties too | |
- if (method.getJetMethod().kind() == JvmStdlibNames.JET_METHOD_KIND_PROPERTY) { | |
+ final List<TypeParameterDescriptor> classTypeParameters; | |
+ if (anyMember instanceof PsiMethodWrapper && !anyMember.isStatic()) { | |
+ classTypeParameters = ((ClassDescriptor) owner).getTypeConstructor().getParameters(); | |
+ } else { | |
+ classTypeParameters = new ArrayList<TypeParameterDescriptor>(0); | |
+ } | |
+ TypeParameterListTypeVariableResolver typeVariableResolver = new TypeParameterListTypeVariableResolver(classTypeParameters); | |
- if (psiMethod.getName().equals(JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD)) { | |
- continue; | |
- } | |
+ List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(0); | |
- int i = 0; | |
+ if (members.setter != null) { | |
+ // call ugly code with side effects | |
+ typeParameters = resolveMethodTypeParameters(members.setter, propertyDescriptor.getSetter(), typeVariableResolver); | |
+ } | |
+ if (members.getter != null) { | |
+ // call ugly code with side effects | |
+ typeParameters = resolveMethodTypeParameters(members.getter, propertyDescriptor.getGetter(), typeVariableResolver); | |
+ } | |
- 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); | |
+ JetType receiverJetType; | |
+ if (receiverType == null) { | |
+ receiverJetType = null; | |
+ } else { | |
+ receiverJetType = semanticServices.getTypeTransformer().transformToType(receiverType); | |
+ } | |
- // TODO: check conflicts with setter | |
- members.type = psiMethod.getReturnType(); | |
- members.receiverType = receiverType; | |
- } | |
- } else if (psiMethod.getName().startsWith(JvmAbi.SETTER_PREFIX)) { | |
+ JetType type = semanticServices.getTypeTransformer().transformToType(propertyType); | |
- if (method.getJetMethod().kind() == JvmStdlibNames.JET_METHOD_KIND_PROPERTY) { | |
- if (psiMethod.getParameterList().getParametersCount() == 0) { | |
- // TODO: report error properly | |
- throw new IllegalStateException(); | |
- } | |
+ propertyDescriptor.setType( | |
+ type, | |
+ typeParameters, | |
+ DescriptorUtils.getExpectedThisObjectIfNeeded(owner), | |
+ receiverJetType | |
+ ); | |
+ if (getterDescriptor != null) { | |
+ getterDescriptor.initialize(type); | |
+ } | |
+ if (setterDescriptor != null) { | |
+ // TODO: initialize | |
+ } | |
- int i = 0; | |
+ semanticServices.getTrace().record(BindingContext.VARIABLE, anyMember.psiMember, propertyDescriptor); | |
+ namedMembers.propertyDescriptors = Collections.<VariableDescriptor>singleton(propertyDescriptor); | |
+ } | |
- 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(); | |
- } | |
- | |
- 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); | |
- } | |
- members.setter = new PsiMethodWrapper(psiMethod); | |
+ private void resolveNamedGroupFunctions(DeclarationDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, boolean staticMembers, NamedMembers namedMembers, String functionName) { | |
+ if (namedMembers.functionDescriptors != null) { | |
+ return; | |
+ } | |
- // TODO: check conflicts with getter | |
- members.type = propertyType; | |
- members.receiverType = receiverType; | |
- } | |
- } | |
+ if (namedMembers.methods == null) { | |
+ namedMembers.functionDescriptors = Collections.emptySet(); | |
+ return; | |
} | |
- | |
- 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); | |
- } | |
+ | |
+ Set<FunctionDescriptor> functionDescriptors = new HashSet<FunctionDescriptor>(namedMembers.methods.size()); | |
+ for (PsiMethodWrapper method : namedMembers.methods) { | |
+ functionDescriptors.add(resolveMethodToFunctionDescriptor(owner, psiClass, typeSubstitutorForGenericSuperclasses, method)); | |
} | |
- return r; | |
+ namedMembers.functionDescriptors = functionDescriptors; | |
} | |
- @NotNull | |
- public Set<VariableDescriptor> resolveFieldGroup(@NotNull DeclarationDescriptor owner, PsiClass psiClass, boolean staticMembers) { | |
- | |
+ 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(); | |
} | |
@@ -999,151 +954,29 @@ public class JavaDescriptorResolver { | |
throw new IllegalStateException(); | |
} | |
- if (scopeData.properties != null) { | |
- return scopeData.properties; | |
+ if (scopeData.namedMembersMap == null) { | |
+ scopeData.namedMembersMap = JavaDescriptorResolverHelper.getNamedMembers(psiClass, staticMembers, scopeData.kotlin); | |
} | |
- 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(); | |
- | |
- boolean isFinal; | |
- if (members.setter == null && members.getter == null) { | |
- isFinal = false; | |
- } else if (members.getter != null) { | |
- isFinal = members.getter.isFinal(); | |
- } else if (members.setter != null) { | |
- isFinal = members.setter.isFinal(); | |
- } else { | |
- isFinal = false; | |
- } | |
- | |
- PsiMemberWrapper anyMember; | |
- if (members.getter != null) { | |
- anyMember = members.getter; | |
- } else if (members.field != null) { | |
- anyMember = members.field; | |
- } else if (members.setter != null) { | |
- anyMember = members.setter; | |
- } else { | |
- throw new IllegalStateException(); | |
- } | |
- | |
- boolean isVar; | |
- if (members.getter == null && members.setter == null) { | |
- isVar = !members.field.isFinal(); | |
- } else { | |
- isVar = members.setter != null; | |
- } | |
- | |
- PropertyDescriptor propertyDescriptor = new PropertyDescriptor( | |
- owner, | |
- Collections.<AnnotationDescriptor>emptyList(), | |
- isFinal && !staticMembers ? Modality.FINAL : Modality.OPEN, // TODO: abstract | |
- resolveVisibilityFromPsiModifiers(anyMember.psiMember), | |
- isVar, | |
- false, | |
- propertyName); | |
- | |
- PropertyGetterDescriptor getterDescriptor = null; | |
- PropertySetterDescriptor setterDescriptor = null; | |
- if (members.getter != null) { | |
- getterDescriptor = new PropertyGetterDescriptor(propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.OPEN, Visibility.PUBLIC, true, false); | |
- } | |
- if (members.setter != null) { | |
- setterDescriptor = new PropertySetterDescriptor(propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.OPEN, Visibility.PUBLIC, true, false); | |
- } | |
- | |
- propertyDescriptor.initialize(getterDescriptor, setterDescriptor); | |
- | |
- final List<TypeParameterDescriptor> classTypeParameters; | |
- if (anyMember instanceof PsiMethodWrapper && !anyMember.isStatic()) { | |
- classTypeParameters = ((ClassDescriptor) owner).getTypeConstructor().getParameters(); | |
- } else { | |
- classTypeParameters = new ArrayList<TypeParameterDescriptor>(0); | |
- } | |
- TypeParameterListTypeVariableResolver typeVariableResolver = new TypeParameterListTypeVariableResolver(classTypeParameters); | |
- | |
- List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(0); | |
- | |
- if (members.setter != null) { | |
- // call ugly code with side effects | |
- typeParameters = resolveMethodTypeParameters(members.setter, propertyDescriptor.getSetter(), typeVariableResolver); | |
- } | |
- if (members.getter != null) { | |
- // call ugly code with side effects | |
- typeParameters = resolveMethodTypeParameters(members.getter, propertyDescriptor.getGetter(), typeVariableResolver); | |
- } | |
- | |
- JetType receiverJetType; | |
- if (receiverType == null) { | |
- receiverJetType = null; | |
- } else { | |
- receiverJetType = semanticServices.getTypeTransformer().transformToType(receiverType); | |
- } | |
- | |
- JetType type = semanticServices.getTypeTransformer().transformToType(propertyType); | |
- | |
- propertyDescriptor.setType( | |
- type, | |
- typeParameters, | |
- DescriptorUtils.getExpectedThisObjectIfNeeded(owner), | |
- receiverJetType | |
- ); | |
- if (getterDescriptor != null) { | |
- getterDescriptor.initialize(type); | |
- } | |
- if (setterDescriptor != null) { | |
- // TODO: initialize | |
- } | |
- | |
- semanticServices.getTrace().record(BindingContext.VARIABLE, anyMember.psiMember, propertyDescriptor); | |
- //fieldDescriptorCache.put(field, propertyDescriptor); | |
- descriptors.add(propertyDescriptor); | |
- } | |
- scopeData.properties = descriptors; | |
- return descriptors; | |
+ return scopeData; | |
} | |
@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; | |
- } | |
- FunctionDescriptor substitutedFunctionDescriptor = resolveHierarchicalSignatureToFunction(owner, psiClass, staticMembers, typeSubstitutor, signature); | |
- if (substitutedFunctionDescriptor != null) { | |
- writableFunctionGroup.add(substitutedFunctionDescriptor); | |
- } | |
- } | |
- return writableFunctionGroup; | |
- } | |
+ ResolverScopeData resolverScopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass)); | |
- @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; | |
+ Map<String, NamedMembers> namedMembersMap = resolverScopeData.namedMembersMap; | |
+ | |
+ NamedMembers namedMembers = namedMembersMap.get(methodName); | |
+ if (namedMembers == null || namedMembers.methods == null) { | |
+ return Collections.emptySet(); | |
} | |
- 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; | |
+ | |
+ 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); | |
diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolverHelper.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolverHelper.java | |
new file mode 100644 | |
index 0000000..c56fb65 | |
--- /dev/null | |
+++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolverHelper.java | |
@@ -0,0 +1,173 @@ | |
+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; | |
+ } | |
+ | |
+ | |
+} | |
diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/MembersForProperty.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/MembersForProperty.java | |
new file mode 100644 | |
index 0000000..db363b8 | |
--- /dev/null | |
+++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/MembersForProperty.java | |
@@ -0,0 +1,15 @@ | |
+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; | |
+} | |
diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/NamedMembers.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/NamedMembers.java | |
new file mode 100644 | |
index 0000000..7da0943 | |
--- /dev/null | |
+++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/NamedMembers.java | |
@@ -0,0 +1,41 @@ | |
+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); | |
+ } | |
+} | |
diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiClassWrapper.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiClassWrapper.java | |
new file mode 100644 | |
index 0000000..0eb5204 | |
--- /dev/null | |
+++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiClassWrapper.java | |
@@ -0,0 +1,59 @@ | |
+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; | |
+ } | |
+} | |
diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiFieldWrapper.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiFieldWrapper.java | |
index 75ad3e1..a896d42 100644 | |
--- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiFieldWrapper.java | |
+++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiFieldWrapper.java | |
@@ -1,6 +1,8 @@ | |
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(); | |
+ } | |
} | |
diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMethodWrapper.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMethodWrapper.java | |
index 0f67274..66b1df1 100644 | |
--- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMethodWrapper.java | |
+++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMethodWrapper.java | |
@@ -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(); | |
+ } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment