Changed name resolution for dynamic extension. Added annotation DynamicExtension.
This commit is contained in:
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -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(
|
||||
|
||||
+16
-4
@@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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)
|
||||
|
||||
+1
-1
@@ -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,
|
||||
|
||||
Vendored
+8
@@ -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
|
||||
+17
@@ -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<!>()
|
||||
}
|
||||
Vendored
+7
@@ -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<!>()
|
||||
}
|
||||
+28
@@ -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) {}
|
||||
+6
@@ -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
|
||||
+1
-1
@@ -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()
|
||||
|
||||
+6
@@ -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
|
||||
|
||||
+5
-5
@@ -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) {
|
||||
|
||||
+6
@@ -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
|
||||
|
||||
+5
-5
@@ -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) {}
|
||||
|
||||
|
||||
+2
@@ -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) {
|
||||
|
||||
Vendored
+54
@@ -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
|
||||
+29
-29
@@ -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
-1
@@ -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
|
||||
|
||||
|
||||
Vendored
+2
@@ -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
|
||||
|
||||
+4
-4
@@ -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)
|
||||
}
|
||||
Vendored
+2
-2
@@ -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<!>()
|
||||
|
||||
|
||||
+7
@@ -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
|
||||
+12
@@ -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<!>
|
||||
}
|
||||
+5
@@ -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
|
||||
+18
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user