public ParamTagInfo[] paramTags() { if (mParamTags == null) { final int N = mParameters.size(); String[] names = new String[N]; String[] comments = new String[N]; SourcePositionInfo[] positions = new SourcePositionInfo[N]; // get the right names so we can handle our names being different from // our parent's names. int i = 0; for (ParameterInfo param : mParameters) { names[i] = param.name(); comments[i] = ""; positions[i] = param.position(); i++; } // gather our comments, and complain about misnamed @param tags for (ParamTagInfo tag : comment().paramTags()) { int index = indexOfParam(tag.parameterName(), names); if (index >= 0) { comments[index] = tag.parameterComment(); positions[index] = tag.position(); } else { Errors.error( Errors.UNKNOWN_PARAM_TAG_NAME, tag.position(), "@param tag with name that doesn't match the parameter list: '" + tag.parameterName() + "'"); } } // get our parent's tags to fill in the blanks MethodInfo overridden = this.findOverriddenMethod(name(), signature()); if (overridden != null) { ParamTagInfo[] maternal = overridden.paramTags(); for (i = 0; i < N; i++) { if (comments[i].equals("")) { comments[i] = maternal[i].parameterComment(); positions[i] = maternal[i].position(); } } } // construct the results, and cache them for next time mParamTags = new ParamTagInfo[N]; for (i = 0; i < N; i++) { mParamTags[i] = new ParamTagInfo( "@param", "@param", names[i] + " " + comments[i], parent(), positions[i]); // while we're here, if we find any parameters that are still undocumented at this // point, complain. (this warning is off by default, because it's really, really // common; but, it's good to be able to enforce it) if (comments[i].equals("")) { Errors.error( Errors.UNDOCUMENTED_PARAMETER, positions[i], "Undocumented parameter '" + names[i] + "' on method '" + name() + "'"); } } } return mParamTags; }