private static List<String> areShapesCompatible(Shape oldShape, Shape newShape) {
        if (oldShape == null || newShape == null) {
            return ListUtils.of();
        }

        if (oldShape.getType() != newShape.getType()) {
            return ListUtils.of(String.format("The type of the targeted shape changed from %s to %s",
                    oldShape.getType(),
                    newShape.getType()));
        }

        if (!(oldShape instanceof SimpleShape || oldShape instanceof CollectionShape || oldShape instanceof MapShape)) {
            return ListUtils.of(String.format("The name of a %s is significant", oldShape.getType()));
        }

        List<String> results = new ArrayList<>();
        for (ShapeId significantCodegenTrait : SIGNIFICANT_CODEGEN_TRAITS) {
            if (oldShape.hasTrait(significantCodegenTrait)) {
                results.add(String.format("The `%s` trait was found on the target, so the name of the targeted "
                        + "shape matters for codegen",
                        significantCodegenTrait));
            }
        }

        if (!oldShape.getAllTraits().equals(newShape.getAllTraits())) {
            results.add(createTraitDiffMessage(oldShape, newShape));
        }

        if (oldShape instanceof CollectionShape) {
            evaluateMember(oldShape.getType(),
                    results,
                    ((CollectionShape) oldShape).getMember(),
                    ((CollectionShape) newShape).getMember());
        } else if (oldShape instanceof MapShape) {
            MapShape oldMapShape = (MapShape) oldShape;
            MapShape newMapShape = (MapShape) newShape;
            // Both the key and value need to be evaluated for maps.
            evaluateMember(oldShape.getType(),
                    results,
                    oldMapShape.getKey(),
                    newMapShape.getKey());
            evaluateMember(oldShape.getType(),
                    results,
                    oldMapShape.getValue(),
                    newMapShape.getValue());
        }

        return results;
    }
These traits are traits that are known to significantly influence
code generation. Right now it just contains the enum trait, but
other traits could be added in the future as needed.
smithy-diff/src/main/java/software/amazon/smithy/diff/evaluators/ChangedMemberTarget.java