Merge remote branch 'origin/master'
This commit is contained in:
@@ -375,6 +375,9 @@ public interface Errors {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FunctionSignatureDiagnosticFactory CONFLICTING_OVERLOADS = new FunctionSignatureDiagnosticFactory(ERROR, "{1} is already defined in ''{0}''");
|
||||||
|
|
||||||
|
|
||||||
ParameterizedDiagnosticFactory3<String, JetType, JetType> RESULT_TYPE_MISMATCH = ParameterizedDiagnosticFactory3.create(ERROR, "{0} must return {1} but returns {2}");
|
ParameterizedDiagnosticFactory3<String, JetType, JetType> RESULT_TYPE_MISMATCH = ParameterizedDiagnosticFactory3.create(ERROR, "{0} must return {1} but returns {2}");
|
||||||
ParameterizedDiagnosticFactory3<String, String, String> UNSAFE_INFIX_CALL = ParameterizedDiagnosticFactory3.create(ERROR, "Infix call corresponds to a dot-qualified call ''{0}.{1}({2})'' which is not allowed on a nullable receiver ''{0}''. Use '?.'-qualified call instead");
|
ParameterizedDiagnosticFactory3<String, String, String> UNSAFE_INFIX_CALL = ParameterizedDiagnosticFactory3.create(ERROR, "Infix call corresponds to a dot-qualified call ''{0}.{1}({2})'' which is not allowed on a nullable receiver ''{0}''. Use '?.'-qualified call instead");
|
||||||
|
|
||||||
|
|||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
package org.jetbrains.jet.lang.diagnostics;
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.TextRange;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetNamedFunction;
|
||||||
|
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Stepan Koltsov
|
||||||
|
*/
|
||||||
|
public class FunctionSignatureDiagnosticFactory extends DiagnosticFactoryWithMessageFormat {
|
||||||
|
|
||||||
|
public FunctionSignatureDiagnosticFactory(Severity severity, String messageTemplate) {
|
||||||
|
super(severity, messageTemplate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public Diagnostic on(@NotNull JetNamedFunction functionElement, @NotNull FunctionDescriptor functionDescriptor,
|
||||||
|
@NotNull String functionContainer)
|
||||||
|
{
|
||||||
|
TextRange rangeToMark = new TextRange(
|
||||||
|
functionElement.getStartOfSignatureElement().getTextRange().getStartOffset(),
|
||||||
|
functionElement.getEndOfSignatureElement().getTextRange().getEndOffset()
|
||||||
|
);
|
||||||
|
String message = messageFormat.format(new Object[]{
|
||||||
|
functionContainer,
|
||||||
|
DescriptorRenderer.TEXT.render(functionDescriptor)});
|
||||||
|
return new GenericDiagnostic(this, severity, message, functionElement.getContainingFile(), rangeToMark);
|
||||||
|
}
|
||||||
|
|
||||||
|
} //~
|
||||||
@@ -40,4 +40,26 @@ public class JetNamedFunction extends JetFunction {
|
|||||||
return findChildByType(JetTokens.EQ) == null;
|
return findChildByType(JetTokens.EQ) == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JetElement getStartOfSignatureElement() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JetElement getEndOfSignatureElement() {
|
||||||
|
JetElement r = getReturnTypeRef();
|
||||||
|
if (r != null) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = getValueParameterList();
|
||||||
|
if (r != null) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise it is an error
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,116 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.Pair;
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.util.containers.MultiMap;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||||
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.lang.resolve.BindingContext.DELEGATED;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Stepan Koltsov
|
||||||
|
*/
|
||||||
|
public class OverloadResolver {
|
||||||
|
private final TopDownAnalysisContext context;
|
||||||
|
|
||||||
|
public OverloadResolver(@NotNull TopDownAnalysisContext context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void process() {
|
||||||
|
checkOverloads();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkOverloads() {
|
||||||
|
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
|
||||||
|
checkOverloadsInAClass(entry.getValue(), entry.getKey());
|
||||||
|
}
|
||||||
|
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) {
|
||||||
|
checkOverloadsInAClass(entry.getValue(), entry.getKey());
|
||||||
|
}
|
||||||
|
checkOverloadsInANamespace();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkOverloadsInANamespace() {
|
||||||
|
class Key extends Pair<String, String> {
|
||||||
|
Key(String namespace, String name) {
|
||||||
|
super(namespace, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace() {
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFunctionName() {
|
||||||
|
return second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiMap<Key, FunctionDescriptor> functionsByName = MultiMap.create();
|
||||||
|
|
||||||
|
for (FunctionDescriptorImpl function : context.getFunctions().values()) {
|
||||||
|
DeclarationDescriptor containingDeclaration = function.getContainingDeclaration();
|
||||||
|
if (containingDeclaration instanceof NamespaceDescriptor) {
|
||||||
|
NamespaceDescriptor namespaceDescriptor = (NamespaceDescriptor) containingDeclaration;
|
||||||
|
functionsByName.putValue(new Key(namespaceDescriptor.getName(), function.getName()), function);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<Key, Collection<FunctionDescriptor>> e : functionsByName.entrySet()) {
|
||||||
|
checkOverloadsWithSameName(e.getKey().getFunctionName(), e.getValue(), e.getKey().getNamespace());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkOverloadsInAClass(MutableClassDescriptor classDescriptor, JetClassOrObject klass) {
|
||||||
|
MultiMap<String, FunctionDescriptor> functionsByName = MultiMap.create();
|
||||||
|
|
||||||
|
for (FunctionDescriptor function : classDescriptor.getFunctions()) {
|
||||||
|
functionsByName.putValue(function.getName(), function);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<String, Collection<FunctionDescriptor>> e : functionsByName.entrySet()) {
|
||||||
|
checkOverloadsWithSameName(e.getKey(), e.getValue(), klass.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// properties are checked elsewhere
|
||||||
|
|
||||||
|
// Kotlin has no secondary constructors at this time
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkOverloadsWithSameName(String name, Collection<FunctionDescriptor> functions, String functionContainer) {
|
||||||
|
if (functions.size() == 1) {
|
||||||
|
// microoptimization
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (FunctionDescriptor function : functions) {
|
||||||
|
for (FunctionDescriptor function2 : functions) {
|
||||||
|
if (function == function2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
OverloadUtil.OverloadCompatibilityInfo overloadble = OverloadUtil.isOverloadble(function, function2);
|
||||||
|
if (!overloadble.isSuccess()) {
|
||||||
|
JetNamedFunction member = (JetNamedFunction) context.getTrace().get(BindingContext.DESCRIPTOR_TO_DECLARATION, function);
|
||||||
|
if (member == null) {
|
||||||
|
assert context.getTrace().get(DELEGATED, function);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.getTrace().report(Errors.CONFLICTING_OVERLOADS.on(member, function, functionContainer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Stepan Koltsov
|
||||||
|
*/
|
||||||
|
public class OverloadUtil {
|
||||||
|
|
||||||
|
public static OverloadCompatibilityInfo isOverloadble(FunctionDescriptor a, FunctionDescriptor b) {
|
||||||
|
OverridingUtil.OverrideCompatibilityInfo overrideCompatibilityInfo = OverridingUtil.isOverridableByImpl(a, b, false);
|
||||||
|
if (overrideCompatibilityInfo.isSuccess()) {
|
||||||
|
return OverloadCompatibilityInfo.someError();
|
||||||
|
} else {
|
||||||
|
return OverloadCompatibilityInfo.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class OverloadCompatibilityInfo {
|
||||||
|
|
||||||
|
private static final OverloadCompatibilityInfo SUCCESS = new OverloadCompatibilityInfo(true, "SUCCESS");
|
||||||
|
|
||||||
|
public static OverloadCompatibilityInfo success() {
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OverloadCompatibilityInfo someError() {
|
||||||
|
return new OverloadCompatibilityInfo(false, "XXX");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private final boolean isSuccess;
|
||||||
|
private final String message;
|
||||||
|
|
||||||
|
public OverloadCompatibilityInfo(boolean success, String message) {
|
||||||
|
isSuccess = success;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSuccess() {
|
||||||
|
return isSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -93,6 +93,13 @@ public class OverridingUtil {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static OverrideCompatibilityInfo isOverridableBy(@NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor) {
|
public static OverrideCompatibilityInfo isOverridableBy(@NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor) {
|
||||||
|
return isOverridableByImpl(superDescriptor, subDescriptor, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param forOverride true for override, false for overload
|
||||||
|
*/
|
||||||
|
static OverrideCompatibilityInfo isOverridableByImpl(CallableDescriptor superDescriptor, CallableDescriptor subDescriptor, boolean forOverride) {
|
||||||
if (superDescriptor instanceof FunctionDescriptor) {
|
if (superDescriptor instanceof FunctionDescriptor) {
|
||||||
if (subDescriptor instanceof PropertyDescriptor) return OverrideCompatibilityInfo.memberKindMismatch();
|
if (subDescriptor instanceof PropertyDescriptor) return OverrideCompatibilityInfo.memberKindMismatch();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ public class TopDownAnalyzer {
|
|||||||
new DeclarationResolver(context).process();
|
new DeclarationResolver(context).process();
|
||||||
new DelegationResolver(context).process();
|
new DelegationResolver(context).process();
|
||||||
new OverrideResolver(context).process();
|
new OverrideResolver(context).process();
|
||||||
|
new OverloadResolver(context).process();
|
||||||
new BodyResolver(context).resolveBehaviorDeclarationBodies();
|
new BodyResolver(context).resolveBehaviorDeclarationBodies();
|
||||||
new ControlFlowAnalyzer(context, flowDataTraceFactory, declaredLocally).process();
|
new ControlFlowAnalyzer(context, flowDataTraceFactory, declaredLocally).process();
|
||||||
new DeclarationsChecker(context).process();
|
new DeclarationsChecker(context).process();
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
// http://youtrack.jetbrains.net/issue/KT-424
|
||||||
|
|
||||||
|
class A {
|
||||||
|
<!CONFLICTING_OVERLOADS!>fun a(a: Int): Int<!> = 0
|
||||||
|
|
||||||
|
<!CONFLICTING_OVERLOADS!>fun a(a: Int)<!> {
|
||||||
|
}
|
||||||
|
|
||||||
|
<!CONFLICTING_OVERLOADS!>fun b()<!> {
|
||||||
|
}
|
||||||
|
|
||||||
|
<!CONFLICTING_OVERLOADS!>fun b()<!> {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace deepSpace {
|
||||||
|
<!CONFLICTING_OVERLOADS!>fun c(s: String)<!> {
|
||||||
|
}
|
||||||
|
|
||||||
|
<!CONFLICTING_OVERLOADS!>fun c(s: String)<!> {
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
<!CONFLICTING_OVERLOADS!>fun d(s: String)<!> {
|
||||||
|
}
|
||||||
|
|
||||||
|
<!CONFLICTING_OVERLOADS!>fun d(s: String)<!> {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// check no error in overload in different namespaces
|
||||||
|
|
||||||
|
namespace ns1 {
|
||||||
|
fun e() = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace ns2 {
|
||||||
|
fun e() = 1
|
||||||
|
}
|
||||||
|
|
||||||
+1
-1
@@ -15,7 +15,7 @@ fun test(a : A?) {
|
|||||||
a<!UNNECESSARY_SAFE_CALL!>?.<!>buzz() // warning
|
a<!UNNECESSARY_SAFE_CALL!>?.<!>buzz() // warning
|
||||||
}
|
}
|
||||||
|
|
||||||
fun A.test() {
|
fun A.test2() {
|
||||||
foo()
|
foo()
|
||||||
bar()
|
bar()
|
||||||
buzz()
|
buzz()
|
||||||
|
|||||||
@@ -0,0 +1,158 @@
|
|||||||
|
package org.jetbrains.jet.types;
|
||||||
|
|
||||||
|
import org.jetbrains.jet.JetLiteFixture;
|
||||||
|
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||||
|
import org.jetbrains.jet.JetTestUtils;
|
||||||
|
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetNamedFunction;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetPsiFactory;
|
||||||
|
import org.jetbrains.jet.lang.resolve.ClassDescriptorResolver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.OverloadUtil;
|
||||||
|
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Stepan Koltsov
|
||||||
|
*/
|
||||||
|
public class JetOverloadTest extends JetLiteFixture {
|
||||||
|
|
||||||
|
private ModuleDescriptor root = new ModuleDescriptor("test_root");
|
||||||
|
private JetStandardLibrary library;
|
||||||
|
private JetSemanticServices semanticServices;
|
||||||
|
private ClassDescriptorResolver classDescriptorResolver;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
library = JetStandardLibrary.getJetStandardLibrary(getProject());
|
||||||
|
semanticServices = JetSemanticServices.createSemanticServices(library);
|
||||||
|
classDescriptorResolver = semanticServices.getClassDescriptorResolver(JetTestUtils.DUMMY_TRACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getTestDataPath() {
|
||||||
|
return JetTestCaseBuilder.getTestDataPathBase();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBasic() throws Exception {
|
||||||
|
|
||||||
|
assertNotOverloadable(
|
||||||
|
"fun a() : Int",
|
||||||
|
"fun a() : Int");
|
||||||
|
|
||||||
|
assertNotOverloadable(
|
||||||
|
"fun a() : Int",
|
||||||
|
"fun a() : Any");
|
||||||
|
|
||||||
|
assertNotOverloadable(
|
||||||
|
"fun a<T1>() : T1",
|
||||||
|
"fun a<T>() : T");
|
||||||
|
|
||||||
|
assertNotOverloadable(
|
||||||
|
"fun a<T1>(a : T1) : T1",
|
||||||
|
"fun a<T>(a : T) : T");
|
||||||
|
|
||||||
|
assertNotOverloadable(
|
||||||
|
"fun a<T1, X : T1>(a : T1) : T1",
|
||||||
|
"fun a<T, Y : T>(a : T) : T");
|
||||||
|
|
||||||
|
assertNotOverloadable(
|
||||||
|
"fun a<T1, X : T1>(a : T1) : T1",
|
||||||
|
"fun a<T, Y : T>(a : T) : Y");
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
assertOverloadable(
|
||||||
|
"fun ab() : Int",
|
||||||
|
"fun a() : Int");
|
||||||
|
|
||||||
|
assertNotOverloadable(
|
||||||
|
"fun a() : Int",
|
||||||
|
"fun a() : Any");
|
||||||
|
|
||||||
|
assertOverloadable(
|
||||||
|
"fun a(a : Int) : Int",
|
||||||
|
"fun a() : Int");
|
||||||
|
|
||||||
|
assertOverloadable(
|
||||||
|
"fun a() : Int",
|
||||||
|
"fun a(a : Int) : Int");
|
||||||
|
|
||||||
|
assertOverloadable(
|
||||||
|
"fun a(a : Int?) : Int",
|
||||||
|
"fun a(a : Int) : Int");
|
||||||
|
|
||||||
|
// XXX: different from overridable
|
||||||
|
/*
|
||||||
|
assertNotOverloadable(
|
||||||
|
"fun a<T>(a : Int) : Int",
|
||||||
|
"fun a(a : Int) : Int");
|
||||||
|
*/
|
||||||
|
|
||||||
|
assertOverloadable(
|
||||||
|
"fun a<T1, X : T1>(a : T1) : T1",
|
||||||
|
"fun a<T, Y>(a : T) : T");
|
||||||
|
|
||||||
|
assertOverloadable(
|
||||||
|
"fun a<T1, X : T1>(a : T1) : T1",
|
||||||
|
"fun a<T, Y : T>(a : Y) : T");
|
||||||
|
|
||||||
|
assertNotOverloadable(
|
||||||
|
"fun a<T1, X : T1>(a : T1) : X",
|
||||||
|
"fun a<T, Y : T>(a : T) : T");
|
||||||
|
|
||||||
|
assertNotOverloadable(
|
||||||
|
"fun a<T1, X : Array<out T1>>(a : Array<in T1>) : T1",
|
||||||
|
"fun a<T, Y : Array<out T>>(a : Array<in T>) : T");
|
||||||
|
|
||||||
|
assertOverloadable(
|
||||||
|
"fun a<T1, X : Array<T1>>(a : Array<in T1>) : T1",
|
||||||
|
"fun a<T, Y : Array<out T>>(a : Array<in T>) : T");
|
||||||
|
|
||||||
|
assertOverloadable(
|
||||||
|
"fun a<T1, X : Array<out T1>>(a : Array<in T1>) : T1",
|
||||||
|
"fun a<T, Y : Array<in T>>(a : Array<in T>) : T");
|
||||||
|
|
||||||
|
assertOverloadable(
|
||||||
|
"fun a<T1, X : Array<out T1>>(a : Array<in T1>) : T1",
|
||||||
|
"fun a<T, Y : Array<*>>(a : Array<in T>) : T");
|
||||||
|
|
||||||
|
assertOverloadable(
|
||||||
|
"fun a<T1, X : Array<out T1>>(a : Array<in T1>) : T1",
|
||||||
|
"fun a<T, Y : Array<out T>>(a : Array<out T>) : T");
|
||||||
|
|
||||||
|
assertOverloadable(
|
||||||
|
"fun a<T1, X : Array<out T1>>(a : Array<*>) : T1",
|
||||||
|
"fun a<T, Y : Array<out T>>(a : Array<in T>) : T");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertNotOverloadable(String funA, String funB) {
|
||||||
|
assertOverloadabilityRelation(funA, funB, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertOverloadable(String funA, String funB) {
|
||||||
|
assertOverloadabilityRelation(funA, funB, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertOverloadabilityRelation(String funA, String funB, boolean expectedIsError) {
|
||||||
|
FunctionDescriptor a = makeFunction(funA);
|
||||||
|
FunctionDescriptor b = makeFunction(funB);
|
||||||
|
{
|
||||||
|
OverloadUtil.OverloadCompatibilityInfo overloadableWith = OverloadUtil.isOverloadble(a, b);
|
||||||
|
assertEquals(overloadableWith.getMessage(), expectedIsError, !overloadableWith.isSuccess());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
OverloadUtil.OverloadCompatibilityInfo overloadableWith = OverloadUtil.isOverloadble(b, a);
|
||||||
|
assertEquals(overloadableWith.getMessage(), expectedIsError, !overloadableWith.isSuccess());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private FunctionDescriptor makeFunction(String funDecl) {
|
||||||
|
JetNamedFunction function = JetPsiFactory.createFunction(getProject(), funDecl);
|
||||||
|
return classDescriptorResolver.resolveFunctionDescriptor(root, library.getLibraryScope(), function);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -67,6 +67,13 @@ public class JetOverridingTest extends JetLiteFixture {
|
|||||||
"fun a() : Int",
|
"fun a() : Int",
|
||||||
"fun a() : Any");
|
"fun a() : Any");
|
||||||
|
|
||||||
|
// return types are not cheked in the utility
|
||||||
|
/*
|
||||||
|
assertNotOverridable(
|
||||||
|
"fun a() : Any",
|
||||||
|
"fun a() : Int");
|
||||||
|
*/
|
||||||
|
|
||||||
assertNotOverridable(
|
assertNotOverridable(
|
||||||
"fun a(a : Int) : Int",
|
"fun a(a : Int) : Int",
|
||||||
"fun a() : Int");
|
"fun a() : Int");
|
||||||
|
|||||||
Reference in New Issue
Block a user