Skip to content
This repository was archived by the owner on May 12, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
286 changes: 206 additions & 80 deletions openrewrite/src/javascript/parser.ts

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions openrewrite/test/javascript/parser/class.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -375,4 +375,18 @@ describe('class mapping', () => {
);
});

test('class with SemicolonClassElement', () => {
rewriteRun(
//language=typescript
typeScript(`
class MyClass {
/*a*/; // This is a SemicolonClassElement
myMethod() {
console.log('Hello');
}
}
`)
);
});

});
41 changes: 41 additions & 0 deletions openrewrite/test/javascript/parser/do-while.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {connect, disconnect, rewriteRun, typeScript} from '../testHarness';

describe('do-while mapping', () => {
beforeAll(() => connect());
afterAll(() => disconnect());

test('empty do-while', () => {
rewriteRun(
//language=typescript
typeScript('do {} while (true);')
);
});

test('empty do-while with comments', () => {
rewriteRun(
//language=typescript
typeScript('/*a*/ do /*b*/{/*c*/} /*d*/while/*e*/ (/*f*/true/*g*/)/*h*/;')
);
});

test('empty do-while with expression and comments', () => {
rewriteRun(
//language=typescript
typeScript('/*a*/ do /*b*/{/*c*/} /*d*/while/*e*/ (/*f*/Math/*0*/./*1*/random(/*2*/) /*3*/ > /*4*/0.7/*g*/)/*h*/;')
);
});

test('do-while with statements', () => {
rewriteRun(
//language=typescript
typeScript(`
let count = 0;
do {
console.log(count)
/*count*/
count++;
} while (count < 10);
`)
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import {connect, disconnect, rewriteRun, typeScript} from '../testHarness';

describe('array literal mapping', () => {
beforeAll(() => connect());
afterAll(() => disconnect());

test('access by index', () => {
rewriteRun(
//language=typescript
typeScript(`
const numbers = [10, 20, 30, 40];
const v = numbers[2];
`)
);
});

test('access by index with comments', () => {
rewriteRun(
//language=typescript
typeScript(`
const numbers = [10, 20, 30, 40];
const v = /*a*/ numbers/*b*/[/*c*/2/*d*/]/*e*/;/*f*/
`)
);
});

test('access by index with !', () => {
rewriteRun(
//language=typescript
typeScript(`
const numbers = [10, 20, 30, 40];
const v = numbers[2]!;
`)
);
});

test('access by index with ! and comments', () => {
rewriteRun(
//language=typescript
typeScript(`
const numbers = [10, 20, 30, 40];
const v = numbers[2]/*a*/!/*b*/;
`)
);
});

test('access by key', () => {
rewriteRun(
//language=typescript
typeScript(`
const data = { a: 100, b: 200, c: 300 };
const v = /*a*/data/*b*/[/*c*/'a'/*d*/]/*e*/;/*f*/
`)
);
});

test('access by key with comments', () => {
rewriteRun(
//language=typescript
typeScript(`
const data = { a: 100, b: 200, c: 300 };
const v = data['a'];
`)
);
});

test('access by key with ?.', () => {
rewriteRun(
//language=typescript
typeScript(`
const data = { a: 100, b: 200, c: 300 };
const v = data['d'] ?. toString();
`)
);
});

});
6 changes: 3 additions & 3 deletions openrewrite/test/javascript/parser/enum.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe('empty mapping', () => {
//language=typescript
typeScript(`
enum Test {
A ,
A/*a*/,
};
`)
);
Expand Down Expand Up @@ -116,9 +116,9 @@ describe('empty mapping', () => {
//language=typescript
typeScript(`
enum Test /*xx*/ {
A /*aa*/,
A /*aa*/, /*ab*/
/*bb*/ B /*cc*/,
C, /*dd*/
C/*de*/, /*dd*/
};
`)
);
Expand Down
25 changes: 25 additions & 0 deletions openrewrite/test/javascript/parser/expressionStatement.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,29 @@ describe('expression statement mapping', () => {
`)
);
});

test('mixed expression with methods with special tokens', () => {
rewriteRun(
//language=typescript
typeScript(`
interface Profile {
username?(): string; // Optional property

}

interface User {
profile?(): Profile; // Optional property
}

function getUser(id: number) : User | null {
return null;
}

const user = getUser(1);
const username1 = user ! . profile() ?. username() !. toLowerCase() /*test*/ ;
const username2 = getUser(1) ! . profile() ?. username() ; // test;
const username3 = getUser(1) ?. profile()?.username() ?? 'Guest' ;
`)
);
});
});
113 changes: 110 additions & 3 deletions openrewrite/test/javascript/parser/for.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,123 @@ describe('for mapping', () => {
beforeAll(() => connect());
afterAll(() => disconnect());

test('indexed', () => {
test('empty for', () => {
rewriteRun(
//language=typescript
typeScript('for (;;);')
);
});

test('empty for with comments', () => {
rewriteRun(
//language=typescript
typeScript('/*a*/for /*b*/ (/*c*/;/*d*/;/*e*/)/*f*/;/*g*/')
);
});

test('for indexed', () => {
rewriteRun(
//language=typescript
typeScript('for (let i = 0; i < 10; i++) ;')
);
});
test('indexed multiple variables', () => {

test('for indexed multiple variables', () => {
rewriteRun(
//language=typescript
typeScript('for (let /*0*/ i /*1*/ = /*2*/ 0 /*3*/ , j = 0; i < 10; i++) ;')
typeScript('for (let /*0*/ i /*1*/ = /*2*/ 0 /*3*/ , j = 0/*4*/; /*5*/ i /*6*/ < 10 /*7*/; /*8*/i++/*9*/)/*10*/ ;/*11*/')
);
});

test('for indexed with empty body', () => {
rewriteRun(
//language=typescript
typeScript('for (let i = 0; i < 10; i++) /*a*/ {/*b*/} /*c*/;')
);
});

test('for indexed with body', () => {
rewriteRun(
//language=typescript
typeScript('for (let i = 0; i < 10; i++) { console.log(i); };')
);
});

test('for with continue', () => {
rewriteRun(
//language=typescript
typeScript(`
for (let i = 0; i < 5; i++) {
if (i === 2) {
continue /*a*/; // Skip the current iteration when i equals 2
}
console.log(i);
}
`)
);
});

test('for with break', () => {
rewriteRun(
//language=typescript
typeScript(`
for (let i = 0; i < 5; i++) {
if (i === 2) {
break /*a*/; // Exit the loop when i equals 5
}
console.log(i);
}
`)
);
});

test('for with labeled break', () => {
rewriteRun(
//language=typescript
typeScript(`
/*a*/labelName/*b*/:/*c*/ for (let i = 0; i < 5; i++) {
for (let j = 0; j < 5; j++) {
if (i === 2 && j === 2) {
/*d*/break /*e*/ labelName/*f*/; // Exits the outer loop when i and j are both 2
}
}
}
`)
);
});

test('for-of empty', () => {
rewriteRun(
//language=typescript
typeScript('for (let char of "text") ;')
);
});

test('for-of empty with array', () => {
rewriteRun(
//language=typescript
typeScript('for (let i of [0, 1, 2, [3, 4, 5]]) ;')
);
});

test('for-of with comments', () => {
rewriteRun(
//language=typescript
typeScript('/*a*/for/*b*/ (/*c*/const /*d*/char /*e*/of /*f*/ "text"/*g*/)/*h*/ {/*j*/} /*k*/;/*l*/')
);
});

test.skip('for-in empty', () => {
rewriteRun(
//language=typescript
typeScript('for (const index in []) ;')
);
});

test.skip('for-in with comments', () => {
rewriteRun(
//language=typescript
typeScript('/*a*/for/*b*/ (/*c*/const /*d*/index /*e*/in /*f*/ []/*g*/)/*h*/ {/*j*/} /*k*/;/*l*/')
);
});
});
Loading