Pretty.java revision c38ee7ae0239899e7f9d0d5243d8bed77836891c
1881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon/* 2881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon * Copyright 2016 Google Inc. All Rights Reserved. 3881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon * 4881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon * Licensed under the Apache License, Version 2.0 (the "License"); 5881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon * you may not use this file except in compliance with the License. 6881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon * You may obtain a copy of the License at 7881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon * 8881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon * http://www.apache.org/licenses/LICENSE-2.0 9881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon * 10881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon * Unless required by applicable law or agreed to in writing, software 11881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon * distributed under the License is distributed on an "AS IS" BASIS, 12881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon * See the License for the specific language governing permissions and 14881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon * limitations under the License. 15881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon */ 16881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 17881d847a3ccf0bca29a5c809aeb68eff9f467cedcushonpackage com.google.turbine.tree; 18881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 19881d847a3ccf0bca29a5c809aeb68eff9f467cedcushonimport com.google.common.base.Joiner; 20881d847a3ccf0bca29a5c809aeb68eff9f467cedcushonimport com.google.common.base.Strings; 21881d847a3ccf0bca29a5c809aeb68eff9f467cedcushonimport com.google.common.collect.ImmutableSet; 22c38ee7ae0239899e7f9d0d5243d8bed77836891ccushonimport com.google.turbine.tree.Tree.ClassLiteral; 23881d847a3ccf0bca29a5c809aeb68eff9f467cedcushonimport java.util.ArrayList; 24881d847a3ccf0bca29a5c809aeb68eff9f467cedcushonimport java.util.Collections; 25881d847a3ccf0bca29a5c809aeb68eff9f467cedcushonimport java.util.List; 26881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 27881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon/** A pretty-printer for {@link Tree}s. */ 28881d847a3ccf0bca29a5c809aeb68eff9f467cedcushonpublic class Pretty implements Tree.Visitor<Void, Void> { 29881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 30881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon static String pretty(Tree tree) { 31881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon Pretty pretty = new Pretty(); 32881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon tree.accept(pretty, null); 33881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return pretty.sb.toString(); 34881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 35881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 36881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon private final StringBuilder sb = new StringBuilder(); 37881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon int indent = 0; 38881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon boolean newLine = false; 39881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 40881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon void printLine() { 41881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append('\n'); 42881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon newLine = true; 43881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 44881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 45881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon void printLine(String line) { 46881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (!newLine) { 47881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append('\n'); 48881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 49881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(line).append('\n'); 50881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon newLine = true; 51881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 52881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 53881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon Pretty append(char c) { 54881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (c == '\n') { 55881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon newLine = true; 56881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } else if (newLine) { 57881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon sb.append(Strings.repeat(" ", indent * 2)); 58881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon newLine = false; 59881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 60881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon sb.append(c); 61881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return this; 62881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 63881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 64881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon Pretty append(String s) { 65881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (newLine) { 66881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon sb.append(Strings.repeat(" ", indent * 2)); 67881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon newLine = false; 68881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 69881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon sb.append(s); 70881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return this; 71881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 72881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 73881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon @Override 74881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon public Void visitWildTy(Tree.WildTy wildTy, Void input) { 75881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append('?'); 76881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (wildTy.lower().isPresent()) { 77881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(" super "); 78881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon wildTy.lower().get().accept(this, null); 79881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 80881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (wildTy.upper().isPresent()) { 81881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(" extends "); 82881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon wildTy.upper().get().accept(this, null); 83881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 84881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return null; 85881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 86881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 87881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon @Override 88881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon public Void visitArrTy(Tree.ArrTy arrTy, Void input) { 89881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon arrTy.elem().accept(this, null); 90881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(Strings.repeat("[]", arrTy.dim())); 91881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return null; 92881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 93881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 94881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon @Override 95881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon public Void visitPrimTy(Tree.PrimTy primTy, Void input) { 96881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(primTy.tykind().toString()); 97881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return null; 98881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 99881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 100881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon @Override 101881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon public Void visitVoidTy(Tree.VoidTy primTy, Void input) { 102881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append("void"); 103881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return null; 104881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 105881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 106881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon @Override 107881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon public Void visitClassTy(Tree.ClassTy classTy, Void input) { 108881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (classTy.base().isPresent()) { 109881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon classTy.base().get().accept(this, null); 110881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append('.'); 111881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 112881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(classTy.name()); 113881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (!classTy.tyargs().isEmpty()) { 114881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append('<'); 115881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon boolean first = true; 116881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon for (Tree t : classTy.tyargs()) { 117881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (!first) { 118881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(", "); 119881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 120881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon t.accept(this, null); 121881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon first = false; 122881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 123881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append('>'); 124881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 125881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return null; 126881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 127881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 128881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon @Override 129881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon public Void visitLiteral(Tree.Literal literal, Void input) { 130881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(literal.value().toString()); 131881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return null; 132881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 133881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 134881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon @Override 135881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon public Void visitTypeCast(Tree.TypeCast typeCast, Void input) { 136881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append('('); 137881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon typeCast.ty().accept(this, null); 138881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(") "); 139881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon typeCast.expr().accept(this, null); 140881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return null; 141881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 142881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 143881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon @Override 144881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon public Void visitUnary(Tree.Unary unary, Void input) { 145881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon switch (unary.op()) { 146881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case POST_INCR: 147881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case POST_DECR: 148881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon unary.expr().accept(this, null); 149881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(unary.op().toString()); 150881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon break; 151881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case PRE_INCR: 152881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case PRE_DECR: 153881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case UNARY_PLUS: 154881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case NEG: 155881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case NOT: 156881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case BITWISE_COMP: 157881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(unary.op().toString()); 158881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon unary.expr().accept(this, null); 159881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon break; 160881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon default: 161881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon throw new AssertionError(unary.op().name()); 162881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 163881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return null; 164881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 165881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 166881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon @Override 167881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon public Void visitBinary(Tree.Binary binary, Void input) { 168881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append('('); 169881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon binary.lhs().accept(this, null); 170881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(" " + binary.op() + " "); 171881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon binary.rhs().accept(this, null); 172881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(')'); 173881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return null; 174881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 175881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 176881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon @Override 177881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon public Void visitConstVarName(Tree.ConstVarName constVarName, Void input) { 178881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(Joiner.on('.').join(constVarName.name())); 179881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return null; 180881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 181881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 182881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon @Override 183c38ee7ae0239899e7f9d0d5243d8bed77836891ccushon public Void visitClassLiteral(ClassLiteral classLiteral, Void input) { 184c38ee7ae0239899e7f9d0d5243d8bed77836891ccushon classLiteral.accept(this, input); 185c38ee7ae0239899e7f9d0d5243d8bed77836891ccushon append(".class"); 186c38ee7ae0239899e7f9d0d5243d8bed77836891ccushon return null; 187c38ee7ae0239899e7f9d0d5243d8bed77836891ccushon } 188c38ee7ae0239899e7f9d0d5243d8bed77836891ccushon 189c38ee7ae0239899e7f9d0d5243d8bed77836891ccushon @Override 190881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon public Void visitAssign(Tree.Assign assign, Void input) { 191881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(assign.name()).append(" = "); 192881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon assign.expr().accept(this, null); 193881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return null; 194881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 195881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 196881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon @Override 197881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon public Void visitConditional(Tree.Conditional conditional, Void input) { 198881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon conditional.cond().accept(this, null); 199881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(" ? "); 200881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon conditional.iftrue().accept(this, null); 201881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(" : "); 202881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon conditional.iffalse().accept(this, null); 203881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return null; 204881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 205881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 206881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon @Override 207881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon public Void visitArrayInit(Tree.ArrayInit arrayInit, Void input) { 208881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append('{'); 209881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon boolean first = true; 210881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon for (Tree.Expression e : arrayInit.exprs()) { 211881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (!first) { 212881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(", "); 213881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 214881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon e.accept(this, null); 215881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon first = false; 216881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 217881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append('}'); 218881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return null; 219881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 220881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 221881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon @Override 222881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon public Void visitCompUnit(Tree.CompUnit compUnit, Void input) { 223881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (compUnit.pkg().isPresent()) { 224881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon compUnit.pkg().get().accept(this, null); 225881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon printLine(); 226881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 227881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon for (Tree.ImportDecl i : compUnit.imports()) { 228881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon i.accept(this, null); 229881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon printLine(); 230881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 231881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon boolean first = true; 232881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon for (Tree.TyDecl decl : compUnit.decls()) { 233881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (!first) { 234881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon printLine(); 235881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 236881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon decl.accept(this, null); 237881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon first = false; 238881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 239881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return null; 240881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 241881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 242881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon @Override 243881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon public Void visitImportDecl(Tree.ImportDecl importDecl, Void input) { 244881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append("import "); 245881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (importDecl.stat()) { 246881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append("static "); 247881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 248881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(importDecl.type()).append(";").append('\n'); 249881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return null; 250881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 251881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 252881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon @Override 253881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon public Void visitVarDecl(Tree.VarDecl varDecl, Void input) { 254881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon printVarDecl(varDecl); 255881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(';'); 256881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return null; 257881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 258881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 259881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon private void printVarDecl(Tree.VarDecl varDecl) { 260881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon for (Tree.Anno anno : varDecl.annos()) { 261881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon anno.accept(this, null); 262881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(' '); 263881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 264881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon printModifiers(varDecl.mods()); 265881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon varDecl.ty().accept(this, null); 266881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(' ').append(varDecl.name()); 267881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (varDecl.init().isPresent()) { 268881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(" = "); 269881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon varDecl.init().get().accept(this, null); 270881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 271881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 272881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 273881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon @Override 274881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon public Void visitMethDecl(Tree.MethDecl methDecl, Void input) { 275881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon for (Tree.Anno anno : methDecl.annos()) { 276881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon anno.accept(this, null); 277881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon printLine(); 278881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 279881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon printModifiers(methDecl.mods()); 280881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (!methDecl.typarams().isEmpty()) { 281881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append('<'); 282881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon boolean first = true; 283881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon for (Tree.TyParam t : methDecl.typarams()) { 284881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (!first) { 285881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(", "); 286881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 287881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon t.accept(this, null); 288881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon first = false; 289881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 290881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append('>'); 291881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(' '); 292881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 293881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (methDecl.ret().isPresent()) { 294881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon methDecl.ret().get().accept(this, null); 295881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(' '); 296881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 297881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(methDecl.name()); 298881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append('('); 299881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon boolean first = true; 300881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon for (Tree.VarDecl param : methDecl.params()) { 301881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (!first) { 302881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(", "); 303881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 304881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon printVarDecl(param); 305881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon first = false; 306881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 307881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(')'); 3083088f83b806b82d866d119e344da274105f42821cushon if (methDecl.defaultValue().isPresent()) { 309881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(" default "); 3103088f83b806b82d866d119e344da274105f42821cushon methDecl.defaultValue().get().accept(this, null); 311881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(";"); 312881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } else if (methDecl.mods().contains(TurbineModifier.ABSTRACT) 313881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon || methDecl.mods().contains(TurbineModifier.NATIVE)) { 314881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(";"); 315881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } else { 316881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(" {}"); 317881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 318881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return null; 319881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 320881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 321881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon @Override 322881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon public Void visitAnno(Tree.Anno anno, Void input) { 323881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append('@'); 324881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(anno.name()); 325881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (!anno.args().isEmpty()) { 326881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append('('); 327881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon boolean first = true; 328881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon for (Tree.Expression e : anno.args()) { 329881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (!first) { 330881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(", "); 331881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 332881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon e.accept(this, null); 333881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon first = false; 334881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 335881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(')'); 336881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 337881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return null; 338881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 339881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 340881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon @Override 341881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon public Void visitTyDecl(Tree.TyDecl tyDecl, Void input) { 342881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon for (Tree.Anno anno : tyDecl.annos()) { 343881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon anno.accept(this, null); 344881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon printLine(); 345881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 346881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon printModifiers(tyDecl.mods()); 347881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon switch (tyDecl.tykind()) { 348881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case CLASS: 349881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append("class"); 350881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon break; 351881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case INTERFACE: 352881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append("interface"); 353881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon break; 354881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case ENUM: 355881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append("enum"); 356881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon break; 357881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case ANNOTATION: 358881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append("@interface"); 359881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon break; 360881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 361881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(' ').append(tyDecl.name()); 362881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (!tyDecl.typarams().isEmpty()) { 363881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append('<'); 364881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon boolean first = true; 365881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon for (Tree.TyParam t : tyDecl.typarams()) { 366881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (!first) { 367881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(", "); 368881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 369881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon t.accept(this, null); 370881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon first = false; 371881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 372881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append('>'); 373881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 374881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (tyDecl.xtnds().isPresent()) { 375881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(" extends "); 376881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon tyDecl.xtnds().get().accept(this, null); 377881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 378881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (!tyDecl.impls().isEmpty()) { 379881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(" implements "); 380881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon boolean first = true; 381881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon for (Tree.ClassTy t : tyDecl.impls()) { 382881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (!first) { 383881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(", "); 384881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 385881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon t.accept(this, null); 386881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon first = false; 387881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 388881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 389881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(" {").append('\n'); 390881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon indent++; 391881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon switch (tyDecl.tykind()) { 392881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case ENUM: 393881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon { 394881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon List<Tree> nonConsts = new ArrayList<>(); 395881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon for (Tree t : tyDecl.members()) { 396881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (t instanceof Tree.VarDecl) { 397881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon Tree.VarDecl decl = (Tree.VarDecl) t; 398881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (decl.mods().contains(TurbineModifier.ACC_ENUM)) { 399881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(decl.name()).append(',').append('\n'); 400881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon continue; 401881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 402881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 403881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon nonConsts.add(t); 404881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 405881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon printLine(";"); 406881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon boolean first = true; 407881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon for (Tree t : nonConsts) { 408881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (!first) { 409881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon printLine(); 410881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 411881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon t.accept(this, null); 412881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon first = false; 413881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 414881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon break; 415881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 416881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon default: 417881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon { 418881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon boolean first = true; 419881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon for (Tree t : tyDecl.members()) { 420881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (!first) { 421881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon printLine(); 422881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 423881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon t.accept(this, null); 424881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon first = false; 425881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 426881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon break; 427881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 428881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 429881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon indent--; 430881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon printLine("}"); 431881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return null; 432881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 433881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 434881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon private void printModifiers(ImmutableSet<TurbineModifier> mods) { 435881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon List<TurbineModifier> modifiers = new ArrayList<>(mods); 436881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon Collections.sort(modifiers); 437881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon for (TurbineModifier mod : modifiers) { 438881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon switch (mod) { 439881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case PRIVATE: 440881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case PROTECTED: 441881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case PUBLIC: 442881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case ABSTRACT: 443881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case FINAL: 444881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case STATIC: 445881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case VOLATILE: 446881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case SYNCHRONIZED: 447881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case STRICTFP: 448881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case NATIVE: 449881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case TRANSIENT: 450881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case DEFAULT: 451881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(mod.toString()).append(' '); 452881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon break; 453881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case ACC_SUPER: 454881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case VARARGS: 455881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case INTERFACE: 456881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case ACC_ENUM: 457881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case ACC_ANNOTATION: 458881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case ACC_SYNTHETIC: 459881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case ACC_BRIDGE: 460881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon case ENUM_IMPL: 461881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon break; 462881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon default: 463881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon throw new AssertionError(mod); 464881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 465881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 466881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 467881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 468881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon @Override 469881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon public Void visitTyParam(Tree.TyParam tyParam, Void input) { 470881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(tyParam.name()); 471881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (!tyParam.bounds().isEmpty()) { 472881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(" extends "); 473881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon boolean first = true; 474881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon for (Tree bound : tyParam.bounds()) { 475881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon if (!first) { 476881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append(" & "); 477881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 478881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon bound.accept(this, null); 479881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon first = false; 480881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 481881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 482881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return null; 483881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 484881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon 485881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon @Override 486881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon public Void visitPkgDecl(Tree.PkgDecl pkgDecl, Void input) { 487881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon append("package ").append(pkgDecl.name()).append(';'); 488881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon return null; 489881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon } 490881d847a3ccf0bca29a5c809aeb68eff9f467cedcushon} 491