TypePrinter.java revision 3062:15bdc18525ff
1/* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package jdk.jshell; 27 28import static com.sun.tools.javac.code.Flags.COMPOUND; 29import static com.sun.tools.javac.code.Kinds.Kind.PCK; 30import com.sun.tools.javac.code.Printer; 31import com.sun.tools.javac.code.Symbol; 32import com.sun.tools.javac.code.Symbol.ClassSymbol; 33import com.sun.tools.javac.code.Symbol.PackageSymbol; 34import com.sun.tools.javac.code.Type; 35import com.sun.tools.javac.code.Type.ClassType; 36import com.sun.tools.javac.util.JavacMessages; 37import java.util.Locale; 38import java.util.function.BinaryOperator; 39 40/** 41 * Print types in source form. 42 */ 43class TypePrinter extends Printer { 44 45 private final JavacMessages messages; 46 private final BinaryOperator<String> fullClassNameAndPackageToClass; 47 private final Type typeToPrint; 48 49 TypePrinter(JavacMessages messages, BinaryOperator<String> fullClassNameAndPackageToClass, Type typeToPrint) { 50 this.messages = messages; 51 this.fullClassNameAndPackageToClass = fullClassNameAndPackageToClass; 52 this.typeToPrint = typeToPrint; 53 } 54 55 @Override 56 protected String localize(Locale locale, String key, Object... args) { 57 return messages.getLocalizedString(locale, key, args); 58 } 59 60 @Override 61 protected String capturedVarId(Type.CapturedType t, Locale locale) { 62 throw new InternalError("should never call this"); 63 } 64 65 @Override 66 public String visitCapturedType(Type.CapturedType t, Locale locale) { 67 if (t == typeToPrint) { 68 return visit(t.getUpperBound(), locale); 69 } else { 70 return visit(t.wildcard, locale); 71 } 72 } 73 74 @Override 75 public String visitType(Type t, Locale locale) { 76 String s = (t.tsym == null || t.tsym.name == null) 77 ? "Object" // none 78 : t.tsym.name.toString(); 79 return s; 80 } 81 82 /** 83 * Converts a class name into a (possibly localized) string. Anonymous 84 * inner classes get converted into a localized string. 85 * 86 * @param t the type of the class whose name is to be rendered 87 * @param longform if set, the class' fullname is displayed - if unset the 88 * short name is chosen (w/o package) 89 * @param locale the locale in which the string is to be rendered 90 * @return localized string representation 91 */ 92 @Override 93 protected String className(ClassType t, boolean longform, Locale locale) { 94 Symbol sym = t.tsym; 95 if (sym.name.length() == 0 && (sym.flags() & COMPOUND) != 0) { 96 /*** 97 StringBuilder s = new StringBuilder(visit(t.supertype_field, locale)); 98 for (List<Type> is = t.interfaces_field; is.nonEmpty(); is = is.tail) { 99 s.append('&'); 100 s.append(visit(is.head, locale)); 101 } 102 return s.toString(); 103 ***/ 104 return "Object"; 105 } else if (sym.name.length() == 0) { 106 // Anonymous 107 String s; 108 ClassType norm = (ClassType) t.tsym.type; 109 if (norm == null) { 110 s = "object"; 111 } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) { 112 s = visit(norm.interfaces_field.head, locale); 113 } else { 114 s = visit(norm.supertype_field, locale); 115 } 116 return s; 117 } else if (longform) { 118 String pkg = ""; 119 for (Symbol psym = sym; psym != null; psym = psym.owner) { 120 if (psym.kind == PCK) { 121 pkg = psym.getQualifiedName().toString(); 122 break; 123 } 124 } 125 return fullClassNameAndPackageToClass.apply( 126 sym.getQualifiedName().toString(), 127 pkg 128 ); 129 } else { 130 return sym.name.toString(); 131 } 132 } 133 134 @Override 135 public String visitClassSymbol(ClassSymbol sym, Locale locale) { 136 return sym.name.isEmpty() 137 ? sym.flatname.toString() // Anonymous 138 : sym.fullname.toString(); 139 } 140 141 @Override 142 public String visitPackageSymbol(PackageSymbol s, Locale locale) { 143 return s.isUnnamed() 144 ? "" // Unnamed package 145 : s.fullname.toString(); 146 } 147 148} 149