001/* 002 * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package jdk.internal.jvmci.meta; 024 025import java.util.*; 026 027/** 028 * Represents a reference to a Java field, either resolved or unresolved fields. Fields, like 029 * methods and types, are resolved through {@link ConstantPool constant pools}. 030 */ 031public interface JavaField extends TrustedInterface { 032 033 /** 034 * Returns the name of this field. 035 */ 036 String getName(); 037 038 /** 039 * Returns a {@link JavaType} object that identifies the declared type for this field. 040 */ 041 JavaType getType(); 042 043 /** 044 * Returns the kind of this field. This is the same as calling {@link #getType}. 045 * {@link JavaType#getKind getKind}. 046 */ 047 default Kind getKind() { 048 return getType().getKind(); 049 } 050 051 /** 052 * Returns the {@link JavaType} object representing the class or interface that declares this 053 * field. 054 */ 055 JavaType getDeclaringClass(); 056 057 /** 058 * Gets a string for this field formatted according to a given format specification. A format 059 * specification is composed of characters that are to be copied verbatim to the result and 060 * specifiers that denote an attribute of this field that is to be copied to the result. A 061 * specifier is a single character preceded by a '%' character. The accepted specifiers and the 062 * field attributes they denote are described below: 063 * 064 * <pre> 065 * Specifier | Description | Example(s) 066 * ----------+------------------------------------------------------------------------------------------ 067 * 'T' | Qualified type | "int" "java.lang.String" 068 * 't' | Unqualified type | "int" "String" 069 * 'H' | Qualified holder | "java.util.Map.Entry" 070 * 'h' | Unqualified holder | "Entry" 071 * 'n' | Field name | "age" 072 * 'f' | Indicator if field is unresolved, static or instance | "unresolved" "static" "instance" 073 * '%' | A '%' character | "%" 074 * </pre> 075 * 076 * @param format a format specification 077 * @return the result of formatting this field according to {@code format} 078 * @throws IllegalFormatException if an illegal specifier is encountered in {@code format} 079 */ 080 default String format(String format) throws IllegalFormatException { 081 StringBuilder sb = new StringBuilder(); 082 int index = 0; 083 JavaType type = getType(); 084 while (index < format.length()) { 085 char ch = format.charAt(index++); 086 if (ch == '%') { 087 if (index >= format.length()) { 088 throw new UnknownFormatConversionException("An unquoted '%' character cannot terminate a field format specification"); 089 } 090 char specifier = format.charAt(index++); 091 boolean qualified = false; 092 switch (specifier) { 093 case 'T': 094 qualified = true; 095 // fall through 096 case 't': { 097 sb.append(type.toJavaName(qualified)); 098 break; 099 } 100 case 'H': 101 qualified = true; 102 // fall through 103 case 'h': { 104 sb.append(getDeclaringClass().toJavaName(qualified)); 105 break; 106 } 107 case 'n': { 108 sb.append(getName()); 109 break; 110 } 111 case 'f': { 112 sb.append(!(this instanceof ResolvedJavaField) ? "unresolved" : ((ResolvedJavaField) this).isStatic() ? "static" : "instance"); 113 break; 114 } 115 case '%': { 116 sb.append('%'); 117 break; 118 } 119 default: { 120 throw new UnknownFormatConversionException(String.valueOf(specifier)); 121 } 122 } 123 } else { 124 sb.append(ch); 125 } 126 } 127 return sb.toString(); 128 } 129}