Skip to content

Commit 39f6234

Browse files
committed
Generate more files and fixing some imports
Generates static files, index.ts, etc. Fixes imports that were `../` instead of `./`
1 parent 1d208ff commit 39f6234

File tree

8 files changed

+172
-231
lines changed

8 files changed

+172
-231
lines changed

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/CodegenVisitor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,8 @@ void execute() {
236236
.replace("-", "_")
237237
.replace(".", "_");
238238
String protocolTestFileName = String.format("test/functional/%s.spec.ts", baseName);
239-
context.setDeferredWriter(() -> writers.checkoutFileWriter(protocolTestFileName));
240-
protocolGenerator.generateProtocolTests(context);
239+
// context.setDeferredWriter(() -> writers.checkoutFileWriter(protocolTestFileName));
240+
// protocolGenerator.generateProtocolTests(context);
241241
}
242242

243243
// Write each pending writer.

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/DirectedTypeScriptCodegen.java

Lines changed: 145 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,27 @@
2020
import java.util.Collection;
2121
import java.util.HashMap;
2222
import java.util.List;
23+
import java.util.Locale;
2324
import java.util.Map;
2425
import java.util.Set;
2526
import java.util.logging.Logger;
27+
import java.util.stream.Collectors;
2628
import software.amazon.smithy.build.FileManifest;
29+
import software.amazon.smithy.codegen.core.CodegenException;
2730
import software.amazon.smithy.codegen.core.Symbol;
31+
import software.amazon.smithy.codegen.core.SymbolDependency;
2832
import software.amazon.smithy.codegen.core.SymbolProvider;
2933
import software.amazon.smithy.codegen.core.directed.CreateContextDirective;
3034
import software.amazon.smithy.codegen.core.directed.CreateSymbolProviderDirective;
35+
import software.amazon.smithy.codegen.core.directed.CustomizeDirective;
3136
import software.amazon.smithy.codegen.core.directed.DirectedCodegen;
3237
import software.amazon.smithy.codegen.core.directed.GenerateEnumDirective;
3338
import software.amazon.smithy.codegen.core.directed.GenerateErrorDirective;
3439
import software.amazon.smithy.codegen.core.directed.GenerateServiceDirective;
3540
import software.amazon.smithy.codegen.core.directed.GenerateStructureDirective;
3641
import software.amazon.smithy.codegen.core.directed.GenerateUnionDirective;
3742
import software.amazon.smithy.model.Model;
43+
import software.amazon.smithy.model.knowledge.OperationIndex;
3844
import software.amazon.smithy.model.knowledge.TopDownIndex;
3945
import software.amazon.smithy.model.shapes.OperationShape;
4046
import software.amazon.smithy.model.shapes.ServiceShape;
@@ -43,6 +49,7 @@
4349
import software.amazon.smithy.typescript.codegen.integration.ProtocolGenerator;
4450
import software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin;
4551
import software.amazon.smithy.typescript.codegen.integration.TypeScriptIntegration;
52+
import software.amazon.smithy.utils.MapUtils;
4653
import software.amazon.smithy.utils.SmithyUnstableApi;
4754
import software.amazon.smithy.waiters.WaitableTrait;
4855
import software.amazon.smithy.waiters.Waiter;
@@ -52,6 +59,19 @@ final class DirectedTypeScriptCodegen implements DirectedCodegen<TypeScriptCodeg
5259

5360
private static final Logger LOGGER = Logger.getLogger(DirectedTypeScriptCodegen.class.getName());
5461

62+
/**
63+
* A mapping of static resource files to copy over to a new filename.
64+
*/
65+
private static final Map<String, String> STATIC_FILE_COPIES = MapUtils.of(
66+
"typedoc.json", "typedoc.json",
67+
"tsconfig.json", "tsconfig.json",
68+
"tsconfig.cjs.json", "tsconfig.cjs.json",
69+
"tsconfig.es.json", "tsconfig.es.json",
70+
"tsconfig.types.json", "tsconfig.types.json"
71+
);
72+
private static final ShapeId VALIDATION_EXCEPTION_SHAPE =
73+
ShapeId.fromParts("smithy.framework", "ValidationException");
74+
5575
@Override
5676
public SymbolProvider createSymbolProvider(CreateSymbolProviderDirective<TypeScriptSettings> directive) {
5777
return new SymbolVisitor(directive.model(), directive.settings());
@@ -89,11 +109,15 @@ public TypeScriptCodegenContext createContext(CreateContextDirective<TypeScriptS
89109
.protocolGenerator(protocolGenerator)
90110
.applicationProtocol(applicationProtocol)
91111

112+
// //TODO: fix delegator constructor
113+
// .writerDelegator(new TypeScriptDelegator(
114+
// directive.settings(), directive.model(),
115+
// directive.fileManifest(), directive.symbolProvider(),
116+
// directive.integrations())) // TODO: integrations?
117+
92118
//TODO: fix delegator constructor
93-
.writerDelegator(new TypeScriptDelegator(
94-
directive.settings(), directive.model(),
95-
directive.fileManifest(), directive.symbolProvider(),
96-
directive.integrations())) // TODO: integrations?
119+
.writerDelegator(new TypeScriptDelegator(directive.fileManifest(), directive.symbolProvider()))
120+
97121
.build();
98122
}
99123

@@ -340,4 +364,121 @@ public void generateEnumShape(GenerateEnumDirective<TypeScriptCodegenContext, Ty
340364
generator.run();
341365
});
342366
}
367+
368+
@Override
369+
public void customizeBeforeIntegrations(CustomizeDirective<TypeScriptCodegenContext, TypeScriptSettings> directive) {
370+
// Write shared / static content.
371+
STATIC_FILE_COPIES.forEach((from, to) -> {
372+
LOGGER.fine(() -> "Writing contents of `" + from + "` to `" + to + "`");
373+
directive.fileManifest().writeFile(from, getClass(), to);
374+
});
375+
376+
// TODO: do all of these parts below are before/after?
377+
SymbolVisitor.writeModelIndex(directive.model(), directive.symbolProvider(), directive.fileManifest());
378+
379+
// Generate the client Node and Browser configuration files. These
380+
// files are switched between in package.json based on the targeted
381+
// environment.
382+
if (directive.settings().generateClient()) {
383+
// For now these are only generated for clients.
384+
// TODO: generate ssdk config
385+
RuntimeConfigGenerator configGenerator = new RuntimeConfigGenerator(
386+
directive.settings(),
387+
directive.model(),
388+
directive.symbolProvider(),
389+
directive.context().writerDelegator(),
390+
directive.context().integrations());
391+
for (LanguageTarget target : LanguageTarget.values()) {
392+
LOGGER.fine("Generating " + target + " runtime configuration");
393+
configGenerator.generate(target);
394+
}
395+
}
396+
397+
// Write each custom file.
398+
for (TypeScriptIntegration integration : directive.context().integrations()) {
399+
LOGGER.finer(() -> "Calling writeAdditionalFiles on " + integration.getClass().getCanonicalName());
400+
integration.writeAdditionalFiles(
401+
directive.settings(),
402+
directive.model(),
403+
directive.symbolProvider(),
404+
directive.context().writerDelegator()::useFileWriter);
405+
}
406+
407+
// Generate index for client.
408+
IndexGenerator.writeIndex(
409+
directive.settings(),
410+
directive.model(),
411+
directive.symbolProvider(),
412+
directive.fileManifest(),
413+
directive.context().integrations(),
414+
directive.context().protocolGenerator());
415+
416+
if (directive.settings().generateServerSdk()) {
417+
checkValidationSettings(directive.settings(), directive.model(), directive.service());
418+
// Generate index for server
419+
IndexGenerator.writeServerIndex(
420+
directive.settings(),
421+
directive.model(),
422+
directive.symbolProvider(),
423+
directive.fileManifest());
424+
}
425+
426+
// Generate protocol tests IFF found in the model.
427+
ProtocolGenerator protocolGenerator = directive.context().protocolGenerator();
428+
if (protocolGenerator != null) {
429+
ShapeId protocol = protocolGenerator.getProtocol();
430+
ProtocolGenerator.GenerationContext context = new ProtocolGenerator.GenerationContext();
431+
context.setProtocolName(protocolGenerator.getName());
432+
context.setIntegrations(directive.context().integrations());
433+
context.setModel(directive.model());
434+
context.setService(directive.service());
435+
context.setSettings(directive.settings());
436+
context.setSymbolProvider(directive.symbolProvider());
437+
String baseName = protocol.getName().toLowerCase(Locale.US)
438+
.replace("-", "_")
439+
.replace(".", "_");
440+
String protocolTestFileName = String.format("test/functional/%s.spec.ts", baseName);
441+
442+
// TODO: what to do here?
443+
// context.setDeferredWriter(() -> directive.context().writerDelegator().checkoutFileWriter(protocolTestFileName));
444+
445+
// protocolGenerator.generateProtocolTests(context);
446+
}
447+
448+
}
449+
450+
private void checkValidationSettings(TypeScriptSettings settings, Model model, ServiceShape service) {
451+
if (settings.isDisableDefaultValidation()) {
452+
return;
453+
}
454+
455+
final OperationIndex operationIndex = OperationIndex.of(model);
456+
457+
List<String> unvalidatedOperations = TopDownIndex.of(model)
458+
.getContainedOperations(service)
459+
.stream()
460+
.filter(o -> operationIndex.getErrors(o, service).stream()
461+
.noneMatch(e -> e.getId().equals(VALIDATION_EXCEPTION_SHAPE)))
462+
.map(s -> s.getId().toString())
463+
.sorted()
464+
.collect(Collectors.toList());
465+
466+
if (!unvalidatedOperations.isEmpty()) {
467+
throw new CodegenException(String.format("Every operation must have the %s error attached unless %s is set "
468+
+ "to 'true' in the plugin settings. Operations without %s errors attached: %s",
469+
VALIDATION_EXCEPTION_SHAPE,
470+
TypeScriptSettings.DISABLE_DEFAULT_VALIDATION,
471+
VALIDATION_EXCEPTION_SHAPE,
472+
unvalidatedOperations));
473+
}
474+
}
475+
476+
@Override
477+
public void customizeAfterIntegrations(CustomizeDirective<TypeScriptCodegenContext, TypeScriptSettings> directive) {
478+
LOGGER.fine("Generating package.json files");
479+
PackageJsonGenerator.writePackageJson(
480+
directive.settings(),
481+
directive.fileManifest(),
482+
SymbolDependency.gatherDependencies(directive.context().writerDelegator().getDependencies().stream()));
483+
}
343484
}

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/ImportDeclarations.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ ImportDeclarations addImport(String name, String alias, String module) {
8282

8383
@Override
8484
public void importSymbol(Symbol symbol, String alias) {
85+
// TODO: is this if needed?
8586
if (!symbol.getNamespace().isEmpty() && !symbol.getNamespace().equals(moduleNameString)) {
8687
addImport(symbol.getName(), alias, symbol.getNamespace());
8788
}

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/TypeScriptCodegenPlugin.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ public void execute(PluginContext context) {
5858

5959
// Configure the director to perform some common model transforms.
6060
runner.performDefaultCodegenTransforms();
61-
runner.createDedicatedInputsAndOutputs();
61+
62+
// TODO: How is smithy-typescript currently dealing with no input/output?
63+
// runner.createDedicatedInputsAndOutputs();
6264

6365
// Run it!
6466
runner.run();

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/TypeScriptDelegator.java

Lines changed: 4 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,24 @@
1515

1616
package software.amazon.smithy.typescript.codegen;
1717

18-
import java.nio.file.Paths;
1918
import java.util.ArrayList;
20-
import java.util.HashMap;
2119
import java.util.List;
22-
import java.util.Map;
23-
import java.util.function.Consumer;
2420
import software.amazon.smithy.build.FileManifest;
25-
import software.amazon.smithy.codegen.core.Symbol;
2621
import software.amazon.smithy.codegen.core.SymbolDependency;
2722
import software.amazon.smithy.codegen.core.SymbolProvider;
28-
import software.amazon.smithy.codegen.core.SymbolReference;
2923
import software.amazon.smithy.codegen.core.WriterDelegator;
3024
import software.amazon.smithy.model.Model;
31-
import software.amazon.smithy.model.shapes.Shape;
3225
import software.amazon.smithy.typescript.codegen.integration.TypeScriptIntegration;
33-
import software.amazon.smithy.typescript.codegen.validation.IsTypeScriptFileExtension;
3426
import software.amazon.smithy.utils.SmithyUnstableApi;
3527

3628
@SmithyUnstableApi
3729
final class TypeScriptDelegator extends WriterDelegator<TypeScriptWriter> {
3830

39-
private final TypeScriptSettings settings;
40-
private final Model model;
41-
private final FileManifest fileManifest;
42-
private final SymbolProvider symbolProvider;
43-
private final List<TypeScriptIntegration> integrations;
44-
private final Map<String, TypeScriptWriter> writers = new HashMap<>();
31+
TypeScriptDelegator(FileManifest fileManifest, SymbolProvider symbolProvider) {
32+
super(fileManifest, symbolProvider, new TypeScriptWriter.TypeScriptWriterFactory());
33+
}
4534

35+
// TODO: remove
4636
TypeScriptDelegator(
4737
TypeScriptSettings settings,
4838
Model model,
@@ -51,24 +41,6 @@ final class TypeScriptDelegator extends WriterDelegator<TypeScriptWriter> {
5141
List<TypeScriptIntegration> integrations
5242
) {
5343
super(fileManifest, symbolProvider, new TypeScriptWriter.TypeScriptWriterFactory());
54-
this.settings = settings;
55-
this.model = model;
56-
this.fileManifest = fileManifest;
57-
this.symbolProvider = symbolProvider;
58-
this.integrations = integrations;
59-
}
60-
61-
@Override
62-
public void flushWriters() {
63-
// for (Map.Entry<String, W> entry : getWriters().entrySet()) {
64-
// fileManifest.writeFile(entry.getKey(), entry.getValue().toString());
65-
// }
66-
//
67-
// writers.clear();
68-
69-
writers.forEach((filename, writer) ->
70-
fileManifest.writeFile(filename, writer.toString(IsTypeScriptFileExtension.check(filename))));
71-
writers.clear();
7244
}
7345

7446
/**
@@ -84,76 +56,4 @@ public List<SymbolDependency> getDependencies() {
8456
resolved.addAll(super.getDependencies());
8557
return resolved;
8658
}
87-
88-
/**
89-
* Gets a previously created writer or creates a new one if needed.
90-
*
91-
* <p>Any imports required by the given symbol are automatically registered
92-
* with the writer.
93-
*
94-
* @param shape Shape to create the writer for.
95-
* @param writerConsumer Consumer that accepts and works with the file.
96-
*/
97-
public void useShapeWriter(Shape shape, Consumer<TypeScriptWriter> writerConsumer) {
98-
// Checkout/create the appropriate writer for the shape.
99-
Symbol symbol = symbolProvider.toSymbol(shape);
100-
String fileName = symbol.getDefinitionFile();
101-
if (!fileName.startsWith(Paths.get(".", CodegenUtils.SOURCE_FOLDER).toString())) {
102-
fileName = Paths.get(".", CodegenUtils.SOURCE_FOLDER, fileName).toString();
103-
}
104-
TypeScriptWriter writer = checkoutWriter(fileName);
105-
106-
// Add any needed DECLARE symbols.
107-
writer.addImportReferences(symbol, SymbolReference.ContextOption.DECLARE);
108-
symbol.getDependencies().forEach(writer::addDependency);
109-
110-
writer.pushState();
111-
112-
// Allow integrations to do things like add onSection callbacks.
113-
// These onSection callbacks are removed when popState is called.
114-
for (TypeScriptIntegration integration : integrations) {
115-
integration.onShapeWriterUse(settings, model, symbolProvider, writer, shape);
116-
}
117-
118-
writerConsumer.accept(writer);
119-
writer.popState();
120-
}
121-
122-
// /**
123-
// * Gets a previously created writer or creates a new one if needed
124-
// * and adds a new line if the writer already exists.
125-
// *
126-
// * @param filename Name of the file to create.
127-
// * @param writerConsumer Consumer that accepts and works with the file.
128-
// */
129-
// void useFileWriter(String filename, Consumer<TypeScriptWriter> writerConsumer) {
130-
// writerConsumer.accept(checkoutWriter(filename));
131-
// }
132-
133-
/**
134-
* Gets a previously created writer or creates a new one if needed
135-
* and adds a new line if the writer already exists.
136-
*
137-
* @param filename Name of the file to create.
138-
*/
139-
TypeScriptWriter checkoutFileWriter(String filename) {
140-
return checkoutWriter(filename);
141-
}
142-
143-
private TypeScriptWriter checkoutWriter(String filename) {
144-
String formattedFilename = Paths.get(filename).normalize().toString();
145-
boolean needsNewline = writers.containsKey(formattedFilename);
146-
147-
TypeScriptWriter writer = writers.computeIfAbsent(formattedFilename, f -> {
148-
String moduleName = filename.endsWith(".ts") ? filename.substring(0, filename.length() - 3) : filename;
149-
return new TypeScriptWriter(moduleName);
150-
});
151-
152-
// Add newlines/separators between types in the same file.
153-
if (needsNewline) {
154-
writer.write("\n");
155-
}
156-
157-
return writer;
158-
}
15959
}

0 commit comments

Comments
 (0)