update the DOM API so that we implement using the property style access of properties which work natively in JS and avoid using getter/setter methods in the DOM library so that they can easily compile to JS too from the same org.w3c.dom API on the JVM

This commit is contained in:
James Strachan
2012-06-01 07:45:55 +01:00
parent 570f9d765d
commit bc7104a8fe
5 changed files with 373 additions and 236 deletions
+2 -2
View File
@@ -60,7 +60,7 @@ class DomBuilderTest() : TestCase() {
assertEquals(1, doc["#id2"].size())
assertEquals(1, doc["#id3"].size())
val root = doc.rootElement
val root = doc.documentElement
if (root == null) {
fail("No root!")
} else {
@@ -120,7 +120,7 @@ class DomBuilderTest() : TestCase() {
} else {
fail("Not an Element $grandChild")
}
val children = doc.rootElement.children()
val children = doc.documentElement.children()
val xml = nodesToXmlString(children)
println("root element has children: ${xml}")
assertEquals(1, children.size())
@@ -3,8 +3,11 @@ package org.jetbrains.kotlin.tools
import java.io.File
import java.io.FileWriter
import java.io.PrintWriter
import org.w3c.dom.*
import java.lang.reflect.Method
import java.lang.reflect.Modifier
import java.util.ArrayList
import java.util.TreeMap
import org.w3c.dom.*
/**
* This tool generates JavaScript stubs for classes available in the JDK which are already available in the browser environment
@@ -29,10 +32,10 @@ import js.noImpl
val classes = arrayList(javaClass<Attr>(), javaClass<CDATASection>(),
javaClass<CharacterData>(), javaClass<Comment>(),
javaClass<Document>(),javaClass<DocumentFragment>(),javaClass<DocumentType>(),
javaClass<Document>(), javaClass<DocumentFragment>(), javaClass<DocumentType>(),
javaClass<DOMConfiguration>(),
javaClass<DOMError>(), javaClass<DOMErrorHandler>(),
javaClass<DOMImplementation>(),
javaClass<DOMImplementation>(), javaClass<DOMImplementationList>(),
javaClass<DOMLocator>(),
javaClass<DOMStringList>(),
javaClass<Element>(),
@@ -53,31 +56,78 @@ import js.noImpl
println("native public trait ${klass.getSimpleName()}$extends {")
// lets iterate through each method
val methods = klass.getDeclaredMethods()
if (methods != null) {
// lets figure out the properties versus methods
val validMethods = ArrayList<Method>()
val properties = TreeMap<String, String>()
for (method in methods) {
if (method != null) {
val parameterTypes = method.getParameterTypes()!!
val name = method.getName() ?: ""
fun propertyName(): String {
val answer = name.substring(3).decapitalize()
return if (answer == "type") {
"`type`"
} else answer
}
fun propertyType() = simpleTypeName(method.getReturnType())
// TODO in java 7 its not easy with reflection to get the parameter argument name...
var counter = 0
val parameters = parameterTypes.map<Class<out Any?>?, String>{ "arg${++counter}: ${simpleTypeName(it)}" }.makeString(", ")
val returnType = simpleTypeName(method.getReturnType())
println(" fun ${method.getName()}($parameters): $returnType = js.noImpl")
val params = method.getParameterTypes()
val paramSize = params?.size ?: 0
if (name.size > 3) {
if (name.startsWith("get") && paramSize == 0) {
val propName = propertyName()
if (!properties.containsKey(propName)) {
properties.put(propName, "public val $propName: ${propertyType()}")
}
} else if (name.startsWith("set") && paramSize == 0) {
val propName = propertyName()
properties.put(propName, "public var $propName: ${propertyType()}")
} else {
validMethods.add(method)
}
} else {
validMethods.add(method)
}
}
}
for (statement in properties.values()) {
println(" $statement")
}
for (method in validMethods) {
val parameterTypes = method.getParameterTypes()!!
// TODO in java 7 its not easy with reflection to get the parameter argument name...
var counter = 0
val parameters = parameterTypes.map<Class<out Any?>?, String>{ "arg${++counter}: ${simpleTypeName(it)}" }.makeString(", ")
val returnType = simpleTypeName(method.getReturnType())
println(" public fun ${method.getName()}($parameters): $returnType = js.noImpl")
}
}
val fields = klass.getDeclaredFields()
if (fields != null) {
for (field in fields) {
if (field != null) {
val modifiers = field.getModifiers()
if (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers)) {
val fieldType = simpleTypeName(field.getType())
println(" public val ${field.getName()}: $fieldType")
if (fields.notEmpty()) {
println("")
println(" class object {")
for (field in fields) {
if (field != null) {
val modifiers = field.getModifiers()
if (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers)) {
val fieldType = simpleTypeName(field.getType())
try {
val value = field.get(null)
if (value != null) {
val fieldType = simpleTypeName(field.getType())
println(" public val ${field.getName()}: $fieldType = $value")
}
} catch (e: Exception) {
println("Caught: $e")
e.printStackTrace()
}
}
}
}
println(" }")
}
}
println("}")