diff --git a/openrewrite/src/core/tree.ts b/openrewrite/src/core/tree.ts index 0b5892e..76ebfb4 100644 --- a/openrewrite/src/core/tree.ts +++ b/openrewrite/src/core/tree.ts @@ -318,7 +318,6 @@ export class FileAttributes { } export function isSourceFile(tree: any & Tree): tree is SourceFile { - // return 'sourcePath' in tree && 'printer' in tree; return !!tree.constructor.isSourceFile; } diff --git a/openrewrite/src/javascript/parser.ts b/openrewrite/src/javascript/parser.ts index a1cd352..48e837e 100644 --- a/openrewrite/src/javascript/parser.ts +++ b/openrewrite/src/javascript/parser.ts @@ -173,23 +173,27 @@ export class JavaScriptParserVisitor { } visitNumericLiteral(node: ts.NumericLiteral) { + return this.mapLiteral(node, node.text) // FIXME value not in AST + } + + private mapLiteral(node: ts.LiteralExpression, value: any) { return new J.Literal( randomId(), this.prefix(node), Markers.EMPTY, - node.text, // FIXME value not in AST - node.text, + value, + node.getText(), null, this.mapType(node) as JavaType.Primitive ); } visitBigIntLiteral(node: ts.BigIntLiteral) { - return this.visitUnknown(node) + return this.mapLiteral(node, node.text) // FIXME value not in AST } visitStringLiteral(node: ts.StringLiteral) { - return this.visitUnknown(node) + return this.mapLiteral(node, node.text) // FIXME value not in AST } visitJsxText(node: ts.JsxText) { @@ -1016,7 +1020,12 @@ export class JavaScriptParserVisitor { private mapType(node: ts.Expression): JavaType | null { if (ts.isLiteralExpression(node)) { - return JavaType.Primitive.of(JavaType.PrimitiveKind.Int); + if (ts.isNumericLiteral(node)) { + return JavaType.Primitive.of(JavaType.PrimitiveKind.Int); + } else if (ts.isStringLiteral(node)) { + return JavaType.Primitive.of(JavaType.PrimitiveKind.String); + } + return JavaType.Primitive.of(JavaType.PrimitiveKind.Void); } return JavaType.Unknown.INSTANCE; } diff --git a/openrewrite/test/javascript/parser/expressionStatement.test.ts b/openrewrite/test/javascript/parser/expressionStatement.test.ts index db24b2f..df875df 100644 --- a/openrewrite/test/javascript/parser/expressionStatement.test.ts +++ b/openrewrite/test/javascript/parser/expressionStatement.test.ts @@ -1,6 +1,9 @@ -import {javaScript, rewriteRunWithOptions} from '../testHarness'; +import {connect, disconnect, javaScript, rewriteRunWithOptions} from '../testHarness'; describe('expression statement mapping', () => { + beforeAll(() => connect()); + afterAll(() => disconnect()); + test('literal with semicolon', () => { rewriteRunWithOptions( {normalizeIndent: false}, diff --git a/openrewrite/test/javascript/parser/literal.test.ts b/openrewrite/test/javascript/parser/literal.test.ts index d3af5f2..1ef95f9 100644 --- a/openrewrite/test/javascript/parser/literal.test.ts +++ b/openrewrite/test/javascript/parser/literal.test.ts @@ -1,8 +1,11 @@ import * as J from "../../../dist/java/tree"; import * as JS from "../../../dist/javascript/tree"; -import {javaScript, rewriteRunWithOptions} from '../testHarness'; +import {connect, disconnect, javaScript, rewriteRunWithOptions} from '../testHarness'; describe('literal mapping', () => { + beforeAll(() => connect()); + afterAll(() => disconnect()); + test('number', () => { rewriteRunWithOptions( {normalizeIndent: false}, @@ -16,4 +19,17 @@ describe('literal mapping', () => { expect((expression as J.Literal).valueSource).toBe('1'); })); }); + test('string', () => { + rewriteRunWithOptions( + {normalizeIndent: false}, + javaScript('"1"', sourceFile => { + expect(sourceFile).toBeDefined(); + expect(sourceFile.statements).toHaveLength(1); + let statement = sourceFile.statements[0]; + expect(statement).toBeInstanceOf(JS.ExpressionStatement); + let expression = (statement as JS.ExpressionStatement).expression; + expect(expression).toBeInstanceOf(J.Literal); + expect((expression as J.Literal).valueSource).toBe('"1"'); + })); + }); }); diff --git a/openrewrite/test/javascript/parser/sourceFile.test.ts b/openrewrite/test/javascript/parser/sourceFile.test.ts index a1d5e71..172abbf 100644 --- a/openrewrite/test/javascript/parser/sourceFile.test.ts +++ b/openrewrite/test/javascript/parser/sourceFile.test.ts @@ -1,6 +1,9 @@ -import {javaScript, rewriteRunWithOptions} from '../testHarness'; +import {connect, disconnect, javaScript, rewriteRunWithOptions} from '../testHarness'; describe('source file mapping', () => { + beforeAll(() => connect()); + afterAll(() => disconnect()); + test('whitespace after last statement', () => { rewriteRunWithOptions( {normalizeIndent: false}, diff --git a/openrewrite/test/javascript/parser/variableDeclarations.test.ts b/openrewrite/test/javascript/parser/variableDeclarations.test.ts index 56400e5..928acb5 100644 --- a/openrewrite/test/javascript/parser/variableDeclarations.test.ts +++ b/openrewrite/test/javascript/parser/variableDeclarations.test.ts @@ -1,7 +1,10 @@ import * as J from "../../../dist/java/tree"; -import {javaScript, rewriteRun, rewriteRunWithOptions} from '../testHarness'; +import {connect, disconnect, javaScript, rewriteRun, rewriteRunWithOptions} from '../testHarness'; describe('variable declaration mapping', () => { + beforeAll(() => connect()); + afterAll(() => disconnect()); + test('const', () => { rewriteRunWithOptions( { validatePrintIdempotence: false}, diff --git a/openrewrite/test/javascript/testHarness.ts b/openrewrite/test/javascript/testHarness.ts index 0fc0657..1a4a67b 100644 --- a/openrewrite/test/javascript/testHarness.ts +++ b/openrewrite/test/javascript/testHarness.ts @@ -14,6 +14,49 @@ export interface RewriteTestOptions { export type SourceSpec = (options: RewriteTestOptions) => void; +let client: net.Socket; +let remoting: RemotingContext; + +export async function connect(): Promise { + return new Promise((resolve, reject) => { + SenderContext.register(JS.isJavaScript, () => new JavaScriptSender()); + ReceiverContext.register(JS.isJavaScript, () => new JavaScriptReceiver()); + deser.register(); + + client = new net.Socket(); + client.connect(65432, 'localhost'); + + client.once('error', (err) => reject(err)); + client.once('connect', () => { + remoting = new RemotingContext(); + remoting.connect(client); + PrinterFactory.current = new RemotePrinterFactory(remoting.client!); + resolve(remoting); + }); + client.setTimeout(10000, () => { + client.destroy(); + reject(new Error('Connection timed out')); + }); + }); +} + +export async function disconnect(): Promise { + return new Promise((resolve, reject) => { + if (client) { + client.end(); + client.destroy(); + client.once('close', resolve); + client.once('error', reject); + if (remoting) { + remoting.close(); + } + } else { + resolve(); + } + }); +} + + export function rewriteRun(...sourceSpecs: SourceSpec[]) { rewriteRunWithOptions({}, ...sourceSpecs); } @@ -38,31 +81,7 @@ export function javaScript(before: string, spec?: (sourceFile: JS.CompilationUni } function print(parsed: SourceFile) { - SenderContext.register(JS.isJavaScript, () => new JavaScriptSender()); - ReceiverContext.register(JS.isJavaScript, () => new JavaScriptReceiver()); - deser.register(); - - const client = new net.Socket(); - - client.on('error', (err) => { - console.error('Socket error:', err); - }); - - // Connect to the server - client.connect(65432, 'localhost'); - - const remoting = new RemotingContext(); - - try { - remoting.connect(client); - remoting.reset(); - remoting.client?.reset(); - PrinterFactory.current = new RemotePrinterFactory(remoting.client!); - - return parsed.print(new Cursor(null, Cursor.ROOT_VALUE), new PrintOutputCapture(0)); - } finally { - client.end(); - client.destroy(); - remoting.close(); - } + remoting.reset(); + remoting.client?.reset(); + return parsed.print(new Cursor(null, Cursor.ROOT_VALUE), new PrintOutputCapture(0)); }