Skip to content

Commit

Permalink
feat: add downconversion from ?? to ||
Browse files Browse the repository at this point in the history
  • Loading branch information
feywind committed Dec 12, 2022
1 parent 54a540d commit bd1e7fd
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 15 deletions.
4 changes: 2 additions & 2 deletions packages/typeless-sample-bot/__snapshots__/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/typeless-sample-bot/src/samples.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import babel from '@babel/core';
import path from 'node:path';
import {typescript as presetTypescript} from './preset-loader.js';
import importToRequire from './transforms/import-to-require.js';
import nullCoalescing from './transforms/null-coalescing.js';
import {addComments} from './transforms/add-comments.js';

// Converts an async iterable into an array of the same type.
Expand Down Expand Up @@ -84,7 +85,7 @@ export async function* filterByContents(
// the transform process.
const babelConfig = {
presets: [[presetTypescript, {}]],
plugins: [[importToRequire]],
plugins: [[importToRequire], [nullCoalescing]],
parserOpts: {} as babel.ParserOptions,
generatorOpts: {
// Ensures that Babel keeps newlines so that comments end up
Expand Down
28 changes: 28 additions & 0 deletions packages/typeless-sample-bot/src/transforms/babel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License 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.

// Reference notes:
// https://lihautan.com/step-by-step-guide-for-writing-a-babel-transformation/
// https://lihautan.com/babel-ast-explorer/
// https://github.com/esamattis/babel-plugin-ts-optchain/blob/master/packages/babel-plugin-ts-optchain/src/plugin.ts

import {NodePath, Visitor} from '@babel/traverse';
import * as Babel from '@babel/types';

export interface VisitorPlugin {
visitor: Visitor<unknown>;
}

export type NodePathArray = NodePath<Babel.Node>[];
export type NodePathSingle = NodePath<Babel.Node>;
13 changes: 1 addition & 12 deletions packages/typeless-sample-bot/src/transforms/import-to-require.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// Reference notes:
// https://lihautan.com/step-by-step-guide-for-writing-a-babel-transformation/
// https://lihautan.com/babel-ast-explorer/
// https://github.com/esamattis/babel-plugin-ts-optchain/blob/master/packages/babel-plugin-ts-optchain/src/plugin.ts

import * as Babel from '@babel/types';
import {NodePath, Visitor} from '@babel/traverse';

type NodePathArray = NodePath<Babel.Node>[];
type NodePathSingle = NodePath<Babel.Node>;
import {NodePathArray, NodePathSingle, VisitorPlugin} from './babel';

function getArray(path: NodePathSingle, subPathName: string): NodePathArray {
return path.get(subPathName) as NodePathArray;
Expand Down Expand Up @@ -102,10 +95,6 @@ function wildcardImport(path: NodePathSingle) {
path.replaceWith(replacement);
}

interface VisitorPlugin {
visitor: Visitor<unknown>;
}

export default function importToRequire(): VisitorPlugin {
return {
visitor: {
Expand Down
32 changes: 32 additions & 0 deletions packages/typeless-sample-bot/src/transforms/null-coalescing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License 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.

import * as Babel from '@babel/types';
import {NodePathSingle, VisitorPlugin} from './babel';


// Because null coalescing is still a proposal in many versions of Node,
// go ahead and convert it to plain ||. It should work in TypeScript.
export default function nullCoalescing(): VisitorPlugin {
return {
visitor: {
LogicalExpression(path: NodePathSingle) {
const node = path.node as Babel.LogicalExpression;
if (node.operator === '??') {
path.replaceWith(Babel.logicalExpression('||', node.left, node.right));
}
},
},
};
}
3 changes: 3 additions & 0 deletions packages/typeless-sample-bot/test/fixtures/deleteSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ async function deleteSchema(schemaNameOrId: string) {
}
// [END pubsub_delete_schema]

const someValue: number | undefined = undefined;
const coalesced = someValue ?? 5;

function main(schemaNameOrId = 'YOUR_SCHEMA_NAME_OR_ID') {
deleteSchema(schemaNameOrId).catch(err => {
console.error(err.message);
Expand Down

0 comments on commit bd1e7fd

Please sign in to comment.