Skip to content

Commit

Permalink
Map ts.ObjectLiteralExpression, ts.BinaryExpression, and `ts.Vari…
Browse files Browse the repository at this point in the history
…ableDeclaration`
  • Loading branch information
knutwannheden committed Sep 27, 2024
1 parent 989f8a1 commit 92fec89
Show file tree
Hide file tree
Showing 7 changed files with 377 additions and 7 deletions.
2 changes: 1 addition & 1 deletion openrewrite/src/java/tree/support_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export interface J extends Tree {
type Constructor<T = {}> = new (...args: any[]) => T;

export function isJava(tree: any): tree is J {
return !!tree.constructor.isJava || !!tree.isJava;
return !!tree?.constructor.isJava || !!tree?.isJava;
}

export function JMixin<TBase extends Constructor<Object>>(Base: TBase) {
Expand Down
149 changes: 145 additions & 4 deletions openrewrite/src/javascript/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,14 @@ export class JavaScriptParserVisitor {
}

private mapModifiers(node: ts.VariableStatement) {
return [];
return [new J.Modifier(
randomId(),
Space.EMPTY,
Markers.EMPTY,
node.declarationList.getFirstToken()?.getText()!,
J.Modifier.Type.LanguageExtension,
[]
)];
}

private rightPadded<T>(t: T, trailing: Space, markers?: Markers) {
Expand Down Expand Up @@ -477,7 +484,17 @@ export class JavaScriptParserVisitor {
}

visitObjectLiteralExpression(node: ts.ObjectLiteralExpression) {
return this.visitUnknown(node);
return new J.NewClass(
randomId(),
this.prefix(node),
Markers.EMPTY,
null,
Space.EMPTY,
null,
this.mapArguments(node.properties),
null,
this.mapMethodType(node)
);
}

visitPropertyAccessExpression(node: ts.PropertyAccessExpression) {
Expand Down Expand Up @@ -593,7 +610,119 @@ export class JavaScriptParserVisitor {
}

visitBinaryExpression(node: ts.BinaryExpression) {
return this.visitUnknown(node);
let binaryOperator: J.Binary.Type | JS.JsBinary.Type | undefined;
switch (node.operatorToken.kind) {
case ts.SyntaxKind.EqualsEqualsEqualsToken:
binaryOperator = JS.JsBinary.Type.IdentityEquals;
break;
case ts.SyntaxKind.ExclamationEqualsEqualsToken:
binaryOperator = JS.JsBinary.Type.IdentityNotEquals;
break;
}

if (binaryOperator !== undefined) {
return new JS.JsBinary(
randomId(),
this.prefix(node),
Markers.EMPTY,
this.convert(node.left),
this.leftPadded(this.prefix(node.operatorToken), binaryOperator as JS.JsBinary.Type),
this.convert(node.right),
this.mapType(node)
);
}

if (node.operatorToken.kind == ts.SyntaxKind.InstanceOfKeyword) {
return new J.InstanceOf(
randomId(),
this.prefix(node),
Markers.EMPTY,
this.rightPadded(this.convert(node.left), this.prefix(node.operatorToken)),
this.convert(node.right),
null,
this.mapType(node)
);
}

binaryOperator = this.mapBinaryOperator(node);
if (binaryOperator === undefined) {
return this.visitUnknown(node);
}

return new J.Binary(
randomId(),
this.prefix(node),
Markers.EMPTY,
this.convert(node.left),
this.leftPadded(this.prefix(node.operatorToken), binaryOperator),
this.convert(node.right),
this.mapType(node)
)
}

private mapBinaryOperator(node: ts.BinaryExpression): J.Binary.Type | undefined {
switch (node.operatorToken.kind) {
case ts.SyntaxKind.PlusToken:
return J.Binary.Type.Addition;
case ts.SyntaxKind.MinusToken:
return J.Binary.Type.Subtraction;
case ts.SyntaxKind.AsteriskToken:
return J.Binary.Type.Multiplication;
case ts.SyntaxKind.SlashToken:
return J.Binary.Type.Division;
case ts.SyntaxKind.PercentToken:
return J.Binary.Type.Modulo;
case ts.SyntaxKind.LessThanLessThanToken:
return J.Binary.Type.LeftShift;
case ts.SyntaxKind.GreaterThanGreaterThanToken:
return J.Binary.Type.RightShift;
case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
return J.Binary.Type.UnsignedRightShift;
// case ts.SyntaxKind.LessThanLessThanEqualsToken:
// return J.Binary.Type.LeftShiftEquals;
// case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken:
// return J.Binary.Type.RightShiftEquals;

case ts.SyntaxKind.AmpersandToken:
return J.Binary.Type.BitAnd;
// case ts.SyntaxKind.AmpersandEqualsToken:
// return J.Binary.Type.BitwiseAndEquals;
case ts.SyntaxKind.BarToken:
return J.Binary.Type.BitOr;
// case ts.SyntaxKind.BarEqualsToken:
// return J.Binary.Type.BitwiseOrEquals;
case ts.SyntaxKind.CaretToken:
return J.Binary.Type.BitXor;
// case ts.SyntaxKind.CaretEqualsToken:
// return J.Binary.Type.BitwiseXorEquals;

case ts.SyntaxKind.EqualsEqualsToken:
return J.Binary.Type.Equal;
// case ts.SyntaxKind.EqualsEqualsEqualsToken:
// return J.Binary.Type.StrictEquals;
case ts.SyntaxKind.ExclamationEqualsToken:
return J.Binary.Type.NotEqual;
// case ts.SyntaxKind.ExclamationEqualsEqualsToken:
// return J.Binary.Type.StrictNotEquals;
case ts.SyntaxKind.LessThanToken:
return J.Binary.Type.LessThan;
case ts.SyntaxKind.LessThanEqualsToken:
return J.Binary.Type.LessThanOrEqual;
case ts.SyntaxKind.GreaterThanToken:
return J.Binary.Type.GreaterThan;
case ts.SyntaxKind.GreaterThanEqualsToken:
return J.Binary.Type.GreaterThanOrEqual;

case ts.SyntaxKind.AmpersandAmpersandToken:
return J.Binary.Type.And;
case ts.SyntaxKind.BarBarToken:
return J.Binary.Type.Or;
// case ts.SyntaxKind.BarBarEqualsToken:
// return J.Binary.Type.OrEquals;
// case ts.SyntaxKind.AmpersandEqualsToken:
// return J.Binary.Type.AndEquals;
}
return undefined;
}

visitConditionalExpression(node: ts.ConditionalExpression) {
Expand Down Expand Up @@ -752,7 +881,15 @@ export class JavaScriptParserVisitor {
}

visitVariableDeclaration(node: ts.VariableDeclaration) {
return this.visitUnknown(node);
return new J.VariableDeclarations.NamedVariable(
randomId(),
this.prefix(node),
Markers.EMPTY,
this.visit(node.name),
[],
node.initializer ? this.leftPadded(this.prefix(node.getChildAt(node.getChildCount() - 2)), this.visit(node.initializer)) : null,
this.mapVariableType(node)
);
}

visitVariableDeclarationList(node: ts.VariableDeclarationList) {
Expand Down Expand Up @@ -1171,6 +1308,10 @@ export class JavaScriptParserVisitor {
return JavaType.Unknown.INSTANCE;
}

private mapVariableType(node: ts.Node): JavaType.Variable | null {
return null;
}

private mapMethodType(node: ts.Node): JavaType.Method | null {
// FIXME JavaType.Method
return null;
Expand Down
159 changes: 159 additions & 0 deletions openrewrite/test/javascript/parser/binary.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import {connect, disconnect, rewriteRun, typeScript} from '../testHarness';

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

test('plus', () => {
rewriteRun(
//language=typescript
typeScript('1 + 2')
);
});

test('minus', () => {
rewriteRun(
//language=typescript
typeScript('1 - 2')
);
});

test('multiply', () => {
rewriteRun(
//language=typescript
typeScript('1 * 2')
);
});

test('divide', () => {
rewriteRun(
//language=typescript
typeScript('1 / 2')
);
});

test('modulo', () => {
rewriteRun(
//language=typescript
typeScript('1 % 2')
);
});

test('left shift', () => {
rewriteRun(
//language=typescript
typeScript('1 << 2')
);
});

test('right shift', () => {
rewriteRun(
//language=typescript
typeScript('1 >> 2')
);
});

test('unsigned right shift', () => {
rewriteRun(
//language=typescript
typeScript('1 >>> 2')
);
});
});

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

test('and', () => {
rewriteRun(
//language=typescript
typeScript('1 & 2')
);
});
test('or', () => {
rewriteRun(
//language=typescript
typeScript('1 | 2')
);
});
test('xor', () => {
rewriteRun(
//language=typescript
typeScript('1 ^ 2')
);
});
});

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

test('less than', () => {
rewriteRun(
//language=typescript
typeScript('1 < 2')
);
});
test('less than or equal', () => {
rewriteRun(
//language=typescript
typeScript('1 <= 2')
);
});
test('greater than', () => {
rewriteRun(
//language=typescript
typeScript('1 > 2')
);
});
test('greater than or equal', () => {
rewriteRun(
//language=typescript
typeScript('1 >= 2')
);
});
test('equal', () => {
rewriteRun(
//language=typescript
typeScript('1 == 2')
);
});
test('not equal', () => {
rewriteRun(
//language=typescript
typeScript('1 != 2')
);
});

test('strict equal', () => {
rewriteRun(
//language=typescript
typeScript('1 === 2')
);
});
test('strict not equal', () => {
rewriteRun(
//language=typescript
typeScript('1 !== 2')
);
});
})

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

test('and', () => {
rewriteRun(
//language=typescript
typeScript('1 && 2')
);
});
test('or', () => {
rewriteRun(
//language=typescript
typeScript('1 || 2')
);
});
});
13 changes: 13 additions & 0 deletions openrewrite/test/javascript/parser/instanceof.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {connect, disconnect, rewriteRun, typeScript} from '../testHarness';

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

test('simple', () => {
rewriteRun(
//language=typescript
typeScript('1 instanceof Object')
);
});
});
Loading

0 comments on commit 92fec89

Please sign in to comment.