1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import org.clearsilver.HDF; 18 import org.clearsilver.CS; 19 import java.util.*; 20 import java.io.*; 21 22 public class TodoFile { 23 24 public static final String MISSING = "No description text"; 25 areTagsUseful(InheritedTags tags)26 public static boolean areTagsUseful(InheritedTags tags) { 27 while (tags != null) { 28 if (areTagsUseful(tags.tags())) { 29 return true; 30 } 31 tags = tags.inherited(); 32 } 33 return false; 34 } 35 areTagsUseful(TagInfo[] tags)36 public static boolean areTagsUseful(TagInfo[] tags) { 37 for (TagInfo t: tags) { 38 if ("Text".equals(t.name()) && t.text().trim().length() != 0) { 39 return true; 40 } 41 if ("@inheritDoc".equals(t.name())) { 42 return true; 43 } 44 } 45 return false; 46 } 47 setHDF(HDF data, String base, SourcePositionInfo pos, String name, String descr)48 public static void setHDF(HDF data, String base, SourcePositionInfo pos, String name, 49 String descr) { 50 data.setValue(base + ".pos", pos.toString()); 51 data.setValue(base + ".name", name); 52 data.setValue(base + ".descr", descr); 53 } 54 55 static class PackageStats { 56 String name; 57 public int total; 58 public int errors; 59 } 60 percent(int a, int b)61 public static String percent(int a, int b) { 62 return ""+Math.round((((b-a)/(float)b))*100) + "%"; 63 } 64 writeTodoFile(String filename)65 public static void writeTodoFile(String filename) { 66 HDF data = DroidDoc.makeHDF(); 67 DroidDoc.setPageTitle(data, "Missing Documentation"); 68 TreeMap<String,PackageStats> packageStats = new TreeMap<String,PackageStats>(); 69 70 ClassInfo[] classes = Converter.rootClasses(); 71 Arrays.sort(classes); 72 73 int classIndex = 0; 74 75 for (ClassInfo cl: classes) { 76 if (cl.isHidden()) { 77 continue; 78 } 79 80 String classBase = "classes." + classIndex; 81 82 String base = classBase + ".errors."; 83 int errors = 0; 84 int total = 1; 85 86 if (!areTagsUseful(cl.inlineTags())) { 87 setHDF(data, base + errors, cl.position(), "<class comment>", MISSING); 88 errors++; 89 } 90 91 92 for (MethodInfo m: cl.constructors()) { 93 boolean good = true; 94 total++; 95 if (m.checkLevel()) { 96 if (!areTagsUseful(m.inlineTags())) { 97 setHDF(data, base + errors, m.position(), m.name() + m.prettySignature(), 98 MISSING); 99 good = false; 100 } 101 } 102 if (!good) { 103 errors++; 104 } 105 } 106 107 for (MethodInfo m: cl.selfMethods()) { 108 boolean good = true; 109 total++; 110 if (m.checkLevel()) { 111 if (!areTagsUseful(m.inlineTags())) { 112 setHDF(data, base + errors, m.position(), m.name() + m.prettySignature(), 113 MISSING); 114 good = false; 115 } 116 } 117 if (!good) { 118 errors++; 119 } 120 } 121 122 123 for (FieldInfo f: cl.enumConstants()) { 124 boolean good = true; 125 total++; 126 if (f.checkLevel()) { 127 if (!areTagsUseful(f.inlineTags())) { 128 setHDF(data, base + errors, f.position(), f.name(), MISSING); 129 good = false; 130 } 131 } 132 if (!good) { 133 errors++; 134 } 135 } 136 137 for (FieldInfo f: cl.selfFields()) { 138 boolean good = true; 139 total++; 140 if (f.checkLevel()) { 141 if (!areTagsUseful(f.inlineTags())) { 142 setHDF(data, base + errors, f.position(), f.name(), MISSING); 143 good = false; 144 } 145 } 146 if (!good) { 147 errors++; 148 } 149 } 150 151 if (errors > 0) { 152 data.setValue(classBase + ".qualified", cl.qualifiedName()); 153 data.setValue(classBase + ".errorCount", ""+errors); 154 data.setValue(classBase + ".totalCount", ""+total); 155 data.setValue(classBase + ".percentGood", percent(errors, total)); 156 } 157 158 PackageInfo pkg = cl.containingPackage(); 159 String pkgName = pkg != null ? pkg.name() : ""; 160 PackageStats ps = packageStats.get(pkgName); 161 if (ps == null) { 162 ps = new PackageStats(); 163 ps.name = pkgName; 164 packageStats.put(pkgName, ps); 165 } 166 ps.total += total; 167 ps.errors += errors; 168 169 classIndex++; 170 } 171 172 int allTotal = 0; 173 int allErrors = 0; 174 175 int i = 0; 176 for (PackageStats ps: packageStats.values()) { 177 data.setValue("packages." + i + ".name", ""+ps.name); 178 data.setValue("packages." + i + ".errorCount", ""+ps.errors); 179 data.setValue("packages." + i + ".totalCount", ""+ps.total); 180 data.setValue("packages." + i + ".percentGood", percent(ps.errors, ps.total)); 181 182 allTotal += ps.total; 183 allErrors += ps.errors; 184 185 i++; 186 } 187 188 data.setValue("all.errorCount", ""+allErrors); 189 data.setValue("all.totalCount", ""+allTotal); 190 data.setValue("all.percentGood", percent(allErrors, allTotal)); 191 192 ClearPage.write(data, "todo.cs", filename, true); 193 } 194 } 195 196