001package Torello.JavaDoc;
002
003
004// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
005// Standard-Java Imports
006// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
007
008import java.io.IOException;
009import java.sql.CallableStatement;
010import java.util.Optional;
011
012
013// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
014// Java-HTML Imports
015// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
016
017import Torello.Java.*;
018
019import static Torello.JavaDoc.PF.*;
020
021import Torello.Java.Additional.Ret4;
022
023
024// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
025// JDUInternal
026// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
027
028import Torello.JDUInternal.Annotations.EntityAnnotations.EntityAnnotationData;
029import Torello.JDUInternal.Parse.HTML.Signature.D1_CallableSignature;
030
031
032// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
033// The new Source-Code Parser: com.sun.source.*
034// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
035
036import com.sun.source.tree.MethodTree;
037
038
039/**
040 * <B CLASS=JDDescLabel>Reflection Class:</B>
041 * 
042 * <BR />Holds all information extracted from <CODE>'&#46;java'</CODE> Source-Files about
043 * Constructor's identified in that file.
044 * 
045 * <EMBED CLASS='external-html' DATA-FILE-ID=JPB_GET_INST>
046 * <EMBED CLASS='external-html' DATA-FILE-ID=JPB_CONSTRUCTOR>
047 * <!-- EMBED CLASS='external-html' DATA-FILE-ID=JPB_DIAGRAM -->
048 */
049@JDHeaderBackgroundImg(EmbedTagFileID={"REFLECTION_EXTENSION"})
050public class Constructor extends Callable
051    implements java.io.Serializable, Comparable<Constructor>, Cloneable
052{
053    /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */
054    public static final long serialVersionUID = 1;
055
056
057    // ********************************************************************************************
058    // ********************************************************************************************
059    // Reference-Hook: com.sun.source.tree
060    // ********************************************************************************************
061    // ********************************************************************************************
062
063
064    /**
065     * <EMBED CLASS='external-html' DATA-FILE-ID=SSTB_HOOK_FIELD>
066     * 
067     * If a user decides to make use of the native Sun/Oracle {@code MethodTree} instance that was
068     * used to build this {@code Constructor} instance, it may be retrieved from this
069     * {@code transient} field.
070     * 
071     * <BR /><BR /><B CLASS=JDDescLabel>{@code MethodTree} Note:</B>
072     * 
073     * <BR />The package {@code com.sun.source.tree} "reuses" or "overloads" the {@code MethodTree}
074     * class.  {@code com.sun.source.tree.MethodTree} can actually represent either a Method, or a
075     * Constructor.
076     * 
077     * <BR /><BR />When a {@code MethodTree} instance is actually representing a constructor, the
078     * name that it uses for the instance will be Java-String {@code '<init>'}, rather than an
079     * actual Method-Name.
080     */
081    public final transient MethodTree methodTree;
082
083
084    // ********************************************************************************************
085    // ********************************************************************************************
086    // Constructor - com.sun.source.tree 
087    // ********************************************************************************************
088    // ********************************************************************************************
089
090
091    /**
092     * <EMBED CLASS="defs" DATA-KIND=Constructor DATA-ENTITY=MethodTree>
093     * <EMBED CLASS='external-html' DATA-FILE-ID=RC_DESCRIPTION>
094     * @param mt <EMBED CLASS='external-html' DATA-FILE-ID=RC_PARAM_TREE>
095     * @param util <EMBED CLASS='external-html' DATA-FILE-ID=RC_PARAM_UTIL>
096     * 
097     * @param constructorName The name of the type (which is also the name of the constructor) has
098     * to be passed here, in order for this constructor to work.
099     */
100    public Constructor(
101            final MethodTree            mt,
102            final EntityAnnotationData  ead,
103            final TreeUtils             util,
104            final String                constructorName
105        )
106    {
107        super(mt, constructorName, Entity.CONSTRUCTOR, ead, util);
108
109        // Only the 2 reference hooks are needed here
110        this.methodTree = mt;
111    }
112
113
114    // ********************************************************************************************
115    // ********************************************************************************************
116    // Constructor: Used Internally by SignatureParse
117    // ********************************************************************************************
118    // ********************************************************************************************
119
120
121    // Ensures that the Version with longer type-information strings is used.
122    // Java Doc often uses longer type strings than is available from the source-code parse
123    // Remember, JavaParser Symbol-Solver doesn't work well, and the Sun/Oracle Parser doesn't have
124    // a linker at all.
125
126    public Constructor(final D1_CallableSignature cSig, final Constructor cFromSourceParser)
127    {
128        // Does the same thing as the loop statement below, but for the "parameterTypes"
129        super(cSig, cFromSourceParser);
130
131        this.methodTree = cFromSourceParser.methodTree;
132    }
133
134    // This is only used to construct a constructor for SYNTHETIC-CONSTRUCTORS.  At the present
135    // moment, that means this is only used when there is a Zero-Argument Constructor that the user
136    // did not actually type into his code, but rather is being auto-added by javac.
137
138    public Constructor(final D1_CallableSignature cSig)
139    {
140        super(cSig, Entity.CONSTRUCTOR);
141
142        this.methodTree = null;
143    }
144
145
146    // ********************************************************************************************
147    // ********************************************************************************************
148    // toString()
149    // ********************************************************************************************
150    // ********************************************************************************************
151
152
153    /**
154     * Generates a string of this constructor, with most information included.
155     * 
156     * <BR /><BR /><B CLASS=JDDescLabel>Reduced Information:</B>
157     * 
158     * <BR />This {@code 'toString'} will not return every piece of information contained by this
159     * class. For example, both the constructor body, and any possible JavaDoc Comments are not
160     * included.  For a more enhanced {@code toString()} method version, invoke the 
161     * {@link #toString(int) toString(PrintFlags)} method which accepts {@link PF Print-Flags}.
162     * 
163     * @return A printable string of this field.
164     * @see PF
165     * @see #toString(int)
166     */
167    public String toString()
168    {
169        return
170            "Name:            [" + name + "]\n" +
171            "Signature:       [" + StrPrint.abbrevEndRDSF(signature, MAX_STR_LEN, true) + "]\n" +
172            "Modifiers:       [" + StrCSV.toCSV(modifiers, true, true, null) + "]\n" +
173            printedParameterNamesTS() +
174            printedParameterTypesTS() +
175            printedExceptionsTS() +
176
177            // This will **NEVER** be null - unless 'this' instance was built from an HTML File,
178            // rather than a source-code file.  Instances like that are only used temporarily, and
179            // are garbage collected instantly.  Do this check anyway (just in case).
180
181            "Location:        " + ((this.location == null)
182                ? "null" 
183                : ('[' + this.location.quickSummary() + ']'));
184    }
185
186    /**
187     * <EMBED CLASS='external-html' DATA-FILE-ID=TO_STR_PF>
188     * @param flags These are defined in the {@link PF Print-Flags} class
189     * @return A printable {@code String} of this {@code Constructor}.
190     * @see #toString()
191     * @see PF
192     */
193    public String toString(int flags)
194    {
195        boolean color = (flags & UNIX_COLORS) > 0;
196
197        return
198            printedName("Constructor", 20, color) + 
199            printedSignature(20, color) +
200            printedModifiers(20) +
201            printedParamNames() + 
202            printedParamTypes(jowFlags(flags)) +
203            printedExceptions() +
204            printedLocation(20, color, (flags & BRIEF_LOCATION) > 0) +
205
206            // The previous method does not add a '\n' end to the end of the returned string
207            // These are both optional, they add a '\n' AT THE BEGINNING if one of them is included
208
209            printedComments(20, color, (flags & JAVADOC_COMMENTS) > 0) +
210            printedCallableBody(flags);
211    }
212
213
214    // ********************************************************************************************
215    // ********************************************************************************************
216    //  CompareTo and Equals
217    // ********************************************************************************************
218    // ********************************************************************************************
219
220
221    /**
222     * Java's {@code interface Comparable<T>} requirements.  This looks at the number of
223     * parameters, and parameter types in making a sort-decision.
224     * 
225     * @param c Any other {@code Constructor} to be compared to {@code 'this' Constructor}
226     * 
227     * @return An integer that fulfills Java's {@code Comparable<Constructor>} interface
228     * requirements.
229     */
230    public int compareTo(Constructor c)
231    {
232        if (this == c) return 0;
233
234        int ret = this.numParameters() - c.numParameters();
235        if (ret != 0) return ret;
236
237        if (this.parameterTypesJOW != null)
238
239            for (int i=0; i < this.parameterTypesJOW.size(); i++)
240            {
241                ret = this.parameterTypesJOW.get(i).compareTo(c.parameterTypesJOW.get(i));
242                if (ret != 0) return ret;
243            }
244
245        return 0;
246    }
247
248    /**
249     * This <I>should be called an "atypical version" of</I> the usual
250     * {@code equals(Object other)} constructor.  This version of equals merely compares the name
251     * and parameters-list of the constructor.  The presumption here is that the definition of a
252     * 'constructor' only has meaning - <I>at all</I> - inside the context of a {@code class} or
253     * {@code enumerated-type} where that constructor is defined. Since inside any {@code '.java'}
254     * source-code file, there may only be one constructor with a given parameter-list, this shall
255     * return {@code TRUE} whenever the constructor being compared has the same parameter types as
256     * {@code 'this'} does.
257     * 
258     * @param other This may be any other constructor.  It is <I><B>strongly suggested</B></I> that
259     * this be a constructor defined in the same {@code '.java'} source-code file as 'this'
260     * constructor.
261     * 
262     * @return This method returns {@code TRUE} when 'this' instance of Constructor has the same
263     * parameter-list as {@code 'other'}.
264     */
265    public boolean equals(Constructor other)
266    {
267        // If the number of parameters in the 'other' instance of Constructor differ from the
268        // number of parameters in 'this' Constructor, then return FALSE immediately.  It cannot be
269        // a match
270
271        if (this.numParameters() != other.numParameters()) return false;
272
273        // If there are no parameters (for either of them), then return true immediately
274        if (this.numParameters() == 0) return true;
275
276        // If any of the parameter-names are different, break immediately and return false;
277        for (int i=0; i < this.parameterNames.size(); i++)
278            if (! this.parameterNames.get(i).equals(other.parameterNames.get(i)))
279                return false;
280
281    
282        // If the parameter-types listed by the javadoc '.html' file differ from parameter-types
283        // listed in the original '.java' source-code file, then break immediately.
284        //
285        // NOTE: The "package-information" for the FULL CLASS OR INTERFACE NAME is not always
286        // available.
287
288        for (int i=0; i < this.parameterTypes.size(); i++)
289            if (! this.parameterTypesJOW.get(i).equals(other.parameterTypesJOW.get(i)))
290                return false;
291
292        // ALL TESTS PASSED
293        return true;
294    }
295}