diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java index 6a0140211ea..f388bcc53e0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java @@ -2,22 +2,26 @@ package org.jetbrains.jet.codegen; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassKind; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.psi.JetClass; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.types.JetType; /** * @author abreslav + * @author alex.tkachman */ public class CodegenUtil { - public static boolean isInterface(DeclarationDescriptor descriptor, BindingContext bindingContext) { - PsiElement psiElement = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor); - if(psiElement instanceof JetClass) { - return ((JetClass)psiElement).isTrait(); - } - if(psiElement instanceof PsiClass) { - return ((PsiClass)psiElement).isInterface(); - } - return false; + private CodegenUtil() { + } + + public static boolean isInterface(DeclarationDescriptor descriptor) { + return descriptor instanceof ClassDescriptor && ((ClassDescriptor)descriptor).getKind() == ClassKind.TRAIT; + } + + public static boolean isInterface(JetType type) { + return isInterface(type.getConstructor().getDeclarationDescriptor()); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index c5ccf901bfb..b5d9adb0dfe 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -721,7 +721,7 @@ public class ExpressionCodegen extends JetVisitor { receiver.put(receiverType != null ? typeMapper.mapType(receiverType) : JetTypeMapper.TYPE_OBJECT, v); if(receiverType != null) { ClassDescriptor propReceiverDescriptor = (ClassDescriptor) propertyDescriptor.getContainingDeclaration(); - if(!CodegenUtil.isInterface(propReceiverDescriptor, bindingContext) && CodegenUtil.isInterface(receiverType.getConstructor().getDeclarationDescriptor(), bindingContext)) { + if(!CodegenUtil.isInterface(propReceiverDescriptor) && CodegenUtil.isInterface(receiverType.getConstructor().getDeclarationDescriptor())) { // I hope it happens only in case of required super class for traits v.checkcast(typeMapper.mapType(propReceiverDescriptor.getDefaultType())); } @@ -2026,7 +2026,7 @@ public class ExpressionCodegen extends JetVisitor { JetType defaultType = descriptor.getDefaultType(); Type ownerType = typeMapper.mapType(defaultType); ownerType = JetTypeMapper.boxType(ownerType); - if(!typeMapper.isInterface(descriptor)) { + if(!CodegenUtil.isInterface(descriptor)) { if (descriptor.getTypeConstructor().getParameters().size() > 0) { v.load(0, JetTypeMapper.TYPE_OBJECT); v.getfield(ownerType.getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;"); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index ac8c94bad21..d7b0b188569 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -8,7 +8,6 @@ import org.jetbrains.jet.lang.psi.JetDeclarationWithBody; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetNamedFunction; import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.types.TypeUtils; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; @@ -47,33 +46,6 @@ public class FunctionCodegen { generatedMethod(bodyExpression, jvmMethod, funContext, functionDescriptor); } - private void generateBridgeMethod(Method function, Method overriden) - { - int flags = Opcodes.ACC_PUBLIC; // TODO. - - final MethodVisitor mv = v.visitMethod(flags, function.getName(), overriden.getDescriptor(), null, null); - mv.visitCode(); - - Type[] argTypes = function.getArgumentTypes(); - InstructionAdapter iv = new InstructionAdapter(mv); - iv.load(0, JetTypeMapper.TYPE_OBJECT); - for (int i = 0, reg = 1; i < argTypes.length; i++) { - Type argType = argTypes[i]; - iv.load(reg, argType); - //noinspection AssignmentToForLoopParameter - reg += argType.getSize(); - } - - iv.invokevirtual(state.getTypeMapper().jvmName((ClassDescriptor) owner.getContextDescriptor(), OwnerKind.IMPLEMENTATION), function.getName(), function.getDescriptor()); - if(JetTypeMapper.isPrimitive(function.getReturnType()) && !JetTypeMapper.isPrimitive(overriden.getReturnType())) - StackValue.valueOf(iv, function.getReturnType()); - if(function.getReturnType() == Type.VOID_TYPE) - iv.aconst(null); - iv.areturn(overriden.getReturnType()); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - private void generatedMethod(JetExpression bodyExpressions, Method jvmSignature, ClassContext context, @@ -86,10 +58,13 @@ public class FunctionCodegen { OwnerKind kind = context.getContextKind(); + if(kind == OwnerKind.TRAIT_IMPL && bodyExpressions == null) + return; + boolean isStatic = kind == OwnerKind.NAMESPACE || kind == OwnerKind.TRAIT_IMPL; if (isStatic) flags |= Opcodes.ACC_STATIC; - boolean isAbstract = !isStatic && (bodyExpressions == null || CodegenUtil.isInterface(functionDescriptor.getContainingDeclaration(), state.getBindingContext())); + boolean isAbstract = !isStatic && (bodyExpressions == null || CodegenUtil.isInterface(functionDescriptor.getContainingDeclaration())); if (isAbstract) flags |= Opcodes.ACC_ABSTRACT; final MethodVisitor mv = v.visitMethod(flags, jvmSignature.getName(), jvmSignature.getDescriptor(), null, null); @@ -122,21 +97,58 @@ public class FunctionCodegen { iv.invokeinterface(dk.getOwnerClass(), jvmSignature.getName(), jvmSignature.getDescriptor()); iv.areturn(jvmSignature.getReturnType()); } - else if (!isAbstract) { + else { codegen.returnExpression(bodyExpressions); } mv.visitMaxs(0, 0); mv.visitEnd(); - Set overriddenFunctions = functionDescriptor.getOverriddenDescriptors(); - if(overriddenFunctions.size() > 0) { - for (FunctionDescriptor overriddenFunction : overriddenFunctions) { - // TODO should we check params here as well? - if(!TypeUtils.equalClasses(overriddenFunction.getOriginal().getReturnType(), functionDescriptor.getReturnType())) { - generateBridgeMethod(jvmSignature, state.getTypeMapper().mapSignature(overriddenFunction.getName(), overriddenFunction.getOriginal())); - } - } + generateBridgeIfNeeded(owner, state, v, jvmSignature, functionDescriptor, kind); + } + } + + static void generateBridgeIfNeeded(ClassContext owner, GenerationState state, ClassVisitor v, Method jvmSignature, FunctionDescriptor functionDescriptor, OwnerKind kind) { + Set overriddenFunctions = functionDescriptor.getOverriddenDescriptors(); + if(kind != OwnerKind.TRAIT_IMPL) { + for (FunctionDescriptor overriddenFunction : overriddenFunctions) { + // TODO should we check params here as well? + checkOverride(owner, state, v, jvmSignature, functionDescriptor, overriddenFunction); } + checkOverride(owner, state, v, jvmSignature, functionDescriptor, functionDescriptor.getOriginal()); + } + } + + private static void checkOverride(ClassContext owner, GenerationState state, ClassVisitor v, Method jvmSignature, FunctionDescriptor functionDescriptor, FunctionDescriptor overriddenFunction) { + Type type1 = state.getTypeMapper().mapType(overriddenFunction.getOriginal().getReturnType()); + Type type2 = state.getTypeMapper().mapType(functionDescriptor.getReturnType()); + if(!type1.equals(type2)) { + Method overriden = state.getTypeMapper().mapSignature(overriddenFunction.getName(), overriddenFunction.getOriginal()); + int flags = Opcodes.ACC_PUBLIC; // TODO. + + final MethodVisitor mv = v.visitMethod(flags, jvmSignature.getName(), overriden.getDescriptor(), null, null); + mv.visitCode(); + + Type[] argTypes = jvmSignature.getArgumentTypes(); + InstructionAdapter iv = new InstructionAdapter(mv); + iv.load(0, JetTypeMapper.TYPE_OBJECT); + for (int i = 0, reg = 1; i < argTypes.length; i++) { + Type argType = argTypes[i]; + iv.load(reg, argType); + if(argType.getSort() == Type.OBJECT) { + iv.checkcast(argType); + } + //noinspection AssignmentToForLoopParameter + reg += argType.getSize(); + } + + iv.invokevirtual(state.getTypeMapper().jvmName((ClassDescriptor) owner.getContextDescriptor(), OwnerKind.IMPLEMENTATION), jvmSignature.getName(), jvmSignature.getDescriptor()); + if(JetTypeMapper.isPrimitive(jvmSignature.getReturnType()) && !JetTypeMapper.isPrimitive(overriden.getReturnType())) + StackValue.valueOf(iv, jvmSignature.getReturnType()); + if(jvmSignature.getReturnType() == Type.VOID_TYPE) + iv.aconst(null); + iv.areturn(overriden.getReturnType()); + mv.visitMaxs(0, 0); + mv.visitEnd(); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 697c82e7147..f3fdbb7b180 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -6,6 +6,7 @@ import org.jetbrains.annotations.Nullable; 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.constants.CompileTimeConstant; import org.jetbrains.jet.lang.types.JetStandardClasses; import org.jetbrains.jet.lang.types.JetType; @@ -314,74 +315,60 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if(!(myClass instanceof JetClass) || ((JetClass)myClass).isTrait() || ((JetClass)myClass).hasModifier(JetTokens.ABSTRACT_KEYWORD)) return; - HashSet set = new HashSet(); - getAbstractMethods(descriptor.getDefaultType(), set); - for(FunctionDescriptor fun: set) { - int flags = Opcodes.ACC_PUBLIC; // TODO. + for (CallableDescriptor callableDescriptor : OverridingUtil.getEffectiveMembers(descriptor)) { + if(callableDescriptor instanceof FunctionDescriptor) { + FunctionDescriptor fun = (FunctionDescriptor) callableDescriptor; + DeclarationDescriptor containingDeclaration = fun.getContainingDeclaration(); + if(containingDeclaration instanceof ClassDescriptor) { + ClassDescriptor declaration = (ClassDescriptor) containingDeclaration; + PsiElement psiElement = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, declaration); + if(psiElement instanceof JetClass) { + JetClass jetClass = (JetClass) psiElement; + if(jetClass.isTrait()) { + int flags = Opcodes.ACC_PUBLIC; // TODO. - Method function = state.getTypeMapper().mapSignature(fun.getName(), fun); + Method function = state.getTypeMapper().mapSignature(fun.getName(), fun); + Method functionOriginal = state.getTypeMapper().mapSignature(fun.getName(), fun.getOriginal()); - final MethodVisitor mv = v.visitMethod(flags, function.getName(), function.getDescriptor(), null, null); - mv.visitCode(); + final MethodVisitor mv = v.visitMethod(flags, function.getName(), function.getDescriptor(), null, null); + mv.visitCode(); - codegen.generateThisOrOuter(descriptor); + codegen.generateThisOrOuter(descriptor); - Type[] argTypes = function.getArgumentTypes(); - InstructionAdapter iv = new InstructionAdapter(mv); - iv.load(0, JetTypeMapper.TYPE_OBJECT); - for (int i = 0, reg = 1; i < argTypes.length; i++) { - Type argType = argTypes[i]; - iv.load(reg, argType); - //noinspection AssignmentToForLoopParameter - reg += argType.getSize(); - } + Type[] argTypes = function.getArgumentTypes(); + InstructionAdapter iv = new InstructionAdapter(mv); + iv.load(0, JetTypeMapper.TYPE_OBJECT); + for (int i = 0, reg = 1; i < argTypes.length; i++) { + Type argType = argTypes[i]; + iv.load(reg, argType); + //noinspection AssignmentToForLoopParameter + reg += argType.getSize(); + } - ClassDescriptor containingDeclaration = (ClassDescriptor) fun.getContainingDeclaration(); - JetType jetType = TraitImplBodyCodegen.getSuperClass(containingDeclaration, state.getBindingContext()); - Type type = state.getTypeMapper().mapType(jetType); - if(type.getInternalName().equals("java/lang/Object")) { - jetType = containingDeclaration.getDefaultType(); - type = state.getTypeMapper().mapType(jetType); - } + JetType jetType = TraitImplBodyCodegen.getSuperClass(declaration, state.getBindingContext()); + Type type = state.getTypeMapper().mapType(jetType); + if(type.getInternalName().equals("java/lang/Object")) { + jetType = declaration.getDefaultType(); + type = state.getTypeMapper().mapType(jetType); + } - String fdescriptor = function.getDescriptor().replace("(","(" + type.getDescriptor()); - iv.invokestatic(state.getTypeMapper().jvmName((ClassDescriptor) fun.getContainingDeclaration(), OwnerKind.TRAIT_IMPL), function.getName(), fdescriptor); - iv.areturn(function.getReturnType()); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - } - - private void getAbstractMethods(JetType type, Set set) { - if(type.equals(JetStandardClasses.getAny())) { - return; - } + String fdescriptor = functionOriginal.getDescriptor().replace("(","(" + type.getDescriptor()); + iv.invokestatic(state.getTypeMapper().jvmName((ClassDescriptor) fun.getContainingDeclaration(), OwnerKind.TRAIT_IMPL), function.getName(), fdescriptor); + if(function.getReturnType().getSort() == Type.OBJECT) { + iv.checkcast(function.getReturnType()); + } + iv.areturn(function.getReturnType()); + mv.visitMaxs(0, 0); + mv.visitEnd(); - for(JetType superType : type.getConstructor().getSupertypes()) { - getAbstractMethods(superType, set); - } - - PsiElement psiElement = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, type.getConstructor().getDeclarationDescriptor()); - if(psiElement instanceof JetClass) { - JetClass jetClass = (JetClass) psiElement; - for(JetDeclaration decl : jetClass.getDeclarations()) { - if(decl instanceof JetNamedFunction) { - JetNamedFunction jetNamedFunction = (JetNamedFunction) decl; - FunctionDescriptor funDescriptor = state.getBindingContext().get(BindingContext.FUNCTION, decl); - set.removeAll(funDescriptor.getOverriddenDescriptors()); - - if(jetNamedFunction.getBodyExpression() == null || jetClass.isTrait()) { - set.add(funDescriptor); + FunctionCodegen.generateBridgeIfNeeded(context, state, v, function, fun, kind); + } } } } } - else if(psiElement instanceof PsiClass) { - // todo - PsiClass psiClass = (PsiClass) psiElement; - } } - + @Nullable private ClassDescriptor getOuterClassDescriptor() { if (myClass.getParent() instanceof JetClassObject) { @@ -762,9 +749,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { return false; } - public boolean hasDerivedTypeInfoField(JetType type, boolean exceptOwn) { + public static boolean hasDerivedTypeInfoField(JetType type, boolean exceptOwn) { if(!exceptOwn) { - if(!state.getTypeMapper().isInterface((ClassDescriptor) type.getConstructor().getDeclarationDescriptor())) + if(!CodegenUtil.isInterface(type)) if(isParametrizedClass(type)) return true; } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index c44f54556af..6f4c07b316f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -222,14 +222,6 @@ public class JetTypeMapper { return jvmName(descriptor, OwnerKind.IMPLEMENTATION); } - public boolean isInterface(ClassDescriptor jetClass) { - PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, jetClass); - if (declaration instanceof JetObjectDeclaration) { - return false; - } - return declaration instanceof JetClass && ((JetClass) declaration).isTrait(); - } - private static String jetJvmName(ClassDescriptor jetClass, OwnerKind kind) { if (jetClass.getKind() == ClassKind.OBJECT) { return jvmNameForImplementation(jetClass); @@ -496,7 +488,7 @@ public class JetTypeMapper { else if (functionParent instanceof ClassDescriptor) { ClassDescriptor containingClass = (ClassDescriptor) functionParent; owner = jvmName(containingClass, OwnerKind.IMPLEMENTATION); - invokeOpcode = isInterface(containingClass) + invokeOpcode = CodegenUtil.isInterface(containingClass) ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL; needsReceiver = true; @@ -577,7 +569,7 @@ public class JetTypeMapper { List parameterTypes = new ArrayList(); ClassDescriptor classDescriptor = descriptor.getContainingDeclaration(); final DeclarationDescriptor outerDescriptor = classDescriptor.getContainingDeclaration(); - if (outerDescriptor instanceof ClassDescriptor) { + if (outerDescriptor instanceof ClassDescriptor && classDescriptor.getKind() != ClassKind.OBJECT) { parameterTypes.add(jvmType((ClassDescriptor) outerDescriptor, OwnerKind.IMPLEMENTATION)); } for (ValueParameterDescriptor parameter : parameters) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/MethodCodeGen.java b/compiler/backend/src/org/jetbrains/jet/codegen/MethodCodeGen.java deleted file mode 100644 index d9d657ac822..00000000000 --- a/compiler/backend/src/org/jetbrains/jet/codegen/MethodCodeGen.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.jetbrains.jet.codegen; - -/** - * @author max - */ -public class MethodCodeGen { - -} diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 0de28e5e0fe..6dc17c82643 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -2,9 +2,7 @@ package org.jetbrains.jet.codegen; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; -import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; -import org.jetbrains.jet.lang.descriptors.PropertySetterDescriptor; -import org.jetbrains.jet.lang.descriptors.VariableDescriptor; +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.constants.CompileTimeConstant; @@ -52,6 +50,10 @@ public class PropertyCodegen { private void generateBackingField(JetProperty p, PropertyDescriptor propertyDescriptor) { if (state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) { + DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration(); + if(CodegenUtil.isInterface(containingDeclaration)) + return; + Object value = null; final JetExpression initializer = p.getInitializer(); if (initializer != null) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java index c1817e67cc1..c8226572073 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java @@ -51,7 +51,7 @@ public class IntrinsicMethods { declareIntrinsicFunction(type, "dec", 0, DEC); } - final FunctionGroup typeInfoFunctionGroup = stdlib.getTypeInfoFunctionGroup(); + final Set typeInfoFunctionGroup = stdlib.getTypeInfoFunctions(); declareOverload(typeInfoFunctionGroup, 0, TYPEINFO); declareOverload(typeInfoFunctionGroup, 1, VALUE_TYPEINFO); @@ -108,12 +108,12 @@ public class IntrinsicMethods { private void declareIntrinsicFunction(String className, String functionName, int arity, IntrinsicMethod implementation) { JetScope memberScope = getClassMemberScope(className); - final FunctionGroup group = memberScope.getFunctionGroup(functionName); + final Set group = memberScope.getFunctions(functionName); declareOverload(group, arity, implementation); } - private void declareOverload(FunctionGroup group, int arity, IntrinsicMethod implementation) { - for (FunctionDescriptor descriptor : group.getFunctionDescriptors()) { + private void declareOverload(Set group, int arity, IntrinsicMethod implementation) { + for (FunctionDescriptor descriptor : group) { if (descriptor.getValueParameters().size() == arity) { myMethods.put(descriptor.getOriginal(), implementation); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassDescriptor.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassDescriptor.java index 6419589cff4..f1fed5d2201 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassDescriptor.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassDescriptor.java @@ -1,5 +1,6 @@ package org.jetbrains.jet.lang.resolve.java; +import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; @@ -12,6 +13,7 @@ import org.jetbrains.jet.lang.types.*; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Set; /** * @author abreslav @@ -21,7 +23,7 @@ public class JavaClassDescriptor extends MutableDeclarationDescriptor implements private TypeConstructor typeConstructor; private JavaClassMembersScope unsubstitutedMemberScope; private JetType classObjectType; - private final WritableFunctionGroup constructors = new WritableFunctionGroup(""); + private final Set constructors = Sets.newLinkedHashSet(); private Modality modality; private Visibility visibility; private JetType superclassType; @@ -65,7 +67,7 @@ public class JavaClassDescriptor extends MutableDeclarationDescriptor implements } public void addConstructor(ConstructorDescriptor constructorDescriptor) { - this.constructors.addFunction(constructorDescriptor); + this.constructors.add(constructorDescriptor); } private TypeSubstitutor createTypeSubstitutor(List typeArguments) { @@ -97,10 +99,7 @@ public class JavaClassDescriptor extends MutableDeclarationDescriptor implements @NotNull @Override - public FunctionGroup getConstructors() { -// assert typeArguments.size() == typeConstructor.getParameters().size(); -// if (typeArguments.isEmpty()) return constructors; -// return new LazySubstitutingFunctionGroup(createTypeSubstitutor(typeArguments), constructors); + public Set getConstructors() { return constructors; } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java index 23fbbacaa7b..713f828c4f3 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java @@ -12,6 +12,7 @@ import org.jetbrains.jet.lang.types.TypeSubstitutor; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Set; /** * @author abreslav @@ -21,7 +22,7 @@ public class JavaClassMembersScope implements JetScope { private final JavaSemanticServices semanticServices; private final boolean staticMembers; private final DeclarationDescriptor containingDeclaration; - private final Map functionGroups = Maps.newHashMap(); + private final Map> functionGroups = Maps.newHashMap(); private final Map variables = Maps.newHashMap(); private final Map classifiers = Maps.newHashMap(); private Collection allDescriptors; @@ -130,8 +131,8 @@ public class JavaClassMembersScope implements JetScope { @NotNull @Override - public FunctionGroup getFunctionGroup(@NotNull String name) { - FunctionGroup functionGroup = functionGroups.get(name); + public Set getFunctions(@NotNull String name) { + Set functionGroup = functionGroups.get(name); if (functionGroup == null) { functionGroup = semanticServices.getDescriptorResolver().resolveFunctionGroup( containingDeclaration, diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index 2e7ab8bf723..90aa3ac07c4 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.resolve.java; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; @@ -306,8 +307,8 @@ public class JavaDescriptorResolver { } @NotNull - public FunctionGroup resolveFunctionGroup(@NotNull DeclarationDescriptor owner, @NotNull PsiClass psiClass, @Nullable ClassDescriptor classDescriptor, @NotNull String methodName, boolean staticMembers) { - WritableFunctionGroup writableFunctionGroup = new WritableFunctionGroup(methodName); + public Set resolveFunctionGroup(@NotNull DeclarationDescriptor owner, @NotNull PsiClass psiClass, @Nullable ClassDescriptor classDescriptor, @NotNull String methodName, boolean staticMembers) { + Set writableFunctionGroup = Sets.newLinkedHashSet(); final Collection signatures = psiClass.getVisibleSignatures(); TypeSubstitutor typeSubstitutor = createSubstitutorForGenericSupertypes(classDescriptor); for (HierarchicalMethodSignature signature: signatures) { @@ -321,7 +322,7 @@ public class JavaDescriptorResolver { FunctionDescriptor substitutedFunctionDescriptor = resolveMethodToFunctionDescriptor(owner, psiClass, typeSubstitutor, method); if (substitutedFunctionDescriptor != null) { - writableFunctionGroup.addFunction(substitutedFunctionDescriptor); + writableFunctionGroup.add(substitutedFunctionDescriptor); } } return writableFunctionGroup; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java index 7c43e8a8bba..2b69b86e161 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java @@ -4,6 +4,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.scopes.JetScopeImpl; +import java.util.Collections; +import java.util.Set; + /** * @author abreslav */ @@ -31,13 +34,8 @@ public class JavaPackageScope extends JetScopeImpl { @NotNull @Override - public FunctionGroup getFunctionGroup(@NotNull String name) { -// ClassifierDescriptor classifier = getClassifier(name); -// if (classifier instanceof ClassDescriptor) { -// ClassDescriptor classDescriptor = (ClassDescriptor) classifier; -// return classDescriptor.getConstructors(); -// } - return FunctionGroup.EMPTY; + public Set getFunctions(@NotNull String name) { + return Collections.emptySet(); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/CallableMemberDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/CallableMemberDescriptor.java new file mode 100644 index 00000000000..1b8889a40b3 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/CallableMemberDescriptor.java @@ -0,0 +1,14 @@ +package org.jetbrains.jet.lang.descriptors; + +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +/** + * @author abreslav + */ +public interface CallableMemberDescriptor extends CallableDescriptor, MemberDescriptor { + @NotNull + @Override + Set getOverriddenDescriptors(); +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java index 2109517bfee..1b7057a76d4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java @@ -9,6 +9,7 @@ import org.jetbrains.jet.lang.types.TypeProjection; import org.jetbrains.jet.lang.types.TypeSubstitutor; import java.util.List; +import java.util.Set; /** * @author abreslav @@ -25,7 +26,7 @@ public interface ClassDescriptor extends ClassifierDescriptor { JetType getSuperclassType(); @NotNull - FunctionGroup getConstructors(); + Set getConstructors(); @Nullable ConstructorDescriptor getUnsubstitutedPrimaryConstructor(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorImpl.java index 7c74b53575b..962ec21cd3f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorImpl.java @@ -12,6 +12,7 @@ import org.jetbrains.jet.lang.types.*; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Set; /** * @author abreslav @@ -20,7 +21,7 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl private TypeConstructor typeConstructor; private JetScope memberDeclarations; - private FunctionGroup constructors; + private Set constructors; private ConstructorDescriptor primaryConstructor; private JetType superclassType; private ReceiverDescriptor implicitReceiver; @@ -36,7 +37,7 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl @NotNull List typeParameters, @NotNull Collection supertypes, @NotNull JetScope memberDeclarations, - @NotNull FunctionGroup constructors, + @NotNull Set constructors, @Nullable ConstructorDescriptor primaryConstructor) { return initialize(sealed, typeParameters, supertypes, memberDeclarations, constructors, primaryConstructor, getClassType(supertypes)); } @@ -45,7 +46,7 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl @NotNull List typeParameters, @NotNull Collection supertypes, @NotNull JetScope memberDeclarations, - @NotNull FunctionGroup constructors, + @NotNull Set constructors, @Nullable ConstructorDescriptor primaryConstructor, @Nullable JetType superclassType) { this.typeConstructor = new TypeConstructorImpl(this, getAnnotations(), sealed, getName(), typeParameters, supertypes); @@ -53,7 +54,6 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl this.constructors = constructors; this.primaryConstructor = primaryConstructor; this.superclassType = superclassType; -// assert !constructors.isEmpty() || primaryConstructor == null; return this; } @@ -103,13 +103,8 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl @NotNull @Override - public FunctionGroup getConstructors() { -// assert typeArguments.size() == getTypeConstructor().getParameters().size() : "Argument list length mismatch for " + getName(); -// if (typeArguments.size() == 0) { -// return constructors; -// } -// Map substitutionContext = TypeUtils.buildSubstitutionContext(getTypeConstructor().getParameters(), typeArguments); - return constructors;// LazySubstitutingFunctionGroup(TypeSubstitutor.create(substitutionContext), constructors); + public Set getConstructors() { + return constructors; } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptor.java index 1547e7d515e..ecfe2a80bc5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptor.java @@ -8,7 +8,7 @@ import java.util.Set; /** * @author abreslav */ -public interface FunctionDescriptor extends CallableDescriptor, MemberDescriptor { +public interface FunctionDescriptor extends CallableMemberDescriptor { @Override @NotNull DeclarationDescriptor getContainingDeclaration(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionGroup.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionGroup.java deleted file mode 100644 index 1dcfc99cf83..00000000000 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionGroup.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.jetbrains.jet.lang.descriptors; - -import org.jetbrains.annotations.NotNull; - -import java.util.Collections; -import java.util.Set; - -/** - * @author abreslav - */ -public interface FunctionGroup extends Named { - FunctionGroup EMPTY = new FunctionGroup() { - @NotNull - @Override - public String getName() { - return ""; - } - - @Override - public boolean isEmpty() { - return true; - } - - @NotNull - @Override - public Set getFunctionDescriptors() { - return Collections.emptySet(); - } - - @Override - public String toString() { - return "EMPTY"; - } - }; - - - @NotNull - @Override - String getName(); - - boolean isEmpty(); - - @NotNull - Set getFunctionDescriptors(); -} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LazySubstitutingClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LazySubstitutingClassDescriptor.java index be4f47938e3..aae2aa17435 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LazySubstitutingClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LazySubstitutingClassDescriptor.java @@ -10,6 +10,7 @@ import org.jetbrains.jet.lang.types.*; import java.util.Collection; import java.util.List; +import java.util.Set; /** * @author abreslav @@ -103,7 +104,7 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor { @NotNull @Override - public FunctionGroup getConstructors() { + public Set getConstructors() { throw new UnsupportedOperationException(); // TODO } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LazySubstitutingFunctionGroup.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LazySubstitutingFunctionGroup.java deleted file mode 100644 index c10e718d60c..00000000000 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LazySubstitutingFunctionGroup.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.jetbrains.jet.lang.descriptors; - -import com.google.common.collect.Sets; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.types.TypeSubstitutor; - -import java.util.Collections; -import java.util.Set; - -/** - * @author abreslav - */ -public class LazySubstitutingFunctionGroup implements FunctionGroup { - private final TypeSubstitutor substitutor; - private final FunctionGroup functionGroup; - private Set functionDescriptors; - - public LazySubstitutingFunctionGroup(TypeSubstitutor substitutor, FunctionGroup functionGroup) { - this.substitutor = substitutor; - this.functionGroup = functionGroup; - } - - @NotNull - @Override - public String getName() { - return functionGroup.getName(); - } - - @Override - public boolean isEmpty() { - return functionGroup.isEmpty(); - } - - @NotNull - @Override - public Set getFunctionDescriptors() { - if (functionDescriptors == null) { - if (substitutor.isEmpty()) { - functionDescriptors = functionGroup.getFunctionDescriptors(); - } - else { - Set functionDescriptorSet = Sets.newLinkedHashSet(); - for (FunctionDescriptor descriptor : functionGroup.getFunctionDescriptors()) { - FunctionDescriptor substitute = descriptor.substitute(substitutor); - if (substitute != null) { - functionDescriptorSet.add(substitute); - } - } - functionDescriptors = Collections.unmodifiableSet(functionDescriptorSet); - } - } - return functionDescriptors; - } -} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java index 3eb15deeb91..2870b819424 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java @@ -22,7 +22,7 @@ import java.util.*; */ public class MutableClassDescriptor extends MutableDeclarationDescriptor implements ClassDescriptor, NamespaceLike { private ConstructorDescriptor primaryConstructor; - private final WritableFunctionGroup constructors = new WritableFunctionGroup(""); + private final Set constructors = Sets.newLinkedHashSet(); private final Set functions = Sets.newHashSet(); private final Set properties = Sets.newHashSet(); private List typeParameters = Lists.newArrayList(); @@ -85,7 +85,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme public void addConstructor(@NotNull ConstructorDescriptor constructorDescriptor) { assert constructorDescriptor.getContainingDeclaration() == this; // assert constructorDescriptor.getTypeParameters().size() == getTypeConstructor().getParameters().size(); - constructors.addFunction(constructorDescriptor); + constructors.add(constructorDescriptor); if (defaultType != null) { // constructorDescriptor.getTypeParameters().addAll(typeParameters); ((ConstructorDescriptorImpl) constructorDescriptor).setReturnType(getDefaultType()); @@ -169,7 +169,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme typeParameters, supertypes); scopeForMemberResolution.setImplicitReceiver(new ClassReceiver(this)); - for (FunctionDescriptor functionDescriptor : constructors.getFunctionDescriptors()) { + for (FunctionDescriptor functionDescriptor : constructors) { ((ConstructorDescriptorImpl) functionDescriptor).setReturnType(getDefaultType()); } } @@ -202,15 +202,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme @NotNull @Override - public FunctionGroup getConstructors() { - // TODO : Duplicates ClassDescriptorImpl -// assert typeArguments.size() == getTypeConstructor().getParameters().size(); - -// if (typeArguments.size() == 0) { -// return constructors; -// } -// Map substitutionContext = TypeUtils.buildSubstitutionContext(getTypeConstructor().getParameters(), typeArguments); -// return new LazySubstitutingFunctionGroup(TypeSubstitutor.create(substitutionContext), constructors); + public Set getConstructors() { return constructors; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java index d56ba48d855..a4c897e05bd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java @@ -17,7 +17,7 @@ import java.util.Set; /** * @author abreslav */ -public class PropertyDescriptor extends VariableDescriptorImpl implements MemberDescriptor { +public class PropertyDescriptor extends VariableDescriptorImpl implements CallableMemberDescriptor { private final Modality modality; private final Visibility visibility; @@ -166,7 +166,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member @NotNull @Override - public Set getOverriddenDescriptors() { + public Set getOverriddenDescriptors() { return overriddenProperties; } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/WritableFunctionGroup.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/WritableFunctionGroup.java deleted file mode 100644 index 1892b5984a1..00000000000 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/WritableFunctionGroup.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.jetbrains.jet.lang.descriptors; - -import com.google.common.collect.Sets; -import org.jetbrains.annotations.NotNull; - -import java.util.Collections; -import java.util.Set; - -/** - * @author abreslav - */ -public class WritableFunctionGroup implements FunctionGroup { - private final String name; - private Set functionDescriptors; - private Set unmodifiableFunctionDescriptors; - - public WritableFunctionGroup(String name) { - this.name = name; - } - - @NotNull - @Override - public String getName() { - return name; - } - - @Override - public String toString() { - return "FunctionGroup{" + - "name='" + name + '\'' + - '}'; - } - - public void addFunction(@NotNull FunctionDescriptor functionDescriptor) { - getWritableFunctionDescriptors().add(functionDescriptor); - } - - @Override - @NotNull - public Set getFunctionDescriptors() { - if (unmodifiableFunctionDescriptors == null) { - unmodifiableFunctionDescriptors = Collections.unmodifiableSet(getWritableFunctionDescriptors()); - } - return unmodifiableFunctionDescriptors; - } - - private Set getWritableFunctionDescriptors() { - if (functionDescriptors == null) { - functionDescriptors = Sets.newLinkedHashSet(); - } - return functionDescriptors; - } - - @Override - public boolean isEmpty() { - return functionDescriptors == null || functionDescriptors.isEmpty(); - } - - public void addAllFunctions(@NotNull FunctionGroup functionGroup) { - if (functionGroup.isEmpty()) return; - getWritableFunctionDescriptors().addAll(functionGroup.getFunctionDescriptors()); - } -} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java index 2065ee465e6..addf843e41e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java @@ -1,6 +1,5 @@ package org.jetbrains.jet.lang.diagnostics; -import com.google.common.collect.Lists; import com.intellij.lang.ASTNode; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; @@ -107,7 +106,7 @@ public interface Errors { SimpleDiagnosticFactory BY_IN_SECONDARY_CONSTRUCTOR = SimpleDiagnosticFactory.create(ERROR, "'by'-clause is only supported for primary constructors"); SimpleDiagnosticFactory INITIALIZER_WITH_NO_ARGUMENTS = SimpleDiagnosticFactory.create(ERROR, "Constructor arguments required"); SimpleDiagnosticFactory MANY_CALLS_TO_THIS = SimpleDiagnosticFactory.create(ERROR, "Only one call to 'this(...)' is allowed"); - PsiElementOnlyDiagnosticFactory1 NOTHING_TO_OVERRIDE = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Function {0} overrides nothing"); + PsiElementOnlyDiagnosticFactory1 NOTHING_TO_OVERRIDE = PsiElementOnlyDiagnosticFactory1.create(ERROR, "{0} overrides nothing"); ParameterizedDiagnosticFactory1 PRIMARY_CONSTRUCTOR_MISSING_STATEFUL_PROPERTY = ParameterizedDiagnosticFactory1.create(ERROR, "This class must have a primary constructor, because property {0} has a backing field"); ParameterizedDiagnosticFactory1 PRIMARY_CONSTRUCTOR_MISSING_SUPER_CONSTRUCTOR_CALL = new ParameterizedDiagnosticFactory1(ERROR, "Class {0} must have a constructor in order to be able to initialize supertypes") { @Override @@ -121,7 +120,7 @@ public interface Errors { return e.getClass().getSimpleName() + ": " + e.getMessage(); } }; - PsiElementOnlyDiagnosticFactory3 VIRTUAL_METHOD_HIDDEN = PsiElementOnlyDiagnosticFactory3.create(ERROR, "Function ''{0}'' hides ''{1}'' in class {2} and needs 'override' modifier"); + PsiElementOnlyDiagnosticFactory3 VIRTUAL_MEMBER_HIDDEN = PsiElementOnlyDiagnosticFactory3.create(ERROR, "''{0}'' hides ''{1}'' in class {2} and needs 'override' modifier"); SimpleDiagnosticFactory UNREACHABLE_CODE = SimpleDiagnosticFactory.create(ERROR, "Unreachable code"); ParameterizedDiagnosticFactory1 UNREACHABLE_BECAUSE_OF_NOTHING = ParameterizedDiagnosticFactory1.create(ERROR, "This code is unreachable, because ''{0}'' never terminates normally"); @@ -274,9 +273,10 @@ public interface Errors { return nameExpression.getReferencedName(); } }; - ParameterizedDiagnosticFactory2 OVERRIDING_FINAL_FUNCTION = new ParameterizedDiagnosticFactory2(ERROR, "Method {0} in {1} is final and cannot be overridden") { + ParameterizedDiagnosticFactory2 OVERRIDING_FINAL_MEMBER = new ParameterizedDiagnosticFactory2(ERROR, "{0} in {1} is final and cannot be overridden") { + @Override - protected String makeMessageForA(@NotNull FunctionDescriptor functionDescriptor) { + protected String makeMessageForA(@NotNull CallableMemberDescriptor functionDescriptor) { return functionDescriptor.getName(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java index f9624422740..2d5218a40a3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java @@ -7,6 +7,7 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope; import java.util.Collection; import java.util.List; +import java.util.Set; /** * @author abreslav @@ -28,8 +29,8 @@ public abstract class AbstractScopeAdapter implements JetScope { @NotNull @Override - public FunctionGroup getFunctionGroup(@NotNull String name) { - return getWorkerScope().getFunctionGroup(name); + public Set getFunctions(@NotNull String name) { + return getWorkerScope().getFunctions(name); } @Override diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java index 3048ec1503a..985064fd161 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java @@ -131,7 +131,7 @@ public class DeclarationResolver { if (!klass.hasPrimaryConstructor()) return; if (classDescriptor.getKind() == ClassKind.TRAIT) { -// context.getTrace().getErrorHandler().genericError(klass.getPrimaryConstructorParameterList().getNode(), "A trait may not have a constructor"); +// context.getTrace().getErrorHandler().genericError(klass.getPrimaryConstructorParameterList().getNode(), "A trait may not have a constructor"); context.getTrace().report(CONSTRUCTOR_IN_TRAIT.on(klass.getPrimaryConstructorParameterList())); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java index d0371925643..de1b8e91298 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java @@ -1,5 +1,6 @@ package org.jetbrains.jet.lang.resolve; +import com.google.common.collect.Multimap; import com.google.common.collect.Sets; import com.intellij.lang.ASTNode; import com.intellij.psi.PsiElement; @@ -8,7 +9,9 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.JetTypeChecker; import org.jetbrains.jet.lexer.JetTokens; +import org.jetbrains.jet.util.CommonSuppliers; import java.util.Collection; import java.util.Map; @@ -63,8 +66,8 @@ public class OverrideResolver { @Nullable private FunctionDescriptor findFunctionOverridableBy(@NotNull FunctionDescriptor declaredFunction, @NotNull JetType supertype) { - FunctionGroup functionGroup = supertype.getMemberScope().getFunctionGroup(declaredFunction.getName()); - for (FunctionDescriptor functionDescriptor : functionGroup.getFunctionDescriptors()) { + Set functionGroup = supertype.getMemberScope().getFunctions(declaredFunction.getName()); + for (FunctionDescriptor functionDescriptor : functionGroup) { if (OverridingUtil.isOverridableBy(context.getSemanticServices().getTypeChecker(), functionDescriptor, declaredFunction).isSuccess()) { return functionDescriptor; } @@ -94,29 +97,68 @@ public class OverrideResolver { } protected void checkOverridesInAClass(MutableClassDescriptor classDescriptor, JetClassOrObject klass) { - - Set inheritedFunctions = Sets.newLinkedHashSet(); - Set inheritedProperties = Sets.newLinkedHashSet(); + // Everything from supertypes + Set inheritedFunctions = Sets.newLinkedHashSet(); for (JetType supertype : classDescriptor.getSupertypes()) { for (DeclarationDescriptor descriptor : supertype.getMemberScope().getAllDescriptors()) { - if (descriptor instanceof FunctionDescriptor) { - FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor; - inheritedFunctions.add(functionDescriptor); - } - else if (descriptor instanceof PropertyDescriptor) { - PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor; - inheritedProperties.add(propertyDescriptor); + if (descriptor instanceof CallableMemberDescriptor) { + CallableMemberDescriptor memberDescriptor = (CallableMemberDescriptor) descriptor; + inheritedFunctions.add(memberDescriptor); } } } - OverridingUtil.filterOverrides(inheritedFunctions); - OverridingUtil.filterOverrides(inheritedProperties); + // Only those actually inherited + Set filteredMembers = OverridingUtil.filterOverrides(inheritedFunctions); + + // Group members with "the same" signature + Multimap factoredMembers = CommonSuppliers.newLinkedHashSetHashSetMultimap(); + JetTypeChecker typeChecker = context.getSemanticServices().getTypeChecker(); + for (CallableMemberDescriptor one : filteredMembers) { + if (factoredMembers.values().contains(one)) continue; + for (CallableMemberDescriptor another : filteredMembers) { + if (one == another) continue; + factoredMembers.put(one, one); + if (OverridingUtil.isOverridableBy(typeChecker, one, another).isSuccess() + || OverridingUtil.isOverridableBy(typeChecker, another, one).isSuccess()) { + factoredMembers.put(one, another); + } + } + } + + // More than one implementation or no implementations at all + Set mustBeOverridden = Sets.newLinkedHashSet(); + for (CallableMemberDescriptor key : factoredMembers.keySet()) { + Collection mutuallyOverridable = factoredMembers.get(key); + + int implementationCount = 0; + for (CallableMemberDescriptor member : mutuallyOverridable) { + if (member.getModality() != Modality.ABSTRACT) { + implementationCount++; + } + } + + if (implementationCount != 1) { + mustBeOverridden.addAll(mutuallyOverridable); + } + } + + // Members actually present (declared) in the class + Set actuallyOverridden = Sets.newHashSet(); + for (FunctionDescriptor declaredFunction : classDescriptor.getFunctions()) { + actuallyOverridden.addAll(declaredFunction.getOverriddenDescriptors()); + } + for (PropertyDescriptor declaredProperty : classDescriptor.getProperties()) { + actuallyOverridden.addAll(declaredProperty.getOverriddenDescriptors()); + } + + // Those to be overridden that are actually not + mustBeOverridden.removeAll(actuallyOverridden); // System.out.println(classDescriptor); -// println(inheritedFunctions); -// println(inheritedProperties); - +// println(mustBeOverridden); +// System.out.println("Actually overridden:"); +// println(actuallyOverridden); for (FunctionDescriptor declaredFunction : classDescriptor.getFunctions()) { checkOverrideForFunction(declaredFunction); @@ -160,41 +202,47 @@ public class OverrideResolver { } } - private void println(Set inheritedProperties) { + private void println(Collection inheritedProperties) { for (CallableDescriptor inheritedProperty : inheritedProperties) { System.out.println(" " + inheritedProperty); } } - private void checkOverrideForFunction(FunctionDescriptor declaredFunction) { - JetFunction function = (JetFunction) context.getTrace().get(BindingContext.DESCRIPTOR_TO_DECLARATION, declaredFunction); - assert function != null; - JetModifierList modifierList = function.getModifierList(); + private void checkOverrideForFunction(CallableMemberDescriptor declared) { + JetNamedDeclaration member = (JetNamedDeclaration) context.getTrace().get(BindingContext.DESCRIPTOR_TO_DECLARATION, declared); + assert member != null; + JetModifierList modifierList = member.getModifierList(); ASTNode overrideNode = modifierList != null ? modifierList.getModifierNode(JetTokens.OVERRIDE_KEYWORD) : null; boolean hasOverrideModifier = overrideNode != null; - boolean foundError = false; + boolean error = false; - for (FunctionDescriptor overridden : declaredFunction.getOverriddenDescriptors()) { + for (CallableMemberDescriptor overridden : declared.getOverriddenDescriptors()) { if (overridden != null) { - if (hasOverrideModifier && !overridden.getModality().isOpen() && !foundError) { -// context.getTrace().getErrorHandler().genericError(overrideNode, "Method " + overridden.getName() + " in " + overridden.getContainingDeclaration().getName() + " is final and cannot be overridden"); - context.getTrace().report(OVERRIDING_FINAL_FUNCTION.on(overrideNode, overridden, overridden.getContainingDeclaration())); - foundError = true; + if (hasOverrideModifier) { + if (!overridden.getModality().isOpen() && !error) { + // context.getTrace().getErrorHandler().genericError(overrideNode, "Method " + overridden.getName() + " in " + overridden.getContainingDeclaration().getName() + " is final and cannot be overridden"); + context.getTrace().report(OVERRIDING_FINAL_MEMBER.on(overrideNode, overridden, overridden.getContainingDeclaration())); + error = true; + } + + if (!OverridingUtil.isReturnTypeOkForOverride(JetTypeChecker.INSTANCE, overridden, declared).isSuccess()) { + + } } } } - if (hasOverrideModifier && declaredFunction.getOverriddenDescriptors().size() == 0) { -// context.getTrace().getErrorHandler().genericError(overrideNode, "Method " + declaredFunction.getName() + " overrides nothing"); - context.getTrace().report(NOTHING_TO_OVERRIDE.on(function, overrideNode, declaredFunction)); + if (hasOverrideModifier && declared.getOverriddenDescriptors().size() == 0) { +// context.getTrace().getErrorHandler().genericError(overrideNode, "Method " + declared.getName() + " overrides nothing"); + context.getTrace().report(NOTHING_TO_OVERRIDE.on(member, overrideNode, declared)); } - PsiElement nameIdentifier = function.getNameIdentifier(); - if (!hasOverrideModifier && declaredFunction.getOverriddenDescriptors().size() > 0 && nameIdentifier != null) { - FunctionDescriptor overriddenFunction = declaredFunction.getOverriddenDescriptors().iterator().next(); + PsiElement nameIdentifier = member.getNameIdentifier(); + if (!hasOverrideModifier && declared.getOverriddenDescriptors().size() > 0 && nameIdentifier != null) { + CallableMemberDescriptor overridden = declared.getOverriddenDescriptors().iterator().next(); // context.getTrace().getErrorHandler().genericError(nameIdentifier.getNode(), -// "Method '" + declaredFunction.getName() + "' overrides method '" + overriddenFunction.getName() + "' in class " + -// overriddenFunction.getContainingDeclaration().getName() + " and needs 'override' modifier"); - context.getTrace().report(VIRTUAL_METHOD_HIDDEN.on(function, nameIdentifier, declaredFunction, overriddenFunction, overriddenFunction.getContainingDeclaration())); +// "Method '" + declared.getName() + "' overrides method '" + overridden.getName() + "' in class " + +// overridden.getContainingDeclaration().getName() + " and needs 'override' modifier"); + context.getTrace().report(VIRTUAL_MEMBER_HIDDEN.on(member, nameIdentifier, declared, overridden, overridden.getContainingDeclaration())); } } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java index 2ca2700119e..f850e3efb3d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java @@ -18,6 +18,9 @@ import java.util.Set; */ public class OverridingUtil { + private OverridingUtil() { + } + public static Set getEffectiveMembers(@NotNull ClassDescriptor classDescriptor) { Collection allDescriptors = classDescriptor.getDefaultType().getMemberScope().getAllDescriptors(); Set allMembers = Sets.newLinkedHashSet(); @@ -99,14 +102,10 @@ public class OverridingUtil { List superTypeParameters = superDescriptor.getTypeParameters(); List subTypeParameters = subDescriptor.getTypeParameters(); - Map substitutionContext = Maps.newHashMap(); BiMap axioms = HashBiMap.create(); for (int i = 0, typeParametersSize = superTypeParameters.size(); i < typeParametersSize; i++) { TypeParameterDescriptor superTypeParameter = superTypeParameters.get(i); TypeParameterDescriptor subTypeParameter = subTypeParameters.get(i); - substitutionContext.put( - superTypeParameter.getTypeConstructor(), - new TypeProjection(subTypeParameter.getDefaultType())); axioms.put(superTypeParameter.getTypeConstructor(), subTypeParameter.getTypeConstructor()); } @@ -114,7 +113,6 @@ public class OverridingUtil { TypeParameterDescriptor superTypeParameter = superTypeParameters.get(i); TypeParameterDescriptor subTypeParameter = subTypeParameters.get(i); - if (!JetTypeImpl.equalTypes(superTypeParameter.getBoundsAsType(), subTypeParameter.getBoundsAsType(), axioms)) { return OverrideCompatibilityInfo.boundsMismatch(superTypeParameter, subTypeParameter); } @@ -133,6 +131,23 @@ public class OverridingUtil { // TODO : Default values, varargs etc + return OverrideCompatibilityInfo.success(); + } + + @NotNull + public static OverrideCompatibilityInfo isReturnTypeOkForOverride(@NotNull JetTypeChecker typeChecker, @NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor) { + List superTypeParameters = superDescriptor.getTypeParameters(); + List subTypeParameters = subDescriptor.getTypeParameters(); + Map substitutionContext = Maps.newHashMap(); + for (int i = 0, typeParametersSize = superTypeParameters.size(); i < typeParametersSize; i++) { + TypeParameterDescriptor superTypeParameter = superTypeParameters.get(i); + TypeParameterDescriptor subTypeParameter = subTypeParameters.get(i); + substitutionContext.put( + superTypeParameter.getTypeConstructor(), + new TypeProjection(subTypeParameter.getDefaultType())); + } + + // This code compares return types, but they are not a part of the signature, so this code does not belong here TypeSubstitutor typeSubstitutor = TypeSubstitutor.create(substitutionContext); JetType substitutedSuperReturnType = typeSubstitutor.substitute(superDescriptor.getReturnType(), Variance.OUT_VARIANCE); assert substitutedSuperReturnType != null; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java index 56b18bbb19e..fbf91dd2808 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -7,6 +7,7 @@ import com.intellij.lang.ASTNode; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiNameIdentifierOwner; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; @@ -20,6 +21,7 @@ import org.jetbrains.jet.lexer.JetTokens; import java.util.*; import static org.jetbrains.jet.lang.diagnostics.Errors.*; +import static org.jetbrains.jet.lang.resolve.BindingContext.CONSTRUCTOR; import static org.jetbrains.jet.lang.resolve.BindingContext.DESCRIPTOR_TO_DECLARATION; import static org.jetbrains.jet.lang.resolve.BindingContext.TYPE; @@ -98,7 +100,7 @@ public class TypeHierarchyResolver { classObjectDescriptor.setModality(Modality.FINAL); classObjectDescriptor.setVisibility(ClassDescriptorResolver.resolveVisibilityFromModifiers(context.getTrace(), klass.getModifierList())); classObjectDescriptor.createTypeConstructor(); - createPrimaryConstructor(classObjectDescriptor); + createPrimaryConstructorForObject(null, classObjectDescriptor); mutableClassDescriptor.setClassObjectDescriptor(classObjectDescriptor); } visitClassOrObject( @@ -144,17 +146,20 @@ public class TypeHierarchyResolver { } }; visitClassOrObject(declaration, (Map) context.getObjects(), owner, outerScope, mutableClassDescriptor); - createPrimaryConstructor(mutableClassDescriptor); + createPrimaryConstructorForObject((JetDeclaration) declaration, mutableClassDescriptor); context.getTrace().record(BindingContext.CLASS, declaration, mutableClassDescriptor); return mutableClassDescriptor; } - private void createPrimaryConstructor(MutableClassDescriptor mutableClassDescriptor) { + private void createPrimaryConstructorForObject(@Nullable JetDeclaration object, MutableClassDescriptor mutableClassDescriptor) { ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(mutableClassDescriptor, Collections.emptyList(), true); constructorDescriptor.initialize(Collections.emptyList(), Collections.emptyList(), Modality.FINAL, Visibility.INTERNAL);//TODO check set mutableClassDescriptor.getVisibility() // TODO : make the constructor private? mutableClassDescriptor.setPrimaryConstructor(constructorDescriptor); + if (object != null) { + context.getTrace().record(CONSTRUCTOR, object, constructorDescriptor); + } } private void visitClassOrObject(@NotNull JetClassOrObject declaration, Map map, NamespaceLike owner, JetScope outerScope, MutableClassDescriptor mutableClassDescriptor) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index d2649b587c6..f0423457999 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -138,7 +138,7 @@ public class CallResolver { DeclarationDescriptor declarationDescriptor = constructedType.getConstructor().getDeclarationDescriptor(); if (declarationDescriptor instanceof ClassDescriptor) { ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor; - Set constructors = classDescriptor.getConstructors().getFunctionDescriptors(); + Set constructors = classDescriptor.getConstructors(); if (constructors.isEmpty()) { // trace.getErrorHandler().genericError(reportAbsenceOn, "This class does not have a constructor"); trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn)); @@ -159,7 +159,7 @@ public class CallResolver { ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration; - Set constructors = classDescriptor.getConstructors().getFunctionDescriptors(); + Set constructors = classDescriptor.getConstructors(); if (constructors.isEmpty()) { // trace.getErrorHandler().genericError(reportAbsenceOn, "This class does not have a constructor"); trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn)); @@ -630,7 +630,7 @@ public class CallResolver { private List findCandidatesByExactSignature(JetScope scope, ReceiverDescriptor receiver, String name, List parameterTypes) { List result = Lists.newArrayList(); if (receiver != NO_RECEIVER) { - Set extensionFunctionDescriptors = scope.getFunctionGroup(name).getFunctionDescriptors(); + Set extensionFunctionDescriptors = scope.getFunctions(name); List nonlocal = Lists.newArrayList(); List local = Lists.newArrayList(); TaskPrioritizer.splitLexicallyLocalDescriptors(extensionFunctionDescriptors, scope.getContainingDeclaration(), local, nonlocal); @@ -640,7 +640,7 @@ public class CallResolver { return result; } - Set functionDescriptors = receiver.getType().getMemberScope().getFunctionGroup(name).getFunctionDescriptors(); + Set functionDescriptors = receiver.getType().getMemberScope().getFunctions(name); if (lookupExactSignature(functionDescriptors, parameterTypes, result)) { return result; @@ -649,7 +649,7 @@ public class CallResolver { return result; } else { - lookupExactSignature(scope.getFunctionGroup(name).getFunctionDescriptors(), parameterTypes, result); + lookupExactSignature(scope.getFunctions(name), parameterTypes, result); return result; } } @@ -696,7 +696,7 @@ public class CallResolver { @NotNull @Override protected Collection getNonExtensionsByName(JetScope scope, String name) { - Set functions = Sets.newLinkedHashSet(scope.getFunctionGroup(name).getFunctionDescriptors()); + Set functions = Sets.newLinkedHashSet(scope.getFunctions(name)); for (Iterator iterator = functions.iterator(); iterator.hasNext(); ) { FunctionDescriptor functionDescriptor = iterator.next(); if (functionDescriptor.getReceiver() != NO_RECEIVER) { @@ -713,7 +713,7 @@ public class CallResolver { @Override protected Collection getMembersByName(@NotNull ReceiverDescriptor receiver, String name) { JetScope receiverScope = receiver.getType().getMemberScope(); - Set members = Sets.newHashSet(receiverScope.getFunctionGroup(name).getFunctionDescriptors()); + Set members = Sets.newHashSet(receiverScope.getFunctions(name)); addConstructors(receiverScope, name, members); addVariableAsFunction(receiverScope, name, members, false); return members; @@ -722,7 +722,7 @@ public class CallResolver { @NotNull @Override protected Collection getExtensionsByName(JetScope scope, String name) { - Set extensionFunctions = Sets.newHashSet(scope.getFunctionGroup(name).getFunctionDescriptors()); + Set extensionFunctions = Sets.newHashSet(scope.getFunctions(name)); for (Iterator iterator = extensionFunctions.iterator(); iterator.hasNext(); ) { FunctionDescriptor descriptor = iterator.next(); if (descriptor.getReceiver() == NO_RECEIVER) { @@ -743,7 +743,7 @@ public class CallResolver { ClassifierDescriptor classifier = scope.getClassifier(name); if (classifier instanceof ClassDescriptor && !ErrorUtils.isError(classifier.getTypeConstructor())) { ClassDescriptor classDescriptor = (ClassDescriptor) classifier; - functions.addAll(classDescriptor.getConstructors().getFunctionDescriptors()); + functions.addAll(classDescriptor.getConstructors()); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java index 5b61003165e..6e457d2ebce 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java @@ -9,6 +9,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Set; /** * @author abreslav @@ -56,16 +57,15 @@ public class ChainedScope implements JetScope { @NotNull @Override - public FunctionGroup getFunctionGroup(@NotNull String name) { + public Set getFunctions(@NotNull String name) { if (scopeChain.length == 0) { - return FunctionGroup.EMPTY; + return Collections.emptySet(); } - WritableFunctionGroup result = new WritableFunctionGroup(name); + Set result = Sets.newLinkedHashSet(); for (JetScope jetScope : scopeChain) { - result.addAllFunctions(jetScope.getFunctionGroup(name)); + result.addAll(jetScope.getFunctions(name)); } - return result; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java index eb5bfb96890..6f4495e1bef 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java @@ -7,6 +7,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import java.util.Collection; import java.util.List; +import java.util.Set; /** * @author abreslav @@ -35,7 +36,7 @@ public interface JetScope { VariableDescriptor getVariable(@NotNull String name); @NotNull - FunctionGroup getFunctionGroup(@NotNull String name); + Set getFunctions(@NotNull String name); @NotNull DeclarationDescriptor getContainingDeclaration(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeImpl.java index 8eeec10a018..b738d76a50c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeImpl.java @@ -7,6 +7,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Set; /** * @author abreslav @@ -35,8 +36,8 @@ public abstract class JetScopeImpl implements JetScope { @NotNull @Override - public FunctionGroup getFunctionGroup(@NotNull String name) { - return FunctionGroup.EMPTY; + public Set getFunctions(@NotNull String name) { + return Collections.emptySet(); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java index fb7497551f0..f09364216e1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java @@ -8,9 +8,7 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.TypeSubstitutor; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.util.*; /** * @author abreslav @@ -20,7 +18,7 @@ public class SubstitutingScope implements JetScope { private final JetScope workerScope; private final TypeSubstitutor substitutor; - private Map functionGroups = null; + private Map substitutedDescriptors = null; private Collection allDescriptors = null; public SubstitutingScope(JetScope workerScope, @NotNull TypeSubstitutor substitutor) { @@ -28,26 +26,54 @@ public class SubstitutingScope implements JetScope { this.substitutor = substitutor; } - @Override - public VariableDescriptor getVariable(@NotNull String name) { - VariableDescriptor variable = workerScope.getVariable(name); - if (variable == null || substitutor.isEmpty()) { - return variable; + @Nullable + private D substitute(@Nullable D descriptor) { + if (descriptor == null) return null; + if (substitutor.isEmpty()) return descriptor; + + if (substitutedDescriptors == null) { + substitutedDescriptors = Maps.newHashMap(); } - return variable.substitute(substitutor); + DeclarationDescriptor substituted = substitutedDescriptors.get(descriptor); + if (substituted == null) { + substituted = descriptor.substitute(substitutor); + substitutedDescriptors.put(descriptor, substituted); + } + //noinspection unchecked + return (D) substituted; + } + + @NotNull + private Set substitute(@NotNull Set descriptors) { + if (substitutor.isEmpty()) return descriptors; + if (descriptors.isEmpty()) return descriptors; + + Set result = Sets.newHashSet(); + for (D descriptor : descriptors) { + D substitute = substitute(descriptor); + if (substitute != null) { + result.add(substitute); + } + } + + return result; + } + + @Override + public VariableDescriptor getVariable(@NotNull String name) { + return substitute(workerScope.getVariable(name)); } @Override public ClassifierDescriptor getClassifier(@NotNull String name) { - ClassifierDescriptor descriptor = workerScope.getClassifier(name); - if (descriptor == null) { - return null; - } - if (descriptor instanceof ClassDescriptor) { - return new LazySubstitutingClassDescriptor((ClassDescriptor) descriptor, substitutor); - } - throw new UnsupportedOperationException(); // TODO + return substitute(workerScope.getClassifier(name)); + } + + @NotNull + @Override + public Set getFunctions(@NotNull String name) { + return substitute(workerScope.getFunctions(name)); } @Override @@ -66,32 +92,6 @@ public class SubstitutingScope implements JetScope { throw new UnsupportedOperationException(); // TODO } - @NotNull - @Override - public FunctionGroup getFunctionGroup(@NotNull String name) { - if (substitutor.isEmpty()) { - return workerScope.getFunctionGroup(name); - } - if (functionGroups == null) { - functionGroups = Maps.newHashMap(); - } - FunctionGroup cachedGroup = functionGroups.get(name); - if (cachedGroup != null) { - return cachedGroup; - } - - FunctionGroup functionGroup = workerScope.getFunctionGroup(name); - FunctionGroup result; - if (functionGroup.isEmpty()) { - result = FunctionGroup.EMPTY; - } - else { - result = new LazySubstitutingFunctionGroup(substitutor, functionGroup); - } - functionGroups.put(name, result); - return result; - } - @NotNull @Override public DeclarationDescriptor getContainingDeclaration() { @@ -121,7 +121,7 @@ public class SubstitutingScope implements JetScope { if (allDescriptors == null) { allDescriptors = Sets.newHashSet(); for (DeclarationDescriptor descriptor : workerScope.getAllDescriptors()) { - DeclarationDescriptor substitute = descriptor.substitute(substitutor); + DeclarationDescriptor substitute = substitute(descriptor); assert substitute != null; allDescriptors.add(substitute); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java index 9fa55238319..b63ee731480 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java @@ -1,13 +1,12 @@ package org.jetbrains.jet.lang.resolve.scopes; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; +import com.google.common.collect.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; +import org.jetbrains.jet.util.CommonSuppliers; import java.util.*; @@ -27,7 +26,7 @@ public class WritableScopeImpl extends WritableScopeWithImports { private Map propertyDescriptorsByFieldNames; @Nullable - private Map functionGroups; + private SetMultimap functionGroups; @Nullable private Map variableClassOrNamespaceDescriptors; @@ -144,13 +143,6 @@ public class WritableScopeImpl extends WritableScopeWithImports { return (VariableDescriptor) descriptor; } -// if (implicitReceiver != null) { -// VariableDescriptor variable = getImplicitReceiver().getMemberScope().getVariable(name); -// if (variable != null) { -// return variable; -// } -// } - VariableDescriptor variableDescriptor = getWorkerScope().getVariable(name); if (variableDescriptor != null) { return variableDescriptor; @@ -159,45 +151,27 @@ public class WritableScopeImpl extends WritableScopeWithImports { } @NotNull - private Map getFunctionGroups() { + private SetMultimap getFunctionGroups() { if (functionGroups == null) { - functionGroups = new HashMap(); + functionGroups = CommonSuppliers.newLinkedHashSetHashSetMultimap(); } return functionGroups; } @Override public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) { - String name = functionDescriptor.getName(); - Map functionGroups = getFunctionGroups(); - - @Nullable - WritableFunctionGroup functionGroup = functionGroups.get(name); - if (functionGroup == null) { - functionGroup = new WritableFunctionGroup(name); - functionGroups.put(name, functionGroup); - } - functionGroup.addFunction(functionDescriptor); + getFunctionGroups().put(functionDescriptor.getName(), functionDescriptor); allDescriptors.add(functionDescriptor); } @Override @NotNull - public FunctionGroup getFunctionGroup(@NotNull String name) { - WritableFunctionGroup result = new WritableFunctionGroup(name); - - FunctionGroup functionGroup = getFunctionGroups().get(name); - if (functionGroup != null) { - result.addAllFunctions(functionGroup); - } - -// if (implicitReceiver != null) { -// result.addAllFunctions(getImplicitReceiver().getMemberScope().getFunctionGroup(name)); -// } + public Set getFunctions(@NotNull String name) { + Set result = Sets.newLinkedHashSet(getFunctionGroups().get(name)); - result.addAllFunctions(getWorkerScope().getFunctionGroup(name)); + result.addAll(getWorkerScope().getFunctions(name)); - result.addAllFunctions(super.getFunctionGroup(name)); + result.addAll(super.getFunctions(name)); return result; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java index 00dee3bc289..b88a8d17be3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java @@ -1,11 +1,17 @@ package org.jetbrains.jet.lang.resolve.scopes; +import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Set; /** * @author abreslav @@ -58,16 +64,13 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement @NotNull @Override - public FunctionGroup getFunctionGroup(@NotNull String name) { + public Set getFunctions(@NotNull String name) { if (getImports().isEmpty()) { - return FunctionGroup.EMPTY; + return Collections.emptySet(); } - WritableFunctionGroup result = new WritableFunctionGroup(name); + Set result = Sets.newLinkedHashSet(); for (JetScope imported : getImports()) { - FunctionGroup importedFunctions = imported.getFunctionGroup(name); - if (!importedFunctions.isEmpty()) { - result.addAllFunctions(importedFunctions); - } + result.addAll(imported.getFunctions(name)); } return result; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java index e3082888951..fb5e6e6a8b5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java @@ -1,12 +1,14 @@ package org.jetbrains.jet.lang.resolve.scopes; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import java.util.Collection; +import java.util.Set; /** * @author abreslav @@ -46,14 +48,14 @@ public class WriteThroughScope extends WritableScopeWithImports { @Override @NotNull - public FunctionGroup getFunctionGroup(@NotNull String name) { - WritableFunctionGroup result = new WritableFunctionGroup(name); + public Set getFunctions(@NotNull String name) { + Set result = Sets.newLinkedHashSet(); - result.addAllFunctions(writableWorker.getFunctionGroup(name)); + result.addAll(writableWorker.getFunctions(name)); - result.addAllFunctions(getWorkerScope().getFunctionGroup(name)); + result.addAll(getWorkerScope().getFunctions(name)); - result.addAllFunctions(super.getFunctionGroup(name)); // Imports + result.addAll(super.getFunctions(name)); // Imports return result; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java index afa7a1dba62..b30f40e2aa2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java @@ -43,7 +43,7 @@ public class ErrorUtils { @NotNull @Override - public FunctionGroup getFunctionGroup(@NotNull String name) { + public Set getFunctions(@NotNull String name) { return ERROR_FUNCTION_GROUP; } @@ -77,33 +77,17 @@ public class ErrorUtils { }; - private static final FunctionGroup ERROR_FUNCTION_GROUP = new FunctionGroup() { - @NotNull - @Override - public String getName() { - return ""; - } - - @Override - public boolean isEmpty() { - return false; - } - - @NotNull - @Override - public Set getFunctionDescriptors() { - return Collections.singleton(createErrorFunction(0, Collections.emptyList())); - } - }; - private static final ClassDescriptorImpl ERROR_CLASS = new ClassDescriptorImpl(ERROR_MODULE, Collections.emptyList(), "") { @NotNull @Override - public FunctionGroup getConstructors() { + public Set getConstructors() { return ERROR_FUNCTION_GROUP; } }; + + private static final Set ERROR_FUNCTION_GROUP = Collections.singleton(createErrorFunction(0, Collections.emptyList())); private static final ConstructorDescriptor ERROR_CONSTRUCTOR = new ConstructorDescriptorImpl(ERROR_CLASS, Collections.emptyList(), true); + static { ERROR_CLASS.initialize( true, Collections.emptyList(), Collections.emptyList(), getErrorScope(), ERROR_FUNCTION_GROUP, ERROR_CONSTRUCTOR); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardClasses.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardClasses.java index 3ce7eb0d2d6..41774dc14c4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardClasses.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardClasses.java @@ -48,7 +48,7 @@ public class JetStandardClasses { } }, JetScope.EMPTY, - FunctionGroup.EMPTY, + Collections.emptySet(), null, null ); @@ -71,7 +71,7 @@ public class JetStandardClasses { Collections.emptyList(), Collections.emptySet(), JetScope.EMPTY, - FunctionGroup.EMPTY, + Collections.emptySet(), null, null ); @@ -97,7 +97,6 @@ public class JetStandardClasses { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public static final JetScope STUB = JetScope.EMPTY; - public static final FunctionGroup STUB_FG = FunctionGroup.EMPTY; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -124,7 +123,7 @@ public class JetStandardClasses { parameters, Collections.singleton(getAnyType()), STUB, - STUB_FG, + Collections.emptySet(), // TODO null); // TODO : constructor TUPLE_CONSTRUCTORS.add(TUPLE[i].getTypeConstructor()); } @@ -149,7 +148,7 @@ public class JetStandardClasses { FUNCTION[i] = function.initialize( false, createTypeParameters(i, function), - Collections.singleton(getAnyType()), STUB, FunctionGroup.EMPTY, null); + Collections.singleton(getAnyType()), STUB, Collections.emptySet(), null); FUNCTION_TYPE_CONSTRUCTORS.add(FUNCTION[i].getTypeConstructor()); ClassDescriptorImpl receiverFunction = new ClassDescriptorImpl( @@ -164,7 +163,7 @@ public class JetStandardClasses { RECEIVER_FUNCTION[i] = receiverFunction.initialize( false, parameters, - Collections.singleton(getAnyType()), STUB, FunctionGroup.EMPTY, null); + Collections.singleton(getAnyType()), STUB, Collections.emptySet(), null); RECEIVER_FUNCTION_TYPE_CONSTRUCTORS.add(RECEIVER_FUNCTION[i].getTypeConstructor()); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java index 1ec692c6930..85a0476036e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java @@ -6,7 +6,7 @@ import com.intellij.psi.PsiFileFactory; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -import org.jetbrains.jet.lang.descriptors.FunctionGroup; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.JetFile; @@ -21,6 +21,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.util.Collections; import java.util.List; +import java.util.Set; /** * @author abreslav @@ -60,7 +61,6 @@ public class JetStandardLibrary { private final ClassDescriptor arrayClass; private final ClassDescriptor iterableClass; private final ClassDescriptor typeInfoClass; - private final ClassDescriptor tuple0Class; private final JetType byteType; private final JetType nullableByteType; @@ -89,7 +89,7 @@ public class JetStandardLibrary { private final JetType nullableStringType; private final NamespaceDescriptor typeInfoNamespace; - private final FunctionGroup typeInfoFunction; + private final Set typeInfoFunction; private JetStandardLibrary(@NotNull Project project) { // TODO : review @@ -120,10 +120,9 @@ public class JetStandardLibrary { this.stringClass = (ClassDescriptor) libraryScope.getClassifier("String"); this.arrayClass = (ClassDescriptor) libraryScope.getClassifier("Array"); this.iterableClass = (ClassDescriptor) libraryScope.getClassifier("Iterable"); - this.tuple0Class = (ClassDescriptor) libraryScope.getClassifier("Tuple0"); typeInfoNamespace = libraryScope.getNamespace("typeinfo"); this.typeInfoClass = (ClassDescriptor) typeInfoNamespace.getMemberScope().getClassifier("TypeInfo"); - typeInfoFunction = typeInfoNamespace.getMemberScope().getFunctionGroup("typeinfo"); + typeInfoFunction = typeInfoNamespace.getMemberScope().getFunctions("typeinfo"); this.byteType = new JetTypeImpl(getByte()); this.charType = new JetTypeImpl(getChar()); @@ -134,7 +133,7 @@ public class JetStandardLibrary { this.doubleType = new JetTypeImpl(getDouble()); this.booleanType = new JetTypeImpl(getBoolean()); this.stringType = new JetTypeImpl(getString()); - this.tuple0Type = new JetTypeImpl(getTuple0()); + this.tuple0Type = new JetTypeImpl(JetStandardClasses.getTuple(0)); this.nullableByteType = TypeUtils.makeNullable(byteType); this.nullableCharType = TypeUtils.makeNullable(charType); @@ -210,10 +209,6 @@ public class JetStandardLibrary { return iterableClass; } - public ClassDescriptor getTuple0() { - return tuple0Class; - } - public NamespaceDescriptor getTypeInfoNamespace() { return typeInfoNamespace; } @@ -222,7 +217,7 @@ public class JetStandardLibrary { return typeInfoClass; } - public FunctionGroup getTypeInfoFunctionGroup() { + public Set getTypeInfoFunctions() { return typeInfoFunction; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index b0d8058f0d7..7da4d79b325 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -875,30 +875,27 @@ public class JetTypeInferrer { @Override public JetType visitObjectLiteralExpression(final JetObjectLiteralExpression expression, final TypeInferenceContext context) { final JetType[] result = new JetType[1]; - BindingTraceAdapter.RecordHandler handler = new BindingTraceAdapter.RecordHandler() { + BindingTraceAdapter.RecordHandler handler = new BindingTraceAdapter.RecordHandler() { @Override - public void handleRecord(WritableSlice slice, PsiElement declaration, final DeclarationDescriptor descriptor) { - if (declaration == expression.getObjectDeclaration()) { + public void handleRecord(WritableSlice slice, PsiElement declaration, final ClassDescriptor descriptor) { + if (slice == CLASS && declaration == expression.getObjectDeclaration()) { JetType defaultType = new DeferredType(new LazyValue() { @Override protected JetType compute() { - return ((ClassDescriptor) descriptor).getDefaultType(); + return descriptor.getDefaultType(); } }); result[0] = defaultType; - if (!context.trace.get(BindingContext.PROCESSED, expression)) { - context.trace.record(BindingContext.EXPRESSION_TYPE, expression, defaultType); - context.trace.record(BindingContext.PROCESSED, expression); + if (!context.trace.get(PROCESSED, expression)) { + context.trace.record(EXPRESSION_TYPE, expression, defaultType); + context.trace.record(PROCESSED, expression); } } } }; BindingTraceAdapter traceAdapter = new BindingTraceAdapter(context.trace); - for (WritableSlice slice : BindingContext.DECLARATIONS_TO_DESCRIPTORS) { - //noinspection unchecked - traceAdapter.addHandler(slice, handler); - } + traceAdapter.addHandler(CLASS, handler); TopDownAnalyzer.processObject(semanticServices, traceAdapter, context.scope, context.scope.getContainingDeclaration(), expression.getObjectDeclaration()); return context.services.checkType(result[0], expression, context); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeProjection.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeProjection.java index d401d388834..f85c20a6e2d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeProjection.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeProjection.java @@ -31,7 +31,7 @@ public class TypeProjection { @Override public String toString() { if (projection == Variance.INVARIANT) { - return type + ""; + return type.toString(); } return projection + " " + type; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java index ca595ac72cf..5d5cd433cc5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java @@ -237,7 +237,7 @@ public class TypeUtils { @NotNull public static Multimap buildDeepSubstitutionMultimap(@NotNull JetType type) { - Multimap fullSubstitution = Multimaps.newSetMultimap(Maps.>newHashMap(), CommonSuppliers.getLinkedHashSetSupplier()); + Multimap fullSubstitution = CommonSuppliers.newLinkedHashSetHashSetMultimap(); Map substitution = Maps.newHashMap(); TypeSubstitutor typeSubstitutor = TypeSubstitutor.create(substitution); // we use the mutability of the map here diff --git a/compiler/frontend/src/org/jetbrains/jet/util/CommonSuppliers.java b/compiler/frontend/src/org/jetbrains/jet/util/CommonSuppliers.java index b596e476a44..d467debb201 100644 --- a/compiler/frontend/src/org/jetbrains/jet/util/CommonSuppliers.java +++ b/compiler/frontend/src/org/jetbrains/jet/util/CommonSuppliers.java @@ -1,9 +1,9 @@ package org.jetbrains.jet.util; import com.google.common.base.Supplier; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; +import com.google.common.collect.*; +import java.util.Collection; import java.util.List; import java.util.Set; @@ -36,4 +36,8 @@ public class CommonSuppliers { //noinspection unchecked return (Supplier>) LINKED_HASH_SET_SUPPLIER; } + + public static SetMultimap newLinkedHashSetHashSetMultimap() { + return Multimaps.newSetMultimap(Maps.>newHashMap(), CommonSuppliers.getLinkedHashSetSupplier()); + } } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java index 79b4184183b..be85717c4b2 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java @@ -13,7 +13,6 @@ import org.jetbrains.jet.lexer.JetToken; import org.jetbrains.jet.lexer.JetTokens; import java.util.Collection; -import java.util.Set; /** * @author svtk @@ -71,7 +70,7 @@ public class QuickFixes { add(Errors.NON_MEMBER_FUNCTION_NO_BODY, addFunctionBodyFactory); add(Errors.NOTHING_TO_OVERRIDE, RemoveModifierFix.createFactory(JetTokens.OVERRIDE_KEYWORD)); - add(Errors.VIRTUAL_METHOD_HIDDEN, AddModifierFix.createFactory(JetTokens.OVERRIDE_KEYWORD)); + add(Errors.VIRTUAL_MEMBER_HIDDEN, AddModifierFix.createFactory(JetTokens.OVERRIDE_KEYWORD)); add(Errors.VAL_WITH_SETTER, ChangeVariableMutabilityFix.createFactory()); diff --git a/idea/testData/checkerWithErrorTypes/full/Override.jet b/idea/testData/checkerWithErrorTypes/quick/Override.jet similarity index 93% rename from idea/testData/checkerWithErrorTypes/full/Override.jet rename to idea/testData/checkerWithErrorTypes/quick/Override.jet index fecb1c72304..4bc46e47790 100644 --- a/idea/testData/checkerWithErrorTypes/full/Override.jet +++ b/idea/testData/checkerWithErrorTypes/quick/Override.jet @@ -27,12 +27,12 @@ namespace normal { } class MyIllegalClass4 : MyTrait, MyAbstractClass { - fun foo() {} + fun foo() {} override fun other() {} } class MyChildClass1 : MyClass { - fun foo() {} + fun foo() {} override fun bar() {} } } @@ -54,7 +54,7 @@ namespace generics { class MyChildClass : MyGenericClass {} class MyChildClass1 : MyGenericClass {} class MyChildClass2 : MyGenericClass { - fun foo(t: T) = t + fun foo(t: T) = t override fun bar(t: T) = t } diff --git a/idea/testData/codegen/traits/stdlib.jet b/idea/testData/codegen/traits/stdlib.jet new file mode 100644 index 00000000000..7be1c38af9c --- /dev/null +++ b/idea/testData/codegen/traits/stdlib.jet @@ -0,0 +1,44 @@ +trait ISized { + val size : Int +} + +trait ReadOnlyArray : ISized, Iterable { + fun get(index : Int) : T + + override fun iterator () : Iterator = object : Iterator { + private var index = 0 + + override fun hasNext() : Boolean = index < size + + val next : T + get() = get(index++) + } +} + +trait WriteOnlyArray : ISized { + fun set(index : Int, value : T) : Unit + + fun set(from: Int, count: Int, value: T) { + for(i in 0..(count-1)) { + set(i, value) + } + } +} + +class MutableArray(length: Int) : ReadOnlyArray, WriteOnlyArray { + private val array = Array(length) + + override fun get(index : Int) : T = array[index] + override fun set(index : Int, value : T) : Unit { array[index] = value } + + override val size : Int + get() = array.size +} + +fun box() : String { + var a = MutableArray (4) + a [0] = 10 + a.set(1, 2, 13) + a [3] = 40 + return "OK" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/codegen/TraitsTest.java b/idea/tests/org/jetbrains/jet/codegen/TraitsTest.java index 8ed803135fb..07acb80f120 100644 --- a/idea/tests/org/jetbrains/jet/codegen/TraitsTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/TraitsTest.java @@ -20,4 +20,9 @@ public class TraitsTest extends CodegenTestCase { blackBoxFile("traits/multiple.jet"); System.out.println(generateToText()); } + + public void testStdlib () throws Exception { + blackBoxFile("traits/stdlib.jet"); + System.out.println(generateToText()); + } } diff --git a/idea/tests/org/jetbrains/jet/types/JetOverridingTest.java b/idea/tests/org/jetbrains/jet/types/JetOverridingTest.java index d34a474936a..158958e0101 100644 --- a/idea/tests/org/jetbrains/jet/types/JetOverridingTest.java +++ b/idea/tests/org/jetbrains/jet/types/JetOverridingTest.java @@ -70,7 +70,7 @@ public class JetOverridingTest extends LightDaemonAnalyzerTestCase { "fun ab() : Int", "fun a() : Int"); - assertNotOverridable( + assertOverridable( "fun a() : Int", "fun a() : Any"); @@ -98,7 +98,7 @@ public class JetOverridingTest extends LightDaemonAnalyzerTestCase { "fun a(a : T1) : T1", "fun a(a : Y) : T"); - assertNotOverridable( + assertOverridable( "fun a(a : T1) : X", "fun a(a : T) : T"); diff --git a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java index c5eee12fc5d..1903d2b13f1 100644 --- a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java +++ b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java @@ -610,18 +610,13 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase { @NotNull @Override - public FunctionGroup getFunctionGroup(@NotNull String name) { - WritableFunctionGroup writableFunctionGroup = new WritableFunctionGroup(name); -// ClassifierDescriptor classifier = getClassifier(name); -// if (classifier instanceof ClassDescriptor) { -// ClassDescriptor classDescriptor = (ClassDescriptor) classifier; -// writableFunctionGroup.addAllFunctions(classDescriptor.getConstructors()); -// } + public Set getFunctions(@NotNull String name) { + Set writableFunctionGroup = Sets.newLinkedHashSet(); ModuleDescriptor module = new ModuleDescriptor("TypeCheckerTest"); for (String funDecl : FUNCTION_DECLARATIONS) { FunctionDescriptor functionDescriptor = classDescriptorResolver.resolveFunctionDescriptor(module, this, JetPsiFactory.createFunction(getProject(), funDecl)); if (name.equals(functionDescriptor.getName())) { - writableFunctionGroup.addFunction(functionDescriptor); + writableFunctionGroup.add(functionDescriptor); } } return writableFunctionGroup; @@ -690,7 +685,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase { }); } - WritableFunctionGroup constructors = new WritableFunctionGroup(""); + Set constructors = Sets.newLinkedHashSet(); classDescriptor.initialize( !open, typeParameters, @@ -702,12 +697,12 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase { for (JetConstructor constructor : classElement.getSecondaryConstructors()) { ConstructorDescriptorImpl functionDescriptor = classDescriptorResolver.resolveSecondaryConstructorDescriptor(memberDeclarations, classDescriptor, constructor); functionDescriptor.setReturnType(classDescriptor.getDefaultType()); - constructors.addFunction(functionDescriptor); + constructors.add(functionDescriptor); } ConstructorDescriptorImpl primaryConstructorDescriptor = classDescriptorResolver.resolvePrimaryConstructorDescriptor(scope, classDescriptor, classElement); if (primaryConstructorDescriptor != null) { primaryConstructorDescriptor.setReturnType(classDescriptor.getDefaultType()); - constructors.addFunction(primaryConstructorDescriptor); + constructors.add(primaryConstructorDescriptor); classDescriptor.setPrimaryConstructor(primaryConstructorDescriptor); } return classDescriptor; diff --git a/stdlib/src/jet/typeinfo/TypeInfo.java b/stdlib/src/jet/typeinfo/TypeInfo.java index 8fd2391567b..e4a971e90fe 100644 --- a/stdlib/src/jet/typeinfo/TypeInfo.java +++ b/stdlib/src/jet/typeinfo/TypeInfo.java @@ -1,6 +1,5 @@ package jet.typeinfo; -import com.sun.org.apache.bcel.internal.generic.MethodGen; import jet.JetObject; import jet.Tuple0; @@ -92,7 +91,7 @@ public abstract class TypeInfo implements JetObject { nullable = false; } - public TypeInfoVar(boolean nullable, Integer varIndex) { + public TypeInfoVar(boolean nullable, int varIndex) { this.nullable = nullable; this.varIndex = varIndex; } @@ -474,11 +473,12 @@ public abstract class TypeInfo implements JetObject { public List parseVars() { List list = null; - while(cur != string.length && string[cur] == 'T') { + while(cur < string.length && string[cur] == 'T') { if(list == null) { list = new LinkedList(); variables = new HashMap(); } + cur++; list.add(parseVar()); } return list == null ? Collections.emptyList() : list; @@ -508,7 +508,7 @@ public abstract class TypeInfo implements JetObject { } private String parseName() { - int c = ++cur; // skip 'T' + int c = cur; while (string[c] != ';') { c++; } @@ -522,7 +522,7 @@ public abstract class TypeInfo implements JetObject { cur += 3; return TypeInfoVariance.IN_VARIANCE; } - else if (string[cur] == 'o' && string[cur+1] == 'u' && string[cur+2] == 't' && string[cur+2] == ' ') { + else if (string[cur] == 'o' && string[cur+1] == 'u' && string[cur+2] == 't' && string[cur+3] == ' ') { cur += 4; return TypeInfoVariance.OUT_VARIANCE; } @@ -545,6 +545,7 @@ public abstract class TypeInfo implements JetObject { private TypeInfo parseType() { switch (string[cur]) { case 'L': + cur++; String name = parseName(); Class aClass; try { @@ -572,6 +573,7 @@ public abstract class TypeInfo implements JetObject { return new TypeInfoImpl(aClass, nullable,proj.toArray(new TypeInfoProjection[proj.size()])); case 'T': + cur++; return parseTypeVar(); default: @@ -580,6 +582,7 @@ public abstract class TypeInfo implements JetObject { } private TypeInfo parseTypeVar() { + TypeInfoVariance variance = parseVariance(); String name = parseName(); boolean nullable = false; if(string[cur] == '?') {