1 /* 2 * Copyright (c) 2009, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package jdk.vm.ci.meta; 24 25 import java.util.IllegalFormatException; 26 import java.util.UnknownFormatConversionException; 27 28 /** 29 * Represents a reference to a Java field, either resolved or unresolved fields. Fields, like 30 * methods and types, are resolved through {@link ConstantPool constant pools}. 31 */ 32 public interface JavaField extends TrustedInterface { 33 34 /** 35 * Returns the name of this field. 36 */ 37 String getName(); 38 39 /** 40 * Returns a {@link JavaType} object that identifies the declared type for this field. 41 */ 42 JavaType getType(); 43 44 /** 45 * Returns the kind of this field. This is the same as calling {@link #getType}. 46 * {@link JavaType#getJavaKind getJavaKind}. 47 */ 48 default JavaKind getJavaKind() { 49 return getType().getJavaKind(); 50 } 51 52 /** 53 * Returns the {@link JavaType} object representing the class or interface that declares this 54 * field. 55 */ 56 JavaType getDeclaringClass(); 57 58 /** 59 * Gets a string for this field formatted according to a given format specification. A format 60 * specification is composed of characters that are to be copied verbatim to the result and 61 * specifiers that denote an attribute of this field that is to be copied to the result. A 62 * specifier is a single character preceded by a '%' character. The accepted specifiers and the 63 * field attributes they denote are described below: 64 * 65 * <pre> 66 * Specifier | Description | Example(s) 67 * ----------+------------------------------------------------------------------------------------------ 68 * 'T' | Qualified type | "int" "java.lang.String" 69 * 't' | Unqualified type | "int" "String" 70 * 'H' | Qualified holder | "java.util.Map.Entry" 71 * 'h' | Unqualified holder | "Entry" 72 * 'n' | Field name | "age" 73 * 'f' | Indicator if field is unresolved, static or instance | "unresolved" "static" "instance" 74 * '%' | A '%' character | "%" 75 * </pre> 76 * 77 * @param format a format specification 78 * @return the result of formatting this field according to {@code format} 79 * @throws IllegalFormatException if an illegal specifier is encountered in {@code format} 80 */ 81 default String format(String format) throws IllegalFormatException { 82 StringBuilder sb = new StringBuilder(); 83 int index = 0; 84 JavaType type = getType(); 85 while (index < format.length()) { 86 char ch = format.charAt(index++); 87 if (ch == '%') { 88 if (index >= format.length()) { 89 throw new UnknownFormatConversionException("An unquoted '%' character cannot terminate a field format specification"); 90 } 91 char specifier = format.charAt(index++); 92 switch (specifier) { 93 case 'T': 94 case 't': { 95 sb.append(type.toJavaName(specifier == 'T')); 96 break; 97 } 98 case 'H': 99 case 'h': { 100 sb.append(getDeclaringClass().toJavaName(specifier == 'H')); 101 break; 102 } 103 case 'n': { 104 sb.append(getName()); 105 break; 106 } 107 case 'f': { 108 sb.append(!(this instanceof ResolvedJavaField) ? "unresolved" : ((ResolvedJavaField) this).isStatic() ? "static" : "instance"); 109 break; 110 } 111 case '%': { 112 sb.append('%'); 113 break; 114 } 115 default: { 116 throw new UnknownFormatConversionException(String.valueOf(specifier)); 117 } 118 } 119 } else { 120 sb.append(ch); 121 } 122 } 123 return sb.toString(); 124 } 125 }