Merge remote branch 'origin/master'
This commit is contained in:
@@ -9,6 +9,7 @@ import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
|||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
@@ -65,7 +66,7 @@ public class PropertyCodegen {
|
|||||||
value = compileTimeValue != null ? compileTimeValue.getValue() : null;
|
value = compileTimeValue != null ? compileTimeValue.getValue() : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final int modifiers;
|
int modifiers;
|
||||||
if (kind == OwnerKind.NAMESPACE) {
|
if (kind == OwnerKind.NAMESPACE) {
|
||||||
int access = isExternallyAccessible(p) ? Opcodes.ACC_PUBLIC : Opcodes.ACC_PRIVATE;
|
int access = isExternallyAccessible(p) ? Opcodes.ACC_PUBLIC : Opcodes.ACC_PRIVATE;
|
||||||
modifiers = access | Opcodes.ACC_STATIC;
|
modifiers = access | Opcodes.ACC_STATIC;
|
||||||
@@ -73,6 +74,9 @@ public class PropertyCodegen {
|
|||||||
else {
|
else {
|
||||||
modifiers = Opcodes.ACC_PRIVATE;
|
modifiers = Opcodes.ACC_PRIVATE;
|
||||||
}
|
}
|
||||||
|
if (!propertyDescriptor.isVar()) {
|
||||||
|
modifiers |= Opcodes.ACC_FINAL;
|
||||||
|
}
|
||||||
v.newField(p, modifiers, p.getName(), state.getTypeMapper().mapType(propertyDescriptor.getOutType()).getDescriptor(), null, value);
|
v.newField(p, modifiers, p.getName(), state.getTypeMapper().mapType(propertyDescriptor.getOutType()).getDescriptor(), null, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -212,10 +216,10 @@ public class PropertyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String getterName(String propertyName) {
|
public static String getterName(String propertyName) {
|
||||||
return "get" + StringUtil.capitalizeWithJavaBeanConvention(propertyName);
|
return JvmAbi.GETTER_PREFIX + StringUtil.capitalizeWithJavaBeanConvention(propertyName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String setterName(String propertyName) {
|
public static String setterName(String propertyName) {
|
||||||
return "set" + StringUtil.capitalizeWithJavaBeanConvention(propertyName);
|
return JvmAbi.SETTER_PREFIX + StringUtil.capitalizeWithJavaBeanConvention(propertyName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+116
-57
@@ -86,11 +86,33 @@ public class JavaDescriptorResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final Map<String, ClassDescriptor> classDescriptorCache = Maps.newHashMap();
|
private static class ResolverClassData {
|
||||||
|
private JavaClassDescriptor classDescriptor;
|
||||||
|
private boolean kotlin;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public ClassDescriptor getClassDescriptor() {
|
||||||
|
return classDescriptor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ResolverNamespaceData {
|
||||||
|
private JavaNamespaceDescriptor namespaceDescriptor;
|
||||||
|
private boolean kotlin;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public NamespaceDescriptor getNamespaceDescriptor() {
|
||||||
|
return namespaceDescriptor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final Map<String, ResolverClassData> classDescriptorCache = Maps.newHashMap();
|
||||||
|
protected final Map<String, ResolverNamespaceData> namespaceDescriptorCacheByFqn = Maps.newHashMap();
|
||||||
|
protected final Map<PsiElement, ResolverNamespaceData> namespaceDescriptorCache = Maps.newHashMap();
|
||||||
|
|
||||||
protected final Map<PsiTypeParameter, TypeParameterDescriptorInitialization> typeParameterDescriptorCache = Maps.newHashMap();
|
protected 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 Map<PsiField, VariableDescriptor> fieldDescriptorCache = Maps.newHashMap();
|
||||||
protected final Map<PsiElement, NamespaceDescriptor> namespaceDescriptorCache = 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;
|
||||||
@@ -122,12 +144,12 @@ public class JavaDescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Not let's take a descriptor of a Java class
|
// Not let's take a descriptor of a Java class
|
||||||
ClassDescriptor classDescriptor = classDescriptorCache.get(qualifiedName);
|
ResolverClassData classData = classDescriptorCache.get(qualifiedName);
|
||||||
if (classDescriptor == null) {
|
if (classData == null) {
|
||||||
classDescriptor = createJavaClassDescriptor(psiClass);
|
classData = createJavaClassDescriptor(psiClass);
|
||||||
classDescriptorCache.put(qualifiedName, classDescriptor);
|
classDescriptorCache.put(qualifiedName, classData);
|
||||||
}
|
}
|
||||||
return classDescriptor;
|
return classData.getClassDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -145,26 +167,27 @@ public class JavaDescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Not let's take a descriptor of a Java class
|
// Not let's take a descriptor of a Java class
|
||||||
ClassDescriptor classDescriptor = classDescriptorCache.get(qualifiedName);
|
ResolverClassData classData = classDescriptorCache.get(qualifiedName);
|
||||||
if (classDescriptor == null) {
|
if (classData == null) {
|
||||||
PsiClass psiClass = findClass(qualifiedName);
|
PsiClass psiClass = findClass(qualifiedName);
|
||||||
if (psiClass == null) {
|
if (psiClass == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
classDescriptor = createJavaClassDescriptor(psiClass);
|
classData = createJavaClassDescriptor(psiClass);
|
||||||
}
|
}
|
||||||
return classDescriptor;
|
return classData.getClassDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassDescriptor createJavaClassDescriptor(@NotNull final PsiClass psiClass) {
|
private ResolverClassData createJavaClassDescriptor(@NotNull final PsiClass psiClass) {
|
||||||
assert !classDescriptorCache.containsKey(psiClass.getQualifiedName()) : psiClass.getQualifiedName();
|
assert !classDescriptorCache.containsKey(psiClass.getQualifiedName()) : psiClass.getQualifiedName();
|
||||||
classDescriptorCache.put(psiClass.getQualifiedName(), null); // TODO
|
classDescriptorCache.put(psiClass.getQualifiedName(), null); // TODO
|
||||||
|
|
||||||
String name = psiClass.getName();
|
String name = psiClass.getName();
|
||||||
JavaClassDescriptor classDescriptor = new JavaClassDescriptor(
|
ResolverClassData classData = new ResolverClassData();
|
||||||
|
classData.classDescriptor = new JavaClassDescriptor(
|
||||||
resolveParentDescriptor(psiClass), psiClass.isInterface() ? ClassKind.TRAIT : ClassKind.CLASS
|
resolveParentDescriptor(psiClass), psiClass.isInterface() ? ClassKind.TRAIT : ClassKind.CLASS
|
||||||
);
|
);
|
||||||
classDescriptor.setName(name);
|
classData.classDescriptor.setName(name);
|
||||||
|
|
||||||
class OuterClassTypeVariableResolver implements TypeVariableResolver {
|
class OuterClassTypeVariableResolver implements TypeVariableResolver {
|
||||||
|
|
||||||
@@ -176,9 +199,9 @@ public class JavaDescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<JetType> supertypes = new ArrayList<JetType>();
|
List<JetType> supertypes = new ArrayList<JetType>();
|
||||||
List<TypeParameterDescriptor> typeParameters = resolveClassTypeParameters(psiClass, classDescriptor, new OuterClassTypeVariableResolver());
|
List<TypeParameterDescriptor> typeParameters = resolveClassTypeParameters(psiClass, classData, new OuterClassTypeVariableResolver());
|
||||||
classDescriptor.setTypeConstructor(new TypeConstructorImpl(
|
classData.classDescriptor.setTypeConstructor(new TypeConstructorImpl(
|
||||||
classDescriptor,
|
classData.classDescriptor,
|
||||||
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
||||||
// TODO
|
// TODO
|
||||||
psiClass.hasModifierProperty(PsiModifier.FINAL),
|
psiClass.hasModifierProperty(PsiModifier.FINAL),
|
||||||
@@ -186,20 +209,20 @@ public class JavaDescriptorResolver {
|
|||||||
typeParameters,
|
typeParameters,
|
||||||
supertypes
|
supertypes
|
||||||
));
|
));
|
||||||
classDescriptor.setModality(Modality.convertFromFlags(
|
classData.classDescriptor.setModality(Modality.convertFromFlags(
|
||||||
psiClass.hasModifierProperty(PsiModifier.ABSTRACT) || psiClass.isInterface(),
|
psiClass.hasModifierProperty(PsiModifier.ABSTRACT) || psiClass.isInterface(),
|
||||||
!psiClass.hasModifierProperty(PsiModifier.FINAL))
|
!psiClass.hasModifierProperty(PsiModifier.FINAL))
|
||||||
);
|
);
|
||||||
classDescriptor.setVisibility(resolveVisibilityFromPsiModifiers(psiClass));
|
classData.classDescriptor.setVisibility(resolveVisibilityFromPsiModifiers(psiClass));
|
||||||
classDescriptorCache.put(psiClass.getQualifiedName(), classDescriptor);
|
classDescriptorCache.put(psiClass.getQualifiedName(), classData);
|
||||||
classDescriptor.setUnsubstitutedMemberScope(new JavaClassMembersScope(classDescriptor, psiClass, semanticServices, false));
|
classData.classDescriptor.setUnsubstitutedMemberScope(new JavaClassMembersScope(classData.classDescriptor, psiClass, semanticServices, false));
|
||||||
|
|
||||||
// UGLY HACK (Andrey Breslav is not sure what did he mean)
|
// UGLY HACK (Andrey Breslav is not sure what did he mean)
|
||||||
initializeTypeParameters(psiClass);
|
initializeTypeParameters(psiClass);
|
||||||
|
|
||||||
supertypes.addAll(getSupertypes(psiClass));
|
supertypes.addAll(getSupertypes(psiClass));
|
||||||
if (psiClass.isInterface()) {
|
if (psiClass.isInterface()) {
|
||||||
classDescriptor.setSuperclassType(JetStandardClasses.getAnyType()); // TODO : Make it java.lang.Object
|
classData.classDescriptor.setSuperclassType(JetStandardClasses.getAnyType()); // TODO : Make it java.lang.Object
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PsiClassType[] extendsListTypes = psiClass.getExtendsListTypes();
|
PsiClassType[] extendsListTypes = psiClass.getExtendsListTypes();
|
||||||
@@ -207,7 +230,7 @@ public class JavaDescriptorResolver {
|
|||||||
JetType superclassType = extendsListTypes.length == 0
|
JetType superclassType = extendsListTypes.length == 0
|
||||||
? JetStandardClasses.getAnyType()
|
? JetStandardClasses.getAnyType()
|
||||||
: semanticServices.getTypeTransformer().transformToType(extendsListTypes[0]);
|
: semanticServices.getTypeTransformer().transformToType(extendsListTypes[0]);
|
||||||
classDescriptor.setSuperclassType(superclassType);
|
classData.classDescriptor.setSuperclassType(superclassType);
|
||||||
}
|
}
|
||||||
|
|
||||||
PsiMethod[] psiConstructors = psiClass.getConstructors();
|
PsiMethod[] psiConstructors = psiClass.getConstructors();
|
||||||
@@ -219,19 +242,19 @@ public class JavaDescriptorResolver {
|
|||||||
// abstract public class Java {}
|
// abstract public class Java {}
|
||||||
if (!psiClass.isInterface()) {
|
if (!psiClass.isInterface()) {
|
||||||
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
|
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
|
||||||
classDescriptor,
|
classData.classDescriptor,
|
||||||
Collections.<AnnotationDescriptor>emptyList(),
|
Collections.<AnnotationDescriptor>emptyList(),
|
||||||
false);
|
false);
|
||||||
constructorDescriptor.initialize(typeParameters, Collections.<ValueParameterDescriptor>emptyList(), Modality.FINAL, classDescriptor.getVisibility());
|
constructorDescriptor.initialize(typeParameters, Collections.<ValueParameterDescriptor>emptyList(), Modality.FINAL, classData.classDescriptor.getVisibility());
|
||||||
constructorDescriptor.setReturnType(classDescriptor.getDefaultType());
|
constructorDescriptor.setReturnType(classData.classDescriptor.getDefaultType());
|
||||||
classDescriptor.addConstructor(constructorDescriptor);
|
classData.classDescriptor.addConstructor(constructorDescriptor);
|
||||||
semanticServices.getTrace().record(BindingContext.CONSTRUCTOR, psiClass, constructorDescriptor);
|
semanticServices.getTrace().record(BindingContext.CONSTRUCTOR, psiClass, constructorDescriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (PsiMethod constructor : psiConstructors) {
|
for (PsiMethod constructor : psiConstructors) {
|
||||||
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
|
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
|
||||||
classDescriptor,
|
classData.classDescriptor,
|
||||||
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
||||||
false);
|
false);
|
||||||
ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(constructorDescriptor,
|
ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(constructorDescriptor,
|
||||||
@@ -243,30 +266,31 @@ public class JavaDescriptorResolver {
|
|||||||
}
|
}
|
||||||
constructorDescriptor.initialize(typeParameters, valueParameterDescriptors.descriptors, Modality.FINAL,
|
constructorDescriptor.initialize(typeParameters, valueParameterDescriptors.descriptors, Modality.FINAL,
|
||||||
resolveVisibilityFromPsiModifiers(constructor));
|
resolveVisibilityFromPsiModifiers(constructor));
|
||||||
constructorDescriptor.setReturnType(classDescriptor.getDefaultType());
|
constructorDescriptor.setReturnType(classData.classDescriptor.getDefaultType());
|
||||||
classDescriptor.addConstructor(constructorDescriptor);
|
classData.classDescriptor.addConstructor(constructorDescriptor);
|
||||||
semanticServices.getTrace().record(BindingContext.CONSTRUCTOR, constructor, constructorDescriptor);
|
semanticServices.getTrace().record(BindingContext.CONSTRUCTOR, constructor, constructorDescriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
semanticServices.getTrace().record(BindingContext.CLASS, psiClass, classDescriptor);
|
semanticServices.getTrace().record(BindingContext.CLASS, psiClass, classData.classDescriptor);
|
||||||
|
|
||||||
return classDescriptor;
|
return classData;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<TypeParameterDescriptor> resolveClassTypeParameters(PsiClass psiClass, JavaClassDescriptor classDescriptor, TypeVariableResolver typeVariableResolver) {
|
private List<TypeParameterDescriptor> resolveClassTypeParameters(PsiClass psiClass, ResolverClassData classData, TypeVariableResolver typeVariableResolver) {
|
||||||
for (PsiAnnotation annotation : psiClass.getModifierList().getAnnotations()) {
|
for (PsiAnnotation annotation : psiClass.getModifierList().getAnnotations()) {
|
||||||
if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_CLASS.getFqName())) {
|
if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_CLASS.getFqName())) {
|
||||||
|
classData.kotlin = true;
|
||||||
PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_CLASS_SIGNATURE);
|
PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_CLASS_SIGNATURE);
|
||||||
if (attributeValue != null) {
|
if (attributeValue != null) {
|
||||||
String typeParametersString = (String) attributeValue.getValue();
|
String typeParametersString = (String) attributeValue.getValue();
|
||||||
if (typeParametersString != null) {
|
if (typeParametersString != null) {
|
||||||
return resolveClassTypeParametersFromJetSignature(typeParametersString, psiClass, classDescriptor, typeVariableResolver);
|
return resolveClassTypeParametersFromJetSignature(typeParametersString, psiClass, classData.classDescriptor, typeVariableResolver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return makeUninitializedTypeParameters(classDescriptor, psiClass.getTypeParameters());
|
return makeUninitializedTypeParameters(classData.classDescriptor, psiClass.getTypeParameters());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -523,34 +547,40 @@ public class JavaDescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private NamespaceDescriptor resolveNamespace(@NotNull PsiPackage psiPackage) {
|
private NamespaceDescriptor resolveNamespace(@NotNull PsiPackage psiPackage) {
|
||||||
NamespaceDescriptor namespaceDescriptor = namespaceDescriptorCache.get(psiPackage);
|
ResolverNamespaceData namespaceData = namespaceDescriptorCache.get(psiPackage);
|
||||||
if (namespaceDescriptor == null) {
|
if (namespaceData == null) {
|
||||||
namespaceDescriptor = createJavaNamespaceDescriptor(psiPackage);
|
namespaceData = createJavaNamespaceDescriptor(psiPackage);
|
||||||
namespaceDescriptorCache.put(psiPackage, namespaceDescriptor);
|
namespaceDescriptorCache.put(psiPackage, namespaceData);
|
||||||
|
namespaceDescriptorCacheByFqn.put(psiPackage.getQualifiedName(), namespaceData);
|
||||||
}
|
}
|
||||||
return namespaceDescriptor;
|
return namespaceData.namespaceDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private NamespaceDescriptor resolveNamespace(@NotNull PsiClass psiClass) {
|
private NamespaceDescriptor resolveNamespace(@NotNull PsiClass psiClass) {
|
||||||
NamespaceDescriptor namespaceDescriptor = namespaceDescriptorCache.get(psiClass);
|
ResolverNamespaceData namespaceData = namespaceDescriptorCache.get(psiClass);
|
||||||
if (namespaceDescriptor == null) {
|
if (namespaceData == null) {
|
||||||
namespaceDescriptor = createJavaNamespaceDescriptor(psiClass);
|
namespaceData = createJavaNamespaceDescriptor(psiClass);
|
||||||
namespaceDescriptorCache.put(psiClass, namespaceDescriptor);
|
namespaceDescriptorCache.put(psiClass, namespaceData);
|
||||||
|
namespaceDescriptorCacheByFqn.put(psiClass.getQualifiedName(), namespaceData);
|
||||||
}
|
}
|
||||||
return namespaceDescriptor;
|
return namespaceData.namespaceDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private NamespaceDescriptor createJavaNamespaceDescriptor(@NotNull PsiPackage psiPackage) {
|
private ResolverNamespaceData createJavaNamespaceDescriptor(@NotNull PsiPackage psiPackage) {
|
||||||
|
ResolverNamespaceData namespaceData = new ResolverNamespaceData();
|
||||||
String name = psiPackage.getName();
|
String name = psiPackage.getName();
|
||||||
JavaNamespaceDescriptor namespaceDescriptor = new JavaNamespaceDescriptor(
|
namespaceData.namespaceDescriptor = new JavaNamespaceDescriptor(
|
||||||
resolveParentDescriptor(psiPackage),
|
resolveParentDescriptor(psiPackage),
|
||||||
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
||||||
name == null ? JAVA_ROOT : name
|
name == null ? JAVA_ROOT : name,
|
||||||
|
name == null ? JAVA_ROOT : psiPackage.getQualifiedName()
|
||||||
);
|
);
|
||||||
|
|
||||||
namespaceDescriptor.setMemberScope(new JavaPackageScope(psiPackage.getQualifiedName(), namespaceDescriptor, semanticServices));
|
namespaceData.namespaceDescriptor.setMemberScope(new JavaPackageScope(psiPackage.getQualifiedName(), namespaceData.namespaceDescriptor, semanticServices));
|
||||||
semanticServices.getTrace().record(BindingContext.NAMESPACE, psiPackage, namespaceDescriptor);
|
semanticServices.getTrace().record(BindingContext.NAMESPACE, psiPackage, namespaceData.namespaceDescriptor);
|
||||||
return namespaceDescriptor;
|
// TODO: hack
|
||||||
|
namespaceData.kotlin = true;
|
||||||
|
return namespaceData;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DeclarationDescriptor resolveParentDescriptor(@NotNull PsiPackage psiPackage) {
|
private DeclarationDescriptor resolveParentDescriptor(@NotNull PsiPackage psiPackage) {
|
||||||
@@ -561,15 +591,17 @@ public class JavaDescriptorResolver {
|
|||||||
return resolveNamespace(parentPackage);
|
return resolveNamespace(parentPackage);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NamespaceDescriptor createJavaNamespaceDescriptor(@NotNull final PsiClass psiClass) {
|
private ResolverNamespaceData createJavaNamespaceDescriptor(@NotNull final PsiClass psiClass) {
|
||||||
JavaNamespaceDescriptor namespaceDescriptor = new JavaNamespaceDescriptor(
|
ResolverNamespaceData namespaceData = new ResolverNamespaceData();
|
||||||
|
namespaceData.namespaceDescriptor = new JavaNamespaceDescriptor(
|
||||||
resolveParentDescriptor(psiClass),
|
resolveParentDescriptor(psiClass),
|
||||||
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
||||||
psiClass.getName()
|
psiClass.getName(),
|
||||||
|
psiClass.getQualifiedName()
|
||||||
);
|
);
|
||||||
namespaceDescriptor.setMemberScope(new JavaClassMembersScope(namespaceDescriptor, psiClass, semanticServices, true));
|
namespaceData.namespaceDescriptor.setMemberScope(new JavaClassMembersScope(namespaceData.namespaceDescriptor, psiClass, semanticServices, true));
|
||||||
semanticServices.getTrace().record(BindingContext.NAMESPACE, psiClass, namespaceDescriptor);
|
semanticServices.getTrace().record(BindingContext.NAMESPACE, psiClass, namespaceData.namespaceDescriptor);
|
||||||
return namespaceDescriptor;
|
return namespaceData;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ValueParameterDescriptors {
|
private static class ValueParameterDescriptors {
|
||||||
@@ -819,6 +851,33 @@ public class JavaDescriptorResolver {
|
|||||||
}
|
}
|
||||||
return functionDescriptor;
|
return functionDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean kotlin;
|
||||||
|
if (owner instanceof JavaNamespaceDescriptor) {
|
||||||
|
JavaNamespaceDescriptor javaNamespaceDescriptor = (JavaNamespaceDescriptor) owner;
|
||||||
|
ResolverNamespaceData namespaceData = namespaceDescriptorCacheByFqn.get(javaNamespaceDescriptor.getQualifiedName());
|
||||||
|
if (namespaceData == null) {
|
||||||
|
throw new IllegalStateException("namespaceData not found by name " + javaNamespaceDescriptor.getQualifiedName());
|
||||||
|
}
|
||||||
|
kotlin = namespaceData.kotlin;
|
||||||
|
} else {
|
||||||
|
ResolverClassData classData = classDescriptorCache.get(psiClass.getQualifiedName());
|
||||||
|
if (classData == null) {
|
||||||
|
throw new IllegalStateException("classData not found by name " + psiClass.getQualifiedName());
|
||||||
|
}
|
||||||
|
kotlin = classData.kotlin;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: hide getters and setters properly
|
||||||
|
if (kotlin) {
|
||||||
|
if (method.getName().startsWith(JvmAbi.GETTER_PREFIX) && method.getParameterList().getParametersCount() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (method.getName().startsWith(JvmAbi.SETTER_PREFIX) && method.getParameterList().getParametersCount() == 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DeclarationDescriptor classDescriptor;
|
DeclarationDescriptor classDescriptor;
|
||||||
final List<TypeParameterDescriptor> classTypeParameters;
|
final List<TypeParameterDescriptor> classTypeParameters;
|
||||||
if (method.hasModifierProperty(PsiModifier.STATIC)) {
|
if (method.hasModifierProperty(PsiModifier.STATIC)) {
|
||||||
|
|||||||
+9
-2
@@ -13,9 +13,12 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class JavaNamespaceDescriptor extends AbstractNamespaceDescriptorImpl {
|
public class JavaNamespaceDescriptor extends AbstractNamespaceDescriptorImpl {
|
||||||
private JetScope memberScope;
|
private JetScope memberScope;
|
||||||
|
private final String qualifiedName;
|
||||||
public JavaNamespaceDescriptor(DeclarationDescriptor containingDeclaration, List<AnnotationDescriptor> annotations, String name) {
|
|
||||||
|
public JavaNamespaceDescriptor(DeclarationDescriptor containingDeclaration, List<AnnotationDescriptor> annotations,
|
||||||
|
@NotNull String name, @NotNull String qualifiedName) {
|
||||||
super(containingDeclaration, annotations, name);
|
super(containingDeclaration, annotations, name);
|
||||||
|
this.qualifiedName = qualifiedName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMemberScope(@NotNull JetScope memberScope) {
|
public void setMemberScope(@NotNull JetScope memberScope) {
|
||||||
@@ -27,4 +30,8 @@ public class JavaNamespaceDescriptor extends AbstractNamespaceDescriptorImpl {
|
|||||||
public JetScope getMemberScope() {
|
public JetScope getMemberScope() {
|
||||||
return memberScope;
|
return memberScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getQualifiedName() {
|
||||||
|
return qualifiedName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+39
-8
@@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.resolve.java;
|
|||||||
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.psi.PsiClass;
|
import com.intellij.psi.PsiClass;
|
||||||
|
import com.intellij.psi.PsiField;
|
||||||
import com.intellij.psi.PsiModifier;
|
import com.intellij.psi.PsiModifier;
|
||||||
import com.intellij.psi.PsiPackage;
|
import com.intellij.psi.PsiPackage;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -37,29 +38,59 @@ public class JavaPackageScope extends JetScopeImpl {
|
|||||||
public NamespaceDescriptor getNamespace(@NotNull String name) {
|
public NamespaceDescriptor getNamespace(@NotNull String name) {
|
||||||
return semanticServices.getDescriptorResolver().resolveNamespace(getQualifiedName(name));
|
return semanticServices.getDescriptorResolver().resolveNamespace(getQualifiedName(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
private PsiClass getPsiClassForPackage() {
|
||||||
@Override
|
|
||||||
public Set<FunctionDescriptor> getFunctions(@NotNull String name) {
|
|
||||||
// If this package is actually a Kotlin namespace, then we access it through a namespace descriptor, and
|
// If this package is actually a Kotlin namespace, then we access it through a namespace descriptor, and
|
||||||
// Kotlin functions are already there
|
// Kotlin functions are already there
|
||||||
NamespaceDescriptor kotlinNamespaceDescriptor = semanticServices.getKotlinNamespaceDescriptor(packageFQN);
|
NamespaceDescriptor kotlinNamespaceDescriptor = semanticServices.getKotlinNamespaceDescriptor(packageFQN);
|
||||||
if (kotlinNamespaceDescriptor != null) {
|
if (kotlinNamespaceDescriptor != null) {
|
||||||
return Collections.emptySet();
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: what is GlobalSearchScope
|
// TODO: what is GlobalSearchScope
|
||||||
PsiClass psiClass = semanticServices.getDescriptorResolver().javaFacade.findClass(getQualifiedName("namespace"));
|
PsiClass psiClass = semanticServices.getDescriptorResolver().javaFacade.findClass(getQualifiedName("namespace"));
|
||||||
if (psiClass == null) {
|
if (psiClass == null) {
|
||||||
return Collections.emptySet();
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (containingDescriptor == null) {
|
if (containingDescriptor == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return psiClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Set<FunctionDescriptor> getFunctions(@NotNull String name) {
|
||||||
|
PsiClass psiClassForPackage = getPsiClassForPackage();
|
||||||
|
|
||||||
|
if (psiClassForPackage == null) {
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
return semanticServices.getDescriptorResolver().resolveFunctionGroup(containingDescriptor, psiClass, null, name, true);
|
return semanticServices.getDescriptorResolver().resolveFunctionGroup(containingDescriptor, psiClassForPackage, null, name, true);
|
||||||
// return Collections.emptySet();
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Set<VariableDescriptor> getProperties(@NotNull String name) {
|
||||||
|
PsiClass psiClassForPackage = getPsiClassForPackage();
|
||||||
|
|
||||||
|
if (psiClassForPackage == null) {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
PsiField field = psiClassForPackage.findFieldByName(name, true);
|
||||||
|
if (field == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!field.hasModifierProperty(PsiModifier.STATIC)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: cache
|
||||||
|
return Collections.singleton(semanticServices.getDescriptorResolver().resolveFieldToVariableDescriptor(containingDescriptor, field));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -6,4 +6,6 @@ package org.jetbrains.jet.lang.resolve.java;
|
|||||||
public class JvmAbi {
|
public class JvmAbi {
|
||||||
public static final String TRAIT_IMPL_SUFFIX = "$$TImpl";
|
public static final String TRAIT_IMPL_SUFFIX = "$$TImpl";
|
||||||
public static final String DEFAULT_PARAMS_IMPL_SUFFIX = "$default";
|
public static final String DEFAULT_PARAMS_IMPL_SUFFIX = "$default";
|
||||||
|
public static final String GETTER_PREFIX = "get";
|
||||||
|
public static final String SETTER_PREFIX = "set";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,25 +78,6 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
|||||||
setType(inType, outType, Collections.<TypeParameterDescriptor>emptyList(), expectedThisObject, receiverType);
|
setType(inType, outType, Collections.<TypeParameterDescriptor>emptyList(), expectedThisObject, receiverType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PropertyDescriptor(
|
|
||||||
@NotNull PropertyDescriptor original,
|
|
||||||
@Nullable JetType receiverType,
|
|
||||||
@NotNull ReceiverDescriptor expectedThisObject,
|
|
||||||
@Nullable JetType inType,
|
|
||||||
@NotNull JetType outType
|
|
||||||
) {
|
|
||||||
this(
|
|
||||||
original,
|
|
||||||
original.getContainingDeclaration(),
|
|
||||||
original.getAnnotations(), // TODO : substitute?
|
|
||||||
original.getModality(),
|
|
||||||
original.getVisibility(),
|
|
||||||
original.isVar,
|
|
||||||
original.getName()
|
|
||||||
);
|
|
||||||
setType(inType, outType, Collections.<TypeParameterDescriptor>emptyList(), expectedThisObject, receiverType);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setType(@Nullable JetType inType, @NotNull JetType outType, @NotNull List<TypeParameterDescriptor> typeParameters, @NotNull ReceiverDescriptor expectedThisObject, @Nullable JetType receiverType) {
|
public void setType(@Nullable JetType inType, @NotNull JetType outType, @NotNull List<TypeParameterDescriptor> typeParameters, @NotNull ReceiverDescriptor expectedThisObject, @Nullable JetType receiverType) {
|
||||||
ReceiverDescriptor receiver = receiverType == null
|
ReceiverDescriptor receiver = receiverType == null
|
||||||
? NO_RECEIVER
|
? NO_RECEIVER
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class ClassVal() {
|
||||||
|
val aa = 1
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class ClassVar() {
|
||||||
|
var aa = 1
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
val nsVal = 1
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
var nsVal = 1
|
||||||
@@ -53,7 +53,7 @@ public class CompileJavaAgainstKotlinTest extends UsefulTestCase {
|
|||||||
@Override
|
@Override
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
tmpdir = new File("tmp/" + this.getClass().getSimpleName() + "." + this.getName());
|
tmpdir = JetTestUtils.tmpDirForTest(this);
|
||||||
JetTestUtils.recreateDirectory(tmpdir);
|
JetTestUtils.recreateDirectory(tmpdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.jetbrains.jet;
|
|||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.intellij.openapi.Disposable;
|
import com.intellij.openapi.Disposable;
|
||||||
|
import junit.framework.TestCase;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
||||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||||
@@ -166,6 +167,10 @@ public class JetTestUtils {
|
|||||||
file.delete();
|
file.delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static File tmpDirForTest(TestCase test) {
|
||||||
|
return new File("tmp/" + test.getClass().getSimpleName() + "/" + test.getName());
|
||||||
|
}
|
||||||
|
|
||||||
public static void recreateDirectory(File file) throws IOException {
|
public static void recreateDirectory(File file) throws IOException {
|
||||||
rmrf(file);
|
rmrf(file);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.jet.codegen.ClassBuilderFactory;
|
import org.jetbrains.jet.codegen.ClassBuilderFactory;
|
||||||
import org.jetbrains.jet.codegen.ClassFileFactory;
|
import org.jetbrains.jet.codegen.ClassFileFactory;
|
||||||
import org.jetbrains.jet.codegen.GenerationState;
|
import org.jetbrains.jet.codegen.GenerationState;
|
||||||
|
import org.jetbrains.jet.codegen.PropertyCodegen;
|
||||||
import org.jetbrains.jet.compiler.CompileEnvironment;
|
import org.jetbrains.jet.compiler.CompileEnvironment;
|
||||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
@@ -62,7 +63,7 @@ public class ReadClassDataTest extends UsefulTestCase {
|
|||||||
@Override
|
@Override
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
tmpdir = new File("tmp/" + this.getClass().getSimpleName() + "." + this.getName());
|
tmpdir = JetTestUtils.tmpDirForTest(this);
|
||||||
JetTestUtils.recreateDirectory(tmpdir);
|
JetTestUtils.recreateDirectory(tmpdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +133,16 @@ public class ReadClassDataTest extends UsefulTestCase {
|
|||||||
Assert.assertTrue(functions.size() >= 1);
|
Assert.assertTrue(functions.size() >= 1);
|
||||||
Assert.assertTrue("not implemented", functions.size() == 1);
|
Assert.assertTrue("not implemented", functions.size() == 1);
|
||||||
FunctionDescriptor bd = functions.iterator().next();
|
FunctionDescriptor bd = functions.iterator().next();
|
||||||
compareFunctions((FunctionDescriptor) ad, bd);
|
compareDescriptors(ad, bd);
|
||||||
|
} else if (ad instanceof PropertyDescriptor) {
|
||||||
|
Set<VariableDescriptor> properties = nsb.getMemberScope().getProperties(ad.getName());
|
||||||
|
Assert.assertTrue(properties.size() >= 1);
|
||||||
|
Assert.assertTrue("not implemented", properties.size() == 1);
|
||||||
|
PropertyDescriptor bd = (PropertyDescriptor) properties.iterator().next();
|
||||||
|
compareDescriptors(ad, bd);
|
||||||
|
|
||||||
|
Assert.assertTrue(nsb.getMemberScope().getFunctions(PropertyCodegen.getterName(ad.getName())).isEmpty());
|
||||||
|
Assert.assertTrue(nsb.getMemberScope().getFunctions(PropertyCodegen.setterName(ad.getName())).isEmpty());
|
||||||
} else {
|
} else {
|
||||||
throw new AssertionError("Unknown member: " + ad);
|
throw new AssertionError("Unknown member: " + ad);
|
||||||
}
|
}
|
||||||
@@ -153,7 +163,7 @@ public class ReadClassDataTest extends UsefulTestCase {
|
|||||||
System.out.println(as);
|
System.out.println(as);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void compareFunctions(@NotNull FunctionDescriptor a, @NotNull FunctionDescriptor b) {
|
private void compareDescriptors(@NotNull DeclarationDescriptor a, @NotNull DeclarationDescriptor b) {
|
||||||
StringBuilder sba = new StringBuilder();
|
StringBuilder sba = new StringBuilder();
|
||||||
StringBuilder sbb = new StringBuilder();
|
StringBuilder sbb = new StringBuilder();
|
||||||
new Serializer(sba).serialize(a);
|
new Serializer(sba).serialize(a);
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public class PropertyGenTest extends CodegenTestCase {
|
|||||||
final Field field = fields[0];
|
final Field field = fields[0];
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
assertEquals("x", field.getName());
|
assertEquals("x", field.getName());
|
||||||
assertEquals(Modifier.PRIVATE | Modifier.STATIC, field.getModifiers());
|
assertEquals(Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL, field.getModifiers());
|
||||||
assertEquals(239, field.get(null));
|
assertEquals(239, field.get(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user