X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=binding%2Fmdsal-binding-generator%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fmdsal%2Fbinding%2Fgenerator%2Fimpl%2Freactor%2FAbstractCompositeGenerator.java;h=5d74b61ad083ffde5e27683cd134c432daa13ada;hb=b1e88583f0d16ef8b8dab5d43f61978e064e27e5;hp=810d2d876d493a3e36a6187c4e3f5da57e8249f0;hpb=4460442fba0d2efe0249a42b371ba21f1c898273;p=mdsal.git diff --git a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/AbstractCompositeGenerator.java b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/AbstractCompositeGenerator.java index 810d2d876d..5d74b61ad0 100644 --- a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/AbstractCompositeGenerator.java +++ b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/AbstractCompositeGenerator.java @@ -8,19 +8,24 @@ package org.opendaylight.mdsal.binding.generator.impl.reactor; import static com.google.common.base.Verify.verify; +import static com.google.common.base.Verify.verifyNotNull; import static java.util.Objects.requireNonNull; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.mdsal.binding.model.api.Enumeration; import org.opendaylight.mdsal.binding.model.api.GeneratedTransferObject; -import org.opendaylight.mdsal.binding.model.api.GeneratedType; +import org.opendaylight.mdsal.binding.model.api.Type; import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilder; import org.opendaylight.mdsal.binding.model.ri.BindingTypes; +import org.opendaylight.mdsal.binding.runtime.api.CompositeRuntimeType; +import org.opendaylight.mdsal.binding.runtime.api.RuntimeType; +import org.opendaylight.yangtools.rfc8040.model.api.YangDataEffectiveStatement; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.AddedByUsesAware; import org.opendaylight.yangtools.yang.model.api.CopyableNode; @@ -32,6 +37,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.AugmentEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.CaseEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ChoiceEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ContainerEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.FeatureEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.GroupingEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.IdentityEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.InputEffectiveStatement; @@ -108,19 +114,20 @@ import org.slf4j.LoggerFactory; * with linking original instances in the tree iteration order. The part dealing with augment attachment lives mostly * in {@link AugmentRequirement}. */ -abstract class AbstractCompositeGenerator> extends AbstractExplicitGenerator { +public abstract class AbstractCompositeGenerator, R extends CompositeRuntimeType> + extends AbstractExplicitGenerator { private static final Logger LOG = LoggerFactory.getLogger(AbstractCompositeGenerator.class); // FIXME: we want to allocate this lazily to lower memory footprint private final @NonNull CollisionDomain domain = new CollisionDomain(this); - private final List children; + private final @NonNull List childGenerators; /** * List of {@code augment} statements targeting this generator. This list is maintained only for the primary * incarnation. This list is an evolving entity until after we have finished linkage of original statements. It is * expected to be stable at the start of {@code step 2} in {@link GeneratorReactor#execute(TypeBuilderFactory)}. */ - private List augments = List.of(); + private @NonNull List augments = List.of(); /** * List of {@code grouping} statements this statement references. This field is set once by @@ -133,53 +140,73 @@ abstract class AbstractCompositeGenerator> ex * have some children which have not completed linking. Once we have completed linking of all children, including * {@link #unlinkedChildren}, this will be set to {@code null}. */ - private List> unlinkedComposites = List.of(); + private List> unlinkedComposites = List.of(); /** * List of children which have not had their original linked. This list starts of as null. When we first attempt * linkage, it becomes non-null. */ private List unlinkedChildren; - AbstractCompositeGenerator(final T statement) { + AbstractCompositeGenerator(final S statement) { super(statement); - children = createChildren(statement); + childGenerators = createChildren(statement); } - AbstractCompositeGenerator(final T statement, final AbstractCompositeGenerator parent) { + AbstractCompositeGenerator(final S statement, final AbstractCompositeGenerator parent) { super(statement, parent); - children = createChildren(statement); + childGenerators = createChildren(statement); } @Override public final Iterator iterator() { - return children.iterator(); + return childGenerators.iterator(); + } + + final @NonNull List augments() { + return augments; + } + + final @NonNull List groupings() { + return verifyNotNull(groupings, "Groupings not initialized in %s", this); + } + + @Override + final R createExternalRuntimeType(final Type type) { + return createBuilder(statement()).populate(new AugmentResolver(), this).build(verifyGeneratedType(type)); + } + + abstract @NonNull CompositeRuntimeTypeBuilder createBuilder(S statement); + + @Override + final R createInternalRuntimeType(final AugmentResolver resolver, final S statement, final Type type) { + return createBuilder(statement).populate(resolver, this).build(verifyGeneratedType(type)); } @Override final boolean isEmpty() { - return children.isEmpty(); + return childGenerators.isEmpty(); } - final @Nullable AbstractExplicitGenerator findGenerator(final List> stmtPath) { + final @Nullable AbstractExplicitGenerator findGenerator(final List> stmtPath) { return findGenerator(MatchStrategy.identity(), stmtPath, 0); } - final @Nullable AbstractExplicitGenerator findGenerator(final MatchStrategy childStrategy, + final @Nullable AbstractExplicitGenerator findGenerator(final MatchStrategy childStrategy, // TODO: Wouldn't this method be nicer with Deque> ? final List> stmtPath, final int offset) { - final EffectiveStatement stmt = stmtPath.get(offset); + final var stmt = stmtPath.get(offset); // Try direct children first, which is simple - AbstractExplicitGenerator ret = childStrategy.findGenerator(stmt, children); + var ret = childStrategy.findGenerator(stmt, childGenerators); if (ret != null) { final int next = offset + 1; if (stmtPath.size() == next) { // Final step, return child return ret; } - if (ret instanceof AbstractCompositeGenerator) { + if (ret instanceof AbstractCompositeGenerator composite) { // We know how to descend down - return ((AbstractCompositeGenerator) ret).findGenerator(childStrategy, stmtPath, next); + return composite.findGenerator(childStrategy, stmtPath, next); } // Yeah, don't know how to continue here return null; @@ -222,18 +249,17 @@ abstract class AbstractCompositeGenerator> ex // - we propagate those groupings as anchors to any augment statements, which takes out some amount of guesswork // from augment+uses resolution case, as groupings know about their immediate augments as soon as uses linkage // is resolved - final List tmp = new ArrayList<>(); - for (EffectiveStatement stmt : statement().effectiveSubstatements()) { - if (stmt instanceof UsesEffectiveStatement) { - final UsesEffectiveStatement uses = (UsesEffectiveStatement) stmt; - final GroupingGenerator grouping = context.resolveTreeScoped(GroupingGenerator.class, uses.argument()); + final var tmp = new ArrayList(); + for (var stmt : statement().effectiveSubstatements()) { + if (stmt instanceof UsesEffectiveStatement uses) { + final var grouping = context.resolveTreeScoped(GroupingGenerator.class, uses.argument()); tmp.add(grouping); // Trigger resolution of uses/augment statements. This looks like guesswork, but there may be multiple // 'augment' statements in a 'uses' statement and keeping a ListMultimap here seems wasteful. for (Generator gen : this) { - if (gen instanceof UsesAugmentGenerator) { - ((UsesAugmentGenerator) gen).resolveGrouping(uses, grouping); + if (gen instanceof UsesAugmentGenerator usesGen) { + usesGen.resolveGrouping(uses, grouping); } } } @@ -241,13 +267,36 @@ abstract class AbstractCompositeGenerator> ex groupings = List.copyOf(tmp); } + // Iterate over a some generators recursively, linking them to the GroupingGenerators they use. GroupingGenerators + // are skipped and added to unprocessedGroupings for later processing. + final void linkUsedGroupings(final Set skippedChildren) { + // Link to used groupings IFF we have a corresponding generated Java class + switch (classPlacement()) { + case NONE: + case PHANTOM: + break; + default: + for (var grouping : groupings()) { + grouping.addUser(this); + } + } + + for (var child : childGenerators) { + if (child instanceof GroupingGenerator grouping) { + skippedChildren.add(grouping); + } else if (child instanceof AbstractCompositeGenerator composite) { + composite.linkUsedGroupings(skippedChildren); + } + } + } + final void startUsesAugmentLinkage(final List requirements) { - for (Generator child : children) { - if (child instanceof UsesAugmentGenerator) { - requirements.add(((UsesAugmentGenerator) child).startLinkage()); + for (var child : childGenerators) { + if (child instanceof UsesAugmentGenerator uses) { + requirements.add(uses.startLinkage()); } - if (child instanceof AbstractCompositeGenerator) { - ((AbstractCompositeGenerator) child).startUsesAugmentLinkage(requirements); + if (child instanceof AbstractCompositeGenerator composite) { + composite.startUsesAugmentLinkage(requirements); } } } @@ -272,9 +321,9 @@ abstract class AbstractCompositeGenerator> ex } if (unlinkedChildren == null) { - unlinkedChildren = children.stream() + unlinkedChildren = childGenerators.stream() .filter(AbstractExplicitGenerator.class::isInstance) - .map(child -> (AbstractExplicitGenerator) child) + .map(child -> (AbstractExplicitGenerator) child) .collect(Collectors.toList()); } @@ -283,19 +332,16 @@ abstract class AbstractCompositeGenerator> ex // Attempt to make progress on child linkage final var it = unlinkedChildren.iterator(); while (it.hasNext()) { - final var child = it.next(); - if (child instanceof AbstractExplicitGenerator) { - if (((AbstractExplicitGenerator) child).linkOriginalGenerator()) { - progress = LinkageProgress.SOME; - it.remove(); - - // If this is a composite generator we need to process is further - if (child instanceof AbstractCompositeGenerator) { - if (unlinkedComposites.isEmpty()) { - unlinkedComposites = new ArrayList<>(); - } - unlinkedComposites.add((AbstractCompositeGenerator) child); + if (it.next() instanceof AbstractExplicitGenerator explicit && explicit.linkOriginalGenerator()) { + progress = LinkageProgress.SOME; + it.remove(); + + // If this is a composite generator we need to process is further + if (explicit instanceof AbstractCompositeGenerator composite) { + if (unlinkedComposites.isEmpty()) { + unlinkedComposites = new ArrayList<>(); } + unlinkedComposites.add(composite); } } } @@ -329,20 +375,21 @@ abstract class AbstractCompositeGenerator> ex } @Override - final AbstractCompositeGenerator getOriginal() { - return (AbstractCompositeGenerator) super.getOriginal(); + final AbstractCompositeGenerator getOriginal() { + return (AbstractCompositeGenerator) super.getOriginal(); } @Override - final AbstractCompositeGenerator tryOriginal() { - return (AbstractCompositeGenerator) super.tryOriginal(); + final AbstractCompositeGenerator tryOriginal() { + return (AbstractCompositeGenerator) super.tryOriginal(); } - final @Nullable OriginalLink originalChild(final QName childQName) { + final , Y extends RuntimeType> @Nullable OriginalLink originalChild( + final QName childQName) { // First try groupings/augments ... var found = findInferredGenerator(childQName); if (found != null) { - return OriginalLink.partial(found); + return (OriginalLink) OriginalLink.partial(found); } // ... no luck, we really need to start looking at our origin @@ -351,7 +398,7 @@ abstract class AbstractCompositeGenerator> ex final QName prevQName = childQName.bindTo(prev.getQName().getModule()); found = prev.findSchemaTreeGenerator(prevQName); if (found != null) { - return found.originalLink(); + return (OriginalLink) found.originalLink(); } } @@ -359,8 +406,8 @@ abstract class AbstractCompositeGenerator> ex } @Override - final AbstractExplicitGenerator findSchemaTreeGenerator(final QName qname) { - final AbstractExplicitGenerator found = super.findSchemaTreeGenerator(qname); + final AbstractExplicitGenerator findSchemaTreeGenerator(final QName qname) { + final var found = super.findSchemaTreeGenerator(qname); return found != null ? found : findInferredGenerator(qname); } @@ -375,7 +422,7 @@ abstract class AbstractCompositeGenerator> ex } final @Nullable GroupingGenerator findGroupingForGenerator(final QName qname) { - for (GroupingGenerator grouping : groupings) { + for (var grouping : groupings) { final var gen = grouping.findSchemaTreeGenerator(qname.bindTo(grouping.statement().argument().getModule())); if (gen != null) { return grouping; @@ -384,7 +431,7 @@ abstract class AbstractCompositeGenerator> ex return null; } - private @Nullable AbstractExplicitGenerator findInferredGenerator(final QName qname) { + private @Nullable AbstractExplicitGenerator findInferredGenerator(final QName qname) { // First search our local groupings ... for (var grouping : groupings) { final var gen = grouping.findSchemaTreeGenerator(qname.bindTo(grouping.statement().argument().getModule())); @@ -411,7 +458,7 @@ abstract class AbstractCompositeGenerator> ex * @return The number of groupings this type uses. */ final int addUsesInterfaces(final GeneratedTypeBuilder builder, final TypeBuilderFactory builderFactory) { - for (GroupingGenerator grp : groupings) { + for (var grp : groupings) { builder.addImplementsType(grp.getGeneratedType(builderFactory)); } return groupings.size(); @@ -422,90 +469,90 @@ abstract class AbstractCompositeGenerator> ex } final void addGetterMethods(final GeneratedTypeBuilder builder, final TypeBuilderFactory builderFactory) { - for (Generator child : this) { + for (var child : this) { // Only process explicit generators here - if (child instanceof AbstractExplicitGenerator) { - ((AbstractExplicitGenerator) child).addAsGetterMethod(builder, builderFactory); + if (child instanceof AbstractExplicitGenerator explicit) { + explicit.addAsGetterMethod(builder, builderFactory); } - final GeneratedType enclosedType = child.enclosedType(builderFactory); - if (enclosedType instanceof GeneratedTransferObject) { - builder.addEnclosingTransferObject((GeneratedTransferObject) enclosedType); - } else if (enclosedType instanceof Enumeration) { - builder.addEnumeration((Enumeration) enclosedType); + final var enclosedType = child.enclosedType(builderFactory); + if (enclosedType instanceof GeneratedTransferObject gto) { + builder.addEnclosingTransferObject(gto); + } else if (enclosedType instanceof Enumeration enumeration) { + builder.addEnumeration(enumeration); } else { verify(enclosedType == null, "Unhandled enclosed type %s in %s", enclosedType, child); } } } - private List createChildren(final EffectiveStatement statement) { - final List tmp = new ArrayList<>(); - final List tmpAug = new ArrayList<>(); + private @NonNull List createChildren(final EffectiveStatement statement) { + final var tmp = new ArrayList(); + final var tmpAug = new ArrayList(); - for (EffectiveStatement stmt : statement.effectiveSubstatements()) { - if (stmt instanceof ActionEffectiveStatement) { - if (!isAugmenting(stmt)) { - tmp.add(new ActionGenerator((ActionEffectiveStatement) stmt, this)); + for (var stmt : statement.effectiveSubstatements()) { + if (stmt instanceof ActionEffectiveStatement action) { + if (!isAugmenting(action)) { + tmp.add(new ActionGenerator(action, this)); } - } else if (stmt instanceof AnydataEffectiveStatement) { - if (!isAugmenting(stmt)) { - tmp.add(new OpaqueObjectGenerator<>((AnydataEffectiveStatement) stmt, this)); + } else if (stmt instanceof AnydataEffectiveStatement anydata) { + if (!isAugmenting(anydata)) { + tmp.add(new OpaqueObjectGenerator.Anydata(anydata, this)); } - } else if (stmt instanceof AnyxmlEffectiveStatement) { - if (!isAugmenting(stmt)) { - tmp.add(new OpaqueObjectGenerator<>((AnyxmlEffectiveStatement) stmt, this)); + } else if (stmt instanceof AnyxmlEffectiveStatement anyxml) { + if (!isAugmenting(anyxml)) { + tmp.add(new OpaqueObjectGenerator.Anyxml(anyxml, this)); } - } else if (stmt instanceof CaseEffectiveStatement) { - tmp.add(new CaseGenerator((CaseEffectiveStatement) stmt, this)); - } else if (stmt instanceof ChoiceEffectiveStatement) { + } else if (stmt instanceof CaseEffectiveStatement cast) { + tmp.add(new CaseGenerator(cast, this)); + } else if (stmt instanceof ChoiceEffectiveStatement choice) { // FIXME: use isOriginalDeclaration() ? - if (!isAddedByUses(stmt)) { - tmp.add(new ChoiceGenerator((ChoiceEffectiveStatement) stmt, this)); + if (!isAddedByUses(choice)) { + tmp.add(new ChoiceGenerator(choice, this)); } - } else if (stmt instanceof ContainerEffectiveStatement) { - if (isOriginalDeclaration(stmt)) { - tmp.add(new ContainerGenerator((ContainerEffectiveStatement) stmt, this)); + } else if (stmt instanceof ContainerEffectiveStatement container) { + if (isOriginalDeclaration(container)) { + tmp.add(new ContainerGenerator(container, this)); } - } else if (stmt instanceof GroupingEffectiveStatement) { - tmp.add(new GroupingGenerator((GroupingEffectiveStatement) stmt, this)); - } else if (stmt instanceof IdentityEffectiveStatement) { - tmp.add(new IdentityGenerator((IdentityEffectiveStatement) stmt, this)); - } else if (stmt instanceof InputEffectiveStatement) { - // FIXME: do not generate legacy RPC layout - tmp.add(this instanceof RpcGenerator ? new RpcContainerGenerator((InputEffectiveStatement) stmt, this) - : new OperationContainerGenerator((InputEffectiveStatement) stmt, this)); - } else if (stmt instanceof LeafEffectiveStatement) { - if (!isAugmenting(stmt)) { - tmp.add(new LeafGenerator((LeafEffectiveStatement) stmt, this)); + } else if (stmt instanceof FeatureEffectiveStatement feature && this instanceof ModuleGenerator parent) { + tmp.add(new FeatureGenerator(feature, parent)); + } else if (stmt instanceof GroupingEffectiveStatement grouping) { + tmp.add(new GroupingGenerator(grouping, this)); + } else if (stmt instanceof IdentityEffectiveStatement identity) { + tmp.add(new IdentityGenerator(identity, this)); + } else if (stmt instanceof InputEffectiveStatement input) { + tmp.add(new InputGenerator(input, this)); + } else if (stmt instanceof LeafEffectiveStatement leaf) { + if (!isAugmenting(leaf)) { + tmp.add(new LeafGenerator(leaf, this)); } - } else if (stmt instanceof LeafListEffectiveStatement) { - if (!isAugmenting(stmt)) { - tmp.add(new LeafListGenerator((LeafListEffectiveStatement) stmt, this)); + } else if (stmt instanceof LeafListEffectiveStatement leafList) { + if (!isAugmenting(leafList)) { + tmp.add(new LeafListGenerator(leafList, this)); } - } else if (stmt instanceof ListEffectiveStatement) { - if (isOriginalDeclaration(stmt)) { - final ListGenerator listGen = new ListGenerator((ListEffectiveStatement) stmt, this); + } else if (stmt instanceof ListEffectiveStatement list) { + if (isOriginalDeclaration(list)) { + final var listGen = new ListGenerator(list, this); tmp.add(listGen); - final KeyGenerator keyGen = listGen.keyGenerator(); + final var keyGen = listGen.keyGenerator(); if (keyGen != null) { tmp.add(keyGen); } } - } else if (stmt instanceof NotificationEffectiveStatement) { - if (!isAugmenting(stmt)) { - tmp.add(new NotificationGenerator((NotificationEffectiveStatement) stmt, this)); + } else if (stmt instanceof NotificationEffectiveStatement notification) { + if (!isAugmenting(notification)) { + tmp.add(new NotificationGenerator(notification, this)); } - } else if (stmt instanceof OutputEffectiveStatement) { - // FIXME: do not generate legacy RPC layout - tmp.add(this instanceof RpcGenerator ? new RpcContainerGenerator((OutputEffectiveStatement) stmt, this) - : new OperationContainerGenerator((OutputEffectiveStatement) stmt, this)); - } else if (stmt instanceof RpcEffectiveStatement) { - tmp.add(new RpcGenerator((RpcEffectiveStatement) stmt, this)); - } else if (stmt instanceof TypedefEffectiveStatement) { - tmp.add(new TypedefGenerator((TypedefEffectiveStatement) stmt, this)); - } else if (stmt instanceof AugmentEffectiveStatement) { + } else if (stmt instanceof OutputEffectiveStatement output) { + tmp.add(new OutputGenerator(output, this)); + } else if (stmt instanceof RpcEffectiveStatement rpc) { + if (this instanceof ModuleGenerator module) { + tmp.add(new RpcGenerator(rpc, module)); + } + } else if (stmt instanceof TypedefEffectiveStatement typedef) { + tmp.add(new TypedefGenerator(typedef, this)); + } else if (stmt instanceof AugmentEffectiveStatement augment) { // FIXME: MDSAL-695: So here we are ignoring any augment which is not in a module, while the 'uses' // processing takes care of the rest. There are two problems here: // @@ -520,16 +567,19 @@ abstract class AbstractCompositeGenerator> ex // So here is where we should decide how to handle this augment, and make sure we // retain information about this being an alias. That will serve as the base for keys // in the augment -> original map we provide to BindingRuntimeTypes. - if (this instanceof ModuleGenerator) { - tmpAug.add(new ModuleAugmentGenerator((AugmentEffectiveStatement) stmt, this)); + if (this instanceof ModuleGenerator module) { + tmpAug.add(new ModuleAugmentGenerator(augment, module)); } - } else if (stmt instanceof UsesEffectiveStatement) { - final UsesEffectiveStatement uses = (UsesEffectiveStatement) stmt; - for (EffectiveStatement usesSub : uses.effectiveSubstatements()) { - if (usesSub instanceof AugmentEffectiveStatement) { - tmpAug.add(new UsesAugmentGenerator((AugmentEffectiveStatement) usesSub, uses, this)); + } else if (stmt instanceof UsesEffectiveStatement uses) { + for (var usesSub : uses.effectiveSubstatements()) { + if (usesSub instanceof AugmentEffectiveStatement usesAug) { + tmpAug.add(new UsesAugmentGenerator(usesAug, uses, this)); } } + } else if (stmt instanceof YangDataEffectiveStatement yangData) { + if (this instanceof ModuleGenerator moduleGen) { + tmp.add(YangDataGenerator.of(yangData, moduleGen)); + } } else { LOG.trace("Ignoring statement {}", stmt); } @@ -541,48 +591,24 @@ abstract class AbstractCompositeGenerator> ex // substatements to establish this order. tmpAug.sort(AbstractAugmentGenerator.COMPARATOR); tmp.addAll(tmpAug); - - // Compatibility FooService and FooListener interfaces, only generated for modules. - if (this instanceof ModuleGenerator) { - final ModuleGenerator moduleGen = (ModuleGenerator) this; - - final List notifs = tmp.stream() - .filter(NotificationGenerator.class::isInstance) - .map(NotificationGenerator.class::cast) - .collect(Collectors.toUnmodifiableList()); - if (!notifs.isEmpty()) { - tmp.add(new NotificationServiceGenerator(moduleGen, notifs)); - } - - final List rpcs = tmp.stream() - .filter(RpcGenerator.class::isInstance) - .map(RpcGenerator.class::cast) - .collect(Collectors.toUnmodifiableList()); - if (!rpcs.isEmpty()) { - tmp.add(new RpcServiceGenerator(moduleGen, rpcs)); - } - } - return List.copyOf(tmp); } // Utility equivalent of (!isAddedByUses(stmt) && !isAugmenting(stmt)). Takes advantage of relationship between // CopyableNode and AddedByUsesAware private static boolean isOriginalDeclaration(final EffectiveStatement stmt) { - if (stmt instanceof AddedByUsesAware) { - if (((AddedByUsesAware) stmt).isAddedByUses() - || stmt instanceof CopyableNode && ((CopyableNode) stmt).isAugmenting()) { - return false; - } + if (stmt instanceof AddedByUsesAware aware + && (aware.isAddedByUses() || aware instanceof CopyableNode copyable && copyable.isAugmenting())) { + return false; } return true; } private static boolean isAddedByUses(final EffectiveStatement stmt) { - return stmt instanceof AddedByUsesAware && ((AddedByUsesAware) stmt).isAddedByUses(); + return stmt instanceof AddedByUsesAware aware && aware.isAddedByUses(); } private static boolean isAugmenting(final EffectiveStatement stmt) { - return stmt instanceof CopyableNode && ((CopyableNode) stmt).isAugmenting(); + return stmt instanceof CopyableNode copyable && copyable.isAugmenting(); } }