diff --git a/libraries/stdlib/src/kotlin/Iterators.kt b/libraries/stdlib/src/kotlin/Iterators.kt index 841ecd71644..d286af1160d 100644 --- a/libraries/stdlib/src/kotlin/Iterators.kt +++ b/libraries/stdlib/src/kotlin/Iterators.kt @@ -14,13 +14,15 @@ public inline fun iterate(nextFunction: () -> T?) : java.util.Iterator = public inline fun java.util.Iterator.filterIsInstance(klass: Class): java.util.Iterator = FilterIsIterator(this, klass) private class FilterIsIterator(val iterator : java.util.Iterator, val klass: Class) : AbstractIterator() { - override protected fun computeNext(): R? { + override protected fun computeNext(): Unit { while (iterator.hasNext()) { val next = iterator.next() - if (klass.isInstance(next)) return next as R + if (klass.isInstance(next)) { + setNext(next as R) + return + } } done() - return null } } @@ -32,13 +34,15 @@ private class FilterIsIterator(val iterator : java.util.Iterator, va public inline fun java.util.Iterator.filter(predicate: (T) -> Boolean) : java.util.Iterator = FilterIterator(this, predicate) private class FilterIterator(val iterator : java.util.Iterator, val predicate: (T)-> Boolean) : AbstractIterator() { - override protected fun computeNext(): T? { + override protected fun computeNext(): Unit { while (iterator.hasNext()) { val next = iterator.next() - if ((predicate)(next)) return next + if ((predicate)(next)) { + setNext(next) + return + } } done() - return null } } @@ -49,15 +53,17 @@ public inline fun java.util.Iterator.filterNot(predicate: (T) -> Boolean) public inline fun java.util.Iterator?.filterNotNull() : java.util.Iterator = FilterNotNullIterator(this) private class FilterNotNullIterator(val iterator : java.util.Iterator?) : AbstractIterator() { - override protected fun computeNext(): T? { + override protected fun computeNext(): Unit { if (iterator != null) { while (iterator.hasNext()) { val next = iterator.next() - if (next != null) return next + if (next != null) { + setNext(next) + return + } } } done() - return null } } @@ -69,7 +75,13 @@ private class FilterNotNullIterator(val iterator : java.util.Iterator?) : public inline fun java.util.Iterator.map(transform: (T) -> R): java.util.Iterator = MapIterator(this, transform) private class MapIterator(val iterator : java.util.Iterator, val transform: (T) -> R) : AbstractIterator() { - override protected fun computeNext() : R? = if (iterator.hasNext()) (transform)(iterator.next()) else { done(); null } + override protected fun computeNext() : Unit { + if (iterator.hasNext()) { + setNext((transform)(iterator.next())) + } else { + done() + } + } } /** @@ -82,14 +94,19 @@ public inline fun java.util.Iterator.flatMap(transform: (T) -> java.ut private class FlatMapIterator(val iterator : java.util.Iterator, val transform: (T) -> java.util.Iterator) : AbstractIterator() { var transformed: java.util.Iterator = iterate { null } - override protected fun computeNext() : R? { - if (transformed.hasNext()) return transformed.next() - if (iterator.hasNext()) { - transformed = (transform)(iterator.next()) - return computeNext() + override protected fun computeNext() : Unit { + while (true) { + if (transformed.hasNext()) { + setNext(transformed.next()) + return + } + if (iterator.hasNext()) { + transformed = (transform)(iterator.next()) + } else { + done() + return + } } - done() - return null } } @@ -114,13 +131,15 @@ public inline fun java.util.Iterator.take(n: Int): java.util.Iterator public inline fun java.util.Iterator.takeWhile(predicate: (T) -> Boolean): java.util.Iterator = TakeWhileIterator(this, predicate) private class TakeWhileIterator(val iterator: java.util.Iterator, val predicate: (T) -> Boolean) : AbstractIterator() { - override protected fun computeNext() : T? { + override protected fun computeNext() : Unit { if (iterator.hasNext()) { val item = iterator.next() - if ((predicate)(item)) return item + if ((predicate)(item)) { + setNext(item) + return + } } done() - return null } } @@ -139,3 +158,4 @@ public inline fun java.util.Iterator.join(separator: String = ", ", prefi if (limit != null && count > limit) buffer.append("...") return buffer.append(postfix).toString().sure() } + diff --git a/libraries/stdlib/src/kotlin/dom/Dom.kt b/libraries/stdlib/src/kotlin/dom/Dom.kt index 57d9c617e37..6cb6de510b0 100644 --- a/libraries/stdlib/src/kotlin/dom/Dom.kt +++ b/libraries/stdlib/src/kotlin/dom/Dom.kt @@ -96,7 +96,7 @@ set(value) { // Helper methods /** Returns true if the element has the given CSS class style in its 'class' attribute */ -public fun Element.hasClass(cssClass: String): Boolean { +fun Element.hasClass(cssClass: String): Boolean { val c = this.classes return if (c != null) c.matches("""(^|.*\s+)$cssClass($|\s+.*)""") @@ -104,7 +104,7 @@ public fun Element.hasClass(cssClass: String): Boolean { } /** Adds the given CSS class to this element's 'class' attribute */ -public fun Element.addClass(cssClass: String): Boolean { +fun Element.addClass(cssClass: String): Boolean { val classSet = this.classSet val answer = classSet.add(cssClass) if (answer) { @@ -114,7 +114,7 @@ public fun Element.addClass(cssClass: String): Boolean { } /** Removes the given CSS class to this element's 'class' attribute */ -public fun Element.removeClass(cssClass: String): Boolean { +fun Element.removeClass(cssClass: String): Boolean { val classSet = this.classSet val answer = classSet.remove(cssClass) if (answer) { @@ -125,7 +125,7 @@ public fun Element.removeClass(cssClass: String): Boolean { /** TODO this approach generates compiler errors... -public fun Element.addClass(varargs cssClasses: Array): Boolean { +fun Element.addClass(varargs cssClasses: Array): Boolean { val set = this.classSet var answer = false for (cs in cssClasses) { @@ -139,7 +139,7 @@ public fun Element.addClass(varargs cssClasses: Array): Boolean { return answer } -public fun Element.removeClass(varargs cssClasses: Array): Boolean { +fun Element.removeClass(varargs cssClasses: Array): Boolean { val set = this.classSet var answer = false for (cs in cssClasses) { @@ -155,7 +155,7 @@ public fun Element.removeClass(varargs cssClasses: Array): Boolean { */ /** Searches for elements using the element name, an element ID (if prefixed with dot) or element class (if prefixed with #) */ -public fun Document?.get(selector: String): List { +fun Document?.get(selector: String): List { val root = this?.getDocumentElement() return if (root != null) { if (selector == "*") { @@ -179,7 +179,7 @@ public fun Document?.get(selector: String): List { } /** Searches for elements using the element name, an element ID (if prefixed with dot) or element class (if prefixed with #) */ -public fun Element.get(selector: String): List { +fun Element.get(selector: String): List { return if (selector == "*") { elements } else if (selector.startsWith(".")) { @@ -197,57 +197,53 @@ public fun Element.get(selector: String): List { } /** Returns an [[Iterator]] over the next siblings of this node */ -public fun Node.nextSiblings() : Iterator = NextSiblingIterator(this) +fun Node.nextSiblings() : Iterator = NextSiblingIterator(this) class NextSiblingIterator(var node: Node) : AbstractIterator() { - public override fun computeNext(): Node? { + override fun computeNext(): Unit { val next = node.getNextSibling() if (next != null) { - node = next - return next + setNext(next) } else { done() - return null } } } /** Returns an [[Iterator]] over the next siblings of this node */ -public fun Node.previousSiblings() : Iterator = PreviousSiblingIterator(this) +fun Node.previousSiblings() : Iterator = PreviousSiblingIterator(this) class PreviousSiblingIterator(var node: Node) : AbstractIterator() { - public override fun computeNext(): Node? { + override fun computeNext(): Unit { val next = node.getPreviousSibling() if (next != null) { - node = next - return next + setNext(next) } else { done() - return null } } } /** Returns true if this node is a Text node or a CDATA node */ -public fun Node.isText(): Boolean { +fun Node.isText(): Boolean { val nodeType = getNodeType() return nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE } /** Returns an [[Iterator]] of all the next [[Element]] siblings */ -public fun Node.nextElements(): Iterator = nextSiblings().filterIsInstance(javaClass()) +fun Node.nextElements(): Iterator = nextSiblings().filterIsInstance(javaClass()) /** Returns an [[Iterator]] of all the previous [[Element]] siblings */ -public fun Node.previousElements(): Iterator = previousSiblings().filterIsInstance(javaClass()) +fun Node.previousElements(): Iterator = previousSiblings().filterIsInstance(javaClass()) /** Returns the attribute value or empty string if its not present */ -public inline fun Element.attribute(name: String): String { +inline fun Element.attribute(name: String): String { return this.getAttribute(name) ?: "" } /** Returns the children of the element as a list */ -public inline fun Element?.children(): List { +inline fun Element?.children(): List { return this?.getChildNodes().toList() } @@ -261,22 +257,22 @@ get() = this?.getElementsByTagName("*").toElementList() /** Returns all the child elements given the local element name */ -public inline fun Element?.elements(localName: String?): List { +inline fun Element?.elements(localName: String?): List { return this?.getElementsByTagName(localName).toElementList() } /** Returns all the elements given the local element name */ -public inline fun Document?.elements(localName: String?): List { +inline fun Document?.elements(localName: String?): List { return this?.getElementsByTagName(localName).toElementList() } /** Returns all the child elements given the namespace URI and local element name */ -public inline fun Element?.elements(namespaceUri: String?, localName: String?): List { +inline fun Element?.elements(namespaceUri: String?, localName: String?): List { return this?.getElementsByTagNameNS(namespaceUri, localName).toElementList() } /** Returns all the elements given the namespace URI and local element name */ -public inline fun Document?.elements(namespaceUri: String?, localName: String?): List { +inline fun Document?.elements(namespaceUri: String?, localName: String?): List { return this?.getElementsByTagNameNS(namespaceUri, localName).toElementList() } @@ -300,7 +296,7 @@ val NodeList?.last : Node? get() = this.tail -public inline fun NodeList?.toList(): List { +inline fun NodeList?.toList(): List { return if (this == null) { Collections.EMPTY_LIST as List } @@ -309,7 +305,7 @@ public inline fun NodeList?.toList(): List { } } -public inline fun NodeList?.toElementList(): List { +inline fun NodeList?.toElementList(): List { return if (this == null) { Collections.EMPTY_LIST as List } @@ -319,7 +315,7 @@ public inline fun NodeList?.toElementList(): List { } /** Converts the node list to an XML String */ -public fun NodeList?.toXmlString(xmlDeclaration: Boolean = false): String { +fun NodeList?.toXmlString(xmlDeclaration: Boolean = false): String { return if (this == null) "" else { nodesToXmlString(this.toList(), xmlDeclaration) @@ -327,7 +323,7 @@ public fun NodeList?.toXmlString(xmlDeclaration: Boolean = false): String { } class NodeListAsList(val nodeList: NodeList): AbstractList() { - public override fun get(index: Int): Node { + override fun get(index: Int): Node { val node = nodeList.item(index) if (node == null) { throw IndexOutOfBoundsException("NodeList does not contain a node at index: " + index) @@ -336,11 +332,11 @@ class NodeListAsList(val nodeList: NodeList): AbstractList() { } } - public override fun size(): Int = nodeList.getLength() + override fun size(): Int = nodeList.getLength() } class ElementListAsList(val nodeList: NodeList): AbstractList() { - public override fun get(index: Int): Element { + override fun get(index: Int): Element { val node = nodeList.item(index) if (node is Element) { return node @@ -353,23 +349,23 @@ class ElementListAsList(val nodeList: NodeList): AbstractList() { } } - public override fun size(): Int = nodeList.getLength() + override fun size(): Int = nodeList.getLength() } // Syntax sugar -public inline fun Node.plus(child: Node?): Node { +inline fun Node.plus(child: Node?): Node { if (child != null) { this.appendChild(child) } return this } -public inline fun Element.plus(text: String?): Element = this.addText(text) +inline fun Element.plus(text: String?): Element = this.addText(text) -public inline fun Element.plusAssign(text: String?): Element = this.addText(text) +inline fun Element.plusAssign(text: String?): Element = this.addText(text) // Builder @@ -377,7 +373,7 @@ public inline fun Element.plusAssign(text: String?): Element = this.addText(text /** * Creates a new element which can be configured via a function */ -public fun Document.createElement(name: String, init: Element.()-> Unit): Element { +fun Document.createElement(name: String, init: Element.()-> Unit): Element { val elem = this.createElement(name).sure() elem.init() return elem @@ -386,14 +382,14 @@ public fun Document.createElement(name: String, init: Element.()-> Unit): Elemen /** * Creates a new element to an element which has an owner Document which can be configured via a function */ -public fun Element.createElement(name: String, doc: Document? = null, init: Element.()-> Unit): Element { +fun Element.createElement(name: String, doc: Document? = null, init: Element.()-> Unit): Element { val elem = ownerDocument(doc).createElement(name).sure() elem.init() return elem } /** Returns the owner document of the element or uses the provided document */ -public fun Node.ownerDocument(doc: Document? = null): Document { +fun Node.ownerDocument(doc: Document? = null): Document { val answer = if (this is Document) this as Document else if (doc == null) this.getOwnerDocument() else doc @@ -408,7 +404,7 @@ public fun Node.ownerDocument(doc: Document? = null): Document { /** Adds a newly created element which can be configured via a function */ -public fun Document.addElement(name: String, init: Element.()-> Unit): Element { +fun Document.addElement(name: String, init: Element.()-> Unit): Element { val child = createElement(name, init) this.appendChild(child) return child @@ -417,7 +413,7 @@ public fun Document.addElement(name: String, init: Element.()-> Unit): Element { /** Adds a newly created element to an element which has an owner Document which can be configured via a function */ -public fun Element.addElement(name: String, doc: Document? = null, init: Element.()-> Unit): Element { +fun Element.addElement(name: String, doc: Document? = null, init: Element.()-> Unit): Element { val child = createElement(name, doc, init) this.appendChild(child) return child @@ -426,7 +422,7 @@ public fun Element.addElement(name: String, doc: Document? = null, init: Element /** Adds a newly created text node to an element which either already has an owner Document or one must be provided as a parameter */ -public fun Element.addText(text: String?, doc: Document? = null): Element { +fun Element.addText(text: String?, doc: Document? = null): Element { if (text != null) { val child = ownerDocument(doc).createTextNode(text) this.appendChild(child) diff --git a/libraries/stdlib/src/kotlin/support/AbstractIterator.kt b/libraries/stdlib/src/kotlin/support/AbstractIterator.kt index d54b2300b45..4ae0bb878aa 100644 --- a/libraries/stdlib/src/kotlin/support/AbstractIterator.kt +++ b/libraries/stdlib/src/kotlin/support/AbstractIterator.kt @@ -2,7 +2,7 @@ package kotlin.support import java.util.NoSuchElementException -public enum class State { +enum class State { Ready NotReady Done @@ -14,10 +14,10 @@ public enum class State { * to implement the iterator, calling [[done()]] when the iteration is complete. */ public abstract class AbstractIterator: java.util.Iterator { - public var state: State = State.NotReady - public var next: T? = null + private var state: State = State.NotReady + private var next: T? = null - public override fun hasNext(): Boolean { + override fun hasNext(): Boolean { require(state != State.Failed) return when (state) { State.Done -> false @@ -26,13 +26,13 @@ public abstract class AbstractIterator: java.util.Iterator { } } - public override fun next(): T { + override fun next(): T { if (!hasNext()) throw NoSuchElementException() state = State.NotReady return next.sure() } - public override fun remove() { throw UnsupportedOperationException() } + override fun remove() { throw UnsupportedOperationException() } /** Returns the next element in the iteration without advancing the iteration */ fun peek(): T { @@ -42,14 +42,33 @@ public abstract class AbstractIterator: java.util.Iterator { private fun tryToComputeNext(): Boolean { state = State.Failed - next = computeNext(); - return if (state != State.Done) { state = State.Ready; true } else false + computeNext(); + return state == State.Ready } - /** Computes the next element in the iterator, calling [[done()]] when there are no more elements */ - abstract protected fun computeNext(): T? + /** + * Computes the next item in the iterator. + * + * This callback method should call one of these two methods + * + * * [[setNext(T)]] with the next value of the iteration + * * [[done()]] to indicate there are no more elements + * + * Failure to call either method will result in the iteration terminating with a failed state + */ + abstract protected fun computeNext(): Unit - /** Sets the state to done so that the iteration terminates */ + /** + * Sets the next value in the iteration, called from the [[computeNext()]] function + */ + protected fun setNext(value: T): Unit { + next = value + state = State.Ready + } + + /** + * Sets the state to done so that the iteration terminates + */ protected fun done() { state = State.Done } @@ -58,9 +77,12 @@ public abstract class AbstractIterator: java.util.Iterator { /** An [[Iterator]] which invokes a function to calculate the next value in the iteration until the function returns *null* */ class FunctionIterator(val nextFunction : () -> T?) : AbstractIterator() { - override protected fun computeNext(): T? { + override protected fun computeNext(): Unit { val next = (nextFunction)() - if (next == null) done() - return next + if (next == null) { + done() + } else { + setNext(next) + } } }