/** Returns the package name of this class */ @NonNull public String getPackageName() { String name = getName(); String simpleName = getSimpleName(); if (name.length() > simpleName.length() + 1) { return name.substring(0, name.length() - simpleName.length() - 1); } return name; }
@Nullable private static Set<String> getInterfaceNames( @Nullable Set<String> addTo, @NonNull ResolvedClass cls) { Iterable<ResolvedClass> interfaces = cls.getInterfaces(); for (ResolvedClass resolvedInterface : interfaces) { String name = resolvedInterface.getName(); if (addTo == null) { addTo = Sets.newHashSet(); } else if (addTo.contains(name)) { // Superclasses can explicitly implement the same interface, // so keep track of visited interfaces as we traverse up the // super class chain to avoid checking the same interface // more than once. continue; } addTo.add(name); getInterfaceNames(addTo, resolvedInterface); } return addTo; }
@Nullable private ClassInfo findClass(@NonNull ResolvedClass cls) { return mClassMap.get(cls.getName()); }
cls.getName()); context.report(ISSUE, node, context.getLocation(node.astName()), message); return; "This fragment inner class should be static (%1$s)", cls.getName()); context.report(ISSUE, node, context.getLocation(node.astName()), message); return; "This fragment should provide a default constructor (a public " + "constructor with no arguments) (`%1$s`)", cls.getName()); context.report(ISSUE, node, context.getLocation(node.astName()), message);
int depth = 0; while (cls != null) { List<VisitingDetector> list = mSuperClassDetectors.get(cls.getName()); if (list != null) { for (VisitingDetector v : list) {
ResolvedClass cls = resolvedClass; while (cls != null) { List<VisitingDetector> list = mSuperClassDetectors.get(cls.getName()); if (list != null) { for (VisitingDetector v : list) {
@Override public boolean visitConstructorInvocation(ConstructorInvocation node) { if (mVisitConstructors) { TypeReference typeReference = node.astTypeReference(); if (typeReference != null) { TypeReferencePart last = typeReference.astParts().last(); if (last != null) { String name = last.astIdentifier().astValue(); if (mConstructorSimpleNames.contains(name)) { ResolvedNode resolved = mContext.resolve(node); if (resolved instanceof ResolvedMethod) { ResolvedMethod method = (ResolvedMethod) resolved; String type = method.getContainingClass().getName(); List<VisitingDetector> list = mConstructorDetectors.get(type); if (list != null) { for (VisitingDetector v : list) { v.getJavaScanner().visitConstructor(mContext, v.getVisitor(), node, method); } } } } } } } return super.visitConstructorInvocation(node); } }
@Override public void checkClass(@NonNull JavaContext context, @Nullable ClassDeclaration node, @NonNull Node declarationOrAnonymous, @NonNull ResolvedClass resolvedClass) { if (!context.getProject().getReportIssues()) { return; } String className = resolvedClass.getName(); if (resolvedClass.isSubclassOf(PREFERENCE_ACTIVITY, false) && mExportedActivities.containsKey(className)) { // Ignore the issue if we target an API greater than 19 and the class in // question specifically overrides isValidFragment() and thus knowingly white-lists // valid fragments. if (context.getMainProject().getTargetSdk() >= 19 && overridesIsValidFragment(resolvedClass)) { return; } String message = String.format( "`PreferenceActivity` subclass `%1$s` should not be exported", className); context.report(ISSUE, mExportedActivities.get(className).resolve(), message); } }
@Nullable @Override public Node findAstNode() { // Map back from type binding to AST ResolvedClass containingClass = getContainingClass(); TypeDeclaration typeDeclaration = findTypeDeclaration(containingClass.getName()); if (typeDeclaration != null) { for (FieldDeclaration field : typeDeclaration.fields) { if (field.binding == mBinding) { EcjTreeConverter converter = new EcjTreeConverter(); converter.visit(null, field); List<? extends Node> nodes = converter.getAll(); if (nodes.size() == 1) { return nodes.get(0); } break; } } } return super.findAstNode(); }
@Override public void checkClass(@NonNull JavaContext context, @Nullable ClassDeclaration declaration, @NonNull Node node, @NonNull ResolvedClass cls) { if (!isInnerClass(declaration)) { return; } if (isStaticClass(declaration)) { return; } // Only flag handlers using the default looper if (hasLooperConstructorParameter(cls)) { return; } Node locationNode = node instanceof ClassDeclaration ? ((ClassDeclaration) node).astName() : node; Location location = context.getLocation(locationNode); context.report(ISSUE, location, String.format( "This Handler class should be static or leaks might occur (%1$s)", cls.getName())); }
public TypeDescriptor getType() { return new DefaultTypeDescriptor(getName()); }
@Nullable public String getContainingClassName() { ResolvedClass containingClass = getContainingClass(); return containingClass != null ? containingClass.getName() : null; }