Merge branch 'master' of ssh://git.labs.intellij.net/jet

This commit is contained in:
svtk
2011-09-24 21:36:58 +04:00
50 changed files with 485 additions and 581 deletions
@@ -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());
}
}
@@ -721,7 +721,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
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<StackValue, StackValue> {
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;");
@@ -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<? extends FunctionDescriptor> 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<? extends FunctionDescriptor> 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();
}
}
@@ -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<FunctionDescriptor> set = new HashSet<FunctionDescriptor>();
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<FunctionDescriptor> 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;
}
@@ -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<Type> parameterTypes = new ArrayList<Type>();
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) {
@@ -1,8 +0,0 @@
package org.jetbrains.jet.codegen;
/**
* @author max
*/
public class MethodCodeGen {
}
@@ -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) {
@@ -51,7 +51,7 @@ public class IntrinsicMethods {
declareIntrinsicFunction(type, "dec", 0, DEC);
}
final FunctionGroup typeInfoFunctionGroup = stdlib.getTypeInfoFunctionGroup();
final Set<FunctionDescriptor> 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<FunctionDescriptor> 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<FunctionDescriptor> group, int arity, IntrinsicMethod implementation) {
for (FunctionDescriptor descriptor : group) {
if (descriptor.getValueParameters().size() == arity) {
myMethods.put(descriptor.getOriginal(), implementation);
}
@@ -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("<init>");
private final Set<FunctionDescriptor> 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<TypeProjection> 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<FunctionDescriptor> getConstructors() {
return constructors;
}
@@ -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<String, FunctionGroup> functionGroups = Maps.newHashMap();
private final Map<String, Set<FunctionDescriptor>> functionGroups = Maps.newHashMap();
private final Map<String, VariableDescriptor> variables = Maps.newHashMap();
private final Map<String, ClassifierDescriptor> classifiers = Maps.newHashMap();
private Collection<DeclarationDescriptor> 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<FunctionDescriptor> getFunctions(@NotNull String name) {
Set<FunctionDescriptor> functionGroup = functionGroups.get(name);
if (functionGroup == null) {
functionGroup = semanticServices.getDescriptorResolver().resolveFunctionGroup(
containingDeclaration,
@@ -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<FunctionDescriptor> resolveFunctionGroup(@NotNull DeclarationDescriptor owner, @NotNull PsiClass psiClass, @Nullable ClassDescriptor classDescriptor, @NotNull String methodName, boolean staticMembers) {
Set<FunctionDescriptor> writableFunctionGroup = Sets.newLinkedHashSet();
final Collection<HierarchicalMethodSignature> 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;
@@ -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<FunctionDescriptor> getFunctions(@NotNull String name) {
return Collections.emptySet();
}
@NotNull
@@ -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<? extends CallableMemberDescriptor> getOverriddenDescriptors();
}
@@ -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<FunctionDescriptor> getConstructors();
@Nullable
ConstructorDescriptor getUnsubstitutedPrimaryConstructor();
@@ -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<FunctionDescriptor> constructors;
private ConstructorDescriptor primaryConstructor;
private JetType superclassType;
private ReceiverDescriptor implicitReceiver;
@@ -36,7 +37,7 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
@NotNull List<TypeParameterDescriptor> typeParameters,
@NotNull Collection<JetType> supertypes,
@NotNull JetScope memberDeclarations,
@NotNull FunctionGroup constructors,
@NotNull Set<FunctionDescriptor> 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<TypeParameterDescriptor> typeParameters,
@NotNull Collection<JetType> supertypes,
@NotNull JetScope memberDeclarations,
@NotNull FunctionGroup constructors,
@NotNull Set<FunctionDescriptor> 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<TypeConstructor, TypeProjection> substitutionContext = TypeUtils.buildSubstitutionContext(getTypeConstructor().getParameters(), typeArguments);
return constructors;// LazySubstitutingFunctionGroup(TypeSubstitutor.create(substitutionContext), constructors);
public Set<FunctionDescriptor> getConstructors() {
return constructors;
}
@NotNull
@@ -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();
@@ -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 "<empty>";
}
@Override
public boolean isEmpty() {
return true;
}
@NotNull
@Override
public Set<FunctionDescriptor> getFunctionDescriptors() {
return Collections.emptySet();
}
@Override
public String toString() {
return "EMPTY";
}
};
@NotNull
@Override
String getName();
boolean isEmpty();
@NotNull
Set<FunctionDescriptor> getFunctionDescriptors();
}
@@ -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<FunctionDescriptor> getConstructors() {
throw new UnsupportedOperationException(); // TODO
}
@@ -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<FunctionDescriptor> 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<FunctionDescriptor> getFunctionDescriptors() {
if (functionDescriptors == null) {
if (substitutor.isEmpty()) {
functionDescriptors = functionGroup.getFunctionDescriptors();
}
else {
Set<FunctionDescriptor> 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;
}
}
@@ -22,7 +22,7 @@ import java.util.*;
*/
public class MutableClassDescriptor extends MutableDeclarationDescriptor implements ClassDescriptor, NamespaceLike {
private ConstructorDescriptor primaryConstructor;
private final WritableFunctionGroup constructors = new WritableFunctionGroup("<init>");
private final Set<FunctionDescriptor> constructors = Sets.newLinkedHashSet();
private final Set<FunctionDescriptor> functions = Sets.newHashSet();
private final Set<PropertyDescriptor> properties = Sets.newHashSet();
private List<TypeParameterDescriptor> 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<TypeConstructor, TypeProjection> substitutionContext = TypeUtils.buildSubstitutionContext(getTypeConstructor().getParameters(), typeArguments);
// return new LazySubstitutingFunctionGroup(TypeSubstitutor.create(substitutionContext), constructors);
public Set<FunctionDescriptor> getConstructors() {
return constructors;
}
@@ -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<? extends CallableDescriptor> getOverriddenDescriptors() {
public Set<? extends PropertyDescriptor> getOverriddenDescriptors() {
return overriddenProperties;
}
}
@@ -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<FunctionDescriptor> functionDescriptors;
private Set<FunctionDescriptor> 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<FunctionDescriptor> getFunctionDescriptors() {
if (unmodifiableFunctionDescriptors == null) {
unmodifiableFunctionDescriptors = Collections.unmodifiableSet(getWritableFunctionDescriptors());
}
return unmodifiableFunctionDescriptors;
}
private Set<FunctionDescriptor> 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());
}
}
@@ -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<JetFunction, FunctionDescriptor> NOTHING_TO_OVERRIDE = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Function {0} overrides nothing");
PsiElementOnlyDiagnosticFactory1<JetModifierListOwner, CallableMemberDescriptor> NOTHING_TO_OVERRIDE = PsiElementOnlyDiagnosticFactory1.create(ERROR, "{0} overrides nothing");
ParameterizedDiagnosticFactory1<PropertyDescriptor> PRIMARY_CONSTRUCTOR_MISSING_STATEFUL_PROPERTY = ParameterizedDiagnosticFactory1.create(ERROR, "This class must have a primary constructor, because property {0} has a backing field");
ParameterizedDiagnosticFactory1<JetClassOrObject> PRIMARY_CONSTRUCTOR_MISSING_SUPER_CONSTRUCTOR_CALL = new ParameterizedDiagnosticFactory1<JetClassOrObject>(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<JetFunction, FunctionDescriptor, FunctionDescriptor, DeclarationDescriptor> VIRTUAL_METHOD_HIDDEN = PsiElementOnlyDiagnosticFactory3.create(ERROR, "Function ''{0}'' hides ''{1}'' in class {2} and needs 'override' modifier");
PsiElementOnlyDiagnosticFactory3<JetModifierListOwner, CallableMemberDescriptor, CallableMemberDescriptor, DeclarationDescriptor> 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<String> 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<FunctionDescriptor, DeclarationDescriptor> OVERRIDING_FINAL_FUNCTION = new ParameterizedDiagnosticFactory2<FunctionDescriptor, DeclarationDescriptor>(ERROR, "Method {0} in {1} is final and cannot be overridden") {
ParameterizedDiagnosticFactory2<CallableMemberDescriptor, DeclarationDescriptor> OVERRIDING_FINAL_MEMBER = new ParameterizedDiagnosticFactory2<CallableMemberDescriptor, DeclarationDescriptor>(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();
}
@@ -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<FunctionDescriptor> getFunctions(@NotNull String name) {
return getWorkerScope().getFunctions(name);
}
@Override
@@ -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()));
}
@@ -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<FunctionDescriptor> 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<FunctionDescriptor> inheritedFunctions = Sets.newLinkedHashSet();
Set<PropertyDescriptor> inheritedProperties = Sets.newLinkedHashSet();
// Everything from supertypes
Set<CallableMemberDescriptor> 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<CallableMemberDescriptor> filteredMembers = OverridingUtil.filterOverrides(inheritedFunctions);
// Group members with "the same" signature
Multimap<CallableMemberDescriptor, CallableMemberDescriptor> 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<CallableMemberDescriptor> mustBeOverridden = Sets.newLinkedHashSet();
for (CallableMemberDescriptor key : factoredMembers.keySet()) {
Collection<CallableMemberDescriptor> 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<CallableDescriptor> 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<? extends CallableDescriptor> inheritedProperties) {
private void println(Collection<? extends CallableDescriptor> 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()));
}
}
}
@@ -18,6 +18,9 @@ import java.util.Set;
*/
public class OverridingUtil {
private OverridingUtil() {
}
public static Set<CallableDescriptor> getEffectiveMembers(@NotNull ClassDescriptor classDescriptor) {
Collection<DeclarationDescriptor> allDescriptors = classDescriptor.getDefaultType().getMemberScope().getAllDescriptors();
Set<CallableDescriptor> allMembers = Sets.newLinkedHashSet();
@@ -99,14 +102,10 @@ public class OverridingUtil {
List<TypeParameterDescriptor> superTypeParameters = superDescriptor.getTypeParameters();
List<TypeParameterDescriptor> subTypeParameters = subDescriptor.getTypeParameters();
Map<TypeConstructor, TypeProjection> substitutionContext = Maps.newHashMap();
BiMap<TypeConstructor, TypeConstructor> 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<TypeParameterDescriptor> superTypeParameters = superDescriptor.getTypeParameters();
List<TypeParameterDescriptor> subTypeParameters = subDescriptor.getTypeParameters();
Map<TypeConstructor, TypeProjection> 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;
@@ -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.<AnnotationDescriptor>emptyList(), true);
constructorDescriptor.initialize(Collections.<TypeParameterDescriptor>emptyList(), Collections.<ValueParameterDescriptor>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<JetClassOrObject, MutableClassDescriptor> map, NamespaceLike owner, JetScope outerScope, MutableClassDescriptor mutableClassDescriptor) {
@@ -138,7 +138,7 @@ public class CallResolver {
DeclarationDescriptor declarationDescriptor = constructedType.getConstructor().getDeclarationDescriptor();
if (declarationDescriptor instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor;
Set<FunctionDescriptor> constructors = classDescriptor.getConstructors().getFunctionDescriptors();
Set<FunctionDescriptor> 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<FunctionDescriptor> constructors = classDescriptor.getConstructors().getFunctionDescriptors();
Set<FunctionDescriptor> 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<FunctionDescriptor> findCandidatesByExactSignature(JetScope scope, ReceiverDescriptor receiver, String name, List<JetType> parameterTypes) {
List<FunctionDescriptor> result = Lists.newArrayList();
if (receiver != NO_RECEIVER) {
Set<FunctionDescriptor> extensionFunctionDescriptors = scope.getFunctionGroup(name).getFunctionDescriptors();
Set<FunctionDescriptor> extensionFunctionDescriptors = scope.getFunctions(name);
List<FunctionDescriptor> nonlocal = Lists.newArrayList();
List<FunctionDescriptor> local = Lists.newArrayList();
TaskPrioritizer.splitLexicallyLocalDescriptors(extensionFunctionDescriptors, scope.getContainingDeclaration(), local, nonlocal);
@@ -640,7 +640,7 @@ public class CallResolver {
return result;
}
Set<FunctionDescriptor> functionDescriptors = receiver.getType().getMemberScope().getFunctionGroup(name).getFunctionDescriptors();
Set<FunctionDescriptor> 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<FunctionDescriptor> getNonExtensionsByName(JetScope scope, String name) {
Set<FunctionDescriptor> functions = Sets.newLinkedHashSet(scope.getFunctionGroup(name).getFunctionDescriptors());
Set<FunctionDescriptor> functions = Sets.newLinkedHashSet(scope.getFunctions(name));
for (Iterator<FunctionDescriptor> iterator = functions.iterator(); iterator.hasNext(); ) {
FunctionDescriptor functionDescriptor = iterator.next();
if (functionDescriptor.getReceiver() != NO_RECEIVER) {
@@ -713,7 +713,7 @@ public class CallResolver {
@Override
protected Collection<FunctionDescriptor> getMembersByName(@NotNull ReceiverDescriptor receiver, String name) {
JetScope receiverScope = receiver.getType().getMemberScope();
Set<FunctionDescriptor> members = Sets.newHashSet(receiverScope.getFunctionGroup(name).getFunctionDescriptors());
Set<FunctionDescriptor> 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<FunctionDescriptor> getExtensionsByName(JetScope scope, String name) {
Set<FunctionDescriptor> extensionFunctions = Sets.newHashSet(scope.getFunctionGroup(name).getFunctionDescriptors());
Set<FunctionDescriptor> extensionFunctions = Sets.newHashSet(scope.getFunctions(name));
for (Iterator<FunctionDescriptor> 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());
}
}
@@ -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<FunctionDescriptor> getFunctions(@NotNull String name) {
if (scopeChain.length == 0) {
return FunctionGroup.EMPTY;
return Collections.emptySet();
}
WritableFunctionGroup result = new WritableFunctionGroup(name);
Set<FunctionDescriptor> result = Sets.newLinkedHashSet();
for (JetScope jetScope : scopeChain) {
result.addAllFunctions(jetScope.getFunctionGroup(name));
result.addAll(jetScope.getFunctions(name));
}
return result;
}
@@ -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<FunctionDescriptor> getFunctions(@NotNull String name);
@NotNull
DeclarationDescriptor getContainingDeclaration();
@@ -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<FunctionDescriptor> getFunctions(@NotNull String name) {
return Collections.emptySet();
}
@NotNull
@@ -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<String, FunctionGroup> functionGroups = null;
private Map<DeclarationDescriptor, DeclarationDescriptor> substitutedDescriptors = null;
private Collection<DeclarationDescriptor> 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 extends DeclarationDescriptor> 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 <D extends DeclarationDescriptor> Set<D> substitute(@NotNull Set<D> descriptors) {
if (substitutor.isEmpty()) return descriptors;
if (descriptors.isEmpty()) return descriptors;
Set<D> 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<FunctionDescriptor> 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);
}
@@ -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<String, PropertyDescriptor> propertyDescriptorsByFieldNames;
@Nullable
private Map<String, WritableFunctionGroup> functionGroups;
private SetMultimap<String, FunctionDescriptor> functionGroups;
@Nullable
private Map<String, DeclarationDescriptor> 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<String, WritableFunctionGroup> getFunctionGroups() {
private SetMultimap<String, FunctionDescriptor> getFunctionGroups() {
if (functionGroups == null) {
functionGroups = new HashMap<String, WritableFunctionGroup>();
functionGroups = CommonSuppliers.newLinkedHashSetHashSetMultimap();
}
return functionGroups;
}
@Override
public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) {
String name = functionDescriptor.getName();
Map<String, WritableFunctionGroup> 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<FunctionDescriptor> getFunctions(@NotNull String name) {
Set<FunctionDescriptor> 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;
}
@@ -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<FunctionDescriptor> getFunctions(@NotNull String name) {
if (getImports().isEmpty()) {
return FunctionGroup.EMPTY;
return Collections.emptySet();
}
WritableFunctionGroup result = new WritableFunctionGroup(name);
Set<FunctionDescriptor> 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;
}
@@ -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<FunctionDescriptor> getFunctions(@NotNull String name) {
Set<FunctionDescriptor> 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;
}
@@ -43,7 +43,7 @@ public class ErrorUtils {
@NotNull
@Override
public FunctionGroup getFunctionGroup(@NotNull String name) {
public Set<FunctionDescriptor> 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 "<ERROR FUNCTION>";
}
@Override
public boolean isEmpty() {
return false;
}
@NotNull
@Override
public Set<FunctionDescriptor> getFunctionDescriptors() {
return Collections.singleton(createErrorFunction(0, Collections.<JetType>emptyList()));
}
};
private static final ClassDescriptorImpl ERROR_CLASS = new ClassDescriptorImpl(ERROR_MODULE, Collections.<AnnotationDescriptor>emptyList(), "<ERROR CLASS>") {
@NotNull
@Override
public FunctionGroup getConstructors() {
public Set<FunctionDescriptor> getConstructors() {
return ERROR_FUNCTION_GROUP;
}
};
private static final Set<FunctionDescriptor> ERROR_FUNCTION_GROUP = Collections.singleton(createErrorFunction(0, Collections.<JetType>emptyList()));
private static final ConstructorDescriptor ERROR_CONSTRUCTOR = new ConstructorDescriptorImpl(ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), true);
static {
ERROR_CLASS.initialize(
true, Collections.<TypeParameterDescriptor>emptyList(), Collections.<JetType>emptyList(), getErrorScope(), ERROR_FUNCTION_GROUP, ERROR_CONSTRUCTOR);
@@ -48,7 +48,7 @@ public class JetStandardClasses {
}
},
JetScope.EMPTY,
FunctionGroup.EMPTY,
Collections.<FunctionDescriptor>emptySet(),
null,
null
);
@@ -71,7 +71,7 @@ public class JetStandardClasses {
Collections.<TypeParameterDescriptor>emptyList(),
Collections.<JetType>emptySet(),
JetScope.EMPTY,
FunctionGroup.EMPTY,
Collections.<FunctionDescriptor>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.<FunctionDescriptor>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.<FunctionDescriptor>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.<FunctionDescriptor>emptySet(), null);
RECEIVER_FUNCTION_TYPE_CONSTRUCTORS.add(RECEIVER_FUNCTION[i].getTypeConstructor());
}
}
@@ -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<FunctionDescriptor> 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<FunctionDescriptor> getTypeInfoFunctions() {
return typeInfoFunction;
}
@@ -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<PsiElement, DeclarationDescriptor> handler = new BindingTraceAdapter.RecordHandler<PsiElement, DeclarationDescriptor>() {
BindingTraceAdapter.RecordHandler<PsiElement, ClassDescriptor> handler = new BindingTraceAdapter.RecordHandler<PsiElement, ClassDescriptor>() {
@Override
public void handleRecord(WritableSlice<PsiElement, DeclarationDescriptor> slice, PsiElement declaration, final DeclarationDescriptor descriptor) {
if (declaration == expression.getObjectDeclaration()) {
public void handleRecord(WritableSlice<PsiElement, ClassDescriptor> slice, PsiElement declaration, final ClassDescriptor descriptor) {
if (slice == CLASS && declaration == expression.getObjectDeclaration()) {
JetType defaultType = new DeferredType(new LazyValue<JetType>() {
@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);
}
@@ -31,7 +31,7 @@ public class TypeProjection {
@Override
public String toString() {
if (projection == Variance.INVARIANT) {
return type + "";
return type.toString();
}
return projection + " " + type;
}
@@ -237,7 +237,7 @@ public class TypeUtils {
@NotNull
public static Multimap<TypeConstructor, TypeProjection> buildDeepSubstitutionMultimap(@NotNull JetType type) {
Multimap<TypeConstructor, TypeProjection> fullSubstitution = Multimaps.newSetMultimap(Maps.<TypeConstructor, Collection<TypeProjection>>newHashMap(), CommonSuppliers.<TypeProjection>getLinkedHashSetSupplier());
Multimap<TypeConstructor, TypeProjection> fullSubstitution = CommonSuppliers.newLinkedHashSetHashSetMultimap();
Map<TypeConstructor, TypeProjection> substitution = Maps.newHashMap();
TypeSubstitutor typeSubstitutor = TypeSubstitutor.create(substitution);
// we use the mutability of the map here
@@ -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<Set<T>>) LINKED_HASH_SET_SUPPLIER;
}
public static <K, V> SetMultimap<K, V> newLinkedHashSetHashSetMultimap() {
return Multimaps.newSetMultimap(Maps.<K, Collection<V>>newHashMap(), CommonSuppliers.<V>getLinkedHashSetSupplier());
}
}
@@ -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());
@@ -27,12 +27,12 @@ namespace normal {
}
class <!ABSTRACT_METHOD_NOT_IMPLEMENTED!>MyIllegalClass4<!> : MyTrait, MyAbstractClass {
fun <!VIRTUAL_METHOD_HIDDEN!>foo<!>() {}
fun <!VIRTUAL_MEMBER_HIDDEN!>foo<!>() {}
<!NOTHING_TO_OVERRIDE!>override<!> fun other() {}
}
class MyChildClass1 : MyClass {
fun <!VIRTUAL_METHOD_HIDDEN!>foo<!>() {}
fun <!VIRTUAL_MEMBER_HIDDEN!>foo<!>() {}
override fun bar() {}
}
}
@@ -54,7 +54,7 @@ namespace generics {
class MyChildClass : MyGenericClass<Int> {}
class MyChildClass1<T> : MyGenericClass<T> {}
class MyChildClass2<T> : MyGenericClass<T> {
fun <!VIRTUAL_METHOD_HIDDEN!>foo<!>(t: T) = t
fun <!VIRTUAL_MEMBER_HIDDEN!>foo<!>(t: T) = t
override fun bar(t: T) = t
}
+44
View File
@@ -0,0 +1,44 @@
trait ISized {
val size : Int
}
trait ReadOnlyArray<out T> : ISized, Iterable<T> {
fun get(index : Int) : T
override fun iterator () : Iterator<T> = object : Iterator<T> {
private var index = 0
override fun hasNext() : Boolean = index < size
val next : T
get() = get(index++)
}
}
trait WriteOnlyArray<in T> : 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<T>(length: Int) : ReadOnlyArray<T>, WriteOnlyArray<T> {
private val array = Array<T>(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<Int> (4)
a [0] = 10
a.set(1, 2, 13)
a [3] = 40
return "OK"
}
@@ -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());
}
}
@@ -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<T1, X : T1>(a : T1) : T1",
"fun a<T, Y : T>(a : Y) : T");
assertNotOverridable(
assertOverridable(
"fun a<T1, X : T1>(a : T1) : X",
"fun a<T, Y : T>(a : T) : T");
@@ -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<FunctionDescriptor> getFunctions(@NotNull String name) {
Set<FunctionDescriptor> 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("<init>");
Set<FunctionDescriptor> 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;
+8 -5
View File
@@ -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<T> 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<T> implements JetObject {
public List<TypeInfoProjection> parseVars() {
List<TypeInfoProjection> list = null;
while(cur != string.length && string[cur] == 'T') {
while(cur < string.length && string[cur] == 'T') {
if(list == null) {
list = new LinkedList<TypeInfoProjection>();
variables = new HashMap<String, Integer>();
}
cur++;
list.add(parseVar());
}
return list == null ? Collections.<TypeInfoProjection>emptyList() : list;
@@ -508,7 +508,7 @@ public abstract class TypeInfo<T> 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<T> 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<T> 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<T> 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<T> implements JetObject {
}
private TypeInfo parseTypeVar() {
TypeInfoVariance variance = parseVariance();
String name = parseName();
boolean nullable = false;
if(string[cur] == '?') {