001package Torello.JavaDoc; 002 003 004// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 005// Standard-Java Imports 006// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 007 008import java.io.IOException; 009import java.util.Optional; 010 011 012// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 013// Java-HTML Imports 014// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 015 016import Torello.Java.*; 017 018import static Torello.Java.C.*; 019import static Torello.JavaDoc.PF.*; 020 021 022// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 023// JDUInternal 024// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 025 026import Torello.JDUInternal.Annotations.ReflAnnotations.ReflAnnotationData; 027 028 029// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 030// The new Source-Code Parser: com.sun.source.* 031// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 032 033import com.sun.source.tree.Tree; 034import com.sun.source.tree.VariableTree; 035import com.sun.source.tree.ExpressionTree; 036 037 038/** 039 * <B CLASS=JDDescLabel>Reflection Class:</B> 040 * 041 * <BR />Holds all information extracted from <CODE>'.java'</CODE> Source-Files about Field's 042 * identified in that file. 043 * 044 * <EMBED CLASS='external-html' DATA-FILE-ID=JPB_GET_INST> 045 * <EMBED CLASS='external-html' DATA-FILE-ID=JPB_FIELD> 046 */ 047@JDHeaderBackgroundImg(EmbedTagFileID={"REFLECTION_EXTENSION"}) 048public class Field extends Declaration 049 implements java.io.Serializable, Comparable<Field>, Cloneable 050{ 051 /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */ 052 protected static final long serialVersionUID = 1; 053 054 @Override 055 String codeHiLiteString() { return this.signature; } 056 057 058 // ******************************************************************************************** 059 // ******************************************************************************************** 060 // Public Fields: The Type, and the Initializer 061 // ******************************************************************************************** 062 // ******************************************************************************************** 063 064 065 /** The definition of this field, as a {@code String}. */ 066 public final String definition; 067 068 /** The type / class of this field, as a {@code String}. */ 069 public final String type; 070 071 /** 072 * The type / class of this field, as a {@code String}. 073 * <BR /><BR /> 074 * <EMBED CLASS='external-html' DATA-FILE-ID=JPB_JOW_TITLE> 075 */ 076 public final String typeJOW; 077 078 079 // ******************************************************************************************** 080 // ******************************************************************************************** 081 // Reference-Hook: com.sun.source.tree 082 // ******************************************************************************************** 083 // ******************************************************************************************** 084 085 086 /** 087 * <EMBED CLASS='external-html' DATA-FILE-ID=SSTB_HOOK_FIELD> 088 * 089 * If a user decides to make use of the native Oracle {@code VariableTree}-Instance that 090 * was used to build this {@code Field}-Instance, the {@code VariableTree} may be retrieved 091 * from this {@code transient} field. 092 */ 093 public final transient VariableTree variableTree; 094 095 096 // ******************************************************************************************** 097 // ******************************************************************************************** 098 // Constructor - com.sun.source.tree 099 // ******************************************************************************************** 100 // ******************************************************************************************** 101 102 103 // Public, but internally-used-only Constructor for "Field" 104 public Field( 105 final VariableTree vt, 106 final ReflAnnotationData rad, 107 final TreeUtils util 108 ) 109 { 110 super( 111 rad, // Stuff for building ReflAnnotationMirrors 112 util, // TreeUtils instance (contains all the parser and stuff) 113 vt, // 'Tree' instance 114 vt.getModifiers(), // ModifiersTree: Annotations on the Field & key-words 115 vt.getName().toString(), // Name of the Field 116 Entity.FIELD, // Entity 117 vt.getInitializer() // NEW: Pass the initializer to the 'body' tree-node 118 ); 119 120 this.type = vt.getType().toString(); 121 this.typeJOW = StrSource.typeToJavaIdentifier(this.type); 122 123 ExpressionTree initializer = vt.getInitializer(); 124 125 this.definition = (initializer == null) ? null : util.substring(initializer).trim(); 126 127 // Reference Hook: This was built using the com.sun.source.tree.VariableTree class 128 this.variableTree = vt; 129 } 130 131 132 // ******************************************************************************************** 133 // ******************************************************************************************** 134 // Constructor: Used Internally by SignatureParse 135 // ******************************************************************************************** 136 // ******************************************************************************************** 137 138 139 // Ensures that the Version with longer type-information strings is used. 140 // Java Doc often uses longer type strings than is available from the source-code parse 141 // Remember, JavaParser Symbol-Solver doesn't work well, and the Sun/Oracle Parser doesn't have 142 // a linker at all. 143 // 144 // Intended for JDU Internal-Use-Only 145 146 public Field(final Field fFromSourceParser, final Field fFromHTMLParser) 147 { 148 // Calls the super 'clone' constructor for Declaration 149 // Java Parser has much more information for everything, except the "Type" 150 // JP elects to leave off the "Package Information" for types - while Java Doc includes 151 // it (**unless** it can provide an <A HREF=...> for the type, then it leaves it off too!) 152 153 super(fFromSourceParser); 154 155 // Continuing with: "JP has this info", while Java Doc just leaves this blank. 156 this.definition = fFromSourceParser.definition; 157 158 // Java Doc always produces "java.lang.String", while JP just gives "String" 159 /// 160 // REMEMBER: JP is lazy when it comes to "Package Information" for types. 161 // Java-Doc includes it often - BUT NOT ALWAYS. (See above comment) 162 // 163 // Remember, though, the rest of the JavaParser fields are filled out, Java Doc 164 // leaves out all the other information that JP retrieves. 165 166 this.type = 167 (fFromHTMLParser.type.length() > fFromSourceParser.type.length()) 168 ? fFromHTMLParser.type 169 : fFromSourceParser.type; 170 171 // This should never matter. They must be identical. 172 this.typeJOW = fFromSourceParser.typeJOW; 173 this.variableTree = fFromSourceParser.variableTree; 174 } 175 176 177 // ************************************************************************************* 178 // ************************************************************************************* 179 // toString() 180 // ************************************************************************************* 181 // ************************************************************************************* 182 183 184 /** 185 * Generates a {@code String} of this field, with all information included. 186 * @return A printable {@code String} of this field. 187 * @see #toString(int) 188 */ 189 public String toString() 190 { 191 String defStr = (definition == null) 192 ? "null" 193 : StrPrint.abbrevEndRDSF(definition, MAX_STR_LEN, true); 194 195 return 196 "Name: [" + name + "]\n" + 197 "Declaration: [" + StrPrint.abbrevEndRDSF(signature, MAX_STR_LEN, true) + "]\n" + 198 "Type: [" + type + "]\n" + 199 "Definition: [" + defStr + "]\n" + 200 "Modifiers: [" + StrCSV.toCSV(modifiers, true, true, null) + "]\n" + 201 202 // This will **NEVER** be null - unless 'this' instance was built from an HTML File, 203 // rather than a source-code file. Instances like that are only used temporarily, and 204 // are garbage collected instantly. Do this check anyway (just in case). 205 206 "Location: " + ((this.location == null) 207 ? "null" 208 : ('[' + this.location.quickSummary() + ']')); 209 } 210 211 /** 212 * <EMBED CLASS='external-html' DATA-FILE-ID=TO_STR_PF> 213 * 214 * <BR /><BR />There is additional information printed by this {@code 'toString'} method 215 * (versus the zero-argument, standard, Java {@code 'toString'}). This method will print any 216 * available Java-Doc Comment's that were placed on this {@code Field}. 217 * 218 * <BR /><BR />This {@code 'toString'} also allows for adding UNIX-Terminal color codes. 219 * 220 * @param flags These are defined in the {@link PF Print-Flags} class 221 * @return A printable {@code String} of this {@code Field}. 222 * @see PF 223 * @see #toString() 224 */ 225 public String toString(int flags) 226 { 227 boolean color = (flags & UNIX_COLORS) > 0; 228 229 return 230 printedName("Field", 15, color) + 231 printedDeclaration(15, color) + 232 printedType(jowFlags(flags)) + 233 printedDefinition(color) + 234 printedModifiers(15) + 235 printedLocation(15, color, (flags & BRIEF_LOCATION) > 0) + 236 237 // The previous method does not add a '\n' end to the end of the returned string 238 // This is optional, it adds a '\n' AT THE BEGINNING if it is included 239 240 printedComments(15, color, (flags & JAVADOC_COMMENTS) > 0); 241 } 242 243 private String printedType(Torello.Java.Additional.Ret2<Boolean, Boolean> jow) 244 { 245 if (jow.a /*add-JOW*/) 246 return 247 "Type: [" + type + "]\n" + 248 "Type-JOW: [" + typeJOW + "]\n"; 249 else if (jow.b /*only-JOW*/) 250 return "Type-JOW: [" + typeJOW + "]\n"; 251 else 252 return "Type: [" + type + "]\n"; 253 } 254 255 private String printedDefinition(boolean color) 256 { 257 return (definition == null) 258 ? "Definition: [null]\n" 259 : "Definition: [" + 260 (color ? BGREEN : "") + 261 StrPrint.abbrevEndRDSF(definition, MAX_STR_LEN, true) + 262 (color ? RESET : "") + "]\n"; 263 } 264 265 266 // ************************************************************************************* 267 // ************************************************************************************* 268 // CompareTo & Equals Stuff 269 // ************************************************************************************* 270 // ************************************************************************************* 271 272 273 /** 274 * Java's {@code interface Comparable<T>} requirements. This does a very simple comparison 275 * using the two field's {@link #name} field. 276 * 277 * @param f Any other {@code Field} to be compared to {@code 'this' Field} 278 * 279 * @return An integer that fulfills Java's {@code Comparable<Field>} interface 280 * requirements. 281 */ 282 public int compareTo(Field f) 283 { return (this == f) ? 0 : this.name.compareTo(f.name); } 284 285 /** 286 * This <I>should be called an "atypical version" of </I> the usual {@code equals(Object 287 * other)} method. This version of equals merely compares the name of the field defined. The 288 * presumption here is that the definition of a 'field' only has meaning - <I>at all</I> - 289 * inside the context of a {@code class, interface, } or {@code enumerated-type} where that 290 * field is defined. Since inside any {@code '.java'} source-code file, there may only be one 291 * field with a given name, this method shall return {@code TRUE} whenever the field being 292 * compared also has the same name. 293 * 294 * @param other This may be any other field. It is <I><B>strongly suggested</B></I> that 295 * {@code 'other'} be a field defined in the same {@code '.java'} source-code file as 296 * {@code 'this'} field. 297 * 298 * @return This method returns {@code TRUE} when {@code 'this'} instance of {@code Field} has 299 * the same {@code 'name'} as the name-field of input-parameter {@code 'other'} 300 */ 301 public boolean equals(Field other) 302 { return this.name.equals(other.name); } 303}