diff options
Diffstat (limited to 'lint')
6 files changed, 210 insertions, 2 deletions
diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Location.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Location.java index f574189..183e7c1 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Location.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Location.java @@ -235,6 +235,7 @@ public class Location { Position start = null; int line = 0; int lineOffset = 0; + char prev = 0; for (int offset = 0; offset <= size; offset++) { if (offset == startOffset) { start = new DefaultPosition(line, offset - lineOffset, offset); @@ -246,8 +247,14 @@ public class Location { char c = contents.charAt(offset); if (c == '\n') { lineOffset = offset + 1; + if (prev != '\r') { + line++; + } + } else if (c == '\r') { line++; + lineOffset = offset + 1; } + prev = c; } return Location.create(file); } diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java index aafcd5c..22a6c9d 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java @@ -55,7 +55,7 @@ public class BuiltinIssueRegistry extends IssueRegistry { private static final List<Issue> sIssues; static { - final int initialCapacity = 120; + final int initialCapacity = 121; List<Issue> issues = new ArrayList<Issue>(initialCapacity); issues.add(AccessibilityDetector.ISSUE); @@ -102,6 +102,7 @@ public class BuiltinIssueRegistry extends IssueRegistry { issues.add(TranslationDetector.MISSING); issues.add(HardcodedValuesDetector.ISSUE); issues.add(Utf8Detector.ISSUE); + issues.add(DosLineEndingDetector.ISSUE); issues.add(ProguardDetector.WRONGKEEP); issues.add(ProguardDetector.SPLITCONFIG); issues.add(PxUsageDetector.PX_ISSUE); @@ -306,7 +307,7 @@ public class BuiltinIssueRegistry extends IssueRegistry { // to give a hint to the user that some fixes don't require manual work if (sAdtFixes == null) { - sAdtFixes = new HashSet<Issue>(20); + sAdtFixes = new HashSet<Issue>(25); sAdtFixes.add(InefficientWeightDetector.INEFFICIENT_WEIGHT); sAdtFixes.add(AccessibilityDetector.ISSUE); sAdtFixes.add(InefficientWeightDetector.BASELINE_WEIGHTS); @@ -327,6 +328,10 @@ public class BuiltinIssueRegistry extends IssueRegistry { sAdtFixes.add(UseCompoundDrawableDetector.ISSUE); sAdtFixes.add(ApiDetector.UNSUPPORTED); sAdtFixes.add(TypoDetector.ISSUE); + sAdtFixes.add(ManifestOrderDetector.ALLOW_BACKUP); + sAdtFixes.add(MissingIdDetector.ISSUE); + sAdtFixes.add(TranslationDetector.MISSING); + sAdtFixes.add(DosLineEndingDetector.ISSUE); } return sAdtFixes.contains(issue); diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/DosLineEndingDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/DosLineEndingDetector.java new file mode 100644 index 0000000..c2e735c --- /dev/null +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/DosLineEndingDetector.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.tools.lint.checks; + +import com.android.annotations.NonNull; +import com.android.tools.lint.detector.api.Category; +import com.android.tools.lint.detector.api.Issue; +import com.android.tools.lint.detector.api.LayoutDetector; +import com.android.tools.lint.detector.api.Location; +import com.android.tools.lint.detector.api.Scope; +import com.android.tools.lint.detector.api.Severity; +import com.android.tools.lint.detector.api.Speed; +import com.android.tools.lint.detector.api.XmlContext; + +import org.w3c.dom.Document; + +/** + * Checks that the line endings in DOS files are consistent + */ +public class DosLineEndingDetector extends LayoutDetector { + /** Detects mangled DOS line ending documents */ + public static final Issue ISSUE = Issue.create( + "MangledCRLF", //$NON-NLS-1$ + "Checks that files with DOS line endings are consistent", + + "On Windows, line endings are typically recorded as carriage return plus " + + "newline: \\r\\n.\n" + + "\n" + + "This detector looks for invalid line endings with repeated carriage return " + + "characters (without newlines). Previous versions of the ADT plugin could " + + "accidentally introduce these into the file, and when editing the file, the " + + "editor could produce confusing visual artifacts.", + + Category.CORRECTNESS, + 2, + Severity.ERROR, + DosLineEndingDetector.class, + Scope.RESOURCE_FILE_SCOPE) + .setMoreInfo("https://bugs.eclipse.org/bugs/show_bug.cgi?id=375421"); //$NON-NLS-1$ + + /** Constructs a new {@link DosLineEndingDetector} */ + public DosLineEndingDetector() { + } + + @Override + public @NonNull Speed getSpeed() { + return Speed.NORMAL; + } + + @Override + public void visitDocument(@NonNull XmlContext context, @NonNull Document document) { + String contents = context.getContents(); + if (contents == null) { + return; + } + + // We could look for *consistency* and complain if you mix \n and \r\n too, + // but that isn't really a problem (most editors handle it) so let's + // not complain needlessly. + + char prev = 0; + for (int i = 0, n = contents.length(); i < n; i++) { + char c = contents.charAt(i); + if (c == '\r' && prev == '\r') { + String message = "Incorrect line ending: found carriage return (\\r) without " + + "corresponding newline (\\n)"; + + // Mark the whole line as the error range, since pointing just to the + // line ending makes the error invisible in IDEs and error reports etc + // Find the most recent non-blank line + boolean blankLine = true; + for (int index = i - 2; index < i; index++) { + char d = contents.charAt(index); + if (!Character.isWhitespace(d)) { + blankLine = false; + } + } + + int lineBegin = i; + for (int index = i - 2; index >= 0; index--) { + char d = contents.charAt(index); + if (d == '\n') { + lineBegin = index + 1; + if (!blankLine) { + break; + } + } else if (!Character.isWhitespace(d)) { + blankLine = false; + } + } + + int lineEnd = Math.min(contents.length(), i + 1); + Location location = Location.create(context.file, contents, lineBegin, lineEnd); + context.report(ISSUE, document.getDocumentElement(), location, message, null); + return; + } + prev = c; + } + } +} diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/DosLineEndingDetectorTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/DosLineEndingDetectorTest.java new file mode 100644 index 0000000..3682420 --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/DosLineEndingDetectorTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.tools.lint.checks; + +import com.android.tools.lint.detector.api.Detector; + +@SuppressWarnings("javadoc") +public class DosLineEndingDetectorTest extends AbstractCheckTest { + @Override + protected Detector getDetector() { + return new DosLineEndingDetector(); + } + + public void test() throws Exception { + assertEquals( + "res/layout/crcrlf.xml:4: Error: Incorrect line ending: found carriage return (\\r) without corresponding newline (\\n) [MangledCRLF]\n" + + " android:layout_height=\"match_parent\" >\r\n" + + "^\n" + + "1 errors, 0 warnings\n", + lintProject("res/layout/crcrlf.xml")); + } + + public void testIgnore() throws Exception { + assertEquals( + "No warnings.", + lintProject("res/layout/crcrlf_ignore.xml")); + } + + public void testNegative() throws Exception { + // Make sure we don't get warnings for a correct file + assertEquals( + "No warnings.", + lintProject("res/layout/layout1.xml")); + } +} diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/crcrlf.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/crcrlf.xml new file mode 100644 index 0000000..d029725 --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/crcrlf.xml @@ -0,0 +1,14 @@ +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerHorizontal="true"
+ android:layout_centerVertical="true"
+ android:text="Hello"
+ tools:context=".MainActivity" />
+
+</RelativeLayout>
diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/crcrlf_ignore.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/crcrlf_ignore.xml new file mode 100644 index 0000000..680a765 --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/crcrlf_ignore.xml @@ -0,0 +1,19 @@ +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:ignore="MangledCRLF" >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerHorizontal="true"
+ android:layout_centerVertical="true"
+ android:text="@string/app_name"
+ tools:context=".MainActivity" />
+
+
+
+
+
+</RelativeLayout>
|