Libraries written in Kotlin are factored out into a separate project

This commit is contained in:
Andrey Breslav
2012-03-06 18:48:49 +04:00
parent 7c6f1657d2
commit 0a08ac5fe8
253 changed files with 252 additions and 2703 deletions
+1
View File
@@ -0,0 +1 @@
libraries
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AntConfiguration">
<defaultAnt bundledAnt="true" />
</component>
</project>
+21
View File
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac" />
<resourceExtensions />
<wildcardResourcePatterns>
<entry name="?*.properties" />
<entry name="?*.xml" />
<entry name="?*.gif" />
<entry name="?*.png" />
<entry name="?*.jpeg" />
<entry name="?*.jpg" />
<entry name="?*.html" />
<entry name="?*.dtd" />
<entry name="?*.tld" />
<entry name="?*.ftl" />
</wildcardResourcePatterns>
<annotationProcessing enabled="false" useClasspath="true" />
</component>
</project>
+5
View File
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
</project>
+9
View File
@@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="kotlin-runtime">
<CLASSES>
<root url="file://$PROJECT_DIR$/../dist/classes/runtime" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/kdoc/kdoc.iml" filepath="$PROJECT_DIR$/kdoc/kdoc.iml" />
<module fileurl="file://$PROJECT_DIR$/kunit/kunit.iml" filepath="$PROJECT_DIR$/kunit/kunit.iml" />
<module fileurl="file://$PROJECT_DIR$/runtests/runtests.iml" filepath="$PROJECT_DIR$/runtests/runtests.iml" />
<module fileurl="file://$PROJECT_DIR$/stdlib/stdlib.iml" filepath="$PROJECT_DIR$/stdlib/stdlib.iml" />
<module fileurl="file://$PROJECT_DIR$/testlib/testlib.iml" filepath="$PROJECT_DIR$/testlib/testlib.iml" />
</modules>
</component>
</project>
+5
View File
@@ -0,0 +1,5 @@
<component name="DependencyValidationManager">
<state>
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
</state>
</component>
+125
View File
@@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="" />
</component>
</project>
+1
View File
@@ -0,0 +1 @@
target
+11
View File
@@ -0,0 +1,11 @@
import kotlin.modules.*
fun project() {
module("apidocs") {
classpath += "kunit/lib/junit-4.9.jar"
addSourceFiles("../stdlib/ktSrc")
addSourceFiles("../stdlib/src")
addSourceFiles("../kunit/src/main/kotlin")
}
}
+160
View File
@@ -0,0 +1,160 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/kotlin" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/kotlin" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="stdlib" exported="" />
<orderEntry type="module-library" exported="" scope="TEST">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../testlib/lib/junit-4.9.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library" exported="">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../../dist/kotlinc/lib/intellij-core.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library" exported="">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../../dist/kotlinc/lib/kotlin-compiler.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$MODULE_DIR$/../compiler/cli/src" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../../dist/kotlinc/lib/annotations.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../../dist/kotlinc/lib/asm-commons.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../../dist/kotlinc/lib/asm.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../../dist/kotlinc/lib/cli-10.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../../dist/kotlinc/lib/guava-11.0.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../../dist/kotlinc/lib/picocontainer.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../../dist/kotlinc/lib/trove4j.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../../lib/asm-util-3.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../../lib/asm-tree-3.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../../lib/asm-analysis-3.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../../lib/parboiled-core-1.0.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../../lib/parboiled-java-1.0.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../../lib/pegdown-1.1.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
</component>
</module>
+15
View File
@@ -0,0 +1,15 @@
import kotlin.modules.*
fun project() {
module("kdoc") {
classpath += "dist/kotlinc/lib/intellij-core.jar"
classpath += "dist/kotlinc/lib/kotlin-compiler.jar"
// TODO its a bit sad we can't use patterns here...
addClasspathEntry("dist/kotlinc/lib/pegdown-1.1.0.jar")
addClasspathEntry("dist/kotlinc/lib/parboiled-core-1.0.2.jar")
addClasspathEntry("dist/kotlinc/lib/parboiled-java-1.0.2.jar")
addSourceFiles("src/main/kotlin")
}
}
+113
View File
@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kdoc</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<junit-version>4.8.1</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-sdk>${project.basedir}/../dist/kotlinc</kotlin-sdk>
</properties>
<repositories>
<repository>
<id>evgeny-goldin.org</id>
<url>http://evgeny-goldin.org/artifactory/repo/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>evgeny-goldin.org</id>
<url>http://evgeny-goldin.org/artifactory/repo/</url>
</pluginRepository>
</pluginRepositories>
<dependencies>
<!-- TODO a dirty hack until we have the artifacts in a mvn repo -->
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-compiler</artifactId>
<version>${kotlin-compiler.version}</version>
<scope>system</scope>
<systemPath>${kotlin-sdk}/lib/kotlin-compiler.jar</systemPath>
</dependency>
<dependency>
<groupId>org.pegdown</groupId>
<artifactId>pegdown</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<groupId>com.goldin.plugins</groupId>
<artifactId>ivy-maven-plugin</artifactId>
<version>${kotlin-maven-plugin.version}</version>
<executions>
<execution>
<id>add-ivy-dependencies</id>
<goals>
<goal>ivy</goal>
</goals>
<phase>initialize</phase>
<configuration>
<ivyconf>${project.basedir}/src/main/resources/ivyconf.xml</ivyconf>
<dependencies>
<dependency>
<groupId>ivy.org</groupId>
<artifactId>bt343</artifactId>
<version>latest.lastSuccessful</version>
<classifier>core/intellij-core</classifier>
</dependency>
<dependency>
<groupId>ivy.org</groupId>
<artifactId>bt344</artifactId>
<version>latest.lastSuccessful</version>
<classifier>kotlin-runtime</classifier>
</dependency>
</dependencies>
<scope>compile</scope>
<verbose>true</verbose>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.goldin.plugins</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin-maven-plugin.version}</version>
<executions>
<execution>
<id>compile-kotlin-sources</id>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,12 @@
package org.jetbrains.kotlin.doc
import org.jetbrains.kotlin.doc.model.KModel
import java.io.File
/**
* A simple plugin to KDoc to generate information from the model into a directory
* which can be implemented using any kind of layout or format.
*/
trait Doclet {
fun generate(model: KModel, outputDir: File): Unit
}
@@ -0,0 +1,94 @@
package org.jetbrains.kotlin.doc
import kotlin.*
import kotlin.util.*
import org.jetbrains.kotlin.doc.templates.*
import org.jetbrains.kotlin.template.TextTemplate
import org.jetbrains.kotlin.doc.model.*
import java.io.File
import java.util.List
import java.util.HashSet
import java.util.*
import com.intellij.psi.PsiElement
import org.jetbrains.jet.lang.resolve.BindingContext
import org.jetbrains.jet.lang.resolve.BindingContext.*
import org.jetbrains.jet.compiler.CompilerPlugin
import org.jetbrains.jet.lang.psi.JetFile
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor
import org.jetbrains.jet.lexer.JetTokens
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
import org.jetbrains.jet.lang.descriptors.CallableDescriptor
import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor
import org.jetbrains.jet.lang.resolve.java.JavaNamespaceDescriptor
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor
import org.jetbrains.jet.lang.resolve.scopes.JetScope
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver
import org.jetbrains.jet.util.slicedmap.WritableSlice
import org.jetbrains.jet.lang.resolve.BindingContextUtils
/** Creates JavaDoc style HTML output from the model */
class JavadocStyleHtmlDoclet() : Doclet {
override fun generate(model: KModel, outputDir: File): Unit {
fun run(fileName: String, template: TextTemplate): Unit {
val file = File(outputDir, fileName)
file.getParentFile()?.mkdirs()
log("Generating $fileName")
template.renderTo(file)
}
fun generateExtensionFunctions(p: KPackage): Unit {
val map = inheritedExtensionFunctions(p.functions)
val pmap = inheritedExtensionProperties(p.properties)
val classes = hashSet<KClass>()
classes.addAll(map.keySet())
classes.addAll(pmap.keySet())
for (c in classes) {
if (c != null) {
val functions = map.get(c).orEmpty()
val properties = pmap.get(c).orEmpty()
run("${p.nameAsPath}/${c.nameAsPath}-extensions.html",
ClassExtensionsTemplate(model, p, c, functions, properties))
}
}
}
println("Generating kdoc to $outputDir")
run("allclasses-frame.html", AllClassesFrameTemplate(model, " target=\"classFrame\""))
run("allclasses-noframe.html", AllClassesFrameTemplate(model))
// run("constant-values.html", ConstantValuesTemplate(model))
// run("deprecated-list.html", DeprecatedListTemplate(model))
run("help-doc.html", HelpDocTemplate(model))
// run("index-all.html", IndexAllTemplate(model))
run("index.html", IndexTemplate(model))
run("overview-frame.html", OverviewFrameTemplate(model))
run("overview-summary.html", OverviewSummaryTemplate(model))
run("overview-tree.html", OverviewTreeTemplate(model))
run("package-list", PackageListTemplate(model))
// run("serialized-form.html", SerializedFormTemplate(model))
for (p in model.packages) {
run("${p.nameAsPath}/package-frame.html", PackageFrameTemplate(model, p))
run("${p.nameAsPath}/package-summary.html", PackageSummaryTemplate(model, p))
//run("${p.nameAsPath}/package-tree.html", PackageTreeTemplate(model, p))
//run("${p.nameAsPath}/package-use.html", PackageUseTemplate(model, p))
for (c in p.classes) {
run("${c.nameAsPath}.html", ClassTemplate(model, p, c))
}
generateExtensionFunctions(p)
}
}
protected fun log(text: String) {
println(text)
}
}
@@ -0,0 +1,43 @@
package org.jetbrains.kotlin.doc
import kotlin.*
import kotlin.util.*
import org.jetbrains.kotlin.doc.templates.*
import org.jetbrains.kotlin.template.TextTemplate
import org.jetbrains.kotlin.doc.model.*
import java.io.File
import java.util.List
import java.util.HashSet
import java.util.Collection
import com.intellij.psi.PsiElement
import org.jetbrains.jet.lang.resolve.BindingContext
import org.jetbrains.jet.lang.resolve.BindingContext.*
import org.jetbrains.jet.compiler.CompilerPlugin
import org.jetbrains.jet.lang.psi.JetFile
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor
import org.jetbrains.jet.lexer.JetTokens
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
import org.jetbrains.jet.lang.descriptors.CallableDescriptor
import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor
import org.jetbrains.jet.lang.resolve.java.JavaNamespaceDescriptor
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor
import org.jetbrains.jet.lang.resolve.scopes.JetScope
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver
import org.jetbrains.jet.util.slicedmap.WritableSlice
import org.jetbrains.jet.lang.resolve.BindingContextUtils
/** Generates the Kotlin Documentation for the model */
class KDoc(val outputDir: File) : KModelCompilerPlugin() {
override fun processModel(model: KModel) {
// TODO allow this to be configured; maybe we use configuration on the KotlinModule
// to define what doclets to use?
val generator = JavadocStyleHtmlDoclet()
generator.generate(model, outputDir)
}
}
@@ -0,0 +1,90 @@
package org.jetbrains.kotlin.doc
import kotlin.*
import kotlin.util.*
import java.util.*
/**
* The configuration used with KDoc
*/
class KDocConfig() {
/**
* Returns the name of the documentation set
*/
public var title: String = "Documentation"
/**
* Returns a map of the package prefix to the URLs to use to link to it in the documentation
*/
public val packagePrefixToUrls: Map<String, String> = TreeMap<String, String>(LongestFirstStringComparator())
/**
* Returns true if a warning should be generated if there are no comments
* on documented function or property
*/
public var warnNoComments: Boolean = true
/**
* Returns true if protected functions and properties should be documented
*/
public var includeProtected: Boolean = true
{
// add some common defaults
addPackageLink("http://docs.oracle.com/javase/6/docs/api/", "java", "org.w3c.dom", "org.xml.sax", "org.omg", "org.ietf.jgss")
addPackageLink("http://kentbeck.github.com/junit/javadoc/latest/", "org.junit", "junit")
}
/**
* Returns a set of all the package which have been warned that were missing an external URL
*/
public val missingPackageUrls: Set<String> = TreeSet<String>()
/**
* Adds one or more package prefixes to the given javadoc URL
*/
fun addPackageLink(url: String, vararg packagePrefixes: String): Unit {
for (p in packagePrefixes) {
packagePrefixToUrls.put(p, url)
}
}
/**
* Resolves a link to the given class name
*/
fun resolveLink(packageName: String): String {
// TODO should be able to do something like
// for (e in packageUrls.filterNulls()) {
val entrySet = packagePrefixToUrls.entrySet()
if (entrySet != null) {
for (e in entrySet) {
val p = e?.getKey()
val url = e?.getValue()
if (p != null && url != null) {
if (packageName.startsWith(p)) {
return url
}
}
}
}
if (missingPackageUrls.add(packageName)) {
println("Warning: could not find external link to package: $packageName")
}
return ""
}
}
protected class LongestFirstStringComparator() : Comparator<String> {
override fun compare(s1: String, s2: String): Int {
var answer = s1.length() - s2.length()
if (answer == 0) {
answer = s1.compareTo(s2)
}
return answer
}
override fun equals(obj : Any?) : Boolean {
return obj is LongestFirstStringComparator
}
}
@@ -0,0 +1,50 @@
package org.jetbrains.kotlin.doc.model
import kotlin.*
import kotlin.util.*
import org.jetbrains.kotlin.doc.KDocConfig
import org.jetbrains.kotlin.doc.templates.*
import org.jetbrains.kotlin.template.TextTemplate
import java.io.File
import java.util.List
import java.util.HashSet
import java.util.Collection
import com.intellij.psi.PsiElement
import org.jetbrains.jet.lang.resolve.BindingContext
import org.jetbrains.jet.lang.resolve.BindingContext.*
import org.jetbrains.jet.compiler.CompilerPlugin
import org.jetbrains.jet.lang.psi.JetFile
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor
import org.jetbrains.jet.lexer.JetTokens
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
import org.jetbrains.jet.lang.descriptors.CallableDescriptor
import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor
import org.jetbrains.jet.lang.resolve.java.JavaNamespaceDescriptor
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor
import org.jetbrains.jet.lang.resolve.scopes.JetScope
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver
import org.jetbrains.jet.util.slicedmap.WritableSlice
import org.jetbrains.jet.lang.resolve.BindingContextUtils
/** Base class for any compiler plugin which needs to process a KModel */
abstract class KModelCompilerPlugin : CompilerPlugin {
public open var config: KDocConfig = KDocConfig()
override fun processFiles(context: BindingContext?, sources: List<JetFile?>?) {
if (context != null && sources != null) {
val model = KModel(context, config)
model.load(sources)
processModel(model)
}
}
abstract fun processModel(model: KModel): Unit
}
@@ -0,0 +1,652 @@
package org.jetbrains.kotlin.doc.model
import kotlin.*
import kotlin.util.*
import org.jetbrains.kotlin.doc.KDocConfig
import java.util.*
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor
import org.jetbrains.jet.lang.resolve.java.JavaNamespaceDescriptor
import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.lang.resolve.BindingContextUtils
import org.jetbrains.jet.lexer.JetTokens
import org.jetbrains.jet.lang.resolve.BindingContext
import org.jetbrains.jet.lang.resolve.scopes.JetScope
import org.jetbrains.jet.lang.descriptors.CallableDescriptor
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor
import org.jetbrains.jet.lang.psi.JetFile
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
import org.pegdown.PegDownProcessor
import org.pegdown.LinkRenderer
import org.pegdown.ast.WikiLinkNode
import org.pegdown.LinkRenderer.Rendering
import org.pegdown.ast.RefLinkNode
import org.pegdown.ast.AutoLinkNode
import org.pegdown.ast.ExpLinkNode
import org.pegdown.Extensions
fun containerName(descriptor: DeclarationDescriptor): String = qualifiedName(descriptor.getContainingDeclaration())
fun qualifiedName(descriptor: DeclarationDescriptor?): String {
if (descriptor == null || descriptor is ModuleDescriptor) {
return ""
} else {
val parent = containerName(descriptor)
var name = descriptor.getName() ?: ""
if (name.startsWith("<")) {
name = ""
}
val answer = if (parent.length() > 0) parent + "." + name else name
return if (answer.startsWith(".")) answer.substring(1) else answer
}
}
// TODO for some reason the SortedMap causes kotlin to freak out a little :)
fun inheritedExtensionFunctions(functions: Collection<KFunction>): Map<KClass, SortedSet<KFunction>> {
//fun inheritedExtensionFunctions(functions: Collection<KFunction>): SortedMap<KClass, SortedSet<KFunction>> {
val map = extensionFunctions(functions)
// for each class, lets walk its base classes and add any other extension functions from base classes
val answer = TreeMap<KClass, SortedSet<KFunction>>()
for (c in map.keySet()) {
val allFunctions = map.get(c).orEmpty().toSortedSet()
answer.put(c, allFunctions)
val des = c.descendants()
for (b in des) {
val list = map.get(b)
if (list != null) {
if (allFunctions != null) {
for (f in list) {
if (f != null) {
// add the methods from the base class if we don't have a matching method
if (!allFunctions.any{ it.name == f.name && it.parameterTypeText == f.parameterTypeText}) {
allFunctions.add(f)
}
}
}
}
}
}
}
return answer
}
// TODO for some reason the SortedMap causes kotlin to freak out a little :)
fun inheritedExtensionProperties(properties: Collection<KProperty>): Map<KClass, SortedSet<KProperty>> {
val map = extensionProperties(properties)
// for each class, lets walk its base classes and add any other extension properties from base classes
val answer = TreeMap<KClass, SortedSet<KProperty>>()
for (c in map.keySet()) {
val allProperties = map.get(c).orEmpty().toSortedSet()
answer.put(c, allProperties)
val des = c.descendants()
for (b in des) {
val list = map.get(b)
if (list != null) {
if (allProperties != null) {
for (f in list) {
if (f != null) {
// add the proeprties from the base class if we don't have a matching method
if (!allProperties.any{ it.name == f.name}) {
allProperties.add(f)
}
}
}
}
}
}
}
return answer
}
// TODO for some reason the SortedMap causes kotlin to freak out a little :)
fun extensionFunctions(functions: Collection<KFunction>): Map<KClass, List<KFunction>> {
val map = TreeMap<KClass, List<KFunction>>()
functions.filter{ it.extensionClass != null }.groupBy(map){ it.extensionClass.sure() }
return map
}
// TODO for some reason the SortedMap causes kotlin to freak out a little :)
fun extensionProperties(properties: Collection<KProperty>): Map<KClass, List<KProperty>> {
val map = TreeMap<KClass, List<KProperty>>()
properties.filter{ it.extensionClass != null }.groupBy(map){ it.extensionClass.sure() }
return map
}
abstract class KClassOrPackage : KAnnotated() {
public open val functions: SortedSet<KFunction> = TreeSet<KFunction>()
public open val properties: SortedSet<KProperty> = TreeSet<KProperty>()
}
class KModel(var context: BindingContext, val config: KDocConfig, var title: String = "Documentation", var version: String = "TODO") {
// TODO generates java.lang.NoSuchMethodError: kotlin.util.namespace.hashMap(Ljet/TypeInfo;Ljet/TypeInfo;)Ljava/util/HashMap;
//val packages = sortedMap<String,KPackage>()
public val packageMap: SortedMap<String, KPackage> = TreeMap<String, KPackage>()
public val allPackages: Collection<KPackage>
get() = packageMap.values().sure()
/** Returns the local packages */
public val packages: Collection<KPackage>
get() = allPackages.filter{ it.local }
public val classes: Collection<KClass>
get() = packages.flatMap{ it.classes }
public var markdownProcessor: PegDownProcessor = PegDownProcessor(Extensions.ALL)
/** Loads the model from the given set of source files */
fun load(sources: List<JetFile?>): Unit {
val allNamespaces = HashSet<NamespaceDescriptor>()
for (source in sources) {
if (source != null) {
// We retrieve a descriptor by a PSI element from the context
val namespaceDescriptor = BindingContextUtils.namespaceDescriptor(context, source)
if (namespaceDescriptor != null) {
allNamespaces.add(namespaceDescriptor);
}
}
}
val allClasses = HashSet<KClass>()
for (namespace in allNamespaces) {
getPackage(namespace)
for (descriptor in namespace.getMemberScope().getAllDescriptors()) {
if (descriptor is ClassDescriptor) {
val klass = getClass(descriptor)
if (klass != null) {
allClasses.add(klass)
}
} else if (descriptor is NamespaceDescriptor) {
getPackage(descriptor)
}
}
}
}
/* Returns the package for the given name or null if it does not exist */
fun getPackage(name: String): KPackage? = packageMap.get(name)
/** Returns the package for the given descriptor, creating one if its not available */
fun getPackage(descriptor: NamespaceDescriptor): KPackage {
val name = qualifiedName(descriptor)
var created = false
val pkg = packageMap.getOrPut(name) {
created = true
KPackage(this, descriptor, name)
}
if (created) {
pkg.description = commentsFor(descriptor)
val scope = descriptor.getMemberScope()
addFunctions(pkg, scope)
pkg.local = isLocal(descriptor)
}
return pkg;
}
protected fun isLocal(descriptor: DeclarationDescriptor): Boolean {
return if (descriptor is ModuleDescriptor) {
true
} else {
val parent = descriptor.getContainingDeclaration()
if (parent != null) {
isLocal(parent)
} else {
false
}
}
}
protected fun addFunctions(owner: KClassOrPackage, scope: JetScope): Unit {
try {
val descriptors = scope.getAllDescriptors()
for (descriptor in descriptors) {
if (descriptor is PropertyDescriptor) {
val name = descriptor.getName()
val returnType = getType(descriptor.getReturnType())
if (returnType != null) {
val receiver = descriptor.getReceiverParameter()
val extensionClass = if (receiver is ExtensionReceiver) {
getType(receiver.getType())
} else null
val property = KProperty(owner, descriptor, name, returnType, extensionClass?.klass)
owner.properties.add(property)
}
} else if (descriptor is CallableDescriptor) {
val function = createFunction(owner, descriptor)
if (function != null) {
owner.functions.add(function)
}
}
}
} catch (e: Throwable) {
println("Caught exception finding function declarations on $owner")
}
}
protected fun createFunction(owner: KClassOrPackage, descriptor: CallableDescriptor): KFunction? {
val returnType = getType(descriptor.getReturnType())
if (returnType != null) {
val name = descriptor.getName() ?: "null"
val parameters = ArrayList<KParameter>()
val params = descriptor.getValueParameters()
for (param in params) {
if (param != null) {
val p = createParameter(param)
if (p != null) {
parameters.add(p)
}
}
}
val function = KFunction(descriptor, owner, name, returnType, parameters)
addTypeParameters(function.typeParameters, descriptor.getTypeParameters())
function.description = commentsFor(descriptor)
val receiver = descriptor.getReceiverParameter()
if (receiver is ExtensionReceiver) {
function.extensionClass = getType(receiver.getType())?.klass
}
return function
}
return null
}
protected fun addTypeParameters(answer: List<KTypeParameter>, descriptors: List<TypeParameterDescriptor?>): Unit {
for (typeParam in descriptors) {
if (typeParam != null) {
val p = createTypeParameter(typeParam)
if (p != null){
answer.add(p)
}
}
}
}
protected fun createTypeParameter(descriptor: TypeParameterDescriptor): KTypeParameter? {
val name = descriptor.getName()
val answer = KTypeParameter(name, descriptor)
answer.description = commentsFor(descriptor)
return answer
}
protected fun createParameter(descriptor: ValueParameterDescriptor): KParameter? {
val returnType = getType(descriptor.getReturnType())
if (returnType != null) {
val name = descriptor.getName()
val answer = KParameter(name, returnType)
answer.description = commentsFor(descriptor)
return answer
}
return null
}
fun commentsFor(descriptor: DeclarationDescriptor): String {
val psiElement = try {
BindingContextUtils.descriptorToDeclaration(context, descriptor)
} catch (e: Throwable) {
// ignore exceptions on fake descriptors
null
}
// This method is a hack. Doc comments should be easily accessible, but they aren't for now.
if (psiElement != null) {
var node = psiElement.getNode()?.getTreePrev()
while (node != null && (node?.getElementType() == JetTokens.WHITE_SPACE || node?.getElementType() == JetTokens.BLOCK_COMMENT)) {
node = node?.getTreePrev()
}
if (node == null) return ""
if (node?.getElementType() != JetTokens.DOC_COMMENT) return ""
var text = node?.getText() ?: ""
// lets remove the comment tokens
val lines = text.trim().split("\\n")
if (lines != null) {
// lets remove the /** ... * ... */ tokens
val buffer = StringBuilder()
val last = lines.size - 1
for (i in 0.upto(last)) {
var text = lines[i] ?: ""
text = text.trim()
if (i == 0) {
text = text.trimLeading("/**").trimLeading("/*")
} else {
buffer.append("\n")
}
if (i >= last) {
text = text.trimTrailing("*/")
} else if (i > 0) {
text = text.trimLeading("* ")
if (text == "*") text = ""
}
buffer.append(text)
}
val linkRenderer = CustomLinkRenderer(descriptor)
return wikiConvert(buffer.toString() ?: "", linkRenderer)
} else {
return text
}
}
return ""
}
fun wikiConvert(text: String, linkRenderer: LinkRenderer): String {
return markdownProcessor.markdownToHtml(text, linkRenderer).sure()
}
fun getType(aType: JetType?): KType? {
if (aType != null) {
val classifierDescriptor = aType.getConstructor().getDeclarationDescriptor()
val klass = if (classifierDescriptor is ClassDescriptor) {
getClass(classifierDescriptor)
} else null
return KType(aType, this, klass)
}
return null
}
fun getClass(classElement: ClassDescriptor): KClass? {
val name = classElement.getName()
val container = classElement.getContainingDeclaration()
if (name != null && container is NamespaceDescriptor) {
val pkg = getPackage(container)
return pkg.getClass(name, classElement)
} else {
println("No package found for $container and class $name")
return null
}
}
fun previous(pkg: KPackage): KPackage? {
// TODO
return null
}
fun next(pkg: KPackage): KPackage? {
// TODO
return null
}
}
class CustomLinkRenderer(descriptor: DeclarationDescriptor) : LinkRenderer() {
override fun render(node : WikiLinkNode?) : Rendering? {
println("LinkRenderer.render(WikiLinkNode): $node")
// TODO translate the wiki link to a Class/function/property/extensionFunction etc
return super.render(node)
}
override fun render(node : RefLinkNode?, url : String?, title : String?, text : String?) : Rendering? {
// println("LinkRenderer.render(RefLinkNode): $node url: $url title: $title text: $text")
return super.render(node, url, title, text)
}
override fun render(node : AutoLinkNode?) : Rendering? {
// println("LinkRenderer.render(AutoLinkNode): $node")
return super.render(node)
}
override fun render(node : ExpLinkNode?, text : String?) : Rendering? {
// println("LinkRenderer.render(ExpLinkNode): $node text: $text")
return super.render(node, text)
}
}
abstract class KAnnotated {
public open var description: String = ""
public open var detailedDescription: String = ""
get() = if ($detailedDescription.notEmpty()) $detailedDescription else description
public open var deprecated: Boolean = false
}
abstract class KNamed(val name: String) : KAnnotated(), Comparable<KNamed> {
override fun compareTo(other: KNamed): Int = name.compareTo(other.name)
open fun equals(other: KPackage) = name == other.name
open fun toString() = name
}
class KPackage(val model: KModel, val descriptor: NamespaceDescriptor,
val name: String,
var local: Boolean = false) : KClassOrPackage(), Comparable<KPackage> {
override fun compareTo(other: KPackage): Int = name.compareTo(other.name)
fun equals(other: KPackage) = name == other.name
fun toString() = "KPackage($name)"
fun getClass(name: String, descriptor: ClassDescriptor): KClass {
var created = false
val klass = classMap.getOrPut(name) {
created = true
KClass(this, descriptor, name)
}
if (created) {
klass.description = model.commentsFor(descriptor)
val typeConstructor = descriptor.getTypeConstructor()
val superTypes = typeConstructor.getSupertypes()
for (st in superTypes) {
val sc = model.getType(st)
if (sc != null) {
klass.baseClasses.add(sc)
}
}
val scope = descriptor.getDefaultType().getMemberScope()
model.addFunctions(klass, scope)
model.addTypeParameters(klass.typeParameters, typeConstructor.getParameters())
}
return klass
}
/** Returns the name as a directory using '/' instead of '.' */
public val nameAsPath: String
get() = if (name.length() == 0) "." else name.replace('.', '/')
/** Returns a list of all the paths in the package name */
public val namePaths: List<String>
get() {
val answer = ArrayList<String>()
for (n in name.split("\\.")) {
if (n != null) {
answer.add(n)
}
}
return answer;
}
/** Returns a relative path like ../.. for each path in the name */
public val nameAsRelativePath: String
get() {
val answer = namePaths.map{ ".." }.join("/")
return if (answer.length == 0) "" else answer + "/"
}
// TODO generates java.lang.NoSuchMethodError: kotlin.util.namespace.hashMap(Ljet/TypeInfo;Ljet/TypeInfo;)Ljava/util/HashMap;
//val classes = sortedMap<String,KClass>()
public val classMap: SortedMap<String, KClass> = TreeMap<String, KClass>()
public val classes: Collection<KClass> = classMap.values().sure()
public val annotations: Collection<KClass> = ArrayList<KClass>()
fun qualifiedName(simpleName: String): String {
return if (name.length() > 0) {
"${name}.${simpleName}"
} else {
simpleName
}
}
fun previous(pkg: KClass): KClass? {
// TODO
return null
}
fun next(pkg: KClass): KClass? {
// TODO
return null
}
fun groupClassMap(): Map<String, List<KClass>> {
return classes.groupBy(TreeMap<String, List<KClass>>()){it.group}
}
fun packageFunctions() = functions.filter{ it.extensionClass == null }
}
class KType(val jetType: JetType, val model: KModel, val klass: KClass?, val arguments: List<KType> = ArrayList<KType>()) : KNamed(klass?.name ?: jetType.toString()) {
{
if (klass != null) {
this.description = klass.description
this.detailedDescription = klass.detailedDescription
}
for (arg in jetType.getArguments()) {
if (arg != null) {
val argJetType = arg.getType()
val t = model.getType(argJetType)
if (t != null) {
$arguments.add(t)
}
}
}
}
override fun toString() = if (nullable) "$name?" else name
val nullable: Boolean
get() = jetType.isNullable()
}
class KClass(val pkg: KPackage, val descriptor: ClassDescriptor,
val simpleName: String,
var kind: String = "class", var group: String = "Other",
var annotations: List<KAnnotation> = arrayList<KAnnotation>(),
var typeParameters: List<KTypeParameter> = arrayList<KTypeParameter>(),
var since: String = "",
var authors: List<String> = arrayList<String>(),
var baseClasses: List<KType> = arrayList<KType>(),
var nestedClasses: List<KClass> = arrayList<KClass>(),
var sourceLine: Int = 2) : KClassOrPackage(), Comparable<KClass> {
override fun compareTo(other: KClass): Int = name.compareTo(other.name)
fun equals(other: KClass) = name == other.name
fun toString() = "$kind($name)"
/** Link to the type which is relative if its a local type but could be a type in a different library or null if no link */
public var url: String? = null
get() {
if ($url == null) $url = "${nameAsPath}.html"
return $url
}
public val name: String = pkg.qualifiedName(simpleName)
public val model: KModel = pkg.model
public val packageName: String = pkg.name
/** Returns the name as a directory using '/' instead of '.' */
public val nameAsPath: String
get() = name.replace('.', '/')
fun isAnnotation() = kind == "annotation"
fun isInterface() = kind == "interface"
/** Returns all of the base classes and all of their descendants */
fun descendants(answer: Set<KClass> = LinkedHashSet<KClass>()): Set<KClass> {
for (b in baseClasses) {
val c = b.klass
if (c != null) {
answer.add(c)
c.descendants(answer)
}
}
return answer
}
}
class KFunction(val descriptor: CallableDescriptor, val owner: KClassOrPackage, val name: String,
var returnType: KType,
var parameters: List<KParameter>,
var extensionClass: KClass? = null,
var modifiers: List<String> = arrayList<String>(),
var typeParameters: List<KTypeParameter> = arrayList<KTypeParameter>(),
var exceptions: List<KClass> = arrayList<KClass>(),
var annotations: List<KAnnotation> = arrayList<KAnnotation>(),
var sourceLine: Int = 2) : KAnnotated(), Comparable<KFunction> {
public val parameterTypeText: String = parameters.map{ it.aType.name }.join(", ")
override fun compareTo(other: KFunction): Int {
var answer = name.compareTo(other.name)
if (answer == 0) {
answer = parameterTypeText.compareTo(other.parameterTypeText)
if (answer == 0) {
val ec1 = extensionClass?.name ?: ""
val ec2 = other.extensionClass?.name ?: ""
answer = ec1.compareTo(ec2)
}
}
return answer
}
fun equals(other: KFunction) = name == other.name && this.parameterTypeText == other.parameterTypeText &&
this.extensionClass == other.extensionClass && this.owner == other.owner
fun toString() = "fun $name($parameterTypeText): $returnType"
public val link: String = "$name($parameterTypeText)"
/** Returns a list of generic type parameter names kinds like "A, I" */
public val typeParametersText: String
get() = typeParameters.map{ it.name }.join(", ")
}
class KProperty(val owner: KClassOrPackage, val descriptor: PropertyDescriptor, val name: String,
val returnType: KType, val extensionClass: KClass?) : KAnnotated(), Comparable<KProperty> {
override fun compareTo(other: KProperty): Int = name.compareTo(other.name)
public val link: String = "$name"
fun equals(other: KFunction) = name == other.name
fun toString() = "property $name"
}
class KParameter(val name: String,
var aType: KType) : KAnnotated() {
fun toString() = "$name: ${aType.name}"
}
class KTypeParameter(val name: String,
val descriptor: TypeParameterDescriptor,
var extends: List<KClass> = arrayList<KClass>()) : KAnnotated() {
fun toString() = "$name"
}
class KAnnotation(var klass: KClass) : KAnnotated() {
// TODO add some parameter values?
fun toString() = "@$klass.simpleName"
}
@@ -0,0 +1,45 @@
package org.jetbrains.kotlin.doc.templates
import kotlin.*
import org.jetbrains.kotlin.template.*
import kotlin.io.*
import kotlin.util.*
import java.util.*
import org.jetbrains.kotlin.doc.model.KModel
class AllClassesFrameTemplate(val model: KModel, val classAttributes: String = "") : KDocTemplate() {
override fun render() {
println("""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!--NewPage-->
<HTML>
<HEAD>
<!-- Generated by kdoc (${model.version}) on ${Date()} -->
<META http-equiv="Content-Type"
content="text/html; charset=UTF-8">
<TITLE>
All Classes (${model.title})</TITLE>
<META NAME="date" CONTENT="2012-01-09">
<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
</HEAD>
<BODY BGCOLOR="white">
<FONT size="+1" CLASS="FrameHeadingFont">
<B>All Classes</B></FONT>
<BR>
<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
<TR>
<TD NOWRAP><FONT CLASS="FrameItemFont">""")
for (c in model.classes) {
println("""<A HREF="${c.nameAsPath}.html" title="class in ${c.packageName}"$classAttributes>${c.simpleName}</A>
<BR>""")
}
println("""</FONT></TD>
</TR>
</TABLE>
</BODY>
</HTML>
""")
}
}
@@ -0,0 +1,46 @@
package org.jetbrains.kotlin.doc.templates
import kotlin.*
import org.jetbrains.kotlin.template.*
import kotlin.io.*
import kotlin.util.*
import java.util.*
import org.jetbrains.kotlin.doc.model.KModel
import org.jetbrains.kotlin.doc.model.KPackage
import org.jetbrains.kotlin.doc.model.KClass
import org.jetbrains.kotlin.doc.model.KFunction
import org.jetbrains.kotlin.doc.model.KAnnotation
import org.jetbrains.kotlin.doc.model.KProperty
class ClassExtensionsTemplate(m: KModel, p: KPackage, k: KClass,
val functions: Collection<KFunction>, val properties: Collection<KProperty>) : ClassTemplate(m, p, k) {
override fun pageTitle(): String = "${klass.name} Extensions fom ${pkg.name} (${model.title})"
override fun printBody(): Unit {
println("""<HR>
<!-- ======== START OF CLASS EXTENSIONS DATA ======== -->
<H2>
<FONT SIZE="-1">
${pkg.name}</FONT>
<BR>
Extensions on ${klass.name}</H2>
<DL>
<DT>
extension functions on class <A HREF="${sourceHref(klass)}"><B>${klass.name}</B></A><DT>
from package ${link(pkg)}
</DL>
</PRE>
<P>""")
printPropertySummary(properties)
printFunctionSummary(functions)
printFunctionDetail(functions)
println("""<!-- ========= END OF CLASS EXTENSIONS DATA ========= -->
<HR>
""")
}
override fun href(f: KFunction): String = "#${f.link}"
}
@@ -0,0 +1,263 @@
package org.jetbrains.kotlin.doc.templates
import kotlin.*
import org.jetbrains.kotlin.template.*
import kotlin.io.*
import kotlin.util.*
import java.util.*
import org.jetbrains.kotlin.doc.model.KModel
import org.jetbrains.kotlin.doc.model.KPackage
import org.jetbrains.kotlin.doc.model.KClass
import org.jetbrains.kotlin.doc.model.KFunction
import org.jetbrains.kotlin.doc.model.KAnnotation
open class ClassTemplate(open val model: KModel, pkg: KPackage, open val klass: KClass) : PackageTemplateSupport(pkg) {
open fun pageTitle(): String = "${klass.name} (${model.title})"
override fun render() {
println("""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!--NewPage-->
<HTML>
<HEAD>
<!-- Generated by kdoc (${model.version}) on ${Date()} -->
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>
${pageTitle()}
</TITLE>
<META NAME="date" CONTENT="2012-01-09">
<META NAME="date" CONTENT="2012-01-09">
<LINK REL="stylesheet" TYPE="text/css" HREF="${pkg.nameAsRelativePath}stylesheet.css" TITLE="Style">
<SCRIPT type="text/javascript">
function windowTitle()
{
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="${klass.name} (${model.title})";
}
}
</SCRIPT>
<NOSCRIPT>
</NOSCRIPT>
</HEAD>
<BODY BGCOLOR="white" onload="windowTitle();">
<HR>
<!-- ========= START OF TOP NAVBAR ======= -->
<A NAME="navbar_top"><!-- --></A>
<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
<TR>
<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
<A NAME="navbar_top_firstrow"><!-- --></A>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
<TR ALIGN="center" VALIGN="top">
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="${pkg.nameAsRelativePath}overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/${klass.simpleName}.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="${pkg.nameAsRelativePath}deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="${pkg.nameAsRelativePath}index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="${pkg.nameAsRelativePath}help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
</TR>
</TABLE>
</TD>
<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
</EM>
</TD>
</TR>
<TR>
""")
printPrevNextClass()
println("""<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="${pkg.nameAsRelativePath}index.html?${klass.nameAsPath}.html" target="_top"><B>FRAMES</B></A> &nbsp;
&nbsp;<A HREF="${klass.simpleName}.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
document.writeln('<A HREF="${pkg.nameAsRelativePath}allclasses-noframe.html"><B>All Classes</B></A>');
}
//-->
</SCRIPT>
<NOSCRIPT>
<A HREF="${pkg.nameAsRelativePath}allclasses-noframe.html"><B>All Classes</B></A>
</NOSCRIPT>
</FONT></TD>
</TR>
<TR>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
SUMMARY:&nbsp;<A HREF="#nested_class_summary">NESTED</A>&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
</TR>
</TABLE>
<A NAME="skip-navbar_top"></A>
<!-- ========= END OF TOP NAVBAR ========= -->
""")
printBody()
println("""<!-- ======= START OF BOTTOM NAVBAR ====== -->
<A NAME="navbar_bottom"><!-- --></A>
<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
<TR>
<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
<A NAME="navbar_bottom_firstrow"><!-- --></A>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
<TR ALIGN="center" VALIGN="top">
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="${pkg.nameAsRelativePath}overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/${klass.simpleName}.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="${pkg.nameAsRelativePath}deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="${pkg.nameAsRelativePath}index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="${pkg.nameAsRelativePath}help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
</TR>
</TABLE>
</TD>
<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
</EM>
</TD>
</TR>
<TR>""")
printPrevNextClass()
println("""<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="${pkg.nameAsRelativePath}index.html?${klass.nameAsPath}.html" target="_top"><B>FRAMES</B></A> &nbsp;
&nbsp;<A HREF="${klass.simpleName}.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
document.writeln('<A HREF="${pkg.nameAsRelativePath}allclasses-noframe.html"><B>All Classes</B></A>');
}
//-->
</SCRIPT>
<NOSCRIPT>${pkg.nameAsRelativePath}allclasses-noframe.html"><B>All Classes</B></A>
</NOSCRIPT>
</FONT></TD>
</TR>
<TR>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
SUMMARY:&nbsp;<A HREF="#nested_class_summary">NESTED</A>&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
</TR>
</TABLE>
<A NAME="skip-navbar_bottom"></A>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
<HR>
Copyright &#169; 2010-2012. All Rights Reserved.
</BODY>
</HTML>""")
}
open fun printBody(): Unit {
println("""<HR>
<!-- ======== START OF CLASS DATA ======== -->
<H2>
<FONT SIZE="-1">
${pkg.name}</FONT>
<BR>
Class ${klass.simpleName}</H2>
<PRE>""")
for (bc in klass.baseClasses) {
println(link(bc, true))
}
println(""" <IMG SRC="${pkg.nameAsRelativePath}resources/inherit.gif" ALT="extended by "><B>${klass.name}</B>
</PRE>
<HR>
<DL>
<DT><PRE><FONT SIZE="-1">""")
printAnnotations(klass.annotations)
print("""</FONT>public class <A HREF="${sourceHref(klass)}"><B>${klass.simpleName}</B></A><DT>""")
if (!klass.baseClasses.isEmpty()) {
print("""extends """)
for (bc in klass.baseClasses) {
println(link(bc))
}
}
println("""</DL>
</PRE>
<P>""")
println(klass.detailedDescription)
if (klass.since.size > 0 || klass.authors.size > 0) {
println("""<P>
<DL>""")
if (klass.since.size > 0) {
println("""<DT><B>Since:</B></DT>
<DD>${klass.since}</DD>""")
}
for (author in klass.authors) {
println("""<DT><B>Author:</B></DT>
<DD>${author}</DD>""")
}
println("""</DL>""")
}
println("""<HR>
<P>""")
val nestedClasses = klass.nestedClasses
if (!nestedClasses.isEmpty()) {
println("""<!-- ======== NESTED CLASS SUMMARY ======== -->
<A NAME="nested_class_summary"><!-- --></A>
<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
<B>Nested Class Summary</B></FONT></TH>
</TR>""")
for (nc in nestedClasses) {
println("""<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>static&nbsp;class</CODE></FONT></TD>
<TD><CODE><B><A HREF="${pkg.nameAsRelativePath}${nc.nameAsPath}.html" title="class in ${nc.packageName}">${klass.simpleName}.${nc.simpleName}</A></B></CODE>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${nc.description}
</TD>""")
}
println("""</TR>
</TABLE>
&nbsp;""")
}
printPropertySummary(klass.properties)
printFunctionSummary(klass.functions)
printFunctionDetail(klass.functions)
println("""<!-- ========= END OF CLASS DATA ========= -->
<HR>
""")
}
open fun printPrevNextClass(): Unit {
println("""<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">""")
val prev = pkg.previous(klass)
if (prev != null) {
println("""&nbsp;<A HREF="${pkg.nameAsRelativePath}${prev.nameAsPath}.html" title="class in ${prev.packageName}"><B>PREV CLASS</B></A>&nbsp;""")
}
val next = pkg.next(klass)
if (next != null) {
println("""&nbsp;<A HREF="${pkg.nameAsRelativePath}${next.nameAsPath}.html" title="class in ${next.packageName}"><B>NEXT CLASS</B></A>""")
}
println("""</FONT></TD>""")
}
}
@@ -0,0 +1,237 @@
package org.jetbrains.kotlin.doc.templates
import kotlin.*
import org.jetbrains.kotlin.template.*
import kotlin.io.*
import kotlin.util.*
import java.util.*
import org.jetbrains.kotlin.doc.model.KModel
class HelpDocTemplate(val model: KModel) : KDocTemplate() {
override fun render() {
println("""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<!--NewPage-->
<HTML>
<HEAD>
<!-- Generated by javadoc on Mon Jan 09 13:32:00 EST 2012-->
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>
API Help (${model.title})
</TITLE>
<META NAME="date" CONTENT="2012-01-09">
<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
<SCRIPT type="text/javascript">
function windowTitle()
{
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="API Help (${model.title})";
}
}
</SCRIPT>
<NOSCRIPT>
</NOSCRIPT>
</HEAD>
<BODY BGCOLOR="white" onload="windowTitle();">
<HR>
<!-- ========= START OF TOP NAVBAR ======= -->
<A NAME="navbar_top"><!-- --></A>
<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
<TR>
<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
<A NAME="navbar_top_firstrow"><!-- --></A>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
<TR ALIGN="center" VALIGN="top">
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Help</B></FONT>&nbsp;</TD>
</TR>
</TABLE>
</TD>
<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
</EM>
</TD>
</TR>
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
&nbsp;PREV&nbsp;
&nbsp;NEXT</FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="index.html?help-doc.html" target="_top"><B>FRAMES</B></A> &nbsp;
&nbsp;<A HREF="help-doc.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
}
//-->
</SCRIPT>
<NOSCRIPT>
<A HREF="allclasses-noframe.html"><B>All Classes</B></A>
</NOSCRIPT>
</FONT></TD>
</TR>
</TABLE>
<A NAME="skip-navbar_top"></A>
<!-- ========= END OF TOP NAVBAR ========= -->
<HR>
<CENTER>
<H1>
How This API Document Is Organized</H1>
</CENTER>
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.<H3>
Overview</H3>
<BLOCKQUOTE>
<P>
The <A HREF="overview-summary.html">Overview</A> page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.</BLOCKQUOTE>
<H3>
Package</H3>
<BLOCKQUOTE>
<P>
Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain four categories:<UL>
<LI>Interfaces (italic)<LI>Classes<LI>Enums<LI>Exceptions<LI>Errors<LI>Annotation Types</UL>
</BLOCKQUOTE>
<H3>
Class/Interface</H3>
<BLOCKQUOTE>
<P>
Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:<UL>
<LI>Class inheritance diagram<LI>Direct Subclasses<LI>All Known Subinterfaces<LI>All Known Implementing Classes<LI>Class/interface declaration<LI>Class/interface description
<P>
<LI>Nested Class Summary<LI>Field Summary<LI>Constructor Summary<LI>Method Summary
<P>
<LI>Field Detail<LI>Constructor Detail<LI>Method Detail</UL>
Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.</BLOCKQUOTE>
</BLOCKQUOTE>
<H3>
Annotation Type</H3>
<BLOCKQUOTE>
<P>
Each annotation type has its own separate page with the following sections:<UL>
<LI>Annotation Type declaration<LI>Annotation Type description<LI>Required Element Summary<LI>Optional Element Summary<LI>Element Detail</UL>
</BLOCKQUOTE>
</BLOCKQUOTE>
<H3>
Enum</H3>
<BLOCKQUOTE>
<P>
Each enum has its own separate page with the following sections:<UL>
<LI>Enum declaration<LI>Enum description<LI>Enum Constant Summary<LI>Enum Constant Detail</UL>
</BLOCKQUOTE>
<H3>
Use</H3>
<BLOCKQUOTE>
Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.</BLOCKQUOTE>
<H3>
Tree (Class Hierarchy)</H3>
<BLOCKQUOTE>
There is a <A HREF="overview-tree.html">Class Hierarchy</A> page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with <code>java.lang.Object</code>. The interfaces do not inherit from <code>java.lang.Object</code>.<UL>
<LI>When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.<LI>When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.</UL>
</BLOCKQUOTE>
<H3>
Deprecated API</H3>
<BLOCKQUOTE>
The <A HREF="deprecated-list.html">Deprecated API</A> page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.</BLOCKQUOTE>
<H3>
Index</H3>
<BLOCKQUOTE>
The <A HREF="index-all.html">Index</A> contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.</BLOCKQUOTE>
<H3>
Prev/Next</H3>
These links take you to the next or previous class, interface, package, or related page.<H3>
Frames/No Frames</H3>
These links show and hide the HTML frames. All pages are available with or without frames.
<P>
<H3>
Serialized Form</H3>
Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.
<P>
<H3>
Constant Field Values</H3>
The <a href="constant-values.html">Constant Field Values</a> page lists the static final fields and their values.
<P>
<FONT SIZE="-1">
<EM>
This help file applies to API documentation generated using the standard doclet.</EM>
</FONT>
<BR>
<HR>
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<A NAME="navbar_bottom"><!-- --></A>
<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
<TR>
<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
<A NAME="navbar_bottom_firstrow"><!-- --></A>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
<TR ALIGN="center" VALIGN="top">
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Help</B></FONT>&nbsp;</TD>
</TR>
</TABLE>
</TD>
<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
</EM>
</TD>
</TR>
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
&nbsp;PREV&nbsp;
&nbsp;NEXT</FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="index.html?help-doc.html" target="_top"><B>FRAMES</B></A> &nbsp;
&nbsp;<A HREF="help-doc.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
}
//-->
</SCRIPT>
<NOSCRIPT>
<A HREF="allclasses-noframe.html"><B>All Classes</B></A>
</NOSCRIPT>
</FONT></TD>
</TR>
</TABLE>
<A NAME="skip-navbar_bottom"></A>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
<HR>
Copyright &#169; 2012. All Rights Reserved.
</BODY>
</HTML>""")
}
}
@@ -0,0 +1,54 @@
package org.jetbrains.kotlin.doc.templates
import kotlin.*
import org.jetbrains.kotlin.template.*
import kotlin.io.*
import kotlin.util.*
import java.util.*
import org.jetbrains.kotlin.doc.model.KModel
class IndexTemplate(val model: KModel) : KDocTemplate() {
override fun render() {
print("""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<!--NewPage-->
<HTML>
<HEAD>
<!-- Generated by javadoc on Mon Jan 09 13:32:00 EST 2012-->
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>
${model.title}
</TITLE>
<SCRIPT type="text/javascript">
targetPage = "" + window.location.search;
if (targetPage != "" && targetPage != "undefined")
targetPage = targetPage.substring(1);
if (targetPage.indexOf(":") != -1)
targetPage = "undefined";
function loadFrames() {
if (targetPage != "" && targetPage != "undefined")
top.classFrame.location = top.targetPage;
}
</SCRIPT>
<NOSCRIPT>
</NOSCRIPT>
</HEAD>
<FRAMESET cols="20%,80%" title="" onLoad="top.loadFrames()">
<FRAMESET rows="30%,70%" title="" onLoad="top.loadFrames()">
<FRAME src="overview-frame.html" name="packageListFrame" title="All Packages">
<FRAME src="allclasses-frame.html" name="packageFrame" title="All classes and interfaces (except non-static nested types)">
</FRAMESET>
<FRAME src="overview-summary.html" name="classFrame" title="Package, class and interface descriptions" scrolling="yes">
<NOFRAMES>
<H2>
Frame Alert</H2>
<P>
This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
<BR>
Link to<A HREF="overview-summary.html">Non-frame version.</A>
</NOFRAMES>
</FRAMESET>
</HTML>
""")
}
}
@@ -0,0 +1,130 @@
package org.jetbrains.kotlin.doc.templates
import kotlin.*
import kotlin.util.*
import org.jetbrains.kotlin.doc.model.KClass
import org.jetbrains.kotlin.doc.model.KAnnotation
import org.jetbrains.kotlin.doc.model.KPackage
import org.jetbrains.kotlin.template.TextTemplate
import org.jetbrains.kotlin.doc.model.KFunction
import java.util.Collection
import org.jetbrains.kotlin.doc.model.KProperty
import org.jetbrains.kotlin.doc.model.KType
import java.util.List
abstract class KDocTemplate() : TextTemplate() {
open fun rootHref(pkg: KPackage): String {
return if (pkg.local)
relativePrefix()
else
pkg.model.config.resolveLink(pkg.name)
}
open fun href(p: KPackage): String
= "${rootHref(p)}${p.nameAsPath}/package-summary.html"
open fun href(c: KClass): String {
val postfix = if (c.pkg.local) "" else "?is-external=true"
return "${rootHref(c.pkg)}${c.nameAsPath}.html$postfix"
}
open fun href(f: KFunction): String {
return if (f.owner is KClass) {
"${href(f.owner)}#${f.link}"
} else {
"package-summary.html#${f.link}"
}
}
open fun href(f: KProperty): String {
return if (f.owner is KClass) {
"${href(f.owner)}#${f.link}"
} else {
"package-summary.html#${f.link}"
}
}
open fun extensionsHref(pkg: KPackage, c: KClass): String {
// is inside the pkg so no need to use it...
return "${c.nameAsPath}-extensions.html"
}
open fun extensionsHref(pkg: KPackage, c: KClass, f: KFunction): String {
return "${extensionsHref(pkg, c)}#${f.link}"
}
open fun sourceHref(klass: KClass): String {
val pkg = klass.pkg
return if (pkg.local) {
"${pkg.nameAsRelativePath}src-html/${klass.nameAsPath}.html#line.${klass.sourceLine}"
} else {
href(klass)
}
}
open fun sourceHref(f: KFunction): String {
val owner = f.owner
return if (owner is KClass) {
val pkg = owner.pkg
if (pkg.local) {
"${rootHref(pkg)}src-html/${owner.simpleName}.html#line.${f.sourceLine}"
} else {
href(f)
}
} else if (owner is KPackage) {
if (owner.local) {
// TODO how to find the function in a package???
"${rootHref(owner)}src-html/namespace.html#line.${f.sourceLine}"
} else {
href(owner)
}
} else href(f)
}
open fun link(c: KClass, fullName: Boolean = false): String {
val prefix = if (c.isAnnotation()) "@" else ""
val name = if (fullName) c.name else c.simpleName
return "<A HREF=\"${href(c)}\" title=\"${c.kind} in ${c.packageName}\">$prefix$name</A>"
}
open fun link(t: KType, fullName: Boolean = false): String {
val c = t.klass
val arguments = t.arguments
return if (c != null) {
val prefix = if (c.isAnnotation()) "@" else ""
val cname = c.name
if ((cname.startsWith("jet.Function") || cname.startsWith("jet.ExtensionFunction")) && arguments.notEmpty()) {
val rt = arguments.last()
// TODO use drop()
val rest = arguments.subList(0, arguments.size - 1).orEmpty()
"${typeArguments(rest, "(", ")", "()")}&nbsp;<A HREF=\"${href(c)}\" title=\"${c.kind} in ${c.packageName}\">-&gt;</a>&nbsp;${link(rt)}"
} else if (cname.startsWith("jet.Tuple")) {
if (arguments.isEmpty()) {
"Unit"
} else {
"<A HREF=\"${href(c)}\" title=\"${c.kind} in ${c.packageName}\">#</a>${typeArguments(arguments, "(", ")", "()")}"
}
} else {
val name = if (fullName) cname else c.simpleName
"<A HREF=\"${href(c)}\" title=\"${c.kind} in ${c.packageName}\">$prefix$name</A>${typeArguments(arguments)}"
}
} else {
"${t.name}${typeArguments(arguments)}"
}
}
open fun typeArguments(arguments: List<KType>, val prefix: String = "&lt;", val postfix: String = "&gt;", val empty: String = ""): String {
val text = arguments.map<KType, String>() { link(it) }.join(", ")
return if (text.length() == 0) empty else "$prefix$text$postfix"
}
open fun link(p: KPackage): String {
return "<A HREF=\"${href(p)}\" title=\"package ${p.name}}\">${p.name}</A>"
}
open fun link(a: KAnnotation): String {
val c = a.klass
return "<A HREF=\"${href(c)}\" title=\"annotation in ${c.packageName}\">@${c.simpleName}</A>"
}
protected open fun relativePrefix(): String = ""
}
@@ -0,0 +1,56 @@
package org.jetbrains.kotlin.doc.templates
import kotlin.*
import org.jetbrains.kotlin.template.*
import kotlin.io.*
import kotlin.util.*
import java.util.*
import org.jetbrains.kotlin.doc.model.KModel
class OverviewFrameTemplate(val model: KModel) : KDocTemplate() {
override fun render() {
println("""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!--NewPage-->
<HTML>
<HEAD>
<!-- Generated by kdoc (${model.version}) on ${Date()} -->
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>
Overview List (${model.title})
</TITLE>
<META NAME="date" CONTENT="2012-01-09">
<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
</HEAD>
<BODY BGCOLOR="white">
<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
<TR>
<TH ALIGN="left" NOWRAP><FONT size="+1" CLASS="FrameTitleFont">
<B></B></FONT></TH>
</TR>
</TABLE>
<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
<TR>
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="allclasses-frame.html" target="packageFrame">All Classes</A></FONT>
<P>
<FONT size="+1" CLASS="FrameHeadingFont">
Packages</FONT>
<BR>""")
for (p in model.packages) {
println("""<FONT CLASS="FrameItemFont"><A HREF="${p.nameAsPath}/package-frame.html" target="packageFrame">${p.name}</A></FONT>
<BR>""")
}
println("""</TD>
</TR>
</TABLE>
<P>
&nbsp;
</BODY>
</HTML>
""")
}
}
@@ -0,0 +1,172 @@
package org.jetbrains.kotlin.doc.templates
import kotlin.*
import org.jetbrains.kotlin.template.*
import kotlin.io.*
import kotlin.util.*
import java.util.*
import org.jetbrains.kotlin.doc.model.KModel
class OverviewSummaryTemplate(val model: KModel) : KDocTemplate() {
override fun render() {
println("""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<!--NewPage-->
<HTML>
<HEAD>
<!-- Generated by javadoc on Mon Jan 09 13:32:00 EST 2012-->
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>
Overview (${model.title})
</TITLE>
<META NAME="date" CONTENT="2012-01-09">
<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
<SCRIPT type="text/javascript">
function windowTitle()
{
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="Overview (${model.title})";
}
}
</SCRIPT>
<NOSCRIPT>
</NOSCRIPT>
</HEAD>
<BODY BGCOLOR="white" onload="windowTitle();">
<HR>
<!-- ========= START OF TOP NAVBAR ======= -->
<A NAME="navbar_top"><!-- --></A>
<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
<TR>
<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
<A NAME="navbar_top_firstrow"><!-- --></A>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
<TR ALIGN="center" VALIGN="top">
<TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Overview</B></FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
</TR>
</TABLE>
</TD>
<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
</EM>
</TD>
</TR>
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
&nbsp;PREV&nbsp;
&nbsp;NEXT</FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="index.html?overview-summary.html" target="_top"><B>FRAMES</B></A> &nbsp;
&nbsp;<A HREF="overview-summary.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
}
//-->
</SCRIPT>
<NOSCRIPT>
<A HREF="allclasses-noframe.html"><B>All Classes</B></A>
</NOSCRIPT>
</FONT></TD>
</TR>
</TABLE>
<A NAME="skip-navbar_top"></A>
<!-- ========= END OF TOP NAVBAR ========= -->
<HR>
<CENTER>
<H1>
${model.title}
</H1>
</CENTER>
<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
<B>Packages</B></FONT></TH>
</TR>""")
for (p in model.packages) {
println("""<TR BGCOLOR="white" CLASS="TableRowColor">
<TD WIDTH="20%"><B><A HREF="${p.nameAsPath}/package-summary.html">${p.name}</A></B></TD>
<TD>${p.description}</TD>
</TR>""")
}
println("""</TABLE>
<P>
&nbsp;<HR>
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<A NAME="navbar_bottom"><!-- --></A>
<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
<TR>
<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
<A NAME="navbar_bottom_firstrow"><!-- --></A>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
<TR ALIGN="center" VALIGN="top">
<TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Overview</B></FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
</TR>
</TABLE>
</TD>
<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
</EM>
</TD>
</TR>
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
&nbsp;PREV&nbsp;
&nbsp;NEXT</FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="index.html?overview-summary.html" target="_top"><B>FRAMES</B></A> &nbsp;
&nbsp;<A HREF="overview-summary.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
}
//-->
</SCRIPT>
<NOSCRIPT>
<A HREF="allclasses-noframe.html"><B>All Classes</B></A>
</NOSCRIPT>
</FONT></TD>
</TR>
</TABLE>
<A NAME="skip-navbar_bottom"></A>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
<HR>
Copyright &#169; 2010-2012. All Rights Reserved.
</BODY>
</HTML>""")
}
}
@@ -0,0 +1,194 @@
package org.jetbrains.kotlin.doc.templates
import kotlin.*
import org.jetbrains.kotlin.template.*
import kotlin.io.*
import kotlin.util.*
import java.util.*
import org.jetbrains.kotlin.doc.model.KModel
class OverviewTreeTemplate(val model: KModel) : KDocTemplate() {
override fun render() {
println("""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<!--NewPage-->
<HTML>
<HEAD>
<!-- Generated by javadoc on Mon Jan 09 13:32:00 EST 2012-->
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>
Class Hierarchy (${model.title})
</TITLE>
<META NAME="date" CONTENT="2012-01-09">
<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
<SCRIPT type="text/javascript">
function windowTitle()
{
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="Class Hierarchy (${model.title})";
}
}
</SCRIPT>
<NOSCRIPT>
</NOSCRIPT>
</HEAD>
<BODY BGCOLOR="white" onload="windowTitle();">
<HR>
<!-- ========= START OF TOP NAVBAR ======= -->
<A NAME="navbar_top"><!-- --></A>
<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
<TR>
<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
<A NAME="navbar_top_firstrow"><!-- --></A>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
<TR ALIGN="center" VALIGN="top">
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
<TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
</TR>
</TABLE>
</TD>
<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
</EM>
</TD>
</TR>
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
&nbsp;PREV&nbsp;
&nbsp;NEXT</FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="index.html?overview-tree.html" target="_top"><B>FRAMES</B></A> &nbsp;
&nbsp;<A HREF="overview-tree.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
}
//-->
</SCRIPT>
<NOSCRIPT>
<A HREF="allclasses-noframe.html"><B>All Classes</B></A>
</NOSCRIPT>
</FONT></TD>
</TR>
</TABLE>
<A NAME="skip-navbar_top"></A>
<!-- ========= END OF TOP NAVBAR ========= -->
<HR>
<CENTER>
<H2>
Hierarchy For All Packages</H2>
</CENTER>
<DL>
<DT><B>Package Hierarchies:</B><DD>""")
var first = true
for (p in model.packages) {
if (first) {
first = false
} else {
print(""",
<A HREF="${p.nameAsPath}/package-tree.html">${p.nameAsPath}</A>""")
}
}
println("""</DL>
<HR>
<H2>
Class Hierarchy
</H2>""")
// TODO walk the hierarchy...
/*
<UL>
<LI TYPE="circle">java.util.<A HREF="http://download.oracle.com/javase/1.5.0/docs/api/java/util/AbstractQueue.html?is-external=true" title="class or interface in java.util"><B>AbstractQueue</B></A>&lt;E&gt; (implements java.util.<A HREF="http://download.oracle.com/javase/1.5.0/docs/api/java/util/Queue.html?is-external=true" title="class or interface in java.util">Queue</A>&lt;E&gt;)
<UL>
*/
println("""<H2>
Interface Hierarchy
</H2>""")
// TODO
println("""<H2>
Annotation Type Hierarchy
</H2>""")
// TODO
println("""<H2>
Enum Hierarchy
</H2>
<HR>
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<A NAME="navbar_bottom"><!-- --></A>
<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
<TR>
<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
<A NAME="navbar_bottom_firstrow"><!-- --></A>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
<TR ALIGN="center" VALIGN="top">
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
<TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
</TR>
</TABLE>
</TD>
<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
</EM>
</TD>
</TR>
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
&nbsp;PREV&nbsp;
&nbsp;NEXT</FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="index.html?overview-tree.html" target="_top"><B>FRAMES</B></A> &nbsp;
&nbsp;<A HREF="overview-tree.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
}
//-->
</SCRIPT>
<NOSCRIPT>
<A HREF="allclasses-noframe.html"><B>All Classes</B></A>
</NOSCRIPT>
</FONT></TD>
</TR>
</TABLE>
<A NAME="skip-navbar_bottom"></A>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
<HR>
Copyright &#169; 2010-2012. All Rights Reserved.
</BODY>
</HTML>""")
}
}
@@ -0,0 +1,103 @@
package org.jetbrains.kotlin.doc.templates
import kotlin.*
import org.jetbrains.kotlin.template.*
import kotlin.io.*
import kotlin.util.*
import java.util.*
import org.jetbrains.kotlin.doc.model.KModel
import org.jetbrains.kotlin.doc.model.KPackage
import org.jetbrains.kotlin.doc.model.KClass
import org.jetbrains.kotlin.doc.model.KFunction
import org.jetbrains.kotlin.doc.model.extensionFunctions
class PackageFrameTemplate(val model: KModel, p: KPackage) : PackageTemplateSupport(p) {
override fun render() {
println("""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!--NewPage-->
<HTML>
<HEAD>
<!-- Generated by kdoc (${model.version}) on ${Date()} -->
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>
${pkg.name} (${model.title})
</TITLE>
<META NAME="date" CONTENT="2012-01-09">
<LINK REL ="stylesheet" TYPE="text/css" HREF="${pkg.nameAsRelativePath}stylesheet.css" TITLE="Style">
</HEAD>
<BODY BGCOLOR="white">
<FONT size="+1" CLASS="FrameTitleFont">
<A HREF="${pkg.nameAsRelativePath}${pkg.nameAsPath}/package-summary.html" target="classFrame">${pkg.name}</A></FONT>""")
printClasses("interface", "Interfaces")
printClasses("class", "Classes")
printClasses("enum", "Enums")
printClasses("annotation", "Annotations")
printClasses("exception", "Exceptions")
printFunctions()
printExtensionFunctions()
println("""</BODY>
</HTML>""")
}
protected fun printClasses(kind: String, description: String): Unit {
val classes = pkg.classes.filter{ it.kind == kind }
if (! classes.isEmpty()) {
println("""<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
<TR>
<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">""")
print(description)
println("""</FONT>&nbsp;
<FONT CLASS="FrameItemFont">
<BR>""")
for (c in classes) {
val formatted = if (kind == "interface") "<I>${c.simpleName}</I>" else c.simpleName
println("""<A HREF="${c.simpleName}.html" title="$kind in ${pkg.name}" target="classFrame">$formatted</A>
<BR>""")
}
println("""</TR>
</TABLE>""")
}
}
protected fun printFunctions(): Unit {
val functions = pkg.packageFunctions()
if (! functions.isEmpty()) {
println("""<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
<TR>
<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">Functions</FONT>&nbsp;
<FONT CLASS="FrameItemFont">
<BR>""")
for (c in functions) {
println("""<A HREF="${href(c)}" title="function in ${pkg.name}" target="classFrame"><I>${c.name}</I></A>
<BR>""")
}
println("""</TR>
</TABLE>""")
}
}
protected fun printExtensionFunctions(): Unit {
val map = extensionFunctions(pkg.functions)
if (! map.isEmpty()) {
println("""<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
<TR>
<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">Extensions</FONT>&nbsp;
<FONT CLASS="FrameItemFont">
<BR>""")
for (e in map.entrySet()) {
val c = e?.getKey()
if (c != null) {
println("""<A HREF="${extensionsHref(pkg, c)}" title="extensions functions on class ${c.name} from ${pkg.name}" target="classFrame"><I>${c.name}</I></A>
<BR>""")
}
}
println("""</TR>
</TABLE>""")
}
}
}
@@ -0,0 +1,16 @@
package org.jetbrains.kotlin.doc.templates
import kotlin.*
import org.jetbrains.kotlin.template.*
import kotlin.io.*
import kotlin.util.*
import java.util.*
import org.jetbrains.kotlin.doc.model.KModel
class PackageListTemplate(val model: KModel) : KDocTemplate() {
override fun render() {
for (p in model.packages) {
println(p.name)
}
}
}
@@ -0,0 +1,313 @@
package org.jetbrains.kotlin.doc.templates
import kotlin.*
import org.jetbrains.kotlin.template.*
import kotlin.io.*
import kotlin.util.*
import java.util.*
import org.jetbrains.kotlin.doc.model.KModel
import org.jetbrains.kotlin.doc.model.KPackage
import org.jetbrains.kotlin.doc.model.KClass
import org.jetbrains.kotlin.doc.model.extensionFunctions
import org.jetbrains.kotlin.doc.model.inheritedExtensionFunctions
class PackageSummaryTemplate(val model: KModel, pkg: KPackage) : PackageTemplateSupport(pkg) {
override fun render() {
println("""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!--NewPage-->
<HTML>
<HEAD>
<!-- Generated by kdoc (${model.version}) on ${Date()} -->
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>
${pkg.name} (${model.title})
</TITLE>
<META NAME="date" CONTENT="2012-01-09">
<META NAME="date" CONTENT="2012-01-09">
<LINK REL="stylesheet" TYPE="text/css" HREF="${pkg.nameAsRelativePath}stylesheet.css" TITLE="Style">
<SCRIPT type="text/javascript">
function windowTitle()
{
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="${pkg.name} (${model.title})";
}
}
</SCRIPT>
<NOSCRIPT>
</NOSCRIPT>
</HEAD>
<BODY BGCOLOR="white" onload="windowTitle();">
<HR>
<!-- ========= START OF TOP NAVBAR ======= -->
<A NAME="navbar_top"><!-- --></A>
<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
<TR>
<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
<A NAME="navbar_top_firstrow"><!-- --></A>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
<TR ALIGN="center" VALIGN="top">
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="${pkg.nameAsRelativePath}overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="${pkg.nameAsRelativePath}deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="${pkg.nameAsRelativePath}index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="${pkg.nameAsRelativePath}help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
</TR>
</TABLE>
</TD>
<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
</EM>
</TD>
</TR>
<TR>""")
printNextPrevPackages()
println("""<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="${pkg.nameAsRelativePath}index.html?${pkg.nameAsPath}/package-summary.html" target="_top"><B>FRAMES</B></A> &nbsp;
&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
document.writeln('<A HREF="${pkg.nameAsRelativePath}allclasses-noframe.html"><B>All Classes</B></A>');
}
//-->
</SCRIPT>
<NOSCRIPT>
<A HREF="${pkg.nameAsRelativePath}allclasses-noframe.html"><B>All Classes</B></A>
</NOSCRIPT>
</FONT></TD>
</TR>
</TABLE>
<A NAME="skip-navbar_top"></A>
<!-- ========= END OF TOP NAVBAR ========= -->
<HR>
<FONT SIZE="-1">""")
for (a in pkg.annotations) {
val url = a.url
if (url != null) {
println("""<A HREF="$url?is-external=true" title="class or interface in ${a.packageName}">@${a.simpleName}</A>""")
}
}
println("""</FONT><H2>
Package ${pkg.name}
</H2>
${pkg.description}
<P>
<B>See:</B>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="#package_description"><B>Description</B></A>
<P>
""")
printClasses("interface", "Interfaces")
printClasses("class", "Classes")
printClasses("enum", "Enums")
printClasses("annotation", "Annotations")
printClasses("exception", "Exceptions")
printFunctions()
printExtensionFunctions()
println("""<A NAME="package_description"><!-- --></A><H2>
Package ${pkg.name} Description
</H2>
<P>
${pkg.detailedDescription}
<h2>Contents</h2>
""")
val groupMap = pkg.groupClassMap()
for (e in groupMap.entrySet()) {
val group = e?.getKey() ?: "Other"
val list = e?.getValue()
if (list != null) {
println(""" <h3>$group</h3>
<ul>""")
for (c in list) {
println(""" <li><A HREF="${pkg.nameAsRelativePath}${c.nameAsPath}.html" title="class in ${pkg.name}"><CODE>${c.simpleName}</CODE></A>""")
}
println("""
</ul>""")
}
}
println("""<P>""")
printFunctionDetail(pkg.packageFunctions())
println("""
<P>
<DL>
</DL>
<HR>
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<A NAME="navbar_bottom"><!-- --></A>
<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
<TR>
<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
<A NAME="navbar_bottom_firstrow"><!-- --></A>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
<TR ALIGN="center" VALIGN="top">
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="${pkg.nameAsRelativePath}overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="${pkg.nameAsRelativePath}deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="${pkg.nameAsRelativePath}index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="${pkg.nameAsRelativePath}help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
</TR>
</TABLE>
</TD>
<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
</EM>
</TD>
</TR>
<TR>""")
printNextPrevPackages()
println("""<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
) <A HREF="${pkg.nameAsRelativePath}index.html?${pkg.nameAsPath}/package-summary.html" target="_top"><B>FRAMES</B></A> &nbsp;
&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
document.writeln('<A HREF="${pkg.nameAsRelativePath}allclasses-noframe.html"><B>All Classes</B></A>');
}
//-->
</SCRIPT>
<NOSCRIPT>
<A HREF="${pkg.nameAsRelativePath}allclasses-noframe.html"><B>All Classes</B></A>
</NOSCRIPT>
</FONT></TD>
</TR>
</TABLE>
<A NAME="skip-navbar_bottom"></A>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
<HR>
Copyright &#169; 2010-2012. All Rights Reserved.
</BODY>
</HTML>""")
}
protected fun printClasses(kind: String, description: String): Unit {
val classes = pkg.classes.filter{ it.kind == kind }
if (! classes.isEmpty()) {
print("""<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
<B>$description Summary</B></FONT></TH>
</TR>""")
for (c in classes) {
println("""<TR BGCOLOR="white" CLASS="TableRowColor">
<TD WIDTH="15%"><B><A HREF="${pkg.nameAsRelativePath}${c.nameAsPath}.html" title="$kind in ${pkg.name}">${c.simpleName}</A></B></TD>
<TD>${c.description}</TD>
</TR>""")
}
println("""</TABLE>
&nbsp;
<P>
""")
}
}
protected fun printFunctions(): Unit {
val functions = pkg.functions.filter{ it.extensionClass == null }
if (! functions.isEmpty()) {
print("""<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
<B>Functions Summary</B></FONT></TH>
</TR>""")
for (f in functions) {
println("""<TR BGCOLOR="white" CLASS="TableRowColor">
<TD WIDTH="15%"><B><A HREF="${href(f)}" title="function in ${pkg.name}">${f.name}</A></B></TD>
<TD>${f.description}</TD>
</TR>""")
}
println("""</TABLE>
&nbsp;
<P>
""")
}
}
protected fun printExtensionFunctions(): Unit {
val map = inheritedExtensionFunctions(pkg.functions)
if (! map.isEmpty()) {
print("""<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
<B>Extensions Summary</B></FONT></TH>
</TR>""")
for (e in map.entrySet()) {
val c = e?.getKey()
if (c != null) {
println("""<TR BGCOLOR="white" CLASS="TableRowColor">
<TD WIDTH="15%"><B><A HREF="${extensionsHref(pkg, c)}" title="extensions on ${pkg.name}">${c.name}</A></B></TD>
<TD>""")
val list = e?.getValue()
if (list != null) {
for (f in list) {
println("""<A HREF="${extensionsHref(pkg, c, f)}">${f.name}<A> """)
}
}
println("""</TD>
</TR>""")
}
}
println("""</TABLE>
&nbsp;
<P>
""")
}
}
protected fun printNextPrevPackages(): Unit {
println("""<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">""")
val prev = model.previous(pkg)
if (prev != null) {
println("""&nbsp;<A HREF="${prev.nameAsRelativePath}${prev.nameAsPath}/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;""")
}
val next = model.next(pkg)
if (next != null) {
println("""&nbsp;<A HREF="${next.nameAsRelativePath}${next.nameAsPath}/package-summary.html"><B>NEXT PACKAGE</B></A>""")
}
println("""</FONT></TD>""")
}
}
@@ -0,0 +1,236 @@
package org.jetbrains.kotlin.doc.templates
import kotlin.*
import kotlin.io.*
import kotlin.util.*
import java.util.*
import org.jetbrains.kotlin.template.*
import org.jetbrains.kotlin.doc.model.KModel
import org.jetbrains.kotlin.doc.model.KPackage
import org.jetbrains.kotlin.doc.model.KClass
import org.jetbrains.kotlin.doc.model.KFunction
import org.jetbrains.kotlin.doc.model.KAnnotation
import org.jetbrains.kotlin.doc.model.KProperty
import org.jetbrains.kotlin.doc.model.KTypeParameter
abstract class PackageTemplateSupport(open val pkg: KPackage) : KDocTemplate() {
protected override fun relativePrefix(): String = pkg.nameAsRelativePath
fun printFunctionSummary(functions: Collection<KFunction>): Unit {
if (functions.notEmpty()) {
println("""<!-- ========== FUNCTION SUMMARY =========== -->
<A NAME="method_summary"><!-- --></A>
<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
<B>Function Summary</B></FONT></TH>
</TR>""")
for (f in functions) {
printFunctionSummary(f)
}
println("""</TABLE>
&nbsp;
<P>
""")
}
}
fun printFunctionSummary(function: KFunction): Unit {
val deprecated = if (function.deprecated) "<B>Deprecated.</B>" else ""
print("""<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>""")
if (!function.typeParameters.isEmpty()) {
println("""<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
<TR ALIGN="right" VALIGN="">
<TD NOWRAP><FONT SIZE="-1">
<CODE>""")
printTypeParameters(function)
println("""<BR>""")
print(link(function.returnType))
println("""</CODE></FONT></TD>
</TR>
</TABLE>""")
} else {
print(link(function.returnType))
}
println("""</CODE></FONT></TD>""")
print("""<TD><CODE><B><A HREF="${href(function)}">${function.name}</A></B>""")
printParameters(function)
println("""</CODE>""")
println("")
if (true) {
val detail = function.detailedDescription
println("""${detail}""")
} else {
println("""<BR>""")
println("""&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${deprecated}&nbsp;${function.detailedDescription}</TD>""")
}
println("""</TD>""")
println("""</TR>""")
}
fun printFunctionDetail(functions: Collection<KFunction>): Unit {
if (functions.notEmpty()) {
println("""
<!-- ============ FUNCTION DETAIL ========== -->
<A NAME="method_detail"><!-- --></A>
<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
<B>Function Detail</B></FONT></TH>
</TR>
</TABLE>
""")
for (f in functions) {
printFunctionDetail(f)
}
}
}
fun printFunctionDetail(function: KFunction): Unit {
println("""<A NAME="${function.name}{${function.parameterTypeText}}"><!-- --></A><A NAME="${function.link}"><!-- --></A><H3>""")
println("""${function.name}</H3>""")
println("""<PRE>""")
println("""<FONT SIZE="-1">""")
printAnnotations(function.annotations)
print("""</FONT>${function.modifiers.join(" ")} """)
printTypeParameters(function)
print(link(function.returnType))
print(""" <A HREF="${sourceHref(function)}"><B>${function.name}</B></A>""")
printParameters(function)
val exlist = function.exceptions
var first = true
if (!exlist.isEmpty()) {
println(""" throws """);
for (ex in exlist) {
if (first) first = false else print(", ")
print(link(ex))
}
}
println("""</PRE>""")
println(function.detailedDescription)
/* TODO
println("""<DL>
<DD><B>Deprecated.</B>&nbsp;TODO text
<P>
<DD><b>Deprecated.</b>
<P>
<DD>
<DL>
<DT><B>Throws:</B>
<DD><CODE>${link(ex}</CODE><DT><B>Since:</B></DT>
<DD>${since}</DD>
</DL>
</DD>
</DL>
*/
println("""<HR>""")
}
fun printPropertySummary(properties: Collection<KProperty>): Unit {
if (properties.notEmpty()) {
println("""<!-- ========== PROPERTY SUMMARY =========== -->
<A NAME="method_summary"><!-- --></A>
<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
<B>Property Summary</B></FONT></TH>
</TR>""")
for (f in properties) {
printPropertySummary(f)
}
println("""</TABLE>
&nbsp;
<P>
""")
}
}
fun printPropertySummary(property: KProperty): Unit {
val deprecated = if (property.deprecated) "<B>Deprecated.</B>" else ""
print("""<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>""")
/*
if (!property.typeParameters.isEmpty()) {
println("""<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
<TR ALIGN="right" VALIGN="">
<TD NOWRAP><FONT SIZE="-1">
<CODE>""")
printTypeParameters(property)
println("""<BR>""")
print(link(property.returnType))
println("""</CODE></FONT></TD>
</TR>
</TABLE>""")
} else {
print(link(property.returnType))
}
*/
print(link(property.returnType))
println("""</CODE></FONT></TD>""")
print("""<TD><CODE><B><A HREF="${href(property)}">${property.name}</A></B>""")
//printParameters(property)
println("""</CODE>""")
println("""""")
println("""<BR>""")
println("""&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${deprecated}&nbsp;${property.detailedDescription}</TD>""")
println("""</TR>""")
}
fun printTypeParameters(method: KFunction): Unit {
val typeParameters = method.typeParameters
if (!typeParameters.isEmpty()) {
print("&lt")
var separator = ""
for (t in typeParameters) {
print(separator)
separator = ", "
print(t.name)
val elist = t.extends
if (!elist.isEmpty()) {
print(" extends ")
var esep = ""
for (e in elist) {
print(esep)
esep = " & "
print(link(e))
}
}
}
print("&gt;&nbsp;")
}
}
fun printParameters(method: KFunction): Unit {
print("(")
var first = true
for (p in method.parameters) {
if (first) first = false else print(", ")
print("${p.name}:&nbsp;")
print(link(p.aType))
}
print(")")
}
fun printAnnotations(annotations: Collection<KAnnotation>): Unit {
for (a in annotations) {
println(link(a))
}
}
}
@@ -0,0 +1,109 @@
package org.jetbrains.kotlin.template
import kotlin.io.*
import java.io.Writer
import java.io.StringWriter
import java.io.OutputStream
import java.io.OutputStreamWriter
import java.io.FileWriter
import java.io.File
/**
* Represents a generic API to templates which should be usable
* in JavaScript in a browser or on the server side stand alone or in a web app etc.
*
* To make things easier to implement in JS this namespace won't refer to any java.io or servlet
* stuff
*/
trait Template {
/** Renders the template to the output printer */
fun render(): Unit
}
/**
* Represents the output of a template which is a stream of objects
* usually strings which then write to some underlying output stream
* such as a java.io.Writer on the server side.
*
* We abstract away java.io.* APIs here to make the JS implementation simpler
*/
trait Printer {
fun print(value: Any): Unit
//fun print(text: String): Unit
}
class NullPrinter() : Printer {
override fun print(value: Any) {
throw UnsupportedOperationException("No Printer defined on the Template")
}
}
/**
* Base class for template implementations to hold any helpful behaviour
*/
abstract class TemplateSupport : Template {
}
val newline: String = System.getProperty("line.separator") ?: "\n"
/**
* Base class for templates generating text output
* by printing values to some underlying Printer which
* will typically output to a String, File, stream etc.
*/
abstract class TextTemplate() : TemplateSupport(), Printer {
public var printer: Printer = NullPrinter()
fun String.plus(): Unit {
printer.print(this)
}
override fun print(value: Any) = printer.print(value)
fun println(value: Any) {
print(value)
print(newline)
}
fun renderToText(): String {
val buffer = StringWriter()
renderTo(buffer)
return buffer.toString().sure()
}
fun renderTo(writer: Writer): Unit {
this.printer = WriterPrinter(writer)
this.render()
}
fun renderTo(os: OutputStream): Unit {
// TODO compiler error
//OutputStreamWriter(os).foreach{ renderTo(it) }
val s = OutputStreamWriter(os)
renderTo(s)
s.close()
}
fun renderTo(file: File): Unit {
// TODO compiler error
//FileWriter(file).foreach{ s -> renderTo(s) }
val s = FileWriter(file)
renderTo(s)
s.close()
}
}
/**
* A Printer implementation which uses a Writer
*/
class WriterPrinter(val writer: Writer) : Printer {
override fun print(value: Any) {
// TODO should be using a formatter to do the conversion
writer.write(value.toString())
}
}
@@ -0,0 +1,18 @@
<ivysettings>
<property name='ivy.checksums' value=''/>
<caches defaultCache="${user.home}/.ivy/cache"/>
<settings defaultResolver="jetbrains-repo"/>
<statuses>
<status name='integration' integration='true'/>
</statuses>
<resolvers>
<url name='jetbrains-repo' alwaysCheckExactRevision='yes' checkmodified='true'>
<ivy pattern='http://teamcity.jetbrains.com/guestAuth/repository/download/[module]/[revision]/teamcity-ivy.xml'/>
<artifact pattern='http://teamcity.jetbrains.com/guestAuth/repository/download/[module]/[revision]/[artifact](.[ext])'/>
</url>
</resolvers>
<modules>
<module organisation='org' name='bt343' matcher='regexp' resolver='jetbrains-repo'/>
<module organisation='org' name='bt344' matcher='regexp' resolver='jetbrains-repo'/>
</modules>
</ivysettings>
@@ -0,0 +1,54 @@
package test.pegdown
import kotlin.*
import kotlin.util.*
import kotlin.test.*
import junit.framework.TestCase
import org.pegdown.*
import org.pegdown.ast.*
import org.pegdown.LinkRenderer.Rendering
class PegdownTest() : TestCase() {
var markdownProcessor = PegDownProcessor(Extensions.ALL)
var linkRenderer = CustomLinkRenderer()
fun testPegDown() {
val markups = arrayList(
"hello **there **",
"a [[WikiLink]] blah",
"a [[WikiLink someText]] blah",
"a [[SomeClass.property]] blah",
"a [[SomeClass.method()]] blah",
"a [Link](somewhere) blah")
for (text in markups) {
val answer = markdownProcessor.markdownToHtml(text, linkRenderer).sure()
println("$text = $answer")
}
}
}
class CustomLinkRenderer() : LinkRenderer() {
override fun render(node : WikiLinkNode?) : Rendering? {
println("LinkRenderer.render(WikiLinkNode): $node")
return super.render(node)
}
override fun render(node : RefLinkNode?, url : String?, title : String?, text : String?) : Rendering? {
println("LinkRenderer.render(RefLinkNode): $node url: $url title: $title text: $text")
return super.render(node, url, title, text)
}
override fun render(node : AutoLinkNode?) : Rendering? {
println("LinkRenderer.render(AutoLinkNode): $node")
return super.render(node)
}
override fun render(node : ExpLinkNode?, text : String?) : Rendering? {
println("LinkRenderer.render(ExpLinkNode): $node text: $text")
return super.render(node, text)
}
}
@@ -0,0 +1,45 @@
package test.kotlin.template
import kotlin.*
import org.jetbrains.kotlin.template.*
import kotlin.io.*
import kotlin.util.*
import java.util.*
import junit.framework.TestCase
import junit.framework.Assert.*
class EmailTemplate(var name: String = "James", var time: Date = Date()) : TextTemplate() {
override fun render() {
print("Hello there $name and how are you? Today is $time. Kotlin rocks")
}
}
class MoreDryTemplate(var name: String = "James", var time: Date = Date()) : TextTemplate() {
override fun render() {
+"Hey there $name and how are you? Today is $time. Kotlin rocks"
}
}
class TemplateCoreTest() : TestCase() {
fun testDefaultValues() {
val text = EmailTemplate().renderToText()
assertTrue(
text.startsWith("Hello there James")
)
}
fun testDifferentValues() {
val text = EmailTemplate("Andrey").renderToText()
assertTrue(
text.startsWith("Hello there Andrey")
)
}
fun testMoreDryTemplate() {
val text = MoreDryTemplate("Alex").renderToText()
assertTrue(
text.startsWith("Hey there Alex")
)
}
}
+22
View File
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/kotlin" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library" exported="">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/junit-4.9.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module" module-name="stdlib" />
</component>
</module>
Binary file not shown.
+10
View File
@@ -0,0 +1,10 @@
import kotlin.modules.*
fun project() {
module("kunit") {
// TODO how to refer to the dir of the module?
classpath += "kunit/lib/junit-4.9.jar"
addSourceFiles("src/main/kotlin")
}
}
@@ -0,0 +1,10 @@
package org.jetbrains.kotlin.junit
import junit.framework.TestCase
/**
* Useful base class for test cases using the old JUnit 3 naming convention of functions
* starting with "test*" as being a test case
*/
abstract class TestSupport() : TestCase() {
}
@@ -0,0 +1,26 @@
package org.jetbrains.kotlin.test.junit
import kotlin.test.Asserter
import org.junit.Assert
class JUnitAsserter : Asserter {
override fun assertEquals(message : String, expected : Any?, actual : Any?) {
Assert.assertEquals(message, expected, actual)
}
override fun assertNotNull(message : String, actual : Any?) {
Assert.assertNotNull(message, actual)
}
override fun assertNull(message : String, actual : Any?) {
Assert.assertNull(message, actual)
}
override fun assertTrue(message : String, actual : Boolean) {
Assert.assertTrue(message, actual)
}
override fun fail(message : String) {
Assert.fail(message)
}
}
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="stdlib" exported="" />
<orderEntry type="module" module-name="testlib" exported="" />
<orderEntry type="module" module-name="kunit" exported="" />
<orderEntry type="module" module-name="kdoc" exported="" />
</component>
</module>
@@ -0,0 +1,29 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package stdlib.testall;
import junit.framework.TestSuite;
import test.collections.*;
import test.string.*;
/**
*/
public class CollectionTestAllTest {
public static TestSuite suite() {
return new TestSuite(StringTest.class, CollectionTest.class, MapTest.class);
}
}
@@ -0,0 +1,28 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package stdlib.testall;
import junit.framework.TestSuite;
import test.dom.*;
/**
*/
public class DomTestAllTest {
public static TestSuite suite() {
return new TestSuite(DomBuilderTest.class, DomTest.class);
}
}
@@ -0,0 +1,28 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package stdlib.testall;
import junit.framework.TestSuite;
import test.language.*;
/**
*/
public class LanguageTestAllTest {
public static TestSuite suite() {
return new TestSuite(JavaClassTest.class, NullableCollectionsTest.class);
}
}
@@ -0,0 +1,28 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package stdlib.testall;
import junit.framework.TestSuite;
import test.pegdown.*;
/**
*/
public class PegdownAllTest {
public static TestSuite suite() {
return new TestSuite(PegdownTest.class);
}
}
@@ -0,0 +1,28 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package stdlib.testall;
import junit.framework.TestSuite;
import test.properties.*;
/**
*/
public class PropertiesAllTest {
public static TestSuite suite() {
return new TestSuite(PropertiesTest.class);
}
}
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package stdlib.testall;
import junit.framework.TestSuite;
import test.collections.*;
import test.standard.*;
/**
*/
public class TestAll {
public static TestSuite suite() {
TestSuite suite = new TestSuite(GetOrElseTest.class, test.stdlib.issues.StdLibIssuesTest.class, StandardCollectionTest.class, CollectionTest.class, IoTest.class, ListTest.class, MapTest.class, SetTest.class, OldStdlibTest.class);
suite.addTest(testDslExample.namespace.getSuite());
return suite;
}
}
+59
View File
@@ -0,0 +1,59 @@
package kotlin.template
import kotlin.io.*
/**
* Represents a generic API to templates which should be usable
* in JavaScript in a browser or on the server side stand alone or in a web app etc.
*
* To make things easier to implement in JS this namespace won't refer to any java.io or servlet
* stuff
*/
trait Template {
var printer: Printer
/** Renders the template to the output printer */
fun render(): Unit
}
/**
* Represents the output of a template which is a stream of objects
* usually strings which then write to some underlying output stream
* such as a java.io.Writer on the server side.
*
* We abstract away java.io.* APIs here to make the JS implementation simpler
*/
trait Printer {
fun print(value: Any): Unit
//fun print(text: String): Unit
}
class NullPrinter() : Printer {
//override fun print(text: String) = none()
override fun print(value: Any) {
throw UnsupportedOperationException("No Printer defined on the Template")
}
}
/**
* Base class for template implementations to hold any helpful behaviour
*/
abstract class TemplateSupport : Template {
}
/**
* Base class for templates generating text output
* by printing values to some underlying Printer which
* will typically output to a String, File, stream etc.
*/
abstract class TextTemplate() : TemplateSupport(), Printer {
override var printer: Printer = NullPrinter()
fun String.plus(): Unit {
printer.print(this)
}
//override fun print(value: String) = printer.print(value)
override fun print(value: Any) = printer.print(value)
}
+181
View File
@@ -0,0 +1,181 @@
package kotlin.template.html
import kotlin.*
import kotlin.template.*
import kotlin.io.*
import kotlin.util.*
import java.io.*
import java.util.*
trait Factory<T> {
fun create() : T
}
abstract class Element {
abstract fun appendTo(builder: StringBuilder): Unit
}
class TextElement(val text : String) : Element() {
override fun appendTo(builder: StringBuilder) {
builder.append(text)
}
}
abstract class Tag(val name : String) : Element() {
val children = ArrayList<Element>()
val attributes = HashMap<String, String>()
protected fun initTag<T : Element>(init : T.()-> Unit) : T
where class object T : Factory<T> {
val tag = try {
T.create()
} catch (e: NullPointerException) {
val typeName = javaClass.getName()
throw UnsupportedOperationException("No class object create() method for $typeName")
}
tag.init()
children.add(tag)
return tag
}
override fun appendTo(builder: StringBuilder): Unit {
builder.append("<")
builder.append(name)
if (!attributes.isEmpty()) {
for (e in attributes.entrySet()) {
if (e != null) {
builder.append(" ${e.getKey()}=\"${e.getValue()}\"")
}
}
}
if (children.isEmpty()) {
builder.append("/>")
} else {
builder.append(">")
for (c in children) {
c.appendTo(builder)
}
builder.append("<")
builder.append(name)
builder.append(">")
}
}
fun toString(): String {
val builder = StringBuilder()
appendTo(builder)
return builder.toString().sure()
}
}
abstract class TagWithText(name : String) : Tag(name) {
fun String.plus() {
children.add(TextElement(this))
}
}
class HTML() : TagWithText("html") {
class object : Factory<HTML> {
override fun create() = HTML()
}
fun head(init : Head.()-> Unit) = initTag(init)
fun body(init : Body.()-> Unit) = initTag(init)
}
class Head() : TagWithText("head") {
class object : Factory<Head> {
override fun create() = Head()
}
fun title(init : Title.()-> Unit) = initTag(init)
}
class Title() : TagWithText("title") {
class object : Factory<Title> {
override fun create() = Title()
}
}
abstract class BodyTag(name : String) : TagWithText(name) {
}
class Body() : BodyTag("body") {
class object : Factory<Body> {
override fun create() = Body()
}
fun b(init : B.()-> Unit) = initTag(init)
fun p(init : P.()-> Unit) = initTag(init)
fun h1(init : H1.()-> Unit) = initTag(init)
fun a(href : String) {
a(href, {})
}
fun a(href : String, init : A.()-> Unit) {
val a = initTag(init)
a.href = href
}
}
class B() : BodyTag("b") {
class object : Factory<B> {
override fun create() = B()
}
}
class P() : BodyTag("p") {
class object : Factory<P> {
override fun create() = P()
}
}
class H1() : BodyTag("h1") {
class object : Factory<H1> {
override fun create() = H1()
}
}
class A() : BodyTag("a") {
class object : Factory<A> {
override fun create() = A()
}
var href : String
get() = attributes["href"] ?: ""
set(value) {
attributes["href"] = value
}
}
fun body(init: Body.()-> Unit): Body {
val elem = Body()
elem.init()
return elem
}
fun html(init : HTML.()-> Unit) : HTML {
val html = HTML()
html.init()
return html
}
/**
* Base class for templates which generate markup (XML or HTML for example)
* which have additional helper methods for escaping markup etc
*/
abstract class MarkupTemplate() : TemplateSupport() {
override fun render() {
val markup = markup()
print(markup)
}
/** Returns the markup to be rendered */
abstract fun markup(): Iterable<Element>
}
@@ -0,0 +1,34 @@
// Server side Java IO code to avoid coupling
// the core template code to java.* for easier JS porting
package kotlin.template.io
import kotlin.template.*
import java.io.Writer
import java.io.OutputStream
import java.io.OutputStreamWriter
import java.io.PrintStream
import java.io.StringWriter
/**
* A Printer implementation which uses a Writer
*/
class WriterPrinter(val writer: Writer) : Printer {
override fun print(value: Any) {
// TODO should be using a formatter to do the conversion
writer.write(value.toString())
}
}
fun Template.renderToText(): String {
val buffer = StringWriter()
renderTo(buffer)
return buffer.toString().sure()
}
fun Template.renderTo(writer: Writer): Unit {
this.printer = WriterPrinter(writer)
this.render()
}
fun Template.renderTo(os: OutputStream): Unit = renderTo(OutputStreamWriter(os))
+15
View File
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="stdlib" />
<orderEntry type="module" module-name="testlib" />
</component>
</module>
@@ -0,0 +1,46 @@
package kotlin.template
import kotlin.*
import kotlin.template.io.*
import kotlin.io.*
import kotlin.util.*
import kotlin.test.*
import java.util.*
class EmailTemplate(var name: String = "James", var time: Date = Date()) : TextTemplate() {
override fun render() {
print("Hello there $name and how are you? Today is $time. Kotlin rocks")
}
}
class MoreDryTemplate(var name: String = "James", var time: Date = Date()) : TextTemplate() {
override fun render() {
+"Hey there $name and how are you? Today is $time. Kotlin rocks"
}
}
class TemplateCoreTest() : TestSupport() {
fun testDefaultValues() {
val text = EmailTemplate().renderToText()
assert {
println(text)
text.startsWith("Hello there James")
}
}
fun testDifferentValues() {
val text = EmailTemplate("Andrey").renderToText()
assert {
println(text)
text.startsWith("Hello there Andrey")
}
}
fun testMoreDryTemplate() {
val text = MoreDryTemplate("Alex").renderToText()
assert {
println(text)
text.startsWith("Hey there Alex")
}
}
}
@@ -0,0 +1,118 @@
package kotlin.template.html
import kotlin.*
import kotlin.template.*
import kotlin.template.io.*
import kotlin.io.*
import kotlin.util.*
import kotlin.test.*
import java.util.*
val justBody = body {
+"Hello world"
}
fun result(args : List<String>) =
html {
head {
title {+"XML encoding with Kotlin"}
}
body {
h1 {+"XML encoding with Kotlin"}
p {+"this format can be used as an alternative markup to XML"}
// an element with attributes and text content
a(href = "http://jetbrains.com/kotlin") {+"Kotlin"}
// mixed content
p {
+"This is some"
b {+"mixed"}
+"text. For more see the"
a(href = "http://jetbrains.com/kotlin") {+"Kotlin"}
+"project"
}
p {+"some text"}
// content generated by
p {
for (arg in args)
+arg
}
}
}
/** Create a bad element which doesn't have a class object create() method */
class BadElem() : BodyTag("bad") {
}
/** Creates a bad body to test out badly defined elements */
class BadBody() : BodyTag("badBody") {
fun bad(init : BadElem.()-> Unit) = initTag(init)
}
fun badBody(init: BadBody.()-> Unit): BadBody {
val elem = BadBody()
elem.init()
return elem
}
class TemplateHtmlTest() : TestSupport() {
fun testJustBody() {
assertEquals("<body>Hello world<body>", justBody.toString())
}
fun testEmbeddedSimpleBody() {
val e = body {
+"body with text"
}
assertEquals("<body>body with text<body>", e.toString())
}
fun testEmbeddedBodyWithNestedBold() {
val e = body {
b{
+"this is bold"
}
}
assertEquals("<body><b>this is bold<b><body>", e.toString())
}
fun testEmbeddedBodyWithNestedLinks() {
val e = body {
a("http://jetbrains.com/kotlin") {
+"link text"
}
}
assertEquals("<body><a href=\"http://jetbrains.com/kotlin\">link text<a><body>", e.toString())
}
fun testHtmlFunction() {
val e = result(arrayList("a", "b", "c"))
assertEquals("""<html><head><title>XML encoding with Kotlin<title><head><body><h1>XML encoding with Kotlin<h1><p>this format can be used as an alternative markup to XML<p><a href="http://jetbrains.com/kotlin">Kotlin<a><b>mixed<b><a href="http://jetbrains.com/kotlin">Kotlin<a><p>This is sometext. For more see theproject<p><p>some text<p><p>abc<p><body><html>""", e.toString())
}
fun testEmbeddedFunction() {
val e = html {
head {
title {+"XML encoding with Kotlin"}
}
body {
a("http://jetbrains.com/kotlin")
}
}
assertEquals("<html><head><title>XML encoding with Kotlin<title><head><body><a href=\"http://jetbrains.com/kotlin\"/><body><html>", e.toString())
}
fun testBadlyDefinedElement() {
failsWith<UnsupportedOperationException>{
val e = badBody {
bad{
+"Bad Element Text"
}
}
println("bad body: $e")
}
}
}
@@ -0,0 +1,29 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package kotlin.template;
import kotlin.template.html.*;
import junit.framework.TestSuite;
/**
*/
public class TemplateTestAll {
public static TestSuite suite() {
return new TestSuite(TemplateCoreTest.class, TemplateHtmlTest.class);
}
}
Binary file not shown.
+11
View File
@@ -0,0 +1,11 @@
import kotlin.modules.*
fun project() {
module("testlib") {
// TODO how to refer to the dir of the module?
classpath += "dist/kotlinc/lib/kotlin-test.jar"
classpath += "kunit/lib/junit-4.9.jar"
addSourceFiles("test")
}
}
@@ -0,0 +1,35 @@
package test.apicheck
import kotlin.util.*
import java.util.*
trait Traversable<T> {
/** Returns true if any elements in the collection match the given predicate */
fun any(predicate: (T)-> Boolean) : Boolean
/** Returns true if all elements in the collection match the given predicate */
fun all(predicate: (T)-> Boolean) : Boolean
/** Returns the first item in the collection which matches the given predicate or null if none matched */
fun find(predicate: (T)-> Boolean) : T?
/** Returns a new collection containing all elements in this collection which match the given predicate */
// TODO using: Collection<T> for the return type - I wonder if this exact type could be
// deduced somewhat from the This.Type; e.g. returning Set on a Set, Array on Array etc
fun filter(predicate: (T)-> Boolean) : Collection<T>
/** Performs the given operation on each element inside the collection */
fun foreach(operation: (element: T)-> Unit)
/** Returns a new collection containing the results of applying the given function to each element in this collection */
fun <T, R> java.lang.Iterable<T>.map(transform : (T)-> R) : Collection<R>
}
/**
TODO try use delegation here to make sure we implement all the methods in the Traversable API
class ListImpl<T>(coll: ArrayList<out T>) : Traversable<T> by coll {
}
*/
+296
View File
@@ -0,0 +1,296 @@
package test.collections
import kotlin.test.*
// TODO can we avoid importing all this stuff by default I wonder?
// e.g. making println and the collection builder methods public by default?
import kotlin.*
import kotlin.io.*
import kotlin.util.*
import java.util.*
import junit.framework.TestCase
class CollectionTest() : TestCase() {
class IterableWrapper<T>(collection : java.lang.Iterable<T>) : java.lang.Iterable<T> {
private val collection = collection
override fun iterator(): java.util.Iterator<T> {
return collection.iterator().sure()
}
}
val data = arrayList("foo", "bar")
fun testAny() {
assertTrue {
data.any{it.startsWith("f")}
}
assertNot {
data.any{it.startsWith("x")}
}
}
fun testAll() {
assertTrue {
data.all{it.length == 3}
}
assertNot {
data.all{s -> s.startsWith("b")}
}
}
fun testCount() {
assertEquals(1, data.count{it.startsWith("b")})
assertEquals(2, data.count{it.size == 3})
}
fun testFilter() {
val foo = data.filter{it.startsWith("f")}
assertTrue {
foo.all{it.startsWith("f")}
}
assertEquals(1, foo.size)
assertEquals(arrayList("foo"), foo)
}
fun testFilterNot() {
val foo = data.filterNot{it.startsWith("b")}
assertTrue {
foo.all{it.startsWith("f")}
}
assertEquals(1, foo.size)
assertEquals(arrayList("foo"), foo)
}
fun testFilterIntoLinkedList() {
// TODO would be nice to avoid the <String>
val foo = data.filterTo(linkedList<String>()){it.startsWith("f")}
assertTrue {
foo.all{it.startsWith("f")}
}
assertEquals(1, foo.size)
assertEquals(linkedList("foo"), foo)
assertTrue {
foo is LinkedList<String>
}
}
fun testFilterIntoSortedSet() {
// TODO would be nice to avoid the <String>
val foo = data.filterTo(hashSet<String>()){it.startsWith("f")}
assertTrue {
foo.all{it.startsWith("f")}
}
assertEquals(1, foo.size)
assertEquals(hashSet("foo"), foo)
assertTrue {
foo is HashSet<String>
}
}
fun testFind() {
val x = data.find{it.startsWith("x")}
assertNull(x)
fails {
x.sure()
}
val f = data.find{it.startsWith("f")}
f.sure()
assertEquals("foo", f)
}
fun testFlatMap() {
val characters = arrayList('f', 'o', 'o', 'b', 'a', 'r')
// TODO figure out how to get a line like this to compile :)
/*
val characters = data.flatMap<String,Character>{
it.toCharArray().toList() as Collection<Character>
}
*/
todo {
println("Got list of characters ${characters}")
val text = characters.join("")
assertEquals("foobar", text)
}
}
fun testForeach() {
var count = 0
data.foreach{ count += it.length }
assertEquals(6, count)
}
fun testFold() {
expect(10) {
val numbers = arrayList(1, 2, 3, 4)
// TODO would be nice to be able to write this as this
//numbers.fold(0){it + it2}
numbers.fold(0){(it, it2) -> it + it2}
}
expect(0) {
val numbers = arrayList<Int>()
numbers.fold(0){(it, it2) -> it + it2}
}
expect("1234") {
val numbers = arrayList(1, 2, 3, 4)
// TODO would be nice to be able to write this as this
// numbers.map{it.toString()}.fold(""){it + it2}
numbers.map<Int, String>{it.toString()}.fold(""){(it, it2) -> it + it2}
}
}
fun testFoldRight() {
expect("4321") {
val numbers = arrayList(1, 2, 3, 4)
// TODO would be nice to be able to write this as this
// numbers.map{it.toString()}.foldRight(""){it + it2}
numbers.map<Int, String>{it.toString()}.foldRight(""){(it, it2) -> it + it2}
}
}
fun testGroupBy() {
val words = arrayList("a", "ab", "abc", "def", "abcd")
/*
TODO inference engine should not need this type info?
*/
val byLength = words.groupBy<String, Int>{it.length}
assertEquals(4, byLength.size())
println("Grouped by length is: $byLength")
/*
TODO compiler bug...
val l3 = byLength.getOrElse(3, {ArrayList<String>()})
assertEquals(2, l3.size)
*/
}
fun testJoin() {
val text = data.join("-", "<", ">")
assertEquals("<foo-bar>", text)
}
fun testMap() {
/**
TODO compiler bug
we should be able to remove the explicit type on the function
http://youtrack.jetbrains.net/issue/KT-1145
*/
val lengths = data.map<String, Int>{s -> s.length}
assertTrue {
lengths.all{it == 3}
}
assertEquals(2, lengths.size)
assertEquals(arrayList(3, 3), lengths)
}
fun testReverse() {
val rev = data.reverse()
assertEquals(arrayList("bar", "foo"), rev)
}
fun testSort() {
val coll: List<String> = arrayList("foo", "bar", "abc")
// TODO fixme
// Some sort of in/out variance thing - or an issue with Java interop?
//coll.sort()
todo {
assertEquals(3, coll.size)
assertEquals(arrayList("abc", "bar", "foo"), coll)
}
}
fun testToArray() {
val arr = data.toArray()
println("Got array ${arr}")
todo {
assertTrue {
arr is Array<String>
}
}
}
fun testSimpleCount() {
assertEquals(2, data.count())
assertEquals(3, hashSet(12, 14, 15).count())
assertEquals(0, ArrayList<Double>().count())
}
fun testLast() {
assertEquals("bar", data.last())
assertEquals(25, arrayList(15, 19, 20, 25).last())
// assertEquals(19, TreeSet(arrayList(90, 47, 19)).first())
assertEquals('a', linkedList('a').last())
}
fun testLastException() {
fails { arrayList<Int>().last() }
fails { linkedList<String>().last() }
fails { hashSet<Char>().last() }
}
fun testSubscript() {
val list = arrayList("foo", "bar")
assertEquals("foo", list[0])
assertEquals("bar", list[1])
// lists throw an exception if out of range
fails {
assertEquals(null, list[2])
}
// lets try update the list
list[0] = "new"
list[1] = "thing"
// lists don't allow you to set past the end of the list
fails {
list[2] = "works"
}
list.add("works")
assertEquals(arrayList("new", "thing", "works"), list)
}
fun testIndices() {
val indices = data.indices
assertEquals(0, indices.start)
assertEquals(1, indices.end)
assertEquals(2, indices.size)
assertFalse(indices.isReversed)
}
fun testContains() {
assertTrue(data.contains("foo"))
assertTrue(data.contains("bar"))
assertFalse(data.contains("some"))
// TODO: Problems with generation
// assertTrue(IterableWrapper(data).contains("bar"))
// assertFalse(IterableWrapper(data).contains("some"))
assertFalse(hashSet<Int>().contains(12))
assertTrue(linkedList(15, 19, 20).contains(15))
// assertTrue(IterableWrapper(hashSet(45, 14, 13)).contains(14))
// assertFalse(IterableWrapper(linkedList<Int>()).contains(15))
}
}
@@ -0,0 +1,18 @@
import java.util.Vector
import junit.framework.TestCase
import kotlin.test.assertEquals
class EnumerationIteratorTest() : TestCase() {
fun testIteration () {
val v = Vector<Int>()
for(i in 1..5)
v.add(i)
var sum = 0
for(k in v.elements())
sum += k
assertEquals(15, sum)
}
}
@@ -0,0 +1,83 @@
package org.jetbrains.kotlin.tools
import kotlin.*
import kotlin.io.*
import kotlin.util.*
import java.io.*
import java.util.*
fun generateFile(outFile: File, header: String, inputFile: File, f: (String)-> String) {
println("Parsing $inputFile and writing $outFile")
outFile.getParentFile()?.mkdirs()
val writer = PrintWriter(FileWriter(outFile))
try {
writer.println("// NOTE this file is auto-generated from $inputFile")
writer.println(header)
val reader = FileReader(inputFile).buffered()
try {
// TODO ideally we'd use a filterNot() here :)
val iter = reader.lineIterator()
while (iter.hasNext) {
val line = iter.next()
if (line.startsWith("package")) continue
val xform = f(line)
writer.println(xform)
}
} finally {
reader.close()
reader.close()
}
} finally {
writer.close()
}
}
/**
* Generates methods in the standard library which are mostly identical
* but just using a different input kind.
*
* Kinda like mimicking source macros here, but this avoids the inefficiency of type conversions
* at runtime.
*/
fun main(args: Array<String>) {
var stdlib = File("stdlib")
if (!stdlib.exists()) {
stdlib = File("../stdlib")
if (!stdlib.exists()) {
println("Cannot find stdlib!")
return
}
}
val srcDir = File(stdlib, "ktSrc")
val outDir = File(srcDir, "generated")
// JavaIterables - Generic iterable stuff
generateFile(File(outDir, "ArraysFromJavaIterables.kt"), "package kotlin\n\nimport kotlin.util.*", File(srcDir, "JavaIterables.kt")) {
it.replaceAll("java.lang.Iterable<T", "Array<T").replaceAll("java.lang.Iterable<T", "Array<T")
}
generateFile(File(outDir, "StandardFromJavaIterables.kt"), "package kotlin\n\nimport kotlin.util.*", File(srcDir, "JavaIterables.kt")) {
it.replaceAll("java.lang.Iterable<T", "Iterable<T")
}
// JavaCollections - methods returning a collection of the same input size (if its a collection)
generateFile(File(outDir, "ArraysFromJavaCollections.kt"), "package kotlin", File(srcDir, "JavaCollections.kt")) {
it.replaceAll("java.util.Collection<T", "Array<T")
}
generateFile(File(outDir, "JavaUtilIterablesFromJavaCollections.kt"), "package kotlin.util", File(srcDir, "JavaCollections.kt")) {
it.replaceAll("java.util.Collection<T", "java.lang.Iterable<T").replaceAll("(this.size)", "")
}
generateFile(File(outDir, "StandardFromJavaCollections.kt"), "package kotlin", File(srcDir, "JavaCollections.kt")) {
it.replaceAll("java.util.Collection<T", "Iterable<T").replaceAll("(this.size)", "")
}
}
+42
View File
@@ -0,0 +1,42 @@
package test.standard
import kotlin.*
import kotlin.test.*
import junit.framework.TestCase
class GetOrElseTest() : TestCase() {
val v1: String? = "hello"
val v2: String? = null
var counter = 0
fun testDefaultValue() {
assertEquals("hello", v1?: "bar")
expect("hello") {
v1?: "bar"
}
}
fun testDefaultValueOnNull() {
assertEquals("bar", v2?: "bar")
expect("bar") {
v2?: "bar"
}
}
fun calculateBar(): String {
counter++
return "bar"
}
fun testLazyDefaultValue() {
counter = 0
assertEquals("hello", v1?: calculateBar())
assertEquals(counter, 0, "counter should not be incremented yet")
assertEquals("bar", v2?: calculateBar())
assertEquals(counter, 1, "counter should be incremented in the default function")
}
}
+74
View File
@@ -0,0 +1,74 @@
package test.collections
import kotlin.test.*
import kotlin.io.*
import kotlin.util.*
import java.io.*
import java.util.*
import junit.framework.TestCase
class IoTest() : TestCase() {
fun testLineIteratorWithManualClose() {
val reader = sample().buffered()
try {
val list = reader.lineIterator().toArrayList()
assertEquals(arrayList("Hello", "World"), list)
} finally {
reader.close()
}
}
fun sample() : Reader {
return StringReader("Hello\nWorld");
}
fun testLineIterator() {
// TODO we should maybe zap the useLines approach as it encourages
// use of iterators which don't close the underlying stream
val list1 = sample().useLines{it.toArrayList()}
val list2 = sample().useLines<ArrayList<String>>{it.toArrayList()}
assertEquals(arrayList("Hello", "World"), list1)
assertEquals(arrayList("Hello", "World"), list2)
}
fun testForEach() {
val list = ArrayList<String>()
val reader = sample().buffered()
reader.use{
while (true) {
val line = it.readLine()
if (line != null)
list.add(line)
else
break
}
}
assertEquals(arrayList("Hello", "World"), list)
}
fun testForEachLine() {
val list = ArrayList<String>()
val reader = sample()
/* TODO would be nicer maybe to write this as
reader.lines.foreach { ... }
as we could one day maybe one day write that as
for (line in reader.lines)
if the for(elem in thing) {...} statement could act as syntax sugar for
thing.foreach{ elem -> ... }
if thing is not an Iterable/array/Iterator but has a suitable foreach method
*/
reader.foreachLine{
list.add(it)
}
assertEquals(arrayList("Hello", "World"), list)
}
}
+14
View File
@@ -0,0 +1,14 @@
package testjc
import kotlin.test.*
import junit.framework.TestCase
class C()
class JavaClassTest() : TestCase() {
fun testMe () {
assertEquals("java.util.ArrayList", java.util.ArrayList<Any>().javaClass.getName())
// assertEquals("java.util.ArrayList", javaClass<java.util.ArrayList<Any>>().getName())
// assertEquals("testjc.C", javaClass<C>().getName())
}
}
+42
View File
@@ -0,0 +1,42 @@
package test.collections
import kotlin.test.*
// TODO can we avoid importing all this stuff by default I wonder?
// e.g. making println and the collection builder methods public by default?
import kotlin.*
import kotlin.io.*
import kotlin.util.*
import java.util.*
import junit.framework.TestCase
class ListTest() : TestCase() {
val data = arrayList("foo", "bar")
fun testHeadAndTail() {
val h = data.head
assertEquals("foo", h)
val t = data.tail
assertEquals("bar", t)
}
fun testFirstAndLast() {
val h = data.first
assertEquals("foo", h)
val t = data.last
assertEquals("bar", t)
}
fun testWithIndices() {
val withIndices = data.withIndices()
var index = 0
for (withIndex in withIndices) {
assertEquals(withIndex._1, index)
assertEquals(withIndex._2, data[index])
index++
}
assertEquals(data.size(), index)
}
}
+53
View File
@@ -0,0 +1,53 @@
package test.collections
import kotlin.test.*
// TODO can we avoid importing all this stuff by default I wonder?
// e.g. making println and the collection builder methods public by default?
import kotlin.*
import kotlin.io.*
import kotlin.util.*
import java.util.*
import junit.framework.TestCase
class MapTest() : TestCase() {
val data: java.util.Map<String, Int> = java.util.HashMap<String, Int>()
fun testGetOrElse() {
val a = data.getOrElse("foo"){2}
assertEquals(2, a)
val b = data.getOrElse("foo"){3}
assertEquals(3, b)
assertEquals(0, data.size())
}
fun testGetOrPut() {
val a = data.getOrPut("foo"){2}
assertEquals(2, a)
val b = data.getOrPut("foo"){3}
assertEquals(2, b)
assertEquals(1, data.size())
}
fun testSizeAndEmpty() {
assertTrue{ data.empty }
// TODO using size breaks a test case
assertEquals(data.size(), 0)
}
fun testSetViaIndexOperators() {
val map = java.util.HashMap<String, String>()
assertTrue{ map.empty }
// TODO using size breaks a test case
assertEquals(map.size(), 0)
map["name"] = "James"
assertTrue{ !map.empty }
assertEquals(map.size(), 1)
assertEquals("James", map["name"])
}
}
+40
View File
@@ -0,0 +1,40 @@
package test.collections;
import kotlin.math.*
import java.math.BigInteger
import java.math.BigDecimal
import kotlin.test.*
import junit.framework.TestCase
class MathTest : TestCase() {
fun testBigInteger() {
val a = BigInteger("2")
val b = BigInteger("3")
assertEquals(BigInteger("5"), a + b)
assertEquals(BigInteger("-1"), a - b)
assertEquals(BigInteger("6"), a * b)
assertEquals(BigInteger("0"), a / b)
assertEquals(BigInteger("-2"), -a)
assertEquals(BigInteger("1"), -a % b)
assertEquals(BigInteger("-2"), -a remainder b)
}
fun testBigDecimal() {
val a = BigDecimal("2")
val b = BigDecimal("3")
assertEquals(BigDecimal("5"), a + b)
assertEquals(BigDecimal("-1"), a - b)
assertEquals(BigDecimal("6"), a * b)
assertEquals(BigDecimal("2"), BigDecimal("4") / a)
assertEquals(BigDecimal("-2"), -a)
assertEquals(BigDecimal("-2"), -a % b)
}
}
fun main(args: Array<String>) {
MathTest().testBigInteger()
MathTest().testBigDecimal()
}
+35
View File
@@ -0,0 +1,35 @@
package test.collections
import kotlin.*
import kotlin.io.*
import kotlin.util.*
import kotlin.test.*
import java.util.*
import java.io.*
import junit.framework.TestCase
class OldStdlibTest() : TestCase() {
fun testCollectionEmpty() {
assertNot {
Arrays.asList(0, 1, 2)?.empty ?: false
}
}
fun testCollectionSize() {
assertTrue {
Arrays.asList(0, 1, 2)?.size == 3
}
}
fun testInputStreamIterator() {
val x = ByteArray (10)
for(index in 0..9) {
x [index] = index.toByte()
}
for(b in x.inputStream) {
System.out?.println(b)
}
}
}
+71
View File
@@ -0,0 +1,71 @@
package test.collections
import kotlin.*
import kotlin.io.*
import kotlin.util.*
import kotlin.test.*
import java.util.*
import junit.framework.TestCase
class SetTest() : TestCase() {
val data = hashSet("foo", "bar")
fun testAny() {
assertTrue {
data.any{it.startsWith("f")}
}
assertNot {
data.any{it.startsWith("x")}
}
}
fun testAll() {
assertTrue {
data.all{it.length == 3}
}
assertNot {
data.all{(s: String) -> s.startsWith("b")}
}
}
fun testFilter() {
val foo = data.filter{it.startsWith("f")}.toSet()
assertTrue {
foo.all{it.startsWith("f")}
}
assertEquals(1, foo.size)
assertEquals(hashSet("foo"), foo)
assertTrue("Filter on a Set should return a Set") {
foo is Set<String>
}
}
fun testFind() {
val x = data.find{it.startsWith("x")}
assertNull(x)
fails {
x.sure()
}
val f = data.find{it.startsWith("f")}
f.sure()
assertEquals("foo", f)
}
fun testMap() {
/**
TODO compiler bug
we should be able to remove the explicit type on the function
http://youtrack.jetbrains.net/issue/KT-849
*/
val lengths = data.map<String, Int>{(s: String) -> s.length}
assertTrue {
lengths.all{it == 3}
}
assertEquals(2, lengths.size)
assertEquals(arrayList(3, 3), lengths)
}
}
@@ -0,0 +1,25 @@
package test.collections
import kotlin.*
import kotlin.test.*
import junit.framework.TestCase
class StandardCollectionTest() : TestCase() {
fun testDisabled() {
}
/*
fun testAny() {
// TODO requires KT-924 to be implemented
val data: Iterable<String> = kotlin.util.arrayList("foo", "bar")
assertTrue {
data.any{it.startsWith("f")}
}
assertNot {
data.any{it.startsWith("x")}
}
}
*/
}
@@ -0,0 +1,25 @@
package test.stdlib.issues
import java.util.List
import kotlin.util.*
import kotlin.test.*
import junit.framework.TestCase
private fun listDifference<T>(first : List<T>, second : List<T>) : List<T> {
return first.filter{ !second.contains(it) }.toList()
}
class StdLibIssuesTest() : TestCase() {
fun test_KT_1131() {
val data = arrayList("blah", "foo", "bar")
val filterValues = arrayList("bar", "something", "blah")
expect(arrayList("foo")) {
val answer = listDifference(data, filterValues)
println("Found answer ${answer}")
answer
}
}
}
+36
View File
@@ -0,0 +1,36 @@
package test.string
import kotlin.io.*
import kotlin.test.*
import junit.framework.*
class StringTest() : TestCase() {
fun testStringIterator() {
var sum = 0
for(c in "239")
sum += (c.toInt() - '0'.toInt())
assertTrue(sum == 14)
}
fun testStringBuilderIterator() {
var sum = 0
val sb = StringBuilder()
for(c in "239")
sb.append(c)
println(sb)
for(c in sb)
sum += (c.toInt() - '0'.toInt())
assertTrue(sum == 14)
}
fun testOrEmpty() {
val s: String? = "hey"
val ns: String? = null
assertEquals("hey", s.orEmpty())
assertEquals("", ns.orEmpty())
}
}
+16
View File
@@ -0,0 +1,16 @@
package test.string
import kotlin.*
import kotlin.test.*
import kotlin.util.*
import junit.framework.*
class StringUtilTest() : TestCase() {
fun testToRegex() {
val re = """foo""".toRegex()
val list = re.split("hellofoobar").filterNulls()
assertEquals(arrayList("hello", "bar"), list)
}
}
+157
View File
@@ -0,0 +1,157 @@
package kotlinhack.test
import junit.framework.*
import kotlin.io.*
import kotlin.util.*
import java.util.*
import org.junit.*
import org.junit.runner.*
import org.junit.runner.notification.*
protected class TestBuilt<T>(name: String, val builder: TestBuilder<T>, val test: TestBuilt<T>.() -> Unit) : TestCase(name) {
private var myState: T? = null
var state : T
get() = myState.sure()
set(newState: T) { myState = newState }
override fun countTestCases(): Int = 1
override fun setUp() = this.(builder.setUp)()
override fun tearDown() = this.(builder.tearDown)()
override fun runTest() = this.(test)()
}
open class TestBuilder<T>(name: String) {
val mySuite : TestSuite = TestSuite(name)
public var setUp : TestBuilt<T>.() -> Unit = {}
public var tearDown : TestBuilt<T>.() -> Unit = {}
fun String.minus(test: TestBuilt<T>.() -> Unit) {
mySuite.addTest(TestBuilt<T>(this, this@TestBuilder, test))
}
}
private val currentTestBuilder = ThreadLocal<TestSuite> ()
private fun <T> testSuite(builder: TestBuilder<T>, description: TestBuilder<T>.() -> Unit) : TestSuite? {
val currentTestSuite = currentTestBuilder.get()
currentTestBuilder.set(builder.mySuite)
try {
builder.(description)()
return if(currentTestSuite != null) {
currentTestSuite.addTest(builder.mySuite)
null
}
else {
builder.mySuite
}
}
finally {
currentTestBuilder.set(currentTestSuite)
}
}
fun <T> testSuite(name: String, description: TestBuilder<T>.() -> Unit) : TestSuite? =
testSuite(TestBuilder<T>(name), description)
fun assert(message: String, block: ()-> Boolean) {
val actual = block()
Assert.assertTrue(message, actual)
}
fun assert(block: ()-> Boolean) = assert(block.toString(), block)
fun assertNot(message: String, block: ()-> Boolean) {
assert(message){ !block() }
}
fun assertNot(block: ()-> Boolean) = assertNot(block.toString(), block)
fun assert(actual: Boolean, message: String) {
println("Answer: ${actual} for ${message}")
}
fun assertTrue(actual: Boolean, message: String = "") {
return assertEquals(true, actual, message)
}
fun assertFalse(actual: Boolean, message: String = "") {
return assertEquals(false, actual, message)
}
fun assertEquals(expected: Any?, actual: Any?, message: String = "") {
Assert.assertEquals(message, expected, actual)
}
fun assertNotNull(actual: Any?, message: String = "") {
Assert.assertNotNull(message, actual)
}
fun assertNull(actual: Any?, message: String = "") {
Assert.assertNull(message, actual)
}
fun fail(message: String = "") {
Assert.fail(message)
}
fun <T> expect(expected: T, block: ()-> T) {
expect(expected, block.toString(), block)
}
fun <T> expect(expected: T, message: String, block: ()-> T) {
val actual = block()
assertEquals(expected, actual, message)
}
fun fails(block: ()-> Any) {
try {
block()
Assert.fail("Expected an exception to be thrown")
} catch (e: Exception) {
println("Caught excepted exception: $e")
// OK
}
}
fun <T: Exception> failsWith(block: ()-> Any) {
try {
block()
Assert.fail("Expected an exception to be thrown")
} catch (e: T) {
println("Caught excepted exception: $e")
// OK
}
}
fun todo(block: ()-> Any) {
println("TODO at " + (Exception() as java.lang.Throwable).getStackTrace()?.get(1) + " for " + block)
}
/*
TODO we could maybe create our own test runner for JUnit
to avoid a runtime dependency on JUnit for running tests?
class KotlinTestRunner() : Runner() {
override fun getDescription(): Description? {
return null
}
override fun run(notifier: RunNotifier?) {
println("About to run a test case on ${this}")
}
}
*/
// TODO no annotations yet?
//@RunWith(KotlinTestRunner)
abstract class TestSupport() : TestCase() {
}
+60
View File
@@ -0,0 +1,60 @@
package testDslExample
import kotlin.io.*
import kotlinhack.test.*
import junit.framework.*
import junit.textui.TestRunner
public val suite : TestSuite? = testSuite<Int>("test group") {
var staticState = 10
setUp = {
staticState += 10
state = staticState
println("test '${getName()}' started")
}
tearDown = {
println("test '${getName()}' ended")
}
"test 1" - {
Assert.assertEquals(state, 20)
println("test '${getName()}': state: $state")
}
"test 2" - {
assert(state == 31, "message")
println("test '${getName()}': state: $state")
}
"test 3" - {
Assert.assertEquals(state, 40)
println("test '${getName()}': state: $state")
}
testSuite<Any>("nested test suite") {
setUp = {
staticState += 10
state = staticState
println("nested test '${getName()}' started")
}
tearDown = {
println("nested test '${getName()}' ended")
}
"nested test 1" - {
println("test '${getName()}'")
}
"nested test 2" - {
println("test '${getName()}'")
}
"nested test 3" - {
println("test '${getName()}'")
}
}
}
@@ -0,0 +1,16 @@
package test.concurrent
import kotlin.concurrent.*
import junit.framework.*
class FListTest() : TestCase() {
fun testEmpty() {
val empty = FunctionalQueue<Int> ()
Assert.assertTrue(empty.empty)
}
fun testNonEmpty() {
// val empty = FunctionalList.emptyList<Int> ()
// assertTrue(!(empty + 10).empty)
}
}
@@ -0,0 +1,50 @@
package serial
import java.io.ObjectOutputStream
import java.io.ByteArrayOutputStream
import java.io.ByteArrayInputStream
import java.io.ObjectInputStream
import java.io.Serializable
import java.util.HashMap
import junit.framework.TestCase
import junit.framework.Assert
class Serial(val a : String) : java.lang.Object(), Serializable {
override fun toString() = a
}
class SerialTest() : TestCase() {
fun testMe() {
val tuple = #("lala", "bbb", Serial("serial"))
val op = { -> tuple.toString() }
val baos = ByteArrayOutputStream()
val oos = ObjectOutputStream(baos)
oos.writeObject(op)
oos.close()
val bais = ByteArrayInputStream(baos.toByteArray())
val ins = ObjectInputStream(bais)
val ops = ins.readObject() as (() -> String)
Assert.assertEquals(op (), ops())
}
fun testComplex() {
val y = 12
val op = { (x:Int) -> (x + y).toString() }
val op2 : Int.(Int) -> String = { op(this + it) }
val baos = ByteArrayOutputStream()
val oos = ObjectOutputStream(baos)
oos.writeObject(op2)
oos.close()
val bais = ByteArrayInputStream(baos.toByteArray())
val ins = ObjectInputStream(bais)
val ops = ins.readObject() as (Int.(Int) -> String)
Assert.assertEquals("27", 5.ops(10))
}
}
@@ -0,0 +1,123 @@
package test.dom
import kotlin.*
import kotlin.dom.*
import kotlin.util.*
import kotlin.test.*
import org.w3c.dom.*
import junit.framework.TestCase
class DomBuilderTest() : TestCase() {
fun testBuildDocument() {
var doc = createDocument()
assertTrue {
doc["grandchild"].isEmpty()
}
doc.addElement("foo") {
id = "id1"
style = "bold"
classes = "bar"
addElement("child") {
id = "id2"
classes = "another"
addElement("grandChild") {
id = "id3"
classes = " bar tiny"
addText("Hello World!")
// TODO support neater syntax sugar for adding text?
// += "Hello World!"
}
addElement("grandChild2") {
id = "id3"
classes = "tiny thing bar "
addText("Hello World!")
// TODO support neater syntax sugar for adding text?
// += "Hello World!"
}
}
}
println("builder document: ${doc.toXmlString()}")
// test css selections on document
assertEquals(0, doc[".doesNotExist"].size())
assertEquals(1, doc[".another"].size())
assertEquals(3, doc[".bar"].size())
assertEquals(2, doc[".tiny"].size())
// element tag selections
assertEquals(0, doc["doesNotExist"].size())
assertEquals(1, doc["foo"].size())
assertEquals(1, doc["child"].size())
assertEquals(1, doc["grandChild"].size())
// id selections
assertEquals(1, doc["#id1"].size())
assertEquals(1, doc["#id2"].size())
assertEquals(1, doc["#id3"].size())
val root = doc.rootElement
if (root != null) {
assertTrue {
root.hasClass("bar")
}
// test css selections on element
assertEquals(0, root[".doesNotExist"].size())
assertEquals(1, root[".another"].size())
assertEquals(2, root[".bar"].size())
assertEquals(2, root[".tiny"].size())
// element tag selections
assertEquals(0, root["doesNotExist"].size())
assertEquals(0, root["foo"].size())
assertEquals(1, root["child"].size())
assertEquals(1, root["grandChild"].size())
// id selections
assertEquals(1, root["#id1"].size())
assertEquals(1, root["#id2"].size())
assertEquals(1, root["#id3"].size())
} else {
fail("No root!")
}
val grandChild = doc["grandChild"].first
if (grandChild != null) {
println("got element ${grandChild.toXmlString()} with text '${grandChild.text}`")
assertEquals("Hello World!", grandChild.text)
assertEquals(" bar tiny", grandChild.attribute("class"))
// test the classSet
val classSet = grandChild.classSet
assertTrue(classSet.contains("bar"))
assertTrue(classSet.contains("tiny"))
assertTrue(classSet.size == 2 )
assertFalse(classSet.contains("doesNotExist"))
// lets add a new class and some existing classes
grandChild.addClass("bar")
grandChild.addClass("newThingy")
assertEquals("bar tiny newThingy", grandChild.classes)
// remove
grandChild.removeClass("bar")
assertEquals("tiny newThingy", grandChild.classes)
grandChild.removeClass("tiny")
assertEquals("newThingy", grandChild.classes)
} else {
fail("Not an Element $grandChild")
}
val children = doc.rootElement.children()
val xml = children.toXmlString()
println("root element has children: ${xml}")
assertEquals(1, children.size())
}
}
+39
View File
@@ -0,0 +1,39 @@
package test.dom
import kotlin.*
import kotlin.dom.*
import kotlin.test.*
import org.w3c.dom.*
import junit.framework.TestCase
class DomTest() : TestCase() {
fun testCreateDocument() {
var doc = createDocument()
assertNotNull(doc, "Should have created a document")
val e = doc.createElement("foo").sure()
assertCssClass(e, "")
// now lets update the cssClass property
e.classes = "foo"
assertCssClass(e, "foo")
// now using the attribute directly
e.setAttribute("class", "bar")
assertCssClass(e, "bar")
doc += e
println("document ${doc.toXmlString()}")
}
fun assertCssClass(e: Element, value: String?): Unit {
val cl = e.classes
val cl2 = e.getAttribute("class")
println("element ${e.toXmlString()} has cssClass `${cl}` class attr `${cl2}`")
assertEquals(value, cl, "value of element.cssClass")
assertEquals(value, cl2, "value of element.getAttribute(\"class\")")
}
}
@@ -0,0 +1,23 @@
package test.language
import junit.framework.TestCase
import kotlin.test.*
import org.jetbrains.kotlin.support.*
fun localUseWorks(): Unit {
val c = javaClass<Runnable>()
println("class is $c")
}
class JavaClassTest : TestCase() {
fun testJavaClass() {
localUseWorks()
// TODO this function fails!
// see KT-1515
// loadAsserter()
}
}
@@ -0,0 +1,20 @@
package test.language
import junit.framework.TestCase
import java.util.Collection
import kotlin.test.*
class NullableCollectionsTest : TestCase() {
fun testIterateOverNullCollectionsThrowsNPE() {
val c: Collection<String>? = null
// TODO currently this will throw a NPE
// should it either be a compile error or handle nulls gracefully?
failsWith<NullPointerException> {
for (e in c) {
println("Hey got $e")
}
}
}
}
@@ -0,0 +1,5 @@
package language.main
fun main(args: Array<String>) {
println("Hello world!")
}
@@ -0,0 +1,51 @@
package test.properties
import kotlin.*
import kotlin.properties.*
import kotlin.util.*
import kotlin.test.*
import java.util.*
import junit.framework.TestCase
class Customer() : ChangeSupport() {
// TODO the setter code should be generated
// via KT-1299
var name: String? = null
set(value) {
changeProperty("name", $name, value)
$name = value
}
var city: String? = null
set(value) {
changeProperty("city", $city, value)
$city = value
}
fun toString() = "Customer($name, $city)"
}
class MyChangeListener() : ChangeListener {
val events = ArrayList<ChangeEvent>()
override fun onPropertyChange(event: ChangeEvent): Unit {
println("Property changed: $event")
events.add(event)
}
}
class PropertiesTest() : TestCase() {
fun testModel() {
val c = Customer()
c.name = "James"
c.city = "Mells"
val listener = MyChangeListener()
c.addChangeListener(listener)
c.name = "Andrey"
println("Customer $c and raised change events ${listener.events}")
assertEquals(1, listener.events.size(), "Should have received a change event ${listener.events}")
}
}
@@ -0,0 +1,23 @@
package test.regressions.kt1149
import java.util.ArrayList
import kotlin.util.*
import junit.framework.*
public trait SomeTrait {
fun foo()
}
class Kt1149Test() : TestCase() {
fun testMe() {
val list = ArrayList<SomeTrait>()
var res = ArrayList<String>()
list.add(object : SomeTrait {
override fun foo() {
res.add("anonymous.foo()")
}
})
list.foreach{ it.foo() }
Assert.assertEquals("anonymous.foo()", res[0])
}
}
@@ -0,0 +1,19 @@
package test.regressions.kt1172
import kotlin.concurrent.*
import junit.framework.*
import java.util.*
public fun scheduleRefresh(vararg files : Object) {
// TODO
// java.util.ArrayList<Object>(files.map{ it })
}
fun main(args : Array<String?>?) {
}
class Kt1172Test() : TestCase() {
fun testMe() {
main(null)
}
}
@@ -0,0 +1,120 @@
package testeval
import java.util.*
import junit.framework.TestCase.*
import junit.framework.Assert.* // TODO unnecessary import
trait Expression
class Num(val value : Int) : Expression
class Sum(val left : Expression, val right : Expression) : Expression
class Mult(val left : Expression, val right : Expression) : Expression
fun eval(e : Expression) : Int {
return when (e) {
is Num -> e.value
is Sum -> eval(e.left) + eval (e.right)
is Mult -> eval(e.left) * eval (e.right)
else -> throw AssertionError("Unknown expression")
}
}
trait ParseResult<out T> {
val success : Boolean
val value : T
}
class Success<T>(override val value : T) : ParseResult<T> {
public override val success : Boolean = true
}
class Failure(val message : String) : ParseResult<Nothing> {
override val success = false
override val value : Nothing = throw UnsupportedOperationException("Don't call value on a Failure")
}
open class Token(val text : String) {
fun toString() = text
}
object LPAR : Token("(")
object RPAR : Token(")")
object PLUS : Token("+")
object TIMES : Token("*")
object EOF : Token("EOF")
class Number(text : String) : Token(text)
class Error(text : String) : Token("[Error: $text]")
fun tokenize(text : String) : Deque<Token> {
val result = LinkedList<Token>()
for (c in text) {
result add when (c) {
'(' -> LPAR
')' -> RPAR
'+' -> PLUS
'*' -> TIMES
in '0'..'9' -> Number(c.toString())
else -> Error(c.toString())
}
}
result.add(EOF)
return result
}
fun parseSum(tokens : Deque<Token>) : ParseResult<Expression> {
val left = parseMult(tokens)
if (!left.success) return left
if (tokens.peek() == PLUS) {
tokens.pop()
val right = parseSum(tokens)
if (!right.success) return right
return Success(Sum(left.value, right.value))
}
return left
}
fun parseMult(tokens : Deque<Token>) : ParseResult<Expression> {
val left = parseAtomic(tokens)
if (!left.success) return left
if (tokens.peek() == PLUS) {
tokens.pop()
val right = parseMult(tokens)
if (!right.success) return right
return Success(Mult(left.value, right.value))
}
return left
}
fun parseAtomic(tokens : Deque<Token>) : ParseResult<Expression> {
val token = tokens.poll()
return when (token) {
LPAR -> {
val result = parseSum(tokens)
val rpar = tokens.poll()
if (rpar == RPAR)
result
else
Failure("Expecting ')'")
}
is Number -> Success(Num(Integer.parseInt((token as Token).text).sure()))
else -> Failure("Unexpected EOF")
}
}
fun parse(text : String) : ParseResult<Expression> = parseSum(tokenize(text))
class EvalTest : junit.framework.TestCase() {
fun testEval() {
assertEquals(1, eval(Num(1)))
assertEquals(2, eval(Sum(Num(1), Num(1))))
assertEquals(3, eval(Mult(Num(3), Num(1))))
assertEquals(6, eval(Mult(Num(3), Sum(Num(1), Num(1)))))
}
fun testParse() {
assertEquals(1, eval(parse("1").value))
}
}
+24
View File
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="stdlib" exported="" />
<orderEntry type="module" module-name="kunit" exported="" />
<orderEntry type="module-library" exported="">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../kunit/lib/junit-4.9.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
</component>
</module>