All Downloads are FREE. Search and download functionalities are using the official Maven repository.

software.amazon.smithy.model.neighbor.UnreferencedTraitDefinitions Maven / Gradle / Ivy

/*
 * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

package software.amazon.smithy.model.neighbor;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import software.amazon.smithy.model.Model;
import software.amazon.smithy.model.knowledge.NeighborProviderIndex;
import software.amazon.smithy.model.loader.Prelude;
import software.amazon.smithy.model.shapes.ServiceShape;
import software.amazon.smithy.model.shapes.Shape;
import software.amazon.smithy.model.shapes.ShapeId;
import software.amazon.smithy.model.traits.TraitDefinition;
import software.amazon.smithy.utils.FunctionalUtils;

/**
 * Finds trait definitions that are not connected to a service shape.
 *
 * 

Prelude traits are never considered unreferenced. */ public final class UnreferencedTraitDefinitions { private final Predicate keepFilter; public UnreferencedTraitDefinitions() { this(FunctionalUtils.alwaysTrue()); } /** * @param keepFilter Predicate that if matched keeps a trait definition from being unreferenced. */ public UnreferencedTraitDefinitions(Predicate keepFilter) { this.keepFilter = keepFilter; } public Set compute(Model model) { Walker walker = new Walker(NeighborProviderIndex.of(model).getProvider()); // Begin with a mutable set of all trait definitions contained in the model Set unused = model.getShapesWithTrait(TraitDefinition.class).stream() // Exclude prelude traits -- these are defined by Smithy, not by the model itself .filter(FunctionalUtils.not(Prelude::isPreludeShape)) .collect(Collectors.toSet()); // Find all traits used directly or indirectly by a service shape and remove // their definitions from the unused set. model.shapes(ServiceShape.class) .flatMap(service -> walker.walkShapes(service).stream()) .distinct() .map(Shape::getAllTraits) .flatMap(traits -> traits.keySet().stream()) .distinct() .flatMap(traitId -> getTraitShapes(model, traitId).stream()) .filter(keepFilter) .forEach(unused::remove); return unused; } private Collection getTraitShapes(Model model, ShapeId traitId) { return getTraitShapes(model, traitId, new HashMap<>()).values(); } private Map getTraitShapes(Model model, ShapeId traitId, Map traitShapes) { Optional initialTraitShapeOp = model.getShape(traitId); if (initialTraitShapeOp.isPresent()) { Shape initialTraitShape = initialTraitShapeOp.get(); traitShapes.put(traitId, initialTraitShape); for (ShapeId metaTraitId : initialTraitShape.getAllTraits().keySet()) { if (!metaTraitId.equals(TraitDefinition.ID) && !traitShapes.containsKey(metaTraitId)) { traitShapes.putAll(getTraitShapes(model, metaTraitId, traitShapes)); } } } return traitShapes; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy