IDE perf tests for Kotlin/Native projects
Issue #MMPP-201
This commit is contained in:
+18
-68
@@ -11,7 +11,6 @@ import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl
|
|||||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo
|
import com.intellij.codeInsight.daemon.impl.HighlightInfo
|
||||||
import com.intellij.codeInsight.daemon.impl.IdentifierHighlighterPassFactory
|
import com.intellij.codeInsight.daemon.impl.IdentifierHighlighterPassFactory
|
||||||
import com.intellij.codeInsight.lookup.LookupElement
|
import com.intellij.codeInsight.lookup.LookupElement
|
||||||
import com.intellij.ide.highlighter.ModuleFileType
|
|
||||||
import com.intellij.ide.startup.impl.StartupManagerImpl
|
import com.intellij.ide.startup.impl.StartupManagerImpl
|
||||||
import com.intellij.openapi.actionSystem.IdeActions
|
import com.intellij.openapi.actionSystem.IdeActions
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
@@ -20,26 +19,23 @@ import com.intellij.openapi.editor.EditorFactory
|
|||||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl
|
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl
|
||||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||||
import com.intellij.openapi.fileEditor.FileEditorManager
|
import com.intellij.openapi.fileEditor.FileEditorManager
|
||||||
import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl
|
|
||||||
import com.intellij.openapi.module.ModuleManager
|
import com.intellij.openapi.module.ModuleManager
|
||||||
import com.intellij.openapi.module.ModuleTypeId
|
|
||||||
import com.intellij.openapi.project.DumbService
|
import com.intellij.openapi.project.DumbService
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.project.ex.ProjectManagerEx
|
|
||||||
import com.intellij.openapi.project.impl.ProjectImpl
|
|
||||||
import com.intellij.openapi.projectRoots.JavaSdk
|
import com.intellij.openapi.projectRoots.JavaSdk
|
||||||
import com.intellij.openapi.projectRoots.Sdk
|
import com.intellij.openapi.projectRoots.Sdk
|
||||||
import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl
|
import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl
|
||||||
import com.intellij.openapi.roots.ProjectRootManager
|
|
||||||
import com.intellij.openapi.startup.StartupManager
|
import com.intellij.openapi.startup.StartupManager
|
||||||
import com.intellij.openapi.vcs.changes.ChangeListManager
|
import com.intellij.openapi.vcs.changes.ChangeListManager
|
||||||
import com.intellij.openapi.vcs.changes.ChangeListManagerImpl
|
import com.intellij.openapi.vcs.changes.ChangeListManagerImpl
|
||||||
import com.intellij.openapi.vfs.LocalFileSystem
|
|
||||||
import com.intellij.openapi.vfs.VirtualFileManager
|
import com.intellij.openapi.vfs.VirtualFileManager
|
||||||
import com.intellij.psi.PsiDocumentManager
|
import com.intellij.psi.PsiDocumentManager
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
import com.intellij.psi.PsiManager
|
import com.intellij.psi.PsiManager
|
||||||
import com.intellij.testFramework.*
|
import com.intellij.testFramework.EditorTestUtil
|
||||||
|
import com.intellij.testFramework.RunAll
|
||||||
|
import com.intellij.testFramework.TestDataProvider
|
||||||
|
import com.intellij.testFramework.UsefulTestCase
|
||||||
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl
|
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl
|
||||||
import com.intellij.util.ArrayUtilRt
|
import com.intellij.util.ArrayUtilRt
|
||||||
import com.intellij.util.ThrowableRunnable
|
import com.intellij.util.ThrowableRunnable
|
||||||
@@ -51,7 +47,6 @@ import org.jetbrains.kotlin.idea.framework.KotlinSdkType
|
|||||||
import org.jetbrains.kotlin.idea.perf.Stats.Companion.WARM_UP
|
import org.jetbrains.kotlin.idea.perf.Stats.Companion.WARM_UP
|
||||||
import org.jetbrains.kotlin.idea.perf.Stats.Companion.runAndMeasure
|
import org.jetbrains.kotlin.idea.perf.Stats.Companion.runAndMeasure
|
||||||
import org.jetbrains.kotlin.idea.project.getAndCacheLanguageLevelByDependencies
|
import org.jetbrains.kotlin.idea.project.getAndCacheLanguageLevelByDependencies
|
||||||
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
|
|
||||||
import org.jetbrains.kotlin.idea.test.invalidateLibraryCache
|
import org.jetbrains.kotlin.idea.test.invalidateLibraryCache
|
||||||
import org.jetbrains.kotlin.idea.testFramework.*
|
import org.jetbrains.kotlin.idea.testFramework.*
|
||||||
import org.jetbrains.kotlin.idea.testFramework.Fixture.Companion.cleanupCaches
|
import org.jetbrains.kotlin.idea.testFramework.Fixture.Companion.cleanupCaches
|
||||||
@@ -98,11 +93,15 @@ abstract class AbstractPerformanceProjectsTest : UsefulTestCase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun warmUpProject(stats: Stats) {
|
protected fun warmUpProject(stats: Stats, vararg filesToHighlight: String, openProject: () -> Project) {
|
||||||
val project = perfOpenHelloWorld(stats, WARM_UP)
|
assertTrue(filesToHighlight.isNotEmpty())
|
||||||
|
|
||||||
|
val project = openProject()
|
||||||
try {
|
try {
|
||||||
val perfHighlightFile = perfHighlightFile(project, "src/HelloMain.kt", stats, WARM_UP)
|
filesToHighlight.forEach {
|
||||||
assertTrue("kotlin project has been not imported properly", perfHighlightFile.isNotEmpty())
|
val perfHighlightFile = perfHighlightFile(project, it, stats, WARM_UP)
|
||||||
|
assertTrue("kotlin project has been not imported properly", perfHighlightFile.isNotEmpty())
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
closeProject(project)
|
closeProject(project)
|
||||||
myApplication.setDataProvider(null)
|
myApplication.setDataProvider(null)
|
||||||
@@ -130,22 +129,12 @@ abstract class AbstractPerformanceProjectsTest : UsefulTestCase() {
|
|||||||
return if (lastIndexOf >= 0) fileName.substring(lastIndexOf + 1) else fileName
|
return if (lastIndexOf >= 0) fileName.substring(lastIndexOf + 1) else fileName
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun perfOpenKotlinProjectFast(stats: Stats) =
|
protected fun perfOpenProject(
|
||||||
perfOpenKotlinProject(stats, fast = true)
|
|
||||||
|
|
||||||
protected fun perfOpenKotlinProject(stats: Stats, fast: Boolean = false) {
|
|
||||||
myProject = innerPerfOpenProject("kotlin", stats = stats, path = "../perfTestProject", note = "", fast = fast)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun perfOpenHelloWorld(stats: Stats, note: String = ""): Project =
|
|
||||||
innerPerfOpenProject("helloKotlin", stats, note, path = "idea/testData/perfTest/helloKotlin", simpleModule = true)
|
|
||||||
|
|
||||||
protected fun innerPerfOpenProject(
|
|
||||||
name: String,
|
name: String,
|
||||||
stats: Stats,
|
stats: Stats,
|
||||||
note: String,
|
note: String,
|
||||||
path: String,
|
path: String,
|
||||||
simpleModule: Boolean = false,
|
openAction: ProjectOpenAction,
|
||||||
fast: Boolean = false
|
fast: Boolean = false
|
||||||
): Project {
|
): Project {
|
||||||
val projectPath = File(path).canonicalPath
|
val projectPath = File(path).canonicalPath
|
||||||
@@ -154,7 +143,6 @@ abstract class AbstractPerformanceProjectsTest : UsefulTestCase() {
|
|||||||
|
|
||||||
val warmUpIterations = if (fast) 0 else 5
|
val warmUpIterations = if (fast) 0 else 5
|
||||||
val iterations = if (fast) 1 else 5
|
val iterations = if (fast) 1 else 5
|
||||||
val projectManagerEx = ProjectManagerEx.getInstanceEx()
|
|
||||||
|
|
||||||
var lastProject: Project? = null
|
var lastProject: Project? = null
|
||||||
var counter = 0
|
var counter = 0
|
||||||
@@ -166,27 +154,10 @@ abstract class AbstractPerformanceProjectsTest : UsefulTestCase() {
|
|||||||
iterations(iterations)
|
iterations(iterations)
|
||||||
checkStability(!fast)
|
checkStability(!fast)
|
||||||
test {
|
test {
|
||||||
val project = if (!simpleModule) {
|
val project = openAction.openProject(
|
||||||
val project = loadProjectWithName(name = name, path = path)
|
projectPath = path,
|
||||||
assertNotNull("project $name at $path is not loaded", project)
|
projectName = name,
|
||||||
val projectRootManager = ProjectRootManager.getInstance(project!!)
|
jdk = jdk18
|
||||||
|
|
||||||
runWriteAction {
|
|
||||||
with(projectRootManager) {
|
|
||||||
projectSdk = jdk18
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assertTrue("project $name at $path is not opened", projectManagerEx.openProject(project))
|
|
||||||
project
|
|
||||||
} else {
|
|
||||||
val project = projectManagerEx.loadAndOpenProject(projectPath)!!
|
|
||||||
initKotlinProject(project, projectPath, name)
|
|
||||||
project
|
|
||||||
}
|
|
||||||
|
|
||||||
(project as ProjectImpl).registerComponentImplementation(
|
|
||||||
FileEditorManager::class.java,
|
|
||||||
FileEditorManagerImpl::class.java
|
|
||||||
)
|
)
|
||||||
|
|
||||||
dispatchAllInvocationEvents()
|
dispatchAllInvocationEvents()
|
||||||
@@ -537,27 +508,6 @@ abstract class AbstractPerformanceProjectsTest : UsefulTestCase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initKotlinProject(
|
|
||||||
project: Project,
|
|
||||||
projectPath: String,
|
|
||||||
name: String
|
|
||||||
) {
|
|
||||||
val modulePath = "$projectPath/$name${ModuleFileType.DOT_DEFAULT_EXTENSION}"
|
|
||||||
val projectFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(File(projectPath))!!
|
|
||||||
val srcFile = projectFile.findChild("src")!!
|
|
||||||
val module = runWriteAction {
|
|
||||||
val projectRootManager = ProjectRootManager.getInstance(project)
|
|
||||||
with(projectRootManager) {
|
|
||||||
projectSdk = jdk18
|
|
||||||
}
|
|
||||||
val moduleManager = ModuleManager.getInstance(project)
|
|
||||||
val module = moduleManager.newModule(modulePath, ModuleTypeId.JAVA_MODULE)
|
|
||||||
PsiTestUtil.addSourceRoot(module, srcFile)
|
|
||||||
module
|
|
||||||
}
|
|
||||||
ConfigLibraryUtil.configureKotlinRuntimeAndSdk(module, jdk18)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun perfHighlightFile(name: String, stats: Stats): List<HighlightInfo> =
|
protected fun perfHighlightFile(name: String, stats: Stats): List<HighlightInfo> =
|
||||||
perfHighlightFile(project(), name, stats)
|
perfHighlightFile(project(), name, stats)
|
||||||
|
|
||||||
|
|||||||
+229
@@ -0,0 +1,229 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.perf
|
||||||
|
|
||||||
|
import com.intellij.openapi.application.runReadAction
|
||||||
|
import com.intellij.openapi.module.Module
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.project.rootManager
|
||||||
|
import com.intellij.openapi.roots.LibraryOrderEntry
|
||||||
|
import com.intellij.openapi.roots.OrderRootType
|
||||||
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
|
import org.jetbrains.kotlin.gradle.KotlinSourceSet.Companion.COMMON_TEST_SOURCE_SET_NAME
|
||||||
|
import org.jetbrains.kotlin.ide.konan.NativeLibraryKind
|
||||||
|
import org.jetbrains.kotlin.idea.caches.project.isMPPModule
|
||||||
|
import org.jetbrains.kotlin.idea.configuration.klib.KotlinNativeLibraryNameUtil.parseIDELibraryName
|
||||||
|
import org.jetbrains.kotlin.idea.facet.KotlinFacet
|
||||||
|
import org.jetbrains.kotlin.idea.framework.CommonLibraryKind
|
||||||
|
import org.jetbrains.kotlin.idea.framework.detectLibraryKind
|
||||||
|
import org.jetbrains.kotlin.idea.perf.Stats.Companion.WARM_UP
|
||||||
|
import org.jetbrains.kotlin.idea.perf.Stats.Companion.tcSuite
|
||||||
|
import org.jetbrains.kotlin.idea.testFramework.ProjectOpenAction.GRADLE_PROJECT
|
||||||
|
import org.jetbrains.kotlin.idea.testFramework.logMessage
|
||||||
|
import org.jetbrains.kotlin.idea.util.projectStructure.allModules
|
||||||
|
import org.jetbrains.kotlin.library.KOTLIN_STDLIB_NAME
|
||||||
|
import org.jetbrains.kotlin.platform.konan.isNative
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class PerformanceNativeProjectsTest : AbstractPerformanceProjectsTest() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val GRADLE_VERSION = "6.0.1"
|
||||||
|
private const val KOTLIN_PLUGIN_VERSION = "1.4.0-dev-3273" // TODO: use 1.4-M1 when it's published
|
||||||
|
|
||||||
|
private var warmedUp: Boolean = false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setUp() {
|
||||||
|
super.setUp()
|
||||||
|
|
||||||
|
// warm up: open simple small project
|
||||||
|
if (!warmedUp) {
|
||||||
|
val projectTemplate = "HelloWorld"
|
||||||
|
val enableCommonizer = true
|
||||||
|
|
||||||
|
val projectName = "${projectName(projectTemplate, enableCommonizer)}-$WARM_UP"
|
||||||
|
|
||||||
|
// don't share this stats instance with another one used in "Hello World" test
|
||||||
|
Stats(projectName).use { stats ->
|
||||||
|
warmUpProject(stats, "src/iosX64Main/kotlin/HelloMain.kt") {
|
||||||
|
perfOpenTemplateGradleProject(stats, projectTemplate, enableCommonizer, WARM_UP)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
warmedUp = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testHelloWorldProjectWithCommonizer() = doTestHighlighting(
|
||||||
|
"HelloWorld",
|
||||||
|
true,
|
||||||
|
"src/iosX64Main/kotlin/HelloMain.kt",
|
||||||
|
"src/iosX64Main/kotlin/HelloMain2.kt",
|
||||||
|
"src/iosX64Main/kotlin/HelloMain3.kt",
|
||||||
|
"src/iosX64Test/kotlin/HelloTest.kt",
|
||||||
|
"src/iosX64Test/kotlin/HelloTest2.kt",
|
||||||
|
"src/iosX64Test/kotlin/HelloTest3.kt"
|
||||||
|
)
|
||||||
|
|
||||||
|
fun testHelloWorldProjectWithoutCommonizer() = doTestHighlighting(
|
||||||
|
"HelloWorld",
|
||||||
|
false,
|
||||||
|
"src/iosX64Main/kotlin/HelloMain.kt",
|
||||||
|
"src/iosX64Main/kotlin/HelloMain2.kt",
|
||||||
|
"src/iosX64Main/kotlin/HelloMain3.kt",
|
||||||
|
"src/iosX64Test/kotlin/HelloTest.kt",
|
||||||
|
"src/iosX64Test/kotlin/HelloTest2.kt",
|
||||||
|
"src/iosX64Test/kotlin/HelloTest3.kt"
|
||||||
|
)
|
||||||
|
|
||||||
|
fun testCvsParserProjectWithCommonizer() = doTestHighlighting(
|
||||||
|
"CsvParser",
|
||||||
|
true,
|
||||||
|
"src/iosX64Main/kotlin/CsvParser.kt",
|
||||||
|
"src/iosX64Main/kotlin/CsvParser2.kt",
|
||||||
|
"src/iosX64Main/kotlin/CsvParser3.kt"
|
||||||
|
)
|
||||||
|
|
||||||
|
fun testCvsParserProjectWithoutCommonizer() = doTestHighlighting(
|
||||||
|
"CsvParser",
|
||||||
|
false,
|
||||||
|
"src/iosX64Main/kotlin/CsvParser.kt",
|
||||||
|
"src/iosX64Main/kotlin/CsvParser2.kt",
|
||||||
|
"src/iosX64Main/kotlin/CsvParser3.kt"
|
||||||
|
)
|
||||||
|
|
||||||
|
fun testUIKitAppProjectWithCommonizer() = doTestHighlighting(
|
||||||
|
"UIKitApp",
|
||||||
|
true,
|
||||||
|
"src/iosX64Main/kotlin/UIKitApp.kt",
|
||||||
|
"src/iosX64Main/kotlin/UIKitApp2.kt",
|
||||||
|
"src/iosX64Main/kotlin/UIKitApp3.kt"
|
||||||
|
)
|
||||||
|
|
||||||
|
fun testUIKitAppProjectWithoutCommonizer() = doTestHighlighting(
|
||||||
|
"UIKitApp",
|
||||||
|
false,
|
||||||
|
"src/iosX64Main/kotlin/UIKitApp.kt",
|
||||||
|
"src/iosX64Main/kotlin/UIKitApp2.kt",
|
||||||
|
"src/iosX64Main/kotlin/UIKitApp3.kt"
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun doTestHighlighting(
|
||||||
|
templateName: String,
|
||||||
|
enableCommonizer: Boolean,
|
||||||
|
vararg filesToHighlight: String
|
||||||
|
) {
|
||||||
|
assertTrue(filesToHighlight.isNotEmpty())
|
||||||
|
|
||||||
|
val projectName = projectName(templateName, enableCommonizer)
|
||||||
|
tcSuite(projectName) {
|
||||||
|
Stats(projectName).use { stats ->
|
||||||
|
myProject = perfOpenTemplateGradleProject(stats, templateName, enableCommonizer)
|
||||||
|
|
||||||
|
// highlight
|
||||||
|
filesToHighlight.forEach { perfHighlightFile(it, stats) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun perfOpenTemplateGradleProject(
|
||||||
|
stats: Stats,
|
||||||
|
templateName: String,
|
||||||
|
enableCommonizer: Boolean,
|
||||||
|
note: String = ""
|
||||||
|
): Project {
|
||||||
|
val templateRoot = File("idea/testData/perfTest/native/").resolve(templateName)
|
||||||
|
val projectRoot = FileUtil.createTempDirectory("project", "", false)
|
||||||
|
|
||||||
|
templateRoot.walkTopDown()
|
||||||
|
.filter { it.isFile }
|
||||||
|
.forEach { source ->
|
||||||
|
val destination = projectRoot.resolve(source.relativeTo(templateRoot))
|
||||||
|
|
||||||
|
val filename = source.name
|
||||||
|
if (filename == "build.gradle.kts" || filename == "gradle-wrapper.properties" || filename == "gradle.properties") {
|
||||||
|
val text = source.readText()
|
||||||
|
.replace("{{kotlin_plugin_version}}", KOTLIN_PLUGIN_VERSION)
|
||||||
|
.replace("{{gradle_version}}", GRADLE_VERSION)
|
||||||
|
.replace("{{disable_commonizer}}", (!enableCommonizer).toString())
|
||||||
|
|
||||||
|
destination.parentFile.mkdirs()
|
||||||
|
destination.writeText(text)
|
||||||
|
} else {
|
||||||
|
source.copyTo(destination)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val projectName = projectName(templateName, enableCommonizer, separator = '-')
|
||||||
|
|
||||||
|
val project = perfOpenProject(
|
||||||
|
name = projectName,
|
||||||
|
stats = stats,
|
||||||
|
note = note,
|
||||||
|
path = projectRoot.absolutePath,
|
||||||
|
openAction = GRADLE_PROJECT
|
||||||
|
)
|
||||||
|
runProjectSanityChecks(project)
|
||||||
|
|
||||||
|
return project
|
||||||
|
}
|
||||||
|
|
||||||
|
// goal: make sure that the project imported from Gradle is valid
|
||||||
|
private fun runProjectSanityChecks(project: Project) {
|
||||||
|
|
||||||
|
val nativeModules: Map<Module, Set<String>> = runReadAction {
|
||||||
|
project.allModules().mapNotNull { module ->
|
||||||
|
val facetSettings = KotlinFacet.get(module)?.configuration?.settings ?: return@mapNotNull null
|
||||||
|
if (!facetSettings.isMPPModule || !facetSettings.targetPlatform.isNative()) return@mapNotNull null
|
||||||
|
|
||||||
|
// workaround to skip top-level common test module, which in fact does not get any Kotlin/Native KLIB libraries
|
||||||
|
// but accidentally gets Kotlin facet with Native platform
|
||||||
|
if (module.name == "${project.name}.$COMMON_TEST_SOURCE_SET_NAME") return@mapNotNull null
|
||||||
|
|
||||||
|
val nativeLibraries = module.rootManager.orderEntries
|
||||||
|
.asSequence()
|
||||||
|
.filterIsInstance<LibraryOrderEntry>()
|
||||||
|
.mapNotNull { it.library }
|
||||||
|
.filter { library ->
|
||||||
|
val libraryKind = detectLibraryKind(library.getFiles(OrderRootType.CLASSES))
|
||||||
|
libraryKind == NativeLibraryKind
|
||||||
|
// TODO: remove this check for CommonLibraryKind when detection of K/N KLIBs in
|
||||||
|
// org.jetbrains.kotlin.ide.konan.KotlinNativePluginUtilKt.isKonanLibraryRoot
|
||||||
|
// is correctly implemented
|
||||||
|
|| libraryKind == CommonLibraryKind
|
||||||
|
}
|
||||||
|
.mapNotNull inner@{ library ->
|
||||||
|
val libraryNameParts = parseIDELibraryName(library.name.orEmpty()) ?: return@inner null
|
||||||
|
val (_, pureLibraryName, platformPart) = libraryNameParts
|
||||||
|
pureLibraryName + if (platformPart != null) " [$platformPart]" else ""
|
||||||
|
}
|
||||||
|
.toSet()
|
||||||
|
|
||||||
|
module to nativeLibraries
|
||||||
|
}.toMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue("No Native modules found in project $project", nativeModules.isNotEmpty())
|
||||||
|
|
||||||
|
nativeModules.forEach { (module, nativeLibraries) ->
|
||||||
|
assertTrue(
|
||||||
|
"$KOTLIN_STDLIB_NAME not found for for Native module $module in project $project",
|
||||||
|
KOTLIN_STDLIB_NAME in nativeLibraries
|
||||||
|
)
|
||||||
|
|
||||||
|
assertTrue(
|
||||||
|
"No Native libraries except for $KOTLIN_STDLIB_NAME for Native module $module in project $project",
|
||||||
|
(nativeLibraries - KOTLIN_STDLIB_NAME).isNotEmpty()
|
||||||
|
)
|
||||||
|
|
||||||
|
logMessage { "$module has ${nativeLibraries.size} native libraries" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun projectName(templateName: String, enableCommonizer: Boolean, separator: Char = ' ') =
|
||||||
|
"$templateName project ${if (enableCommonizer) "with" else "without"} commonizer".replace(' ', separator)
|
||||||
|
}
|
||||||
+26
-2
@@ -14,11 +14,14 @@ import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
|
|||||||
import org.jetbrains.kotlin.idea.highlighter.KotlinPsiChecker
|
import org.jetbrains.kotlin.idea.highlighter.KotlinPsiChecker
|
||||||
import org.jetbrains.kotlin.idea.highlighter.KotlinPsiCheckerAndHighlightingUpdater
|
import org.jetbrains.kotlin.idea.highlighter.KotlinPsiCheckerAndHighlightingUpdater
|
||||||
import org.jetbrains.kotlin.idea.perf.Stats.Companion.TEST_KEY
|
import org.jetbrains.kotlin.idea.perf.Stats.Companion.TEST_KEY
|
||||||
|
import org.jetbrains.kotlin.idea.perf.Stats.Companion.WARM_UP
|
||||||
import org.jetbrains.kotlin.idea.perf.Stats.Companion.runAndMeasure
|
import org.jetbrains.kotlin.idea.perf.Stats.Companion.runAndMeasure
|
||||||
import org.jetbrains.kotlin.idea.perf.Stats.Companion.tcSuite
|
import org.jetbrains.kotlin.idea.perf.Stats.Companion.tcSuite
|
||||||
import org.jetbrains.kotlin.idea.testFramework.Fixture
|
import org.jetbrains.kotlin.idea.testFramework.Fixture
|
||||||
import org.jetbrains.kotlin.idea.testFramework.Fixture.Companion.cleanupCaches
|
import org.jetbrains.kotlin.idea.testFramework.Fixture.Companion.cleanupCaches
|
||||||
import org.jetbrains.kotlin.idea.testFramework.Fixture.Companion.isAKotlinScriptFile
|
import org.jetbrains.kotlin.idea.testFramework.Fixture.Companion.isAKotlinScriptFile
|
||||||
|
import org.jetbrains.kotlin.idea.testFramework.ProjectOpenAction.EXISTING_IDEA_PROJECT
|
||||||
|
import org.jetbrains.kotlin.idea.testFramework.ProjectOpenAction.SIMPLE_JAVA_MODULE
|
||||||
import java.util.concurrent.atomic.AtomicLong
|
import java.util.concurrent.atomic.AtomicLong
|
||||||
import kotlin.test.assertNotEquals
|
import kotlin.test.assertNotEquals
|
||||||
|
|
||||||
@@ -53,8 +56,7 @@ class PerformanceProjectsTest : AbstractPerformanceProjectsTest() {
|
|||||||
super.setUp()
|
super.setUp()
|
||||||
// warm up: open simple small project
|
// warm up: open simple small project
|
||||||
if (!warmedUp) {
|
if (!warmedUp) {
|
||||||
warmUpProject(hwStats)
|
warmUpProject(hwStats, "src/HelloMain.kt") { perfOpenHelloWorld(hwStats, WARM_UP) }
|
||||||
|
|
||||||
warmedUp = true
|
warmedUp = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -207,6 +209,28 @@ class PerformanceProjectsTest : AbstractPerformanceProjectsTest() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun perfOpenKotlinProjectFast(stats: Stats) = perfOpenKotlinProject(stats, fast = true)
|
||||||
|
|
||||||
|
private fun perfOpenKotlinProject(stats: Stats, fast: Boolean = false) {
|
||||||
|
myProject = perfOpenProject(
|
||||||
|
name = "kotlin",
|
||||||
|
stats = stats,
|
||||||
|
note = "",
|
||||||
|
path = "../perfTestProject",
|
||||||
|
openAction = EXISTING_IDEA_PROJECT,
|
||||||
|
fast = fast
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun perfOpenHelloWorld(stats: Stats, note: String = ""): Project =
|
||||||
|
perfOpenProject(
|
||||||
|
name = "helloKotlin",
|
||||||
|
stats = stats,
|
||||||
|
note = note,
|
||||||
|
path = "idea/testData/perfTest/helloKotlin",
|
||||||
|
openAction = SIMPLE_JAVA_MODULE
|
||||||
|
)
|
||||||
|
|
||||||
private fun perfScriptDependenciesBuildGradleKts(it: Stats) {
|
private fun perfScriptDependenciesBuildGradleKts(it: Stats) {
|
||||||
perfScriptDependencies("build.gradle.kts", stats = it)
|
perfScriptDependencies("build.gradle.kts", stats = it)
|
||||||
}
|
}
|
||||||
|
|||||||
+79
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.testFramework
|
||||||
|
|
||||||
|
import com.intellij.ide.highlighter.ModuleFileType
|
||||||
|
import com.intellij.openapi.application.runWriteAction
|
||||||
|
import com.intellij.openapi.module.ModuleManager
|
||||||
|
import com.intellij.openapi.module.ModuleTypeId
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.project.ex.ProjectManagerEx
|
||||||
|
import com.intellij.openapi.projectRoots.Sdk
|
||||||
|
import com.intellij.openapi.roots.ProjectRootManager
|
||||||
|
import com.intellij.openapi.vfs.LocalFileSystem
|
||||||
|
import com.intellij.testFramework.PsiTestUtil
|
||||||
|
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
|
||||||
|
import java.io.File
|
||||||
|
import kotlin.test.assertNotNull
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
enum class ProjectOpenAction {
|
||||||
|
SIMPLE_JAVA_MODULE {
|
||||||
|
override fun openProject(projectPath: String, projectName: String, jdk: Sdk): Project {
|
||||||
|
val project = ProjectManagerEx.getInstanceEx().loadAndOpenProject(projectPath)!!
|
||||||
|
|
||||||
|
val modulePath = "$projectPath/$name${ModuleFileType.DOT_DEFAULT_EXTENSION}"
|
||||||
|
val projectFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(File(projectPath))!!
|
||||||
|
val srcFile = projectFile.findChild("src")!!
|
||||||
|
|
||||||
|
val module = runWriteAction {
|
||||||
|
ProjectRootManager.getInstance(project).projectSdk = jdk
|
||||||
|
|
||||||
|
val module = ModuleManager.getInstance(project).newModule(modulePath, ModuleTypeId.JAVA_MODULE)
|
||||||
|
PsiTestUtil.addSourceRoot(module, srcFile)
|
||||||
|
|
||||||
|
module
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigLibraryUtil.configureKotlinRuntimeAndSdk(module, jdk)
|
||||||
|
|
||||||
|
return project
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
EXISTING_IDEA_PROJECT {
|
||||||
|
override fun openProject(projectPath: String, projectName: String, jdk: Sdk): Project {
|
||||||
|
val projectManagerEx = ProjectManagerEx.getInstanceEx()
|
||||||
|
|
||||||
|
val project = loadProjectWithName(projectPath, projectName)
|
||||||
|
assertNotNull(project, "project $projectName at $projectPath is not loaded")
|
||||||
|
|
||||||
|
runWriteAction {
|
||||||
|
ProjectRootManager.getInstance(project).projectSdk = jdk
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue(projectManagerEx.openProject(project), "project $projectName at $projectPath is not opened")
|
||||||
|
|
||||||
|
return project
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
GRADLE_PROJECT {
|
||||||
|
override fun openProject(projectPath: String, projectName: String, jdk: Sdk): Project {
|
||||||
|
val project = ProjectManagerEx.getInstanceEx().loadAndOpenProject(projectPath)!!
|
||||||
|
|
||||||
|
runWriteAction {
|
||||||
|
ProjectRootManager.getInstance(project).projectSdk = jdk
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshGradleProject(projectPath, project)
|
||||||
|
|
||||||
|
return project
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
abstract fun openProject(projectPath: String, projectName: String, jdk: Sdk): Project
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
build
|
||||||
|
.idea
|
||||||
|
.gradle
|
||||||
|
gradlew*
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("multiplatform") version "{{kotlin_plugin_version}}"
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
maven("https://dl.bintray.com/kotlin/kotlin-dev")
|
||||||
|
maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
ios() {
|
||||||
|
compilations["main"].enableEndorsedLibs = true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
kotlin.mpp.enableGranularSourceSetsMetadata=true
|
||||||
|
kotlin.native.enableDependencyPropagation={{disable_commonizer}}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-{{gradle_version}}-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
pluginManagement {
|
||||||
|
repositories {
|
||||||
|
gradlePluginPortal()
|
||||||
|
maven("https://dl.bintray.com/kotlin/kotlin-dev")
|
||||||
|
maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import kotlinx.cinterop.ByteVar
|
||||||
|
import kotlinx.cinterop.allocArray
|
||||||
|
import kotlinx.cinterop.memScoped
|
||||||
|
import kotlinx.cinterop.toKString
|
||||||
|
import kotlinx.cli.ArgParser
|
||||||
|
import kotlinx.cli.ArgType
|
||||||
|
import kotlinx.cli.required
|
||||||
|
import platform.posix.fclose
|
||||||
|
import platform.posix.fgets
|
||||||
|
import platform.posix.fopen
|
||||||
|
import platform.posix.perror
|
||||||
|
import kotlin.collections.set
|
||||||
|
|
||||||
|
private fun parseLine(line: String, separator: Char) : List<String> {
|
||||||
|
val result = mutableListOf<String>()
|
||||||
|
val builder = StringBuilder()
|
||||||
|
var quotes = 0
|
||||||
|
for (ch in line) {
|
||||||
|
when {
|
||||||
|
ch == '\"' -> {
|
||||||
|
quotes++
|
||||||
|
builder.append(ch)
|
||||||
|
}
|
||||||
|
(ch == '\n') || (ch == '\r') -> {}
|
||||||
|
(ch == separator) && (quotes % 2 == 0) -> {
|
||||||
|
result.add(builder.toString())
|
||||||
|
builder.setLength(0)
|
||||||
|
}
|
||||||
|
else -> builder.append(ch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val argParser = ArgParser("csvparser")
|
||||||
|
val fileName by argParser.argument(ArgType.String, description = "CSV file")
|
||||||
|
val column by argParser.option(ArgType.Int, description = "Column to parse").required()
|
||||||
|
val count by argParser.option(ArgType.Int, description = "Count of lines to parse").required()
|
||||||
|
argParser.parse(args)
|
||||||
|
|
||||||
|
val file = fopen(fileName, "r")
|
||||||
|
if (file == null) {
|
||||||
|
perror("cannot open input file $fileName")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val keyValue = mutableMapOf<String, Int>()
|
||||||
|
|
||||||
|
try {
|
||||||
|
memScoped {
|
||||||
|
val bufferLength = 64 * 1024
|
||||||
|
val buffer = allocArray<ByteVar>(bufferLength)
|
||||||
|
|
||||||
|
for (i in 1..count) {
|
||||||
|
val nextLine = fgets(buffer, bufferLength, file)?.toKString()
|
||||||
|
if (nextLine == null || nextLine.isEmpty()) break
|
||||||
|
|
||||||
|
val records = parseLine(nextLine, ',')
|
||||||
|
val key = records[column]
|
||||||
|
val current = keyValue[key] ?: 0
|
||||||
|
keyValue[key] = current + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
fclose(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
keyValue.forEach {
|
||||||
|
println("${it.key} -> ${it.value}")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import kotlinx.cinterop.ByteVar
|
||||||
|
import kotlinx.cinterop.allocArray
|
||||||
|
import kotlinx.cinterop.memScoped
|
||||||
|
import kotlinx.cinterop.toKString
|
||||||
|
import kotlinx.cli.ArgParser
|
||||||
|
import kotlinx.cli.ArgType
|
||||||
|
import kotlinx.cli.required
|
||||||
|
import platform.posix.fclose
|
||||||
|
import platform.posix.fgets
|
||||||
|
import platform.posix.fopen
|
||||||
|
import platform.posix.perror
|
||||||
|
import kotlin.collections.set
|
||||||
|
|
||||||
|
private fun parseLine(line: String, separator: Char) : List<String> {
|
||||||
|
val result = mutableListOf<String>()
|
||||||
|
val builder = StringBuilder()
|
||||||
|
var quotes = 0
|
||||||
|
for (ch in line) {
|
||||||
|
when {
|
||||||
|
ch == '\"' -> {
|
||||||
|
quotes++
|
||||||
|
builder.append(ch)
|
||||||
|
}
|
||||||
|
(ch == '\n') || (ch == '\r') -> {}
|
||||||
|
(ch == separator) && (quotes % 2 == 0) -> {
|
||||||
|
result.add(builder.toString())
|
||||||
|
builder.setLength(0)
|
||||||
|
}
|
||||||
|
else -> builder.append(ch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val argParser = ArgParser("csvparser")
|
||||||
|
val fileName by argParser.argument(ArgType.String, description = "CSV file")
|
||||||
|
val column by argParser.option(ArgType.Int, description = "Column to parse").required()
|
||||||
|
val count by argParser.option(ArgType.Int, description = "Count of lines to parse").required()
|
||||||
|
argParser.parse(args)
|
||||||
|
|
||||||
|
val file = fopen(fileName, "r")
|
||||||
|
if (file == null) {
|
||||||
|
perror("cannot open input file $fileName")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val keyValue = mutableMapOf<String, Int>()
|
||||||
|
|
||||||
|
try {
|
||||||
|
memScoped {
|
||||||
|
val bufferLength = 64 * 1024
|
||||||
|
val buffer = allocArray<ByteVar>(bufferLength)
|
||||||
|
|
||||||
|
for (i in 1..count) {
|
||||||
|
val nextLine = fgets(buffer, bufferLength, file)?.toKString()
|
||||||
|
if (nextLine == null || nextLine.isEmpty()) break
|
||||||
|
|
||||||
|
val records = parseLine(nextLine, ',')
|
||||||
|
val key = records[column]
|
||||||
|
val current = keyValue[key] ?: 0
|
||||||
|
keyValue[key] = current + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
fclose(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
keyValue.forEach {
|
||||||
|
println("${it.key} -> ${it.value}")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import kotlinx.cinterop.ByteVar
|
||||||
|
import kotlinx.cinterop.allocArray
|
||||||
|
import kotlinx.cinterop.memScoped
|
||||||
|
import kotlinx.cinterop.toKString
|
||||||
|
import kotlinx.cli.ArgParser
|
||||||
|
import kotlinx.cli.ArgType
|
||||||
|
import kotlinx.cli.required
|
||||||
|
import platform.posix.fclose
|
||||||
|
import platform.posix.fgets
|
||||||
|
import platform.posix.fopen
|
||||||
|
import platform.posix.perror
|
||||||
|
import kotlin.collections.set
|
||||||
|
|
||||||
|
private fun parseLine(line: String, separator: Char) : List<String> {
|
||||||
|
val result = mutableListOf<String>()
|
||||||
|
val builder = StringBuilder()
|
||||||
|
var quotes = 0
|
||||||
|
for (ch in line) {
|
||||||
|
when {
|
||||||
|
ch == '\"' -> {
|
||||||
|
quotes++
|
||||||
|
builder.append(ch)
|
||||||
|
}
|
||||||
|
(ch == '\n') || (ch == '\r') -> {}
|
||||||
|
(ch == separator) && (quotes % 2 == 0) -> {
|
||||||
|
result.add(builder.toString())
|
||||||
|
builder.setLength(0)
|
||||||
|
}
|
||||||
|
else -> builder.append(ch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val argParser = ArgParser("csvparser")
|
||||||
|
val fileName by argParser.argument(ArgType.String, description = "CSV file")
|
||||||
|
val column by argParser.option(ArgType.Int, description = "Column to parse").required()
|
||||||
|
val count by argParser.option(ArgType.Int, description = "Count of lines to parse").required()
|
||||||
|
argParser.parse(args)
|
||||||
|
|
||||||
|
val file = fopen(fileName, "r")
|
||||||
|
if (file == null) {
|
||||||
|
perror("cannot open input file $fileName")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val keyValue = mutableMapOf<String, Int>()
|
||||||
|
|
||||||
|
try {
|
||||||
|
memScoped {
|
||||||
|
val bufferLength = 64 * 1024
|
||||||
|
val buffer = allocArray<ByteVar>(bufferLength)
|
||||||
|
|
||||||
|
for (i in 1..count) {
|
||||||
|
val nextLine = fgets(buffer, bufferLength, file)?.toKString()
|
||||||
|
if (nextLine == null || nextLine.isEmpty()) break
|
||||||
|
|
||||||
|
val records = parseLine(nextLine, ',')
|
||||||
|
val key = records[column]
|
||||||
|
val current = keyValue[key] ?: 0
|
||||||
|
keyValue[key] = current + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
fclose(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
keyValue.forEach {
|
||||||
|
println("${it.key} -> ${it.value}")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
build
|
||||||
|
.idea
|
||||||
|
.gradle
|
||||||
|
gradlew*
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("multiplatform") version "{{kotlin_plugin_version}}"
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
maven("https://dl.bintray.com/kotlin/kotlin-dev")
|
||||||
|
maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
ios()
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
kotlin.mpp.enableGranularSourceSetsMetadata=true
|
||||||
|
kotlin.native.enableDependencyPropagation={{disable_commonizer}}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-{{gradle_version}}-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
pluginManagement {
|
||||||
|
repositories {
|
||||||
|
gradlePluginPortal()
|
||||||
|
maven("https://dl.bintray.com/kotlin/kotlin-dev")
|
||||||
|
maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println("Hello World!")
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println("Hello World!")
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println("Hello World!")
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
private const val GREETING = "Hello, Kotlin/Native!"
|
||||||
|
|
||||||
|
class HelloTest {
|
||||||
|
@Test
|
||||||
|
fun testHello() {
|
||||||
|
assertTrue("Kotlin/Native" in GREETING)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
private const val GREETING = "Hello, Kotlin/Native!"
|
||||||
|
|
||||||
|
class HelloTest2 {
|
||||||
|
@Test
|
||||||
|
fun testHello() {
|
||||||
|
assertTrue("Kotlin/Native" in GREETING)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
private const val GREETING = "Hello, Kotlin/Native!"
|
||||||
|
|
||||||
|
class HelloTest3 {
|
||||||
|
@Test
|
||||||
|
fun testHello() {
|
||||||
|
assertTrue("Kotlin/Native" in GREETING)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
build
|
||||||
|
.idea
|
||||||
|
.gradle
|
||||||
|
gradlew*
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("multiplatform") version "{{kotlin_plugin_version}}"
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
maven("https://dl.bintray.com/kotlin/kotlin-dev")
|
||||||
|
maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
ios()
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
kotlin.mpp.enableGranularSourceSetsMetadata=true
|
||||||
|
kotlin.native.enableDependencyPropagation={{disable_commonizer}}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-{{gradle_version}}-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
pluginManagement {
|
||||||
|
repositories {
|
||||||
|
gradlePluginPortal()
|
||||||
|
maven("https://dl.bintray.com/kotlin/kotlin-dev")
|
||||||
|
maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import kotlinx.cinterop.ExportObjCClass
|
||||||
|
import kotlinx.cinterop.ObjCAction
|
||||||
|
import kotlinx.cinterop.ObjCOutlet
|
||||||
|
import kotlinx.cinterop.autoreleasepool
|
||||||
|
import kotlinx.cinterop.cstr
|
||||||
|
import kotlinx.cinterop.memScoped
|
||||||
|
import kotlinx.cinterop.toCValues
|
||||||
|
import kotlinx.cinterop.useContents
|
||||||
|
import platform.CoreGraphics.CGPointMake
|
||||||
|
import platform.CoreGraphics.CGRectMake
|
||||||
|
import platform.Foundation.NSCoder
|
||||||
|
import platform.Foundation.NSSelectorFromString
|
||||||
|
import platform.Foundation.NSStringFromClass
|
||||||
|
import platform.UIKit.NSTextAlignmentCenter
|
||||||
|
import platform.UIKit.UIApplication
|
||||||
|
import platform.UIKit.UIApplicationDelegateProtocol
|
||||||
|
import platform.UIKit.UIApplicationDelegateProtocolMeta
|
||||||
|
import platform.UIKit.UIApplicationMain
|
||||||
|
import platform.UIKit.UIButton
|
||||||
|
import platform.UIKit.UIColor
|
||||||
|
import platform.UIKit.UIControlEventTouchUpInside
|
||||||
|
import platform.UIKit.UIControlStateNormal
|
||||||
|
import platform.UIKit.UIFont
|
||||||
|
import platform.UIKit.UILabel
|
||||||
|
import platform.UIKit.UIResponder
|
||||||
|
import platform.UIKit.UIResponderMeta
|
||||||
|
import platform.UIKit.UIScreen
|
||||||
|
import platform.UIKit.UIView
|
||||||
|
import platform.UIKit.UIViewController
|
||||||
|
import platform.UIKit.UIWindow
|
||||||
|
import platform.UIKit.addSubview
|
||||||
|
import platform.UIKit.backgroundColor
|
||||||
|
import platform.UIKit.font
|
||||||
|
import platform.UIKit.heightAnchor
|
||||||
|
import platform.UIKit.leadingAnchor
|
||||||
|
import platform.UIKit.setFrame
|
||||||
|
import platform.UIKit.topAnchor
|
||||||
|
import platform.UIKit.translatesAutoresizingMaskIntoConstraints
|
||||||
|
import platform.UIKit.widthAnchor
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
memScoped {
|
||||||
|
val argc = args.size + 1
|
||||||
|
val argv = (arrayOf("konan") + args).map { it.cstr.ptr }.toCValues()
|
||||||
|
|
||||||
|
autoreleasepool {
|
||||||
|
UIApplicationMain(argc, argv, null, NSStringFromClass(AppDelegate))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class AppDelegate : UIResponder, UIApplicationDelegateProtocol {
|
||||||
|
companion object : UIResponderMeta(), UIApplicationDelegateProtocolMeta {}
|
||||||
|
|
||||||
|
@OverrideInit
|
||||||
|
constructor() : super()
|
||||||
|
|
||||||
|
private var _window: UIWindow? = null
|
||||||
|
override fun window() = _window
|
||||||
|
override fun setWindow(window: UIWindow?) {
|
||||||
|
_window = window
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun application(application: UIApplication, didFinishLaunchingWithOptions: Map<Any?, *>?): Boolean {
|
||||||
|
window = UIWindow(frame = UIScreen.mainScreen.bounds)
|
||||||
|
window!!.rootViewController = ViewController()
|
||||||
|
window!!.makeKeyAndVisible()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportObjCClass
|
||||||
|
private class ViewController : UIViewController {
|
||||||
|
|
||||||
|
@OverrideInit
|
||||||
|
constructor() : super(nibName = null, bundle = null)
|
||||||
|
|
||||||
|
@OverrideInit
|
||||||
|
constructor(coder: NSCoder) : super(coder)
|
||||||
|
|
||||||
|
@ObjCOutlet
|
||||||
|
lateinit var label: UILabel
|
||||||
|
|
||||||
|
@ObjCOutlet
|
||||||
|
lateinit var button: UIButton
|
||||||
|
|
||||||
|
var pressed = 0
|
||||||
|
|
||||||
|
@ObjCAction
|
||||||
|
fun buttonPressed() {
|
||||||
|
label.text = "Hello #${pressed++} from Konan!"
|
||||||
|
println("Button pressed")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
val (width, height) = UIScreen.mainScreen.bounds.useContents {
|
||||||
|
this.size.width to this.size.height
|
||||||
|
}
|
||||||
|
|
||||||
|
val header = UIView().apply {
|
||||||
|
backgroundColor = UIColor.lightGrayColor
|
||||||
|
view.addSubview(this)
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
leadingAnchor.constraintEqualToAnchor(view.leadingAnchor).active = true
|
||||||
|
topAnchor.constraintEqualToAnchor(view.topAnchor).active = true
|
||||||
|
widthAnchor.constraintEqualToAnchor(view.widthAnchor).active = true
|
||||||
|
heightAnchor.constraintEqualToAnchor(view.heightAnchor).active = true
|
||||||
|
}
|
||||||
|
|
||||||
|
label = UILabel().apply {
|
||||||
|
setFrame(CGRectMake(x = 10.0, y = 10.0, width = width - 100.0, height = 40.0))
|
||||||
|
center = CGPointMake(x = width / 2, y = 40.0 )
|
||||||
|
textAlignment = NSTextAlignmentCenter
|
||||||
|
text = "Press OK"
|
||||||
|
header.addSubview(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
button = UIButton().apply {
|
||||||
|
setFrame(CGRectMake(x = 10.0, y = height - 100.0, width = width - 100.0, height = 40.0))
|
||||||
|
center = CGPointMake(x = width / 2, y = height / 2)
|
||||||
|
backgroundColor = UIColor.blueColor
|
||||||
|
setTitle("OK", forState = UIControlStateNormal)
|
||||||
|
font = UIFont.fontWithName(fontName = font.fontName, size = 28.0)!!
|
||||||
|
layer.borderWidth = 1.0
|
||||||
|
layer.borderColor = UIColor.colorWithRed(0x47 / 255.0, 0x43 / 255.0, 0x70 / 255.0, 1.0).CGColor
|
||||||
|
layer.masksToBounds = true
|
||||||
|
addTarget(target = this@ViewController, action = NSSelectorFromString("buttonPressed"),
|
||||||
|
forControlEvents = UIControlEventTouchUpInside)
|
||||||
|
header.addSubview(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import kotlinx.cinterop.ExportObjCClass
|
||||||
|
import kotlinx.cinterop.ObjCAction
|
||||||
|
import kotlinx.cinterop.ObjCOutlet
|
||||||
|
import kotlinx.cinterop.autoreleasepool
|
||||||
|
import kotlinx.cinterop.cstr
|
||||||
|
import kotlinx.cinterop.memScoped
|
||||||
|
import kotlinx.cinterop.toCValues
|
||||||
|
import kotlinx.cinterop.useContents
|
||||||
|
import platform.CoreGraphics.CGPointMake
|
||||||
|
import platform.CoreGraphics.CGRectMake
|
||||||
|
import platform.Foundation.NSCoder
|
||||||
|
import platform.Foundation.NSSelectorFromString
|
||||||
|
import platform.Foundation.NSStringFromClass
|
||||||
|
import platform.UIKit.NSTextAlignmentCenter
|
||||||
|
import platform.UIKit.UIApplication
|
||||||
|
import platform.UIKit.UIApplicationDelegateProtocol
|
||||||
|
import platform.UIKit.UIApplicationDelegateProtocolMeta
|
||||||
|
import platform.UIKit.UIApplicationMain
|
||||||
|
import platform.UIKit.UIButton
|
||||||
|
import platform.UIKit.UIColor
|
||||||
|
import platform.UIKit.UIControlEventTouchUpInside
|
||||||
|
import platform.UIKit.UIControlStateNormal
|
||||||
|
import platform.UIKit.UIFont
|
||||||
|
import platform.UIKit.UILabel
|
||||||
|
import platform.UIKit.UIResponder
|
||||||
|
import platform.UIKit.UIResponderMeta
|
||||||
|
import platform.UIKit.UIScreen
|
||||||
|
import platform.UIKit.UIView
|
||||||
|
import platform.UIKit.UIViewController
|
||||||
|
import platform.UIKit.UIWindow
|
||||||
|
import platform.UIKit.addSubview
|
||||||
|
import platform.UIKit.backgroundColor
|
||||||
|
import platform.UIKit.font
|
||||||
|
import platform.UIKit.heightAnchor
|
||||||
|
import platform.UIKit.leadingAnchor
|
||||||
|
import platform.UIKit.setFrame
|
||||||
|
import platform.UIKit.topAnchor
|
||||||
|
import platform.UIKit.translatesAutoresizingMaskIntoConstraints
|
||||||
|
import platform.UIKit.widthAnchor
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
memScoped {
|
||||||
|
val argc = args.size + 1
|
||||||
|
val argv = (arrayOf("konan") + args).map { it.cstr.ptr }.toCValues()
|
||||||
|
|
||||||
|
autoreleasepool {
|
||||||
|
UIApplicationMain(argc, argv, null, NSStringFromClass(AppDelegate))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class AppDelegate : UIResponder, UIApplicationDelegateProtocol {
|
||||||
|
companion object : UIResponderMeta(), UIApplicationDelegateProtocolMeta {}
|
||||||
|
|
||||||
|
@OverrideInit
|
||||||
|
constructor() : super()
|
||||||
|
|
||||||
|
private var _window: UIWindow? = null
|
||||||
|
override fun window() = _window
|
||||||
|
override fun setWindow(window: UIWindow?) {
|
||||||
|
_window = window
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun application(application: UIApplication, didFinishLaunchingWithOptions: Map<Any?, *>?): Boolean {
|
||||||
|
window = UIWindow(frame = UIScreen.mainScreen.bounds)
|
||||||
|
window!!.rootViewController = ViewController()
|
||||||
|
window!!.makeKeyAndVisible()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportObjCClass
|
||||||
|
private class ViewController : UIViewController {
|
||||||
|
|
||||||
|
@OverrideInit
|
||||||
|
constructor() : super(nibName = null, bundle = null)
|
||||||
|
|
||||||
|
@OverrideInit
|
||||||
|
constructor(coder: NSCoder) : super(coder)
|
||||||
|
|
||||||
|
@ObjCOutlet
|
||||||
|
lateinit var label: UILabel
|
||||||
|
|
||||||
|
@ObjCOutlet
|
||||||
|
lateinit var button: UIButton
|
||||||
|
|
||||||
|
var pressed = 0
|
||||||
|
|
||||||
|
@ObjCAction
|
||||||
|
fun buttonPressed() {
|
||||||
|
label.text = "Hello #${pressed++} from Konan!"
|
||||||
|
println("Button pressed")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
val (width, height) = UIScreen.mainScreen.bounds.useContents {
|
||||||
|
this.size.width to this.size.height
|
||||||
|
}
|
||||||
|
|
||||||
|
val header = UIView().apply {
|
||||||
|
backgroundColor = UIColor.lightGrayColor
|
||||||
|
view.addSubview(this)
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
leadingAnchor.constraintEqualToAnchor(view.leadingAnchor).active = true
|
||||||
|
topAnchor.constraintEqualToAnchor(view.topAnchor).active = true
|
||||||
|
widthAnchor.constraintEqualToAnchor(view.widthAnchor).active = true
|
||||||
|
heightAnchor.constraintEqualToAnchor(view.heightAnchor).active = true
|
||||||
|
}
|
||||||
|
|
||||||
|
label = UILabel().apply {
|
||||||
|
setFrame(CGRectMake(x = 10.0, y = 10.0, width = width - 100.0, height = 40.0))
|
||||||
|
center = CGPointMake(x = width / 2, y = 40.0 )
|
||||||
|
textAlignment = NSTextAlignmentCenter
|
||||||
|
text = "Press OK"
|
||||||
|
header.addSubview(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
button = UIButton().apply {
|
||||||
|
setFrame(CGRectMake(x = 10.0, y = height - 100.0, width = width - 100.0, height = 40.0))
|
||||||
|
center = CGPointMake(x = width / 2, y = height / 2)
|
||||||
|
backgroundColor = UIColor.blueColor
|
||||||
|
setTitle("OK", forState = UIControlStateNormal)
|
||||||
|
font = UIFont.fontWithName(fontName = font.fontName, size = 28.0)!!
|
||||||
|
layer.borderWidth = 1.0
|
||||||
|
layer.borderColor = UIColor.colorWithRed(0x47 / 255.0, 0x43 / 255.0, 0x70 / 255.0, 1.0).CGColor
|
||||||
|
layer.masksToBounds = true
|
||||||
|
addTarget(target = this@ViewController, action = NSSelectorFromString("buttonPressed"),
|
||||||
|
forControlEvents = UIControlEventTouchUpInside)
|
||||||
|
header.addSubview(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import kotlinx.cinterop.ExportObjCClass
|
||||||
|
import kotlinx.cinterop.ObjCAction
|
||||||
|
import kotlinx.cinterop.ObjCOutlet
|
||||||
|
import kotlinx.cinterop.autoreleasepool
|
||||||
|
import kotlinx.cinterop.cstr
|
||||||
|
import kotlinx.cinterop.memScoped
|
||||||
|
import kotlinx.cinterop.toCValues
|
||||||
|
import kotlinx.cinterop.useContents
|
||||||
|
import platform.CoreGraphics.CGPointMake
|
||||||
|
import platform.CoreGraphics.CGRectMake
|
||||||
|
import platform.Foundation.NSCoder
|
||||||
|
import platform.Foundation.NSSelectorFromString
|
||||||
|
import platform.Foundation.NSStringFromClass
|
||||||
|
import platform.UIKit.NSTextAlignmentCenter
|
||||||
|
import platform.UIKit.UIApplication
|
||||||
|
import platform.UIKit.UIApplicationDelegateProtocol
|
||||||
|
import platform.UIKit.UIApplicationDelegateProtocolMeta
|
||||||
|
import platform.UIKit.UIApplicationMain
|
||||||
|
import platform.UIKit.UIButton
|
||||||
|
import platform.UIKit.UIColor
|
||||||
|
import platform.UIKit.UIControlEventTouchUpInside
|
||||||
|
import platform.UIKit.UIControlStateNormal
|
||||||
|
import platform.UIKit.UIFont
|
||||||
|
import platform.UIKit.UILabel
|
||||||
|
import platform.UIKit.UIResponder
|
||||||
|
import platform.UIKit.UIResponderMeta
|
||||||
|
import platform.UIKit.UIScreen
|
||||||
|
import platform.UIKit.UIView
|
||||||
|
import platform.UIKit.UIViewController
|
||||||
|
import platform.UIKit.UIWindow
|
||||||
|
import platform.UIKit.addSubview
|
||||||
|
import platform.UIKit.backgroundColor
|
||||||
|
import platform.UIKit.font
|
||||||
|
import platform.UIKit.heightAnchor
|
||||||
|
import platform.UIKit.leadingAnchor
|
||||||
|
import platform.UIKit.setFrame
|
||||||
|
import platform.UIKit.topAnchor
|
||||||
|
import platform.UIKit.translatesAutoresizingMaskIntoConstraints
|
||||||
|
import platform.UIKit.widthAnchor
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
memScoped {
|
||||||
|
val argc = args.size + 1
|
||||||
|
val argv = (arrayOf("konan") + args).map { it.cstr.ptr }.toCValues()
|
||||||
|
|
||||||
|
autoreleasepool {
|
||||||
|
UIApplicationMain(argc, argv, null, NSStringFromClass(AppDelegate))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class AppDelegate : UIResponder, UIApplicationDelegateProtocol {
|
||||||
|
companion object : UIResponderMeta(), UIApplicationDelegateProtocolMeta {}
|
||||||
|
|
||||||
|
@OverrideInit
|
||||||
|
constructor() : super()
|
||||||
|
|
||||||
|
private var _window: UIWindow? = null
|
||||||
|
override fun window() = _window
|
||||||
|
override fun setWindow(window: UIWindow?) {
|
||||||
|
_window = window
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun application(application: UIApplication, didFinishLaunchingWithOptions: Map<Any?, *>?): Boolean {
|
||||||
|
window = UIWindow(frame = UIScreen.mainScreen.bounds)
|
||||||
|
window!!.rootViewController = ViewController()
|
||||||
|
window!!.makeKeyAndVisible()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportObjCClass
|
||||||
|
private class ViewController : UIViewController {
|
||||||
|
|
||||||
|
@OverrideInit
|
||||||
|
constructor() : super(nibName = null, bundle = null)
|
||||||
|
|
||||||
|
@OverrideInit
|
||||||
|
constructor(coder: NSCoder) : super(coder)
|
||||||
|
|
||||||
|
@ObjCOutlet
|
||||||
|
lateinit var label: UILabel
|
||||||
|
|
||||||
|
@ObjCOutlet
|
||||||
|
lateinit var button: UIButton
|
||||||
|
|
||||||
|
var pressed = 0
|
||||||
|
|
||||||
|
@ObjCAction
|
||||||
|
fun buttonPressed() {
|
||||||
|
label.text = "Hello #${pressed++} from Konan!"
|
||||||
|
println("Button pressed")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
val (width, height) = UIScreen.mainScreen.bounds.useContents {
|
||||||
|
this.size.width to this.size.height
|
||||||
|
}
|
||||||
|
|
||||||
|
val header = UIView().apply {
|
||||||
|
backgroundColor = UIColor.lightGrayColor
|
||||||
|
view.addSubview(this)
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
leadingAnchor.constraintEqualToAnchor(view.leadingAnchor).active = true
|
||||||
|
topAnchor.constraintEqualToAnchor(view.topAnchor).active = true
|
||||||
|
widthAnchor.constraintEqualToAnchor(view.widthAnchor).active = true
|
||||||
|
heightAnchor.constraintEqualToAnchor(view.heightAnchor).active = true
|
||||||
|
}
|
||||||
|
|
||||||
|
label = UILabel().apply {
|
||||||
|
setFrame(CGRectMake(x = 10.0, y = 10.0, width = width - 100.0, height = 40.0))
|
||||||
|
center = CGPointMake(x = width / 2, y = 40.0 )
|
||||||
|
textAlignment = NSTextAlignmentCenter
|
||||||
|
text = "Press OK"
|
||||||
|
header.addSubview(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
button = UIButton().apply {
|
||||||
|
setFrame(CGRectMake(x = 10.0, y = height - 100.0, width = width - 100.0, height = 40.0))
|
||||||
|
center = CGPointMake(x = width / 2, y = height / 2)
|
||||||
|
backgroundColor = UIColor.blueColor
|
||||||
|
setTitle("OK", forState = UIControlStateNormal)
|
||||||
|
font = UIFont.fontWithName(fontName = font.fontName, size = 28.0)!!
|
||||||
|
layer.borderWidth = 1.0
|
||||||
|
layer.borderColor = UIColor.colorWithRed(0x47 / 255.0, 0x43 / 255.0, 0x70 / 255.0, 1.0).CGColor
|
||||||
|
layer.masksToBounds = true
|
||||||
|
addTarget(target = this@ViewController, action = NSSelectorFromString("buttonPressed"),
|
||||||
|
forControlEvents = UIControlEventTouchUpInside)
|
||||||
|
header.addSubview(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user