From: Robert Varga Date: Sat, 5 Dec 2020 13:27:37 +0000 (+0100) Subject: Do not access TypeNamespace during declared build X-Git-Tag: v7.0.0~371 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;ds=sidebyside;h=b5b039cadb34a19c97929327928818185a6e877c;p=yangtools.git Do not access TypeNamespace during declared build We have a shadowing check here which is being executed at buildDeclared() time. Move the check into an inference action, so that we do not even go to statement build if it is violated. JIRA: YANGTOOLS-1198 Change-Id: Ibb5d121862bc2d822c5919a3233ae790412e53f4 Signed-off-by: Robert Varga --- diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/typedef/TypedefStatementSupport.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/typedef/TypedefStatementSupport.java index 2f534f9b38..3eb0ccdded 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/typedef/TypedefStatementSupport.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/typedef/TypedefStatementSupport.java @@ -10,6 +10,7 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.typedef; import static com.google.common.base.Preconditions.checkState; import com.google.common.collect.ImmutableList; +import java.util.Collection; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.Status; import org.opendaylight.yangtools.yang.model.api.YangStmtMapping; @@ -25,6 +26,11 @@ import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMix import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStmtUtils; import org.opendaylight.yangtools.yang.parser.spi.TypeNamespace; import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.InferenceAction; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.InferenceContext; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.Prerequisite; +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.StmtContext.Mutable; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; @@ -61,13 +67,32 @@ public final class TypedefStatementSupport extends public void onFullDefinitionDeclared(final Mutable stmt) { super.onFullDefinitionDeclared(stmt); - if (stmt != null) { - final Mutable parent = stmt.getParentContext(); - if (parent != null) { - // Shadowing check: make sure we do not trample on pre-existing definitions. This catches sibling - // declarations and parent declarations which have already been declared. - checkConflict(parent, stmt); - parent.addContext(TypeNamespace.class, stmt.getArgument(), stmt); + final Mutable parent = stmt.getParentContext(); + if (parent != null) { + // Shadowing check: make sure we do not trample on pre-existing definitions. This catches sibling + // declarations and parent declarations which have already been declared. + checkConflict(parent, stmt); + parent.addContext(TypeNamespace.class, stmt.getArgument(), stmt); + + final StmtContext grandParent = parent.getParentContext(); + if (grandParent != null) { + // Shadowing check: make sure grandparent does not see a conflicting definition. This is required to + // ensure that a typedef in child scope does not shadow a typedef in parent scope which occurs later in + // the text. For that check we need the full declaration of our model. + + final ModelActionBuilder action = stmt.newInferenceAction(ModelProcessingPhase.FULL_DECLARATION); + action.requiresCtx(grandParent.getRoot(), ModelProcessingPhase.FULL_DECLARATION); + action.apply(new InferenceAction() { + @Override + public void apply(final InferenceContext ctx) { + checkConflict(grandParent, stmt); + } + + @Override + public void prerequisiteFailed(final Collection> failed) { + // No-op + } + }); } } } @@ -80,13 +105,11 @@ public final class TypedefStatementSupport extends @Override protected TypedefStatement createDeclared(final StmtContext ctx, final ImmutableList> substatements) { - checkDeclared(ctx); return new RegularTypedefStatement(ctx.getArgument(), substatements); } @Override protected TypedefStatement createEmptyDeclared(final StmtContext ctx) { - checkDeclared(ctx); return new EmptyTypedefStatement(ctx.getArgument()); } @@ -114,18 +137,6 @@ public final class TypedefStatementSupport extends SourceException.throwIf(existing != null, stmt, "Duplicate name for typedef %s", arg); } - private static void checkDeclared(final StmtContext ctx) { - // Shadowing check: make sure grandparent does not see a conflicting definition. This is required to ensure - // that a typedef in child scope does not shadow a typedef in parent scope which occurs later in the text. - final StmtContext parent = ctx.getParentContext(); - if (parent != null) { - final StmtContext grandParent = parent.getParentContext(); - if (grandParent != null) { - checkConflict(grandParent, ctx); - } - } - } - private static int computeFlags(final ImmutableList> substatements) { return new FlagsBuilder() .setStatus(findFirstArgument(substatements, StatusEffectiveStatement.class, Status.CURRENT))