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