@Override public void afterCheckProject(@NonNull Context context) { if (mNames != null && mNames.size() > 0 && mHaveBytecode) { List<String> names = new ArrayList<String>(mNames.keySet()); Collections.sort(names); LintDriver driver = context.getDriver(); for (String name : names) { Handle handle = mNames.get(name); Object clientData = handle.getClientData(); if (clientData instanceof Node) { if (driver.isSuppressed(ISSUE, (Node) clientData)) { continue; } } Location location = handle.resolve(); String message = String.format( "Corresponding method handler 'public void %1$s(android.view.View)' not found", name); List<String> similar = mSimilar != null ? mSimilar.get(name) : null; if (similar != null) { Collections.sort(similar); message = message + String.format(" (did you mean %1$s ?)", Joiner.on(", ").join(similar)); } context.report(ISSUE, location, message, null); } } }
@Override public void visitAttribute(@NonNull XmlContext context, @NonNull Attr attribute) { String value = attribute.getValue(); if (value.isEmpty() || value.trim().isEmpty()) { context.report( ISSUE, attribute, context.getLocation(attribute), "onClick attribute value cannot be empty", null); } else if (!value.equals(value.trim())) { context.report( ISSUE, attribute, context.getLocation(attribute), "There should be no whitespace around attribute values", null); } else { if (mNames == null) { mNames = new HashMap<String, Location.Handle>(); } Handle handle = context.parser.createLocationHandle(context, attribute); handle.setClientData(attribute); // Replace unicode characters with the actual value since that's how they // appear in the ASM signatures if (value.contains("\\u")) { // $NON-NLS-1$ Pattern pattern = Pattern.compile("\\\\u(\\d\\d\\d\\d)"); // $NON-NLS-1$ Matcher matcher = pattern.matcher(value); StringBuilder sb = new StringBuilder(value.length()); int remainder = 0; while (matcher.find()) { sb.append(value.substring(0, matcher.start())); String unicode = matcher.group(1); int hex = Integer.parseInt(unicode, 16); sb.append((char) hex); remainder = matcher.end(); } sb.append(value.substring(remainder)); value = sb.toString(); } mNames.put(value, handle); } }