0001: /**
0002: *
0003: * Copyright 2005 Jeremy Rayner
0004: *
0005: * Licensed under the Apache License, Version 2.0 (the "License");
0006: * you may not use this file except in compliance with the License.
0007: * You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: *
0017: **/package org.codehaus.groovy.antlr.treewalker;
0018:
0019: import java.io.PrintStream;
0020: import java.util.Stack;
0021:
0022: import org.codehaus.groovy.antlr.GroovySourceAST;
0023: import org.codehaus.groovy.antlr.parser.GroovyTokenTypes;
0024:
0025: /**
0026: * An antlr AST visitor that prints groovy source code for each visited node
0027: * to the supplied PrintStream.
0028: *
0029: * @author <a href="mailto:groovy@ross-rayner.com">Jeremy Rayner</a>
0030: * @version $Revision: 4538 $
0031: */
0032:
0033: public class SourcePrinter extends VisitorAdapter {
0034: private String[] tokenNames;
0035: private int tabLevel;
0036: private int lastLinePrinted;
0037: private boolean newLines;
0038: protected PrintStream out;
0039: private String className;
0040: private Stack stack;
0041: private int stringConstructorCounter;
0042:
0043: /**
0044: * A visitor that prints groovy source code for each node visited.
0045: * @param out where to print the source code to
0046: * @param tokenNames an array of token names from antlr
0047: */
0048: public SourcePrinter(PrintStream out, String[] tokenNames) {
0049: this (out, tokenNames, true);
0050: }
0051:
0052: /**
0053: * A visitor that prints groovy source code for each node visited.
0054: * @param out where to print the source code to
0055: * @param tokenNames an array of token names from antlr
0056: * @param newLines output newline character
0057: */
0058: public SourcePrinter(PrintStream out, String[] tokenNames,
0059: boolean newLines) {
0060: this .tokenNames = tokenNames;
0061: tabLevel = 0;
0062: lastLinePrinted = 0;
0063: this .out = out;
0064: this .newLines = newLines;
0065: this .stack = new Stack();
0066: }
0067:
0068: public void visitAbstract(GroovySourceAST t, int visit) {
0069: print(t, visit, "abstract ", null, null);
0070: }
0071:
0072: public void visitAnnotation(GroovySourceAST t, int visit) {
0073: if (visit == OPENING_VISIT) {
0074: print(t, visit, "@");
0075: }
0076: if (visit == SECOND_VISIT) {
0077: print(t, visit, "(");
0078: }
0079: if (visit == SUBSEQUENT_VISIT) {
0080: print(t, visit, ", ");
0081: }
0082: if (visit == CLOSING_VISIT) {
0083: if (t.getNumberOfChildren() > 1) {
0084: print(t, visit, ") ");
0085: } else {
0086: print(t, visit, " ");
0087: }
0088: }
0089:
0090: }
0091:
0092: public void visitAnnotations(GroovySourceAST t, int visit) {
0093: // do nothing
0094: }
0095:
0096: public void visitAnnotationDef(GroovySourceAST t, int visit) {
0097: print(t, visit, "@interface ", null, null);
0098: }
0099:
0100: public void visitAnnotationFieldDef(GroovySourceAST t, int visit) {
0101: print(t, visit, "() ", "default ", null);
0102: }
0103:
0104: public void visitAnnotationMemberValuePair(GroovySourceAST t,
0105: int visit) {
0106: print(t, visit, " = ", null, null);
0107: }
0108:
0109: public void visitArrayDeclarator(GroovySourceAST t, int visit) {
0110: //<ARRAY_DECLARATOR>int</ARRAY_DECLARATOR> primes = new int(<ARRAY_DECLARATOR>5</ARRAY_DECLARATOR>)
0111: if (getParentNode().getType() == GroovyTokenTypes.TYPE
0112: || getParentNode().getType() == GroovyTokenTypes.TYPECAST) { // ugly hack
0113: // type defintion, i.e. int[] x;
0114: print(t, visit, null, null, "[]");
0115: } else {
0116: // usually in new, i.e. def y = new int[5];
0117: print(t, visit, "[", null, "]");
0118: }
0119: }
0120:
0121: public void visitAssign(GroovySourceAST t, int visit) {
0122: print(t, visit, " = ", null, null);
0123: }
0124:
0125: // visitAt() ...
0126: // token type 'AT' should never be visited, as annotation definitions and usage, and
0127: // direct field access should have all moved this token out of the way. No test needed.
0128:
0129: // one of the BAND tokens is actually replaced by TYPE_UPPER_BOUNDS (e.g. class Foo<T extends C & I> {T t} )
0130: public void visitBand(GroovySourceAST t, int visit) {
0131: print(t, visit, " & ", null, null);
0132: }
0133:
0134: public void visitBandAssign(GroovySourceAST t, int visit) {
0135: print(t, visit, " &= ", null, null);
0136: }
0137:
0138: // visitBigSuffix() ...
0139: // token type BIG_SUFFIX never created/visited, NUM_BIG_INT, NUM_BIG_DECIMAL instead...
0140:
0141: // visitBlock() ...
0142: // token type BLOCK never created/visited, see CLOSABLE_BLOCK etc...
0143:
0144: public void visitBnot(GroovySourceAST t, int visit) {
0145: print(t, visit, "~", null, null);
0146: }
0147:
0148: // Note: old closure syntax using BOR is deprecated, and also never creates/visits a BOR node
0149: public void visitBor(GroovySourceAST t, int visit) {
0150: print(t, visit, " | ", null, null);
0151: }
0152:
0153: public void visitBorAssign(GroovySourceAST t, int visit) {
0154: print(t, visit, " |= ", null, null);
0155: }
0156:
0157: public void visitBsr(GroovySourceAST t, int visit) {
0158: print(t, visit, " >>> ", null, null);
0159: }
0160:
0161: public void visitBsrAssign(GroovySourceAST t, int visit) {
0162: print(t, visit, " >>>= ", null, null);
0163: }
0164:
0165: public void visitBxor(GroovySourceAST t, int visit) {
0166: print(t, visit, " ^ ", null, null);
0167: }
0168:
0169: public void visitBxorAssign(GroovySourceAST t, int visit) {
0170: print(t, visit, " ^= ", null, null);
0171: }
0172:
0173: public void visitCaseGroup(GroovySourceAST t, int visit) {
0174: if (visit == OPENING_VISIT) {
0175: tabLevel++;
0176: }
0177: if (visit == CLOSING_VISIT) {
0178: tabLevel--;
0179: }
0180: }
0181:
0182: public void visitClassDef(GroovySourceAST t, int visit) {
0183: print(t, visit, "class ", null, null);
0184:
0185: if (visit == OPENING_VISIT) {
0186: // store name of class away for use in constructor ident
0187: className = t.childOfType(GroovyTokenTypes.IDENT).getText();
0188: }
0189: }
0190:
0191: public void visitClosedBlock(GroovySourceAST t, int visit) {
0192: printUpdatingTabLevel(t, visit, "{", "-> ", "}");
0193: }
0194:
0195: // visitClosureOp ...
0196: // token type CLOSABLE_BLOCK_OP never created/visited, see CLOSABLE_BLOCK...
0197:
0198: // visitColon ...
0199: // token type COLON never created/visited, see LABELED_STAT, FOR_IN_ITERABLE,
0200: // ASSERT, CASE, QUESTION, MAP_CONSTRUCTOR, LABELED_ARG, SPREAD_MAP_ARG
0201:
0202: // visitComma ...
0203: // token type COMMA never created/visited,
0204: // see TYPE_ARGUMENTS, ANNOTATION, many others ...
0205:
0206: public void visitCompareTo(GroovySourceAST t, int visit) {
0207: print(t, visit, " <=> ", null, null);
0208: }
0209:
0210: public void visitCtorCall(GroovySourceAST t, int visit) {
0211: printUpdatingTabLevel(t, visit, "this(", " ", ")");
0212: }
0213:
0214: public void visitCtorIdent(GroovySourceAST t, int visit) {
0215: // use name of class for constructor from the class definition
0216: print(t, visit, className, null, null);
0217: }
0218:
0219: public void visitDec(GroovySourceAST t, int visit) {
0220: print(t, visit, "--", null, null);
0221: }
0222:
0223: // visitDigit ...
0224: // never created/visited
0225:
0226: public void visitDiv(GroovySourceAST t, int visit) {
0227: print(t, visit, " / ", null, null);
0228: }
0229:
0230: public void visitDivAssign(GroovySourceAST t, int visit) {
0231: print(t, visit, " /= ", null, null);
0232: }
0233:
0234: // visitDollar ...
0235: // token type DOLLAR never created/visited, see SCOPE_ESCAPE instead
0236:
0237: public void visitDot(GroovySourceAST t, int visit) {
0238: print(t, visit, ".", null, null);
0239: }
0240:
0241: public void visitDynamicMember(GroovySourceAST t, int visit) {
0242: if (t.childOfType(GroovyTokenTypes.STRING_CONSTRUCTOR) == null) {
0243: printUpdatingTabLevel(t, visit, "(", null, ")");
0244: }
0245: }
0246:
0247: public void visitElist(GroovySourceAST t, int visit) {
0248: if (getParentNode().getType() == GroovyTokenTypes.ENUM_CONSTANT_DEF) {
0249: print(t, visit, "(", ", ", ")");
0250: } else {
0251: print(t, visit, null, ", ", null);
0252: }
0253: }
0254:
0255: // visitEmptyStat ...
0256: // token type EMPTY_STAT obsolete and should be removed, never visited/created
0257:
0258: public void visitEnumConstantDef(GroovySourceAST t, int visit) {
0259: GroovySourceAST sibling = (GroovySourceAST) t.getNextSibling();
0260: if (sibling != null
0261: && sibling.getType() == GroovyTokenTypes.ENUM_CONSTANT_DEF) {
0262: print(t, visit, null, null, ", ");
0263: }
0264: }
0265:
0266: public void visitEnumDef(GroovySourceAST t, int visit) {
0267: print(t, visit, "enum ", null, null);
0268: }
0269:
0270: // visitEof ...
0271: // token type EOF never visited/created
0272:
0273: public void visitEqual(GroovySourceAST t, int visit) {
0274: print(t, visit, " == ", null, null);
0275: }
0276:
0277: // visitExponent ...
0278: // token type EXPONENT only used by lexer, never visited/created
0279:
0280: public void visitExpr(GroovySourceAST t, int visit) {
0281: // do nothing
0282: }
0283:
0284: public void visitExtendsClause(GroovySourceAST t, int visit) {
0285: if (visit == OPENING_VISIT) {
0286: if (t.getNumberOfChildren() != 0) {
0287: print(t, visit, " extends ");
0288: }
0289: }
0290: }
0291:
0292: public void visitFinal(GroovySourceAST t, int visit) {
0293: print(t, visit, "final ", null, null);
0294: }
0295:
0296: // visitFloatSuffix ... never visited/created see NUM_DOUBLE or NUM_FLOAT instead
0297:
0298: public void visitForCondition(GroovySourceAST t, int visit) {
0299: print(t, visit, " ; ", null, null);
0300: }
0301:
0302: // visitForEachClause ...
0303: // FOR_EACH_CLAUSE obsolete and should be removed, never visited/created
0304:
0305: public void visitForInit(GroovySourceAST t, int visit) {
0306: print(t, visit, "(", null, null);
0307: }
0308:
0309: public void visitForInIterable(GroovySourceAST t, int visit) {
0310: printUpdatingTabLevel(t, visit, "(", " in ", ") ");
0311: }
0312:
0313: public void visitForIterator(GroovySourceAST t, int visit) {
0314: print(t, visit, " ; ", null, ")");
0315: }
0316:
0317: public void visitGe(GroovySourceAST t, int visit) {
0318: print(t, visit, " >= ", null, null);
0319: }
0320:
0321: public void visitGt(GroovySourceAST t, int visit) {
0322: print(t, visit, " > ", null, null);
0323: }
0324:
0325: public void visitIdent(GroovySourceAST t, int visit) {
0326: print(t, visit, t.getText(), null, null);
0327: }
0328:
0329: public void visitImplementsClause(GroovySourceAST t, int visit) {
0330: if (visit == OPENING_VISIT) {
0331: if (t.getNumberOfChildren() != 0) {
0332: print(t, visit, " implements ");
0333: }
0334: }
0335: if (visit == CLOSING_VISIT) {
0336: //space between classdef and objblock
0337: print(t, visit, " ");
0338: }
0339: }
0340:
0341: public void visitImplicitParameters(GroovySourceAST t, int visit) {
0342: // do nothing
0343: }
0344:
0345: public void visitImport(GroovySourceAST t, int visit) {
0346: print(t, visit, "import ", null, null);
0347: }
0348:
0349: public void visitInc(GroovySourceAST t, int visit) {
0350: print(t, visit, "++", null, null);
0351: }
0352:
0353: public void visitIndexOp(GroovySourceAST t, int visit) {
0354: printUpdatingTabLevel(t, visit, "[", null, "]");
0355: }
0356:
0357: public void visitInterfaceDef(GroovySourceAST t, int visit) {
0358: print(t, visit, "interface ", null, null);
0359: }
0360:
0361: public void visitInstanceInit(GroovySourceAST t, int visit) {
0362: // do nothing
0363: }
0364:
0365: public void visitLabeledArg(GroovySourceAST t, int visit) {
0366: print(t, visit, ":", null, null);
0367: }
0368:
0369: public void visitLabeledStat(GroovySourceAST t, int visit) {
0370: print(t, visit, ":", null, null);
0371: }
0372:
0373: public void visitLand(GroovySourceAST t, int visit) {
0374: print(t, visit, " && ", null, null);
0375: }
0376:
0377: // visit lbrack()
0378: // token type LBRACK only used inside parser, never visited/created
0379:
0380: // visit lcurly()
0381: // token type LCURLY only used inside parser, never visited/created
0382:
0383: public void visitLe(GroovySourceAST t, int visit) {
0384: print(t, visit, " <= ", null, null);
0385: }
0386:
0387: // visitLetter ...
0388: // token type LETTER only used by lexer, never visited/created
0389:
0390: public void visitListConstructor(GroovySourceAST t, int visit) {
0391: printUpdatingTabLevel(t, visit, "[", null, "]");
0392: }
0393:
0394: public void visitLiteralAny(GroovySourceAST t, int visit) {
0395: print(t, visit, "any", null, null);
0396: }
0397:
0398: public void visitLiteralAs(GroovySourceAST t, int visit) {
0399: print(t, visit, " as ", null, null);
0400: }
0401:
0402: public void visitLiteralAssert(GroovySourceAST t, int visit) {
0403: if (t.getNumberOfChildren() > 1) {
0404: print(t, visit, "assert ", null, " : ");
0405: } else {
0406: print(t, visit, "assert ", null, null);
0407: }
0408: }
0409:
0410: public void visitLiteralBoolean(GroovySourceAST t, int visit) {
0411: print(t, visit, "boolean", null, null);
0412: }
0413:
0414: public void visitLiteralBreak(GroovySourceAST t, int visit) {
0415: print(t, visit, "break ", null, null);
0416: }
0417:
0418: public void visitLiteralByte(GroovySourceAST t, int visit) {
0419: print(t, visit, "byte", null, null);
0420: }
0421:
0422: public void visitLiteralCase(GroovySourceAST t, int visit) {
0423: print(t, visit, "case ", null, ":");
0424: }
0425:
0426: public void visitLiteralCatch(GroovySourceAST t, int visit) {
0427: printUpdatingTabLevel(t, visit, " catch (", null, ") ");
0428: }
0429:
0430: public void visitLiteralChar(GroovySourceAST t, int visit) {
0431: print(t, visit, "char", null, null);
0432: }
0433:
0434: // visitLiteralClass ...
0435: // token type "class" only used by parser, never visited/created directly
0436:
0437: public void visitLiteralContinue(GroovySourceAST t, int visit) {
0438: print(t, visit, "continue ", null, null);
0439: }
0440:
0441: // visitLiteralDef ...
0442: // token type "def" only used by parser, never visited/created directly
0443:
0444: public void visitLiteralDefault(GroovySourceAST t, int visit) {
0445: print(t, visit, "default", null, ":");
0446: }
0447:
0448: public void visitLiteralDouble(GroovySourceAST t, int visit) {
0449: print(t, visit, "double", null, null);
0450: }
0451:
0452: // visitLiteralElse ...
0453: // token type "else" only used by parser, never visited/created directly
0454:
0455: // visitLiteralEnum ...
0456: // token type "enum" only used by parser, never visited/created directly
0457:
0458: // visitLiteralExtends
0459: // token type "extends" only used by parser, never visited/created directly
0460:
0461: public void visitLiteralFalse(GroovySourceAST t, int visit) {
0462: print(t, visit, "false", null, null);
0463: }
0464:
0465: public void visitLiteralFinally(GroovySourceAST t, int visit) {
0466: print(t, visit, "finally ", null, null);
0467: }
0468:
0469: public void visitLiteralFloat(GroovySourceAST t, int visit) {
0470: print(t, visit, "float", null, null);
0471: }
0472:
0473: public void visitLiteralFor(GroovySourceAST t, int visit) {
0474: print(t, visit, "for ", null, null);
0475: }
0476:
0477: public void visitLiteralIf(GroovySourceAST t, int visit) {
0478: // slightly strange as subsequent visit is done after closing visit
0479: printUpdatingTabLevel(t, visit, "if (", " else ", ") ");
0480: }
0481:
0482: // visitLiteralImplements
0483: // token type "implements" only used by parser, never visited/created directly
0484:
0485: // visitLiteralImport
0486: // token type "import" only used by parser, never visited/created directly
0487:
0488: public void visitLiteralIn(GroovySourceAST t, int visit) {
0489: print(t, visit, " in ", null, null);
0490: }
0491:
0492: public void visitLiteralInstanceof(GroovySourceAST t, int visit) {
0493: print(t, visit, " instanceof ", null, null);
0494: }
0495:
0496: public void visitLiteralInt(GroovySourceAST t, int visit) {
0497: print(t, visit, "int", null, null);
0498: }
0499:
0500: // visitLiteralInterface
0501: // token type "interface" only used by parser, never visited/created directly
0502:
0503: public void visitLiteralLong(GroovySourceAST t, int visit) {
0504: print(t, visit, "long", null, null);
0505: }
0506:
0507: public void visitLiteralNative(GroovySourceAST t, int visit) {
0508: print(t, visit, "native ", null, null);
0509: }
0510:
0511: public void visitLiteralNew(GroovySourceAST t, int visit) {
0512: if (t.childOfType(GroovyTokenTypes.ARRAY_DECLARATOR) == null) {
0513: // only print parenthesis if is not of form def x = new int[5]
0514: print(t, visit, "new ", "(", ")");
0515: } else {
0516: print(t, visit, "new ", null, null);
0517: }
0518: }
0519:
0520: public void visitLiteralNull(GroovySourceAST t, int visit) {
0521: print(t, visit, "null", null, null);
0522: }
0523:
0524: // visitLiteralPackage
0525: // token type "package" only used by parser, never visited/created directly
0526:
0527: public void visitLiteralPrivate(GroovySourceAST t, int visit) {
0528: print(t, visit, "private ", null, null);
0529: }
0530:
0531: public void visitLiteralProtected(GroovySourceAST t, int visit) {
0532: print(t, visit, "protected ", null, null);
0533: }
0534:
0535: public void visitLiteralPublic(GroovySourceAST t, int visit) {
0536: print(t, visit, "public ", null, null);
0537: }
0538:
0539: public void visitLiteralReturn(GroovySourceAST t, int visit) {
0540: print(t, visit, "return ", null, null);
0541: }
0542:
0543: public void visitLiteralShort(GroovySourceAST t, int visit) {
0544: print(t, visit, "short", null, null);
0545: }
0546:
0547: public void visitLiteralStatic(GroovySourceAST t, int visit) {
0548: print(t, visit, "static ", null, null);
0549: }
0550:
0551: public void visitLiteralSuper(GroovySourceAST t, int visit) {
0552: // only visited when calling super() without parentheses, i.e. "super 99" is equivalent to "super(99)"
0553: print(t, visit, "super", null, null);
0554: }
0555:
0556: public void visitLiteralSwitch(GroovySourceAST t, int visit) {
0557: if (visit == OPENING_VISIT) {
0558: print(t, visit, "switch (");
0559: tabLevel++;
0560: }
0561: if (visit == SUBSEQUENT_VISIT) {
0562: print(t, visit, ") {");
0563: }
0564: if (visit == CLOSING_VISIT) {
0565: tabLevel--;
0566: print(t, visit, "}");
0567: }
0568: }
0569:
0570: public void visitLiteralSynchronized(GroovySourceAST t, int visit) {
0571: if (t.getNumberOfChildren() > 0) {
0572: print(t, visit, "synchronized (", null, ") ");
0573: } else {
0574: print(t, visit, "synchronized ", null, null);
0575: }
0576: }
0577:
0578: public void visitLiteralThis(GroovySourceAST t, int visit) {
0579: print(t, visit, "this", null, null);
0580: }
0581:
0582: public void visitLiteralThreadsafe(GroovySourceAST t, int visit) {
0583: print(t, visit, "threadsafe ", null, null);
0584: }
0585:
0586: public void visitLiteralThrow(GroovySourceAST t, int visit) {
0587: print(t, visit, "throw ", null, null);
0588: }
0589:
0590: public void visitLiteralThrows(GroovySourceAST t, int visit) {
0591: print(t, visit, "throws ", null, null);
0592: }
0593:
0594: public void visitLiteralTransient(GroovySourceAST t, int visit) {
0595: print(t, visit, "transient ", null, null);
0596: }
0597:
0598: public void visitLiteralTrue(GroovySourceAST t, int visit) {
0599: print(t, visit, "true", null, null);
0600: }
0601:
0602: public void visitLiteralTry(GroovySourceAST t, int visit) {
0603: print(t, visit, "try ", null, null);
0604: }
0605:
0606: public void visitLiteralVoid(GroovySourceAST t, int visit) {
0607: print(t, visit, "void", null, null);
0608: }
0609:
0610: public void visitLiteralVolatile(GroovySourceAST t, int visit) {
0611: print(t, visit, "volatile ", null, null);
0612: }
0613:
0614: public void visitLiteralWhile(GroovySourceAST t, int visit) {
0615: printUpdatingTabLevel(t, visit, "while (", null, ") ");
0616: }
0617:
0618: public void visitLiteralWith(GroovySourceAST t, int visit) {
0619: printUpdatingTabLevel(t, visit, "with (", null, ") ");
0620: }
0621:
0622: public void visitLnot(GroovySourceAST t, int visit) {
0623: print(t, visit, "!", null, null);
0624: }
0625:
0626: // Note: old closure syntax using LOR is deprecated, and also never creates/visits a LOR node
0627: public void visitLor(GroovySourceAST t, int visit) {
0628: print(t, visit, " || ", null, null);
0629: }
0630:
0631: public void visitLt(GroovySourceAST t, int visit) {
0632: print(t, visit, " < ", null, null);
0633: }
0634:
0635: public void visitMapConstructor(GroovySourceAST t, int visit) {
0636: if (t.getNumberOfChildren() == 0) {
0637: print(t, visit, "[:]", null, null);
0638: } else {
0639: printUpdatingTabLevel(t, visit, "[", null, "]");
0640: }
0641: }
0642:
0643: public void visitMemberPointer(GroovySourceAST t, int visit) {
0644: print(t, visit, ".&", null, null);
0645: }
0646:
0647: public void visitMethodCall(GroovySourceAST t, int visit) {
0648: if ("<command>".equals(t.getText())) {
0649: printUpdatingTabLevel(t, visit, " ", " ", null);
0650: } else {
0651: printUpdatingTabLevel(t, visit, "(", " ", ")");
0652: }
0653: }
0654:
0655: public void visitMethodDef(GroovySourceAST t, int visit) {
0656: //do nothing
0657: }
0658:
0659: public void visitMinus(GroovySourceAST t, int visit) {
0660: print(t, visit, " - ", null, null);
0661: }
0662:
0663: public void visitMinusAssign(GroovySourceAST t, int visit) {
0664: print(t, visit, " -= ", null, null);
0665: }
0666:
0667: // visitMlComment
0668: // multi-line comments are not created on the AST currently.
0669:
0670: public void visitMod(GroovySourceAST t, int visit) {
0671: print(t, visit, " % ", null, null);
0672: }
0673:
0674: public void visitModifiers(GroovySourceAST t, int visit) {
0675: //do nothing
0676: }
0677:
0678: public void visitModAssign(GroovySourceAST t, int visit) {
0679: print(t, visit, " %= ", null, null);
0680: }
0681:
0682: // visitNls
0683: // new lines are used by parser, but are not created on the AST,
0684: // they can be implied by the source code line/column information
0685:
0686: // visitNullTreeLookahead
0687: // not used explicitly by parser.
0688:
0689: public void visitNotEqual(GroovySourceAST t, int visit) {
0690: print(t, visit, " != ", null, null);
0691: }
0692:
0693: public void visitNumBigDecimal(GroovySourceAST t, int visit) {
0694: print(t, visit, t.getText(), null, null);
0695: }
0696:
0697: public void visitNumBigInt(GroovySourceAST t, int visit) {
0698: print(t, visit, t.getText(), null, null);
0699: }
0700:
0701: public void visitNumDouble(GroovySourceAST t, int visit) {
0702: print(t, visit, t.getText(), null, null);
0703: }
0704:
0705: public void visitNumInt(GroovySourceAST t, int visit) {
0706: print(t, visit, t.getText(), null, null);
0707: }
0708:
0709: public void visitNumFloat(GroovySourceAST t, int visit) {
0710: print(t, visit, t.getText(), null, null);
0711: }
0712:
0713: public void visitNumLong(GroovySourceAST t, int visit) {
0714: print(t, visit, t.getText(), null, null);
0715: }
0716:
0717: public void visitObjblock(GroovySourceAST t, int visit) {
0718: if (visit == OPENING_VISIT) {
0719: tabLevel++;
0720: print(t, visit, "{");
0721: } else {
0722: tabLevel--;
0723: print(t, visit, "}");
0724: }
0725: }
0726:
0727: // visitOneNl
0728: // new lines are used by parser, but are not created on the AST,
0729: // they can be implied by the source code line/column information
0730:
0731: public void visitOptionalDot(GroovySourceAST t, int visit) {
0732: print(t, visit, "?.", null, null);
0733: }
0734:
0735: public void visitPackageDef(GroovySourceAST t, int visit) {
0736: print(t, visit, "package ", null, null);
0737: }
0738:
0739: public void visitParameterDef(GroovySourceAST t, int visit) {
0740: //do nothing
0741: }
0742:
0743: public void visitParameters(GroovySourceAST t, int visit) {
0744: if (getParentNode().getType() == GroovyTokenTypes.CLOSABLE_BLOCK) {
0745: printUpdatingTabLevel(t, visit, null, ",", " ");
0746: } else {
0747: printUpdatingTabLevel(t, visit, "(", ", ", ") ");
0748: }
0749: }
0750:
0751: public void visitPlus(GroovySourceAST t, int visit) {
0752: print(t, visit, " + ", null, null);
0753: }
0754:
0755: public void visitPlusAssign(GroovySourceAST t, int visit) {
0756: print(t, visit, " += ", null, null);
0757: }
0758:
0759: public void visitPostDec(GroovySourceAST t, int visit) {
0760: print(t, visit, null, null, "--");
0761: }
0762:
0763: public void visitPostInc(GroovySourceAST t, int visit) {
0764: print(t, visit, null, null, "++");
0765: }
0766:
0767: public void visitQuestion(GroovySourceAST t, int visit) {
0768: // ternary operator
0769: print(t, visit, "?", ":", null);
0770: }
0771:
0772: public void visitRangeExclusive(GroovySourceAST t, int visit) {
0773: print(t, visit, "..<", null, null);
0774: }
0775:
0776: public void visitRangeInclusive(GroovySourceAST t, int visit) {
0777: print(t, visit, "..", null, null);
0778: }
0779:
0780: // visit rbrack()
0781: // token type RBRACK only used inside parser, never visited/created
0782:
0783: // visit rcurly()
0784: // token type RCURLY only used inside parser, never visited/created
0785:
0786: // visit RegexpCtorEnd
0787: // visit RegexpLiteral
0788: // visit RegexpSymbol
0789: // token types REGEXP_CTOR_END, REGEXP_LITERAL, REGEXP_SYMBOL only used inside lexer
0790:
0791: public void visitRegexFind(GroovySourceAST t, int visit) {
0792: print(t, visit, " =~ ", null, null);
0793: }
0794:
0795: public void visitRegexMatch(GroovySourceAST t, int visit) {
0796: print(t, visit, " ==~ ", null, null);
0797: }
0798:
0799: // visit rparen()
0800: // token type RPAREN only used inside parser, never visited/created
0801:
0802: public void visitScopeEscape(GroovySourceAST t, int visit) {
0803: print(t, visit, "$", null, null);
0804: }
0805:
0806: public void visitSelectSlot(GroovySourceAST t, int visit) {
0807: print(t, visit, "@", null, null);
0808: }
0809:
0810: // visit semi()
0811: // SEMI only used inside parser, never visited/created (see visitForCondition(), visitForIterator())
0812:
0813: // visit ShComment()
0814: // never visited/created by parser
0815:
0816: public void visitSl(GroovySourceAST t, int visit) {
0817: print(t, visit, " << ", null, null);
0818: }
0819:
0820: public void visitSlAssign(GroovySourceAST t, int visit) {
0821: print(t, visit, " <<= ", null, null);
0822: }
0823:
0824: public void visitSlist(GroovySourceAST t, int visit) {
0825: if (visit == OPENING_VISIT) {
0826: tabLevel++;
0827: print(t, visit, "{");
0828: } else {
0829: tabLevel--;
0830: print(t, visit, "}");
0831: }
0832: }
0833:
0834: // visit SlComment()
0835: // never visited/created by parser
0836:
0837: public void visitSpreadArg(GroovySourceAST t, int visit) {
0838: print(t, visit, "*", null, null);
0839: }
0840:
0841: public void visitSpreadMapArg(GroovySourceAST t, int visit) {
0842: print(t, visit, "*:", null, null);
0843: }
0844:
0845: public void visitSr(GroovySourceAST t, int visit) {
0846: print(t, visit, " >> ", null, null);
0847: }
0848:
0849: public void visitSrAssign(GroovySourceAST t, int visit) {
0850: print(t, visit, " >>= ", null, null);
0851: }
0852:
0853: public void visitStar(GroovySourceAST t, int visit) {
0854: print(t, visit, "*", null, null);
0855: }
0856:
0857: public void visitStarAssign(GroovySourceAST t, int visit) {
0858: print(t, visit, " *= ", null, null);
0859: }
0860:
0861: public void visitStarStar(GroovySourceAST t, int visit) {
0862: print(t, visit, "**", null, null);
0863: }
0864:
0865: public void visitStarStarAssign(GroovySourceAST t, int visit) {
0866: print(t, visit, " **= ", null, null);
0867: }
0868:
0869: public void visitStaticInit(GroovySourceAST t, int visit) {
0870: print(t, visit, "static ", null, null);
0871: }
0872:
0873: public void visitStaticImport(GroovySourceAST t, int visit) {
0874: print(t, visit, "import static ", null, null);
0875: }
0876:
0877: public void visitStrictfp(GroovySourceAST t, int visit) {
0878: print(t, visit, "strictfp ", null, null);
0879: }
0880:
0881: // visitStringch
0882: // String characters only used by lexer, never visited/created directly
0883:
0884: public void visitStringConstructor(GroovySourceAST t, int visit) {
0885: if (visit == OPENING_VISIT) {
0886: stringConstructorCounter = 0;
0887: print(t, visit, "\"");
0888: }
0889: if (visit == SUBSEQUENT_VISIT) {
0890: // every other subsequent visit use an escaping $
0891: if (stringConstructorCounter % 2 == 0) {
0892: print(t, visit, "$");
0893: }
0894: stringConstructorCounter++;
0895: }
0896: if (visit == CLOSING_VISIT) {
0897: print(t, visit, "\"");
0898: }
0899: }
0900:
0901: public void visitStringLiteral(GroovySourceAST t, int visit) {
0902: if (visit == OPENING_VISIT) {
0903: String theString = escape(t.getText());
0904: if (getParentNode().getType() != GroovyTokenTypes.LABELED_ARG
0905: && getParentNode().getType() != GroovyTokenTypes.STRING_CONSTRUCTOR) {
0906: theString = "\"" + theString + "\"";
0907: }
0908: print(t, visit, theString);
0909: }
0910: }
0911:
0912: private String escape(String literal) {
0913: literal = literal.replaceAll("\n", "\\\\<<REMOVE>>n"); // can't seem to do \n in one go with Java regex
0914: literal = literal.replaceAll("<<REMOVE>>", "");
0915: return literal;
0916: }
0917:
0918: public void visitSuperCtorCall(GroovySourceAST t, int visit) {
0919: printUpdatingTabLevel(t, visit, "super(", " ", ")");
0920: }
0921:
0922: // visit TripleDot, not used in the AST
0923:
0924: public void visitType(GroovySourceAST t, int visit) {
0925: GroovySourceAST parent = getParentNode();
0926: GroovySourceAST modifiers = parent
0927: .childOfType(GroovyTokenTypes.MODIFIERS);
0928:
0929: // No need to print 'def' if we already have some modifiers
0930: if (modifiers == null || modifiers.getNumberOfChildren() == 0) {
0931:
0932: if (visit == OPENING_VISIT) {
0933: if (t.getNumberOfChildren() == 0
0934: && parent.getType() != GroovyTokenTypes.PARAMETER_DEF) { // no need for 'def' if in a parameter list
0935: print(t, visit, "def");
0936: }
0937: }
0938: if (visit == CLOSING_VISIT) {
0939: print(t, visit, " ");
0940: }
0941: } else {
0942: if (visit == CLOSING_VISIT) {
0943: if (t.getNumberOfChildren() != 0) {
0944: print(t, visit, " ");
0945: }
0946: }
0947: }
0948: }
0949:
0950: public void visitTypeArgument(GroovySourceAST t, int visit) {
0951: // print nothing
0952: }
0953:
0954: public void visitTypeArguments(GroovySourceAST t, int visit) {
0955: print(t, visit, "<", ", ", ">");
0956: }
0957:
0958: public void visitTypecast(GroovySourceAST t, int visit) {
0959: print(t, visit, "(", null, ")");
0960: }
0961:
0962: public void visitTypeLowerBounds(GroovySourceAST t, int visit) {
0963: print(t, visit, " super ", " & ", null);
0964: }
0965:
0966: public void visitTypeParameter(GroovySourceAST t, int visit) {
0967: // print nothing
0968: }
0969:
0970: public void visitTypeParameters(GroovySourceAST t, int visit) {
0971: print(t, visit, "<", ", ", ">");
0972: }
0973:
0974: public void visitTypeUpperBounds(GroovySourceAST t, int visit) {
0975: print(t, visit, " extends ", " & ", null);
0976: }
0977:
0978: public void visitUnaryMinus(GroovySourceAST t, int visit) {
0979: print(t, visit, "-", null, null);
0980: }
0981:
0982: public void visitUnaryPlus(GroovySourceAST t, int visit) {
0983: print(t, visit, "+", null, null);
0984: }
0985:
0986: // visit Unused "const", "do", "goto" - unsurprisingly these are unused by the AST.
0987:
0988: public void visitVariableDef(GroovySourceAST t, int visit) {
0989: // do nothing
0990: }
0991:
0992: // a.k.a. "variable arity parameter" in the JLS
0993: public void visitVariableParameterDef(GroovySourceAST t, int visit) {
0994: print(t, visit, null, "... ", null);
0995: }
0996:
0997: // visit Vocab - only used by Lexer
0998:
0999: public void visitWildcardType(GroovySourceAST t, int visit) {
1000: print(t, visit, "?", null, null);
1001: }
1002:
1003: // visit WS - only used by lexer
1004:
1005: public void visitDefault(GroovySourceAST t, int visit) {
1006: if (visit == OPENING_VISIT) {
1007: print(t, visit, "<" + tokenNames[t.getType()] + ">");
1008: //out.print("<" + t.getType() + ">");
1009: } else {
1010: print(t, visit, "</" + tokenNames[t.getType()] + ">");
1011: //out.print("</" + t.getType() + ">");
1012: }
1013: }
1014:
1015: protected void printUpdatingTabLevel(GroovySourceAST t, int visit,
1016: String opening, String subsequent, String closing) {
1017: if (visit == OPENING_VISIT && opening != null) {
1018: print(t, visit, opening);
1019: tabLevel++;
1020: }
1021: if (visit == SUBSEQUENT_VISIT && subsequent != null) {
1022: print(t, visit, subsequent);
1023: }
1024: if (visit == CLOSING_VISIT && closing != null) {
1025: tabLevel--;
1026: print(t, visit, closing);
1027: }
1028: }
1029:
1030: protected void print(GroovySourceAST t, int visit, String opening,
1031: String subsequent, String closing) {
1032: if (visit == OPENING_VISIT && opening != null) {
1033: print(t, visit, opening);
1034: }
1035: if (visit == SUBSEQUENT_VISIT && subsequent != null) {
1036: print(t, visit, subsequent);
1037: }
1038: if (visit == CLOSING_VISIT && closing != null) {
1039: print(t, visit, closing);
1040: }
1041: }
1042:
1043: protected void print(GroovySourceAST t, int visit, String value) {
1044: if (visit == OPENING_VISIT) {
1045: printNewlineAndIndent(t, visit);
1046: }
1047: if (visit == CLOSING_VISIT) {
1048: printNewlineAndIndent(t, visit);
1049: }
1050: out.print(value);
1051: }
1052:
1053: protected void printNewlineAndIndent(GroovySourceAST t, int visit) {
1054: int currentLine = t.getLine();
1055: if (lastLinePrinted == 0) {
1056: lastLinePrinted = currentLine;
1057: }
1058: if (lastLinePrinted != currentLine) {
1059: if (newLines) {
1060: if (!(visit == OPENING_VISIT && t.getType() == GroovyTokenTypes.SLIST)) {
1061: for (int i = lastLinePrinted; i < currentLine; i++) {
1062: out.println();
1063: }
1064: if (lastLinePrinted > currentLine) {
1065: out.println();
1066: }
1067: if (visit == OPENING_VISIT
1068: || (visit == CLOSING_VISIT && lastLinePrinted > currentLine)) {
1069: for (int i = 0; i < tabLevel; i++) {
1070: out.print(" ");
1071: }
1072: }
1073: }
1074: }
1075: lastLinePrinted = Math.max(currentLine, lastLinePrinted);
1076: }
1077: }
1078:
1079: public void push(GroovySourceAST t) {
1080: stack.push(t);
1081: }
1082:
1083: public GroovySourceAST pop() {
1084: if (!stack.empty()) {
1085: return (GroovySourceAST) stack.pop();
1086: }
1087: return null;
1088: }
1089:
1090: private GroovySourceAST getParentNode() {
1091: Object currentNode = stack.pop();
1092: Object parentNode = stack.peek();
1093: stack.push(currentNode);
1094: return (GroovySourceAST) parentNode;
1095: }
1096:
1097: }
|