diff --git a/build.xml b/build.xml
index 01b4b052a2d..6a2a51b6aaf 100644
--- a/build.xml
+++ b/build.xml
@@ -48,12 +48,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -70,13 +87,6 @@
-
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/KDocProcessor.java b/compiler/cli/src/org/jetbrains/jet/cli/KDocProcessor.java
index 8ba77e5f151..ee6fd5b83c2 100644
--- a/compiler/cli/src/org/jetbrains/jet/cli/KDocProcessor.java
+++ b/compiler/cli/src/org/jetbrains/jet/cli/KDocProcessor.java
@@ -17,38 +17,30 @@
*/
package org.jetbrains.jet.cli;
-import com.google.common.base.Predicates;
import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.Disposable;
-import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jet.compiler.CompilerPlugin;
import org.jetbrains.jet.compiler.JetCoreEnvironment;
-import org.jetbrains.jet.compiler.JetFileProcessor;
-import org.jetbrains.jet.lang.Configuration;
-import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
-import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiFactory;
-import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext;
-import org.jetbrains.jet.lang.resolve.BindingTraceContext;
-import org.jetbrains.jet.lang.resolve.java.JavaBridgeConfiguration;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.resolve.DescriptorRenderer;
+import java.io.File;
+import java.lang.reflect.Constructor;
import java.util.Collection;
import java.util.List;
-import java.util.Set;
/**
+ * A simple facade to auto-detect the KDoc processor if its available on the classpath
*/
-public class KDocProcessor implements JetFileProcessor {
+public class KDocProcessor implements CompilerPlugin {
private final String outputDir;
@@ -56,11 +48,50 @@ public class KDocProcessor implements JetFileProcessor {
this.outputDir = outputDir;
}
+ public CompilerPlugin createCompilerPlugin() {
+ // lets see if we can see the KDoc class
+ String name = "org.jetbrains.kotlin.doc.KDoc";
+ Class> aClass = null;
+ try {
+ aClass = loadClass(name);
+ } catch (ClassNotFoundException e) {
+ System.out.println("Could not find class: " + name);
+ return null;
+ }
+ if (aClass != null) {
+ try {
+ File dir = new File(outputDir);
+ Constructor> constructor = aClass.getConstructor(File.class);
+ if (constructor != null) {
+ return (CompilerPlugin) constructor.newInstance(dir);
+ }
+ } catch (Exception e) {
+ System.out.println("Failed to create Processor: " + e);
+ }
+ }
+ return null;
+ }
+
+ public static Class> loadClass(String name) throws ClassNotFoundException {
+ try {
+ return Class.forName(name);
+ } catch (ClassNotFoundException e) {
+ try {
+ return Thread.currentThread().getContextClassLoader().loadClass(name);
+ } catch (ClassNotFoundException e1) {
+ return KDocProcessor.class.getClassLoader().loadClass(name);
+ }
+ }
+ }
+
+
@Override
- public void processFiles(List sources) {
+ public void processFiles(BindingContext context, List sources) {
+ /*
// JetFile's are PSI (Program Source Interface) classes, i.e. they contain the concrete syntax trees of files
if (sources.isEmpty()) return;
+
// Let's perform the semantic analysis
Project project = sources.get(0).getProject();
Configuration javaBridgeConfiguration = JavaBridgeConfiguration.createJavaBridgeConfiguration(project, new BindingTraceContext(), Configuration.EMPTY);
@@ -82,6 +113,7 @@ public class KDocProcessor implements JetFileProcessor {
}
// TODO fire up the KDoc processor here...
+ */
}
private void processDescriptors(Collection allDescriptors, BindingContext context) {
@@ -125,6 +157,6 @@ public class KDocProcessor implements JetFileProcessor {
});
List files = Lists.newArrayList();
files.add(JetPsiFactory.createFile(jetCoreEnvironment.getProject(), "package a;/**sdfsdf*/class A {fun foo() {} /**doc*/ fun bar() {}}"));
- new KDocProcessor("").processFiles(files);
+ new KDocProcessor("").processFiles(null, files);
}
}
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java
index 6b7b9a4a146..917319eaa70 100644
--- a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java
+++ b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java
@@ -21,6 +21,7 @@ import com.sampullara.cli.Argument;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.compiler.CompileEnvironment;
import org.jetbrains.jet.compiler.CompileEnvironmentException;
+import org.jetbrains.jet.compiler.CompilerPlugin;
import org.jetbrains.jet.compiler.FileNameTransformer;
import java.io.ByteArrayOutputStream;
@@ -127,9 +128,13 @@ public class KotlinCompiler {
environment.setErrorStream(errStream);
}
-// if (arguments.docOutputDir != null) {
-// environment.getMyEnvironment().getFileProcessors().add(new KDocProcessor(arguments.docOutputDir));
-// }
+ if (arguments.docOutputDir != null) {
+ KDocProcessor factory = new KDocProcessor(arguments.docOutputDir);
+ CompilerPlugin processor = factory.createCompilerPlugin();
+ if (processor != null) {
+ environment.getMyEnvironment().getCompilerPlugins().add(processor);
+ }
+ }
if (arguments.stdlib != null) {
environment.setStdlib(arguments.stdlib);
diff --git a/compiler/cli/src/org/jetbrains/jet/compiler/CompileSession.java b/compiler/cli/src/org/jetbrains/jet/compiler/CompileSession.java
index 41732517191..50342a7bc7b 100644
--- a/compiler/cli/src/org/jetbrains/jet/compiler/CompileSession.java
+++ b/compiler/cli/src/org/jetbrains/jet/compiler/CompileSession.java
@@ -204,10 +204,10 @@ public class CompileSession {
generationState.compileCorrectFiles(myBindingContext, mySourceFiles);
ClassFileFactory answer = generationState.getFactory();
- List fileProcessors = myEnvironment.getFileProcessors();
+ List fileProcessors = myEnvironment.getCompilerPlugins();
if (fileProcessors != null) {
- for (JetFileProcessor processor : fileProcessors) {
- processor.processFiles(getSourceFileNamespaces());
+ for (CompilerPlugin processor : fileProcessors) {
+ processor.processFiles(myBindingContext, getSourceFileNamespaces());
}
}
return answer;
diff --git a/compiler/cli/src/org/jetbrains/jet/compiler/JetFileProcessor.java b/compiler/cli/src/org/jetbrains/jet/compiler/CompilerPlugin.java
similarity index 74%
rename from compiler/cli/src/org/jetbrains/jet/compiler/JetFileProcessor.java
rename to compiler/cli/src/org/jetbrains/jet/compiler/CompilerPlugin.java
index 990623cb236..24905cda477 100644
--- a/compiler/cli/src/org/jetbrains/jet/compiler/JetFileProcessor.java
+++ b/compiler/cli/src/org/jetbrains/jet/compiler/CompilerPlugin.java
@@ -18,11 +18,14 @@
package org.jetbrains.jet.compiler;
import org.jetbrains.jet.lang.psi.JetFile;
+import org.jetbrains.jet.lang.resolve.BindingContext;
import java.util.List;
/**
+ * A simple interface for compiler plugins to run after the compiler has finished such as for things like
+ * generating documentation or code generation etc
*/
-public interface JetFileProcessor {
- void processFiles(List sources);
+public interface CompilerPlugin {
+ void processFiles(BindingContext context, List sources);
}
diff --git a/compiler/cli/src/org/jetbrains/jet/compiler/JetCoreEnvironment.java b/compiler/cli/src/org/jetbrains/jet/compiler/JetCoreEnvironment.java
index 303dc2b01fb..a101157b641 100644
--- a/compiler/cli/src/org/jetbrains/jet/compiler/JetCoreEnvironment.java
+++ b/compiler/cli/src/org/jetbrains/jet/compiler/JetCoreEnvironment.java
@@ -33,7 +33,7 @@ import java.util.List;
* @author yole
*/
public class JetCoreEnvironment extends JavaCoreEnvironment {
- private List fileProcessors = new ArrayList();
+ private List compilerPlugins = new ArrayList();
public JetCoreEnvironment(Disposable parentDisposable) {
super(parentDisposable);
@@ -61,11 +61,11 @@ public class JetCoreEnvironment extends JavaCoreEnvironment {
return myApplication;
}
- public List getFileProcessors() {
- return fileProcessors;
+ public List getCompilerPlugins() {
+ return compilerPlugins;
}
- public void setFileProcessors(List fileProcessors) {
- this.fileProcessors = fileProcessors;
+ public void setCompilerPlugins(List compilerPlugins) {
+ this.compilerPlugins = compilerPlugins;
}
}
diff --git a/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/KDoc.kt b/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/KDoc.kt
index 3ca1091696f..af5429a2d71 100644
--- a/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/KDoc.kt
+++ b/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/KDoc.kt
@@ -5,8 +5,67 @@ import org.jetbrains.kotlin.template.TextTemplate
import org.jetbrains.kotlin.model.KModel
import java.io.File
+import org.jetbrains.jet.lang.resolve.BindingContext
+import org.jetbrains.jet.compiler.CompilerPlugin
+import java.util.List
+import org.jetbrains.jet.lang.psi.JetFile
+import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor
+import java.util.HashSet
+import com.intellij.psi.PsiElement
+import org.jetbrains.jet.lexer.JetTokens
-class KDocProcessor(val model: KModel, val outputDir: File) {
+class KDoc(val outputDir: File) : KDocSupport() {
+ val model = KModel()
+
+ /** TODO compile errors so lets use Java for this bit for now...
+ override fun processFiles(context: BindingContext, files: List?) {
+ println("==== KDoc running! Generating to $outputDir")
+ if (context != null) {
+ val namespaces = HashSet()
+ if (files != null) {
+ for (source in files) {
+ if (source != null) {
+ val namespaceDescriptor = context.get(BindingContext.NAMESPACE, source)
+ if (namespaceDescriptor != null) {
+ namespaces.add(namespaceDescriptor)
+ }
+ }
+ }
+ }
+ }
+ }
+ */
+
+ override fun generate() {
+ for (classElement in allClasses) {
+ if (classElement != null) {
+ //val docComment = getDocCommentFor(classElement.sure()) ?: "";
+ val name = classElement?.getName()
+ if (name != null) {
+ println("Found class: ${name}")
+ //model.getClass(name)
+ }
+ }
+ }
+ if (!model.packages.isEmpty()) {
+ val generator = KDocGenerator(model, outputDir)
+ generator.execute()
+ }
+ }
+
+ protected fun getDocCommentFor(psiElement: PsiElement): String? {
+ // This method is a hack. Doc comments should be easily accessible, but they aren't for now.
+ 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 null;
+ if (node?.getElementType() != JetTokens.DOC_COMMENT) return null;
+ return node?.getText();
+ }
+}
+
+class KDocGenerator(val model: KModel, val outputDir: File) {
fun execute(): Unit {
run("allclasses-frame.html", AllClassesFrameTemplate(model, " target=\"classFrame\""))
diff --git a/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/KDocSupport.java b/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/KDocSupport.java
new file mode 100644
index 00000000000..8944f5877a2
--- /dev/null
+++ b/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/KDocSupport.java
@@ -0,0 +1,84 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.doc;
+
+import com.intellij.psi.PsiElement;
+import org.jetbrains.jet.compiler.CompilerPlugin;
+import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
+import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
+import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
+import org.jetbrains.jet.lang.psi.JetFile;
+import org.jetbrains.jet.lang.resolve.BindingContext;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * TODO This class is written in Java for now to work around a few gremlins in Kotlin...
+ */
+public abstract class KDocSupport implements CompilerPlugin {
+ protected Set allNamespaces = new HashSet();
+ protected Set allClasses = new HashSet();
+
+ public void processFiles(BindingContext context, List sources) {
+ for (JetFile source : sources) {
+ // We retrieve a descriptor by a PSI element from the context
+ NamespaceDescriptor namespaceDescriptor = context.get(BindingContext.NAMESPACE, source);
+ if (namespaceDescriptor != null) {
+ allNamespaces.add(namespaceDescriptor);
+ }
+ }
+
+ for (NamespaceDescriptor namespace : allNamespaces) {
+ // Let's take all the declarations in the namespace...
+ processDescriptors(namespace.getMemberScope().getAllDescriptors(), context);
+ }
+
+ generate();
+ }
+
+ protected abstract void generate();
+
+ private void processDescriptors(Collection allDescriptors, BindingContext context) {
+ for (DeclarationDescriptor descriptor : allDescriptors) {
+ PsiElement classElement = context.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
+/*
+ // Print the doc comment text
+ String docComment = getDocCommentFor(classElement);
+ if (docComment != null) {
+ System.out.println("Docs for " + descriptor.getName() + ": " + docComment);
+ }
+ else {
+ System.out.println("No docs for " + descriptor.getName());
+ }
+ // Print the class header (verbose)
+ System.out.println(DescriptorRenderer.TEXT.render(descriptor));
+*/
+ // Process members, if any
+ if (descriptor instanceof ClassDescriptor) {
+ ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
+ if (classElement != null) {
+ allClasses.add(classDescriptor);
+ }
+ //processDescriptors(classDescriptor.getDefaultType().getMemberScope().getAllDescriptors(), context);
+ }
+ }
+ }
+}
diff --git a/kdoc/src/test/kotlin/test/kotlin/doc/ModelTest.kt b/kdoc/src/test/kotlin/test/kotlin/doc/ModelTest.kt
index 9438a0b4ca7..0755772bd26 100644
--- a/kdoc/src/test/kotlin/test/kotlin/doc/ModelTest.kt
+++ b/kdoc/src/test/kotlin/test/kotlin/doc/ModelTest.kt
@@ -9,7 +9,7 @@ import junit.framework.TestCase
// TODO should use the ktest library really for nicer asserts
import junit.framework.Assert.assertEquals
-import org.jetbrains.kotlin.doc.KDocProcessor
+import org.jetbrains.kotlin.doc.KDocGenerator
import java.io.File
class ModelTest : TestCase() {
@@ -56,7 +56,7 @@ class ModelTest : TestCase() {
println()
}
- val processor = KDocProcessor(model, File("target/test-data/ModelTest"))
+ val processor = KDocGenerator(model, File("target/test-data/ModelTest"))
processor.execute()
}
}