Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,8 +48,6 @@ public abstract class ClassBodyCodegen {
|
||||
generateSyntheticParts(accessors);
|
||||
|
||||
generateStaticInitializer();
|
||||
|
||||
v.done();
|
||||
}
|
||||
|
||||
protected abstract void generateDeclaration();
|
||||
|
||||
@@ -26,6 +26,12 @@ public class ClassCodegen {
|
||||
}
|
||||
|
||||
final CodegenContext contextForInners = context.intoClass(descriptor, OwnerKind.IMPLEMENTATION, state.getTypeMapper());
|
||||
|
||||
if (!classBuilder.generateCode()) {
|
||||
// Outer class implementation must happen prior inner classes so we get proper scoping tree in JetLightClass's delegate
|
||||
generateImplementation(context, aClass, OwnerKind.IMPLEMENTATION, contextForInners.accessors, classBuilder);
|
||||
}
|
||||
|
||||
for (JetDeclaration declaration : aClass.getDeclarations()) {
|
||||
if (declaration instanceof JetClass && !(declaration instanceof JetEnumEntry)) {
|
||||
generate(contextForInners, (JetClass) declaration);
|
||||
@@ -35,7 +41,11 @@ public class ClassCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
generateImplementation(context, aClass, OwnerKind.IMPLEMENTATION, contextForInners.accessors, classBuilder);
|
||||
if (classBuilder.generateCode()) {
|
||||
generateImplementation(context, aClass, OwnerKind.IMPLEMENTATION, contextForInners.accessors, classBuilder);
|
||||
}
|
||||
|
||||
classBuilder.done();
|
||||
}
|
||||
|
||||
private void generateImplementation(CodegenContext context, JetClassOrObject aClass, OwnerKind kind, HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors, ClassBuilder classBuilder) {
|
||||
@@ -46,6 +56,7 @@ public class ClassCodegen {
|
||||
if(aClass instanceof JetClass && ((JetClass)aClass).isTrait()) {
|
||||
ClassBuilder traitBuilder = state.forTraitImplementation(descriptor);
|
||||
new TraitImplBodyCodegen(aClass, context.intoClass(descriptor, OwnerKind.TRAIT_IMPL, state.getTypeMapper()), traitBuilder, state).generate(null);
|
||||
traitBuilder.done();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2410,13 +2410,19 @@ If finally block is present, its last expression is the value of try expression.
|
||||
return generateTuplePatternMatch((JetTuplePattern) pattern, negated, expressionToMatch, nextEntry);
|
||||
}
|
||||
else if (pattern instanceof JetExpressionPattern) {
|
||||
final Type subjectType = expressionToMatch.type;
|
||||
expressionToMatch.dupReceiver(v);
|
||||
expressionToMatch.put(subjectType, v);
|
||||
JetExpression condExpression = ((JetExpressionPattern) pattern).getExpression();
|
||||
Type condType = isNumberPrimitive(subjectType) ? expressionType(condExpression) : TYPE_OBJECT;
|
||||
gen(condExpression, condType);
|
||||
return generateEqualsForExpressionsOnStack(JetTokens.EQEQ, subjectType, condType, false, false);
|
||||
if(expressionToMatch != null) {
|
||||
final Type subjectType = expressionToMatch.type;
|
||||
expressionToMatch.dupReceiver(v);
|
||||
expressionToMatch.put(subjectType, v);
|
||||
JetExpression condExpression = ((JetExpressionPattern) pattern).getExpression();
|
||||
Type condType = isNumberPrimitive(subjectType) ? expressionType(condExpression) : TYPE_OBJECT;
|
||||
gen(condExpression, condType);
|
||||
return generateEqualsForExpressionsOnStack(JetTokens.EQEQ, subjectType, condType, false, false);
|
||||
}
|
||||
else {
|
||||
JetExpression condExpression = ((JetExpressionPattern) pattern).getExpression();
|
||||
return gen(condExpression);
|
||||
}
|
||||
}
|
||||
else if (pattern instanceof JetWildcardPattern) {
|
||||
return StackValue.constant(!negated, Type.BOOLEAN_TYPE);
|
||||
@@ -2665,9 +2671,11 @@ If finally block is present, its last expression is the value of try expression.
|
||||
JetExpression expr = expression.getSubjectExpression();
|
||||
final Type subjectType = expressionType(expr);
|
||||
final Type resultType = expressionType(expression);
|
||||
final int subjectLocal = myFrameMap.enterTemp(subjectType.getSize());
|
||||
gen(expr, subjectType);
|
||||
v.store(subjectLocal, subjectType);
|
||||
final int subjectLocal = expr != null ? myFrameMap.enterTemp(subjectType.getSize()) : -1;
|
||||
if(subjectLocal != -1) {
|
||||
gen(expr, subjectType);
|
||||
v.store(subjectLocal, subjectType);
|
||||
}
|
||||
|
||||
Label end = new Label();
|
||||
boolean hasElse = false;
|
||||
@@ -2736,7 +2744,7 @@ If finally block is present, its last expression is the value of try expression.
|
||||
JetWhenConditionIsPattern patternCondition = (JetWhenConditionIsPattern) condition;
|
||||
JetPattern pattern = patternCondition.getPattern();
|
||||
conditionValue = generatePatternMatch(pattern, patternCondition.isNegated(),
|
||||
StackValue.local(subjectLocal, subjectType), nextEntry);
|
||||
subjectLocal == -1 ? null : StackValue.local(subjectLocal, subjectType), nextEntry);
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("unsupported kind of when condition");
|
||||
|
||||
@@ -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 + start));
|
||||
}
|
||||
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,8 +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.OverridingUtil;
|
||||
import org.jetbrains.jet.lang.resolve.java.StdlibNames;
|
||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
@@ -47,19 +47,41 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
boolean isAbstract = false;
|
||||
boolean isInterface = false;
|
||||
boolean isFinal = false;
|
||||
boolean isStatic = 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) && !isAbstract) {
|
||||
isFinal = true;
|
||||
}
|
||||
}
|
||||
else if (myClass.getParent() instanceof JetClassObject) {
|
||||
isStatic = 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;
|
||||
}
|
||||
if (isStatic) {
|
||||
access |= Opcodes.ACC_STATIC;
|
||||
}
|
||||
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(),
|
||||
@@ -67,17 +89,27 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
);
|
||||
v.visitSource(myClass.getContainingFile().getName(), null);
|
||||
|
||||
if(descriptor.getContainingDeclaration() instanceof ClassDescriptor) {
|
||||
v.visitOuterClass(typeMapper.mapType(((ClassDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), null, null);
|
||||
ClassDescriptor container = getContainingClassDescriptor(descriptor);
|
||||
if(container != null) {
|
||||
v.visitOuterClass(typeMapper.mapType(container.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), null, null);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
private static ClassDescriptor getContainingClassDescriptor(ClassDescriptor decl) {
|
||||
DeclarationDescriptor container = decl.getContainingDeclaration();
|
||||
while (container != null && !(container instanceof NamespaceDescriptor)) {
|
||||
if (container instanceof ClassDescriptor) return (ClassDescriptor) container;
|
||||
container = container.getContainingDeclaration();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private JvmClassSignature signature() {
|
||||
List<String> superInterfaces;
|
||||
|
||||
@@ -106,7 +138,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,29 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getLocalNameForObject(JetObjectDeclaration object) {
|
||||
PsiElement parent = object.getParent();
|
||||
if (parent instanceof JetClassObject) {
|
||||
return "ClassObject$";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getFQName(DeclarationDescriptor descriptor) {
|
||||
descriptor = descriptor.getOriginal();
|
||||
|
||||
@@ -200,7 +224,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 +256,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 +326,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());
|
||||
@@ -738,6 +784,8 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
private void initKnownTypeNames() {
|
||||
knowTypeNames.put(JetStandardClasses.getAnyType(), "ANY_TYPE_INFO");
|
||||
knowTypeNames.put(JetStandardClasses.getNullableAnyType(), "NULLABLE_ANY_TYPE_INFO");
|
||||
knowTypeNames.put(standardLibrary.getIntType(), "INT_TYPE_INFO");
|
||||
knowTypeNames.put(standardLibrary.getNullableIntType(), "NULLABLE_INT_TYPE_INFO");
|
||||
knowTypeNames.put(standardLibrary.getLongType(), "LONG_TYPE_INFO");
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -7,6 +7,9 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.Processor;
|
||||
import jet.ExtensionFunction0;
|
||||
import jet.ExtensionFunction10;
|
||||
import jet.Function1;
|
||||
import jet.modules.IModuleBuilder;
|
||||
import jet.modules.IModuleSetBuilder;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -18,6 +21,7 @@ import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
||||
import org.jetbrains.jet.plugin.JetMainDetector;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
@@ -123,6 +127,11 @@ public class CompileEnvironment {
|
||||
if (rtJar.exists()) {
|
||||
return rtJar;
|
||||
}
|
||||
|
||||
File classesJar = new File(new File(javaHome).getParentFile().getAbsolutePath(), "Classes/classes.jar");
|
||||
if (classesJar.exists()) {
|
||||
return classesJar;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -193,17 +202,19 @@ public class CompileEnvironment {
|
||||
final IModuleSetBuilder moduleSetBuilder = (IModuleSetBuilder) moduleSetBuilderClass.newInstance();
|
||||
|
||||
Class namespaceClass = loader.loadClass("namespace");
|
||||
final Method[] methods = namespaceClass.getMethods();
|
||||
final Field[] fields = namespaceClass.getDeclaredFields();
|
||||
boolean modulesDefined = false;
|
||||
for (Method method : methods) {
|
||||
if (method.getName().equals("defineModules")) {
|
||||
method.invoke(null, moduleSetBuilder);
|
||||
for (Field field : fields) {
|
||||
if (field.getName().equals("modules")) {
|
||||
field.setAccessible(true);
|
||||
ExtensionFunction0 defineMudules = (ExtensionFunction0) field.get(null);
|
||||
defineMudules.invoke(moduleSetBuilder);
|
||||
modulesDefined = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!modulesDefined) {
|
||||
throw new CompileEnvironmentException("Module script " + moduleFile + " must define a defineModules() method");
|
||||
throw new CompileEnvironmentException("Module script " + moduleFile + " must define a modules() property");
|
||||
}
|
||||
return moduleSetBuilder;
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -37,6 +37,9 @@ public class CompileSession {
|
||||
}
|
||||
|
||||
public void addSources(String path) {
|
||||
if(path == null)
|
||||
return;
|
||||
|
||||
VirtualFile vFile = myEnvironment.getLocalFileSystem().findFileByPath(path);
|
||||
if (vFile == null) {
|
||||
myErrors.add("File/directory not found: " + path);
|
||||
@@ -68,15 +71,15 @@ public class CompileSession {
|
||||
public void addSources(VirtualFile vFile) {
|
||||
if (vFile.isDirectory()) {
|
||||
for (VirtualFile virtualFile : vFile.getChildren()) {
|
||||
if (virtualFile.getFileType() == JetFileType.INSTANCE) {
|
||||
addSources(virtualFile);
|
||||
}
|
||||
addSources(virtualFile);
|
||||
}
|
||||
}
|
||||
else {
|
||||
PsiFile psiFile = PsiManager.getInstance(myEnvironment.getProject()).findFile(vFile);
|
||||
if (psiFile instanceof JetFile) {
|
||||
mySourceFileNamespaces.add(((JetFile) psiFile).getRootNamespace());
|
||||
if (vFile.getFileType() == JetFileType.INSTANCE) {
|
||||
PsiFile psiFile = PsiManager.getInstance(myEnvironment.getProject()).findFile(vFile);
|
||||
if (psiFile instanceof JetFile) {
|
||||
mySourceFileNamespaces.add(((JetFile) psiFile).getRootNamespace());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,8 +124,9 @@ public class CompileSession {
|
||||
else {
|
||||
final File runtimeJarPath = CompileEnvironment.getRuntimeJarPath();
|
||||
if (runtimeJarPath != null && runtimeJarPath.exists()) {
|
||||
// todo
|
||||
throw new UnsupportedOperationException("Loading of stdlib sources from jar");
|
||||
VirtualFile runtimeJar = myEnvironment.getLocalFileSystem().findFileByPath(runtimeJarPath.getAbsolutePath());
|
||||
VirtualFile jarRoot = myEnvironment.getJarFileSystem().findFileByPath(runtimeJar.getPath() + "!/stdlib/ktSrc");
|
||||
addSources(jarRoot);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
package org.jetbrains.jet.compiler;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintResolutionListener;
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl;
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemSolution;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScopeUtils;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.NamespaceType;
|
||||
import org.jetbrains.jet.lang.types.Variance;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintType.RECEIVER;
|
||||
|
||||
/**
|
||||
* @author Nikolay Krasko
|
||||
*/
|
||||
public final class TipsManager {
|
||||
|
||||
private TipsManager() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Collection<DeclarationDescriptor> getReferenceVariants(JetSimpleNameExpression expression, BindingContext context) {
|
||||
PsiElement parent = expression.getParent();
|
||||
if (parent instanceof JetQualifiedExpression) {
|
||||
JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) parent;
|
||||
JetExpression receiverExpression = qualifiedExpression.getReceiverExpression();
|
||||
|
||||
final JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression);
|
||||
final JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, receiverExpression);
|
||||
|
||||
if (expressionType != null && resolutionScope != null) {
|
||||
return includeExternalCallableExtensions(
|
||||
expressionType.getMemberScope().getAllDescriptors(),
|
||||
resolutionScope, new ExpressionReceiver(receiverExpression, expressionType));
|
||||
}
|
||||
}
|
||||
else {
|
||||
JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, expression);
|
||||
if (resolutionScope != null) {
|
||||
return excludeNotCallableExtensions(resolutionScope.getAllDescriptors(), resolutionScope);
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private static Collection<DeclarationDescriptor> excludeNotCallableExtensions(
|
||||
@NotNull Collection<DeclarationDescriptor> descriptors, @NotNull final JetScope scope
|
||||
) {
|
||||
final Set<DeclarationDescriptor> descriptorsSet = Sets.newHashSet(descriptors);
|
||||
|
||||
descriptorsSet.removeAll(
|
||||
Collections2.filter(JetScopeUtils.getAllExtensions(scope), new Predicate<CallableDescriptor>() {
|
||||
@Override
|
||||
public boolean apply(CallableDescriptor callableDescriptor) {
|
||||
return !checkReceiverResolution(scope.getImplicitReceiver(), callableDescriptor);
|
||||
}
|
||||
}));
|
||||
|
||||
return Lists.newArrayList(descriptorsSet);
|
||||
}
|
||||
|
||||
private static Collection<DeclarationDescriptor> includeExternalCallableExtensions(
|
||||
@NotNull Collection<DeclarationDescriptor> descriptors,
|
||||
@NotNull final JetScope externalScope,
|
||||
@NotNull final ReceiverDescriptor receiverDescriptor
|
||||
) {
|
||||
// It's impossible to add extension function for namespace
|
||||
if (receiverDescriptor.getType() instanceof NamespaceType) {
|
||||
return descriptors;
|
||||
}
|
||||
|
||||
Set<DeclarationDescriptor> descriptorsSet = Sets.newHashSet(descriptors);
|
||||
|
||||
descriptorsSet.addAll(
|
||||
Collections2.filter(JetScopeUtils.getAllExtensions(externalScope),
|
||||
new Predicate<CallableDescriptor>() {
|
||||
@Override
|
||||
public boolean apply(CallableDescriptor callableDescriptor) {
|
||||
return checkReceiverResolution(receiverDescriptor, callableDescriptor);
|
||||
}
|
||||
}));
|
||||
|
||||
return descriptorsSet;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if receiver declaration could be resolved to call expected receiver.
|
||||
*/
|
||||
private static boolean checkReceiverResolution (
|
||||
@NotNull ReceiverDescriptor expectedReceiver,
|
||||
@NotNull CallableDescriptor receiverArgument
|
||||
) {
|
||||
ConstraintSystem constraintSystem = new ConstraintSystemImpl(ConstraintResolutionListener.DO_NOTHING);
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : receiverArgument.getTypeParameters()) {
|
||||
constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT);
|
||||
}
|
||||
|
||||
ReceiverDescriptor receiverParameter = receiverArgument.getReceiverParameter();
|
||||
if (expectedReceiver.exists() && receiverParameter.exists()) {
|
||||
constraintSystem.addSubtypingConstraint(
|
||||
RECEIVER.assertSubtyping(expectedReceiver.getType(), receiverParameter.getType()));
|
||||
}
|
||||
else if (expectedReceiver.exists() || receiverParameter.exists()) {
|
||||
// Only one of receivers exist
|
||||
return false;
|
||||
}
|
||||
|
||||
ConstraintSystemSolution solution = constraintSystem.solve();
|
||||
return solution.getStatus().isSuccessful();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user