From 40ca0f292261d2b0230899483cbf233c40fd7857 Mon Sep 17 00:00:00 2001 From: Knut Wannheden Date: Wed, 20 Nov 2024 15:00:10 +0100 Subject: [PATCH 1/6] Implement type validation as part of parser Make sure that all LST elements or of the expected type. Type inconsistencies can occur due to the type erasure of Java generics. --- .../javascript/JavaScriptParser.java | 16 +- .../javascript/JavaScriptValidator.java | 683 ++++++++++++++++++ 2 files changed, 696 insertions(+), 3 deletions(-) create mode 100644 rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptValidator.java diff --git a/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptParser.java b/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptParser.java index 66b43593..3e7a0e19 100644 --- a/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptParser.java +++ b/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptParser.java @@ -117,9 +117,9 @@ public Stream parseInputs(Iterable inputs, @Nullable Path rel return parsed; } - JS.CompilationUnit py = (JS.CompilationUnit) parsed; - parsingListener.parsed(input, py); - SourceFile sourceFile = requirePrintEqualsInput(py, input, relativeTo, ctx); + JS.CompilationUnit js = (JS.CompilationUnit) parsed; + parsingListener.parsed(input, js); + SourceFile sourceFile = validate(js, input, relativeTo, ctx); if (sourceFile instanceof ParseError) { return ((ParseError) sourceFile).withErroneous(null); } @@ -134,6 +134,16 @@ public Stream parseInputs(Iterable inputs, @Nullable Path rel }); } + private SourceFile validate(JS.CompilationUnit sourceFile, Input input, @Nullable Path relativeTo, ExecutionContext ctx) { + JavaScriptValidator typeValidator = new JavaScriptValidator<>(); + try { + typeValidator.visit(sourceFile, 0); + return requirePrintEqualsInput(sourceFile, input, relativeTo, ctx); + } catch (Exception e) { + return ParseError.build(this, input, relativeTo, ctx, new IllegalStateException("LST model has type validation errors", e)); + } + } + private final static List EXTENSIONS = Collections.unmodifiableList(Arrays.asList( ".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx", ".mts", ".cts" diff --git a/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptValidator.java b/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptValidator.java new file mode 100644 index 00000000..1cb5b82d --- /dev/null +++ b/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptValidator.java @@ -0,0 +1,683 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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. + */ + +/* + * -------------------THIS FILE IS AUTO GENERATED-------------------------- + * Changes to this file may cause incorrect behavior and will be lost if + * the code is regenerated. +*/ + +package org.openrewrite.javascript; + +import org.jspecify.annotations.Nullable; +import org.openrewrite.*; +import org.openrewrite.internal.ListUtils; +import org.openrewrite.marker.Markers; +import org.openrewrite.tree.*; +import org.openrewrite.java.JavaVisitor; +import org.openrewrite.java.tree.*; +import org.openrewrite.javascript.tree.*; + +import java.util.List; + +class JavaScriptValidator

extends JavaScriptIsoVisitor

{ + + private @Nullable T visitAndValidate(@Nullable T tree, Class expected, P p) { + if (tree != null && !expected.isInstance(tree)) { + throw new IllegalStateException("Type " + tree.getClass() + " is not assignable to " + expected); + } + // noinspection unchecked + return (T) visit(tree, p); + } + + private @Nullable List visitAndValidate(@Nullable List<@Nullable T> list, Class expected, P p) { + return list == null ? null : ListUtils.map(list, e -> visitAndValidate(e, expected, p)); + } + + @Override + public JS.CompilationUnit visitCompilationUnit(JS.CompilationUnit compilationUnit, P p) { + ListUtils.map(compilationUnit.getImports(), el -> visitAndValidate(el, J.Import.class, p)); + ListUtils.map(compilationUnit.getStatements(), el -> visitAndValidate(el, Statement.class, p)); + return compilationUnit; + } + + @Override + public JS.Alias visitAlias(JS.Alias alias, P p) { + visitAndValidate(alias.getAlias(), J.Identifier.class, p); + return alias; + } + + @Override + public JS.ArrowFunction visitArrowFunction(JS.ArrowFunction arrowFunction, P p) { + ListUtils.map(arrowFunction.getLeadingAnnotations(), el -> visitAndValidate(el, J.Annotation.class, p)); + ListUtils.map(arrowFunction.getModifiers(), el -> visitAndValidate(el, J.Modifier.class, p)); + visitAndValidate(arrowFunction.getTypeParameters(), J.TypeParameters.class, p); + visitAndValidate(arrowFunction.getParameters(), J.Lambda.Parameters.class, p); + visitAndValidate(arrowFunction.getReturnTypeExpression(), TypeTree.class, p); + visitAndValidate(arrowFunction.getBody(), J.class, p); + return arrowFunction; + } + + @Override + public JS.Await visitAwait(JS.Await await, P p) { + visitAndValidate(await.getExpression(), Expression.class, p); + return await; + } + + @Override + public JS.DefaultType visitDefaultType(JS.DefaultType defaultType, P p) { + visitAndValidate(defaultType.getLeft(), Expression.class, p); + visitAndValidate(defaultType.getRight(), Expression.class, p); + return defaultType; + } + + @Override + public JS.Delete visitDelete(JS.Delete delete, P p) { + visitAndValidate(delete.getExpression(), Expression.class, p); + return delete; + } + + @Override + public JS.Export visitExport(JS.Export export, P p) { + visitAndValidate(export.getTarget(), J.Literal.class, p); + return export; + } + + @Override + public JS.ExpressionStatement visitExpressionStatement(JS.ExpressionStatement expressionStatement, P p) { + visitAndValidate(expressionStatement.getExpression(), Expression.class, p); + return expressionStatement; + } + + @Override + public JS.FunctionType visitFunctionType(JS.FunctionType functionType, P p) { + visitAndValidate(functionType.getReturnType(), Expression.class, p); + return functionType; + } + + @Override + public JS.JsImport visitJsImport(JS.JsImport jsImport, P p) { + visitAndValidate(jsImport.getTarget(), J.Literal.class, p); + return jsImport; + } + + @Override + public JS.JsImportSpecifier visitJsImportSpecifier(JS.JsImportSpecifier jsImportSpecifier, P p) { + visitAndValidate(jsImportSpecifier.getSpecifier(), Expression.class, p); + return jsImportSpecifier; + } + + @Override + public JS.JsBinary visitJsBinary(JS.JsBinary jsBinary, P p) { + visitAndValidate(jsBinary.getLeft(), Expression.class, p); + visitAndValidate(jsBinary.getRight(), Expression.class, p); + return jsBinary; + } + + @Override + public JS.ObjectBindingDeclarations visitObjectBindingDeclarations(JS.ObjectBindingDeclarations objectBindingDeclarations, P p) { + ListUtils.map(objectBindingDeclarations.getLeadingAnnotations(), el -> visitAndValidate(el, J.Annotation.class, p)); + ListUtils.map(objectBindingDeclarations.getModifiers(), el -> visitAndValidate(el, J.Modifier.class, p)); + visitAndValidate(objectBindingDeclarations.getTypeExpression(), TypeTree.class, p); + return objectBindingDeclarations; + } + + @Override + public JS.ObjectBindingDeclarations.Binding visitBinding(JS.ObjectBindingDeclarations.Binding binding, P p) { + visitAndValidate(binding.getName(), TypedTree.class, p); + return binding; + } + + @Override + public JS.PropertyAssignment visitPropertyAssignment(JS.PropertyAssignment propertyAssignment, P p) { + visitAndValidate(propertyAssignment.getInitializer(), Expression.class, p); + return propertyAssignment; + } + + @Override + public JS.ScopedVariableDeclarations visitScopedVariableDeclarations(JS.ScopedVariableDeclarations scopedVariableDeclarations, P p) { + ListUtils.map(scopedVariableDeclarations.getModifiers(), el -> visitAndValidate(el, J.Modifier.class, p)); + ListUtils.map(scopedVariableDeclarations.getVariables(), el -> visitAndValidate(el, Expression.class, p)); + return scopedVariableDeclarations; + } + + @Override + public JS.StatementExpression visitStatementExpression(JS.StatementExpression statementExpression, P p) { + visitAndValidate(statementExpression.getStatement(), Statement.class, p); + return statementExpression; + } + + @Override + public JS.TemplateExpression visitTemplateExpression(JS.TemplateExpression templateExpression, P p) { + ListUtils.map(templateExpression.getStrings(), el -> visitAndValidate(el, J.class, p)); + return templateExpression; + } + + @Override + public JS.TemplateExpression.Value visitTemplateExpressionValue(JS.TemplateExpression.Value value, P p) { + visitAndValidate(value.getTree(), J.class, p); + return value; + } + + @Override + public JS.Tuple visitTuple(JS.Tuple tuple, P p) { + return tuple; + } + + @Override + public JS.TypeDeclaration visitTypeDeclaration(JS.TypeDeclaration typeDeclaration, P p) { + ListUtils.map(typeDeclaration.getModifiers(), el -> visitAndValidate(el, J.Modifier.class, p)); + visitAndValidate(typeDeclaration.getName(), J.Identifier.class, p); + visitAndValidate(typeDeclaration.getTypeParameters(), J.TypeParameters.class, p); + return typeDeclaration; + } + + @Override + public JS.TypeOf visitTypeOf(JS.TypeOf typeOf, P p) { + visitAndValidate(typeOf.getExpression(), Expression.class, p); + return typeOf; + } + + @Override + public JS.TypeOperator visitTypeOperator(JS.TypeOperator typeOperator, P p) { + return typeOperator; + } + + @Override + public JS.Unary visitUnary(JS.Unary unary, P p) { + visitAndValidate(unary.getExpression(), Expression.class, p); + return unary; + } + + @Override + public JS.Union visitUnion(JS.Union union, P p) { + ListUtils.map(union.getTypes(), el -> visitAndValidate(el, Expression.class, p)); + return union; + } + + @Override + public JS.Void visitVoid(JS.Void void_, P p) { + visitAndValidate(void_.getExpression(), Expression.class, p); + return void_; + } + + @Override + public JS.Yield visitYield(JS.Yield yield, P p) { + visitAndValidate(yield.getExpression(), Expression.class, p); + return yield; + } + + @Override + public JS.TypeInfo visitTypeInfo(JS.TypeInfo typeInfo, P p) { + visitAndValidate(typeInfo.getTypeIdentifier(), TypeTree.class, p); + return typeInfo; + } + + @Override + public JS.JSVariableDeclarations visitJSVariableDeclarations(JS.JSVariableDeclarations jSVariableDeclarations, P p) { + ListUtils.map(jSVariableDeclarations.getLeadingAnnotations(), el -> visitAndValidate(el, J.Annotation.class, p)); + ListUtils.map(jSVariableDeclarations.getModifiers(), el -> visitAndValidate(el, J.Modifier.class, p)); + visitAndValidate(jSVariableDeclarations.getTypeExpression(), TypeTree.class, p); + ListUtils.map(jSVariableDeclarations.getVariables(), el -> visitAndValidate(el, JS.JSVariableDeclarations.JSNamedVariable.class, p)); + return jSVariableDeclarations; + } + + @Override + public JS.JSVariableDeclarations.JSNamedVariable visitJSVariableDeclarationsJSNamedVariable(JS.JSVariableDeclarations.JSNamedVariable jSNamedVariable, P p) { + visitAndValidate(jSNamedVariable.getName(), Expression.class, p); + return jSNamedVariable; + } + + @Override + public JS.JSMethodDeclaration visitJSMethodDeclaration(JS.JSMethodDeclaration jSMethodDeclaration, P p) { + ListUtils.map(jSMethodDeclaration.getLeadingAnnotations(), el -> visitAndValidate(el, J.Annotation.class, p)); + ListUtils.map(jSMethodDeclaration.getModifiers(), el -> visitAndValidate(el, J.Modifier.class, p)); + visitAndValidate(jSMethodDeclaration.getTypeParameters(), J.TypeParameters.class, p); + visitAndValidate(jSMethodDeclaration.getReturnTypeExpression(), TypeTree.class, p); + visitAndValidate(jSMethodDeclaration.getName(), Expression.class, p); + visitAndValidate(jSMethodDeclaration.getBody(), J.Block.class, p); + return jSMethodDeclaration; + } + + @Override + public JS.JSMethodInvocation visitJSMethodInvocation(JS.JSMethodInvocation jSMethodInvocation, P p) { + visitAndValidate(jSMethodInvocation.getName(), Expression.class, p); + return jSMethodInvocation; + } + + @Override + public JS.NamespaceDeclaration visitNamespaceDeclaration(JS.NamespaceDeclaration namespaceDeclaration, P p) { + ListUtils.map(namespaceDeclaration.getModifiers(), el -> visitAndValidate(el, J.Modifier.class, p)); + visitAndValidate(namespaceDeclaration.getBody(), J.Block.class, p); + return namespaceDeclaration; + } + + @Override + public JS.FunctionDeclaration visitFunctionDeclaration(JS.FunctionDeclaration functionDeclaration, P p) { + ListUtils.map(functionDeclaration.getModifiers(), el -> visitAndValidate(el, J.Modifier.class, p)); + visitAndValidate(functionDeclaration.getName(), J.Identifier.class, p); + visitAndValidate(functionDeclaration.getTypeParameters(), J.TypeParameters.class, p); + visitAndValidate(functionDeclaration.getReturnTypeExpression(), TypeTree.class, p); + visitAndValidate(functionDeclaration.getBody(), J.class, p); + return functionDeclaration; + } + + @Override + public J.AnnotatedType visitAnnotatedType(J.AnnotatedType annotatedType, P p) { + ListUtils.map(annotatedType.getAnnotations(), el -> visitAndValidate(el, J.Annotation.class, p)); + visitAndValidate(annotatedType.getTypeExpression(), TypeTree.class, p); + return annotatedType; + } + + @Override + public J.Annotation visitAnnotation(J.Annotation annotation, P p) { + visitAndValidate(annotation.getAnnotationType(), NameTree.class, p); + return annotation; + } + + @Override + public J.ArrayAccess visitArrayAccess(J.ArrayAccess arrayAccess, P p) { + visitAndValidate(arrayAccess.getIndexed(), Expression.class, p); + visitAndValidate(arrayAccess.getDimension(), J.ArrayDimension.class, p); + return arrayAccess; + } + + @Override + public J.ArrayType visitArrayType(J.ArrayType arrayType, P p) { + visitAndValidate(arrayType.getElementType(), TypeTree.class, p); + ListUtils.map(arrayType.getAnnotations(), el -> visitAndValidate(el, J.Annotation.class, p)); + return arrayType; + } + + @Override + public J.Assert visitAssert(J.Assert assert_, P p) { + visitAndValidate(assert_.getCondition(), Expression.class, p); + return assert_; + } + + @Override + public J.Assignment visitAssignment(J.Assignment assignment, P p) { + visitAndValidate(assignment.getVariable(), Expression.class, p); + return assignment; + } + + @Override + public J.AssignmentOperation visitAssignmentOperation(J.AssignmentOperation assignmentOperation, P p) { + visitAndValidate(assignmentOperation.getVariable(), Expression.class, p); + visitAndValidate(assignmentOperation.getAssignment(), Expression.class, p); + return assignmentOperation; + } + + @Override + public J.Binary visitBinary(J.Binary binary, P p) { + visitAndValidate(binary.getLeft(), Expression.class, p); + visitAndValidate(binary.getRight(), Expression.class, p); + return binary; + } + + @Override + public J.Block visitBlock(J.Block block, P p) { + ListUtils.map(block.getStatements(), el -> visitAndValidate(el, Statement.class, p)); + return block; + } + + @Override + public J.Break visitBreak(J.Break break_, P p) { + visitAndValidate(break_.getLabel(), J.Identifier.class, p); + return break_; + } + + @Override + public J.Case visitCase(J.Case case_, P p) { + return case_; + } + + @Override + public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDeclaration, P p) { + ListUtils.map(classDeclaration.getLeadingAnnotations(), el -> visitAndValidate(el, J.Annotation.class, p)); + ListUtils.map(classDeclaration.getModifiers(), el -> visitAndValidate(el, J.Modifier.class, p)); + visit(classDeclaration.getPadding().getKind(), p); + visitAndValidate(classDeclaration.getName(), J.Identifier.class, p); + visitAndValidate(classDeclaration.getBody(), J.Block.class, p); + return classDeclaration; + } + + @Override + public J.Continue visitContinue(J.Continue continue_, P p) { + visitAndValidate(continue_.getLabel(), J.Identifier.class, p); + return continue_; + } + + @Override + public J.DoWhileLoop visitDoWhileLoop(J.DoWhileLoop doWhileLoop, P p) { + return doWhileLoop; + } + + @Override + public J.Empty visitEmpty(J.Empty empty, P p) { + return empty; + } + + @Override + public J.EnumValue visitEnumValue(J.EnumValue enumValue, P p) { + ListUtils.map(enumValue.getAnnotations(), el -> visitAndValidate(el, J.Annotation.class, p)); + visitAndValidate(enumValue.getName(), J.Identifier.class, p); + visitAndValidate(enumValue.getInitializer(), J.NewClass.class, p); + return enumValue; + } + + @Override + public J.EnumValueSet visitEnumValueSet(J.EnumValueSet enumValueSet, P p) { + ListUtils.map(enumValueSet.getEnums(), el -> visitAndValidate(el, J.EnumValue.class, p)); + return enumValueSet; + } + + @Override + public J.FieldAccess visitFieldAccess(J.FieldAccess fieldAccess, P p) { + visitAndValidate(fieldAccess.getTarget(), Expression.class, p); + return fieldAccess; + } + + @Override + public J.ForEachLoop visitForEachLoop(J.ForEachLoop forEachLoop, P p) { + visitAndValidate(forEachLoop.getControl(), J.ForEachLoop.Control.class, p); + return forEachLoop; + } + + @Override + public J.ForEachLoop.Control visitForEachControl(J.ForEachLoop.Control control, P p) { + return control; + } + + @Override + public J.ForLoop visitForLoop(J.ForLoop forLoop, P p) { + visitAndValidate(forLoop.getControl(), J.ForLoop.Control.class, p); + return forLoop; + } + + @Override + public J.ForLoop.Control visitForControl(J.ForLoop.Control control, P p) { + ListUtils.map(control.getInit(), el -> visitAndValidate(el, Statement.class, p)); + ListUtils.map(control.getUpdate(), el -> visitAndValidate(el, Statement.class, p)); + return control; + } + + @Override + public J.ParenthesizedTypeTree visitParenthesizedTypeTree(J.ParenthesizedTypeTree parenthesizedTypeTree, P p) { + ListUtils.map(parenthesizedTypeTree.getAnnotations(), el -> visitAndValidate(el, J.Annotation.class, p)); + visitAndValidate(parenthesizedTypeTree.getParenthesizedType(), J.Parentheses.class, p); + return parenthesizedTypeTree; + } + + @Override + public J.Identifier visitIdentifier(J.Identifier identifier, P p) { + ListUtils.map(identifier.getAnnotations(), el -> visitAndValidate(el, J.Annotation.class, p)); + return identifier; + } + + @Override + public J.If visitIf(J.If if_, P p) { + visitAndValidate(if_.getIfCondition(), J.ControlParentheses.class, p); + visitAndValidate(if_.getElsePart(), J.If.Else.class, p); + return if_; + } + + @Override + public J.If.Else visitElse(J.If.Else else_, P p) { + return else_; + } + + @Override + public J.Import visitImport(J.Import import_, P p) { + visitAndValidate(import_.getQualid(), J.FieldAccess.class, p); + return import_; + } + + @Override + public J.InstanceOf visitInstanceOf(J.InstanceOf instanceOf, P p) { + visitAndValidate(instanceOf.getClazz(), J.class, p); + visitAndValidate(instanceOf.getPattern(), J.class, p); + return instanceOf; + } + + @Override + public J.IntersectionType visitIntersectionType(J.IntersectionType intersectionType, P p) { + return intersectionType; + } + + @Override + public J.Label visitLabel(J.Label label, P p) { + visitAndValidate(label.getStatement(), Statement.class, p); + return label; + } + + @Override + public J.Lambda visitLambda(J.Lambda lambda, P p) { + visitAndValidate(lambda.getParameters(), J.Lambda.Parameters.class, p); + visitAndValidate(lambda.getBody(), J.class, p); + return lambda; + } + + @Override + public J.Literal visitLiteral(J.Literal literal, P p) { + return literal; + } + + @Override + public J.MemberReference visitMemberReference(J.MemberReference memberReference, P p) { + return memberReference; + } + + @Override + public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration methodDeclaration, P p) { + ListUtils.map(methodDeclaration.getLeadingAnnotations(), el -> visitAndValidate(el, J.Annotation.class, p)); + ListUtils.map(methodDeclaration.getModifiers(), el -> visitAndValidate(el, J.Modifier.class, p)); + visitAndValidate(methodDeclaration.getTypeParameters(), J.TypeParameters.class, p); + visitAndValidate(methodDeclaration.getReturnTypeExpression(), TypeTree.class, p); + visitAndValidate(methodDeclaration.getBody(), J.Block.class, p); + return methodDeclaration; + } + + @Override + public J.MethodInvocation visitMethodInvocation(J.MethodInvocation methodInvocation, P p) { + visitAndValidate(methodInvocation.getName(), J.Identifier.class, p); + return methodInvocation; + } + + @Override + public J.MultiCatch visitMultiCatch(J.MultiCatch multiCatch, P p) { + ListUtils.map(multiCatch.getAlternatives(), el -> visitAndValidate(el, NameTree.class, p)); + return multiCatch; + } + + @Override + public J.NewArray visitNewArray(J.NewArray newArray, P p) { + visitAndValidate(newArray.getTypeExpression(), TypeTree.class, p); + ListUtils.map(newArray.getDimensions(), el -> visitAndValidate(el, J.ArrayDimension.class, p)); + return newArray; + } + + @Override + public J.ArrayDimension visitArrayDimension(J.ArrayDimension arrayDimension, P p) { + return arrayDimension; + } + + @Override + public J.NewClass visitNewClass(J.NewClass newClass, P p) { + visitAndValidate(newClass.getClazz(), TypeTree.class, p); + visitAndValidate(newClass.getBody(), J.Block.class, p); + return newClass; + } + + @Override + public J.NullableType visitNullableType(J.NullableType nullableType, P p) { + ListUtils.map(nullableType.getAnnotations(), el -> visitAndValidate(el, J.Annotation.class, p)); + return nullableType; + } + + @Override + public J.Package visitPackage(J.Package package_, P p) { + visitAndValidate(package_.getExpression(), Expression.class, p); + ListUtils.map(package_.getAnnotations(), el -> visitAndValidate(el, J.Annotation.class, p)); + return package_; + } + + @Override + public J.ParameterizedType visitParameterizedType(J.ParameterizedType parameterizedType, P p) { + visitAndValidate(parameterizedType.getClazz(), NameTree.class, p); + return parameterizedType; + } + + @Override + public J.Parentheses visitParentheses(J.Parentheses parentheses, P p) { + return parentheses; + } + + @Override + public J.ControlParentheses visitControlParentheses(J.ControlParentheses controlParentheses, P p) { + return controlParentheses; + } + + @Override + public J.Primitive visitPrimitive(J.Primitive primitive, P p) { + return primitive; + } + + @Override + public J.Return visitReturn(J.Return return_, P p) { + visitAndValidate(return_.getExpression(), Expression.class, p); + return return_; + } + + @Override + public J.Switch visitSwitch(J.Switch switch_, P p) { + visitAndValidate(switch_.getSelector(), J.ControlParentheses.class, p); + visitAndValidate(switch_.getCases(), J.Block.class, p); + return switch_; + } + + @Override + public J.SwitchExpression visitSwitchExpression(J.SwitchExpression switchExpression, P p) { + visitAndValidate(switchExpression.getSelector(), J.ControlParentheses.class, p); + visitAndValidate(switchExpression.getCases(), J.Block.class, p); + return switchExpression; + } + + @Override + public J.Synchronized visitSynchronized(J.Synchronized synchronized_, P p) { + visitAndValidate(synchronized_.getLock(), J.ControlParentheses.class, p); + visitAndValidate(synchronized_.getBody(), J.Block.class, p); + return synchronized_; + } + + @Override + public J.Ternary visitTernary(J.Ternary ternary, P p) { + visitAndValidate(ternary.getCondition(), Expression.class, p); + return ternary; + } + + @Override + public J.Throw visitThrow(J.Throw throw_, P p) { + visitAndValidate(throw_.getException(), Expression.class, p); + return throw_; + } + + @Override + public J.Try visitTry(J.Try try_, P p) { + visitAndValidate(try_.getBody(), J.Block.class, p); + ListUtils.map(try_.getCatches(), el -> visitAndValidate(el, J.Try.Catch.class, p)); + return try_; + } + + @Override + public J.Try.Resource visitTryResource(J.Try.Resource resource, P p) { + visitAndValidate(resource.getVariableDeclarations(), TypedTree.class, p); + return resource; + } + + @Override + public J.Try.Catch visitCatch(J.Try.Catch catch_, P p) { + visitAndValidate(catch_.getParameter(), J.ControlParentheses.class, p); + visitAndValidate(catch_.getBody(), J.Block.class, p); + return catch_; + } + + @Override + public J.TypeCast visitTypeCast(J.TypeCast typeCast, P p) { + visitAndValidate(typeCast.getClazz(), J.ControlParentheses.class, p); + visitAndValidate(typeCast.getExpression(), Expression.class, p); + return typeCast; + } + + @Override + public J.TypeParameter visitTypeParameter(J.TypeParameter typeParameter, P p) { + ListUtils.map(typeParameter.getAnnotations(), el -> visitAndValidate(el, J.Annotation.class, p)); + ListUtils.map(typeParameter.getModifiers(), el -> visitAndValidate(el, J.Modifier.class, p)); + visitAndValidate(typeParameter.getName(), Expression.class, p); + return typeParameter; + } + + @Override + public J.Unary visitUnary(J.Unary unary, P p) { + visitAndValidate(unary.getExpression(), Expression.class, p); + return unary; + } + + @Override + public J.VariableDeclarations visitVariableDeclarations(J.VariableDeclarations variableDeclarations, P p) { + ListUtils.map(variableDeclarations.getLeadingAnnotations(), el -> visitAndValidate(el, J.Annotation.class, p)); + ListUtils.map(variableDeclarations.getModifiers(), el -> visitAndValidate(el, J.Modifier.class, p)); + visitAndValidate(variableDeclarations.getTypeExpression(), TypeTree.class, p); + ListUtils.map(variableDeclarations.getVariables(), el -> visitAndValidate(el, J.VariableDeclarations.NamedVariable.class, p)); + return variableDeclarations; + } + + @Override + public J.VariableDeclarations.NamedVariable visitVariable(J.VariableDeclarations.NamedVariable namedVariable, P p) { + visitAndValidate(namedVariable.getName(), J.Identifier.class, p); + return namedVariable; + } + + @Override + public J.WhileLoop visitWhileLoop(J.WhileLoop whileLoop, P p) { + visitAndValidate(whileLoop.getCondition(), J.ControlParentheses.class, p); + return whileLoop; + } + + @Override + public J.Wildcard visitWildcard(J.Wildcard wildcard, P p) { + visitAndValidate(wildcard.getBoundedType(), NameTree.class, p); + return wildcard; + } + + @Override + public J.Yield visitYield(J.Yield yield, P p) { + visitAndValidate(yield.getValue(), Expression.class, p); + return yield; + } + + @Override + public J.Unknown visitUnknown(J.Unknown unknown, P p) { + visitAndValidate(unknown.getSource(), J.Unknown.Source.class, p); + return unknown; + } + + @Override + public J.Unknown.Source visitUnknownSource(J.Unknown.Source source, P p) { + return source; + } + +} From bbd8ce97831f201e9f75b45ba9c4780f321d1640 Mon Sep 17 00:00:00 2001 From: Knut Wannheden Date: Wed, 20 Nov 2024 15:08:30 +0100 Subject: [PATCH 2/6] Add two missing visit calls --- .../java/org/openrewrite/javascript/JavaScriptValidator.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptValidator.java b/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptValidator.java index 1cb5b82d..25aac2df 100644 --- a/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptValidator.java +++ b/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptValidator.java @@ -543,11 +543,13 @@ public J.ParameterizedType visitParameterizedType(J.ParameterizedType parameteri @Override public J.Parentheses visitParentheses(J.Parentheses parentheses, P p) { + visitAndValidate(parentheses.getTree(), J.class, p); return parentheses; } @Override public J.ControlParentheses visitControlParentheses(J.ControlParentheses controlParentheses, P p) { + visitAndValidate(controlParentheses.getTree(), J.class, p); return controlParentheses; } From 2e6aa04413856c876d3934393ad042698291f3c3 Mon Sep 17 00:00:00 2001 From: Knut Wannheden Date: Wed, 20 Nov 2024 15:16:57 +0100 Subject: [PATCH 3/6] Add a few more missing calls --- .../javascript/JavaScriptValidator.java | 79 +++++++++++++++++-- 1 file changed, 74 insertions(+), 5 deletions(-) diff --git a/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptValidator.java b/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptValidator.java index 25aac2df..e3cbd294 100644 --- a/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptValidator.java +++ b/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptValidator.java @@ -23,13 +23,10 @@ package org.openrewrite.javascript; import org.jspecify.annotations.Nullable; -import org.openrewrite.*; +import org.openrewrite.Tree; import org.openrewrite.internal.ListUtils; -import org.openrewrite.marker.Markers; -import org.openrewrite.tree.*; -import org.openrewrite.java.JavaVisitor; import org.openrewrite.java.tree.*; -import org.openrewrite.javascript.tree.*; +import org.openrewrite.javascript.tree.JS; import java.util.List; @@ -56,6 +53,7 @@ public JS.CompilationUnit visitCompilationUnit(JS.CompilationUnit compilationUni @Override public JS.Alias visitAlias(JS.Alias alias, P p) { + visitAndValidate(alias.getPropertyName(), J.Identifier.class, p); visitAndValidate(alias.getAlias(), J.Identifier.class, p); return alias; } @@ -92,7 +90,9 @@ public JS.Delete visitDelete(JS.Delete delete, P p) { @Override public JS.Export visitExport(JS.Export export, P p) { + visitAndValidate(export.getExports(), Expression.class, p); visitAndValidate(export.getTarget(), J.Literal.class, p); + visitAndValidate(export.getInitializer(), Expression.class, p); return export; } @@ -104,13 +104,17 @@ public JS.ExpressionStatement visitExpressionStatement(JS.ExpressionStatement ex @Override public JS.FunctionType visitFunctionType(JS.FunctionType functionType, P p) { + visitAndValidate(functionType.getParameters(), Statement.class, p); visitAndValidate(functionType.getReturnType(), Expression.class, p); return functionType; } @Override public JS.JsImport visitJsImport(JS.JsImport jsImport, P p) { + visitAndValidate(jsImport.getName(), J.Identifier.class, p); + visitAndValidate(jsImport.getImports(), Expression.class, p); visitAndValidate(jsImport.getTarget(), J.Literal.class, p); + visitAndValidate(jsImport.getInitializer(), Expression.class, p); return jsImport; } @@ -132,17 +136,22 @@ public JS.ObjectBindingDeclarations visitObjectBindingDeclarations(JS.ObjectBind ListUtils.map(objectBindingDeclarations.getLeadingAnnotations(), el -> visitAndValidate(el, J.Annotation.class, p)); ListUtils.map(objectBindingDeclarations.getModifiers(), el -> visitAndValidate(el, J.Modifier.class, p)); visitAndValidate(objectBindingDeclarations.getTypeExpression(), TypeTree.class, p); + visitAndValidate(objectBindingDeclarations.getBindings(), JS.ObjectBindingDeclarations.Binding.class, p); + visitAndValidate(objectBindingDeclarations.getInitializer(), Expression.class, p); return objectBindingDeclarations; } @Override public JS.ObjectBindingDeclarations.Binding visitBinding(JS.ObjectBindingDeclarations.Binding binding, P p) { + visitAndValidate(binding.getPropertyName(), J.Identifier.class, p); visitAndValidate(binding.getName(), TypedTree.class, p); + visitAndValidate(binding.getInitializer(), Expression.class, p); return binding; } @Override public JS.PropertyAssignment visitPropertyAssignment(JS.PropertyAssignment propertyAssignment, P p) { + visitAndValidate(propertyAssignment.getName(), Expression.class, p); visitAndValidate(propertyAssignment.getInitializer(), Expression.class, p); return propertyAssignment; } @@ -162,6 +171,7 @@ public JS.StatementExpression visitStatementExpression(JS.StatementExpression st @Override public JS.TemplateExpression visitTemplateExpression(JS.TemplateExpression templateExpression, P p) { + visitAndValidate(templateExpression.getTag(), Expression.class, p); ListUtils.map(templateExpression.getStrings(), el -> visitAndValidate(el, J.class, p)); return templateExpression; } @@ -174,6 +184,7 @@ public JS.TemplateExpression.Value visitTemplateExpressionValue(JS.TemplateExpre @Override public JS.Tuple visitTuple(JS.Tuple tuple, P p) { + visitAndValidate(tuple.getElements(), J.class, p); return tuple; } @@ -182,6 +193,7 @@ public JS.TypeDeclaration visitTypeDeclaration(JS.TypeDeclaration typeDeclaratio ListUtils.map(typeDeclaration.getModifiers(), el -> visitAndValidate(el, J.Modifier.class, p)); visitAndValidate(typeDeclaration.getName(), J.Identifier.class, p); visitAndValidate(typeDeclaration.getTypeParameters(), J.TypeParameters.class, p); + visitAndValidate(typeDeclaration.getInitializer(), Expression.class, p); return typeDeclaration; } @@ -193,6 +205,7 @@ public JS.TypeOf visitTypeOf(JS.TypeOf typeOf, P p) { @Override public JS.TypeOperator visitTypeOperator(JS.TypeOperator typeOperator, P p) { + visitAndValidate(typeOperator.getExpression(), Expression.class, p); return typeOperator; } @@ -238,6 +251,7 @@ public JS.JSVariableDeclarations visitJSVariableDeclarations(JS.JSVariableDeclar @Override public JS.JSVariableDeclarations.JSNamedVariable visitJSVariableDeclarationsJSNamedVariable(JS.JSVariableDeclarations.JSNamedVariable jSNamedVariable, P p) { visitAndValidate(jSNamedVariable.getName(), Expression.class, p); + visitAndValidate(jSNamedVariable.getInitializer(), Expression.class, p); return jSNamedVariable; } @@ -248,19 +262,26 @@ public JS.JSMethodDeclaration visitJSMethodDeclaration(JS.JSMethodDeclaration jS visitAndValidate(jSMethodDeclaration.getTypeParameters(), J.TypeParameters.class, p); visitAndValidate(jSMethodDeclaration.getReturnTypeExpression(), TypeTree.class, p); visitAndValidate(jSMethodDeclaration.getName(), Expression.class, p); + visitAndValidate(jSMethodDeclaration.getParameters(), Statement.class, p); + visitAndValidate(jSMethodDeclaration.getThrowz(), NameTree.class, p); visitAndValidate(jSMethodDeclaration.getBody(), J.Block.class, p); + visitAndValidate(jSMethodDeclaration.getDefaultValue(), Expression.class, p); return jSMethodDeclaration; } @Override public JS.JSMethodInvocation visitJSMethodInvocation(JS.JSMethodInvocation jSMethodInvocation, P p) { + visitAndValidate(jSMethodInvocation.getSelect(), Expression.class, p); + visitAndValidate(jSMethodInvocation.getTypeParameters(), Expression.class, p); visitAndValidate(jSMethodInvocation.getName(), Expression.class, p); + visitAndValidate(jSMethodInvocation.getArguments(), Expression.class, p); return jSMethodInvocation; } @Override public JS.NamespaceDeclaration visitNamespaceDeclaration(JS.NamespaceDeclaration namespaceDeclaration, P p) { ListUtils.map(namespaceDeclaration.getModifiers(), el -> visitAndValidate(el, J.Modifier.class, p)); + visitAndValidate(namespaceDeclaration.getName(), Expression.class, p); visitAndValidate(namespaceDeclaration.getBody(), J.Block.class, p); return namespaceDeclaration; } @@ -270,6 +291,7 @@ public JS.FunctionDeclaration visitFunctionDeclaration(JS.FunctionDeclaration fu ListUtils.map(functionDeclaration.getModifiers(), el -> visitAndValidate(el, J.Modifier.class, p)); visitAndValidate(functionDeclaration.getName(), J.Identifier.class, p); visitAndValidate(functionDeclaration.getTypeParameters(), J.TypeParameters.class, p); + visitAndValidate(functionDeclaration.getParameters(), Statement.class, p); visitAndValidate(functionDeclaration.getReturnTypeExpression(), TypeTree.class, p); visitAndValidate(functionDeclaration.getBody(), J.class, p); return functionDeclaration; @@ -285,6 +307,7 @@ public J.AnnotatedType visitAnnotatedType(J.AnnotatedType annotatedType, P p) { @Override public J.Annotation visitAnnotation(J.Annotation annotation, P p) { visitAndValidate(annotation.getAnnotationType(), NameTree.class, p); + visitAndValidate(annotation.getArguments(), Expression.class, p); return annotation; } @@ -305,12 +328,14 @@ public J.ArrayType visitArrayType(J.ArrayType arrayType, P p) { @Override public J.Assert visitAssert(J.Assert assert_, P p) { visitAndValidate(assert_.getCondition(), Expression.class, p); + visitAndValidate(assert_.getDetail().getElement(), Expression.class, p); return assert_; } @Override public J.Assignment visitAssignment(J.Assignment assignment, P p) { visitAndValidate(assignment.getVariable(), Expression.class, p); + visitAndValidate(assignment.getAssignment(), Expression.class, p); return assignment; } @@ -342,6 +367,9 @@ public J.Break visitBreak(J.Break break_, P p) { @Override public J.Case visitCase(J.Case case_, P p) { + visitAndValidate(case_.getExpressions(), Expression.class, p); + visitAndValidate(case_.getStatements(), Statement.class, p); + visitAndValidate(case_.getBody(), J.class, p); return case_; } @@ -351,6 +379,11 @@ public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDeclarat ListUtils.map(classDeclaration.getModifiers(), el -> visitAndValidate(el, J.Modifier.class, p)); visit(classDeclaration.getPadding().getKind(), p); visitAndValidate(classDeclaration.getName(), J.Identifier.class, p); + visitAndValidate(classDeclaration.getTypeParameters(), J.TypeParameter.class, p); + visitAndValidate(classDeclaration.getPrimaryConstructor(), Statement.class, p); + visitAndValidate(classDeclaration.getExtends(), TypeTree.class, p); + visitAndValidate(classDeclaration.getImplements(), TypeTree.class, p); + visitAndValidate(classDeclaration.getPermits(), TypeTree.class, p); visitAndValidate(classDeclaration.getBody(), J.Block.class, p); return classDeclaration; } @@ -363,6 +396,8 @@ public J.Continue visitContinue(J.Continue continue_, P p) { @Override public J.DoWhileLoop visitDoWhileLoop(J.DoWhileLoop doWhileLoop, P p) { + visitAndValidate(doWhileLoop.getBody(), Statement.class, p); + visitAndValidate(doWhileLoop.getWhileCondition(), Expression.class, p); return doWhileLoop; } @@ -388,29 +423,35 @@ public J.EnumValueSet visitEnumValueSet(J.EnumValueSet enumValueSet, P p) { @Override public J.FieldAccess visitFieldAccess(J.FieldAccess fieldAccess, P p) { visitAndValidate(fieldAccess.getTarget(), Expression.class, p); + visitAndValidate(fieldAccess.getName(), J.Identifier.class, p); return fieldAccess; } @Override public J.ForEachLoop visitForEachLoop(J.ForEachLoop forEachLoop, P p) { visitAndValidate(forEachLoop.getControl(), J.ForEachLoop.Control.class, p); + visitAndValidate(forEachLoop.getBody(), Statement.class, p); return forEachLoop; } @Override public J.ForEachLoop.Control visitForEachControl(J.ForEachLoop.Control control, P p) { + visitAndValidate(control.getVariable(), J.VariableDeclarations.class, p); + visitAndValidate(control.getIterable(), Expression.class, p); return control; } @Override public J.ForLoop visitForLoop(J.ForLoop forLoop, P p) { visitAndValidate(forLoop.getControl(), J.ForLoop.Control.class, p); + visitAndValidate(forLoop.getBody(), Statement.class, p); return forLoop; } @Override public J.ForLoop.Control visitForControl(J.ForLoop.Control control, P p) { ListUtils.map(control.getInit(), el -> visitAndValidate(el, Statement.class, p)); + visitAndValidate(control.getCondition(), Expression.class, p); ListUtils.map(control.getUpdate(), el -> visitAndValidate(el, Statement.class, p)); return control; } @@ -431,23 +472,27 @@ public J.Identifier visitIdentifier(J.Identifier identifier, P p) { @Override public J.If visitIf(J.If if_, P p) { visitAndValidate(if_.getIfCondition(), J.ControlParentheses.class, p); + visitAndValidate(if_.getThenPart(), Statement.class, p); visitAndValidate(if_.getElsePart(), J.If.Else.class, p); return if_; } @Override public J.If.Else visitElse(J.If.Else else_, P p) { + visitAndValidate(else_.getBody(), Statement.class, p); return else_; } @Override public J.Import visitImport(J.Import import_, P p) { visitAndValidate(import_.getQualid(), J.FieldAccess.class, p); + visitAndValidate(import_.getAlias(), J.Identifier.class, p); return import_; } @Override public J.InstanceOf visitInstanceOf(J.InstanceOf instanceOf, P p) { + visitAndValidate(instanceOf.getExpression(), Expression.class, p); visitAndValidate(instanceOf.getClazz(), J.class, p); visitAndValidate(instanceOf.getPattern(), J.class, p); return instanceOf; @@ -455,11 +500,13 @@ public J.InstanceOf visitInstanceOf(J.InstanceOf instanceOf, P p) { @Override public J.IntersectionType visitIntersectionType(J.IntersectionType intersectionType, P p) { + visitAndValidate(intersectionType.getBounds(), TypeTree.class, p); return intersectionType; } @Override public J.Label visitLabel(J.Label label, P p) { + visitAndValidate(label.getLabel(), J.Identifier.class, p); visitAndValidate(label.getStatement(), Statement.class, p); return label; } @@ -478,6 +525,9 @@ public J.Literal visitLiteral(J.Literal literal, P p) { @Override public J.MemberReference visitMemberReference(J.MemberReference memberReference, P p) { + visitAndValidate(memberReference.getContaining(), Expression.class, p); + visitAndValidate(memberReference.getTypeParameters(), Expression.class, p); + visitAndValidate(memberReference.getReference(), J.Identifier.class, p); return memberReference; } @@ -487,13 +537,19 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration methodDecl ListUtils.map(methodDeclaration.getModifiers(), el -> visitAndValidate(el, J.Modifier.class, p)); visitAndValidate(methodDeclaration.getTypeParameters(), J.TypeParameters.class, p); visitAndValidate(methodDeclaration.getReturnTypeExpression(), TypeTree.class, p); + visitAndValidate(methodDeclaration.getParameters(), Statement.class, p); + visitAndValidate(methodDeclaration.getThrows(), NameTree.class, p); visitAndValidate(methodDeclaration.getBody(), J.Block.class, p); + visitAndValidate(methodDeclaration.getDefaultValue(), Expression.class, p); return methodDeclaration; } @Override public J.MethodInvocation visitMethodInvocation(J.MethodInvocation methodInvocation, P p) { + visitAndValidate(methodInvocation.getSelect(), Expression.class, p); + visitAndValidate(methodInvocation.getTypeParameters(), Expression.class, p); visitAndValidate(methodInvocation.getName(), J.Identifier.class, p); + visitAndValidate(methodInvocation.getArguments(), Expression.class, p); return methodInvocation; } @@ -507,17 +563,21 @@ public J.MultiCatch visitMultiCatch(J.MultiCatch multiCatch, P p) { public J.NewArray visitNewArray(J.NewArray newArray, P p) { visitAndValidate(newArray.getTypeExpression(), TypeTree.class, p); ListUtils.map(newArray.getDimensions(), el -> visitAndValidate(el, J.ArrayDimension.class, p)); + visitAndValidate(newArray.getInitializer(), Expression.class, p); return newArray; } @Override public J.ArrayDimension visitArrayDimension(J.ArrayDimension arrayDimension, P p) { + visitAndValidate(arrayDimension.getIndex(), Expression.class, p); return arrayDimension; } @Override public J.NewClass visitNewClass(J.NewClass newClass, P p) { + visitAndValidate(newClass.getEnclosing(), Expression.class, p); visitAndValidate(newClass.getClazz(), TypeTree.class, p); + visitAndValidate(newClass.getArguments(), Expression.class, p); visitAndValidate(newClass.getBody(), J.Block.class, p); return newClass; } @@ -525,6 +585,7 @@ public J.NewClass visitNewClass(J.NewClass newClass, P p) { @Override public J.NullableType visitNullableType(J.NullableType nullableType, P p) { ListUtils.map(nullableType.getAnnotations(), el -> visitAndValidate(el, J.Annotation.class, p)); + visitAndValidate(nullableType.getTypeTree(), TypeTree.class, p); return nullableType; } @@ -538,6 +599,7 @@ public J.Package visitPackage(J.Package package_, P p) { @Override public J.ParameterizedType visitParameterizedType(J.ParameterizedType parameterizedType, P p) { visitAndValidate(parameterizedType.getClazz(), NameTree.class, p); + visitAndValidate(parameterizedType.getTypeParameters(), Expression.class, p); return parameterizedType; } @@ -588,6 +650,8 @@ public J.Synchronized visitSynchronized(J.Synchronized synchronized_, P p) { @Override public J.Ternary visitTernary(J.Ternary ternary, P p) { visitAndValidate(ternary.getCondition(), Expression.class, p); + visitAndValidate(ternary.getTruePart(), Expression.class, p); + visitAndValidate(ternary.getFalsePart(), Expression.class, p); return ternary; } @@ -599,8 +663,10 @@ public J.Throw visitThrow(J.Throw throw_, P p) { @Override public J.Try visitTry(J.Try try_, P p) { + visitAndValidate(try_.getResources(), J.Try.Resource.class, p); visitAndValidate(try_.getBody(), J.Block.class, p); ListUtils.map(try_.getCatches(), el -> visitAndValidate(el, J.Try.Catch.class, p)); + visitAndValidate(try_.getFinally(), J.Block.class, p); return try_; } @@ -629,6 +695,7 @@ public J.TypeParameter visitTypeParameter(J.TypeParameter typeParameter, P p) { ListUtils.map(typeParameter.getAnnotations(), el -> visitAndValidate(el, J.Annotation.class, p)); ListUtils.map(typeParameter.getModifiers(), el -> visitAndValidate(el, J.Modifier.class, p)); visitAndValidate(typeParameter.getName(), Expression.class, p); + visitAndValidate(typeParameter.getBounds(), TypeTree.class, p); return typeParameter; } @@ -650,12 +717,14 @@ public J.VariableDeclarations visitVariableDeclarations(J.VariableDeclarations v @Override public J.VariableDeclarations.NamedVariable visitVariable(J.VariableDeclarations.NamedVariable namedVariable, P p) { visitAndValidate(namedVariable.getName(), J.Identifier.class, p); + visitAndValidate(namedVariable.getInitializer(), Expression.class, p); return namedVariable; } @Override public J.WhileLoop visitWhileLoop(J.WhileLoop whileLoop, P p) { visitAndValidate(whileLoop.getCondition(), J.ControlParentheses.class, p); + visitAndValidate(whileLoop.getBody(), Statement.class, p); return whileLoop; } From 173d7bb30e8c7a397a0ece3a766307058478b984 Mon Sep 17 00:00:00 2001 From: Knut Wannheden Date: Fri, 22 Nov 2024 09:15:08 +0100 Subject: [PATCH 4/6] Move and register validator --- .../remote/JavaScriptSenderReceiverProvider.java | 6 ++++++ .../javascript/remote}/JavaScriptValidator.java | 12 ++++++++---- .../org/openrewrite/javascript/JavaScriptParser.java | 8 +++++--- 3 files changed, 19 insertions(+), 7 deletions(-) rename {rewrite-javascript/src/main/java/org/openrewrite/javascript => rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote}/JavaScriptValidator.java (98%) diff --git a/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptSenderReceiverProvider.java b/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptSenderReceiverProvider.java index 0a2426f6..2c8393d2 100644 --- a/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptSenderReceiverProvider.java +++ b/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptSenderReceiverProvider.java @@ -20,6 +20,7 @@ import org.openrewrite.remote.Receiver; import org.openrewrite.remote.Sender; import org.openrewrite.remote.SenderReceiverProvider; +import org.openrewrite.remote.Validator; @AutoService(SenderReceiverProvider.class) public class JavaScriptSenderReceiverProvider implements SenderReceiverProvider { @@ -37,4 +38,9 @@ public Sender newSender() { public Receiver newReceiver() { return new JavaScriptReceiver(); } + + @Override + public Validator newValidator() { + return Validator.fromVisitor(new JavaScriptValidator<>()); + } } diff --git a/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptValidator.java b/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptValidator.java similarity index 98% rename from rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptValidator.java rename to rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptValidator.java index e3cbd294..ced300da 100644 --- a/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptValidator.java +++ b/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptValidator.java @@ -20,13 +20,17 @@ * the code is regenerated. */ -package org.openrewrite.javascript; +package org.openrewrite.javascript.remote; import org.jspecify.annotations.Nullable; -import org.openrewrite.Tree; +import org.openrewrite.*; import org.openrewrite.internal.ListUtils; +import org.openrewrite.marker.Markers; +import org.openrewrite.tree.*; +import org.openrewrite.java.JavaVisitor; import org.openrewrite.java.tree.*; -import org.openrewrite.javascript.tree.JS; +import org.openrewrite.javascript.JavaScriptIsoVisitor; +import org.openrewrite.javascript.tree.*; import java.util.List; @@ -34,7 +38,7 @@ class JavaScriptValidator

extends JavaScriptIsoVisitor

{ private @Nullable T visitAndValidate(@Nullable T tree, Class expected, P p) { if (tree != null && !expected.isInstance(tree)) { - throw new IllegalStateException("Type " + tree.getClass() + " is not assignable to " + expected); + throw new ClassCastException("Type " + tree.getClass() + " is not assignable to " + expected); } // noinspection unchecked return (T) visit(tree, p); diff --git a/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptParser.java b/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptParser.java index 3e7a0e19..112f0e80 100644 --- a/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptParser.java +++ b/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptParser.java @@ -25,6 +25,7 @@ import org.openrewrite.remote.RemotingContext; import org.openrewrite.remote.RemotingExecutionContextView; import org.openrewrite.remote.RemotingMessenger; +import org.openrewrite.remote.Validator; import org.openrewrite.remote.java.RemotingClient; import org.openrewrite.style.NamedStyles; import org.openrewrite.text.PlainTextParser; @@ -135,13 +136,14 @@ public Stream parseInputs(Iterable inputs, @Nullable Path rel } private SourceFile validate(JS.CompilationUnit sourceFile, Input input, @Nullable Path relativeTo, ExecutionContext ctx) { - JavaScriptValidator typeValidator = new JavaScriptValidator<>(); + assert remotingContext != null; + Validator validator = remotingContext.getProvider(sourceFile.getClass()).newValidator(); try { - typeValidator.visit(sourceFile, 0); - return requirePrintEqualsInput(sourceFile, input, relativeTo, ctx); + validator.validate(sourceFile, ctx); } catch (Exception e) { return ParseError.build(this, input, relativeTo, ctx, new IllegalStateException("LST model has type validation errors", e)); } + return requirePrintEqualsInput(sourceFile, input, relativeTo, ctx); } private final static List EXTENSIONS = Collections.unmodifiableList(Arrays.asList( From 1da09b0ec43edcbae4204960e9b7913c9199d55c Mon Sep 17 00:00:00 2001 From: Knut Wannheden Date: Fri, 22 Nov 2024 09:41:03 +0100 Subject: [PATCH 5/6] Polish --- .../main/java/org/openrewrite/javascript/JavaScriptParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptParser.java b/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptParser.java index 112f0e80..020d1249 100644 --- a/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptParser.java +++ b/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptParser.java @@ -141,7 +141,7 @@ private SourceFile validate(JS.CompilationUnit sourceFile, Input input, @Nullabl try { validator.validate(sourceFile, ctx); } catch (Exception e) { - return ParseError.build(this, input, relativeTo, ctx, new IllegalStateException("LST model has type validation errors", e)); + return ParseError.build(this, input, relativeTo, ctx, e); } return requirePrintEqualsInput(sourceFile, input, relativeTo, ctx); } From 82897f8b54095b01e121ec667ef5fca2e2b4db14 Mon Sep 17 00:00:00 2001 From: Knut Wannheden Date: Fri, 22 Nov 2024 10:05:06 +0100 Subject: [PATCH 6/6] `J.MethodDeclaration#typeParameters` has a non-standard accessor --- .../remote/JavaScriptValidator.java | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptValidator.java b/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptValidator.java index ced300da..6c66ec31 100644 --- a/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptValidator.java +++ b/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptValidator.java @@ -23,14 +23,11 @@ package org.openrewrite.javascript.remote; import org.jspecify.annotations.Nullable; -import org.openrewrite.*; +import org.openrewrite.Tree; import org.openrewrite.internal.ListUtils; -import org.openrewrite.marker.Markers; -import org.openrewrite.tree.*; -import org.openrewrite.java.JavaVisitor; import org.openrewrite.java.tree.*; import org.openrewrite.javascript.JavaScriptIsoVisitor; -import org.openrewrite.javascript.tree.*; +import org.openrewrite.javascript.tree.JS; import java.util.List; @@ -225,6 +222,12 @@ public JS.Union visitUnion(JS.Union union, P p) { return union; } + @Override + public JS.Intersection visitIntersection(JS.Intersection intersection, P p) { + ListUtils.map(intersection.getTypes(), el -> visitAndValidate(el, Expression.class, p)); + return intersection; + } + @Override public JS.Void visitVoid(JS.Void void_, P p) { visitAndValidate(void_.getExpression(), Expression.class, p); @@ -301,6 +304,20 @@ public JS.FunctionDeclaration visitFunctionDeclaration(JS.FunctionDeclaration fu return functionDeclaration; } + @Override + public JS.TypeLiteral visitTypeLiteral(JS.TypeLiteral typeLiteral, P p) { + visitAndValidate(typeLiteral.getMembers(), J.Block.class, p); + return typeLiteral; + } + + @Override + public JS.IndexSignatureDeclaration visitIndexSignatureDeclaration(JS.IndexSignatureDeclaration indexSignatureDeclaration, P p) { + ListUtils.map(indexSignatureDeclaration.getModifiers(), el -> visitAndValidate(el, J.Modifier.class, p)); + visitAndValidate(indexSignatureDeclaration.getParameters(), J.class, p); + visitAndValidate(indexSignatureDeclaration.getTypeExpression(), Expression.class, p); + return indexSignatureDeclaration; + } + @Override public J.AnnotatedType visitAnnotatedType(J.AnnotatedType annotatedType, P p) { ListUtils.map(annotatedType.getAnnotations(), el -> visitAndValidate(el, J.Annotation.class, p)); @@ -539,7 +556,7 @@ public J.MemberReference visitMemberReference(J.MemberReference memberReference, public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration methodDeclaration, P p) { ListUtils.map(methodDeclaration.getLeadingAnnotations(), el -> visitAndValidate(el, J.Annotation.class, p)); ListUtils.map(methodDeclaration.getModifiers(), el -> visitAndValidate(el, J.Modifier.class, p)); - visitAndValidate(methodDeclaration.getTypeParameters(), J.TypeParameters.class, p); + visitAndValidate(methodDeclaration.getPadding().getTypeParameters(), J.TypeParameters.class, p); visitAndValidate(methodDeclaration.getReturnTypeExpression(), TypeTree.class, p); visitAndValidate(methodDeclaration.getParameters(), Statement.class, p); visitAndValidate(methodDeclaration.getThrows(), NameTree.class, p);