1 /* 2 * Copyright (C) 2010 Google Inc. 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 package com.google.doclava; 18 19 import com.google.clearsilver.jsilver.data.Data; 20 21 import java.util.*; 22 23 public class TodoFile { 24 25 public static final String MISSING = "No description text"; 26 areTagsUseful(InheritedTags tags)27 public static boolean areTagsUseful(InheritedTags tags) { 28 while (tags != null) { 29 if (areTagsUseful(tags.tags())) { 30 return true; 31 } 32 tags = tags.inherited(); 33 } 34 return false; 35 } 36 areTagsUseful(TagInfo[] tags)37 public static boolean areTagsUseful(TagInfo[] tags) { 38 for (TagInfo t : tags) { 39 if ("Text".equals(t.name()) && t.text().trim().length() != 0) { 40 return true; 41 } 42 if ("@inheritDoc".equals(t.name())) { 43 return true; 44 } 45 } 46 return false; 47 } 48 setHDF(Data data, String base, SourcePositionInfo pos, String name, String descr)49 public static void setHDF(Data data, String base, SourcePositionInfo pos, String name, 50 String descr) { 51 data.setValue(base + ".pos", pos.toString()); 52 data.setValue(base + ".name", name); 53 data.setValue(base + ".descr", descr); 54 } 55 56 static class PackageStats { 57 String name; 58 public int total; 59 public int errors; 60 } 61 percent(int a, int b)62 public static String percent(int a, int b) { 63 return "" + Math.round((((b - a) / (float) b)) * 100) + "%"; 64 } 65 writeTodoFile(String filename)66 public static void writeTodoFile(String filename) { 67 Data data = Doclava.makeHDF(); 68 Doclava.setPageTitle(data, "Missing Documentation"); 69 TreeMap<String, PackageStats> packageStats = new TreeMap<String, PackageStats>(); 70 71 ClassInfo[] classes = Converter.rootClasses(); 72 Arrays.sort(classes); 73 74 int classIndex = 0; 75 76 for (ClassInfo cl : classes) { 77 if (cl.isHiddenOrRemoved()){ 78 continue; 79 } 80 81 String classBase = "classes." + classIndex; 82 83 String base = classBase + ".errors."; 84 int errors = 0; 85 int total = 1; 86 87 if (!areTagsUseful(cl.inlineTags())) { 88 setHDF(data, base + errors, cl.position(), "<class comment>", MISSING); 89 errors++; 90 } 91 92 93 for (MethodInfo m : cl.constructors()) { 94 boolean good = true; 95 total++; 96 if (m.checkLevel()) { 97 if (!areTagsUseful(m.inlineTags())) { 98 setHDF(data, base + errors, m.position(), m.prettySignature(), 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(), MISSING); 113 good = false; 114 } 115 } 116 if (!good) { 117 errors++; 118 } 119 } 120 121 122 for (FieldInfo f : cl.enumConstants()) { 123 boolean good = true; 124 total++; 125 if (f.checkLevel()) { 126 if (!areTagsUseful(f.inlineTags())) { 127 setHDF(data, base + errors, f.position(), f.name(), MISSING); 128 good = false; 129 } 130 } 131 if (!good) { 132 errors++; 133 } 134 } 135 136 for (FieldInfo f : cl.selfFields()) { 137 boolean good = true; 138 total++; 139 if (f.checkLevel()) { 140 if (!areTagsUseful(f.inlineTags())) { 141 setHDF(data, base + errors, f.position(), f.name(), MISSING); 142 good = false; 143 } 144 } 145 if (!good) { 146 errors++; 147 } 148 } 149 150 if (errors > 0) { 151 data.setValue(classBase + ".qualified", cl.qualifiedName()); 152 data.setValue(classBase + ".errorCount", "" + errors); 153 data.setValue(classBase + ".totalCount", "" + total); 154 data.setValue(classBase + ".percentGood", percent(errors, total)); 155 } 156 157 PackageInfo pkg = cl.containingPackage(); 158 String pkgName = pkg != null ? pkg.name() : ""; 159 PackageStats ps = packageStats.get(pkgName); 160 if (ps == null) { 161 ps = new PackageStats(); 162 ps.name = pkgName; 163 packageStats.put(pkgName, ps); 164 } 165 ps.total += total; 166 ps.errors += errors; 167 168 classIndex++; 169 } 170 171 int allTotal = 0; 172 int allErrors = 0; 173 174 int i = 0; 175 for (PackageStats ps : packageStats.values()) { 176 data.setValue("packages." + i + ".name", "" + ps.name); 177 data.setValue("packages." + i + ".errorCount", "" + ps.errors); 178 data.setValue("packages." + i + ".totalCount", "" + ps.total); 179 data.setValue("packages." + i + ".percentGood", percent(ps.errors, ps.total)); 180 181 allTotal += ps.total; 182 allErrors += ps.errors; 183 184 i++; 185 } 186 187 data.setValue("all.errorCount", "" + allErrors); 188 data.setValue("all.totalCount", "" + allTotal); 189 data.setValue("all.percentGood", percent(allErrors, allTotal)); 190 191 ClearPage.write(data, "todo.cs", filename, true); 192 } 193 } 194