From 94d9453cc224270a8bcc0f033e29e04bdab937e2 Mon Sep 17 00:00:00 2001 From: Ido Rosenthal Date: Thu, 25 Aug 2022 09:49:45 +0300 Subject: [PATCH] fix(import-tkn)!: named imports to preserve all --- packages/imports-parser/src/imports-parser.ts | 20 ++-- .../test/import-tokenizer.spec.ts | 101 ++++++++++++------ 2 files changed, 79 insertions(+), 42 deletions(-) diff --git a/packages/imports-parser/src/imports-parser.ts b/packages/imports-parser/src/imports-parser.ts index 695e52b..da41c9d 100644 --- a/packages/imports-parser/src/imports-parser.ts +++ b/packages/imports-parser/src/imports-parser.ts @@ -59,14 +59,16 @@ const shouldAddToken = (type: CodeToken['type']) => export interface ImportValue { star: boolean; defaultName: string | undefined; - named: Record | undefined; - tagged: Record> | undefined; + named: NamedMapping[] | undefined; + tagged: Record; from: string | undefined; errors: string[]; start: number; end: number; } +type NamedMapping = [from: string, to: string]; + const isImportBlockEndError = (token: CodeToken) => token.value === 'from' || token.type === ';'; function findImports( @@ -89,8 +91,8 @@ function findImports( const errors = []; let defaultName; let star = false; - let named = undefined; - let tagged = undefined; + let named: ImportValue['named'] = undefined; + let tagged: ImportValue['tagged'] = {}; let from; t = s.next(); if (t.type === 'string') { @@ -186,7 +188,7 @@ function findImports( star, defaultName, named, - tagged: tagged, + tagged, from, errors, start: s.tokens[startTokenIndex].start, @@ -198,8 +200,8 @@ function findImports( } function processNamedBlock(block: CodeToken[], errors: string[], taggedImportSupport: boolean) { - const named: Record = {}; - const tagged: Record> = {}; + const named: [from: string, to: string][] = []; + const tagged: Record = {}; const tokens: CodeToken[] = []; for (let i = 0; i < block.length; i++) { @@ -238,10 +240,10 @@ function processNamedBlock(block: CodeToken[], errors: string[], taggedImportSup function pushToken() { if (tokens.length === 1) { const name = tokens[0].value; - named[name] = name; + named.push([name, name]); } else if (tokens.length === 3) { if (tokens[1].value === 'as') { - named[tokens[0].value] = tokens[2].value; + named.push([tokens[0].value, tokens[2].value]); } } tokens.length = 0; diff --git a/packages/imports-parser/test/import-tokenizer.spec.ts b/packages/imports-parser/test/import-tokenizer.spec.ts index e595b33..bc2bcf6 100644 --- a/packages/imports-parser/test/import-tokenizer.spec.ts +++ b/packages/imports-parser/test/import-tokenizer.spec.ts @@ -22,7 +22,7 @@ describe(`demos/import-tokenizer`, () => { createImportValue({ star: false, named: undefined, - tagged: undefined, + tagged: {}, from: 'x', defaultName: undefined, errors: [], @@ -39,7 +39,7 @@ describe(`demos/import-tokenizer`, () => { createImportValue({ star: false, named: undefined, - tagged: undefined, + tagged: {}, from: 'x', defaultName: undefined, errors: [], @@ -55,7 +55,7 @@ describe(`demos/import-tokenizer`, () => { createImportValue({ star: false, named: undefined, - tagged: undefined, + tagged: {}, from: 'x', defaultName: undefined, errors: ['missing semicolon'], @@ -65,7 +65,7 @@ describe(`demos/import-tokenizer`, () => { createImportValue({ star: false, named: undefined, - tagged: undefined, + tagged: {}, from: 'y', defaultName: undefined, errors: [], @@ -81,7 +81,7 @@ describe(`demos/import-tokenizer`, () => { createImportValue({ star: false, named: undefined, - tagged: undefined, + tagged: {}, from: 'x', defaultName: undefined, errors: [], @@ -97,7 +97,7 @@ describe(`demos/import-tokenizer`, () => { createImportValue({ star: false, named: undefined, - tagged: undefined, + tagged: {}, from: 'x', defaultName: undefined, errors: [], @@ -113,7 +113,7 @@ describe(`demos/import-tokenizer`, () => { createImportValue({ star: false, named: undefined, - tagged: undefined, + tagged: {}, from: 'x', defaultName: undefined, errors: [], @@ -129,7 +129,7 @@ describe(`demos/import-tokenizer`, () => { createImportValue({ star: false, named: undefined, - tagged: undefined, + tagged: {}, from: 'x', defaultName: undefined, errors: [], @@ -145,7 +145,7 @@ describe(`demos/import-tokenizer`, () => { createImportValue({ star: false, named: undefined, - tagged: undefined, + tagged: {}, from: 'x', defaultName: 'name', errors: [], @@ -160,7 +160,7 @@ describe(`demos/import-tokenizer`, () => { expectedAst: [ createImportValue({ star: false, - named: { named: 'named' }, + named: [['named', 'named']], tagged: {}, from: 'x', defaultName: undefined, @@ -176,7 +176,7 @@ describe(`demos/import-tokenizer`, () => { expectedAst: [ createImportValue({ star: false, - named: { named: 'renamed' }, + named: [['named', 'renamed']], tagged: {}, from: 'x', defaultName: undefined, @@ -187,12 +187,31 @@ describe(`demos/import-tokenizer`, () => { ], }); }); + it(`import {x, x as local-x} from "x"`, () => { + test(`import {x, x as local-x} from "x"`, { + expectedAst: [ + createImportValue({ + star: false, + named: [ + ['x', 'x'], + ['x', 'local-x'], + ], + tagged: {}, + from: 'x', + defaultName: undefined, + errors: [], + start: 0, + end: 33, + }), + ], + }); + }); it(`import name, {named} from "x"`, () => { test(`import name, {named} from "x"`, { expectedAst: [ createImportValue({ star: false, - named: { named: 'named' }, + named: [['named', 'named']], tagged: {}, from: 'x', defaultName: 'name', @@ -209,7 +228,7 @@ describe(`demos/import-tokenizer`, () => { createImportValue({ star: true, named: undefined, - tagged: undefined, + tagged: {}, from: 'x', defaultName: 'name', errors: [], @@ -224,7 +243,10 @@ describe(`demos/import-tokenizer`, () => { expectedAst: [ createImportValue({ star: false, - named: { named1: 'named1', named2: 'named2' }, + named: [ + ['named1', 'named1'], + ['named2', 'named2'], + ], tagged: {}, from: 'x', defaultName: undefined, @@ -240,7 +262,7 @@ describe(`demos/import-tokenizer`, () => { expectedAst: [ createImportValue({ star: false, - named: { named: 'named' }, + named: [['named', 'named']], tagged: {}, from: 'x', defaultName: undefined, @@ -258,7 +280,7 @@ describe(`demos/import-tokenizer`, () => { createImportValue({ star: true, named: undefined, - tagged: undefined, + tagged: {}, from: 'x', defaultName: undefined, errors: ['expected as after *'], @@ -274,7 +296,7 @@ describe(`demos/import-tokenizer`, () => { createImportValue({ star: true, named: undefined, - tagged: undefined, + tagged: {}, from: 'x', defaultName: undefined, errors: ['expected as after *', 'invalid missing from'], @@ -290,7 +312,7 @@ describe(`demos/import-tokenizer`, () => { expectedAst: [ createImportValue({ star: false, - named: { b: 'b' }, + named: [['b', 'b']], tagged: {}, from: 'x', defaultName: undefined, @@ -308,7 +330,7 @@ describe(`demos/import-tokenizer`, () => { createImportValue({ star: false, named: undefined, - tagged: undefined, + tagged: {}, from: 'x', defaultName: undefined, errors: ['unclosed block'], @@ -324,7 +346,7 @@ describe(`demos/import-tokenizer`, () => { createImportValue({ star: false, named: undefined, - tagged: undefined, + tagged: {}, from: undefined, defaultName: undefined, errors: [ @@ -338,7 +360,7 @@ describe(`demos/import-tokenizer`, () => { createImportValue({ star: false, named: undefined, - tagged: undefined, + tagged: {}, from: 'y', defaultName: undefined, errors: [], @@ -354,7 +376,7 @@ describe(`demos/import-tokenizer`, () => { createImportValue({ star: false, named: undefined, - tagged: undefined, + tagged: {}, from: 'x', defaultName: undefined, errors: ['missing name'], @@ -369,7 +391,7 @@ describe(`demos/import-tokenizer`, () => { expectedAst: [ createImportValue({ star: true, - named: { a: 'a' }, + named: [['a', 'a']], tagged: {}, from: 'x', defaultName: 'x', @@ -387,8 +409,13 @@ describe(`demos/import-tokenizer`, () => { expectedAst: [ createImportValue({ star: false, - named: {}, - tagged: { named: { a: 'b', c: 'c' } }, + named: [], + tagged: { + named: [ + ['a', 'b'], + ['c', 'c'], + ], + }, from: 'x', defaultName: undefined, errors: [], @@ -403,8 +430,13 @@ describe(`demos/import-tokenizer`, () => { expectedAst: [ createImportValue({ star: false, - named: {}, - tagged: { ',': { a: 'b', c: 'c' } }, + named: [], + tagged: { + ',': [ + ['a', 'b'], + ['c', 'c'], + ], + }, from: 'x', defaultName: undefined, errors: ['invalid tag name: ,'], @@ -419,8 +451,13 @@ describe(`demos/import-tokenizer`, () => { expectedAst: [ createImportValue({ star: false, - named: {}, - tagged: { named: { a: 'b', c: 'c' } }, + named: [], + tagged: { + named: [ + ['a', 'b'], + ['c', 'c'], + ], + }, from: 'x', defaultName: undefined, errors: ['unclosed tagged import "named"'], @@ -435,10 +472,8 @@ describe(`demos/import-tokenizer`, () => { expectedAst: [ createImportValue({ star: false, - named: { - c: 'c', - }, - tagged: { tag1: { a: 'a' }, tag2: { b: 'b' } }, + named: [['c', 'c']], + tagged: { tag1: [['a', 'a']], tag2: [['b', 'b']] }, from: 'x', defaultName: undefined, errors: [],