JS: update IDL2K to generate correct declarations WRT new restrictions for external declarations
This commit is contained in:
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* 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.idl2k
|
||||
|
||||
private fun Operation.getterOrSetter() = this.attributes.map { it.call }.toSet().let { attributes ->
|
||||
@@ -9,7 +25,7 @@ private fun Operation.getterOrSetter() = this.attributes.map { it.call }.toSet()
|
||||
}
|
||||
|
||||
fun generateFunction(repository: Repository, function: Operation, functionName: String, nativeGetterOrSetter: NativeGetterOrSetter = function.getterOrSetter()): GenerateFunction =
|
||||
function.attributes.map { it.call }.toSet().let { attributes ->
|
||||
function.attributes.map { it.call }.toSet().let {
|
||||
GenerateFunction(
|
||||
name = functionName,
|
||||
returnType = mapType(repository, function.returnType).let { mapped -> if (nativeGetterOrSetter == NativeGetterOrSetter.GETTER) mapped.toNullableIfNonPrimitive() else mapped },
|
||||
@@ -19,7 +35,7 @@ fun generateFunction(repository: Repository, function: Operation, functionName:
|
||||
GenerateAttribute(
|
||||
name = it.name,
|
||||
type = mappedType,
|
||||
initializer = mapLiteral(it.defaultValue, mappedType),
|
||||
initializer = if (it.defaultValue != null) "noImpl" else null,
|
||||
getterSetterNoImpl = false,
|
||||
override = false,
|
||||
kind = AttributeKind.ARGUMENT,
|
||||
@@ -28,7 +44,8 @@ fun generateFunction(repository: Repository, function: Operation, functionName:
|
||||
)
|
||||
},
|
||||
nativeGetterOrSetter = nativeGetterOrSetter,
|
||||
static = function.static
|
||||
static = function.static,
|
||||
override = false
|
||||
)
|
||||
}
|
||||
|
||||
@@ -69,7 +86,16 @@ fun generateFunctions(repository: Repository, function: Operation): List<Generat
|
||||
fun generateAttribute(putNoImpl: Boolean, repository: Repository, attribute: Attribute, nullableAttributes: Boolean): GenerateAttribute =
|
||||
GenerateAttribute(attribute.name,
|
||||
type = mapType(repository, attribute.type).let { if (nullableAttributes) it.toNullable() else it },
|
||||
initializer = mapLiteral(attribute.defaultValue, mapType(repository, attribute.type)),
|
||||
initializer =
|
||||
if (putNoImpl && !attribute.static) {
|
||||
mapLiteral(attribute.defaultValue, mapType(repository, attribute.type))
|
||||
}
|
||||
else if (attribute.defaultValue != null) {
|
||||
"noImpl"
|
||||
}
|
||||
else {
|
||||
null
|
||||
},
|
||||
getterSetterNoImpl = putNoImpl,
|
||||
kind = if (attribute.readOnly) AttributeKind.VAL else AttributeKind.VAR,
|
||||
override = false,
|
||||
@@ -90,9 +116,9 @@ private fun resolveDefinitionKind(repository: Repository, iface: InterfaceDefini
|
||||
}
|
||||
|
||||
private fun InterfaceDefinition.mapAttributes(repository: Repository)
|
||||
= attributes.map { generateAttribute(putNoImpl = !dictionary, repository = repository, attribute = it, nullableAttributes = dictionary) }
|
||||
= attributes.map { generateAttribute(putNoImpl = dictionary, repository = repository, attribute = it, nullableAttributes = dictionary) }
|
||||
private fun InterfaceDefinition.mapOperations(repository: Repository) = operations.flatMap { generateFunctions(repository, it) }
|
||||
private fun Constant.mapConstant(repository : Repository) = GenerateAttribute(name, mapType(repository, type), value, false, AttributeKind.VAL, false, false, true)
|
||||
private fun Constant.mapConstant(repository : Repository) = GenerateAttribute(name, mapType(repository, type), null, false, AttributeKind.VAL, false, false, true)
|
||||
private val EMPTY_CONSTRUCTOR = ExtendedAttribute(null, "Constructor", emptyList())
|
||||
|
||||
fun generateTrait(repository: Repository, iface: InterfaceDefinition): GenerateTraitOrClass {
|
||||
@@ -143,8 +169,8 @@ fun generateTrait(repository: Repository, iface: InterfaceDefinition): GenerateT
|
||||
}
|
||||
|
||||
return GenerateTraitOrClass(iface.name, iface.namespace, entityKind, (iface.superTypes + extensions.map { it.name }).distinct(),
|
||||
memberAttributes = iface.mapAttributes(repository),
|
||||
memberFunctions = iface.mapOperations(repository),
|
||||
memberAttributes = iface.mapAttributes(repository).toMutableList(),
|
||||
memberFunctions = iface.mapOperations(repository).toMutableList(),
|
||||
constants = (iface.constants.map { it.mapConstant(repository) } + extensions.flatMap { it.constants.map { it.mapConstant(repository) } }.distinct().toList()),
|
||||
primaryConstructor = primaryConstructorWithCall,
|
||||
secondaryConstructors = secondaryConstructorsWithCall,
|
||||
@@ -173,8 +199,8 @@ fun mapUnionType(it: UnionType) = GenerateTraitOrClass(
|
||||
namespace = it.namespace,
|
||||
kind = GenerateDefinitionKind.INTERFACE,
|
||||
superTypes = emptyList(),
|
||||
memberAttributes = emptyList(),
|
||||
memberFunctions = emptyList(),
|
||||
memberAttributes = mutableListOf(),
|
||||
memberFunctions = mutableListOf(),
|
||||
constants = emptyList(),
|
||||
primaryConstructor = null,
|
||||
secondaryConstructors = emptyList(),
|
||||
@@ -228,4 +254,59 @@ private fun mapLiteral(literal: String?, expectedType: Type = DynamicType) = whe
|
||||
else -> "arrayOf()"
|
||||
}
|
||||
else -> literal
|
||||
}
|
||||
}
|
||||
|
||||
fun implementInterfaces(declarations: List<GenerateTraitOrClass>) {
|
||||
val unimplementedMemberMap = getUnimplementedMembers(declarations)
|
||||
val nonAbstractDeclarations = declarations.filter { it.kind == GenerateDefinitionKind.CLASS }
|
||||
for (declaration in nonAbstractDeclarations) {
|
||||
val unimplementedMembers = unimplementedMemberMap[declaration.name] ?: continue
|
||||
|
||||
for (attribute in unimplementedMembers.attributes) {
|
||||
declaration.memberAttributes += attribute.copy(override = true)
|
||||
}
|
||||
for (function in unimplementedMembers.functions) {
|
||||
declaration.memberFunctions += function.copy(override = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getUnimplementedMembers(declarations: List<GenerateTraitOrClass>): Map<String, UnimplementedMembers> {
|
||||
val declarationMap = declarations.associate { it.name to it }
|
||||
val unimplementedMemberCache = mutableMapOf<String, UnimplementedMembers>()
|
||||
|
||||
fun getForClass(className: String): UnimplementedMembers = unimplementedMemberCache.getOrPut(className) {
|
||||
val declaration = declarationMap[className] ?: return@getOrPut UnimplementedMembers(emptyList(), emptyList())
|
||||
val unimplementedInSuperClasses = declaration.superTypes.map { getForClass(it) }
|
||||
val attributeMap = unimplementedInSuperClasses
|
||||
.flatMap { it.attributes }
|
||||
.associate { it.name to it }
|
||||
.toMutableMap()
|
||||
val functionMap = unimplementedInSuperClasses
|
||||
.flatMap { it.functions }
|
||||
.associate { "${it.name}(${it.signature})" to it }
|
||||
.toMutableMap()
|
||||
|
||||
val (implementedAttributes, unimplementedAttributes) = declaration.memberAttributes
|
||||
.filter { !it.static }
|
||||
.partition { declaration.kind != GenerateDefinitionKind.INTERFACE && !it.getterSetterNoImpl }
|
||||
val (implementedFunctions, unimplementedFunctions) = declaration.memberFunctions
|
||||
.filter { !it.static }
|
||||
.partition { declaration.kind != GenerateDefinitionKind.INTERFACE }
|
||||
|
||||
attributeMap += unimplementedAttributes.map { it.name to it }
|
||||
attributeMap.keys -= implementedAttributes.map { it.name }
|
||||
functionMap += unimplementedFunctions.map { "${it.name}(${it.signature})" to it }
|
||||
functionMap.keys -= implementedFunctions.map { "${it.name}(${it.signature})" }
|
||||
|
||||
UnimplementedMembers(attributeMap.values.toList(), functionMap.values.toList())
|
||||
}
|
||||
|
||||
for (declaration in declarations) {
|
||||
getForClass(declaration.name)
|
||||
}
|
||||
|
||||
return unimplementedMemberCache
|
||||
}
|
||||
|
||||
private class UnimplementedMembers(val attributes: List<GenerateAttribute>, val functions: List<GenerateFunction>)
|
||||
@@ -41,6 +41,7 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
val unions = generateUnions(definitions, repository.typeDefs.values)
|
||||
val allPackages = definitions.map { it.namespace }.distinct().sorted()
|
||||
implementInterfaces(definitions)
|
||||
|
||||
outDir.deleteRecursively()
|
||||
outDir.mkdirs()
|
||||
|
||||
@@ -69,7 +69,8 @@ data class GenerateFunction(
|
||||
val returnType: Type,
|
||||
val arguments: List<GenerateAttribute>,
|
||||
val nativeGetterOrSetter: NativeGetterOrSetter,
|
||||
val static: Boolean
|
||||
val static: Boolean,
|
||||
val override: Boolean
|
||||
)
|
||||
|
||||
data class ConstructorWithSuperTypeCall(val constructor: GenerateFunction, val constructorAttribute: ExtendedAttribute, val initTypeCall: GenerateFunctionCall?)
|
||||
@@ -78,8 +79,8 @@ data class GenerateTraitOrClass(
|
||||
val namespace: String,
|
||||
val kind: GenerateDefinitionKind,
|
||||
val superTypes: List<String>,
|
||||
val memberAttributes: List<GenerateAttribute>,
|
||||
val memberFunctions: List<GenerateFunction>,
|
||||
val memberAttributes: MutableList<GenerateAttribute>,
|
||||
val memberFunctions: MutableList<GenerateFunction>,
|
||||
val constants: List<GenerateAttribute>,
|
||||
val primaryConstructor: ConstructorWithSuperTypeCall?,
|
||||
val secondaryConstructors: List<ConstructorWithSuperTypeCall>,
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* 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.idl2k
|
||||
|
||||
import java.math.BigInteger
|
||||
@@ -108,7 +124,7 @@ private fun Appendable.renderFunctionDeclaration(f: GenerateFunction, override:
|
||||
}
|
||||
append("fun ${f.name.replaceKeywords()}")
|
||||
renderArgumentsDeclaration(f.arguments, override)
|
||||
appendln(": ${f.returnType.render()} = noImpl")
|
||||
appendln(": ${f.returnType.render()}")
|
||||
}
|
||||
|
||||
private fun List<GenerateAttribute>.hasNoVars() = none { it.isVar }
|
||||
@@ -180,10 +196,7 @@ fun Appendable.render(allTypes: Map<String, GenerateTraitOrClass>, typeNamesToUn
|
||||
val modality = when {
|
||||
attribute.signature in superSignatures -> MemberModality.OVERRIDE
|
||||
iface.kind == GenerateDefinitionKind.CLASS && attribute.isVal -> MemberModality.OPEN
|
||||
iface.kind == GenerateDefinitionKind.ABSTRACT_CLASS -> when {
|
||||
attribute.initializer != null || attribute.getterSetterNoImpl -> MemberModality.OPEN
|
||||
else -> MemberModality.ABSTRACT
|
||||
}
|
||||
iface.kind == GenerateDefinitionKind.ABSTRACT_CLASS -> MemberModality.OPEN
|
||||
else -> MemberModality.FINAL
|
||||
}
|
||||
|
||||
@@ -203,8 +216,8 @@ fun Appendable.render(allTypes: Map<String, GenerateTraitOrClass>, typeNamesToUn
|
||||
)
|
||||
}
|
||||
}
|
||||
iface.memberFunctions.filter { it !in superFunctions && !it.static }.map { it.dynamicIfUnknownType(allTypes.keys) }.groupBy { it.signature }.reduceValues(::betterFunction).values.forEach {
|
||||
renderFunctionDeclaration(it.fixRequiredArguments(iface.name), it.signature in superSignatures, commented = it.isCommented(iface.name))
|
||||
iface.memberFunctions.filter { (it !in superFunctions || it.override) && !it.static }.map { it.dynamicIfUnknownType(allTypes.keys) }.groupBy { it.signature }.reduceValues(::betterFunction).values.forEach {
|
||||
renderFunctionDeclaration(it.fixRequiredArguments(iface.name), it.signature in superSignatures || it.override, commented = it.isCommented(iface.name))
|
||||
}
|
||||
|
||||
val staticAttributes = iface.memberAttributes.filter { it.static }
|
||||
|
||||
Reference in New Issue
Block a user