Fix InferredStatementContext.isSupportedByFeatures() 51/106351/8
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 1 Jun 2023 14:24:45 +0000 (16:24 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Sat, 3 Jun 2023 07:34:09 +0000 (09:34 +0200)
StmtContextUtils.checkFeatureSupport() does not work for
InferredStatementContext, as it does not have any declared
substatements -- that only works for OriginalStmtCtx and its subclasses.

Split out computation of this statement's contribution to
isSupportedByFeatures() into a separate method -- allowing
{Inferred,Replica}StatementContext to forward to their prototype or
source.

This also flushes out a bad assertion in YT1393Test, as the second
augment now get correctly disabled.

JIRA: YANGTOOLS-1514
Change-Id: Icf9740cd828bd337b76f38cf33ee29d607f680aa
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/InferredStatementContext.java
parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/OriginalStmtCtx.java
parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReactorStmtCtx.java
parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReplicaStatementContext.java
parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/UsesStatementSupport.java
parser/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1393Test.java
parser/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1514Test.java [new file with mode: 0644]
parser/yang-parser-rfc7950/src/test/resources/bugs/YT1514/foo.yang [new file with mode: 0644]

index 7f61710bec8c5ddf8ff3a727ff24a920f2e33859..f3aa2e9b99c2712ab2ab845193c1c79e189bc52f 100644 (file)
@@ -729,6 +729,11 @@ final class InferredStatementContext<A, D extends DeclaredStatement<A>, E extend
         return ret;
     }
 
+    @Override
+    boolean computeSupportedByFeatures() {
+        return prototype.isSupportedByFeatures();
+    }
+
     @Override
     protected boolean isParentSupportedByFeatures() {
         return parent.isSupportedByFeatures();
index 1cb67054b830e7fdb1a5ee8a63026e11089a6bb6..48ce7189f3c8f032af069693c4d6a72d405a2376 100644 (file)
@@ -18,12 +18,15 @@ import java.util.List;
 import java.util.Optional;
 import java.util.stream.Stream;
 import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.Empty;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.parser.spi.ParserNamespaces;
 import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
 import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -38,7 +41,7 @@ abstract class OriginalStmtCtx<A, D extends DeclaredStatement<A>, E extends Effe
 
     OriginalStmtCtx(final OriginalStmtCtx<A, D, E> original) {
         super(original);
-        this.ref = original.ref;
+        ref = original.ref;
     }
 
     OriginalStmtCtx(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref) {
@@ -121,6 +124,13 @@ abstract class OriginalStmtCtx<A, D extends DeclaredStatement<A>, E extends Effe
             || noSensitiveSubstatements(effective) && noSensitiveSubstatements(mutableDeclaredSubstatements());
     }
 
+    @Override
+    final boolean computeSupportedByFeatures() {
+        // If the set of supported features has not been provided, all features are supported by default.
+        final var supportedFeatures = namespaceItem(ParserNamespaces.SUPPORTED_FEATURES, Empty.value());
+        return supportedFeatures == null || StmtContextUtils.checkFeatureSupport(this, supportedFeatures);
+    }
+
     @Override
     final void markNoParentRef() {
         markNoParentRef(mutableDeclaredSubstatements());
index ad8f95c21c2b43ac781c007a0db60ff93b12b5c4..ef6b1154b784bf617c4a42196a79d4b32d10a281 100644 (file)
@@ -19,7 +19,6 @@ import java.util.Optional;
 import java.util.stream.Stream;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.yangtools.yang.common.Empty;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.common.YangVersion;
@@ -33,7 +32,6 @@ import org.opendaylight.yangtools.yang.model.api.stmt.RefineStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
 import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement;
 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
-import org.opendaylight.yangtools.yang.parser.spi.ParserNamespaces;
 import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
 import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStatementState;
 import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
@@ -484,16 +482,10 @@ abstract class ReactorStmtCtx<A, D extends DeclaredStatement<A>, E extends Effec
             return true;
         }
 
-        /*
-         * If parent is supported, we need to check if-features statements of this context.
-         */
-        if (isParentSupportedByFeatures()) {
-            // If the set of supported features has not been provided, all features are supported by default.
-            final var supportedFeatures = namespaceItem(ParserNamespaces.SUPPORTED_FEATURES, Empty.value());
-            if (supportedFeatures == null || StmtContextUtils.checkFeatureSupport(this, supportedFeatures)) {
-                flags |= SET_SUPPORTED_BY_FEATURES;
-                return true;
-            }
+        // If parent is supported, we need to check if-features statements of this context.
+        if (isParentSupportedByFeatures() && computeSupportedByFeatures()) {
+            flags |= SET_SUPPORTED_BY_FEATURES;
+            return true;
         }
 
         // Either parent is not supported or this statement is not supported
@@ -501,6 +493,14 @@ abstract class ReactorStmtCtx<A, D extends DeclaredStatement<A>, E extends Effec
         return false;
     }
 
+    /**
+     * Compute whether this statement is supported by features. Returned value is combined with
+     * {@link #isParentSupportedByFeatures()} and cached.
+     *
+     * @return {@code true} if the current feature set matches {@code if-feature} of this statement
+     */
+    abstract boolean computeSupportedByFeatures();
+
     protected abstract boolean isParentSupportedByFeatures();
 
     /**
index 5af0597bc684fb8f0e2ae5a505d40175f1c4e866..5e900158de2442e1c6f18f52f037cfe166dc3c38 100644 (file)
@@ -262,6 +262,11 @@ final class ReplicaStatementContext<A, D extends DeclaredStatement<A>, E extends
         return isIgnoringConfig(parent);
     }
 
+    @Override
+    boolean computeSupportedByFeatures() {
+        return source.isSupportedByFeatures();
+    }
+
     @Override
     protected boolean isParentSupportedByFeatures() {
         return parent.isSupportedByFeatures();
index c9a8495502f251d96cfac21a13c1fef0e2ef257b..cd9b9b13248ff651f0430335c224a6e88bf3273e 100644 (file)
@@ -301,7 +301,7 @@ public final class UsesStatementSupport
 
         // Target is a prerequisite for the 'refine', hence if the target is not supported, the refine is not supported
         // as well. Otherwise add a pointer to the target into refine's local namespace.
-        if (refineTargetNodeCtx.isSupportedToBuildEffective()) {
+        if (refineTargetNodeCtx.isSupportedToBuildEffective() && refineTargetNodeCtx.isSupportedByFeatures()) {
             subStmtCtx.addToNs(RefineTargetNamespace.INSTANCE, Empty.value(), refineTargetNodeCtx);
         } else {
             subStmtCtx.setUnsupported();
index bec1ac8099ba46549ede02dca40fbb9b6892e7f2..7eb086f6cbb94657c05afb9c8c63e85ee643378d 100644 (file)
@@ -35,7 +35,7 @@ class YT1393Test {
         final var module = StmtTestUtils.parseYangSource("/bugs/YT1393/baz.yang", Set.of())
             .findModuleStatement(QName.create("baz", "baz"))
             .orElseThrow();
-        assertEquals(5, module.effectiveSubstatements().size());
+        assertEquals(4, module.effectiveSubstatements().size());
     }
 
     @Test
diff --git a/parser/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1514Test.java b/parser/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1514Test.java
new file mode 100644 (file)
index 0000000..55d0de5
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2023 PANTHEON.tech s.r.o. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.stmt;
+
+import java.util.Set;
+import org.junit.jupiter.api.Test;
+
+class YT1514Test extends AbstractYangTest {
+    @Test
+    void testLeafFooFeatureSupported() {
+        assertEffectiveModelDir("/bugs/YT1514", Set.of());
+    }
+}
diff --git a/parser/yang-parser-rfc7950/src/test/resources/bugs/YT1514/foo.yang b/parser/yang-parser-rfc7950/src/test/resources/bugs/YT1514/foo.yang
new file mode 100644 (file)
index 0000000..a5e6115
--- /dev/null
@@ -0,0 +1,25 @@
+module foo {
+  namespace foo;
+  prefix foo;
+
+  feature feat;
+
+  grouping grp {
+    choice foo {
+      case bar {
+        if-feature feat;
+        leaf baz {
+          type string;
+        }
+      }
+    }
+  }
+
+  container cont {
+    uses grp {
+      refine foo/bar/baz {
+        reference "something";
+      }
+    }
+  }
+}