156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson/* 256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Copyright (C) 2010 Google Inc. 356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Licensed under the Apache License, Version 2.0 (the "License"); 556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * you may not use this file except in compliance with the License. 656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * You may obtain a copy of the License at 756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * http://www.apache.org/licenses/LICENSE-2.0 956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 1056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Unless required by applicable law or agreed to in writing, software 1156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * distributed under the License is distributed on an "AS IS" BASIS, 1256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * See the License for the specific language governing permissions and 1456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * limitations under the License. 1556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 1656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 1756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonpackage com.google.clearsilver.jsilver.compiler; 1856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 1956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport java.io.Closeable; 2056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport java.io.Flushable; 2156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport java.io.PrintWriter; 2256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport java.io.Writer; 2356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport java.lang.reflect.Method; 2456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport java.lang.reflect.Modifier; 2556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 2656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson/** 2756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Simple API for generating Java source code. Easier than lots of string manipulation. 2856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 2956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * <h3>Example</h3> 3056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 3156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * <pre> 3256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * java = new JavaSourceWriter(out); 3356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 3456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * java.writeComment("// Auto generated file"); 3556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * java.writePackage("com.something.mypackage"); 3656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * java.writeImports(SomeClassToImport.class, Another.class); 3756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 3856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * java.startClass("SomeClass", "InterfaceA"); 3956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * java.startMethod(Object.class.getMethod("toString")); 4056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * java.writeStatement(call("System.out.println", string("hello"))); 4156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * java.endClass(); 4256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * </pre> 4356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 4456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Note: For writing statements/expressions, staticly import the methods on {@link JavaExpression}. 4556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 4656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonpublic class JavaSourceWriter implements Closeable, Flushable { 4756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 4856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private final PrintWriter out; 4956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private int indent; 5056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 5156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public JavaSourceWriter(Writer out) { 5256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson this.out = new PrintWriter(out); 5356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 5456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 5556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void writePackage(String packageName) { 5656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // TODO: Verify packageName is valid. 5756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (packageName != null) { 5856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startLine(); 5956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append("package ").append(packageName).append(';'); 6056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson endLine(); 6156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson emptyLine(); 6256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 6356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 6456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 6556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void writeImports(Class... javaClasses) { 6656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson for (Class javaClass : javaClasses) { 6756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startLine(); 6856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append("import ").append(javaClass.getName()).append(';'); 6956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson endLine(); 7056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 7156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (javaClasses.length > 0) { 7256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson emptyLine(); 7356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 7456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 7556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 7656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void writeComment(String comment) { 7756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // TODO: Handle line breaks in comments. 7856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startLine(); 7956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append("// ").append(comment); 8056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson endLine(); 8156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 8256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 8356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void startClass(String className, String baseClassName, String... interfaceNames) { 8456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startLine(); 8556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append("public class "); 8656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson writeJavaSymbol(out, className); 8756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 8856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (baseClassName != null) { 8956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(" extends "); 9056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson writeJavaSymbol(out, baseClassName); 9156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 9256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 9356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson boolean seenAnyInterfaces = false; 9456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson for (String interfaceName : interfaceNames) { 9556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (!seenAnyInterfaces) { 9656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson seenAnyInterfaces = true; 9756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(" implements "); 9856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } else { 9956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(", "); 10056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 10156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson writeJavaSymbol(out, interfaceName); 10256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 10356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 10456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(' '); 10556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startBlock(); 10656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson emptyLine(); 10756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 10856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 10956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void startAnonymousClass(String baseClass, JavaExpression... constructorArgs) { 11056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append("new "); 11156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson writeJavaSymbol(out, baseClass); 11256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append('('); 11356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 11456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson boolean seenAnyArgs = false; 11556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson for (JavaExpression constructorArg : constructorArgs) { 11656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (seenAnyArgs) { 11756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(", "); 11856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 11956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson seenAnyArgs = true; 12056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson constructorArg.write(out); 12156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 12256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 12356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(") "); 12456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startBlock(); 12556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson emptyLine(); 12656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 12756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 12856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void endAnonymousClass() { 12956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson endBlock(); 13056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 13156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 13256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 13356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Start a method. The signature is based on that of an existing method. 13456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 13556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void startMethod(Method method, String... paramNames) { 13656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // This currently does not support generics, varargs or arrays. 13756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // If you need it - add the support. Don't want to overcomplicate it 13856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // until necessary. 13956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 14056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (paramNames.length != method.getParameterTypes().length) { 14156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson throw new IllegalArgumentException("Did not specifiy correct " 14256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson + "number of parameter names for method signature " + method); 14356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 14456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 14556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startLine(); 14656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 14756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // @Override abstract methods. 14856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson int modifiers = method.getModifiers(); 14956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (Modifier.isAbstract(modifiers)) { 15056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append("@Override"); 15156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson endLine(); 15256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startLine(); 15356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 15456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 15556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // Modifiers: (public, protected, static) 15656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (modifiers != 0) { 15756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // Modifiers we care about. Ditch the rest. Specifically NOT ABSTRACT. 15856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson modifiers &= Modifier.PUBLIC | Modifier.PROTECTED | Modifier.STATIC; 15956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(Modifier.toString(modifiers)).append(' '); 16056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 16156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 16256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // Return type and name: (e.g. "void doStuff(") 16356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(method.getReturnType().getSimpleName()).append(' ').append(method.getName()).append( 16456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson '('); 16556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 16656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // Parameters. 16756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson int paramIndex = 0; 16856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson for (Class<?> paramType : method.getParameterTypes()) { 16956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (paramIndex > 0) { 17056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(", "); 17156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 17256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson writeJavaSymbol(out, paramType.getSimpleName()); 17356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(' '); 17456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson writeJavaSymbol(out, paramNames[paramIndex]); 17556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson paramIndex++; 17656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 17756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 17856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(')'); 17956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 18056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // Exceptions thrown. 18156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson boolean seenAnyExceptions = false; 18256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson for (Class exception : method.getExceptionTypes()) { 18356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (!seenAnyExceptions) { 18456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson seenAnyExceptions = true; 18556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson endLine(); 18656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startLine(); 18756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(" throws "); 18856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } else { 18956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(", "); 19056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 19156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson writeJavaSymbol(out, exception.getSimpleName()); 19256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 19356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 19456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(' '); 19556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startBlock(); 19656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 19756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 19856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void startIfBlock(JavaExpression expression) { 19956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startLine(); 20056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append("if ("); 20156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson writeExpression(expression); 20256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(") "); 20356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startBlock(); 20456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 20556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 20656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void endIfStartElseBlock() { 20756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson endBlock(); 20856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(" else "); 20956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startBlock(); 21056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 21156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 21256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void endIfBlock() { 21356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson endBlock(); 21456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson endLine(); 21556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 21656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 21756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void startScopedBlock() { 21856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startLine(); 21956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startBlock(); 22056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 22156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 22256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void endScopedBlock() { 22356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson endBlock(); 22456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson endLine(); 22556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 22656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 22756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void startIterableForLoop(String type, String name, JavaExpression expression) { 22856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startLine(); 22956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append("for ("); 23056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson writeJavaSymbol(out, type); 23156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(' '); 23256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson writeJavaSymbol(out, name); 23356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(" : "); 23456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson writeExpression(expression); 23556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(") "); 23656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startBlock(); 23756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 23856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 23956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void startForLoop(JavaExpression start, JavaExpression end, JavaExpression increment) { 24056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startLine(); 24156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append("for ("); 24256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson writeExpression(start); 24356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append("; "); 24456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson writeExpression(end); 24556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append("; "); 24656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson writeExpression(increment); 24756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(") "); 24856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startBlock(); 24956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 25056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 25156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void endLoop() { 25256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson endBlock(); 25356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson endLine(); 25456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 25556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 25656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void writeStatement(JavaExpression expression) { 25756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startLine(); 25856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson writeExpression(expression); 25956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(';'); 26056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson endLine(); 26156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 26256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 26356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void writeExpression(JavaExpression expression) { 26456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson expression.write(out); 26556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 26656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 26756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void endMethod() { 26856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson endBlock(); 26956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson endLine(); 27056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson emptyLine(); 27156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 27256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 27356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void endClass() { 27456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson endBlock(); 27556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson endLine(); 27656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson emptyLine(); 27756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 27856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 27956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson @Override 28056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void flush() { 28156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.flush(); 28256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 28356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 28456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson @Override 28556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void close() { 28656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.close(); 28756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 28856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 28956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private void startBlock() { 29056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append('{'); 29156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson endLine(); 29256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson indent++; 29356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 29456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 29556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private void endBlock() { 29656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson indent--; 29756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startLine(); 29856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append('}'); 29956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 30056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 30156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private void startLine() { 30256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson for (int i = 0; i < indent; i++) { 30356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(" "); 30456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 30556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 30656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 30756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private void endLine() { 30856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append('\n'); 30956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 31056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 31156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private void emptyLine() { 31256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append('\n'); 31356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 31456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 31556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public static void writeJavaSymbol(PrintWriter out, String symbol) { 31656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(symbol); // TODO Make safe and validate. 31756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 31856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 31956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void startField(String type, JavaExpression name) { 32056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson startLine(); 32156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append("private final "); 32256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson writeJavaSymbol(out, type); 32356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(' '); 32456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson name.write(out); 32556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(" = "); 32656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 32756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 32856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void endField() { 32956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson out.append(';'); 33056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson endLine(); 33156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson emptyLine(); 33256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 33356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 33456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson} 335