Skip to content

Commit

Permalink
add custom VD to support optional typing (#138)
Browse files Browse the repository at this point in the history
for now this add support for optional params in the method declaration.

---------

Co-authored-by: Andrii Rodionov <[email protected]>
  • Loading branch information
OlegDokuka and Andrii Rodionov authored Nov 5, 2024
1 parent ab41fde commit 82bdbeb
Show file tree
Hide file tree
Showing 17 changed files with 846 additions and 11 deletions.
56 changes: 55 additions & 1 deletion openrewrite/src/java/tree/support_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,12 +373,66 @@ export class JLeftPadded<T> {
this._markers = markers;
}

static getElements<T>(ls: Array<JLeftPadded<T>>): Array<T> {
if (ls == null) {
return [];
}
const list = new Array<T>(ls.length);
for (let l of ls) {
if (l == null) {
continue;
}
const elem = l.element;
list.push(elem);
}
return list;
}

static withElement<T>(before: JLeftPadded<T> | null, element: T | null): JLeftPadded<T> | null {
if (element == null) return null;
if (before == null) return new JLeftPadded<T>(Space.EMPTY, element, Markers.EMPTY);
return before.withElement(element);
}

static withElements<T>(before: JLeftPadded<T>[], elements: T[]): JLeftPadded<T>[] {
// a cheaper check for the most common case when there are no changes
if (elements.length === before.length) {
let hasChanges = false;
for (let i = 0; i < before.length; i++) {
if (before[i].element !== elements[i]) {
hasChanges = true;
break;
}
}
if (!hasChanges) {
return before;
}
} else if (elements.length === 0) {
return [];
}

const after: JLeftPadded<T>[] = new Array<JLeftPadded<T>>();
const beforeById: Map<T, JLeftPadded<T>> = new Map();

for (const j of before) {
if (beforeById.has(j.element)) {
throw new Error("Duplicate key");
}
beforeById.set(j.element, j);
}

for (const t of elements) {
const found = beforeById.get(t);
if (found) {
after.push(found.withElement(t));
} else {
after.push(new JLeftPadded<T>(Space.EMPTY, t, Markers.EMPTY));
}
}

return after;
}

private readonly _before: Space;

get before(): Space {
Expand Down Expand Up @@ -756,4 +810,4 @@ export namespace JContainer {
return null!;
}
}
}
}
31 changes: 31 additions & 0 deletions openrewrite/src/javascript/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,37 @@ export class JavaScriptParserVisitor {
}

visitParameter(node: ts.ParameterDeclaration) {
if (node.questionToken) {
return new JS.JSVariableDeclarations(
randomId(),
this.prefix(node),
Markers.EMPTY,
[],
this.mapModifiers(node),
this.mapTypeInfo(node),
null,
[this.rightPadded(
new JS.JSVariableDeclarations.JSNamedVariable(
randomId(),
this.prefix(node.name),
Markers.EMPTY,
new JS.Unary(
randomId(),
Space.EMPTY,
Markers.EMPTY,
this.leftPadded(this.suffix(node.name), JS.Unary.Type.Optional),
this.visit(node.name),
this.mapType(node)
),
[],
node.initializer ? this.leftPadded(this.prefix(node.getChildAt(node.getChildCount(this.sourceFile) - 2)), this.visit(node.initializer)) : null,
this.mapVariableType(node)
),
this.suffix(node.name)
)]
);
}

return new J.VariableDeclarations(
randomId(),
this.prefix(node),
Expand Down
50 changes: 49 additions & 1 deletion openrewrite/src/javascript/remote/receiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as extensions from "./remote_extensions";
import {Checksum, Cursor, FileAttributes, ListUtils, Tree} from '../../core';
import {DetailsReceiver, Receiver, ReceiverContext, ReceiverFactory, ValueType} from '@openrewrite/rewrite-remote';
import {JavaScriptVisitor} from '..';
import {JS, CompilationUnit, Alias, ArrowFunction, Await, DefaultType, Delete, Export, ExpressionStatement, FunctionType, JsImport, JsBinary, ObjectBindingDeclarations, PropertyAssignment, ScopedVariableDeclarations, StatementExpression, TemplateExpression, Tuple, TypeDeclaration, TypeOf, TypeOperator, Unary, Union, Void, Yield, TypeInfo, NamespaceDeclaration} from '../tree';
import {JS, JsLeftPadded, JsRightPadded, JsContainer, JsSpace, CompilationUnit, Alias, ArrowFunction, Await, DefaultType, Delete, Export, ExpressionStatement, FunctionType, JsImport, JsBinary, ObjectBindingDeclarations, PropertyAssignment, ScopedVariableDeclarations, StatementExpression, TemplateExpression, Tuple, TypeDeclaration, TypeOf, TypeOperator, Unary, Union, Void, Yield, TypeInfo, JSVariableDeclarations, NamespaceDeclaration} from '../tree';
import {Expression, J, JContainer, JLeftPadded, JRightPadded, NameTree, Space, Statement, TypeTree, TypedTree} from "../../java";
import * as Java from "../../java/tree";

Expand Down Expand Up @@ -300,6 +300,29 @@ class Visitor extends JavaScriptVisitor<ReceiverContext> {
return typeInfo;
}

public visitJSVariableDeclarations(jSVariableDeclarations: JSVariableDeclarations, ctx: ReceiverContext): J {
jSVariableDeclarations = jSVariableDeclarations.withId(ctx.receiveValue(jSVariableDeclarations.id, ValueType.UUID)!);
jSVariableDeclarations = jSVariableDeclarations.withPrefix(ctx.receiveNode(jSVariableDeclarations.prefix, receiveSpace)!);
jSVariableDeclarations = jSVariableDeclarations.withMarkers(ctx.receiveNode(jSVariableDeclarations.markers, ctx.receiveMarkers)!);
jSVariableDeclarations = jSVariableDeclarations.withLeadingAnnotations(ctx.receiveNodes(jSVariableDeclarations.leadingAnnotations, ctx.receiveTree)!);
jSVariableDeclarations = jSVariableDeclarations.withModifiers(ctx.receiveNodes(jSVariableDeclarations.modifiers, ctx.receiveTree)!);
jSVariableDeclarations = jSVariableDeclarations.withTypeExpression(ctx.receiveNode(jSVariableDeclarations.typeExpression, ctx.receiveTree));
jSVariableDeclarations = jSVariableDeclarations.withVarargs(ctx.receiveNode(jSVariableDeclarations.varargs, receiveSpace));
jSVariableDeclarations = jSVariableDeclarations.padding.withVariables(ctx.receiveNodes(jSVariableDeclarations.padding.variables, receiveRightPaddedTree)!);
return jSVariableDeclarations;
}

public visitJSVariableDeclarationsJSNamedVariable(jSNamedVariable: JSVariableDeclarations.JSNamedVariable, ctx: ReceiverContext): J {
jSNamedVariable = jSNamedVariable.withId(ctx.receiveValue(jSNamedVariable.id, ValueType.UUID)!);
jSNamedVariable = jSNamedVariable.withPrefix(ctx.receiveNode(jSNamedVariable.prefix, receiveSpace)!);
jSNamedVariable = jSNamedVariable.withMarkers(ctx.receiveNode(jSNamedVariable.markers, ctx.receiveMarkers)!);
jSNamedVariable = jSNamedVariable.withName(ctx.receiveNode(jSNamedVariable.name, ctx.receiveTree)!);
jSNamedVariable = jSNamedVariable.padding.withDimensionsAfterName(ctx.receiveNodes(jSNamedVariable.padding.dimensionsAfterName, leftPaddedNodeReceiver(Space))!);
jSNamedVariable = jSNamedVariable.padding.withInitializer(ctx.receiveNode(jSNamedVariable.padding.initializer, receiveLeftPaddedTree));
jSNamedVariable = jSNamedVariable.withVariableType(ctx.receiveValue(jSNamedVariable.variableType, ValueType.Object));
return jSNamedVariable;
}

public visitNamespaceDeclaration(namespaceDeclaration: NamespaceDeclaration, ctx: ReceiverContext): J {
namespaceDeclaration = namespaceDeclaration.withId(ctx.receiveValue(namespaceDeclaration.id, ValueType.UUID)!);
namespaceDeclaration = namespaceDeclaration.withPrefix(ctx.receiveNode(namespaceDeclaration.prefix, receiveSpace)!);
Expand Down Expand Up @@ -1281,6 +1304,31 @@ class Factory implements ReceiverFactory {
);
}

if (type === "org.openrewrite.javascript.tree.JS$JSVariableDeclarations") {
return new JSVariableDeclarations(
ctx.receiveValue(null, ValueType.UUID)!,
ctx.receiveNode(null, receiveSpace)!,
ctx.receiveNode(null, ctx.receiveMarkers)!,
ctx.receiveNodes<Java.Annotation>(null, ctx.receiveTree)!,
ctx.receiveNodes<Java.Modifier>(null, ctx.receiveTree)!,
ctx.receiveNode<TypeTree>(null, ctx.receiveTree),
ctx.receiveNode(null, receiveSpace),
ctx.receiveNodes(null, receiveRightPaddedTree)!
);
}

if (type === "org.openrewrite.javascript.tree.JS$JSVariableDeclarations$JSNamedVariable") {
return new JSVariableDeclarations.JSNamedVariable(
ctx.receiveValue(null, ValueType.UUID)!,
ctx.receiveNode(null, receiveSpace)!,
ctx.receiveNode(null, ctx.receiveMarkers)!,
ctx.receiveNode<Expression>(null, ctx.receiveTree)!,
ctx.receiveNodes(null, leftPaddedNodeReceiver(Space))!,
ctx.receiveNode<JLeftPadded<Expression>>(null, receiveLeftPaddedTree),
ctx.receiveValue(null, ValueType.Object)
);
}

if (type === "org.openrewrite.javascript.tree.JS$NamespaceDeclaration") {
return new NamespaceDeclaration(
ctx.receiveValue(null, ValueType.UUID)!,
Expand Down
25 changes: 24 additions & 1 deletion openrewrite/src/javascript/remote/sender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as extensions from "./remote_extensions";
import {Cursor, ListUtils, Tree} from '../../core';
import {Sender, SenderContext, ValueType} from '@openrewrite/rewrite-remote';
import {JavaScriptVisitor} from '..';
import {JS, JsLeftPadded, JsRightPadded, JsContainer, JsSpace, CompilationUnit, Alias, ArrowFunction, Await, DefaultType, Delete, Export, ExpressionStatement, FunctionType, JsImport, JsBinary, ObjectBindingDeclarations, PropertyAssignment, ScopedVariableDeclarations, StatementExpression, TemplateExpression, Tuple, TypeDeclaration, TypeOf, TypeOperator, Unary, Union, Void, Yield, TypeInfo, NamespaceDeclaration} from '../tree';
import {JS, JsLeftPadded, JsRightPadded, JsContainer, JsSpace, CompilationUnit, Alias, ArrowFunction, Await, DefaultType, Delete, Export, ExpressionStatement, FunctionType, JsImport, JsBinary, ObjectBindingDeclarations, PropertyAssignment, ScopedVariableDeclarations, StatementExpression, TemplateExpression, Tuple, TypeDeclaration, TypeOf, TypeOperator, Unary, Union, Void, Yield, TypeInfo, JSVariableDeclarations, NamespaceDeclaration} from '../tree';
import {Expression, J, JContainer, JLeftPadded, JRightPadded, Space, Statement} from "../../java";
import * as Java from "../../java/tree";

Expand Down Expand Up @@ -295,6 +295,29 @@ class Visitor extends JavaScriptVisitor<SenderContext> {
return typeInfo;
}

public visitJSVariableDeclarations(jSVariableDeclarations: JSVariableDeclarations, ctx: SenderContext): J {
ctx.sendValue(jSVariableDeclarations, v => v.id, ValueType.UUID);
ctx.sendNode(jSVariableDeclarations, v => v.prefix, Visitor.sendSpace);
ctx.sendNode(jSVariableDeclarations, v => v.markers, ctx.sendMarkers);
ctx.sendNodes(jSVariableDeclarations, v => v.leadingAnnotations, ctx.sendTree, t => t.id);
ctx.sendNodes(jSVariableDeclarations, v => v.modifiers, ctx.sendTree, t => t.id);
ctx.sendNode(jSVariableDeclarations, v => v.typeExpression, ctx.sendTree);
ctx.sendNode(jSVariableDeclarations, v => v.varargs, Visitor.sendSpace);
ctx.sendNodes(jSVariableDeclarations, v => v.padding.variables, Visitor.sendRightPadded(ValueType.Tree), t => t.element.id);
return jSVariableDeclarations;
}

public visitJSVariableDeclarationsJSNamedVariable(jSNamedVariable: JSVariableDeclarations.JSNamedVariable, ctx: SenderContext): J {
ctx.sendValue(jSNamedVariable, v => v.id, ValueType.UUID);
ctx.sendNode(jSNamedVariable, v => v.prefix, Visitor.sendSpace);
ctx.sendNode(jSNamedVariable, v => v.markers, ctx.sendMarkers);
ctx.sendNode(jSNamedVariable, v => v.name, ctx.sendTree);
ctx.sendNodes(jSNamedVariable, v => v.padding.dimensionsAfterName, Visitor.sendLeftPadded(ValueType.Object), t => t);
ctx.sendNode(jSNamedVariable, v => v.padding.initializer, Visitor.sendLeftPadded(ValueType.Tree));
ctx.sendTypedValue(jSNamedVariable, v => v.variableType, ValueType.Object);
return jSNamedVariable;
}

public visitNamespaceDeclaration(namespaceDeclaration: NamespaceDeclaration, ctx: SenderContext): J {
ctx.sendValue(namespaceDeclaration, v => v.id, ValueType.UUID);
ctx.sendNode(namespaceDeclaration, v => v.prefix, Visitor.sendSpace);
Expand Down
8 changes: 7 additions & 1 deletion openrewrite/src/javascript/tree/support_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,11 @@ export namespace JsSpace {
VOID_PREFIX,
YIELD_PREFIX,
TYPE_INFO_PREFIX,
JSVARIABLE_DECLARATIONS_PREFIX,
JSVARIABLE_DECLARATIONS_VARARGS,
JSVARIABLE_DECLARATIONS_JSNAMED_VARIABLE_PREFIX,
NAMESPACE_DECLARATION_PREFIX,
NAMESPACE_KEYWORD_DECLARATION_PREFIX
NAMESPACE_DECLARATION_NAMESPACE
}
}
export namespace JsLeftPadded {
Expand All @@ -229,6 +232,8 @@ export namespace JsLeftPadded {
TYPE_DECLARATION_INITIALIZER,
TYPE_OPERATOR_EXPRESSION,
UNARY_OPERATOR,
JSVARIABLE_DECLARATIONS_JSNAMED_VARIABLE_INITIALIZER,
JSVARIABLE_DECLARATIONS_JSNAMED_VARIABLE_DIMENSIONS_AFTER_NAME,
}
}
export namespace JsRightPadded {
Expand All @@ -241,6 +246,7 @@ export namespace JsRightPadded {
SCOPED_VARIABLE_DECLARATIONS_VARIABLES,
TEMPLATE_EXPRESSION_TAG,
UNION_TYPES,
JSVARIABLE_DECLARATIONS_VARIABLES,
NAMESPACE_DECLARATION_NAME,
}
}
Expand Down
Loading

0 comments on commit 82bdbeb

Please sign in to comment.