Skip to content

Commit

Permalink
Implemented try-catch support (#133)
Browse files Browse the repository at this point in the history
Implemented visitors for visitTryStatement, visitThrowStatement, visitUnknownKeyword and visitAnyKeyword
  • Loading branch information
arodionov authored Nov 4, 2024
1 parent 8d4b720 commit 2227d44
Show file tree
Hide file tree
Showing 4 changed files with 229 additions and 2 deletions.
51 changes: 49 additions & 2 deletions openrewrite/src/javascript/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,14 @@ export class JavaScriptParserVisitor {
return this.mapIdentifier(node, 'undefined');
}

visitAnyKeyword(node: ts.Node) {
return this.mapIdentifier(node, 'any');
}

visitUnknownKeyword(node: ts.Node) {
return this.mapIdentifier(node, 'unknown');
}

visitVoidKeyword(node: ts.Node) {
return this.mapIdentifier(node, 'void');
}
Expand Down Expand Up @@ -1566,11 +1574,50 @@ export class JavaScriptParserVisitor {
}

visitThrowStatement(node: ts.ThrowStatement) {
return this.visitUnknown(node);
return new J.Throw(
randomId(),
this.prefix(node),
Markers.EMPTY,
this.visit(node.expression)
);
}

visitTryStatement(node: ts.TryStatement) {
return this.visitUnknown(node);
return new J.Try(
randomId(),
this.prefix(node),
Markers.EMPTY,
null,
this.visit(node.tryBlock),
node.catchClause ?
[new J.Try.Catch(
randomId(),
this.prefix(node.catchClause.getFirstToken()!),
Markers.EMPTY,
new J.ControlParentheses(
randomId(),
this.suffix(node.catchClause.getFirstToken()!),
Markers.EMPTY,
this.rightPadded(
new J.VariableDeclarations(
randomId(),
this.prefix(node.catchClause.variableDeclaration!),
Markers.EMPTY,
[],
[],
this.mapTypeInfo(node.catchClause.variableDeclaration!),
null,
[],
[this.rightPadded(this.visit(node.catchClause.variableDeclaration!), Space.EMPTY)]
),
this.suffix(node.catchClause.variableDeclaration!))
),
this.visit(node.catchClause?.block!)
)] : [],
node.finallyBlock ? this.leftPadded(
this.prefix(node.getChildren().find(n => n.kind === ts.SyntaxKind.FinallyKeyword)!), this.visit(node.finallyBlock))
: null
);
}

visitDebuggerStatement(node: ts.DebuggerStatement) {
Expand Down
40 changes: 40 additions & 0 deletions openrewrite/test/javascript/parser/throw.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {connect, disconnect, rewriteRun, typeScript} from '../testHarness';

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

test('simple throw', () => {
rewriteRun(
//language=typescript
typeScript(`
throw new Error("Cannot divide by zero!");
`)
);
});

test('simple throw with comments', () => {
rewriteRun(
//language=typescript
typeScript(`
/*a*/ throw /*b*/ new /*c*/ Error/*d*/(/*e*/'Cannot divide by zero!'/*f*/)/*g*/;
`)
);
});

test('re-throwing', () => {
rewriteRun(
//language=typescript
typeScript(`
function riskyOperation() {
try {
throw new Error("An error occurred during risky operation.");
} catch (error) {
console.error("Logging Error:", (error as Error).message);
throw error; // Re-throw the error to be handled at a higher level
}
}
`)
);
});
});
128 changes: 128 additions & 0 deletions openrewrite/test/javascript/parser/try-catch.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import {connect, disconnect, rewriteRun, typeScript} from '../testHarness';

describe('try-catch mapping', () => {
beforeAll(() => connect());
afterAll(() => disconnect());

test('try-catch empty', () => {
rewriteRun(
//language=typescript
typeScript(`
try {
} catch (error) {
}
`)
);
});

test('try-finally empty', () => {
rewriteRun(
//language=typescript
typeScript(`
try {
} finally {
}
`)
);
});

test('try-catch-finally empty', () => {
rewriteRun(
//language=typescript
typeScript(`
try {
} catch (error) {
} finally {
}
`)
);
});

test('try-catch-finally empty comments', () => {
rewriteRun(
//language=typescript
typeScript(`
/*a*/ try /*b*/ {
} /*c*/ catch /*d*/ ( /*e*/ error /*f*/) { /*g*/
} /*h*/ finally /*i*/ { /*j*/
} /*k*/
`)
);
});

test('try-catch with typed unknown error', () => {
rewriteRun(
//language=typescript
typeScript(`
try {
// error
} catch (error: unknown) {
// handel error
}
`)
);
});

test('try-catch with typed any error', () => {
rewriteRun(
//language=typescript
typeScript(`
try {
// error
} catch (error: any) {
// handel error
}
`)
);
});

test('try-catch with typed error and comments', () => {
rewriteRun(
//language=typescript
typeScript(`
try {
// error
} catch (/*a*/ error /*b*/: /*c*/ unknown /*d*/) {
// handel error
}
`)
);
});

test('try-catch-finally with body', () => {
rewriteRun(
//language=typescript
typeScript(`
try {
// Try to parse JSON string
const data = JSON.parse('{ "name": "Alice" }');
console.log(data.name); // Output: "Alice"
} catch (error: unknown) {
if (error instanceof Error) {
console.error("Caught an error:", error.message);
} else {
console.error("An unknown error occurred");
}
} finally {
console.log("Parsing attempt finished.");
}
`)
);
});

test('try-catch-finally with throw', () => {
rewriteRun(
//language=typescript
typeScript(`
try {
throw new Error("Failed to perform database operation.");
} catch (error) {
console.error("Database Error:", (error as Error).message);
} finally {
console.log("Clean.");
}
`)
);
});

});
12 changes: 12 additions & 0 deletions openrewrite/test/javascript/parser/variableDeclarations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@ describe('variable declaration mapping', () => {
typeScript('let a : number =2')
);
});
test('typed unknown', () => {
rewriteRun(
//language=typescript
typeScript('const a : unknown')
);
});
test('typed any', () => {
rewriteRun(
//language=typescript
typeScript('let a : any = 2;')
);
});
test('multi', () => {
rewriteRun(
//language=typescript
Expand Down

0 comments on commit 2227d44

Please sign in to comment.