diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index bb3a578a368..379a1e36630 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -755,4 +755,25 @@ public class JetPsiUtil { public static boolean isInComment(PsiElement element) { return CommentUtilCore.isComment(element) || element instanceof KDocElement; } + + @Nullable + public static JetExpression getCalleeExpressionIfAny(@NotNull JetExpression expression) { + if (expression instanceof JetCallElement) { + JetCallElement callExpression = (JetCallElement) expression; + return callExpression.getCalleeExpression(); + } + if (expression instanceof JetQualifiedExpression) { + JetExpression selectorExpression = ((JetQualifiedExpression) expression).getSelectorExpression(); + if (selectorExpression != null) { + return getCalleeExpressionIfAny(selectorExpression); + } + } + if (expression instanceof JetUnaryExpression) { + return ((JetUnaryExpression) expression).getOperationReference(); + } + if (expression instanceof JetBinaryExpression) { + return ((JetBinaryExpression) expression).getOperationReference(); + } + return null; + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java index fe4b97949a4..9e51ebd58c2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -26,6 +26,7 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; +import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemCompleter; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.name.FqName; @@ -82,6 +83,7 @@ public interface BindingContext { new BasicWritableSlice(DO_NOTHING); WritableSlice> RESOLVED_CALL = new BasicWritableSlice>(DO_NOTHING); + WritableSlice CONSTRAINT_SYSTEM_COMPLETER = new BasicWritableSlice(DO_NOTHING); WritableSlice CALL = new BasicWritableSlice(DO_NOTHING); WritableSlice> AMBIGUOUS_REFERENCE_TARGET = diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index 19c1188212f..f3f5946f9cb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -26,6 +26,10 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.impl.FunctionDescriptorUtil; import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition; +import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem; +import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemCompleter; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.util.CallMaker; import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults; @@ -46,7 +50,8 @@ import java.util.*; import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER; import static org.jetbrains.jet.lang.diagnostics.Errors.*; -import static org.jetbrains.jet.lang.resolve.BindingContext.DEFERRED_TYPE; +import static org.jetbrains.jet.lang.resolve.BindingContext.*; +import static org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults.Code; import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE; public class BodyResolver { @@ -487,10 +492,25 @@ public class BodyResolver { JetScope propertyDeclarationInnerScope = descriptorResolver.getPropertyDeclarationInnerScopeForInitializer( propertyScope, propertyDescriptor.getTypeParameters(), NO_RECEIVER_PARAMETER, trace); - JetType delegateType = expressionTypingServices.safeGetType(propertyDeclarationInnerScope, delegateExpression, NO_EXPECTED_TYPE, - DataFlowInfo.EMPTY, trace); + TemporaryBindingTrace traceToResolveDelegatedProperty = TemporaryBindingTrace.create(trace, "Trace to resolve delegated property"); + JetScope accessorScope = JetScopeUtils.makeScopeForPropertyAccessor( + propertyDescriptor, parentScopeForAccessor, descriptorResolver, trace); + + JetExpression calleeExpression = JetPsiUtil.getCalleeExpressionIfAny(delegateExpression); + ConstraintSystemCompleter completer = + createConstraintSystemCompleter(jetProperty, propertyDescriptor, delegateExpression, accessorScope); + if (calleeExpression != null) { + traceToResolveDelegatedProperty.record(CONSTRAINT_SYSTEM_COMPLETER, calleeExpression, completer); + } + JetType delegateType = expressionTypingServices.safeGetType(propertyDeclarationInnerScope, delegateExpression, NO_EXPECTED_TYPE, + DataFlowInfo.EMPTY, traceToResolveDelegatedProperty); + traceToResolveDelegatedProperty.commit(new TraceEntryFilter() { + @Override + public boolean accept(@NotNull WritableSlice slice, Object key) { + return slice != CONSTRAINT_SYSTEM_COMPLETER; + } + }, true); - JetScope accessorScope = JetScopeUtils.makeScopeForPropertyAccessor(propertyDescriptor, parentScopeForAccessor, descriptorResolver, trace); DelegatedPropertyUtils.resolveDelegatedPropertyGetMethod(propertyDescriptor, delegateExpression, delegateType, expressionTypingServices, trace, accessorScope); @@ -500,6 +520,73 @@ public class BodyResolver { } } + private ConstraintSystemCompleter createConstraintSystemCompleter( + JetProperty property, + final PropertyDescriptor propertyDescriptor, + final JetExpression delegateExpression, + final JetScope accessorScope + ) { + final JetType expectedType = property.getTypeRef() != null ? propertyDescriptor.getType() : NO_EXPECTED_TYPE; + return new ConstraintSystemCompleter() { + @Override + public void completeConstraintSystem( + @NotNull ConstraintSystem constraintSystem, @NotNull ResolvedCall resolvedCall + ) { + JetType returnType = resolvedCall.getCandidateDescriptor().getReturnType(); + if (returnType == null) return; + + TemporaryBindingTrace traceToResolveConventionMethods = + TemporaryBindingTrace.create(trace, "Trace to resolve delegated property convention methods"); + OverloadResolutionResults + getMethodResults = DelegatedPropertyUtils.getDelegatedPropertyConventionMethod( + propertyDescriptor, delegateExpression, returnType, expressionTypingServices, + traceToResolveConventionMethods, accessorScope, true); + + if (conventionMethodFound(getMethodResults)) { + FunctionDescriptor descriptor = getMethodResults.getResultingDescriptor(); + JetType returnTypeOfGetMethod = descriptor.getReturnType(); + if (returnTypeOfGetMethod != null) { + constraintSystem.addSupertypeConstraint(expectedType, returnTypeOfGetMethod, ConstraintPosition.FROM_COMPLETER); + } + addConstraintForThisValue(constraintSystem, descriptor); + } + if (propertyDescriptor.isVar()) { + OverloadResolutionResults setMethodResults = + DelegatedPropertyUtils.getDelegatedPropertyConventionMethod( + propertyDescriptor, delegateExpression, returnType, expressionTypingServices, + traceToResolveConventionMethods, accessorScope, false); + + if (conventionMethodFound(setMethodResults)) { + FunctionDescriptor descriptor = setMethodResults.getResultingDescriptor(); + List valueParameters = descriptor.getValueParameters(); + if (valueParameters.size() == 3) { + ValueParameterDescriptor valueParameterForThis = valueParameters.get(2); + constraintSystem.addSubtypeConstraint(expectedType, valueParameterForThis.getType(), ConstraintPosition.FROM_COMPLETER); + addConstraintForThisValue(constraintSystem, descriptor); + } + } + } + } + + private boolean conventionMethodFound(@NotNull OverloadResolutionResults results) { + return results.isSuccess() || + (results.isSingleResult() && results.getResultCode() == Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH); + } + + private void addConstraintForThisValue(ConstraintSystem constraintSystem, FunctionDescriptor resultingDescriptor) { + ReceiverParameterDescriptor receiverParameter = propertyDescriptor.getReceiverParameter(); + ReceiverParameterDescriptor thisObject = propertyDescriptor.getExpectedThisObject(); + if (receiverParameter == null && thisObject == null) return; + + List valueParameters = resultingDescriptor.getValueParameters(); + if (valueParameters.isEmpty()) return; + ValueParameterDescriptor valueParameterForThis = valueParameters.get(0); + JetType typeOfThis = receiverParameter != null ? receiverParameter.getType() : thisObject.getType(); + constraintSystem.addSubtypeConstraint(typeOfThis, valueParameterForThis.getType(), ConstraintPosition.FROM_COMPLETER); + } + }; + } + public void resolvePropertyInitializer( @NotNull JetProperty property, @NotNull PropertyDescriptor propertyDescriptor, diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java index d79ca3fbbf1..8d15321b81d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java @@ -235,6 +235,21 @@ public class CandidateResolver { constraintSystem.addSupertypeConstraint(context.expectedType, descriptor.getReturnType(), ConstraintPosition.EXPECTED_TYPE_POSITION); + ConstraintSystemCompleter constraintSystemCompleter = context.trace.get( + BindingContext.CONSTRAINT_SYSTEM_COMPLETER, context.call.getCalleeExpression()); + if (constraintSystemCompleter != null) { + ConstraintSystemImpl backup = (ConstraintSystemImpl) constraintSystem.copy(); + + //todo improve error reporting with errors in constraints from completer + constraintSystemCompleter.completeConstraintSystem(constraintSystem, resolvedCall); + if (constraintSystem.hasTypeConstructorMismatchAt(ConstraintPosition.FROM_COMPLETER) || + (constraintSystem.hasContradiction() && !backup.hasContradiction())) { + + constraintSystem = backup; + resolvedCall.setConstraintSystem(backup); + } + } + if (constraintSystem.hasContradiction()) { return reportInferenceError(context); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintPosition.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintPosition.java index c8c77099e8d..d2343cb0e7b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintPosition.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintPosition.java @@ -24,6 +24,7 @@ public class ConstraintPosition { public static final ConstraintPosition RECEIVER_POSITION = new ConstraintPosition("RECEIVER_POSITION"); public static final ConstraintPosition EXPECTED_TYPE_POSITION = new ConstraintPosition("EXPECTED_TYPE_POSITION"); public static final ConstraintPosition BOUND_CONSTRAINT_POSITION = new ConstraintPosition("BOUND_CONSTRAINT_POSITION"); + public static final ConstraintPosition FROM_COMPLETER = new ConstraintPosition("FROM_COMPLETER"); private static final Map valueParameterPositions = Maps.newHashMap(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemCompleter.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemCompleter.java new file mode 100644 index 00000000000..20df3897113 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemCompleter.java @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.resolve.calls.inference; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; + +public interface ConstraintSystemCompleter { + void completeConstraintSystem( + @NotNull ConstraintSystem constraintSystem, + @NotNull ResolvedCall resolvedCall + ); +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DelegatedPropertyUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DelegatedPropertyUtils.java index c852ed51ad2..2165091bd94 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DelegatedPropertyUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DelegatedPropertyUtils.java @@ -123,8 +123,48 @@ public class DelegatedPropertyUtils { PropertyAccessorDescriptor accessor = isGet ? propertyDescriptor.getGetter() : propertyDescriptor.getSetter(); assert accessor != null : "Delegated property should have getter/setter " + propertyDescriptor + " " + delegateExpression.getText(); + if (trace.getBindingContext().get(DELEGATED_PROPERTY_CALL, accessor) != null) return; + + OverloadResolutionResults functionResults = getDelegatedPropertyConventionMethod( + propertyDescriptor, delegateExpression, delegateType, expressionTypingServices, trace, scope, isGet); Call call = trace.getBindingContext().get(DELEGATED_PROPERTY_CALL, accessor); - if (call != null) return; + assert call != null : "'getDelegatedPropertyConventionMethod' didn't record a call"; + + if (!functionResults.isSuccess()) { + String expectedFunction = renderCall(call, trace.getBindingContext()); + if (functionResults.isIncomplete()) { + trace.report(DELEGATE_SPECIAL_FUNCTION_MISSING.on(delegateExpression, expectedFunction, delegateType)); + } + else if (functionResults.isSingleResult() || + functionResults.getResultCode() == OverloadResolutionResults.Code.MANY_FAILED_CANDIDATES) { + trace.report(DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE + .on(delegateExpression, expectedFunction, functionResults.getResultingCalls())); + } + else if (functionResults.isAmbiguity()) { + trace.report(DELEGATE_SPECIAL_FUNCTION_AMBIGUITY + .on(delegateExpression, expectedFunction, functionResults.getResultingCalls())); + } + else { + trace.report(DELEGATE_SPECIAL_FUNCTION_MISSING.on(delegateExpression, expectedFunction, delegateType)); + } + return; + } + + trace.record(DELEGATED_PROPERTY_RESOLVED_CALL, accessor, functionResults.getResultingCall()); + } + + /* Resolve get() or set() methods from delegate */ + public static OverloadResolutionResults getDelegatedPropertyConventionMethod( + @NotNull PropertyDescriptor propertyDescriptor, + @NotNull JetExpression delegateExpression, + @NotNull JetType delegateType, + @NotNull ExpressionTypingServices expressionTypingServices, + @NotNull BindingTrace trace, + @NotNull JetScope scope, + boolean isGet + ) { + PropertyAccessorDescriptor accessor = isGet ? propertyDescriptor.getGetter() : propertyDescriptor.getSetter(); + assert accessor != null : "Delegated property should have getter/setter " + propertyDescriptor + " " + delegateExpression.getText(); ExpressionTypingContext context = ExpressionTypingContext.newContext( expressionTypingServices, trace, scope, @@ -144,39 +184,17 @@ public class DelegatedPropertyUtils { propertyDescriptor.getType()); arguments.add(fakeArgument); List valueParameters = accessor.getValueParameters(); - context.trace.record(REFERENCE_TARGET, fakeArgument, valueParameters.get(0)); + trace.record(REFERENCE_TARGET, fakeArgument, valueParameters.get(0)); } Name functionName = Name.identifier(isGet ? "get" : "set"); JetReferenceExpression fakeCalleeExpression = createSimpleName(project, functionName.asString()); ExpressionReceiver receiver = new ExpressionReceiver(delegateExpression, delegateType); - call = CallMaker.makeCallWithExpressions(fakeCalleeExpression, receiver, null, fakeCalleeExpression, arguments, Call.CallType.DEFAULT); - context.trace.record(BindingContext.DELEGATED_PROPERTY_CALL, accessor, call); + Call call = CallMaker.makeCallWithExpressions(fakeCalleeExpression, receiver, null, fakeCalleeExpression, arguments, Call.CallType.DEFAULT); + trace.record(BindingContext.DELEGATED_PROPERTY_CALL, accessor, call); - OverloadResolutionResults functionResults = context.resolveCallWithGivenName(call, fakeCalleeExpression, functionName); - - if (!functionResults.isSuccess()) { - String expectedFunction = renderCall(call, trace.getBindingContext()); - if (functionResults.isIncomplete()) { - context.trace.report(DELEGATE_SPECIAL_FUNCTION_MISSING.on(delegateExpression, expectedFunction, delegateType)); - } - else if (functionResults.isSingleResult() || - functionResults.getResultCode() == OverloadResolutionResults.Code.MANY_FAILED_CANDIDATES) { - context.trace.report(DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE - .on(delegateExpression, expectedFunction, functionResults.getResultingCalls())); - } - else if (functionResults.isAmbiguity()) { - context.trace.report(DELEGATE_SPECIAL_FUNCTION_AMBIGUITY - .on(delegateExpression, expectedFunction, functionResults.getResultingCalls())); - } - else { - context.trace.report(DELEGATE_SPECIAL_FUNCTION_MISSING.on(delegateExpression, expectedFunction, delegateType)); - } - return; - } - - context.trace.record(DELEGATED_PROPERTY_RESOLVED_CALL, accessor, functionResults.getResultingCall()); + return context.resolveCallWithGivenName(call, fakeCalleeExpression, functionName); } private static String renderCall(@NotNull Call call, @NotNull BindingContext context) { diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/differentDelegatedExpressions.kt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/differentDelegatedExpressions.kt new file mode 100644 index 00000000000..fe071d20932 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/differentDelegatedExpressions.kt @@ -0,0 +1,50 @@ +package baz + +class A(outer: Outer) { + var i: String by + getMyConcreteProperty() + var d: String by getMyConcreteProperty() - 1 + var c: String by O.getMyProperty() + var g: String by outer.getContainer().getMyProperty() + + + var b: String by foo(getMyProperty()) + var r: String by foo(outer.getContainer().getMyProperty()) + var e: String by + foo(getMyProperty()) + var f: String by foo(getMyProperty()) - 1 +} + +fun foo(a: Any?) = MyProperty() + +fun getMyProperty() = MyProperty() + +fun getMyConcreteProperty() = MyProperty() + +class MyProperty { + + public fun get(thisRef: R, desc: PropertyMetadata): T { + println("get $thisRef ${desc.name}") + return null as T + } + + public fun set(thisRef: R, desc: PropertyMetadata, value: T) { + println("set $thisRef ${desc.name} $value") + } +} + +fun MyProperty.plus() = MyProperty() +fun MyProperty.minus(i: Int) = MyProperty() + +object O { + fun getMyProperty() = MyProperty() +} + +trait MyPropertyContainer { + fun getMyProperty(): MyProperty +} + +trait Outer { + fun getContainer(): MyPropertyContainer +} + +// ----------------- +fun println(a: Any?) = a \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/noErrorsForImplicitConstraints.kt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/noErrorsForImplicitConstraints.kt new file mode 100644 index 00000000000..8a4bdbe9836 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/noErrorsForImplicitConstraints.kt @@ -0,0 +1,42 @@ +package foo + +class A { + var a5: String by MyProperty1() + var b5: String by getMyProperty1() +} + +fun getMyProperty1() = MyProperty1() + +class MyProperty1 { + + public fun get(thisRef: R, desc: PropertyMetadata): T { + throw Exception() + } + + public fun set(i: Int, j: Int, k: Int) { + println("set") + } +} + +// ----------------- + +class B { + var a5: String by MyProperty2() + var b5: String by getMyProperty2() +} + +fun getMyProperty2() = MyProperty2() + +class MyProperty2 { + + public fun get(thisRef: R, desc: PropertyMetadata): T { + throw Exception() + } + + public fun set(i: Int) { + println("set") + } +} + +// ----------------- +fun println(a: Any?) = a \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/useExpectedType.kt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/useExpectedType.kt new file mode 100644 index 00000000000..ac018117d76 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/useExpectedType.kt @@ -0,0 +1,84 @@ +package foo + +class A1 { + var a1: String by MyProperty1() + var b1: String by getMyProperty1() +} + +var c1: String by getMyProperty1() + +fun getMyProperty1() = MyProperty1() + +class MyProperty1 { + + public fun get(thisRef: R, desc: PropertyMetadata): T { + println("get $thisRef ${desc.name}") + throw Exception() + } + + public fun set(thisRef: R, desc: PropertyMetadata, value: T) { + println("set $thisRef ${desc.name} $value") + } +} + +//-------------------------- + +class A2 { + var a2: String by MyProperty2() + var b2: String by getMyProperty2() +} + +fun getMyProperty2() = MyProperty2() + +class MyProperty2 { + + public fun get(thisRef: Any?, desc: PropertyMetadata): T { + println("get $thisRef ${desc.name}") + throw Exception() + } + + public fun set(thisRef: Any?, desc: PropertyMetadata, value: T) { + println("set $thisRef ${desc.name} $value") + } +} + +//-------------------------- + +class A3 { + var a3: String by MyProperty3() + var b3: String by getMyProperty3() +} + +fun getMyProperty3() = MyProperty3() + +class MyProperty3 { + + public fun get(thisRef: T, desc: PropertyMetadata): String { + println("get $thisRef ${desc.name}") + return "" + } + + public fun set(thisRef: Any?, desc: PropertyMetadata, value: T) { + println("set $thisRef ${desc.name} $value") + } +} + +//-------------------------- + +class A4 { + val a4: String by MyProperty4() + val b4: String by getMyProperty4() +} + +fun getMyProperty4() = MyProperty4() + +class MyProperty4 { + + public fun get(thisRef: R, desc: PropertyMetadata): T { + println("get $thisRef ${desc.name}") + throw Exception() + } +} + +//-------------------------- +fun println(a: Any?) = a \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 3ccf049c0d8..6c6e4d1a01c 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -1888,6 +1888,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage } @TestMetadata("compiler/testData/diagnostics/tests/delegatedProperty") + @InnerTestClasses({DelegatedProperty.Inference.class}) public static class DelegatedProperty extends AbstractDiagnosticsTestWithEagerResolve { @TestMetadata("absentErrorAboutInitializer.kt") public void testAbsentErrorAboutInitializer() throws Exception { @@ -2053,6 +2054,35 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/delegatedProperty/wrongSetterReturnType.kt"); } + @TestMetadata("compiler/testData/diagnostics/tests/delegatedProperty/inference") + public static class Inference extends AbstractDiagnosticsTestWithEagerResolve { + public void testAllFilesPresentInInference() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/delegatedProperty/inference"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("differentDelegatedExpressions.kt") + public void testDifferentDelegatedExpressions() throws Exception { + doTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/differentDelegatedExpressions.kt"); + } + + @TestMetadata("noErrorsForImplicitConstraints.kt") + public void testNoErrorsForImplicitConstraints() throws Exception { + doTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/noErrorsForImplicitConstraints.kt"); + } + + @TestMetadata("useExpectedType.kt") + public void testUseExpectedType() throws Exception { + doTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/useExpectedType.kt"); + } + + } + + public static Test innerSuite() { + TestSuite suite = new TestSuite("DelegatedProperty"); + suite.addTestSuite(DelegatedProperty.class); + suite.addTestSuite(Inference.class); + return suite; + } } @TestMetadata("compiler/testData/diagnostics/tests/deparenthesize") @@ -4717,6 +4747,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/smartCasts"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("combineWithNoSelectorInfo.kt") + public void testCombineWithNoSelectorInfo() throws Exception { + doTest("compiler/testData/diagnostics/tests/smartCasts/combineWithNoSelectorInfo.kt"); + } + @TestMetadata("kt1461.kt") public void testKt1461() throws Exception { doTest("compiler/testData/diagnostics/tests/smartCasts/kt1461.kt"); @@ -4945,7 +4980,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage suite.addTestSuite(DataFlow.class); suite.addTestSuite(DataFlowInfoTraversal.class); suite.addTest(DeclarationChecks.innerSuite()); - suite.addTestSuite(DelegatedProperty.class); + suite.addTest(DelegatedProperty.innerSuite()); suite.addTestSuite(Deparenthesize.class); suite.addTest(Enum.innerSuite()); suite.addTestSuite(Extensions.class); diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index aa30ff43a69..bd7388a1c49 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -1546,8 +1546,8 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/defaultArguments/constructor/kt2852.kt"); } - } - + } + @TestMetadata("compiler/testData/codegen/box/defaultArguments/function") public static class Function extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInFunction() throws Exception {