Skip to content

Use service renames #292

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
Expand All @@ -29,15 +28,13 @@
import java.util.logging.Logger;
import software.amazon.smithy.build.FileManifest;
import software.amazon.smithy.build.PluginContext;
import software.amazon.smithy.codegen.core.CodegenException;
import software.amazon.smithy.codegen.core.Symbol;
import software.amazon.smithy.codegen.core.SymbolDependency;
import software.amazon.smithy.codegen.core.SymbolProvider;
import software.amazon.smithy.codegen.core.TopologicalIndex;
import software.amazon.smithy.model.Model;
import software.amazon.smithy.model.knowledge.TopDownIndex;
import software.amazon.smithy.model.neighbor.Walker;
import software.amazon.smithy.model.shapes.MemberShape;
import software.amazon.smithy.model.shapes.OperationShape;
import software.amazon.smithy.model.shapes.ServiceShape;
import software.amazon.smithy.model.shapes.Shape;
Expand All @@ -46,10 +43,8 @@
import software.amazon.smithy.model.shapes.StringShape;
import software.amazon.smithy.model.shapes.StructureShape;
import software.amazon.smithy.model.shapes.UnionShape;
import software.amazon.smithy.model.traits.BoxTrait;
import software.amazon.smithy.model.traits.EnumTrait;
import software.amazon.smithy.model.traits.PaginatedTrait;
import software.amazon.smithy.model.traits.Trait;
import software.amazon.smithy.typescript.codegen.integration.ProtocolGenerator;
import software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin;
import software.amazon.smithy.typescript.codegen.integration.TypeScriptIntegration;
Expand Down Expand Up @@ -115,7 +110,7 @@ class CodegenVisitor extends ShapeVisitor.Default<Void> {
LOGGER.info(() -> "Generating TypeScript client for service " + service.getId());

// Decorate the symbol provider using integrations.
SymbolProvider resolvedProvider = TypeScriptCodegenPlugin.createSymbolProvider(model);
SymbolProvider resolvedProvider = TypeScriptCodegenPlugin.createSymbolProvider(model, settings);
for (TypeScriptIntegration integration : integrations) {
resolvedProvider = integration.decorateSymbolProvider(settings, model, resolvedProvider);
}
Expand Down Expand Up @@ -163,11 +158,12 @@ void execute() {

// Generate models that are connected to the service being generated.
LOGGER.fine("Walking shapes from " + service.getId() + " to find shapes to generate");
// Walk the tree and condense duplicate shapes
Collection<Shape> shapeSet = condenseShapes(new Walker(nonTraits).walkShapes(service));
// Walk the tree.
Collection<Shape> shapeSet = new Walker(nonTraits).walkShapes(service);

Model prunedModel = Model.builder().addShapes(shapeSet).build();

// Generate models from condensed shapes
// Generate models from shapes.
for (Shape shape : TopologicalIndex.of(prunedModel).getOrderedShapes()) {
shape.accept(this);
}
Expand Down Expand Up @@ -348,57 +344,4 @@ public Void serviceShape(ServiceShape shape) {

return null;
}

private Collection<Shape> condenseShapes(Set<Shape> shapes) {
Map<String, Shape> shapeMap = new LinkedHashMap<>();

// Check for colliding shapes and prune non-unique shapes
for (Shape shape : shapes) {
String shapeReference = shape.getType().toString() + shape.getId().asRelativeReference();

if (shapeMap.containsKey(shapeReference)) {
Shape knownShape = shapeMap.get(shapeReference);
if (isShapeCollision(shape, knownShape)) {
throw new CodegenException(("Shape Collision: cannot condense " + shape + " and " + knownShape));
}
} else {
shapeMap.put(shapeReference, shape);
}
}

return shapeMap.values();
}

private boolean isShapeCollision(Shape shapeA, Shape shapeB) {
// Check names match.
if (!shapeA.getId().getName().equals(shapeB.getId().getName())) {
return true;
}

// Check traits match.
Map<ShapeId, Trait> traitsA = new HashMap<>(shapeA.getAllTraits());
Map<ShapeId, Trait> traitsB = new HashMap<>(shapeB.getAllTraits());
// Ignore the box trait since it has no effect in JavaScript.
traitsA.remove(BoxTrait.ID);
traitsB.remove(BoxTrait.ID);
if (!traitsA.equals(traitsB)) {
return false;
}

// Check members match.
Collection<MemberShape> memberShapesA = shapeA.members();
Collection<MemberShape> memberShapesB = shapeB.members();
for (MemberShape memberShape : memberShapesA) {
if (!memberShapesB.stream().anyMatch(s -> s.getMemberName().contains(memberShape.getMemberName()))) {
return true;
}
}
for (MemberShape otherMemberShape : memberShapesB) {
if (!memberShapesA.stream().anyMatch(s -> s.getMemberName().contains(otherMemberShape.getMemberName()))) {
return true;
}
}

return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,18 @@ final class SymbolVisitor implements SymbolProvider, ShapeVisitor<Symbol> {
private static final Logger LOGGER = Logger.getLogger(SymbolVisitor.class.getName());

private final Model model;
private final TypeScriptSettings settings;
private final ReservedWordSymbolProvider.Escaper escaper;
private final Set<StructureShape> errorShapes = new HashSet<>();
private final ModuleNameDelegator moduleNameDelegator;

SymbolVisitor(Model model) {
this(model, ModuleNameDelegator.DEFAULT_CHUNK_SIZE);
SymbolVisitor(Model model, TypeScriptSettings settings) {
this(model, settings, ModuleNameDelegator.DEFAULT_CHUNK_SIZE);
}

SymbolVisitor(Model model, int shapeChunkSize) {
SymbolVisitor(Model model, TypeScriptSettings settings, int shapeChunkSize) {
this.model = model;
this.settings = settings;

// Load reserved words from a new-line delimited file.
ReservedWords reservedWords = new ReservedWordsBuilder()
Expand Down Expand Up @@ -285,7 +287,7 @@ public Symbol resourceShape(ResourceShape shape) {

@Override
public Symbol serviceShape(ServiceShape shape) {
String name = StringUtils.capitalize(shape.getId().getName()) + "Client";
String name = StringUtils.capitalize(shape.getId().getName(shape)) + "Client";
String moduleName = moduleNameDelegator.formatModuleName(shape, name);
return createGeneratedSymbolBuilder(shape, name, moduleName).build();
}
Expand Down Expand Up @@ -368,7 +370,8 @@ public Symbol timestampShape(TimestampShape shape) {
}

private String flattenShapeName(ToShapeId id) {
return StringUtils.capitalize(id.toShapeId().getName());
ServiceShape serviceShape = model.expectShape(settings.getService(), ServiceShape.class);
return StringUtils.capitalize(id.toShapeId().getName(serviceShape));
}

private Symbol.Builder createObjectSymbolBuilder(Shape shape) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ public void execute(PluginContext context) {
* Creates a TypeScript symbol provider.
*
* @param model Model to generate symbols for.
* @param settings Settings used by the plugin.
* @return Returns the created provider.
*/
public static SymbolProvider createSymbolProvider(Model model) {
return new SymbolVisitor(model);
public static SymbolProvider createSymbolProvider(Model model, TypeScriptSettings settings) {
return new SymbolVisitor(model, settings);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.junit.jupiter.api.Test;
import software.amazon.smithy.codegen.core.Symbol;
import software.amazon.smithy.model.Model;
import software.amazon.smithy.model.node.Node;
import software.amazon.smithy.model.shapes.StringShape;
import software.amazon.smithy.model.traits.EnumDefinition;
import software.amazon.smithy.model.traits.EnumTrait;
Expand All @@ -19,7 +20,16 @@ public void generatesNamedEnums() {
.build();
StringShape shape = StringShape.builder().id("com.foo#Baz").addTrait(trait).build();
TypeScriptWriter writer = new TypeScriptWriter("foo");
Symbol symbol = TypeScriptCodegenPlugin.createSymbolProvider(Model.builder().build()).toSymbol(shape);
Model model = Model.assembler()
.addShape(shape)
.addImport(getClass().getResource("simple-service.smithy"))
.assemble()
.unwrap();
TypeScriptSettings settings = TypeScriptSettings.from(model, Node.objectNodeBuilder()
.withMember("package", Node.from("example"))
.withMember("packageVersion", Node.from("1.0.0"))
.build());
Symbol symbol = TypeScriptCodegenPlugin.createSymbolProvider(model, settings).toSymbol(shape);
new EnumGenerator(shape, symbol, writer).run();

assertThat(writer.toString(), containsString("export enum Baz {"));
Expand All @@ -35,7 +45,16 @@ public void generatesUnnamedEnums() {
.build();
StringShape shape = StringShape.builder().id("com.foo#Baz").addTrait(trait).build();
TypeScriptWriter writer = new TypeScriptWriter("foo");
Symbol symbol = TypeScriptCodegenPlugin.createSymbolProvider(Model.builder().build()).toSymbol(shape);
Model model = Model.assembler()
.addShape(shape)
.addImport(getClass().getResource("simple-service.smithy"))
.assemble()
.unwrap();
TypeScriptSettings settings = TypeScriptSettings.from(model, Node.objectNodeBuilder()
.withMember("package", Node.from("example"))
.withMember("packageVersion", Node.from("1.0.0"))
.build());
Symbol symbol = TypeScriptCodegenPlugin.createSymbolProvider(model, settings).toSymbol(shape);
new EnumGenerator(shape, symbol, writer).run();

assertThat(writer.toString(), containsString("export type Baz = \"BAR\" | \"FOO\""));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public void writesIndex() {
.withMember("package", Node.from("example"))
.withMember("packageVersion", Node.from("1.0.0"))
.build());
SymbolProvider symbolProvider = TypeScriptCodegenPlugin.createSymbolProvider(model);
SymbolProvider symbolProvider = TypeScriptCodegenPlugin.createSymbolProvider(model, settings);
MockManifest manifest = new MockManifest();

IndexGenerator.writeIndex(settings, model, symbolProvider, manifest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public Map<String, Consumer<TypeScriptWriter>> getRuntimeConfigWriters(
.withMember("package", Node.from("example"))
.withMember("packageVersion", Node.from("1.0.0"))
.build());
SymbolProvider symbolProvider = TypeScriptCodegenPlugin.createSymbolProvider(model);
SymbolProvider symbolProvider = TypeScriptCodegenPlugin.createSymbolProvider(model, settings);
TypeScriptDelegator delegator = new TypeScriptDelegator(
settings, model, manifest, symbolProvider, integrations);
RuntimeConfigGenerator generator = new RuntimeConfigGenerator(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public void addsCustomIntegrationDependencyFields() {
.withMember("packageVersion", Node.from("1.0.0"))
.build());
TypeScriptWriter writer = new TypeScriptWriter("./foo");
SymbolProvider symbolProvider = TypeScriptCodegenPlugin.createSymbolProvider(model);
SymbolProvider symbolProvider = TypeScriptCodegenPlugin.createSymbolProvider(model, settings);
ApplicationProtocol applicationProtocol = ApplicationProtocol.createDefaultHttpApplicationProtocol();

List<TypeScriptIntegration> integrations = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -487,12 +487,18 @@ private void testErrorStructureCodegen(String file, String expectedType) {
@Test
public void generatesNonErrorStructures() {
StructureShape struct = createNonErrorStructure();
ModelAssembler assembler = Model.assembler().addShape(struct);
ModelAssembler assembler = Model.assembler()
.addShape(struct)
.addImport(getClass().getResource("simple-service.smithy"));
struct.getAllMembers().values().forEach(assembler::addShape);
Model model = assembler.assemble().unwrap();
TypeScriptSettings settings = TypeScriptSettings.from(model, Node.objectNodeBuilder()
.withMember("package", Node.from("example"))
.withMember("packageVersion", Node.from("1.0.0"))
.build());

TypeScriptWriter writer = new TypeScriptWriter("./foo");
new StructureGenerator(model, TypeScriptCodegenPlugin.createSymbolProvider(model), writer, struct).run();
new StructureGenerator(model, TypeScriptCodegenPlugin.createSymbolProvider(model, settings), writer, struct).run();
String output = writer.toString();

assertThat(output, containsString("export interface Bar {"));
Expand All @@ -510,14 +516,20 @@ private StructureShape createNonErrorStructure() {
@Test
public void generatesNonErrorStructuresThatExtendOtherInterfaces() {
StructureShape struct = createNonErrorStructure();
ModelAssembler assembler = Model.assembler().addShape(struct);
ModelAssembler assembler = Model.assembler()
.addShape(struct)
.addImport(getClass().getResource("simple-service.smithy"));
struct.getAllMembers().values().forEach(assembler::addShape);
OperationShape operation = OperationShape.builder().id("com.foo#Operation").output(struct).build();
assembler.addShape(operation);
Model model = assembler.assemble().unwrap();
TypeScriptSettings settings = TypeScriptSettings.from(model, Node.objectNodeBuilder()
.withMember("package", Node.from("example"))
.withMember("packageVersion", Node.from("1.0.0"))
.build());

TypeScriptWriter writer = new TypeScriptWriter("./foo");
new StructureGenerator(model, TypeScriptCodegenPlugin.createSymbolProvider(model), writer, struct).run();
new StructureGenerator(model, TypeScriptCodegenPlugin.createSymbolProvider(model, settings), writer, struct).run();
String output = writer.toString();

assertThat(output, containsString("export interface Bar {"));
Expand Down
Loading