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