Merge remote-tracking branch 'origin/master'

This commit is contained in:
Andrey Breslav
2011-12-21 11:37:40 +02:00
22 changed files with 295 additions and 89 deletions
@@ -3,13 +3,11 @@ package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.types.JetType;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import org.objectweb.asm.commons.Method;
import java.util.List;
@@ -87,7 +85,8 @@ public class CallableMethod implements Callable {
else {
if(getInvokeOpcode() != Opcodes.INVOKESTATIC)
desc = desc.replace("(", "(L" + getOwner() + ";");
v.visitMethodInsn(Opcodes.INVOKESTATIC, getInvokeOpcode() == Opcodes.INVOKEINTERFACE ? getOwner() + "$$TImpl" : getOwner(), getSignature().getAsmMethod().getName() + "$default", desc);
v.visitMethodInsn(Opcodes.INVOKESTATIC, getInvokeOpcode() == Opcodes.INVOKEINTERFACE ? getOwner() + JvmAbi.TRAIT_IMPL_SUFFIX
: getOwner(), getSignature().getAsmMethod().getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, desc);
}
}
@@ -6,7 +6,8 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.StdlibNames;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Label;
@@ -68,6 +69,10 @@ public class FunctionCodegen {
{
flags |= ACC_VARARGS;
}
if (functionDescriptor.getModality() == Modality.FINAL) {
flags |= ACC_FINAL;
}
OwnerKind kind = context.getContextKind();
@@ -88,48 +93,48 @@ public class FunctionCodegen {
if(kind != OwnerKind.TRAIT_IMPL) {
AnnotationVisitor av = mv.visitAnnotation(JetTypeMapper.JET_METHOD_TYPE.getDescriptor(), true);
if(functionDescriptor.getReturnType().isNullable()) {
av.visit(StdlibNames.JET_METHOD_NULLABLE_RETURN_TYPE_FIELD, true);
av.visit(JvmStdlibNames.JET_METHOD_NULLABLE_RETURN_TYPE_FIELD, true);
}
if (jvmSignature.getKotlinReturnType() != null) {
av.visit(StdlibNames.JET_METHOD_RETURN_TYPE_FIELD, jvmSignature.getKotlinReturnType());
av.visit(JvmStdlibNames.JET_METHOD_RETURN_TYPE_FIELD, jvmSignature.getKotlinReturnType());
}
if (jvmSignature.getKotlinTypeParameter() != null) {
av.visit(StdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD, jvmSignature.getKotlinTypeParameter());
av.visit(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD, jvmSignature.getKotlinTypeParameter());
}
av.visitEnd();
}
if(kind == OwnerKind.TRAIT_IMPL) {
AnnotationVisitor av = mv.visitParameterAnnotation(start++, StdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true);
av.visit(StdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, "this$self");
AnnotationVisitor av = mv.visitParameterAnnotation(start++, JvmStdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true);
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, "this$self");
av.visitEnd();
}
if(receiverParameter.exists()) {
AnnotationVisitor av = mv.visitParameterAnnotation(start++, StdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true);
av.visit(StdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, "this$receiver");
AnnotationVisitor av = mv.visitParameterAnnotation(start++, JvmStdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true);
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, "this$receiver");
if(receiverParameter.getType().isNullable()) {
av.visit(StdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true);
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true);
}
av.visit(StdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD, true);
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD, true);
av.visitEnd();
}
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
AnnotationVisitor av = mv.visitParameterAnnotation(start++, StdlibNames.JET_TYPE_PARAMETER.getDescriptor(), true);
av.visit(StdlibNames.JET_TYPE_PARAMETER_NAME_FIELD, typeParameterDescriptor.getName());
AnnotationVisitor av = mv.visitParameterAnnotation(start++, JvmStdlibNames.JET_TYPE_PARAMETER.getDescriptor(), true);
av.visit(JvmStdlibNames.JET_TYPE_PARAMETER_NAME_FIELD, typeParameterDescriptor.getName());
av.visitEnd();
}
for(int i = 0; i != paramDescrs.size(); ++i) {
AnnotationVisitor av = mv.visitParameterAnnotation(i + start, StdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true);
AnnotationVisitor av = mv.visitParameterAnnotation(i + start, JvmStdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true);
ValueParameterDescriptor parameterDescriptor = paramDescrs.get(i);
av.visit(StdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, parameterDescriptor.getName());
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, parameterDescriptor.getName());
if(parameterDescriptor.hasDefaultValue()) {
av.visit(StdlibNames.JET_VALUE_PARAMETER_HAS_DEFAULT_VALUE_FIELD, true);
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_HAS_DEFAULT_VALUE_FIELD, true);
}
if(parameterDescriptor.getOutType().isNullable()) {
av.visit(StdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true);
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true);
}
if (jvmSignature.getKotlinParameterTypes() != null && jvmSignature.getKotlinParameterTypes().get(i) != null) {
av.visit(StdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD, jvmSignature.getKotlinParameterTypes().get(i));
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD, jvmSignature.getKotlinParameterTypes().get(i));
}
av.visitEnd();
}
@@ -300,7 +305,7 @@ public class FunctionCodegen {
boolean isConstructor = "<init>".equals(jvmSignature.getName());
if(!isStatic && !isConstructor)
descriptor = descriptor.replace("(","(L" + ownerInternalName + ";");
final MethodVisitor mv = v.newMethod(null, flags | (isConstructor ? 0 : ACC_STATIC), isConstructor ? "<init>" : jvmSignature.getName() + "$default", descriptor, null, null);
final MethodVisitor mv = v.newMethod(null, flags | (isConstructor ? 0 : ACC_STATIC), isConstructor ? "<init>" : jvmSignature.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, descriptor, null, null);
InstructionAdapter iv = new InstructionAdapter(mv);
if (v.generateCode()) {
mv.visitCode();
@@ -6,7 +6,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.OverridingUtil;
import org.jetbrains.jet.lang.resolve.java.StdlibNames;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeProjection;
@@ -47,19 +47,33 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
boolean isAbstract = false;
boolean isInterface = false;
boolean isFinal = false;
if(myClass instanceof JetClass) {
if(((JetClass) myClass).hasModifier(JetTokens.ABSTRACT_KEYWORD))
JetClass jetClass = (JetClass) myClass;
if (jetClass.hasModifier(JetTokens.ABSTRACT_KEYWORD))
isAbstract = true;
if(((JetClass) myClass).isTrait()) {
if (jetClass.isTrait()) {
isAbstract = true;
isInterface = true;
}
if (!jetClass.hasModifier(JetTokens.OPEN_KEYWORD)) {
isFinal = true;
}
}
int access = 0;
access |= Opcodes.ACC_PUBLIC;
if (isAbstract) {
access |= Opcodes.ACC_ABSTRACT;
}
if (isInterface) {
access |= Opcodes.ACC_INTERFACE; // ACC_SUPER
}
if (isFinal) {
access |= Opcodes.ACC_FINAL;
}
v.defineClass(myClass, Opcodes.V1_6,
Opcodes.ACC_PUBLIC | (isAbstract ? Opcodes.ACC_ABSTRACT : 0) | (isInterface
? Opcodes.ACC_INTERFACE
: 0/*Opcodes.ACC_SUPER*/),
access,
signature.getName(),
signature.getJavaGenericSignature(),
signature.getSuperclassName(),
@@ -72,8 +86,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
if(myClass instanceof JetClass && signature.getKotlinGenericSignature() != null) {
AnnotationVisitor annotationVisitor = v.newAnnotation(myClass, StdlibNames.JET_CLASS.getDescriptor(), true);
annotationVisitor.visit(StdlibNames.JET_CLASS_SIGNATURE, signature.getKotlinGenericSignature());
AnnotationVisitor annotationVisitor = v.newAnnotation(myClass, JvmStdlibNames.JET_CLASS.getDescriptor(), true);
annotationVisitor.visit(JvmStdlibNames.JET_CLASS_SIGNATURE, signature.getKotlinGenericSignature());
annotationVisitor.visitEnd();
}
}
@@ -106,7 +120,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
{ // superinterfaces
superInterfacesLinkedHashSet.add(StdlibNames.JET_OBJECT.getInternalName());
superInterfacesLinkedHashSet.add(JvmStdlibNames.JET_OBJECT.getInternalName());
for (JetDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference());
@@ -1,5 +1,6 @@
package org.jetbrains.jet.codegen;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import jet.JetObject;
import jet.typeinfo.TypeInfo;
@@ -12,6 +13,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.JavaNamespaceDescriptor;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lexer.JetTokens;
@@ -180,7 +182,39 @@ public class JetTypeMapper {
}
private HashMap<DeclarationDescriptor,Map<DeclarationDescriptor,String>> naming = new HashMap<DeclarationDescriptor, Map<DeclarationDescriptor, String>>();
private String getStableNameForObject(JetObjectDeclaration object, DeclarationDescriptor descriptor) {
String local = getLocalNameForObject(object);
if (local == null) return null;
DeclarationDescriptor containingClass = getContainingClass(descriptor);
if (containingClass != null) {
return getFQName(containingClass) + "$" + local;
}
else {
return getFQName(getContainingNamespace(descriptor)) + "/" + local;
}
}
private static String getLocalNameForObject(JetObjectDeclaration object) {
PsiElement parent = object.getParent();
if (parent instanceof JetObjectLiteralExpression) {
PsiElement expressionParent = parent.getParent();
if (expressionParent instanceof JetProperty) {
JetProperty property = (JetProperty) expressionParent;
if (property.getInitializer() == parent) {
return property.getName();
}
}
}
else if (parent instanceof JetClassObject) {
return "$ClassObject";
}
return null;
}
public String getFQName(DeclarationDescriptor descriptor) {
descriptor = descriptor.getOriginal();
@@ -200,7 +234,17 @@ public class JetTypeMapper {
name = map.get(descriptor);
if(name == null) {
name = getFQName(container) + "$" + (map.size()+1);
PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
if (declaration instanceof JetObjectDeclaration) {
String stable = getStableNameForObject((JetObjectDeclaration) declaration, descriptor);
if (stable != null) {
name = stable;
}
}
if (name == null) {
name = getFQName(container) + "$" + (map.size()+1);
}
map.put(descriptor, name);
}
return name;
@@ -222,7 +266,19 @@ public class JetTypeMapper {
return name;
}
private static ClassDescriptor getContainingClass(DeclarationDescriptor descriptor) {
DeclarationDescriptor parent = descriptor.getContainingDeclaration();
if (parent == null || parent instanceof ClassDescriptor) return (ClassDescriptor) parent;
return getContainingClass(parent);
}
private static NamespaceDescriptor getContainingNamespace(DeclarationDescriptor descriptor) {
DeclarationDescriptor parent = descriptor.getContainingDeclaration();
if (parent == null || parent instanceof NamespaceDescriptor) return (NamespaceDescriptor) parent;
return getContainingNamespace(parent);
}
@NotNull public Type mapType(final JetType jetType) {
return mapType(jetType, (BothSignatureWriter) null);
}
@@ -280,7 +336,7 @@ public class JetTypeMapper {
if (descriptor instanceof ClassDescriptor) {
String name = getFQName(descriptor);
Type asmType = Type.getObjectType(name + (kind == OwnerKind.TRAIT_IMPL ? "$$TImpl" : ""));
Type asmType = Type.getObjectType(name + (kind == OwnerKind.TRAIT_IMPL ? JvmAbi.TRAIT_IMPL_SUFFIX : ""));
if (signatureVisitor != null) {
signatureVisitor.writeClassBegin(asmType.getInternalName(), jetType.isNullable());
@@ -6,6 +6,7 @@ import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lexer.JetTokens;
@@ -754,7 +755,7 @@ public abstract class StackValue {
@Override
public void put(Type type, InstructionAdapter v) {
if(isSuper && isInterface) {
v.visitMethodInsn(Opcodes.INVOKESTATIC, owner + "$$TImpl", getter.getName(), getter.getDescriptor().replace("(","(L" + owner + ";"));
v.visitMethodInsn(Opcodes.INVOKESTATIC, owner + JvmAbi.TRAIT_IMPL_SUFFIX, getter.getName(), getter.getDescriptor().replace("(","(L" + owner + ";"));
}
else {
if (getter == null) {
@@ -770,7 +771,7 @@ public abstract class StackValue {
@Override
public void store(InstructionAdapter v) {
if(isSuper && isInterface) {
v.visitMethodInsn(Opcodes.INVOKESTATIC, owner + "$$TImpl", setter.getName(), setter.getDescriptor().replace("(","(L" + owner + ";"));
v.visitMethodInsn(Opcodes.INVOKESTATIC, owner + JvmAbi.TRAIT_IMPL_SUFFIX, setter.getName(), setter.getDescriptor().replace("(","(L" + owner + ";"));
}
else {
if (setter == null) {
@@ -106,7 +106,10 @@ public class JavaClassMembersScope implements JetScope {
for (PsiClass innerClass : psiClass.getAllInnerClasses()) {
if (name.equals(innerClass.getName())) {
if (innerClass.hasModifierProperty(PsiModifier.STATIC) != staticMembers) return null;
return semanticServices.getDescriptorResolver().resolveClass(innerClass);
ClassDescriptor classDescriptor = semanticServices.getDescriptorResolver().resolveClass(innerClass);
if (classDescriptor != null) {
return classDescriptor;
}
}
}
return null;
@@ -9,7 +9,6 @@ import com.intellij.psi.*;
import com.intellij.psi.search.DelegatingGlobalSearchScope;
import com.intellij.psi.search.GlobalSearchScope;
import jet.typeinfo.TypeInfoVariance;
import org.eclipse.jdt.internal.core.JavaModelManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
@@ -107,9 +106,14 @@ public class JavaDescriptorResolver {
this.semanticServices = semanticServices;
}
@NotNull
@Nullable
public ClassDescriptor resolveClass(@NotNull PsiClass psiClass) {
String qualifiedName = psiClass.getQualifiedName();
if (qualifiedName.endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) {
// TODO: only if -$$TImpl class is created by Kotlin
return null;
}
// First, let's check that this is a real Java class, not a Java's view on a Kotlin class:
ClassDescriptor kotlinClassDescriptor = semanticServices.getKotlinClassDescriptor(qualifiedName);
@@ -128,6 +132,12 @@ public class JavaDescriptorResolver {
@Nullable
public ClassDescriptor resolveClass(@NotNull String qualifiedName) {
if (qualifiedName.endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) {
// TODO: only if -$$TImpl class is created by Kotlin
return null;
}
// First, let's check that this is a real Java class, not a Java's view on a Kotlin class:
ClassDescriptor kotlinClassDescriptor = semanticServices.getKotlinClassDescriptor(qualifiedName);
if (kotlinClassDescriptor != null) {
@@ -234,8 +244,8 @@ public class JavaDescriptorResolver {
private List<TypeParameterDescriptor> resolveClassTypeParameters(PsiClass psiClass, JavaClassDescriptor classDescriptor) {
for (PsiAnnotation annotation : psiClass.getModifierList().getAnnotations()) {
if (annotation.getQualifiedName().equals(StdlibNames.JET_CLASS.getFqName())) {
PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_CLASS_SIGNATURE);
if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_CLASS.getFqName())) {
PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_CLASS_SIGNATURE);
if (attributeValue != null) {
String typeParametersString = (String) attributeValue.getValue();
if (typeParametersString != null) {
@@ -608,18 +618,19 @@ public class JavaDescriptorResolver {
String typeFromAnnotation = null;
boolean receiver = false;
boolean hasDefaultValue = false;
// TODO: must be very slow, make it lazy?
String name = parameter.getName() != null ? parameter.getName() : "p" + i;
for (PsiAnnotation annotation : parameter.getModifierList().getAnnotations()) {
if (annotation.getQualifiedName().equals(StdlibNames.JET_VALUE_PARAMETER.getFqName())) {
PsiLiteralExpression nameExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_VALUE_PARAMETER_NAME_FIELD);
if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_VALUE_PARAMETER.getFqName())) {
PsiLiteralExpression nameExpression = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_VALUE_PARAMETER_NAME_FIELD);
if (nameExpression != null) {
name = (String) nameExpression.getValue();
}
PsiLiteralExpression nullableExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD);
PsiLiteralExpression nullableExpression = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD);
if (nullableExpression != null) {
nullable = (Boolean) nullableExpression.getValue();
} else {
@@ -628,19 +639,24 @@ public class JavaDescriptorResolver {
changeNullable = true;
}
PsiLiteralExpression signatureExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD);
PsiLiteralExpression signatureExpression = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD);
if (signatureExpression != null) {
typeFromAnnotation = (String) signatureExpression.getValue();
}
PsiLiteralExpression receiverExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD);
PsiLiteralExpression receiverExpression = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD);
if (receiverExpression != null) {
receiver = true;
receiver = (Boolean) receiverExpression.getValue();
}
PsiLiteralExpression hasDefaultValueExpression = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_VALUE_PARAMETER_HAS_DEFAULT_VALUE_FIELD);
if (hasDefaultValueExpression != null) {
hasDefaultValue = (Boolean) hasDefaultValueExpression.getValue();
}
} else if (annotation.getQualifiedName().equals(StdlibNames.JET_TYPE_PARAMETER.getFqName())) {
} else if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_TYPE_PARAMETER.getFqName())) {
return JvmMethodParameterMeaning.typeInfo(new Object());
}
}
@@ -661,7 +677,7 @@ public class JavaDescriptorResolver {
name,
null, // TODO : review
changeNullable ? TypeUtils.makeNullableAsSpecified(outType, nullable) : outType,
false,
hasDefaultValue,
varargElementType
));
}
@@ -748,6 +764,9 @@ public class JavaDescriptorResolver {
return functionDescriptor;
}
DeclarationDescriptor classDescriptor = method.hasModifierProperty(PsiModifier.STATIC) ? resolveNamespace(method.getContainingClass()) : resolveClass(method.getContainingClass());
if (classDescriptor == null) {
return null;
}
PsiParameter[] parameters = method.getParameterList().getParameters();
FunctionDescriptorImpl functionDescriptorImpl = new FunctionDescriptorImpl(
owner,
@@ -776,8 +795,8 @@ public class JavaDescriptorResolver {
private List<TypeParameterDescriptor> resolveMethodTypeParameters(PsiMethod method, FunctionDescriptorImpl functionDescriptorImpl) {
for (PsiAnnotation annotation : method.getModifierList().getAnnotations()) {
if (annotation.getQualifiedName().equals(StdlibNames.JET_METHOD.getFqName())) {
PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD);
if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_METHOD.getFqName())) {
PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD);
if (attributeValue != null) {
String typeParametersString = (String) attributeValue.getValue();
if (typeParametersString != null) {
@@ -822,8 +841,8 @@ public class JavaDescriptorResolver {
String returnTypeFromAnnotation = null;
for (PsiAnnotation annotation : method.getModifierList().getAnnotations()) {
if (annotation.getQualifiedName().equals(StdlibNames.JET_METHOD.getFqName())) {
PsiLiteralExpression nullableExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_METHOD_NULLABLE_RETURN_TYPE_FIELD);
if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_METHOD.getFqName())) {
PsiLiteralExpression nullableExpression = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_METHOD_NULLABLE_RETURN_TYPE_FIELD);
if (nullableExpression != null) {
nullable = (Boolean) nullableExpression.getValue();
} else {
@@ -832,7 +851,7 @@ public class JavaDescriptorResolver {
changeNullable = true;
}
PsiLiteralExpression returnTypeExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_METHOD_RETURN_TYPE_FIELD);
PsiLiteralExpression returnTypeExpression = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_METHOD_RETURN_TYPE_FIELD);
if (returnTypeExpression != null) {
returnTypeFromAnnotation = (String) returnTypeExpression.getValue();
}
@@ -94,7 +94,10 @@ public class JavaPackageScope extends JetScopeImpl {
}
if (psiClass.hasModifierProperty(PsiModifier.PUBLIC)) {
allDescriptors.add(descriptorResolver.resolveClass(psiClass));
ClassDescriptor classDescriptor = descriptorResolver.resolveClass(psiClass);
if (classDescriptor != null) {
allDescriptors.add(classDescriptor);
}
}
}
}
@@ -94,6 +94,9 @@ public class JavaTypeTransformer {
}
ClassDescriptor descriptor = resolver.resolveClass(psiClass);
if (descriptor == null) {
return ErrorUtils.createErrorType("Unresolve java class: " + classType.getPresentableText());
}
List<TypeProjection> arguments = Lists.newArrayList();
if (classType.isRaw()) {
@@ -1,17 +1,18 @@
package org.jetbrains.jet.lang.resolve.java;
import org.jetbrains.jet.rt.signature.JetSignatureExceptionsAdapter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.rt.signature.JetSignatureVisitor;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetStandardClasses;
import org.jetbrains.jet.lang.types.JetStandardLibrary;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.JetTypeImpl;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.Variance;
import org.jetbrains.jet.rt.signature.JetSignatureExceptionsAdapter;
import org.jetbrains.jet.rt.signature.JetSignatureVisitor;
import java.util.ArrayList;
import java.util.Collections;
@@ -119,6 +120,17 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd
};
}
@Override
public JetSignatureVisitor visitArrayType(final boolean nullable) {
return new JetTypeJetSignatureReader(javaDescriptorResolver, jetStandardLibrary) {
@Override
protected void done(@NotNull JetType jetType) {
JetType arrayType = TypeUtils.makeNullableAsSpecified(jetStandardLibrary.getArrayType(jetType), nullable);
JetTypeJetSignatureReader.this.done(arrayType);
}
};
}
@Override
public void visitEnd() {
JetType jetType = new JetTypeImpl(
@@ -0,0 +1,9 @@
package org.jetbrains.jet.lang.resolve.java;
/**
* @author Stepan Koltsov
*/
public class JvmAbi {
public static final String TRAIT_IMPL_SUFFIX = "$$TImpl";
public static final String DEFAULT_PARAMS_IMPL_SUFFIX = "$default";
}
@@ -5,7 +5,7 @@ import org.objectweb.asm.Type;
/**
* @author Stepan Koltsov
*/
public class StdlibNames {
public class JvmStdlibNames {
public static final JvmClassName JET_VALUE_PARAMETER = new JvmClassName("jet.typeinfo.JetValueParameter");
@@ -36,6 +36,6 @@ public class StdlibNames {
public static final JvmClassName JET_OBJECT = new JvmClassName("jet.JetObject");
private StdlibNames() {
private JvmStdlibNames() {
}
}
@@ -0,0 +1,7 @@
namespace container_test
class Container<T>(var t : T) {
fun getT() : T = t
}
fun box() = Container<String>("OK").getT()
@@ -0,0 +1,5 @@
namespace test
class ExtFunInClass {
fun Int.shuffle() = 1
}
@@ -0,0 +1,3 @@
namespace test
fun funDefaultArg(p: Int, q: Int = 17, r: Int = 18) = 19
@@ -0,0 +1,3 @@
namespace test
fun varargCharSequence(a: Int, vararg b: java.lang.CharSequence) = 1
@@ -0,0 +1,3 @@
namespace test
fun varargInt(a: Int, vararg b: Int) = 1
@@ -0,0 +1,5 @@
namespace test
abstract class ModifierAbstract {
abstract fun abs(): Int
}
@@ -0,0 +1,5 @@
namespace test
open class ModifierOpen {
open fun abs() = 1
}
@@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
import org.jetbrains.jet.lang.types.JetType;
@@ -123,6 +124,8 @@ public class ReadClassDataTest extends UsefulTestCase {
if (ad instanceof ClassifierDescriptor) {
ClassifierDescriptor bd = nsb.getMemberScope().getClassifier(ad.getName());
compareClassifiers((ClassifierDescriptor) ad, bd);
Assert.assertNull(nsb.getMemberScope().getClassifier(ad.getName() + JvmAbi.TRAIT_IMPL_SUFFIX));
} else if (ad instanceof FunctionDescriptor) {
Set<FunctionDescriptor> functions = nsb.getMemberScope().getFunctions(ad.getName());
Assert.assertTrue(functions.size() >= 1);
@@ -146,6 +149,10 @@ public class ReadClassDataTest extends UsefulTestCase {
private String serializeContent(ClassDescriptor klass) {
StringBuilder sb = new StringBuilder();
serialize(klass.getModality(), sb);
sb.append(" ");
serialize(klass.getKind(), sb);
sb.append(" ");
@@ -221,6 +228,9 @@ public class ReadClassDataTest extends UsefulTestCase {
private void serialize(FunctionDescriptor fun, StringBuilder sb) {
serialize(fun.getModality(), sb);
sb.append(" ");
sb.append("fun ");
if (!fun.getTypeParameters().isEmpty()) {
sb.append("<");
@@ -256,11 +266,13 @@ public class ReadClassDataTest extends UsefulTestCase {
}
private void serialize(ValueParameterDescriptor valueParameter, StringBuilder sb) {
if (valueParameter.getVarargElementType() != null) {
sb.append("vararg ");
}
sb.append(valueParameter.getName());
sb.append(": ");
if (valueParameter.getVarargElementType() != null) {
sb.append("vararg ");
serialize(valueParameter.getVarargElementType());
serialize(valueParameter.getVarargElementType(), sb);
} else {
serialize(valueParameter.getOutType(), sb);
}
@@ -276,7 +288,11 @@ public class ReadClassDataTest extends UsefulTestCase {
sb.append(variance);
sb.append(' ');
}
}
}
private void serialize(Modality modality, StringBuilder sb) {
sb.append(modality.name().toLowerCase());
}
private void serialize(JetType type, StringBuilder sb) {
serialize(type.getConstructor().getDeclarationDescriptor(), sb);
@@ -235,4 +235,8 @@ public class ClassGenTest extends CodegenTestCase {
public void testKt707 () throws Exception {
blackBoxFile("regressions/kt707.jet");
}
public void testKt857 () throws Exception {
// blackBoxFile("regressions/kt857.jet");
}
}
@@ -9,7 +9,7 @@ import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.*;
import com.intellij.psi.*;
import com.intellij.psi.impl.file.PsiPackageImpl;
import com.intellij.psi.search.GlobalSearchScope;
@@ -18,18 +18,40 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.plugin.JetFileType;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
public class JavaElementFinder extends PsiElementFinder {
private final Project project;
private final PsiManager psiManager;
private WeakHashMap<GlobalSearchScope, List<JetFile>> jetFiles = new WeakHashMap<GlobalSearchScope, List<JetFile>>();
public JavaElementFinder(Project project) {
this.project = project;
psiManager = PsiManager.getInstance(project);
// Monitoring for files instead of collecting them each time
VirtualFileManager.getInstance().addVirtualFileListener(new VirtualFileAdapter() {
@Override
public void fileCreated(VirtualFileEvent event) {
invalidateJetFilesCache();
}
@Override
public void fileDeleted(VirtualFileEvent event) {
invalidateJetFilesCache();
}
@Override
public void fileMoved(VirtualFileMoveEvent event) {
invalidateJetFilesCache();
}
@Override
public void fileCopied(VirtualFileCopyEvent event) {
invalidateJetFilesCache();
}
});
}
@Override
@@ -45,7 +67,7 @@ public class JavaElementFinder extends PsiElementFinder {
if (qualifiedName.startsWith("java.")) return PsiClass.EMPTY_ARRAY;
List<PsiClass> answer = new SmartList<PsiClass>();
final List<JetFile> filesInScope = collectProjectFiles(project, scope);
final List<JetFile> filesInScope = collectProjectJetFiles(project, scope);
for (JetFile file : filesInScope) {
JetNamespace rootNamespace = file.getRootNamespace();
final String packageName = JetPsiUtil.getFQName(rootNamespace);
@@ -71,7 +93,7 @@ public class JavaElementFinder extends PsiElementFinder {
Set<String> answer = new HashSet<String>();
String packageFQN = psiPackage.getQualifiedName();
for (JetFile psiFile : collectProjectFiles(project, GlobalSearchScope.allScope(project))) {
for (JetFile psiFile : collectProjectJetFiles(project, GlobalSearchScope.allScope(project))) {
final JetNamespace rootNamespace = psiFile.getRootNamespace();
if (packageFQN.equals(JetPsiUtil.getFQName(rootNamespace))) {
answer.add("namespace");
@@ -93,7 +115,7 @@ public class JavaElementFinder extends PsiElementFinder {
@Override
public PsiPackage findPackage(@NotNull String qualifiedName) {
final List<JetFile> psiFiles = collectProjectFiles(project, GlobalSearchScope.allScope(project));
final List<JetFile> psiFiles = collectProjectJetFiles(project, GlobalSearchScope.allScope(project));
for (JetFile psiFile : psiFiles) {
if (qualifiedName.equals(JetPsiUtil.getFQName(psiFile.getRootNamespace()))) {
@@ -108,7 +130,7 @@ public class JavaElementFinder extends PsiElementFinder {
@Override
public PsiClass[] getClasses(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
List<PsiClass> answer = new SmartList<PsiClass>();
final List<JetFile> filesInScope = collectProjectFiles(project, scope);
final List<JetFile> filesInScope = collectProjectJetFiles(project, scope);
String packageFQN = psiPackage.getQualifiedName();
for (JetFile file : filesInScope) {
final JetNamespace rootNamespace = file.getRootNamespace();
@@ -125,31 +147,40 @@ public class JavaElementFinder extends PsiElementFinder {
return answer.toArray(new PsiClass[answer.size()]);
}
private synchronized void invalidateJetFilesCache() {
jetFiles.clear();
}
private static List<JetFile> collectProjectFiles(final Project project, @NotNull final GlobalSearchScope scope) {
final List<JetFile> answer = new ArrayList<JetFile>();
private synchronized List<JetFile> collectProjectJetFiles(final Project project, @NotNull final GlobalSearchScope scope) {
List<JetFile> cachedFiles = jetFiles.get(scope);
if (cachedFiles == null) {
final List<JetFile> answer = new ArrayList<JetFile>();
final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
final PsiManager psiManager = PsiManager.getInstance(project);
VirtualFile[] contentRoots = ProjectRootManager.getInstance(project).getContentRoots();
VirtualFile[] contentRoots = ProjectRootManager.getInstance(project).getContentRoots();
CompilerPathsEx.visitFiles(contentRoots, new CompilerPathsEx.FileVisitor() {
@Override
protected void acceptFile(VirtualFile file, String fileRoot, String filePath) {
final FileType fileType = fileTypeManager.getFileTypeByFile(file);
if (fileType != JetFileType.INSTANCE) return;
CompilerPathsEx.visitFiles(contentRoots, new CompilerPathsEx.FileVisitor() {
@Override
protected void acceptFile(VirtualFile file, String fileRoot, String filePath) {
final FileType fileType = fileTypeManager.getFileTypeByFile(file);
if (fileType != JetFileType.INSTANCE) return;
if (scope.accept(file)) {
final PsiFile psiFile = psiManager.findFile(file);
if (psiFile instanceof JetFile) {
answer.add((JetFile) psiFile);
if (scope.accept(file)) {
final PsiFile psiFile = psiManager.findFile(file);
if (psiFile instanceof JetFile) {
answer.add((JetFile) psiFile);
}
}
}
}
});
});
return answer;
cachedFiles = answer;
jetFiles.put(scope, answer);
}
return cachedFiles;
}
}