diff --git a/libraries/tools/idl2k/build.gradle b/libraries/tools/idl2k/build.gradle index 490b3dc4989..0aa153dfb90 100644 --- a/libraries/tools/idl2k/build.gradle +++ b/libraries/tools/idl2k/build.gradle @@ -20,6 +20,8 @@ dependencies { implementation "org.antlr:antlr4-runtime:$antlr4_version" implementation project(':kotlin-stdlib') implementation "org.jsoup:jsoup:1.8.2" + + testImplementation "junit:junit:4.12" } sourceSets.main.kotlin.srcDirs += file("$buildDir/generated-src/antlr/main/") diff --git a/libraries/tools/idl2k/src/main/kotlin/build.kt b/libraries/tools/idl2k/src/main/kotlin/build.kt index 967f6b86c9e..5e7dea2d9aa 100644 --- a/libraries/tools/idl2k/src/main/kotlin/build.kt +++ b/libraries/tools/idl2k/src/main/kotlin/build.kt @@ -1,14 +1,12 @@ package org.jetbrains.idl2k -import org.antlr.v4.runtime.ANTLRFileStream -import kotlin.collections.HashSet +import org.antlr.v4.runtime.CharStreams import java.io.File import java.io.IOException import java.net.URL import java.util.ArrayList import java.util.LinkedHashMap - class BuildWebIdl(val mdnCacheFile: File, val srcDir: File) { val repositoryPre = loadPreliminaryRepository() @@ -18,16 +16,17 @@ class BuildWebIdl(val mdnCacheFile: File, val srcDir: File) { System.exit(1) } - return srcDir.walkTopDown().filter { it.isDirectory || it.extension == "idl" }.asSequence().filter { it.isFile }.toList().sortedBy { it.absolutePath }.fold(Repository(emptyMap(), emptyMap(), emptyMap(), emptyMap())) { acc, e -> + return srcDir.walkTopDown().filter { it.isDirectory || it.extension == "idl" }.asSequence().filter { it.isFile }.toList() + .sortedBy { it.absolutePath }.fold(Repository(emptyMap(), emptyMap(), emptyMap(), emptyMap())) { acc, e -> System.err.flush() System.err.println("Parsing ${e.absolutePath}") - val fileRepository = parseIDL(ANTLRFileStream(e.absolutePath, "UTF-8")) + val fileRepository = parseIDL(CharStreams.fromFileName(e.absolutePath, Charsets.UTF_8)) Repository( - interfaces = acc.interfaces.mergeReduce(fileRepository.interfaces, ::merge), - typeDefs = acc.typeDefs + fileRepository.typeDefs, - externals = acc.externals.merge(fileRepository.externals), - enums = acc.enums + fileRepository.enums + interfaces = acc.interfaces.mergeReduce(fileRepository.interfaces, ::merge), + typeDefs = acc.typeDefs + fileRepository.typeDefs, + externals = acc.externals.merge(fileRepository.externals), + enums = acc.enums + fileRepository.enums ) } } @@ -36,7 +35,8 @@ class BuildWebIdl(val mdnCacheFile: File, val srcDir: File) { println("Prepare...") } - val repository = repositoryPre.copy(typeDefs = repositoryPre.typeDefs.mapValues { it.value.copy(mapType(repositoryPre, it.value.types)) }) + val repository = + repositoryPre.copy(typeDefs = repositoryPre.typeDefs.mapValues { it.value.copy(mapType(repositoryPre, it.value.types)) }) val definitions = mapDefinitions(repository, repository.interfaces.values).map { if (it.name in relocations) { @@ -91,9 +91,9 @@ class BuildWebIdl(val mdnCacheFile: File, val srcDir: File) { } -internal fun Map>.reduceValues(reduce: (V, V) -> V = { a, b -> b }): Map = mapValues { it.value.reduce(reduce) } +internal fun Map>.reduceValues(reduce: (V, V) -> V = { _, b -> b }): Map = mapValues { it.value.reduce(reduce) } -internal fun Map.mergeReduce(other: Map, reduce: (V, V) -> V = { a, b -> b }): Map { +internal fun Map.mergeReduce(other: Map, reduce: (V, V) -> V = { _, b -> b }): Map { val result = LinkedHashMap(this.size + other.size) result.putAll(this) other.forEach { e -> @@ -101,8 +101,7 @@ internal fun Map.mergeReduce(other: Map, reduce: (V, V) -> V if (existing == null) { result[e.key] = e.value - } - else { + } else { result[e.key] = reduce(e.value, existing) } } @@ -119,8 +118,7 @@ internal fun Map>.merge(other: Map>): Map().filter { it.name.isEmpty().not() }.groupBy { it.name }.mapValues { it.value.reduce(::merge) }, declarations.filterIsInstance().groupBy { it.name }.mapValues { it.value.first() }, declarations.filterIsInstance().groupBy { it.name }.mapValues { it.value.map { it.implements } }, - declarations.filterIsInstance().groupBy { it.name }.mapValues { it.value.reduce { a, b -> a } } + declarations.filterIsInstance().groupBy { it.name }.mapValues { it.value.reduce { a, _ -> a } } ) } diff --git a/libraries/tools/idl2k/src/test/kotlin/Idl2kTest.kt b/libraries/tools/idl2k/src/test/kotlin/Idl2kTest.kt new file mode 100644 index 00000000000..eb10cf18f13 --- /dev/null +++ b/libraries/tools/idl2k/src/test/kotlin/Idl2kTest.kt @@ -0,0 +1,52 @@ +/* + * 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 org.jetbrains.idl2k.BuildWebIdl +import org.jetbrains.idl2k.render +import org.junit.Assert.assertEquals +import org.junit.Test +import java.io.File +import java.io.StringWriter +import java.io.Writer + + +class Idl2kTests { + + + private fun convertIdlToWriter(file: File): Writer { + val nonExistentCache = File.createTempFile("mdnCache", System.nanoTime().toString()) + val buildWebIdl = BuildWebIdl(nonExistentCache, file) + + val stringWriter = StringWriter() + stringWriter.render( + "", + buildWebIdl.definitions, + buildWebIdl.unions, + buildWebIdl.repository.enums.values.toList(), + buildWebIdl.mdnCache + ) + + nonExistentCache.delete() + return stringWriter + } + + private fun assertIdlCompiledTo(fileName: String, expectedOutputName: String) { + val testResourcePrefix = "src/test/resources/" + + assertEquals( + File(testResourcePrefix).resolve(expectedOutputName).readText(), + convertIdlToWriter(File(testResourcePrefix).resolve(fileName)).toString() + ) + } + + @Test + fun basicTest() { + assertIdlCompiledTo( + "SomethingNotInCache.idl", + "SomethingNotInCache.kt" + ) + } +} diff --git a/libraries/tools/idl2k/src/test/resources/SomethingNotInCache.idl b/libraries/tools/idl2k/src/test/resources/SomethingNotInCache.idl new file mode 100644 index 00000000000..d1252dd149e --- /dev/null +++ b/libraries/tools/idl2k/src/test/resources/SomethingNotInCache.idl @@ -0,0 +1,8 @@ +[Constructor] +interface SomethingNotInCache { + DOMString someEmptyMethod (); + DOMString someMethod (SomethingUnknown root); + USVString? optionalUsvStringFetcher(USVString name); + readonly attribute WhateverUknownParam someReadOnlyParam; + attribute WhateverUknownParam someWriteableParam; +}; \ No newline at end of file diff --git a/libraries/tools/idl2k/src/test/resources/SomethingNotInCache.kt b/libraries/tools/idl2k/src/test/resources/SomethingNotInCache.kt new file mode 100644 index 00000000000..ef71790c824 --- /dev/null +++ b/libraries/tools/idl2k/src/test/resources/SomethingNotInCache.kt @@ -0,0 +1,8 @@ +public external open class SomethingNotInCache { + open val someReadOnlyParam: dynamic + var someWriteableParam: dynamic + fun someEmptyMethod(): String + fun someMethod(root: dynamic): String + fun optionalUsvStringFetcher(name: String): String? +} +