Changed name resolution for dynamic extension. Added annotation DynamicExtension.

This commit is contained in:
Stanislav Erokhin
2016-12-14 00:50:16 +03:00
parent 91fcb15f3e
commit 457918a6dd
34 changed files with 319 additions and 61 deletions
@@ -828,6 +828,8 @@ public interface Errors {
DiagnosticFactory0<PsiElement> ABBREVIATED_NOTHING_PROPERTY_TYPE = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<PsiElement, KotlinType> IMPLICIT_INTERSECTION_TYPE = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<KtCallableDeclaration> DYNAMIC_RECEIVER_NOT_ALLOWED = DiagnosticFactory0.create(ERROR, PositioningStrategies.RECEIVER);
// Context tracking
DiagnosticFactory1<KtExpression, KtExpression> EXPRESSION_EXPECTED = DiagnosticFactory1.create(ERROR);
@@ -492,4 +492,11 @@ object PositioningStrategies {
return markElement(element.returnKeyword)
}
}
@JvmField val RECEIVER: PositioningStrategy<KtCallableDeclaration> = object : DeclarationHeader<KtCallableDeclaration>() {
override fun mark(element: KtCallableDeclaration): List<TextRange> {
element.receiverTypeReference?.let { return markElement(it) }
return DEFAULT.mark(element)
}
}
}
@@ -635,6 +635,8 @@ public class DefaultErrorMessages {
MAP.put(IMPLICIT_INTERSECTION_TYPE, "Inferred type {0} is an intersection, please specify the required type explicitly", RENDER_TYPE);
MAP.put(EXPECTED_CONDITION, "Expected condition of type Boolean");
MAP.put(DYNAMIC_RECEIVER_NOT_ALLOWED, "Dynamic receiver is prohibited");
MAP.put(CANNOT_CHECK_FOR_ERASED, "Cannot check for instance of erased type: {0}", RENDER_TYPE);
MAP.put(UNCHECKED_CAST, "Unchecked cast: {0} to {1}", RENDER_TYPE, RENDER_TYPE);
@@ -75,7 +75,8 @@ private val DEFAULT_DECLARATION_CHECKERS = listOf(
InfixModifierChecker(),
CoroutineModifierChecker,
SinceKotlinAnnotationValueChecker,
ReifiedTypeParameterAnnotationChecker()
ReifiedTypeParameterAnnotationChecker(),
DynamicReceiverChecker
)
private val DEFAULT_CALL_CHECKERS = listOf(
@@ -43,6 +43,7 @@ import org.jetbrains.kotlin.resolve.calls.results.ResolutionResultsHandler
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.calls.tasks.*
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDynamicExtensionAnnotation
import org.jetbrains.kotlin.resolve.isHiddenInResolution
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.MemberScope
@@ -347,10 +348,21 @@ class NewResolutionOldInference(
basicCallContext.dataFlowInfoForArguments // todo may be we should create new mutable info for arguments
)
// see spec-docs/dynamic-types.md
if (extensionReceiver != null && extensionReceiver.receiverValue.type.isDynamic()
&& !towerCandidate.descriptor.extensionReceiverParameter!!.value.type.isDynamic()) {
return MyCandidate(ResolutionCandidateStatus(listOf(ExtensionWithStaticTypeWithDynamicReceiver)), candidateCall)
/**
* See https://jetbrains.quip.com/qcTDAFcgFLEM
*
* For now we have only 2 functions with dynamic receivers: iterator() and unsafeCast()
* Both this function are marked via @kotlin.internal.DynamicExtension.
*/
if (extensionReceiver != null) {
val parameterIsDynamic = towerCandidate.descriptor.extensionReceiverParameter!!.value.type.isDynamic()
val argumentIsDynamic = extensionReceiver.receiverValue.type.isDynamic()
if (parameterIsDynamic != argumentIsDynamic ||
(parameterIsDynamic && !towerCandidate.descriptor.hasDynamicExtensionAnnotation())
) {
return MyCandidate(ResolutionCandidateStatus(listOf(HiddenExtensionRelatedToDynamicTypes)), candidateCall)
}
}
if (towerCandidate.descriptor.isHiddenInResolution(languageVersionSettings, basicCallContext.isSuperCall)) {
@@ -0,0 +1,46 @@
/*
* Copyright 2010-2016 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.kotlin.resolve.checkers
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDynamicExtensionAnnotation
import org.jetbrains.kotlin.types.isDynamic
object DynamicReceiverChecker : SimpleDeclarationChecker {
override fun check(
declaration: KtDeclaration,
descriptor: DeclarationDescriptor,
diagnosticHolder: DiagnosticSink,
bindingContext: BindingContext
) {
if (descriptor !is CallableDescriptor || declaration !is KtCallableDeclaration || descriptor.hasDynamicExtensionAnnotation()) return
// function expression
if (declaration is KtNamedFunction && declaration.name == null) return
if (descriptor.extensionReceiverParameter?.value?.type?.isDynamic() == true) {
diagnosticHolder.report(Errors.DYNAMIC_RECEIVER_NOT_ALLOWED.on(declaration))
}
}
}
@@ -90,7 +90,7 @@ object ErrorDescriptorDiagnostic : ResolutionDiagnostic(ResolutionCandidateAppli
object LowPriorityDescriptorDiagnostic : ResolutionDiagnostic(ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY)
object DynamicDescriptorDiagnostic: ResolutionDiagnostic(ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY)
object UnstableSmartCastDiagnostic: ResolutionDiagnostic(ResolutionCandidateApplicability.MAY_THROW_RUNTIME_ERROR)
object ExtensionWithStaticTypeWithDynamicReceiver: ResolutionDiagnostic(ResolutionCandidateApplicability.HIDDEN)
object HiddenExtensionRelatedToDynamicTypes : ResolutionDiagnostic(ResolutionCandidateApplicability.HIDDEN)
object HiddenDescriptor: ResolutionDiagnostic(ResolutionCandidateApplicability.HIDDEN)
object InvokeConventionCallNoOperatorModifier : ResolutionDiagnostic(ResolutionCandidateApplicability.CONVENTION_ERROR)
@@ -20,7 +20,7 @@ public class J {
import p.*
class K: J.C() {
fun <!UNSUPPORTED!>dynamic<!>.test() {
fun <!UNSUPPORTED, DYNAMIC_RECEIVER_NOT_ALLOWER!>dynamic<!>.test() {
<!DEBUG_INFO_DYNAMIC!>sam<!>(null)
<!DEBUG_INFO_DYNAMIC!>sam<!>(
name = null,
@@ -0,0 +1,8 @@
public final var foo: dynamic
public final fun <get-foo>(): dynamic
public final fun <set-foo>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final var bar: dynamic
public final fun <get-bar>(): dynamic
public final fun <set-bar>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final fun dynamicProperty(): dynamic
public final fun dynamicParameter(): dynamic
@@ -0,0 +1,17 @@
// !MARK_DYNAMIC_CALLS
fun withDynamicReceiver(<!UNUSED_PARAMETER!>d<!>: dynamic.() -> Unit) {}
fun test() = withDynamicReceiver {
<!DEBUG_INFO_DYNAMIC!>foo<!>
<!DEBUG_INFO_DYNAMIC!>bar<!> = 1
}
fun test2() = withDynamicReceiver(fun dynamic.() {})
val dynamicProperty: dynamic.() -> Unit = TODO()
fun test(d: dynamic, <!UNUSED_PARAMETER!>dynamicParameter<!>: dynamic.() -> Unit) {
d.<!DEBUG_INFO_DYNAMIC!>dynamicProperty<!>()
d.<!DEBUG_INFO_DYNAMIC!>dynamicParameter<!>()
}
@@ -0,0 +1,7 @@
package
public val dynamicProperty: dynamic.() -> kotlin.Unit
public fun test(): kotlin.Unit
public fun test(/*0*/ d: dynamic, /*1*/ dynamicParameter: dynamic.() -> kotlin.Unit): kotlin.Unit
public fun test2(): kotlin.Unit
public fun withDynamicReceiver(/*0*/ d: dynamic.() -> kotlin.Unit): kotlin.Unit
@@ -7,7 +7,7 @@ fun test() {
}
}
fun <T> dynamic(body: dynamic.() -> T): T {
fun <T> dynamic(<!UNUSED_PARAMETER!>body<!>: dynamic.() -> T): T {
val topLevel = null
return topLevel.body()
return topLevel.<!UNRESOLVED_REFERENCE!>body<!>()
}
@@ -0,0 +1,28 @@
// !MARK_DYNAMIC_CALLS
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@kotlin.internal.DynamicExtension
fun dynamic.onDynamicFun() = 1
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@kotlin.internal.DynamicExtension
var dynamic.onDynamicProperty
get() = ""
set(value) {}
fun test(d: dynamic, a: Any?) {
eatT<Int>(d.onDynamicFun())
eatT<String>(d.onDynamicProperty)
d.onDynamicProperty = ""
eatT<Iterator<*>>(d.iterator())
for (item in d) {
println(item)
}
a.<!UNRESOLVED_REFERENCE!>onDynamicFun<!>()
a.<!UNRESOLVED_REFERENCE!>onDynamicProperty<!>
}
fun <T> eatT(<!UNUSED_PARAMETER!>t<!>: T) {}
@@ -0,0 +1,6 @@
package
@kotlin.Suppress(names = {"INVISIBLE_MEMBER", "INVISIBLE_REFERENCE"}) @kotlin.internal.DynamicExtension public var dynamic.onDynamicProperty: kotlin.String
public fun </*0*/ T> eatT(/*0*/ t: T): kotlin.Unit
public fun test(/*0*/ d: dynamic, /*1*/ a: kotlin.Any?): kotlin.Unit
@kotlin.Suppress(names = {"INVISIBLE_MEMBER", "INVISIBLE_REFERENCE"}) @kotlin.internal.DynamicExtension public fun dynamic.onDynamicFun(): kotlin.Int
@@ -3,7 +3,7 @@ object X2
class Inv<T>
fun dynamic.foo() = X1
fun <!DYNAMIC_RECEIVER_NOT_ALLOWED!>dynamic<!>.foo() = X1
fun <T> Inv<T>.foo() = X2
fun test(): X2 = Inv<Any>().foo()
@@ -22,6 +22,12 @@ public final var onNullableAnyVal: dynamic
public final var onStringVal: dynamic
public final fun <get-onStringVal>(): dynamic
public final fun <set-onStringVal>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final var onDynamicVal: dynamic
public final fun <get-onDynamicVal>(): dynamic
public final fun <set-onDynamicVal>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final var onDynamicVal: dynamic
public final fun <get-onDynamicVal>(): dynamic
public final fun <set-onDynamicVal>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final var memberVal: dynamic
public final fun <get-memberVal>(): dynamic
public final fun <set-memberVal>(/*0*/ <set-?>: dynamic): kotlin.Unit
@@ -19,29 +19,29 @@ fun test(d: dynamic) {
d.<!DEBUG_INFO_DYNAMIC!>onStringVal<!> = 1
<!VAL_REASSIGNMENT!>d.onDynamicVal<!> = 1
d.<!DEBUG_INFO_DYNAMIC!>onDynamicVal<!> = 1
(d as String).onStringVal
(d as Any).onAnyVal
(d as Any?).onNullableAnyVal
(d as Any).onDynamicVal
(d as Any).<!UNRESOLVED_REFERENCE!>onDynamicVal<!>
}
fun testReassignmentWithSafeCall(d: dynamic) {
<!VAL_REASSIGNMENT!>d?.onDynamicVal<!> = 1
d?.<!DEBUG_INFO_DYNAMIC!>onDynamicVal<!> = 1
}
fun testReassignmentWithStaticCalls(d: dynamic) {
<!VAL_REASSIGNMENT!>(d as String).onStringVal<!> = 1
<!VAL_REASSIGNMENT!>(d as Any).onAnyVal<!> = 1
<!VAL_REASSIGNMENT!>(d as Any?).onNullableAnyVal<!> = 1
<!VAL_REASSIGNMENT!>(d as Any).onDynamicVal<!> = 1
(d as Any).<!UNRESOLVED_REFERENCE!>onDynamicVal<!> = 1
}
val Any.onAnyVal: Int get() = 1
val Any?.onNullableAnyVal: Int get() = 1
val String.onStringVal: Int get() = 1
val dynamic.onDynamicVal: Int get() = 1
val <!DYNAMIC_RECEIVER_NOT_ALLOWED!>dynamic<!>.onDynamicVal: Int get() = 1
class C {
fun test(d: dynamic) {
@@ -22,6 +22,12 @@ public final var onNullableAnyVar: dynamic
public final var onStringVar: dynamic
public final fun <get-onStringVar>(): dynamic
public final fun <set-onStringVar>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final var onDynamicVar: dynamic
public final fun <get-onDynamicVar>(): dynamic
public final fun <set-onDynamicVar>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final var onDynamicVar: dynamic
public final fun <get-onDynamicVar>(): dynamic
public final fun <set-onDynamicVar>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final var memberVar: dynamic
public final fun <get-memberVar>(): dynamic
public final fun <set-memberVar>(/*0*/ <set-?>: dynamic): kotlin.Unit
@@ -20,19 +20,19 @@ fun test(d: dynamic) {
d.<!DEBUG_INFO_DYNAMIC!>onStringVar<!> = 1
d.onDynamicVar = 1
d.<!DEBUG_INFO_DYNAMIC!>onDynamicVar<!> = 1
d?.onDynamicVar = 1
d?.<!DEBUG_INFO_DYNAMIC!>onDynamicVar<!> = 1
(d as String).onStringVar
(d as Any).onAnyVar
(d as Any?).onNullableAnyVar
(d as Any).onDynamicVar
(d as Any).<!UNRESOLVED_REFERENCE!>onDynamicVar<!>
(d as String).onStringVar = 1
(d as Any).onAnyVar = 1
(d as Any?).onNullableAnyVar = 1
(d as Any).onDynamicVar = 1
(d as Any).<!UNRESOLVED_REFERENCE!>onDynamicVar<!> = 1
}
var Any.onAnyVar: Int
@@ -47,7 +47,7 @@ var String.onStringVar: Int
get() = 1
set(v) {}
var dynamic.onDynamicVar: Int
var <!DYNAMIC_RECEIVER_NOT_ALLOWED!>dynamic<!>.onDynamicVar: Int
get() = 1
set(v) {}
@@ -4,5 +4,7 @@ public final fun onAny(): dynamic
public final fun onAny(/*0*/ p0: dynamic): dynamic
public final fun onNullableAny(): dynamic
public final fun onString(): dynamic
public final fun onDynamic(): dynamic
public final fun onDynamic(): dynamic
public final fun member(): dynamic
public final fun memberExtension(): dynamic
@@ -13,19 +13,19 @@ fun test(d: dynamic) {
d.<!DEBUG_INFO_DYNAMIC!>onNullableAny<!>()
d.<!DEBUG_INFO_DYNAMIC!>onString<!>()
d.onDynamic()
d?.onDynamic()
d.<!DEBUG_INFO_DYNAMIC!>onDynamic<!>()
d?.<!DEBUG_INFO_DYNAMIC!>onDynamic<!>()
(d as String).onString()
(d as Any).onAny()
(d as Any?).onNullableAny()
(d as Any).onDynamic()
(d as Any).<!UNRESOLVED_REFERENCE!>onDynamic<!>()
}
fun Any.onAny() {}
fun Any?.onNullableAny() {}
fun String.onString() {}
fun dynamic.onDynamic() {}
fun <!DYNAMIC_RECEIVER_NOT_ALLOWED!>dynamic<!>.onDynamic() {}
class C {
fun test(d: dynamic) {
@@ -0,0 +1,54 @@
public final fun onDynamic(): dynamic
public final fun onNullableDynamic(): dynamic
public final var valOnDynamic: dynamic
public final fun <get-valOnDynamic>(): dynamic
public final fun <set-valOnDynamic>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final var valOnDynamic: dynamic
public final fun <get-valOnDynamic>(): dynamic
public final fun <set-valOnDynamic>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final var varOnDynamic: dynamic
public final fun <get-varOnDynamic>(): dynamic
public final fun <set-varOnDynamic>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final var varOnDynamic: dynamic
public final fun <get-varOnDynamic>(): dynamic
public final fun <set-varOnDynamic>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final fun onDynamic(): dynamic
public final fun onNullableDynamic(): dynamic
public final var valOnDynamic: dynamic
public final fun <get-valOnDynamic>(): dynamic
public final fun <set-valOnDynamic>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final var valOnDynamic: dynamic
public final fun <get-valOnDynamic>(): dynamic
public final fun <set-valOnDynamic>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final var varOnDynamic: dynamic
public final fun <get-varOnDynamic>(): dynamic
public final fun <set-varOnDynamic>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final var varOnDynamic: dynamic
public final fun <get-varOnDynamic>(): dynamic
public final fun <set-varOnDynamic>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final fun onDynamic(): dynamic
public final fun onNullableDynamic(): dynamic
public final var valOnDynamic: dynamic
public final fun <get-valOnDynamic>(): dynamic
public final fun <set-valOnDynamic>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final var valOnDynamic: dynamic
public final fun <get-valOnDynamic>(): dynamic
public final fun <set-valOnDynamic>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final var varOnDynamic: dynamic
public final fun <get-varOnDynamic>(): dynamic
public final fun <set-varOnDynamic>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final var varOnDynamic: dynamic
public final fun <get-varOnDynamic>(): dynamic
public final fun <set-varOnDynamic>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final var memberExtensionVar: dynamic
public final fun <get-memberExtensionVar>(): dynamic
public final fun <set-memberExtensionVar>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final var memberExtensionVar: dynamic
public final fun <get-memberExtensionVar>(): dynamic
public final fun <set-memberExtensionVar>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final var memberExtensionVal: dynamic
public final fun <get-memberExtensionVal>(): dynamic
public final fun <set-memberExtensionVal>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final var memberExtensionVal: dynamic
public final fun <get-memberExtensionVal>(): dynamic
public final fun <set-memberExtensionVal>(/*0*/ <set-?>: dynamic): kotlin.Unit
@@ -1,58 +1,58 @@
// !MARK_DYNAMIC_CALLS
fun test(d: dynamic) {
d.onDynamic()
d.onNullableDynamic()
d.<!DEBUG_INFO_DYNAMIC!>onDynamic<!>()
d.<!DEBUG_INFO_DYNAMIC!>onNullableDynamic<!>()
d.valOnDynamic
<!VAL_REASSIGNMENT!>d.valOnDynamic<!> = 1
d.<!DEBUG_INFO_DYNAMIC!>valOnDynamic<!>
d.<!DEBUG_INFO_DYNAMIC!>valOnDynamic<!> = 1
d.varOnDynamic
d.varOnDynamic = 1
d.<!DEBUG_INFO_DYNAMIC!>varOnDynamic<!>
d.<!DEBUG_INFO_DYNAMIC!>varOnDynamic<!> = 1
}
fun dynamic.extTest() {
onDynamic()
onNullableDynamic()
fun <!DYNAMIC_RECEIVER_NOT_ALLOWED!>dynamic<!>.extTest() {
<!DEBUG_INFO_DYNAMIC!>onDynamic<!>()
<!DEBUG_INFO_DYNAMIC!>onNullableDynamic<!>()
valOnDynamic
<!VAL_REASSIGNMENT!>valOnDynamic<!> = 1
<!DEBUG_INFO_DYNAMIC!>valOnDynamic<!>
<!DEBUG_INFO_DYNAMIC!>valOnDynamic<!> = 1
varOnDynamic
varOnDynamic = 1
<!DEBUG_INFO_DYNAMIC!>varOnDynamic<!>
<!DEBUG_INFO_DYNAMIC!>varOnDynamic<!> = 1
this.onDynamic()
this.onNullableDynamic()
this.<!DEBUG_INFO_DYNAMIC!>onDynamic<!>()
this.<!DEBUG_INFO_DYNAMIC!>onNullableDynamic<!>()
this.valOnDynamic
this.valOnDynamic = 1
this.<!DEBUG_INFO_DYNAMIC!>valOnDynamic<!>
this.<!DEBUG_INFO_DYNAMIC!>valOnDynamic<!> = 1
this.varOnDynamic
this.varOnDynamic = 1
this.<!DEBUG_INFO_DYNAMIC!>varOnDynamic<!>
this.<!DEBUG_INFO_DYNAMIC!>varOnDynamic<!> = 1
}
fun dynamic.onDynamic() {}
fun dynamic<!REDUNDANT_NULLABLE!>?<!>.onNullableDynamic() {}
fun <!DYNAMIC_RECEIVER_NOT_ALLOWED!>dynamic<!>.onDynamic() {}
fun <!DYNAMIC_RECEIVER_NOT_ALLOWED!>dynamic<!REDUNDANT_NULLABLE!>?<!><!>.onNullableDynamic() {}
val dynamic.valOnDynamic: Int get() = 1
val <!DYNAMIC_RECEIVER_NOT_ALLOWED!>dynamic<!>.valOnDynamic: Int get() = 1
var dynamic.varOnDynamic: Int
var <!DYNAMIC_RECEIVER_NOT_ALLOWED!>dynamic<!>.varOnDynamic: Int
get() = 1
set(v) {}
class ForMemberExtensions {
fun test(d: dynamic) {
d.memberExtensionVar
d.memberExtensionVar = 1
d.<!DEBUG_INFO_DYNAMIC!>memberExtensionVar<!>
d.<!DEBUG_INFO_DYNAMIC!>memberExtensionVar<!> = 1
d.memberExtensionVal
<!VAL_REASSIGNMENT!>d.memberExtensionVal<!> = 1
d.<!DEBUG_INFO_DYNAMIC!>memberExtensionVal<!>
d.<!DEBUG_INFO_DYNAMIC!>memberExtensionVal<!> = 1
}
val dynamic.memberExtensionVal: Int get() = 1
var dynamic.memberExtensionVar: Int
val <!DYNAMIC_RECEIVER_NOT_ALLOWED!>dynamic<!>.memberExtensionVal: Int get() = 1
var <!DYNAMIC_RECEIVER_NOT_ALLOWED!>dynamic<!>.memberExtensionVar: Int
get() = 1
set(v) {}
}
@@ -1,4 +1,4 @@
fun dynamic.test() {
fun <!DYNAMIC_RECEIVER_NOT_ALLOWED!>dynamic<!>.test() {
val v1 = foo()
v1.isDynamic() // to check that anything is resolvable
@@ -1 +1,3 @@
public final fun foo(/*0*/ p0: dynamic, /*1*/ p1: dynamic): dynamic
public final fun foo(/*0*/ p0: dynamic, /*1*/ p1: dynamic): dynamic
public final fun foo(/*0*/ p0: dynamic, /*1*/ p1: dynamic): dynamic
@@ -1,11 +1,11 @@
// !MARK_DYNAMIC_CALLS
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun dynamic.foo(s: String, a: Any) {}
fun dynamic.foo(s: Any, a: String) {}
fun <!DYNAMIC_RECEIVER_NOT_ALLOWED!>dynamic<!>.foo(s: String, a: Any) {}
fun <!DYNAMIC_RECEIVER_NOT_ALLOWED!>dynamic<!>.foo(s: Any, a: String) {}
fun test(d: dynamic) {
d.foo(1, "")
d.<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>("", "")
d.<!DEBUG_INFO_DYNAMIC!>foo<!>(1, "")
d.<!DEBUG_INFO_DYNAMIC!>foo<!>("", "")
d.<!DEBUG_INFO_DYNAMIC!>foo<!>(1, 1)
}
@@ -1,7 +1,7 @@
// !MARK_DYNAMIC_CALLS
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun dynamic.test() {
fun <!DYNAMIC_RECEIVER_NOT_ALLOWED!>dynamic<!>.test() {
<!DEBUG_INFO_DYNAMIC!>foo<!>()
<!DEBUG_INFO_DYNAMIC!>ext<!>()
@@ -57,7 +57,7 @@ class C {
val withInvoke = WithInvoke()
fun dynamic.test() {
fun <!DYNAMIC_RECEIVER_NOT_ALLOWED!>dynamic<!>.test() {
s()
<!DEBUG_INFO_DYNAMIC!>this<!>()
@@ -0,0 +1,7 @@
public final fun staticExtension(): dynamic
public final var staticProperty: dynamic
public final fun <get-staticProperty>(): dynamic
public final fun <set-staticProperty>(/*0*/ <set-?>: dynamic): kotlin.Unit
public final var staticParameter: dynamic
public final fun <get-staticParameter>(): dynamic
public final fun <set-staticParameter>(/*0*/ <set-?>: dynamic): kotlin.Unit
@@ -0,0 +1,12 @@
// !MARK_DYNAMIC_CALLS
fun Any?.staticExtension() = 1
val Any?.staticProperty get() = 2
fun test(d: dynamic, <!UNUSED_PARAMETER!>staticParameter<!>: Any?.() -> Unit) {
d.<!DEBUG_INFO_DYNAMIC!>staticExtension<!>()
d.<!DEBUG_INFO_DYNAMIC!>staticProperty<!>
d.<!DEBUG_INFO_DYNAMIC!>staticParameter<!>
}
@@ -0,0 +1,5 @@
package
public val kotlin.Any?.staticProperty: kotlin.Int
public fun test(/*0*/ d: dynamic, /*1*/ staticParameter: kotlin.Any?.() -> kotlin.Unit): kotlin.Unit
public fun kotlin.Any?.staticExtension(): kotlin.Int
@@ -50,6 +50,12 @@ public class DiagnosticsTestWithJsStdLibGenerated extends AbstractDiagnosticsTes
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("allowedDynamicFunctionType.kt")
public void testAllowedDynamicFunctionType() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/allowedDynamicFunctionType.kt");
doTest(fileName);
}
@TestMetadata("assignment.kt")
public void testAssignment() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/assignment.kt");
@@ -110,6 +116,12 @@ public class DiagnosticsTestWithJsStdLibGenerated extends AbstractDiagnosticsTes
doTest(fileName);
}
@TestMetadata("dynamicExtension.kt")
public void testDynamicExtension() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/dynamicExtension.kt");
doTest(fileName);
}
@TestMetadata("dynamicSafeCalls.kt")
public void testDynamicSafeCalls() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/dynamicSafeCalls.kt");
@@ -242,6 +254,12 @@ public class DiagnosticsTestWithJsStdLibGenerated extends AbstractDiagnosticsTes
doTest(fileName);
}
@TestMetadata("staticExtensions.kt")
public void testStaticExtensions() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/staticExtensions.kt");
doTest(fileName);
}
@TestMetadata("substitution.kt")
public void testSubstitution() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/substitution.kt");
@@ -30,6 +30,7 @@ private val EXACT_ANNOTATION_FQ_NAME = FqName("kotlin.internal.Exact")
val LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_FQ_NAME = FqName("kotlin.internal.LowPriorityInOverloadResolution")
private val HIDES_MEMBERS_ANNOTATION_FQ_NAME = FqName("kotlin.internal.HidesMembers")
private val ONLY_INPUT_TYPES_FQ_NAME = FqName("kotlin.internal.OnlyInputTypes")
private val DYNAMIC_EXTENSION_FQ_NAME = FqName("kotlin.internal.DynamicExtension")
// @HidesMembers annotation only has effect for members with these names
val HIDES_MEMBERS_NAME_LIST = setOf(Name.identifier("forEach"))
@@ -46,6 +47,7 @@ fun FqName.isInternalAnnotationForResolve() = this == NO_INFER_ANNOTATION_FQ_NAM
fun CallableDescriptor.hasLowPriorityInOverloadResolution(): Boolean = annotations.hasAnnotation(LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_FQ_NAME)
fun CallableDescriptor.hasHidesMembersAnnotation(): Boolean = annotations.hasAnnotation(HIDES_MEMBERS_ANNOTATION_FQ_NAME)
fun CallableDescriptor.hasDynamicExtensionAnnotation(): Boolean = annotations.hasAnnotation(DYNAMIC_EXTENSION_FQ_NAME)
fun TypeParameterDescriptor.hasOnlyInputTypesAnnotation(): Boolean = annotations.hasAnnotation(ONLY_INPUT_TYPES_FQ_NAME)
+1
View File
@@ -24,6 +24,7 @@ public inline fun Any?.asDynamic(): dynamic = this
public inline fun <T> Any?.unsafeCast(): @kotlin.internal.NoInfer T = this.asDynamic()
// TODO add the support ES6 iterators
@kotlin.internal.DynamicExtension
public operator fun dynamic.iterator(): Iterator<dynamic> {
val r: Any? = this
@@ -57,4 +57,11 @@ internal annotation class OnlyInputTypes
*/
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.BINARY)
internal annotation class InlineOnly
internal annotation class InlineOnly
/**
* Specifies that this declaration can have dynamic receiver type.
*/
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.BINARY)
internal annotation class DynamicExtension