From 7eb73ccf812cd01cccdd4edbc23988e64a075163 Mon Sep 17 00:00:00 2001 From: Giancarlo Anemone Date: Wed, 31 Oct 2018 17:24:30 -0400 Subject: [PATCH] Fix issue with flow and special reserved words https://github.com/uber-web/thrift2flow/pull/38 --- src/main/convert.js | 31 ++++++++++++++--------------- src/main/identifier.js | 10 ++++++++++ src/main/types.js | 18 ++++++++++------- src/test/imports.spec.js | 42 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 23 deletions(-) create mode 100644 src/main/identifier.js diff --git a/src/main/convert.js b/src/main/convert.js index e62056a..1caef5a 100644 --- a/src/main/convert.js +++ b/src/main/convert.js @@ -28,7 +28,7 @@ import {Thrift} from 'thriftrw'; import {TypeConverter} from './types'; import prettier from 'prettier'; import path from 'path'; - +import {id} from './identifier'; import type {Base} from 'bufrw'; import type { Struct, @@ -69,20 +69,19 @@ export class ThriftFileConverter { this.withsource = withsource; } - generateFlowFile = () => - prettier.format( - [ - '// @flow', - `// Generated by thrift2flow at ${new Date().toString()}${ - this.withsource ? `\n// Source: ${this.thriftPath}` : '' - }`, - this.generateImports(), - ...this.thriftAstDefinitions.map(this.convertDefinitionToCode), - ] - .filter(Boolean) - .join('\n\n'), - {parser: 'flow'} - ); + generateFlowFile = () => { + const result = [ + '// @flow', + `// Generated by thrift2flow at ${new Date().toString()}${ + this.withsource ? `\n// Source: ${this.thriftPath}` : '' + }`, + this.generateImports(), + ...this.thriftAstDefinitions.map(this.convertDefinitionToCode), + ] + .filter(Boolean) + .join('\n\n'); + return prettier.format(result, {parser: 'flow'}); + }; convertDefinitionToCode = (def: any) => { switch (def.type) { @@ -229,7 +228,7 @@ export class ThriftFileConverter { baseName = `_${baseName}`; } } - return `import * as ${baseName} from '${relpath}';`; + return `import * as ${id(baseName)} from '${relpath}';`; }); if (this.isLongDefined()) { diff --git a/src/main/identifier.js b/src/main/identifier.js new file mode 100644 index 0000000..2135a9b --- /dev/null +++ b/src/main/identifier.js @@ -0,0 +1,10 @@ +// @flow +const reservedTypes = ['any', 'mixed', 'number']; + +export function id(s: string): string { + const split = s.split('.'); + if (reservedTypes.includes(s) || reservedTypes.includes(split[0])) { + return `_${s}`; + } + return s; +} diff --git a/src/main/types.js b/src/main/types.js index 8117e8c..bae2fa5 100644 --- a/src/main/types.js +++ b/src/main/types.js @@ -25,6 +25,7 @@ // @flow import {BaseType, Enum, ListType, MapType, SetType} from 'thriftrw/ast'; +import {id} from './identifier'; export class TypeConverter { static primitives = { @@ -65,13 +66,16 @@ export class TypeConverter { return ''; } - convert = (t: BaseType): string => - this.arrayType(t) || - this.enumType(t) || - this.mapType(t) || - this.annotation(t) || - TypeConverter.primitives[t.baseType] || - this.transformName(t.name); + convert = (t: BaseType): string => { + return ( + this.arrayType(t) || + this.enumType(t) || + this.mapType(t) || + this.annotation(t) || + TypeConverter.primitives[t.baseType] || + this.transformName(id(t.name)) + ); + }; enumType = (thriftValueType: BaseType) => this.isEnum(thriftValueType) && this.transformName(thriftValueType.name); diff --git a/src/test/imports.spec.js b/src/test/imports.spec.js index cc12540..a76d3c3 100644 --- a/src/test/imports.spec.js +++ b/src/test/imports.spec.js @@ -79,6 +79,48 @@ struct MyStruct { ) ); +test( + 'imports with special type file names', + flowResultTest( + { + // language=thrift + 'any.thrift': ` + typedef i32 Thing + `, + // language=thrift + 'shared.thrift': ` +include "./any.thrift" +struct MyStruct { + 1: any.Thing a + 2: map b + 3: map c +} +typedef any.Thing MyTypedef +const any.Thing MyConst = 10; +const set MySet = [0]; +union MyUnion { + 1: any.Thing a + 2: i32 b +} +`, + // language=JavaScript + 'index.js': ` +// @flow +import type {MyStructXXX} from './shared'; + +function go(s : MyStructXXX) { + const numbers : number[] = [s.a]; + return [numbers]; +} + `, + }, + (t: Test, r: FlowResult) => { + t.equal(r.errors.length, 0); + t.end(); + } + ) +); + test( 'imports in sub directory', flowResultTest(