init sampler
diff --git a/idea-runner/build.gradle.kts b/idea-runner/build.gradle.kts
index 580719e..e3d2890 100644
--- a/idea-runner/build.gradle.kts
+++ b/idea-runner/build.gradle.kts
@@ -9,6 +9,7 @@
compileOnly(project(":idea:idea-maven"))
compileOnly(project(":idea:idea-gradle"))
compileOnly(project(":idea:idea-jvm"))
+ compileOnly(project(":idea:idea-sampler"))
runtimeOnly(intellijDep())
runtimeOnly(intellijRuntimeAnnotations())
diff --git a/idea/idea-sampler/build.gradle.kts b/idea/idea-sampler/build.gradle.kts
new file mode 100644
index 0000000..9ed8ba7
--- /dev/null
+++ b/idea/idea-sampler/build.gradle.kts
@@ -0,0 +1,16 @@
+plugins {
+ kotlin("jvm")
+ id("jps-compatible")
+}
+
+dependencies {
+ compileOnly(project(":idea"))
+ compileOnly(project(":idea:idea-core"))
+
+ compileOnly(intellijDep())
+}
+
+sourceSets {
+ "main" { projectDefault() }
+ "test" { projectDefault() }
+}
diff --git a/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/KotlinSamplerModuleBuilder.kt b/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/KotlinSamplerModuleBuilder.kt
new file mode 100644
index 0000000..2087349
--- /dev/null
+++ b/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/KotlinSamplerModuleBuilder.kt
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2010-2019 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.ide.sampler
+
+import com.intellij.ide.actions.ImportModuleAction
+import com.intellij.ide.util.newProjectWizard.AddModuleWizard
+import com.intellij.ide.util.projectWizard.ModuleBuilder
+import com.intellij.ide.util.projectWizard.ModuleWizardStep
+import com.intellij.ide.util.projectWizard.WizardContext
+import com.intellij.openapi.components.ServiceManager
+import com.intellij.openapi.externalSystem.service.project.ProjectDataManager
+import com.intellij.openapi.externalSystem.service.project.wizard.AbstractExternalModuleBuilder
+import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings
+import com.intellij.openapi.module.JavaModuleType
+import com.intellij.openapi.module.ModifiableModuleModel
+import com.intellij.openapi.module.Module
+import com.intellij.openapi.module.ModuleType
+import com.intellij.openapi.progress.ProgressManager
+import com.intellij.openapi.roots.ModifiableRootModel
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider
+import com.intellij.ui.components.JBTextField
+import org.jetbrains.kotlin.idea.KotlinIcons
+import org.jetbrains.kotlin.idea.framework.SAMPLER_SYSTEM_ID
+import org.jetbrains.plugins.gradle.service.project.wizard.GradleProjectImportBuilder
+import org.jetbrains.plugins.gradle.service.project.wizard.GradleProjectImportProvider
+import java.io.File
+import javax.swing.Icon
+import javax.swing.JComponent
+import javax.swing.event.DocumentEvent
+import javax.swing.event.DocumentListener
+
+class KotlinSamplerModuleBuilder : AbstractExternalModuleBuilder<SamplerProjectSettings>(SAMPLER_SYSTEM_ID, SamplerProjectSettings()) {
+
+ private val samples = mutableMapOf<String, SampleInfo>()
+
+ private val settingsComponents = SampleTemplateList()
+
+ private val searchField: JBTextField = JBTextField().apply {
+ emptyText.text = "input some int"
+ }
+
+ override fun getGroupName(): String = "Kotlin"
+
+ override fun getNodeIcon(): Icon = KotlinIcons.SMALL_LOGO
+
+ override fun getBuilderId() = "KotlinSamplerBuilderId"
+
+ override fun getModuleType(): ModuleType<*> = JavaModuleType.getModuleType()
+
+ override fun createModule(moduleModel: ModifiableModuleModel): Module {
+ val oldPath = moduleFilePath
+ val file = File(oldPath)
+ val path = file.parent + "/" + file.name.toLowerCase()
+ moduleFilePath = path
+
+ val settings = externalProjectSettings
+ settings.externalProjectPath = path
+ settings.isUseAutoImport = false
+ settings.isCreateEmptyContentRootDirectories = false
+
+ ModuleBuilder.deleteModuleFile(oldPath)
+
+ val module: Module = moduleModel.newModule(path, moduleType.id)
+ moduleModel.commit()
+
+ setupModule(module)
+ return module
+ }
+
+ // TODO
+ override fun setupRootModel(model: ModifiableRootModel) {
+ val info = settingsComponents.list.selectedValue
+ val moduleDir = File(contentEntryPath!!)
+ val sample = SamplerInteraction.getSample(info.id)!!
+ createTemplate(sample, moduleDir)
+
+ when (sample.type) {
+ BuildSystemType.GRADLE -> {
+ val buildFile = sample.files.find { it.extension == "gradle" }!!
+ val gradleFile = File(moduleDir, buildFile.fullPath())
+ val projectDataManager = ServiceManager.getService(ProjectDataManager::class.java)
+ val gradleProjectImportBuilder = GradleProjectImportBuilder(projectDataManager)
+ val gradleProjectImportProvider = GradleProjectImportProvider(gradleProjectImportBuilder)
+ val wizard = AddModuleWizard(model.project, gradleFile.getPath(), gradleProjectImportProvider)
+ if (wizard.stepCount <= 0 || wizard.showAndGet()) {
+ ImportModuleAction.createFromWizard(model.project, wizard)
+ }
+ }
+ BuildSystemType.MAVEN -> TODO()
+ BuildSystemType.NONE -> {
+ }
+ }
+ }
+
+ private fun createTemplate(sample: Sample, moduleDir: File) {
+ sample.files.forEach { sf ->
+ val file = File(
+ moduleDir,
+ "${sf.path}/${sf.name}.${sf.extension}"
+ )
+ if (!file.exists()) {
+ file.parentFile.mkdirs()
+ file.createNewFile()
+ }
+ file.printWriter().use { out -> out.print(sf.content) }
+ }
+ }
+
+ override fun createWizardSteps(wizardContext: WizardContext, modulesProvider: ModulesProvider): Array<ModuleWizardStep> {
+ settingsComponents.setItems(SamplerInteraction.getSamplerInfos())
+ val step = object : ModuleWizardStep() {
+ override fun updateDataModel() {
+ }
+
+ override fun getComponent(): JComponent = settingsComponents.mainPanel
+ }
+
+ searchField.document.addDocumentListener(object : DocumentListener {
+ override fun changedUpdate(e: DocumentEvent?) {
+ }
+
+ override fun insertUpdate(e: DocumentEvent?) {
+ }
+
+ override fun removeUpdate(e: DocumentEvent?) {
+ }
+ })
+
+ return arrayOf(step)
+ }
+
+ private fun downloadSamples() {
+ doWithProgress(
+ // TODO report errors
+ {
+ SamplerInteraction.getSamplerInfos().forEach { samples[it.name] = it }
+ },
+ "Downloading list of templates..."
+ )
+ }
+
+
+ private fun doWithProgress(body: () -> Unit, title: String) {
+ ProgressManager.getInstance().runProcessWithProgressSynchronously(
+ body, title, false, null
+ )
+ }
+}
+
+
+class SamplerProjectSettings : ExternalProjectSettings() {
+ override fun clone(): ExternalProjectSettings {
+ return SamplerProjectSettings()
+ }
+}
diff --git a/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/SampleTemplateList.kt b/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/SampleTemplateList.kt
new file mode 100644
index 0000000..a10e7ac
--- /dev/null
+++ b/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/SampleTemplateList.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2010-2019 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.ide.sampler
+
+import com.intellij.ui.components.JBList
+import com.intellij.ui.components.JBScrollPane
+import com.intellij.ui.components.JBTextField
+import com.intellij.ui.layout.GrowPolicy
+import com.intellij.ui.layout.panel
+import javax.swing.JPanel
+import javax.swing.JTextPane
+
+class SampleTemplateList {
+ lateinit var search: JBTextField
+ lateinit var description: JTextPane
+ lateinit var list: JBList<SampleInfo>
+ private set
+
+ fun setItems(items: List<SampleInfo>) {
+ list.model = JBList.createDefaultListModel(items)
+ }
+
+ val mainPanel: JPanel =
+ panel {
+ row {
+ cell {
+ JBTextField().apply { search = this }(growX, pushX)
+ }
+ }
+ row {
+ JBScrollPane(JBList<SampleInfo>().apply { list = this })(growX, pushX, growPolicy = GrowPolicy.MEDIUM_TEXT)
+ JTextPane().apply {
+ description = this
+ isRequestFocusEnabled = true
+ }(growX, pushX)
+ }
+ }
+
+ init {
+ list.addListSelectionListener {
+ list.selectedValue?.let {
+ description.text = assemblyText(it)
+ description.caretPosition = 0
+ }
+ }
+ }
+
+ private fun assemblyText(item: SampleInfo): String {
+ return StringBuilder()
+ .append(item.description).append("\n")
+ .append("Tags: ").append(item.tags).append("\n")
+ .append("Libraries: ").append(item.libraries)
+ .toString()
+ }
+}
\ No newline at end of file
diff --git a/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/SamplerInteraction.kt b/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/SamplerInteraction.kt
new file mode 100644
index 0000000..22b5b70
--- /dev/null
+++ b/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/SamplerInteraction.kt
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2010-2019 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.ide.sampler
+
+data class SampleInfo(
+ val id: Int,
+ val name: String,
+ val description: String,
+ val libraries: List<String>,
+ val tags: List<String>
+) {
+ override fun toString(): String {
+ return name
+ }
+}
+
+class Sample(
+ val id: Int,
+ val name: String,
+ val description: String,
+ val libraries: List<String>,
+ val tags: List<String>,
+ val files: List<File>,
+ val type: BuildSystemType
+)
+
+enum class BuildSystemType {
+ MAVEN, GRADLE, NONE
+}
+
+data class File(
+ val id: Int,
+ val snapshotId: Int,
+ val path: String,
+ val name: String,
+ val extension: String,
+ val content: String
+) {
+ fun fullPath() : String = "$path/$name.$extension"
+}
+
+object SamplerInteraction {
+ private val samples = (1..10).map { nameNo ->
+ SampleInfo(
+ nameNo,
+ "Name$nameNo",
+ "Description$nameNo",
+ (1..nameNo).map { "Library$it" },
+ (nameNo..10).map { "Tag$it" }
+ )
+ }
+
+ fun getSamplerInfos(
+ namePattern: String = "",
+ libraries: List<String> = emptyList(),
+ tags: List<String> = emptyList()
+ ): List<SampleInfo> {
+ return samples.filter { it.name.contains(namePattern) }
+ .filter { it.libraries.containsAll(libraries) }
+ .filter { it.tags.containsAll(tags) }
+ }
+
+ fun getSample(id: Int): Sample? {
+ return samples.get(id).let {
+ Sample(
+ it.id,
+ it.name,
+ it.description,
+ it.libraries,
+ it.tags,
+ listOf(
+ File(
+ 1,
+ 100 + id,
+ "",
+ "build",
+ "gradle",
+ buldGradle
+ ),
+ File(
+ id, 100 + id, "src/main/kotlin", "app", "kt", "fun main(){\n" +
+ " println(\"Hello world!\")\n" +
+ "}"
+ )
+ ),
+ BuildSystemType.GRADLE
+ )
+ }
+ }
+
+ private val buldGradle = """
+ plugins {
+ id 'java'
+ id 'org.jetbrains.kotlin.jvm' version '1.3.40'
+ }
+
+ group 'asd'
+ version '1.0-SNAPSHOT'
+
+ sourceCompatibility = 1.8
+
+ repositories {
+ maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
+ mavenCentral()
+ }
+
+ dependencies {
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
+ testCompile group: 'junit', name: 'junit', version: '4.12'
+ }
+
+ compileKotlin {
+ kotlinOptions.jvmTarget = "1.8"
+ }
+ compileTestKotlin {
+ kotlinOptions.jvmTarget = "1.8"
+ }
+ """.trimIndent()
+}
\ No newline at end of file
diff --git a/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/SamplerProjectTemplate.kt b/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/SamplerProjectTemplate.kt
new file mode 100644
index 0000000..1563bdf
--- /dev/null
+++ b/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/SamplerProjectTemplate.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2010-2019 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.ide.sampler
+
+import com.intellij.ide.util.projectWizard.AbstractModuleBuilder
+import com.intellij.openapi.ui.ValidationInfo
+import com.intellij.platform.ProjectTemplate
+import org.jetbrains.kotlin.idea.KotlinIcons
+import javax.swing.Icon
+
+class SamplerProjectTemplate : ProjectTemplate {
+ override fun getName(): String = "Kotlin Sampler"
+
+ override fun getIcon(): Icon = KotlinIcons.SMALL_LOGO
+
+ override fun getDescription(): String = "Create project from samples published on Git-Hub."
+
+ override fun validateSettings(): ValidationInfo? = null
+
+ override fun createModuleBuilder(): AbstractModuleBuilder = KotlinSamplerModuleBuilder()
+}
\ No newline at end of file
diff --git a/idea/resources/META-INF/gradle-java.xml b/idea/resources/META-INF/gradle-java.xml
index 18558b5..4f98237 100644
--- a/idea/resources/META-INF/gradle-java.xml
+++ b/idea/resources/META-INF/gradle-java.xml
@@ -48,5 +48,6 @@
<moduleBuilder implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleWebMultiplatformModuleBuilder"/>
<moduleBuilder implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleMobileMultiplatformModuleBuilder"/>
<moduleBuilder implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleMobileSharedMultiplatformModuleBuilder"/>
+ <moduleBuilder implementation="org.jetbrains.kotlin.ide.sampler.KotlinSamplerModuleBuilder"/>
</extensions>
</idea-plugin>
diff --git a/idea/src/org/jetbrains/kotlin/idea/framework/KotlinLibraryUtil.kt b/idea/src/org/jetbrains/kotlin/idea/framework/KotlinLibraryUtil.kt
index d78a8e0..4145091 100644
--- a/idea/src/org/jetbrains/kotlin/idea/framework/KotlinLibraryUtil.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/framework/KotlinLibraryUtil.kt
@@ -13,12 +13,14 @@
val MAVEN_SYSTEM_ID = ProjectSystemId("Maven")
val GRADLE_SYSTEM_ID = ProjectSystemId("GRADLE")
val KOBALT_SYSTEM_ID = ProjectSystemId("KOBALT")
+val SAMPLER_SYSTEM_ID = ProjectSystemId("SAMPLER")
fun isExternalLibrary(library: Library): Boolean {
return ExternalSystemApiUtil.isExternalSystemLibrary(library, ProjectSystemId.IDE) ||
ExternalSystemApiUtil.isExternalSystemLibrary(library, GRADLE_SYSTEM_ID) ||
ExternalSystemApiUtil.isExternalSystemLibrary(library, KOBALT_SYSTEM_ID) ||
- ExternalSystemApiUtil.isExternalSystemLibrary(library, MAVEN_SYSTEM_ID)
+ ExternalSystemApiUtil.isExternalSystemLibrary(library, MAVEN_SYSTEM_ID) ||
+ ExternalSystemApiUtil.isExternalSystemLibrary(library, SAMPLER_SYSTEM_ID)
}
diff --git a/prepare/idea-plugin/build.gradle.kts b/prepare/idea-plugin/build.gradle.kts
index aafcc9b..b7e718a 100644
--- a/prepare/idea-plugin/build.gradle.kts
+++ b/prepare/idea-plugin/build.gradle.kts
@@ -52,6 +52,7 @@
":idea:idea-core",
":idea:idea-gradle",
":idea:idea-gradle-native",
+ ":idea:idea-sampler",
":compiler:ir.psi2ir",
":compiler:ir.tree",
":js:js.ast",
diff --git a/settings.gradle b/settings.gradle
index ab3999a..d443fd3 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -102,6 +102,7 @@
":idea:idea-test-framework",
":idea:idea-native",
":idea:idea-gradle-native",
+ ":idea:idea-sampler",
":idea",
":idea-runner",
":idea:jvm-debugger:eval4j",