Merge remote branch 'origin/master'
This commit is contained in:
@@ -6,6 +6,7 @@ import org.jetbrains.jet.lang.resolve.java.JetSignatureUtils;
|
|||||||
import org.jetbrains.jet.lang.types.Variance;
|
import org.jetbrains.jet.lang.types.Variance;
|
||||||
import org.jetbrains.jet.rt.signature.JetSignatureAdapter;
|
import org.jetbrains.jet.rt.signature.JetSignatureAdapter;
|
||||||
import org.jetbrains.jet.rt.signature.JetSignatureReader;
|
import org.jetbrains.jet.rt.signature.JetSignatureReader;
|
||||||
|
import org.jetbrains.jet.rt.signature.JetSignatureVariance;
|
||||||
import org.jetbrains.jet.rt.signature.JetSignatureWriter;
|
import org.jetbrains.jet.rt.signature.JetSignatureWriter;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
import org.objectweb.asm.commons.Method;
|
import org.objectweb.asm.commons.Method;
|
||||||
@@ -203,10 +204,20 @@ public class BothSignatureWriter {
|
|||||||
public void writeArrayEnd() {
|
public void writeArrayEnd() {
|
||||||
pop();
|
pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static JetSignatureVariance toJetSignatureVariance(Variance variance) {
|
||||||
|
switch (variance) {
|
||||||
|
case INVARIANT: return JetSignatureVariance.INVARIANT;
|
||||||
|
case IN_VARIANCE: return JetSignatureVariance.IN;
|
||||||
|
case OUT_VARIANCE: return JetSignatureVariance.OUT;
|
||||||
|
default: throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void writeTypeArgument(char c) {
|
public void writeTypeArgument(Variance variance) {
|
||||||
push(signatureVisitor().visitTypeArgument(c));
|
JetSignatureVariance jsVariance = toJetSignatureVariance(variance);
|
||||||
jetSignatureWriter.visitTypeArgument(c);
|
push(signatureVisitor().visitTypeArgument(jsVariance.getC()));
|
||||||
|
jetSignatureWriter.visitTypeArgument(jsVariance);
|
||||||
generic = true;
|
generic = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -124,6 +124,9 @@ public class FunctionCodegen {
|
|||||||
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true);
|
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true);
|
||||||
}
|
}
|
||||||
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD, true);
|
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD, true);
|
||||||
|
if (jvmSignature.getKotlinParameterTypes() != null && jvmSignature.getKotlinParameterTypes().get(0) != null) {
|
||||||
|
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD, jvmSignature.getKotlinParameterTypes().get(0).getKotlinSignature());
|
||||||
|
}
|
||||||
av.visitEnd();
|
av.visitEnd();
|
||||||
}
|
}
|
||||||
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
|
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
|
||||||
|
|||||||
@@ -298,7 +298,7 @@ public class JetTypeMapper {
|
|||||||
signatureVisitor.writeClassBegin(asmType.getInternalName(), jetType.isNullable());
|
signatureVisitor.writeClassBegin(asmType.getInternalName(), jetType.isNullable());
|
||||||
for (TypeProjection proj : jetType.getArguments()) {
|
for (TypeProjection proj : jetType.getArguments()) {
|
||||||
// TODO: +-
|
// TODO: +-
|
||||||
signatureVisitor.writeTypeArgument('=');
|
signatureVisitor.writeTypeArgument(proj.getProjectionKind());
|
||||||
mapType(proj.getType(), kind, signatureVisitor, true);
|
mapType(proj.getType(), kind, signatureVisitor, true);
|
||||||
signatureVisitor.writeTypeArgumentEnd();
|
signatureVisitor.writeTypeArgumentEnd();
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-39
@@ -2,15 +2,26 @@ package org.jetbrains.jet.lang.resolve.java;
|
|||||||
|
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Sets;
|
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.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
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.JetScope;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
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
|
* @author abreslav
|
||||||
@@ -20,8 +31,6 @@ public class JavaClassMembersScope implements JetScope {
|
|||||||
private final JavaSemanticServices semanticServices;
|
private final JavaSemanticServices semanticServices;
|
||||||
private final boolean staticMembers;
|
private final boolean staticMembers;
|
||||||
private final DeclarationDescriptor containingDeclaration;
|
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 final Map<String, ClassifierDescriptor> classifiers = Maps.newHashMap();
|
||||||
private Collection<DeclarationDescriptor> allDescriptors;
|
private Collection<DeclarationDescriptor> allDescriptors;
|
||||||
|
|
||||||
@@ -76,7 +85,7 @@ public class JavaClassMembersScope implements JetScope {
|
|||||||
if (method.hasModifierProperty(PsiModifier.STATIC) != staticMembers) {
|
if (method.hasModifierProperty(PsiModifier.STATIC) != staticMembers) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
FunctionDescriptor functionDescriptor = semanticServices.getDescriptorResolver().resolveMethodToFunctionDescriptor(containingDeclaration, psiClass, substitutorForGenericSupertypes, method);
|
FunctionDescriptor functionDescriptor = semanticServices.getDescriptorResolver().resolveMethodToFunctionDescriptor(containingDeclaration, psiClass, substitutorForGenericSupertypes, new PsiMethodWrapper(method));
|
||||||
if (functionDescriptor != null) {
|
if (functionDescriptor != null) {
|
||||||
allDescriptors.add(functionDescriptor);
|
allDescriptors.add(functionDescriptor);
|
||||||
}
|
}
|
||||||
@@ -117,14 +126,7 @@ public class JavaClassMembersScope implements JetScope {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Set<VariableDescriptor> getProperties(@NotNull String name) {
|
public Set<VariableDescriptor> getProperties(@NotNull String name) {
|
||||||
Set<VariableDescriptor> variableDescriptor = variables.get(name);
|
return semanticServices.getDescriptorResolver().resolveFieldGroupByName(containingDeclaration, psiClass, name, staticMembers);
|
||||||
if (variableDescriptor == null) {
|
|
||||||
variableDescriptor = doGetVariable(name);
|
|
||||||
if (variableDescriptor != null) {
|
|
||||||
variables.put(name, variableDescriptor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return variableDescriptor != null ? variableDescriptor : Collections.<VariableDescriptor>emptySet();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -132,32 +134,15 @@ public class JavaClassMembersScope implements JetScope {
|
|||||||
return null;
|
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
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Set<FunctionDescriptor> getFunctions(@NotNull String name) {
|
public Set<FunctionDescriptor> getFunctions(@NotNull String name) {
|
||||||
Set<FunctionDescriptor> functionGroup = functionGroups.get(name);
|
return semanticServices.getDescriptorResolver().resolveFunctionGroup(
|
||||||
if (functionGroup == null) {
|
containingDeclaration,
|
||||||
functionGroup = semanticServices.getDescriptorResolver().resolveFunctionGroup(
|
psiClass,
|
||||||
containingDeclaration,
|
staticMembers ? null : (ClassDescriptor) containingDeclaration,
|
||||||
psiClass,
|
name,
|
||||||
staticMembers ? null : (ClassDescriptor) containingDeclaration,
|
staticMembers);
|
||||||
name,
|
|
||||||
staticMembers);
|
|
||||||
functionGroups.put(name, functionGroup);
|
|
||||||
}
|
|
||||||
return functionGroup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+214
-370
@@ -4,15 +4,12 @@ import com.google.common.collect.Lists;
|
|||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.util.text.StringUtil;
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.psi.HierarchicalMethodSignature;
|
|
||||||
import com.intellij.psi.JavaPsiFacade;
|
import com.intellij.psi.JavaPsiFacade;
|
||||||
import com.intellij.psi.PsiClass;
|
import com.intellij.psi.PsiClass;
|
||||||
import com.intellij.psi.PsiClassType;
|
import com.intellij.psi.PsiClassType;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.PsiEllipsisType;
|
import com.intellij.psi.PsiEllipsisType;
|
||||||
import com.intellij.psi.PsiField;
|
|
||||||
import com.intellij.psi.PsiJavaFile;
|
import com.intellij.psi.PsiJavaFile;
|
||||||
import com.intellij.psi.PsiMethod;
|
import com.intellij.psi.PsiMethod;
|
||||||
import com.intellij.psi.PsiModifier;
|
import com.intellij.psi.PsiModifier;
|
||||||
@@ -63,6 +60,7 @@ import org.jetbrains.jet.rt.signature.JetSignatureVisitor;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -128,11 +126,12 @@ public class JavaDescriptorResolver {
|
|||||||
this.lowerBoundsForKotlin = lowerBoundsForKotlin;
|
this.lowerBoundsForKotlin = lowerBoundsForKotlin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static abstract class ResolverScopeData {
|
private static abstract class ResolverScopeData {
|
||||||
@Nullable
|
|
||||||
private Set<VariableDescriptor> properties;
|
|
||||||
protected boolean kotlin;
|
protected boolean kotlin;
|
||||||
|
|
||||||
|
private Map<String, NamedMembers> namedMembersMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ResolverClassData extends ResolverScopeData {
|
private static class ResolverClassData extends ResolverScopeData {
|
||||||
@@ -159,7 +158,6 @@ public class JavaDescriptorResolver {
|
|||||||
|
|
||||||
private final Map<PsiTypeParameter, TypeParameterDescriptorInitialization> typeParameterDescriptorCache = Maps.newHashMap();
|
private final Map<PsiTypeParameter, TypeParameterDescriptorInitialization> typeParameterDescriptorCache = Maps.newHashMap();
|
||||||
protected final Map<PsiMethod, FunctionDescriptor> methodDescriptorCache = Maps.newHashMap();
|
protected final Map<PsiMethod, FunctionDescriptor> methodDescriptorCache = Maps.newHashMap();
|
||||||
protected final Map<PsiField, VariableDescriptor> fieldDescriptorCache = Maps.newHashMap();
|
|
||||||
protected final JavaPsiFacade javaFacade;
|
protected final JavaPsiFacade javaFacade;
|
||||||
protected final GlobalSearchScope javaSearchScope;
|
protected final GlobalSearchScope javaSearchScope;
|
||||||
protected final JavaSemanticServices semanticServices;
|
protected final JavaSemanticServices semanticServices;
|
||||||
@@ -737,15 +735,6 @@ public class JavaDescriptorResolver {
|
|||||||
|
|
||||||
PsiType psiType = parameter.getPsiParameter().getType();
|
PsiType psiType = parameter.getPsiParameter().getType();
|
||||||
|
|
||||||
JetType varargElementType;
|
|
||||||
if (psiType instanceof PsiEllipsisType) {
|
|
||||||
PsiEllipsisType psiEllipsisType = (PsiEllipsisType) psiType;
|
|
||||||
varargElementType = semanticServices.getTypeTransformer().transformToType(psiEllipsisType.getComponentType());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
varargElementType = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean nullable = parameter.getJetValueParameter().nullable();
|
boolean nullable = parameter.getJetValueParameter().nullable();
|
||||||
|
|
||||||
// TODO: must be very slow, make it lazy?
|
// TODO: must be very slow, make it lazy?
|
||||||
@@ -765,6 +754,14 @@ public class JavaDescriptorResolver {
|
|||||||
} else {
|
} else {
|
||||||
outType = semanticServices.getTypeTransformer().transformToType(psiType);
|
outType = semanticServices.getTypeTransformer().transformToType(psiType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JetType varargElementType;
|
||||||
|
if (psiType instanceof PsiEllipsisType) {
|
||||||
|
varargElementType = semanticServices.getJetSemanticServices().getStandardLibrary().getArrayElementType(outType);
|
||||||
|
} else {
|
||||||
|
varargElementType = null;
|
||||||
|
}
|
||||||
|
|
||||||
if (receiver) {
|
if (receiver) {
|
||||||
return JvmMethodParameterMeaning.receiver(outType);
|
return JvmMethodParameterMeaning.receiver(outType);
|
||||||
} else {
|
} else {
|
||||||
@@ -781,217 +778,187 @@ 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
MembersForProperty members = new MembersForProperty();
|
|
||||||
members.field = new PsiFieldWrapper(field);
|
|
||||||
members.type = field.getType();
|
|
||||||
membersMap.put(new PropertyKey(field.getName() /*, field.getType(), null*/), members);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (PsiMethod psiMethod : clazz.getMethods()) {
|
|
||||||
PsiMethodWrapper method = new PsiMethodWrapper(psiMethod);
|
|
||||||
|
|
||||||
if (method.isStatic() != staticMembers) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (method.isPrivate()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: "is" prefix
|
|
||||||
// TODO: remove getJavaClass
|
|
||||||
if (psiMethod.getName().startsWith(JvmAbi.GETTER_PREFIX)) {
|
|
||||||
|
|
||||||
// TODO: some java properties too
|
|
||||||
if (method.getJetMethod().kind() == JvmStdlibNames.JET_METHOD_KIND_PROPERTY) {
|
|
||||||
|
|
||||||
if (psiMethod.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(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();
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// 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) {
|
public Set<VariableDescriptor> resolveFieldGroupByName(@NotNull DeclarationDescriptor owner, PsiClass psiClass, String fieldName, boolean staticMembers) {
|
||||||
Set<VariableDescriptor> r = Sets.newHashSet();
|
ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass));
|
||||||
// TODO: slow
|
|
||||||
Set<VariableDescriptor> variables = resolveFieldGroup(owner, psiClass, staticMembers);
|
|
||||||
for (VariableDescriptor variable : variables) {
|
|
||||||
if (variable.getName().equals(fieldName)) {
|
|
||||||
r.add(variable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
NamedMembers namedMembers = scopeData.namedMembersMap.get(fieldName);
|
||||||
|
if (namedMembers == null) {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
resolveNamedGroupProperties(owner, staticMembers, namedMembers, fieldName);
|
||||||
|
|
||||||
|
return namedMembers.propertyDescriptors;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Set<VariableDescriptor> resolveFieldGroup(@NotNull DeclarationDescriptor owner, PsiClass psiClass, boolean staticMembers) {
|
public Set<VariableDescriptor> resolveFieldGroup(@NotNull DeclarationDescriptor owner, PsiClass psiClass, boolean staticMembers) {
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
resolveNamedGroupProperties(owner, staticMembers, namedMembers, propertyName);
|
||||||
|
descriptors.addAll(namedMembers.propertyDescriptors);
|
||||||
|
}
|
||||||
|
return descriptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeSource propertyType = namedMembers.properties.type;
|
||||||
|
TypeSource receiver = 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<TypeParameterDescriptor> typeParametersForReceiver = new ArrayList<TypeParameterDescriptor>();
|
||||||
|
typeParametersForReceiver.addAll(classTypeParameters);
|
||||||
|
typeParametersForReceiver.addAll(typeParameters);
|
||||||
|
|
||||||
|
TypeParameterListTypeVariableResolver typeVariableResolverForPropertyInternals = new TypeParameterListTypeVariableResolver(typeParametersForReceiver);
|
||||||
|
|
||||||
|
JetType receiverJetType;
|
||||||
|
if (receiver == null) {
|
||||||
|
receiverJetType = null;
|
||||||
|
} else if (receiver.getTypeString().length() > 0) {
|
||||||
|
receiverJetType = semanticServices.getTypeTransformer().transformToType(receiver.getTypeString(), typeVariableResolverForPropertyInternals);
|
||||||
|
} else {
|
||||||
|
receiverJetType = semanticServices.getTypeTransformer().transformToType(receiver.getPsiType());
|
||||||
|
}
|
||||||
|
|
||||||
|
JetType type;
|
||||||
|
if (propertyType.getTypeString().length() > 0) {
|
||||||
|
type = semanticServices.getTypeTransformer().transformToType(propertyType.getTypeString(), typeVariableResolverForPropertyInternals);
|
||||||
|
} else {
|
||||||
|
type = semanticServices.getTypeTransformer().transformToType(propertyType.getPsiType());
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
namedMembers.propertyDescriptors = Collections.<VariableDescriptor>singleton(propertyDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resolveNamedGroupFunctions(DeclarationDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, boolean staticMembers, NamedMembers namedMembers, String functionName) {
|
||||||
|
if (namedMembers.functionDescriptors != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (namedMembers.methods == null) {
|
||||||
|
namedMembers.functionDescriptors = Collections.emptySet();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<FunctionDescriptor> functionDescriptors = new HashSet<FunctionDescriptor>(namedMembers.methods.size());
|
||||||
|
for (PsiMethodWrapper method : namedMembers.methods) {
|
||||||
|
functionDescriptors.add(resolveMethodToFunctionDescriptor(owner, psiClass, typeSubstitutorForGenericSuperclasses, method));
|
||||||
|
}
|
||||||
|
namedMembers.functionDescriptors = functionDescriptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResolverScopeData getResolverScopeData(DeclarationDescriptor owner, PsiClassWrapper psiClass) {
|
||||||
ResolverScopeData scopeData;
|
ResolverScopeData scopeData;
|
||||||
|
boolean staticMembers;
|
||||||
if (owner instanceof JavaNamespaceDescriptor) {
|
if (owner instanceof JavaNamespaceDescriptor) {
|
||||||
scopeData = namespaceDescriptorCacheByFqn.get(((JavaNamespaceDescriptor) owner).getQualifiedName());
|
scopeData = namespaceDescriptorCacheByFqn.get(((JavaNamespaceDescriptor) owner).getQualifiedName());
|
||||||
|
staticMembers = true;
|
||||||
} else if (owner instanceof ClassDescriptor) {
|
} else if (owner instanceof ClassDescriptor) {
|
||||||
scopeData = classDescriptorCache.get(psiClass.getQualifiedName());
|
scopeData = classDescriptorCache.get(psiClass.getQualifiedName());
|
||||||
|
staticMembers = false;
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
@@ -999,151 +966,29 @@ public class JavaDescriptorResolver {
|
|||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scopeData.properties != null) {
|
if (scopeData.namedMembersMap == null) {
|
||||||
return scopeData.properties;
|
scopeData.namedMembersMap = JavaDescriptorResolverHelper.getNamedMembers(psiClass, staticMembers, scopeData.kotlin);
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<VariableDescriptor> descriptors = Sets.newHashSet();
|
return scopeData;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Set<FunctionDescriptor> resolveFunctionGroup(@NotNull DeclarationDescriptor owner, @NotNull PsiClass psiClass, @Nullable ClassDescriptor classDescriptor, @NotNull String methodName, boolean staticMembers) {
|
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();
|
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);
|
TypeSubstitutor typeSubstitutor = createSubstitutorForGenericSupertypes(classDescriptor);
|
||||||
for (HierarchicalMethodSignature signature: signatures) {
|
resolveNamedGroupFunctions(owner, psiClass, typeSubstitutor, staticMembers, namedMembers, methodName);
|
||||||
if (!methodName.equals(signature.getName())) {
|
|
||||||
continue;
|
return namedMembers.functionDescriptors;
|
||||||
}
|
|
||||||
|
|
||||||
FunctionDescriptor substitutedFunctionDescriptor = resolveHierarchicalSignatureToFunction(owner, psiClass, staticMembers, typeSubstitutor, signature);
|
|
||||||
if (substitutedFunctionDescriptor != null) {
|
|
||||||
writableFunctionGroup.add(substitutedFunctionDescriptor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return writableFunctionGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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;
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeSubstitutor createSubstitutorForGenericSupertypes(ClassDescriptor classDescriptor) {
|
public TypeSubstitutor createSubstitutorForGenericSupertypes(ClassDescriptor classDescriptor) {
|
||||||
@@ -1178,16 +1023,15 @@ public class JavaDescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public FunctionDescriptor resolveMethodToFunctionDescriptor(DeclarationDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, PsiMethod psiMethod) {
|
public FunctionDescriptor resolveMethodToFunctionDescriptor(DeclarationDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, PsiMethodWrapper method) {
|
||||||
PsiMethodWrapper method = new PsiMethodWrapper(psiMethod);
|
|
||||||
|
|
||||||
PsiType returnType = psiMethod.getReturnType();
|
PsiType returnType = method.getReturnType();
|
||||||
if (returnType == null) {
|
if (returnType == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
FunctionDescriptor functionDescriptor = methodDescriptorCache.get(psiMethod);
|
FunctionDescriptor functionDescriptor = methodDescriptorCache.get(method.getPsiMethod());
|
||||||
if (functionDescriptor != null) {
|
if (functionDescriptor != null) {
|
||||||
if (psiMethod.getContainingClass() != psiClass) {
|
if (method.getPsiMethod().getContainingClass() != psiClass) {
|
||||||
functionDescriptor = functionDescriptor.substitute(typeSubstitutorForGenericSuperclasses);
|
functionDescriptor = functionDescriptor.substitute(typeSubstitutorForGenericSuperclasses);
|
||||||
}
|
}
|
||||||
return functionDescriptor;
|
return functionDescriptor;
|
||||||
@@ -1238,11 +1082,11 @@ public class JavaDescriptorResolver {
|
|||||||
DeclarationDescriptor classDescriptor;
|
DeclarationDescriptor classDescriptor;
|
||||||
final List<TypeParameterDescriptor> classTypeParameters;
|
final List<TypeParameterDescriptor> classTypeParameters;
|
||||||
if (method.isStatic()) {
|
if (method.isStatic()) {
|
||||||
classDescriptor = resolveNamespace(psiMethod.getContainingClass());
|
classDescriptor = resolveNamespace(method.getPsiMethod().getContainingClass());
|
||||||
classTypeParameters = Collections.emptyList();
|
classTypeParameters = Collections.emptyList();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ClassDescriptor classClassDescriptor = resolveClass(psiMethod.getContainingClass());
|
ClassDescriptor classClassDescriptor = resolveClass(method.getPsiMethod().getContainingClass());
|
||||||
classDescriptor = classClassDescriptor;
|
classDescriptor = classClassDescriptor;
|
||||||
classTypeParameters = classClassDescriptor.getTypeConstructor().getParameters();
|
classTypeParameters = classClassDescriptor.getTypeConstructor().getParameters();
|
||||||
}
|
}
|
||||||
@@ -1252,14 +1096,14 @@ public class JavaDescriptorResolver {
|
|||||||
NamedFunctionDescriptorImpl functionDescriptorImpl = new NamedFunctionDescriptorImpl(
|
NamedFunctionDescriptorImpl functionDescriptorImpl = new NamedFunctionDescriptorImpl(
|
||||||
owner,
|
owner,
|
||||||
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
||||||
psiMethod.getName()
|
method.getName()
|
||||||
);
|
);
|
||||||
methodDescriptorCache.put(psiMethod, functionDescriptorImpl);
|
methodDescriptorCache.put(method.getPsiMethod(), functionDescriptorImpl);
|
||||||
|
|
||||||
// TODO: add outer classes
|
// TODO: add outer classes
|
||||||
TypeParameterListTypeVariableResolver typeVariableResolverForParameters = new TypeParameterListTypeVariableResolver(classTypeParameters);
|
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 {
|
class MethodTypeVariableResolver implements TypeVariableResolver {
|
||||||
|
|
||||||
@@ -1288,12 +1132,12 @@ public class JavaDescriptorResolver {
|
|||||||
methodTypeParameters,
|
methodTypeParameters,
|
||||||
valueParameterDescriptors.descriptors,
|
valueParameterDescriptors.descriptors,
|
||||||
makeReturnType(returnType, method, new MethodTypeVariableResolver()),
|
makeReturnType(returnType, method, new MethodTypeVariableResolver()),
|
||||||
Modality.convertFromFlags(psiMethod.hasModifierProperty(PsiModifier.ABSTRACT), !psiMethod.hasModifierProperty(PsiModifier.FINAL)),
|
Modality.convertFromFlags(method.getPsiMethod().hasModifierProperty(PsiModifier.ABSTRACT), !method.isFinal()),
|
||||||
resolveVisibilityFromPsiModifiers(psiMethod)
|
resolveVisibilityFromPsiModifiers(method.getPsiMethod())
|
||||||
);
|
);
|
||||||
semanticServices.getTrace().record(BindingContext.FUNCTION, psiMethod, functionDescriptorImpl);
|
semanticServices.getTrace().record(BindingContext.FUNCTION, method.getPsiMethod(), functionDescriptorImpl);
|
||||||
FunctionDescriptor substitutedFunctionDescriptor = functionDescriptorImpl;
|
FunctionDescriptor substitutedFunctionDescriptor = functionDescriptorImpl;
|
||||||
if (psiMethod.getContainingClass() != psiClass) {
|
if (method.getPsiMethod().getContainingClass() != psiClass) {
|
||||||
substitutedFunctionDescriptor = functionDescriptorImpl.substitute(typeSubstitutorForGenericSuperclasses);
|
substitutedFunctionDescriptor = functionDescriptorImpl.substitute(typeSubstitutorForGenericSuperclasses);
|
||||||
}
|
}
|
||||||
return substitutedFunctionDescriptor;
|
return substitutedFunctionDescriptor;
|
||||||
@@ -1400,7 +1244,7 @@ public class JavaDescriptorResolver {
|
|||||||
ownerOwner = classDescriptor;
|
ownerOwner = classDescriptor;
|
||||||
substitutorForGenericSupertypes = semanticServices.getDescriptorResolver().createSubstitutorForGenericSupertypes(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);
|
return resolveTypeParameter(functionDescriptor, typeParameter);
|
||||||
}
|
}
|
||||||
throw new IllegalStateException("Unknown parent type: " + owner);
|
throw new IllegalStateException("Unknown parent type: " + owner);
|
||||||
|
|||||||
+174
@@ -0,0 +1,174 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve.java;
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.text.StringUtil;
|
||||||
|
import com.intellij.psi.HierarchicalMethodSignature;
|
||||||
|
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 = new TypeSource("", 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;
|
||||||
|
|
||||||
|
TypeSource receiverType;
|
||||||
|
if (i < method.getParameters().size() && method.getParameter(i).getJetValueParameter().receiver()) {
|
||||||
|
PsiParameterWrapper receiverParameter = method.getParameter(i);
|
||||||
|
receiverType = new TypeSource(receiverParameter.getJetValueParameter().type(), receiverParameter.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 = new TypeSource(method.getJetMethod().propertyType(), 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;
|
||||||
|
|
||||||
|
TypeSource receiverType = null;
|
||||||
|
PsiParameterWrapper p1 = method.getParameter(0);
|
||||||
|
if (p1.getJetValueParameter().receiver()) {
|
||||||
|
receiverType = new TypeSource(p1.getJetValueParameter().type(), p1.getPsiParameter().getType());
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i < method.getParameters().size() && method.getParameter(i).getJetTypeParameter().isDefined()) {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i + 1 != method.getParameters().size()) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
|
PsiParameterWrapper propertyTypeParameter = method.getParameter(i);
|
||||||
|
TypeSource propertyType = new TypeSource(method.getJetMethod().propertyType(), propertyTypeParameter.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
-1
@@ -190,7 +190,6 @@ public class JavaTypeTransformer {
|
|||||||
PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType();
|
PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType();
|
||||||
classDescriptorMap.put(jvmPrimitiveType.getWrapper().getFqName(), standardLibrary.getPrimitiveClassDescriptor(primitiveType));
|
classDescriptorMap.put(jvmPrimitiveType.getWrapper().getFqName(), standardLibrary.getPrimitiveClassDescriptor(primitiveType));
|
||||||
}
|
}
|
||||||
//classDescriptorMap.put("java.lang.Object", standardLibrary.get
|
|
||||||
classDescriptorMap.put("java.lang.String", standardLibrary.getString());
|
classDescriptorMap.put("java.lang.String", standardLibrary.getString());
|
||||||
}
|
}
|
||||||
return classDescriptorMap;
|
return classDescriptorMap;
|
||||||
|
|||||||
+30
-7
@@ -12,11 +12,14 @@ import org.jetbrains.jet.lang.types.TypeProjection;
|
|||||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||||
import org.jetbrains.jet.lang.types.Variance;
|
import org.jetbrains.jet.lang.types.Variance;
|
||||||
import org.jetbrains.jet.rt.signature.JetSignatureExceptionsAdapter;
|
import org.jetbrains.jet.rt.signature.JetSignatureExceptionsAdapter;
|
||||||
|
import org.jetbrains.jet.rt.signature.JetSignatureVariance;
|
||||||
import org.jetbrains.jet.rt.signature.JetSignatureVisitor;
|
import org.jetbrains.jet.rt.signature.JetSignatureVisitor;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Stepan Koltsov
|
* @author Stepan Koltsov
|
||||||
@@ -75,6 +78,26 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd
|
|||||||
|
|
||||||
this.classDescriptor = this.javaSemanticServices.getTypeTransformer().getPrimitiveWrappersClassDescriptorMap().get(ourName);
|
this.classDescriptor = this.javaSemanticServices.getTypeTransformer().getPrimitiveWrappersClassDescriptorMap().get(ourName);
|
||||||
|
|
||||||
|
if (this.classDescriptor == null && ourName.equals("java.lang.Object")) {
|
||||||
|
this.classDescriptor = JetStandardClasses.getAny();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (classDescriptor == null) {
|
||||||
|
// TODO: this is the worst code in Kotlin project
|
||||||
|
Matcher matcher = Pattern.compile("jet\\.Function(\\d+)").matcher(ourName);
|
||||||
|
if (matcher.matches()) {
|
||||||
|
classDescriptor = JetStandardClasses.getFunction(Integer.parseInt(matcher.group(1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (classDescriptor == null) {
|
||||||
|
Matcher matcher = Pattern.compile("jet\\.Tuple(\\d+)").matcher(ourName);
|
||||||
|
if (matcher.matches()) {
|
||||||
|
classDescriptor = JetStandardClasses.getTuple(Integer.parseInt(matcher.group(1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (this.classDescriptor == null) {
|
if (this.classDescriptor == null) {
|
||||||
this.classDescriptor = javaDescriptorResolver.resolveClass(ourName);
|
this.classDescriptor = javaDescriptorResolver.resolveClass(ourName);
|
||||||
}
|
}
|
||||||
@@ -86,22 +109,22 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd
|
|||||||
this.typeArguments = new ArrayList<TypeProjection>();
|
this.typeArguments = new ArrayList<TypeProjection>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Variance parseVariance(char wildcard) {
|
private static Variance parseVariance(JetSignatureVariance variance) {
|
||||||
switch (wildcard) {
|
switch (variance) {
|
||||||
case '=': return Variance.INVARIANT;
|
case INVARIANT: return Variance.INVARIANT;
|
||||||
case '+': return Variance.OUT_VARIANCE;
|
case OUT: return Variance.OUT_VARIANCE;
|
||||||
case '-': return Variance.IN_VARIANCE;
|
case IN: return Variance.IN_VARIANCE;
|
||||||
default: throw new IllegalStateException();
|
default: throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetSignatureVisitor visitTypeArgument(final char wildcard) {
|
public JetSignatureVisitor visitTypeArgument(final JetSignatureVariance variance) {
|
||||||
return new JetTypeJetSignatureReader(javaSemanticServices, jetStandardLibrary, typeVariableResolver) {
|
return new JetTypeJetSignatureReader(javaSemanticServices, jetStandardLibrary, typeVariableResolver) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void done(@NotNull JetType jetType) {
|
protected void done(@NotNull JetType jetType) {
|
||||||
typeArguments.add(new TypeProjection(parseVariance(wildcard), jetType));
|
typeArguments.add(new TypeProjection(parseVariance(variance), jetType));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve.java;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Stepan Koltsov
|
||||||
|
*/
|
||||||
|
class MembersForProperty {
|
||||||
|
PsiFieldWrapper field;
|
||||||
|
PsiMethodWrapper setter;
|
||||||
|
PsiMethodWrapper getter;
|
||||||
|
|
||||||
|
TypeSource type;
|
||||||
|
TypeSource receiverType;
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package org.jetbrains.jet.lang.resolve.java;
|
package org.jetbrains.jet.lang.resolve.java;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiField;
|
||||||
import com.intellij.psi.PsiMember;
|
import com.intellij.psi.PsiMember;
|
||||||
|
import com.intellij.psi.PsiType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -10,4 +12,12 @@ public class PsiFieldWrapper extends PsiMemberWrapper {
|
|||||||
public PsiFieldWrapper(@NotNull PsiMember psiMember) {
|
public PsiFieldWrapper(@NotNull PsiMember psiMember) {
|
||||||
super(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.PsiMethod;
|
||||||
import com.intellij.psi.PsiModifier;
|
import com.intellij.psi.PsiModifier;
|
||||||
import com.intellij.psi.PsiParameter;
|
import com.intellij.psi.PsiParameter;
|
||||||
|
import com.intellij.psi.PsiType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
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.JetConstructorAnnotation;
|
||||||
import org.jetbrains.jet.lang.resolve.java.kt.JetMethodAnnotation;
|
import org.jetbrains.jet.lang.resolve.java.kt.JetMethodAnnotation;
|
||||||
|
|
||||||
@@ -55,8 +57,17 @@ public class PsiMethodWrapper extends PsiMemberWrapper {
|
|||||||
return jetConstructor;
|
return jetConstructor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAbstract() {
|
||||||
|
return psiMember.hasModifierProperty(PsiModifier.ABSTRACT);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public PsiMethod getPsiMethod() {
|
public PsiMethod getPsiMethod() {
|
||||||
return (PsiMethod) psiMember;
|
return (PsiMethod) psiMember;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public PsiType getReturnType() {
|
||||||
|
return getPsiMethod().getReturnType();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve.java;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiType;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Stepan Koltsov
|
||||||
|
*/
|
||||||
|
class TypeSource {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final String typeString;
|
||||||
|
@NotNull
|
||||||
|
private final PsiType psiType;
|
||||||
|
|
||||||
|
TypeSource(@NotNull String typeString, @NotNull PsiType psiType) {
|
||||||
|
this.typeString = typeString;
|
||||||
|
this.psiType = psiType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String getTypeString() {
|
||||||
|
return typeString;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public PsiType getPsiType() {
|
||||||
|
return psiType;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -78,6 +78,7 @@ public class JetStandardLibrary {
|
|||||||
private EnumMap<PrimitiveType, JetType> primitiveTypeToArrayJetType;
|
private EnumMap<PrimitiveType, JetType> primitiveTypeToArrayJetType;
|
||||||
private EnumMap<PrimitiveType, JetType> primitiveTypeToNullableArrayJetType;
|
private EnumMap<PrimitiveType, JetType> primitiveTypeToNullableArrayJetType;
|
||||||
private Map<JetType, JetType> primitiveJetTypeToJetArrayType;
|
private Map<JetType, JetType> primitiveJetTypeToJetArrayType;
|
||||||
|
private Map<JetType, JetType> jetArrayTypeToPrimitiveJetType;
|
||||||
|
|
||||||
private JetStandardLibrary(@NotNull Project project) {
|
private JetStandardLibrary(@NotNull Project project) {
|
||||||
// TODO : review
|
// TODO : review
|
||||||
@@ -147,6 +148,7 @@ public class JetStandardLibrary {
|
|||||||
primitiveTypeToArrayJetType = new EnumMap<PrimitiveType, JetType>(PrimitiveType.class);
|
primitiveTypeToArrayJetType = new EnumMap<PrimitiveType, JetType>(PrimitiveType.class);
|
||||||
primitiveTypeToNullableArrayJetType = new EnumMap<PrimitiveType, JetType>(PrimitiveType.class);
|
primitiveTypeToNullableArrayJetType = new EnumMap<PrimitiveType, JetType>(PrimitiveType.class);
|
||||||
primitiveJetTypeToJetArrayType = new HashMap<JetType, JetType>();
|
primitiveJetTypeToJetArrayType = new HashMap<JetType, JetType>();
|
||||||
|
jetArrayTypeToPrimitiveJetType = new HashMap<JetType, JetType>();
|
||||||
|
|
||||||
for (PrimitiveType primitive : PrimitiveType.values()) {
|
for (PrimitiveType primitive : PrimitiveType.values()) {
|
||||||
makePrimitive(primitive);
|
makePrimitive(primitive);
|
||||||
@@ -167,6 +169,7 @@ public class JetStandardLibrary {
|
|||||||
primitiveTypeToArrayJetType.put(primitiveType, arrayType);
|
primitiveTypeToArrayJetType.put(primitiveType, arrayType);
|
||||||
primitiveTypeToNullableArrayJetType.put(primitiveType, TypeUtils.makeNullable(arrayType));
|
primitiveTypeToNullableArrayJetType.put(primitiveType, TypeUtils.makeNullable(arrayType));
|
||||||
primitiveJetTypeToJetArrayType.put(type, arrayType);
|
primitiveJetTypeToJetArrayType.put(type, arrayType);
|
||||||
|
jetArrayTypeToPrimitiveJetType.put(arrayType, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -334,6 +337,22 @@ public class JetStandardLibrary {
|
|||||||
getArray().getMemberScope(types)
|
getArray().getMemberScope(types)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JetType getArrayElementType(@NotNull JetType arrayType) {
|
||||||
|
// make non-null?
|
||||||
|
if (arrayType.getConstructor().getDeclarationDescriptor() == getArray()) {
|
||||||
|
if (arrayType.getArguments().size() != 1) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
return arrayType.getArguments().get(0).getType();
|
||||||
|
}
|
||||||
|
JetType primitiveType = jetArrayTypeToPrimitiveJetType.get(arrayType);
|
||||||
|
if (primitiveType == null) {
|
||||||
|
throw new IllegalStateException("not array: " + arrayType);
|
||||||
|
}
|
||||||
|
return primitiveType;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JetType getIterableType(@NotNull JetType argument) {
|
public JetType getIterableType(@NotNull JetType argument) {
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import java.util.Collection
|
||||||
|
|
||||||
|
val Collection<*>.anotherSize : Int
|
||||||
|
get() = size()
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun any(): Any = 1
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun anyq(): Any? = 1
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun fun1(): (String) -> Int = throw Exception()
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import java.util.List
|
||||||
|
|
||||||
|
fun listOfAny(): List<Any> = throw Exception()
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import java.util.List
|
||||||
|
|
||||||
|
fun listOfAnyQ(): List<Any?> = throw Exception()
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import java.util.List
|
||||||
|
|
||||||
|
fun listOfStar(): List<*> = throw Exception()
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import java.util.List
|
||||||
|
|
||||||
|
fun listOfStar(): List<*> = throw Exception()
|
||||||
|
|
||||||
|
// method: namespace::listOfStar
|
||||||
|
// jvm signature: ()Ljava/util/List;
|
||||||
|
// generic signature: ()Ljava/util/List<+Ljava/lang/Object;>;
|
||||||
|
// kotlin signature: ()Ljava/util/List<+?Ljava/lang/Object;>;
|
||||||
@@ -15,6 +15,8 @@ import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
|||||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.JavaNamespaceDescriptor;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
@@ -216,7 +218,13 @@ class NamespaceComparator {
|
|||||||
} else {
|
} else {
|
||||||
sb.append("val ");
|
sb.append("val ");
|
||||||
}
|
}
|
||||||
|
if (!prop.getTypeParameters().isEmpty()) {
|
||||||
|
sb.append(" <");
|
||||||
|
new Serializer(sb).serializeCommaSeparated(prop.getTypeParameters());
|
||||||
|
sb.append("> ");
|
||||||
|
}
|
||||||
if (prop.getReceiverParameter().exists()) {
|
if (prop.getReceiverParameter().exists()) {
|
||||||
|
// TODO: print only name for type parameter
|
||||||
new Serializer(sb).serialize(prop.getReceiverParameter().getType());
|
new Serializer(sb).serialize(prop.getReceiverParameter().getType());
|
||||||
sb.append(".");
|
sb.append(".");
|
||||||
}
|
}
|
||||||
@@ -272,6 +280,9 @@ class NamespaceComparator {
|
|||||||
}
|
}
|
||||||
sb.append(">");
|
sb.append(">");
|
||||||
}
|
}
|
||||||
|
if (type.isNullable()) {
|
||||||
|
sb.append("?");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void serializeCommaSeparated(List<?> list) {
|
public void serializeCommaSeparated(List<?> list) {
|
||||||
@@ -290,6 +301,10 @@ class NamespaceComparator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Method getMethodToSerialize(Object o) {
|
private Method getMethodToSerialize(Object o) {
|
||||||
|
if (o == null) {
|
||||||
|
throw new IllegalStateException("won't serialize null");
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: cache
|
// TODO: cache
|
||||||
for (Method method : this.getClass().getMethods()) {
|
for (Method method : this.getClass().getMethods()) {
|
||||||
if (!method.getName().equals("serialize")) {
|
if (!method.getName().equals("serialize")) {
|
||||||
@@ -328,11 +343,12 @@ class NamespaceComparator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void serialize(NamespaceDescriptor ns) {
|
public void serialize(NamespaceDescriptor ns) {
|
||||||
if (ns.getContainingDeclaration() == null) {
|
if (isRootNs(ns)) {
|
||||||
// root ns
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new NamespacePrefixSerializer(sb).serialize(ns.getContainingDeclaration());
|
if (ns.getContainingDeclaration() != null) {
|
||||||
|
new NamespacePrefixSerializer(sb).serialize(ns.getContainingDeclaration());
|
||||||
|
}
|
||||||
sb.append(ns.getName());
|
sb.append(ns.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,6 +372,11 @@ class NamespaceComparator {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isRootNs(DeclarationDescriptor ns) {
|
||||||
|
// upyachka
|
||||||
|
return ns instanceof JavaNamespaceDescriptor && JavaDescriptorResolver.JAVA_ROOT.equals(ns.getName());
|
||||||
|
}
|
||||||
|
|
||||||
private static class NamespacePrefixSerializer extends Serializer {
|
private static class NamespacePrefixSerializer extends Serializer {
|
||||||
|
|
||||||
public NamespacePrefixSerializer(StringBuilder sb) {
|
public NamespacePrefixSerializer(StringBuilder sb) {
|
||||||
@@ -364,11 +385,10 @@ class NamespaceComparator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serialize(NamespaceDescriptor ns) {
|
public void serialize(NamespaceDescriptor ns) {
|
||||||
if (ns.getContainingDeclaration() == null) {
|
super.serialize(ns);
|
||||||
// root ns
|
if (isRootNs(ns)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
super.serialize(ns);
|
|
||||||
sb.append(".");
|
sb.append(".");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,21 @@
|
|||||||
package jet.typeinfo;
|
package jet.typeinfo;
|
||||||
|
|
||||||
|
import org.jetbrains.jet.rt.signature.JetSignatureVariance;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author alex.tkachman
|
* @author alex.tkachman
|
||||||
*/
|
*/
|
||||||
public enum TypeInfoVariance {
|
public enum TypeInfoVariance {
|
||||||
INVARIANT("") ,
|
INVARIANT("", JetSignatureVariance.INVARIANT) ,
|
||||||
IN("in"),
|
IN("in", JetSignatureVariance.IN),
|
||||||
OUT("out");
|
OUT("out", JetSignatureVariance.OUT);
|
||||||
|
|
||||||
private final String label;
|
private final String label;
|
||||||
|
private final JetSignatureVariance variance;
|
||||||
|
|
||||||
TypeInfoVariance(String label) {
|
TypeInfoVariance(String label, JetSignatureVariance variance) {
|
||||||
this.label = label;
|
this.label = label;
|
||||||
|
this.variance = variance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import jet.typeinfo.TypeInfoProjection;
|
|||||||
import jet.typeinfo.TypeInfoVariance;
|
import jet.typeinfo.TypeInfoVariance;
|
||||||
import org.jetbrains.jet.rt.signature.JetSignatureExceptionsAdapter;
|
import org.jetbrains.jet.rt.signature.JetSignatureExceptionsAdapter;
|
||||||
import org.jetbrains.jet.rt.signature.JetSignatureReader;
|
import org.jetbrains.jet.rt.signature.JetSignatureReader;
|
||||||
|
import org.jetbrains.jet.rt.signature.JetSignatureVariance;
|
||||||
import org.jetbrains.jet.rt.signature.JetSignatureVisitor;
|
import org.jetbrains.jet.rt.signature.JetSignatureVisitor;
|
||||||
|
|
||||||
import java.lang.reflect.TypeVariable;
|
import java.lang.reflect.TypeVariable;
|
||||||
@@ -176,17 +177,17 @@ class TypeInfoParser {
|
|||||||
this.projections = new ArrayList<TypeInfoProjection>();
|
this.projections = new ArrayList<TypeInfoProjection>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TypeInfoVariance parseVariance(char wildcard) {
|
private static TypeInfoVariance parseVariance(JetSignatureVariance variance) {
|
||||||
switch (wildcard) {
|
switch (variance) {
|
||||||
case '=': return TypeInfoVariance.INVARIANT;
|
case INVARIANT: return TypeInfoVariance.INVARIANT;
|
||||||
case '+': return TypeInfoVariance.OUT;
|
case OUT: return TypeInfoVariance.OUT;
|
||||||
case '-': return TypeInfoVariance.IN;
|
case IN: return TypeInfoVariance.IN;
|
||||||
default: throw new IllegalStateException();
|
default: throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetSignatureVisitor visitTypeArgument(final char wildcard) {
|
public JetSignatureVisitor visitTypeArgument(final JetSignatureVariance wildcard) {
|
||||||
final TypeInfoVariance variance = parseVariance(wildcard);
|
final TypeInfoVariance variance = parseVariance(wildcard);
|
||||||
return new SignatureParserJetSignatureAdapter(classLoader, signature) {
|
return new SignatureParserJetSignatureAdapter(classLoader, signature) {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public class JetSignatureAdapter implements JetSignatureVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetSignatureVisitor visitTypeArgument(char wildcard) {
|
public JetSignatureVisitor visitTypeArgument(JetSignatureVariance wildcard) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ public class JetSignatureExceptionsAdapter implements JetSignatureVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetSignatureVisitor visitTypeArgument(char wildcard) {
|
public JetSignatureVisitor visitTypeArgument(JetSignatureVariance wildcard) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -194,12 +194,12 @@ public class JetSignatureReader {
|
|||||||
case '-':
|
case '-':
|
||||||
pos = parseType(signature,
|
pos = parseType(signature,
|
||||||
pos + 1,
|
pos + 1,
|
||||||
v.visitTypeArgument(c));
|
v.visitTypeArgument(JetSignatureVariance.parseVariance(c)));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pos = parseType(signature,
|
pos = parseType(signature,
|
||||||
pos,
|
pos,
|
||||||
v.visitTypeArgument('='));
|
v.visitTypeArgument(JetSignatureVariance.INVARIANT));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package org.jetbrains.jet.rt.signature;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Stepan Koltsov
|
||||||
|
*/
|
||||||
|
public enum JetSignatureVariance {
|
||||||
|
INVARIANT('='),
|
||||||
|
IN('-'),
|
||||||
|
OUT('+'),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final char c;
|
||||||
|
|
||||||
|
private JetSignatureVariance(char c) {
|
||||||
|
this.c = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public char getC() {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JetSignatureVariance parseVariance(char c) {
|
||||||
|
switch (c) {
|
||||||
|
case '=': return INVARIANT;
|
||||||
|
case '+': return OUT;
|
||||||
|
case '-': return IN;
|
||||||
|
default: throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -134,7 +134,7 @@ public interface JetSignatureVisitor {
|
|||||||
* @param wildcard '+', '-' or '='.
|
* @param wildcard '+', '-' or '='.
|
||||||
* @return a non null visitor to visit the signature of the type argument.
|
* @return a non null visitor to visit the signature of the type argument.
|
||||||
*/
|
*/
|
||||||
JetSignatureVisitor visitTypeArgument(char wildcard);
|
JetSignatureVisitor visitTypeArgument(JetSignatureVariance wildcard);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ends the visit of a signature corresponding to a class or interface type.
|
* Ends the visit of a signature corresponding to a class or interface type.
|
||||||
|
|||||||
@@ -171,13 +171,13 @@ public class JetSignatureWriter implements JetSignatureVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetSignatureWriter visitTypeArgument(final char wildcard) {
|
public JetSignatureWriter visitTypeArgument(JetSignatureVariance variance) {
|
||||||
if (argumentStack % 2 == 0) {
|
if (argumentStack % 2 == 0) {
|
||||||
++argumentStack;
|
++argumentStack;
|
||||||
buf.append('<');
|
buf.append('<');
|
||||||
}
|
}
|
||||||
if (wildcard != '=') {
|
if (variance.getC() != '=') {
|
||||||
buf.append(wildcard);
|
buf.append(variance.getC());
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user