Ticket #19180: 19180-check-deprecated.2.patch

File 19180-check-deprecated.2.patch, 10.6 KB (added by GerdP, 6 years ago)

handle also the "Key 'x' looks like 'y' " message

  • src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java

     
    938938        }
    939939
    940940        if (partialSelection && !tested.isEmpty()) {
    941             // #14287: see https://josm.openstreetmap.de/ticket/14287#comment:15
    942             // execute tests for objects which might contain or cross previously tested elements
     941            testPartial(currentCheck, tested, surrounding);
     942        }
     943    }
    943944
    944             // rebuild index with a reduced set of rules (those that use ChildOrParentSelector) and thus may have left selectors
    945             // matching the previously tested elements
    946             indexData = createMapCSSTagCheckerIndex(currentCheck, includeOtherSeverityChecks(), ONLY_SELECTED_TESTS);
     945    private void testPartial(MultiMap<String, TagCheck> currentCheck, Set<OsmPrimitive> tested,
     946            Set<OsmPrimitive> surrounding) {
    947947
    948             if (surrounding.isEmpty()) {
    949                 for (OsmPrimitive p : tested) {
    950                     if (p.getDataSet() != null) {
    951                         surrounding.addAll(p.getDataSet().searchWays(p.getBBox()));
    952                         surrounding.addAll(p.getDataSet().searchRelations(p.getBBox()));
    953                     }
     948        // #14287: see https://josm.openstreetmap.de/ticket/14287#comment:15
     949        // execute tests for objects which might contain or cross previously tested elements
     950
     951        final boolean includeOtherSeverity = includeOtherSeverityChecks();
     952        // rebuild index with a reduced set of rules (those that use ChildOrParentSelector) and thus may have left selectors
     953        // matching the previously tested elements
     954        indexData = createMapCSSTagCheckerIndex(currentCheck, includeOtherSeverity, ONLY_SELECTED_TESTS);
     955        if (indexData.isEmpty())
     956            return; // performance: some *.mapcss rule files don't use ChildOrParentSelector
     957
     958        if (surrounding.isEmpty()) {
     959            for (OsmPrimitive p : tested) {
     960                if (p.getDataSet() != null) {
     961                    surrounding.addAll(p.getDataSet().searchWays(p.getBBox()));
     962                    surrounding.addAll(p.getDataSet().searchRelations(p.getBBox()));
    954963                }
    955964            }
     965        }
    956966
    957             final boolean includeOtherSeverity = includeOtherSeverityChecks();
    958             for (OsmPrimitive p : surrounding) {
    959                 if (tested.contains(p))
    960                     continue;
    961                 Collection<TestError> additionalErrors = getErrorsForPrimitive(p, includeOtherSeverity);
    962                 for (TestError e : additionalErrors) {
    963                     if (e.getPrimitives().stream().anyMatch(tested::contains))
    964                         addIfNotSimilar(e, errors);
    965                 }
     967        for (OsmPrimitive p : surrounding) {
     968            if (tested.contains(p))
     969                continue;
     970            Collection<TestError> additionalErrors = getErrorsForPrimitive(p, includeOtherSeverity);
     971            for (TestError e : additionalErrors) {
     972                if (e.getPrimitives().stream().anyMatch(tested::contains))
     973                    addIfNotSimilar(e, errors);
    966974            }
    967975        }
     976
    968977    }
     978
     979    /**
     980     * Execute only the rules for the rules matching the given file name. See #19180
     981     * @param ruleFile the name of the mapcss file, e.g. deprecated.mapcss
     982     * @param selection collection of primitives
     983     * @since xxx
     984     */
     985    public void runOnly(String ruleFile, Collection<OsmPrimitive> selection) {
     986        mpAreaCache.clear();
     987
     988        Set<OsmPrimitive> surrounding = new HashSet<>();
     989        for (Entry<String, Set<TagCheck>> entry : checks.entrySet()) {
     990            if (isCanceled()) {
     991                break;
     992            }
     993            if (entry.getKey().endsWith(ruleFile)) {
     994                visit(entry.getKey(), entry.getValue(), selection, surrounding);
     995            }
     996        }
     997
     998    }
    969999}
  • src/org/openstreetmap/josm/data/validation/tests/TagChecker.java

     
    1717import java.util.EnumSet;
    1818import java.util.HashMap;
    1919import java.util.HashSet;
     20import java.util.Iterator;
    2021import java.util.LinkedHashMap;
    2122import java.util.LinkedHashSet;
    2223import java.util.List;
     
    4445import org.openstreetmap.josm.data.osm.TagMap;
    4546import org.openstreetmap.josm.data.osm.Tagged;
    4647import org.openstreetmap.josm.data.preferences.sources.ValidatorPrefHelper;
     48import org.openstreetmap.josm.data.validation.OsmValidator;
    4749import org.openstreetmap.josm.data.validation.Severity;
    4850import org.openstreetmap.josm.data.validation.Test.TagTest;
    4951import org.openstreetmap.josm.data.validation.TestError;
     
    100102    /** The preferences prefix */
    101103    protected static final String PREFIX = ValidatorPrefHelper.PREFIX + "." + TagChecker.class.getSimpleName();
    102104
     105    MapCSSTagChecker deprecatedChecker;
     106
    103107    /**
    104108     * The preference key to check values
    105109     */
     
    852856            fixedKey = prettifiedKey;
    853857        }
    854858
     859        // see #19180: Don't suggest a key which is deprecated
     860        if (deprecatedChecker != null && !p.hasTag(fixedKey) && fixedKey != null && !"".equals(fixedKey)) {
     861            String val = p.get(key);
     862            boolean isDeprecated = false;
     863            try {
     864                int origDeprecated = countDeprecated(p);
     865                p.remove(key);
     866                p.put(fixedKey, val);
     867                isDeprecated = countDeprecated(p) > origDeprecated;
     868            } finally {
     869                p.remove(fixedKey);
     870                p.put(key, val);
     871            }
     872            if (isDeprecated) {
     873                fixedKey = null;
     874            }
     875        }
     876
    855877        if (fixedKey != null && !"".equals(fixedKey) && !fixedKey.equals(key)) {
    856878            final String proposedKey = fixedKey;
    857879            // misspelled preset key
     
    893915            List<String> fixVals = new ArrayList<>();
    894916            // use Levenshtein distance to find typical typos
    895917            int minDist = MAX_LEVENSHTEIN_DISTANCE + 1;
    896             String closest = null;
    897918            for (Set<String> possibleValues: sets) {
    898919                for (String possibleVal : possibleValues) {
    899920                    if (possibleVal.isEmpty())
     
    910931                        continue;
    911932                    }
    912933                    if (dist < minDist) {
    913                         closest = possibleVal;
    914934                        minDist = dist;
    915935                        fixVals.clear();
    916936                        fixVals.add(possibleVal);
     
    919939                    }
    920940                }
    921941            }
    922 
     942            filterDeprecatedTags(p, key, fixVals);
    923943            if (minDist <= MAX_LEVENSHTEIN_DISTANCE && maxPresetValueLen > MAX_LEVENSHTEIN_DISTANCE
     944                    && !fixVals.isEmpty()
    924945                    && (harmonizedValue.length() > 3 || minDist < MAX_LEVENSHTEIN_DISTANCE)) {
    925946                if (fixVals.size() < 2) {
    926                     fixedValue = closest;
     947                    fixedValue = fixVals.get(0);
    927948                } else {
    928949                    Collections.sort(fixVals);
    929950                    // misspelled preset value with multiple good alternatives
     
    957978        }
    958979    }
    959980
     981    // see #19180
     982    private void filterDeprecatedTags(OsmPrimitive p, String key, List<String> fixVals) {
     983        if (fixVals.isEmpty() || deprecatedChecker == null)
     984            return;
     985
     986        String origVal = p.get(key);
     987        try {
     988            int unchangedDeprecated = countDeprecated(p);
     989            Iterator<String> iter = fixVals.iterator();
     990            while (iter.hasNext()) {
     991                p.put(key, iter.next());
     992                if (countDeprecated(p) > unchangedDeprecated)
     993                    iter.remove();
     994            }
     995        } finally {
     996            // restore original value
     997            p.put(key, origVal);
     998        }
     999    }
     1000
     1001    private int countDeprecated(OsmPrimitive p) {
     1002        if (deprecatedChecker == null)
     1003            return 0;
     1004        deprecatedChecker.getErrors().clear();
     1005        deprecatedChecker.runOnly("deprecated.mapcss", Collections.singleton(p));
     1006        return deprecatedChecker.getErrors().size();
     1007    }
     1008
    9601009    private static boolean isNum(String harmonizedValue) {
    9611010        try {
    9621011            Double.parseDouble(harmonizedValue);
     
    10071056        if (isBeforeUpload) {
    10081057            checkPresetsTypes = checkPresetsTypes && Config.getPref().getBoolean(PREF_CHECK_PRESETS_TYPES_BEFORE_UPLOAD, true);
    10091058        }
     1059        deprecatedChecker = OsmValidator.getTest(MapCSSTagChecker.class);
    10101060    }
    10111061
    10121062    @Override
     1063    public void endTest() {
     1064        deprecatedChecker = null;
     1065        super.endTest();
     1066    }
     1067
     1068    @Override
    10131069    public void visit(Collection<OsmPrimitive> selection) {
    10141070        if (checkKeys || checkValues || checkComplex || checkFixmes || checkPresetsTypes) {
    10151071            super.visit(selection);
  • src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSRuleIndex.java

     
    246246        index.clear();
    247247        remaining.clear();
    248248    }
     249
     250    /**
     251     * Check if this index is empty.
     252     * @return true if this index is empty.
     253     * @since xxx
     254     */
     255    public boolean isEmpty() {
     256        return rules.isEmpty();
     257    }
    249258}
  • src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleIndex.java

     
    172172    public Iterator<MapCSSRule> getRuleCandidates(IPrimitive osm) {
    173173        return get(osm).getRuleCandidates(osm);
    174174    }
     175
     176    /**
     177     * Check if this index is empty.
     178     * @return true if this index is empty.
     179     * @since xxx
     180     */
     181    public boolean isEmpty() {
     182        return nodeRules.isEmpty() && wayRules.isEmpty() && wayNoAreaRules.isEmpty() && relationRules.isEmpty()
     183                && multipolygonRules.isEmpty() && canvasRules.isEmpty();
     184    }
    175185}