Ignore:
Timestamp:
2023-06-14T18:01:00+02:00 (13 months ago)
Author:
taylor.smock
Message:

Fix #17669, #22096: Allow placeholders in more locations in MapCSS

Location:
trunk/src/org/openstreetmap/josm/data/validation/tests
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java

    r18365 r18757  
    232232                final Selector selector = check.whichSelectorMatchesEnvironment(env);
    233233                if (selector != null) {
    234                     check.rule.declaration.execute(env);
     234                    final Environment envWithSelector = env.withSelector(selector);
     235                    check.rule.declaration.execute(envWithSelector);
    235236                    if (!ignoreError && !check.errors.isEmpty()) {
    236                         r.addAll(check.getErrorsForPrimitive(p, selector, env, new MapCSSTagCheckerAndRule(check.rule)));
     237                        r.addAll(check.getErrorsForPrimitive(p, selector, envWithSelector, new MapCSSTagCheckerAndRule(check.rule)));
    237238                    }
    238239                }
  • trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagCheckerAsserts.java

    r18365 r18757  
    7575                Command fix = check.fixPrimitive(p);
    7676                if (fix != null && fix.executeCommand() && !MapCSSTagChecker.getErrorsForPrimitive(p, true, checksToRun).isEmpty()) {
    77                     assertionConsumer.accept(MessageFormat.format("Autofix does not work for test ''{0}'' (i.e., {1})",
    78                             check.getMessage(p), check.rule.selectors));
     77                    assertionConsumer.accept(MessageFormat.format("Autofix does not work for test ''{0}'' (i.e., {1}). Failing test: {2}",
     78                            check.getMessage(p), check.rule.selectors, i.getKey()));
    7979                }
    8080            }
  • trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagCheckerFixCommand.java

    r17620 r18757  
    4949        final String s;
    5050        if (obj instanceof Expression) {
    51             s = (String) ((Expression) obj).evaluate(new Environment(p));
     51            s = (String) ((Expression) obj).evaluate(new Environment(p).withSelector(matchingSelector));
    5252        } else if (obj instanceof String) {
    5353            s = (String) obj;
  • trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagCheckerRule.java

    r18365 r18757  
    1818import java.util.function.Consumer;
    1919import java.util.function.Predicate;
    20 import java.util.regex.Matcher;
    21 import java.util.regex.Pattern;
    2220import java.util.stream.Collectors;
    2321
     
    2725import org.openstreetmap.josm.data.osm.IPrimitive;
    2826import org.openstreetmap.josm.data.osm.OsmPrimitive;
    29 import org.openstreetmap.josm.data.osm.Tag;
    3027import org.openstreetmap.josm.data.osm.Way;
    3128import org.openstreetmap.josm.data.osm.WaySegment;
     
    3532import org.openstreetmap.josm.gui.mappaint.Environment;
    3633import org.openstreetmap.josm.gui.mappaint.Keyword;
     34import org.openstreetmap.josm.gui.mappaint.MultiCascade;
    3735import org.openstreetmap.josm.gui.mappaint.mapcss.Condition;
    38 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.TagCondition;
    3936import org.openstreetmap.josm.gui.mappaint.mapcss.Expression;
    4037import org.openstreetmap.josm.gui.mappaint.mapcss.Instruction;
    4138import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSRule;
    4239import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource;
     40import org.openstreetmap.josm.gui.mappaint.mapcss.PlaceholderExpression;
    4341import org.openstreetmap.josm.gui.mappaint.mapcss.Selector;
    4442import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.MapCSSParser;
     
    215213
    216214    Selector whichSelectorMatchesPrimitive(OsmPrimitive primitive) {
    217         return whichSelectorMatchesEnvironment(new Environment(primitive));
     215        return whichSelectorMatchesEnvironment(new Environment(primitive, new MultiCascade(), Environment.DEFAULT_LAYER, null));
    218216    }
    219217
     
    226224
    227225    /**
    228      * Determines the {@code index}-th key/value/tag (depending on {@code type}) of the
    229      * {@link org.openstreetmap.josm.gui.mappaint.mapcss.Selector.GeneralSelector}.
    230      *
    231      * @param matchingSelector matching selector
    232      * @param index            index
    233      * @param type             selector type ("key", "value" or "tag")
    234      * @param p                OSM primitive
    235      * @return argument value, can be {@code null}
    236      */
    237     static String determineArgument(Selector.GeneralSelector matchingSelector, int index, String type, OsmPrimitive p) {
    238         try {
    239             final Condition c = matchingSelector.getConditions().get(index);
    240             final Tag tag = c instanceof TagCondition
    241                     ? ((TagCondition) c).asTag(p)
    242                     : null;
    243             if (tag == null) {
    244                 return null;
    245             } else if ("key".equals(type)) {
    246                 return tag.getKey();
    247             } else if ("value".equals(type)) {
    248                 return tag.getValue();
    249             } else if ("tag".equals(type)) {
    250                 return tag.toString();
    251             }
    252         } catch (IndexOutOfBoundsException ignore) {
    253             Logging.debug(ignore);
    254         }
    255         return null;
    256     }
    257 
    258     /**
    259226     * Replaces occurrences of <code>{i.key}</code>, <code>{i.value}</code>, <code>{i.tag}</code> in {@code s} by the corresponding
    260227     * key/value/tag of the {@code index}-th {@link Condition} of {@code matchingSelector}.
     
    266233     */
    267234    static String insertArguments(Selector matchingSelector, String s, OsmPrimitive p) {
    268         if (s != null && matchingSelector instanceof Selector.ChildOrParentSelector) {
    269             return insertArguments(((Selector.ChildOrParentSelector) matchingSelector).right, s, p);
    270         } else if (s == null || !(matchingSelector instanceof Selector.GeneralSelector)) {
    271             return s;
    272         }
    273         final Matcher m = Pattern.compile("\\{(\\d+)\\.(key|value|tag)\\}").matcher(s);
    274         final StringBuffer sb = new StringBuffer();
    275         while (m.find()) {
    276             final String argument = determineArgument((Selector.GeneralSelector) matchingSelector,
    277                     Integer.parseInt(m.group(1)), m.group(2), p);
    278             try {
    279                 // Perform replacement with null-safe + regex-safe handling
    280                 m.appendReplacement(sb, String.valueOf(argument).replace("^(", "").replace(")$", ""));
    281             } catch (IndexOutOfBoundsException | IllegalArgumentException e) {
    282                 Logging.log(Logging.LEVEL_ERROR, tr("Unable to replace argument {0} in {1}: {2}", argument, sb, e.getMessage()), e);
    283             }
    284         }
    285         m.appendTail(sb);
    286         return sb.toString();
     235        return PlaceholderExpression.insertArguments(matchingSelector, s, p);
    287236    }
    288237
     
    329278            return String.valueOf(
    330279                    val instanceof Expression
    331                             ? ((Expression) val).evaluate(new Environment(p))
     280                            ? ((Expression) val).evaluate(new Environment(p).withSelector(p == null ? null : whichSelectorMatchesPrimitive(p)))
    332281                            : val
    333282            );
Note: See TracChangeset for help on using the changeset viewer.