/* * Copyright 2025 the original author or authors. *

* Licensed under the Moderne Source Available License (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* https://docs.moderne.io/licensing/moderne-source-available-license *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import {JavaScriptVisitor} from "./visitor"; import {asRef, registerVisitor, RpcReceiveQueue, RpcSendQueue} from "../rpc"; import {AutoformatVisitor} from "./format"; import {isJavaScript, JS, JSX} from "./tree"; import {Expression, J, Statement, Type, TypedTree, TypeTree} from "../java"; import {JavaReceiver, JavaSender, registerJLanguageCodecs} from "../java/rpc"; import {Cursor, Tree} from "../tree"; import {updateIfChanged} from "../util"; import ComputedPropertyName = JS.ComputedPropertyName; class JavaScriptSender extends JavaScriptVisitor { private delegate: JavaScriptDelegateSender; constructor() { super(); this.delegate = new JavaScriptDelegateSender(this); } override async visit(tree: Tree, p: RpcSendQueue, parent?: Cursor): Promise { if (isJavaScript(tree)) { return super.visit(tree, p, parent); } return this.delegate.visit(tree, p, parent); } override async preVisit(j: JS, q: RpcSendQueue): Promise { await q.getAndSend(j, j2 => j2.id); await q.getAndSend(j, j2 => j2.prefix, space => this.visitSpace(space, q)); await q.getAndSend(j, j2 => j2.markers); return j; } override async visitJsCompilationUnit(cu: JS.CompilationUnit, q: RpcSendQueue): Promise { await q.getAndSend(cu, c => c.sourcePath); await q.getAndSend(cu, c => c.charsetName); await q.getAndSend(cu, c => c.charsetBomMarked); await q.getAndSend(cu, c => c.checksum); await q.getAndSend(cu, c => c.fileAttributes); await q.getAndSendList(cu, c => c.statements, stmt => stmt.element.id, stmt => this.visitRightPadded(stmt, q)); await q.getAndSend(cu, c => c.eof, space => this.visitSpace(space, q)); return cu; } override async visitAlias(alias: JS.Alias, q: RpcSendQueue): Promise { await q.getAndSend(alias, el => el.propertyName, el => this.visitRightPadded(el, q)); await q.getAndSend(alias, el => el.alias, el => this.visit(el, q)); return alias; } override async visitArrowFunction(arrowFunction: JS.ArrowFunction, q: RpcSendQueue): Promise { await q.getAndSendList(arrowFunction, el => el.leadingAnnotations, el => el.id, el => this.visit(el, q)); await q.getAndSendList(arrowFunction, el => el.modifiers, el => el.id, el => this.visit(el, q)); await q.getAndSend(arrowFunction, el => el.typeParameters, el => this.visit(el, q)); await q.getAndSend(arrowFunction, el => el.lambda, el => this.visit(el, q)); await q.getAndSend(arrowFunction, el => el.returnTypeExpression, el => this.visit(el, q)); return arrowFunction; } override async visitAwait(await_: JS.Await, q: RpcSendQueue): Promise { await q.getAndSend(await_, el => el.expression, el => this.visit(el, q)); await q.getAndSend(await_, el => asRef(el.type), el => this.visitType(el, q)); return await_; } override async visitConditionalType(conditionalType: JS.ConditionalType, q: RpcSendQueue): Promise { await q.getAndSend(conditionalType, el => el.checkType, el => this.visit(el, q)); await q.getAndSend(conditionalType, el => el.condition, el => this.visitLeftPadded(el, q)); await q.getAndSend(conditionalType, el => asRef(el.type), el => this.visitType(el, q)); return conditionalType; } override async visitDelete(delete_: JS.Delete, q: RpcSendQueue): Promise { await q.getAndSend(delete_, el => el.expression, el => this.visit(el, q)); return delete_; } override async visitExpressionStatement(expressionStatement: JS.ExpressionStatement, q: RpcSendQueue): Promise { await q.getAndSend(expressionStatement, el => el.expression, el => this.visit(el, q)); return expressionStatement; } override async visitExpressionWithTypeArguments(expressionWithTypeArguments: JS.ExpressionWithTypeArguments, q: RpcSendQueue): Promise { await q.getAndSend(expressionWithTypeArguments, el => el.clazz, el => this.visit(el, q)); await q.getAndSend(expressionWithTypeArguments, el => el.typeArguments, el => this.visitContainer(el, q)); await q.getAndSend(expressionWithTypeArguments, el => asRef(el.type), el => this.visitType(el, q)); return expressionWithTypeArguments; } override async visitFunctionCall(functionCall: JS.FunctionCall, q: RpcSendQueue): Promise { await q.getAndSend(functionCall, m => m.function, f => this.visitRightPadded(f, q)); await q.getAndSend(functionCall, m => m.typeParameters, params => this.visitContainer(params, q)); await q.getAndSend(functionCall, m => m.arguments, args => this.visitContainer(args, q)); await q.getAndSend(functionCall, m => asRef(m.methodType), type => this.visitType(type, q)); return functionCall; } override async visitFunctionType(functionType: JS.FunctionType, q: RpcSendQueue): Promise { await q.getAndSendList(functionType, el => el.modifiers, el => el.id, el => this.visit(el, q)); await q.getAndSend(functionType, el => el.constructorType, el => this.visitLeftPadded(el, q)); await q.getAndSend(functionType, el => el.typeParameters, el => this.visit(el, q)); await q.getAndSend(functionType, el => el.parameters, el => this.visitContainer(el, q)); await q.getAndSend(functionType, el => el.returnType, el => this.visitLeftPadded(el, q)); return functionType; } override async visitInferType(inferType: JS.InferType, q: RpcSendQueue): Promise { await q.getAndSend(inferType, el => el.typeParameter, el => this.visitLeftPadded(el, q)); await q.getAndSend(inferType, el => asRef(el.type), el => this.visitType(el, q)); return inferType; } override async visitImportType(importType: JS.ImportType, q: RpcSendQueue): Promise { await q.getAndSend(importType, el => el.hasTypeof, el => this.visitRightPadded(el, q)); await q.getAndSend(importType, el => el.argumentAndAttributes, el => this.visitContainer(el, q)); await q.getAndSend(importType, el => el.qualifier, el => this.visitLeftPadded(el, q)); await q.getAndSend(importType, el => el.typeArguments, el => this.visitContainer(el, q)); await q.getAndSend(importType, el => asRef(el.type), el => this.visitType(el, q)); return importType; } override async visitImportDeclaration(jsImport: JS.Import, q: RpcSendQueue): Promise { await q.getAndSendList(jsImport, el => el.modifiers, el => el.id, el => this.visit(el, q)); await q.getAndSend(jsImport, el => el.importClause, el => this.visit(el, q)); await q.getAndSend(jsImport, el => el.moduleSpecifier, el => this.visitLeftPadded(el, q)); await q.getAndSend(jsImport, el => el.attributes, el => this.visit(el, q)); await q.getAndSend(jsImport, el => el.initializer, el => this.visitLeftPadded(el, q)); return jsImport; } override async visitImportClause(jsImportClause: JS.ImportClause, q: RpcSendQueue): Promise { await q.getAndSend(jsImportClause, el => el.typeOnly); await q.getAndSend(jsImportClause, el => el.name, el => this.visitRightPadded(el, q)); await q.getAndSend(jsImportClause, el => el.namedBindings, el => this.visit(el, q)); return jsImportClause; } override async visitNamedImports(namedImports: JS.NamedImports, q: RpcSendQueue): Promise { await q.getAndSend(namedImports, el => el.elements, el => this.visitContainer(el, q)); await q.getAndSend(namedImports, el => asRef(el.type), el => this.visitType(el, q)); return namedImports; } override async visitImportSpecifier(jsImportSpecifier: JS.ImportSpecifier, q: RpcSendQueue): Promise { await q.getAndSend(jsImportSpecifier, el => el.importType, el => this.visitLeftPadded(el, q)); await q.getAndSend(jsImportSpecifier, el => el.specifier, el => this.visit(el, q)); await q.getAndSend(jsImportSpecifier, el => asRef(el.type), el => this.visitType(el, q)); return jsImportSpecifier; } override async visitImportAttributes(importAttributes: JS.ImportAttributes, q: RpcSendQueue): Promise { await q.getAndSend(importAttributes, el => el.token); await q.getAndSend(importAttributes, el => el.elements, el => this.visitContainer(el, q)); return importAttributes; } override async visitImportTypeAttributes(importTypeAttributes: JS.ImportTypeAttributes, q: RpcSendQueue): Promise { await q.getAndSend(importTypeAttributes, el => el.token, el => this.visitRightPadded(el, q)); await q.getAndSend(importTypeAttributes, el => el.elements, el => this.visitContainer(el, q)); await q.getAndSend(importTypeAttributes, el => el.end, el => this.visitSpace(el, q)); return importTypeAttributes; } override async visitImportAttribute(importAttribute: JS.ImportAttribute, q: RpcSendQueue): Promise { await q.getAndSend(importAttribute, el => el.name, el => this.visit(el, q)); await q.getAndSend(importAttribute, el => el.value, el => this.visitLeftPadded(el, q)); return importAttribute; } override async visitBinaryExtensions(binary: JS.Binary, q: RpcSendQueue): Promise { await q.getAndSend(binary, el => el.left, el => this.visit(el, q)); await q.getAndSend(binary, el => el.operator, el => this.visitLeftPadded(el, q)); await q.getAndSend(binary, el => el.right, el => this.visit(el, q)); await q.getAndSend(binary, el => asRef(el.type), el => this.visitType(el, q)); return binary; } override async visitLiteralType(literalType: JS.LiteralType, q: RpcSendQueue): Promise { await q.getAndSend(literalType, el => el.literal, el => this.visit(el, q)); await q.getAndSend(literalType, el => asRef(el.type), el => this.visitType(el, q)); return literalType; } override async visitMappedType(mappedType: JS.MappedType, q: RpcSendQueue): Promise { await q.getAndSend(mappedType, el => el.prefixToken, el => this.visitLeftPadded(el, q)); await q.getAndSend(mappedType, el => el.hasReadonly, el => this.visitLeftPadded(el, q)); await q.getAndSend(mappedType, el => el.keysRemapping, el => this.visit(el, q)); await q.getAndSend(mappedType, el => el.suffixToken, el => this.visitLeftPadded(el, q)); await q.getAndSend(mappedType, el => el.hasQuestionToken, el => this.visitLeftPadded(el, q)); await q.getAndSend(mappedType, el => el.valueType, el => this.visitContainer(el, q)); await q.getAndSend(mappedType, el => asRef(el.type), el => this.visitType(el, q)); return mappedType; } override async visitMappedTypeKeysRemapping(keysRemapping: JS.MappedType.KeysRemapping, q: RpcSendQueue): Promise { await q.getAndSend(keysRemapping, el => el.typeParameter, el => this.visitRightPadded(el, q)); await q.getAndSend(keysRemapping, el => el.nameType, el => this.visitRightPadded(el, q)); return keysRemapping; } override async visitMappedTypeParameter(mappedTypeParameter: JS.MappedType.Parameter, q: RpcSendQueue): Promise { await q.getAndSend(mappedTypeParameter, el => el.name, el => this.visit(el, q)); await q.getAndSend(mappedTypeParameter, el => el.iterateType, el => this.visitLeftPadded(el, q)); return mappedTypeParameter; } override async visitObjectBindingPattern(objectBindingPattern: JS.ObjectBindingPattern, q: RpcSendQueue): Promise { await q.getAndSendList(objectBindingPattern, el => el.leadingAnnotations, el => el.id, el => this.visit(el, q)); await q.getAndSendList(objectBindingPattern, el => el.modifiers, el => el.id, el => this.visit(el, q)); await q.getAndSend(objectBindingPattern, el => el.typeExpression, el => this.visit(el, q)); await q.getAndSend(objectBindingPattern, el => el.bindings, el => this.visitContainer(el, q)); await q.getAndSend(objectBindingPattern, el => el.initializer, el => this.visitLeftPadded(el, q)); return objectBindingPattern; } override async visitPropertyAssignment(propertyAssignment: JS.PropertyAssignment, q: RpcSendQueue): Promise { await q.getAndSend(propertyAssignment, el => el.name, el => this.visitRightPadded(el, q)); await q.getAndSend(propertyAssignment, el => el.assigmentToken); await q.getAndSend(propertyAssignment, el => el.initializer, el => this.visit(el, q)); return propertyAssignment; } override async visitSatisfiesExpression(satisfiesExpression: JS.SatisfiesExpression, q: RpcSendQueue): Promise { await q.getAndSend(satisfiesExpression, el => el.expression, el => this.visit(el, q)); await q.getAndSend(satisfiesExpression, el => el.satisfiesType, el => this.visitLeftPadded(el, q)); await q.getAndSend(satisfiesExpression, el => asRef(el.type), el => this.visitType(el, q)); return satisfiesExpression; } override async visitScopedVariableDeclarations(scopedVariableDeclarations: JS.ScopedVariableDeclarations, q: RpcSendQueue): Promise { await q.getAndSendList(scopedVariableDeclarations, el => el.modifiers, el => el.id, el => this.visit(el, q)); await q.getAndSendList(scopedVariableDeclarations, el => el.variables, el => el.element.id, el => this.visitRightPadded(el, q)); return scopedVariableDeclarations; } override async visitShebang(shebang: JS.Shebang, q: RpcSendQueue): Promise { await q.getAndSend(shebang, el => el.text); return shebang; } override async visitSpread(spread: JS.Spread, q: RpcSendQueue): Promise { await q.getAndSend(spread, el => el.expression, el => this.visit(el, q)); await q.getAndSend(spread, el => asRef(el.type), el => this.visitType(el, q)); return spread; } override async visitStatementExpression(statementExpression: JS.StatementExpression, q: RpcSendQueue): Promise { await q.getAndSend(statementExpression, el => el.statement, el => this.visit(el, q)); return statementExpression; } override async visitTaggedTemplateExpression(taggedTemplateExpression: JS.TaggedTemplateExpression, q: RpcSendQueue): Promise { await q.getAndSend(taggedTemplateExpression, el => el.tag, el => this.visitRightPadded(el, q)); await q.getAndSend(taggedTemplateExpression, el => el.typeArguments, el => this.visitContainer(el, q)); await q.getAndSend(taggedTemplateExpression, el => el.templateExpression, el => this.visit(el, q)); await q.getAndSend(taggedTemplateExpression, el => asRef(el.type), el => this.visitType(el, q)); return taggedTemplateExpression; } override async visitTemplateExpression(templateExpression: JS.TemplateExpression, q: RpcSendQueue): Promise { await q.getAndSend(templateExpression, el => el.head, el => this.visit(el, q)); await q.getAndSendList(templateExpression, el => el.spans, el => el.element.id, el => this.visitRightPadded(el, q)); await q.getAndSend(templateExpression, el => asRef(el.type), el => this.visitType(el, q)); return templateExpression; } override async visitTemplateExpressionSpan(span: JS.TemplateExpression.Span, q: RpcSendQueue): Promise { await q.getAndSend(span, el => el.expression, el => this.visit(el, q)); await q.getAndSend(span, el => el.tail, el => this.visit(el, q)); return span; } override async visitTuple(tuple: JS.Tuple, q: RpcSendQueue): Promise { await q.getAndSend(tuple, el => el.elements, el => this.visitContainer(el, q)); await q.getAndSend(tuple, el => asRef(el.type), el => this.visitType(el, q)); return tuple; } override async visitTypeDeclaration(typeDeclaration: JS.TypeDeclaration, q: RpcSendQueue): Promise { await q.getAndSendList(typeDeclaration, el => el.modifiers, el => el.id, el => this.visit(el, q)); await q.getAndSend(typeDeclaration, el => el.name, el => this.visitLeftPadded(el, q)); await q.getAndSend(typeDeclaration, el => el.typeParameters, el => this.visit(el, q)); await q.getAndSend(typeDeclaration, el => el.initializer, el => this.visitLeftPadded(el, q)); await q.getAndSend(typeDeclaration, el => asRef(el.type), el => this.visitType(el, q)); return typeDeclaration; } override async visitTypeOf(typeOf: JS.TypeOf, q: RpcSendQueue): Promise { await q.getAndSend(typeOf, el => el.expression, el => this.visit(el, q)); await q.getAndSend(typeOf, el => asRef(el.type), el => this.visitType(el, q)); return typeOf; } override async visitTypeTreeExpression(typeTreeExpression: JS.TypeTreeExpression, q: RpcSendQueue): Promise { await q.getAndSend(typeTreeExpression, el => el.expression, el => this.visit(el, q)); return typeTreeExpression; } override async visitAs(as_: JS.As, q: RpcSendQueue): Promise { await q.getAndSend(as_, el => el.left, el => this.visitRightPadded(el, q)); await q.getAndSend(as_, el => el.right, el => this.visit(el, q)); await q.getAndSend(as_, el => asRef(el.type), el => this.visitType(el, q)); return as_; } override async visitAssignmentOperationExtensions(assignmentOperation: JS.AssignmentOperation, q: RpcSendQueue): Promise { await q.getAndSend(assignmentOperation, el => el.variable, el => this.visit(el, q)); await q.getAndSend(assignmentOperation, el => el.operator, el => this.visitLeftPadded(el, q)); await q.getAndSend(assignmentOperation, el => el.assignment, el => this.visit(el, q)); await q.getAndSend(assignmentOperation, el => asRef(el.type), el => this.visitType(el, q)); return assignmentOperation; } override async visitIndexedAccessType(indexedAccessType: JS.IndexedAccessType, q: RpcSendQueue): Promise { await q.getAndSend(indexedAccessType, el => el.objectType, el => this.visit(el, q)); await q.getAndSend(indexedAccessType, el => el.indexType, el => this.visit(el, q)); await q.getAndSend(indexedAccessType, el => asRef(el.type), el => this.visitType(el, q)); return indexedAccessType; } override async visitIndexedAccessTypeIndexType(indexType: JS.IndexedAccessType.IndexType, q: RpcSendQueue): Promise { await q.getAndSend(indexType, el => el.element, el => this.visitRightPadded(el, q)); await q.getAndSend(indexType, el => asRef(el.type), el => this.visitType(el, q)); return indexType; } override async visitTypeQuery(typeQuery: JS.TypeQuery, q: RpcSendQueue): Promise { await q.getAndSend(typeQuery, el => el.typeExpression, el => this.visit(el, q)); await q.getAndSend(typeQuery, el => el.typeArguments, el => this.visitContainer(el, q)); await q.getAndSend(typeQuery, el => asRef(el.type), el => this.visitType(el, q)); return typeQuery; } override async visitTypeInfo(typeInfo: JS.TypeInfo, q: RpcSendQueue): Promise { await q.getAndSend(typeInfo, el => el.typeIdentifier, el => this.visit(el, q)); return typeInfo; } override async visitComputedPropertyName(computedPropertyName: JS.ComputedPropertyName, q: RpcSendQueue): Promise { await q.getAndSend(computedPropertyName, el => el.expression, el => this.visitRightPadded(el, q)); return computedPropertyName; } override async visitTypeOperator(typeOperator: JS.TypeOperator, q: RpcSendQueue): Promise { await q.getAndSend(typeOperator, el => el.operator); await q.getAndSend(typeOperator, el => el.expression, el => this.visitLeftPadded(el, q)); return typeOperator; } override async visitTypePredicate(typePredicate: JS.TypePredicate, q: RpcSendQueue): Promise { await q.getAndSend(typePredicate, el => el.asserts, el => this.visitLeftPadded(el, q)); await q.getAndSend(typePredicate, el => el.parameterName, el => this.visit(el, q)); await q.getAndSend(typePredicate, el => el.expression, el => this.visitLeftPadded(el, q)); await q.getAndSend(typePredicate, el => asRef(el.type), el => this.visitType(el, q)); return typePredicate; } override async visitUnion(union: JS.Union, q: RpcSendQueue): Promise { await q.getAndSendList(union, el => el.types, el => el.element.id, el => this.visitRightPadded(el, q)); await q.getAndSend(union, el => asRef(el.type), el => this.visitType(el, q)); return union; } override async visitIntersection(intersection: JS.Intersection, q: RpcSendQueue): Promise { await q.getAndSendList(intersection, el => el.types, el => el.element.id, el => this.visitRightPadded(el, q)); await q.getAndSend(intersection, el => asRef(el.type), el => this.visitType(el, q)); return intersection; } override async visitVoid(void_: JS.Void, q: RpcSendQueue): Promise { await q.getAndSend(void_, el => el.expression, el => this.visit(el, q)); return void_; } override async visitWithStatement(withStatement: JS.WithStatement, q: RpcSendQueue): Promise { await q.getAndSend(withStatement, el => el.expression, el => this.visit(el, q)); await q.getAndSend(withStatement, el => el.body, el => this.visitRightPadded(el, q)); return withStatement; } override async visitJsxTag(tag: JSX.Tag, q: RpcSendQueue): Promise { await q.getAndSend(tag, el => el.openName, el => this.visitLeftPadded(el, q)); await q.getAndSend(tag, el => el.typeArguments, el => this.visitContainer(el, q)); await q.getAndSend(tag, el => el.afterName, space => this.visitSpace(space, q)); await q.getAndSendList(tag, el => el.attributes, attr => attr.element.id, attr => this.visitRightPadded(attr, q)); await q.getAndSend(tag, el => el.selfClosing, space => this.visitSpace(space, q)); await q.getAndSendList(tag, el => el.children!, child => child.id, child => this.visit(child, q)); await q.getAndSend(tag, el => el.closingName, el => this.visitLeftPadded(el, q)); await q.getAndSend(tag, el => el.afterClosingName, el => this.visitSpace(el, q)); return tag; } override async visitJsxAttribute(attribute: JSX.Attribute, q: RpcSendQueue): Promise { await q.getAndSend(attribute, el => el.key, el => this.visit(el, q)); await q.getAndSend(attribute, el => el.value, el => this.visitLeftPadded(el, q)); return attribute; } override async visitJsxSpreadAttribute(spreadAttribute: JSX.SpreadAttribute, q: RpcSendQueue): Promise { await q.getAndSend(spreadAttribute, el => el.dots, space => this.visitSpace(space, q)); await q.getAndSend(spreadAttribute, el => el.expression, el => this.visitRightPadded(el, q)); return spreadAttribute; } override async visitJsxEmbeddedExpression(embeddedExpression: JSX.EmbeddedExpression, q: RpcSendQueue): Promise { await q.getAndSend(embeddedExpression, el => el.expression, el => this.visitRightPadded(el, q)); return embeddedExpression; } override async visitJsxNamespacedName(namespacedName: JSX.NamespacedName, q: RpcSendQueue): Promise { await q.getAndSend(namespacedName, el => el.namespace, el => this.visit(el, q)); await q.getAndSend(namespacedName, el => el.name, el => this.visitLeftPadded(el, q)); return namespacedName; } override async visitIndexSignatureDeclaration(indexSignatureDeclaration: JS.IndexSignatureDeclaration, q: RpcSendQueue): Promise { await q.getAndSendList(indexSignatureDeclaration, el => el.modifiers, el => el.id, el => this.visit(el, q)); await q.getAndSend(indexSignatureDeclaration, el => el.parameters, el => this.visitContainer(el, q)); await q.getAndSend(indexSignatureDeclaration, el => el.typeExpression, el => this.visitLeftPadded(el, q)); await q.getAndSend(indexSignatureDeclaration, el => asRef(el.type), el => this.visitType(el, q)); return indexSignatureDeclaration; } override async visitComputedPropertyMethodDeclaration(computedPropMethod: JS.ComputedPropertyMethodDeclaration, q: RpcSendQueue): Promise { await q.getAndSendList(computedPropMethod, el => el.leadingAnnotations, el => el.id, el => this.visit(el, q)); await q.getAndSendList(computedPropMethod, el => el.modifiers, el => el.id, el => this.visit(el, q)); await q.getAndSend(computedPropMethod, el => el.typeParameters, el => this.visit(el, q)); await q.getAndSend(computedPropMethod, el => el.returnTypeExpression, el => this.visit(el, q)); await q.getAndSend(computedPropMethod, el => el.name, el => this.visit(el, q)); await q.getAndSend(computedPropMethod, el => el.parameters, el => this.visitContainer(el, q)); await q.getAndSend(computedPropMethod, el => el.body, el => this.visit(el, q)); await q.getAndSend(computedPropMethod, el => el.methodType, el => this.visitType(el, q)); return computedPropMethod; } override async visitForOfLoop(forOfLoop: JS.ForOfLoop, q: RpcSendQueue): Promise { await q.getAndSend(forOfLoop, el => el.await, space => this.visitSpace(space, q)); await q.getAndSend(forOfLoop, el => el.loop, el => this.visit(el, q)); return forOfLoop; } override async visitForInLoop(forInLoop: JS.ForInLoop, q: RpcSendQueue): Promise { await q.getAndSend(forInLoop, el => el.control, el => this.visit(el, q)); await q.getAndSend(forInLoop, el => el.body, el => this.visitRightPadded(el, q)); return forInLoop; } override async visitNamespaceDeclaration(namespaceDeclaration: JS.NamespaceDeclaration, q: RpcSendQueue): Promise { await q.getAndSendList(namespaceDeclaration, el => el.modifiers, el => el.id, el => this.visit(el, q)); await q.getAndSend(namespaceDeclaration, el => el.keywordType, el => this.visitLeftPadded(el, q)); await q.getAndSend(namespaceDeclaration, el => el.name, el => this.visitRightPadded(el, q)); await q.getAndSend(namespaceDeclaration, el => el.body, el => this.visit(el, q)); return namespaceDeclaration; } override async visitTypeLiteral(typeLiteral: JS.TypeLiteral, q: RpcSendQueue): Promise { await q.getAndSend(typeLiteral, el => el.members, el => this.visit(el, q)); await q.getAndSend(typeLiteral, el => asRef(el.type), el => this.visitType(el, q)); return typeLiteral; } override async visitArrayBindingPattern(arrayBindingPattern: JS.ArrayBindingPattern, q: RpcSendQueue): Promise { await q.getAndSend(arrayBindingPattern, el => el.elements, el => this.visitContainer(el, q)); await q.getAndSend(arrayBindingPattern, el => asRef(el.type), el => this.visitType(el, q)); return arrayBindingPattern; } override async visitBindingElement(bindingElement: JS.BindingElement, q: RpcSendQueue): Promise { await q.getAndSend(bindingElement, el => el.propertyName, el => this.visitRightPadded(el, q)); await q.getAndSend(bindingElement, el => el.name, el => this.visit(el, q)); await q.getAndSend(bindingElement, el => el.initializer, el => this.visitLeftPadded(el, q)); await q.getAndSend(bindingElement, el => el.variableType, el => this.visitType(el, q)); return bindingElement; } override async visitExportDeclaration(exportDeclaration: JS.ExportDeclaration, q: RpcSendQueue): Promise { await q.getAndSendList(exportDeclaration, el => el.modifiers, el => el.id, el => this.visit(el, q)); await q.getAndSend(exportDeclaration, el => el.typeOnly, el => this.visitLeftPadded(el, q)); await q.getAndSend(exportDeclaration, el => el.exportClause, el => this.visit(el, q)); await q.getAndSend(exportDeclaration, el => el.moduleSpecifier, el => this.visitLeftPadded(el, q)); await q.getAndSend(exportDeclaration, el => el.attributes, el => this.visit(el, q)); return exportDeclaration; } override async visitExportAssignment(exportAssignment: JS.ExportAssignment, q: RpcSendQueue): Promise { await q.getAndSend(exportAssignment, el => el.exportEquals); await q.getAndSend(exportAssignment, el => el.expression, el => this.visitLeftPadded(el, q)); return exportAssignment; } override async visitNamedExports(namedExports: JS.NamedExports, q: RpcSendQueue): Promise { await q.getAndSend(namedExports, el => el.elements, el => this.visitContainer(el, q)); await q.getAndSend(namedExports, el => asRef(el.type), el => this.visitType(el, q)); return namedExports; } override async visitExportSpecifier(exportSpecifier: JS.ExportSpecifier, q: RpcSendQueue): Promise { await q.getAndSend(exportSpecifier, el => el.typeOnly, el => this.visitLeftPadded(el, q)); await q.getAndSend(exportSpecifier, el => el.specifier, el => this.visit(el, q)); await q.getAndSend(exportSpecifier, el => asRef(el.type), el => this.visitType(el, q)); return exportSpecifier; } override async visitRightPadded(right: J.RightPadded, q: RpcSendQueue): Promise> { return this.delegate.visitRightPadded(right, q); } override async visitLeftPadded(left: J.LeftPadded, q: RpcSendQueue): Promise> { return this.delegate.visitLeftPadded(left, q); } override async visitContainer(container: J.Container, q: RpcSendQueue): Promise> { return this.delegate.visitContainer(container, q); } override async visitSpace(space: J.Space, q: RpcSendQueue): Promise { return this.delegate.visitSpace(space, q); } override async visitType(javaType: Type | undefined, q: RpcSendQueue): Promise { return this.delegate.visitType(javaType, q); } } class JavaScriptDelegateSender extends JavaSender { private javascriptSender: JavaScriptSender; constructor(javascriptSender: JavaScriptSender) { super(); this.javascriptSender = javascriptSender; } async visit(tree: Tree, p: RpcSendQueue, parent?: Cursor): Promise { // Delegate to JavaScript sender if this is a JavaScript element if (isJavaScript(tree)) { return this.javascriptSender.visit(tree, p, parent); } // Otherwise handle as a Java element return super.visit(tree, p, parent); } } class JavaScriptReceiver extends JavaScriptVisitor { private delegate: JavaReceiver; constructor() { super(); this.delegate = new JavaScriptDelegateReceiver(this); } async visit(tree: Tree, p: RpcReceiveQueue, parent?: Cursor): Promise { if (isJavaScript(tree)) { return super.visit(tree, p, parent); } return this.delegate.visit(tree, p, parent); } override async preVisit(j: JS, q: RpcReceiveQueue): Promise { const updates = { id: await q.receive(j.id), prefix: await q.receive(j.prefix, space => this.visitSpace(space, q)), markers: await q.receive(j.markers) }; return updateIfChanged(j, updates); } override async visitJsCompilationUnit(cu: JS.CompilationUnit, q: RpcReceiveQueue): Promise { const updates = { sourcePath: await q.receive(cu.sourcePath), charsetName: await q.receive(cu.charsetName), charsetBomMarked: await q.receive(cu.charsetBomMarked), checksum: await q.receive(cu.checksum), fileAttributes: await q.receive(cu.fileAttributes), statements: await q.receiveListDefined(cu.statements, stmt => this.visitRightPadded(stmt, q)), eof: await q.receive(cu.eof, space => this.visitSpace(space, q)) }; return updateIfChanged(cu, updates); } override async visitAlias(alias: JS.Alias, q: RpcReceiveQueue): Promise { const updates = { propertyName: await q.receive(alias.propertyName, el => this.visitRightPadded(el, q)), alias: await q.receive(alias.alias, el => this.visitDefined(el, q)) }; return updateIfChanged(alias, updates); } override async visitArrowFunction(arrowFunction: JS.ArrowFunction, q: RpcReceiveQueue): Promise { const updates = { leadingAnnotations: await q.receiveListDefined(arrowFunction.leadingAnnotations, el => this.visitDefined(el, q)), modifiers: await q.receiveListDefined(arrowFunction.modifiers, el => this.visitDefined(el, q)), typeParameters: await q.receive(arrowFunction.typeParameters, el => this.visitDefined(el, q)), lambda: await q.receive(arrowFunction.lambda, el => this.visitDefined(el, q)), returnTypeExpression: await q.receive(arrowFunction.returnTypeExpression, el => this.visitDefined(el, q)) }; return updateIfChanged(arrowFunction, updates); } override async visitAwait(anAwait: JS.Await, q: RpcReceiveQueue): Promise { const updates = { expression: await q.receive(anAwait.expression, el => this.visitDefined(el, q)), type: await q.receive(anAwait.type, el => this.visitType(el, q)) }; return updateIfChanged(anAwait, updates); } override async visitConditionalType(conditionalType: JS.ConditionalType, q: RpcReceiveQueue): Promise { const updates = { checkType: await q.receive(conditionalType.checkType, el => this.visitDefined(el, q)), condition: await q.receive(conditionalType.condition, el => this.visitLeftPadded(el, q)), type: await q.receive(conditionalType.type, el => this.visitType(el, q)) }; return updateIfChanged(conditionalType, updates); } override async visitDelete(delete_: JS.Delete, q: RpcReceiveQueue): Promise { const updates = { expression: await q.receive(delete_.expression, el => this.visitDefined(el, q)) }; return updateIfChanged(delete_, updates); } override async visitExpressionStatement(expressionStatement: JS.ExpressionStatement, q: RpcReceiveQueue): Promise { const updates = { expression: await q.receive(expressionStatement.expression, el => this.visitDefined(el, q)) }; return updateIfChanged(expressionStatement, updates); } override async visitExpressionWithTypeArguments(expressionWithTypeArguments: JS.ExpressionWithTypeArguments, q: RpcReceiveQueue): Promise { const updates = { clazz: await q.receive(expressionWithTypeArguments.clazz, el => this.visitDefined(el, q)), typeArguments: await q.receive(expressionWithTypeArguments.typeArguments, el => this.visitContainer(el, q)), type: await q.receive(expressionWithTypeArguments.type, el => this.visitType(el, q)) }; return updateIfChanged(expressionWithTypeArguments, updates); } override async visitFunctionCall(functionCall: JS.FunctionCall, q: RpcReceiveQueue): Promise { const updates = { function: await q.receive(functionCall.function, select => this.visitRightPadded(select, q)), typeParameters: await q.receive(functionCall.typeParameters, typeParams => this.visitContainer(typeParams, q)), arguments: await q.receive(functionCall.arguments, args => this.visitContainer(args, q)), methodType: await q.receive(functionCall.methodType, type => this.visitType(type, q) as unknown as Type.Method) }; return updateIfChanged(functionCall, updates); } override async visitFunctionType(functionType: JS.FunctionType, q: RpcReceiveQueue): Promise { const updates = { modifiers: await q.receiveListDefined(functionType.modifiers, el => this.visitDefined(el, q)), constructorType: await q.receive(functionType.constructorType, el => this.visitLeftPadded(el, q)), typeParameters: await q.receive(functionType.typeParameters, el => this.visitDefined(el, q)), parameters: await q.receive(functionType.parameters, el => this.visitContainer(el, q)), returnType: await q.receive(functionType.returnType, el => this.visitLeftPadded(el, q)) }; return updateIfChanged(functionType, updates); } override async visitInferType(inferType: JS.InferType, q: RpcReceiveQueue): Promise { const updates = { typeParameter: await q.receive(inferType.typeParameter, el => this.visitLeftPadded(el, q)), type: await q.receive(inferType.type, el => this.visitType(el, q)) }; return updateIfChanged(inferType, updates); } override async visitImportType(importType: JS.ImportType, q: RpcReceiveQueue): Promise { const updates = { hasTypeof: await q.receive(importType.hasTypeof, el => this.visitRightPadded(el, q)), argumentAndAttributes: await q.receive(importType.argumentAndAttributes, el => this.visitContainer(el, q)), qualifier: await q.receive(importType.qualifier, el => this.visitLeftPadded(el, q)), typeArguments: await q.receive(importType.typeArguments, el => this.visitContainer(el, q)), type: await q.receive(importType.type, el => this.visitType(el, q)) }; return updateIfChanged(importType, updates); } override async visitImportDeclaration(jsImport: JS.Import, q: RpcReceiveQueue): Promise { const updates = { modifiers: await q.receiveListDefined(jsImport.modifiers, el => this.visitDefined(el, q)), importClause: await q.receive(jsImport.importClause, el => this.visitDefined(el, q)), moduleSpecifier: await q.receive(jsImport.moduleSpecifier, el => this.visitLeftPadded(el, q)), attributes: await q.receive(jsImport.attributes, el => this.visitDefined(el, q)), initializer: await q.receive(jsImport.initializer, el => this.visitLeftPadded(el, q)) }; return updateIfChanged(jsImport, updates); } override async visitImportClause(jsImportClause: JS.ImportClause, q: RpcReceiveQueue): Promise { const updates = { typeOnly: await q.receive(jsImportClause.typeOnly), name: await q.receive(jsImportClause.name, el => this.visitRightPadded(el, q)), namedBindings: await q.receive(jsImportClause.namedBindings, el => this.visitDefined(el, q)) }; return updateIfChanged(jsImportClause, updates); } override async visitNamedImports(namedImports: JS.NamedImports, q: RpcReceiveQueue): Promise { const updates = { elements: await q.receive(namedImports.elements, el => this.visitContainer(el, q)), type: await q.receive(namedImports.type, el => this.visitType(el, q)) }; return updateIfChanged(namedImports, updates); } override async visitImportSpecifier(jsImportSpecifier: JS.ImportSpecifier, q: RpcReceiveQueue): Promise { const updates = { importType: await q.receive(jsImportSpecifier.importType, el => this.visitLeftPadded(el, q)), specifier: await q.receive(jsImportSpecifier.specifier, el => this.visitDefined(el, q)), type: await q.receive(jsImportSpecifier.type, el => this.visitType(el, q)) }; return updateIfChanged(jsImportSpecifier, updates); } override async visitImportAttributes(importAttributes: JS.ImportAttributes, q: RpcReceiveQueue): Promise { const updates = { token: await q.receive(importAttributes.token), elements: await q.receive(importAttributes.elements, el => this.visitContainer(el, q)) }; return updateIfChanged(importAttributes, updates); } override async visitImportTypeAttributes(importTypeAttributes: JS.ImportTypeAttributes, q: RpcReceiveQueue): Promise { const updates = { token: await q.receive(importTypeAttributes.token, el => this.visitRightPadded(el, q)), elements: await q.receive(importTypeAttributes.elements, el => this.visitContainer(el, q)), end: await q.receive(importTypeAttributes.end, el => this.visitSpace(el, q)) }; return updateIfChanged(importTypeAttributes, updates); } override async visitImportAttribute(importAttribute: JS.ImportAttribute, q: RpcReceiveQueue): Promise { const updates = { name: await q.receive(importAttribute.name, el => this.visitDefined(el, q)), value: await q.receive(importAttribute.value, el => this.visitLeftPadded(el, q)) }; return updateIfChanged(importAttribute, updates); } override async visitBinaryExtensions(binary: JS.Binary, q: RpcReceiveQueue): Promise { const updates = { left: await q.receive(binary.left, el => this.visitDefined(el, q)), operator: await q.receive(binary.operator, el => this.visitLeftPadded(el, q)), right: await q.receive(binary.right, el => this.visitDefined(el, q)), type: await q.receive(binary.type, el => this.visitType(el, q)) }; return updateIfChanged(binary, updates); } override async visitLiteralType(literalType: JS.LiteralType, q: RpcReceiveQueue): Promise { const updates = { literal: await q.receive(literalType.literal, el => this.visitDefined(el, q)), type: await q.receive(literalType.type, el => this.visitType(el, q)) }; return updateIfChanged(literalType, updates); } override async visitMappedType(mappedType: JS.MappedType, q: RpcReceiveQueue): Promise { const updates = { prefixToken: await q.receive(mappedType.prefixToken, el => this.visitLeftPadded(el, q)), hasReadonly: await q.receive(mappedType.hasReadonly, el => this.visitLeftPadded(el, q)), keysRemapping: await q.receive(mappedType.keysRemapping, el => this.visitDefined(el, q)), suffixToken: await q.receive(mappedType.suffixToken, el => this.visitLeftPadded(el, q)), hasQuestionToken: await q.receive(mappedType.hasQuestionToken, el => this.visitLeftPadded(el, q)), valueType: await q.receive(mappedType.valueType, el => this.visitContainer(el, q)), type: await q.receive(mappedType.type, el => this.visitType(el, q)) }; return updateIfChanged(mappedType, updates); } override async visitMappedTypeKeysRemapping(keysRemapping: JS.MappedType.KeysRemapping, q: RpcReceiveQueue): Promise { const updates = { typeParameter: await q.receive(keysRemapping.typeParameter, el => this.visitRightPadded(el, q)), nameType: await q.receive(keysRemapping.nameType, el => this.visitRightPadded(el, q)) }; return updateIfChanged(keysRemapping, updates); } override async visitMappedTypeParameter(mappedTypeParameter: JS.MappedType.Parameter, q: RpcReceiveQueue): Promise { const updates = { name: await q.receive(mappedTypeParameter.name, el => this.visitDefined(el, q)), iterateType: await q.receive(mappedTypeParameter.iterateType, el => this.visitLeftPadded(el, q)) }; return updateIfChanged(mappedTypeParameter, updates); } override async visitObjectBindingPattern(objectBindingPattern: JS.ObjectBindingPattern, q: RpcReceiveQueue): Promise { const updates = { leadingAnnotations: await q.receiveListDefined(objectBindingPattern.leadingAnnotations, el => this.visitDefined(el, q)), modifiers: await q.receiveListDefined(objectBindingPattern.modifiers, el => this.visitDefined(el, q)), typeExpression: await q.receive(objectBindingPattern.typeExpression, el => this.visitDefined(el, q)), bindings: await q.receive(objectBindingPattern.bindings, el => this.visitContainer(el, q)), initializer: await q.receive(objectBindingPattern.initializer, el => this.visitLeftPadded(el, q)) }; return updateIfChanged(objectBindingPattern, updates); } override async visitPropertyAssignment(propertyAssignment: JS.PropertyAssignment, q: RpcReceiveQueue): Promise { const updates = { name: await q.receive(propertyAssignment.name, el => this.visitRightPadded(el, q)), assigmentToken: await q.receive(propertyAssignment.assigmentToken), initializer: await q.receive(propertyAssignment.initializer, el => this.visitDefined(el, q)) }; return updateIfChanged(propertyAssignment, updates); } override async visitSatisfiesExpression(satisfiesExpression: JS.SatisfiesExpression, q: RpcReceiveQueue): Promise { const updates = { expression: await q.receive(satisfiesExpression.expression, el => this.visitDefined(el, q)), satisfiesType: await q.receive(satisfiesExpression.satisfiesType, el => this.visitLeftPadded(el, q)), type: await q.receive(satisfiesExpression.type, el => this.visitType(el, q)) }; return updateIfChanged(satisfiesExpression, updates); } override async visitScopedVariableDeclarations(scopedVariableDeclarations: JS.ScopedVariableDeclarations, q: RpcReceiveQueue): Promise { const updates = { modifiers: await q.receiveListDefined(scopedVariableDeclarations.modifiers, el => this.visitDefined(el, q)), variables: await q.receiveListDefined(scopedVariableDeclarations.variables, el => this.visitRightPadded(el, q)) }; return updateIfChanged(scopedVariableDeclarations, updates); } override async visitShebang(shebang: JS.Shebang, q: RpcReceiveQueue): Promise { const updates = { text: await q.receive(shebang.text) }; return updateIfChanged(shebang, updates); } override async visitSpread(spread: JS.Spread, q: RpcReceiveQueue): Promise { const updates = { expression: await q.receive(spread.expression, el => this.visitDefined(el, q)), type: await q.receive(spread.type, el => this.visitType(el, q)) }; return updateIfChanged(spread, updates); } override async visitStatementExpression(statementExpression: JS.StatementExpression, q: RpcReceiveQueue): Promise { const updates = { statement: await q.receive(statementExpression.statement, el => this.visitDefined(el, q)) }; return updateIfChanged(statementExpression, updates); } override async visitTaggedTemplateExpression(taggedTemplateExpression: JS.TaggedTemplateExpression, q: RpcReceiveQueue): Promise { const updates = { tag: await q.receive(taggedTemplateExpression.tag, el => this.visitRightPadded(el, q)), typeArguments: await q.receive(taggedTemplateExpression.typeArguments, el => this.visitContainer(el, q)), templateExpression: await q.receive(taggedTemplateExpression.templateExpression, el => this.visitDefined(el, q)), type: await q.receive(taggedTemplateExpression.type, el => this.visitType(el, q)) }; return updateIfChanged(taggedTemplateExpression, updates); } override async visitTemplateExpression(templateExpression: JS.TemplateExpression, q: RpcReceiveQueue): Promise { const updates = { head: await q.receive(templateExpression.head, el => this.visitDefined(el, q)), spans: await q.receiveListDefined(templateExpression.spans, el => this.visitRightPadded(el, q)), type: await q.receive(templateExpression.type, el => this.visitType(el, q)) }; return updateIfChanged(templateExpression, updates); } override async visitTemplateExpressionSpan(span: JS.TemplateExpression.Span, q: RpcReceiveQueue): Promise { const updates = { expression: await q.receive(span.expression, el => this.visitDefined(el, q)), tail: await q.receive(span.tail, el => this.visitDefined(el, q)) }; return updateIfChanged(span, updates); } override async visitTuple(tuple: JS.Tuple, q: RpcReceiveQueue): Promise { const updates = { elements: await q.receive(tuple.elements, el => this.visitContainer(el, q)), type: await q.receive(tuple.type, el => this.visitType(el, q)) }; return updateIfChanged(tuple, updates); } override async visitTypeDeclaration(typeDeclaration: JS.TypeDeclaration, q: RpcReceiveQueue): Promise { const updates = { modifiers: await q.receiveListDefined(typeDeclaration.modifiers, el => this.visitDefined(el, q)), name: await q.receive(typeDeclaration.name, el => this.visitLeftPadded(el, q)), typeParameters: await q.receive(typeDeclaration.typeParameters, el => this.visitDefined(el, q)), initializer: await q.receive(typeDeclaration.initializer, el => this.visitLeftPadded(el, q)), type: await q.receive(typeDeclaration.type, el => this.visitType(el, q)) }; return updateIfChanged(typeDeclaration, updates); } override async visitTypeOf(typeOf: JS.TypeOf, q: RpcReceiveQueue): Promise { const updates = { expression: await q.receive(typeOf.expression, el => this.visitDefined(el, q)), type: await q.receive(typeOf.type, el => this.visitType(el, q)) }; return updateIfChanged(typeOf, updates); } override async visitTypeTreeExpression(typeTreeExpression: JS.TypeTreeExpression, q: RpcReceiveQueue): Promise { const updates = { expression: await q.receive(typeTreeExpression.expression, el => this.visitDefined(el, q)) }; return updateIfChanged(typeTreeExpression, updates); } override async visitAs(as_: JS.As, q: RpcReceiveQueue): Promise { const updates = { left: await q.receive(as_.left, el => this.visitRightPadded(el, q)), right: await q.receive(as_.right, el => this.visitDefined(el, q)), type: await q.receive(as_.type, el => this.visitType(el, q)) }; return updateIfChanged(as_, updates); } override async visitAssignmentOperationExtensions(assignmentOperation: JS.AssignmentOperation, q: RpcReceiveQueue): Promise { const updates = { variable: await q.receive(assignmentOperation.variable, el => this.visitDefined(el, q)), operator: await q.receive(assignmentOperation.operator, el => this.visitLeftPadded(el, q)), assignment: await q.receive(assignmentOperation.assignment, el => this.visitDefined(el, q)), type: await q.receive(assignmentOperation.type, el => this.visitType(el, q)) }; return updateIfChanged(assignmentOperation, updates); } override async visitIndexedAccessType(indexedAccessType: JS.IndexedAccessType, q: RpcReceiveQueue): Promise { const updates = { objectType: await q.receive(indexedAccessType.objectType, el => this.visitDefined(el, q)), indexType: await q.receive(indexedAccessType.indexType, el => this.visitDefined(el, q)), type: await q.receive(indexedAccessType.type, el => this.visitType(el, q)) }; return updateIfChanged(indexedAccessType, updates); } override async visitIndexedAccessTypeIndexType(indexType: JS.IndexedAccessType.IndexType, q: RpcReceiveQueue): Promise { const updates = { element: await q.receive(indexType.element, el => this.visitRightPadded(el, q)), type: await q.receive(indexType.type, el => this.visitType(el, q)) }; return updateIfChanged(indexType, updates); } override async visitTypeQuery(typeQuery: JS.TypeQuery, q: RpcReceiveQueue): Promise { const updates = { typeExpression: await q.receive(typeQuery.typeExpression, el => this.visitDefined(el, q)), typeArguments: await q.receive(typeQuery.typeArguments, el => this.visitContainer(el, q)), type: await q.receive(typeQuery.type, el => this.visitType(el, q)) }; return updateIfChanged(typeQuery, updates); } override async visitTypeInfo(typeInfo: JS.TypeInfo, q: RpcReceiveQueue): Promise { const updates = { typeIdentifier: await q.receive(typeInfo.typeIdentifier, el => this.visitDefined(el, q)) }; return updateIfChanged(typeInfo, updates); } override async visitComputedPropertyName(computedPropertyName: JS.ComputedPropertyName, q: RpcReceiveQueue): Promise { const updates = { expression: await q.receive(computedPropertyName.expression, el => this.visitRightPadded(el, q)) }; return updateIfChanged(computedPropertyName, updates); } override async visitTypeOperator(typeOperator: JS.TypeOperator, q: RpcReceiveQueue): Promise { const updates = { operator: await q.receive(typeOperator.operator), expression: await q.receive(typeOperator.expression, el => this.visitLeftPadded(el, q)) }; return updateIfChanged(typeOperator, updates); } override async visitTypePredicate(typePredicate: JS.TypePredicate, q: RpcReceiveQueue): Promise { const updates = { asserts: await q.receive(typePredicate.asserts, el => this.visitLeftPadded(el, q)), parameterName: await q.receive(typePredicate.parameterName, el => this.visitDefined(el, q)), expression: await q.receive(typePredicate.expression, el => this.visitLeftPadded(el, q)), type: await q.receive(typePredicate.type, el => this.visitType(el, q)) }; return updateIfChanged(typePredicate, updates); } override async visitUnion(union: JS.Union, q: RpcReceiveQueue): Promise { const updates = { types: await q.receiveListDefined(union.types, el => this.visitRightPadded(el, q)), type: await q.receive(union.type, el => this.visitType(el, q)) }; return updateIfChanged(union, updates); } override async visitIntersection(intersection: JS.Intersection, q: RpcReceiveQueue): Promise { const updates = { types: await q.receiveListDefined(intersection.types, el => this.visitRightPadded(el, q)), type: await q.receive(intersection.type, el => this.visitType(el, q)) }; return updateIfChanged(intersection, updates); } override async visitVoid(void_: JS.Void, q: RpcReceiveQueue): Promise { const updates = { expression: await q.receive(void_.expression, el => this.visitDefined(el, q)) }; return updateIfChanged(void_, updates); } override async visitWithStatement(withStatement: JS.WithStatement, q: RpcReceiveQueue): Promise { const updates = { expression: await q.receive(withStatement.expression, el => this.visitDefined>(el, q)), body: await q.receive(withStatement.body, el => this.visitRightPadded(el, q)) }; return updateIfChanged(withStatement, updates); } override async visitJsxTag(tag: JSX.Tag, q: RpcReceiveQueue): Promise { const updates = { openName: await q.receive(tag.openName, el => this.visitLeftPadded(el, q)), typeArguments: await q.receive(tag.typeArguments, el => this.visitContainer(el, q)), afterName: await q.receive(tag.afterName, space => this.visitSpace(space, q)), attributes: await q.receiveListDefined(tag.attributes, attr => this.visitRightPadded(attr, q)), selfClosing: await q.receive(tag.selfClosing, space => this.visitSpace(space, q)), children: await q.receiveList(tag.children, child => this.visit(child, q)), closingName: await q.receive(tag.closingName, el => this.visitLeftPadded(el, q)), afterClosingName: await q.receive(tag.afterClosingName, el => this.visitSpace(el, q)) }; // Type assertion is needed due to `JSX.Tag` being a union type return updateIfChanged(tag, updates as any); } override async visitJsxAttribute(attribute: JSX.Attribute, q: RpcReceiveQueue): Promise { const updates = { key: await q.receive(attribute.key, el => this.visitDefined(el, q)), value: await q.receive(attribute.value, el => this.visitLeftPadded(el, q)) }; return updateIfChanged(attribute, updates); } override async visitJsxSpreadAttribute(spreadAttribute: JSX.SpreadAttribute, q: RpcReceiveQueue): Promise { const updates = { dots: await q.receive(spreadAttribute.dots, space => this.visitSpace(space, q)), expression: await q.receive(spreadAttribute.expression, el => this.visitRightPadded(el, q)) }; return updateIfChanged(spreadAttribute, updates); } override async visitJsxEmbeddedExpression(embeddedExpression: JSX.EmbeddedExpression, q: RpcReceiveQueue): Promise { const updates = { expression: await q.receive(embeddedExpression.expression, el => this.visitRightPadded(el, q)) }; return updateIfChanged(embeddedExpression, updates); } override async visitJsxNamespacedName(namespacedName: JSX.NamespacedName, q: RpcReceiveQueue): Promise { const updates = { namespace: await q.receive(namespacedName.namespace, el => this.visitDefined(el, q)), name: await q.receive(namespacedName.name, el => this.visitLeftPadded(el, q)) }; return updateIfChanged(namespacedName, updates); } override async visitIndexSignatureDeclaration(indexSignatureDeclaration: JS.IndexSignatureDeclaration, q: RpcReceiveQueue): Promise { const updates = { modifiers: await q.receiveListDefined(indexSignatureDeclaration.modifiers, el => this.visitDefined(el, q)), parameters: await q.receive(indexSignatureDeclaration.parameters, el => this.visitContainer(el, q)), typeExpression: await q.receive(indexSignatureDeclaration.typeExpression, el => this.visitLeftPadded(el, q)), type: await q.receive(indexSignatureDeclaration.type, el => this.visitType(el, q)) }; return updateIfChanged(indexSignatureDeclaration, updates); } override async visitComputedPropertyMethodDeclaration(computedPropMethod: JS.ComputedPropertyMethodDeclaration, q: RpcReceiveQueue): Promise { const updates = { leadingAnnotations: await q.receiveListDefined(computedPropMethod.leadingAnnotations, el => this.visitDefined(el, q)), modifiers: await q.receiveListDefined(computedPropMethod.modifiers, el => this.visitDefined(el, q)), typeParameters: await q.receive(computedPropMethod.typeParameters, el => this.visitDefined(el, q)), returnTypeExpression: await q.receive(computedPropMethod.returnTypeExpression, el => this.visitDefined(el, q)), name: await q.receive(computedPropMethod.name, el => this.visitDefined(el, q)), parameters: await q.receive(computedPropMethod.parameters, el => this.visitContainer(el, q)), body: await q.receive(computedPropMethod.body, el => this.visitDefined(el, q)), methodType: await q.receive(computedPropMethod.methodType, el => this.visitType(el, q) as any as Type.Method) }; return updateIfChanged(computedPropMethod, updates); } override async visitForOfLoop(forOfLoop: JS.ForOfLoop, q: RpcReceiveQueue): Promise { const updates = { await: await q.receive(forOfLoop.await, space => this.visitSpace(space, q)), loop: await q.receive(forOfLoop.loop, el => this.visitDefined(el, q)) }; return updateIfChanged(forOfLoop, updates); } override async visitForInLoop(forInLoop: JS.ForInLoop, q: RpcReceiveQueue): Promise { const updates = { control: await q.receive(forInLoop.control, el => this.visitDefined(el, q)), body: await q.receive(forInLoop.body, el => this.visitRightPadded(el, q)) }; return updateIfChanged(forInLoop, updates); } override async visitNamespaceDeclaration(namespaceDeclaration: JS.NamespaceDeclaration, q: RpcReceiveQueue): Promise { const updates = { modifiers: await q.receiveListDefined(namespaceDeclaration.modifiers, el => this.visitDefined(el, q)), keywordType: await q.receive(namespaceDeclaration.keywordType, el => this.visitLeftPadded(el, q)), name: await q.receive(namespaceDeclaration.name, el => this.visitRightPadded(el, q)), body: await q.receive(namespaceDeclaration.body, el => this.visitDefined(el, q)) }; return updateIfChanged(namespaceDeclaration, updates); } override async visitTypeLiteral(typeLiteral: JS.TypeLiteral, q: RpcReceiveQueue): Promise { const updates = { members: await q.receive(typeLiteral.members, el => this.visitDefined(el, q)), type: await q.receive(typeLiteral.type, el => this.visitType(el, q)) }; return updateIfChanged(typeLiteral, updates); } override async visitArrayBindingPattern(arrayBindingPattern: JS.ArrayBindingPattern, q: RpcReceiveQueue): Promise { const updates = { elements: await q.receive(arrayBindingPattern.elements, el => this.visitContainer(el, q)), type: await q.receive(arrayBindingPattern.type, el => this.visitType(el, q)) }; return updateIfChanged(arrayBindingPattern, updates); } override async visitBindingElement(bindingElement: JS.BindingElement, q: RpcReceiveQueue): Promise { const updates = { propertyName: await q.receive(bindingElement.propertyName, el => this.visitRightPadded(el, q)), name: await q.receive(bindingElement.name, el => this.visitDefined(el, q)), initializer: await q.receive(bindingElement.initializer, el => this.visitLeftPadded(el, q)), variableType: await q.receive(bindingElement.variableType, el => this.visitType(el, q) as any as Type.Variable) }; return updateIfChanged(bindingElement, updates); } override async visitExportDeclaration(exportDeclaration: JS.ExportDeclaration, q: RpcReceiveQueue): Promise { const updates = { modifiers: await q.receiveListDefined(exportDeclaration.modifiers, el => this.visitDefined(el, q)), typeOnly: await q.receive(exportDeclaration.typeOnly, el => this.visitLeftPadded(el, q)), exportClause: await q.receive(exportDeclaration.exportClause, el => this.visitDefined(el, q)), moduleSpecifier: await q.receive(exportDeclaration.moduleSpecifier, el => this.visitLeftPadded(el, q)), attributes: await q.receive(exportDeclaration.attributes, el => this.visitDefined(el, q)) }; return updateIfChanged(exportDeclaration, updates); } override async visitExportAssignment(exportAssignment: JS.ExportAssignment, q: RpcReceiveQueue): Promise { const updates = { exportEquals: await q.receive(exportAssignment.exportEquals), expression: await q.receive(exportAssignment.expression, el => this.visitLeftPadded(el, q)) }; return updateIfChanged(exportAssignment, updates); } override async visitNamedExports(namedExports: JS.NamedExports, q: RpcReceiveQueue): Promise { const updates = { elements: await q.receive(namedExports.elements, el => this.visitContainer(el, q)), type: await q.receive(namedExports.type, el => this.visitType(el, q)) }; return updateIfChanged(namedExports, updates); } override async visitExportSpecifier(exportSpecifier: JS.ExportSpecifier, q: RpcReceiveQueue): Promise { const updates = { typeOnly: await q.receive(exportSpecifier.typeOnly, el => this.visitLeftPadded(el, q)), specifier: await q.receive(exportSpecifier.specifier, el => this.visitDefined(el, q)), type: await q.receive(exportSpecifier.type, el => this.visitType(el, q)) }; return updateIfChanged(exportSpecifier, updates); } override async visitRightPadded(right: J.RightPadded, q: RpcReceiveQueue): Promise> { return this.delegate.visitRightPadded(right, q) } async visitLeftPadded(left: J.LeftPadded, q: RpcReceiveQueue): Promise> { return this.delegate.visitLeftPadded(left, q); } async visitContainer(container: J.Container, q: RpcReceiveQueue): Promise> { return this.delegate.visitContainer(container, q); } override async visitSpace(space: J.Space, q: RpcReceiveQueue): Promise { return this.delegate.visitSpace(space, q); } override async visitType(javaType: Type | undefined, q: RpcReceiveQueue): Promise { return this.delegate.visitType(javaType, q); } } class JavaScriptDelegateReceiver extends JavaReceiver { private javascriptReceiver: JavaScriptReceiver; constructor(javascriptReceiver: JavaScriptReceiver) { super(); this.javascriptReceiver = javascriptReceiver; } async visit(tree: Tree, p: RpcReceiveQueue, parent?: Cursor): Promise { if (isJavaScript(tree)) { return this.javascriptReceiver.visit(tree, p, parent); } return super.visit(tree, p, parent); } } registerJLanguageCodecs(JS.Kind.CompilationUnit, new JavaScriptReceiver(), new JavaScriptSender(), JS.Kind); registerVisitor("org.openrewrite.javascript.format.AutoformatVisitor", AutoformatVisitor);