-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add const typing for Language Names (#2554)
* standardise json formatting * fix @types in deps * add file association for schema files * uses const type for All array * move python args to own constructor * make constructor first in misc languages * add generics to TargetLanguage for names and extension * fix generics for JavaScript + subclassing * add strict types for language names and display names * move language displayName, names, extension to class static members * add strict typing for language name * ♻️ * Revert "move language displayName, names, extension to class static members" This reverts commit 5ca879c. * add generics to TargetLanguage for names and extension * fix generics for JavaScript + subclassing * ♻️ * install eslint packages * add eslint config * remove tslint * eslint autofix * update eslint rules, eslintignore * add lint:fix script * update eslint rules, eslintignore * add lint:fix script * add import rules * add import rules * update import rules * reduce excess style rules * downgrade remaining to warnings * fix enum values fixup! fix enum values * add all missing accessibility modifiers fixup! add all missing accessibility modifiers fixup! add all missing accessibility modifiers * fix nullish errors * update import rules * fix all require imports * fix all imports * reduce excess style rules * fix any types fixup! fix any types fixup! fix any types * fix misc errors * downgrade remaining to warnings * return types * fix types errors * fix json import for test tsconfig * auto lint fix * fix lint errors in extension * fix lint errors in Elixir * make ref.pushElement public * fix misc * fix accidental public in CSharp raw text get * use full generics for all languages to all extensibility * add generics for elixir * typescript 4.9 doesn't support const generics yet * export LanguageName type and predicates * fix type safety for extension * fix type safety for cli * reduce target language generic to singular config object * update all non-inherited target languages to have external language config * flatten all languages to extend from TargetLanguage * fix new lint errors * Merge branch 'refactor/imports/languages' * fix package-lock * lint fixed * use LanguageName in cli index * fix type errors in test * add docs for creating custom languages and renderers * update README
- Loading branch information
1 parent
0a34f5b
commit 15b652d
Showing
40 changed files
with
537 additions
and
1,675 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
# Extending quicktype functionality with a Custom Renderer | ||
|
||
## quicktype Interface | ||
|
||
To customise your rendering output, you can extend existing quicktype classes and override existing methods to achieve the behaviour you want. | ||
|
||
This process requires 3 main steps: | ||
|
||
1. [Extending a `Renderer` Class](#creating-a-custom-renderer) | ||
2. [Wrapping your `Renderer` in a `TargetLanguage` Class](#creating-a-targetlanguage) | ||
3. [Using your new classes in the `quicktype` function](#using-your-custom-language) | ||
4. [Advanced Usage: Creating an entirely new Language](#creating-a-new-language) | ||
|
||
## Creating a custom `Renderer` | ||
|
||
Adding custom render logic for an existing language often involves extending a Renderer class and simply overriding or amending one of the `emit` methods: | ||
|
||
```ts | ||
// MyCustomRenderer.ts | ||
import { CSharpRenderer } from "quicktype-core"; | ||
|
||
export class MyCustomRenderer extends CSharpRenderer { | ||
// Add your custom logic here, feel free to reference the source code for how existing methods work | ||
// | ||
// ex. | ||
protected superclassForType(t: Type): Sourcelike | undefined { | ||
// if the type is a class, it should extend `GameObject` when rendered in C# | ||
if (t instanceof ClassType) { | ||
return "GameObject"; | ||
} | ||
return undefined; | ||
} | ||
// See: http://blog.quicktype.io/customizing-quicktype/ for more context | ||
} | ||
``` | ||
|
||
## Creating a `TargetLanguage` | ||
|
||
If you just want to change the rendering logic for an existing language, you can just extend an exported Language class (`CSharpTargetLanguage` in this example) and override the `makeRenderer` method: | ||
|
||
```ts | ||
// MyCustomLanguage.ts | ||
import { CSharpTargetLanguage } from "quicktype-core"; | ||
|
||
import { MyCustomRenderer } from "./MyCustomRenderer"; | ||
|
||
export class MyCustomLanguage extends CSharpTargetLanguage { | ||
// `makeRenderer` instantiates the Renderer class for the TargetLanguage | ||
protected makeRenderer( | ||
renderContext: RenderContext, | ||
untypedOptionValues: Record<string, unknown> | ||
): MyCustomRenderer { | ||
// use your new custom renderer class here | ||
return new MyCustomRenderer(this, renderContext, getOptionValues(cSharpOptions, untypedOptionValues)); | ||
} | ||
} | ||
``` | ||
|
||
## Using your custom Language | ||
|
||
```ts | ||
import { quicktype } from "quicktype-core"; | ||
|
||
import { MyCustomLanguage } from './MyCustomLanguage'; | ||
|
||
const lang = new MyCustomLanguage(); | ||
|
||
const lines = await quicktype({ | ||
lang: lang, // use your new TargetLanguage in the `lang` field here | ||
... | ||
}); | ||
|
||
console.log(lines); | ||
``` | ||
|
||
## Creating a new Language | ||
|
||
If none of the existing `quicktype` Language classes suit your needs, you can creating your own `TargetLanguge` and `Renderer` classes from scratch. If this satisfies your use cases for a language we don't currently support, please consider opening a PR with your new language and we'd love to take a look. | ||
|
||
If you run into any issues, you can open a GitHub issue and we'll help you take a look. | ||
|
||
### Creating a `TargetLanguage` from scratch | ||
|
||
Instead of just extending an existing language, a new Language requires two additional steps: | ||
|
||
- Defining the language config | ||
- Adding any language-specific options | ||
|
||
```ts | ||
import { TargetLanguage, BooleanOption } from "quicktype-core"; | ||
|
||
// language config | ||
const brandNewLanguageConfig = { | ||
displayName: "Scratch", // these can be the same | ||
names: ["scratch"], // these can be the same | ||
extension: "sb" // the file extension that this language commonly has | ||
} as const; | ||
|
||
// language options | ||
const brandNewLanguageOptions = { | ||
allowFoo: new BooleanOption( | ||
"allow-foo", // option name | ||
"Allows Foo", // description | ||
true // default value | ||
) | ||
// The default available Option classes are: StringOption, BooleanOption, EnumOption | ||
// Please visit the source code for more examples and usage | ||
}; | ||
|
||
class BrandNewLanguage extends TargetLanguage<typeof brandNewLanguageConfig> { | ||
public constructor() { | ||
super(brandNewLanguageConfig); | ||
} | ||
|
||
protected getOptions(): Array<Option<any>> { | ||
return [ | ||
brandNewLanguageOptions.allowFoo // list all options from the options config | ||
]; | ||
} | ||
|
||
protected makeRenderer( | ||
renderContext: RenderContext, | ||
untypedOptionValues: Record<string, unknown> | ||
): BrandNewRenderer { | ||
return new BrandNewRenderer(this, renderContext, getOptionValues(brandNewLanguageOptions, untypedOptionValues)); | ||
} | ||
} | ||
``` | ||
|
||
### Creating a `Renderer` from scratch | ||
|
||
Creating a brand new `Renderer` class is very similar to extending an existing class: | ||
|
||
```ts | ||
export class BrandNewRenderer extends ConvenienceRenderer { | ||
public constructor(targetLanguage: TargetLanguage, renderContext: RenderContext) { | ||
super(targetLanguage, renderContext); | ||
} | ||
|
||
// Additional render methods go here | ||
// Please reference existing Renderer classes and open a GitHub issue if you need help | ||
} | ||
``` | ||
|
||
## Links | ||
|
||
Blog post with an older example: http://blog.quicktype.io/customizing-quicktype/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.