Merge remote branch 'origin/master'

This commit is contained in:
Alex Tkachman
2011-12-30 10:34:01 +02:00
14 changed files with 209 additions and 94 deletions
@@ -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);
} }
} }
@@ -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)) {
@@ -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;
}
} }
@@ -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;
@@ -38,28 +39,58 @@ public class JavaPackageScope extends JetScopeImpl {
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;
@@ -167,6 +168,10 @@ public class JetTestUtils {
} }
} }
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);
mkdirs(file); mkdirs(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));
} }