package x10doc.doc; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import polyglot.types.LocalDef; import polyglot.types.Ref; import x10.types.ParameterType; import x10.types.X10ConstructorDef; import x10.types.X10MethodDef; import com.sun.javadoc.AnnotationDesc; import com.sun.javadoc.ClassDoc; import com.sun.javadoc.ConstructorDoc; import com.sun.javadoc.PackageDoc; import com.sun.javadoc.ParamTag; import com.sun.javadoc.Parameter; import com.sun.javadoc.Tag; import com.sun.javadoc.ThrowsTag; import com.sun.javadoc.Type; import com.sun.javadoc.TypeVariable; public class X10ConstructorDoc extends X10Doc implements ConstructorDoc { private X10ConstructorDef constrDef; private X10ClassDoc containingClass; private X10RootDoc rootDoc; private ArrayList<X10Parameter> parameters; private Type returnType; private X10TypeVariable[] typeParams; private boolean included; public X10ConstructorDoc() { super(); processComment(""); } public X10ConstructorDoc(X10ConstructorDef constrDef, X10ClassDoc containingClass, String comment) { //super(comment); this.constrDef = constrDef; this.containingClass = containingClass; this.rootDoc = X10RootDoc.getRootDoc(); // the following ensure that methodDef.signature() does not contain <unknown> in place // of formal parameter types; see constructor X10MethodDoc(...) for more details // List<Ref<? extends polyglot.types.Type>> ls = constrDef.formalTypes(); // for (Ref<? extends polyglot.types.Type> ref: ls) { // polyglot.types.Type formalType = ref.get(); // } // type parameters should be initialized before parameter types because the latter may use the former initTypeParameters(); // containingClass.addConstructor(this); // initialize returnType returnType = rootDoc.getType(constrDef.returnType().get(), typeParams); // initialize parameters List<LocalDef> formals = constrDef.formalNames(); int n = ((formals == null) ? 0 : formals.size()); parameters = new ArrayList<X10Parameter>(n); for (LocalDef ld: formals) { String paramName = ld.name().toString(); polyglot.types.Type paramType = ld.type().get(); parameters.add(new X10Parameter(paramName, rootDoc.getType(paramType, typeParams))); } // X10Doc.isIncluded(..., this) valid only if this.{isPublic(),...,isPrivate()} are valid, which requires // this.constrDef to have been set appropriately this.included = X10Doc.isIncluded(rootDoc.accessModFilter(), this); super.processComment(comment); } void initTypeParameters() { // [IP] Constructors don't have type parameters, they inherit them from the container. //List<ParameterType> params = constrDef.typeParameters(); //typeParams = new X10TypeVariable[params.size()]; //int i = 0; //for (ParameterType p: params) { // X10TypeVariable v = new X10TypeVariable(p, this); // // typeParams.put(typeParameterKey(p), v); // typeParams[i++] = v; //} typeParams = new X10TypeVariable[0]; } public X10ConstructorDef getConstructorDef() { return constrDef; } public X10Tag[] getX10Tags() { List<X10Tag> list = new ArrayList<X10Tag>(); addGuardTags(list); return list.toArray(new X10Tag[list.size()]); } public void addDeclTag(String declString) { if (declString == null) { return; } X10Tag[] declTags = createInlineTags(declString, this).toArray(new X10Tag[0]); X10Tag[] tags = getX10Tags(); // place declaration before the first sentence of the existing comment so that // the declaration is displayed in the "Methods Summary" table before the first sentence firstSentenceTags = concat(declTags, firstSentenceTags); inlineTags = concat(concat(declTags, tags), inlineTags); } public String declString() { // the X10 constructor declaration needs to be displayed in the constructors's comments only if a param type, // return type or the constructor is X10-specific if (!(X10Type.isX10Specific(returnType)) && constrDef.guard() == null) { boolean hasConstraints = false; for (X10Parameter p: parameters) { if (p.isX10Specific()) { hasConstraints = true; break; } } if (!hasConstraints) { return ""; } } String guard = (constrDef.guard() == null) ? "" : constrDef.guard().toString(); String result = "<B>Declaration</B>: <TT>" + constrDef.signature() + guard + ": " + constrDef.returnType().toString() + ".</TT><PRE>\n</PRE>"; return result; } @Override public boolean isConstructor() { return true; } @Override public boolean isIncluded() { return included; } @Override public String name() { return containingClass.name(); } public String flatSignature() { return signature(); } public boolean isNative() { return constrDef.flags().isNative(); } public boolean isSynchronized() { return false; } public boolean isVarArgs() { return false; // no variable args. constructors in current X10 implementation } public ParamTag[] paramTags() { // TODO Auto-generated method stub return new ParamTag[0]; } public Parameter[] parameters() { return parameters.toArray(new Parameter[0]); } public String signature() { String sig = constrDef.signature(); return sig.substring(sig.indexOf('(')); } public Type[] thrownExceptionTypes() { return thrownExceptions(); } public ClassDoc[] thrownExceptions() { // TODO: look at the @Throws annotation when we have one // List<Ref<? extends polyglot.types.Type>> throwTypes = constrDef.throwTypes(); // if(throwTypes != null && throwTypes.size() > 0) // { // ClassDoc[] types = new ClassDoc[throwTypes.size()]; // int i = 0; // for(Ref<? extends polyglot.types.Type> type : throwTypes) // { // types[i++] = (ClassDoc)rootDoc.getType(type.get()); // } // // return types; // } return new ClassDoc[0]; } public ThrowsTag[] throwsTags() { Tag[] tags = tags(X10Tag.THROWS); ThrowsTag[] newTags = new ThrowsTag[tags.length]; System.arraycopy(tags, 0, newTags, 0, tags.length); return newTags; } public ParamTag[] typeParamTags() { // TODO Auto-generated method stub return new ParamTag[0]; } public TypeVariable[] typeParameters() { // return typeParams.values().toArray(new TypeVariable[0]); return typeParams; } public TypeVariable getTypeVariable(ParameterType p) { // return typeParams.get(typeParameterKey(p)); return null; } public boolean isSynthetic() { // TODO Auto-generated method stub return false; } public AnnotationDesc[] annotations() { // TODO Auto-generated method stub return new AnnotationDesc[0]; } public ClassDoc containingClass() { return containingClass; } public PackageDoc containingPackage() { return containingClass.containingPackage(); } public boolean isFinal() { return constrDef.flags().isFinal(); } public boolean isPackagePrivate() { return constrDef.flags().isPackage(); } public boolean isPrivate() { return constrDef.flags().isPrivate(); } public boolean isProtected() { return constrDef.flags().isProtected(); } public boolean isPublic() { return constrDef.flags().isPublic(); } public boolean isStatic() { return constrDef.flags().isStatic(); } public int modifierSpecifier() { return X10Doc.flagsToModifierSpecifier(constrDef.flags().flags()); } public String modifiers() { return constrDef.flags().toString(); } public String qualifiedName() { return containingClass.qualifiedName(); } }