Restructure JavaDescriptorResolverHelper into MembersByNameCache, which encapsulates the logic
Rename: ResolverScopeData#getNamedMembersMap -> ResolverScopeData#getMembersCache Make cache initialize lazily
This commit is contained in:
-6
@@ -126,12 +126,6 @@ public final class DescriptorResolverUtils {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void getResolverScopeData(@NotNull ResolverScopeData scopeData) {
|
|
||||||
if (scopeData.getNamedMembersMap() == null) {
|
|
||||||
scopeData.setNamedMembersMap(JavaDescriptorResolverHelper.getNamedMembers(scopeData));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void checkPsiClassIsNotJet(@Nullable PsiClass psiClass) {
|
public static void checkPsiClassIsNotJet(@Nullable PsiClass psiClass) {
|
||||||
if (psiClass instanceof JetJavaMirrorMarker) {
|
if (psiClass instanceof JetJavaMirrorMarker) {
|
||||||
throw new IllegalStateException("trying to resolve fake jet PsiClass as regular PsiClass: " + psiClass.getQualifiedName());
|
throw new IllegalStateException("trying to resolve fake jet PsiClass as regular PsiClass: " + psiClass.getQualifiedName());
|
||||||
|
|||||||
+58
-42
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve.java;
|
|||||||
|
|
||||||
import com.intellij.psi.*;
|
import com.intellij.psi.*;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.resolve.java.data.ResolverScopeData;
|
import org.jetbrains.jet.lang.resolve.java.data.ResolverScopeData;
|
||||||
import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation;
|
import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation;
|
||||||
import org.jetbrains.jet.lang.resolve.java.prop.PropertyNameUtils;
|
import org.jetbrains.jet.lang.resolve.java.prop.PropertyNameUtils;
|
||||||
@@ -28,11 +29,41 @@ import org.jetbrains.jet.lang.resolve.name.Name;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
public final class MembersByNameCache {
|
||||||
* @author Stepan Koltsov
|
|
||||||
*/
|
@NotNull
|
||||||
class JavaDescriptorResolverHelper {
|
private final Map<Name, NamedMembers> namedMembersMap = new HashMap<Name, NamedMembers>();
|
||||||
private JavaDescriptorResolverHelper() {
|
|
||||||
|
@Nullable
|
||||||
|
public NamedMembers get(@NotNull Name name) {
|
||||||
|
return namedMembersMap.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterable<? extends Map.Entry<Name, NamedMembers>> entrySet() {
|
||||||
|
return namedMembersMap.entrySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private NamedMembers getOrCreateEmpty(@NotNull Name name) {
|
||||||
|
NamedMembers r = namedMembersMap.get(name);
|
||||||
|
if (r == null) {
|
||||||
|
r = new NamedMembers();
|
||||||
|
namedMembersMap.put(name, r);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static MembersByNameCache buildMembersByNameCache(
|
||||||
|
@Nullable PsiClass psiClass,
|
||||||
|
@Nullable PsiPackage psiPackage,
|
||||||
|
boolean staticMembers,
|
||||||
|
boolean isKotlin
|
||||||
|
) {
|
||||||
|
PsiClassWrapper classWrapper = psiClass == null ? null : new PsiClassWrapper(psiClass);
|
||||||
|
Builder builder = new Builder(classWrapper, psiPackage, staticMembers, isKotlin);
|
||||||
|
builder.build();
|
||||||
|
return builder.cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Builder {
|
private static class Builder {
|
||||||
@@ -40,33 +71,25 @@ class JavaDescriptorResolverHelper {
|
|||||||
private final PsiPackage psiPackage;
|
private final PsiPackage psiPackage;
|
||||||
private final boolean staticMembers;
|
private final boolean staticMembers;
|
||||||
private final boolean kotlin;
|
private final boolean kotlin;
|
||||||
|
|
||||||
private final Map<Name, NamedMembers> namedMembersMap = new HashMap<Name, NamedMembers>();
|
|
||||||
|
|
||||||
private Builder(PsiClassWrapper psiClass, PsiPackage psiPackage, boolean staticMembers, boolean kotlin) {
|
private final MembersByNameCache cache = new MembersByNameCache();
|
||||||
|
|
||||||
|
private Builder(@Nullable PsiClassWrapper psiClass, @Nullable PsiPackage psiPackage, boolean staticMembers, boolean kotlin) {
|
||||||
this.psiClass = psiClass;
|
this.psiClass = psiClass;
|
||||||
this.psiPackage = psiPackage;
|
this.psiPackage = psiPackage;
|
||||||
this.staticMembers = staticMembers;
|
this.staticMembers = staticMembers;
|
||||||
this.kotlin = kotlin;
|
this.kotlin = kotlin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
@NotNull
|
||||||
|
public MembersByNameCache build() {
|
||||||
if (psiClass != null) {
|
if (psiClass != null) {
|
||||||
processFields();
|
processFields();
|
||||||
processMethods();
|
processMethods();
|
||||||
}
|
}
|
||||||
processObjectClasses();
|
processObjectClasses();
|
||||||
}
|
}
|
||||||
|
|
||||||
private NamedMembers getNamedMembers(Name name) {
|
|
||||||
NamedMembers r = namedMembersMap.get(name);
|
|
||||||
if (r == null) {
|
|
||||||
r = new NamedMembers();
|
|
||||||
namedMembersMap.put(name, r);
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean includeMember(PsiMemberWrapper member) {
|
private boolean includeMember(PsiMemberWrapper member) {
|
||||||
if (psiClass.getPsiClass().isEnum() && staticMembers) {
|
if (psiClass.getPsiClass().isEnum() && staticMembers) {
|
||||||
return member.isStatic();
|
return member.isStatic();
|
||||||
@@ -79,14 +102,14 @@ class JavaDescriptorResolverHelper {
|
|||||||
if (member.getPsiMember().getContainingClass() != psiClass.getPsiClass()) {
|
if (member.getPsiMember().getContainingClass() != psiClass.getPsiClass()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (member.isPrivate()) {
|
if (member.isPrivate()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processFields() {
|
private void processFields() {
|
||||||
// Hack to load static members for enum class loaded from class file
|
// Hack to load static members for enum class loaded from class file
|
||||||
if (kotlin && !psiClass.getPsiClass().isEnum()) {
|
if (kotlin && !psiClass.getPsiClass().isEnum()) {
|
||||||
@@ -96,7 +119,7 @@ class JavaDescriptorResolverHelper {
|
|||||||
PsiFieldWrapper field = new PsiFieldWrapper(field0);
|
PsiFieldWrapper field = new PsiFieldWrapper(field0);
|
||||||
|
|
||||||
// group must be created even for excluded field
|
// group must be created even for excluded field
|
||||||
NamedMembers namedMembers = getNamedMembers(Name.identifier(field.getName()));
|
NamedMembers namedMembers = cache.getOrCreateEmpty(Name.identifier(field.getName()));
|
||||||
|
|
||||||
if (!includeMember(field)) {
|
if (!includeMember(field)) {
|
||||||
continue;
|
continue;
|
||||||
@@ -109,18 +132,18 @@ class JavaDescriptorResolverHelper {
|
|||||||
|
|
||||||
private void processMethods() {
|
private void processMethods() {
|
||||||
for (PsiMethod method : psiClass.getPsiClass().getAllMethods()) {
|
for (PsiMethod method : psiClass.getPsiClass().getAllMethods()) {
|
||||||
getNamedMembers(Name.identifier(method.getName()));
|
createEmptyEntry(Name.identifier(method.getName()));
|
||||||
|
|
||||||
PropertyParseResult propertyParseResult = PropertyNameUtils.parseMethodToProperty(method.getName());
|
PropertyParseResult propertyParseResult = PropertyNameUtils.parseMethodToProperty(method.getName());
|
||||||
if (propertyParseResult != null) {
|
if (propertyParseResult != null) {
|
||||||
getNamedMembers(Name.identifier(propertyParseResult.getPropertyName()));
|
cache.getOrCreateEmpty(Name.identifier(propertyParseResult.getPropertyName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (PsiMethod method0 : psiClass.getPsiClass().getMethods()) {
|
for (PsiMethod method0 : psiClass.getPsiClass().getMethods()) {
|
||||||
PsiMethodWrapper method = new PsiMethodWrapper(method0);
|
PsiMethodWrapper method = new PsiMethodWrapper(method0);
|
||||||
|
|
||||||
if (!includeMember(method)) {
|
if (!includeMember(method)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -131,7 +154,7 @@ class JavaDescriptorResolverHelper {
|
|||||||
if (propertyParseResult != null && propertyParseResult.isGetter()) {
|
if (propertyParseResult != null && propertyParseResult.isGetter()) {
|
||||||
|
|
||||||
String propertyName = propertyParseResult.getPropertyName();
|
String propertyName = propertyParseResult.getPropertyName();
|
||||||
NamedMembers members = getNamedMembers(Name.identifier(propertyName));
|
NamedMembers members = cache.getOrCreateEmpty(Name.identifier(propertyName));
|
||||||
|
|
||||||
// TODO: some java properties too
|
// TODO: some java properties too
|
||||||
if (method.getJetMethod().hasPropertyFlag()) {
|
if (method.getJetMethod().hasPropertyFlag()) {
|
||||||
@@ -169,7 +192,7 @@ class JavaDescriptorResolverHelper {
|
|||||||
else if (propertyParseResult != null && !propertyParseResult.isGetter()) {
|
else if (propertyParseResult != null && !propertyParseResult.isGetter()) {
|
||||||
|
|
||||||
String propertyName = propertyParseResult.getPropertyName();
|
String propertyName = propertyParseResult.getPropertyName();
|
||||||
NamedMembers members = getNamedMembers(Name.identifier(propertyName));
|
NamedMembers members = cache.getOrCreateEmpty(Name.identifier(propertyName));
|
||||||
|
|
||||||
if (method.getJetMethod().hasPropertyFlag()) {
|
if (method.getJetMethod().hasPropertyFlag()) {
|
||||||
if (method.getParameters().size() == 0) {
|
if (method.getParameters().size() == 0) {
|
||||||
@@ -200,14 +223,18 @@ class JavaDescriptorResolverHelper {
|
|||||||
members.addPropertyAccessor(new PropertyAccessorData(method, false, propertyType, receiverType));
|
members.addPropertyAccessor(new PropertyAccessorData(method, false, propertyType, receiverType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!method.getJetMethod().hasPropertyFlag()) {
|
if (!method.getJetMethod().hasPropertyFlag()) {
|
||||||
NamedMembers namedMembers = getNamedMembers(Name.identifier(method.getName()));
|
NamedMembers namedMembers = cache.getOrCreateEmpty(Name.identifier(method.getName()));
|
||||||
namedMembers.addMethod(method);
|
namedMembers.addMethod(method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createEmptyEntry(@NotNull Name identifier) {
|
||||||
|
cache.getOrCreateEmpty(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
private void processObjectClasses() {
|
private void processObjectClasses() {
|
||||||
PsiClass[] classes = psiPackage != null ? psiPackage.getClasses() : psiClass.getPsiClass().getInnerClasses();
|
PsiClass[] classes = psiPackage != null ? psiPackage.getClasses() : psiClass.getPsiClass().getInnerClasses();
|
||||||
for (PsiClass psiClass : classes) {
|
for (PsiClass psiClass : classes) {
|
||||||
@@ -219,7 +246,7 @@ class JavaDescriptorResolverHelper {
|
|||||||
}
|
}
|
||||||
PsiField instanceField = psiClass.findFieldByName(JvmAbi.INSTANCE_FIELD, false);
|
PsiField instanceField = psiClass.findFieldByName(JvmAbi.INSTANCE_FIELD, false);
|
||||||
if (instanceField != null) {
|
if (instanceField != null) {
|
||||||
NamedMembers namedMembers = getNamedMembers(Name.identifier(psiClass.getName()));
|
NamedMembers namedMembers = cache.getOrCreateEmpty(Name.identifier(psiClass.getName()));
|
||||||
|
|
||||||
TypeSource type = new TypeSource("", instanceField.getType(), instanceField);
|
TypeSource type = new TypeSource("", instanceField.getType(), instanceField);
|
||||||
namedMembers.addPropertyAccessor(new PropertyAccessorData(new PsiFieldWrapper(instanceField), type, null));
|
namedMembers.addPropertyAccessor(new PropertyAccessorData(new PsiFieldWrapper(instanceField), type, null));
|
||||||
@@ -227,15 +254,4 @@ class JavaDescriptorResolverHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
static Map<Name, NamedMembers> getNamedMembers(@NotNull ResolverScopeData resolverScopeData) {
|
|
||||||
PsiClassWrapper aClass = resolverScopeData.getPsiClass() != null ? new PsiClassWrapper(resolverScopeData.getPsiClass()) : null;
|
|
||||||
Builder builder = new Builder(aClass, resolverScopeData.getPsiPackage(), resolverScopeData.isStaticMembers(), resolverScopeData.isKotlin());
|
|
||||||
builder.run();
|
|
||||||
return builder.namedMembersMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
+8
-10
@@ -24,12 +24,10 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor;
|
||||||
import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils;
|
import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||||
import org.jetbrains.jet.lang.resolve.java.NamedMembers;
|
import org.jetbrains.jet.lang.resolve.java.MembersByNameCache;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Pavel Talanov
|
* @author Pavel Talanov
|
||||||
*/
|
*/
|
||||||
@@ -120,13 +118,13 @@ public abstract class ResolverScopeData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<Name, NamedMembers> namedMembersMap;
|
private MembersByNameCache membersCache = null;
|
||||||
|
|
||||||
public Map<Name, NamedMembers> getNamedMembersMap() {
|
@NotNull
|
||||||
return namedMembersMap;
|
public MembersByNameCache getMembersCache() {
|
||||||
}
|
if (membersCache == null) {
|
||||||
|
membersCache = MembersByNameCache.buildMembersByNameCache(psiClass, psiPackage, staticMembers, kotlin);
|
||||||
public void setNamedMembersMap(Map<Name, NamedMembers> namedMembersMap) {
|
}
|
||||||
this.namedMembersMap = namedMembersMap;
|
return membersCache;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-10
@@ -80,9 +80,6 @@ public final class JavaFunctionResolver {
|
|||||||
@NotNull final PsiClass psiClass, final PsiMethodWrapper method,
|
@NotNull final PsiClass psiClass, final PsiMethodWrapper method,
|
||||||
@NotNull ResolverScopeData scopeData
|
@NotNull ResolverScopeData scopeData
|
||||||
) {
|
) {
|
||||||
|
|
||||||
DescriptorResolverUtils.getResolverScopeData(scopeData);
|
|
||||||
|
|
||||||
PsiType returnPsiType = method.getReturnType();
|
PsiType returnPsiType = method.getReturnType();
|
||||||
if (returnPsiType == null) {
|
if (returnPsiType == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -224,9 +221,7 @@ public final class JavaFunctionResolver {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Set<FunctionDescriptor> resolveFunctionGroup(Name methodName, ResolverScopeData scopeData) {
|
public Set<FunctionDescriptor> resolveFunctionGroup(Name methodName, ResolverScopeData scopeData) {
|
||||||
DescriptorResolverUtils.getResolverScopeData(scopeData);
|
MembersByNameCache namedMembersMap = scopeData.getMembersCache();
|
||||||
|
|
||||||
Map<Name, NamedMembers> namedMembersMap = scopeData.getNamedMembersMap();
|
|
||||||
|
|
||||||
NamedMembers namedMembers = namedMembersMap.get(methodName);
|
NamedMembers namedMembers = namedMembersMap.get(methodName);
|
||||||
if (namedMembers != null) {
|
if (namedMembers != null) {
|
||||||
@@ -284,12 +279,9 @@ public final class JavaFunctionResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<FunctionDescriptor> resolveMethods(@NotNull ResolverScopeData scopeData) {
|
public List<FunctionDescriptor> resolveMethods(@NotNull ResolverScopeData scopeData) {
|
||||||
|
|
||||||
DescriptorResolverUtils.getResolverScopeData(scopeData);
|
|
||||||
|
|
||||||
List<FunctionDescriptor> functions = new ArrayList<FunctionDescriptor>();
|
List<FunctionDescriptor> functions = new ArrayList<FunctionDescriptor>();
|
||||||
|
|
||||||
for (Map.Entry<Name, NamedMembers> entry : scopeData.getNamedMembersMap().entrySet()) {
|
for (Map.Entry<Name, NamedMembers> entry : scopeData.getMembersCache().entrySet()) {
|
||||||
Name methodName = entry.getKey();
|
Name methodName = entry.getKey();
|
||||||
NamedMembers namedMembers = entry.getValue();
|
NamedMembers namedMembers = entry.getValue();
|
||||||
PsiClass psiClass = scopeData.getPsiClass();
|
PsiClass psiClass = scopeData.getPsiClass();
|
||||||
|
|||||||
+2
-6
@@ -85,9 +85,8 @@ public final class JavaPropertiesResolver {
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
PsiClass psiClass = scopeData.getPsiClass();
|
PsiClass psiClass = scopeData.getPsiClass();
|
||||||
DescriptorResolverUtils.getResolverScopeData(scopeData);
|
|
||||||
|
|
||||||
NamedMembers namedMembers = scopeData.getNamedMembersMap().get(fieldName);
|
NamedMembers namedMembers = scopeData.getMembersCache().get(fieldName);
|
||||||
if (namedMembers == null) {
|
if (namedMembers == null) {
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
@@ -104,12 +103,11 @@ public final class JavaPropertiesResolver {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Set<VariableDescriptor> resolveFieldGroup(@NotNull ResolverScopeData scopeData) {
|
public Set<VariableDescriptor> resolveFieldGroup(@NotNull ResolverScopeData scopeData) {
|
||||||
DescriptorResolverUtils.getResolverScopeData(scopeData);
|
|
||||||
final PsiClass psiClass = scopeData.getPsiClass();
|
final PsiClass psiClass = scopeData.getPsiClass();
|
||||||
assert psiClass != null;
|
assert psiClass != null;
|
||||||
|
|
||||||
Set<VariableDescriptor> descriptors = Sets.newHashSet();
|
Set<VariableDescriptor> descriptors = Sets.newHashSet();
|
||||||
Map<Name, NamedMembers> membersForProperties = scopeData.getNamedMembersMap();
|
MembersByNameCache membersForProperties = scopeData.getMembersCache();
|
||||||
for (Map.Entry<Name, NamedMembers> entry : membersForProperties.entrySet()) {
|
for (Map.Entry<Name, NamedMembers> entry : membersForProperties.entrySet()) {
|
||||||
NamedMembers namedMembers = entry.getValue();
|
NamedMembers namedMembers = entry.getValue();
|
||||||
Name propertyName = entry.getKey();
|
Name propertyName = entry.getKey();
|
||||||
@@ -136,8 +134,6 @@ public final class JavaPropertiesResolver {
|
|||||||
@NotNull Name propertyName,
|
@NotNull Name propertyName,
|
||||||
@NotNull String context
|
@NotNull String context
|
||||||
) {
|
) {
|
||||||
DescriptorResolverUtils.getResolverScopeData(scopeData);
|
|
||||||
|
|
||||||
if (namedMembers.getPropertyDescriptors() != null) {
|
if (namedMembers.getPropertyDescriptors() != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user