Support platform modifier in back-ends, add multi-platform integration test
Skip 'platform' declarations completely in back-ends
This commit is contained in:
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
@@ -100,6 +101,8 @@ public class PackageCodegenImpl implements PackageCodegen {
|
||||
List<KtClassOrObject> classOrObjects = new ArrayList<KtClassOrObject>();
|
||||
|
||||
for (KtDeclaration declaration : file.getDeclarations()) {
|
||||
if (declaration.hasModifier(KtTokens.PLATFORM_KEYWORD)) continue;
|
||||
|
||||
if (declaration instanceof KtProperty || declaration instanceof KtNamedFunction || declaration instanceof KtTypeAlias) {
|
||||
generatePackagePart = true;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.descriptors.VariableDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
@@ -91,6 +92,8 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
|
||||
@Override
|
||||
protected void generateBody() {
|
||||
for (KtDeclaration declaration : element.getDeclarations()) {
|
||||
if (declaration.hasModifier(KtTokens.PLATFORM_KEYWORD)) continue;
|
||||
|
||||
if (declaration instanceof KtNamedFunction || declaration instanceof KtProperty || declaration instanceof KtTypeAlias) {
|
||||
genSimpleMember(declaration);
|
||||
}
|
||||
|
||||
@@ -20,11 +20,11 @@ import com.google.common.collect.HashMultimap
|
||||
import com.google.common.collect.Multimap
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.MemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.REDECLARATION
|
||||
import org.jetbrains.kotlin.diagnostics.reportOnDeclaration
|
||||
import org.jetbrains.kotlin.diagnostics.reportOnDeclarationOrFail
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -78,14 +78,17 @@ class DeclarationResolver(
|
||||
for ((fqName, declarationsOrPackageDirectives) in topLevelFqNames.asMap()) {
|
||||
if (fqName.isRoot) continue
|
||||
|
||||
val descriptors = getTopLevelDescriptorsByFqName(topLevelDescriptorProvider, fqName, NoLookupLocation.WHEN_CHECK_REDECLARATIONS)
|
||||
// TODO: report error on platform class and impl val, or vice versa
|
||||
val (platform, impl) =
|
||||
getTopLevelDescriptorsByFqName(topLevelDescriptorProvider, fqName, NoLookupLocation.WHEN_CHECK_REDECLARATIONS)
|
||||
.partition { it is MemberDescriptor && it.isPlatform }
|
||||
|
||||
if (descriptors.size > 1) {
|
||||
for (declarationOrPackageDirective in declarationsOrPackageDirectives) {
|
||||
val reportAt =
|
||||
if (declarationOrPackageDirective is KtPackageDirective) declarationOrPackageDirective.getNameIdentifier()
|
||||
else declarationOrPackageDirective
|
||||
trace.report(Errors.PACKAGE_OR_CLASSIFIER_REDECLARATION.on(reportAt!!, fqName.shortName().asString()))
|
||||
for (descriptors in listOf(platform, impl)) {
|
||||
if (descriptors.size > 1) {
|
||||
for (directive in declarationsOrPackageDirectives) {
|
||||
val reportAt = (directive as? KtPackageDirective)?.nameIdentifier ?: directive
|
||||
trace.report(Errors.PACKAGE_OR_CLASSIFIER_REDECLARATION.on(reportAt, fqName.shortName().asString()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
platform class Printer {
|
||||
fun print(message: String)
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val printer = Printer()
|
||||
printer.print("Hello, world!")
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
impl class Printer {
|
||||
fun print(message: String) {
|
||||
println("JS says: " + message)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
impl class Printer {
|
||||
fun print(message: String) {
|
||||
println("JVM says: " + message)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
-- Common --
|
||||
Exit code: OK
|
||||
Output:
|
||||
|
||||
-- JVM --
|
||||
Exit code: OK
|
||||
Output:
|
||||
|
||||
-- JS --
|
||||
Exit code: OK
|
||||
Output:
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.multiplatform
|
||||
|
||||
import org.jetbrains.kotlin.cli.AbstractCliTest
|
||||
import org.jetbrains.kotlin.cli.js.K2JSCompiler
|
||||
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
|
||||
import org.jetbrains.kotlin.cli.metadata.K2MetadataCompiler
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase
|
||||
import java.io.File
|
||||
|
||||
class MultiPlatformIntegrationTest : KtUsefulTestCase() {
|
||||
fun doTest(directoryPath: String) {
|
||||
val root = File(KotlinTestUtils.getTestDataPathBase() + directoryPath)
|
||||
val commonSrc = File(root, "common.kt")
|
||||
val jsSrc = File(root, "js.kt")
|
||||
val jvmSrc = File(root, "jvm.kt")
|
||||
|
||||
val tmpdir = KotlinTestUtils.tmpDir(getTestName(true))
|
||||
|
||||
val commonDest = File(tmpdir, "common")
|
||||
val jvmDest = File(tmpdir, "jvm")
|
||||
val jsDest = File(File(tmpdir, "js"), "output.js")
|
||||
|
||||
val result = buildString {
|
||||
val (commonOutput, commonExitCode) = AbstractCliTest.executeCompilerGrabOutput(K2MetadataCompiler(), listOf(
|
||||
commonSrc.absolutePath, "-d", commonDest.absolutePath
|
||||
))
|
||||
appendln("-- Common --")
|
||||
appendln("Exit code: $commonExitCode")
|
||||
appendln("Output:")
|
||||
appendln(commonOutput)
|
||||
|
||||
val (jvmOutput, jvmExitCode) = AbstractCliTest.executeCompilerGrabOutput(K2JVMCompiler(), listOf(
|
||||
jvmSrc.absolutePath, commonSrc.absolutePath,
|
||||
"-d", jvmDest.absolutePath,
|
||||
"-Xmulti-platform"
|
||||
))
|
||||
appendln("-- JVM --")
|
||||
appendln("Exit code: $jvmExitCode")
|
||||
appendln("Output:")
|
||||
appendln(jvmOutput)
|
||||
|
||||
val (jsOutput, jsExitCode) = AbstractCliTest.executeCompilerGrabOutput(K2JSCompiler(), listOf(
|
||||
jsSrc.absolutePath, commonSrc.absolutePath,
|
||||
"-output", jsDest.absolutePath,
|
||||
"-Xmulti-platform"
|
||||
))
|
||||
appendln("-- JS --")
|
||||
appendln("Exit code: $jsExitCode")
|
||||
appendln("Output:")
|
||||
append(jsOutput)
|
||||
}
|
||||
|
||||
KotlinTestUtils.assertEqualsToFile(File(root, "output.txt"), result)
|
||||
}
|
||||
|
||||
fun testSimple() {
|
||||
doTest("/multiplatform/simple/")
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -55,7 +55,7 @@ class JsNameClashChecker : SimpleDeclarationChecker {
|
||||
val scope = getScope(suggested.scope)
|
||||
val name = suggested.names.last()
|
||||
val existing = scope[name]
|
||||
if (existing != null && existing != suggested.descriptor) {
|
||||
if (existing != null && existing != suggested.descriptor && !(existing is MemberDescriptor && existing.isPlatform)) {
|
||||
diagnosticHolder.report(ErrorsJs.JS_NAME_CLASH.on(declaration, name, existing))
|
||||
val existingDeclaration = existing.findPsi()
|
||||
if (clashedDescriptors.add(existing) && existingDeclaration is KtDeclaration && existingDeclaration != declaration) {
|
||||
|
||||
@@ -18,10 +18,7 @@ package org.jetbrains.kotlin.js.translate.utils;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
@@ -140,11 +137,14 @@ public final class AnnotationsUtils {
|
||||
}
|
||||
|
||||
public static boolean isPredefinedObject(@NotNull DeclarationDescriptor descriptor) {
|
||||
if (descriptor instanceof MemberDescriptor && ((MemberDescriptor) descriptor).isPlatform()) return true;
|
||||
|
||||
for (PredefinedAnnotation annotation : PredefinedAnnotation.values()) {
|
||||
if (hasAnnotationOrInsideAnnotatedClass(descriptor, annotation)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user