1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | package Torello.JavaDoc; // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // Standard-Java Imports // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** import java.io.IOException; import java.util.Optional; // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // Java-HTML Imports // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** import Torello.Java.*; import static Torello.Java.C.*; import static Torello.JavaDoc.PF.*; // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // The new Source-Code Parser: com.sun.source.* // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** import com.sun.source.tree.Tree; import com.sun.source.tree.VariableTree; import com.sun.source.tree.ExpressionTree; /** * * <B STYLE='color:darkred;'>Reflection Class:</B> * * Holds all information extracted from <CODE>'.java'</CODE> Source-Files about Field's * identified in that file. * * <EMBED CLASS='external-html' DATA-FILE-ID=JPB_GET_INST> * <EMBED CLASS='external-html' DATA-FILE-ID=JPB_FIELD> * <EMBED CLASS='external-html' DATA-FILE-ID=JPB_DIAGRAM> */ @JDHeaderBackgroundImg(EmbedTagFileID={"REFLECTION_EXTENSION"}) public class Field extends Declaration implements java.io.Serializable, Comparable<Field>, Cloneable { /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */ protected static final long serialVersionUID = 1; @Override String codeHiLiteString() { return this.signature; } // ******************************************************************************************** // ******************************************************************************************** // Public Fields: The Type, and the Initializer // ******************************************************************************************** // ******************************************************************************************** /** The definition of this field, as a {@code String}. */ public final String definition; /** The type / class of this field, as a {@code String}. */ public final String type; /** * The type / class of this field, as a {@code String}.<BR /><BR /> * <EMBED CLASS='external-html' DATA-FILE-ID=JPB_JOW_TITLE> */ public final String typeJOW; // ******************************************************************************************** // ******************************************************************************************** // Reference-Hook: com.sun.source.tree // ******************************************************************************************** // ******************************************************************************************** /** * <EMBED CLASS='external-html' DATA-FILE-ID=SSTB_HOOK_FIELD> * * If a user decides to make use of the native Sun/Oracle {@code VariableTree} instance that * was used to build this {@code Field} instance, it may be retrieved from this * {@code transient} field. */ public final transient VariableTree variableTree; // ******************************************************************************************** // ******************************************************************************************** // Constructor - com.sun.source.tree // ******************************************************************************************** // ******************************************************************************************** /** * <EMBED CLASS="defs" DATA-KIND=Field DATA-ENTITY=VariableTree> * <EMBED CLASS='external-html' DATA-FILE-ID=RC_DESCRIPTION> * @param vt <EMBED CLASS='external-html' DATA-FILE-ID=RC_PARAM_TREE> * @param util <EMBED CLASS='external-html' DATA-FILE-ID=RC_PARAM_UTIL> */ public Field(VariableTree vt, TreeUtils util) { super( util, // TreeUtils instance (contains all the parser and stuff) vt, // 'Tree' instance vt.getModifiers(), // ModifiersTree: Annotations on the Field & key-words vt.getName().toString(), // Name of the Field Entity.FIELD, // Entity vt.getInitializer() // NEW: Pass the initializer to the 'body' tree-node ); this.type = vt.getType().toString(); this.typeJOW = StrSource.typeToJavaIdentifier(this.type); ExpressionTree initializer = vt.getInitializer(); this.definition = (initializer == null) ? null : util.substring(initializer).trim(); // Reference Hook: This was built using the com.sun.source.tree.VariableTree class this.variableTree = vt; } // ******************************************************************************************** // ******************************************************************************************** // Constructor: Used Internally by SignatureParse // ******************************************************************************************** // ******************************************************************************************** // Ensures that the Version with longer type-information strings is used. // Java Doc often uses longer type strings than is available from the source-code parse // Remember, JavaParser Symbol-Solver doesn't work well, and the Sun/Oracle Parser doesn't have // a linker at all. public Field(Field fFromSourceParser, Field fFromHTMLParser) { // Calls the super 'clone' constructor for Declaration // Java Parser has much more information for everything, except the "Type" // JP elects to leave off the "Package Information" for types - while Java Doc includes // it (**unless** it can provide an <A HREF=...> for the type, then it leaves it off too!) super(fFromSourceParser); // Continuing with: "JP has this info", while Java Doc just leaves this blank. this.definition = fFromSourceParser.definition; // Java Doc always produces "java.lang.String", while JP just gives "String" /// // REMEMBER: JP is lazy when it comes to "Package Information" for types. // Java-Doc includes it often - BUT NOT ALWAYS. (See above comment) // // Remember, though, the rest of the JavaParser fields are filled out, Java Doc // leaves out all the other information that JP retrieves. this.type = (fFromHTMLParser.type.length() > fFromSourceParser.type.length()) ? fFromHTMLParser.type : fFromSourceParser.type; // This should never matter. They must be identical. this.typeJOW = fFromSourceParser.typeJOW; this.variableTree = fFromSourceParser.variableTree; } // ************************************************************************************* // ************************************************************************************* // toString() // ************************************************************************************* // ************************************************************************************* /** * Generates a {@code String} of this field, with all information included. * * @return A printable {@code String} of this field. * * @see StrCSV#toCSV(String[], boolean, boolean, Integer) * @see #toString(int) */ public String toString() { String defStr = (definition == null) ? "null" : StrPrint.abbrevEndRDSF(definition, MAX_STR_LEN, true); return "Name: [" + name + "]\n" + "Declaration: [" + StrPrint.abbrevEndRDSF(signature, MAX_STR_LEN, true) + "]\n" + "Type: [" + type + "]\n" + "Definition: [" + defStr + "]\n" + "Modifiers: [" + StrCSV.toCSV(modifiers, true, true, null) + "]\n" + // This will **NEVER** be null - unless 'this' instance was built from an HTML File, // rather than a source-code file. Instances like that are only used temporarily, and // are garbage collected instantly. Do this check anyway (just in case). "Location: " + ((this.location == null) ? "null" : ('[' + this.location.quickSummary() + ']')); } /** * Generates a {@code String} of this {@code field}, with all information included. This will * also included any content requested by the {@code 'flags'} parameter. For this class * ({@code class Field}), the only additional information printed by this {@code 'toString'} * method is the Java-Doc Comment {@code String}. * * <BR /><BR />This {@code String} may also have UNIX color codes added. * * @param flags These are the {@code toString(...)} flags from class {@code PF} * ("Print Flags"). View available flags listed in class {@link PF}. * * @return A printable {@code String} of this {@code Field}. * * @see PF * @see StrCSV#toCSV(String[], boolean, boolean, Integer) * @see #toString() */ public String toString(int flags) { boolean color = (flags & UNIX_COLORS) > 0; return printedName("Field", 15, color) + printedDeclaration(15, color) + printedType(jowFlags(flags)) + printedDefinition(color) + printedModifiers(15) + printedLocation(15, color, (flags & BRIEF_LOCATION) > 0) + // The previous method does not add a '\n' end to the end of the returned string // This is optional, it adds a '\n' AT THE BEGINNING if it is included printedComments(15, color, (flags & JAVADOC_COMMENTS) > 0); } private String printedType(Torello.Java.Additional.Ret2<Boolean, Boolean> jow) { if (jow.a /*add-JOW*/) return "Type: [" + type + "]\n" + "Type-JOW: [" + typeJOW + "]\n"; else if (jow.b /*only-JOW*/) return "Type-JOW: [" + typeJOW + "]\n"; else return "Type: [" + type + "]\n"; } private String printedDefinition(boolean color) { return (definition == null) ? "Definition: [null]\n" : "Definition: [" + (color ? BGREEN : "") + StrPrint.abbrevEndRDSF(definition, MAX_STR_LEN, true) + (color ? RESET : "") + "]\n"; } // ************************************************************************************* // ************************************************************************************* // CompareTo & Equals Stuff // ************************************************************************************* // ************************************************************************************* /** * Java's {@code interface Comparable<T>} requirements. This does a very simple comparison * using the two field's {@code 'name'} field. * * @param f Any other {@code Field} to be compared to {@code 'this' Field} * * @return An integer that fulfills Java's * {@code interface Comparable<Field> public boolean compareTo(Field f)} method requirements. */ public int compareTo(Field f) { return (this == f) ? 0 : this.name.compareTo(f.name); } /** * This <I>should be called an "atypical version" of </I> the usual {@code equals(Object * other)} method. This version of equals merely compares the name of the field defined. The * presumption here is that the definition of a 'field' only has meaning - <I>at all</I> - * inside the context of a {@code class, interface, } or {@code enumerated-type} where that * field is defined. Since inside any {@code '.java'} source-code file, there may only be one * field with a given name, this method shall return {@code TRUE} whenever the field being * compared also has the same name. * * @param other This may be any other field. It is <I><B>strongly suggested</B></I> that * {@code 'other'} be a field defined in the same {@code '.java'} source-code file as * {@code 'this'} field. * * @return This method returns {@code TRUE} when {@code 'this'} instance of {@code Field} has * the same {@code 'name'} as the name-field of input-parameter {@code 'other'} */ public boolean equals(Field other) { return this.name.equals(other.name); } } |