Merge branch 'master' of github.com:JetBrains/kotlin

This commit is contained in:
James Strachan
2012-04-19 09:52:11 +01:00
61 changed files with 468 additions and 202 deletions
@@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
@@ -118,7 +119,7 @@ public class ClosureAnnotator {
} }
public boolean hasThis0(ClassDescriptor classDescriptor) { public boolean hasThis0(ClassDescriptor classDescriptor) {
if(CodegenUtil.isClassObject(classDescriptor)) if(DescriptorUtils.isClassObject(classDescriptor))
return false; return false;
ClassDescriptor other = enclosing.get(classDescriptor); ClassDescriptor other = enclosing.get(classDescriptor);
@@ -42,21 +42,6 @@ public class CodegenUtil {
public static boolean isInterface(JetType type) { public static boolean isInterface(JetType type) {
return isInterface(type.getConstructor().getDeclarationDescriptor()); return isInterface(type.getConstructor().getDeclarationDescriptor());
} }
public static boolean isClassObject(DeclarationDescriptor descriptor) {
if(descriptor instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
if(classDescriptor.getKind() == ClassKind.OBJECT) {
if(classDescriptor.getContainingDeclaration() instanceof ClassDescriptor) {
ClassDescriptor containingDeclaration = (ClassDescriptor) classDescriptor.getContainingDeclaration();
if(classDescriptor.getDefaultType().equals(containingDeclaration.getClassObjectType())) {
return true;
}
}
}
}
return false;
}
public static SimpleFunctionDescriptor createInvoke(FunctionDescriptor fd) { public static SimpleFunctionDescriptor createInvoke(FunctionDescriptor fd) {
int arity = fd.getValueParameters().size(); int arity = fd.getValueParameters().size();
@@ -1021,7 +1021,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
final boolean directToField = expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL ; final boolean directToField = expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL ;
JetExpression r = getReceiverForSelector(expression); JetExpression r = getReceiverForSelector(expression);
final boolean isSuper = r instanceof JetSuperExpression; final boolean isSuper = r instanceof JetSuperExpression;
if(propertyDescriptor.getVisibility() == Visibilities.PRIVATE && !CodegenUtil.isClassObject(propertyDescriptor.getContainingDeclaration())) { if(propertyDescriptor.getVisibility() == Visibilities.PRIVATE && !DescriptorUtils
.isClassObject(propertyDescriptor.getContainingDeclaration())) {
if(context.getClassOrNamespaceDescriptor() != propertyDescriptor.getContainingDeclaration()) { if(context.getClassOrNamespaceDescriptor() != propertyDescriptor.getContainingDeclaration()) {
DeclarationDescriptor enclosed = propertyDescriptor.getContainingDeclaration(); DeclarationDescriptor enclosed = propertyDescriptor.getContainingDeclaration();
if(enclosed != null && enclosed != context.getThisDescriptor()) { if(enclosed != null && enclosed != context.getThisDescriptor()) {
@@ -1374,7 +1375,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
Type exprType = asmType(descriptor.getType()); Type exprType = asmType(descriptor.getType());
ClassReceiver classReceiver = (ClassReceiver) descriptor; ClassReceiver classReceiver = (ClassReceiver) descriptor;
ClassDescriptor classReceiverDeclarationDescriptor = (ClassDescriptor) classReceiver.getDeclarationDescriptor(); ClassDescriptor classReceiverDeclarationDescriptor = (ClassDescriptor) classReceiver.getDeclarationDescriptor();
if(CodegenUtil.isClassObject(classReceiverDeclarationDescriptor)) { if(DescriptorUtils.isClassObject(classReceiverDeclarationDescriptor)) {
ClassDescriptor containingDeclaration = (ClassDescriptor) classReceiverDeclarationDescriptor.getContainingDeclaration(); ClassDescriptor containingDeclaration = (ClassDescriptor) classReceiverDeclarationDescriptor.getContainingDeclaration();
Type classObjType = typeMapper.mapType(containingDeclaration.getDefaultType(), MapTypeMode.IMPL); Type classObjType = typeMapper.mapType(containingDeclaration.getDefaultType(), MapTypeMode.IMPL);
v.getstatic(classObjType.getInternalName(), "$classobj", exprType.getDescriptor()); v.getstatic(classObjType.getInternalName(), "$classobj", exprType.getDescriptor());
@@ -835,7 +835,7 @@ public class JetTypeMapper {
return ACC_PROTECTED; return ACC_PROTECTED;
} }
else if (p.getVisibility() == Visibilities.PRIVATE) { else if (p.getVisibility() == Visibilities.PRIVATE) {
if(CodegenUtil.isClassObject(declaration)) { if(DescriptorUtils.isClassObject(declaration)) {
return defaultFlags; return defaultFlags;
} }
return ACC_PRIVATE; return ACC_PRIVATE;
@@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
@@ -121,7 +122,7 @@ public class PropertyCodegen {
} }
private static boolean isExternallyAccessible(PropertyDescriptor p) { private static boolean isExternallyAccessible(PropertyDescriptor p) {
return p.getVisibility() != Visibilities.PRIVATE || CodegenUtil.isClassObject(p.getContainingDeclaration()); return p.getVisibility() != Visibilities.PRIVATE || DescriptorUtils.isClassObject(p.getContainingDeclaration());
} }
private void generateSetter(JetProperty p, PropertyDescriptor propertyDescriptor) { private void generateSetter(JetProperty p, PropertyDescriptor propertyDescriptor) {
@@ -1394,7 +1394,7 @@ public class JavaDescriptorResolver {
if (owner instanceof ClassDescriptor) { if (owner instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) owner; ClassDescriptor classDescriptor = (ClassDescriptor) owner;
OverrideResolver.generateOverridesInFunctionGroup(propertyName, propertiesFromSupertypes, propertiesFromCurrent, classDescriptor, new OverrideResolver.DescriptorSink() { OverrideResolver.generateOverridesInFunctionGroup(propertyName, null, propertiesFromSupertypes, propertiesFromCurrent, classDescriptor, new OverrideResolver.DescriptorSink() {
@Override @Override
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) { public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
properties.add((PropertyDescriptor) fakeOverride); properties.add((PropertyDescriptor) fakeOverride);
@@ -1433,7 +1433,7 @@ public class JavaDescriptorResolver {
Set<SimpleFunctionDescriptor> functionsFromSupertypes = getFunctionsFromSupertypes(scopeData, methodName); Set<SimpleFunctionDescriptor> functionsFromSupertypes = getFunctionsFromSupertypes(scopeData, methodName);
OverrideResolver.generateOverridesInFunctionGroup(methodName, functionsFromSupertypes, functionsFromCurrent, classDescriptor, new OverrideResolver.DescriptorSink() { OverrideResolver.generateOverridesInFunctionGroup(methodName, null, functionsFromSupertypes, functionsFromCurrent, classDescriptor, new OverrideResolver.DescriptorSink() {
@Override @Override
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) { public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
functions.add((FunctionDescriptor) fakeOverride); functions.add((FunctionDescriptor) fakeOverride);
@@ -106,6 +106,10 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorImpl i
return this; return this;
} }
public void setVisibility(@NotNull Visibility visibility) {
this.visibility = visibility;
}
public void setReturnType(@NotNull JetType unsubstitutedReturnType) { public void setReturnType(@NotNull JetType unsubstitutedReturnType) {
this.unsubstitutedReturnType = unsubstitutedReturnType; this.unsubstitutedReturnType = unsubstitutedReturnType;
} }
@@ -34,9 +34,9 @@ public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorIm
private final boolean hasBody; private final boolean hasBody;
private final boolean isDefault; private final boolean isDefault;
private final Modality modality; private final Modality modality;
private final Visibility visibility;
private final PropertyDescriptor correspondingProperty; private final PropertyDescriptor correspondingProperty;
private final Kind kind; private final Kind kind;
private Visibility visibility;
public PropertyAccessorDescriptor( public PropertyAccessorDescriptor(
@NotNull Modality modality, @NotNull Modality modality,
@@ -99,6 +99,10 @@ public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorIm
return visibility; return visibility;
} }
public void setVisibility(Visibility visibility) {
this.visibility = visibility;
}
@NotNull @NotNull
public PropertyDescriptor getCorrespondingProperty() { public PropertyDescriptor getCorrespondingProperty() {
return correspondingProperty; return correspondingProperty;
@@ -131,6 +131,10 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
this.setter = setter; this.setter = setter;
} }
public void setVisibility(@NotNull Visibility visibility) {
this.visibility = visibility;
}
@NotNull @NotNull
@Override @Override
public List<TypeParameterDescriptor> getTypeParameters() { public List<TypeParameterDescriptor> getTypeParameters() {
@@ -32,11 +32,14 @@ public class Visibilities {
public static final Visibility PRIVATE = new Visibility("private", false) { public static final Visibility PRIVATE = new Visibility("private", false) {
@Override @Override
protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
if (what instanceof CallableMemberDescriptor && ((CallableMemberDescriptor)what).getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
return false;
}
DeclarationDescriptor parent = what; DeclarationDescriptor parent = what;
while (parent != null) { while (parent != null) {
parent = parent.getContainingDeclaration(); parent = parent.getContainingDeclaration();
if ((parent instanceof ClassDescriptor && ((ClassDescriptor)parent).getKind() != ClassKind.OBJECT) || if ((parent instanceof ClassDescriptor && !DescriptorUtils.isClassObject(parent)) ||
parent instanceof NamespaceDescriptor) { parent instanceof NamespaceDescriptor) {
break; break;
} }
} }
@@ -93,7 +96,14 @@ public class Visibilities {
public static final Visibility LOCAL = new Visibility("local", false) { public static final Visibility LOCAL = new Visibility("local", false) {
@Override @Override
protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
return true; throw new IllegalStateException(); //This method shouldn't be invoked for LOCAL visibility
}
};
public static final Visibility INHERITED = new Visibility("inherited", false) {
@Override
protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
throw new IllegalStateException("Visibility is unknown yet"); //This method shouldn't be invoked for INHERITED visibility
} }
}; };
@@ -102,6 +112,9 @@ public class Visibilities {
public static boolean isVisible(DeclarationDescriptorWithVisibility what, DeclarationDescriptor from) { public static boolean isVisible(DeclarationDescriptorWithVisibility what, DeclarationDescriptor from) {
DeclarationDescriptorWithVisibility parent = what; DeclarationDescriptorWithVisibility parent = what;
while (parent != null) { while (parent != null) {
if (parent.getVisibility() == LOCAL) {
return true;
}
if (!parent.getVisibility().isVisible(parent, from)) { if (!parent.getVisibility().isVisible(parent, from)) {
return false; return false;
} }
@@ -157,7 +157,10 @@ public interface Errors {
DiagnosticFactory<JetDelegatorToSuperClass> INITIALIZER_WITH_NO_ARGUMENTS = DiagnosticFactory.create(ERROR, "Constructor arguments required"); DiagnosticFactory<JetDelegatorToSuperClass> INITIALIZER_WITH_NO_ARGUMENTS = DiagnosticFactory.create(ERROR, "Constructor arguments required");
DiagnosticFactory<JetDelegationSpecifier> MANY_CALLS_TO_THIS = DiagnosticFactory.create(ERROR, "Only one call to 'this(...)' is allowed"); DiagnosticFactory<JetDelegationSpecifier> MANY_CALLS_TO_THIS = DiagnosticFactory.create(ERROR, "Only one call to 'this(...)' is allowed");
DiagnosticFactory1<JetModifierListOwner, CallableMemberDescriptor> NOTHING_TO_OVERRIDE = DiagnosticFactory1.create(ERROR, "{0} overrides nothing", PositioningStrategies.positionModifier(JetTokens.OVERRIDE_KEYWORD), DescriptorRenderer.TEXT); DiagnosticFactory1<JetModifierListOwner, CallableMemberDescriptor> NOTHING_TO_OVERRIDE = DiagnosticFactory1.create(ERROR, "{0} overrides nothing", PositioningStrategies.positionModifier(JetTokens.OVERRIDE_KEYWORD), DescriptorRenderer.TEXT);
DiagnosticFactory3<PsiNameIdentifierOwner, CallableMemberDescriptor, CallableMemberDescriptor, DeclarationDescriptor> VIRTUAL_MEMBER_HIDDEN = DiagnosticFactory3.create(ERROR, "''{0}'' hides ''{1}'' in class {2} and needs 'override' modifier", PositioningStrategies.POSITION_NAME_IDENTIFIER, DescriptorRenderer.TEXT, DescriptorRenderer.TEXT, DescriptorRenderer.TEXT); DiagnosticFactory3<PsiNameIdentifierOwner, CallableMemberDescriptor, CallableMemberDescriptor, DeclarationDescriptor> VIRTUAL_MEMBER_HIDDEN =
DiagnosticFactory3.create(ERROR, "''{0}'' hides ''{1}'' in class {2} and needs 'override' modifier", PositioningStrategies.POSITION_NAME_IDENTIFIER, DescriptorRenderer.TEXT, DescriptorRenderer.TEXT, DescriptorRenderer.TEXT);
DiagnosticFactory3<JetModifierListOwner, CallableMemberDescriptor, CallableDescriptor, DeclarationDescriptor> CANNOT_OVERRIDE_INVISIBLE_MEMBER =
DiagnosticFactory3.create(ERROR, "''{0}'' cannot has no access to ''{1}'' in class {2}, so it cannot override it", PositioningStrategies.positionModifier(JetTokens.OVERRIDE_KEYWORD), DescriptorRenderer.TEXT, DescriptorRenderer.TEXT, DescriptorRenderer.TEXT);
DiagnosticFactory1<JetClass, ClassDescriptor> ENUM_ENTRY_SHOULD_BE_INITIALIZED = DiagnosticFactory1.create(ERROR, "Missing delegation specifier ''{0}''", PositioningStrategies.POSITION_NAME_IDENTIFIER, NAME); DiagnosticFactory1<JetClass, ClassDescriptor> ENUM_ENTRY_SHOULD_BE_INITIALIZED = DiagnosticFactory1.create(ERROR, "Missing delegation specifier ''{0}''", PositioningStrategies.POSITION_NAME_IDENTIFIER, NAME);
DiagnosticFactory1<JetTypeReference, ClassDescriptor> ENUM_ENTRY_ILLEGAL_TYPE = DiagnosticFactory1.create(ERROR, "The type constructor of enum entry should be ''{0}''", NAME); DiagnosticFactory1<JetTypeReference, ClassDescriptor> ENUM_ENTRY_ILLEGAL_TYPE = DiagnosticFactory1.create(ERROR, "The type constructor of enum entry should be ''{0}''", NAME);
@@ -223,7 +223,7 @@ public class DeclarationResolver {
parameter, trace parameter, trace
); );
classDescriptor.addPropertyDescriptor(propertyDescriptor); classDescriptor.addPropertyDescriptor(propertyDescriptor);
context.getPrimaryConstructorParameterProperties().add(propertyDescriptor); context.getPrimaryConstructorParameterProperties().put(parameter, propertyDescriptor);
} }
} }
if (constructorDescriptor != null) { if (constructorDescriptor != null) {
@@ -673,7 +673,8 @@ public class DescriptorResolver {
@NotNull @NotNull
/*package*/ static Visibility resolveVisibilityFromModifiers(@Nullable JetModifierList modifierList) { /*package*/ static Visibility resolveVisibilityFromModifiers(@Nullable JetModifierList modifierList) {
return resolveVisibilityFromModifiers(modifierList, Visibilities.INTERNAL); Visibility defaultVisibility = modifierList != null && modifierList.hasModifier(JetTokens.OVERRIDE_KEYWORD) ? Visibilities.INHERITED : Visibilities.INTERNAL;
return resolveVisibilityFromModifiers(modifierList, defaultVisibility);
} }
@NotNull @NotNull
@@ -314,4 +314,18 @@ public class DescriptorUtils {
return namespaceDescriptor.getContainingDeclaration() instanceof ModuleDescriptor; return namespaceDescriptor.getContainingDeclaration() instanceof ModuleDescriptor;
} }
public static boolean isClassObject(@NotNull DeclarationDescriptor descriptor) {
if(descriptor instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
if(classDescriptor.getKind() == ClassKind.OBJECT) {
if(classDescriptor.getContainingDeclaration() instanceof ClassDescriptor) {
ClassDescriptor containingDeclaration = (ClassDescriptor) classDescriptor.getContainingDeclaration();
if(classDescriptor.getDefaultType().equals(containingDeclaration.getClassObjectType())) {
return true;
}
}
}
}
return false;
}
} }
@@ -16,14 +16,13 @@
package org.jetbrains.jet.lang.resolve; package org.jetbrains.jet.lang.resolve;
import com.google.common.collect.Lists; import com.google.common.collect.*;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.intellij.lang.ASTNode; import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.util.containers.LinkedMultiMap; import com.intellij.util.containers.LinkedMultiMap;
import com.intellij.util.containers.MultiMap; import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
@@ -67,15 +66,26 @@ public class OverrideResolver {
public void process() { public void process() {
generateOverrides(); //all created fake descriptors are stored to resolve visibility on them later
checkOverrides(); Set<CallableMemberDescriptor> fakeOverrides = Sets.newHashSet();
checkVisibilityForOverriddenMembers(); generateOverrides(fakeOverrides);
//functions and properties visibility can be inherited when overriding, so for overridden members
//it can be resolved only after overrides resolve is finished
resolveUnknownVisibilityForMembers(fakeOverrides);
//invisible overridden descriptors are saved for proper error reporting
Multimap<CallableDescriptor, CallableDescriptor> invisibleOverriddenDescriptors = LinkedHashMultimap.create();
removeInvisibleOverriddenDescriptors(invisibleOverriddenDescriptors);
checkVisibility();
checkOverrides(invisibleOverriddenDescriptors);
} }
/** /**
* Generate fake overrides and add overriden descriptors to existing descriptors. * Generate fake overrides and add overridden descriptors to existing descriptors.
*/ */
private void generateOverrides() { private void generateOverrides(@NotNull Set<CallableMemberDescriptor> fakeOverrides) {
Set<MutableClassDescriptor> ourClasses = new HashSet<MutableClassDescriptor>(); Set<MutableClassDescriptor> ourClasses = new HashSet<MutableClassDescriptor>();
ourClasses.addAll(context.getClasses().values()); ourClasses.addAll(context.getClasses().values());
ourClasses.addAll(context.getObjects().values()); ourClasses.addAll(context.getObjects().values());
@@ -83,11 +93,12 @@ public class OverrideResolver {
Set<ClassifierDescriptor> processed = new HashSet<ClassifierDescriptor>(); Set<ClassifierDescriptor> processed = new HashSet<ClassifierDescriptor>();
for (MutableClassDescriptor clazz : ourClasses) { for (MutableClassDescriptor clazz : ourClasses) {
generateOverridesInAClass(clazz, processed, ourClasses); generateOverridesInAClass(clazz, processed, ourClasses, fakeOverrides);
} }
} }
private void generateOverridesInAClass(final MutableClassDescriptor classDescriptor, Set<ClassifierDescriptor> processed, Set<MutableClassDescriptor> ourClasses) { private void generateOverridesInAClass(@NotNull final MutableClassDescriptor classDescriptor, @NotNull Set<ClassifierDescriptor> processed,
@NotNull Set<MutableClassDescriptor> ourClasses, @NotNull Set<CallableMemberDescriptor> fakeOverrides) {
if (!processed.add(classDescriptor)) { if (!processed.add(classDescriptor)) {
return; return;
} }
@@ -100,7 +111,7 @@ public class OverrideResolver {
for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) { for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
ClassDescriptor superclass = (ClassDescriptor) supertype.getConstructor().getDeclarationDescriptor(); ClassDescriptor superclass = (ClassDescriptor) supertype.getConstructor().getDeclarationDescriptor();
if (superclass instanceof MutableClassDescriptor) { if (superclass instanceof MutableClassDescriptor) {
generateOverridesInAClass((MutableClassDescriptor) superclass, processed, ourClasses); generateOverridesInAClass((MutableClassDescriptor) superclass, processed, ourClasses, fakeOverrides);
} }
} }
@@ -115,7 +126,7 @@ public class OverrideResolver {
functionNames.addAll(functionsFromCurrentByName.keySet()); functionNames.addAll(functionsFromCurrentByName.keySet());
for (String functionName : functionNames) { for (String functionName : functionNames) {
generateOverridesInFunctionGroup(functionName, generateOverridesInFunctionGroup(functionName, fakeOverrides,
functionsFromSupertypesByName.get(functionName), functionsFromSupertypesByName.get(functionName),
functionsFromCurrentByName.get(functionName), functionsFromCurrentByName.get(functionName),
classDescriptor, classDescriptor,
@@ -150,18 +161,15 @@ public class OverrideResolver {
public static void generateOverridesInFunctionGroup( public static void generateOverridesInFunctionGroup(
@NotNull String name, @NotNull String name,
@Nullable Set<CallableMemberDescriptor> fakeOverrides,
@NotNull Collection<? extends CallableMemberDescriptor> functionsFromSupertypes, @NotNull Collection<? extends CallableMemberDescriptor> functionsFromSupertypes,
@NotNull Collection<? extends CallableMemberDescriptor> functionsFromCurrent, @NotNull Collection<? extends CallableMemberDescriptor> functionsFromCurrent,
@NotNull ClassDescriptor current, @NotNull ClassDescriptor current,
@NotNull DescriptorSink sink) { @NotNull DescriptorSink sink) {
List<CallableMemberDescriptor> fakeOverrides = Lists.newArrayList(); List<CallableMemberDescriptor> fakeOverrideList = Lists.newArrayList();
for (CallableMemberDescriptor functionFromSupertype : functionsFromSupertypes) { for (CallableMemberDescriptor functionFromSupertype : functionsFromSupertypes) {
if (!Visibilities.isVisible(functionFromSupertype, current)) {
continue;
}
boolean overrides = false; boolean overrides = false;
for (CallableMemberDescriptor functionFromCurrent : functionsFromCurrent) { for (CallableMemberDescriptor functionFromCurrent : functionsFromCurrent) {
@@ -175,7 +183,7 @@ public class OverrideResolver {
} }
} }
for (CallableMemberDescriptor fakeOverride : fakeOverrides) { for (CallableMemberDescriptor fakeOverride : fakeOverrideList) {
if (OverridingUtil.isOverridableBy(functionFromSupertype, fakeOverride).getResult() == OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE) { if (OverridingUtil.isOverridableBy(functionFromSupertype, fakeOverride).getResult() == OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE) {
fakeOverride.addOverriddenDescriptor(functionFromSupertype); fakeOverride.addOverriddenDescriptor(functionFromSupertype);
overrides = true; overrides = true;
@@ -185,9 +193,10 @@ public class OverrideResolver {
if (!overrides) { if (!overrides) {
CallableMemberDescriptor fakeOverride = functionFromSupertype.copy(current, false, CallableMemberDescriptor.Kind.FAKE_OVERRIDE, false); CallableMemberDescriptor fakeOverride = functionFromSupertype.copy(current, false, CallableMemberDescriptor.Kind.FAKE_OVERRIDE, false);
fakeOverride.addOverriddenDescriptor(functionFromSupertype); fakeOverride.addOverriddenDescriptor(functionFromSupertype);
fakeOverrideList.add(fakeOverride);
fakeOverrides.add(fakeOverride); if (fakeOverrides != null) {
fakeOverrides.add(fakeOverride);
}
sink.addToScope(fakeOverride); sink.addToScope(fakeOverride);
} }
} }
@@ -222,21 +231,22 @@ public class OverrideResolver {
return r; return r;
} }
private void checkOverrides() { private void checkOverrides(@NotNull Multimap<CallableDescriptor, CallableDescriptor> invisibleOverriddenDescriptors) {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) { for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
checkOverridesInAClass(entry.getValue(), entry.getKey()); checkOverridesInAClass(entry.getValue(), entry.getKey(), invisibleOverriddenDescriptors);
} }
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) { for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) {
checkOverridesInAClass(entry.getValue(), entry.getKey()); checkOverridesInAClass(entry.getValue(), entry.getKey(), invisibleOverriddenDescriptors);
} }
} }
protected void checkOverridesInAClass(MutableClassDescriptor classDescriptor, JetClassOrObject klass) { protected void checkOverridesInAClass(@NotNull MutableClassDescriptor classDescriptor, @NotNull JetClassOrObject klass,
@NotNull Multimap<CallableDescriptor, CallableDescriptor> invisibleOverriddenDescriptors) {
if (topDownAnalysisParameters.isAnalyzingBootstrapLibrary()) return; if (topDownAnalysisParameters.isAnalyzingBootstrapLibrary()) return;
// Check overrides for internal consistency // Check overrides for internal consistency
for (CallableMemberDescriptor member : classDescriptor.getCallableMembers()) { for (CallableMemberDescriptor member : classDescriptor.getCallableMembers()) {
checkOverride(member); checkOverrideForMember(member, invisibleOverriddenDescriptors);
} }
// Check if everything that must be overridden, actually is // Check if everything that must be overridden, actually is
@@ -271,34 +281,6 @@ public class OverrideResolver {
trace.report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(nameIdentifier, klass, memberDescriptor)); trace.report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(nameIdentifier, klass, memberDescriptor));
break; break;
} }
// Set<FunctionDescriptor> allOverriddenFunctions = Sets.newHashSet();
// Collection<DeclarationDescriptor> allDescriptors = classDescriptor.getDefaultType().getMemberScope().getAllDescriptors();
// for (DeclarationDescriptor descriptor : allDescriptors) {
// if (descriptor instanceof FunctionDescriptor) {
// FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
// if (functionDescriptor.getModality() != Modality.ABSTRACT) {
// for (FunctionDescriptor overriddenDescriptor : functionDescriptor.getOverriddenDescriptors()) {
// allOverriddenFunctions.add(overriddenDescriptor.getOriginal());
// }
// }
// }
// }
// boolean foundError = false;
// for (DeclarationDescriptor descriptor : allDescriptors) {
// if (descriptor instanceof FunctionDescriptor) {
// FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
// if (functionDescriptor.getModality() == Modality.ABSTRACT && !allOverriddenFunctions.contains(functionDescriptor.getOriginal()) && !foundError && nameIdentifier != null) {
// DeclarationDescriptor declarationDescriptor = functionDescriptor.getContainingDeclaration();
// if (declarationDescriptor != classDescriptor) {
//// trace.getErrorHandler().genericError(nameIdentifier.getNode(), "Class '" + klass.getName() + "' must be declared abstract or implement abstract method '" +
//// functionDescriptor.getName() + "' declared in " + declarationDescriptor.getName());
// trace.report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(nameIdentifier, klass, functionDescriptor));
// foundError = true;
// }
// }
// }
// }
} }
public static void collectMissingImplementations(MutableClassDescriptor classDescriptor, Set<CallableMemberDescriptor> abstractNoImpl, Set<CallableMemberDescriptor> manyImpl) { public static void collectMissingImplementations(MutableClassDescriptor classDescriptor, Set<CallableMemberDescriptor> abstractNoImpl, Set<CallableMemberDescriptor> manyImpl) {
@@ -317,21 +299,21 @@ public class OverrideResolver {
} }
} }
else { else {
Collection<CallableMemberDescriptor> overridenDeclarations = OverridingUtil.getOverridenDeclarations(descriptor); Collection<CallableMemberDescriptor> overriddenDeclarations = OverridingUtil.getOverridenDeclarations(descriptor);
if (overridenDeclarations.size() == 0) { if (overriddenDeclarations.size() == 0) {
throw new IllegalStateException(); throw new IllegalStateException();
} }
else if (overridenDeclarations.size() == 1) { else if (overriddenDeclarations.size() == 1) {
CallableMemberDescriptor single = overridenDeclarations.iterator().next(); CallableMemberDescriptor single = overriddenDeclarations.iterator().next();
if (single.getModality() == Modality.ABSTRACT) { if (single.getModality() == Modality.ABSTRACT) {
abstractNoImpl.add(single); abstractNoImpl.add(single);
} }
} }
else { else {
List<CallableMemberDescriptor> nonAbstractManyImpl = Lists.newArrayList(); List<CallableMemberDescriptor> nonAbstractManyImpl = Lists.newArrayList();
for (CallableMemberDescriptor overriden : overridenDeclarations) { for (CallableMemberDescriptor overridden : overriddenDeclarations) {
if (overriden.getModality() != Modality.ABSTRACT) { if (overridden.getModality() != Modality.ABSTRACT) {
nonAbstractManyImpl.add(overriden); nonAbstractManyImpl.add(overridden);
} }
} }
if (nonAbstractManyImpl.size() > 1) { if (nonAbstractManyImpl.size() > 1) {
@@ -371,7 +353,8 @@ public class OverrideResolver {
return factoredMembers; return factoredMembers;
} }
private void checkOverride(CallableMemberDescriptor declared) { private void checkOverrideForMember(@NotNull CallableMemberDescriptor declared,
@NotNull Multimap<CallableDescriptor, CallableDescriptor> invisibleOverriddenDescriptors) {
JetNamedDeclaration member = (JetNamedDeclaration) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), declared); JetNamedDeclaration member = (JetNamedDeclaration) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), declared);
if (member == null) { if (member == null) {
assert trace.get(DELEGATED, declared); assert trace.get(DELEGATED, declared);
@@ -410,7 +393,13 @@ public class OverrideResolver {
} }
} }
if (hasOverrideModifier && declared.getOverriddenDescriptors().size() == 0) { if (hasOverrideModifier && declared.getOverriddenDescriptors().size() == 0) {
trace.report(NOTHING_TO_OVERRIDE.on(member, declared)); if (!invisibleOverriddenDescriptors.get(declared).isEmpty()) {
CallableDescriptor descriptor = invisibleOverriddenDescriptors.values().iterator().next();
trace.report(CANNOT_OVERRIDE_INVISIBLE_MEMBER.on(member, declared, descriptor, descriptor.getContainingDeclaration()));
}
else {
trace.report(NOTHING_TO_OVERRIDE.on(member, declared));
}
} }
PsiElement nameIdentifier = member.getNameIdentifier(); PsiElement nameIdentifier = member.getNameIdentifier();
if (!hasOverrideModifier && declared.getOverriddenDescriptors().size() > 0 && nameIdentifier != null) { if (!hasOverrideModifier && declared.getOverriddenDescriptors().size() > 0 && nameIdentifier != null) {
@@ -427,38 +416,102 @@ public class OverrideResolver {
return false; return false;
} }
private void checkVisibilityForOverriddenMembers() { private void resolveUnknownVisibilityForMembers(@NotNull Set<CallableMemberDescriptor> fakeOverrides) {
for (Map.Entry<JetNamedFunction, SimpleFunctionDescriptor> entry : context.getFunctions().entrySet()) { for (CallableMemberDescriptor override : fakeOverrides) {
JetNamedFunction function = entry.getKey(); resolveUnknownVisibilityForMember(override);
SimpleFunctionDescriptor functionDescriptor = entry.getValue();
checkVisibilityForMember(functionDescriptor.getVisibility(), function, functionDescriptor.getOverriddenDescriptors());
} }
for (Map.Entry<JetProperty, PropertyDescriptor> entry : context.getProperties().entrySet()) { for (CallableMemberDescriptor memberDescriptor : context.getMembers().values()) {
JetProperty property = entry.getKey(); resolveUnknownVisibilityForMember(memberDescriptor);
PropertyDescriptor propertyDescriptor = entry.getValue();
checkVisibilityForMember(propertyDescriptor.getVisibility(), property, propertyDescriptor.getOverriddenDescriptors());
} }
for (PropertyDescriptor propertyDescriptor : context.getPrimaryConstructorParameterProperties()) { for (PropertyDescriptor propertyDescriptor : context.getProperties().values()) {
PsiElement parameter = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), propertyDescriptor); for (PropertyAccessorDescriptor accessor : propertyDescriptor.getAccessors()) {
if (parameter instanceof JetParameter) { if (accessor != null && accessor.getVisibility() == Visibilities.INHERITED) {
checkVisibilityForMember(propertyDescriptor.getVisibility(), (JetParameter)parameter, propertyDescriptor.getOverriddenDescriptors()); accessor.setVisibility(propertyDescriptor.getVisibility());
}
} }
} }
} }
private void checkVisibilityForMember(@NotNull Visibility visibility, private void resolveUnknownVisibilityForMember(@NotNull CallableMemberDescriptor memberDescriptor) {
@NotNull JetModifierListOwner modifierListOwner, resolveUnknownVisibilityForOverriddenDescriptors(memberDescriptor.getOverriddenDescriptors());
@NotNull Collection<? extends CallableMemberDescriptor> descriptors) { if (memberDescriptor.getVisibility() != Visibilities.INHERITED) {
return;
}
Visibility visibility = findMaxVisibility(memberDescriptor.getOverriddenDescriptors());
if (memberDescriptor instanceof PropertyDescriptor) {
((PropertyDescriptor)memberDescriptor).setVisibility(visibility);
}
else {
assert memberDescriptor instanceof FunctionDescriptorImpl;
((FunctionDescriptorImpl)memberDescriptor).setVisibility(visibility);
}
}
private void removeInvisibleOverriddenDescriptors(@NotNull Multimap<CallableDescriptor, CallableDescriptor> invisibleOverriddenDescriptors) {
for (CallableMemberDescriptor memberDescriptor : context.getMembers().values()) {
Set<? extends CallableDescriptor> overriddenDescriptors = memberDescriptor.getOverriddenDescriptors();
for (Iterator<? extends CallableDescriptor> iterator = overriddenDescriptors.iterator(); iterator.hasNext(); ) {
CallableDescriptor superDescriptor = iterator.next();
if (!Visibilities.isVisible(superDescriptor, memberDescriptor)) {
invisibleOverriddenDescriptors.put(memberDescriptor, superDescriptor);
iterator.remove();
}
}
}
}
private void resolveUnknownVisibilityForOverriddenDescriptors(@NotNull Collection<? extends CallableMemberDescriptor> descriptors) {
for (CallableMemberDescriptor descriptor : descriptors) { for (CallableMemberDescriptor descriptor : descriptors) {
if (descriptor.getVisibility() == Visibilities.INHERITED) {
resolveUnknownVisibilityForMember(descriptor);
}
}
}
@NotNull
private Visibility findMaxVisibility(@NotNull Collection<? extends CallableMemberDescriptor> descriptors) {
if (descriptors.isEmpty()) {
return Visibilities.INTERNAL;
}
Visibility maxVisibility = null;
for (CallableMemberDescriptor descriptor : descriptors) {
Visibility visibility = descriptor.getVisibility();
assert visibility != Visibilities.INHERITED;
if (maxVisibility == null) {
maxVisibility = visibility;
continue;
}
Integer compare = Visibilities.compare(visibility, maxVisibility);
if (compare == null) {
maxVisibility = Visibilities.PUBLIC; //todo error or warning when inference only from incomparable visibilities
continue;
}
if (compare > 0) {
maxVisibility = visibility;
}
}
assert maxVisibility != null;
return maxVisibility;
}
private void checkVisibility() {
for (Map.Entry<JetDeclaration, CallableMemberDescriptor> entry : context.getMembers().entrySet()) {
checkVisibilityForMember(entry.getKey(), entry.getValue());
}
}
private void checkVisibilityForMember(@NotNull JetDeclaration declaration, @NotNull CallableMemberDescriptor memberDescriptor) {
Visibility visibility = memberDescriptor.getVisibility();
for (CallableMemberDescriptor descriptor : memberDescriptor.getOverriddenDescriptors()) {
Integer compare = Visibilities.compare(visibility, descriptor.getVisibility()); Integer compare = Visibilities.compare(visibility, descriptor.getVisibility());
if (compare == null) { if (compare == null) {
trace.report(CANNOT_CHANGE_ACCESS_PRIVILEGE.on(modifierListOwner, descriptor.getVisibility(), descriptor, descriptor.getContainingDeclaration())); trace.report(CANNOT_CHANGE_ACCESS_PRIVILEGE.on(declaration, descriptor.getVisibility(), descriptor, descriptor.getContainingDeclaration()));
return; return;
} }
if (compare < 0) { else if (compare < 0) {
trace.report(CANNOT_WEAKEN_ACCESS_PRIVILEGE.on(modifierListOwner, descriptor.getVisibility(), descriptor, descriptor.getContainingDeclaration())); trace.report(CANNOT_WEAKEN_ACCESS_PRIVILEGE.on(declaration, descriptor.getVisibility(), descriptor, descriptor.getContainingDeclaration()));
return; return;
} }
} }
@@ -16,6 +16,7 @@
package org.jetbrains.jet.lang.resolve; package org.jetbrains.jet.lang.resolve;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
@@ -46,7 +47,8 @@ public class TopDownAnalysisContext {
private final Map<JetNamedFunction, SimpleFunctionDescriptor> functions = Maps.newLinkedHashMap(); private final Map<JetNamedFunction, SimpleFunctionDescriptor> functions = Maps.newLinkedHashMap();
private final Map<JetSecondaryConstructor, ConstructorDescriptor> constructors = Maps.newLinkedHashMap(); private final Map<JetSecondaryConstructor, ConstructorDescriptor> constructors = Maps.newLinkedHashMap();
private final Map<JetProperty, PropertyDescriptor> properties = Maps.newLinkedHashMap(); private final Map<JetProperty, PropertyDescriptor> properties = Maps.newLinkedHashMap();
private final Set<PropertyDescriptor> primaryConstructorParameterProperties = Sets.newHashSet(); private final Map<JetParameter, PropertyDescriptor> primaryConstructorParameterProperties = Maps.newHashMap();
private Map<JetDeclaration, CallableMemberDescriptor> members = null;
private StringBuilder debugOutput; private StringBuilder debugOutput;
@@ -114,7 +116,7 @@ public class TopDownAnalysisContext {
return namespaceDescriptors; return namespaceDescriptors;
} }
public Set<PropertyDescriptor> getPrimaryConstructorParameterProperties() { public Map<JetParameter, PropertyDescriptor> getPrimaryConstructorParameterProperties() {
return primaryConstructorParameterProperties; return primaryConstructorParameterProperties;
} }
@@ -134,4 +136,13 @@ public class TopDownAnalysisContext {
return functions; return functions;
} }
public Map<JetDeclaration, CallableMemberDescriptor> getMembers() {
if (members == null) {
members = Maps.newHashMap();
members.putAll(functions);
members.putAll(properties);
members.putAll(primaryConstructorParameterProperties);
}
return members;
}
} }
@@ -495,7 +495,9 @@ public class CallResolver {
// and throw the results away // and throw the results away
// We'll type check the arguments later, with the inferred types expected // We'll type check the arguments later, with the inferred types expected
TemporaryBindingTrace traceForUnknown = TemporaryBindingTrace.create(context.trace); TemporaryBindingTrace traceForUnknown = TemporaryBindingTrace.create(context.trace);
JetType type = expressionTypingServices.getType(context.scope, valueArgument.getArgumentExpression(), substituteDontCare.substitute(valueParameterDescriptor.getType(), Variance.INVARIANT), traceForUnknown); JetExpression argumentExpression = valueArgument.getArgumentExpression();
JetType type = argumentExpression != null ? expressionTypingServices.getType(context.scope, argumentExpression,
substituteDontCare.substitute(valueParameterDescriptor.getType(), Variance.INVARIANT), traceForUnknown) : null;
if (type != null && !ErrorUtils.isErrorType(type)) { if (type != null && !ErrorUtils.isErrorType(type)) {
constraintSystem.addSubtypingConstraint(VALUE_ARGUMENT.assertSubtyping(type, effectiveExpectedType)); constraintSystem.addSubtypingConstraint(VALUE_ARGUMENT.assertSubtyping(type, effectiveExpectedType));
} }
@@ -48,7 +48,7 @@ public class DataFlowUtils {
@NotNull @NotNull
public static DataFlowInfo extractDataFlowInfoFromCondition(@Nullable JetExpression condition, final boolean conditionValue, @Nullable final WritableScope scopeToExtend, final ExpressionTypingContext context) { public static DataFlowInfo extractDataFlowInfoFromCondition(@Nullable JetExpression condition, final boolean conditionValue, @Nullable final WritableScope scopeToExtend, final ExpressionTypingContext context) {
if (condition == null) return context.dataFlowInfo; if (condition == null) return context.dataFlowInfo;
final Ref<DataFlowInfo> result = new Ref<DataFlowInfo>(context.dataFlowInfo); final Ref<DataFlowInfo> result = new Ref<DataFlowInfo>(null);
condition.accept(new JetVisitorVoid() { condition.accept(new JetVisitorVoid() {
@Override @Override
public void visitIsExpression(JetIsExpression expression) { public void visitIsExpression(JetIsExpression expression) {
@@ -148,7 +148,7 @@ public class DataFlowUtils {
if (result.get() == null) { if (result.get() == null) {
return context.dataFlowInfo; return context.dataFlowInfo;
} }
return result.get(); return context.dataFlowInfo.and(result.get());
} }
@Nullable @Nullable
@@ -2,7 +2,7 @@ class C() {
fun getInstance(): Runnable = C fun getInstance(): Runnable = C
class object: Runnable { class object: Runnable {
public override fun run(): Unit { } override fun run(): Unit { }
} }
} }
@@ -1,8 +1,10 @@
fun box() : String { fun box() : String {
if (!B().test()) return "fail 1"; if (!B().test()) return "fail 1";
if (!D().test()) return "fail 2" if (!D().test()) return "fail 2"
if (!F().test()) return "fail 3"
if (!L().test()) return "fail 4" if (!L().test()) return "fail 4"
if (!N().test()) return "fail 5" if (!H().test()) return "fail 5"
if (!N().test()) return "fail 6"
return "OK" return "OK"
} }
@@ -31,16 +33,26 @@ class D {
fun test() = C().bar() == 1 fun test() = C().bar() == 1
} }
class E
fun E.foo() = 2
class M class F {
fun M.foo() = 2 fun foo() = 1
class N { fun E.bar() = foo()
fun M.foo() = 1
fun M.bar() = foo() fun test() = E().bar() == 1
}
fun test() = M().bar() == 1 class G
fun G.foo() = 2
class H {
fun G.foo() = 1
fun G.bar() = foo()
fun test() = G().bar() == 1
} }
class K class K
@@ -51,3 +63,13 @@ class L {
} }
fun K.foo() = 1 fun K.foo() = 1
fun L.foo() = 2 fun L.foo() = 2
class M
class N {
fun foo() = 1
fun M.foo() = 2
fun M.bar() = foo()
fun test() = M().bar() == 1
}
@@ -78,25 +78,25 @@ fun box() : String {
} }
class MyCollection1(): java.lang.Iterable<Int> { class MyCollection1(): java.lang.Iterable<Int> {
public override fun iterator(): java.util.Iterator<Int> = MyIterator() override fun iterator(): java.util.Iterator<Int> = MyIterator()
class MyIterator(): java.util.Iterator<Int> { class MyIterator(): java.util.Iterator<Int> {
var k : Int = 5 var k : Int = 5
public override fun next() : Int = k-- override fun next() : Int = k--
public override fun hasNext() = k > 0 override fun hasNext() = k > 0
public override fun remove() {} override fun remove() {}
} }
} }
class MyCollection2(): Iterable<Int> { class MyCollection2(): Iterable<Int> {
public override fun iterator(): Iterator<Int> = MyIterator() override fun iterator(): Iterator<Int> = MyIterator()
class MyIterator(): Iterator<Int> { class MyIterator(): Iterator<Int> {
var k : Int = 5 var k : Int = 5
public override fun next() : Int = k-- override fun next() : Int = k--
public override val hasNext : Boolean override val hasNext : Boolean
get() = k > 0 get() = k > 0
} }
} }
@@ -3,7 +3,7 @@ import java.util.concurrent.atomic.*
fun thread(block: ()->Unit ) { fun thread(block: ()->Unit ) {
val thread = object: Thread() { val thread = object: Thread() {
public override fun run() { override fun run() {
block() block()
} }
} }
@@ -1,7 +1,7 @@
class C(x: Int, val y : Int) { class C(x: Int, val y : Int) {
fun initChild(var x: Int) : java.lang.Object { fun initChild(var x: Int) : java.lang.Object {
return object : java.lang.Object() { return object : java.lang.Object() {
public override fun toString(): String? { override fun toString(): String? {
x = x + y x = x + y
return "child" + x return "child" + x
} }
@@ -3,7 +3,7 @@ package p
class C(val y : Int) { class C(val y : Int) {
val initChild = { -> val initChild = { ->
object : java.lang.Object() { object : java.lang.Object() {
public override fun toString(): String { override fun toString(): String {
return "child" + y return "child" + y
} }
} }
@@ -2,7 +2,7 @@ import java.util.ArrayList
public object SomeObject { public object SomeObject {
private val workerThread = object : Thread() { private val workerThread = object : Thread() {
public override fun run() { override fun run() {
foo() foo()
} }
} }
@@ -2,7 +2,7 @@ public object SomeClass {
var bug: Any = "" var bug: Any = ""
private val workerThread = object : Thread() { private val workerThread = object : Thread() {
public override fun run() { override fun run() {
try { try {
foo() foo()
bug = "none" bug = "none"
@@ -1,6 +1,6 @@
public object RefreshQueue { public object RefreshQueue {
private val workerThread: Thread = Thread(object : Runnable { private val workerThread: Thread = Thread(object : Runnable {
public override fun run() { override fun run() {
workerThread.isInterrupted() workerThread.isInterrupted()
} }
}); });
@@ -7,9 +7,9 @@ public abstract class BaseClass() {
} }
public class Subclass : BaseClass() { public class Subclass : BaseClass() {
protected override val kind : String = "Physical" override val kind : String = "Physical"
protected override val kind2 : String = " kind2" override val kind2 : String = " kind2"
} }
fun box():String = if(Subclass().debug() == "Physical kind2") "OK" else "fail" fun box():String = if(Subclass().debug() == "Physical kind2") "OK" else "fail"
@@ -1,5 +1,5 @@
class MyRange1() : Range<Int> { class MyRange1() : Range<Int> {
public override fun contains(item: Int) = true override fun contains(item: Int) = true
} }
class MyRange2() { class MyRange2() {
@@ -163,7 +163,7 @@ fun t11(var x: Int) : Int {
fun t12(x: Int) : Int { fun t12(x: Int) : Int {
var y = x var y = x
val runnable = object : Runnable { val runnable = object : Runnable {
public override fun run () { override fun run () {
y = y + 1 y = y + 1
} }
} }
@@ -95,11 +95,11 @@ fun LinkedList<Int>.sum(f : (Int, Int) -> Int) : Int {
} }
fun <T> List<T>.backwards() : Iterable<T> = object : Iterable<T> { fun <T> List<T>.backwards() : Iterable<T> = object : Iterable<T> {
public override fun iterator() : jet.Iterator<T> = override fun iterator() : jet.Iterator<T> =
object : jet.Iterator<T> { object : jet.Iterator<T> {
var current = size() var current = size()
public override fun next() : T = get(--current) override fun next() : T = get(--current)
public override val hasNext : Boolean get() = current > 0 override val hasNext : Boolean get() = current > 0
} }
} }
@@ -1,5 +1,5 @@
class Book(val name: String) : Comparable<Book> { class Book(val name: String) : Comparable<Book> {
public override fun compareTo(other: Book) = name.compareTo(other.name) override fun compareTo(other: Book) = name.compareTo(other.name)
} }
fun box() = if(Book("239").compareTo(Book("932")) != 0) "OK" else "fail" fun box() = if(Book("239").compareTo(Book("932")) != 0) "OK" else "fail"
@@ -3,13 +3,13 @@ import java.util.*
fun box() : String { fun box() : String {
val w = object : Comparator<String?> { val w = object : Comparator<String?> {
public override fun compare(o1 : String?, o2 : String?) : Int { override fun compare(o1 : String?, o2 : String?) : Int {
val l1 : Int = o1?.length ?: 0 val l1 : Int = o1?.length ?: 0
val l2 = o2?.length ?: 0 val l2 = o2?.length ?: 0
return l1 - l2 return l1 - l2
} }
public override fun equals(obj: Any?): Boolean = obj === this override fun equals(obj: Any?): Boolean = obj === this
} }
w.compare("aaa", "bbb") w.compare("aaa", "bbb")
@@ -1,7 +1,7 @@
import java.util.ArrayList import java.util.ArrayList
class N() : ArrayList<Any>() { class N() : ArrayList<Any>() {
public override fun add(el: Any) : Boolean { override fun add(el: Any) : Boolean {
if (!super<ArrayList>.add(el)) { if (!super<ArrayList>.add(el)) {
throw Exception() throw Exception()
} }
+1 -1
View File
@@ -3,7 +3,7 @@ trait SimpleClass : java.lang.Object {
} }
class SimpleClassImpl() : SimpleClass { class SimpleClassImpl() : SimpleClass {
public override fun toString() = "SimpleClassImpl" override fun toString() = "SimpleClassImpl"
} }
fun box() : String { fun box() : String {
+4 -4
View File
@@ -3,7 +3,7 @@ trait ISized {
} }
trait javaUtilIterator<T> : java.util.Iterator<T> { trait javaUtilIterator<T> : java.util.Iterator<T> {
public override fun remove() : Unit { override fun remove() : Unit {
throw UnsupportedOperationException() throw UnsupportedOperationException()
} }
} }
@@ -11,9 +11,9 @@ trait javaUtilIterator<T> : java.util.Iterator<T> {
class MyIterator<T>(val array : ReadOnlyArray<T>) : javaUtilIterator<T> { class MyIterator<T>(val array : ReadOnlyArray<T>) : javaUtilIterator<T> {
private var index = 0 private var index = 0
public override fun hasNext() : Boolean = index < array.size override fun hasNext() : Boolean = index < array.size
public override fun next() : T = array.get(index++) override fun next() : T = array.get(index++)
} }
trait ReadOnlyArray<out T> : ISized, java.lang.Iterable<T> { trait ReadOnlyArray<out T> : ISized, java.lang.Iterable<T> {
@@ -23,7 +23,7 @@ trait ReadOnlyArray<out T> : ISized, java.lang.Iterable<T> {
fun check(v: Any) = v is T fun check(v: Any) = v is T
} }
public override fun iterator() : java.util.Iterator<T> = MyIterator<T>(this) override fun iterator() : java.util.Iterator<T> = MyIterator<T>(this)
} }
trait WriteOnlyArray<in T> : ISized { trait WriteOnlyArray<in T> : ISized {
@@ -1,4 +1,3 @@
class X { class X {
val <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>x<!> : Int val <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>x<!> : Int
} }
@@ -18,12 +17,12 @@ class Z : Y() {
class MyIterable<T> : Iterable<T> class MyIterable<T> : Iterable<T>
{ {
public override fun iterator(): Iterator<T> = MyIterator() override fun iterator(): Iterator<T> = MyIterator()
class MyIterator : Iterator<T> class MyIterator : Iterator<T>
{ {
public override val hasNext: Boolean = false override val hasNext: Boolean = false
public override fun next(): T { override fun next(): T {
throw UnsupportedOperationException() throw UnsupportedOperationException()
} }
} }
@@ -1,10 +1,10 @@
import java.util.Enumeration import java.util.Enumeration
inline fun <T> java.util.Enumeration<T>.iterator() = object: Iterator<T> { inline fun <T> java.util.Enumeration<T>.iterator() = object: Iterator<T> {
public override val hasNext: Boolean override val hasNext: Boolean
get() = hasMoreElements() get() = hasMoreElements()
public override fun next() = nextElement() override fun next() = nextElement()
} }
fun <T : Any> T?.iterator() = object { fun <T : Any> T?.iterator() = object {
@@ -0,0 +1,10 @@
//EA-35646
package a
class MyClass1 {
public fun plus() {}
}
fun main(arg: MyClass1) {
arg<!TOO_MANY_ARGUMENTS!>+<!><!SYNTAX!><!>
}
@@ -0,0 +1,11 @@
//KT-1778 Automatically cast error
package kt1778
fun main(args : Array<String>) {
val x = args[0]: Any
if(x is java.lang.CharSequence) {
if ("a" == x) x.length() else x.length() // OK
if ("a" == x || "b" == x) x.length() else x.length() // < THEN ERROR
if ("a" == x && "a" == x) x.length() else x.length() // < ELSE ERROR
}
}
@@ -0,0 +1,17 @@
//KT-1820 Write test for ASSIGN_OPERATOR_AMBIGUITY
package kt1820
class MyInt(val i: Int) {
fun plus(m: MyInt) : MyInt = MyInt(m.i + i)
}
fun Any.plusAssign(<!UNUSED_PARAMETER!>a<!>: Any) {}
fun test(m: MyInt) {
m <!ASSIGN_OPERATOR_AMBIGUITY!>+=<!> m
var i = 1
i <!ASSIGN_OPERATOR_AMBIGUITY!>+=<!> 34
}
@@ -0,0 +1,27 @@
//KT-1821 Write test for ITERATOR_AMBIGUITY diagnostic
trait MyCollectionInterface {
}
trait MyAnotherCollectionInterface {
}
class MyCollection : MyCollectionInterface, MyAnotherCollectionInterface {
}
fun MyCollectionInterface.iterator() = MyIterator()
fun MyAnotherCollectionInterface.iterator() = MyIterator()
class MyIterator {
fun next() : MyElement = MyElement()
fun hasNext() = true
}
class MyElement
fun test1(collection: MyCollection) {
collection.<!OVERLOAD_RESOLUTION_AMBIGUITY!>iterator()<!>
for (val element in <!ITERATOR_AMBIGUITY!>collection<!>) {
}
}
@@ -6,7 +6,7 @@ class Test() : Thread("Test") {
} }
} }
public override fun run() { override fun run() {
init2() // unresolved init2() // unresolved
Test.init2() // ok Test.init2() // ok
} }
@@ -18,7 +18,7 @@ open class D {
} }
class E : D() { class E : D() {
internal <!NOTHING_TO_OVERRIDE!>override<!> fun self() = this internal <!CANNOT_OVERRIDE_INVISIBLE_MEMBER!>override<!> fun self() = this
fun test() { fun test() {
val <!UNUSED_VARIABLE!>s<!> : E = self() val <!UNUSED_VARIABLE!>s<!> : E = self()
@@ -31,7 +31,11 @@ open class F {
} }
class G : F() { class G : F() {
<!CANNOT_CHANGE_ACCESS_PRIVILEGE!>override<!> fun protected_fun() {} override fun protected_fun() {}
}
fun test_fun_stays_protected(g: G) {
g.<!INVISIBLE_MEMBER!>protected_fun<!>()
} }
//------------ //------------
@@ -57,11 +61,11 @@ trait T {
} }
open class L : T { open class L : T {
<!CANNOT_WEAKEN_ACCESS_PRIVILEGE!>override<!> fun foo() {} override fun foo() {}
} }
class M : L() { class M : L() {
internal override fun foo() {} <!CANNOT_WEAKEN_ACCESS_PRIVILEGE!>internal<!> override fun foo() {}
} }
//--------------- //---------------
trait R { trait R {
@@ -0,0 +1,40 @@
//KT-151 Inherit visibility when overriding
package kt151
open class A {
protected open fun x() {}
}
class B : A() {
override fun x() {} // No visibility modifier required
}
fun test(b: B) {
b.<!INVISIBLE_MEMBER!>x<!>()
}
//more tests
open class C {
internal open fun foo() {}
}
trait T {
protected fun foo() {}
}
class D : C(), T {
<!CANNOT_CHANGE_ACCESS_PRIVILEGE!>protected<!> override fun foo() {}
}
class E : C(), T {
<!CANNOT_CHANGE_ACCESS_PRIVILEGE!>internal<!> override fun foo() {}
}
class F : C(), T {
<!CANNOT_WEAKEN_ACCESS_PRIVILEGE!>private<!> override fun foo() {}
}
class G : C(), T {
override fun foo() {}
}
@@ -0,0 +1,20 @@
package kt1805
//KT-1805 Better diagnostic for access to private field of parent class
open class Some {
private val privateField = 12
}
class SomeSubclass : Some() {
fun test() {
this.<!INVISIBLE_MEMBER!>privateField<!> // 1. Unresolved reference
}
}
fun test() {
val s2 = Some()
s2.<!INVISIBLE_MEMBER!>privateField<!> // 2. Can't access to 'privateField' in Some
val s1 = SomeSubclass()
s1.<!INVISIBLE_MEMBER!>privateField<!> // 3. Unresolved reference
}
@@ -0,0 +1,22 @@
//KT-1806 accessing private member in object class/anonymous object is not highlighted as error
package kt1806
object MyObject {
private var message: String = "'Static'"
}
fun test1() {
doSmth(MyObject.<!INVISIBLE_MEMBER!>message<!>)
}
val MyObject1 = object {
private var message: String = "'Static'"
}
fun test2() {
doSmth(MyObject1.<!INVISIBLE_MEMBER!>message<!>)
}
fun doSmth(s: String) = s
@@ -12,7 +12,4 @@ class SomeSubclass : Some() {
} }
// TIME: 2 // TIME: 2
// EXIST: testPublic, testProtected, testPackage // EXIST: testPublic, testProtected, testPackage, testPrivate
// Should exist after KT-1805 Better diagnostic for access to private field of parent class
// ABSENT: testPrivate
@@ -4,5 +4,5 @@ open class A {
} }
class B : A() { class B : A() {
<caret>override fun run() {} <caret>internal override fun run() {}
} }
@@ -4,6 +4,6 @@ trait ParseResult<out T> {
public val value : T public val value : T
} }
class Success<T>(<caret>override val value : T) : ParseResult<T> { class Success<T>(<caret>internal override val value : T) : ParseResult<T> {
public override val success : Boolean = true public override val success : Boolean = true
} }
@@ -4,23 +4,23 @@ import kotlin.test.Asserter
import org.junit.Assert import org.junit.Assert
class JUnitAsserter : Asserter { class JUnitAsserter : Asserter {
public override fun assertEquals(message : String, expected : Any?, actual : Any?) { override fun assertEquals(message : String, expected : Any?, actual : Any?) {
Assert.assertEquals(message, expected, actual) Assert.assertEquals(message, expected, actual)
} }
public override fun assertNotNull(message : String, actual : Any?) { override fun assertNotNull(message : String, actual : Any?) {
Assert.assertNotNull(message, actual) Assert.assertNotNull(message, actual)
} }
public override fun assertNull(message : String, actual : Any?) { override fun assertNull(message : String, actual : Any?) {
Assert.assertNull(message, actual) Assert.assertNull(message, actual)
} }
public override fun assertTrue(message : String, actual : Boolean) { override fun assertTrue(message : String, actual : Boolean) {
Assert.assertTrue(message, actual) Assert.assertTrue(message, actual)
} }
public override fun fail(message : String) { override fun fail(message : String) {
Assert.fail(message) Assert.fail(message)
} }
} }
+2 -2
View File
@@ -25,7 +25,7 @@ public inline fun <T> java.util.Iterator<T>.iterator() : java.util.Iterator<T> =
Helper to make java.util.Enumeration usable in for Helper to make java.util.Enumeration usable in for
*/ */
public fun <erased T> java.util.Enumeration<T>.iterator(): Iterator<T> = object: Iterator<T> { public fun <erased T> java.util.Enumeration<T>.iterator(): Iterator<T> = object: Iterator<T> {
public override val hasNext: Boolean override val hasNext: Boolean
get() = hasMoreElements() get() = hasMoreElements()
public override fun next() : T = nextElement().sure() public override fun next() : T = nextElement().sure()
@@ -114,4 +114,4 @@ public inline fun Throwable.printStackTrace(writer: PrintWriter): Unit {
public inline fun Throwable.printStackTrace(stream: PrintStream): Unit { public inline fun Throwable.printStackTrace(stream: PrintStream): Unit {
val jlt = this as java.lang.Throwable val jlt = this as java.lang.Throwable
jlt.printStackTrace(stream) jlt.printStackTrace(stream)
} }
@@ -35,15 +35,15 @@ abstract class FunctionalList<T>(public val size: Int) {
return head return head
} }
public override val hasNext: Boolean override val hasNext: Boolean
get() = !cur.empty get() = !cur.empty
} }
class object { class object {
class Empty<T>() : FunctionalList<T>(0) { class Empty<T>() : FunctionalList<T>(0) {
public override val head: T override val head: T
get() = throw java.util.NoSuchElementException() get() = throw java.util.NoSuchElementException()
public override val tail: FunctionalList<T> override val tail: FunctionalList<T>
get() = throw java.util.NoSuchElementException() get() = throw java.util.NoSuchElementException()
} }
+6 -6
View File
@@ -201,7 +201,7 @@ fun Node.nextSiblings() : Iterator<Node> = NextSiblingIterator(this)
class NextSiblingIterator(var node: Node) : AbstractIterator<Node>() { class NextSiblingIterator(var node: Node) : AbstractIterator<Node>() {
protected override fun computeNext(): Unit { override fun computeNext(): Unit {
val next = node.getNextSibling() val next = node.getNextSibling()
if (next != null) { if (next != null) {
setNext(next) setNext(next)
@@ -215,7 +215,7 @@ fun Node.previousSiblings() : Iterator<Node> = PreviousSiblingIterator(this)
class PreviousSiblingIterator(var node: Node) : AbstractIterator<Node>() { class PreviousSiblingIterator(var node: Node) : AbstractIterator<Node>() {
protected override fun computeNext(): Unit { override fun computeNext(): Unit {
val next = node.getPreviousSibling() val next = node.getPreviousSibling()
if (next != null) { if (next != null) {
setNext(next) setNext(next)
@@ -323,7 +323,7 @@ fun NodeList?.toXmlString(xmlDeclaration: Boolean = false): String {
} }
class NodeListAsList(val nodeList: NodeList): AbstractList<Node>() { class NodeListAsList(val nodeList: NodeList): AbstractList<Node>() {
public override fun get(index: Int): Node { override fun get(index: Int): Node {
val node = nodeList.item(index) val node = nodeList.item(index)
if (node == null) { if (node == null) {
throw IndexOutOfBoundsException("NodeList does not contain a node at index: " + index) throw IndexOutOfBoundsException("NodeList does not contain a node at index: " + index)
@@ -332,11 +332,11 @@ class NodeListAsList(val nodeList: NodeList): AbstractList<Node>() {
} }
} }
public override fun size(): Int = nodeList.getLength() override fun size(): Int = nodeList.getLength()
} }
class ElementListAsList(val nodeList: NodeList): AbstractList<Element>() { class ElementListAsList(val nodeList: NodeList): AbstractList<Element>() {
public override fun get(index: Int): Element { override fun get(index: Int): Element {
val node = nodeList.item(index) val node = nodeList.item(index)
if (node is Element) { if (node is Element) {
return node return node
@@ -349,7 +349,7 @@ class ElementListAsList(val nodeList: NodeList): AbstractList<Element>() {
} }
} }
public override fun size(): Int = nodeList.getLength() override fun size(): Int = nodeList.getLength()
} }
+2 -2
View File
@@ -172,7 +172,7 @@ public inline fun <T: Closeable, R> T.use(block: (T)-> R) : R {
/** Returns an [Iterator] of bytes over an input stream */ /** Returns an [Iterator] of bytes over an input stream */
public fun InputStream.iterator() : ByteIterator = public fun InputStream.iterator() : ByteIterator =
object: ByteIterator() { object: ByteIterator() {
public override val hasNext : Boolean override val hasNext : Boolean
get() = available() > 0 get() = available() > 0
public override fun nextByte() : Byte = read().toByte() public override fun nextByte() : Byte = read().toByte()
@@ -238,7 +238,7 @@ class LineIterator(val reader: BufferedReader) : Iterator<String> {
private var nextValue: String? = null private var nextValue: String? = null
private var done = false private var done = false
public override val hasNext: Boolean override val hasNext: Boolean
get() { get() {
if (nextValue == null && !done) { if (nextValue == null && !done) {
nextValue = reader.readLine() nextValue = reader.readLine()
@@ -17,7 +17,7 @@ public abstract class AbstractIterator<T>: java.util.Iterator<T> {
private var state: State = State.NotReady private var state: State = State.NotReady
private var next: T? = null private var next: T? = null
public override fun hasNext(): Boolean { override fun hasNext(): Boolean {
require(state != State.Failed) require(state != State.Failed)
return when (state) { return when (state) {
State.Done -> false State.Done -> false
@@ -26,13 +26,13 @@ public abstract class AbstractIterator<T>: java.util.Iterator<T> {
} }
} }
public override fun next(): T { override fun next(): T {
if (!hasNext()) throw NoSuchElementException() if (!hasNext()) throw NoSuchElementException()
state = State.NotReady state = State.NotReady
return next.sure() return next.sure()
} }
public override fun remove() { override fun remove() {
throw UnsupportedOperationException() throw UnsupportedOperationException()
} }
+1 -1
View File
@@ -389,7 +389,7 @@ class CollectionTest {
class IterableWrapper<T>(collection : java.lang.Iterable<T>) : java.lang.Iterable<T> { class IterableWrapper<T>(collection : java.lang.Iterable<T>) : java.lang.Iterable<T> {
private val collection = collection private val collection = collection
public override fun iterator(): java.util.Iterator<T> { override fun iterator(): java.util.Iterator<T> {
return collection.iterator().sure() return collection.iterator().sure()
} }
} }
+2 -2
View File
@@ -43,10 +43,10 @@ class CompareTest {
Test fun sortUsingCustomComparator() { Test fun sortUsingCustomComparator() {
val c = object : Comparator<Item>{ val c = object : Comparator<Item>{
public override fun compare(o1: Item?, o2: Item?): Int { override fun compare(o1: Item?, o2: Item?): Int {
return compareBy(o1, o2, {(it: Item) -> it.name}, {(it: Item) -> it.rating}) return compareBy(o1, o2, {(it: Item) -> it.name}, {(it: Item) -> it.rating})
} }
public override fun equals(obj: Any?): Boolean { override fun equals(obj: Any?): Boolean {
return this == obj return this == obj
} }
} }
+4 -4
View File
@@ -17,13 +17,13 @@ class TestBuilt<T>(name: String, val builder: TestBuilder<T>, val test: TestBuil
get() = myState.sure() get() = myState.sure()
set(newState: T) { myState = newState } set(newState: T) { myState = newState }
public override fun countTestCases(): Int = 1 override fun countTestCases(): Int = 1
protected override fun setUp() = this.(builder.setUp)() override fun setUp() = this.(builder.setUp)()
protected override fun tearDown() = this.(builder.tearDown)() override fun tearDown() = this.(builder.tearDown)()
protected override fun runTest() = this.(test)() override fun runTest() = this.(test)()
} }
open class TestBuilder<T>(name: String) { open class TestBuilder<T>(name: String) {
@@ -10,7 +10,7 @@ import junit.framework.TestCase
import junit.framework.Assert import junit.framework.Assert
class Serial(val a : String) : java.lang.Object(), Serializable { class Serial(val a : String) : java.lang.Object(), Serializable {
public override fun toString() = a override fun toString() = a
} }
class SerialTest() : TestCase() { class SerialTest() : TestCase() {
@@ -28,7 +28,7 @@ class Customer() : ChangeSupport() {
class MyChangeListener() : ChangeListener { class MyChangeListener() : ChangeListener {
val events = ArrayList<ChangeEvent>() val events = ArrayList<ChangeEvent>()
public override fun onPropertyChange(event: ChangeEvent): Unit { override fun onPropertyChange(event: ChangeEvent): Unit {
println("Property changed: $event") println("Property changed: $event")
events.add(event) events.add(event)
} }