All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.groovy.tools.groovydoc.GroovyRootDocBuilder Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2003-2007 the original author or authors.
 *
 * 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.codehaus.groovy.tools.groovydoc;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.Map;

import org.codehaus.groovy.antlr.AntlrASTProcessor;
import org.codehaus.groovy.antlr.SourceBuffer;
import org.codehaus.groovy.antlr.UnicodeEscapingReader;
import org.codehaus.groovy.antlr.java.Groovifier;
import org.codehaus.groovy.antlr.java.Java2GroovyConverter;
import org.codehaus.groovy.antlr.java.JavaLexer;
import org.codehaus.groovy.antlr.java.JavaRecognizer;
import org.codehaus.groovy.antlr.parser.GroovyLexer;
import org.codehaus.groovy.antlr.parser.GroovyRecognizer;
import org.codehaus.groovy.antlr.treewalker.PreOrderTraversal;
import org.codehaus.groovy.antlr.treewalker.SourceCodeTraversal;
import org.codehaus.groovy.antlr.treewalker.Visitor;
import org.codehaus.groovy.groovydoc.GroovyRootDoc;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;


import antlr.RecognitionException;
import antlr.TokenStreamException;
import antlr.collections.AST;

/*
 * todo
 *  comma at the end of method parameters
 *  add comments
 *  static modifier
 *  order methods alphabetically (implement compareTo enough?)
 *  provide links to other html files (e.g. return type of a method)
 */
public class GroovyRootDocBuilder {
	private final GroovyDocTool tool;
	private final String sourcepath;
	private final SimpleGroovyRootDoc rootDoc;
	private static final char FS = '/';

	
	public GroovyRootDocBuilder(GroovyDocTool tool,
			String sourcepath) {
		this.tool = tool;
		this.sourcepath = sourcepath;
		
		this.rootDoc = new SimpleGroovyRootDoc("root");
	}

	
	// parsing
	public Map getClassDocsFromSingleSource(String packagePath, String file, String src) throws RecognitionException, TokenStreamException {
		Map classDocsFromSrc = null;
		if (file.indexOf(".java") > 0) { // simple (for now) decision on java or groovy
			// java
			classDocsFromSrc = parseJava(packagePath, file, src);
		} else if (file.indexOf(".sourcefile") > 0){
			// java (special name used for testing)
			classDocsFromSrc = parseJava(packagePath, file, src);
		} else {
			// not java, try groovy instead :-)
			classDocsFromSrc = parseGroovy(packagePath, file, src);
		}		
		return classDocsFromSrc;
	}

	private Map parseJava(String packagePath, String file, String src) throws RecognitionException, TokenStreamException {
        SourceBuffer sourceBuffer = new SourceBuffer();
        JavaRecognizer parser = getJavaParser(src, sourceBuffer);
        String[] tokenNames = parser.getTokenNames();
        parser.compilationUnit();
        AST ast = parser.getAST();

        // modify the Java AST into a Groovy AST (just token types)
		Visitor java2groovyConverter = new Java2GroovyConverter(tokenNames);
        AntlrASTProcessor java2groovyTraverser = new PreOrderTraversal(java2groovyConverter);
        java2groovyTraverser.process(ast);

        // now mutate (groovify) the ast into groovy
		Visitor groovifier = new Groovifier(tokenNames);
        AntlrASTProcessor groovifierTraverser = new PreOrderTraversal(groovifier);
        groovifierTraverser.process(ast);

        
        // now do the business     
        Visitor visitor = new SimpleGroovyClassDocAssembler(packagePath, file, sourceBuffer);
        AntlrASTProcessor traverser = new SourceCodeTraversal(visitor);

        traverser.process(ast);
        
        return ((SimpleGroovyClassDocAssembler) visitor).getGroovyClassDocs();
	}
	
	private Map parseGroovy(String packagePath, String file, String src) throws RecognitionException, TokenStreamException {
        SourceBuffer sourceBuffer = new SourceBuffer();
        GroovyRecognizer parser = getGroovyParser(src, sourceBuffer);
        String[] tokenNames = parser.getTokenNames();
        parser.compilationUnit();
        AST ast = parser.getAST();

        // now do the business     
        Visitor visitor = new SimpleGroovyClassDocAssembler(packagePath, file, sourceBuffer);
        AntlrASTProcessor traverser = new SourceCodeTraversal(visitor);

        traverser.process(ast);
        
        return ((SimpleGroovyClassDocAssembler) visitor).getGroovyClassDocs();
	}
	
	private JavaRecognizer getJavaParser(String input, SourceBuffer sourceBuffer) {
		JavaRecognizer parser = null;
        UnicodeEscapingReader unicodeReader = new UnicodeEscapingReader(new StringReader(input),sourceBuffer);
        JavaLexer lexer = new JavaLexer(unicodeReader);
        unicodeReader.setLexer(lexer);
        parser = JavaRecognizer.make(lexer);
        parser.setSourceBuffer(sourceBuffer);
		return parser;
	}

	private GroovyRecognizer getGroovyParser(String input, SourceBuffer sourceBuffer) {
		GroovyRecognizer parser = null;
        UnicodeEscapingReader unicodeReader = new UnicodeEscapingReader(new StringReader(input),sourceBuffer);
        GroovyLexer lexer = new GroovyLexer(unicodeReader);
        unicodeReader.setLexer(lexer);
        parser = GroovyRecognizer.make(lexer);
        parser.setSourceBuffer(sourceBuffer);
		return parser;
	}

	public void buildTree(String filename) throws IOException, RecognitionException, TokenStreamException {
		String srcFileName = sourcepath + FS + filename;
		String src = DefaultGroovyMethods.getText(new File(srcFileName));

		String packagePath = tool.getPath(filename);
		packagePath = packagePath.replace('\\', FS);
		String file = tool.getFile(filename);
		try {
			Map classDocs = getClassDocsFromSingleSource(packagePath, file, src);
		
			rootDoc.putAllClasses(classDocs);

			SimpleGroovyPackageDoc packageDoc = (SimpleGroovyPackageDoc) rootDoc.packageNamed(packagePath);
			if (packageDoc == null) {
				packageDoc = new SimpleGroovyPackageDoc(packagePath);
			}
			packageDoc.putAll(classDocs);		
			rootDoc.put(packagePath, packageDoc);
		} catch (RecognitionException e) {
			System.out.println("ignored due to RecognitionException: " + filename);
		} catch (TokenStreamException e) {
			System.out.println("ignored due to TokenStreamException: " + filename);
		}
	}


	public GroovyRootDoc getRootDoc() {
		rootDoc.resolve();
		
		return rootDoc;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy