diff --git a/libraries/apidocs/pom.xml b/libraries/apidocs/pom.xml
index d664a34d27e..a86d507f4c4 100644
--- a/libraries/apidocs/pom.xml
+++ b/libraries/apidocs/pom.xml
@@ -14,12 +14,14 @@
apidocs
+
+ org.pegdown
+ pegdown
+ ${pegdown.version}
+
- ${project.basedir}/../stdlib/src
- test
-
com.goldin.plugins
@@ -28,23 +30,21 @@
com.goldin.plugins
kotlin-maven-plugin
-
- 0.2.3.8-SNAPSHOT
-
- compile-kotlin-sources
-
- compile
-
-
- ${project.basedir}/target/apidocs
-
- ${project.basedir}/../stdlib/src
- ${project.basedir}/../kunit/src
-
-
-
-
+
+ compile-kotlin-sources
+
+ compile
+
+
+ ${project.basedir}/target/site/apidocs
+
+ ${project.basedir}/../stdlib/src
+ ${project.basedir}/../kunit/src
+
+
+
+
org.jetbrains.kotlin
@@ -61,6 +61,41 @@
+
+
+
+ org.apache.maven.wagon
+ wagon-scm
+ 2.2
+
+
+ org.apache.maven.scm
+ maven-scm-manager-plexus
+ 1.6
+
+
+ org.apache.maven.scm
+ maven-scm-provider-gitexe
+ 1.6
+
+
+
+
+
+
+ github-project-site
+ scm:git:ssh://git@github.com/JetBrains/kotlin.git
+
+
diff --git a/libraries/pom.xml b/libraries/pom.xml
index 8d43d3c57b0..e4912da3dea 100644
--- a/libraries/pom.xml
+++ b/libraries/pom.xml
@@ -13,7 +13,7 @@
4.9
0.2.3.8
- 0.2.3.8-beta-6
+ 0.2.3.8-beta-7
${project.basedir}/../../dist/kotlinc
1.1.0
${project.basedir}/..
diff --git a/libraries/stdlib/src/JavaIo.kt b/libraries/stdlib/src/JavaIo.kt
index 6dcd0a421b1..dd3a982f984 100644
--- a/libraries/stdlib/src/JavaIo.kt
+++ b/libraries/stdlib/src/JavaIo.kt
@@ -3,6 +3,9 @@ package kotlin.io
import java.io.*
import java.nio.charset.*
import java.util.NoSuchElementException
+import java.net.URL
+
+protected val defaultBufferSize: Int = 64 * 1024
inline fun print(message : Any?) {
System.out?.print(message)
@@ -273,22 +276,92 @@ fun File.isDescendant(file: File): Boolean {
}
/**
-* Loads the text file as a String
-*/
-fun File.loadText(): String {
- val buffer = StringWriter()
- FileReader(this).use {
- it.copyTo(buffer)
+ * Returns the relative path of the given descendant of this file if its a descendant
+ */
+fun File.relativePath(descendant: File): String {
+ val prefix = this.directory.canonicalPath
+ val answer = descendant.canonicalPath
+ return if (answer.startsWith(prefix)) {
+ answer.substring(prefix.size + 1)
+ } else {
+ answer
}
+}
+
+/**
+ * Reads the entire content of the file as a String
+ *
+ * This method is not recommended on huge files.
+ */
+fun File.readText(): String {
+ return FileReader(this).use{ it.readText() }
+}
+
+/**
+ * Reads the entire content of the file as bytes
+ *
+ * This method is not recommended on huge files.
+ */
+fun File.readBytes(): ByteArray {
+ return FileInputStream(this).use{ it.readBytes() }
+}
+
+/**
+ * Writes the bytes as the contents of the file
+ */
+fun File.writeBytes(data: ByteArray): Unit {
+ return FileOutputStream(this).use{ it.write(data) }
+}
+
+/**
+ * Writes the text as the contents of the file
+ */
+fun File.writeText(text: String): Unit {
+ return FileWriter(this).use{ it.write(text) }
+}
+
+/**
+ * Copies this file to the given output file, returning the number of bytes copied
+ */
+fun File.copyTo(file: File, bufferSize: Int = defaultBufferSize): Long {
+ file.directory.mkdirs()
+ val input = FileInputStream(this)
+ return input.use{
+ val output = FileOutputStream(file)
+ output.use{
+ input.copyTo(output, bufferSize)
+ }
+ }
+}
+
+/**
+ * Reads this stream completely into a byte array
+ *
+ * **Note** it is the callers responsibility to close this resource
+ */
+fun InputStream.readBytes(): ByteArray {
+ val buffer = ByteArrayOutputStream()
+ this.copyTo(buffer)
+ return buffer.toByteArray().sure()
+}
+
+/**
+ * Reads this reader completely as a String
+ *
+ * **Note** it is the callers responsibility to close this resource
+ */
+fun Reader.readText(): String {
+ val buffer = StringWriter()
+ this.copyTo(buffer)
return buffer.toString() ?: ""
}
/**
-* Copies this stream to the given output stream, returning the number of bytes copied
-*
-* **Note** it is the callers responsibility to close both of these resources
-*/
-fun InputStream.copyTo(out: OutputStream, bufferSize: Int = 64 * 1024): Long {
+ * Copies this stream to the given output stream, returning the number of bytes copied
+ *
+ * **Note** it is the callers responsibility to close both of these resources
+ */
+fun InputStream.copyTo(out: OutputStream, bufferSize: Int = defaultBufferSize): Long {
var bytesCopied: Long = 0
val buffer = ByteArray(bufferSize)
var bytes = read(buffer)
@@ -302,11 +375,11 @@ fun InputStream.copyTo(out: OutputStream, bufferSize: Int = 64 * 1024): Long {
/**
-* Copies this reader to the given output writer, returning the number of bytes copied.
-*
-* **Note** it is the callers responsibility to close both of these resources
-*/
-fun Reader.copyTo(out: Writer, bufferSize: Int = 64 * 1024): Long {
+ * Copies this reader to the given output writer, returning the number of bytes copied.
+ *
+ * **Note** it is the callers responsibility to close both of these resources
+ */
+fun Reader.copyTo(out: Writer, bufferSize: Int = defaultBufferSize): Long {
var charsCopied: Long = 0
val buffer = CharArray(bufferSize)
var chars = read(buffer)
@@ -317,3 +390,24 @@ fun Reader.copyTo(out: Writer, bufferSize: Int = 64 * 1024): Long {
}
return charsCopied
}
+
+
+/**
+ * Reads the entire content of the URL as a String with an optional character set name
+ *
+ * This method is not recommended on huge files.
+ */
+fun URL.readText(encoding: String? = null): String {
+ val bytes = readBytes()
+ return if (encoding != null) String(bytes, encoding) else String(bytes)
+}
+
+/**
+ * Reads the entire content of the URL as bytes
+ *
+ * This method is not recommended on huge files.
+ */
+fun URL.readBytes(): ByteArray {
+ return this.openStream().sure().use{ it.readBytes() }
+}
+
diff --git a/libraries/stdlib/src/Preconditions.kt b/libraries/stdlib/src/Preconditions.kt
new file mode 100644
index 00000000000..061a095332c
--- /dev/null
+++ b/libraries/stdlib/src/Preconditions.kt
@@ -0,0 +1,48 @@
+package kotlin
+
+object Assertions {
+ // TODO make private once KT-1528 is fixed.
+ val _ENABLED = (javaClass()).desiredAssertionStatus()
+}
+
+/**
+ * Throws an [[AssertionError]] if the `value` is false and runtime assertions have been
+ * enabled on the JVM using the `-ea` JVM option.
+ */
+inline fun assert(value:Boolean):Unit {
+ if(Assertions._ENABLED) {
+ if(!value) {
+ throw AssertionError();
+ }
+ }
+}
+
+/**
+* Throws an [[AssertionError]] with specified `message` if the `value` is false
+* and runtime assertions have been enabled on the JVM using the `-ea` JVM option.
+*/
+inline fun assert(value:Boolean, message:T) {
+ if(Assertions._ENABLED) {
+ if(!value) {
+ throw AssertionError(message);
+ }
+ }
+}
+
+/**
+ * Throws an [[IllegalArgumentException]] if the `value` is false.
+ */
+inline fun require(value:Boolean):Unit {
+ if(!value) {
+ throw IllegalArgumentException();
+ }
+}
+
+/**
+* Throws an [[IllegalArgumentException]] with specified `message` if the `value` is false.
+*/
+inline fun require(value:Boolean, message:T) {
+ if(!value) {
+ throw IllegalArgumentException(message.toString());
+ }
+}
diff --git a/libraries/stdlib/src/String.kt b/libraries/stdlib/src/String.kt
index 6f6ac6540f0..9c5b9922e2d 100644
--- a/libraries/stdlib/src/String.kt
+++ b/libraries/stdlib/src/String.kt
@@ -164,4 +164,22 @@ inline fun String.toLowerCase(locale : java.util.Locale) = (this as java.lang.St
inline fun String.toUpperCase(locale : java.util.Locale) = (this as java.lang.String).toUpperCase(locale).sure()
/** Returns the string if it is not null or the empty string if its null */
-inline fun String?.orEmpty(): String = this ?: ""
\ No newline at end of file
+inline fun String?.orEmpty(): String = this ?: ""
+
+
+// "Extension functions" for CharSequence
+
+inline fun CharSequence.length() = (this as java.lang.CharSequence).length()
+
+inline val CharSequence.size : Int
+get() = length()
+
+inline fun CharSequence.charAt(index : Int) = (this as java.lang.CharSequence).charAt(index)
+
+inline fun CharSequence.get(index : Int) = charAt(index)
+
+inline fun CharSequence.subSequence(start : Int, end : Int) = (this as java.lang.CharSequence).subSequence(start, end)
+
+inline fun CharSequence.get(start : Int, end : Int) = subSequence(start, end)
+
+inline fun CharSequence.toString() = (this as java.lang.CharSequence).toString()
\ No newline at end of file
diff --git a/libraries/stdlib/src/test/Test.kt b/libraries/stdlib/src/test/Test.kt
index 310cf5cf33f..e4af2cc5bb1 100644
--- a/libraries/stdlib/src/test/Test.kt
+++ b/libraries/stdlib/src/test/Test.kt
@@ -84,19 +84,19 @@ inline fun expect(expected: T, message: String, block: ()-> T) {
}
/** Asserts that given function block fails by throwing an exception */
-fun fails(block: ()-> Unit): Exception? {
+fun fails(block: ()-> Unit): Throwable? {
try {
block()
asserter().fail("Expected an exception to be thrown")
return null
- } catch (e: Exception) {
+ } catch (e: Throwable) {
println("Caught excepted exception: $e")
return e
}
}
/** Asserts that a block fails with a specific exception being thrown */
-fun failsWith(block: ()-> Unit) {
+fun failsWith(block: ()-> Unit) {
try {
block()
asserter().fail("Expected an exception to be thrown")
diff --git a/libraries/testlib/test/PreconditionsTest.kt b/libraries/testlib/test/PreconditionsTest.kt
new file mode 100644
index 00000000000..278108c8cbd
--- /dev/null
+++ b/libraries/testlib/test/PreconditionsTest.kt
@@ -0,0 +1,49 @@
+package test.collections
+
+import junit.framework.TestCase
+import kotlin.test.*
+import java.lang.IllegalArgumentException
+
+class PreconditionsTest() : TestCase() {
+
+ fun testPassingRequire() {
+ require(true)
+ }
+
+ fun testFailingRequire() {
+ val error = fails {
+ require(false)
+ }
+ if(error is IllegalArgumentException) {
+ assertNull(error.getMessage())
+ } else {
+ fail("Invalid exception type: "+error)
+ }
+ }
+
+ fun testPassingRequireWithMessage() {
+ require(true, "Hello")
+ }
+
+ fun testFailingRequireWithMessage() {
+ val error = fails {
+ require(false, "Hello")
+ }
+ if(error is IllegalArgumentException) {
+ assertEquals("Hello", error.getMessage())
+ } else {
+ fail("Invalid exception type: "+error)
+ }
+ }
+
+// // Not sure why the assert method is not being resolved.
+// fun ignorePassingAssert() {
+// assert(true)
+// }
+//
+// fun ignoreFailingAssert() {
+// failsWith {
+// assert(false)
+// }
+// }
+}
\ No newline at end of file