From 3bceab5312d1c1b957ccdbcd78cd533ebcab57c5 Mon Sep 17 00:00:00 2001 From: EJ-K Date: Mon, 19 May 2025 11:08:24 +0100 Subject: [PATCH 1/2] yfiles 3.0.0.1 --- .../github/turansky/yfiles/ClassRegistry.kt | 44 +- .../com/github/turansky/yfiles/CleanCode.kt | 3 +- .../com/github/turansky/yfiles/Components.kt | 2 - .../com/github/turansky/yfiles/Extensions.kt | 59 +- .../github/turansky/yfiles/FileGenerator.kt | 8 +- .../com/github/turansky/yfiles/Generator.kt | 13 +- .../com/github/turansky/yfiles/Handlers.kt | 28 +- .../com/github/turansky/yfiles/JsonReader.kt | 71 +- .../turansky/yfiles/KotlinFileGenerator.kt | 213 +++--- .../com/github/turansky/yfiles/KotlinTypes.kt | 1 + .../com/github/turansky/yfiles/Modifiers.kt | 5 +- .../com/github/turansky/yfiles/Resources.kt | 3 + .../com/github/turansky/yfiles/Summary.kt | 10 +- .../com/github/turansky/yfiles/TypeParser.kt | 26 +- .../com/github/turansky/yfiles/Wrappers.kt | 342 +++++----- .../com/github/turansky/yfiles/YSettings.kt | 8 - .../com/github/turansky/yfiles/YTypes.kt | 32 +- .../correction/CanvasObjectDescriptorHacks.kt | 122 ---- .../correction/CanvasObjectInstallerHacks.kt | 79 --- .../yfiles/correction/ChangeHandlerHacks.kt | 17 + .../turansky/yfiles/correction/ClassHacks.kt | 629 ++++-------------- .../yfiles/correction/ClipboardHelperHacks.kt | 2 +- .../correction/CollectionCorrections.kt | 11 + .../yfiles/correction/CollectionHacks.kt | 40 -- .../yfiles/correction/CommandHacks.kt | 160 ----- .../yfiles/correction/ComparableHacks.kt | 20 +- .../yfiles/correction/ComparerHacks.kt | 198 ------ .../yfiles/correction/ConstructorHacks.kt | 3 - .../yfiles/correction/ContextLookupHacks.kt | 158 ++--- .../yfiles/correction/ContextMenuHacks.kt | 10 + .../yfiles/correction/ConvertersHacks.kt | 49 -- .../yfiles/correction/ConvertibleHacks.kt | 18 + .../correction/CreationPropertiesHacks.kt | 10 + .../turansky/yfiles/correction/CursorHacks.kt | 85 +-- .../turansky/yfiles/correction/DataHacks.kt | 301 --------- .../turansky/yfiles/correction/DpKeyHacks.kt | 247 ------- .../turansky/yfiles/correction/DpdataHacks.kt | 398 ----------- .../yfiles/correction/EventDispatcherHacks.kt | 32 +- .../turansky/yfiles/correction/EventHacks.kt | 12 +- .../yfiles/correction/ExecutorHacks.kt | 7 + .../turansky/yfiles/correction/Hacks.kt | 185 ++---- .../turansky/yfiles/correction/IdHacks.kt | 43 +- .../yfiles/correction/IncrementalHintHacks.kt | 32 - .../yfiles/correction/IntersectionHacks.kt | 26 - .../correction/ItemDropInputModeHacks.kt | 12 + .../yfiles/correction/IteratorSupport.kt | 7 +- .../github/turansky/yfiles/correction/JKey.kt | 2 + .../yfiles/correction/JsonCorrections.kt | 357 ++-------- .../correction/LabelModelParameterHacks.kt | 34 +- .../yfiles/correction/LayoutStrictTypes.kt | 25 - .../yfiles/correction/ListCellHacks.kt | 17 +- .../turansky/yfiles/correction/ListHacks.kt | 72 -- .../yfiles/correction/MarkupExtensionHacks.kt | 20 + .../yfiles/correction/MementoHacks.kt | 65 -- .../yfiles/correction/NodeTypeHacks.kt | 24 - .../yfiles/correction/NullabilityHacks.kt | 212 +----- .../yfiles/correction/NumberCorrections.kt | 132 +++- .../yfiles/correction/ObservableDelegates.kt | 20 +- .../yfiles/correction/ObstacleDataHacks.kt | 28 - .../yfiles/correction/PartitionCellHacks.kt | 55 -- .../yfiles/correction/ResourceHacks.kt | 79 --- .../yfiles/correction/SerializarionHacks.kt | 4 +- .../correction/SnapLineProviderHacks.kt | 48 -- .../turansky/yfiles/correction/TagHacks.kt | 5 - .../yfiles/correction/TemplateLoadersHacks.kt | 42 -- .../yfiles/correction/TemplatesHacks.kt | 68 -- .../yfiles/correction/TooltipHacks.kt | 42 -- .../yfiles/correction/TypeMetadataHacks.kt | 9 + .../yfiles/correction/VisualTemplateHacks.kt | 59 -- .../turansky/yfiles/correction/YJson.kt | 6 +- .../turansky/yfiles/correction/YListHacks.kt | 83 +-- .../com/github/turansky/yfiles/json/Json.kt | 13 +- .../turansky/yfiles/vsdx/correction/Hacks.kt | 19 +- .../kotlin/CustomLabelModelParameter.kt | 1 - .../kotlin/MyPolylineEdgeStyleRenderer.kt | 6 - .../src/jsMain/kotlin/DataClasses.kt | 3 +- .../build.gradle.kts | 9 - .../gradle.properties | 1 - .../src/jsMain/kotlin/Components.kt | 22 - .../import-optimizer-library/build.gradle.kts | 8 - .../src/jsMain/kotlin/Graphs.kt | 10 - examples/simple-app/src/jsMain/kotlin/App.kt | 20 +- examples/simple-app/src/jsMain/kotlin/Cast.kt | 14 +- .../simple-app/src/jsMain/kotlin/Comparer.kt | 17 +- .../src/jsMain/kotlin/Converters.kt | 23 - .../src/jsMain/kotlin/Destructuring.kt | 9 +- .../src/jsMain/kotlin/ExternalExtensions.kt | 21 +- .../simple-app/src/jsMain/kotlin/Iterators.kt | 16 +- .../simple-app/src/jsMain/kotlin/Lookups.kt | 8 +- .../simple-app/src/jsMain/kotlin/Sequences.kt | 16 +- gradle-plugin-test/build.gradle.kts | 14 +- .../src/jsMain/kotlin/CustomObject.kt | 9 +- .../src/jsMain/kotlin/DataObject.kt | 4 +- .../jsMain/kotlin/SimpleVisibilityTestable.kt | 13 +- .../src/jsMain/resources/yfiles.js | 7 +- .../src/jsTest/kotlin/BaseClassTest.kt | 3 + .../jsTest/kotlin/ConfigurablePropertyTest.kt | 2 + .../src/jsTest/kotlin/CustomObjectTest.kt | 5 + .../yfiles/compiler/backend/common/YFiles.kt | 33 +- gradle.properties | 4 +- package-lock.json | 71 +- settings.gradle.kts | 2 - vsdx-kotlin/build.gradle.kts | 2 +- yfiles-kotlin/build.gradle.kts | 4 +- 104 files changed, 1212 insertions(+), 4486 deletions(-) delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CanvasObjectDescriptorHacks.kt delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CanvasObjectInstallerHacks.kt create mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ChangeHandlerHacks.kt create mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CollectionCorrections.kt delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CollectionHacks.kt delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CommandHacks.kt delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ComparerHacks.kt create mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ContextMenuHacks.kt delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ConvertersHacks.kt create mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ConvertibleHacks.kt create mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CreationPropertiesHacks.kt delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/DataHacks.kt delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/DpKeyHacks.kt delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/DpdataHacks.kt create mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ExecutorHacks.kt delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/IncrementalHintHacks.kt delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/IntersectionHacks.kt create mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ItemDropInputModeHacks.kt delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/LayoutStrictTypes.kt create mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/MarkupExtensionHacks.kt delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/MementoHacks.kt delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/NodeTypeHacks.kt delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ObstacleDataHacks.kt delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/PartitionCellHacks.kt delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ResourceHacks.kt delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/SnapLineProviderHacks.kt delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/TemplateLoadersHacks.kt delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/TemplatesHacks.kt delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/TooltipHacks.kt create mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/TypeMetadataHacks.kt delete mode 100644 buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/VisualTemplateHacks.kt delete mode 100644 examples/configurable-properties/src/jsMain/kotlin/MyPolylineEdgeStyleRenderer.kt delete mode 100644 examples/import-optimizer-application/build.gradle.kts delete mode 100644 examples/import-optimizer-application/gradle.properties delete mode 100644 examples/import-optimizer-application/src/jsMain/kotlin/Components.kt delete mode 100644 examples/import-optimizer-library/build.gradle.kts delete mode 100644 examples/import-optimizer-library/src/jsMain/kotlin/Graphs.kt delete mode 100644 examples/simple-app/src/jsMain/kotlin/Converters.kt diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/ClassRegistry.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/ClassRegistry.kt index d11769e33..a0e591f68 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/ClassRegistry.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/ClassRegistry.kt @@ -19,14 +19,6 @@ internal class ClassRegistry( { it.memberProperties.map { it.name } } ) - private val listenerMap = types - .asSequence() - .filterIsInstance() - .associateBy( - { it.classId }, - { it.events.flatMap { it.listenerNames } } - ) - private fun getParents(className: String): List { val instance = instances.getValue(className) @@ -70,21 +62,21 @@ internal class ClassRegistry( } } - private fun listenerOverridden( - className: String, - listenerName: String, - checkCurrentClass: Boolean, - ): Boolean { - if (checkCurrentClass) { - val listeners = listenerMap.getValue(className) - if (listenerName in listeners) { - return true - } - } - return getParents(className).any { - listenerOverridden(it, listenerName, true) - } - } +// private fun listenerOverridden( +// className: String, +// listenerName: String, +// checkCurrentClass: Boolean, +// ): Boolean { +// if (checkCurrentClass) { +// val listeners = listenerMap.getValue(className) +// if (listenerName in listeners) { +// return true +// } +// } +// return getParents(className).any { +// listenerOverridden(it, listenerName, true) +// } +// } fun functionOverridden(className: String, functionName: String): Boolean { return functionOverridden(className, functionName, false) @@ -94,7 +86,7 @@ internal class ClassRegistry( return propertyOverridden(className, propertyName, false) } - fun listenerOverridden(className: String, listenerName: String): Boolean { - return listenerOverridden(className, listenerName, false) - } +// fun listenerOverridden(className: String, listenerName: String): Boolean { +// return listenerOverridden(className, listenerName, false) +// } } diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/CleanCode.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/CleanCode.kt index fd2bb6f67..eceb7c56f 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/CleanCode.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/CleanCode.kt @@ -45,8 +45,9 @@ private fun String.cleanDoc(): String { private fun String.getImportedClasses(): List { val code = split("\n") .asSequence() + .map { it.trim() } .filterNot { it.startsWith("import yfiles.") } - .filterNot { it.startsWith(" *") } + .filterNot { it.startsWith("*") } .joinToString("\n") val additionalImports = mutableListOf() diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Components.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Components.kt index 63d906558..955f448d3 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Components.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Components.kt @@ -5,8 +5,6 @@ internal fun Class.getComponents(): String? = "yfiles.algorithms.Point2D", "yfiles.algorithms.Rectangle2D", - "yfiles.algorithms.YDimension", - "yfiles.algorithms.YPoint", "yfiles.algorithms.YOrientedRectangle", "yfiles.algorithms.YInsets", diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Extensions.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Extensions.kt index 97f53c075..a48ec7bd4 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Extensions.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Extensions.kt @@ -13,65 +13,20 @@ internal fun Class.getExtensions(): String? = internal fun Interface.getExtensions(): String? = when (classId) { - // language=kotlin - YOBJECT, - -> """ - inline fun T.getClass(): $YCLASS = - $AS_DYNAMIC.getClass() - """.trimIndent() - // language=kotlin ILOOKUP, -> """ - inline fun $ILOOKUP.lookup(): T? = - lookup(T::class.js.yclass) - - inline fun $ILOOKUP.lookupValue(type: $YCLASS):T = + inline fun $ILOOKUP.lookup(): T? = + lookup(T::class.js.unsafeCast>()) + + inline fun $ILOOKUP.lookupValue(type: $ICLASS_METADATA):T = requireNotNull(lookup(type)) { "Unable to lookup type ${'$'}type" } - - inline fun $ILOOKUP.lookupValue(): T = - lookupValue(T::class.js.yclass) + + inline fun $ILOOKUP.lookupValue(): T = + lookupValue(T::class.js.unsafeCast>()) """.trimIndent() - - IMAPPER_REGISTRY, - -> getMapperRegistryExtensions() - else -> null } -private fun getMapperRegistryExtensions(): String { - return getMapperRegistryExtensions(GRAPH_DP_KEY, GRAPH, IGRAPH) -} - -@Suppress("SameParameterValue") -private fun getMapperRegistryExtensions( - dpKeyType: String, - keyType: String, - modelKeyType: String = keyType, -): String { - var keyClass = "$keyType.yclass" - if (keyType != modelKeyType) - keyClass += ".unsafeCast<$YCLASS<$modelKeyType>>()" - - val valueClass = "tag.valueType" - - // language=kotlin - return """ - inline fun IMapperRegistry.createConstantMapper( - tag: $dpKeyType , - constant: V? - ):IMapper<$modelKeyType, V> = - createConstantMapper($keyClass, $valueClass, tag, constant) - - inline fun IMapperRegistry.createDelegateMapper( - tag: $dpKeyType , - noinline getter: MapperDelegate<$modelKeyType, V> - ):IMapper<$modelKeyType, V> = - createDelegateMapper($keyClass, $valueClass, tag, getter) - - inline fun IMapperRegistry.createMapper(tag: $dpKeyType):Mapper<$modelKeyType, V> = - createMapper($keyClass, $valueClass, tag) - """.trimIndent() -} diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/FileGenerator.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/FileGenerator.kt index bcfd3a3a7..bad8326fa 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/FileGenerator.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/FileGenerator.kt @@ -21,18 +21,12 @@ internal class TypeGeneratorData( val jsName = alias ?: name val fileId: String - get() = if (primitive || isYObject) { + get() = if (primitive) { "$packageName.$jsName" } else { fqn } - val isYObject: Boolean - get() = isYObjectClass(fqn) - - val isYBase: Boolean - get() = fqn == YCLASS || fqn == YENUM - val primitive: Boolean get() = isPrimitiveClass(fqn) diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Generator.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Generator.kt index aabacaec5..22b350412 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Generator.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Generator.kt @@ -7,6 +7,8 @@ import com.github.turansky.yfiles.vsdx.correction.correctVsdxNumbers import com.github.turansky.yfiles.vsdx.correction.createVsdxDataClasses import com.github.turansky.yfiles.vsdx.fakeVsdxInterfaces import java.io.File +import java.nio.file.Paths +import kotlin.io.path.writeText private const val GENERATOR_COMMENT = "Automatically generated - do not modify!" private val DEFAULT_SUPPRESSES = """ @@ -52,19 +54,11 @@ fun generateKotlinDeclarations( generateTagUtils(context) generateDataTagUtils(context) generateStyleTagUtils(context) - generateNodeTypeUtils(context) generateLayoutDescriptorUtils(context) - generateResourceUtils(context) - generateConvertersUtils(context) generateEventDispatcherUtils(context) generateClassUtils(context) generateFlagsUtils(context) - generateMementoUtils(context) - generateIncrementalHint(context) - generatePartitionCellUtils(context) - generateObstacleData(context) - generateTooltipUtils(context) generateDragDropData(context) generateYndefined(context) @@ -74,9 +68,10 @@ fun generateKotlinDeclarations( generateEdgeDirectednessUtils(context) addIteratorSupport(context) - generateDpKeyDelegates(context) generateResourceTypes(devguideFile, context) + + //TODO: generate event wrappers } fun generateVsdxKotlinDeclarations( diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Handlers.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Handlers.kt index 766cd0dec..34aebfe91 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Handlers.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Handlers.kt @@ -15,13 +15,13 @@ internal fun getHandlerData(listenerType: String): HandlerData { "yfiles.graph.NodeLayoutChangedHandler" -> HandlerData( handlerType = "(node: $INODE, oldLayout: yfiles.geometry.Rect) -> Unit", - listenerBody = "{ _, node, oldLayout -> handler(node, oldLayout) }" + listenerBody = "{ node, oldLayout, _ -> handler(node, oldLayout) }" ) "yfiles.graph.BendLocationChangedHandler" -> HandlerData( handlerType = "(bend: yfiles.graph.IBend, oldLocation: yfiles.geometry.Point) -> Unit", - listenerBody = "{ _, bend, oldLocation -> handler(bend, oldLocation) }" + listenerBody = "{ bend, oldLocation, _ -> handler(bend, oldLocation) }" ) else -> throw IllegalArgumentException("No handler data for $listenerType") @@ -33,7 +33,7 @@ private fun getEventHandlerData(eventType: String): HandlerData { val itemType = eventType.between("<", ">") return HandlerData( handlerType = "(item:$itemType) -> Unit", - listenerBody = "{ _, event -> handler(event.item) }" + listenerBody = "{ event, _ -> handler(event.item) }" ) } @@ -41,15 +41,15 @@ private fun getEventHandlerData(eventType: String): HandlerData { val (itemType, valueType) = eventType.between("<", ">").split(",") return HandlerData( handlerType = "(item:$itemType, oldValue: $valueType?) -> Unit", - listenerBody = "{ _, event -> handler(event.item, event.oldValue) }" + listenerBody = "{ event, _ -> handler(event.item, event.oldValue) }" ) } if (eventType.startsWith("yfiles.input.SelectionEventArgs<")) { val itemType = eventType.between("<", ">") return HandlerData( - handlerType = "(context:$IINPUT_MODE_CONTEXT, selection: yfiles.view.ISelectionModel<$itemType>) -> Unit", - listenerBody = "{ _, event -> handler(event.context, event.selection) }" + handlerType = "(context:$IINPUT_MODE_CONTEXT, selection: yfiles.collections.IObservableCollection<$itemType>) -> Unit", + listenerBody = "{ event, _ -> handler(event.context, event.selection) }" ) } @@ -78,7 +78,7 @@ private fun getEventHandlerData(eventType: String): HandlerData { else -> HandlerData( handlerType = "(event:$eventType) -> Unit", - listenerBody = "{ _, event -> handler(event) }" + listenerBody = "{ event, _ -> handler(event) }" ) } } @@ -92,37 +92,37 @@ private val EMPTY_HANDLER_DATA = private val PROPERTY_HANDLER_DATA = HandlerData( handlerType = "(propertyName:String) -> Unit", - listenerBody = "{ _, event -> handler(event.propertyName) }" + listenerBody = "{ event, _ -> handler(event.propertyName) }" ) private val INPUT_MODE_HANDLER_DATA = HandlerData( handlerType = "(context:$IINPUT_MODE_CONTEXT) -> Unit", - listenerBody = "{ _, event -> handler(event.context) }" + listenerBody = "{ event, _ -> handler(event.context) }" ) private val TEXT_HANDLER_DATA = HandlerData( handlerType = "(context:$IINPUT_MODE_CONTEXT, text:String) -> Unit", - listenerBody = "{ _, event -> handler(event.context, event.text) }" + listenerBody = "{ event, _ -> handler(event.context, event.text) }" ) private val MARQUEE_HANDLER_DATA = HandlerData( handlerType = "(rectangle:yfiles.geometry.Rect) -> Unit", - listenerBody = "{ _, event -> handler(event.rectangle) }" + listenerBody = "{ event, _ -> handler(event.rectangle) }" ) private val LASSO_HANDLER_DATA = HandlerData( - handlerType = "(selectionPath:yfiles.geometry.GeneralPath) -> Unit", - listenerBody = "{ _, event -> handler(event.selectionPath) }" + handlerType = "(path:yfiles.geometry.GeneralPath) -> Unit", + listenerBody = "{ event, _ -> handler(event.path) }" ) private val HOVER_HANDLER_DATA = HandlerData( handlerType = "(item:$IMODEL_ITEM?, oldItem:$IMODEL_ITEM?) -> Unit", - listenerBody = "{ _, event -> handler(event.item, event.oldItem) }" + listenerBody = "{ event, _ -> handler(event.item, event.oldItem) }" ) internal data class HandlerData( diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/JsonReader.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/JsonReader.kt index 63f0a47ac..d9d586d95 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/JsonReader.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/JsonReader.kt @@ -13,6 +13,10 @@ private const val CREATE = "create" private const val QII = "qii" +private val TYPE_ALIAS_REGEX = Regex("(\\w+)\\['\\w+']") +private val COMPARISON_REGEX = Regex("function\\(([\\w.]+), ?([\\w.]+)\\):number") +private val FUNCTION_SIGNATURE_REGEX = Regex("function\\(([^)]*)\\):([a-zA-Z0-9.]+)") + internal fun File.readJson(): JSONObject = readText(UTF_8) .run { substring(indexOf("{")) } @@ -22,6 +26,7 @@ internal fun File.readJson(): JSONObject = internal fun File.readApiJson(action: JSONObject.() -> Unit): JSONObject = readJson() .apply { fixArrayDeclaration() } + .apply { fixTypeAliasing() } .apply { removeNamespaces() } .apply { fixInsetsDeclaration() } .apply { mergeDeclarations() } @@ -30,8 +35,21 @@ internal fun File.readApiJson(action: JSONObject.() -> Unit): JSONObject = .toString() .replace("yfiles.geometry.IPoint[]", "Array") .replace("yfiles.layout.LabelLayoutData[]", "Array") + .replace(COMPARISON_REGEX, "yfiles.lang.Comparison1<$1>") + .replace("yfiles.analysis.LayoutGraphAlgorithms.DfsNodeVisited", "yfiles.analysis.DfsNodeVisited") + .replace("yfiles.analysis.LayoutGraphAlgorithms.DfsNodeVisiting", "yfiles.analysis.DfsNodeVisiting") + .replace("yfiles.analysis.LayoutGraphAlgorithms.DfsEdgeTraversed", "yfiles.analysis.DfsEdgeTraversed") + .replace("yfiles.analysis.LayoutGraphAlgorithms.DfsEdgeTraversing", "yfiles.analysis.DfsEdgeTraversing") + .replace("yfiles.analysis.LayoutGraphAlgorithms.DfsNextTreeVisiting", "yfiles.analysis.DfsNextTreeVisiting") + .replace("yfiles.analysis.LayoutGraphAlgorithms.DfsNextTreeVisited", "yfiles.analysis.DfsNextTreeVisited") + .replace("yfiles.labeling.GenericLabeling.EdgeLabelCandidateProcessor", "yfiles.labeling.EdgeLabelCandidateProcessor") + .replace("yfiles.labeling.GenericLabeling.NodeLabelCandidateProcessor", "yfiles.labeling.NodeLabelCandidateProcessor") + .replace("IEnumerableConvertible", "IEnumerableConvertible") + .replace("\"FocusOptions\"", "\"web.dom.FocusOptions\"") + .replace("any[]", "Array") + .replaceFunctionSignatures() .fixSystemPackage() - .fixClassDeclaration() +// .fixClassDeclaration() .run { JSONObject(this) } .apply(action) .apply { fixFunctionSignatures() } @@ -42,17 +60,6 @@ private fun String.fixSystemPackage(): String = replace("\"yfiles.system.", "\"yfiles.lang.") .replace("\"system.", "\"yfiles.lang.") -private fun String.fixClassDeclaration(): String = - replace(""""id":"yfiles.lang.Class"""", """"id":"$YCLASS","es6name":"Class"""") - .replace(""""name":"Class"""", """"name":"YClass"""") - .replace(""""yfiles.lang.Class"""", """"$YCLASS"""") - .replace(""""yfiles.lang.Class"""", """"$YCLASS"""") - .replace(""""Array"""", """"Array<$YCLASS>"""") - .replace( - """"yfiles.collections.Map"""", - """"yfiles.collections.Map<$YCLASS,$JS_OBJECT>"""" - ) - private fun String.fixInsetsDeclaration(): String = replace("yfiles.algorithms.Insets", "yfiles.algorithms.YInsets") @@ -78,6 +85,30 @@ private fun JSONObject.fixArrayDeclaration() { put("type", "Array<$type>") } +private fun Any.fixTypeAliasing() { + when (this) { + is JSONObject -> fixTypeAliasing() + is JSONArray -> fixTypeAliasing() + } +} + +private fun JSONArray.fixTypeAliasing() { + for (item in this) { + item.fixTypeAliasing() + } +} + +private fun JSONObject.fixTypeAliasing() { + for (key in keys()) { + get(key).fixTypeAliasing() + } + + val type = optString("type") + .ifEmpty { return } + + put("type", type.replace(TYPE_ALIAS_REGEX, TAG)) +} + private fun JSONArray.fixArrayDeclaration() { for (item in this) { item.fixArrayDeclaration() @@ -123,6 +154,22 @@ private fun JSONObject.removeNamespaces() { set(TYPES, types) } +private fun String.replaceFunctionSignatures() : String { + var str = this + generateSequence { FUNCTION_SIGNATURE_REGEX.find(str) }.forEach { result -> + val arguments = result.groupValues[1] + .split(",") + .joinToString(", ") { + getKotlinType(it) ?: it + } + .replace("unknown", ANY) + + val returnType = result.groupValues[2].let { getKotlinType(it) ?: it } + str = str.replace(result.value, "($arguments) -> $returnType") + } + return str +} + private fun JSONObject.fixFunctionSignatures() { val signatureMap = getJSONObject("functionSignatures") val signatures = JSONArray() diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/KotlinFileGenerator.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/KotlinFileGenerator.kt index 8dd6e007a..270dfded4 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/KotlinFileGenerator.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/KotlinFileGenerator.kt @@ -53,7 +53,7 @@ internal class KotlinFileGenerator( .asSequence() .sortedBy { it.classId } .map { it.toCode() } - .joinToString("\n\n") + .joinToString(System.lineSeparator().repeat(2)) } abstract inner class GeneratedFile(private val declaration: Type) { @@ -102,25 +102,20 @@ internal class KotlinFileGenerator( } protected val memberDeclarations by lazy { - memberProperties.filterNot(::isHidden) + memberFunctions + memberEvents + memberProperties.filterNot(::isHidden) + memberFunctions } protected open fun isHidden(property: Property) = false protected val externalAnnotation: String get() = exp( - data.name != data.jsName && !data.isYObject, - "@JsName(\"${data.jsName}\")\n" + data.name != data.jsName, + "@JsName(\"${data.jsName}\")" ) protected val classDeclaration: String get() { - val name = if (data.isYObject) { - data.jsName - } else { - declaration.name - } - + val name = declaration.name return name + declaration.generics.declaration } @@ -132,24 +127,14 @@ internal class KotlinFileGenerator( } protected fun parentString(): String { - if (data.isYObject || data.isYBase) { - return "" - } - var parentTypes = parentTypes() - when { - parentTypes.isEmpty() -> - parentTypes = listOf(YOBJECT) - - parentTypes.singleOrNull() == IEVENT_DISPATCHER -> - parentTypes = listOf(YOBJECT, IEVENT_DISPATCHER) - } - return ": " + parentTypes.byComma() + if (parentTypes.singleOrNull() == IEVENT_DISPATCHER) parentTypes = listOf(IEVENT_DISPATCHER) + return if (parentTypes.isEmpty()) "" else ": " + parentTypes.byComma() } open fun content(): String { return memberDeclarations - .lines { it.toCode() } + .joinToString(System.lineSeparator().repeat(2)) { it.toCode() } } protected abstract val metadataClass: String @@ -158,21 +143,27 @@ internal class KotlinFileGenerator( protected val companionObjectContent: String get() { - val typeDeclaration: String = when { - data.isYBase -> "" - // TODO: use common solution - data.name == "TreeAnalyzer" -> "" - else -> { - val name = if (data.isYObject) data.jsName else data.name - val generic = name + declaration.generics.placeholder - ": $metadataClass<$generic>" + val content = staticDeclarations.joinToString(System.lineSeparator().repeat(2)) { it.toCode() } + if (content.isEmpty() && factoryMethod.isEmpty() && metadataClass.isEmpty()) { + return "" + } + return buildString { + appendLine() + append("companion object") + if (metadataClass.isNotEmpty()) { + val generic = data.name + declaration.generics.placeholder + append(" : $metadataClass<$generic>") + } + appendLine(" {") + if (content.isNotEmpty()) { + appendLine(content.indent()) + } + if (factoryMethod.isNotEmpty()) { + appendLine() + appendLine(factoryMethod.indent()) } + append("}") } - return """ - |companion object $typeDeclaration { - |${staticDeclarations.lines { it.toCode() } + factoryMethod} - |} - """.trimMargin() } abstract fun companionContent(): String? @@ -192,7 +183,7 @@ internal class KotlinFileGenerator( private fun constructors(): String { return declaration .secondaryConstructors - .lines { it.toCode() } + .joinToString(System.lineSeparator()) { it.toCode() } } override fun parentTypes(): List { @@ -236,16 +227,46 @@ internal class KotlinFileGenerator( ?.let { it + "\n\n" } ?: "" - return documentation + - externalAnnotation + - declaration.annotations + - "external ${declaration.kotlinModifier} class $classDeclaration $primaryConstructor ${parentString()} {\n" + - constructors() + "\n\n" + - super.content() + "\n\n" + - components + - companionContent + "\n" + - "}" + - enumCompanionContent() + val dec = buildList { + if (declaration.kotlinModifier.isNotEmpty()) { + add(declaration.kotlinModifier) + } + add("external class") + add(classDeclaration) + add(primaryConstructor) + add(parentString()) + } + + return buildString { + if (documentation.isNotEmpty()) { + appendLine(documentation) + } + if (externalAnnotation.isNotEmpty()) { + appendLine(externalAnnotation) + } + append(dec.joinToString(" ")).appendLine(" {") + + val constructors = constructors() + if (constructors.isNotEmpty()) { + appendLine(constructors.indent()) + } + + val contents = super.content() + if (contents.isNotEmpty()) { + appendLine(contents.indent()) + } + + if (components.isNotEmpty()) { + appendLine("//components") + appendLine(components.indent()) + } + + if (companionContent.isNotEmpty()) { + appendLine(companionContent.indent()) + } + + append("}") + } } private fun primitiveContent(): String { @@ -254,8 +275,8 @@ internal class KotlinFileGenerator( .uppercase() .let { "__${it}__" } - return documentation + - """ + return """ + $documentation @JsName("${data.jsName}") external object $objectName """.trimIndent() @@ -263,14 +284,15 @@ internal class KotlinFileGenerator( private fun objectContent(): String { val code = staticDeclarations - .lines { it.toCode() } + .joinToString(System.lineSeparator().repeat(2)) { it.toCode() } - return documentation + - externalAnnotation + - """ + return """ + |$documentation + |$externalAnnotation |external object $classDeclaration { - |$code - |}${enumCompanionContent()} + |${code.indent()} + |} + |${enumCompanionContent()} """.trimMargin() } @@ -299,14 +321,12 @@ internal class KotlinFileGenerator( ) val events = memberEvents - .filter { !it.overriden } - if (events.isNotEmpty()) { - content = content + events.lines { it.toExtensionCode() } + content = content + events.joinToString(System.lineSeparator().repeat(2)) { it.toExtensionCode() } } return if (content.isNotEmpty()) { - content.joinToString("\n\n") + content.joinToString(System.lineSeparator().repeat(2)) } else { null } @@ -331,14 +351,13 @@ internal class KotlinFileGenerator( inner class InterfaceFile(private val declaration: Interface) : GeneratedFile(declaration) { override fun content(): String { var content = super.content() - .replace("abstract ", "") - if (data.fqn == IENUMERABLE) { content = content .replace("item: T", "item: @UnsafeVariance T") .replace("items: T", "items: @UnsafeVariance T") + .replace("value: T", "value: @UnsafeVariance T") .replace("elements: $IENUMERABLE", "elements: $IENUMERABLE<@UnsafeVariance T>") - .replace("toList():$LIST", "toList():$LIST<@UnsafeVariance T>") + .replace("toList(): $LIST", "toList(): $LIST<@UnsafeVariance T>") .replace("Accumulator", "Accumulator") } @@ -347,17 +366,28 @@ internal class KotlinFileGenerator( .replace("IEnumerable<", "IEnumerable { - | companion object: $ENUM_METADATA<$name> { - | ${declaration.constants.toContent()} - | } - |} - """.trimMargin() + return buildString { + appendLine(documentation) + appendLine(externalAnnotation) + appendLine("sealed external class $name {") + + declaration.constants + .joinToString(System.lineSeparator().repeat(2)) { + it.toCode() + } + .indent() + .run(::appendLine) + + appendLine("}") + } } + override val metadataClass: String + get() = error("Enums don't have metadata classes") private fun flagsContent(): String { val name = data.name - val members = declaration.constants + declaration.staticMethods - - return documentation + - externalAnnotation + - """ - |external class $name - | private constructor(): $YFLAGS<$name> { - | companion object { - | ${members.lines { it.toCode() }} - | } + return """ + |$documentation + |$externalAnnotation + |external class $name private constructor(): $YFLAGS<$name> { + | companion object { + |${members.joinToString(System.lineSeparator().repeat(2)) { it.toCode() }.indent(INDENT.repeat(2))} + | } |} """.trimMargin() } - override val metadataClass: String - get() = TODO() - override fun companionContent(): String? = null } diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/KotlinTypes.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/KotlinTypes.kt index 556346f14..161b45c00 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/KotlinTypes.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/KotlinTypes.kt @@ -30,6 +30,7 @@ internal fun getKotlinType(type: String): String? = private val STANDARD_TYPE_MAP = mapOf( JS_VOID to "js.core.Void", " unknown" to "*", + "unknown" to ANY, JS_ANY to ANY, JS_OBJECT to ANY, diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Modifiers.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Modifiers.kt index a44e44e41..2ed6e3d1d 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Modifiers.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Modifiers.kt @@ -100,7 +100,8 @@ private val CONSTRUCTOR_MODIFIERS = setOf( PROTECTED, PRIVATE, - PUBLIC + PUBLIC, + EXPERT ) internal class ConstructorModifiers(modifiers: List) : Modifiers(modifiers, CONSTRUCTOR_MODIFIERS) { @@ -115,6 +116,7 @@ private val CONSTANT_MODIFIERS = setOf( STATIC, FINAL, RO, + WO, PROTECTED, @@ -219,6 +221,7 @@ private val PARAMETER_MODIFIERS = setOf( OPTIONAL, CANBENULL, + CANBEUNDEFINED, NOTNULL, CONVERSION diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Resources.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Resources.kt index 0ad2cb0f0..a80f45eb7 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Resources.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Resources.kt @@ -16,6 +16,7 @@ internal fun generateResourceTypes( .map { it.substringAfterLast(">") } .chunked(2) .filter { it.size == 2 } + .distinctBy { it.first() } .map { constDeclaration(it.first(), it.last()) } .joinToString(separator = "\n\n", postfix = "\n") @@ -103,6 +104,8 @@ private fun constDeclaration( val name = key .replace(Regex("([a-z])([A-Z])"), "$1_$2") .replace(".", "__") + .replace("%", "") + .replace(" ", "_") .uppercase() return if (key.endsWith("Key")) { diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Summary.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Summary.kt index 39fd4f5f1..2fd5886d6 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Summary.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Summary.kt @@ -15,6 +15,9 @@ private val TYPE_CLEAN_REGEX_2 = Regex("( data-type=\"[a-zA-Z.]+)<[^\"]+") private val TYPE_REGEX = Regex("") private val TYPE_TEXT_REGEX = Regex("") +private val TYPE_MEMBER_REGEX = Regex("") +private val TYPE_MEMBER_TEXT_REGEX = Regex("") +private val NS_REGEX = Regex("") private val MEMBER_REGEX = Regex("") private val MEMBER_TEXT_REGEX = Regex("") @@ -30,10 +33,11 @@ private fun String.fixApiLinks(): String { .replace(TYPE_CLEAN_REGEX_2, "$1") .replace(TYPE_REGEX, "[$1]") .replace(TYPE_TEXT_REGEX, "[$2][$1]") + .replace(TYPE_MEMBER_REGEX, "[$2][$1]") + .replace(TYPE_MEMBER_TEXT_REGEX, "[$3][$1]") .replace(MEMBER_REGEX, "[$1.$2]") .replace(MEMBER_TEXT_REGEX, "[$3][$1.$2]") - .replace("[$JS_OBJECT.", "[$YOBJECT.") - .replace("[yfiles.lang.Object.", "[$YOBJECT.") + .replace(NS_REGEX, "`$1`") .replace("[$JS_STRING]", "[$STRING]") .replace("[$JS_NUMBER]", "[Number]") .replace("[$JS_NUMBER.", "[$DOUBLE.") @@ -44,7 +48,7 @@ private fun String.fixApiLinks(): String { .replace(">evt.", ">event.") .replace("'", "'") .replace(""", "\"") - .also { check("[^<]*)<") diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/TypeParser.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/TypeParser.kt index 0459678b1..ac31dd788 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/TypeParser.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/TypeParser.kt @@ -17,9 +17,6 @@ internal fun parse( .map { it.replace(" ", "") } .joinToString(" | ") - if ("Promise<" in comment) - println(comment) - result = when (comment) { "T | undefined" -> "T?" "HTMLElement | SVGElement" -> ELEMENT @@ -52,15 +49,6 @@ internal fun parse( } internal fun parseType(type: String): String { - // TODO: remove class hack - if (type.startsWith("$YCLASS<")) { - return type - } - - if (type == YCLASS) { - return "$YCLASS<*>" - } - if (type.startsWith("$ICOMPARABLE<")) { return type } @@ -84,6 +72,18 @@ internal fun parseType(type: String): String { "ItemMapping", -> return "yfiles.layout.ItemMapping>" + + "yfiles.layout.EdgeLabelDataKey<(yfiles.collections.IEnumerable, yfiles.layout.LayoutEdgeLabel) -> js.core.Void>" + -> return type + + "yfiles.layout.NodeLabelDataKey<(yfiles.collections.IEnumerable, yfiles.layout.LayoutNodeLabel) -> js.core.Void>" + -> return type + + "yfiles.collections.ItemMapping, yfiles.layout.LayoutEdgeLabel) -> js.core.Void>" + -> return type + + "yfiles.collections.ItemMapping, yfiles.layout.LayoutNodeLabel) -> js.core.Void>" + -> return type } getKotlinType(type)?.let { @@ -95,7 +95,7 @@ internal fun parseType(type: String): String { } val mainType = parseType(till(type, GENERIC_START)) - val parametrizedTypes = parseGenericParameters(type.between(GENERIC_START, GENERIC_END)) + val parametrizedTypes = parseGenericParameters(type.between(GENERIC_START, GENERIC_END, false)) val generics = parametrizedTypes.byComma() return "$mainType<$generics>" diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Wrappers.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Wrappers.kt index 03c238a7b..8cdbdd590 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Wrappers.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Wrappers.kt @@ -6,6 +6,7 @@ import com.github.turansky.yfiles.json.* import org.json.JSONObject private const val DEPRECATED_ANNOTATION = """@Deprecated("Read documentation for more information")""" +internal const val INDENT = " " internal sealed class JsonWrapper(override val source: JSONObject) : HasSource { open fun toCode(): String = @@ -73,12 +74,17 @@ internal class FunctionSignature(source: JSONObject) : JsonWrapper(source), HasC "" } val parameters = parameters - .byCommaLine { it.toCode() } + .byComma { it.toCode() } val returns = returns?.toCode() ?: UNIT val data = GeneratorData(classId) - return documentation + - "typealias ${data.name}$generics = ($parameters) -> $returns" + return buildString { + if (documentation.isNotEmpty()) { + appendLine(documentation) + } + append("typealias ${data.name}$generics = ($parameters) -> $returns") + } + } } @@ -177,7 +183,6 @@ internal sealed class Type(source: JSONObject) : Declaration(source), TypeDeclar internal sealed class ExtendedType(source: JSONObject) : Type(source) { override val constants: List by declarationList(::TypeConstant) - val events: List by list { Event(it, this) } } @@ -192,6 +197,12 @@ internal class Class(source: JSONObject) : ExtendedType(source) { val abstract: Boolean = modifiers.mode == ClassMode.ABSTRACT val enumLike: Boolean = modifiers.mode == ClassMode.SEALED + val isExtensible = when (modifiers.mode) { + ClassMode.OPEN -> true + ClassMode.ABSTRACT -> true + else -> false + } + val kotlinModifier: String = when (modifiers.mode) { ClassMode.FINAL -> "" ClassMode.OPEN -> "open" @@ -199,7 +210,7 @@ internal class Class(source: JSONObject) : ExtendedType(source) { ClassMode.ABSTRACT -> "abstract" } - private val constructors: List by declarationList(::Constructor) + internal val constructors: List by declarationList(::Constructor) val primaryConstructor: Constructor? = when { name in USE_LAST_CONSTRUCTOR_AS_PRIMARY -> constructors.last() else -> constructors.firstOrNull() @@ -227,7 +238,6 @@ internal class Interface(source: JSONObject) : ExtendedType(source) { val functionalMethod: Method? get() = when { implementedTypes().isNotEmpty() -> null - events.isNotEmpty() -> null memberProperties.any { it.abstract } -> null name in NON_FUNCTIONAL -> null else -> memberMethods @@ -239,7 +249,7 @@ internal class Interface(source: JSONObject) : ExtendedType(source) { internal class Enum(source: JSONObject) : Type(source) { private val modifiers: EnumModifiers by wrapStringList(::EnumModifiers) val flags = modifiers.flags - override val constants: List by declarationList(::EnumConstant) + override val constants: List by declarationList { source, parent -> EnumConstant(source, parent, flags) } } private class TypeReference(override val source: JSONObject) : HasSource { @@ -465,8 +475,8 @@ internal class Constructor( parent: Class, ) : MethodBase(source, parent) { private val modifiers: ConstructorModifiers by wrapStringList(::ConstructorModifiers) - val public = modifiers.visibility == ConstructorVisibility.PUBLIC - + val visibility = modifiers.visibility + val public = visibility == ConstructorVisibility.PUBLIC override val overridden: Boolean = false private val propertyParameterMap: Map? by lazy { @@ -529,8 +539,8 @@ internal class Constructor( fun toPrimaryCode(): String { val declaration: String = when (modifiers.visibility) { ConstructorVisibility.PUBLIC -> "" - ConstructorVisibility.PROTECTED -> "\nprotected constructor" - ConstructorVisibility.PRIVATE -> "\nprivate constructor" + ConstructorVisibility.PROTECTED -> "protected constructor" + ConstructorVisibility.PRIVATE -> "private constructor" } val propertyMap = propertyParameterMap @@ -543,7 +553,7 @@ internal class Constructor( kotlinParametersString() } - return "$declaration ($parametersString)" + return "$declaration($parametersString)" } override fun toCode(): String { @@ -566,8 +576,8 @@ private class TypeConstant( parent: TypeDeclaration, ) : Constant(source, parent) { private val modifiers: ConstantModifiers by wrapStringList(::ConstantModifiers) - private val dpdata: DpData? by optNamed(::DpData) - + override val fixGeneric: Boolean + get() = false private val documentation: String get() = getDocumentation( summary = summary, @@ -577,14 +587,19 @@ private class TypeConstant( override fun toCode(): String { val modifier = exp(modifiers.protected, "protected") - return documentation + - "$modifier val $name: $type" + return buildString { + if (documentation.isNotEmpty()) { + appendLine(documentation) + } + append("$modifier val $name: $type") + } } } private class EnumConstant( source: JSONObject, parent: TypeDeclaration, + private val flags: Boolean = false ) : Constant(source, parent) { private val value: Int by int() @@ -595,8 +610,16 @@ private class EnumConstant( seeAlso = seeAlso + seeAlsoDocs ) - override fun toCode(): String = - documentation + "val $name: ${parent.classId}" + override fun toCode(): String { + return buildString { + appendLine(documentation) + if (flags) { + append("val $name: ${parent.classId}") + } else { + append("object $name: ${parent.classId}") + } + } + } override fun compareTo(other: Declaration): Int = when (other) { @@ -656,52 +679,43 @@ internal class Property( seeAlso = seeAlso + seeAlsoDocs ) - override fun toCode(): String = - "$documentation${toSimpleCode()}" + override fun toCode(): String = """ + |$documentation + |${toSimpleCode()} + """.trimMargin() fun toPrimaryCode(optionalParameter: Boolean): String = toSimpleCode() + exp(optionalParameter, EQ_DE) private fun toSimpleCode(): String { - var str = "" - val definedExternally = parent is Interface && !abstract if (definedExternally) { check(!overridden && !protected) } - if (overridden) { - str += exp(final, "final ") + "override " - } else { - if (protected) { - str += "protected " + val keywords = buildList { + if (protected) add("protected") + if (final || definedExternally) add("final") + else if (abstract && parent !is Interface) add("abstract") + else if (open && parent !is Interface) add("open") + if (overridden) add("override") + if (mode.writable) add("var") else add("val") + }.joinToString(" ") + + return buildString { + if (modifiers.deprecated) { + appendLine(DEPRECATED_ANNOTATION) } - - str += when { - definedExternally -> "final " - abstract -> "abstract " - final -> "final " - open -> "open " - else -> "" + if (!mode.readable) { + appendLine( + """ + |@Deprecated(message = "Write-only property", level = DeprecationLevel.HIDDEN) + |get + """.trimMargin() + ) } + append("$keywords $name: $type${modifiers.nullability}") } - - str += if (mode.writable) "var " else "val " - - str += "$name: $type${modifiers.nullability}" - if (!mode.readable) { - str += """ - - @Deprecated(message = "Write-only property", level = DeprecationLevel.HIDDEN) - get - """.trimIndent() - } - - if (modifiers.deprecated) { - str = DEPRECATED_ANNOTATION + "\n" + str - } - - return str } override fun toExtensionCode(): String { @@ -891,28 +905,26 @@ internal class Method( } if (overridden) { - return exp(final, "final ") + exp(abstract, "abstract ") + "override " + return buildList { + if (final && (parent !is Class || parent.isExtensible)) add("final") + if (abstract) add("abstract") + add("override") + }.joinToString(" ") } - val visibility = when { - internal -> "internal " - protected -> "protected " - else -> "" - } + return buildList { + if (internal) add("internal") + else if (protected) add("protected") - val infix = when { - parameters.size != 1 -> "" - returns == null -> "" - name !in INFIX_METHODS -> "" - else -> "infix " - } + if (parent !is Interface) { + if (abstract) add("abstract") + else if (open) add("open") + } - return when { - abstract -> "abstract " - final -> "final " - open -> "open " - else -> "" - } + visibility + infix + if (parameters.size == 1 && returns != null && name in INFIX_METHODS) { + add("infix") + } + }.joinToString(" ") } private fun nullablePromiseResult(generic: String): Boolean = @@ -930,7 +942,7 @@ internal class Method( // https://youtrack.jetbrains.com/issue/KT-31249 private fun getReturnSignature(definedExternally: Boolean = false): String { var type = returns?.type - ?: return exp(definedExternally, ":$UNIT = definedExternally") + ?: return exp(definedExternally, ": $UNIT = definedExternally") if (type.startsWith("$PROMISE<")) { val newGeneric = when (val generic = type.between("<", ">")) { @@ -941,7 +953,7 @@ internal class Method( type = "$PROMISE<$newGeneric>" } - return ":" + type + modifiers.nullability + exp(definedExternally, " = definedExternally") + return ": " + type + modifiers.nullability + exp(definedExternally, " = definedExternally") } private fun isOperatorMode(): Boolean = @@ -949,8 +961,12 @@ internal class Method( && parameters.first().name != "x" // to exclude RectangleHandle.set override fun toCode(): String { - val staticCreate = static && name in FACTORY_METHODS - && parent.name != "List" && parent.name != "XmlName" && !parent.name.endsWith("s") + val staticCreate = static + && name in FACTORY_METHODS + && parent.name != "List" + && parent.name != "XmlName" + && !parent.name.endsWith("s") + val additionalOperator = operatorName != null val operator = exp(staticCreate || additionalOperator || isOperatorMode(), "operator") @@ -959,27 +975,49 @@ internal class Method( name in APPLY_METHODS -> "applyTo" else -> operatorName ?: name } - val annotation = if (methodName != name) "@JsName(\"$name\")\n" else "" + val annotation = if (methodName != name) "@JsName(\"$name\")" else "" val definedExternally = when { static -> false additionalOperator -> parent is Interface - else -> !static && !abstract && parent is Interface + else -> !abstract && parent is Interface } val returnSignature = getReturnSignature(definedExternally) - val modifier = if (additionalOperator || definedExternally) " final" else kotlinModifier() - val receiver = if (hasReceiver) parameters.first().typeDeclaration + "." else "" + val modifier = if (additionalOperator || definedExternally) "final" else kotlinModifier() val parametersString = kotlinParametersString(hasReceiver) - var code = "$annotation $modifier $operator fun ${generics.declaration}$receiver$methodName($parametersString)$returnSignature" - when { - deprecated -> - code = DEPRECATED_ANNOTATION + "\n" + code - hidden -> - code = HIDDEN_METHOD_ANNOTATION + "\n" + code - } - val result = documentation + code + var result = buildString { + appendLine(documentation) + if (deprecated) appendLine(DEPRECATED_ANNOTATION) + if (hidden) appendLine(HIDDEN_METHOD_ANNOTATION) + if (annotation.isNotEmpty()) + appendLine(annotation) + + append(buildList { + if (modifier.isNotEmpty()) + add(modifier) + + if (operator.isNotEmpty()) + add(operator) + + add("fun") + + if (generics.declaration.isNotEmpty()) + add(generics.declaration) + + add(buildString { + if (hasReceiver) { + append(parameters.first().typeDeclaration) + append(".") + } + append(methodName) + }) + }.joinToString(" ")) + + append("($parametersString)") + append(returnSignature) + } if (additionalOperator) return result if (static) return result @@ -995,20 +1033,20 @@ internal class Method( val functionalMethod = parent.functionalMethod ?: return null val delegateName = functionalMethod.name - val delegateType = """( - ${functionalMethod.parameters.byCommaLine { it.declaration }} - ) -> ${(functionalMethod.returns?.type ?: UNIT)} - """.trimIndent() + val delegateType = "(${functionalMethod.parameters.byComma { it.declaration }}) -> ${(functionalMethod.returns?.type ?: UNIT)}" val factoryGenerics = parent.generics val code = """ - @JsName("$name") - operator fun ${factoryGenerics.wrapperDeclaration} invoke( - $delegateName: $delegateType - )${getReturnSignature()} - """.trimIndent() - - return documentation + code + |@JsName("$name") + |operator fun ${factoryGenerics.wrapperDeclaration} invoke( + | $delegateName: $delegateType + |)${getReturnSignature()} + """.trimMargin() + + return """ + |$documentation + |$code + """.trimMargin() } private fun getStaticOperatorExtensionName(): String? { @@ -1067,10 +1105,12 @@ internal class Method( val returnOperator = exp(returns != null, "return ") val methodCall = "$name(${parameters.byComma { it.name }})" - return documentation + - "inline operator fun $genericDeclaration ${parent.classDeclaration}.$operatorName($extParameters)$returnSignature {\n" + - " $returnOperator $AS_DYNAMIC.$methodCall\n" + - "}" + return """ + |$documentation + |inline operator fun $genericDeclaration ${parent.classDeclaration}.$operatorName($extParameters)$returnSignature { + | $returnOperator $AS_DYNAMIC.$methodCall + |} + """.trimMargin() } } @@ -1095,17 +1135,22 @@ internal sealed class MethodBase( get() = seeAlsoDocs(parent, id) protected fun Parameter.toParameterString(): String { - val vararg = exp(modifiers.vararg, "vararg ") - val body = exp(modifiers.optional && !overridden, EQ_DE) - return "$vararg $declaration $body" + return buildList { + if (modifiers.vararg) add("vararg") + add(declaration) + if (modifiers.optional && !overridden) add(EQ_DE) + }.joinToString(" ") } protected fun kotlinParametersString( ignoreFirstParameter: Boolean = false, - ): String = - parameters - .drop(if (ignoreFirstParameter) 1 else 0) - .byCommaLine { it.toParameterString() } + ): String = parameters + .drop(if (ignoreFirstParameter) 1 else 0) + .takeUnless { it.isEmpty() } + ?.joinToString(separator = "", prefix = System.lineSeparator()) { + INDENT + it.toParameterString() + "," + System.lineSeparator() + } ?: "" + override fun compareTo(other: Declaration): Int { val result = super.compareTo(other) @@ -1135,7 +1180,7 @@ internal class Parameter( override val summary: String? by summary() val modifiers: ParameterModifiers by parameterModifiers() - val declaration: String by lazy { name + ": " + typeDeclaration } + val declaration: String by lazy { "$name: $typeDeclaration" } } internal class TypeParameter(source: JSONObject) : JsonWrapper(source), IParameter, ITypeParameter { @@ -1176,22 +1221,14 @@ internal class Event( private val parent: TypeDeclaration, ) : JsonWrapper(source) { val name: String by string() + val signature: String by string() + val type: String by type { parse(it, signature, emptyList()).asReadOnly() } private val summary: String? by summary() private val seeAlso: List by seeAlso() - private val add: EventListener by eventListener(parent) - private val remove: EventListener by eventListener(parent) - private val listeners = listOf(add, remove) - - val overriden by lazy { - listeners.any { it.overridden } - } private val seeAlsoDocs: List get() = seeAlsoDocs(parent, name) - val listenerNames: List - get() = listeners.map { it.name } - private val documentation: String get() = getDocumentation( summary = summary, @@ -1199,58 +1236,28 @@ internal class Event( ) override fun toCode(): String { - return documentation + - listeners.lines { it.toCode() } + return "" } override fun toExtensionCode(): String { - // TODO: fix in common way val generics = parent.generics.declaration.replace("", "") - val extensionName = "add${name}Handler" - - val listenerType = add.parameters.single().type - val data = getHandlerData(listenerType) - - return documentation + - """ - inline fun $generics $classDeclaration.$extensionName( - crossinline handler: ${data.handlerType} - ): () -> Unit { - val listener: $listenerType = ${data.listenerBody} - ${add.name}(listener) - return { ${remove.name}(listener) } - } - """.trimIndent() - } -} - -private class EventListener( - source: JSONObject, - private val parent: HasClassId, -) : JsonWrapper(source) { - val name: String by string() - val modifiers: EventListenerModifiers by wrapStringList(::EventListenerModifiers) - val parameters: List by list { Parameter(it) } - - val overridden: Boolean - get() = ClassRegistry.instance - .listenerOverridden(parent.classId, name) - - private fun kotlinModificator(): String { - return when { - overridden -> "override " - modifiers.abstract -> "abstract " - else -> "" - } - } - - // TODO: update after nullability fix - override fun toCode(): String { - val parametersString = parameters - .byComma { it.declaration } + val extensionName = name.split("-") + .joinToString(separator = "", prefix = "add", postfix = "Handler") { + it.replaceFirstChar(Char::titlecase) + } - return "${kotlinModificator()}fun $name($parametersString)" + val data = getHandlerData(type) + return """ + |$documentation + |inline fun $generics $classDeclaration.$extensionName( + | crossinline handler: ${data.handlerType} + |): () -> Unit { + | val listener: $type = ${data.listenerBody} + | addEventListener("$name", listener) + | return { removeEventListener("$name", listener) } + |} + """.trimMargin() } } @@ -1310,9 +1317,6 @@ private fun defaultValue(): Prop = .takeIf { it.isNotEmpty() } } -private fun eventListener(parent: HasClassId): Prop = - named { EventListener(it, parent) } - private fun

P.declarationList( create: (JSONObject, P) -> T, ): Prop> = @@ -1364,7 +1368,7 @@ private fun getDocumentation( return "/**\n" + lines.lines { " * $it" } + - " */\n" + " */" } private fun getDocumentationLines( @@ -1492,3 +1496,5 @@ private fun List?.toNamedList(title: String): List { return listOf("### $title") + map(::listItem) } + +internal fun String.indent(indent: String = INDENT) = lines().joinToString(System.lineSeparator()) { indent + it } \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/YSettings.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/YSettings.kt index 756d27424..42d74ecda 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/YSettings.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/YSettings.kt @@ -1,9 +1,5 @@ package com.github.turansky.yfiles -const val YOBJECT = "yfiles.lang.YObject" - -private const val YOBJECT_CLASS = "yfiles.lang.Object" - private val PRIMITIVE_CLASSES = setOf( "yfiles.lang.Boolean", "yfiles.lang.Number", @@ -11,15 +7,11 @@ private val PRIMITIVE_CLASSES = setOf( ) private val MARKER_CLASSES = setOf( - YOBJECT_CLASS, "yfiles.lang.EventArgs", "yfiles.lang.Attribute", GRAPH_OBJECT ) -fun isYObjectClass(className: String): Boolean = - className == YOBJECT_CLASS - fun isPrimitiveClass(className: String): Boolean = className in PRIMITIVE_CLASSES diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/YTypes.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/YTypes.kt index d805b84ad..43af8bd80 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/YTypes.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/YTypes.kt @@ -3,12 +3,8 @@ package com.github.turansky.yfiles const val YID = "yfiles.lang.Id" const val IEVENT_DISPATCHER = "yfiles.lang.IEventDispatcher" -const val YCLASS = "yfiles.lang.YClass" -const val YENUM = "yfiles.lang.YEnum" const val YFLAGS = "yfiles.lang.YFlags" -const val BASE_CLASS = "yfiles.lang.BaseClass" - const val ICLASS_METADATA = "yfiles.lang.IClassMetadata" const val CLASS_METADATA = "yfiles.lang.ClassMetadata" const val ENUM_METADATA = "yfiles.lang.EnumMetadata" @@ -18,8 +14,7 @@ const val ICOMPARABLE = "yfiles.lang.IComparable" const val ICLONEABLE = "yfiles.lang.ICloneable" const val EVENT_HANDLER1 = "yfiles.lang.EventHandler1" -const val ILOOKUP = "yfiles.graph.ILookup" -const val IMAPPER_REGISTRY = "yfiles.graph.IMapperRegistry" +const val ILOOKUP = "yfiles.collections.ILookup" const val ITAG_OWNER = "yfiles.graph.ITagOwner" const val IMODEL_ITEM = "yfiles.graph.IModelItem" @@ -40,21 +35,14 @@ const val IMEMENTO_SUPPORT = "yfiles.graph.IMementoSupport" const val IPORT_CANDIDATE = "yfiles.input.IPortCandidate" const val IINPUT_MODE_CONTEXT = "yfiles.input.IInputModeContext" -const val ICURSOR = "yfiles.algorithms.ICursor" const val YLIST = "yfiles.algorithms.YList" -const val YPOINT = "yfiles.algorithms.YPoint" -const val EDGE_LIST = "yfiles.algorithms.EdgeList" const val GRAPH = "yfiles.algorithms.Graph" const val NODE = "yfiles.algorithms.Node" const val EDGE = "yfiles.algorithms.Edge" const val GRAPH_OBJECT = "yfiles.algorithms.GraphObject" -const val DP_KEY_BASE = "yfiles.algorithms.DpKeyBase" -const val GRAPH_DP_KEY = "yfiles.algorithms.GraphDpKey" -const val IEDGE_LABEL_LAYOUT_DP_KEY = "yfiles.algorithms.IEdgeLabelLayoutDpKey" -const val INODE_LABEL_LAYOUT_DP_KEY = "yfiles.algorithms.INodeLabelLayoutDpKey" - +const val ICURSOR = "yfiles.collections.ICursor" const val IENUMERABLE = "yfiles.collections.IEnumerable" const val ICOLLECTION = "yfiles.collections.ICollection" const val ILIST_ENUMERABLE = "yfiles.collections.IListEnumerable" @@ -71,25 +59,9 @@ const val LAYOUT_GRAPH = "yfiles.layout.LayoutGraph" const val INODE_LABEL_LAYOUT = "yfiles.layout.INodeLabelLayout" const val IEDGE_LABEL_LAYOUT = "yfiles.layout.IEdgeLabelLayout" -const val NODE_LABEL_CANDIDATE = "yfiles.layout.NodeLabelCandidate" -const val EDGE_LABEL_CANDIDATE = "yfiles.layout.EdgeLabelCandidate" - const val OBSTACLE = "yfiles.router.Obstacle" const val PARTITION_CELL = "yfiles.router.PartitionCell" -const val IDATA_PROVIDER = "yfiles.algorithms.IDataProvider" -const val IDATA_ACCEPTOR = "yfiles.algorithms.IDataAcceptor" -const val IDATA_MAP = "yfiles.algorithms.IDataMap" -const val IEDGE_MAP = "yfiles.algorithms.IEdgeMap" -const val INODE_MAP = "yfiles.algorithms.INodeMap" - -const val PARTITION_CELL_KEY = "yfiles.router.PartitionCellKey" -const val BIPARTITION_MARK = "yfiles.algorithms.BipartitionMark" -const val DFS_STATE = "yfiles.algorithms.DfsState" - -const val ICANVAS_OBJECT_DESCRIPTOR = "yfiles.view.ICanvasObjectDescriptor" -const val ICANVAS_OBJECT_INSTALLER = "yfiles.view.ICanvasObjectInstaller" - const val VISUAL = "yfiles.view.Visual" const val IVISUAL_CREATOR = "yfiles.view.IVisualCreator" const val IVISUAL_TEMPLATE = "yfiles.view.IVisualTemplate" diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CanvasObjectDescriptorHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CanvasObjectDescriptorHacks.kt deleted file mode 100644 index a12c2d8cb..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CanvasObjectDescriptorHacks.kt +++ /dev/null @@ -1,122 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.* -import com.github.turansky.yfiles.json.get -import org.json.JSONObject - -internal fun applyCanvasObjectDescriptorHacks(source: Source) { - source.type("ICanvasObjectDescriptor") { - setSingleTypeParameter("in T", YOBJECT) - - fixUserObjectType("T") - - sequenceOf( - "ALWAYS_DIRTY_INSTANCE" to IVISUAL_CREATOR, - "ALWAYS_DIRTY_LOOKUP" to ILOOKUP, - "ALWAYS_DIRTY_VISUAL" to VISUAL, - "DYNAMIC_DIRTY_INSTANCE" to IVISUAL_CREATOR, - "DYNAMIC_DIRTY_LOOKUP" to ILOOKUP, - "VISUAL" to VISUAL, - "VOID" to YOBJECT - ).forEach { (name, typeParameter) -> - constant(name).addGeneric(typeParameter) - } - } - - source.type("ICanvasObject") - .property("descriptor") - .addGeneric("*") - - source.type("ICanvasObjectGroup") - .method("addChild").apply { - setSingleTypeParameter(bound = YOBJECT) - - firstParameter[TYPE] = "T" - firstParameter.changeNullability(false) - secondParameter.addGeneric("T") - } - - source.type("DefaultPortCandidateDescriptor") { - get(IMPLEMENTS).apply { - put(indexOf(ICANVAS_OBJECT_DESCRIPTOR), "$ICANVAS_OBJECT_DESCRIPTOR<$IPORT_CANDIDATE>") - } - - fixUserObjectType(IPORT_CANDIDATE) - } - - source.type("CreateEdgeInputMode") - .flatMap(PROPERTIES) - .filter { it[TYPE] == ICANVAS_OBJECT_DESCRIPTOR } - .forEach { it.addGeneric(IPORT_CANDIDATE) } - - sequenceOf( - "LabelPositionHandler" to ILABEL_MODEL_PARAMETER, - "PortRelocationHandle" to IPORT_CANDIDATE, - "SnapContext" to "yfiles.input.SnapResult" - ).forEach { (className, typeParameter) -> - source.type(className) - .flatMap(METHODS) - .filter { it.has(RETURNS) } - .map { it[RETURNS] } - .filter { it[TYPE] == ICANVAS_OBJECT_DESCRIPTOR } - .forEach { it.addGeneric(typeParameter) } - } - - source.type("ItemModelManager") { - get(TYPE_PARAMETERS).getJSONObject(0)[BOUNDS] = arrayOf(YOBJECT) - - get(PROPERTIES)["descriptor"].addGeneric("T") - method("getDescriptor")[RETURNS].addGeneric("T") - } - - source.type("CollectionModelManager") { - get(TYPE_PARAMETERS).getJSONObject(0)[BOUNDS] = arrayOf(YOBJECT) - } - - source.type("GraphModelManager") { - flatMap(PROPERTIES) - .filter { it[TYPE] == ICANVAS_OBJECT_DESCRIPTOR } - .forEach { - val typeParameter = when (val name = it[NAME]) { - "nodeDescriptor" -> INODE - "edgeDescriptor" -> IEDGE - "portDescriptor" -> IPORT - else -> { - require(name.endsWith("LabelDescriptor")) - ILABEL - } - } - - it.addGeneric(typeParameter) - } - - flatMap(CONSTANTS) - .filter { it[TYPE] == ICANVAS_OBJECT_DESCRIPTOR } - .forEach { - val typeParameter = when (it[NAME]) { - "DEFAULT_EDGE_DESCRIPTOR" -> IEDGE - "DEFAULT_LABEL_DESCRIPTOR" -> ILABEL - "DEFAULT_NODE_DESCRIPTOR" -> INODE - "DEFAULT_PORT_DESCRIPTOR" -> IPORT - else -> TODO() - } - - it.addGeneric(typeParameter) - } - - flatMap(METHODS) - .filter { it.has(PARAMETERS) } - .filter { it.firstParameter[TYPE] == ICANVAS_OBJECT_DESCRIPTOR } - .forEach { - val typeParameter = it[RETURNS][TYPE].between("<", ">") - it.firstParameter.addGeneric(typeParameter) - } - } -} - -private fun JSONObject.fixUserObjectType(type: String) { - flatMap(METHODS) - .optFlatMap(PARAMETERS) - .filter { it[NAME] == "forUserObject" } - .forEach { it[TYPE] = type } -} diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CanvasObjectInstallerHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CanvasObjectInstallerHacks.kt deleted file mode 100644 index c13be3918..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CanvasObjectInstallerHacks.kt +++ /dev/null @@ -1,79 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.* -import org.json.JSONObject - -internal fun applyCanvasObjectInstallerHacks(source: Source) { - source.type("ICanvasObjectInstaller") - .method("create") - .get(RETURNS) - .addGeneric("T") - - source.types() - .filter { it[ID].run { startsWith("yfiles.view.") && endsWith("Installer") } } - .filter { it[GROUP] == "interface" } - .onEach { - it.setSingleTypeParameter( - name = if (it[ID] == ICANVAS_OBJECT_INSTALLER) "in T" else "T", - bound = IMODEL_ITEM - ) - } - .onEach { it.fixUserObjectType("T") } - .filter { it.has(IMPLEMENTS) } - .onEach { require(it[IMPLEMENTS].single() == ICANVAS_OBJECT_INSTALLER) } - .forEach { it[IMPLEMENTS] = arrayOf("$ICANVAS_OBJECT_INSTALLER") } - - source.types() - .filter { it[ID].run { startsWith("yfiles.graph.") && endsWith("Decorator") } } - .optFlatMap(PROPERTIES) - .filter { it[TYPE].endsWith("Installer>") } - .forEach { - it[TYPE] = it[TYPE].run { - val typeParameter = this.between("<", ",") - replace(">", "<$typeParameter>>") - } - } - - source.types() - .filter { it[ID].run { startsWith("yfiles.view.") && endsWith("Installer") } } - .filter { it[GROUP] == "class" } - .forEach { - val name = it[NAME] - val typeParameter = when { - name.startsWith("Node") -> INODE - name.startsWith("Edge") -> IEDGE - name.startsWith("Port") -> IPORT - name.startsWith("Label") -> ILABEL - - else -> { - it.setSingleTypeParameter(bound = IMODEL_ITEM) - "T" - } - } - - if (it.has(IMPLEMENTS)) { - it[IMPLEMENTS] = it[IMPLEMENTS].map { "$it<$typeParameter>" } - } - - it.fixUserObjectType(typeParameter) - } - - source.types() - .filter { it[ID].run { startsWith("yfiles.view.") && endsWith("Manager") } } - .optFlatMap(METHODS) - .filter { it[NAME] == "getInstaller" } - .forEach { it[RETURNS].addGeneric(it.firstParameter[TYPE]) } -} - -private val ITEM_NAMES = setOf( - "item", - "userObject" -) - -private fun JSONObject.fixUserObjectType(type: String) { - optFlatMap(METHODS) - .optFlatMap(PARAMETERS) - .filter { it[NAME] in ITEM_NAMES } - .onEach { it.changeNullability(false) } - .forEach { it[TYPE] = type } -} diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ChangeHandlerHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ChangeHandlerHacks.kt new file mode 100644 index 000000000..fb04878db --- /dev/null +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ChangeHandlerHacks.kt @@ -0,0 +1,17 @@ +package com.github.turansky.yfiles.correction + +import com.github.turansky.yfiles.JS_ANY + +internal fun fixChangeHandlers(source: Source) { + listOf( + "yfiles.graph.BendLocationChangedHandler", + "yfiles.graph.NodeLayoutChangedHandler", + ).map(source::functionSignature) + .forEach { sig -> + sig.flatMap(PARAMETERS) + .filter { it[NAME] == "source" } + .forEach { + it[TYPE] = JS_ANY + } + } +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ClassHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ClassHacks.kt index 2e1115ca0..c721bbe4d 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ClassHacks.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ClassHacks.kt @@ -1,97 +1,42 @@ package com.github.turansky.yfiles.correction import com.github.turansky.yfiles.* -import com.github.turansky.yfiles.ContentMode.* -import com.github.turansky.yfiles.json.get -import com.github.turansky.yfiles.json.jArray -import com.github.turansky.yfiles.json.jObject -import com.github.turansky.yfiles.json.removeAllObjects -import com.github.turansky.yfiles.json.removeItem +import com.github.turansky.yfiles.ContentMode.DELEGATE import org.json.JSONObject internal fun generateClassUtils(context: GeneratorContext) { - // language=kotlin - context[BASE_CLASS, CLASS] = - """ - $HIDDEN_METHOD_ANNOTATION - external fun BaseClass(vararg types: JsClass):JsClass - - $HIDDEN_METHOD_ANNOTATION - inline fun callSuperConstructor(o: $YOBJECT) { - o.$AS_DYNAMIC.__proto__.__proto__.constructor.call(o) - } - """.trimIndent() - - val primitiveTypeMetadata = sequenceOf( - BOOLEAN to "__BOOLEAN__", - DOUBLE to "__NUMBER__", - INT to "__NUMBER__", - STRING to "__STRING__" - ).joinToString("\n\n") { (type, alias) -> - """ - inline val $type.Companion.yclass: $YCLASS<$type> - get() = $alias.unsafeCast<$ICLASS_METADATA<$type>>().yclass - """.trimIndent() - } - - // language=kotlin - context[ICLASS_METADATA] = - """ - private const val YCLASS = "\${'$'}class" - - external interface IClassMetadata { - @JsName(YCLASS) - val yclass:$YCLASS - } - - inline val JsClass.yclass:$YCLASS - get() = unsafeCast>().yclass - - internal fun JsClass.findClass():$YCLASS? = - $AS_DYNAMIC[YCLASS] as? $YCLASS - - $primitiveTypeMetadata - """.trimIndent() - - // language=kotlin - context[ICLASS_METADATA, DELEGATE] = - """ - inline fun classMetadata(): $ICLASS_METADATA = - classMetadata(T::class.js.yclass) - - fun classMetadata(yclass: $YCLASS): $ICLASS_METADATA = - SimpleClassMetadata(yclass) - - private class SimpleClassMetadata( - override val yclass: $YCLASS - ): $ICLASS_METADATA - """.trimIndent() - // language=kotlin context[CLASS_METADATA] = """ @JsName("Object") - abstract external class ClassMetadata - internal constructor() : $ICLASS_METADATA { - override val yclass: $YCLASS - } - """.trimIndent() + abstract external class ClassMetadata internal constructor() : $ICLASS_METADATA - // language=kotlin - context[ENUM_METADATA] = """ - @JsName("Object") - abstract external class EnumMetadata> - internal constructor() : $ICLASS_METADATA { - override val yclass: $YCLASS + inline fun jsInstanceOf( + o: Any?, + type: $CLASS_METADATA<*> + ): Boolean = + type.$AS_DYNAMIC.isInstance(o) + + inline infix fun Any?.yIs(type: $CLASS_METADATA<*>): Boolean = + jsInstanceOf(this, type) + + inline infix fun Any?.yOpt(type: $CLASS_METADATA): T? = + if (yIs(type)) { + unsafeCast() + } else { + null + } + + inline infix fun Any?.yAs(type: $CLASS_METADATA): T { + require(this yIs type) + + return unsafeCast() } """.trimIndent() // language=kotlin context[INTERFACE_METADATA] = """ @JsName("Object") - abstract external class InterfaceMetadata - internal constructor() : $ICLASS_METADATA { - override val yclass: $YCLASS - } + abstract external class InterfaceMetadata internal constructor() : $ICLASS_METADATA inline fun jsInstanceOf( o: Any?, @@ -102,14 +47,14 @@ internal fun generateClassUtils(context: GeneratorContext) { inline infix fun Any?.yIs(type: $INTERFACE_METADATA<*>): Boolean = jsInstanceOf(this, type) - inline infix fun Any?.yOpt(type: $INTERFACE_METADATA): T? = + inline infix fun Any?.yOpt(type: $INTERFACE_METADATA): T? = if (yIs(type)) { unsafeCast() } else { null } - inline infix fun Any?.yAs(type: $INTERFACE_METADATA): T { + inline infix fun Any?.yAs(type: $INTERFACE_METADATA): T { require(this yIs type) return unsafeCast() @@ -117,105 +62,91 @@ internal fun generateClassUtils(context: GeneratorContext) { """.trimIndent() // language=kotlin - context[YENUM, EXTENSIONS] = """ - $HIDDEN_METHOD_ANNOTATION - inline fun > getEnumName( - value: T, - type: EnumMetadata - ): String = - YEnum.getName(type.yclass, value) - - $HIDDEN_METHOD_ANNOTATION - inline fun > getEnumValues( - type: EnumMetadata - ): Array = - YEnum.getValues(type.yclass) - - $HIDDEN_METHOD_ANNOTATION - inline fun > getEnumValueOf( - type: EnumMetadata, - id: String - ): T = - YEnum.parse(type.yclass, id, true) - """.trimIndent() + context[ICLASS_METADATA] = + """ + external interface IClassMetadata + """.trimIndent() } internal fun applyClassHacks(source: Source) { - fixClass(source) - fixEnum(source) - + fixConstructorUsage(source) addClassGeneric(source) - addConstructorClassGeneric(source) - addMethodClassGeneric(source) - addMapperMetadataGeneric(source) + fixLookupGeneric(source) - removeUnusedTypeParameters(source) addClassBounds(source) + removeTypeOf(source) + fixDisposeVisualCallback(source) +} - addTypeParameterBounds(source) - addMapClassBounds(source) +private fun removeTypeOf(source: Source) { + source.types() + .filter { it.has(METHODS) } + .flatMap(METHODS) + .filter { it.has(PARAMETERS) } + .flatMap(PARAMETERS) + .filter { "typeof" in it[TYPE] } + .forEach { it[TYPE] = it[TYPE].removePrefix("typeof ") } } -private fun fixClass(source: Source) { - source.type("Class") { - setSingleTypeParameter(bound = JS_OBJECT) +private fun fixConstructorUsage(source: Source) { + source.types() + .filter { it.has(METHODS) } + .flatMap(METHODS) + .filter { it.has(PARAMETERS) } + .flatMap(PARAMETERS) + .forEach { + it.convertConstructor() + } - get(MODIFIERS).put(FINAL) + source.types() + .filter { it.has(METHODS) } + .flatMap(METHODS) + .filter { it.has(RETURNS) } + .forEach { + it[RETURNS].convertConstructor() + } - this[CONSTRUCTORS] = jArray( - jObject( - MODIFIERS to arrayOf(PRIVATE) - ) - ) + source.types() + .filter { it.has(CONSTRUCTORS) } + .flatMap(CONSTRUCTORS) + .filter { it.has(PARAMETERS) } + .flatMap(PARAMETERS) + .forEach { + it.convertConstructor() + } - get(METHODS).removeItem(method("getProperties")) + source.types() + .filter { it.has(PROPERTIES) } + .flatMap(PROPERTIES) + .forEach { + it.convertConstructor() + } - method("newInstance") - .get(RETURNS) - .set(TYPE, "T") + source.functionSignature("yfiles.collections.ContextLookupDelegate") + .flatMap(PARAMETERS) + .forEach { + it.convertConstructor() + } +} - get(METHODS).apply { - removeAllObjects { - STATIC in it[MODIFIERS] && it[NAME] != "fixType" - } +private val CONSTRUCTOR_REGEX = Regex("Constructor(?:<(\\w+)>)?") - get("fixType").apply { - firstParameter[TYPE] = "$JS_CLASS" - get(MODIFIERS).put(HIDDEN) - } - } - } +private fun JSONObject.convertConstructor() { + if (has(TYPE)) + this[TYPE] = this[TYPE].convertConstructor() + if (has(SIGNATURE)) + this[SIGNATURE] = this[SIGNATURE].convertConstructor() } -private fun fixEnum(source: Source) { - source.type("Enum") { - set(ID, YENUM) - set(NAME, "YEnum") - set(ES6_NAME, "Enum") - set(GROUP, "interface") - setSingleTypeParameter(bound = "$YENUM") - - flatMap(METHODS) - .onEach { it.setSingleTypeParameter(bound = "$YENUM") } - .onEach { - val returns = it[RETURNS] - when (returns[TYPE]) { - JS_NUMBER -> returns[TYPE] = "T" - "Array<$JS_NUMBER>" -> returns[TYPE] = "Array" - } - } - .flatMap(PARAMETERS) - .forEach { - when (it[TYPE]) { - YCLASS -> it.addGeneric("T") - JS_NUMBER -> it[TYPE] = "$YENUM" - } - } +private fun String.convertConstructor() : String { + return CONSTRUCTOR_REGEX.replace(this) { match -> + val typeParameter = match.groupValues[1] + return@replace if (typeParameter.isNotEmpty()) { + "$ICLASS_METADATA<$typeParameter>" + } else { + "$ICLASS_METADATA<*>" + } } - - source.type("Direction") - .get(MODIFIERS) - .put(ENUM_LIKE) } private fun addClassGeneric(source: Source) { @@ -230,237 +161,62 @@ private fun addClassGeneric(source: Source) { "getOrCreateCopy" ) .forEach { - it.setSingleTypeParameter(bound = YOBJECT) - - if (it[NAME] != "lookup" || !it.typeParameter[TYPE].endsWith("")) { - it.typeParameter.addGeneric("T") - - it[RETURNS][TYPE] = "T" - } - it[MODIFIERS] .put(CANBENULL) } - - source.allMethods("getDecoratorFor").forEach { - it.firstParameter.addGeneric("TInterface") - } - - source.allMethods( - "typedHitElementsAt", - "createHitTester", - - "serializeCore", - "deserializeCore" - ) - .forEach { - it.firstParameter.addGeneric("T") - } - - source.allMethods( - "getCurrent", - "serialize", - "deserialize", - "setLookup" - ) - .map { it.firstParameter } - .filter { it[TYPE] == YCLASS } - .forEach { - it.addGeneric("T") - } - - source.allMethods("factoryLookupChainLink", "add", "addConstant") - .filter { it.firstParameter[NAME] == "contextType" } - .forEach { - it.parameter("contextType").addGeneric("TContext") - it.parameter("resultType").addGeneric("TResult") - } - - source.allMethods("addConstant", "ofType") - .map { it.firstParameter } - .filter { it[NAME] == "resultType" } - .forEach { it.addGeneric("TResult") } - - source.allMethods( - "addGraphInputData", - "addGraphOutputData" - ) - .forEach { - it.firstParameter.addGeneric("TValue") - } - - source.allMethods("addOutputMapper") - .forEach { - it.parameter("modelItemType").addGeneric("TModelItem") - it.parameter("dataType").addGeneric("TValue") - } - - source.allMethods("addRegistryOutputMapper") - .filter { it.firstParameter[NAME] == "modelItemType" } - .forEach { - it.parameter("modelItemType").addGeneric("TModelItem") - it.parameter("valueType").addGeneric("TValue") - } - - source.type("GraphMLIOHandler") - .allMethodParameters() - .filter { it[TYPE] == YCLASS } - .forEach { - when (it[NAME]) { - "keyType" -> it.addGeneric("TKey") - "modelItemType" -> it.addGeneric("TKey") - "dataType" -> it.addGeneric("TData") - } - } - - source.allMethods( - "addMapper", - "addConstantMapper", - "addDelegateMapper", - - "createMapper", - "createConstantMapper", - "createDelegateMapper", - - "addDataProvider", - "createDataMap", - "createDataProvider" - ) - .filter { it.firstParameter[NAME] == "keyType" } - .filter { it.secondParameter[NAME] == "valueType" } - .forEach { - it.parameter("keyType").addGeneric("K") - it.parameter("valueType").addGeneric("V") - } } -private fun addConstructorClassGeneric(source: Source) { - source.types() - .forEach { type -> - val typeName = type[NAME] - type.optFlatMap(CONSTRUCTORS) - .optFlatMap(PARAMETERS) - .filter { it[TYPE] == YCLASS } - .forEach { - val generic = when (it[NAME]) { - "edgeStyleType" -> "TStyle" - "decoratedType" -> "TDecoratedType" - "interfaceType" -> "TInterface" - "keyType" -> - when (typeName) { - "DataMapAdapter" -> "K" - "ItemCollectionMapping" -> "TItem" - else -> "TKey" - } - "valueType" -> if (typeName == "DataMapAdapter") "V" else "TValue" - "dataType" -> "TData" - "itemType" -> "T" - "type" -> when (typeName) { - "StripeDecorator" -> "TStripe" - else -> null - } - else -> null - } - - if (generic != null) { - it.addGeneric(generic) - } - } - } -} - -private fun addMethodClassGeneric(source: Source) { - source.type("ILookup") - .method("createSingleLookup") - .apply { - setSingleTypeParameter(bound = YOBJECT) - firstParameter[TYPE] = "T" - secondParameter.addGeneric("T") +private fun fixLookupGeneric(source: Source) { + source.allMethods("lookup") + .forEach { method -> + method.setSingleTypeParameter(bound = JS_ANY) + method.parameter("type")[TYPE] = "$ICLASS_METADATA" + method.returnsSequence().forEach { it[TYPE] = "T" } } } -private fun addMapperMetadataGeneric(source: Source) { - val type = source.type("MapperMetadata") - - type.setTypeParameters("TKey", "TValue") - - type.flatMap(CONSTRUCTORS) - .flatMap(PARAMETERS) - .filter { it[NAME] == "metadata" } - .forEach { it.addGeneric("TKey,TValue") } - - type.flatMap(PROPERTIES) - .forEach { - when (it[NAME]) { - "keyType" -> it.addGeneric("TKey") - "valueType" -> it.addGeneric("TValue") - } - } - - type.method("create") - .apply { - parameter("keyType").addGeneric("TKey") - parameter("valueType").addGeneric("TValue") - - get(RETURNS) - .addGeneric("TKey,TValue") - } - - source.type("MapperOutputHandler") - .property("mapperMetadata") - .addGeneric("TKey,TData") - - source.types( - "IMapperRegistry", - "MapperRegistry" - ).forEach { - it.method("getMapperMetadata").apply { - setTypeParameters("K", "V") - get(RETURNS) - .addGeneric("K,V") - } - - it.method("setMapperMetadata").apply { - setTypeParameters("K", "V") - parameter("metadata") - .addGeneric("K,V") - } - } -} - private fun removeUnusedTypeParameters(source: Source) { source.allMethods("removeLookup") .forEach { it.remove(TYPE_PARAMETERS) } } private fun addClassBounds(source: Source) { - val typeNames = setOf( - "TModelItem", - "TItem" - ) - source.types() + .filter { it.has(TYPE_PARAMETERS) } .forEach { type -> - type.optFlatMap(TYPE_PARAMETERS) - .filter { it[NAME] in typeNames } - .forEach { - val bound = when (type[ID]) { - "yfiles.graph.ItemChangedEventArgs" -> ITAG_OWNER - else -> IMODEL_ITEM - } - it[BOUNDS] = arrayOf(bound) + val methods = type.optFlatMap(CONSTRUCTORS) + type.optFlatMap(METHODS) + val typeParameters = type.flatMap(TYPE_PARAMETERS) + typeParameters.forEach { typeParam -> + val hasJS_CLASSRef = methods.filter { it.has(PARAMETERS) && !it.has(TYPE_PARAMETERS) } + .flatMap(PARAMETERS) + .any { JS_CLASS in it[TYPE] && typeParam[NAME] in it[TYPE] } + + if (hasJS_CLASSRef) { + typeParam[BOUNDS] = arrayOf(JS_OBJECT) } + } + } + + source.types() + .optFlatMap(METHODS) + .filter { it.has(TYPE_PARAMETERS) } + .forEach { method -> + val typeParameters = method.flatMap(TYPE_PARAMETERS) + typeParameters.forEach { typeParam -> + val hasJS_CLASSRef = method.optFlatMap(PARAMETERS) + .any { JS_CLASS in it[TYPE] && typeParam[NAME] in it[TYPE] } + + if (hasJS_CLASSRef) { + typeParam[BOUNDS] = arrayOf(JS_OBJECT) + } + } } source.types( - "DpKeyItemCollection", "ItemClickedEventArgs", "TableItemClickedEventArgs", - "ItemTappedEventArgs", - "TableItemTappedEventArgs", - "IGridConstraintProvider", "GridConstraintProvider", @@ -468,18 +224,14 @@ private fun addClassBounds(source: Source) { "ItemDropInputMode", - "ISelectionModel", - "DefaultSelectionModel", - "ModelManager", // replace mode "SelectionIndicatorManager", "FocusIndicatorManager", "HighlightIndicatorManager", - - "ItemSelectionChangedEventArgs" - ).map { it.flatMap(TYPE_PARAMETERS).single() } + ).filter { it.has(TYPE_PARAMETERS) } + .map { it.flatMap(TYPE_PARAMETERS).single() } .forEach { it[BOUNDS] = arrayOf(IMODEL_ITEM) } source.type("ResultItemMapping") @@ -487,15 +239,14 @@ private fun addClassBounds(source: Source) { .first() .set(BOUNDS, arrayOf(JS_ANY)) - source.types("GraphModelManager", "WebGL2GraphModelManager") + source.types("GraphModelManager") .flatMap(METHODS) .filter { it[NAME] == "createHitTester" || it[NAME] == "typedHitElementsAt" } .flatMap(TYPE_PARAMETERS) .forEach { it[BOUNDS] = arrayOf(IMODEL_ITEM) } source.types( - "DelegateUndoUnit", - "ItemCopiedEventArgs" + "ItemCopiedEventArgs" ).map { it.flatMap(TYPE_PARAMETERS).single() } .forEach { it[BOUNDS] = arrayOf(JS_OBJECT) } @@ -504,14 +255,14 @@ private fun addClassBounds(source: Source) { "IObservableCollection", "ObservableCollection", - - "Future" ).map { it.flatMap(TYPE_PARAMETERS).single() } - .forEach { it[BOUNDS] = arrayOf(YOBJECT) } + .forEach { + it[BOUNDS] = emptyArray() + } source.type("ItemEventArgs") .flatMap(TYPE_PARAMETERS) - .single()[BOUNDS] = arrayOf("$YOBJECT?") + .single()[BOUNDS] = arrayOf("Any?") source.type("HoveredItemChangedEventArgs") { val validExtends = get(EXTENDS) @@ -527,118 +278,8 @@ private fun addClassBounds(source: Source) { .forEach { it[BOUNDS] = arrayOf(JS_OBJECT) } } -private fun addTypeParameterBounds(source: Source) { - source.types() - .filter { it.has(TYPE_PARAMETERS) } - .filter { it.has(CONSTRUCTORS) } - .forEach { - val boundMap = it.flatMap(CONSTRUCTORS) - .optFlatMap(PARAMETERS) - .mapNotNull { it.classBoundPair } - .toMap() - - if (boundMap.isNotEmpty()) { - it.flatMap(TYPE_PARAMETERS) - .filter { !it.has(BOUNDS) } - .forEach { - val bound = boundMap[it[NAME]] - if (bound != null) { - it[BOUNDS] = arrayOf(bound) - } - } - } - } - - source.types() - .optFlatMap(METHODS) - .filter { it.has(TYPE_PARAMETERS) } - .forEach { - val boundMap = it.flatMap(PARAMETERS) - .mapNotNull { it.classBoundPair } - .toMap() - - if (boundMap.isNotEmpty()) { - it.flatMap(TYPE_PARAMETERS) - .filter { !it.has(BOUNDS) } - .forEach { - val name = it[NAME] - val bound = boundMap.get(name) - if (bound != null) { - it[BOUNDS] = arrayOf(bound) - } - } - } - } - - source.types( - "IMapperRegistry", - "MapperRegistry" - ).flatMap(METHODS) - .filter { "Metadata" in it[NAME] } - .flatMap(TYPE_PARAMETERS) - .forEach { it[BOUNDS] = arrayOf(JS_OBJECT) } -} - -private val JSONObject.classBoundPair: Pair? - get() { - val type = get(TYPE) - if (type.startsWith("$YCLASS<")) { - val generic = type.between("$YCLASS<", ">") - if ("." in generic) { - return null - } - - val bound = when { - generic == "TInterface" -> YOBJECT - generic == "TContext" -> YOBJECT - generic == "TResult" -> YOBJECT - generic == "TModelItem" -> IMODEL_ITEM - generic == "TDecoratedType" -> IMODEL_ITEM - get(NAME) == "modelItemType" -> IMODEL_ITEM - else -> JS_OBJECT - } - - return generic to bound - } - - if ("DpKey<" in type) { - val generic = type.between("DpKey<", ">") - if ("." in generic) { - return null - } - - return generic to JS_OBJECT - } - - return null +private fun fixDisposeVisualCallback(source: Source) { + source.functionSignature("yfiles.view.DisposeVisualCallback")[TYPE_PARAMETERS].getJSONObject(0).also { + it[NAME] = "TVisual" } - -private fun addMapClassBounds(source: Source) { - source.types( - "MapEntry", - - "IMap", - "HashMap", - - "IMapper", - "Mapper" - ).map { it.flatMap(TYPE_PARAMETERS).first() } - .forEach { it[BOUNDS] = arrayOf(JS_OBJECT) } - - source.types() - .optFlatMap(METHODS) - .filter { it.has(TYPE_PARAMETERS) } - .map { it.flatMap(TYPE_PARAMETERS).first() } - .filterNot { it.has(BOUNDS) } - .filter { it[NAME] == "K" } - .forEach { it[BOUNDS] = arrayOf(JS_OBJECT) } - - source.types( - "IMapperRegistry", - "MapperRegistry" - ).flatMap(METHODS) - .filter { it[NAME] == "getMapper" } - .flatMap(TYPE_PARAMETERS) - .filter { it[NAME] == "V" } - .forEach { it[BOUNDS] = arrayOf(JS_OBJECT) } } diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ClipboardHelperHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ClipboardHelperHacks.kt index cdbc5d950..20f943563 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ClipboardHelperHacks.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ClipboardHelperHacks.kt @@ -40,7 +40,7 @@ internal fun applyClipboardHelperHacks(source: Source) { fixDecoratorProperties(source, ICLIPBOARD_HELPER, true) - source.type("GraphClipboard") + source.type("ClipboardOperationContext") .method("getClipboardHelper") .apply { setSingleTypeParameter(bound = IMODEL_ITEM) diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CollectionCorrections.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CollectionCorrections.kt new file mode 100644 index 000000000..35e592c58 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CollectionCorrections.kt @@ -0,0 +1,11 @@ +package com.github.turansky.yfiles.correction + +internal fun fixCollections(source: Source) { + fixConstantGenerics(source) +} + +private fun fixConstantGenerics(source: Source) { + source.type("IEnumerable") { + constant("EMPTY").replaceInType("", "<*>") + } +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CollectionHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CollectionHacks.kt deleted file mode 100644 index 8ce034373..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CollectionHacks.kt +++ /dev/null @@ -1,40 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.ICOLLECTION -import com.github.turansky.yfiles.JS_ANY -import com.github.turansky.yfiles.JS_OBJECT -import org.json.JSONObject - -private fun collection(generic: String): String = - "$ICOLLECTION<$generic>" - -private val DEFAULT_COLLECTIONS = setOf( - collection(JS_ANY), - collection(JS_OBJECT) -) - -internal fun applyCollectionHacks(source: Source) { - source.types( - "PathRequest", - "IEdgeData" - ).flatMap { - sequenceOf( - it.property("sourcePortCandidates"), - it.property("targetPortCandidates") - ) - }.forEach { it.fixTypeGeneric("yfiles.layout.PortCandidate") } - - source.type("PartitionGrid") - .flatMap(METHODS) - .single { it[ID] == "PartitionGrid-method-createCellSpanId(yfiles.collections.ICollection,yfiles.collections.ICollection)" } - .apply { - firstParameter.fixTypeGeneric("yfiles.layout.RowDescriptor") - secondParameter.fixTypeGeneric("yfiles.layout.ColumnDescriptor") - } -} - -private fun JSONObject.fixTypeGeneric(generic: String) { - require(get(TYPE) in DEFAULT_COLLECTIONS) - - set(TYPE, collection(generic)) -} diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CommandHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CommandHacks.kt deleted file mode 100644 index 4b226bf56..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CommandHacks.kt +++ /dev/null @@ -1,160 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.* - -private const val JS_NOTHING = "Nothing" - -private val COMMAND_ALIASES = setOf( - "yfiles.input.CanExecuteCommandHandler", - "yfiles.input.ExecuteCommandHandler" -) - -private const val ICOMMAND = "yfiles.input.ICommand" - -private val PARAMETER_MAP = mapOf( - "ADD_LABEL" to "yfiles.graph.ILabelOwner", - "ADJUST_GROUP_NODE_SIZE" to INODE, - "BEGIN_EDGE_CREATION" to "yfiles.input.IPortCandidate", - "CLOSE" to JS_NOTHING, - "COLLAPSE_GROUP" to INODE, - "COPY" to JS_NOTHING, - "CUT" to JS_NOTHING, - "DECREASE_ZOOM" to JS_DOUBLE, - "DELETE" to JS_NOTHING, - "DESELECT_ALL" to JS_NOTHING, - "DESELECT_ITEM" to IMODEL_ITEM, - "DUPLICATE" to JS_NOTHING, - "EDIT_LABEL" to ILABEL, - - "ENTER_GROUP" to INODE, - "EXIT_GROUP" to JS_NOTHING, - "EXPAND_GROUP" to INODE, - - "EXTEND_SELECTION_DOWN" to JS_NOTHING, - "EXTEND_SELECTION_LEFT" to JS_NOTHING, - "EXTEND_SELECTION_RIGHT" to JS_NOTHING, - "EXTEND_SELECTION_UP" to JS_NOTHING, - - "FIT_CONTENT" to JS_NOTHING, - "FIT_GRAPH_BOUNDS" to "yfiles.geometry.Insets", - "GROUP_SELECTION" to JS_NOTHING, - "HELP" to JS_NOTHING, - "INCREASE_ZOOM" to JS_DOUBLE, - "LOWER" to IMODEL_ITEM, - - "MOVE_DOWN" to JS_NOTHING, - "MOVE_FOCUS_BACK" to JS_NOTHING, - "MOVE_FOCUS_DOWN" to JS_NOTHING, - "MOVE_FOCUS_FORWARD" to JS_NOTHING, - "MOVE_FOCUS_PAGE_DOWN" to JS_NOTHING, - "MOVE_FOCUS_PAGE_UP" to JS_NOTHING, - "MOVE_FOCUS_UP" to JS_NOTHING, - "MOVE_LEFT" to JS_NOTHING, - "MOVE_RIGHT" to JS_NOTHING, - "MOVE_TO_PAGE_DOWN" to JS_NOTHING, - "MOVE_TO_PAGE_UP" to JS_NOTHING, - "MOVE_UP" to JS_NOTHING, - - "NEW" to JS_NOTHING, - "OPEN" to JS_NOTHING, - "PASTE" to "yfiles.geometry.IPoint", - "PRINT" to JS_NOTHING, - "PRINT_PREVIEW" to JS_NOTHING, - "PROPERTIES" to JS_NOTHING, - "RAISE" to IMODEL_ITEM, - "REDO" to JS_NOTHING, - "REVERSE_EDGE" to IEDGE, - "SAVE" to JS_NOTHING, - - "SCROLL_PAGE_DOWN" to JS_DOUBLE, - "SCROLL_PAGE_LEFT" to JS_DOUBLE, - "SCROLL_PAGE_RIGHT" to JS_DOUBLE, - "SCROLL_PAGE_UP" to JS_DOUBLE, - - "SELECT_ALL" to JS_NOTHING, - "SELECT_ITEM" to IMODEL_ITEM, - - "SELECT_TO_PAGE_DOWN" to JS_NOTHING, - "SELECT_TO_PAGE_UP" to JS_NOTHING, - - "SET_CURRENT_ITEM" to IMODEL_ITEM, - - "TOGGLE_EXPANSION_STATE" to INODE, - "TOGGLE_ITEM_SELECTION" to IMODEL_ITEM, - - "TO_BACK" to IMODEL_ITEM, - "TO_FRONT" to IMODEL_ITEM, - - "UNDO" to JS_NOTHING, - "UNGROUP_SELECTION" to JS_NOTHING, - "UPDATE_CONTENT_RECT" to "yfiles.geometry.Rect", - "ZOOM" to JS_ANY, - "ZOOM_TO_CURRENT_ITEM" to JS_NOTHING -) - -internal fun applyCommandHacks(source: Source) { - source.type("ICommand").apply { - setSingleTypeParameter(name = "in T", bound = JS_ANY) - - flatMap(METHODS) - .optFlatMap(PARAMETERS) - .filter { it[NAME] == "parameter" } - .forEach { it[TYPE] = "T" } - - flatMap(CONSTANTS) - .forEach { it.addGeneric(PARAMETER_MAP.getValue(it[NAME])) } - - method("createCommand")[RETURNS].addGeneric("*") - } - - COMMAND_ALIASES - .map { source.functionSignature(it) } - .forEach { - it.setSingleTypeParameter(bound = JS_OBJECT) - - it.parameter("command").addGeneric("T") - it.parameter("parameter").also { - it[TYPE] = "T" - it[MODIFIERS] = arrayOf(CANBENULL) - } - } - - source.type("KeyboardInputMode") - .flatMap(METHODS) - .filter { it[NAME].startsWith("add") } - .onEach { it.setSingleTypeParameter(bound = JS_ANY) } - .flatMap(PARAMETERS) - .forEach { - when { - it[TYPE] == ICOMMAND -> it.addGeneric("T") - it.opt(SIGNATURE) in COMMAND_ALIASES -> it[SIGNATURE] = it[SIGNATURE] + "" - it[NAME] in "commandParameter" -> it[TYPE] = "T" - } - } - - source.type("KeyboardInputMode") - .method("removeCommand") - .parameter("command") - .addGeneric("*") - - source.type("KeyboardInputModeBinding") - .property("command") - .addGeneric("*") - - source.types( - "GraphInputMode", - "NavigationInputMode", - "OverviewInputMode" - ).map { it.property("availableCommands") } - .forEach { it.replaceInType(">", "<*>>") } - - source.types( - "GraphInputMode", - "OverviewInputMode", - "TableEditorInputMode" - ).forEach { - it.method("shouldInstallCommand") - .firstParameter - .addGeneric("*") - } -} diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ComparableHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ComparableHacks.kt index 85207ac25..c094b8a7b 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ComparableHacks.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ComparableHacks.kt @@ -10,14 +10,12 @@ internal fun applyComparableHacks(source: Source) { } source.types( - "ColumnDescriptor", - "PartitionCellIdEntry", - "RowDescriptor", + "LayoutGridCell", + "LayoutGridColumn", + "LayoutGridRow", "SnapResult", - "SwimlaneDescriptor", "TimeSpan", - "YDimension", - "YPoint" + "Point" ) .forEach { val id = it[ID] @@ -30,16 +28,6 @@ internal fun applyComparableHacks(source: Source) { it.configureCompareTo(id) } - - source.types( - "IComparer", - "DefaultOutEdgeComparer", - "NodeOrderComparer", - "NodeWeightComparer" - ).flatMap(METHODS) - .filter { it[NAME] == "compare" } - .flatMap(PARAMETERS) - .forEach { it.changeNullability(false) } } private fun JSONObject.configureCompareTo(type: String) { diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ComparerHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ComparerHacks.kt deleted file mode 100644 index 84bff368f..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ComparerHacks.kt +++ /dev/null @@ -1,198 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.* -import com.github.turansky.yfiles.json.get -import org.json.JSONObject - -private val DEFAULT_COMPARERS = setOf( - comparer(JS_ANY), - comparer(JS_OBJECT) -) - -private fun comparer(generic: String): String = - "$ICOMPARER<$generic>" - -internal fun applyComparerHacks(source: Source) { - fixComparerInheritors(source) - fixComparerUtilMethods(source) - fixComparerAsMethodParameter(source) - fixComparerAsProperty(source) - fixReturnType(source) -} - -private fun fixComparerInheritors(source: Source) { - sequenceOf( - "DefaultOutEdgeComparer" to EDGE, - "NodeOrderComparer" to NODE, - "NodeWeightComparer" to NODE - ).forEach { (className, generic) -> - source.type(className) { - get(IMPLEMENTS).apply { - require(length() == 1) - require(get(0) in DEFAULT_COMPARERS) - - put(0, comparer(generic)) - } - - method("compare") - .flatMap(PARAMETERS) - .forEach { it[TYPE] = generic } - } - } -} - -private fun fixComparerUtilMethods(source: Source) { - val staticMethods = source.type("Comparers") - .get(METHODS) - - sequenceOf( - "createIntDataComparer" to GRAPH_OBJECT, - "createNumberDataComparer" to GRAPH_OBJECT, - - "createIntDataSourceComparer" to EDGE, - "createIntDataTargetComparer" to EDGE, - "createNumberDataSourceComparer" to EDGE, - "createNumberDataTargetComparer" to EDGE - ).forEach { (methodName, generic) -> - staticMethods[methodName] - .fixReturnTypeGeneric(generic) - } -} - -private fun fixComparerAsMethodParameter(source: Source) { - source.types( - "Graph", - "YNode", - - "PortCandidateOptimizer", - "PortConstraintOptimizerBase", - - "AssistantNodePlacer", - "ChannelBasedPathRouting", - "GivenSequenceSequencer", - "MultiComponentLayerer", - - "SwimlaneDescriptor" - ).flatMap { it.flatMap(METHODS) + it.optFlatMap(CONSTRUCTORS) } - .forEach { - val methodName = it[NAME] - - it.optFlatMap(PARAMETERS) - .filter { it[TYPE] in DEFAULT_COMPARERS } - .forEach { - val generic = getGeneric(methodName, it[NAME]) - it.fixTypeGeneric("in $generic") - } - } -} - -private fun getGeneric( - methodName: String, - parameterName: String, -): String { - when (methodName) { - "sortNodes", - "GivenSequenceSequencer", - "MultiComponentLayerer", - -> return NODE - - "sortEdges", "sortInEdges", "sortOutEdges", - "createCompoundComparer", - -> return EDGE - - "SwimlaneDescriptor" -> return SWIMLANE_DESCRIPTOR - } - - return when (parameterName) { - "inEdgeOrder", "outEdgeOrder" -> EDGE - "segmentInfoComparer" -> SEGMENT_INFO - else -> throw IllegalStateException("No generic found!") - } -} - -private fun fixComparerAsProperty(source: Source) { - sequenceOf( - Triple("TabularLayout", "nodeComparer", NODE), - Triple("TreeMapLayout", "nodeComparer", NODE), - Triple("GivenSequenceSequencer", "sequenceComparer", NODE), - Triple("MultiComponentLayerer", "componentComparer", NODE), - - Triple("EdgeRouter", "edgeComparer", EDGE), - Triple("SeriesParallelLayout", "defaultOutEdgeComparer", EDGE), - Triple("TreeLayout", "defaultOutEdgeComparer", EDGE), - - Triple("AspectRatioTreeLayout", "comparer", EDGE), - Triple("BalloonLayout", "comparer", EDGE), - Triple("ClassicTreeLayout", "comparer", EDGE), - - Triple("SwimlaneDescriptor", "comparer", SWIMLANE_DESCRIPTOR) - ).forEach { (className, propertyName, generic) -> - source.type(className) - .property(propertyName) - .fixTypeGeneric("in $generic") - } - - source.types( - "TreeLayout", - "SeriesParallelLayout" - ).forEach { - it.constant("OUT_EDGE_COMPARER_DP_KEY").apply { - require(get(TYPE) == nodeDpKey(comparer(JS_ANY))) - - set(TYPE, nodeDpKey(comparer("in $EDGE"))) - } - } -} - -private fun fixReturnType(source: Source) { - source.types( - "IFromSketchNodePlacer", - "AspectRatioNodePlacer", - "DefaultNodePlacer", - "DendrogramNodePlacer", - "GridNodePlacer", - "RotatableNodePlacerBase" - ).forEach { - it.method("createFromSketchComparer") - .fixReturnTypeGeneric(NODE) - } - - source.types( - "RotatableNodePlacerBase", - "AssistantNodePlacer", - "BusNodePlacer", - "LeftRightNodePlacer", - "DefaultNodePlacer", - "DendrogramNodePlacer" - ).forEach { - it.method("createComparer") - .fixReturnTypeGeneric(EDGE) - } - - source.type("AssistantNodePlacer") - .method("createCompoundComparer") - .fixReturnTypeGeneric(EDGE) - - source.method("EdgeRouter", "createDefaultEdgeOrderComparer") - .fixReturnTypeGeneric(EDGE) - - source.method("TreeLayout", "getOutEdgeComparer") - .fixReturnTypeGeneric(EDGE) - - source.method("ChannelBasedPathRouting", "createSegmentInfoComparer") - .fixReturnTypeGeneric(SEGMENT_INFO) -} - -private fun Source.method(className: String, methodName: String) = - type(className).method(methodName) - -private fun JSONObject.fixReturnTypeGeneric(generic: String) { - get(RETURNS) - .fixTypeGeneric(generic) -} - -private fun JSONObject.fixTypeGeneric(generic: String) { - require(get(TYPE) in DEFAULT_COMPARERS) - - set(TYPE, comparer(generic)) -} diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ConstructorHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ConstructorHacks.kt index ab7b96bc7..2718fb16e 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ConstructorHacks.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ConstructorHacks.kt @@ -27,11 +27,8 @@ private fun fixOptionality(source: Source) { } source.types( - "BendConverter", "MinimumNodeSizeStage", "MultiPageLayout", - "OrganicPartitionGridLayoutStage", - "TreeComponentLayout" ).flatMap(CONSTRUCTORS) .filter { it.has(PARAMETERS) } .filter { it[PARAMETERS].length() == 1 } diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ContextLookupHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ContextLookupHacks.kt index 181faa7d8..c3529772f 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ContextLookupHacks.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ContextLookupHacks.kt @@ -1,29 +1,58 @@ package com.github.turansky.yfiles.correction -import com.github.turansky.yfiles.JS_VOID -import com.github.turansky.yfiles.YOBJECT import com.github.turansky.yfiles.json.get -private const val ICONTEXT_LOOKUP = "yfiles.graph.IContextLookup" -private const val ICONTEXT_LOOKUP_CHAIN_LINK = "yfiles.graph.IContextLookupChainLink" +private const val ICONTEXT_LOOKUP = "yfiles.collections.IContextLookup" +private const val ICONTEXT_LOOKUP_CHAIN_LINK = "yfiles.collections.IContextLookupChainLink" private const val T_ITEM = "TItem" -private const val T_ITEM_BOUND = YOBJECT +private const val T_DECORATED_TYPE = "TDecoratedType" -private const val LOOKUP_CALLBACK = "yfiles.graph.LookupCallback" internal fun applyContextLookupHacks(source: Source) { + source.types() + .optFlatMap(CONSTANTS) + .filter { it[TYPE] == ICONTEXT_LOOKUP } + .forEach { it[TYPE] = "$ICONTEXT_LOOKUP<*>" } + + val lookupMethods = setOf("addGenericLookup", "addLookup", "removeLookup", "addGenericInputModeContextLookup") + source.types() + .optFlatMap(METHODS) + .filter { it[NAME] in lookupMethods } + .forEach { method -> + + if (method[NAME] == "addGenericLookup" || method[NAME] == "addGenericInputModeContextLookup") { + method.firstParameter + .also { + it[TYPE] = it[TYPE].replace(ICONTEXT_LOOKUP, "$ICONTEXT_LOOKUP<*>") + it[SIGNATURE] = it[SIGNATURE].replace(ICONTEXT_LOOKUP, "$ICONTEXT_LOOKUP<*>") + } + + method[RETURNS] + .also { + it[TYPE] = it[TYPE].replace(ICONTEXT_LOOKUP_CHAIN_LINK, "$ICONTEXT_LOOKUP_CHAIN_LINK<*>") + } + } + + method.flatMap(PARAMETERS) + .filter { it[TYPE] == ICONTEXT_LOOKUP } + .forEach { it[TYPE] = "$ICONTEXT_LOOKUP<*>" } + + method.flatMap(PARAMETERS) + .filter { it[TYPE] == ICONTEXT_LOOKUP_CHAIN_LINK } + .forEach { it[TYPE] = "$ICONTEXT_LOOKUP_CHAIN_LINK<*>" } + } + source.type("IContextLookup") { - setSingleTypeParameter("in $T_ITEM", T_ITEM_BOUND) + setSingleTypeParameter("in $T_ITEM") method("contextLookup") .parameter("item")[TYPE] = T_ITEM - get(CONSTANTS)["EMPTY_CONTEXT_LOOKUP"] - .addGeneric("*") + method("create")[RETURNS].addGeneric(T_ITEM) } - source.types("DefaultGraph", "Table") + source.types("Table") .flatMap(CONSTANTS) .filter { it[TYPE] == ICONTEXT_LOOKUP } .filter { it[NAME].let { it.startsWith("DEFAULT_") && it.endsWith("_LOOKUP") } } @@ -38,71 +67,8 @@ internal fun applyContextLookupHacks(source: Source) { it.addGeneric(typeParameter) } - source.types( - "TemplateLabelStyleBase", - "TemplateNodeStyleBase", - "TemplatePortStyleBase", - "TemplateStripeStyleBase" - ).forEach { - val typeParameter = it[NAME] - .removePrefix("Template") - .removeSuffix("StyleBase") - .let { "yfiles.graph.I$it" } - - it.property("contextLookup") - .addGeneric(typeParameter) - } - - source.types( - "TemplateNodeStyleRenderer", - "TemplateStripeStyleRenderer" - ).forEach { - val typeParameter = it[NAME] - .removePrefix("Template") - .removeSuffix("StyleRenderer") - .let { "yfiles.graph.I$it" } - - it.method("getContextLookup") - .get(RETURNS) - .addGeneric(typeParameter) - } - - source.type("LookupChain") { - setSingleTypeParameter(T_ITEM, T_ITEM_BOUND) - - get(IMPLEMENTS).also { - it.put(0, it.getString(0) + "<$T_ITEM>") - } - - method("contextLookup") - .parameter("item")[TYPE] = T_ITEM - - flatMap(METHODS) - .flatMap { it.optFlatMap(PARAMETERS) + it.returnsSequence() } - .filter { it[TYPE] == ICONTEXT_LOOKUP_CHAIN_LINK } - .forEach { it[TYPE] = "$ICONTEXT_LOOKUP_CHAIN_LINK<$T_ITEM>" } - } - - source.type("CanvasComponent") - .property("inputModeContextLookupChain") - .addGeneric("CanvasComponent") - - source.functionSignature(LOOKUP_CALLBACK).apply { - setSingleTypeParameter() - - firstParameter[TYPE] = "T" - get(RETURNS)[TYPE] = YOBJECT - } - - source.type("IInputModeContext") - .flatMap(METHODS) - .filter { it[NAME] == "createInputModeContext" } - .flatMap(PARAMETERS) - .filter { it.opt(SIGNATURE) == LOOKUP_CALLBACK } - .forEach { it[SIGNATURE] = "$LOOKUP_CALLBACK<$JS_VOID>" } - source.type("IContextLookupChainLink") { - setSingleTypeParameter(T_ITEM, T_ITEM_BOUND) + setSingleTypeParameter(T_ITEM) get(IMPLEMENTS).also { it.put(0, it.getString(0) + "<$T_ITEM>") @@ -112,13 +78,6 @@ internal fun applyContextLookupHacks(source: Source) { .parameter("next") .addGeneric(T_ITEM) - method("createContextLookupChainLink").apply { - setSingleTypeParameter(bound = YOBJECT) - - firstParameter.also { it[SIGNATURE] = it[SIGNATURE] + "" } - get(RETURNS).also { it[TYPE] = it[TYPE] + "" } - } - flatMap(METHODS) .mapNotNull { it.opt(RETURNS) } .filter { it[TYPE] == ICONTEXT_LOOKUP_CHAIN_LINK } @@ -142,30 +101,43 @@ internal fun applyContextLookupHacks(source: Source) { it.method("remove") .firstParameter .also { it[TYPE] = it[TYPE] + "<${typeParameter}>" } + it.method("add") + .firstParameter + .also { it[TYPE] = it[TYPE] + "<${typeParameter}>" } } source.type("LookupDecorator") .flatMap(METHODS) .flatMap { it.flatMap(PARAMETERS) + it[RETURNS] } .filter { it[TYPE] == ICONTEXT_LOOKUP_CHAIN_LINK } - .forEach { it[TYPE] = "$ICONTEXT_LOOKUP_CHAIN_LINK" } + .forEach { it[TYPE] = "$ICONTEXT_LOOKUP_CHAIN_LINK<$T_DECORATED_TYPE>" } + + source.type("ILookupDecorator") + .flatMap(METHODS) + .optFlatMap(PARAMETERS) + .filter { it[TYPE] == ICONTEXT_LOOKUP_CHAIN_LINK } + .forEach { it[TYPE] = "$ICONTEXT_LOOKUP_CHAIN_LINK<*>" } + + source.type("ContextLookup").apply { + set(IMPLEMENTS, arrayOf("yfiles.collections.IContextLookup<$T_DECORATED_TYPE>")) + + method("contextLookup") + .parameter("item")[TYPE] = T_DECORATED_TYPE - source.type("ILookupDecorator").apply { sequenceOf("addLookup", "removeLookup") .map { method(it) } - .onEach { it.setSingleTypeParameter(bound = YOBJECT) } - .flatMap(PARAMETERS) - .forEach { it[TYPE] = it[TYPE] + "" } + .flatMap { it.flatMap(PARAMETERS) } + .filter { it[TYPE] == "$ICONTEXT_LOOKUP<*>" } + .forEach { it[TYPE] = "$ICONTEXT_LOOKUP<$T_DECORATED_TYPE>" } + sequenceOf("addLookup", "removeLookup") + .map { method(it) } + .flatMap { it.flatMap(PARAMETERS) } + .filter { it[TYPE] == "$ICONTEXT_LOOKUP_CHAIN_LINK<*>" } + .forEach { it[TYPE] = "$ICONTEXT_LOOKUP_CHAIN_LINK<$T_DECORATED_TYPE>" } flatMap(METHODS) .mapNotNull { it.opt(RETURNS) } .filter { it[TYPE] == ICONTEXT_LOOKUP_CHAIN_LINK } - .forEach { it[TYPE] = "$ICONTEXT_LOOKUP_CHAIN_LINK<*>" } + .forEach { it[TYPE] = "$ICONTEXT_LOOKUP_CHAIN_LINK<$T_DECORATED_TYPE>" } } - - source.type("DefaultGraph") - .flatMap(METHODS) - .optFlatMap(PARAMETERS) - .filter { it[TYPE] == ICONTEXT_LOOKUP_CHAIN_LINK } - .forEach { it[TYPE] = "$ICONTEXT_LOOKUP_CHAIN_LINK" } } diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ContextMenuHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ContextMenuHacks.kt new file mode 100644 index 000000000..12df403b5 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ContextMenuHacks.kt @@ -0,0 +1,10 @@ +package com.github.turansky.yfiles.correction + +import com.github.turansky.yfiles.JS_ANY + +internal fun applyContextMenuFixes(source: Source) { + source.types("PopulateContextMenuEventArgs") + .optFlatMap(PROPERTIES) + .filter { it[TYPE] == "ContextMenuContent" } + .forEach { it[TYPE] = JS_ANY } +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ConvertersHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ConvertersHacks.kt deleted file mode 100644 index de277649f..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ConvertersHacks.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.* - -private const val CONVERTERS = "yfiles.styles.Converters" - -internal fun generateConvertersUtils(context: GeneratorContext) { - // language=kotlin - context[CONVERTERS] = - """ - @JsName("Object") - external class Converters - private constructor() - - inline operator fun Converters.invoke( - block: Converters.() -> Unit - ): Converters = - apply(block) - - fun Converters.put( - name: String, - converter: (value: V) -> R - ): Converters { - $AS_DYNAMIC[name] = converter - return this - } - - fun Converters.put( - name: String, - converter: (value: V, parameter: P) -> R - ): Converters { - $AS_DYNAMIC[name] = converter - return this - } - """.trimIndent() -} - -internal fun applyConvertersHacks(source: Source) { - val likeObjectTypes = setOf( - JS_OBJECT, - JS_ANY - ) - - source.type(TEMPLATES_NAME) - .flatMap(CONSTANTS) - .first { it[NAME] == "CONVERTERS" } - .also { check(it[TYPE] in likeObjectTypes) } - .set(TYPE, CONVERTERS) -} diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ConvertibleHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ConvertibleHacks.kt new file mode 100644 index 000000000..7a923f67c --- /dev/null +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ConvertibleHacks.kt @@ -0,0 +1,18 @@ +package com.github.turansky.yfiles.correction + +private val CONVERTIBLE_REGEX = Regex("(\\w+)Convertible") + +internal fun fixConvertibles(source: Source) { + source.types() + .optFlatMap(METHODS) + .optFlatMap(PARAMETERS) + .filter { it.has(TYPE) && "Convertible" in it[TYPE] } + .forEach { + var type = it[TYPE] + generateSequence { CONVERTIBLE_REGEX.find(type) } + .forEach { match -> + type = type.replace(match.value, source.type(match.groupValues[1])[ID]) + } + it[TYPE] = type + } +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CreationPropertiesHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CreationPropertiesHacks.kt new file mode 100644 index 000000000..d1f732409 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CreationPropertiesHacks.kt @@ -0,0 +1,10 @@ +package com.github.turansky.yfiles.correction + +import com.github.turansky.yfiles.FINAL + +internal fun applyCreationPropertiesHacks(source: Source) { + source.type("CreationProperties") + .flatMap(METHODS) + .filter { !it[MODIFIERS].contains(FINAL) } + .forEach { it[MODIFIERS].put(FINAL) } +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CursorHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CursorHacks.kt index db2ebcae9..3bd125d94 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CursorHacks.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/CursorHacks.kt @@ -9,76 +9,20 @@ private fun cursor(generic: String): String = internal fun applyCursorHacks(source: Source) { fixCursor(source) - fixCursorUtil(source) fixMethodParameter(source) - fixReturnType(source) } private fun fixCursor(source: Source) { source.type("ICursor") .fixGeneric() - - sequenceOf( - "IEdgeCursor" to EDGE, - "ILineSegmentCursor" to "yfiles.algorithms.LineSegment", - "INodeCursor" to NODE, - "IPointCursor" to YPOINT - ).forEach { (className, generic) -> - source.type(className) { - get(IMPLEMENTS).apply { - put(0, getString(0) + "<$generic>") - } - - val duplicatedPropertyName = className - .removePrefix("I") - .removeSuffix("Cursor") - .replaceFirstChar { it.lowercase() } - - get(PROPERTIES).removeAllObjects { - it[NAME] == duplicatedPropertyName - } - } - } } private fun JSONObject.fixGeneric() { - setSingleTypeParameter("out T", YOBJECT) + setSingleTypeParameter("out T") property("current")[TYPE] = "T" } -private fun fixCursorUtil(source: Source) { - source.type("Cursors").apply { - flatMap(METHODS) - .onEach { - val bound = when (it[NAME]) { - "createNodeCursor" -> NODE - "createEdgeCursor" -> EDGE - else -> YOBJECT - } - - it.setSingleTypeParameter(bound = bound) - } - .forEach { - it.flatMap(PARAMETERS) - .plus(it[RETURNS]) - .filter { it[TYPE] == ICURSOR } - .forEach { it[TYPE] = cursor("T") } - } - - method("toArray").apply { - sequenceOf(secondParameter, get(RETURNS)) - .forEach { - it.replaceInType("<$JS_ANY>", "") - it.replaceInType("<$JS_OBJECT>", "") - } - - secondParameter[MODIFIERS] - .put(OPTIONAL) - } - } -} - private fun fixMethodParameter(source: Source) { val nodeParameterNames = setOf( "subNodes", @@ -88,37 +32,10 @@ private fun fixMethodParameter(source: Source) { source.types( "Graph", "LayoutGraph", - "DefaultLayoutGraph" ).flatMap(CONSTRUCTORS) .optFlatMap(PARAMETERS) .filter { it[NAME] in nodeParameterNames } .forEach { it.fixTypeGeneric(NODE) } - - source.types( - "GraphPartitionManager", - "LayoutGraphHider" - ).map { it.method("hideItemCursor") } - .map { it.firstParameter } - .forEach { it.fixTypeGeneric(GRAPH_OBJECT) } -} - -private fun fixReturnType(source: Source) { - source.type("YPointPath") - .method("cursor") - .fixReturnTypeGeneric(YPOINT) - - source.type("PathAlgorithm") - .method("findAllPathsCursor") - .fixReturnTypeGeneric(EDGE_LIST) - - source.type("ShortestPathAlgorithm") - .method("kShortestPathsCursor") - .fixReturnTypeGeneric(EDGE_LIST) -} - -private fun JSONObject.fixReturnTypeGeneric(generic: String) { - get(RETURNS) - .fixTypeGeneric(generic) } private fun JSONObject.fixTypeGeneric(generic: String) { diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/DataHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/DataHacks.kt deleted file mode 100644 index ccccc8422..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/DataHacks.kt +++ /dev/null @@ -1,301 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.* -import com.github.turansky.yfiles.json.get -import org.json.JSONObject - -internal fun applyDataHacks(source: Source) { - fixDataProvider(source) - fixDataAcceptor(source) - fixDataMap(source) - fixDataMaps(source) - - fixMethodTypes(source) -} - -private val MAP_INTERFACES = setOf( - IEDGE_MAP, - INODE_MAP -) - -private val DATA_PROVIDER_TYPE_MAP = mapOf( - "IDataMap" to "K,V", - "IEdgeMap" to "$EDGE,V", - "INodeMap" to "$NODE,V", - - "DataProviderBase" to "K,V", - "MapperDataProviderAdapter" to "TKey,TValue" -) - -private val DATA_ACCEPTOR_TYPE_MAP = mapOf( - "IDataMap" to "K,V", - "IEdgeMap" to "$EDGE,V", - "INodeMap" to "$NODE,V" -) - -private val DATA_MAP_TYPE_MAP = mapOf( - "IEdgeMap" to "$EDGE,V", - "INodeMap" to "$NODE,V", - - "DataMapAdapter" to "K,V" -) - -private fun fixDataProvider(source: Source) { - source.type(IDATA_PROVIDER.substringAfterLast(".")) - .setKeyValueTypeParameters("in K", "out V", YOBJECT) - - source.types() - .flatMap { it.getTypeHolders() } - .filter { it[TYPE] == IDATA_PROVIDER } - .forEach { it[TYPE] = "$IDATA_PROVIDER<${it.getDataProviderTypeParameters()}>" } - - source.type("DataProviderBase") - .setKeyValueTypeParameters("in K", "out V", YOBJECT) - - source.type("MapperDataProviderAdapter") - .setKeyValueTypeParameters("in TKey", "out TValue", YOBJECT) - - source.type("DataMapAdapter") - .get(TYPE_PARAMETERS).getJSONObject(0)[BOUNDS] = arrayOf(YOBJECT) - - for ((className, typeParameters) in DATA_PROVIDER_TYPE_MAP) { - source.type(className) - .get(IMPLEMENTS) - .apply { put(indexOf(IDATA_PROVIDER), "$IDATA_PROVIDER<$typeParameters>") } - } -} - -private fun JSONObject.getDataProviderTypeParameters(): String { - val name = opt(NAME) - return if (!has(DP_DATA) && name == "subtreeShapeProvider" || name == "nodeShapeProvider") { - "$NODE,yfiles.tree.SubtreeShape" - } else { - getDefaultTypeParameters() - } -} - -private fun fixDataAcceptor(source: Source) { - source.type(IDATA_ACCEPTOR.substringAfterLast(".")) - .setKeyValueTypeParameters("in K", "in V", YOBJECT) - - source.types() - .flatMap { it.getTypeHolders() } - .filter { it[TYPE] == IDATA_ACCEPTOR } - .forEach { it[TYPE] = "$IDATA_ACCEPTOR<${it.getDefaultTypeParameters()}>" } - - for ((className, typeParameters) in DATA_ACCEPTOR_TYPE_MAP) { - source.type(className) - .get(IMPLEMENTS) - .apply { put(indexOf(IDATA_ACCEPTOR), "$IDATA_ACCEPTOR<$typeParameters>") } - } -} - -private fun fixDataMap(source: Source) { - source.type(IDATA_MAP.substringAfterLast(".")) - .setKeyValueTypeParameters("in K", "V", YOBJECT) - - source.types() - .flatMap { it.getTypeHolders() } - .filter { it[TYPE] == IDATA_MAP } - .forEach { it[TYPE] = "$IDATA_MAP<${it.getDataMapTypeParameters()}>" } - - for ((className, typeParameters) in DATA_MAP_TYPE_MAP) { - source.type(className) - .get(IMPLEMENTS) - .apply { put(indexOf(IDATA_MAP), "$IDATA_MAP<$typeParameters>") } - } -} - -private fun JSONObject.getDataMapTypeParameters(): String = - if (!has(DP_DATA) && opt(NAME) == "connectorMap") { - "$NODE,yfiles.tree.ParentConnectorDirection" - } else { - getDefaultTypeParameters() - } - -private fun JSONObject.getDefaultTypeParameters(): String { - if (!has(DP_DATA)) { - return "*,*" - } - - val name = get(NAME) - return get(DP_DATA) - .run { - val keyType = getDefaultTypeParameter(name, get(DOMAIN)[TYPE]) - val valueType = getDefaultTypeParameter(name, get(VALUES)[TYPE]) - - "$keyType,$valueType" - } -} - -private fun getDefaultTypeParameter(name: String, type: String): String = - when (type) { - JS_BOOLEAN -> type - JS_NUMBER -> getDefaultNumberTypeParameter(name) - JS_OBJECT -> getDefaultObjectTypeParameter(name) - - "$ICOMPARER" -> "$ICOMPARER<*>" - - else -> type - } - -private fun getDefaultObjectTypeParameter(name: String): String = - when (name) { - "busIDAcceptor", - "partitionIDDP", - -> YID - - "nodeType", - -> INODE_TYPE - - else -> "*" - } - -private fun getDefaultNumberTypeParameter(name: String): String = - when (name) { - "connectorMap" -> "yfiles.tree.ParentConnectorDirection" - "edgeDirectedness" -> EDGE_DIRECTEDNESS - - "eCapDP", - "edgeLength", - "keys", - "layerId", - "lCapDP", - "minLength", - "normalizedLayerId", - "uCapDP", - "w", - "weight", - "initialLabel", - "communityIndex", - -> INT - - "cost", - "cost0DP", - "costDP", - "edgeCost", - "edgeCosts", - "edgeWeights", - "nodeWeight", - "edgeWeight", - "heuristicCost", - "supplyDP", - "initialPageRank", - -> DOUBLE - - else -> throw IllegalArgumentException("No type parameter for data map: $name") - } - -private fun fixDataMaps(source: Source) { - MAP_INTERFACES.forEach { - source.type(it.substringAfterLast(".")) - .setSingleTypeParameter("V", JS_OBJECT) - } - - source.types() - .flatMap { it.getTypeHolders() } - .filter { it[TYPE] in MAP_INTERFACES } - .forEach { it.addGeneric(it.getDataMapsTypeParameter()) } - - source.type("Graph") - .flatMap(PROPERTIES) - .forEach { property -> - val type = property[TYPE] - MAP_INTERFACES.find { it in type } - ?.also { property[TYPE] = type.replace(it, "$it<*>") } - } -} - -private fun JSONObject.getDataMapsTypeParameter(): String { - if (!has(DP_DATA)) { - return "*" - } - - return when (val type = get(DP_DATA)[VALUES][TYPE]) { - JS_NUMBER -> getDataMapsNumberTypeParameter(get(NAME)) - JS_OBJECT -> when (get(NAME)) { - "partitionIDMap" -> YID - "markMap" -> BIPARTITION_MARK - else -> type - } - else -> type - } -} - -private fun getDataMapsNumberTypeParameter(name: String): String = - when (name) { - "clusterIDs", - "compNum", - "compNumber", - "dualsNM", - "flowEM", - "groupIDs", - "intWeight", - "layer", - "layerID", - "layerIDMap", - "minLength", - "rank", - "result", - "subtreeDepthMap", - "subtreeSizeMap", - "kValue", - "finalLabel", - "communityIndex", - -> INT - - "centrality", - "closeness", - "dist", - "edgeCentrality", - "map", - "maxDist", - "nodeCentrality", - "centralityMap", - "pageRank", - "coefficientMap", - -> DOUBLE - - else -> throw IllegalArgumentException("No type parameter for data map: $name") - } - -private fun fixMethodTypes(source: Source) { - source.types( - "IDataProvider", - "IDataAcceptor", - - "DataProviderBase", - "DataMapAdapter", - - "MapperDataProviderAdapter" - ).forEach { - val keyTypeParameter = it.getTypeParameterName(0) - val valueTypeParameter = it.getTypeParameterName(1) - - it.flatMap(METHODS) - .forEach { - when (it[NAME]) { - "get" -> it[RETURNS][TYPE] = valueTypeParameter - - "set" -> it[PARAMETERS]["value"] - .set(TYPE, valueTypeParameter) - } - - it.flatMap(PARAMETERS) - .filter { it[NAME] == "dataHolder" } - .forEach { it[TYPE] = keyTypeParameter } - } - } -} - -private fun JSONObject.getTypeParameterName(index: Int): String = - get(TYPE_PARAMETERS) - .getJSONObject(index)[NAME] - .removePrefix("in ") - .removePrefix("out ") - -private fun JSONObject.getTypeHolders(): Sequence = - (optFlatMap(CONSTRUCTORS) + optFlatMap(METHODS)) - .flatMap { it.optFlatMap(PARAMETERS) + it.returnsSequence() } - .plus(optFlatMap(PROPERTIES)) - diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/DpKeyHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/DpKeyHacks.kt deleted file mode 100644 index 8949fca87..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/DpKeyHacks.kt +++ /dev/null @@ -1,247 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.* -import com.github.turansky.yfiles.ContentMode.DELEGATE -import org.json.JSONObject - -internal fun generateDpKeyDelegates(context: GeneratorContext) { - // language=kotlin - context[DP_KEY_BASE, DELEGATE] = """ - import yfiles.lang.findClass - import yfiles.lang.yclass - - private fun $KCLASS.toValueType(): $YCLASS = - when (this) { - $BOOLEAN::class -> $BOOLEAN.yclass - $STRING::class -> $STRING.yclass - - $INT::class -> $INT.yclass - - Number::class, - Float::class, - $DOUBLE::class -> $DOUBLE.yclass - - else -> js.findClass() ?: $YOBJECT.yclass - }.unsafeCast<$YCLASS>() - - fun , V: Any> dpKeyDelegate( - createKey: ($YCLASS, $YCLASS<*>, String) -> T, - valueType: $YCLASS, - declaringType: $YCLASS - ): $READ_ONLY_PROPERTY = - NamedDelegate { name -> - createKey(valueType, declaringType, name) - } - - fun , V: Any> dpKeyDelegate( - createKey: ($YCLASS, $YCLASS<*>, String) -> T, - valueClass: $KCLASS, - declaringType: $YCLASS - ): $READ_ONLY_PROPERTY = - dpKeyDelegate(createKey, valueClass.toValueType(), declaringType) - - private class NamedDelegate( - private val create: (String) -> T - ): $READ_ONLY_PROPERTY { - private lateinit var value: T - - override fun getValue( - thisRef: Any?, - property: $KPROPERTY<*> - ): T { - if (!::value.isInitialized) { - value = create(property.name) - } - - return value - } - } - """.trimIndent() - - for ((className, declaringClass) in DP_KEY_GENERIC_MAP) { - if (className == DP_KEY_BASE_CLASS) { - continue - } - - val classId = "yfiles.algorithms.$className" - val delegateName = className.removePrefix("I").replaceFirstChar { it.lowercase() } - - // language=kotlin - context[classId, DELEGATE] = """ - inline fun $delegateName(): $READ_ONLY_PROPERTY> = - $delegateName($declaringClass.yclass) - - inline fun $delegateName( - declaringType: $YCLASS - ): $READ_ONLY_PROPERTY> = - dpKeyDelegate(::$className, T::class, declaringType) - - inline fun $delegateName( - valueType: $INTERFACE_METADATA - ): $READ_ONLY_PROPERTY> = - $delegateName(valueType, $declaringClass.yclass) - - inline fun $delegateName( - valueType: $INTERFACE_METADATA, - declaringType: $YCLASS - ): $READ_ONLY_PROPERTY> = - dpKeyDelegate(::$className, valueType.yclass, declaringType) - """.trimIndent() - } -} - -internal fun applyDpKeyHacks(source: Source) { - fixClass(source) - fixProperties(source) - fixMethodParameters(source) -} - -private const val DP_KEY_BASE_CLASS = "DpKeyBase" -private const val DP_KEY_BASE_KEY = "TKey" - -private const val DP_KEY_BASE_DECLARATION = "$DP_KEY_BASE<" - -private val DP_KEY_GENERIC_MAP = mapOf( - DP_KEY_BASE_CLASS to DP_KEY_BASE_KEY, - - "GraphDpKey" to GRAPH, - - "NodeDpKey" to NODE, - "EdgeDpKey" to EDGE, - "GraphObjectDpKey" to GRAPH_OBJECT, - - "ILabelLayoutDpKey" to "yfiles.layout.ILabelLayout", - "IEdgeLabelLayoutDpKey" to IEDGE_LABEL_LAYOUT, - "INodeLabelLayoutDpKey" to INODE_LABEL_LAYOUT -) - -private fun fixClass(source: Source) { - source.type(DP_KEY_BASE_CLASS) { - addFirstTypeParameter(DP_KEY_BASE_KEY, YOBJECT) - - addProperty("valueType", "$YCLASS") - - methodParameters( - "equalsCore", - "other", - { true } - ).single() - .updateDpKeyGeneric(TYPE, DP_KEY_BASE_KEY) - } - - for ((className, generic) in DP_KEY_GENERIC_MAP) { - if (className == DP_KEY_BASE_CLASS) { - continue - } - - source.type(className) - .updateDpKeyGeneric(EXTENDS, generic) - } - - source.type("DpKeyItemCollection") - .property("dpKey") - .updateDpKeyGeneric(TYPE, "*") -} - -internal fun dpKeyBase(typeParameter: String): String = "$DP_KEY_BASE<*,$typeParameter>" -internal fun graphDpKey(typeParameter: String): String = "$GRAPH_DP_KEY<$typeParameter>" -internal fun nodeDpKey(typeParameter: String): String = "yfiles.algorithms.NodeDpKey<$typeParameter>" -internal fun edgeDpKey(typeParameter: String): String = "yfiles.algorithms.EdgeDpKey<$typeParameter>" -internal fun labelDpKey(typeParameter: String): String = "yfiles.algorithms.ILabelLayoutDpKey<$typeParameter>" - -private fun fixProperties(source: Source) { - val typeMap = mapOf( - "affectedNodesDpKey" to nodeDpKey(JS_BOOLEAN), - "splitNodesDpKey" to nodeDpKey(JS_BOOLEAN), - - "centerNodesDpKey" to nodeDpKey(JS_BOOLEAN), - - "minSizeDataProviderKey" to nodeDpKey("yfiles.algorithms.YDimension"), - "minimumNodeSizeDpKey" to nodeDpKey("yfiles.algorithms.YDimension"), - - "groupNodeInsetsDpKey" to nodeDpKey("yfiles.algorithms.YInsets"), - - "affectedEdgesDpKey" to edgeDpKey(JS_BOOLEAN), - "interEdgesDpKey" to edgeDpKey(JS_BOOLEAN), - "nonSeriesParallelEdgesDpKey" to edgeDpKey(JS_BOOLEAN), - "nonSeriesParallelEdgeLabelSelectionKey" to edgeDpKey(JS_BOOLEAN), - "nonTreeEdgeSelectionKey" to edgeDpKey(JS_BOOLEAN), - - "affectedLabelsDpKey" to labelDpKey(JS_BOOLEAN), - "nonTreeEdgeLabelSelectionKey" to labelDpKey(JS_BOOLEAN) - ) - - val types = typeMap.keys - source.types() - .optFlatMap(PROPERTIES) - .filter { it[NAME] in types } - .filter { it[TYPE] == JS_ANY } - .forEach { it[TYPE] = typeMap.getValue(it[NAME]) } - - source.type("InsetsGroupBoundsCalculator") - .flatMap(CONSTRUCTORS) - .optFlatMap(PARAMETERS) - .single { it[NAME] == "groupNodeInsetsDPKey" } - .also { - val name = "groupNodeInsetsDpKey" - it[NAME] = name - it[TYPE] = typeMap.getValue(name) - } - - source.type("MinimumSizeGroupBoundsCalculator") - .flatMap(CONSTRUCTORS) - .optFlatMap(PARAMETERS) - .single { it[NAME] == "minSizeDataProviderKey" } - .also { - val name = "minimumNodeSizeDpKey" - it[NAME] = name - it[TYPE] = typeMap.getValue(name) - } -} - -private fun fixMethodParameters(source: Source) { - source.types("IMapperRegistry", "MapperRegistry") - .flatMap(METHODS) - .forEach { method -> - method.flatMap(PARAMETERS) - .filter { it[NAME] == "tag" } - .filter { it[TYPE] == JS_OBJECT } - .forEach { it[TYPE] = dpKeyBase(if (method.has(TYPE_PARAMETERS)) "V" else "*") } - } - - source.type("WeightedLayerer").also { - sequenceOf( - it.flatMap(CONSTRUCTORS) - .flatMap(PARAMETERS) - .single { it[NAME] == "key" }, - it.property("key") - ).forEach { it[TYPE] = edgeDpKey(JS_INT) } - } - - source.type("LabelingBase").apply { - constant("LABEL_MODEL_DP_KEY").also { - it.replaceInType("<$JS_ANY>", "<$YOBJECT>") - } - - flatMap(METHODS) - .filter { it[NAME] == "label" } - .flatMap(PARAMETERS) - .single { it[NAME] == "key" } - .set(TYPE, labelDpKey(JS_BOOLEAN)) - } -} - -private fun JSONObject.updateDpKeyGeneric( - field: JStringKey, - generic: String, -) { - val value = get(field) - - // TODO: check - if (field == EXTENDS && value == "yfiles.algorithms.ILabelLayoutDpKey") { - return - } - - require(value.startsWith(DP_KEY_BASE_DECLARATION)) - set(field, value.replace(DP_KEY_BASE_DECLARATION, "$DP_KEY_BASE_DECLARATION$generic,")) -} diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/DpdataHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/DpdataHacks.kt deleted file mode 100644 index b37e3d373..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/DpdataHacks.kt +++ /dev/null @@ -1,398 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.* -import com.github.turansky.yfiles.json.get -import org.json.JSONObject - -internal fun applyDpdataHacks(source: Source) { - fixGraph(source) - fixDefaultLayoutGraph(source) - fixDfs(source) - fixLayoutGraphAdapter(source) - fixTreeLayout(source) - fixGraphPartitionManager(source) - fixHierarchic(source) - fixTriangulator(source) - fixYGraphAdapter(source) - fixMISLabelingBase(source) - fixParallelEdgeRouter(source) - - fixDataProviders(source) - fixMaps(source) - fixLists(source) - fixComparers(source) -} - -private const val GENERIC_DP_KEY = "$DP_KEY_BASE" - -private fun fixGraph(source: Source) { - val methods = source.type("Graph")[METHODS] - - methods["getDataProvider"].apply { - setKeyValueTypeParameters(keyBound = YOBJECT) - firstParameter[TYPE] = GENERIC_DP_KEY - - get(RETURNS) - .addGeneric("K,V") - } - - methods["addDataProvider"].apply { - setKeyValueTypeParameters(keyBound = YOBJECT) - firstParameter[TYPE] = GENERIC_DP_KEY - - secondParameter.addGeneric("K,V") - } - - methods["removeDataProvider"].firstParameter[TYPE] = "$DP_KEY_BASE<*,*>" - - sequenceOf("createEdgeMap", "createNodeMap") - .map { methods[it] } - .forEach { - it.setSingleTypeParameter("V", JS_OBJECT) - - it[RETURNS] - .addGeneric("V") - } -} - -private fun fixDefaultLayoutGraph(source: Source) { - val properties = source.type("DefaultLayoutGraph")[PROPERTIES] - - properties["nodeLabelMap"].addGeneric("Array<$INODE_LABEL_LAYOUT>") - properties["edgeLabelMap"].addGeneric("Array<$IEDGE_LABEL_LAYOUT>") - - properties["nodeLabelFeatureMap"] - .also { it.replaceInType("$JS_ANY,$JS_ANY", "$INODE_LABEL_LAYOUT,$NODE") } - - properties["edgeLabelFeatureMap"] - .also { it.replaceInType("$JS_ANY,$JS_ANY", "$IEDGE_LABEL_LAYOUT,$EDGE") } -} - -private fun fixDfs(source: Source) { - source.type("DfsAlgorithm") - .property("stateMap") - .addGeneric(DFS_STATE) -} - -private fun fixLayoutGraphAdapter(source: Source) { - val methods = source.type("LayoutGraphAdapter")[METHODS] - - methods["getDataProvider"].apply { - setKeyValueTypeParameters(keyBound = YOBJECT) - firstParameter[TYPE] = GENERIC_DP_KEY - - get(RETURNS) - .addGeneric("K,V") - } - - methods["addDataProvider"].apply { - get(TYPE_PARAMETERS).getJSONObject(0) - .set(BOUNDS, arrayOf(YOBJECT)) - - get(PARAMETERS) - .get("dataKey") - .set(TYPE, GENERIC_DP_KEY) - - get(RETURNS) - .addGeneric("K,V") - } -} - -private fun fixTreeLayout(source: Source) { - val properties = source.type("TreeLayout")[PROPERTIES] - - sequenceOf( - "sourceGroupDataAcceptor" to YID, - "sourcePortConstraintDataAcceptor" to "yfiles.layout.PortConstraint", - "targetGroupDataAcceptor" to YID, - "targetPortConstraintDataAcceptor" to "yfiles.layout.PortConstraint" - ).forEach { (propertyName, valueType) -> - properties[propertyName] - .addGeneric("$EDGE,$valueType") - } - - source.type("TreeComponentLayout") - .method("applyLayoutUsingDummies") - .get(PARAMETERS) - .get("dummyDp") - .addGeneric("$NODE,$JS_BOOLEAN") - - source.type("LeftRightNodePlacer") - .method("createLeftRightDataProvider") - .also { - it.firstParameter.addGeneric("$NODE,yfiles.tree.INodePlacer") - it[RETURNS].addGeneric("$NODE,$JS_BOOLEAN") - } -} - -private fun fixGraphPartitionManager(source: Source) { - val type = source.type("GraphPartitionManager") - (type.optFlatMap(CONSTRUCTORS) + type.optFlatMap(METHODS)) - .optFlatMap(PARAMETERS) - .filter { it[NAME] == "partitionId" } - .filter { it[TYPE] == IDATA_PROVIDER } - .forEach { it.addGeneric("$GRAPH_OBJECT,$YID") } -} - -private fun fixHierarchic(source: Source) { - val methods = source.type("HierarchicLayoutCore")[METHODS] - - sequenceOf( - "getEdgeLayoutDescriptors" to "$EDGE,yfiles.hierarchic.EdgeLayoutDescriptor", - "getIncrementalHints" to "$GRAPH_OBJECT,$INCREMENTAL_HINT", - "getNodeLayoutDescriptors" to "$NODE,yfiles.hierarchic.NodeLayoutDescriptor", - "getSwimLaneDescriptors" to "$NODE,$SWIMLANE_DESCRIPTOR" - ).forEach { (methodName, typeParameters) -> - methods[methodName][RETURNS] - .addGeneric(typeParameters) - } - - source.type("PortCandidateOptimizer") - .method("getPortCandidateSetDataProvider") - .get(RETURNS) - .addGeneric("$NODE,yfiles.layout.PortCandidateSet") - - source.type("WeightedLayerer") - .property("weight") - .addGeneric("$EDGE,$JS_INT") - - source.type("SimplexNodePlacer") - .method("assignNodesToSublayer") - .parameter("lowerSublayer") - .addGeneric("yfiles.hierarchic.ILayer") -} - -private fun fixTriangulator(source: Source) { - source.type("TriangulationAlgorithm") - .flatMap(METHODS) - .filter { STATIC in it[MODIFIERS] } - .flatMap(PARAMETERS) - .forEach { - when (it[NAME]) { - "pointData" -> it.addGeneric("$NODE,$YPOINT") - "revMap", "reverseEdgeMap" -> it.addGeneric(EDGE) - "resultMap" -> it.addGeneric(YPOINT) - } - } -} - -private fun fixYGraphAdapter(source: Source) { - val dataNames = setOf( - "createDataMap", - "createDataProvider" - ) - - val graphDataNames = setOf( - "createEdgeMap", - "createNodeMap" - ) - - val mapperNames = setOf( - "createEdgeMapper", - "createNodeMapper" - ) - - source.type("YGraphAdapter").also { - it.flatMap(METHODS) - .filter { it[NAME] in dataNames } - .onEach { it[TYPE_PARAMETERS].getJSONObject(0)[BOUNDS] = arrayOf(YOBJECT) } - .map { it[RETURNS] } - .forEach { it.addGeneric("K,V") } - - it.method("createMapper").also { - it.strictBound("T") - it.firstParameter.addGeneric("$GRAPH_OBJECT,T") - } - - it.flatMap(METHODS) - .filter { it[NAME] in graphDataNames } - .onEach { it.strictBound("V") } - .map { it[RETURNS] } - .forEach { it.addGeneric("V") } - - it.flatMap(METHODS) - .filter { it[NAME] in mapperNames } - .onEach { it.strictBound("T") } - .map { it.firstParameter } - .forEach { it.addGeneric("T") } - } -} - -private fun fixMISLabelingBase(source: Source) { - source.type("MISLabelingBase").also { - it.property("nodesToBoxes") - .addGeneric("yfiles.layout.LabelCandidate") - - it.property("nodesToID") - .addGeneric(YID) - - it.property("boxesToNodes") - .also { it.replaceInType("$JS_ANY,$JS_ANY", "yfiles.layout.LabelCandidate,$NODE") } - - it.method("assignProfit") - .get(RETURNS) - .addGeneric(JS_DOUBLE) - } -} - -private fun fixParallelEdgeRouter(source: Source) { - source.type("ParallelEdgeRouter") - .property("parallelEdges") - .addGeneric(EDGE) -} - -private fun fixDataProviders(source: Source) { - source.type("DataProviders") - .flatMap(METHODS) - .forEach { - val name = it[NAME] - - val keyType = when { - name == "createConstantDataProvider" || name == "createNegatedDataProvider" -> "K" - "NodeDataProvider" in name -> NODE - else -> EDGE - } - - val valueType = when { - name == "createNegatedDataProvider" -> JS_BOOLEAN - "ForBoolean" in name -> JS_BOOLEAN - "ForInt" in name -> JS_INT - "ForNumber" in name -> JS_DOUBLE - else -> "V" - } - - it[TYPE_PARAMETERS] = mutableListOf().apply { - if (keyType == "K") { - add(typeParameter(keyType, YOBJECT)) - } - - if (valueType == "V") { - add(typeParameter(valueType, JS_OBJECT)) - } - }.toList() - - if (name == "createNegatedDataProvider") { - it.firstParameter.addGeneric("$keyType,$valueType") - } else { - it.flatMap(PARAMETERS) - .forEach { - when (it[NAME]) { - "data", "objectData" -> it.replaceInType(JS_OBJECT, valueType) - "nodeData" -> it.addGeneric("$NODE,$valueType") - } - } - } - - it[RETURNS].addGeneric("$keyType,$valueType") - } -} - -private fun fixMaps(source: Source) { - source.type("Maps") - .flatMap(METHODS) - .forEach { - val returns = it[RETURNS] - - val keyType = when (returns[TYPE]) { - IDATA_MAP -> "K" - INODE_MAP -> NODE - IEDGE_MAP -> EDGE - else -> return@forEach - } - - val name = it[NAME] - val valueType = when { - "ForBoolean" in name -> JS_BOOLEAN - "ForInt" in name || "IntMap" in name -> JS_INT - "ForNumber" in name || "DoubleMap" in name -> JS_DOUBLE - else -> "V" - } - - it[TYPE_PARAMETERS] = mutableListOf().apply { - if (keyType == "K") { - add(typeParameter(keyType, YOBJECT)) - } - - if (valueType == "V") { - add(typeParameter(valueType, JS_OBJECT)) - } - }.toList() - - val typeParameters = "$keyType,$valueType" - it.optFlatMap(PARAMETERS) - .forEach { - when (it[NAME]) { - "map" -> it.replaceInType("$JS_OBJECT,$JS_OBJECT", typeParameters) - "defaultValue" -> if (it[TYPE] == JS_OBJECT) it[TYPE] = "V" - "data", "objectData" -> it.replaceInType("<$JS_OBJECT>", "") - else -> when (it[TYPE]) { - IDATA_PROVIDER, - IDATA_ACCEPTOR, - IDATA_MAP, - -> it.addGeneric(typeParameters) - } - } - } - - it[RETURNS].addGeneric(if (keyType == "K") typeParameters else valueType) - } -} - -private fun fixLists(source: Source) { - sequenceOf( - "YList" to "T", - "YNodeList" to NODE, - "EdgeList" to EDGE - ).forEach { (className, keyType) -> - source.type(className) - .flatMap(CONSTRUCTORS) - .optFlatMap(PARAMETERS) - .filter { it[NAME] == "predicate" } - .forEach { it.addGeneric("$keyType,$JS_BOOLEAN") } - } -} - -private fun fixComparers(source: Source) { - source.type("Comparers") - .flatMap(METHODS) - .filter { it.has(PARAMETERS) } - .filter { it.firstParameter[TYPE] == IDATA_PROVIDER } - .forEach { - val name = it[NAME] - - val nodeProxy = "Source" in name || "Target" in name - val keyType = if (nodeProxy) EDGE else "K" - - val valueType = when { - "IntData" in name -> JS_INT - "NumberData" in name -> JS_DOUBLE - else -> "V" - } - - val valueBound = if (name == "createComparableDataComparer") { - "yfiles.lang.IComparable" - } else { - JS_OBJECT - } - - it[TYPE_PARAMETERS] = mutableListOf().apply { - if (keyType == "K") { - add(typeParameter(keyType, YOBJECT)) - } - - if (valueType == "V") { - add(typeParameter(valueType, valueBound)) - } - }.toList() - - val parameterKeyType = if (nodeProxy) NODE else keyType - it.firstParameter.addGeneric("$parameterKeyType,$valueType") - it[RETURNS].also { - it[TYPE] = it[TYPE].substringBefore("<") + "<$keyType>" - } - } -} - -private fun JSONObject.strictBound(name: String) { - get(TYPE_PARAMETERS)[name][BOUNDS] = arrayOf(JS_OBJECT) -} diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/EventDispatcherHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/EventDispatcherHacks.kt index 42ba1bdf5..eb00efdf8 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/EventDispatcherHacks.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/EventDispatcherHacks.kt @@ -8,10 +8,40 @@ import org.json.JSONObject internal fun generateEventDispatcherUtils(context: GeneratorContext) { // language=kotlin - context[IEVENT_DISPATCHER] = "external interface IEventDispatcher" + context[IEVENT_DISPATCHER] = """ + external interface IEventDispatcher { + final fun addEventListener(event: String, handler: T) + final fun removeEventListener(event: String, handler: T) + } +""".trimIndent() } internal fun applyEventDispatcherHacks(source: Source) { + source.types() + .forEach { type -> + type.optFlatMap(EVENTS) + .forEach { event -> + event[TYPE] = event[TYPE].replace("function(", "").replace(",this)", "") //maybe not necessary + + if (event.has(SUMMARY)) { + event[SUMMARY] = "`${event[NAME]}`: " + event[SUMMARY] + } else { + event[SUMMARY] = "`${event[NAME]}`" + } + + event.optFlatMap(SEE_ALSO) + .filter { it.has(MEMBER) } + .forEach { + val extensionName = it[MEMBER].split("-") + .joinToString(separator = "", prefix = "add", postfix = "Handler") { + it.replaceFirstChar(Char::titlecase) + } + it[MEMBER] = extensionName + } + + } + } + source.types() .filter { it.has(EVENTS) || it[NAME] == "ItemModelManager" } .filterNot { it.hasParentDispatcher(source) } diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/EventHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/EventHacks.kt index 175f7d463..a67acc1f6 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/EventHacks.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/EventHacks.kt @@ -14,7 +14,17 @@ internal fun applyEventHacks(source: Source) { it[NAME] = name } - fixMouseEventArgsConstructor(source) +// fixMouseEventArgsConstructor(source) + + source.types() + .flatMap { it.optFlatMap(METHODS) + it.optFlatMap(CONSTRUCTORS) } + .plus(source.functionSignatures.run { keySet().map { getJSONObject(it) } }) + .optFlatMap(PARAMETERS) + .plus(source.types().optFlatMap(PROPERTIES)) + .filter { it[TYPE] == "UIEvent" } + .forEach { + it[TYPE] = "web.uievents.UIEvent" + } } fun JSONObject.getNewName(): String? = diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ExecutorHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ExecutorHacks.kt new file mode 100644 index 000000000..162a9aa42 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ExecutorHacks.kt @@ -0,0 +1,7 @@ +package com.github.turansky.yfiles.correction + +internal fun applyExecutorHacks(source: Source) { + source.type("LayoutExecutorAsync") { + method("createWebWorkerMessageHandler").firstParameter[TYPE] = "web.workers.Worker" + } +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/Hacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/Hacks.kt index 612faafc0..5c9029559 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/Hacks.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/Hacks.kt @@ -1,7 +1,6 @@ package com.github.turansky.yfiles.correction import com.github.turansky.yfiles.* -import com.github.turansky.yfiles.json.get import com.github.turansky.yfiles.json.removeItem import com.github.turansky.yfiles.json.strictRemove import org.json.JSONObject @@ -11,17 +10,18 @@ internal fun applyHacks(api: JSONObject) { fieldToProperties(source) - cleanYObject(source) - removeUnusedFunctionSignatures(source) removeDuplicatedProperties(source) removeDuplicatedMethods(source) + removeInvalidOverrides(source) removeSystemMethods(source) - removeArtifitialParameters(source) + removeArtificialParameters(source) removeThisParameters(source) + removeTypeMetadataMethods(source) + + fixChangeHandlers(source) fixConstantGenerics(source) - fixFunctionGenerics(source) fixReturnType(source) @@ -33,60 +33,46 @@ internal fun applyHacks(api: JSONObject) { fixMethodParameterName(source) fixMethodParameterType(source) - fixMethodParameterOptionality(source) fixMethodParameterNullability(source) fixMethodNullability(source) fixMethodGenericBounds(source) fixNullability(source) + fixCollections(source) + fixConvertibles(source) + fixMarkupExtensions(source) + fixConstructors(source) applyIdHacks(source) applyBindingHacks(source) applyBusinessObjectHacks(source) applyCloneableHacks(source) applyClassHacks(source) - applyCollectionHacks(source) applyComparableHacks(source) - applyComparerHacks(source) + applyContextMenuFixes(source) applyCursorHacks(source) - applyPartitionCellHacks(source) - applyIntersectionHacks(source) - - applyDpdataHacks(source) - applyDataHacks(source) - applyDpKeyHacks(source) + applyItemDropInputModeHacks(source) applyListCellHacks(source) applyListHacks(source) applyYListHacks(source) applyEventHacks(source) + applyExecutorHacks(source) applyLabelModelParameterHacks(source) - applyMementoHacks(source) applyMementoSupportHacks(source) applyClipboardHelperHacks(source) - applySnapLineProviderHacks(source) - applyIncrementalHintHacks(source) - applyObstacleDataHacks(source) - applyTooltipHacks(source) applyDragDropDataHacks(source) + applyTagHacks(source) applyDataTagHacks(source) applyStyleTagHacks(source) - applyNodeTypeHacks(source) applyLayoutDescriptorHacks(source) - applyResourceHacks(source) - applyTemplatesHacks(source) - applyTemplateLoadersHacks(source) - applyConvertersHacks(source) applyEventDispatcherHacks(source) - applyCommandHacks(source) + applyCreationPropertiesHacks(source) applyContextLookupHacks(source) - applyCanvasObjectDescriptorHacks(source) - applyCanvasObjectInstallerHacks(source) - applyVisualTemplateHacks(source) applyStyleRendererHacks(source) applyElementIdHacks(source) @@ -97,20 +83,10 @@ internal fun applyHacks(api: JSONObject) { applyExtensionHacks(source) applySingletonHacks(source) applyResultHacks(source) - fixConstructors(source) - applyLayoutStrictTypes(source) addSizeExtensions(source) } -private fun cleanYObject(source: Source) { - source.type("YObject") { - set(GROUP, "interface") - - strictRemove(METHODS) - } -} - private fun removeUnusedFunctionSignatures(source: Source) { source.functionSignatures.apply { UNUSED_FUNCTION_SIGNATURES.forEach { @@ -135,15 +111,8 @@ private fun fixFunctionGenerics(source: Source) { } private fun fixReturnType(source: Source) { - source.type("DiscreteEdgeLabelLayoutModel") - .method("getPosition")[RETURNS][TYPE] = "yfiles.layout.DiscreteEdgeLabelPositions" - source.type("SvgExport") .method("exportSvg")[RETURNS][TYPE] = JS_SVG_SVG_ELEMENT - - source.type("PortCandidateSet") - .property("entries") - .also { it.replaceInType("<$JS_ANY>", "") } } private fun fixConstantType(source: Source) { @@ -152,28 +121,8 @@ private fun fixConstantType(source: Source) { } private fun fixPropertyType(source: Source) { - source.type("BalloonLayoutData") - .property("outEdgeComparer") - .also { require(it[SIGNATURE] == "function($IEDGE,$IEDGE):number") } - .set(SIGNATURE, "$ICOMPARER<$IEDGE>") - - source.type("CactusGroupLayoutData") - .property("nodeComparer") - .also { require(it[SIGNATURE] == "function($INODE,$INODE):number") } - .set(SIGNATURE, "$ICOMPARER<$INODE>") - source.type("IRenderContext") - .property("defsElement") - .set(TYPE, JS_SVG_DEFS_ELEMENT) - - source.types( - "RadialLayoutData", - "SeriesParallelLayoutData", - "TreeLayoutData", - ).forEach { - it.property("outEdgeComparers") - .set(TYPE, "yfiles.layout.ItemMapping<$INODE,$ICOMPARER<$IEDGE>>") - } + .property("defsElement")[TYPE] = JS_SVG_DEFS_ELEMENT } private fun fixPropertyNullability(source: Source) { @@ -219,18 +168,6 @@ private fun fixMethodParameterName(source: Source) { } } -private fun fixMethodParameterOptionality(source: Source) { - val methodNames = setOf("onShow", "show") - - source.type("MouseHoverInputMode") - .flatMap(METHODS) - .filter { it[NAME] in methodNames } - .flatMap(PARAMETERS) - .filter { it[NAME] == "content" } - .map { it[MODIFIERS] } - .forEach { it.removeItem(OPTIONAL) } -} - private fun fixMethodParameterNullability(source: Source) { PARAMETERS_NULLABILITY_CORRECTION .forEach { (data, nullable) -> @@ -269,54 +206,16 @@ private fun fixMethodParameterNullability(source: Source) { .filter { it[NAME] in MODEL_MANAGER_ITEM_METHODS } .map { it.firstParameter } .forEach { it.changeNullability(false) } - - source.types("Substructures", "SeriesParallelLayout") - .flatMap(METHODS) - .filter { STATIC in it[MODIFIERS] } - .map { it.firstParameter } - .onEach { check(it[TYPE] == GRAPH) } - .forEach { it.changeNullability(false) } - - source.type("Font") - .let { it.flatMap(CONSTRUCTORS) + it.method("createCopy") } - .flatMap(PARAMETERS) - .filter { it[TYPE] != JS_NUMBER } - .map { it[MODIFIERS] } - .forEach { it.removeItem(CANBENULL) } - - source.types() - .optFlatMap(EVENTS) - .eventListeners() - .flatMap(PARAMETERS) - .forEach { it.changeNullability(false) } } private fun fixMethodParameterType(source: Source) { source.type("IEnumerable") .method("concat") - .parameter("elements") - .set(TYPE, "$IENUMERABLE") - - source.type("IContextLookupChainLink") - .method("addingLookupChainLink") - .parameter("instance") - .set(TYPE, "TResult") - - source.type("DiscreteEdgeLabelLayoutModel") - .method("createPositionParameter") - .parameter("position")[TYPE] = "yfiles.layout.DiscreteEdgeLabelPositions" + .parameter("elements")[TYPE] = "$IENUMERABLE" source.type("SvgExport") .method("exportSvgString") - .parameter("svg") - .set(TYPE, JS_SVG_ELEMENT) - - source.type("AspectRatioTreeLayout") - .flatMap(METHODS) - .optFlatMap(PARAMETERS) - .filter { it[NAME] == "localRoot" } - .filter { it[TYPE] == JS_OBJECT } - .forEach { it[TYPE] = NODE } + .parameter("svg")[TYPE] = JS_SVG_ELEMENT source.type("CreateEdgeInputMode") { val PCC = "$ITEM_EVENT_ARGS<$IPORT_CANDIDATE>" @@ -325,13 +224,6 @@ private fun fixMethodParameterType(source: Source) { .optFlatMap(PARAMETERS) .filter { it[TYPE] == PCC } .forEach { it.replaceInType(">", "?>") } - - val PCC_HANDLER = "$EVENT_HANDLER1<$PCC>" - flatMap(EVENTS) - .eventListeners() - .flatMap(PARAMETERS) - .filter { it[SIGNATURE] == PCC_HANDLER } - .forEach { it.replaceInSignature(">>", "?>>") } } source.type("SvgVisual") @@ -355,10 +247,36 @@ private fun removeDuplicatedProperties(source: Source) { DUPLICATED_PROPERTIES .forEach { declaration -> val properties = source - .type(declaration.className) - .get(PROPERTIES) + .type(declaration.className)[PROPERTIES] - properties.removeItem(properties[declaration.propertyName]) + properties + .map { it as JSONObject } + .filter { it[NAME] == declaration.propertyName } + .drop(1) + .forEach { properties.removeItem(it) } + } +} + +private fun removeInvalidOverrides(source: Source) { + INVALID_PROPERTY_OVERRIDES + .forEach { declaration -> + val properties = source + .type(declaration.className)[PROPERTIES] + + properties + .map { it as JSONObject } + .filter { it[NAME] == declaration.propertyName } + .forEach { properties.removeItem(it) } + } + INVALID_METHOD_OVERRIDES + .forEach { declaration -> + val methods = source + .type(declaration.className)[METHODS] + + methods + .map { it as JSONObject } + .filter { it[NAME] == declaration.methodName } + .forEach { methods.removeItem(it) } } } @@ -366,10 +284,13 @@ private fun removeDuplicatedMethods(source: Source) { DUPLICATED_METHODS .forEach { declaration -> val methods = source - .type(declaration.className) - .get(METHODS) + .type(declaration.className)[METHODS] - methods.removeItem(methods[declaration.methodName]) + methods + .map { it as JSONObject } + .filter { it[NAME] == declaration.methodName } + .drop(1) + .forEach { methods.removeItem(it) } } } @@ -389,7 +310,7 @@ private fun removeSystemMethods(source: Source) { } } -private fun removeArtifitialParameters(source: Source) { +private fun removeArtificialParameters(source: Source) { sequenceOf(CONSTRUCTORS, METHODS) .flatMap { parameter -> source.types().optFlatMap(parameter) } .filter { it.has(PARAMETERS) } diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/IdHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/IdHacks.kt index d810c15d7..a008593b6 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/IdHacks.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/IdHacks.kt @@ -7,33 +7,14 @@ import org.json.JSONObject internal fun generateIdUtils(context: GeneratorContext) { // language=kotlin context[YID] = """ - external interface Id: $YOBJECT + external interface Id inline fun Id(source:Any):Id = source.unsafeCast() """.trimIndent() } -private val ID_DP_KEYS = setOf( - edgeDpKey(JS_ANY), - nodeDpKey(JS_ANY), - - "$IEDGE_LABEL_LAYOUT_DP_KEY<$JS_ANY>", - "$INODE_LABEL_LAYOUT_DP_KEY<$JS_ANY>" -) - internal fun applyIdHacks(source: Source) { - source.types() - .flatMap { it.optFlatMap(CONSTANTS) } - .filter { it[TYPE] in ID_DP_KEYS } - .filter { it[NAME].let { it.endsWith("_ID_DP_KEY") || it == "CUSTOM_GROUPS_DP_KEY" } } - .forEach { - val newType = it[TYPE] - .replace("<$JS_ANY>", "<$YID>") - - it[TYPE] = newType - } - val likeObjectTypes = setOf( JS_OBJECT, JS_ANY @@ -53,32 +34,10 @@ internal fun applyIdHacks(source: Source) { it[TYPE] = newType } - source.type("IEdgeData")[PROPERTIES].also { properties -> - sequenceOf( - "group", - - "sourceGroup", - "targetGroup", - - "sourcePortGroup", - "targetPortGroup" - ).forEach { properties[it][TYPE] = YID } - } - source.types("GraphClipboard", "IClipboardIdProvider") .map { it.method("getId") } .forEach { it[RETURNS][TYPE] = YID } - source.type("BusRouterBusDescriptor") - .flatMap(CONSTRUCTORS) - .flatMap(PARAMETERS) - .forEach { - val name = it[NAME] - if (name.endsWith("ID")) { - it[NAME] = name.replace("ID", "Id") - } - } - source.type("ChannelRoutingTool") .flatMap(METHODS) .optFlatMap(PARAMETERS) diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/IncrementalHintHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/IncrementalHintHacks.kt deleted file mode 100644 index 614892bd4..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/IncrementalHintHacks.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.GeneratorContext -import com.github.turansky.yfiles.JS_ANY - -internal const val INCREMENTAL_HINT = "yfiles.hierarchic.IncrementalHint" - -internal fun generateIncrementalHint(context: GeneratorContext) { - // language=kotlin - context[INCREMENTAL_HINT] = """ - @JsName("Object") - external class IncrementalHint - private constructor() - """.trimIndent() -} - -internal fun applyIncrementalHintHacks(source: Source) { - source.type("IIncrementalHintsFactory") - .flatMap(METHODS) - .forEach { it[RETURNS][TYPE] = INCREMENTAL_HINT } - - source.type("IncrementalHintItemMapping").also { - it[EXTENDS] = it[EXTENDS].replace(",$JS_ANY,", ",$INCREMENTAL_HINT,") - } - - source.types("HierarchicLayout", "HierarchicLayoutCore") - .map { it.constant("INCREMENTAL_HINTS_DP_KEY") } - .forEach { it.replaceInType("<$JS_ANY>", "<$INCREMENTAL_HINT>") } - - source.type("INodeData") - .property("incrementalHint")[TYPE] = INCREMENTAL_HINT -} diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/IntersectionHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/IntersectionHacks.kt deleted file mode 100644 index 314c88c46..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/IntersectionHacks.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.json.get - -private const val IPLANE_OBJECT = "yfiles.algorithms.IPlaneObject" - -internal fun applyIntersectionHacks(source: Source) { - source.type("IntersectionAlgorithm")[METHODS]["intersect"].apply { - setSingleTypeParameter(bound = IPLANE_OBJECT) - - flatMap(PARAMETERS) - .forEach { it.addGeneric("T") } - } - - source.type("IIntersectionHandler") { - setSingleTypeParameter(bound = IPLANE_OBJECT) - - method("checkIntersection") - .flatMap(PARAMETERS) - .forEach { it[TYPE] = "T" } - - method("create") - .get(RETURNS) - .addGeneric("T") - } -} diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ItemDropInputModeHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ItemDropInputModeHacks.kt new file mode 100644 index 000000000..a1fd6a8bc --- /dev/null +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ItemDropInputModeHacks.kt @@ -0,0 +1,12 @@ +package com.github.turansky.yfiles.correction + +import com.github.turansky.yfiles.VARARGS +import com.github.turansky.yfiles.json.removeItem + +internal fun applyItemDropInputModeHacks(source: Source) { + source.type("ItemDropInputMode") { + flatMap(CONSTRUCTORS) + .flatMap(PARAMETERS) + .first()[MODIFIERS].removeItem(VARARGS) + } +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/IteratorSupport.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/IteratorSupport.kt index f07bfd305..bb8a7fdb9 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/IteratorSupport.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/IteratorSupport.kt @@ -4,7 +4,6 @@ import com.github.turansky.yfiles.ContentMode.ITERATOR import com.github.turansky.yfiles.GeneratorContext import com.github.turansky.yfiles.ICURSOR import com.github.turansky.yfiles.IENUMERABLE -import com.github.turansky.yfiles.YOBJECT internal fun addIteratorSupport(context: GeneratorContext) { // language=kotlin @@ -34,13 +33,13 @@ internal fun addIteratorSupport(context: GeneratorContext) { // language=kotlin context[ICURSOR, ITERATOR] = """ - operator fun ICursor.iterator(): Iterator = + operator fun ICursor.iterator(): Iterator = CursorIterator(this) - fun ICursor.asSequence(): Sequence = + fun ICursor.asSequence(): Sequence = iterator().asSequence() - private class CursorIterator( + private class CursorIterator( private val source: ICursor ) : Iterator { diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/JKey.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/JKey.kt index cc3d088d8..99ce66e38 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/JKey.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/JKey.kt @@ -37,6 +37,8 @@ internal object STATIC_METHODS : JArrayKey("staticMethods") internal object METHODS : JArrayKey("methods") internal object EVENTS : JArrayKey("events") +internal object SEE_ALSO : JArrayKey("seeAlso") +internal object MEMBER : JStringKey("member") internal object PARAMETERS : JArrayKey("parameters") internal object RETURNS : JObjectKey("returns") diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/JsonCorrections.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/JsonCorrections.kt index 67138cbac..ee0203d77 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/JsonCorrections.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/JsonCorrections.kt @@ -3,71 +3,41 @@ package com.github.turansky.yfiles.correction import com.github.turansky.yfiles.CANBENULL internal val UNUSED_FUNCTION_SIGNATURES = setOf( - "yfiles.lang.Action3", +// "yfiles.lang.Action3", "yfiles.lang.Action4", - "yfiles.lang.Func1", - "yfiles.lang.Func4", +// "yfiles.lang.Func1", +// "yfiles.lang.Func4", "yfiles.lang.Func5", "yfiles.input.HitTestableHandler", "yfiles.input.KeyEventHandler" ) internal val PROPERTY_NULLABILITY_CORRECTION = mapOf( - PropertyDeclaration("DefaultGraph", "tag") to true, - PropertyDeclaration("GraphWrapperBase", "tag") to true, - PropertyDeclaration("SimpleBend", "tag") to true, - PropertyDeclaration("SimpleEdge", "tag") to true, - PropertyDeclaration("SimpleLabel", "tag") to true, - PropertyDeclaration("SimpleNode", "tag") to true, - PropertyDeclaration("SimplePort", "tag") to true, - - PropertyDeclaration("SimpleBend", "owner") to true, - PropertyDeclaration("SimpleEdge", "sourcePort") to true, - PropertyDeclaration("SimpleEdge", "targetPort") to true, - PropertyDeclaration("SimpleLabel", "owner") to true, - PropertyDeclaration("SimplePort", "owner") to true, +// PropertyDeclaration("DefaultGraph", "tag") to true, +// PropertyDeclaration("GraphWrapperBase", "tag") to true, +// PropertyDeclaration("SimpleBend", "tag") to true, +// PropertyDeclaration("SimpleEdge", "tag") to true, +// PropertyDeclaration("SimpleLabel", "tag") to true, +// PropertyDeclaration("SimpleNode", "tag") to true, +// PropertyDeclaration("SimplePort", "tag") to true, + +// PropertyDeclaration("SimpleBend", "owner") to true, +// PropertyDeclaration("SimpleEdge", "sourcePort") to true, +// PropertyDeclaration("SimpleEdge", "targetPort") to true, +// PropertyDeclaration("SimpleLabel", "owner") to true, +// PropertyDeclaration("SimplePort", "owner") to true, PropertyDeclaration("ICursor", "current") to false, - PropertyDeclaration("DpKeyBase", "name") to false, - PropertyDeclaration("DpKeyBase", "declaringType") to false, - - PropertyDeclaration("INodeData", "firstSameLayerEdgeCell") to true, - PropertyDeclaration("INodeData", "nodeLayoutDescriptor") to true, - PropertyDeclaration("INodeData", "swimLaneDescriptor") to true, - - PropertyDeclaration("ClickInputMode", "inputModeContext") to true, - PropertyDeclaration("ContextMenuInputMode", "inputModeContext") to true, - PropertyDeclaration("CreateBendInputMode", "inputModeContext") to true, - PropertyDeclaration("CreateEdgeInputMode", "inputModeContext") to true, - PropertyDeclaration("DefaultPortCandidate", "candidateTag") to true, - PropertyDeclaration("DefaultPortCandidate", "port") to true, - PropertyDeclaration("DropInputMode", "inputModeContext") to true, - PropertyDeclaration("FocusGuardInputMode", "inputModeContext") to true, - PropertyDeclaration("HandleInputMode", "inputModeContext") to true, - PropertyDeclaration("ItemHoverInputMode", "inputModeContext") to true, - PropertyDeclaration("KeyboardInputMode", "inputModeContext") to true, PropertyDeclaration("LabelDropInputMode", "draggedItem") to true, - PropertyDeclaration("LassoSelectionInputMode", "inputModeContext") to true, - PropertyDeclaration("MarqueeSelectionInputMode", "inputModeContext") to true, - PropertyDeclaration("MouseHoverInputMode", "inputModeContext") to true, - PropertyDeclaration("MoveInputMode", "inputModeContext") to true, - PropertyDeclaration("MoveViewportInputMode", "inputModeContext") to true, - PropertyDeclaration("MultiplexingInputMode", "inputModeContext") to true, - PropertyDeclaration("NavigationInputMode", "inputModeContext") to true, PropertyDeclaration("NodeDropInputMode", "draggedItem") to true, PropertyDeclaration("PortDropInputMode", "draggedItem") to true, - PropertyDeclaration("ResizeStripeInputMode", "inputModeContext") to true, PropertyDeclaration("StripeDropInputMode", "draggedItem") to true, - PropertyDeclaration("TapInputMode", "inputModeContext") to true, - PropertyDeclaration("TextEditorInputMode", "inputModeContext") to true, - PropertyDeclaration("WaitInputMode", "inputModeContext") to true ) internal val CONSTRUCTOR_PARAMETERS_CORRECTION = mapOf( ConstructorParameterData("TimeSpan", "millis") to "milliseconds", ConstructorParameterData("SvgDefsManager", "defsElement") to "defs", - ConstructorParameterData("LayoutGraphHider", "g") to "graph", ConstructorParameterData("LineSegment", "p1") to "firstEndPoint", ConstructorParameterData("LineSegment", "p2") to "secondEndPoint", @@ -81,25 +51,9 @@ internal val CONSTRUCTOR_PARAMETERS_CORRECTION = mapOf( ConstructorParameterData("QueryTypeEventArgs", "xName") to "xmlName", ConstructorParameterData("XmlName", "ns") to "namespace", - ConstructorParameterData("GivenSequenceSequencer", "c") to "sequenceComparer", - ConstructorParameterData("EdgeCellInfo", "enterSegmentNo") to "enterSegmentIndex", ConstructorParameterData("OrthogonalInterval", "isVertical") to "vertical", - ConstructorParameterData("TemplateLabelStyle", "renderTemplateId") to "styleResourceKey", - ConstructorParameterData("TemplateNodeStyle", "renderTemplateId") to "styleResourceKey", - ConstructorParameterData("TemplatePortStyle", "renderTemplateId") to "styleResourceKey", - - ConstructorParameterData("DefaultSeriesParallelLayoutPortAssignment", "ratio") to "borderGapToPortGapRatio", - ConstructorParameterData("DefaultTreeLayoutPortAssignment", "ratio") to "borderGapToPortGapRatio", - - ConstructorParameterData("DefaultNodePlacer", "minFirstSegmentLength") to "minimumFirstSegmentLength", - ConstructorParameterData("DefaultNodePlacer", "minLastSegmentLength") to "minimumLastSegmentLength", - ConstructorParameterData("DefaultNodePlacer", "minSlope") to "minimumSlope", - ConstructorParameterData("DefaultNodePlacer", "minSlopeHeight") to "minimumSlopeHeight", - - ConstructorParameterData("Animator", "canvas") to "canvasComponent", - ConstructorParameterData("ItemSelectionChangedEventArgs", "selected") to "itemSelected", ConstructorParameterData("KeyEventArgs", "type") to "eventType", ConstructorParameterData("SvgVisual", "element") to "svgElement" ) @@ -108,49 +62,12 @@ internal val PARAMETERS_CORRECTION = mapOf( ParameterData("IComparable", "compareTo", "obj") to "o", ParameterData("TimeSpan", "compareTo", "obj") to "o", ParameterData("IEnumerable", "includes", "value") to "item", - ParameterData("IListEnumerable", "get", "i") to "index", +// ParameterData("IListEnumerable", "get", "i") to "index", ParameterData("ListEnumerable", "get", "i") to "index", ParameterData("ResultItemCollection", "get", "i") to "index", ParameterData("YList", "insert", "element") to "item", - ParameterData("YList", "remove", "o") to "item", - - ParameterData("DefaultGraph", "setLabelPreferredSize", "size") to "preferredSize", - - ParameterData("CopiedLayoutGraph", "getLabelLayout", "copiedNode") to "node", - ParameterData("CopiedLayoutGraph", "getLabelLayout", "copiedEdge") to "edge", - ParameterData("CopiedLayoutGraph", "getLayout", "copiedNode") to "node", - ParameterData("CopiedLayoutGraph", "getLayout", "copiedEdge") to "edge", - - ParameterData("DiscreteEdgeLabelLayoutModel", "createModelParameter", "sourceNode") to "sourceLayout", - ParameterData("DiscreteEdgeLabelLayoutModel", "createModelParameter", "targetNode") to "targetLayout", - ParameterData("DiscreteEdgeLabelLayoutModel", "getLabelCandidates", "label") to "labelLayout", - ParameterData("DiscreteEdgeLabelLayoutModel", "getLabelCandidates", "sourceNode") to "sourceLayout", - ParameterData("DiscreteEdgeLabelLayoutModel", "getLabelCandidates", "targetNode") to "targetLayout", - ParameterData("DiscreteEdgeLabelLayoutModel", "getLabelPlacement", "sourceNode") to "sourceLayout", - ParameterData("DiscreteEdgeLabelLayoutModel", "getLabelPlacement", "targetNode") to "targetLayout", - ParameterData("DiscreteEdgeLabelLayoutModel", "getLabelPlacement", "param") to "parameter", - - ParameterData("FreeEdgeLabelLayoutModel", "getLabelPlacement", "sourceNode") to "sourceLayout", - ParameterData("FreeEdgeLabelLayoutModel", "getLabelPlacement", "targetNode") to "targetLayout", - ParameterData("FreeEdgeLabelLayoutModel", "getLabelPlacement", "param") to "parameter", - - ParameterData("SliderEdgeLabelLayoutModel", "createModelParameter", "sourceNode") to "sourceLayout", - ParameterData("SliderEdgeLabelLayoutModel", "createModelParameter", "targetNode") to "targetLayout", - ParameterData("SliderEdgeLabelLayoutModel", "getLabelPlacement", "sourceNode") to "sourceLayout", - ParameterData("SliderEdgeLabelLayoutModel", "getLabelPlacement", "targetNode") to "targetLayout", - ParameterData("SliderEdgeLabelLayoutModel", "getLabelPlacement", "para") to "parameter", - - ParameterData("INodeLabelLayoutModel", "getLabelPlacement", "param") to "parameter", - ParameterData("FreeNodeLabelLayoutModel", "getLabelPlacement", "param") to "parameter", - - ParameterData("NodeOrderComparer", "compare", "edge1") to "x", - ParameterData("NodeOrderComparer", "compare", "edge2") to "y", - ParameterData("NodeWeightComparer", "compare", "o1") to "x", - ParameterData("NodeWeightComparer", "compare", "o2") to "y", - - ParameterData("DefaultOutEdgeComparer", "compare", "o1") to "x", - ParameterData("DefaultOutEdgeComparer", "compare", "o2") to "y", + ParameterData("YList", "remove", "element") to "item", ParameterData("LinearGradient", "accept", "item") to "node", ParameterData("RadialGradient", "accept", "item") to "node", @@ -158,53 +75,26 @@ internal val PARAMETERS_CORRECTION = mapOf( ParameterData("GraphMLParseValueSerializerContext", "lookup", "serviceType") to "type", ParameterData("GraphMLWriteValueSerializerContext", "lookup", "serviceType") to "type", - ParameterData("DefaultLayerSequencer", "sequenceNodeLayers", "glayers") to "layers", - ParameterData("ReparentStripeHandler", "reparent", "stripe") to "movedStripe", ParameterData("StripeDropInputMode", "updatePreview", "newLocation") to "dragLocation", - ParameterData("IElementFactory", "createConnectorNode", "edgesIds") to "edgeIds", - ParameterData("DynamicObstacleDecomposition", "init", "partitionBounds") to "bounds", - ParameterData("PathBasedEdgeStyleRenderer", "isInPath", "path") to "lassoPath", - ParameterData("StripeSelection", "isSelected", "stripe") to "item", - ParameterData("DefaultPortCandidateDescriptor", "isInPath", "path") to "lassoPath", - ParameterData("NodeReshapeHandleProvider", "getHandle", "inputModeContext") to "context", ParameterData("NodeReshapeHandlerHandle", "cancelDrag", "inputModeContext") to "context", ParameterData("NodeReshapeHandlerHandle", "dragFinished", "inputModeContext") to "context", ParameterData("NodeReshapeHandlerHandle", "handleMove", "inputModeContext") to "context", ParameterData("NodeReshapeHandlerHandle", "initializeDrag", "inputModeContext") to "context", - - ParameterData("GraphOverviewCanvasVisualCreator", "createVisual", "ctx") to "context", - ParameterData("GraphOverviewCanvasVisualCreator", "updateVisual", "ctx") to "context", - ParameterData("GraphOverviewWebGLVisualCreator", "createVisual", "ctx") to "context", - ParameterData("GraphOverviewWebGLVisualCreator", "updateVisual", "ctx") to "context" ) internal val PARAMETERS_NULLABILITY_CORRECTION = mapOf( ParameterData("LineSegment", "contains", "point") to false, - ParameterData("Rectangle2D", "contains", "rect") to false, - - ParameterData("Edge", "opposite", "v") to false, - ParameterData("Graph", "disposeEdgeMap", "map") to false, - ParameterData("Graph", "disposeNodeMap", "map") to false, - ParameterData("Graph", "sortEdges", "comparer") to false, - ParameterData("Graph", "sortEdges", "inComparer", true) to false, - ParameterData("Graph", "sortEdges", "outComparer", true) to false, - ParameterData("Graph", "sortNodes", "comparer") to false, - ParameterData("YNode", "sortInEdges", "c") to false, - ParameterData("YNode", "sortOutEdges", "c") to false, - - ParameterData("YList", "setInfo", "value") to false, - ParameterData("List", "binarySearch", "item") to false, ParameterData("IGraph", "contains", "item") to false, ParameterData("IGraph", "isGroupNode", "node") to false, ParameterData("IGraph", "setIsGroupNode", "node") to false, + ParameterData("IGraph", "addLabel", "preferredSize") to true, - ParameterData("DefaultGraph", "contains", "item") to false, - ParameterData("DefaultGraph", "isGroupNode", "node") to false, - ParameterData("DefaultGraph", "setIsGroupNode", "node") to false, + ParameterData("Graph", "contains", "item") to false, + ParameterData("Graph", "isGroupNode", "node") to false, ParameterData("FilteredGraphWrapper", "contains", "item") to false, ParameterData("FilteredGraphWrapper", "isGroupNode", "node") to false, @@ -213,41 +103,24 @@ internal val PARAMETERS_NULLABILITY_CORRECTION = mapOf( ParameterData("GraphWrapperBase", "isGroupNode", "node") to false, ParameterData("GraphWrapperBase", "setIsGroupNode", "node") to false, - ParameterData("ILookupDecorator", "add", "nullIsFallback") to true, - ParameterData("ILookupDecorator", "add", "decorateNull", true) to true, - - ParameterData("GraphClipboard", "isDummy", "item") to false, ParameterData("GraphModelManager", "update", "item") to false, ParameterData("NavigationInputMode", "enterGroup", "node") to false, - ParameterData("NavigationInputMode", "shouldEnterGroup", "node") to false, ParameterData("CreationProperties", "get", "key") to true, ParameterData("CreationProperties", "set", "key") to true, - ParameterData("TemplatePortStyleRenderer", "updateVisual", "context") to false, - ParameterData("TemplatePortStyleRenderer", "updateVisual", "oldVisual") to true, - ParameterData("IAnimation", "createEasedAnimation", "easeIn") to true, ParameterData("IAnimation", "createEasedAnimation", "easeOut") to true, - ParameterData("FocusIndicatorManager", "getInstaller", "item") to true, - - ParameterData("ICanvasObjectDescriptor", "getBoundsProvider", "forUserObject") to false, - ParameterData("ICanvasObjectDescriptor", "getHitTestable", "forUserObject") to false, - ParameterData("ICanvasObjectDescriptor", "getVisibilityTestable", "forUserObject") to false, - ParameterData("ICanvasObjectDescriptor", "getVisualCreator", "forUserObject") to false, - - ParameterData("DefaultPortCandidateDescriptor", "getBoundsProvider", "forUserObject") to false, - ParameterData("DefaultPortCandidateDescriptor", "getHitTestable", "forUserObject") to false, - ParameterData("DefaultPortCandidateDescriptor", "getVisibilityTestable", "forUserObject") to false, - ParameterData("DefaultPortCandidateDescriptor", "getVisualCreator", "forUserObject") to false, - ParameterData("HighlightIndicatorManager", "addHighlight", "item") to false, - ParameterData("HighlightIndicatorManager", "removeHighlight", "item") to false, - ParameterData("SelectionIndicatorManager", "addSelection", "item") to false, - ParameterData("SelectionIndicatorManager", "removeSelection", "item") to false, + ParameterData("ItemModelManager", "itemAddedHandler", "source") to false, - ParameterData("ItemModelManager", "itemAddedHandler", "source") to false + ParameterData("Table", "createChildColumn", "width") to false, + ParameterData("Table", "createChildColumn", "minWidth") to false, + ParameterData("Table", "createChildColumn", "padding") to false, + ParameterData("Table", "createChildRow", "height") to false, + ParameterData("Table", "createChildRow", "minHeight") to false, + ParameterData("Table", "createChildRow", "padding") to false, ) internal val MODEL_MANAGER_ITEM_METHODS = setOf( @@ -263,37 +136,15 @@ internal val BROKEN_NULLABILITY_METHODS = setOf( ) internal val METHOD_NULLABILITY_MAP = mapOf( - MethodDeclaration(className = "Geom", methodName = "calcIntersection") to true, - MethodDeclaration(className = "ShortestPathAlgorithm", methodName = "shortestPair") to true, - MethodDeclaration(className = "YOrientedRectangle", methodName = "intersectionPoint") to true, - MethodDeclaration("HierarchicalClusteringResult", "getDendrogramNode") to false, - MethodDeclaration(className = "PartitionGrid", methodName = "getPartitionGrid") to true, - MethodDeclaration(className = "PortConstraint", methodName = "getSPC") to true, - MethodDeclaration(className = "PortConstraint", methodName = "getTPC") to true, - MethodDeclaration(className = "IEnumerable", methodName = "elementAt") to false, MethodDeclaration(className = "IEnumerable", methodName = "first") to false, MethodDeclaration(className = "IEnumerable", methodName = "last") to false, - MethodDeclaration(className = "Dendrogram", methodName = "getNodeAtLevel") to true, - MethodDeclaration(className = "Dendrogram", methodName = "getOriginalNode") to true, - - MethodDeclaration(className = "IDataProvider", methodName = "get") to true, - MethodDeclaration(className = "DataProviderBase", methodName = "get") to true, - MethodDeclaration(className = "MapperDataProviderAdapter", methodName = "get") to true, - - MethodDeclaration(className = "ConstantLabelCandidateDescriptorProvider", methodName = "getDescriptor") to true, - MethodDeclaration(className = "DefaultFoldingEdgeConverter", methodName = "addFoldingEdge") to true, - MethodDeclaration(className = "DefaultGraph", methodName = "getParent") to true, - MethodDeclaration(className = "DescriptorWrapperLabelModel", methodName = "getDescriptor") to true, MethodDeclaration(className = "ExcludingFoldingEdgeConverter", methodName = "addFoldingEdge") to true, MethodDeclaration(className = "FilteredGraphWrapper", methodName = "getParent") to true, - MethodDeclaration(className = "FoldingEdgeConverterBase", methodName = "addFoldingEdge") to true, MethodDeclaration(className = "GraphWrapperBase", methodName = "getParent") to true, - MethodDeclaration(className = "MapperRegistry", methodName = "getMapper") to true, - MethodDeclaration(className = "MapperRegistry", methodName = "getMapperMetadata") to true, MethodDeclaration(className = "MergingFoldingEdgeConverter", methodName = "addFoldingEdge") to true, MethodDeclaration(className = "ChildParseContext", methodName = "getCurrent") to true, @@ -302,132 +153,15 @@ internal val METHOD_NULLABILITY_MAP = mapOf( MethodDeclaration(className = "MapperInputHandler", methodName = "parseDataCore") to true, MethodDeclaration(className = "MapperOutputHandler", methodName = "getValue") to true, - MethodDeclaration(className = "GraphElementIdAcceptor", methodName = "resolveNode") to true, - MethodDeclaration(className = "GraphElementIdAcceptor", methodName = "resolveGraph") to true, - MethodDeclaration(className = "GraphElementIdAcceptor", methodName = "resolvePort") to true, - MethodDeclaration(className = "GraphElementIdAcceptor", methodName = "resolveEdge") to true, MethodDeclaration(className = "GraphMLParseValueSerializerContext", methodName = "getValueSerializerFor") to true, MethodDeclaration(className = "GraphMLWriteValueSerializerContext", methodName = "getValueSerializerFor") to true, - MethodDeclaration(className = "IncrementalHintItemMapping", methodName = "provideMapperForContext") to true, MethodDeclaration(className = "NodeDropInputMode", methodName = "getDropTarget") to true, - MethodDeclaration(className = "HierarchicLayoutCore", methodName = "createGrouping") to true, - MethodDeclaration(className = "HierarchicLayoutCore", methodName = "createPortConstraintOptimizer") to true, - MethodDeclaration(className = "HierarchicLayoutCore", methodName = "getAlgorithmProperty") to true, - MethodDeclaration(className = "HierarchicLayoutCore", methodName = "getEdgeLayoutDescriptors") to true, - MethodDeclaration(className = "HierarchicLayoutCore", methodName = "getIncrementalHints") to true, - MethodDeclaration(className = "HierarchicLayoutCore", methodName = "getNodeLayoutDescriptors") to true, - MethodDeclaration(className = "HierarchicLayoutCore", methodName = "getSwimLaneDescriptors") to true, - MethodDeclaration(className = "INodeData", methodName = "getNormalizedBorderLine") to true, - - MethodDeclaration(className = "FixNodeLayoutStage", methodName = "calculateFixPoint") to true, - MethodDeclaration(className = "LayoutGroupingSupport", methodName = "getParent") to true, - MethodDeclaration(className = "LayoutGroupingSupport", methodName = "getRepresentative") to true, - MethodDeclaration(className = "IIntersectionCalculator", methodName = "calculateIntersectionPoint") to true, - MethodDeclaration(className = "PartitionGrid", methodName = "getColumn") to true, - MethodDeclaration(className = "PartitionGrid", methodName = "getRow") to true, - - MethodDeclaration(className = "LayoutContext", methodName = "getOriginalEdge") to true, - MethodDeclaration(className = "LayoutContext", methodName = "getOriginalNode") to true, - MethodDeclaration(className = "LayoutContext", methodName = "getPageEdge") to true, - MethodDeclaration(className = "LayoutContext", methodName = "getPageNode") to true, - - MethodDeclaration(className = "BevelNodeStyleRenderer", methodName = "createVisual") to true, - MethodDeclaration(className = "BevelNodeStyleRenderer", methodName = "updateVisual") to true, - MethodDeclaration(className = "CollapsibleNodeStyleDecoratorRenderer", methodName = "createVisual") to true, - MethodDeclaration(className = "CollapsibleNodeStyleDecoratorRenderer", methodName = "updateVisual") to true, - MethodDeclaration(className = "DefaultLabelStyleRenderer", methodName = "createVisual") to true, - MethodDeclaration(className = "DefaultLabelStyleRenderer", methodName = "updateVisual") to true, - MethodDeclaration(className = "GeneralPathNodeStyleRenderer", methodName = "createVisual") to true, - MethodDeclaration(className = "GeneralPathNodeStyleRenderer", methodName = "updateVisual") to true, - MethodDeclaration(className = "IconLabelStyleRenderer", methodName = "createVisual") to true, - MethodDeclaration(className = "IconLabelStyleRenderer", methodName = "updateVisual") to true, - MethodDeclaration(className = "ImageNodeStyleRenderer", methodName = "createVisual") to true, - MethodDeclaration(className = "ImageNodeStyleRenderer", methodName = "updateVisual") to true, - MethodDeclaration(className = "PanelNodeStyleRenderer", methodName = "createVisual") to true, - MethodDeclaration(className = "PanelNodeStyleRenderer", methodName = "updateVisual") to true, - MethodDeclaration(className = "PathBasedEdgeStyleRenderer", methodName = "createVisual") to true, - MethodDeclaration(className = "PathBasedEdgeStyleRenderer", methodName = "updateVisual") to true, - MethodDeclaration(className = "ShapeNodeStyleRenderer", methodName = "createVisual") to true, - MethodDeclaration(className = "ShapeNodeStyleRenderer", methodName = "updateVisual") to true, - MethodDeclaration(className = "ShinyPlateNodeStyleRenderer", methodName = "createVisual") to true, - MethodDeclaration(className = "ShinyPlateNodeStyleRenderer", methodName = "updateVisual") to true, - MethodDeclaration(className = "TableNodeStyleRenderer", methodName = "createVisual") to true, - MethodDeclaration(className = "TableNodeStyleRenderer", methodName = "updateVisual") to true, - MethodDeclaration(className = "TemplateLabelStyleRenderer", methodName = "createVisual") to true, - MethodDeclaration(className = "TemplateLabelStyleRenderer", methodName = "updateVisual") to true, - MethodDeclaration(className = "TemplateNodeStyleRenderer", methodName = "createVisual") to true, - MethodDeclaration(className = "TemplateNodeStyleRenderer", methodName = "updateVisual") to true, - MethodDeclaration(className = "TemplatePortStyleRenderer", methodName = "createVisual") to true, - MethodDeclaration(className = "TemplatePortStyleRenderer", methodName = "updateVisual") to true, - MethodDeclaration(className = "TemplateStripeStyleRenderer", methodName = "createVisual") to true, - MethodDeclaration(className = "TemplateStripeStyleRenderer", methodName = "updateVisual") to true, - MethodDeclaration(className = "GridVisualCreator", methodName = "createVisual") to true, - MethodDeclaration(className = "GridVisualCreator", methodName = "updateVisual") to true, - MethodDeclaration(className = "VoidVisualCreator", methodName = "createVisual") to true, - MethodDeclaration(className = "VoidVisualCreator", methodName = "updateVisual") to true, - - MethodDeclaration(className = "GraphOverviewSvgVisualCreator", methodName = "createVisual") to true, - MethodDeclaration(className = "GraphOverviewSvgVisualCreator", methodName = "updateVisual") to true, - MethodDeclaration(className = "GraphOverviewCanvasVisualCreator", methodName = "createVisual") to true, - MethodDeclaration(className = "GraphOverviewCanvasVisualCreator", methodName = "updateVisual") to true, - MethodDeclaration(className = "GraphOverviewWebGLVisualCreator", methodName = "createVisual") to true, - MethodDeclaration(className = "GraphOverviewWebGLVisualCreator", methodName = "updateVisual") to true, - - MethodDeclaration(className = "BevelNodeStyleRenderer", methodName = "getOutline") to true, - MethodDeclaration(className = "CollapsibleNodeStyleDecoratorRenderer", methodName = "getOutline") to true, - MethodDeclaration(className = "GeneralPathNodeStyleRenderer", methodName = "getOutline") to true, - MethodDeclaration(className = "ImageNodeStyleRenderer", methodName = "getOutline") to true, - MethodDeclaration(className = "PanelNodeStyleRenderer", methodName = "getOutline") to true, - MethodDeclaration(className = "ShapeNodeStyleRenderer", methodName = "getOutline") to true, - MethodDeclaration(className = "ShinyPlateNodeStyleRenderer", methodName = "getOutline") to true, - MethodDeclaration(className = "TableNodeStyleRenderer", methodName = "getOutline") to true, - MethodDeclaration(className = "TemplateNodeStyleRenderer", methodName = "getOutline") to true, - MethodDeclaration(className = "VoidShapeGeometry", methodName = "getOutline") to true, - - MethodDeclaration(className = "ArcEdgeStyleRenderer", methodName = "getTargetArrow") to true, - MethodDeclaration(className = "ArcEdgeStyleRenderer", methodName = "getSourceArrow") to true, - MethodDeclaration(className = "PolylineEdgeStyleRenderer", methodName = "getTargetArrow") to true, - MethodDeclaration(className = "PolylineEdgeStyleRenderer", methodName = "getSourceArrow") to true, - - MethodDeclaration(className = "ArcEdgeStyleRenderer", methodName = "getStroke") to true, - MethodDeclaration(className = "PathBasedEdgeStyleRenderer", methodName = "getObstacles") to true, - MethodDeclaration(className = "PathBasedEdgeStyleRenderer", methodName = "getPath") to true, - MethodDeclaration(className = "PolylineEdgeStyleRenderer", methodName = "getStroke") to true, - MethodDeclaration(className = "ColorExtension", methodName = "provideValue") to true, - MethodDeclaration(className = "EdgeDecorationInstaller", methodName = "addCanvasObject") to true, - MethodDeclaration(className = "EdgeFocusIndicatorInstaller", methodName = "getStroke") to true, - MethodDeclaration(className = "EdgeFocusIndicatorInstaller", methodName = "getBendDrawing") to true, - MethodDeclaration(className = "EdgeHighlightIndicatorInstaller", methodName = "getStroke") to true, - MethodDeclaration(className = "EdgeHighlightIndicatorInstaller", methodName = "getBendDrawing") to true, - MethodDeclaration(className = "EdgeSelectionIndicatorInstaller", methodName = "getStroke") to true, - MethodDeclaration(className = "EdgeSelectionIndicatorInstaller", methodName = "getBendDrawing") to true, - - MethodDeclaration(className = "EdgeStyleDecorationInstaller", methodName = "addCanvasObject") to true, MethodDeclaration(className = "FocusIndicatorManager", methodName = "add") to true, MethodDeclaration(className = "HighlightIndicatorManager", methodName = "getInstaller") to true, - MethodDeclaration(className = "LabelStyleDecorationInstaller", methodName = "addCanvasObject") to true, - MethodDeclaration(className = "NodeStyleDecorationInstaller", methodName = "addCanvasObject") to true, - MethodDeclaration(className = "OrientedRectangleIndicatorInstaller", methodName = "addCanvasObject") to true, - MethodDeclaration(className = "PointSelectionIndicatorInstaller", methodName = "addCanvasObject") to true, - MethodDeclaration(className = "PortStyleDecorationInstaller", methodName = "addCanvasObject") to true, - MethodDeclaration(className = "RectangleIndicatorInstaller", methodName = "addCanvasObject") to true, - - MethodDeclaration(className = "ITreeLayoutNodePlacer", methodName = "createProcessor") to true, - MethodDeclaration(className = "AssistantNodePlacer", methodName = "createProcessor") to true, - MethodDeclaration(className = "CompactNodePlacer", methodName = "createProcessor") to true, - MethodDeclaration(className = "DelegatingNodePlacer", methodName = "createProcessor") to true, - MethodDeclaration(className = "DendrogramNodePlacer", methodName = "createProcessor") to true, - MethodDeclaration(className = "FreeNodePlacer", methodName = "createProcessor") to true, - MethodDeclaration(className = "GroupedNodePlacer", methodName = "createProcessor") to true, - MethodDeclaration(className = "LayeredNodePlacer", methodName = "createProcessor") to true, - MethodDeclaration(className = "LeafNodePlacer", methodName = "createProcessor") to true, - MethodDeclaration(className = "LeftRightNodePlacer", methodName = "createProcessor") to true, - MethodDeclaration(className = "NodePlacerBase", methodName = "createProcessor") to true, - MethodDeclaration(className = "RotatableNodePlacerBase", methodName = "createProcessor") to true ) internal val DUPLICATED_PROPERTIES = listOf( @@ -453,11 +187,6 @@ internal val DUPLICATED_PROPERTIES = listOf( PropertyDeclaration(className = "Rect", propertyName = "topLeft"), PropertyDeclaration(className = "Rect", propertyName = "topRight"), - PropertyDeclaration(className = "DefaultGraph", propertyName = "undoEngineEnabled"), - - PropertyDeclaration(className = "DefaultSelectionModel", propertyName = "size"), - PropertyDeclaration(className = "GraphSelection", propertyName = "size"), - PropertyDeclaration(className = "ISelectionModel", propertyName = "size"), PropertyDeclaration(className = "StripeSelection", propertyName = "size") ) @@ -465,6 +194,7 @@ internal val DUPLICATED_METHODS = listOf( MethodDeclaration(className = "YList", methodName = "elementAt"), MethodDeclaration(className = "YList", methodName = "includes"), MethodDeclaration(className = "YList", methodName = "toArray"), + MethodDeclaration(className = "IEnumerable", methodName = "filter"), MethodDeclaration(className = "ICollection", methodName = "includes"), MethodDeclaration(className = "List", methodName = "includes"), @@ -472,7 +202,34 @@ internal val DUPLICATED_METHODS = listOf( MethodDeclaration(className = "HashMap", methodName = "includes"), MethodDeclaration(className = "ObservableCollection", methodName = "includes"), - MethodDeclaration(className = "YRectangle", methodName = "compareTo") + MethodDeclaration(className = "GraphMLIOHandler", methodName = "addTypeInformation"), +) + +internal val INVALID_METHOD_OVERRIDES = listOf( + MethodDeclaration(className = "Rect", methodName = "toSize"), + MethodDeclaration(className = "MutableRectangle", methodName = "toRect"), + MethodDeclaration(className = "YList", methodName = "includes"), + MethodDeclaration(className = "List", methodName = "includes"), + MethodDeclaration(className = "ICollection", methodName = "includes"), + MethodDeclaration(className = "HashMap", methodName = "includes"), + MethodDeclaration(className = "ObservableCollection", methodName = "includes"), + MethodDeclaration(className = "StripeSelection", methodName = "includes"), +) + +internal val INVALID_PROPERTY_OVERRIDES = listOf( + PropertyDeclaration(className = "ResultItemMapping", propertyName = "size"), + PropertyDeclaration(className = "ResultItemCollection", propertyName = "size"), + PropertyDeclaration(className = "ListEnumerable", propertyName = "size"), + PropertyDeclaration(className = "ICollection", propertyName = "size"), + PropertyDeclaration(className = "HashMap", propertyName = "size"), + PropertyDeclaration(className = "IListEnumerable", propertyName = "size"), + PropertyDeclaration(className = "List", propertyName = "size"), + PropertyDeclaration(className = "ObservableCollection", propertyName = "size"), + PropertyDeclaration(className = "YList", propertyName = "size"), + PropertyDeclaration(className = "StripeSelection", propertyName = "size"), + PropertyDeclaration(className = "OrientedRectangle", propertyName = "bounds"), + PropertyDeclaration(className = "OrientedRectangle", propertyName = "center"), + PropertyDeclaration(className = "Graph", propertyName = "undoEngineEnabled"), ) internal val SYSTEM_FUNCTIONS = listOf( diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/LabelModelParameterHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/LabelModelParameterHacks.kt index f64a17193..5f500b572 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/LabelModelParameterHacks.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/LabelModelParameterHacks.kt @@ -4,44 +4,14 @@ import com.github.turansky.yfiles.ILABEL_MODEL_PARAMETER internal fun applyLabelModelParameterHacks(source: Source) { source.types( - "ILabelLayout", - "LabelLayoutBase", - - "LabelCandidate" - ).forEach { it.property("modelParameter")[TYPE] = ILABEL_MODEL_PARAMETER } + "ExtendedNodeLabelCandidate" + ).forEach { it.property("parameter")[TYPE] = ILABEL_MODEL_PARAMETER } source.types( - "LabelCandidate", - - "EdgeLabelCandidate", "ExtendedEdgeLabelCandidate", - - "NodeLabelCandidate", "ExtendedNodeLabelCandidate", - - "LayoutGraphUtilities" ).flatMap { it.optFlatMap(CONSTRUCTORS) + it.optFlatMap(METHODS) } .optFlatMap(PARAMETERS) .filter { it[NAME] == "param" } .forEach { it[TYPE] = ILABEL_MODEL_PARAMETER } - - source.types( - "IEdgeLabelLayoutModel", - "DiscreteEdgeLabelLayoutModel", - "FreeEdgeLabelLayoutModel", - "SliderEdgeLabelLayoutModel", - - "INodeLabelLayoutModel", - "DiscreteNodeLabelLayoutModel", - "FreeNodeLabelLayoutModel" - ).onEach { it.property("defaultParameter")[TYPE] = ILABEL_MODEL_PARAMETER } - .onEach { it.method("createModelParameter")[RETURNS][TYPE] = ILABEL_MODEL_PARAMETER } - .flatMap(METHODS) - .flatMap(PARAMETERS) - .filter { it[NAME] == "parameter" } - .forEach { it[TYPE] = ILABEL_MODEL_PARAMETER } - - source.type("DiscreteEdgeLabelLayoutModel") - .method("createPositionParameter") - .get(RETURNS)[TYPE] = ILABEL_MODEL_PARAMETER } diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/LayoutStrictTypes.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/LayoutStrictTypes.kt deleted file mode 100644 index b27c0c673..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/LayoutStrictTypes.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.IENUMERABLE -import com.github.turansky.yfiles.JS_ANY -import com.github.turansky.yfiles.JS_OBJECT -import com.github.turansky.yfiles.YOBJECT -import com.github.turansky.yfiles.json.removeAllObjects - -internal fun applyLayoutStrictTypes(source: Source) { - source.types("CopiedLayoutGraph", "LayoutGraphAdapter") - .flatMap(METHODS) - .flatMap { it.optFlatMap(PARAMETERS) + it.returnsSequence() } - .filter { it[TYPE] == JS_OBJECT } - .forEach { it[TYPE] = YOBJECT } - - source.type("LayoutGraphAdapter") - .let { type -> sequenceOf("nodeObjects", "edgeObjects").map { type.method(it) } } - .map { it[RETURNS] } - .onEach { check(it[TYPE] == "$IENUMERABLE<$JS_ANY>") } - .forEach { it[TYPE] = "$IENUMERABLE<$YOBJECT>" } - - source.type("LayoutGraphUtilities")[METHODS].removeAllObjects { - it[ID] == "LayoutGraphUtilities-method-getBoundingBox(yfiles.layout.LayoutGraph,yfiles.algorithms.Node)" - } -} diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ListCellHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ListCellHacks.kt index 2af83cf34..9118f4e65 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ListCellHacks.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ListCellHacks.kt @@ -1,18 +1,16 @@ package com.github.turansky.yfiles.correction -import com.github.turansky.yfiles.EDGE -import com.github.turansky.yfiles.YOBJECT import org.json.JSONObject private const val LIST_CELL = "yfiles.algorithms.ListCell" internal fun applyListCellHacks(source: Source) { source.type("ListCell") { - setSingleTypeParameter(bound = YOBJECT) + setSingleTypeParameter() property("info")[TYPE] = "T" - flatMap(METHODS) + optFlatMap(METHODS) .forEach { it[RETURNS].addGeneric("T") } } @@ -20,17 +18,6 @@ internal fun applyListCellHacks(source: Source) { .getTypeHolders() .filter { it[TYPE] == LIST_CELL } .forEach { it.addGeneric("T") } - - source.type("BorderLine") - .flatMap(METHODS) - .filter { it[NAME] == "getValueAt" } - .flatMap(PARAMETERS) - .single { it[TYPE] == LIST_CELL } - .addGeneric("BorderLineSegment") - - source.type("INodeData") - .property("firstSameLayerEdgeCell") - .addGeneric(EDGE) } private fun JSONObject.getTypeHolders(): Sequence = diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ListHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ListHacks.kt index 9b201404f..bdb2a809d 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ListHacks.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ListHacks.kt @@ -12,55 +12,17 @@ private fun list(generic: String): String = "yfiles.collections.IList<$generic>" internal fun applyListHacks(source: Source) { - fixProperty(source) fixMethodParameter(source) - fixReturnType(source) -} - -private fun fixProperty(source: Source) { - sequenceOf( - Triple("CompositeLayoutStage", "layoutStages", "yfiles.layout.ILayoutStage"), - - Triple("EdgeRouter", "registeredPartitionExtensions", "yfiles.router.IGraphPartitionExtension"), - Triple("EdgeRouter", "registeredPathSearchExtensions", "yfiles.router.PathSearchExtension"), - - Triple("EdgeRouterEdgeLayoutDescriptor", "intermediateRoutingPoints", YPOINT), - Triple("SegmentGroup", "segmentInfos", SEGMENT_INFO), - - Triple("RotatableNodePlacerBase", "createdChildren", NODE) - ).forEach { (className, propertyName, generic) -> - source.type(className) - .property(propertyName) - .fixTypeGeneric(generic) - } } private fun fixMethodParameter(source: Source) { source.types( - "YPointPath", - - "ChannelBasedPathRouting", - "DynamicObstacleDecomposition", - "GraphPartition", - "GraphPartitionExtensionAdapter", - - "IDecompositionListener", - "IEnterIntervalCalculator", - "IObstaclePartition", - - "EdgeRouterPath", "PathSearchExtension", - "SegmentGroup", - "SegmentInfo", - - "RootNodeAlignment" ).flatMap { it.optFlatMap(CONSTRUCTORS) + it.optFlatMap(METHODS) } .flatMap { it.optFlatMap(PARAMETERS) } .filter { it[TYPE] in DEFAULT_LISTS } .forEach { val generic = when (it[NAME]) { - "l" -> YPOINT - "subCells" -> PARTITION_CELL "obstacles" -> OBSTACLE "allEnterIntervals" -> "yfiles.router.OrthogonalInterval" @@ -77,40 +39,6 @@ private fun fixMethodParameter(source: Source) { } } -private fun fixReturnType(source: Source) { - source.types( - "IPartition", - "IObstaclePartition", - "DynamicObstacleDecomposition", - "GraphPartition" - ).flatMap(METHODS) - .forEach { - val generic = when (it[NAME]) { - "getCells", - "getCellsForNode", - "getCellsForObstacle", - "getNeighbors", - -> PARTITION_CELL - - "getNodes" -> NODE - "getObstacles" -> OBSTACLE - - else -> return@forEach - } - - it.fixReturnTypeGeneric(generic) - } - - source.type("YPointPath") - .method("toList") - .fixReturnTypeGeneric(YPOINT) -} - -private fun JSONObject.fixReturnTypeGeneric(generic: String) { - get(RETURNS) - .fixTypeGeneric(generic) -} - private fun JSONObject.fixTypeGeneric(generic: String) { require(get(TYPE) in DEFAULT_LISTS) diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/MarkupExtensionHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/MarkupExtensionHacks.kt new file mode 100644 index 000000000..0ddc3e6d0 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/MarkupExtensionHacks.kt @@ -0,0 +1,20 @@ +package com.github.turansky.yfiles.correction + +import org.json.JSONObject + +internal fun fixMarkupExtensions(source: Source) { + val basis = source.type("ColorExtension") + .flatMap(METHODS) + .first { it[NAME] == "provideValue" } + + source.types( + "CompositeEdgeStyleExtension", + "CompositeNodeStyleExtension", + "CompositeLabelStyleExtension", + "CompositePortStyleExtension" + ).forEach { + val obj = JSONObject(basis.toString(0)) + obj[ID] = "${it[NAME]}-method-provideValue" + it.set(METHODS, listOf(obj)) + } +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/MementoHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/MementoHacks.kt deleted file mode 100644 index 6619c4a48..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/MementoHacks.kt +++ /dev/null @@ -1,65 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.GeneratorContext -import com.github.turansky.yfiles.JS_ANY -import com.github.turansky.yfiles.json.get - -private const val HIERARCHIC_MEMENTOS = "yfiles.hierarchic.Mementos" -private const val TREE_MEMENTOS = "yfiles.tree.Mementos" - -private const val LAYER_CONSTRAINTS_MEMENTO = "yfiles.hierarchic.LayerConstraintsMemento" -private const val SEQUENCE_CONSTRAINTS_MEMENTO = "yfiles.hierarchic.SequenceConstraintsMemento" - -private const val COMPACT_STRATEGY_MEMENTO = "yfiles.tree.CompactStrategyMemento" - -internal fun generateMementoUtils(context: GeneratorContext) { - // language=kotlin - context[HIERARCHIC_MEMENTOS] = """ - @JsName("Object") - external class LayerConstraintsMemento - private constructor() - - @JsName("Object") - external class SequenceConstraintsMemento - private constructor() - """.trimIndent() - - // language=kotlin - context[TREE_MEMENTOS] = """ - @JsName("Object") - external class CompactStrategyMemento - private constructor() - """.trimIndent() -} - -internal fun applyMementoHacks(source: Source) { - source.type("ILayerConstraintFactory") - .property("memento")[TYPE] = LAYER_CONSTRAINTS_MEMENTO - - source.type("ISequenceConstraintFactory") - .property("memento")[TYPE] = SEQUENCE_CONSTRAINTS_MEMENTO - - source.type("HierarchicLayout") - .get(CONSTANTS).apply { - sequenceOf( - "LAYER_CONSTRAINTS_MEMENTO_DP_KEY" to LAYER_CONSTRAINTS_MEMENTO, - "SEQUENCE_CONSTRAINTS_MEMENTO_DP_KEY" to SEQUENCE_CONSTRAINTS_MEMENTO - ).forEach { (name, typeParameter) -> - get(name).also { - require(it[TYPE] == graphDpKey(JS_ANY)) - it[TYPE] = graphDpKey(typeParameter) - } - } - } - - source.type("TreeLayoutData") - .property("compactNodePlacerStrategyMementos") - .also { it.replaceInType(",$JS_ANY>", ",$COMPACT_STRATEGY_MEMENTO>") } - - source.type("CompactNodePlacer") - .constant("STRATEGY_MEMENTO_DP_KEY") - .also { - require(it[TYPE] == nodeDpKey(JS_ANY)) - it[TYPE] = nodeDpKey(COMPACT_STRATEGY_MEMENTO) - } -} diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/NodeTypeHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/NodeTypeHacks.kt deleted file mode 100644 index c3313951e..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/NodeTypeHacks.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.GeneratorContext -import com.github.turansky.yfiles.JS_ANY - -internal const val INODE_TYPE = "yfiles.layout.INodeType" - -internal fun generateNodeTypeUtils(context: GeneratorContext) { - // language=kotlin - context[INODE_TYPE] = - """ - external interface INodeType - - inline fun INodeType(source:Any):INodeType = - source.unsafeCast() - """.trimIndent() -} - -internal fun applyNodeTypeHacks(source: Source) { - source.types() - .optFlatMap(PROPERTIES) - .filter { it[NAME] in "nodeTypes" } - .forEach { it.replaceInType(",$JS_ANY>", ",$INODE_TYPE>") } -} diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/NullabilityHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/NullabilityHacks.kt index 527d109b3..f410715e8 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/NullabilityHacks.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/NullabilityHacks.kt @@ -13,11 +13,6 @@ internal fun fixNullability(source: Source) { fixAlgorithmsNullability(source) fixLayoutNullability(source) fixCommonLayoutNullability(source) - fixStageNullability(source) - fixMultipageNullability(source) - fixHierarchicNullability(source) - fixRouterNullability(source) - fixTreeNullability(source) } private fun fixConstructorNullability(source: Source) { @@ -27,61 +22,16 @@ private fun fixConstructorNullability(source: Source) { ) source.types( - "DpKeyBase", - "EdgeDpKey", - "GraphDpKey", - "GraphObjectDpKey", - "IEdgeLabelLayoutDpKey", - "ILabelLayoutDpKey", - "INodeLabelLayoutDpKey", - "NodeDpKey", - "MapEntry", - "GraphWrapperBase", - "CompositeLayoutStage", - - "AspectRatioComponentLayerer", - "ConstraintIncrementalLayerer" ).flatMap { it.flatMap(CONSTRUCTORS) } .optFlatMap(PARAMETERS) .filterNot { it[TYPE] in excludedTypes } .forEach { it.changeNullability(false) } - source.type("MultiComponentLayerer") - .flatMap(CONSTRUCTORS) - .single() - .firstParameter - .changeNullability(false) - - source.types( - "LookupDecorator", - "StripeDecorator", - - "MapperInputHandler", - "MapperOutputHandler", - "InputHandlerBase", - "OutputHandlerBase", - - "DataMapAdapter", - "MapperDataProviderAdapter", - - "PathBasedEdgeStyleRenderer", - - "ItemModelManager", - "CollectionModelManager" - ).flatMap { it.flatMap(CONSTRUCTORS) } - .flatMap(PARAMETERS) - .filter { it[TYPE].startsWith(YCLASS) } - .filter { it[NAME] != "deserializerTargetType" } - .forEach { it.changeNullability(false) } - source.types( "ItemClickedEventArgs", - "ItemTappedEventArgs", "TableItemClickedEventArgs", - "TableItemTappedEventArgs", - "ItemSelectionChangedEventArgs" ).flatMap { it.flatMap(CONSTRUCTORS) } .map { it.firstParameter } .forEach { it.changeNullability(false) } @@ -179,7 +129,9 @@ private fun fixCollectionsNullability(source: Source) { .optFlatMap(PARAMETERS) .filterNot { it[TYPE] in excludedTypes } .filterNot { it[NAME] in excludedParameters } - .forEach { it.changeNullability(false) } + .forEach { + it.changeNullability(false) + } source.type("IEnumerable") .method("indexOf") @@ -205,10 +157,10 @@ private fun fixGraphNullability(source: Source) { ) source.types( - "ISelectionModel", - "DefaultSelectionModel", - "GraphSelection", - "StripeSelection", +// "ISelectionModel", +// "DefaultSelectionModel", +// "GraphSelection", +// "StripeSelection", "GroupingSupport" ).flatMap { it.flatMap(METHODS) } @@ -282,17 +234,6 @@ private fun fixAlgorithmsNullability(source: Source) { "create" ) - val excludedParameters = setOf( - "edgeCosts", - "edgeWeights", - - "defaultValue", - "dualsNM", - - "revMap", - "reverseEdgeMap" - ) - val excludedTypes = setOf( "boolean", "number", @@ -302,40 +243,6 @@ private fun fixAlgorithmsNullability(source: Source) { "yfiles.algorithms.GraphElementInsertion" ) - source.types( - "AbortHandler", - "BipartitionAlgorithm", - "CentralityAlgorithm", - "Comparers", - "Cursors", - "CycleAlgorithm", - "DataProviders", - "Geom", - "GraphChecker", - "GraphConnectivity", - "GroupAlgorithm", - "IndependentSetAlgorithm", - "IntersectionAlgorithm", - "NetworkFlowAlgorithm", - "NodeOrderAlgorithm", - "PathAlgorithm", - "RankAssignmentAlgorithm", - "SortingAlgorithm", - "ShortestPathAlgorithm", - "SpanningTreeAlgorithm", - "TransitivityAlgorithm", - "TreeAlgorithm", - "TriangulationAlgorithm" - ).flatMap(METHODS) - .filter { STATIC in it[MODIFIERS] } - .filter { it.has(PARAMETERS) } - .filterNot { it[ID] in EXCLUDED_METHOD_IDS } - .filterNot { it[NAME] in excludedMethods } - .flatMap(PARAMETERS) - .filterNot { it[NAME] in excludedParameters } - .filterNot { it[TYPE] in excludedTypes } - .forEach { it.changeNullability(false) } - fun getAffectedMethods(type: JSONObject): Sequence = type.flatMap(METHODS) .plus(type.optFlatMap(CONSTRUCTORS)) @@ -343,63 +250,16 @@ private fun fixAlgorithmsNullability(source: Source) { .filterNot { it[NAME] in excludedMethods } source.types( - "AffineLine", - "BorderLine", - "Dendrogram", - "DfsAlgorithm", - "GraphPartitionManager", - "IIntersectionHandler", - "INodeDistanceProvider", - "INodeSequencer", "LayoutGraphHider", "LineSegment", "PlanarEmbedding", - "Point2D", - "Rectangle2D", - "YPoint", - "YRectangle" ).flatMap { getAffectedMethods(it) } .optFlatMap(PARAMETERS) .filterNot { it[TYPE] in excludedTypes } .forEach { it.changeNullability(false) } - - val yMethodIds = setOf( - "YOrientedRectangle-method-contains(yfiles.algorithms.YOrientedRectangle,number,number,number)", - "YOrientedRectangle-constructor-YOrientedRectangle(yfiles.algorithms.YPoint,yfiles.algorithms.YDimension)", - "YOrientedRectangle-constructor-YOrientedRectangle(yfiles.algorithms.YPoint,yfiles.algorithms.YDimension,yfiles.algorithms.YVector)", - - "YVector-method-add" - ) - - val yMethods = setOf( - "adoptValues", - "calcPoints", - "calcPointsInDouble", - "intersectionPoint", - - "angle", - "getNormal", - "orthoNormal", - "rightOf", - "scalarProduct" - ) - - source.types( - "YOrientedRectangle", - "YVector" - ).flatMap { it.flatMap(METHODS) + it.flatMap(CONSTRUCTORS) } - .filter { it[ID] in yMethodIds || it.get(NAME) in yMethods } - .flatMap(PARAMETERS) - .filterNot { it[TYPE] in excludedTypes } - .forEach { it.changeNullability(false) } } private fun fixLayoutNullability(source: Source) { - val EXCLUDED_METHOD_IDS = setOf( - "LayoutGraphUtilities-method-getBoundingBox(yfiles.layout.LayoutGraph,yfiles.algorithms.Node)", - "LayoutGraphUtilities-method-getBoundingBox(yfiles.layout.LayoutGraph,yfiles.algorithms.Edge)" - ) - val excludedMethods = setOf( "getLabelLayout", "getLayout", @@ -436,22 +296,6 @@ private fun fixLayoutNullability(source: Source) { "yfiles.layout.PortDirections" ) - source.types( - "GraphTransformer", - "LayoutGraphUtilities", - "NodeHalo", - "NormalizeGraphElementOrderStage", - "PortConstraint", - "Swimlanes" - ).flatMap(METHODS) - .filter { STATIC in it[MODIFIERS] } - .filter { it.has(PARAMETERS) } - .filterNot { it[ID] in EXCLUDED_METHOD_IDS } - .filterNot { it[NAME] in excludedMethods } - .flatMap(PARAMETERS) - .filterNot { it[TYPE] in excludedTypes } - .forEach { it.changeNullability(false) } - fun getAffectedMethods(type: JSONObject): Sequence = type.optFlatMap(METHODS) .plus(type.optFlatMap(CONSTRUCTORS)) @@ -459,35 +303,7 @@ private fun fixLayoutNullability(source: Source) { source.types( "ILayoutGroupBoundsCalculator", - "InsetsGroupBoundsCalculator", - "MinimumSizeGroupBoundsCalculator", - - "EdgeLabelOrientationSupport", - "LayoutGroupingSupport", - "PartitionGrid", - "PortConstraintConfigurator", - "PortCandidateSet", - "ItemCollectionMapping", - - "INodeLabelLayoutModel", - "DiscreteNodeLabelLayoutModel", - "FreeNodeLabelLayoutModel", - - "IEdgeLabelLayoutModel", - "DiscreteEdgeLabelLayoutModel", - "FreeEdgeLabelLayoutModel", - "SliderEdgeLabelLayoutModel", - "LabelCandidate", - "EdgeLabelCandidate", - "NodeLabelCandidate", - - "IIntersectionCalculator", - "IPortCandidateMatcher", - - "IProfitModel", - "SimpleProfitModel", - "ExtendedLabelCandidateProfitModel" ).flatMap { getAffectedMethods(it) } .optFlatMap(PARAMETERS) .filterNot { it[TYPE] in excludedTypes } @@ -512,16 +328,10 @@ private fun fixCommonLayoutNullability(source: Source) { source.types( "SequentialLayout", - "LabelingBase", - "MISLabelingBase", - "MultiPageLayout", "InteractiveOrganicLayout", "OrganicLayout", "PartialLayout", - - "ISeriesParallelLayoutPortAssignment", - "DefaultSeriesParallelLayoutPortAssignment" ).flatMap { getAffectedMethods(it) } .optFlatMap(PARAMETERS) .filterNot { it[TYPE] in excludedTypes } @@ -726,13 +536,7 @@ private fun fixRouterNullability(source: Source) { source.types( "IDynamicDecomposition", - "IDecompositionListener", - "IGraphPartitionExtension", "IPartition", - "IObstaclePartition", - "GraphPartition", - "GraphPartitionExtensionAdapter", - "DynamicObstacleDecomposition", "BusRouterBusDescriptor", "Channel", @@ -757,7 +561,7 @@ private fun fixRouterNullability(source: Source) { "ChannelRoutingTool", "ChannelBasedPathRouting", - "IEnterIntervalCalculator", +// "IEnterIntervalCalculator", "ChannelEdgeRouter", "EdgeRouter", diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/NumberCorrections.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/NumberCorrections.kt index 7e5165231..f58eabcb9 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/NumberCorrections.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/NumberCorrections.kt @@ -45,17 +45,6 @@ private fun JSONObject.correctConstants() { it.replaceInSignature(",$JS_NUMBER>", ",$JS_DOUBLE>") return@forEach } - - val type = it[TYPE] - check(type.endsWith("DpKey<$JS_NUMBER>")) - - val name = it[NAME] - val generic = if ("_ID_" in name || "_INDEX_" in name) { - JS_INT - } else { - JS_DOUBLE - } - it[TYPE] = type.replace("<$JS_NUMBER>", "<$generic>") } } @@ -92,7 +81,7 @@ private val INT_SIZE_CLASSES = setOf( "ICursor", "IEnumerable", "GeneralPath", - "UndoEngine" + "UndoEngine", ) private val DOUBLE_CONSTRUCTOR_CLASSES = setOf( @@ -127,23 +116,100 @@ private fun JSONObject.correctProperties() { .forEach { it[TYPE] = getPropertyType(className, it[NAME]) } } +private val METHOD_MAPPING = mapOf( + MethodDeclaration(className = "MultiPageLayoutContext", methodName = "getPage") to JS_INT, + MethodDeclaration(className = "InteractiveOrganicLayoutData", methodName = "updateNodeCenters") to JS_INT, + MethodDeclaration(className = "InteractiveOrganicNodeHandle", methodName = "getZ") to JS_DOUBLE, + MethodDeclaration(className = "RadialTreeLayout", methodName = "getPreferredChildSectorAngle") to JS_DOUBLE, + MethodDeclaration(className = "YList", methodName = "indexOfCell") to JS_DOUBLE, + MethodDeclaration(className = "LineSegment", methodName = "length") to JS_DOUBLE, + MethodDeclaration(className = "LayoutGraphAlgorithms", methodName = "diameter") to JS_DOUBLE, + MethodDeclaration(className = "LayoutGraphAlgorithms", methodName = "density") to JS_DOUBLE, + MethodDeclaration(className = "LayoutGraphAlgorithms", methodName = "simplexRankAssignment") to JS_DOUBLE, + MethodDeclaration(className = "LayoutGraphAlgorithms", methodName = "clusteringCoefficient") to JS_DOUBLE, + MethodDeclaration(className = "LayoutGraphAlgorithms", methodName = "biconnectedComponentClustering") to JS_INT, + MethodDeclaration(className = "LayoutGraphAlgorithms", methodName = "hierarchicalClustering") to JS_INT, + MethodDeclaration(className = "LayoutGraphAlgorithms", methodName = "kCores") to JS_DOUBLE, + MethodDeclaration(className = "LayoutGraphAlgorithms", methodName = "labelPropagation") to JS_DOUBLE, + MethodDeclaration(className = "LayoutGraphAlgorithms", methodName = "modularity") to JS_DOUBLE, + MethodDeclaration(className = "LayoutGraphAlgorithms", methodName = "minimumCostFlow") to JS_DOUBLE, + MethodDeclaration(className = "LayoutGraphAlgorithms", methodName = "maximumFlow") to JS_DOUBLE, + MethodDeclaration(className = "LayoutGraphAlgorithms", methodName = "maximumFlowMinimumCut") to JS_DOUBLE, + MethodDeclaration(className = "LayoutGraphAlgorithms", methodName = "layerAssignment") to JS_INT, + MethodDeclaration(className = "LayoutGraphAlgorithms", methodName = "getMinimum") to JS_DOUBLE, + MethodDeclaration(className = "FromSketchLayerAssigner", methodName = "getMinimum") to JS_DOUBLE, + MethodDeclaration(className = "FromSketchLayerAssigner", methodName = "getMaximum") to JS_DOUBLE, + MethodDeclaration(className = "BorderLine", methodName = "getMinPosition") to JS_DOUBLE, + MethodDeclaration(className = "BorderLine", methodName = "getMaxPosition") to JS_DOUBLE, + MethodDeclaration(className = "BorderLine", methodName = "getMinValue") to JS_DOUBLE, + MethodDeclaration(className = "BorderLine", methodName = "getMaxValue") to JS_DOUBLE, +) + +private val PARAMETER_MAPPING = mapOf( + (MethodDeclaration(className = "InteractiveOrganicLayoutData", methodName = "updateNodeCenters") to "minMovement") to JS_DOUBLE, + (MethodDeclaration(className = "InteractiveOrganicNodeHandle", methodName = "setCenter3D") to "z") to JS_DOUBLE, +) + +private val PROPERTY_MAPPING = mapOf( + PropertyDeclaration(className = "IEnumerable", propertyName = "size") to JS_INT, + PropertyDeclaration(className = "BalloonLayout", propertyName = "minimumNodeDistance") to JS_INT, + PropertyDeclaration(className = "LineSegment", propertyName = "yIntercept") to JS_INT, + PropertyDeclaration(className = "AffineLine", propertyName = "a") to JS_DOUBLE, + PropertyDeclaration(className = "AffineLine", propertyName = "b") to JS_DOUBLE, + PropertyDeclaration(className = "EdgeSegmentLabelModelParameter", propertyName = "segment") to JS_INT, + PropertyDeclaration(className = "EdgeSegmentPortLocationModelParameter", propertyName = "segment") to JS_INT, + PropertyDeclaration(className = "SmartEdgeLabelModelParameter", propertyName = "segment") to JS_INT, + PropertyDeclaration(className = "CoordinateAssigner", propertyName = "layoutGridCrossingWeight") to JS_DOUBLE, + PropertyDeclaration(className = "FromSketchLayerAssigner", propertyName = "nodeMargin") to JS_DOUBLE, + PropertyDeclaration(className = "CreateEdgeInputMode", propertyName = "startPortCandidateHitRadius") to JS_DOUBLE, + PropertyDeclaration(className = "SnapCircle", propertyName = "startAngle") to JS_DOUBLE, + PropertyDeclaration(className = "SnapCircle", propertyName = "endAngle") to JS_DOUBLE, + PropertyDeclaration(className = "SnapCircle", propertyName = "startAngle") to JS_DOUBLE, + PropertyDeclaration(className = "SnapCircle", propertyName = "endAngle") to JS_DOUBLE, + PropertyDeclaration(className = "BorderLine", propertyName = "minPosition") to JS_DOUBLE, + PropertyDeclaration(className = "BorderLine", propertyName = "maxPosition") to JS_DOUBLE, + PropertyDeclaration(className = "RadialGroupLayout", propertyName = "preferredRootSectorAngle") to JS_DOUBLE, + PropertyDeclaration(className = "InteractiveOrganicLayout", propertyName = "defaultPreferredEdgeLength") to JS_DOUBLE, + PropertyDeclaration(className = "InteractiveOrganicNodeHandle", propertyName = "stress") to JS_DOUBLE, + PropertyDeclaration(className = "InteractiveOrganicNodeHandle", propertyName = "inertia") to JS_DOUBLE, + PropertyDeclaration(className = "OrganicLayout", propertyName = "defaultPreferredEdgeLength") to JS_DOUBLE, + PropertyDeclaration(className = "Interval", propertyName = "minimum") to JS_DOUBLE, + PropertyDeclaration(className = "Interval", propertyName = "maximum") to JS_DOUBLE, + PropertyDeclaration(className = "OrthogonalInterval", propertyName = "minimum") to JS_DOUBLE, + PropertyDeclaration(className = "OrthogonalInterval", propertyName = "maximum") to JS_DOUBLE, + PropertyDeclaration(className = "ParallelEdgeRouter", propertyName = "relativeJoinEndDistanceFactor") to JS_DOUBLE, + PropertyDeclaration(className = "SeriesParallelLayout", propertyName = "parallelSubgraphAlignment") to JS_DOUBLE, + PropertyDeclaration(className = "Arrow", propertyName = "lengthScale") to JS_DOUBLE, + PropertyDeclaration(className = "Arrow", propertyName = "widthScale") to JS_DOUBLE, + PropertyDeclaration(className = "Arrow", propertyName = "lengthScale") to JS_DOUBLE, + PropertyDeclaration(className = "Arrow", propertyName = "widthScale") to JS_DOUBLE, + PropertyDeclaration(className = "RadialTreeLayout", propertyName = "preferredChildSectorAngle") to JS_DOUBLE, + PropertyDeclaration(className = "RadialTreeLayout", propertyName = "preferredRootSectorAngle") to JS_DOUBLE, + PropertyDeclaration(className = "SingleLayerSubtreePlacer", propertyName = "minLastSegmentLength") to JS_DOUBLE, + PropertyDeclaration(className = "SingleLayerSubtreePlacer", propertyName = "minSlope") to JS_DOUBLE, + PropertyDeclaration(className = "SingleLayerSubtreePlacer", propertyName = "minSlopeHeight") to JS_DOUBLE, + PropertyDeclaration(className = "PointerEventArgs", propertyName = "pointerId") to JS_INT, + PropertyDeclaration(className = "PointerEventArgs", propertyName = "pressure") to JS_DOUBLE, + PropertyDeclaration(className = "PointerEventArgs", propertyName = "wheelDeltaY") to JS_DOUBLE, + PropertyDeclaration(className = "PointerEventArgs", propertyName = "wheelDeltaY") to JS_DOUBLE, + PropertyDeclaration(className = "PointerEventArgs", propertyName = "pointerId") to JS_INT, + PropertyDeclaration(className = "PointerEventArgs", propertyName = "pressure") to JS_DOUBLE, +) + private fun getPropertyType(className: String, propertyName: String): String = when { propertyName.endsWith("Count") -> JS_INT + propertyName.endsWith("Index") -> JS_INT + propertyName.endsWith("capacity") -> JS_INT propertyName.endsWith("Cost") -> JS_DOUBLE propertyName.endsWith("Ratio") -> JS_DOUBLE - - propertyName == "size" && className in INT_SIZE_CLASSES -> JS_INT - className == "BalloonLayout" && propertyName == "minimumNodeDistance" -> JS_INT - + propertyName.endsWith("padding") -> JS_DOUBLE + propertyName.endsWith("Padding") -> JS_DOUBLE propertyName.endsWith("Distance") -> JS_DOUBLE - - className == "AffineLine" && (propertyName == "a" || propertyName == "b") -> JS_DOUBLE - + propertyName == "size" && className in INT_SIZE_CLASSES -> JS_INT propertyName in INT_PROPERTIES -> JS_INT propertyName in DOUBLE_PROPERTIES -> JS_DOUBLE - - else -> throw IllegalStateException("Unexpected $className.$propertyName") + else -> PROPERTY_MAPPING[PropertyDeclaration(className, propertyName)] ?: error("Unexpected property: $className.$propertyName") } private fun JSONObject.correctPropertiesGeneric() { @@ -197,7 +263,7 @@ private fun JSONObject.correctMethods() { JS_NUMBER -> returns[TYPE] = getReturnType(className, methodName) "Array<$JS_NUMBER>" -> returns[TYPE] = "Array<$JS_DOUBLE>" "$IENUMERABLE<$JS_NUMBER>" -> { - check(methodName == "ofRange") + check(methodName == "ofRange" || methodName == "ofType") { "methodName=$methodName" } returns[TYPE] = "$IENUMERABLE<$JS_INT>" } } @@ -208,18 +274,17 @@ private fun getReturnType(className: String, methodName: String): String = when { methodName.endsWith("Count") -> JS_INT methodName.endsWith("Components") -> JS_INT - methodName.endsWith("Cost") || methodName.endsWith("Costs") -> JS_DOUBLE - methodName.endsWith("Ratio") -> JS_DOUBLE methodName.endsWith("Distance") -> JS_DOUBLE + methodName.endsWith("Intersection") -> JS_DOUBLE className == "YVector" || className == "LineSegment" && methodName == "length" -> JS_DOUBLE methodName in INT_METHODS -> JS_INT methodName in DOUBLE_METHODS -> JS_DOUBLE - else -> throw IllegalStateException("Unexpected $className.$methodName") + else -> METHOD_MAPPING[MethodDeclaration(className, methodName)] ?: error("Unexpected method: $className.$methodName") } private fun JSONObject.correctMethodParameters() { @@ -281,9 +346,17 @@ private fun getParameterType(className: String, methodName: String, parameterNam parameterName.endsWith("Ratio") -> JS_DOUBLE parameterName.endsWith("Duration") -> JS_DOUBLE parameterName.endsWith("Distance") -> JS_DOUBLE + parameterName.endsWith("Tolerance") -> JS_DOUBLE // added 3.0 + parameterName.endsWith("Width") -> JS_DOUBLE // added 3.0 + parameterName.endsWith("Height") -> JS_DOUBLE // added 3.0 + parameterName.endsWith("Intersection") -> JS_DOUBLE // added 3.0 parameterName.endsWith("Index") -> JS_INT parameterName.endsWith("Count") -> JS_INT + parameterName.endsWith("capacity") -> JS_INT + parameterName.endsWith("size") -> JS_INT + parameterName.endsWith("padding") -> JS_DOUBLE + parameterName.endsWith("Padding") -> JS_DOUBLE parameterName == "a" -> A_MAP.getValue(methodName) @@ -293,7 +366,14 @@ private fun getParameterType(className: String, methodName: String, parameterNam parameterName in DOUBLE_METHOD_PARAMETERS -> JS_DOUBLE parameterName in DOUBLE_PROPERTIES -> JS_DOUBLE - else -> throw IllegalStateException("Unexpected $className.$methodName.$parameterName") + className == "OrthogonalSnapLine" -> JS_DOUBLE + className == "ReshapeRectangleContext" -> JS_DOUBLE + className == "SnapConstraint" -> JS_DOUBLE + className == "GenericLabeling" -> JS_DOUBLE + className == "LayoutGrid" -> JS_DOUBLE + + else -> + PARAMETER_MAPPING[MethodDeclaration(className, methodName) to parameterName] ?: error("Unexpected parameter: $className.$methodName.$parameterName") } private fun getGenericParameterType(className: String, methodName: String, parameterName: String): String { diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ObservableDelegates.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ObservableDelegates.kt index 3b1e96c92..e207d7321 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ObservableDelegates.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ObservableDelegates.kt @@ -6,23 +6,11 @@ import com.github.turansky.yfiles.READ_ONLY_PROPERTY import com.github.turansky.yfiles.READ_WRITE_PROPERTY internal val OBSERVABLE = "yfiles.graph.Observable" -internal val MAKE_OBSERVABLE = "yfiles.styles.Templates.makeObservable" internal fun generateObservableDelegates(context: GeneratorContext) { // language=kotlin context[OBSERVABLE] = - """ - fun $TAG.deepObservable(value: T): IPropertyProvider<$TAG, T> { - check(jsTypeOf(value) == "object") - makeObservable() - return TagPropertyProvider(value) - } - - fun $TAG.observable(initialValue: T): $READ_WRITE_PROPERTY<$TAG, T> { - makeObservable() - return Property(initialValue) - } - + """ fun Any.observable(initialValue: T): $READ_WRITE_PROPERTY { return Property(initialValue) } @@ -83,12 +71,6 @@ internal fun generateObservableDelegates(context: GeneratorContext) { } } - private inline fun $TAG.makeObservable() { - if (!firePropertyChangedDeclared) { - $MAKE_OBSERVABLE(this) - } - } - private fun Any.firePropertyChanged(propertyName: String) { asDynamic().firePropertyChanged(propertyName) } diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ObstacleDataHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ObstacleDataHacks.kt deleted file mode 100644 index 4f3d1b4bf..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ObstacleDataHacks.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.GeneratorContext - -private const val OBSTACLE_DATA = "yfiles.router.ObstacleData" - -internal fun generateObstacleData(context: GeneratorContext) { - // language=kotlin - context[OBSTACLE_DATA] = "external interface ObstacleData" -} - -internal fun applyObstacleDataHacks(source: Source) { - source.type("Obstacle").apply { - flatMap(CONSTRUCTORS) - .flatMap(PARAMETERS) - .filter { it[NAME] == "data" } - .plus(property("data")) - .forEach { it[TYPE] = OBSTACLE_DATA } - } - - source.type("GraphPartition") - .flatMap(METHODS) - .filter { it.has(RETURNS) } - .filter { it[RETURNS][TYPE] == "yfiles.router.Obstacle" } - .flatMap(PARAMETERS) - .filter { it[NAME] == "data" } - .forEach { it[TYPE] = OBSTACLE_DATA } -} diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/PartitionCellHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/PartitionCellHacks.kt deleted file mode 100644 index 07d84a053..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/PartitionCellHacks.kt +++ /dev/null @@ -1,55 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.* - -internal fun generatePartitionCellUtils(context: GeneratorContext) { - // language=kotlin - context["yfiles.router.PartitionCellKey"] = """ - external interface PartitionCellKey - - inline fun PartitionCellKey(source:Any):PartitionCellKey = - source.unsafeCast>() - """.trimIndent() -} - -private val KEY_TYPE_MAP = mapOf( - "EDGE_LABEL_CROSSING_COST_FACTORS_KEY" to "$ILIST<$JS_DOUBLE>", - "EDGE_LABEL_LAYOUTS_KEY" to "$ILIST<$IEDGE_LABEL_LAYOUT>", - "NODES_IN_NODE_TO_EDGE_DISTANCE_KEY" to "$ILIST<$NODE>", - "NODES_KEY" to "$ILIST<$NODE>", - "NODE_LABEL_CROSSING_COST_FACTORS_KEY" to "$ILIST<$JS_DOUBLE>", - "NODE_LABEL_LAYOUTS_KEY" to "$ILIST<$INODE_LABEL_LAYOUT>", - "PARTITION_GRID_CELL_ID_KEY" to "yfiles.layout.PartitionCellId", - "PARTITION_GRID_COLUMN_INDEX_KEY" to JS_INT, - "PARTITION_GRID_ROW_INDEX_KEY" to JS_INT -) - -internal fun applyPartitionCellHacks(source: Source) { - val methodNames = setOf( - "getData", - "putData", - "removeData" - ) - - source.type("PartitionCell") - .flatMap(METHODS) - .filter { it[NAME] in methodNames } - .onEach { it.setSingleTypeParameter(bound = JS_OBJECT) } - .onEach { it[RETURNS][TYPE] = "T" } - .onEach { it.changeNullability(true) } - .flatMap(PARAMETERS) - .forEach { - it[TYPE] = when (val name = it[NAME]) { - "key" -> "$PARTITION_CELL_KEY" - "data" -> "T" - else -> throw IllegalArgumentException("Unable to calculate type by name '$name'") - } - } - - source.type("PartitionCellKeys") - .flatMap(CONSTANTS) - .forEach { - val keyType = KEY_TYPE_MAP.getValue(it[NAME]) - it[TYPE] = "$PARTITION_CELL_KEY<$keyType>" - } -} diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ResourceHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ResourceHacks.kt deleted file mode 100644 index ec18e8dd4..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/ResourceHacks.kt +++ /dev/null @@ -1,79 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.GeneratorContext -import com.github.turansky.yfiles.IVISUAL_TEMPLATE -import com.github.turansky.yfiles.JS_STRING - -private const val RESOURCE_KEY = "yfiles.view.ResourceKey" -private const val RESOURCE_MAP = "yfiles.view.ResourceMap" - -private fun resourceKey(typeParameter: String) = - "$RESOURCE_KEY<$typeParameter>" - -internal fun generateResourceUtils(context: GeneratorContext) { - // language=kotlin - context["yfiles.view.Resources"] = """ - @JsName("String") - external class ResourceKey - private constructor() - - external interface ResourceMap { - operator fun set( - key: ResourceKey, - value: T - ) - } - """.trimIndent() -} - -internal fun applyResourceHacks(source: Source) { - source.types().forEach { - val className = it[NAME] - it.optFlatMap(CONSTANTS) - .filter { it[TYPE] == JS_STRING } - .filter { it[NAME].endsWith("_KEY") } - .forEach { it[TYPE] = getType(className, it[NAME]) } - } - - source.type("CanvasComponent") - .property("resources")[TYPE] = RESOURCE_MAP - - val DEFAULT_PORT_CANDIDATE_DESCRIPTOR = "DefaultPortCandidateDescriptor" - source.type(DEFAULT_PORT_CANDIDATE_DESCRIPTOR) - .method("setTemplate").apply { - val typeParameter = getVisualTemplateParameter(DEFAULT_PORT_CANDIDATE_DESCRIPTOR) - firstParameter[TYPE] = resourceKey("$IVISUAL_TEMPLATE<$typeParameter>") - secondParameter.addGeneric(typeParameter) - } - - - val RECTANGLE_INDICATOR_INSTALLER = "RectangleIndicatorInstaller" - source.type(RECTANGLE_INDICATOR_INSTALLER) - .flatMap(CONSTRUCTORS) - .optFlatMap(PARAMETERS) - .filter { it[NAME] == "resourceKey" } - .single { it[TYPE] == JS_STRING } - .also { it[TYPE] = resourceKey("$IVISUAL_TEMPLATE<${getVisualTemplateParameter(RECTANGLE_INDICATOR_INSTALLER)}>") } - - val ORIENTED_RECTANGLE_INDICATOR_INSTALLER = "OrientedRectangleIndicatorInstaller" - source.type(ORIENTED_RECTANGLE_INDICATOR_INSTALLER) - .flatMap(CONSTRUCTORS) - .optFlatMap(PARAMETERS) - .filter { it[NAME] == "templateKey" } - .single { it[TYPE] == JS_STRING } - .also { it[TYPE] = resourceKey("$IVISUAL_TEMPLATE<${getVisualTemplateParameter(ORIENTED_RECTANGLE_INDICATOR_INSTALLER)}>") } -} - -private fun getType( - className: String, - name: String, -): String { - val typeParameter = when { - name == "TEMPLATE_KEY" -> JS_STRING - name.endsWith("_FILL_KEY") -> "yfiles.view.Fill" - name.endsWith("STROKE_KEY") -> "yfiles.view.Stroke" - else -> "$IVISUAL_TEMPLATE<${getVisualTemplateParameter(className)}>" - } - - return resourceKey(typeParameter) -} diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/SerializarionHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/SerializarionHacks.kt index 34273ea17..bb0943a00 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/SerializarionHacks.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/SerializarionHacks.kt @@ -53,6 +53,8 @@ internal fun applySerializationHacks(source: Source) { "IGNORE_PROPERTY_CASE" to JS_BOOLEAN, "IGNORE_XAML_DESERIALIZATION_ERRORS" to JS_BOOLEAN, "INDENT_OUTPUT" to JS_BOOLEAN, + "GRAPH_ELEMENT_IDS" to JS_STRING, + "GRAPH_IDS" to JS_STRING, "PARSE_LABEL_SIZE" to JS_BOOLEAN, "REPRESENTED_EDGE" to IEDGE, "REWRITE_RELATIVE_RESOURCE_URIS" to JS_BOOLEAN, @@ -61,7 +63,7 @@ internal fun applySerializationHacks(source: Source) { "WRITE_LABEL_SIZE_PREDICATE" to "yfiles.lang.Predicate<$ILABEL>", "WRITE_NODE_STYLE_DEFAULT" to JS_BOOLEAN, "WRITE_PORT_STYLE_DEFAULT" to JS_BOOLEAN, - "WRITE_STRIPE_DEFAULTS" to JS_BOOLEAN + "WRITE_STRIPE_DEFAULTS" to JS_BOOLEAN, ) source.type("SerializationProperties") diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/SnapLineProviderHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/SnapLineProviderHacks.kt deleted file mode 100644 index 72c4644f8..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/SnapLineProviderHacks.kt +++ /dev/null @@ -1,48 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.IEDGE -import com.github.turansky.yfiles.IMODEL_ITEM -import com.github.turansky.yfiles.INODE -import org.json.JSONObject - -private const val ISNAP_LINE_PROVIDER = "yfiles.input.ISnapLineProvider" - -internal fun applySnapLineProviderHacks(source: Source) { - source.type("ISnapLineProvider").apply { - setSingleTypeParameter("in T", IMODEL_ITEM) - - fixItemType("T") - - method("create") - .get(RETURNS) - .addGeneric("T") - } - - sequenceOf( - "NodeSnapLineProvider" to INODE, - "EdgeSnapLineProvider" to IEDGE - ).forEach { (className, typeParameter) -> - source.type(className).apply { - get(IMPLEMENTS).apply { - put(indexOf(ISNAP_LINE_PROVIDER), "$ISNAP_LINE_PROVIDER<$typeParameter>") - } - - fixItemType(typeParameter) - } - } - - fixDecoratorProperties(source, ISNAP_LINE_PROVIDER) - - source.type("CreateEdgeInputMode") - .method("getDummyEdgeSnapLines") - .parameter("provider") - .addGeneric(IEDGE) -} - -fun JSONObject.fixItemType(type: String) { - flatMap(METHODS) - .flatMap(PARAMETERS) - .filter { it[NAME] == "item" } - .filter { it[TYPE] == IMODEL_ITEM } - .forEach { it[TYPE] = type } -} diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/TagHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/TagHacks.kt index 71c14c454..2bbc29940 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/TagHacks.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/TagHacks.kt @@ -46,11 +46,6 @@ internal fun applyTagHacks(source: Source) { .eventListeners() .map { it.firstParameter } .forEach { it.replaceInSignature(",$JS_OBJECT>>", ",$TAG>>") } - - source.type("LayoutGraphAdapter") - .constant("ORIGINAL_TAG_DP_KEY").also { - it.replaceInType("<$JS_ANY>", "<$TAG>") - } } private fun looksLikeTag(name: String): Boolean = diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/TemplateLoadersHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/TemplateLoadersHacks.kt deleted file mode 100644 index 5ef2ef1b1..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/TemplateLoadersHacks.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.json.jObject -import com.github.turansky.yfiles.json.removeAllObjects -import org.json.JSONObject - -private const val TEMPLATE_LOADERS = "yfiles.styles.TemplateLoaders" -private val TEMPLATE_LOADERS_NAME = TEMPLATE_LOADERS.substringAfterLast(".") -internal const val TEMPLATE_LOADERS_ALIAS = "TemplateNodeStyleBase" - -private val COPIED_NAMES = setOf( - "loadAllTemplates" -) - -internal fun applyTemplateLoadersHacks(source: Source) { - source.add(createTemplates(source.type(TEMPLATE_LOADERS_ALIAS))) - - source.types() - .filter { it[ID].startsWith("yfiles.styles.") } - .filter { it[NAME].startsWith("Template") } - .filter { it[NAME].endsWith("StyleBase") } - .forEach { it.removeCommonItems() } -} - -private fun JSONObject.removeCommonItems() { - get(METHODS).removeAllObjects { - it[NAME] in COPIED_NAMES - } -} - -private fun createTemplates(sourceType: JSONObject): JSONObject { - return jObject( - ID to TEMPLATE_LOADERS, - NAME to TEMPLATE_LOADERS_NAME, - ES6_NAME to TEMPLATE_LOADERS_ALIAS, - GROUP to "class" - ).also { type -> - type[METHODS] = sourceType.flatMap(METHODS) - .filter { it[NAME] in COPIED_NAMES } - .toList() - } -} diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/TemplatesHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/TemplatesHacks.kt deleted file mode 100644 index 16894d8bc..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/TemplatesHacks.kt +++ /dev/null @@ -1,68 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.INTERNAL -import com.github.turansky.yfiles.JS_OBJECT -import com.github.turansky.yfiles.json.jObject -import com.github.turansky.yfiles.json.removeAllObjects -import org.json.JSONObject - -private const val TEMPLATES = "yfiles.styles.Templates" -internal val TEMPLATES_NAME = TEMPLATES.substringAfterLast(".") -private const val TEMPLATES_ALIAS = "StringTemplateNodeStyle" - -private val COPIED_KEYS = setOf( - CONSTANTS, - PROPERTIES, - METHODS -) - -private val COPIED_NAMES = setOf( - "CONVERTERS", - "trusted", - "makeObservable" -) - -internal fun applyTemplatesHacks(source: Source) { - source.add(createTemplates(source.type(TEMPLATES_ALIAS))) - - source.types() - .filter { it[ID].startsWith("yfiles.styles.") } - .filter { it[NAME].contains("Template") } - .filter { it[NAME].endsWith("Style") } - .forEach { it.removeCommonItems() } -} - -private fun JSONObject.removeCommonItems() { - COPIED_KEYS - .filter { has(it) } - .forEach { key -> - get(key).removeAllObjects { - it[NAME] in COPIED_NAMES - } - } -} - -private fun createTemplates(sourceType: JSONObject): JSONObject { - val type = jObject( - ID to TEMPLATES, - NAME to TEMPLATES_NAME, - ES6_NAME to TEMPLATES_ALIAS, - GROUP to "class" - ) - - COPIED_KEYS.forEach { key -> - type[key] = sourceType.flatMap(key) - .filter { it[NAME] in COPIED_NAMES } - .toList() - } - - type.method("makeObservable").apply { - get(MODIFIERS).put(INTERNAL) - - setSingleTypeParameter(bound = JS_OBJECT) - firstParameter[TYPE] = "T" - get(RETURNS)[TYPE] = "T" - } - - return type -} diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/TooltipHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/TooltipHacks.kt deleted file mode 100644 index f42ae66bb..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/TooltipHacks.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.GeneratorContext -import com.github.turansky.yfiles.HTML_ELEMENT - -private const val TOOL_TIP_CONTENT = "yfiles.view.ToolTipContent" - -internal fun generateTooltipUtils(context: GeneratorContext) { - // language=kotlin - context[TOOL_TIP_CONTENT] = """ - external interface ToolTipContent - - inline fun ToolTipContent(source:$HTML_ELEMENT):$TOOL_TIP_CONTENT = - source.unsafeCast<$TOOL_TIP_CONTENT>() - - inline fun ToolTipContent(source:String):$TOOL_TIP_CONTENT = - source.unsafeCast<$TOOL_TIP_CONTENT>() - """.trimIndent() -} - -internal fun applyTooltipHacks(source: Source) { - source.type("ToolTip") { - property("content")[TYPE] = TOOL_TIP_CONTENT - - flatMap(METHODS) - .optFlatMap(PARAMETERS) - .filter { it[NAME].endsWith("Content") } - .forEach { it[TYPE] = TOOL_TIP_CONTENT } - } - - source.type("ToolTipQueryEventArgs") - .property("toolTip")[TYPE] = TOOL_TIP_CONTENT - - source.type("MouseHoverInputMode") { - method("getToolTipContent")[RETURNS][TYPE] = TOOL_TIP_CONTENT - - flatMap(METHODS) - .optFlatMap(PARAMETERS) - .filter { it[NAME] == "content" } - .forEach { it[TYPE] = TOOL_TIP_CONTENT } - } -} diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/TypeMetadataHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/TypeMetadataHacks.kt new file mode 100644 index 000000000..491d9e7ce --- /dev/null +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/TypeMetadataHacks.kt @@ -0,0 +1,9 @@ +package com.github.turansky.yfiles.correction + +import com.github.turansky.yfiles.json.removeItem + +internal fun removeTypeMetadataMethods(source: Source) { + source.type("GraphMLIOHandler") { + get(METHODS).removeItem(method("addTypeInformation")) + } +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/VisualTemplateHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/VisualTemplateHacks.kt deleted file mode 100644 index 257c2a76d..000000000 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/VisualTemplateHacks.kt +++ /dev/null @@ -1,59 +0,0 @@ -package com.github.turansky.yfiles.correction - -import com.github.turansky.yfiles.IBEND -import com.github.turansky.yfiles.IVISUAL_TEMPLATE -import com.github.turansky.yfiles.JS_VOID -import com.github.turansky.yfiles.STATIC -import com.github.turansky.yfiles.json.get - -internal fun applyVisualTemplateHacks(source: Source) { - source.type("IVisualTemplate") { - setSingleTypeParameter("in T") - - flatMap(METHODS) - .filter { STATIC !in it[MODIFIERS] } - .map { it[PARAMETERS]["dataObject"] } - .onEach { it.changeNullability(false) } - .forEach { it[TYPE] = "T" } - } - - source.types().forEach { - val className = it[NAME] - it.optFlatMap(PROPERTIES) - .filter { it[TYPE] == IVISUAL_TEMPLATE } - .forEach { it[TYPE] = "$IVISUAL_TEMPLATE<${getVisualTemplateParameter(className)}>" } - - it.optFlatMap(METHODS) - .filter { it.has(RETURNS) } - .map { it[RETURNS] } - .filter { it[TYPE] == IVISUAL_TEMPLATE } - .forEach { it[TYPE] = "$IVISUAL_TEMPLATE<${getVisualTemplateParameter(className)}>" } - } -} - -internal fun getVisualTemplateParameter(className: String): String = - when (className) { - "DefaultPortCandidateDescriptor" -> "$TAG?" - "DefaultStripeInputVisualizationHelper" -> "yfiles.graph.IStripe" - "HandleInputMode" -> "yfiles.input.IHandle" - - "EdgeDecorationInstaller", - "EdgeFocusIndicatorInstaller", - "EdgeHighlightIndicatorInstaller", - "EdgeSelectionIndicatorInstaller", - -> IBEND - - "LabelPositionHandler", - - "LassoSelectionInputMode", - "MarqueeSelectionInputMode", - "OverviewInputMode", - - "OrientedRectangleIndicatorInstaller", - "RectangleIndicatorInstaller", - - "Theme", - -> JS_VOID - - else -> throw IllegalArgumentException("Unable to calculate type parameter for class '$className'") - } diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/YJson.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/YJson.kt index 5e7761e7b..615598c87 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/YJson.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/YJson.kt @@ -50,7 +50,7 @@ internal fun JSONObject.property(name: String): JSONObject = get(PROPERTIES)[name] internal fun Sequence.eventListeners(): Sequence = - flatMap { sequenceOf("add", "remove").map(it::getJSONObject) } + flatMap { sequenceOf("add", "remove").filter(it::has).map(it::getJSONObject) } internal fun JSONObject.addProperty( propertyName: String, @@ -87,7 +87,7 @@ internal fun JSONObject.changeOptionality(optional: Boolean) = changeModifier(OPTIONAL, optional) private fun JSONObject.changeModifier(modifier: String, value: Boolean) { - val modifiers = get(MODIFIERS) + val modifiers = opt(MODIFIERS) ?: return val index = modifiers.indexOf(modifier) // TEMP WORKAROUND @@ -213,6 +213,8 @@ internal fun JSONObject.returnsSequence(): Sequence = internal fun JSONObject.addGeneric(generic: String) { val type = get(TYPE) + if (type == generic) + return set(TYPE, "$type<$generic>") } diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/YListHacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/YListHacks.kt index d9acac017..44dae2652 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/YListHacks.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/correction/YListHacks.kt @@ -9,23 +9,21 @@ private fun ylist(generic: String): String = internal fun applyYListHacks(source: Source) { fixYList(source) fixMethodParameter(source) - fixProperty(source) - fixReturnType(source) + + source.types("YList") + .flatMap(CONSTANTS) + .forEach { + it[TYPE] = it[TYPE].replace("", "<*>") + } } private fun fixYList(source: Source) { source.type("YList") .fixGeneric() - - source.type("YNodeList") - .addExtendsGeneric(NODE) - - source.type("EdgeList") - .addExtendsGeneric(EDGE) } private fun JSONObject.fixGeneric() { - setSingleTypeParameter(bound = YOBJECT) + setSingleTypeParameter() get(IMPLEMENTS).apply { put(0, getString(0).replace("<$JS_ANY>", "")) @@ -50,21 +48,7 @@ private fun JSONObject.fixGeneric() { private fun fixMethodParameter(source: Source) { source.types( "YList", - - "Geom", - "TriangulationAlgorithm", "LayoutGraph", - - "LabelingBase", - "SelfLoopCalculator", - "IntersectionAlgorithm", - "ChannelBasedPathRouting", - "OrthogonalPatternEdgeRouter", - - "ILayer", - - "IElementFactory", - "DefaultElementFactory", "MultiPageLayout" ).optFlatMap(METHODS) .forEach { @@ -95,7 +79,6 @@ private fun getGeneric( } return when (parameterName) { - "path", "points" -> YPOINT "nodeLabels" -> INODE_LABEL_LAYOUT "edgeLabels" -> IEDGE_LABEL_LAYOUT "selfLoops" -> EDGE @@ -106,58 +89,6 @@ private fun getGeneric( } } -private fun fixProperty(source: Source) { - sequenceOf( - Triple("ILayer", "sameLayerEdges", EDGE), - ).forEach { (className, propertyName, generic) -> - source.type(className) - .property(propertyName) - .fixTypeGeneric(generic) - } -} - -private fun fixReturnType(source: Source) { - sequenceOf( - "INodeLabelLayoutModel" to NODE_LABEL_CANDIDATE, - "DiscreteNodeLabelLayoutModel" to NODE_LABEL_CANDIDATE, - "FreeNodeLabelLayoutModel" to NODE_LABEL_CANDIDATE, - - "IEdgeLabelLayoutModel" to EDGE_LABEL_CANDIDATE, - "DiscreteEdgeLabelLayoutModel" to EDGE_LABEL_CANDIDATE, - "FreeEdgeLabelLayoutModel" to EDGE_LABEL_CANDIDATE, - "SliderEdgeLabelLayoutModel" to EDGE_LABEL_CANDIDATE - ).forEach { (className, generic) -> - source.type(className) - .method("getLabelCandidates") - .fixReturnTypeGeneric(generic) - } - - sequenceOf( - "LayoutGraph" to "getPathList", - "LayoutGraph" to "getPointList", - - "EdgeInfo" to "calculatePathPoints" - ).forEach { (className, methodName) -> - source.type(className) - .method(methodName) - .fixReturnTypeGeneric(YPOINT) - } - - sequenceOf( - Triple("Geom", "calcConvexHull", YPOINT), - Triple("ShortestPathAlgorithm", "kShortestPaths", EDGE_LIST) - ).forEach { (className, methodName, generic) -> - source.type(className) - .method(methodName) - .fixReturnTypeGeneric(generic) - } -} - -private fun JSONObject.fixReturnTypeGeneric(generic: String) { - get(RETURNS) - .fixTypeGeneric(generic) -} - private fun JSONObject.fixTypeGeneric(generic: String) { require(get(TYPE) == YLIST) diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/json/Json.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/json/Json.kt index 7db9b33de..b81083a98 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/json/Json.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/json/Json.kt @@ -24,7 +24,18 @@ internal fun JSONArray.first(predicate: (JSONObject) -> Boolean): JSONObject = .first(predicate) internal operator fun JSONArray.get(name: String): JSONObject = - first { it[NAME] == name } + (0 until this.length()) + .map(this::getJSONObject) + .find { it[NAME] == name } + ?: error("No item with name '$name'") + +internal fun JSONArray.find(predicate: (JSONObject) -> Boolean): JSONObject? = + (0 until this.length()) + .map(this::getJSONObject) + .firstOrNull(predicate) + +internal fun JSONArray.find(name: String): JSONObject? = + find { it[NAME] == name } internal fun JSONArray.objects(predicate: (JSONObject) -> Boolean): Iterable { return (0 until this.length()) diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/vsdx/correction/Hacks.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/vsdx/correction/Hacks.kt index 2942e79e6..e37feaa11 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/vsdx/correction/Hacks.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/vsdx/correction/Hacks.kt @@ -5,8 +5,6 @@ import com.github.turansky.yfiles.correction.* import org.json.JSONObject private val YFILES_TYPE_MAP = sequenceOf( - YCLASS, - "yfiles.collections.IEnumerator", IENUMERABLE, @@ -62,7 +60,7 @@ private val YFILES_TYPE_MAP = sequenceOf( "yfiles.view.HorizontalTextAlignment", "yfiles.view.VerticalTextAlignment" ).associateBy { - if (it == YCLASS) "Class" else it.substringAfterLast(".") + it.substringAfterLast(".") } private val TYPE_MAP = YFILES_TYPE_MAP + mapOf( @@ -229,22 +227,19 @@ private fun fixOptionTypes(source: VsdxSource) { .apply { parameter("optionsOrNodeStyleType").apply { set(NAME, "nodeStyleType") - set(TYPE, "$YCLASS") + set(TYPE, "$JS_CLASS") } - parameter("edgeStyleType") - .addGeneric("yfiles.styles.IEdgeStyle") - parameter("portStyleType") - .addGeneric("yfiles.styles.IPortStyle") - parameter("labelStyleType") - .addGeneric("yfiles.styles.ILabelStyle") + parameter("edgeStyleType")[TYPE] = "$JS_CLASS" + parameter("portStyleType")[TYPE] = "$JS_CLASS" + parameter("labelStyleType")[TYPE] = "$JS_CLASS" } source.type("CustomEdgeProvider") .flatMap(CONSTRUCTORS) .single() .parameter("edgeStyleType") - .addGeneric("yfiles.styles.IEdgeStyle") + .set(TYPE, "$JS_CLASS") source.type("VssxStencilProviderFactory") { sequenceOf( @@ -254,7 +249,7 @@ private fun fixOptionTypes(source: VsdxSource) { "createMappedPortProvider" to "yfiles.styles.IPortStyle" ).forEach { (methodName, styleGeneric) -> methodParameters(methodName, "styleType") - .forEach { it.addGeneric(styleGeneric) } + .forEach { it[TYPE] = "$JS_CLASS<$styleGeneric>" } } } } diff --git a/examples/configurable-properties/src/jsMain/kotlin/CustomLabelModelParameter.kt b/examples/configurable-properties/src/jsMain/kotlin/CustomLabelModelParameter.kt index 4ca839ee9..b9547c637 100644 --- a/examples/configurable-properties/src/jsMain/kotlin/CustomLabelModelParameter.kt +++ b/examples/configurable-properties/src/jsMain/kotlin/CustomLabelModelParameter.kt @@ -7,6 +7,5 @@ class CustomLabelModelParameter : ILabelModelParameter { override val model: ILabelModel get() = FreeEdgeLabelModel.INSTANCE - override fun supports(label: ILabel): Boolean = true override fun clone(): ILabelModelParameter = this } diff --git a/examples/configurable-properties/src/jsMain/kotlin/MyPolylineEdgeStyleRenderer.kt b/examples/configurable-properties/src/jsMain/kotlin/MyPolylineEdgeStyleRenderer.kt deleted file mode 100644 index d99793e33..000000000 --- a/examples/configurable-properties/src/jsMain/kotlin/MyPolylineEdgeStyleRenderer.kt +++ /dev/null @@ -1,6 +0,0 @@ -import yfiles.styles.PolylineEdgeStyleRenderer - -abstract class MyPolylineEdgeStyleRenderer : PolylineEdgeStyleRenderer() { - override val addBridges: Boolean - get() = false -} diff --git a/examples/data-classes/src/jsMain/kotlin/DataClasses.kt b/examples/data-classes/src/jsMain/kotlin/DataClasses.kt index 8849dfb81..c5a352b39 100644 --- a/examples/data-classes/src/jsMain/kotlin/DataClasses.kt +++ b/examples/data-classes/src/jsMain/kotlin/DataClasses.kt @@ -1,10 +1,9 @@ import yfiles.lang.IComparable -import yfiles.lang.YObject data class Person( val firstName: String, val lastName: String, -) : YObject +) data class YDate( val milliseconds: Int, diff --git a/examples/import-optimizer-application/build.gradle.kts b/examples/import-optimizer-application/build.gradle.kts deleted file mode 100644 index 47fedaa84..000000000 --- a/examples/import-optimizer-application/build.gradle.kts +++ /dev/null @@ -1,9 +0,0 @@ -plugins { - alias(kfc.plugins.library) - alias(libs.plugins.yfiles) -} - -dependencies { - jsMainImplementation(project(":yfiles-kotlin")) - jsMainImplementation(project(":examples:import-optimizer-library")) -} diff --git a/examples/import-optimizer-application/gradle.properties b/examples/import-optimizer-application/gradle.properties deleted file mode 100644 index 8d9ead5f1..000000000 --- a/examples/import-optimizer-application/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -kotlin.js.generate.executable.default=false diff --git a/examples/import-optimizer-application/src/jsMain/kotlin/Components.kt b/examples/import-optimizer-application/src/jsMain/kotlin/Components.kt deleted file mode 100644 index 5b2de638d..000000000 --- a/examples/import-optimizer-application/src/jsMain/kotlin/Components.kt +++ /dev/null @@ -1,22 +0,0 @@ -import yfiles.algorithms.nodeDpKey -import yfiles.input.IHitTestable -import yfiles.styles.IArrow -import yfiles.view.GraphComponent -import yfiles.view.IVisualCreator - -@JsExport -@ExperimentalJsExport -fun createComponent(): GraphComponent = - GraphComponent { - graph = createGraph() - } - -@JsExport -@ExperimentalJsExport -object Keys { - val STRING_DATA_KEY by nodeDpKey() - - val INT_DATA_KEY by nodeDpKey() -} - -abstract class AbstractArrow : IArrow, IVisualCreator, IHitTestable diff --git a/examples/import-optimizer-library/build.gradle.kts b/examples/import-optimizer-library/build.gradle.kts deleted file mode 100644 index d26169e89..000000000 --- a/examples/import-optimizer-library/build.gradle.kts +++ /dev/null @@ -1,8 +0,0 @@ -plugins { - alias(kfc.plugins.library) - alias(libs.plugins.yfiles) -} - -dependencies { - jsMainImplementation(project(":yfiles-kotlin")) -} diff --git a/examples/import-optimizer-library/src/jsMain/kotlin/Graphs.kt b/examples/import-optimizer-library/src/jsMain/kotlin/Graphs.kt deleted file mode 100644 index 1f0a1ebeb..000000000 --- a/examples/import-optimizer-library/src/jsMain/kotlin/Graphs.kt +++ /dev/null @@ -1,10 +0,0 @@ -import yfiles.graph.DefaultGraph -import yfiles.graph.IGraph - -fun createGraph(): IGraph = - DefaultGraph { - val n1 = createNode() - val n2 = createNode() - - createEdge(n1, n2) - } diff --git a/examples/simple-app/src/jsMain/kotlin/App.kt b/examples/simple-app/src/jsMain/kotlin/App.kt index 9d47e48ce..8d4a4457d 100644 --- a/examples/simple-app/src/jsMain/kotlin/App.kt +++ b/examples/simple-app/src/jsMain/kotlin/App.kt @@ -1,7 +1,7 @@ import web.html.HTMLDivElement -import yfiles.graph.DefaultGraph +import yfiles.graph.Graph import yfiles.graph.invoke -import yfiles.hierarchic.HierarchicLayout +import yfiles.hierarchic.HierarchicalLayout import yfiles.input.GraphViewerInputMode import yfiles.layout.LayoutOrientation import yfiles.view.GraphComponent @@ -10,19 +10,19 @@ fun create(): HTMLDivElement = GraphComponent().run { inputMode = GraphViewerInputMode() - div.style.apply { + htmlElement.style.apply { width = "100%" height = "100%" backgroundColor = "#CCCCCC" } - val layout = HierarchicLayout { + val layout = HierarchicalLayout { layoutOrientation = LayoutOrientation.LEFT_TO_RIGHT automaticEdgeGrouping = true gridSpacing = 20.0 } - graph = DefaultGraph { + graph = Graph { val node1 = createNode() val node2 = createNode() createEdge(node1, node2) @@ -31,14 +31,14 @@ fun create(): HTMLDivElement = } graph.decorator { - nodeDecorator { - selectionDecorator.hideImplementation() - focusIndicatorDecorator.hideImplementation() - highlightDecorator.hideImplementation() + nodes { + selectionRenderer.hide { true } + focusRenderer.hide { true } + highlightRenderer.hide { true } } } fitGraphBounds() - div + htmlElement.unsafeCast() } diff --git a/examples/simple-app/src/jsMain/kotlin/Cast.kt b/examples/simple-app/src/jsMain/kotlin/Cast.kt index f0391d1c7..d61e3d86e 100644 --- a/examples/simple-app/src/jsMain/kotlin/Cast.kt +++ b/examples/simple-app/src/jsMain/kotlin/Cast.kt @@ -1,19 +1,17 @@ @file:Suppress("unused", "UNUSED_VARIABLE") -import yfiles.graph.DefaultGraph +import yfiles.graph.Graph import yfiles.graph.IGraph import yfiles.graph.IModelItem import yfiles.graph.INode -import yfiles.lang.yAs -import yfiles.lang.yIs -import yfiles.lang.yOpt +@Suppress("CANNOT_CHECK_FOR_EXTERNAL_INTERFACE", "UNCHECKED_CAST_TO_EXTERNAL_INTERFACE") fun cast() { - val g: IGraph = DefaultGraph() + val g: IGraph = Graph() val n1: IModelItem = g.createNode() val n2: INode = g.createNode() - val isNode: Boolean = n1 yIs INode - val optNode: INode? = n1 yOpt INode - val asNode: INode = n1 yAs INode + val isNode: Boolean = n1 is INode + val optNode: INode? = n1 as? INode + val asNode: INode = n1 as INode } \ No newline at end of file diff --git a/examples/simple-app/src/jsMain/kotlin/Comparer.kt b/examples/simple-app/src/jsMain/kotlin/Comparer.kt index da913001e..d39f44889 100644 --- a/examples/simple-app/src/jsMain/kotlin/Comparer.kt +++ b/examples/simple-app/src/jsMain/kotlin/Comparer.kt @@ -1,17 +1,8 @@ -@file:Suppress("unused", "UNUSED_VARIABLE") +@file:Suppress("unused") -import yfiles.algorithms.Comparers.createComparableComparer -import yfiles.algorithms.Graph -import yfiles.layout.DefaultLayoutGraph -import yfiles.layout.TabularLayout -import yfiles.tree.NodeOrderComparer +import yfiles.layout.LayoutGraph fun comparer() { - val g: Graph = DefaultLayoutGraph() - g.sortNodes(NodeOrderComparer()) - g.sortNodes(createComparableComparer()) - - val l = TabularLayout() - l.nodeComparer = NodeOrderComparer() - l.nodeComparer = createComparableComparer() + val g = LayoutGraph() + g.sortNodes { x, y -> x.index.compareTo(y.index) } } \ No newline at end of file diff --git a/examples/simple-app/src/jsMain/kotlin/Converters.kt b/examples/simple-app/src/jsMain/kotlin/Converters.kt deleted file mode 100644 index 0f9cd13ac..000000000 --- a/examples/simple-app/src/jsMain/kotlin/Converters.kt +++ /dev/null @@ -1,23 +0,0 @@ -@file:Suppress("unused", "UNUSED_VARIABLE") - -import yfiles.styles.Templates -import yfiles.styles.invoke -import yfiles.styles.put - -fun converters() { - Templates.CONVERTERS { - put("visibility", ::visibility) - put("color", ::color) - } -} - -fun visibility(visible: Boolean): String { - return if (visible) "visible" else "none" -} - -fun color(width: Double, defaultColor: String): String = - when { - width > 10 -> "white" - width > 20 -> "grey" - else -> defaultColor - } diff --git a/examples/simple-app/src/jsMain/kotlin/Destructuring.kt b/examples/simple-app/src/jsMain/kotlin/Destructuring.kt index 8c2fbaf24..80af85d69 100644 --- a/examples/simple-app/src/jsMain/kotlin/Destructuring.kt +++ b/examples/simple-app/src/jsMain/kotlin/Destructuring.kt @@ -1,13 +1,12 @@ @file:Suppress("unused", "UNUSED_VARIABLE") -import yfiles.algorithms.YPoint -import yfiles.algorithms.YPoint.Companion.plus import yfiles.collections.* +import yfiles.geometry.Point fun destructuring() { - val p1 = YPoint(4.0, 8.0) - val p2 = YPoint(15.0, 16.0) - val p3 = YPoint(23.0, 42.0) + val p1 = Point(4.0, 8.0) + val p2 = Point(15.0, 16.0) + val p3 = Point(23.0, 42.0) val (x, y) = p1 + p2 + p3 diff --git a/examples/simple-app/src/jsMain/kotlin/ExternalExtensions.kt b/examples/simple-app/src/jsMain/kotlin/ExternalExtensions.kt index 3b1829ae3..d1b57adca 100644 --- a/examples/simple-app/src/jsMain/kotlin/ExternalExtensions.kt +++ b/examples/simple-app/src/jsMain/kotlin/ExternalExtensions.kt @@ -1,17 +1,16 @@ @file:Suppress("unused", "UNUSED_VARIABLE") -import yfiles.algorithms.Graph -import yfiles.algorithms.GraphChecker.isAcyclic -import yfiles.algorithms.GraphChecker.isCyclic -import yfiles.algorithms.Trees.isForest -import yfiles.layout.DefaultLayoutGraph +import yfiles.analysis.LayoutGraphAlgorithms.isAcyclic +import yfiles.analysis.LayoutGraphAlgorithms.isConnected +import yfiles.analysis.LayoutGraphAlgorithms.isForest +import yfiles.layout.LayoutGraph fun externalExtensions() { - val graph: Graph = DefaultLayoutGraph() - // JS: GraphChecker.isCyclic(graph) - graph.isCyclic() - // JS: GraphChecker.isAcyclic(graph) + val graph = LayoutGraph() + // JS: LayoutGraphAlgorithms.isConnected(graph) + graph.isConnected() + // JS: LayoutGraphAlgorithms.isAcyclic(graph) graph.isAcyclic() - // JS: Trees.isForest(graph) - graph.isForest() + // JS: LayoutGraphAlgorithms.isForest(graph, boolean) + graph.isForest(true) } diff --git a/examples/simple-app/src/jsMain/kotlin/Iterators.kt b/examples/simple-app/src/jsMain/kotlin/Iterators.kt index b7cf4a4ff..55d377789 100644 --- a/examples/simple-app/src/jsMain/kotlin/Iterators.kt +++ b/examples/simple-app/src/jsMain/kotlin/Iterators.kt @@ -1,20 +1,18 @@ @file:Suppress("unused") -import yfiles.algorithms.iterator import yfiles.collections.iterator -import yfiles.graph.DefaultGraph +import yfiles.graph.Graph import yfiles.graph.IGraph -import yfiles.hierarchic.HierarchicLayout -import yfiles.layout.DefaultLayoutGraph +import yfiles.hierarchic.HierarchicalLayout import yfiles.layout.LayoutGraph fun enumerableIterator() { - val graph: IGraph = DefaultGraph { + val graph: IGraph = Graph { createNode() createNode() createNode() - applyLayout(HierarchicLayout()) + applyLayout(HierarchicalLayout()) } for (node in graph.nodes) { @@ -23,16 +21,16 @@ fun enumerableIterator() { } fun cursorIterator() { - val graph: LayoutGraph = DefaultLayoutGraph { + val graph = LayoutGraph().apply { createNode() createNode() createNode() } - HierarchicLayout() + HierarchicalLayout() .applyLayout(graph) - for (node in graph.getNodeCursor()) { + for (node in graph.nodes.getCursor()) { println("Node index: ${node.index}") } } diff --git a/examples/simple-app/src/jsMain/kotlin/Lookups.kt b/examples/simple-app/src/jsMain/kotlin/Lookups.kt index c9ddc40c2..4b4638722 100644 --- a/examples/simple-app/src/jsMain/kotlin/Lookups.kt +++ b/examples/simple-app/src/jsMain/kotlin/Lookups.kt @@ -4,15 +4,15 @@ "UNUSED_VARIABLE", ) -import yfiles.graph.DefaultGraph +import yfiles.collections.lookup +import yfiles.collections.lookupValue +import yfiles.graph.Graph import yfiles.graph.IGraph -import yfiles.graph.lookup -import yfiles.graph.lookupValue import yfiles.input.IHitTestable import yfiles.lang.TimeSpan fun lookups() { - val graph: IGraph = DefaultGraph() + val graph: IGraph = Graph() val node = graph.createNode() // for classes diff --git a/examples/simple-app/src/jsMain/kotlin/Sequences.kt b/examples/simple-app/src/jsMain/kotlin/Sequences.kt index 219e4023f..7c1394844 100644 --- a/examples/simple-app/src/jsMain/kotlin/Sequences.kt +++ b/examples/simple-app/src/jsMain/kotlin/Sequences.kt @@ -1,20 +1,18 @@ @file:Suppress("unused") -import yfiles.algorithms.asSequence import yfiles.collections.asSequence -import yfiles.graph.DefaultGraph +import yfiles.graph.Graph import yfiles.graph.IGraph -import yfiles.hierarchic.HierarchicLayout -import yfiles.layout.DefaultLayoutGraph +import yfiles.hierarchic.HierarchicalLayout import yfiles.layout.LayoutGraph fun enumerableSequence() { - val graph: IGraph = DefaultGraph { + val graph: IGraph = Graph { createNode() createNode() createNode() - applyLayout(HierarchicLayout()) + applyLayout(HierarchicalLayout()) } graph.nodes.asSequence() @@ -22,16 +20,16 @@ fun enumerableSequence() { } fun cursorSequence() { - val graph: LayoutGraph = DefaultLayoutGraph { + val graph: LayoutGraph = LayoutGraph().apply { createNode() createNode() createNode() } - HierarchicLayout() + HierarchicalLayout() .applyLayout(graph) - graph.getNodeCursor() + graph.nodes.getCursor() .asSequence() .filter { it.index % 2 == 0 } .forEach { println("Node index: ${it.index}") } diff --git a/gradle-plugin-test/build.gradle.kts b/gradle-plugin-test/build.gradle.kts index 068582d86..9917c986d 100644 --- a/gradle-plugin-test/build.gradle.kts +++ b/gradle-plugin-test/build.gradle.kts @@ -6,6 +6,18 @@ plugins { dependencies { jsMainImplementation(kotlinWrappers.browser) jsMainImplementation(project(":yfiles-kotlin")) - + jsTestImplementation(project(":yfiles-kotlin")) jsTestImplementation(kotlin("test-js")) } + +kotlin { + js(IR) { + browser { + testTask { + useKarma { + useFirefox() + } + } + } + } +} \ No newline at end of file diff --git a/gradle-plugin-test/src/jsMain/kotlin/CustomObject.kt b/gradle-plugin-test/src/jsMain/kotlin/CustomObject.kt index 7054479f9..d113ab750 100644 --- a/gradle-plugin-test/src/jsMain/kotlin/CustomObject.kt +++ b/gradle-plugin-test/src/jsMain/kotlin/CustomObject.kt @@ -1,17 +1,12 @@ import web.prompts.alert -import yfiles.lang.IClassMetadata -import yfiles.lang.YObject -import yfiles.lang.classMetadata -class CustomObject : YObject { +class CustomObject { fun hallo() { alert("Hallo from CustomObject!") } - - companion object : IClassMetadata by classMetadata() } -class OtherCustomObject : YObject { +class OtherCustomObject { fun hallo() { alert("Hallo from OtherCustomObject!") } diff --git a/gradle-plugin-test/src/jsMain/kotlin/DataObject.kt b/gradle-plugin-test/src/jsMain/kotlin/DataObject.kt index c2cf1bbef..63adfc28d 100644 --- a/gradle-plugin-test/src/jsMain/kotlin/DataObject.kt +++ b/gradle-plugin-test/src/jsMain/kotlin/DataObject.kt @@ -1,6 +1,4 @@ -import yfiles.lang.YObject - class DataObject( val key: String, val name: String -) : YObject +) diff --git a/gradle-plugin-test/src/jsMain/kotlin/SimpleVisibilityTestable.kt b/gradle-plugin-test/src/jsMain/kotlin/SimpleVisibilityTestable.kt index 0f2362d56..deb7e9086 100644 --- a/gradle-plugin-test/src/jsMain/kotlin/SimpleVisibilityTestable.kt +++ b/gradle-plugin-test/src/jsMain/kotlin/SimpleVisibilityTestable.kt @@ -1,14 +1,3 @@ -import yfiles.geometry.Rect -import yfiles.view.ICanvasContext import yfiles.view.IVisibilityTestable -abstract class IVisibilityTestableBase : IVisibilityTestable - -class SimpleVisibilityTestable : IVisibilityTestableBase() { - override fun isVisible( - context: ICanvasContext, - rectangle: Rect - ): Boolean { - return true - } -} \ No newline at end of file +abstract class IVisibilityTestableBase : IVisibilityTestable \ No newline at end of file diff --git a/gradle-plugin-test/src/jsMain/resources/yfiles.js b/gradle-plugin-test/src/jsMain/resources/yfiles.js index d3e450081..bb8f8a244 100644 --- a/gradle-plugin-test/src/jsMain/resources/yfiles.js +++ b/gradle-plugin-test/src/jsMain/resources/yfiles.js @@ -1,5 +1,3 @@ -function YObject () {} - function Class () {} Class.fixType = function (type, name) { @@ -9,8 +7,8 @@ Class.fixType = function (type, name) { function BaseClass (...types) { const generic = types - .map(type => type.name) - .join('-') + .map(type => type.name) + .join('-') const className = `BaseClass[${generic}]` const YClass = function () {} @@ -25,7 +23,6 @@ function IVisibilityTestable () {} function IBoundsProvider () {} export { - YObject, Class, BaseClass, IArrow, diff --git a/gradle-plugin-test/src/jsTest/kotlin/BaseClassTest.kt b/gradle-plugin-test/src/jsTest/kotlin/BaseClassTest.kt index 2443cb4d1..cb755dab7 100644 --- a/gradle-plugin-test/src/jsTest/kotlin/BaseClassTest.kt +++ b/gradle-plugin-test/src/jsTest/kotlin/BaseClassTest.kt @@ -1,7 +1,10 @@ +@file:Suppress("USELESS_IS_CHECK") + import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertEquals +@Suppress("CANNOT_CHECK_FOR_EXTERNAL_INTERFACE") @Ignore class BaseClassTest { @Test diff --git a/gradle-plugin-test/src/jsTest/kotlin/ConfigurablePropertyTest.kt b/gradle-plugin-test/src/jsTest/kotlin/ConfigurablePropertyTest.kt index badd41c5a..73e14a871 100644 --- a/gradle-plugin-test/src/jsTest/kotlin/ConfigurablePropertyTest.kt +++ b/gradle-plugin-test/src/jsTest/kotlin/ConfigurablePropertyTest.kt @@ -1,7 +1,9 @@ import Object.Companion.getOwnPropertyDescriptor +import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertTrue +@Ignore class ConfigurablePropertyTest { @Test fun arrowProperties() { diff --git a/gradle-plugin-test/src/jsTest/kotlin/CustomObjectTest.kt b/gradle-plugin-test/src/jsTest/kotlin/CustomObjectTest.kt index 06359aa69..19fd611a6 100644 --- a/gradle-plugin-test/src/jsTest/kotlin/CustomObjectTest.kt +++ b/gradle-plugin-test/src/jsTest/kotlin/CustomObjectTest.kt @@ -1,12 +1,17 @@ import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.test.assertTrue @Ignore +@Suppress("USELESS_IS_CHECK") class CustomObjectTest { @Test fun testClassName() { val o = CustomObject() + assertTrue { + o is CustomObject + } assertEquals("CustomObject", o.asDynamic().className) } } diff --git a/gradle-plugin/src/main/kotlin/com/github/turansky/yfiles/compiler/backend/common/YFiles.kt b/gradle-plugin/src/main/kotlin/com/github/turansky/yfiles/compiler/backend/common/YFiles.kt index b16e451f9..f8d9c3731 100644 --- a/gradle-plugin/src/main/kotlin/com/github/turansky/yfiles/compiler/backend/common/YFiles.kt +++ b/gradle-plugin/src/main/kotlin/com/github/turansky/yfiles/compiler/backend/common/YFiles.kt @@ -1,19 +1,16 @@ package com.github.turansky.yfiles.compiler.backend.common import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name.identifier import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe -import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces private val YFILES_PACKAGE_ID = identifier("yfiles") private val YFILES_PACKAGE = FqName(YFILES_PACKAGE_ID.identifier) internal val LANG_PACKAGE = YFILES_PACKAGE.child(identifier("lang")) -internal val YOBJECT = LANG_PACKAGE.child(identifier("YObject")) internal val YENUM = LANG_PACKAGE.child(identifier("YEnum")) -internal val YCLASS_NAME = identifier("YClass") -internal val BASE_CLASS_NAME = identifier("BaseClass") internal val FqName.isYFiles: Boolean get() = startsWith(YFILES_PACKAGE_ID) @@ -21,29 +18,9 @@ internal val FqName.isYFiles: Boolean internal val ClassDescriptor.locatedInYFilesPackage: Boolean get() = fqNameSafe.isYFiles -private val ClassDescriptor.isYObject: Boolean - get() = isExternal && fqNameSafe == YOBJECT +internal fun ClassDescriptor.isYFilesInterface(): Boolean { + return locatedInYFilesPackage && kind == ClassKind.INTERFACE +} internal val ClassDescriptor.isYEnum: Boolean - get() = isExternal && fqNameSafe == YENUM - -internal fun ClassDescriptor.isYFilesInterface(): Boolean = - isExternal and (isYObject or implementsYObject) - -internal val ClassDescriptor.implementsYObjectDirectly: Boolean - get() = getSuperInterfaces() - .any { it.isYObject } - -private val ClassDescriptor.implementsYObject: Boolean - get() { - if (implementsYObjectDirectly) { - return true - } - - return getSuperInterfaces() - .any { it.implementsYObject } - } - -internal val ClassDescriptor.implementsYFilesInterface: Boolean - get() = getSuperInterfaces() - .any { it.isYFilesInterface() } + get() = locatedInYFilesPackage && kind == ClassKind.ENUM_CLASS diff --git a/gradle.properties b/gradle.properties index ce8675531..8811ff56c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ kotlin.version=2.1.10 kfc.version=13.7.0 kotlin-wrappers.version=2025.2.8 -yfiles.api.url=https://docs.yworks.com/yfileshtml/assets/api.0ca73b0b.js -yfiles.devguide.url=https://docs.yworks.com/yfileshtml/assets/dguide.3fcdb1e9.js +yfiles.api.url=https://docs.yworks.com/yfileshtml/assets/api.d3cfc2b0.js +yfiles.devguide.url=https://docs.yworks.com/yfileshtml/assets/dguide.a2fd761f.js # vsdx.api.url=https://docs.yworks.com/vsdx-html/assets/api.6cb6e578.js vsdx.api.url=https://docs.yworks.com/vsdx-html/assets/api.daa52818.js diff --git a/package-lock.json b/package-lock.json index b5ac77ce7..97eb9d14e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,10 +18,6 @@ "packages/yfiles-kotlin-configurable-properties-test", "packages/yfiles-kotlin-data-classes", "packages/yfiles-kotlin-data-classes-test", - "packages/yfiles-kotlin-import-optimizer-application", - "packages/yfiles-kotlin-import-optimizer-application-test", - "packages/yfiles-kotlin-import-optimizer-library", - "packages/yfiles-kotlin-import-optimizer-library-test", "packages/yfiles-kotlin-simple-app", "packages/yfiles-kotlin-simple-app-test", "packages_imported/kotlin-cssom-core/2025.2.8" @@ -1815,6 +1811,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -1913,6 +1925,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/isbinaryfile": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", @@ -2044,6 +2069,33 @@ "which": "^1.2.1" } }, + "node_modules/karma-firefox-launcher": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-2.1.3.tgz", + "integrity": "sha512-LMM2bseebLbYjODBOVt7TCPP9OI2vZIXCavIXhkO9m+10Uj5l7u/SKoeRmYx8FYHTVGZSpk6peX+3BMHC1WwNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-wsl": "^2.2.0", + "which": "^3.0.0" + } + }, + "node_modules/karma-firefox-launcher/node_modules/which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/karma-mocha": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-2.0.1.tgz", @@ -3916,14 +3968,6 @@ "resolved": "packages/yfiles-kotlin-gradle-plugin-test-test", "link": true }, - "node_modules/yfiles-kotlin-import-optimizer-application": { - "resolved": "packages/yfiles-kotlin-import-optimizer-application", - "link": true - }, - "node_modules/yfiles-kotlin-import-optimizer-library": { - "resolved": "packages/yfiles-kotlin-import-optimizer-library", - "link": true - }, "node_modules/yfiles-kotlin-simple-app": { "resolved": "packages/yfiles-kotlin-simple-app", "link": true @@ -3971,6 +4015,7 @@ "devDependencies": { "karma": "6.4.4", "karma-chrome-launcher": "3.2.0", + "karma-firefox-launcher": "2.1.3", "karma-mocha": "2.0.1", "karma-sourcemap-loader": "0.4.0", "karma-webpack": "5.0.1", @@ -3984,10 +4029,12 @@ }, "packages/yfiles-kotlin-import-optimizer-application": { "version": "0.0.0-unspecified", + "extraneous": true, "devDependencies": {} }, "packages/yfiles-kotlin-import-optimizer-library": { "version": "0.0.0-unspecified", + "extraneous": true, "devDependencies": {} }, "packages/yfiles-kotlin-simple-app": { diff --git a/settings.gradle.kts b/settings.gradle.kts index b65c40971..dc8a1636f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -39,5 +39,3 @@ include("examples:simple-app") include("examples:data-classes") include("examples:configurable-properties") -include("examples:import-optimizer-library") -include("examples:import-optimizer-application") diff --git a/vsdx-kotlin/build.gradle.kts b/vsdx-kotlin/build.gradle.kts index 616e63e12..422644878 100644 --- a/vsdx-kotlin/build.gradle.kts +++ b/vsdx-kotlin/build.gradle.kts @@ -27,7 +27,7 @@ tasks { delete("src") } - val apiDescriptorFile = File(buildDir, "api.js") + val apiDescriptorFile = layout.buildDirectory.file("api.js").get().asFile val downloadApiDescriptor by registering(Download::class) { src(project.property("vsdx.api.url")) diff --git a/yfiles-kotlin/build.gradle.kts b/yfiles-kotlin/build.gradle.kts index fb6acc61f..b1fe827b3 100644 --- a/yfiles-kotlin/build.gradle.kts +++ b/yfiles-kotlin/build.gradle.kts @@ -25,8 +25,8 @@ tasks { delete("src") } - val apiDescriptorFile = File(buildDir, "api.js") - val devguideDescriptorFile = File(buildDir, "devguide.js") + val apiDescriptorFile = layout.buildDirectory.file("api.js").get().asFile + val devguideDescriptorFile = layout.buildDirectory.file("devguide.js").get().asFile val downloadApiDescriptor by registering(Download::class) { src(project.property("yfiles.api.url")) From e5450e64406fc7559283038fb071e0ab77143a76 Mon Sep 17 00:00:00 2001 From: EJ-K Date: Tue, 27 May 2025 16:58:31 +0100 Subject: [PATCH 2/2] remove unused code --- .../github/turansky/yfiles/ClassRegistry.kt | 20 ------------------- .../com/github/turansky/yfiles/Extensions.kt | 8 ++++---- .../com/github/turansky/yfiles/Generator.kt | 2 -- .../com/github/turansky/yfiles/JsonReader.kt | 1 - .../turansky/yfiles/KotlinFileGenerator.kt | 1 - 5 files changed, 4 insertions(+), 28 deletions(-) diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/ClassRegistry.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/ClassRegistry.kt index a0e591f68..57326c5c8 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/ClassRegistry.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/ClassRegistry.kt @@ -62,22 +62,6 @@ internal class ClassRegistry( } } -// private fun listenerOverridden( -// className: String, -// listenerName: String, -// checkCurrentClass: Boolean, -// ): Boolean { -// if (checkCurrentClass) { -// val listeners = listenerMap.getValue(className) -// if (listenerName in listeners) { -// return true -// } -// } -// return getParents(className).any { -// listenerOverridden(it, listenerName, true) -// } -// } - fun functionOverridden(className: String, functionName: String): Boolean { return functionOverridden(className, functionName, false) } @@ -85,8 +69,4 @@ internal class ClassRegistry( fun propertyOverridden(className: String, propertyName: String): Boolean { return propertyOverridden(className, propertyName, false) } - -// fun listenerOverridden(className: String, listenerName: String): Boolean { -// return listenerOverridden(className, listenerName, false) -// } } diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Extensions.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Extensions.kt index a48ec7bd4..0d111c74f 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Extensions.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Extensions.kt @@ -16,16 +16,16 @@ internal fun Interface.getExtensions(): String? = // language=kotlin ILOOKUP, -> """ - inline fun $ILOOKUP.lookup(): T? = - lookup(T::class.js.unsafeCast>()) + inline fun $ILOOKUP.lookup(): T? = + lookup(T::class.js.unsafeCast<$ICLASS_METADATA>()) inline fun $ILOOKUP.lookupValue(type: $ICLASS_METADATA):T = requireNotNull(lookup(type)) { "Unable to lookup type ${'$'}type" } - inline fun $ILOOKUP.lookupValue(): T = - lookupValue(T::class.js.unsafeCast>()) + inline fun $ILOOKUP.lookupValue(): T = + lookupValue(T::class.js.unsafeCast<$ICLASS_METADATA>()) """.trimIndent() else -> null } diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Generator.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Generator.kt index 22b350412..53984ef75 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Generator.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/Generator.kt @@ -70,8 +70,6 @@ fun generateKotlinDeclarations( addIteratorSupport(context) generateResourceTypes(devguideFile, context) - - //TODO: generate event wrappers } fun generateVsdxKotlinDeclarations( diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/JsonReader.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/JsonReader.kt index d9d586d95..36dcb9f9a 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/JsonReader.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/JsonReader.kt @@ -49,7 +49,6 @@ internal fun File.readApiJson(action: JSONObject.() -> Unit): JSONObject = .replace("any[]", "Array") .replaceFunctionSignatures() .fixSystemPackage() -// .fixClassDeclaration() .run { JSONObject(this) } .apply(action) .apply { fixFunctionSignatures() } diff --git a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/KotlinFileGenerator.kt b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/KotlinFileGenerator.kt index 270dfded4..e64f9294e 100644 --- a/buildSrc/src/main/kotlin/com/github/turansky/yfiles/KotlinFileGenerator.kt +++ b/buildSrc/src/main/kotlin/com/github/turansky/yfiles/KotlinFileGenerator.kt @@ -257,7 +257,6 @@ internal class KotlinFileGenerator( } if (components.isNotEmpty()) { - appendLine("//components") appendLine(components.indent()) }