Merge branch 'master' of github.com:JetBrains/kotlin
This commit is contained in:
+54
-19
@@ -14,12 +14,14 @@
|
||||
<artifactId>apidocs</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.pegdown</groupId>
|
||||
<artifactId>pegdown</artifactId>
|
||||
<version>${pegdown.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>${project.basedir}/../stdlib/src</sourceDirectory>
|
||||
<testSourceDirectory>test</testSourceDirectory>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.goldin.plugins</groupId>
|
||||
@@ -28,23 +30,21 @@
|
||||
<plugin>
|
||||
<groupId>com.goldin.plugins</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<!-- TODO use snapshot here! -->
|
||||
<version>0.2.3.8-SNAPSHOT</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile-kotlin-sources</id>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<docOutput>${project.basedir}/target/apidocs</docOutput>
|
||||
<sources>
|
||||
<src>${project.basedir}/../stdlib/src</src>
|
||||
<src>${project.basedir}/../kunit/src</src>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<execution>
|
||||
<id>compile-kotlin-sources</id>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<docOutput>${project.basedir}/target/site/apidocs</docOutput>
|
||||
<sources>
|
||||
<src>${project.basedir}/../stdlib/src</src>
|
||||
<src>${project.basedir}/../kunit/src</src>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
@@ -61,6 +61,41 @@
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
<extensions>
|
||||
<extension>
|
||||
<groupId>org.apache.maven.wagon</groupId>
|
||||
<artifactId>wagon-scm</artifactId>
|
||||
<version>2.2</version>
|
||||
</extension>
|
||||
<extension>
|
||||
<groupId>org.apache.maven.scm</groupId>
|
||||
<artifactId>maven-scm-manager-plexus</artifactId>
|
||||
<version>1.6</version>
|
||||
</extension>
|
||||
<extension>
|
||||
<groupId>org.apache.maven.scm</groupId>
|
||||
<artifactId>maven-scm-provider-gitexe</artifactId>
|
||||
<version>1.6</version>
|
||||
</extension>
|
||||
</extensions>
|
||||
</build>
|
||||
|
||||
<distributionManagement>
|
||||
<!--
|
||||
To deploy this add this to your ~/.m2/settings.xml
|
||||
|
||||
<server>
|
||||
<id>github-project-site</id>
|
||||
<username>git</username>
|
||||
<scmVersionType>branch</scmVersionType>
|
||||
<scmVersion>gh-pages</scmVersion>
|
||||
</server>
|
||||
-->
|
||||
|
||||
<site>
|
||||
<id>github-project-site</id>
|
||||
<url>scm:git:ssh://git@github.com/JetBrains/kotlin.git</url>
|
||||
</site>
|
||||
</distributionManagement>
|
||||
</project>
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
<properties>
|
||||
<junit-version>4.9</junit-version>
|
||||
<kotlin-compiler.version>0.2.3.8</kotlin-compiler.version>
|
||||
<kotlin-maven-plugin.version>0.2.3.8-beta-6</kotlin-maven-plugin.version>
|
||||
<kotlin-maven-plugin.version>0.2.3.8-beta-7</kotlin-maven-plugin.version>
|
||||
<kotlin-sdk>${project.basedir}/../../dist/kotlinc</kotlin-sdk>
|
||||
<pegdown.version>1.1.0</pegdown.version>
|
||||
<project-root>${project.basedir}/..</project-root>
|
||||
|
||||
+110
-16
@@ -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<FileReader,Unit> {
|
||||
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<FileReader,String>{ 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<FileInputStream,ByteArray>{ it.readBytes() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the bytes as the contents of the file
|
||||
*/
|
||||
fun File.writeBytes(data: ByteArray): Unit {
|
||||
return FileOutputStream(this).use<FileOutputStream,Unit>{ it.write(data) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the text as the contents of the file
|
||||
*/
|
||||
fun File.writeText(text: String): Unit {
|
||||
return FileWriter(this).use<FileWriter,Unit>{ 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<FileInputStream,Long>{
|
||||
val output = FileOutputStream(file)
|
||||
output.use<FileOutputStream,Long>{
|
||||
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<InputStream,ByteArray>{ it.readBytes() }
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package kotlin
|
||||
|
||||
object Assertions {
|
||||
// TODO make private once KT-1528 is fixed.
|
||||
val _ENABLED = (javaClass<java.lang.System>()).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<T>(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<T>(value:Boolean, message:T) {
|
||||
if(!value) {
|
||||
throw IllegalArgumentException(message.toString());
|
||||
}
|
||||
}
|
||||
@@ -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 ?: ""
|
||||
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()
|
||||
@@ -84,19 +84,19 @@ inline fun <T> 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 <T: Exception> failsWith(block: ()-> Unit) {
|
||||
fun <T: Throwable> failsWith(block: ()-> Unit) {
|
||||
try {
|
||||
block()
|
||||
asserter().fail("Expected an exception to be thrown")
|
||||
|
||||
@@ -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<AssertionError> {
|
||||
// assert(false)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
Reference in New Issue
Block a user