aboutsummaryrefslogtreecommitdiffstats
path: root/lint/libs/lint_checks/src/com/android/tools/lint/checks/ArraySizeDetector.java
diff options
context:
space:
mode:
Diffstat (limited to 'lint/libs/lint_checks/src/com/android/tools/lint/checks/ArraySizeDetector.java')
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/ArraySizeDetector.java252
1 files changed, 0 insertions, 252 deletions
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ArraySizeDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ArraySizeDetector.java
deleted file mode 100644
index 771c247..0000000
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ArraySizeDetector.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright (C) 2011 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 static com.android.SdkConstants.ATTR_NAME;
-import static com.android.SdkConstants.TAG_ARRAY;
-import static com.android.SdkConstants.TAG_INTEGER_ARRAY;
-import static com.android.SdkConstants.TAG_STRING_ARRAY;
-
-import com.android.annotations.NonNull;
-import com.android.resources.ResourceFolderType;
-import com.android.tools.lint.client.api.LintDriver;
-import com.android.tools.lint.detector.api.Category;
-import com.android.tools.lint.detector.api.Context;
-import com.android.tools.lint.detector.api.Issue;
-import com.android.tools.lint.detector.api.LintUtils;
-import com.android.tools.lint.detector.api.Location;
-import com.android.tools.lint.detector.api.ResourceXmlDetector;
-import com.android.tools.lint.detector.api.Scope;
-import com.android.tools.lint.detector.api.Severity;
-import com.android.tools.lint.detector.api.XmlContext;
-import com.android.utils.Pair;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Checks for arrays with inconsistent item counts
- */
-public class ArraySizeDetector extends ResourceXmlDetector {
-
- /** Are there differences in how many array elements are declared? */
- public static final Issue INCONSISTENT = Issue.create(
- "InconsistentArrays", //$NON-NLS-1$
- "Checks for inconsistencies in the number of elements in arrays",
- "When an array is translated in a different locale, it should normally have " +
- "the same number of elements as the original array. When adding or removing " +
- "elements to an array, it is easy to forget to update all the locales, and this " +
- "lint warning finds inconsistencies like these.\n" +
- "\n" +
- "Note however that there may be cases where you really want to declare a " +
- "different number of array items in each configuration (for example where " +
- "the array represents available options, and those options differ for " +
- "different layout orientations and so on), so use your own judgement to " +
- "decide if this is really an error.\n" +
- "\n" +
- "You can suppress this error type if it finds false errors in your project.",
- Category.CORRECTNESS,
- 7,
- Severity.WARNING,
- ArraySizeDetector.class,
- Scope.ALL_RESOURCES_SCOPE);
-
- private Map<File, Pair<String, Integer>> mFileToArrayCount;
-
- /** Locations for each array name. Populated during phase 2, if necessary */
- private Map<String, Location> mLocations;
-
- /** Error messages for each array name. Populated during phase 2, if necessary */
- private Map<String, String> mDescriptions;
-
- /** Constructs a new {@link ArraySizeDetector} */
- public ArraySizeDetector() {
- }
-
- @Override
- public boolean appliesTo(@NonNull ResourceFolderType folderType) {
- return folderType == ResourceFolderType.VALUES;
- }
-
- @Override
- public Collection<String> getApplicableElements() {
- return Arrays.asList(
- TAG_ARRAY,
- TAG_STRING_ARRAY,
- TAG_INTEGER_ARRAY
- );
- }
-
- @Override
- public void beforeCheckProject(@NonNull Context context) {
- if (context.getPhase() == 1) {
- mFileToArrayCount = new HashMap<File, Pair<String,Integer>>(30);
- }
- }
-
- @Override
- public void afterCheckProject(@NonNull Context context) {
- if (context.getPhase() == 1) {
- // Check that all arrays for the same name have the same number of translations
-
- Set<String> alreadyReported = new HashSet<String>();
- Map<String, Integer> countMap = new HashMap<String, Integer>();
- Map<String, File> fileMap = new HashMap<String, File>();
-
- // Process the file in sorted file order to ensure stable output
- List<File> keys = new ArrayList<File>(mFileToArrayCount.keySet());
- Collections.sort(keys);
-
- for (File file : keys) {
- Pair<String, Integer> pair = mFileToArrayCount.get(file);
- String name = pair.getFirst();
- if (alreadyReported.contains(name)) {
- continue;
- }
- Integer count = pair.getSecond();
-
- Integer current = countMap.get(name);
- if (current == null) {
- countMap.put(name, count);
- fileMap.put(name, file);
- } else if (!count.equals(current)) {
- alreadyReported.add(name);
-
- if (mLocations == null) {
- mLocations = new HashMap<String, Location>();
- mDescriptions = new HashMap<String, String>();
- }
- mLocations.put(name, null);
-
- String thisName = file.getParentFile().getName() + File.separator
- + file.getName();
- File otherFile = fileMap.get(name);
- String otherName = otherFile.getParentFile().getName() + File.separator
- + otherFile.getName();
- String message = String.format(
- "Array %1$s has an inconsistent number of items (%2$d in %3$s, %4$d in %5$s)",
- name, count, thisName, current, otherName);
- mDescriptions.put(name, message);
- }
- }
-
- if (mLocations != null) {
- // Request another scan through the resources such that we can
- // gather the actual locations
- context.getDriver().requestRepeat(this, Scope.ALL_RESOURCES_SCOPE);
- }
- mFileToArrayCount = null;
- } else {
- if (mLocations != null) {
- List<String> names = new ArrayList<String>(mLocations.keySet());
- Collections.sort(names);
- for (String name : names) {
- Location location = mLocations.get(name);
- // We were prepending locations, but we want to prefer the base folders
- location = Location.reverse(location);
-
- // Make sure we still have a conflict, in case one or more of the
- // elements were marked with tools:ignore
- int count = -1;
- Location curr = location;
- LintDriver driver = context.getDriver();
- boolean foundConflict = false;
- for (curr = location; curr != null; curr = curr.getSecondary()) {
- Object clientData = curr.getClientData();
- if (clientData instanceof Node) {
- Node node = (Node) clientData;
- if (driver.isSuppressed(INCONSISTENT, node)) {
- continue;
- }
- int newCount = LintUtils.getChildCount(node);
- if (newCount != count) {
- if (count == -1) {
- count = newCount; // first number encountered
- } else {
- foundConflict = true;
- break;
- }
- }
- } else {
- foundConflict = true;
- break;
- }
- }
-
- // Through one or more tools:ignore, there is no more conflict so
- // ignore this element
- if (!foundConflict) {
- continue;
- }
-
- String message = mDescriptions.get(name);
- context.report(INCONSISTENT, location, message, null);
- }
- }
-
- mLocations = null;
- mDescriptions = null;
- }
- }
-
- @Override
- public void visitElement(@NonNull XmlContext context, @NonNull Element element) {
- int phase = context.getPhase();
-
- Attr attribute = element.getAttributeNode(ATTR_NAME);
- if (attribute == null || attribute.getValue().length() == 0) {
- if (phase != 1) {
- return;
- }
- context.report(INCONSISTENT, element, context.getLocation(element),
- String.format("Missing name attribute in %1$s declaration", element.getTagName()),
- null);
- } else {
- String name = attribute.getValue();
- if (phase == 1) {
- int childCount = LintUtils.getChildCount(element);
- mFileToArrayCount.put(context.file, Pair.of(name, childCount));
- } else {
- assert phase == 2;
- if (mLocations.containsKey(name)) {
- if (context.getDriver().isSuppressed(INCONSISTENT, element)) {
- return;
- }
- Location location = context.getLocation(element);
- location.setClientData(element);
- location.setMessage(String.format("Declaration with array size (%1$d)",
- LintUtils.getChildCount(element)));
- location.setSecondary(mLocations.get(name));
- mLocations.put(name, location);
- }
- }
- }
- }
-}