001package Torello.JavaDoc;
002
003// The "Mirror Class" since Java's Constructors aren't always so pleasant
004import Torello.JDUInternal.Miscellaneous.Location.LocJavaCtorSucks;
005
006
007// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
008// Java-HTML Imports
009// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
010
011import Torello.Java.*;
012
013import static Torello.Java.C.*;
014import static Torello.JavaDoc.PF.*;
015
016
017// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
018// Standard-Java Imports
019// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
020
021import java.util.Optional;
022import java.io.IOException;
023
024
025// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
026// The new Source-Code Parser: com.sun.source.*
027// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
028
029import com.sun.source.tree.Tree;
030import com.sun.source.doctree.DocCommentTree;
031
032/**
033 * Location Information storing line-number, column-number and character-number for items inside
034 * of a Java Source-Code File (a {@code '.java'} file).
035 */
036public class Location implements java.io.Serializable, Cloneable
037{
038    /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */
039    protected static final long serialVersionUID = 1;
040
041
042    // ********************************************************************************************
043    // ********************************************************************************************
044    // This class' public fields
045    // ********************************************************************************************
046    // ********************************************************************************************
047
048
049    /** <EMBED CLASS='external-html' DATA-FILE-ID=LOC_SIG_START_POS> */
050    public final int signatureStartPos;
051
052    /** <EMBED CLASS='external-html' DATA-FILE-ID=LOC_SIG_START_LINE> */
053    public final int signatureStartLine;
054
055    /** <EMBED CLASS='external-html' DATA-FILE-ID=LOC_SIG_START_COL> */
056    public final int signatureStartCol;
057
058
059    /** <EMBED CLASS='external-html' DATA-FILE-ID=LOC_SIG_END_POS> */
060    public final int signatureEndPos;
061
062    /** <EMBED CLASS='external-html' DATA-FILE-ID=LOC_SIG_END_LINE> */
063    public final int signatureEndLine;
064
065    /** <EMBED CLASS='external-html' DATA-FILE-ID=LOC_SIG_END_COL> */
066    public final int signatureEndCol;
067
068
069    /** <EMBED CLASS='external-html' DATA-FILE-ID=LOC_JDC_START_POS> */
070    public final int jdcStartPos;
071
072    /** <EMBED CLASS='external-html' DATA-FILE-ID=LOC_JDC_START_LINE> */
073    public final int jdcStartLine;
074
075    /** <EMBED CLASS='external-html' DATA-FILE-ID=LOC_JDC_START_COL> */
076    public final int jdcStartCol;
077
078
079    /** <EMBED CLASS='external-html' DATA-FILE-ID=LOC_JDC_END_POS> */
080    public final int jdcEndPos;
081
082    /** <EMBED CLASS='external-html' DATA-FILE-ID=LOC_JDC_END_LINE> */
083    public final int jdcEndLine;
084
085    /** <EMBED CLASS='external-html' DATA-FILE-ID=LOC_JDC_END_COL> */
086    public final int jdcEndCol;
087
088
089    /** <EMBED CLASS='external-html' DATA-FILE-ID=LOC_BODY_START_POS> */
090    public final int bodyStartPos;
091
092    /** <EMBED CLASS='external-html' DATA-FILE-ID=LOC_BODY_START_LINE> */
093    public final int bodyStartLine;
094
095    /** <EMBED CLASS='external-html' DATA-FILE-ID=LOC_BODY_START_COL> */
096    public final int bodyStartCol;
097
098
099    /** <EMBED CLASS='external-html' DATA-FILE-ID=LOC_BODY_END_POS> */
100    public final int bodyEndPos;
101
102    /** <EMBED CLASS='external-html' DATA-FILE-ID=LOC_BODY_END_LINE> */
103    public final int bodyEndLine;
104
105    /** <EMBED CLASS='external-html' DATA-FILE-ID=LOC_BODY_END_COL> */
106    public final int bodyEndCol;
107
108
109    // ********************************************************************************************
110    // ********************************************************************************************
111    // Primary-Constructor
112    // ********************************************************************************************
113    // ********************************************************************************************
114
115
116    public Location(LocJavaCtorSucks l)
117    {
118        this.signatureStartPos  = l.signatureStartPos;
119        this.signatureStartLine = l.signatureStartLine;
120        this.signatureStartCol  = l.signatureStartCol;
121    
122        this.signatureEndPos    = l.signatureEndPos;
123        this.signatureEndLine   = l.signatureEndLine;
124        this.signatureEndCol    = l.signatureEndCol;
125    
126        this.jdcStartPos        = l.jdcStartPos;
127        this.jdcStartLine       = l.jdcStartLine;
128        this.jdcStartCol        = l.jdcStartCol;
129    
130        this.jdcEndPos          = l.jdcEndPos;
131        this.jdcEndLine         = l.jdcEndLine;
132        this.jdcEndCol          = l.jdcEndCol;
133    
134        this.bodyStartPos       = l.bodyStartPos;
135        this.bodyStartLine      = l.bodyStartLine;
136        this.bodyStartCol       = l.bodyStartCol;
137    
138        this.bodyEndPos         = l.bodyEndPos;
139        this.bodyEndLine        = l.bodyEndLine;
140        this.bodyEndCol         = l.bodyEndCol;
141    }
142
143
144    // ********************************************************************************************
145    // ********************************************************************************************
146    // Clone & Clone-Constructor
147    // ********************************************************************************************
148    // ********************************************************************************************
149
150
151    private Location(Location l)
152    {
153        this.signatureStartPos  = l.signatureStartPos;
154        this.signatureStartLine = l.signatureStartLine;
155        this.signatureStartCol  = l.signatureStartCol;
156    
157        this.signatureEndPos    = l.signatureEndPos;
158        this.signatureEndLine   = l.signatureEndLine;
159        this.signatureEndCol    = l.signatureEndCol;
160    
161        this.jdcStartPos        = l.jdcStartPos;
162        this.jdcStartLine       = l.jdcStartLine;
163        this.jdcStartCol        = l.jdcStartCol;
164    
165        this.jdcEndPos          = l.jdcEndPos;
166        this.jdcEndLine         = l.jdcEndLine;
167        this.jdcEndCol          = l.jdcEndCol;
168    
169        this.bodyStartPos       = l.bodyStartPos;
170        this.bodyStartLine      = l.bodyStartLine;
171        this.bodyStartCol       = l.bodyStartCol;
172    
173        this.bodyEndPos         = l.bodyEndPos;
174        this.bodyEndLine        = l.bodyEndLine;
175        this.bodyEndCol         = l.bodyEndCol;
176    }
177
178    /**
179     * Standard Java {@code clone()} method
180     * @return Returns a copy of {@code 'this'} instance
181     */
182    public Object clone()
183    { return new Location(this); }
184
185
186    // ********************************************************************************************
187    // ********************************************************************************************
188    // java.lang.Object methods
189    // ********************************************************************************************
190    // ********************************************************************************************
191
192
193    /**
194     * Standard Java {@code toString()} method
195     * @return Returns the contents of this class, as a {@code java.lang.String}
196     */
197    public String toString()
198    {
199        return
200            "signatureStartPos:  " + signatureStartPos + '\n' +
201            "signatureStartLine: " + signatureStartLine + '\n' +
202            "signatureStartCol:  " + signatureStartCol + '\n' +
203    
204            "signatureEndPos:    " + signatureEndPos + '\n' +
205            "signatureEndLine:   " + signatureEndLine + '\n' +
206            "signatureEndCol:    " + signatureEndCol + '\n' +
207    
208            "jdcStartPos:        " + jdcStartPos + '\n' +
209            "jdcStartLine:       " + jdcStartLine + '\n' +
210            "jdcStartCol:        " + jdcStartCol + '\n' +
211    
212            "jdcEndPos:          " + jdcEndPos + '\n' +
213            "jdcEndLine:         " + jdcEndLine + '\n' +
214            "jdcEndCol:          " + jdcEndCol + '\n' +
215    
216            "bodyStartPos:       " + bodyStartPos + '\n' +
217            "bodyStartLine:      " + bodyStartLine + '\n' +
218            "bodyStartCol:       " + bodyStartCol + '\n' +
219    
220            "bodyEndPos:         " + bodyEndPos + '\n' +
221            "bodyEndLine:        " + bodyEndLine + '\n' +
222            "bodyEndCol:         " + bodyEndCol + '\n';
223    }
224
225    /**
226     * Standard Java {@code equals()} method
227     * 
228     * @param other This may be any Java Object, but one that extends class {@code 'Location'}
229     * has the potential to result in a {@code TRUE} evaluation from this method.
230     * 
231     * @return {@code TRUE} if and only if the contents of {@code 'this'} instance are identical to
232     * the contents of {@code 'other'} (and only if {@code 'other'} is actually an instance of
233     * {@code Location}, or extends at least extends it).
234     */
235    public boolean equals(Object other)
236    {
237        if (! Location.class.isAssignableFrom(other.getClass())) return false;
238
239        Location l = (Location) other;
240
241        return
242                (this.signatureStartPos     == l.signatureStartPos)
243            &&  (this.signatureStartLine    == l.signatureStartLine)
244            &&  (this.signatureStartCol     == l.signatureStartCol)
245    
246            &&  (this.signatureEndPos       == l.signatureEndPos)
247            &&  (this.signatureEndLine      == l.signatureEndLine)
248            &&  (this.signatureEndCol       == l.signatureEndCol)
249    
250            &&  (this.jdcStartPos           == l.jdcStartPos)
251            &&  (this.jdcStartLine          == l.jdcStartLine)
252            &&  (this.jdcStartCol           == l.jdcStartCol)
253    
254            &&  (this.jdcEndPos             == l.jdcEndPos)
255            &&  (this.jdcEndLine            == l.jdcEndLine)
256            &&  (this.jdcEndCol             == l.jdcEndCol)
257    
258            &&  (this.bodyStartPos          == l.bodyStartPos)
259            &&  (this.bodyStartLine         == l.bodyStartLine)
260            &&  (this.bodyStartCol          == l.bodyStartCol)
261    
262            &&  (this.bodyEndPos            == l.bodyEndPos)
263            &&  (this.bodyEndLine           == l.bodyEndLine)
264            &&  (this.bodyEndCol            == l.bodyEndCol);
265    }
266
267    /**
268     * Simply invokes the {@code hashCode()} static-method provided by class {@code java.lang.Integer}.
269     * @return a hash code value for this object.
270     */
271    public int hashCode()
272    { return Integer.hashCode(this.signatureStartPos * this.signatureEndPos); }
273
274
275    // ********************************************************************************************
276    // ********************************************************************************************
277    // Specialized toString
278    // ********************************************************************************************
279    // ********************************************************************************************
280
281
282    /**
283     * Generates a {@code String} - with all information available, including any content requested
284     * by the {@code 'flags'} parameter.
285     * 
286     * @param flags These are the {@code toString(...)} flags from class {@code PF}
287     * ("Print Flags"). View available flags listed in class {@link PF}.
288     * 
289     * @param srcFileAsStr This parameter should contain the complete {@code '.java'} source-code
290     * file as a {@code String}.  If you have passed the Print-Flags for requesting that the body
291     * or Java-Doc Comment be output to the returned-{@code String}, this parameter must be passed
292     * a valid copy of the {@code '.java'} File.
293     * 
294     * <BR /><BR />This parameter may be null, and if it is it will be ignored.  When null is
295     * passed to this parameter, the actual Body, Java-Doc Comment &amp; Signature simply cannot
296     * be extracted, and the output of this {@code toString} method shall only print the location
297     * numbers, column's and line-numbers instead.
298     * 
299     * <BR /><BR />If a valid copy of the contents of the {@code '.java'} file that produced
300     * {@code 'this'} instance of {@code Location} is passed <B STYLE='color: red;'><I>and</I></B>
301     * if the appropriate Print-Flags are passed tot he {@code 'flags'} parameter requesting that
302     * the specified-elements (signature, comment and body) be output to the
303     * returned-{@code String},  <B STYLE='color: red;'><I>then</I></B> those elements will be 
304     * printed to the output-{@code String}.
305     * 
306     * <BR /><BR /><B>NOTE:</B> If the contents of parameter {@code 'srcFileAsstr'} are not the
307     * exact and un-modified contents of the {@code'.java} file that produced {@code 'this'}
308     * instance of location, then the {@code String} returned will contain erroneous information.
309     * It is even possible that a {@code StringIndexOutOfBoundsException} may be thrown.
310     * 
311     * @return A printable {@code String} of the locations represented by this instance
312     * 
313     * @see PF
314     * @see StrCSV#toCSV(String[], boolean, boolean, Integer)
315     * @see #toString()
316     */
317    public String toString(int flags, String srcFileAsStr)
318    {
319        boolean color       = (flags & UNIX_COLORS) > 0;
320        boolean src         = srcFileAsStr != null;
321        boolean signature   = src;
322        boolean bodyShort   = src && ((flags & BODY_SHORT) > 0);
323        boolean bodyLong    = (! bodyShort) && src && ((flags & BODY) > 0);
324        boolean jdc         = src && ((flags & JAVADOC_COMMENTS) > 0);
325        boolean locShort    = (flags & BRIEF_LOCATION) > 0;
326        int     M_OVER_2    = MAX_STR_LEN / 2;
327
328        if (locShort) return
329
330            (signature
331                ? ("Signature:        " + StrIndent.indentAfter2ndLine
332                    (srcFileAsStr.substring(signatureStartPos, signatureEndPos), 4, true, false) +
333                    '\n')
334                : "") +
335
336            "Signature-Start:  " +
337            "pos="  + (color ? BGREEN : "") + signatureStartPos  + (color ? RESET : "") + ", " +
338            "line=" + (color ? BGREEN : "") + signatureStartLine + (color ? RESET : "") + ", " +
339            "col="  + (color ? BGREEN : "") + signatureStartCol  + (color ? RESET : "") + "\n" +
340
341            "Signature-End:    " +
342            "pos="  + (color ? BCYAN : "") + signatureEndPos  + (color ? RESET : "") + ", " +
343            "line=" + (color ? BCYAN : "") + signatureEndLine + (color ? RESET : "") + ", " +
344            "col="  + (color ? BCYAN : "") + signatureEndCol  + (color ? RESET : "") + "\n" +
345
346            (jdc
347                ? ("Java-Doc Comment: " + StrPrint.abbrev(srcFileAsStr.substring
348                    (jdcStartPos, jdcEndPos), M_OVER_2, true, null, MAX_STR_LEN) + '\n')
349                : "") +
350
351            "Java-Doc-Start:   " +
352            "pos="  + (color ? BGREEN : "") + jdcStartPos  + (color ? RESET : "") + ", " +
353            "line=" + (color ? BGREEN : "") + jdcStartLine + (color ? RESET : "") + ", " +
354            "col="  + (color ? BGREEN : "") + jdcStartCol  + (color ? RESET : "") + "\n" +
355
356            "Java-Doc-End:     " +
357            "pos="  + (color ? BCYAN : "") + jdcEndPos  + (color ? RESET : "") + ", " +
358            "line=" + (color ? BCYAN : "") + jdcEndLine + (color ? RESET : "") + ", " +
359            "col="  + (color ? BCYAN : "") + jdcEndCol  + (color ? RESET : "") + "\n" +
360
361            (bodyShort
362                ? ("Body:             " + StrPrint.abbrev(srcFileAsStr.substring
363                    (signatureStartPos, signatureEndPos), M_OVER_2, true, null, MAX_STR_LEN))
364                : "") +
365
366            (bodyLong
367                ? ("Body:             " + StrIndent.indentAfter2ndLine
368                    (srcFileAsStr.substring(signatureStartPos, signatureEndPos), 4, true, false))
369                : "") +
370
371            "Body-Start:       " +
372            "pos="  + (color ? BGREEN : "") + bodyStartPos  + (color ? RESET : "") + ", " +
373            "line=" + (color ? BGREEN : "") + bodyStartLine + (color ? RESET : "") + ", " +
374            "col="  + (color ? BGREEN : "") + bodyStartCol  + (color ? RESET : "") + "\n" +
375
376            "Body-End:         " +
377            "pos="  + (color ? BCYAN : "") + bodyEndPos  + (color ? RESET : "") + ", " +
378            "line=" + (color ? BCYAN : "") + bodyEndLine + (color ? RESET : "") + ", " +
379            "col="  + (color ? BCYAN : "") + bodyEndCol  + (color ? RESET : "");
380
381        else return
382
383            (signature
384                ? ("SIGNATURE: " + StrIndent.indentAfter2ndLine
385                    (srcFileAsStr.substring(signatureStartPos, signatureEndPos), 4, true, false))
386                : "") +
387
388            "signatureStartPos:  " + (color ? BGREEN : "") + signatureStartPos + '\n' +
389                (color ? RESET : "") + 
390            "signatureStartLine: " + (color ? BGREEN : "") + signatureStartLine + '\n' +
391                (color ? RESET : "") + 
392            "signatureStartCol:  " + (color ? BGREEN : "") + signatureStartCol + '\n' +
393                (color ? RESET : "") + 
394    
395            "signatureEndPos:    " + (color ? BCYAN : "") + signatureEndPos + '\n' +
396                (color ? RESET : "") + 
397            "signatureEndLine:   " + (color ? BCYAN : "") + signatureEndLine + '\n' +
398                (color ? RESET : "") + 
399            "signatureEndCol:    " + (color ? BCYAN : "") + signatureEndCol + '\n' +
400                (color ? RESET : "") + 
401
402            (jdc
403                ? ("BODY: " + StrPrint.abbrev(srcFileAsStr.substring
404                    (jdcStartPos, jdcEndPos), M_OVER_2, true, null, MAX_STR_LEN))
405                : "") +
406
407            "jdcStartPos:        " + (color ? BGREEN : "") + jdcStartPos + '\n' +
408                (color ? RESET : "") + 
409            "jdcStartLine:       " + (color ? BGREEN : "") + jdcStartLine + '\n' +
410                (color ? RESET : "") + 
411            "jdcStartCol:        " + (color ? BGREEN : "") + jdcStartCol + '\n' +
412                (color ? RESET : "") + 
413
414            "jdcEndPos:          " + (color ? BCYAN : "") + jdcEndPos + '\n' +
415                (color ? RESET : "") + 
416            "jdcEndLine:         " + (color ? BCYAN : "") + jdcEndLine + '\n' +
417                (color ? RESET : "") + 
418            "jdcEndCol:          " + (color ? BCYAN : "") + jdcEndCol + '\n' +
419                (color ? RESET : "") + 
420
421            (bodyShort
422                ? ("BODY: " + StrPrint.abbrev(srcFileAsStr.substring
423                    (signatureStartPos, signatureEndPos), M_OVER_2, true, null, MAX_STR_LEN))
424                : "") +
425
426            (bodyLong
427                ? ("BODY: " + StrIndent.indentAfter2ndLine
428                    (srcFileAsStr.substring(signatureStartPos, signatureEndPos), 4, true, false))
429                : "") +
430
431            "bodyStartPos:       " + (color ? BGREEN : "") + bodyStartPos +'\n' +
432                (color ? RESET : "") + 
433            "bodyStartLine:      " + (color ? BGREEN : "") + bodyStartLine + '\n' +
434                (color ? RESET : "") +
435            "bodyStartCol:       " + (color ? BGREEN : "") + bodyStartCol + '\n' +
436                (color ? RESET : "") + 
437
438            "bodyEndPos:         " + (color ? BCYAN : "") + bodyEndPos + '\n' +
439                (color ? RESET : "") + 
440            "bodyEndLine:        " + (color ? BCYAN : "") + bodyEndLine + '\n' +
441                (color ? RESET : "") + 
442            "bodyEndCol:         " + (color ? BCYAN : "") + bodyEndCol + '\n' +
443                (color ? RESET : "");
444    }
445
446    /**
447     * Produces a quick-summary, as a {@code String}.
448     * @return a very brief summary of the information contained by this class.  Lists only the
449     * starting line numbers for the three sections.
450     */
451    public String quickSummary()
452    {
453        return "signature-line=" + this.signatureStartLine + ", javadoc-line=" + this.jdcStartLine +
454            ", body-line=" + this.bodyStartLine;        
455    }
456}