Skip to content

Commit

Permalink
Merge #1984
Browse files Browse the repository at this point in the history
1984: feat(ts): add TS v3.7/3.8 language features r=spencercorwin a=spencercorwin

### Description of the Change

Upgrades Smart-Contract compiler to support new TS language features:

Features from TS v3.7:
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html
- [x] Optional Chaining
- [x] Nullish Coalescing
  - Added in previous TS PR
- [x] Assertion Functions
  - Not supported?
- [x] `never`-Returning Functions
  - No change needed?
- [x] Recursive Type Aliases
- [x] Uncalled Function Checks
  - Should be supported without change from us?

Features from TS v3.8.1-rc:
https://devblogs.microsoft.com/typescript/announcing-typescript-3-8-rc/
- [x] Type-Only Imports and Exports
- [x] ECMAScript Private Fields
- [x] `export * as ns` Syntax
  - Added in previous TS PR
- [x] Top-Level `await`
  - Not supported?

### Test Plan

- All Unit Tests
  - `rush test`
  - `rush e2e`
- Optional Chaining
  - `rush test -t packages/neo-one-smart-contract-compiler/src/__tests__/compile/expression/CallExpressionCompiler.test.ts`
  - `rush test -t packages/neo-one-smart-contract-compiler/src/__tests__/compile/expression/ElementAccessExpressionCompiler.test.ts`
  - `rush test -t packages/neo-one-smart-contract-compiler/src/__tests__/compile/expression/PropertyAccessExpressionCompiler.test.ts`
- Nullish Coalescing
  - `rush test -t packages/neo-one-smart-contract-compiler/src/__tests__/compile/expression/ToNullishBooleanHelper.test.ts`
- Recursive Type Aliases
  - `rush test -t packages/neo-one-smart-contract-compiler/src/__tests__/compile/declaration/TypeAliasDeclarationCompiler.test.ts`
- Type-Only Imports and Exports
  - `rush test -t packages/neo-one-typescript-concatenator/src/__tests__/concatenate.test.ts`
- ECMAScript Private Fields
  - `rush test -t packages/neo-one-smart-contract-compiler/src/__tests__/compile/declaration/ClassDeclarationCompiler.test.ts`
  - `rush test -t packages/neo-one-smart-contract-compiler/src/__tests__/compile/expression/ObjectLiteralExpressionCompiler.test.ts`
- `export * as ns` Syntax
  - `rush test -t packages/neo-one-typescript-concatenator/src/__tests__/concatenate.test.ts`
- Top-Level `await`
  - `rush test -t packages/neo-one-smart-contract-compiler/src/__tests__/compiler/expression/AwaitExpressionCompiler.test.ts`

### Alternate Designs

None.

### Benefits

- We support the latest language features for writing Smart Contracts in TS.

### Possible Drawbacks

- Prettier doesn't support some TS v3.8 syntax yet, so all Prettier checks will fail on the `neo-one-typescript-concatenator` package until they/we update Prettier. They have an issue open for this [here](prettier/prettier#7263). They are waiting for TS 3.8 support in `typescript-eslint` for the new AST [here](typescript-eslint/typescript-eslint#1465). This is easy to ignore for now.
- Possibly unforeseen problems.

### Applicable Issues

#1889 


Co-authored-by: Spencer Corwin <spencercorwin@icloud.com>
  • Loading branch information
bors[bot] and spencercorwin committed Mar 9, 2020
2 parents db6c5df + 2f64dd9 commit 12690b1
Show file tree
Hide file tree
Showing 20 changed files with 717 additions and 22 deletions.
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@neo-one/smart-contract-compiler",
"comment": "Add support for new language features in TS v3.7, v3.8",
"type": "minor"
}
],
"packageName": "@neo-one/smart-contract-compiler",
"email": "spencercorwin@icloud.com"
}
Expand Up @@ -2,10 +2,10 @@
"changes": [
{
"packageName": "@neo-one/smart-contract-compiler",
"comment": "Upgrade TS to v3.8.1-rc. Add support for Nullish Coalescing",
"comment": "Upgrade TS to v3.8.1-rc. Add support for Nullish Coalescing.",
"type": "minor"
}
],
"packageName": "@neo-one/smart-contract-compiler",
"email": "spencercorwin@icloud.com"
}
}
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@neo-one/typescript-concatenator",
"comment": "Add support for new language features in TS v3.7, v3.8",
"type": "minor"
}
],
"packageName": "@neo-one/typescript-concatenator",
"email": "spencercorwin@icloud.com"
}
Expand Up @@ -2,10 +2,10 @@
"changes": [
{
"packageName": "@neo-one/typescript-concatenator",
"comment": "Upgrade TS to v3.8.1-rc. Add support for namespace exports",
"comment": "Upgrade TS to v3.8.1-rc. Add support for namespace exports.",
"type": "minor"
}
],
"packageName": "@neo-one/typescript-concatenator",
"email": "spencercorwin@icloud.com"
}
}
Expand Up @@ -105,6 +105,74 @@ describe('ClassDeclarationCompiler', () => {
`);
});

test('basic class with ECMAScript private member, inaccessible', async () => {
helpers.compileString(
`
class Foo {
#x: string = 'bar';
['bar'](): string {
return this.#x;
}
}
const f = new Foo();
f.#x;
`,
{ type: 'error' },
);
});

test('ECMAScript private member, no public modifier allowed', async () => {
helpers.compileString(
`
class Foo {
public #x: string = 'bar';
}
`,
{ type: 'error' },
);
});

test('ECMAScript private member, no private modifier allowed', async () => {
helpers.compileString(
`
class Foo {
private #x: string = 'bar';
}
`,
{ type: 'error' },
);
});

test('ECMAScript private member, extends does not override private member', async () => {
await helpers.executeString(
`
class Foo {
#x: string = 'bar';
getX(): string {
return this.#x;
}
}
class Bar extends Foo {
#x: string = 'baz';
getX(): string {
return this.#x;
}
}
const foo = new Foo();
const bar = new Bar();
assertEqual(foo.getX(), 'bar');
assertEqual(bar.getX(), 'baz');
`,
);
});

test('basic class with get accessor', async () => {
await helpers.executeString(`
class Foo {
Expand Down
Expand Up @@ -14,4 +14,26 @@ describe('TypeAliasDeclarationCompiler', () => {
}
`);
});

test('recursive type alias does not emit', async () => {
await helpers.executeString(`
type Json =
| string
| number
| boolean
| null
| { [property: string]: Json }
| Json[];
type VirtualNode =
| string
| [string, { [key: string]: any }, ...VirtualNode[]];
const myNode: VirtualNode =
["div", { id: "parent" },
["div", { id: "first-child" }, "I'm the first child"],
["div", { id: "second-child" }, "I'm the second child"]
];
`);
});
});
@@ -1,5 +1,40 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`ClassDeclarationCompiler ECMAScript private member, no private modifier allowed 1`] = `
"snippetCode.ts (3,9): An accessibility modifier cannot be used with a private identifier.
1 |
2 | class Foo {
> 3 | private #x: string = 'bar';
| ^
4 | }
5 |
"
`;

exports[`ClassDeclarationCompiler ECMAScript private member, no public modifier allowed 1`] = `
"snippetCode.ts (3,9): An accessibility modifier cannot be used with a private identifier.
1 |
2 | class Foo {
> 3 | public #x: string = 'bar';
| ^
4 | }
5 |
"
`;

exports[`ClassDeclarationCompiler basic class with ECMAScript private member, inaccessible 1`] = `
"snippetCode.ts (11,9): Property '#x' is not accessible outside class 'Foo' because it has a private identifier.
9 |
10 | const f = new Foo();
> 11 | f.#x;
| ^
12 |
"
`;

exports[`ClassDeclarationCompiler decorators 1`] = `
"snippetCode.ts (7,9): Custom decorators are not supported
Expand Down
Expand Up @@ -9,4 +9,15 @@ describe('AwaitFunctionCompiler', () => {
{ type: 'error' },
);
});

test('await', async () => {
helpers.compileString(
`
await 2;
export {};
`,
{ type: 'error' },
);
});
});

0 comments on commit 12690b1

Please sign in to comment.