Lines Matching refs:clazz

54     def __init__(self, clazz, line, raw, blame):
55 self.clazz = clazz
80 def __init__(self, clazz, line, raw, blame):
81 self.clazz = clazz
170 clazz = None
189 if clazz and clazz_cb:
190 clazz_cb(clazz)
191 clazz = Class(pkg, line, raw, blame)
193 api[clazz.fullname] = clazz
195 clazz.ctors.append(Method(clazz, line, raw, blame))
197 clazz.methods.append(Method(clazz, line, raw, blame))
199 clazz.fields.append(Field(clazz, line, raw, blame))
202 if clazz and clazz_cb:
203 clazz_cb(clazz)
209 def __init__(self, sig, clazz, detail, error, rule, msg):
222 self.line = clazz.line
223 blame = clazz.blame
228 dump += "\n in " + repr(clazz)
229 dump += "\n in " + repr(clazz.pkg)
242 def _fail(clazz, detail, error, rule, msg):
246 sig = "%s-%s-%s" % (clazz.fullname, repr(detail), msg)
249 failures[sig] = Failure(sig, clazz, detail, error, rule, msg)
252 def warn(clazz, detail, rule, msg):
253 _fail(clazz, detail, False, rule, msg)
255 def error(clazz, detail, rule, msg):
256 _fail(clazz, detail, True, rule, msg)
259 def verify_constants(clazz):
261 if re.match("android\.R\.[a-z]+", clazz.fullname): return
262 if clazz.fullname.startswith("android.os.Build"): return
263 if clazz.fullname == "android.system.OsConstants": return
266 for f in clazz.fields:
269 error(clazz, f, "C2", "Constant field names must be FOO_NAME")
272 warn(clazz, f, "C8", "If min/max could change in future, make them dynamic methods")
274 error(clazz, f, None, "All constants must be defined at compile time")
277 def verify_enums(clazz):
279 if "extends java.lang.Enum" in clazz.raw:
280 error(clazz, None, "F5", "Enums are not allowed")
283 def verify_class_names(clazz):
285 if clazz.fullname.startswith("android.opengl"): return
286 if clazz.fullname.startswith("android.renderscript"): return
287 if re.match("android\.R\.[a-z]+", clazz.fullname): return
289 if re.search("[A-Z]{2,}", clazz.name) is not None:
290 warn(clazz, None, "S1", "Class names with acronyms should be Mtp not MTP")
291 if re.match("[^A-Z]", clazz.name):
292 error(clazz, None, "S1", "Class must start with uppercase char")
295 def verify_method_names(clazz):
297 if clazz.fullname.startswith("android.opengl"): return
298 if clazz.fullname.startswith("android.renderscript"): return
299 if clazz.fullname == "android.system.OsConstants": return
301 for m in clazz.methods:
303 warn(clazz, m, "S1", "Method names with acronyms should be getMtu() instead of getMTU()")
305 error(clazz, m, "S1", "Method name must start with lowercase char")
308 def verify_callbacks(clazz):
312 if clazz.fullname == "android.speech.tts.SynthesisCallback": return
314 if clazz.name.endswith("Callbacks"):
315 error(clazz, None, "L1", "Callback class names should be singular")
316 if clazz.name.endswith("Observer"):
317 warn(clazz, None, "L1", "Class should be named FooCallback")
319 if clazz.name.endswith("Callback"):
320 if "interface" in clazz.split:
321 error(clazz, None, "CL3", "Callbacks must be abstract class to enable extension in future API levels")
323 for m in clazz.methods:
325 error(clazz, m, "L1", "Callback method names must be onFoo() style")
328 def verify_listeners(clazz):
335 if clazz.name.endswith("Listener"):
336 if " abstract class " in clazz.raw:
337 error(clazz, None, "L1", "Listeners should be an interface, or otherwise renamed Callback")
339 for m in clazz.methods:
341 error(clazz, m, "L1", "Listener method names must be onFoo() style")
343 if len(clazz.methods) == 1 and clazz.name.startswith("On"):
344 m = clazz.methods[0]
345 if (m.name + "Listener").lower() != clazz.name.lower():
346 error(clazz, m, "L1", "Single listener method name must match class name")
349 def verify_actions(clazz):
356 for f in clazz.fields:
365 error(clazz, f, "C3", "Intent action constant name must be ACTION_FOO")
367 if clazz.fullname == "android.content.Intent":
369 elif clazz.fullname == "android.provider.Settings":
371 elif clazz.fullname == "android.app.admin.DevicePolicyManager" or clazz.fullname == "android.app.admin.DeviceAdminReceiver":
374 prefix = clazz.pkg.name + ".action"
377 error(clazz, f, "C4", "Inconsistent action value; expected %s" % (expected))
380 def verify_extras(clazz):
387 if clazz.fullname == "android.app.Notification": return
388 if clazz.fullname == "android.appwidget.AppWidgetManager": return
390 for f in clazz.fields:
397 error(clazz, f, "C3", "Intent extra must be EXTRA_FOO")
399 if clazz.pkg.name == "android.content" and clazz.name == "Intent":
401 elif clazz.pkg.name == "android.app.admin":
404 prefix = clazz.pkg.name + ".extra"
407 error(clazz, f, "C4", "Inconsistent extra value; expected %s" % (expected))
410 def verify_equals(clazz):
414 for m in clazz.methods:
419 error(clazz, None, "M8", "Must override both equals and hashCode; missing one")
422 def verify_parcelable(clazz):
424 if "implements android.os.Parcelable" in clazz.raw:
425 creator = [ i for i in clazz.fields if i.name == "CREATOR" ]
426 write = [ i for i in clazz.methods if i.name == "writeToParcel" ]
427 describe = [ i for i in clazz.methods if i.name == "describeContents" ]
430 error(clazz, None, "FW3", "Parcelable requires CREATOR, writeToParcel, and describeContents; missing one")
432 if " final class " not in clazz.raw:
433 error(clazz, None, "FW8", "Parcelable classes must be final")
436 def verify_protected(clazz):
438 for m in clazz.methods:
440 error(clazz, m, "M7", "Protected methods not allowed; must be public")
441 for f in clazz.fields:
443 error(clazz, f, "M7", "Protected fields not allowed; must be public")
446 def verify_fields(clazz):
468 for f in clazz.fields:
470 if clazz.fullname in IGNORE_BARE_FIELDS:
472 elif clazz.fullname.endswith("LayoutParams"):
474 elif clazz.fullname.startswith("android.util.Mutable"):
477 error(clazz, f, "F2", "Bare fields must be marked final, or add accessors if mutable")
481 error(clazz, f, "S1", "Non-static fields must be named using myField style")
484 error(clazz, f, "F1", "Internal objects must not be exposed")
488 error(clazz, f, "C2", "Constants must be marked static final")
491 def verify_register(clazz):
495 methods = [ m.name for m in clazz.methods ]
496 for m in clazz.methods:
501 error(clazz, m, "L2", "Missing unregister method")
505 error(clazz, m, "L2", "Missing register method")
508 error(clazz, m, "L3", "Callback methods should be named register/unregister")
514 error(clazz, m, "L2", "Missing remove method")
518 error(clazz, m, "L2", "Missing add method")
521 error(clazz, m, "L3", "Listener methods should be named add/remove")
524 def verify_sync(clazz):
526 for m in clazz.methods:
528 error(clazz, m, "M5", "Internal locks must not be exposed")
531 def verify_intent_builder(clazz):
533 if clazz.name == "Intent": return
535 for m in clazz.methods:
540 warn(clazz, m, "FW1", "Methods creating an Intent should be named createFooIntent()")
543 def verify_helper_classes(clazz):
547 if "extends android.app.Service" in clazz.raw:
549 if not clazz.name.endswith("Service"):
550 error(clazz, None, "CL4", "Inconsistent class name; should be FooService")
553 for f in clazz.fields:
556 if f.value != clazz.fullname:
557 error(clazz, f, "C4", "Inconsistent interface constant; expected %s" % (clazz.fullname))
559 if "extends android.content.ContentProvider" in clazz.raw:
561 if not clazz.name.endswith("Provider"):
562 error(clazz, None, "CL4", "Inconsistent class name; should be FooProvider")
565 for f in clazz.fields:
568 if f.value != clazz.fullname:
569 error(clazz, f, "C4", "Inconsistent interface constant; expected %s" % (clazz.fullname))
571 if "extends android.content.BroadcastReceiver" in clazz.raw:
573 if not clazz.name.endswith("Receiver"):
574 error(clazz, None, "CL4", "Inconsistent class name; should be FooReceiver")
576 if "extends android.app.Activity" in clazz.raw:
578 if not clazz.name.endswith("Activity"):
579 error(clazz, None, "CL4", "Inconsistent class name; should be FooActivity")
582 for m in clazz.methods:
586 warn(clazz, m, None, "Methods implemented by developers should be named onFoo()")
588 warn(clazz, m, None, "If implemented by developer, should be named onFoo(); otherwise consider marking final")
591 def verify_builder(clazz):
594 if " extends " in clazz.raw: return
595 if not clazz.name.endswith("Builder"): return
597 if clazz.name != "Builder":
598 warn(clazz, None, None, "Builder should be defined as inner class")
601 for m in clazz.methods:
610 warn(clazz, m, None, "Builder methods names should use setFoo() style")
613 if not m.typ.endswith(clazz.fullname):
614 warn(clazz, m, "M4", "Methods must return the builder object")
617 warn(clazz, None, None, "Missing build() method")
620 def verify_aidl(clazz):
622 if "extends android.os.Binder" in clazz.raw or "implements android.os.IInterface" in clazz.raw:
623 error(clazz, None, None, "Raw AIDL interfaces must not be exposed")
626 def verify_internal(clazz):
628 if clazz.pkg.name.startswith("com.android"):
629 error(clazz, None, None, "Internal classes must not be exposed")
632 def verify_layering(clazz):
658 cr = rank(clazz.pkg.name)
661 for f in clazz.fields:
664 warn(clazz, f, "FW6", "Field type violates package layering")
666 for m in clazz.methods:
669 warn(clazz, m, "FW6", "Method return type violates package layering")
673 warn(clazz, m, "FW6", "Method argument type violates package layering")
676 def verify_boolean(clazz):
683 gets = [ m for m in clazz.methods if is_get(m) ]
684 sets = [ m for m in clazz.methods if is_set(m) ]
689 error(clazz, m, "M6", "Symmetric method for %s must be named %s" % (trigger, expected))
691 for m in clazz.methods:
716 def verify_collections(clazz):
718 if clazz.fullname == "android.os.Bundle": return
722 for m in clazz.methods:
724 error(clazz, m, "CL2", "Return type is concrete collection; must be higher-level interface")
727 error(clazz, m, "CL2", "Argument is concrete collection; must be higher-level interface")
730 def verify_flags(clazz):
733 for f in clazz.fields:
742 warn(clazz, f, "C1", "Found overlapping flag constant value")
746 def verify_exception(clazz):
748 for m in clazz.methods:
750 error(clazz, m, "S1", "Methods must not throw generic exceptions")
753 if clazz.name == "android.content.ContentProviderClient": continue
754 if clazz.name == "android.os.Binder": continue
755 if clazz.name == "android.os.IBinder": continue
757 error(clazz, m, "FW9", "Methods calling into system server should rethrow RemoteException as RuntimeException")
760 def verify_google(clazz):
763 if re.search("google", clazz.raw, re.IGNORECASE):
764 error(clazz, None, None, "Must never reference Google")
767 test.extend(clazz.ctors)
768 test.extend(clazz.fields)
769 test.extend(clazz.methods)
773 error(clazz, t, None, "Must never reference Google")
776 def verify_bitset(clazz):
779 for f in clazz.fields:
781 error(clazz, f, None, "Field type must not be heavy BitSet")
783 for m in clazz.methods:
785 error(clazz, m, None, "Return type must not be heavy BitSet")
788 error(clazz, m, None, "Argument type must not be heavy BitSet")
791 def verify_manager(clazz):
794 if not clazz.name.endswith("Manager"): return
796 for c in clazz.ctors:
797 error(clazz, c, None, "Managers must always be obtained from Context; no direct constructors")
799 for m in clazz.methods:
800 if m.typ == clazz.fullname:
801 error(clazz, m, None, "Managers must always be obtained from Context")
804 def verify_boxed(clazz):
809 for c in clazz.ctors:
812 error(clazz, c, "M11", "Must avoid boxed primitives")
814 for f in clazz.fields:
816 error(clazz, f, "M11", "Must avoid boxed primitives")
818 for m in clazz.methods:
820 error(clazz, m, "M11", "Must avoid boxed primitives")
823 error(clazz, m, "M11", "Must avoid boxed primitives")
826 def verify_static_utils(clazz):
828 if clazz.fullname.startswith("android.opengl"): return
829 if clazz.fullname.startswith("android.R"): return
832 if len(clazz.ctors) == 1 and len(clazz.ctors[0].args) == 0:
834 test.extend(clazz.fields)
835 test.extend(clazz.methods)
842 error(clazz, None, None, "Fully-static utility classes must not have constructor")
845 def verify_overload_args(clazz):
847 if clazz.fullname.startswith("android.opengl"): return
850 for m in clazz.methods:
878 warn(clazz, m, "M2", "Expected common arguments [%s] at beginning of overloaded method" % (", ".join(common_args)))
882 error(clazz, m, "M2", "Expected consistent argument ordering between overloads: %s..." % (", ".join(locked_sig)))
885 def verify_callback_handlers(clazz):
899 if s in clazz.pkg.name_path: return
900 if s in clazz.extends_path: return
903 if "app" in clazz.pkg.name_path or "app" in clazz.extends_path:
905 if s in clazz.fullname: return
906 if "content" in clazz.pkg.name_path or "content" in clazz.extends_path:
908 if s in clazz.fullname: return
912 for m in clazz.methods:
929 warn(clazz, f, "L1", "Registration methods should have overload that accepts delivery Handler")
932 def verify_context_first(clazz):
934 examine = clazz.ctors + clazz.methods
938 error(clazz, m, "M3", "Context is distinct, so it must be the first argument")
941 error(clazz, m, "M3", "ContentResolver is distinct, so it must be the first argument")
944 def verify_listener_last(clazz):
946 examine = clazz.ctors + clazz.methods
954 warn(clazz, m, "M3", "Listeners should always be at end of argument list")
957 def verify_resource_names(clazz):
959 if not re.match("android\.R\.[a-z]+", clazz.fullname): return
962 if clazz.name in ["anim","animator","color","dimen","drawable","interpolator","layout","transition","menu","mipmap","string","plurals","raw","xml"]:
963 for f in clazz.fields:
965 error(clazz, f, None, "Expected resource name in this class to be foo_bar_baz style")
968 if clazz.name in ["array","attr","id","bool","fraction","integer"]:
969 for f in clazz.fields:
975 error(clazz, f, "C7", "Expected resource name in this class to be fooBarBaz style")
978 if clazz.name in ["style"]:
979 for f in clazz.fields:
981 error(clazz, f, "C7", "Expected resource name in this class to be FooBar_Baz style")
984 def verify_files(clazz):
991 test.extend(clazz.ctors)
992 test.extend(clazz.methods)
1002 warn(clazz, m, "M10", "Methods accepting File should also accept FileDescriptor or streams")
1005 def verify_manager_list(clazz):
1008 if not clazz.name.endswith("Manager"): return
1010 for m in clazz.methods:
1012 warn(clazz, m, None, "Methods should return List<? extends Parcelable> instead of Parcelable[] to support ParceledListSlice under the hood")
1015 def verify_abstract_inner(clazz):
1018 if re.match(".+?\.[A-Z][^\.]+\.[A-Z]", clazz.fullname):
1019 if " abstract " in clazz.raw and " static " not in clazz.raw:
1020 warn(clazz, None, None, "Abstract inner classes should be static to improve testability")
1023 def verify_runtime_exceptions(clazz):
1061 test.extend(clazz.ctors)
1062 test.extend(clazz.methods)
1069 error(clazz, t, None, "Methods must not mention RuntimeException subclasses in throws clauses")
1072 def verify_error(clazz):
1074 if not clazz.extends: return
1075 if clazz.extends.endswith("Error"):
1076 error(clazz, None, None, "Trouble must be reported through an Exception, not Error")
1077 if clazz.extends.endswith("Exception") and not clazz.name.endswith("Exception"):
1078 error(clazz, None, None, "Exceptions must be named FooException")
1081 def verify_units(clazz):
1095 for m in clazz.methods:
1099 error(clazz, m, None, "Expected method name units to be " + v)
1101 warn(clazz, m, None, "Returned time values are strongly encouraged to be in milliseconds unless you need the extra precision")
1103 error(clazz, m, None, "Returned time values must be in milliseconds")
1105 for m in clazz.methods:
1112 error(clazz, m, None, "Fractions must use floats")
1114 error(clazz, m, None, "Percentage must use ints")
1117 def verify_closable(clazz):
1119 if "implements java.lang.AutoCloseable" in clazz.raw: return
1120 if "implements java.io.Closeable" in clazz.raw: return
1122 for m in clazz.methods:
1125 warn(clazz, m, None, "Classes that release resources should implement AutoClosable and CloseGuard")
1129 def examine_clazz(clazz):
1131 if clazz.pkg.name.startswith("java"): return
1132 if clazz.pkg.name.startswith("junit"): return
1133 if clazz.pkg.name.startswith("org.apache"): return
1134 if clazz.pkg.name.startswith("org.xml"): return
1135 if clazz.pkg.name.startswith("org.json"): return
1136 if clazz.pkg.name.startswith("org.w3c"): return
1137 if clazz.pkg.name.startswith("android.icu."): return
1139 verify_constants(clazz)
1140 verify_enums(clazz)
1141 verify_class_names(clazz)
1142 verify_method_names(clazz)
1143 verify_callbacks(clazz)
1144 verify_listeners(clazz)
1145 verify_actions(clazz)
1146 verify_extras(clazz)
1147 verify_equals(clazz)
1148 verify_parcelable(clazz)
1149 verify_protected(clazz)
1150 verify_fields(clazz)
1151 verify_register(clazz)
1152 verify_sync(clazz)
1153 verify_intent_builder(clazz)
1154 verify_helper_classes(clazz)
1155 verify_builder(clazz)
1156 verify_aidl(clazz)
1157 verify_internal(clazz)
1158 verify_layering(clazz)
1159 verify_boolean(clazz)
1160 verify_collections(clazz)
1161 verify_flags(clazz)
1162 verify_exception(clazz)
1163 if not ALLOW_GOOGLE: verify_google(clazz)
1164 verify_bitset(clazz)
1165 verify_manager(clazz)
1166 verify_boxed(clazz)
1167 verify_static_utils(clazz)
1168 verify_overload_args(clazz)
1169 verify_callback_handlers(clazz)
1170 verify_context_first(clazz)
1171 verify_listener_last(clazz)
1172 verify_resource_names(clazz)
1173 verify_files(clazz)
1174 verify_manager_list(clazz)
1175 verify_abstract_inner(clazz)
1176 verify_runtime_exceptions(clazz)
1177 verify_error(clazz)
1178 verify_units(clazz)
1179 verify_closable(clazz)
1206 def ctor_exists(api, clazz, test):
1207 for m in clazz.ctors:
1211 def all_methods(api, clazz):
1212 methods = list(clazz.methods)
1213 if clazz.extends is not None:
1214 methods.extend(all_methods(api, api[clazz.extends]))
1217 def method_exists(api, clazz, test):
1218 methods = all_methods(api, clazz)
1223 def field_exists(api, clazz, test):
1224 for f in clazz.fields: