[JS FE] Prohibit inline classes as parameter type and return type of external declarations
#KT-26171 Fixed
This commit is contained in:
Vendored
+64
@@ -0,0 +1,64 @@
|
|||||||
|
// !LANGUAGE: +InlineClasses
|
||||||
|
|
||||||
|
// FILE: uint.kt
|
||||||
|
|
||||||
|
package kotlin
|
||||||
|
|
||||||
|
inline class UInt(private val i: Int)
|
||||||
|
|
||||||
|
// FILE: test.kt
|
||||||
|
|
||||||
|
inline class SomeIC(val a: Int)
|
||||||
|
|
||||||
|
external val l: <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!>
|
||||||
|
|
||||||
|
external val ll
|
||||||
|
get(): <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!> = definedExternally
|
||||||
|
|
||||||
|
external var r: <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!>
|
||||||
|
|
||||||
|
external var rr: <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!>
|
||||||
|
get() = definedExternally
|
||||||
|
set(<!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>v: SomeIC<!>) { definedExternally }
|
||||||
|
|
||||||
|
external fun foo(): <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!>
|
||||||
|
external fun foo(<!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>c: SomeIC<!>): <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!>
|
||||||
|
external fun foo(a: Int, <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>c: SomeIC<!>): <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!>
|
||||||
|
|
||||||
|
external fun foo(a: Int, <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!><!FORBIDDEN_VARARG_PARAMETER_TYPE!>vararg<!> args: SomeIC<!>)
|
||||||
|
external fun foo(a: Int, <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>ui: UInt<!>, <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>vararg args: UInt<!>)
|
||||||
|
|
||||||
|
external class CC(
|
||||||
|
<!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>a: SomeIC<!>,
|
||||||
|
<!EXTERNAL_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER, INLINE_CLASS_IN_EXTERNAL_DECLARATION!>val b: <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!><!>,
|
||||||
|
<!EXTERNAL_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER, INLINE_CLASS_IN_EXTERNAL_DECLARATION!>var c: <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!><!>
|
||||||
|
) {
|
||||||
|
val l: <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!>
|
||||||
|
var r: <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!>
|
||||||
|
|
||||||
|
fun foo(): <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!>
|
||||||
|
fun foo(<!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>c: SomeIC<!>): <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!>
|
||||||
|
fun foo(a: Int, <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>c: SomeIC<!>): <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!>
|
||||||
|
|
||||||
|
class N(
|
||||||
|
<!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>a: SomeIC<!>,
|
||||||
|
<!EXTERNAL_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER, INLINE_CLASS_IN_EXTERNAL_DECLARATION!>val b: <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!><!>,
|
||||||
|
<!EXTERNAL_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER, INLINE_CLASS_IN_EXTERNAL_DECLARATION!>var c: <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!><!>
|
||||||
|
) {
|
||||||
|
val l: <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!>
|
||||||
|
var r: <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!>
|
||||||
|
|
||||||
|
fun foo(): <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!>
|
||||||
|
fun foo(<!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>c: SomeIC<!>): <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!>
|
||||||
|
fun foo(a: Int, <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>c: SomeIC<!>): <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
external interface EI {
|
||||||
|
val l: <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!>
|
||||||
|
var r: <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!>
|
||||||
|
|
||||||
|
fun foo(): <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!>
|
||||||
|
fun foo(<!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>c: SomeIC<!>): <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!>
|
||||||
|
fun foo(a: Int, <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>c: SomeIC<!>): <!INLINE_CLASS_IN_EXTERNAL_DECLARATION!>SomeIC<!>
|
||||||
|
}
|
||||||
Vendored
+69
@@ -0,0 +1,69 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public external val l: SomeIC
|
||||||
|
public external val ll: SomeIC
|
||||||
|
public external var r: SomeIC
|
||||||
|
public external var rr: SomeIC
|
||||||
|
public external fun foo(): SomeIC
|
||||||
|
public external fun foo(/*0*/ c: SomeIC): SomeIC
|
||||||
|
public external fun foo(/*0*/ a: kotlin.Int, /*1*/ c: SomeIC): SomeIC
|
||||||
|
public external fun foo(/*0*/ a: kotlin.Int, /*1*/ vararg args: SomeIC /*kotlin.Array<out SomeIC>*/): kotlin.Unit
|
||||||
|
public external fun foo(/*0*/ a: kotlin.Int, /*1*/ ui: kotlin.UInt, /*2*/ vararg args: kotlin.UInt /*kotlin.Array<out kotlin.UInt>*/): kotlin.Unit
|
||||||
|
|
||||||
|
public final external class CC {
|
||||||
|
public constructor CC(/*0*/ a: SomeIC, /*1*/ b: SomeIC, /*2*/ c: SomeIC)
|
||||||
|
public final val b: SomeIC
|
||||||
|
public final var c: SomeIC
|
||||||
|
public final val l: SomeIC
|
||||||
|
public final var r: SomeIC
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun foo(): SomeIC
|
||||||
|
public final fun foo(/*0*/ c: SomeIC): SomeIC
|
||||||
|
public final fun foo(/*0*/ a: kotlin.Int, /*1*/ c: SomeIC): SomeIC
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public final class N {
|
||||||
|
public constructor N(/*0*/ a: SomeIC, /*1*/ b: SomeIC, /*2*/ c: SomeIC)
|
||||||
|
public final val b: SomeIC
|
||||||
|
public final var c: SomeIC
|
||||||
|
public final val l: SomeIC
|
||||||
|
public final var r: SomeIC
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun foo(): SomeIC
|
||||||
|
public final fun foo(/*0*/ c: SomeIC): SomeIC
|
||||||
|
public final fun foo(/*0*/ a: kotlin.Int, /*1*/ c: SomeIC): SomeIC
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public external interface EI {
|
||||||
|
public abstract val l: SomeIC
|
||||||
|
public abstract var r: SomeIC
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public abstract fun foo(): SomeIC
|
||||||
|
public abstract fun foo(/*0*/ c: SomeIC): SomeIC
|
||||||
|
public abstract fun foo(/*0*/ a: kotlin.Int, /*1*/ c: SomeIC): SomeIC
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final inline class SomeIC {
|
||||||
|
public constructor SomeIC(/*0*/ a: kotlin.Int)
|
||||||
|
public final val a: kotlin.Int
|
||||||
|
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin {
|
||||||
|
|
||||||
|
public final inline class UInt {
|
||||||
|
public constructor UInt(/*0*/ i: kotlin.Int)
|
||||||
|
private final val i: kotlin.Int
|
||||||
|
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -664,6 +664,11 @@ public class DiagnosticsTestWithJsStdLibGenerated extends AbstractDiagnosticsTes
|
|||||||
runTest("compiler/testData/diagnostics/testsWithJsStdLib/native/inlineClass.kt");
|
runTest("compiler/testData/diagnostics/testsWithJsStdLib/native/inlineClass.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineClassAsParameterOrReturnType.kt.kt")
|
||||||
|
public void testInlineClassAsParameterOrReturnType_kt() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithJsStdLib/native/inlineClassAsParameterOrReturnType.kt.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("inlineExtensionToNative.kt")
|
@TestMetadata("inlineExtensionToNative.kt")
|
||||||
public void testInlineExtensionToNative() throws Exception {
|
public void testInlineExtensionToNative() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/testsWithJsStdLib/native/inlineExtensionToNative.kt");
|
runTest("compiler/testData/diagnostics/testsWithJsStdLib/native/inlineExtensionToNative.kt");
|
||||||
|
|||||||
+3
-13
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
*
|
* that can be found in the license/LICENSE.txt file.
|
||||||
* 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.js.resolve.diagnostics
|
package org.jetbrains.kotlin.js.resolve.diagnostics
|
||||||
@@ -39,6 +28,7 @@ private val DIAGNOSTIC_FACTORY_TO_RENDERER by lazy {
|
|||||||
put(ErrorsJs.NESTED_EXTERNAL_DECLARATION, "Non top-level `external` declaration")
|
put(ErrorsJs.NESTED_EXTERNAL_DECLARATION, "Non top-level `external` declaration")
|
||||||
put(ErrorsJs.WRONG_EXTERNAL_DECLARATION, "Declaration of such kind ({0}) can't be external", Renderers.STRING)
|
put(ErrorsJs.WRONG_EXTERNAL_DECLARATION, "Declaration of such kind ({0}) can't be external", Renderers.STRING)
|
||||||
put(ErrorsJs.EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION, "Function types with receiver are prohibited in external declarations")
|
put(ErrorsJs.EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION, "Function types with receiver are prohibited in external declarations")
|
||||||
|
put(ErrorsJs.INLINE_CLASS_IN_EXTERNAL_DECLARATION, "Using inline classes as parameter type or return type of external declarations is not supported")
|
||||||
|
|
||||||
put(ErrorsJs.JS_NAME_CLASH, "JavaScript name ({0}) generated for this declaration clashes with another declaration: {1}",
|
put(ErrorsJs.JS_NAME_CLASH, "JavaScript name ({0}) generated for this declaration clashes with another declaration: {1}",
|
||||||
Renderers.STRING, Renderers.COMPACT)
|
Renderers.STRING, Renderers.COMPACT)
|
||||||
|
|||||||
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
*
|
* that can be found in the license/LICENSE.txt file.
|
||||||
* 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.js.resolve.diagnostics;
|
package org.jetbrains.kotlin.js.resolve.diagnostics;
|
||||||
@@ -43,6 +32,7 @@ public interface ErrorsJs {
|
|||||||
DiagnosticFactory1<KtExpression, String> WRONG_EXTERNAL_DECLARATION = DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
DiagnosticFactory1<KtExpression, String> WRONG_EXTERNAL_DECLARATION = DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
DiagnosticFactory0<KtExpression> EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
DiagnosticFactory0<KtExpression> EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
DiagnosticFactory0<KtExpression> NESTED_EXTERNAL_DECLARATION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
DiagnosticFactory0<KtExpression> NESTED_EXTERNAL_DECLARATION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
|
DiagnosticFactory0<KtElement> INLINE_CLASS_IN_EXTERNAL_DECLARATION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
|
|
||||||
DiagnosticFactory2<KtElement, String, DeclarationDescriptor> JS_NAME_CLASH = DiagnosticFactory2.create(
|
DiagnosticFactory2<KtElement, String, DeclarationDescriptor> JS_NAME_CLASH = DiagnosticFactory2.create(
|
||||||
ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
|||||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.*
|
import org.jetbrains.kotlin.resolve.descriptorUtil.*
|
||||||
|
import org.jetbrains.kotlin.resolve.isInlineClassType
|
||||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
|
|
||||||
object JsExternalChecker : DeclarationChecker {
|
object JsExternalChecker : DeclarationChecker {
|
||||||
@@ -84,6 +86,29 @@ object JsExternalChecker : DeclarationChecker {
|
|||||||
trace.report(ErrorsJs.INLINE_EXTERNAL_DECLARATION.on(declaration))
|
trace.report(ErrorsJs.INLINE_EXTERNAL_DECLARATION.on(declaration))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (descriptor is CallableMemberDescriptor && !(descriptor is PropertyAccessorDescriptor && descriptor.isDefault)) {
|
||||||
|
fun checkTypeIsNotInlineClass(type: KotlinType, elementToReport: KtElement) {
|
||||||
|
if (type.isInlineClassType()) {
|
||||||
|
trace.report(ErrorsJs.INLINE_CLASS_IN_EXTERNAL_DECLARATION.on(elementToReport))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (p in descriptor.valueParameters) {
|
||||||
|
val ktParam = p.source.getPsi() as? KtParameter ?: declaration
|
||||||
|
checkTypeIsNotInlineClass(p.varargElementType ?: p.type, ktParam)
|
||||||
|
}
|
||||||
|
|
||||||
|
val elementToReport = when (declaration) {
|
||||||
|
is KtCallableDeclaration -> declaration.typeReference
|
||||||
|
is KtPropertyAccessor -> declaration.returnTypeReference
|
||||||
|
else -> declaration
|
||||||
|
}
|
||||||
|
|
||||||
|
elementToReport?.let {
|
||||||
|
checkTypeIsNotInlineClass(descriptor.returnType!!, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (descriptor is CallableMemberDescriptor && !(descriptor is PropertyAccessorDescriptor && descriptor.isDefault)) {
|
if (descriptor is CallableMemberDescriptor && !(descriptor is PropertyAccessorDescriptor && descriptor.isDefault)) {
|
||||||
for (p in descriptor.valueParameters) {
|
for (p in descriptor.valueParameters) {
|
||||||
if ((p.varargElementType ?: p.type).isExtensionFunctionType) {
|
if ((p.varargElementType ?: p.type).isExtensionFunctionType) {
|
||||||
|
|||||||
Reference in New Issue
Block a user