@@ -128,6 +128,26 @@ private static void warnOnceCompileResolveBridge() {
128128 }
129129
130130 /**
131+ * Returns {@code true} if this entity should take part in <i>any</i> of the
132+ * caller-requested tags.
133+ *
134+ * // @formatter:off
135+ * Semantics – in precedence order
136+ * --------------------------------
137+ * 1. **Legacy wildcard** – if this entity has no tags at all, it matches
138+ * every tag (backwards compatibility).
139+ * 2. **Negative tag overrides** – if the entity contains a literal tag
140+ * {@code "no" + tag} it is <b>excluded</b> from that phase, regardless
141+ * of all other rules (example 'nocompile'.
142+ * 3. **Positive tag match** – if the entity contains a tag that matches a
143+ * requested glob, it is included.
144+ * 4. **7.2 bridge** – while {@link #TRANSITION_COMPILE_IMPLIES_RESOLVE} is
145+ * {@code true}, a request for {@code "compile"} also accepts entities that
146+ * have {@code "resolve"} (and <i>no</i> {@code "noCompile"}).
147+ * The first use logs a deprecation warning; this block will be removed
148+ * in 7.3.
149+ * // @formatter:on
150+ *
131151 * @param tags (globs)
132152 * @return <code>true</code> if any of the given tags is included in the
133153 * current set of tags, otherwise returns <code>false</code>. Also
@@ -147,19 +167,26 @@ public boolean includesAny(String... tags) {
147167
148168 for (String tagGlob : tags ) {
149169
170+ String phase = tagGlob ; // e.g. "compile"
171+ String negativePhase = "no" + phase ; // "noCompile"
172+
173+ /* 1. Explicit negative tag blocks this phase --------------- */
174+ if (matchesAny (new Glob (negativePhase ))) {
175+ continue ; // try next requested tag
176+ }
177+
178+ /* 2. Positive tag match ------------------------------------ */
150179 if (matchesAny (new Glob (tagGlob ))) {
151- return true ;
180+ return true ; // success
152181 }
153182
154- // ──────────────────────────────────────────────────────────
155- // ↓↓↓ Transitional bridge 7.2 → 7.3 (compile ⇒ resolve)
156- // ──────────────────────────────────────────────────────────
157- if (TRANSITION_COMPILE_IMPLIES_RESOLVE && "compile" .equalsIgnoreCase (tagGlob ) // request
158- // is
159- // 'compile'
160- && matchesAny (new Glob ("resolve" ))) { // entity has 'resolve'
183+ /* 3. Transitional bridge (compile ⇒ resolve) -------------- */
184+ if (TRANSITION_COMPILE_IMPLIES_RESOLVE && "compile" .equalsIgnoreCase (phase )
185+ && matchesAny (new Glob ("resolve" )) && !matchesAny (new Glob ("noCompile" ))) { // negative
186+ // still
187+ // wins
161188
162- warnOnceCompileResolveBridge (); // log only once
189+ warnOnceCompileResolveBridge (); // log only first time
163190 return true ;
164191 }
165192 // ↑↑↑ remove in 7.3
@@ -169,11 +196,13 @@ && matchesAny(new Glob("resolve"))) { // entity has 'resolve'
169196
170197 }
171198
199+
172200 private boolean matchesAny (Glob glob ) {
173201 return internalSet .stream ()
174202 .anyMatch (s -> glob .matches (s ));
175203 }
176204
205+
177206 /**
178207 * @param name
179208 * @return a Tags instance with the given tags.
0 commit comments