/* * Copyright 2006 Google Inc. * * 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 com.google.gwt.user.rebind; import com.google.gwt.core.ext.GeneratorContext; import com.google.gwt.core.ext.TreeLogger; import com.google.gwt.user.rebind.ClassSourceFileComposerFactory.JavaSourceCategory; import java.io.PrintWriter; class ClassSourceFileComposer implements SourceWriter { /** * For the interior of a '*' style comment. */ private static final String STAR_COMMENT_LINE = " * "; private boolean atStart; /** * Either STAR/BLOCK comment line, not pulled out into a ENUM class because * only used by this class. */ private String commentIndicator; private final GeneratorContext ctx; /** * Are you currently in a comment? */ private boolean inComment; private int indent; private final PrintWriter printWriter; ClassSourceFileComposer(GeneratorContext ctx, PrintWriter printWriter, String targetPackageName, String[] annotationDeclarations, String targetClassShortName, String superClassName, String[] interfaceNames, String[] imports, JavaSourceCategory category, String classJavaDocComment) { this.ctx = ctx; this.printWriter = printWriter; if (targetPackageName == null) { throw new IllegalArgumentException("Cannot supply a null package name to" + targetClassShortName); } // TODO: support a user-specified file header if (targetPackageName.length() > 0) { println("package " + targetPackageName + ";"); } if (imports != null && imports.length > 0) { println(); for (int i = 0, n = imports.length; i < n; ++i) { println("import " + imports[i] + ";"); } } if (classJavaDocComment != null) { beginJavaDocComment(); print(classJavaDocComment); endJavaDocComment(); } else { // beginJavaDocComment adds its own leading newline, make up for it here. println(); } for (String annotation : annotationDeclarations) { println(annotation); } if (category == JavaSourceCategory.CLASS) { emitClassDecl(targetClassShortName, superClassName, interfaceNames); } else { emitInterfaceDecl(targetClassShortName, superClassName, interfaceNames); } println(" {"); indent(); } /** * Begin emitting a JavaDoc comment. */ public void beginJavaDocComment() { println("\n/**"); inComment = true; commentIndicator = STAR_COMMENT_LINE; } public void commit(TreeLogger logger) { outdent(); println("}"); printWriter.close(); // If generating a class on the command line, may not have a if (ctx != null) { ctx.commit(logger, printWriter); } } /** * End emitting a JavaDoc comment. */ public void endJavaDocComment() { inComment = false; println("\n */"); } public void indent() { ++indent; } public void indentln(String s) { indent(); println(s); outdent(); } public void indentln(String s, Object... args) { indentln(String.format(s, args)); } public void outdent() { --indent; } public void print(String s) { int pos = 0; for (;;) { // If we just printed a newline, print an indent. if (atStart) { for (int j = 0; j < indent; ++j) { printWriter.print(" "); } if (inComment) { printWriter.print(commentIndicator); } atStart = false; } // Now find the next newline. int nl = s.indexOf('\n', pos); // If there's no newline or it's at the end of the string, just write // the rest of the string, and we're done. if (nl == -1 || nl == s.length() - 1) { printWriter.write(s, pos, s.length() - pos); return; } // Otherwise, write up to and including the newline, note that we just // printed a newline, and loop on the rest of the string. printWriter.write(s, pos, nl + 1 - pos); atStart = true; pos = nl + 1; } } public void print(String s, Object... args) { print(String.format(s, args)); } public void println() { print("\n"); atStart = true; } public void println(String s) { print(s + "\n"); atStart = true; } public void println(String s, Object... args) { println(String.format(s, args)); } private void emitClassDecl(String targetClassShortName, String superClassName, String[] interfaceNames) { print("public class " + targetClassShortName); if (superClassName != null) { print(" extends " + superClassName); } if (interfaceNames != null && interfaceNames.length > 0) { print(" implements "); for (int i = 0, n = interfaceNames.length; i < n; ++i) { if (i > 0) { print(", "); } print(interfaceNames[i]); } } } private void emitInterfaceDecl(String targetClassShortName, String superClassName, String[] interfaceNames) { if (superClassName != null) { throw new IllegalArgumentException("Cannot set superclass name " + superClassName + " on a interface."); } print("public interface " + targetClassShortName); if (interfaceNames != null && interfaceNames.length > 0) { print(" extends "); for (int i = 0; i < interfaceNames.length; ++i) { if (i > 0) { print(", "); } print(interfaceNames[i]); } } } }