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
263 for f in clazz.fields:
266 error(clazz, f, "C2", "Constant field names must be FOO_NAME")
269 warn(clazz, f, "C8", "If min/max could change in future, make them dynamic methods")
272 def verify_enums(clazz):
274 if "extends java.lang.Enum" in clazz.raw:
275 error(clazz, None, "F5", "Enums are not allowed")
278 def verify_class_names(clazz):
280 if clazz.fullname.startswith("android.opengl"): return
281 if clazz.fullname.startswith("android.renderscript"): return
282 if re.match("android\.R\.[a-z]+", clazz.fullname): return
284 if re.search("[A-Z]{2,}", clazz.name) is not None:
285 warn(clazz, None, "S1", "Class names with acronyms should be Mtp not MTP")
286 if re.match("[^A-Z]", clazz.name):
287 error(clazz, None, "S1", "Class must start with uppercase char")
290 def verify_method_names(clazz):
292 if clazz.fullname.startswith("android.opengl"): return
293 if clazz.fullname.startswith("android.renderscript"): return
294 if clazz.fullname == "android.system.OsConstants": return
296 for m in clazz.methods:
298 warn(clazz, m, "S1", "Method names with acronyms should be getMtu() instead of getMTU()")
300 error(clazz, m, "S1", "Method name must start with lowercase char")
303 def verify_callbacks(clazz):
307 if clazz.fullname == "android.speech.tts.SynthesisCallback": return
309 if clazz.name.endswith("Callbacks"):
310 error(clazz, None, "L1", "Callback class names should be singular")
311 if clazz.name.endswith("Observer"):
312 warn(clazz, None, "L1", "Class should be named FooCallback")
314 if clazz.name.endswith("Callback"):
315 if "interface" in clazz.split:
316 error(clazz, None, "CL3", "Callbacks must be abstract class to enable extension in future API levels")
318 for m in clazz.methods:
320 error(clazz, m, "L1", "Callback method names must be onFoo() style")
323 def verify_listeners(clazz):
330 if clazz.name.endswith("Listener"):
331 if " abstract class " in clazz.raw:
332 error(clazz, None, "L1", "Listeners should be an interface, or otherwise renamed Callback")
334 for m in clazz.methods:
336 error(clazz, m, "L1", "Listener method names must be onFoo() style")
338 if len(clazz.methods) == 1 and clazz.name.startswith("On"):
339 m = clazz.methods[0]
340 if (m.name + "Listener").lower() != clazz.name.lower():
341 error(clazz, m, "L1", "Single listener method name must match class name")
344 def verify_actions(clazz):
351 for f in clazz.fields:
359 error(clazz, f, "C3", "Intent action constant name must be ACTION_FOO")
361 if clazz.fullname == "android.content.Intent":
363 elif clazz.fullname == "android.provider.Settings":
365 elif clazz.fullname == "android.app.admin.DevicePolicyManager" or clazz.fullname == "android.app.admin.DeviceAdminReceiver":
368 prefix = clazz.pkg.name + ".action"
371 error(clazz, f, "C4", "Inconsistent action value; expected %s" % (expected))
374 def verify_extras(clazz):
381 if clazz.fullname == "android.app.Notification": return
382 if clazz.fullname == "android.appwidget.AppWidgetManager": return
384 for f in clazz.fields:
391 error(clazz, f, "C3", "Intent extra must be EXTRA_FOO")
393 if clazz.pkg.name == "android.content" and clazz.name == "Intent":
395 elif clazz.pkg.name == "android.app.admin":
398 prefix = clazz.pkg.name + ".extra"
401 error(clazz, f, "C4", "Inconsistent extra value; expected %s" % (expected))
404 def verify_equals(clazz):
406 methods = [ m.name for m in clazz.methods ]
410 error(clazz, None, "M8", "Must override both equals and hashCode; missing one")
413 def verify_parcelable(clazz):
415 if "implements android.os.Parcelable" in clazz.raw:
416 creator = [ i for i in clazz.fields if i.name == "CREATOR" ]
417 write = [ i for i in clazz.methods if i.name == "writeToParcel" ]
418 describe = [ i for i in clazz.methods if i.name == "describeContents" ]
421 error(clazz, None, "FW3", "Parcelable requires CREATOR, writeToParcel, and describeContents; missing one")
423 if " final class " not in clazz.raw:
424 error(clazz, None, "FW8", "Parcelable classes must be final")
427 def verify_protected(clazz):
429 for m in clazz.methods:
431 error(clazz, m, "M7", "Protected methods not allowed; must be public")
432 for f in clazz.fields:
434 error(clazz, f, "M7", "Protected fields not allowed; must be public")
437 def verify_fields(clazz):
455 for f in clazz.fields:
457 if clazz.fullname in IGNORE_BARE_FIELDS:
459 elif clazz.fullname.endswith("LayoutParams"):
461 elif clazz.fullname.startswith("android.util.Mutable"):
464 error(clazz, f, "F2", "Bare fields must be marked final, or add accessors if mutable")
468 error(clazz, f, "S1", "Non-static fields must be named using myField style")
471 error(clazz, f, "F1", "Internal objects must not be exposed")
475 error(clazz, f, "C2", "Constants must be marked static final")
478 def verify_register(clazz):
482 methods = [ m.name for m in clazz.methods ]
483 for m in clazz.methods:
488 error(clazz, m, "L2", "Missing unregister method")
492 error(clazz, m, "L2", "Missing register method")
495 error(clazz, m, "L3", "Callback methods should be named register/unregister")
501 error(clazz, m, "L2", "Missing remove method")
505 error(clazz, m, "L2", "Missing add method")
508 error(clazz, m, "L3", "Listener methods should be named add/remove")
511 def verify_sync(clazz):
513 for m in clazz.methods:
515 error(clazz, m, "M5", "Internal locks must not be exposed")
518 def verify_intent_builder(clazz):
520 if clazz.name == "Intent": return
522 for m in clazz.methods:
527 warn(clazz, m, "FW1", "Methods creating an Intent should be named createFooIntent()")
530 def verify_helper_classes(clazz):
534 if "extends android.app.Service" in clazz.raw:
536 if not clazz.name.endswith("Service"):
537 error(clazz, None, "CL4", "Inconsistent class name; should be FooService")
540 for f in clazz.fields:
543 if f.value != clazz.fullname:
544 error(clazz, f, "C4", "Inconsistent interface constant; expected %s" % (clazz.fullname))
546 if "extends android.content.ContentProvider" in clazz.raw:
548 if not clazz.name.endswith("Provider"):
549 error(clazz, None, "CL4", "Inconsistent class name; should be FooProvider")
552 for f in clazz.fields:
555 if f.value != clazz.fullname:
556 error(clazz, f, "C4", "Inconsistent interface constant; expected %s" % (clazz.fullname))
558 if "extends android.content.BroadcastReceiver" in clazz.raw:
560 if not clazz.name.endswith("Receiver"):
561 error(clazz, None, "CL4", "Inconsistent class name; should be FooReceiver")
563 if "extends android.app.Activity" in clazz.raw:
565 if not clazz.name.endswith("Activity"):
566 error(clazz, None, "CL4", "Inconsistent class name; should be FooActivity")
569 for m in clazz.methods:
573 warn(clazz, m, None, "Methods implemented by developers should be named onFoo()")
575 warn(clazz, m, None, "If implemented by developer, should be named onFoo(); otherwise consider marking final")
578 def verify_builder(clazz):
581 if " extends " in clazz.raw: return
582 if not clazz.name.endswith("Builder"): return
584 if clazz.name != "Builder":
585 warn(clazz, None, None, "Builder should be defined as inner class")
588 for m in clazz.methods:
597 warn(clazz, m, None, "Builder methods names should use setFoo() style")
600 if not m.typ.endswith(clazz.fullname):
601 warn(clazz, m, "M4", "Methods must return the builder object")
604 warn(clazz, None, None, "Missing build() method")
607 def verify_aidl(clazz):
609 if "extends android.os.Binder" in clazz.raw or "implements android.os.IInterface" in clazz.raw:
610 error(clazz, None, None, "Raw AIDL interfaces must not be exposed")
613 def verify_internal(clazz):
615 if clazz.pkg.name.startswith("com.android"):
616 error(clazz, None, None, "Internal classes must not be exposed")
619 def verify_layering(clazz):
645 cr = rank(clazz.pkg.name)
648 for f in clazz.fields:
651 warn(clazz, f, "FW6", "Field type violates package layering")
653 for m in clazz.methods:
656 warn(clazz, m, "FW6", "Method return type violates package layering")
660 warn(clazz, m, "FW6", "Method argument type violates package layering")
663 def verify_boolean(clazz):
670 gets = [ m for m in clazz.methods if is_get(m) ]
671 sets = [ m for m in clazz.methods if is_set(m) ]
676 error(clazz, m, "M6", "Symmetric method for %s must be named %s" % (trigger, expected))
678 for m in clazz.methods:
703 def verify_collections(clazz):
705 if clazz.fullname == "android.os.Bundle": return
709 for m in clazz.methods:
711 error(clazz, m, "CL2", "Return type is concrete collection; must be higher-level interface")
714 error(clazz, m, "CL2", "Argument is concrete collection; must be higher-level interface")
717 def verify_flags(clazz):
720 for f in clazz.fields:
729 warn(clazz, f, "C1", "Found overlapping flag constant value")
733 def verify_exception(clazz):
735 for m in clazz.methods:
737 error(clazz, m, "S1", "Methods must not throw generic exceptions")
740 if clazz.name == "android.content.ContentProviderClient": continue
741 if clazz.name == "android.os.Binder": continue
742 if clazz.name == "android.os.IBinder": continue
744 error(clazz, m, "FW9", "Methods calling into system server should rethrow RemoteException as RuntimeException")
747 def verify_google(clazz):
750 if re.search("google", clazz.raw, re.IGNORECASE):
751 error(clazz, None, None, "Must never reference Google")
754 test.extend(clazz.ctors)
755 test.extend(clazz.fields)
756 test.extend(clazz.methods)
760 error(clazz, t, None, "Must never reference Google")
763 def verify_bitset(clazz):
766 for f in clazz.fields:
768 error(clazz, f, None, "Field type must not be heavy BitSet")
770 for m in clazz.methods:
772 error(clazz, m, None, "Return type must not be heavy BitSet")
775 error(clazz, m, None, "Argument type must not be heavy BitSet")
778 def verify_manager(clazz):
781 if not clazz.name.endswith("Manager"): return
783 for c in clazz.ctors:
784 error(clazz, c, None, "Managers must always be obtained from Context; no direct constructors")
787 def verify_boxed(clazz):
792 for c in clazz.ctors:
795 error(clazz, c, "M11", "Must avoid boxed primitives")
797 for f in clazz.fields:
799 error(clazz, f, "M11", "Must avoid boxed primitives")
801 for m in clazz.methods:
803 error(clazz, m, "M11", "Must avoid boxed primitives")
806 error(clazz, m, "M11", "Must avoid boxed primitives")
809 def verify_static_utils(clazz):
811 if clazz.fullname.startswith("android.opengl"): return
812 if re.match("android\.R\.[a-z]+", clazz.fullname): return
814 if len(clazz.fields) > 0: return
815 if len(clazz.methods) == 0: return
817 for m in clazz.methods:
822 if len(clazz.ctors) > 0:
823 error(clazz, None, None, "Fully-static utility classes must not have constructor")
826 def verify_overload_args(clazz):
828 if clazz.fullname.startswith("android.opengl"): return
831 for m in clazz.methods:
859 warn(clazz, m, "M2", "Expected common arguments [%s] at beginning of overloaded method" % (", ".join(common_args)))
863 error(clazz, m, "M2", "Expected consistent argument ordering between overloads: %s..." % (", ".join(locked_sig)))
866 def verify_callback_handlers(clazz):
880 if s in clazz.pkg.name_path: return
881 if s in clazz.extends_path: return
884 if "app" in clazz.pkg.name_path or "app" in clazz.extends_path:
886 if s in clazz.fullname: return
887 if "content" in clazz.pkg.name_path or "content" in clazz.extends_path:
889 if s in clazz.fullname: return
893 for m in clazz.methods:
910 warn(clazz, f, "L1", "Registration methods should have overload that accepts delivery Handler")
913 def verify_context_first(clazz):
915 examine = clazz.ctors + clazz.methods
919 error(clazz, m, "M3", "Context is distinct, so it must be the first argument")
922 def verify_listener_last(clazz):
924 examine = clazz.ctors + clazz.methods
932 warn(clazz, m, "M3", "Listeners should always be at end of argument list")
935 def verify_resource_names(clazz):
937 if not re.match("android\.R\.[a-z]+", clazz.fullname): return
940 if clazz.name in ["anim","animator","color","dimen","drawable","interpolator","layout","transition","menu","mipmap","string","plurals","raw","xml"]:
941 for f in clazz.fields:
943 error(clazz, f, None, "Expected resource name in this class to be foo_bar_baz style")
946 if clazz.name in ["array","attr","id","bool","fraction","integer"]:
947 for f in clazz.fields:
953 error(clazz, f, "C7", "Expected resource name in this class to be fooBarBaz style")
956 if clazz.name in ["style"]:
957 for f in clazz.fields:
959 error(clazz, f, "C7", "Expected resource name in this class to be FooBar_Baz style")
962 def verify_files(clazz):
969 test.extend(clazz.ctors)
970 test.extend(clazz.methods)
980 warn(clazz, m, "M10", "Methods accepting File should also accept FileDescriptor or streams")
983 def verify_manager_list(clazz):
986 if not clazz.name.endswith("Manager"): return
988 for m in clazz.methods:
990 warn(clazz, m, None, "Methods should return List<? extends Parcelable> instead of Parcelable[] to support ParceledListSlice under the hood")
993 def examine_clazz(clazz):
995 if clazz.pkg.name.startswith("java"): return
996 if clazz.pkg.name.startswith("junit"): return
997 if clazz.pkg.name.startswith("org.apache"): return
998 if clazz.pkg.name.startswith("org.xml"): return
999 if clazz.pkg.name.startswith("org.json"): return
1000 if clazz.pkg.name.startswith("org.w3c"): return
1001 if clazz.pkg.name.startswith("android.icu."): return
1003 verify_constants(clazz)
1004 verify_enums(clazz)
1005 verify_class_names(clazz)
1006 verify_method_names(clazz)
1007 verify_callbacks(clazz)
1008 verify_listeners(clazz)
1009 verify_actions(clazz)
1010 verify_extras(clazz)
1011 verify_equals(clazz)
1012 verify_parcelable(clazz)
1013 verify_protected(clazz)
1014 verify_fields(clazz)
1015 verify_register(clazz)
1016 verify_sync(clazz)
1017 verify_intent_builder(clazz)
1018 verify_helper_classes(clazz)
1019 verify_builder(clazz)
1020 verify_aidl(clazz)
1021 verify_internal(clazz)
1022 verify_layering(clazz)
1023 verify_boolean(clazz)
1024 verify_collections(clazz)
1025 verify_flags(clazz)
1026 verify_exception(clazz)
1027 if not ALLOW_GOOGLE: verify_google(clazz)
1028 verify_bitset(clazz)
1029 verify_manager(clazz)
1030 verify_boxed(clazz)
1031 verify_static_utils(clazz)
1032 verify_overload_args(clazz)
1033 verify_callback_handlers(clazz)
1034 verify_context_first(clazz)
1035 verify_listener_last(clazz)
1036 verify_resource_names(clazz)
1037 verify_files(clazz)
1038 verify_manager_list(clazz)
1065 def ctor_exists(api, clazz, test):
1066 for m in clazz.ctors:
1070 def all_methods(api, clazz):
1071 methods = list(clazz.methods)
1072 if clazz.extends is not None:
1073 methods.extend(all_methods(api, api[clazz.extends]))
1076 def method_exists(api, clazz, test):
1077 methods = all_methods(api, clazz)
1082 def field_exists(api, clazz, test):
1083 for f in clazz.fields: