12d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// © 2016 and later: Unicode, Inc. and others. 22d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License 3bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert/** 4bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert******************************************************************************* 5bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert* Copyright (C) 2002-2010, International Business Machines Corporation and * 6bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert* others. All Rights Reserved. * 7bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert******************************************************************************* 8bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert*/ 9bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert/** 10bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * This is a tool to check the tags on ICU4J files. In particular, we're looking for: 11bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * 12bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * - methods that have no tags 13bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * - custom tags: @draft, @stable, @internal? 14bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * - standard tags: @since, @deprecated 15bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * 16bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * Syntax of tags: 17bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * '@draft ICU X.X.X' 18bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * '@stable ICU X.X.X' 19bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * '@internal' 20bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * '@since (don't use)' 21bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * '@obsolete ICU X.X.X' 22bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * '@deprecated to be removed in ICU X.X. [Use ...]' 23bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * 24bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * flags names of classes and their members that have no tags or incorrect syntax. 25bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * 26bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * Requires JDK 1.4 or later 27bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * 28bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * Use build.xml 'checktags' ant target, or 29bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * run from directory containing CheckTags.class as follows: 30bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * javadoc -classpath ${JAVA_HOME}/lib/tools.jar -doclet CheckTags -sourcepath ${ICU4J_src} [packagenames] 31bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert */ 32bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 33bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertpackage com.ibm.icu.dev.tool.docs; 34bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 35bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.sun.javadoc.ClassDoc; 36bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.sun.javadoc.ConstructorDoc; 37bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.sun.javadoc.ExecutableMemberDoc; 38bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.sun.javadoc.ProgramElementDoc; 39bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.sun.javadoc.RootDoc; 40bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.sun.javadoc.Tag; 41bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 42bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertpublic class CheckTags { 43bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert RootDoc root; 44bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert boolean log; 45bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert boolean brief; 46bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert boolean isShort; 47bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert DocStack stack = new DocStack(); 48bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 49bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert class DocNode { 50bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private String header; 51bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private boolean printed; 52bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private boolean reportError; 53bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private int errorCount; 54bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 55bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void reset(String header, boolean reportError) { 56bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert this.header = header; 57bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert this.printed = false; 58bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert this.errorCount = 0; 59bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert this.reportError = reportError; 60bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 61bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public String toString() { 62bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return header + 63bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert " printed: " + printed + 64bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert " reportError: " + reportError + 65bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert " errorCount: " + errorCount; 66bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 67bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 68bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 69bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert class DocStack { 70bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private DocNode[] stack; 71bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private int index; 72bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private boolean newline; 73bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 74bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void push(String header, boolean reportError) { 75bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (stack == null) { 76bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert stack = new DocNode[5]; 77bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } else { 78bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (index == stack.length) { 79bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert DocNode[] temp = new DocNode[stack.length * 2]; 80bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert System.arraycopy(stack, 0, temp, 0, index); 81bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert stack = temp; 82bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 83bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 84bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (stack[index] == null) { 85bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert stack[index] = new DocNode(); 86bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 87bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // System.out.println("reset [" + index + "] header: " + header + " report: " + reportError); 88bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert stack[index++].reset(header, reportError); 89bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 90bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 91bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void pop() { 92bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (index == 0) { 93bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert throw new IndexOutOfBoundsException(); 94bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 95bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert --index; 96bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 97bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int ec = stack[index].errorCount; // index already decremented 98bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (ec > 0 || index == 0) { // always report for outermost element 99bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (stack[index].reportError) { 100bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert output("(" + ec + (ec == 1 ? " error" : " errors") + ")", false, true, index); 101bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 102bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 103bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // propagate to parent 104bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (index > 0) { 105bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert stack[index-1].errorCount += ec; 106bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 107bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 108bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (index == 0) { 109bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert System.out.println(); // always since we always report number of errors 110bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 111bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 112bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 113bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void output(String msg, boolean error, boolean newline) { 114bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert output(msg, error, newline, index-1); 115bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 116bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 117bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert void output(String msg, boolean error, boolean newline, int ix) { 118bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert DocNode last = stack[ix]; 119bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (error) { 120bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert last.errorCount += 1; 121bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 122bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 123bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert boolean show = !brief || last.reportError; 124bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // boolean nomsg = show && brief && error; 125bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // System.out.println(">>> " + last + " error: " + error + " show: " + show + " nomsg: " + nomsg); 126bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 127bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (show) { 128bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (isShort || (brief && error)) { 129bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert msg = null; // nuke error messages if we're brief, just report headers and totals 130bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 131bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert for (int i = 0; i <= ix;) { 132bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert DocNode n = stack[i]; 133bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (n.printed) { 134bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (msg != null || !last.printed) { // since index > 0 last is not null 135bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (this.newline && i == 0) { 136bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert System.out.println(); 137bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert this.newline = false; 138bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 139bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert System.out.print(" "); 140bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 141bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert ++i; 142bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } else { 143bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert System.out.print(n.header); 144bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert n.printed = true; 145bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert this.newline = true; 146bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert i = 0; 147bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 148bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 149bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 150bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (msg != null) { 151bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (index == 0 && this.newline) { 152bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert System.out.println(); 153bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 154bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (error) { 155bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert System.out.print("*** "); 156bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 157bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert System.out.print(msg); 158bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 159bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 160bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 161bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert this.newline = newline; 162bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 163bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 164bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 165bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public static boolean start(RootDoc root) { 166bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return new CheckTags(root).run(); 167bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 168bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 169bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public static int optionLength(String option) { 170bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (option.equals("-log")) { 171bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return 1; 172bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } else if (option.equals("-brief")) { 173bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return 1; 174bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } else if (option.equals("-short")) { 175bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return 1; 176bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 177bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return 0; 178bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 179bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 180bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert CheckTags(RootDoc root) { 181bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert this.root = root; 182bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 183bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert String[][] options = root.options(); 184bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert for (int i = 0; i < options.length; ++i) { 185bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert String opt = options[i][0]; 186bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (opt.equals("-log")) { 187bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert this.log = true; 188bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } else if (opt.equals("-brief")) { 189bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert this.brief = true; 190bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } else if (opt.equals("-short")) { 191bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert this.isShort = true; 192bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 193bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 194bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 195bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 196bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert boolean run() { 197bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert doDocs(root.classes(), "Package", true); 198bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return false; 199bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 200bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 201bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final String[] tagKinds = { 202bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert "@internal", "@draft", "@stable", "@since", "@deprecated", "@author", "@see", "@version", 203bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert "@param", "@return", "@throws", "@obsolete", "@exception", "@serial", "@provisional" 204bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert }; 205bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 206bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final int UNKNOWN = -1; 207bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final int INTERNAL = 0; 208bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final int DRAFT = 1; 209bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final int STABLE = 2; 210bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final int SINCE = 3; 211bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final int DEPRECATED = 4; 212bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final int AUTHOR = 5; 213bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final int SEE = 6; 214bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final int VERSION = 7; 215bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final int PARAM = 8; 216bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final int RETURN = 9; 217bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final int THROWS = 10; 218bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final int OBSOLETE = 11; 219bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final int EXCEPTION = 12; 220bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final int SERIAL = 13; 221bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final int PROVISIONAL = 14; 222bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 223bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static int tagKindIndex(String kind) { 224bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert for (int i = 0; i < tagKinds.length; ++i) { 225bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (kind.equals(tagKinds[i])) { 226bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return i; 227bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 228bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 229bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return UNKNOWN; 230bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 231bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 232bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final String[] icuTagNames = { 233bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert "@icu", "@icunote", "@icuenhanced" 234bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert }; 235bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final int ICU = 0; 236bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final int ICUNOTE = 1; 237bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final int ICUENHANCED = 2; 238bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static int icuTagIndex(String name) { 239bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert for (int i = 0; i < icuTagNames.length; ++i) { 240bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (icuTagNames[i].equals(name)) { 241bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return i; 242bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 243bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 244bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return UNKNOWN; 245bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 246bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 247bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert boolean newline = false; 248bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 249bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert void output(String msg, boolean error, boolean newline) { 250bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert stack.output(msg, error, newline); 251bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 252bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 253bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert void log() { 254bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert output(null, false, false); 255bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 256bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 257bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert void logln() { 258bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert output(null, false, true); 259bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 260bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 261bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert void log(String msg) { 262bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert output(msg, false, false); 263bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 264bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 265bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert void logln(String msg) { 266bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert output(msg, false, true); 267bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 268bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 269bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert void err(String msg) { 270bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert output(msg, true, false); 271bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 272bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 273bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert void errln(String msg) { 274bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert output(msg, true, true); 275bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 276bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 277bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert void tagErr(String msg, Tag tag) { 278bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Tag.position() requires JDK 1.4, build.xml tests for this 279bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (msg.length() > 0) { 280bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert msg += ": "; 281bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 282bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert errln(msg + tag.toString() + " [" + tag.position() + "]"); 283bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert }; 284bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 285bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert void tagErr(Tag tag) { 286bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert tagErr("", tag); 287bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 288bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 289bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert void doDocs(ProgramElementDoc[] docs, String header, boolean reportError) { 290bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (docs != null && docs.length > 0) { 291bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert stack.push(header, reportError); 292bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert for (int i = 0; i < docs.length; ++i) { 293bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert doDoc(docs[i]); 294bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 295bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert stack.pop(); 296bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 297bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 298bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 299bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert void doDoc(ProgramElementDoc doc) { 300bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (doc != null && (doc.isPublic() || doc.isProtected()) 301bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert && !(doc instanceof ConstructorDoc && ((ConstructorDoc)doc).isSynthetic())) { 302bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 303bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // unfortunately, in JDK 1.4.1 MemberDoc.isSynthetic is not properly implemented for 304bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // synthetic constructors. So you'll have to live with spurious errors or 'implement' 305bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // the synthetic constructors... 306bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 307bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert boolean isClass = doc.isClass() || doc.isInterface(); 308bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert String header; 309bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (!isShort || isClass) { 310bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert header = "--- "; 311bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } else { 312bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert header = ""; 313bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 314bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert header += (isClass ? doc.qualifiedName() : doc.name()); 315bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (doc instanceof ExecutableMemberDoc) { 316bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert header += ((ExecutableMemberDoc)doc).flatSignature(); 317bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 318bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (!isShort || isClass) { 319bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert header += " ---"; 320bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 321bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert stack.push(header, isClass); 322bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (log) { 323bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert logln(); 324bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 325bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert boolean recurse = doTags(doc); 326bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (recurse && isClass) { 327bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert ClassDoc cdoc = (ClassDoc)doc; 328bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert doDocs(cdoc.fields(), "Fields", !brief); 329bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert doDocs(cdoc.constructors(), "Constructors", !brief); 330bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert doDocs(cdoc.methods(), "Methods", !brief); 331bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 332bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert stack.pop(); 333bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 334bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 335bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 336bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert /** Return true if subelements of this doc should be checked */ 337bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert boolean doTags(ProgramElementDoc doc) { 338bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert boolean foundRequiredTag = false; 339bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert boolean foundDraftTag = false; 340bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert boolean foundProvisionalTag = false; 341bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert boolean foundDeprecatedTag = false; 342bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert boolean foundObsoleteTag = false; 343bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert boolean foundInternalTag = false; 344bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert boolean foundStableTag = false; 345bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert boolean retainAll = false; 346bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 347bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // first check inline tags 348bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert for (Tag tag : doc.inlineTags()) { 349bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int index = icuTagIndex(tag.name()); 350bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (index >= 0) { 351bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert String text = tag.text().trim(); 352bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert switch (index) { 353bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert case ICU: { 354bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (doc.isClass() || doc.isInterface()) { 355bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert tagErr("tag should appear only in member docs", tag); 356bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 357bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } break; 358bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert case ICUNOTE: { 359bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (text.length() > 0) { 360bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert tagErr("tag should not contain text", tag); 361bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 362bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } break; 363bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert case ICUENHANCED: { 364bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (text.length() == 0) { 365bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert tagErr("text should name related jdk class", tag); 366bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 367bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (!(doc.isClass() || doc.isInterface())) { 368bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert tagErr("tag should appear only in class/interface docs", tag); 369bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 370bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } break; 371bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert default: 372bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert tagErr("unrecognized tag index for tag", tag); 373bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert break; 374bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 375bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 376bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 377bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 378bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // next check regular tags 379bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert for (Tag tag : doc.tags()) { 380bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert String kind = tag.kind(); 381bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int ix = tagKindIndex(kind); 382bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 383bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert switch (ix) { 384bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert case UNKNOWN: 385bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert errln("unknown kind: " + kind); 386bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert break; 387bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 388bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert case INTERNAL: 389bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert foundRequiredTag = true; 390bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert foundInternalTag = true; 391bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert break; 392bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 393bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert case DRAFT: 394bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert foundRequiredTag = true; 395bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert foundDraftTag = true; 396bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (tag.text().indexOf("ICU 2.8") != -1 && 397bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert tag.text().indexOf("(retain") == -1) { // catch both retain and retainAll 398bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert tagErr(tag); 399bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert break; 400bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 401bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (tag.text().indexOf("ICU") != 0) { 402bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert tagErr(tag); 403bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert break; 404bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 405bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert retainAll |= (tag.text().indexOf("(retainAll)") != -1); 406bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert break; 407bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 408bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert case PROVISIONAL: 409bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert foundProvisionalTag = true; 410bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert break; 411bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 412bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert case DEPRECATED: 413bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert foundDeprecatedTag = true; 414bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (tag.text().indexOf("ICU") == 0) { 415bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert foundRequiredTag = true; 416bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 417bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert break; 418bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 419bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert case OBSOLETE: 420bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (tag.text().indexOf("ICU") != 0) { 421bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert tagErr(tag); 422bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 423bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert foundObsoleteTag = true; 424bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert foundRequiredTag = true; 425bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert break; 426bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 427bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert case STABLE: 428bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 429bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert String text = tag.text(); 430bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (text.length() != 0 && text.indexOf("ICU") != 0) { 431bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert tagErr(tag); 432bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 433bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert foundRequiredTag = true; 434bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert foundStableTag = true; 435bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 436bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert break; 437bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 438bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert case SINCE: 439bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert tagErr(tag); 440bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert break; 441bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 442bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert case EXCEPTION: 443bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert logln("You really ought to use @throws, you know... :-)"); 444bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 445bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert case AUTHOR: 446bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert case SEE: 447bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert case PARAM: 448bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert case RETURN: 449bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert case THROWS: 450bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert case SERIAL: 451bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert break; 452bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 453bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert case VERSION: 454bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert tagErr(tag); 455bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert break; 456bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 457bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert default: 458bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert errln("unknown index: " + ix); 459bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 460bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 461bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (!foundRequiredTag) { 462bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert errln("missing required tag [" + doc.position() + "]"); 463bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 464bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (foundInternalTag && !foundDeprecatedTag) { 465bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert errln("internal tag missing deprecated"); 466bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 467bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (foundDraftTag && !(foundDeprecatedTag || foundProvisionalTag)) { 468bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert errln("draft tag missing deprecated or provisional"); 469bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 470bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (foundObsoleteTag && !foundDeprecatedTag) { 471bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert errln("obsolete tag missing deprecated"); 472bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 473bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (foundStableTag && foundDeprecatedTag) { 474bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert logln("stable deprecated"); 475bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 476bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 477bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return !retainAll; 478bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 479bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert} 480