refactored the maven project structure so that things are in a simpler tree structure to avoid folks getting lost

This commit is contained in:
James Strachan
2012-04-05 16:20:06 +01:00
parent 937b5ac16d
commit a40f9ee9b1
74 changed files with 99 additions and 45 deletions
@@ -0,0 +1,8 @@
## KDoc Maven Plugin
This Maven plugin allows you to create API Documentation for your Kotlin code (rather like javadoc but more kool :)
as it allows embedded [markdown](http://daringfireball.net/projects/markdown/syntax#block) wiki markup.
For examples check out the [Kotlin API docs](http://jetbrains.github.com/kotlin/versions/snapshot/apidocs/index.html).
For more details see [how to write code with comments](http://confluence.jetbrains.net/display/Kotlin/Coding+Conventions)
+56
View File
@@ -0,0 +1,56 @@
<?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>
<properties>
<maven-plugin-anno.version>1.4.1</maven-plugin-anno.version>
<maven.version>3.0.4</maven.version>
</properties>
<parent>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>tools</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>kdoc-maven-plugin</artifactId>
<packaging>maven-plugin</packaging>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kdoc</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.pegdown</groupId>
<artifactId>pegdown</artifactId>
<version>${pegdown.version}</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<testSourceDirectory>src/test/java</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>2.9</version>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,164 @@
/*
* 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 org.jetbrains.kotlin.maven.doc;
import org.apache.maven.plugin.MojoExecutionException;
import org.jetbrains.jet.cli.CompilerArguments;
import org.jetbrains.jet.cli.KotlinCompiler;
import org.jetbrains.kotlin.doc.KDocArguments;
import org.jetbrains.kotlin.doc.KDocCompiler;
import org.jetbrains.kotlin.doc.KDocConfig;
import org.jetbrains.kotlin.maven.KotlinCompileMojoBase;
import java.util.List;
/**
* Generates API docs documentation for kotlin sources
*
* @goal apidoc
* @phase site
* @requiresDependencyResolution test
* @noinspection UnusedDeclaration
*/
public class KDocMojo extends KotlinCompileMojoBase {
/**
* Project classpath.
*
* @parameter default-value="${project.compileClasspathElements}"
* @required
* @readonly
*/
public List<String> classpath;
/**
* Project test classpath.
*
* @parameter default-value="${project.testClasspathElements}"
* @required
* @readonly
*/
protected List<String> testClasspath;
/**
* The directory for compiled apidoc classes.
*
* @parameter default-value="${project.build.outputDirectory}"
* @required
* @readonly
*/
public String output;
// TODO not sure why default is stopping us passing this value in via a config
// default-value="${project.compileSourceRoots}"
/**
* The sources used to compile
*
* @parameter expression="${sources}"
* @required
*/
private List<String> sources;
/**
* The directory for the generated KDocs
*
* @parameter expression="${docOutputDir}" default-value="${basedir}/target/site/apidocs"
* @required
*/
private String docOutputDir;
/**
* The module to use for documentation
*
* @parameter expression="${docModule}"
*/
private String docModule;
/**
* Package prefixes which are excluded from the kdoc
*
* @parameter expression="${ignorePackages}"
*/
protected List<String> ignorePackages;
/**
* Whether protected classes, functions and properties should be included
*
* @parameter expression="${includeProtected}" default-value="true"
*/
private boolean includeProtected;
/**
* The title of the documentation
*
* @parameter expression="${title}" default-value="KDoc for ${project.artifactId}"
*/
private String title;
/**
* The version of the documentation
*
* @parameter expression="${version}" default-value="KDoc for ${project.version"
*/
private String version;
/**
* Whether warnings should be generated if no comments could be found for classes, functions and properties being documented
*
* @parameter expression="${warnNoComments}" default-value="true"
*/
private boolean warnNoComments;
@Override
protected KotlinCompiler createCompiler() {
return new KDocCompiler();
}
@Override
protected CompilerArguments createCompilerArguments() {
return new KDocArguments();
}
@Override
protected void configureCompilerArguments(CompilerArguments arguments) throws MojoExecutionException {
configureBaseCompilerArguments(getLog(), arguments, docModule, sources, classpath, output);
if (arguments instanceof KDocArguments) {
KDocArguments kdoc = (KDocArguments) arguments;
KDocConfig docConfig = kdoc.getDocConfig();
docConfig.setDocOutputDir(docOutputDir);
if (ignorePackages != null) {
docConfig.getIgnorePackages().addAll(ignorePackages);
}
docConfig.setIncludeProtected(includeProtected);
docConfig.setTitle(title);
docConfig.setVersion(version);
docConfig.setWarnNoComments(warnNoComments);
getLog().info("API docs output to: " + docConfig.getDocOutputDir());
getLog().info("classpath: " + classpath);
getLog().info("title: " + title);
getLog().info("sources: " + sources);
getLog().info("API docs ignore packages: " + ignorePackages);
} else {
getLog().warn("No KDocArguments available!");
}
}
}
@@ -0,0 +1,26 @@
/*
* 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 org.jetbrains.kotlin.maven;
import org.junit.Test;
public class MojoTest {
@Test
public void dummy() {
}
}
+1
View File
@@ -0,0 +1 @@
target
+12
View File
@@ -0,0 +1,12 @@
import kotlin.modules.*
fun project() {
module("apidocs") {
classpath += "../lib/junit-4.9.jar"
addSourceFiles("../stdlib/src")
addSourceFiles("../kunit/src/main/kotlin")
addSourceFiles("../kotlin-jdbc/src/main/kotlin")
//addSourceFiles("../kotlin-swing/src/main/kotlin")
}
}
+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")
}
}
+67
View File
@@ -0,0 +1,67 @@
<?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>
<parent>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>tools</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>kdoc</artifactId>
<dependencies>
<dependency>
<groupId>org.pegdown</groupId>
<artifactId>pegdown</artifactId>
<version>${pegdown.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>stdlib</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${project.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</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,44 @@
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() : KModelCompilerPlugin() {
protected 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()
val outputDir = File(config.docOutputDir)
generator.generate(model, outputDir)
}
}
@@ -0,0 +1,61 @@
package org.jetbrains.kotlin.doc
import java.io.File
import java.io.PrintStream
import org.jetbrains.jet.cli.CompilerArguments
import org.jetbrains.jet.cli.KotlinCompiler
import org.jetbrains.jet.compiler.CompileEnvironment
import org.jetbrains.kotlin.doc.highlighter.HtmlCompilerPlugin
/**
* Main for running the KDocCompiler
*/
fun main(args: Array<String?>): Unit {
KotlinCompiler.doMain(KDocCompiler(), args);
}
/**
* A version of the [[KotlinCompiler]] which includes the [[KDoc]] compiler plugin and allows
* command line validation or for the configuration to be provided via [[KDocArguments]]
*/
class KDocCompiler() : KotlinCompiler() {
protected override fun configureEnvironment(environment : CompileEnvironment?, arguments : CompilerArguments?, errStream : PrintStream?) {
super.configureEnvironment(environment, arguments, errStream)
val coreEnvironment = environment?.getEnvironment()
if (coreEnvironment != null) {
val kdoc = KDoc()
if (arguments is KDocArguments) {
kdoc.config = arguments.apply()
}
val plugins = coreEnvironment.getCompilerPlugins().orEmpty()
/*
val sourcePlugin = HtmlCompilerPlugin()
plugins.add(sourcePlugin)
*/
plugins.add(kdoc);
}
}
protected override fun createArguments() : CompilerArguments? {
return KDocArguments()
}
protected override fun usage(target : PrintStream?) {
target?.println("Usage: KDocCompiler -docOutput <docOutputDir> [-output <outputDir>|-jar <jarFileName>] [-stdlib <path to runtime.jar>] [-src <filename or dirname>|-module <module file>] [-includeRuntime]");
}
}
class KDocArguments() : CompilerArguments() {
public var docConfig: KDocConfig = KDocConfig()
/**
* Applies the command line arguments to the given KDoc configuration
*/
fun apply(): KDocConfig {
// TODO...
return docConfig
}
}
@@ -0,0 +1,109 @@
package org.jetbrains.kotlin.doc
import kotlin.*
import kotlin.util.*
import java.util.*
import org.jetbrains.kotlin.doc.model.KPackage
/**
* The configuration used with KDoc
*/
class KDocConfig() {
/**
* Returns the directory to use to output the API docs
*/
public var docOutputDir: String = "target/site/apidocs"
/**
* Returns the name of the documentation set
*/
public var title: String = "Documentation"
/**
* Returns the version name of the documentation set
*/
public var version: String = "SNAPSHOT"
/**
* 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 a Set of the package name prefixes to ignore from the KDoc report
*/
public val ignorePackages: Set<String> = HashSet<String>()
/**
* 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.filterNotNull()) {
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 ""
}
/**
* Returns true if the package should be included in the report
*/
fun includePackage(pkg: KPackage): Boolean {
return !ignorePackages.any{ pkg.name.startsWith(it) }
}
}
private class LongestFirstStringComparator() : Comparator<String> {
public override fun compare(s1: String?, s2: String?): Int {
return compareBy(s1, s2, { (s: String) -> s.length() }, { (s: String) -> s })
}
public override fun equals(obj : Any?) : Boolean {
return obj is LongestFirstStringComparator
}
}
@@ -0,0 +1,26 @@
package org.jetbrains.kotlin.doc.highlighter
import org.jetbrains.jet.compiler.CompilerPlugin
import org.jetbrains.jet.compiler.CompilerPluginContext
/**
*/
class HtmlCompilerPlugin: CompilerPlugin {
public override fun processFiles(context: CompilerPluginContext?) {
if (context != null) {
val bindingContext = context.getContext()
val files = context.getFiles()
if (bindingContext != null && files != null) {
if (files != null && bindingContext != null) {
for (file in files) {
if (file != null) {
val visitor = HtmlKotlinVisitor()
file.accept(visitor)
}
}
}
}
}
}
}
@@ -0,0 +1,71 @@
package org.jetbrains.kotlin.doc.highlighter
import com.intellij.psi.PsiFile
import org.jetbrains.jet.lang.psi.*
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.PsiComment
class HtmlKotlinVisitor: JetTreeVisitor<StringBuilder>() {
public override fun visitFile(file: PsiFile?) {
if (file is JetFile) {
val data = StringBuilder()
visitJetFile(file, data)
}
}
public override fun visitJetFile(file: JetFile?, data: StringBuilder?): Void? {
if (file != null) {
println("============ Jet File ${file.getName()}")
acceptChildren(file, data)
}
return null
}
public override fun visitClassObject(classObject: JetClassObject?, data: StringBuilder?): Void? {
println("============ class $classObject data $data")
return super.visitClassObject(classObject, data)
}
public override fun visitClass(klass: JetClass?, data: StringBuilder?): Void? {
println("============ class $klass")
if (klass != null) {
acceptChildren(klass, data)
return null
} else {
return super.visitClass(klass, data)
}
}
public override fun visitClassBody(classBody: JetClassBody?, data: StringBuilder?): Void? {
println("============ class body $classBody data $data")
return super.visitClassBody(classBody, data)
}
public override fun visitFunctionType(fnType: JetFunctionType?, data: StringBuilder?): Void? {
println("======================= function Type $fnType")
return super.visitFunctionType(fnType, data)
}
protected fun accept(child: PsiElement?, data: StringBuilder?): Unit {
if (child is JetElement) {
child.accept(this, data)
} else {
if (child is PsiComment || child is PsiWhiteSpace) {
// ignore
} else {
println("------- Child $child of type ${child.javaClass}")
}
child?.accept(this)
}
}
protected fun acceptChildren(element: PsiElement, data: StringBuilder?): Unit {
for (child in element.getChildren()) {
accept(child, data)
}
}
}
@@ -0,0 +1,138 @@
package org.jetbrains.kotlin.doc.highlighter
import com.intellij.psi.*
import com.intellij.psi.tree.IElementType
import com.intellij.psi.tree.TokenSet
import java.util.HashMap
import java.util.Map
import kotlin.template.HtmlFormatter
import org.jetbrains.jet.lexer.*
fun main(args: Array<String>) {
val tool = SyntaxHighligher()
val answer = tool.highlight(""" val x = arrayList(1, 2, 3)
println("hello")""")
println(answer)
}
/**
* Syntax highlights Kotlin code
*/
class SyntaxHighligher() {
var formatter: HtmlFormatter = HtmlFormatter()
val styleMap = createStyleMap()
/** Highlights the given kotlin code as HTML */
fun highlight(val code: String): String {
try {
val builder = StringBuilder()
builder.append(
"<div class=\"code panel\" style=\"border-width: 1px\">" +
"<div class=\"codeContent panelContent\">" +
"<div class=\"container\">"
)
// lets add the leading whitespace first
var idx = 0
while (Character.isWhitespace(code[idx])) {
idx++
}
if (idx > 0) {
val space = code.substring(0, idx)
builder.append("""<code class="jet whitespace">$space</code>""")
}
val lexer = JetLexer()
lexer.start(code)
val end = lexer.getTokenEnd()
while (true) {
lexer.advance()
val token = lexer.getTokenType()
if (token == null) break
val tokenText = lexer.getTokenSequence().toString().replaceAll("\n", "\r\n")
var style: String? = null
if (token is JetKeywordToken) {
style = "keyword"
} else if (token == JetTokens.IDENTIFIER) {
val types = JetTokens.SOFT_KEYWORDS?.getTypes()
if (types != null) {
for (softKeyword in types) {
if (softKeyword is JetKeywordToken) {
if (softKeyword.getValue().equals(tokenText)) {
style = "softkeyword"
break
}
}
}
}
style = if (style == null) "plain" else style
} else if (styleMap.containsKey(token)) {
style = styleMap.get(token)
if (style == null) {
println("Warning: No style for token $token")
}
} else {
style = "plain"
}
builder.append("""<code class="jet $style">""")
formatter.format(builder, tokenText)
builder.append("</code>")
}
builder.append("</div>")
builder.append("</div>")
builder.append("</div>")
return builder.toString() ?: ""
} catch (e: Exception) {
println("Warning: failed to parse code $e")
val builder = StringBuilder()
builder.append("""<div class="jet herror">Jet highlighter error ["${e.javaClass.getSimpleName()}"]: """)
formatter.format(builder, e.getMessage())
builder.append("<br/>")
builder.append("Original text:")
builder.append("<pre>")
formatter.format(builder, code)
builder.append("</pre>")
builder.append("</div>")
return builder.toString() ?: ""
}
}
protected fun createStyleMap(): Map<IElementType?, String> {
val styleMap = HashMap<IElementType?, String>()
fun putAll(tokenSet: TokenSet?, style: String): Unit {
if (tokenSet != null) {
for (token in tokenSet.getTypes().orEmpty()) {
styleMap.put(token, style)
}
}
}
styleMap.put(JetTokens.BLOCK_COMMENT, "jet-comment")
styleMap.put(JetTokens.DOC_COMMENT, "jet-comment")
styleMap.put(JetTokens.EOL_COMMENT, "jet-comment")
styleMap.put(JetTokens.WHITE_SPACE, "whitespace")
styleMap.put(JetTokens.INTEGER_LITERAL, "number")
styleMap.put(JetTokens.FLOAT_LITERAL, "number")
styleMap.put(JetTokens.OPEN_QUOTE, "string")
styleMap.put(JetTokens.REGULAR_STRING_PART, "string")
styleMap.put(JetTokens.ESCAPE_SEQUENCE, "escape")
styleMap.put(JetTokens.LONG_TEMPLATE_ENTRY_START, "escape")
styleMap.put(JetTokens.LONG_TEMPLATE_ENTRY_END, "escape")
styleMap.put(JetTokens.SHORT_TEMPLATE_ENTRY_START, "escape")
styleMap.put(JetTokens.ESCAPE_SEQUENCE, "escape")
styleMap.put(JetTokens.CLOSING_QUOTE, "string")
styleMap.put(JetTokens.CHARACTER_LITERAL, "string")
styleMap.put(JetTokens.LABEL_IDENTIFIER, "label")
styleMap.put(JetTokens.ATAT, "label")
styleMap.put(JetTokens.FIELD_IDENTIFIER, "field")
styleMap.put(TokenType.BAD_CHARACTER, "bad")
putAll(JetTokens.STRINGS, "string")
putAll(JetTokens.MODIFIER_KEYWORDS, "softkeyword")
putAll(JetTokens.SOFT_KEYWORDS, "softkeyword")
putAll(JetTokens.COMMENTS, "jet-comment")
putAll(JetTokens.OPERATIONS, "operation")
return styleMap
}
}
@@ -0,0 +1,27 @@
package org.jetbrains.kotlin.doc.model
import org.jetbrains.jet.compiler.CompilerPlugin
import org.jetbrains.jet.compiler.CompilerPluginContext
import org.jetbrains.kotlin.doc.KDocConfig
/** Base class for any compiler plugin which needs to process a KModel */
abstract class KModelCompilerPlugin: CompilerPlugin {
public open var config: KDocConfig = KDocConfig()
public override fun processFiles(context: CompilerPluginContext?) {
if (context != null) {
val bindingContext = context.getContext()
val sources = context.getFiles()
if (bindingContext != null && sources != null) {
val model = KModel(bindingContext, config)
model.load(sources)
processModel(model)
}
}
}
protected abstract fun processModel(model: KModel): Unit
}
@@ -0,0 +1,996 @@
package org.jetbrains.kotlin.doc.model
import kotlin.*
import kotlin.util.*
import org.jetbrains.kotlin.doc.KDocConfig
import org.jetbrains.kotlin.doc.highlighter.SyntaxHighligher
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
import org.jetbrains.kotlin.doc.templates.KDocTemplate
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl
import org.jetbrains.jet.lang.descriptors.Visibility
import org.jetbrains.jet.lang.descriptors.ClassKind
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiDirectory
import org.jetbrains.jet.lang.descriptors.Visibilities
/**
* Returns the collection of functions with duplicate function names filtered out
* so only the first one is included
*/
fun filterDuplicateNames(functions: Collection<KFunction>): Collection<KFunction> {
var lastName = ""
return functions.filter{
val name = it.name
val answer = name != lastName
lastName = name
answer
}
}
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
}
}
fun warning(message: String) {
println("Warning: $message")
}
// 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(model: KModel, declarationDescriptor: DeclarationDescriptor): KAnnotated(model, declarationDescriptor) {
public open val functions: SortedSet<KFunction> = TreeSet<KFunction>()
public open val properties: SortedSet<KProperty> = TreeSet<KProperty>()
fun findProperty(name: String): KProperty? {
// TODO we should use a Map<String>?
return properties.find{ it.name == name }
}
fun findFunction(expression: String): KFunction? {
val idx = expression.indexOf('(')
val name = if (idx > 0) expression.substring(0, idx) else expression
val postfix = if (idx > 0) expression.substring(idx).trimTrailing("()") else ""
return functions.find{ it.name == name && it.parameterTypeText == postfix }
}
}
class KModel(var context: BindingContext, val config: KDocConfig) {
// 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 && config.includePackage(it) }
public val classes: Collection<KClass>
get() = packages.flatMap{ it.classes }
public var markdownProcessor: PegDownProcessor = PegDownProcessor(Extensions.ALL)
public var highlighter: SyntaxHighligher = SyntaxHighligher()
public val title: String
get() = config.title
public val version: String
get() = config.version
/** 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) {
configureComments(pkg, descriptor)
val scope = descriptor.getMemberScope()
addFunctions(pkg, scope)
pkg.local = isLocal(descriptor)
}
return pkg;
}
fun wikiConvert(text: String, linkRenderer: LinkRenderer, fileName: String?): String {
return markdownProcessor.markdownToHtml(text, linkRenderer).sure()
}
protected fun isLocal(descriptor: DeclarationDescriptor): Boolean {
return if (descriptor is ModuleDescriptor) {
true
} else {
val parent = descriptor.getContainingDeclaration()
if (parent != null) {
isLocal(parent)
} else {
false
}
}
}
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) {
warning("Caught exception finding function declarations on $owner $e")
e.printStackTrace()
}
}
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())
configureComments(function, descriptor)
val receiver = descriptor.getReceiverParameter()
if (receiver is ExtensionReceiver) {
val receiverType = getType(receiver.getType())
function.receiverType = receiverType
function.extensionClass = receiverType?.klass
}
return function
}
return null
}
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, this)
configureComments(answer, descriptor)
return answer
}
protected fun createParameter(descriptor: ValueParameterDescriptor): KParameter? {
val returnType = getType(descriptor.getReturnType())
if (returnType != null) {
val name = descriptor.getName()
val answer = KParameter(descriptor, name, returnType)
configureComments(answer, descriptor)
return answer
}
return null
}
fun fileFor(descriptor: DeclarationDescriptor): String? {
val psiElement = getPsiElement(descriptor)
return psiElement?.getContainingFile()?.getName()
}
protected fun getPsiElement(descriptor: DeclarationDescriptor): PsiElement? {
return try {
BindingContextUtils.descriptorToDeclaration(context, descriptor)
} catch (e: Throwable) {
// ignore exceptions on fake descriptors
null
}
}
protected fun commentsFor(descriptor: DeclarationDescriptor): String {
val psiElement = getPsiElement(descriptor)
// 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 = ""
}
// lets check for javadoc style @ tags and macros
if (text.startsWith("@")) {
val remaining = text.substring(1)
val macro = "includeFunctionBody"
if (remaining.startsWith(macro)) {
val next = remaining.substring(macro.length()).trim()
val words = next.split("\\s")
// TODO we could default the test function name to match that of the
// source code function if folks adopted a convention of naming the test method after the
// method its acting as a demo/test for
if (words != null && words.size > 1) {
val includeFile = words[0].sure()
val fnName = words[1].sure()
val content = findFunctionInclude(psiElement, includeFile, fnName)
if (content != null) {
text = highlighter.highlight(content)
} else {
warning("could not find function $fnName in file $includeFile from source file ${psiElement.getContainingFile()}")
}
}
} else {
warning("Uknown kdoc macro @$remaining")
}
}
buffer.append(text)
}
return buffer.toString() ?: ""
} else {
return text
}
}
return ""
}
protected fun findFunctionInclude(psiElement: PsiElement, includeFile: String, functionName: String): String? {
var dir = psiElement.getContainingFile()?.getParent()
if (dir != null) {
val file = relativeFile(dir.sure(), includeFile)
if (file != null) {
val text = file.getText()
if (text != null) {
// lets find the function definition
val regex = """fun\s+$functionName\(.*\)""".toRegex()
val matcher = regex.matcher(text)!!
if (matcher.find()) {
val idx = matcher.end()
val remaining = text.substring(idx)
return extractBlock(remaining)
}
}
}
}
return null
}
/**
* Extracts the block of code within { .. } tokens or returning null if it can't be found
*/
protected fun extractBlock(text: String): String? {
val idx = text.indexOf('{')
if (idx >= 0) {
var remaining = text.substring(idx + 1)
// lets remove any leading blank lines
while (true) {
val nidx = remaining.indexOf('\n')
if (nidx >= 0) {
val line = remaining.substring(0, nidx).trim()
if (line.isEmpty()) {
remaining = remaining.substring(nidx + 1)
continue
}
}
break
}
var count = 1
for (i in 0.upto(remaining.size - 1)) {
val ch = remaining[i]
if (ch == '{') count ++
else if (ch == '}') {
if (--count <= 0) {
return remaining.substring(0, i)
}
}
}
warning("missing } in code block for $remaining")
return remaining
}
return null
}
protected fun relativeFile(directory: PsiDirectory, relativeName: String): PsiFile? {
// TODO would have thought there's some helper function already to resolve relative names!
var dir: PsiDirectory? = directory
// lets try resolve the include name relative to this file
val paths = relativeName.split("/")
if (paths != null) {
val size = paths.size
for (i in 0.upto(size - 2)) {
val path = paths[i]
if (path == ".") continue
else if (path == "..") dir = dir?.getParent()
else if (path != null) dir = dir?.findSubdirectory(path)
}
val name = paths[size - 1]
if (dir != null && name != null) {
val file = dir?.findFile(name)
if (file != null) {
return file
} else {
warning("could not find file $relativeName in $dir with name $name")
}
}
}
return null
}
fun configureComments(annotated: KAnnotated, descriptor: DeclarationDescriptor): Unit {
val detailedText = commentsFor(descriptor).trim()
annotated.wikiDescription = detailedText
}
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
}
/**
* Returns the [[KClass]] for the fully qualified name or null if it could not be found
*/
fun getClass(qualifiedName: String): KClass? {
// TODO warning this only works for top level classes
// a better algorithm is to walk down each dot path dealing with nested packages/classes
val idx = qualifiedName.lastIndexOf('.')
val pkgName = if (idx >= 0) qualifiedName.substring(0, idx) ?: "" else ""
val pkg = getPackage(pkgName)
if (pkg != null) {
val simpleName = if (idx >= 0) qualifiedName.substring(idx + 1) ?: "" else qualifiedName
return pkg.classMap.get(simpleName)
}
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 {
warning("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 TemplateLinkRenderer(val annotated: KAnnotated, val template: KDocTemplate): LinkRenderer() {
public override fun render(node: WikiLinkNode?): Rendering? {
val answer = super.render(node)
if (answer != null) {
val text = answer.text
if (text != null) {
val qualified = resolveToQualifiedName(text)
var href = resolveClassNameLink(qualified)
if (href != null) {
answer.href = href
} else {
// TODO really dirty hack alert!!!
// until the resolver is working, lets try adding a few prefixes :)
for (prefix in arrayList("java.lang", "java.util", "java.util.regex", "java.io", "jet"))
if (href == null) {
href = resolveClassNameLink(prefix + "." + qualified)
}
/** TODO use break when KT-1523 is fixed
if (href != null) {
break
}
*/
}
if (href != null) {
answer.href = href
} else {
warning("could not resolve expression: $qualified into a wiki link")
}
}
}
return answer
}
/**
* Try to resolve a fully qualified class name as a link
*/
protected fun resolveClassNameLink(qualifiedName: String): String? {
val model = annotated.model
val pkg = model.getPackage(qualifiedName)
if (pkg != null) {
return template.href(pkg)
}
val klass = model.getClass(qualifiedName)
if (klass != null) {
return template.href(klass)
} else {
// is it a method?
val idx = qualifiedName.lastIndexOf('.')
if (idx > 0) {
val className = qualifiedName.substring(0, idx)
val c = model.getClass(className)
if (c != null) {
// lets try find method...
val remaining = qualifiedName.substring(idx + 1)
// lets try find the function
val fn = c.findFunction(remaining)
if (fn != null) {
return template.href(fn)
}
val p = c.findProperty(remaining)
if (p != null) {
return template.href(p)
}
}
}
return null
}
}
/**
* Attempts to resolve the class, method or property expression using the
* current imports and declaraiton
*/
protected fun resolveToQualifiedName(text: String): String {
// TODO use the CompletionContributors maybe to figure out what local names are imported???
return text
/*
val scope = findWritableScope(annotated.declarationDescriptor)
if (scope != null) {
val classifierDescriptor = scope.getClassifier(text)
if (classifierDescriptor == null) {
val o = scope.getObjectDescriptor(text)
println("Attempt to resolve HREF: $text Found objectDescriptor $o")
} else {
println("Attempt to resolve HREF: $text Found classifierDescriptor $classifierDescriptor")
}
}
}
protected fun findWritableScope(declarationDescriptor: DeclarationDescriptor) : WritableScopeImpl? {
val container = declarationDescriptor.getContainingDeclaration()
if (container is NamespaceDescriptor) {
val scope = container.getMemberScope()
if (scope is WritableScopeImpl) {
return scope
}
} else if (container != null) {
return findWritableScope(container)
}
return null
*/
}
public override fun render(node: RefLinkNode?, url: String?, title: String?, text: String?): Rendering? {
return super.render(node, url, title, text)
}
public override fun render(node: AutoLinkNode?): Rendering? {
return super.render(node)
}
public override fun render(node: ExpLinkNode?, text: String?): Rendering? {
return super.render(node, text)
}
}
abstract class KAnnotated(val model: KModel, val declarationDescriptor: DeclarationDescriptor) {
public open var wikiDescription: String = ""
public open var deprecated: Boolean = false
fun description(template: KDocTemplate): String {
val detailedText = detailedDescription(template)
val idx = detailedText.indexOf("</p>")
return if (idx > 0) {
detailedText.substring(0, idx).trimLeading("<p>")
} else {
detailedText
}
}
fun detailedDescription(template: KDocTemplate): String {
val file = model.fileFor(declarationDescriptor)
return model.wikiConvert(wikiDescription, TemplateLinkRenderer(this, template), file)
}
}
abstract class KNamed(val name: String, model: KModel, declarationDescriptor: DeclarationDescriptor): KAnnotated(model, declarationDescriptor), Comparable<KNamed> {
public override fun compareTo(other: KNamed): Int = name.compareTo(other.name)
open fun equals(other: KPackage) = name == other.name
open fun toString() = name
}
class KPackage(model: KModel, val descriptor: NamespaceDescriptor,
val name: String,
var local: Boolean = false): KClassOrPackage(model, descriptor), Comparable<KPackage> {
public 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) {
model.configureComments(klass, 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{ ".." }.makeString("/")
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>
get() = classMap.values().sure().filter{ it.isApi() }
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, model: KModel, val klass: KClass?, val arguments: List<KType> = ArrayList<KType>())
: KNamed(klass?.name ?: jetType.toString(), model, jetType.getConstructor().getDeclarationDescriptor().sure()) {
{
if (klass != null) {
this.wikiDescription = klass.wikiDescription
}
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 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(pkg.model, descriptor), Comparable<KClass> {
public override fun compareTo(other: KClass): Int = name.compareTo(other.name)
fun equals(other: KClass) = name == other.name
fun toString() = "$kind($name)"
fun isApi(): Boolean {
val visibility = descriptor.getVisibility()
return visibility.isPublicAPI()
}
val kind: String
get() {
val k = descriptor.getKind()
return if (k == ClassKind.TRAIT) "trait"
else if (k == ClassKind.OBJECT) "object"
else if (k == ClassKind.ENUM_CLASS || k == ClassKind.ENUM_ENTRY) "enum"
else if (k == ClassKind.ANNOTATION_CLASS) "annotation"
else "class"
}
val kindCode: String
get() {
val k = descriptor.getKind()
return if (k == ClassKind.TRAIT) "trait"
else if (k == ClassKind.OBJECT) "object"
else if (k == ClassKind.ENUM_CLASS || k == ClassKind.ENUM_ENTRY) "enum class"
else if (k == ClassKind.ANNOTATION_CLASS) "class"
else "class"
}
val visibility: String
get() {
val v = descriptor.getVisibility()
return if (v == Visibilities.PUBLIC) "public"
else if (v == Visibilities.PROTECTED) "protected"
else if (v == Visibilities.PRIVATE) "private"
else ""
}
/** 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 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 receiverType: KType? = null,
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(owner.model, descriptor), Comparable<KFunction> {
public val parameterTypeText: String = parameters.map{ it.aType.name }.makeString(", ")
public 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 }.makeString(", ")
}
class KProperty(val owner: KClassOrPackage, val descriptor: PropertyDescriptor, val name: String,
val returnType: KType, val extensionClass: KClass?): KAnnotated(owner.model, descriptor), Comparable<KProperty> {
public override fun compareTo(other: KProperty): Int = name.compareTo(other.name)
public val link: String = "$name"
fun equals(other: KFunction) = name == other.name
fun isVar(): Boolean = descriptor.isVar()
fun toString() = "property $name"
}
class KParameter(val descriptor: ValueParameterDescriptor, val name: String,
var aType: KType): KAnnotated(aType.model, aType.declarationDescriptor) {
fun toString() = "$name: ${aType.name}"
fun isVarArg(): Boolean = descriptor.getVarargElementType() != null
fun hasDefaultValue(): Boolean = descriptor.hasDefaultValue()
fun varArgType(): KType? {
val varType = descriptor.getVarargElementType()
return if (varType != null) {
aType.model.getType(varType)
} else null
}
}
class KTypeParameter(val name: String,
val descriptor: TypeParameterDescriptor,
model: KModel,
var extends: List<KClass> = arrayList<KClass>()): KAnnotated(model, descriptor) {
fun toString() = "$name"
}
class KAnnotation(var klass: KClass): KAnnotated(klass.model, klass.descriptor) {
// 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,50 @@
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) {
protected override fun relativePrefix(): String = "${pkg.nameAsRelativePath}${klass.pkg.nameAsRelativePath}"
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 {
return if (f.extensionClass != null) "#${f.link}" else super.href(f)
}
}
@@ -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">
${stylesheets()}
<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;PROPERTY&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">FUNCTION</A></FONT></TD>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
DETAIL:&nbsp;PROPERTY&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">FUNCTION</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;PROPERTY&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">FUNCTION</A></FONT></TD>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
DETAIL:&nbsp;PROPERTY&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">FUNCTION</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>${klass.visibility} ${klass.kindCode} <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(this))
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(this)}
</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) }.makeString(", ")
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(this)}</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,110 @@
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
import org.jetbrains.kotlin.doc.model.filterDuplicateNames
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">
${stylesheets()}
</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("trait", "Traits")
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 = filterDuplicateNames(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>""")
var lastName = ""
for (c in functions) {
// only show the first function with a given name
if (c.name != lastName) {
println("""<A HREF="${href(c)}" title="function in ${pkg.name}" target="classFrame"><I>${c.name}</I></A>
<BR>""")
}
lastName = c.name
}
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,317 @@
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
import org.jetbrains.kotlin.doc.model.filterDuplicateNames
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">
${stylesheets()}
<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(this)}
<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("trait", "Traits")
printClasses("class", "Classes")
printClasses("enum", "Enums")
printClasses("annotation", "Annotations")
printClasses("exception", "Exceptions")
printFunctionSummary(pkg.packageFunctions())
//printFunctions()
printExtensionFunctions()
println("""<A NAME="package_description"><!-- --></A><H2>
Package ${pkg.name} Description
</H2>
<P>
${pkg.detailedDescription(this)}
<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(this)}</TD>
</TR>""")
}
println("""</TABLE>
&nbsp;
<P>
""")
}
}
// TODO delete
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(this)}</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) {
val functions = filterDuplicateNames(list)
for (f in functions) {
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,285 @@
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
val funKeyword = keyword("fun")
val valKeyword = keyword("val")
val varKeyword = keyword("var")
protected fun keyword(name: String): String = "<B>$name</B>"
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>""")
print("$funKeyword ")
printTypeParameters(function)
printReceiverType(function, "<BR>")
println("""</CODE></FONT></TD>
</TR>
</TABLE>""")
} else {
print(funKeyword)
printReceiverType(function)
}
// print receiver type
println("""</CODE></FONT></TD>""")
print("""<TD><CODE><B><A HREF="${href(function)}">${function.name}</A></B>""")
printParameters(function)
print(": ")
print(link(function.returnType))
println("""</CODE>""")
println("")
if (true) {
println("""<BR>""")
println("""${function.description(this)}""")
} else {
println("""<BR>""")
println("""&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${deprecated}&nbsp;${function.detailedDescription(this)}</TD>""")
}
println("""</TD>""")
println("""</TR>""")
}
fun printReceiverType(function: KFunction, prefix: String = " ", postfix: String = "", none: String = ""): Unit {
val receiverType = function.receiverType
if (receiverType != null) {
print(prefix)
print(link(receiverType))
print(postfix)
} else {
print(none)
}
}
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.makeString(" ")} $funKeyword""")
printTypeParameters(function, " ")
printReceiverType(function, " ", ".", " ")
print("""<A HREF="${sourceHref(function)}"><B>${function.name}</B></A>""")
printParameters(function)
print(": ")
print(link(function.returnType))
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(this))
/* 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>""")
print(if (property.isVar()) varKeyword else valKeyword)
/*
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))
}
*/
println("""</CODE></FONT></TD>""")
print("""<TD><CODE><B><A HREF="${href(property)}">${property.name}</A></B>: """)
print(link(property.returnType))
//printParameters(property)
println("""</CODE>""")
println("""""")
println("""<BR>""")
println("""&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${deprecated}&nbsp;${property.detailedDescription(this)}</TD>""")
println("""</TR>""")
}
fun printTypeParameters(method: KFunction, separator: String = ""): Unit {
val typeParameters = method.typeParameters
if (!typeParameters.isEmpty()) {
print(separator)
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")
}
}
fun printParameters(method: KFunction): Unit {
print("(")
var first = true
var defaultValue = false
for (p in method.parameters) {
if (!p.hasDefaultValue() && defaultValue) {
print("]")
defaultValue = false
}
if (first) first = false else print(", ")
if (p.hasDefaultValue() && !defaultValue) {
print(" [")
defaultValue = true
}
val pType = if (p.isVarArg()) {
print("vararg ")
p.varArgType().sure()
} else {
p.aType
}
print("${p.name}:&nbsp;")
print(link(pType))
}
if (defaultValue) {
print("]")
}
print(")")
}
fun printAnnotations(annotations: Collection<KAnnotation>): Unit {
for (a in annotations) {
println(link(a))
}
}
fun stylesheets(): String {
return """<LINK REL="stylesheet" TYPE="text/css" HREF="${relativePrefix()}stylesheet.css" TITLE="Style">
<LINK REL="stylesheet" TYPE="text/css" HREF="${relativePrefix()}kotlin.css" TITLE="Style">"""
}
}
@@ -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,31 @@
package test.kotlin.kdoc
import java.io.File
import kotlin.test.assertTrue
import org.jetbrains.jet.cli.CompilerArguments
import org.jetbrains.jet.cli.KotlinCompiler
import org.jetbrains.kotlin.doc.highlighter.HtmlCompilerPlugin
import org.junit.Test
class HtmlVisitorTest {
Test fun generateHtmlFromSource() {
val src = "src/test/sample"
var dir = File(".")
if (!File(dir, src).exists()) {
dir = File("kdoc")
assertTrue(File(dir, src).exists(), "Cannot find file $src")
}
val srcDir = File(dir, src)
val outDir = File(dir, "target/htmldocs")
println("Generating source HTML to $outDir")
val args = CompilerArguments()
args.setSrc(srcDir.toString())
args.setOutputDir(File(dir, "target/classes-htmldocs").toString())
args.getCompilerPlugins()?.add(HtmlCompilerPlugin())
val compiler = KotlinCompiler()
compiler.exec(System.out, args)
}
}
@@ -0,0 +1,42 @@
package test.kotlin.kdoc
import org.jetbrains.kotlin.doc.KDocArguments
import org.jetbrains.kotlin.doc.KDocCompiler
import kotlin.test.assertTrue
import org.junit.Test
import java.io.File
/**
*/
class KDocTest {
Test fun generateKDocForStandardLibrary() {
var moduleName = "ApiDocsModule.kt"
var dir = "."
if (!File(moduleName).exists()) {
dir = "kdoc"
moduleName = dir + "/" + moduleName
assertTrue(File(moduleName).exists(), "Cannot find file $moduleName")
}
val outDir = File(dir, "target/apidocs")
println("Generating library KDocs to $outDir")
val args = KDocArguments()
args.setModule(moduleName)
args.setOutputDir("target/classes-stdlib")
val config = args.docConfig
config.docOutputDir = outDir.toString()!!
config.title = "Kotlin API"
config.ignorePackages.add("org.jetbrains.kotlin")
config.ignorePackages.add("java")
config.ignorePackages.add("jet")
config.ignorePackages.add("junit")
config.ignorePackages.add("sun")
config.ignorePackages.add("org")
val compiler = KDocCompiler()
compiler.exec(System.out, args)
}
}
@@ -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() {
public override fun render(node : WikiLinkNode?) : Rendering? {
println("LinkRenderer.render(WikiLinkNode): $node")
return super.render(node)
}
public 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)
}
public override fun render(node : AutoLinkNode?) : Rendering? {
println("LinkRenderer.render(AutoLinkNode): $node")
return super.render(node)
}
public 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() {
public 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() {
public 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")
)
}
}
@@ -0,0 +1,8 @@
package sample
/** A Comment */
class Person(val name: String, val city: String) {
fun toString(): String = "Person($name, $city)"
fun hello(): String = "Hello $name"
}
+145
View File
@@ -0,0 +1,145 @@
<?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>
<properties>
<maven-plugin-anno.version>1.4.1</maven-plugin-anno.version>
<maven.version>3.0.4</maven.version>
</properties>
<parent>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>tools</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>kotlin-install</artifactId>
<packaging>pom</packaging>
<description>Installs the Kotlin runtime dependencies into the local maven repo</description>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>org.jetbrains.kotlin:kotlin-compiler</id>
<phase>verify</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-compiler</artifactId>
<version>${project.version}</version>
<packaging>jar</packaging>
<file>${kotlin-sdk}/lib/kotlin-compiler.jar</file>
<createChecksum>true</createChecksum>
<generatePom>true</generatePom>
</configuration>
</execution>
<execution>
<id>org.jetbrains.kotlin:kotlin-build-tools</id>
<phase>verify</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-build-tools</artifactId>
<version>${project.version}</version>
<packaging>jar</packaging>
<file>${kotlin-sdk}/lib/kotlin-build-tools.jar</file>
<createChecksum>true</createChecksum>
<generatePom>true</generatePom>
</configuration>
</execution>
<execution>
<id>org.jetbrains.kotlin:intellij-core</id>
<phase>verify</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>intellij-core</artifactId>
<version>${project.version}</version>
<packaging>jar</packaging>
<file>${kotlin-sdk}/lib/intellij-core.jar</file>
<createChecksum>true</createChecksum>
<generatePom>true</generatePom>
</configuration>
</execution>
<execution>
<id>org.jetbrains.kotlin:intellij-annotations</id>
<phase>verify</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>intellij-annotations</artifactId>
<version>${project.version}</version>
<packaging>jar</packaging>
<file>${kotlin-sdk}/lib/annotations.jar</file>
<createChecksum>true</createChecksum>
<generatePom>true</generatePom>
</configuration>
</execution>
<execution>
<id>org.jetbrains.kotlin:trove4j</id>
<phase>verify</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>trove4j</artifactId>
<version>${project.version}</version>
<packaging>jar</packaging>
<file>${kotlin-sdk}/lib/trove4j.jar</file>
<createChecksum>true</createChecksum>
<generatePom>true</generatePom>
</configuration>
</execution>
<execution>
<id>org.jetbrains.kotlin:picocontainer</id>
<phase>verify</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>picocontainer</artifactId>
<version>${project.version}</version>
<packaging>jar</packaging>
<file>${kotlin-sdk}/lib/picocontainer.jar</file>
<createChecksum>true</createChecksum>
<generatePom>true</generatePom>
</configuration>
</execution>
<execution>
<id>org.jetbrains.kotlin:dartc</id>
<phase>verify</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>dartc</artifactId>
<version>${project.version}</version>
<packaging>jar</packaging>
<file>${kotlin-sdk}/lib/js/${dart.name}.jar</file>
<createChecksum>true</createChecksum>
<generatePom>true</generatePom>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,4 @@
## NOTE - this is just an initial spike of some maven plugins
Until this plugin is working, please use this maven plugin:
http://evgeny-goldin.com/wiki/Kotlin-maven-plugin
+170
View File
@@ -0,0 +1,170 @@
<?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>
<properties>
<maven-plugin-anno.version>1.4.1</maven-plugin-anno.version>
<maven.version>3.0.4</maven.version>
</properties>
<parent>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>tools</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>kotlin-maven-plugin</artifactId>
<packaging>maven-plugin</packaging>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>${maven.version}</version>
</dependency>
<!--
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
<version>${maven.version}</version>
</dependency>
-->
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-compiler</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>runtime</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>intellij-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>intellij-annotations</artifactId>
<version>${project.version}</version>
</dependency>
<!-- TODO Req. only for K2JSTranslator, move it to compiler -->
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-build-tools</artifactId>
<version>${project.version}</version>
</dependency>
<!-- Shall be transitive dependencies of Kotlin compiler -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>${asm.version}</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm-tree</artifactId>
<version>${asm.version}</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm-commons</artifactId>
<version>${asm.version}</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm-util</artifactId>
<version>${asm.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>trove4j</artifactId>
<version>${project.version}</version>
</dependency>
<!--
<dependency>
<groupId>net.sf.trove4j</groupId>
<artifactId>trove4j</artifactId>
<version>3.0.2</version>
</dependency>
-->
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>picocontainer</artifactId>
<version>${project.version}</version>
</dependency>
<!--
<dependency>
<groupId>org.picocontainer</groupId>
<artifactId>picocontainer</artifactId>
<version>2.9</version>
</dependency>
-->
<!-- for JS generation -->
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>dartc</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<testSourceDirectory>src/test/java</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>2.9</version>
</plugin>
<!-- Get rid of it right after compiler careful packaging -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<!--
<createDependencyReducedPom>true</createDependencyReducedPom>
<keepDependenciesWithProvidedScope>true</keepDependenciesWithProvidedScope>
<promoteTransitiveDependencies>true</promoteTransitiveDependencies>
-->
<artifactSet>
<includes>
<include>org.jetbrains.kotlin:*</include>
</includes>
<excludes>
<exclude>org.jetbrains.kotlin:stdlib</exclude>
</excludes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,48 @@
/*
* 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 org.jetbrains.kotlin.maven;
import org.apache.maven.plugin.MojoExecutionException;
import org.jetbrains.jet.cli.CompilerArguments;
/**
* Converts Kotlin to JavaScript code
*
* @goal js
* @phase compile
* @noinspection UnusedDeclaration
*/
public class K2JSCompilerMojo extends KotlinCompileMojo {
/**
* The output JS file name
*
* @required
* @parameter default-value="${project.build.directory}/js/${project.artifactId}.js"
*/
private String outFile;
@Override
protected void configureCompilerArguments(CompilerArguments arguments) throws MojoExecutionException {
super.configureCompilerArguments(arguments);
K2JSCompilerPlugin plugin = new K2JSCompilerPlugin();
plugin.setOutFile(outFile);
arguments.getCompilerPlugins().add(plugin);
getLog().info("Compiling Kotlin src from " + arguments.getSrc() + " to JavaScript at: " + outFile);
}
}
@@ -0,0 +1,74 @@
/*
* 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 org.jetbrains.kotlin.maven;
import com.google.common.io.Files;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.compiler.CompilerPlugin;
import org.jetbrains.jet.compiler.CompilerPluginContext;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.k2js.config.Config;
import org.jetbrains.k2js.facade.K2JSTranslator;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
/**
* Compiles Kotlin code to JavaScript
*/
public class K2JSCompilerPlugin implements CompilerPlugin {
private String outFile = "target/js/program.js";
public void processFiles(CompilerPluginContext context) {
if (context != null) {
Project project = context.getProject();
BindingContext bindingContext = context.getContext();
List<JetFile> sources = context.getFiles();
if (bindingContext != null && sources != null && project != null) {
Config config = new Config(project) {
@NotNull
@Override
public List<JetFile> getLibFiles() {
return new ArrayList<JetFile>();
}
};
K2JSTranslator translator = new K2JSTranslator(config);
final String code = translator.generateProgramCode(sources);
File file = new File(outFile);
try {
Files.createParentDirs(file);
Files.write(code, file, Charset.forName("UTF-8"));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
public void setOutFile(String outFile) {
this.outFile = outFile;
}
}
@@ -0,0 +1,36 @@
/*
* 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 org.jetbrains.kotlin.maven;
import org.apache.maven.plugin.MojoExecutionException;
import org.jetbrains.jet.cli.CompilerArguments;
/**
* Compiles kotlin sources
*
* @goal compile
* @phase compile
* @requiresDependencyResolution compile
* @noinspection UnusedDeclaration
*/
public class KotlinCompileMojo extends KotlinCompileMojoBase {
@Override
protected void configureCompilerArguments(CompilerArguments arguments) throws MojoExecutionException {
configureBaseCompilerArguments(getLog(), arguments, module, sources, classpath, output);
}
}
@@ -0,0 +1,162 @@
/*
* 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 org.jetbrains.kotlin.maven;
import com.google.common.base.Joiner;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.jetbrains.jet.cli.CompilerArguments;
import org.jetbrains.jet.cli.KotlinCompiler;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public abstract class KotlinCompileMojoBase extends AbstractMojo {
/**
* The source directories containing the sources to be compiled.
*
* @parameter default-value="${project.compileSourceRoots}"
* @required
* @readonly
*/
public List<String> sources;
/**
* The source directories containing the sources to be compiled for tests.
*
* @parameter default-value="${project.testCompileSourceRoots}"
* @required
* @readonly
*/
protected List<String> testSources;
/**
* Project classpath.
*
* @parameter default-value="${project.compileClasspathElements}"
* @required
* @readonly
*/
public List<String> classpath;
/**
* Project test classpath.
*
* @parameter default-value="${project.testClasspathElements}"
* @required
* @readonly
*/
protected List<String> testClasspath;
/**
* The directory for compiled classes.
*
* @parameter default-value="${project.build.outputDirectory}"
* @required
* @readonly
*/
public String output;
/**
* The directory for compiled tests classes.
*
* @parameter default-value="${project.build.testOutputDirectory}"
* @required
* @readonly
*/
public String testOutput;
/**
* Kotlin compilation module, as alternative to source files or folders.
*
* @parameter
*/
public String module;
/**
* Kotlin compilation module, as alternative to source files or folders (for tests).
*
* @parameter
*/
public String testModule;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
final CompilerArguments arguments = createCompilerArguments();
configureCompilerArguments(arguments);
final KotlinCompiler compiler = createCompiler();
final KotlinCompiler.ExitCode exitCode = compiler.exec(System.err, arguments);
switch (exitCode) {
case COMPILATION_ERROR:
throw new MojoExecutionException("Compilation error. See log for more details");
case INTERNAL_ERROR:
throw new MojoExecutionException("Internal compiler error. See log for more details");
}
}
protected KotlinCompiler createCompiler() {
return new KotlinCompiler();
}
/**
* Derived classes can create custom compiler argument implementations
* such as for KDoc
*/
protected CompilerArguments createCompilerArguments() {
return new CompilerArguments();
}
/**
* Derived classes can register custom plugins or configurations
*/
protected abstract void configureCompilerArguments(CompilerArguments arguments) throws MojoExecutionException;
protected static void configureBaseCompilerArguments(Log log, CompilerArguments arguments, String module,
List<String> sources, List<String> classpath, String output) throws MojoExecutionException {
if (module != null) {
log.info("Compiling Kotlin module " + module);
arguments.setModule(module);
} else {
if (sources.size() <= 0)
throw new MojoExecutionException("No source roots to compile");
arguments.setSourceDirs(sources);
log.info("Compiling Kotlin sources from " + arguments.getSourceDirs());
}
final ArrayList<String> classpathList = new ArrayList<String>(classpath);
if (classpathList.remove(output)) {
log.debug("Removed target directory from classpath (" + output + ")");
}
final String classPathString = Joiner.on(File.pathSeparator).join(classpathList);
log.info("Classpath: " + classPathString);
arguments.setClasspath(classPathString);
log.info("Classes directory is " + output);
arguments.setOutputDir(output);
}
}
@@ -0,0 +1,54 @@
/*
* 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 org.jetbrains.kotlin.maven;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.jetbrains.jet.cli.CompilerArguments;
/**
* Compiles Kotlin test sources
*
* @goal test-compile
* @phase test-compile
* @requiresDependencyResolution test
* @noinspection UnusedDeclaration
*/
public class KotlinTestCompileMojo extends KotlinCompileMojoBase {
/**
* Flag to allow test compilation to be skipped.
*
* @parameter expression="${maven.test.skip}" default-value="false"
* @noinspection UnusedDeclaration
*/
private boolean skip;
public void execute() throws MojoExecutionException, MojoFailureException {
if (skip) {
getLog().info("Test compilation is skipped");
} else {
super.execute();
}
}
@Override
protected void configureCompilerArguments(CompilerArguments arguments) throws MojoExecutionException {
configureBaseCompilerArguments(
getLog(), arguments,
testModule, testSources, testClasspath, testOutput);
}
}
@@ -0,0 +1,26 @@
/*
* 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 org.jetbrains.kotlin.maven;
import org.junit.Test;
public class MojoTest {
@Test
public void dummy() {
}
}
+29
View File
@@ -0,0 +1,29 @@
<?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>
<parent>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-project</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>tools</artifactId>
<packaging>pom</packaging>
<properties>
<project-root>${project.basedir}/../..</project-root>
</properties>
<modules>
<module>kotlin-install</module>
<module>runtime</module>
<module>kotlin-maven-plugin</module>
<module>kdoc</module>
<module>kdoc-maven-plugin</module>
</modules>
</project>
+40
View File
@@ -0,0 +1,40 @@
<?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>
<parent>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>tools</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>runtime</artifactId>
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<!-- Use precompiled class files -->
<execution>
<phase>compile</phase>
<configuration>
<tasks>
<unzip src="${kotlin-sdk}/lib/kotlin-runtime.jar"
dest="${project.build.outputDirectory}"/>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>