Java Code Examples for com.android.tools.lint.detector.api.Location#setMessage()

The following examples show how to use com.android.tools.lint.detector.api.Location#setMessage() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: WebViewDetector.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
@Override
public void visitElement(@NonNull XmlContext context, @NonNull Element element) {
    Node parentNode = element.getParentNode();
    if (parentNode != null && parentNode.getNodeType() == Node.ELEMENT_NODE) {
        Element parent = (Element)parentNode;
        Attr width = parent.getAttributeNodeNS(ANDROID_URI, ATTR_LAYOUT_WIDTH);
        Attr height = parent.getAttributeNodeNS(ANDROID_URI, ATTR_LAYOUT_HEIGHT);
        Attr attr = null;
        if (width != null && VALUE_WRAP_CONTENT.equals(width.getValue())) {
            attr = width;
        }
        if (height != null && VALUE_WRAP_CONTENT.equals(height.getValue())) {
            attr = height;
        }
        if (attr != null) {
            String message = String.format("Placing a `<WebView>` in a parent element that "
                    + "uses a `wrap_content %1$s` can lead to subtle bugs; use `match_parent` "
                    + "instead", attr.getLocalName());
            Location location = context.getLocation(element);
            Location secondary = context.getLocation(attr);
            secondary.setMessage("`wrap_content` here may not work well with WebView below");
            location.setSecondary(secondary);
            context.report(ISSUE, element, location, message);
        }
    }
}
 
Example 2
Source File: TextFieldDetector.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
private static void reportMismatch(XmlContext context, Attr idNode, Node inputTypeNode,
        String message) {
    Location location;
    if (inputTypeNode != null) {
        location = context.getLocation(inputTypeNode);
        Location secondary = context.getLocation(idNode);
        secondary.setMessage("id defined here");
        location.setSecondary(secondary);
    } else {
        location = context.getLocation(idNode);
    }
    context.report(ISSUE, idNode.getOwnerElement(), location, message);
}
 
Example 3
Source File: CutPasteDetector.java    From javaide with GNU General Public License v3.0 4 votes vote down vote up
@Override
public void visitMethod(@NonNull JavaContext context, @Nullable AstVisitor visitor,
        @NonNull MethodInvocation call) {
    String lhs = getLhs(call);
    if (lhs == null) {
        return;
    }

    Node method = JavaContext.findSurroundingMethod(call);
    if (method == null) {
        return;
    } else if (method != mLastMethod) {
        mIds = Maps.newHashMap();
        mLhs = Maps.newHashMap();
        mCallOperands = Maps.newHashMap();
        mLastMethod = method;
    }

    String callOperand = call.astOperand() != null ? call.astOperand().toString() : "";

    Expression first = call.astArguments().first();
    if (first instanceof Select) {
        Select select = (Select) first;
        String id = select.astIdentifier().astValue();
        Expression operand = select.astOperand();
        if (operand instanceof Select) {
            Select type = (Select) operand;
            if (type.astIdentifier().astValue().equals(RESOURCE_CLZ_ID)) {
                if (mIds.containsKey(id)) {
                    if (lhs.equals(mLhs.get(id))) {
                        return;
                    }
                    if (!callOperand.equals(mCallOperands.get(id))) {
                        return;
                    }
                    MethodInvocation earlierCall = mIds.get(id);
                    if (!isReachableFrom(method, earlierCall, call)) {
                        return;
                    }
                    Location location = context.getLocation(call);
                    Location secondary = context.getLocation(earlierCall);
                    secondary.setMessage("First usage here");
                    location.setSecondary(secondary);
                    context.report(ISSUE, call, location, String.format(
                        "The id `%1$s` has already been looked up in this method; possible " +
                        "cut & paste error?", first.toString()));
                } else {
                    mIds.put(id, call);
                    mLhs.put(id, lhs);
                    mCallOperands.put(id, callOperand);
                }
            }
        }
    }
}
 
Example 4
Source File: AnnotationDetector.java    From javaide with GNU General Public License v3.0 4 votes vote down vote up
private void ensureUniqueValues(@NonNull ResolvedAnnotation annotation,
        @NonNull Annotation node) {
    Object allowed = annotation.getValue();
    if (allowed instanceof Object[]) {
        Object[] allowedValues = (Object[]) allowed;
        Map<Number,Integer> valueToIndex =
                Maps.newHashMapWithExpectedSize(allowedValues.length);

        List<Node> constants = null;
        for (AnnotationElement element : node.astElements()) {
            if (element.astName() == null
                    || ATTR_VALUE.equals(element.astName().astValue())) {
                AnnotationValue value = element.astValue();
                if (value instanceof ArrayInitializer) {
                    ArrayInitializer initializer = (ArrayInitializer)value;
                    constants = Lists.newArrayListWithExpectedSize(allowedValues.length);
                    for (Expression expression : initializer.astExpressions()) {
                        constants.add(expression);
                    }
                }
                break;
            }
        }
        if (constants != null) {
            if (constants.size() != allowedValues.length) {
                constants = null;
            } else {
                boolean flag = annotation.getValue(TYPE_DEF_FLAG_ATTRIBUTE) == Boolean.TRUE;
                if (flag) {
                    ensureUsingFlagStyle(constants);
                }
            }
        }

        for (int index = 0; index < allowedValues.length; index++) {
            Object o = allowedValues[index];
            if (o instanceof Number) {
                Number number = (Number)o;
                if (valueToIndex.containsKey(number)) {
                    @SuppressWarnings("UnnecessaryLocalVariable")
                    Number repeatedValue = number;

                    Location location;
                    String message;
                    if (constants != null) {
                        Node constant = constants.get(index);
                        int prevIndex = valueToIndex.get(number);
                        Node prevConstant = constants.get(prevIndex);
                        message = String.format(
                                "Constants `%1$s` and `%2$s` specify the same exact "
                                        + "value (%3$s); this is usually a cut & paste or "
                                        + "merge error",
                                constant.toString(), prevConstant.toString(),
                                repeatedValue.toString());
                        location = mContext.getLocation(constant);
                        Location secondary = mContext.getLocation(prevConstant);
                        secondary.setMessage("Previous same value");
                        location.setSecondary(secondary);
                    } else {
                        message = String.format(
                                "More than one constant specifies the same exact "
                                        + "value (%1$s); this is usually a cut & paste or"
                                        + "merge error",
                                repeatedValue.toString());
                        location = mContext.getLocation(node);
                    }
                    Node scope = getAnnotationScope(node);
                    mContext.report(UNIQUE, scope, location, message);
                    break;
                }
                valueToIndex.put(number, index);
            }
        }
    }
}
 
Example 5
Source File: TextReporterTest.java    From javaide with GNU General Public License v3.0 4 votes vote down vote up
public void test() throws Exception {
    File file = new File(getTargetDir(), "report");
    try {
        LintCliClient client = new LintCliClient() {
            @Override
            String getRevision() {
                return "unittest"; // Hardcode version to keep unit test output stable
            }
        };
        //noinspection ResultOfMethodCallIgnored
        file.getParentFile().mkdirs();
        FileWriter writer = new FileWriter(file);
        TextReporter reporter = new TextReporter(client, client.mFlags, file, writer, true);
        Project project = Project.create(client, new File("/foo/bar/Foo"),
                new File("/foo/bar/Foo"));
        client.mFlags.setShowEverything(true);

        Warning warning1 = new Warning(ManifestDetector.USES_SDK,
                "<uses-sdk> tag should specify a target API level (the highest verified " +
                        "version; when running on later versions, compatibility behaviors may " +
                        "be enabled) with android:targetSdkVersion=\"?\"",
                Severity.WARNING, project);
        warning1.line = 6;
        warning1.file = new File("/foo/bar/Foo/AndroidManifest.xml");
        warning1.errorLine = "    <uses-sdk android:minSdkVersion=\"8\" />\n    ^\n";
        warning1.path = "AndroidManifest.xml";
        warning1.location = Location.create(warning1.file,
                new DefaultPosition(6, 4, 198), new DefaultPosition(6, 42, 236));
        Location secondary = Location.create(warning1.file,
                new DefaultPosition(7, 4, 198), new DefaultPosition(7, 42, 236));
        secondary.setMessage("Secondary location");
        warning1.location.setSecondary(secondary);

        Warning warning2 = new Warning(HardcodedValuesDetector.ISSUE,
                "[I18N] Hardcoded string \"Fooo\", should use @string resource",
                Severity.WARNING, project);
        warning2.line = 11;
        warning2.file = new File("/foo/bar/Foo/res/layout/main.xml");
        warning2.errorLine = "        android:text=\"Fooo\" />\n" +
                "        ~~~~~~~~~~~~~~~~~~~\n";
        warning2.path = "res/layout/main.xml";
        warning2.location = Location.create(warning2.file,
                new DefaultPosition(11, 8, 377), new DefaultPosition(11, 27, 396));
        secondary = Location.create(warning1.file,
                new DefaultPosition(7, 4, 198), new DefaultPosition(7, 42, 236));
        secondary.setMessage("Secondary location");
        warning2.location.setSecondary(secondary);
        Location tertiary = Location.create(warning2.file,
                new DefaultPosition(5, 4, 198), new DefaultPosition(5, 42, 236));
        secondary.setSecondary(tertiary);

        List<Warning> warnings = new ArrayList<Warning>();
        warnings.add(warning1);
        warnings.add(warning2);
        Collections.sort(warnings);

        reporter.write(0, 2, warnings);

        String report = Files.toString(file, Charsets.UTF_8);
        assertEquals(""
                + "AndroidManifest.xml:7: Warning: <uses-sdk> tag should specify a target API level (the highest verified version; when running on later versions, compatibility behaviors may be enabled) with android:targetSdkVersion=\"?\" [UsesMinSdkAttributes]\n"
                + "    <uses-sdk android:minSdkVersion=\"8\" />\n"
                + "    ^\n"
                + "    AndroidManifest.xml:8: Secondary location\n"
                + "res/layout/main.xml:12: Warning: [I18N] Hardcoded string \"Fooo\", should use @string resource [HardcodedText]\n"
                + "        android:text=\"Fooo\" />\n"
                + "        ~~~~~~~~~~~~~~~~~~~\n"
                + "    AndroidManifest.xml:8: Secondary location\n"
                + "Also affects: res/layout/main.xml:6\n"
                + "0 errors, 2 warnings\n",
                report);
    } finally {
        //noinspection ResultOfMethodCallIgnored
        file.delete();
    }
}