JavaScript: fix non-FQ type on enum declarations and harden parseProject#7425
Merged
knutwannheden merged 1 commit intomainfrom Apr 19, 2026
Merged
JavaScript: fix non-FQ type on enum declarations and harden parseProject#7425knutwannheden merged 1 commit intomainfrom
parseProject#7425knutwannheden merged 1 commit intomainfrom
Conversation
parseProject
…parseProject` A string or numeric enum was parsed with `mapType(enumDecl)`, which calls `getTypeAtLocation`. TypeScript resolves that to the union of enum literals — for a string enum this ends up as `Type.Primitive.String`. The Java-side RPC receiver then failed with "A class can only be type attributed with a fully qualified type name" in `J.ClassDeclaration.withType`, aborting the entire stream of parsed source files. Resolve class/interface/enum/class-expression declaration types via the declaration's symbol (`getDeclaredTypeOfSymbol` for classes/interfaces; a minimal class shell with the declaration's FQN and `classKind` for enums, since TypeScript has no class-shaped enum type). The result is always `FullyQualified`. Also harden `parseProject`: wrap the per-file `getObject` in a try/catch so a single failing file becomes a `ParseError` instead of killing the stream, and add `sourcePath` to `ParseProjectResponse.Item` so those errors can point at the offending file. Fixes moderneinc/customer-requests#2234
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Building certain TypeScript projects — originally reported for nashtech-garage/yas — fails with:
The trigger turned out to be as small as:
Two separate problems combined to make this a project-killer rather than a per-file error:
The actual bug.
visitEnumDeclaration(and the otherJ.ClassDeclarationproducers:visitClassDeclaration,visitClassExpression,visitInterfaceDeclaration) set the node's type viamapType(node), which callschecker.getTypeAtLocation(node). TypeScript resolves this to the type of the declared value — for a string enum, that collapses to the union of string-literal members and on the JS side becomesType.Primitive.String. The Java side'sJ.ClassDeclaration.withTypevalidates that the type isFullyQualifiedand throws.No per-file resilience. The failure surfaced deep in RPC tree reconstruction (
getObject), which runs outside the try/catch inparseProject'stryAdvance. A single bad file therefore aborts the entire stream instead of degrading to aParseErrorfor that file.Summary
JavaScriptTypeMapping.declarationType(node), used byvisitClassDeclaration,visitClassExpression,visitInterfaceDeclaration, andvisitEnumDeclaration. It resolves the declared type through the declaration's symbol:getDeclaredTypeOfSymbolyields a class-shapedts.Typethat feeds through the existing pipeline (members, methods, supertypes, type parameters preserved).Type.ClasswithclassKind = Enumand the declaration's own FQN. This preserves theFullyQualifiedinvariant.getFullyQualifiedNameFromSymbol(symbol)helper so the FQN logic works directly from a symbol.getObject(...)call inJavaScriptRewriteRpc.parseProjectwith a try/catch. On failure we produce aParseErrorthat points at the offending file and continue iterating.sourcePathfield toParseProjectResponse.Item/ParseProjectResponseItemso the Java side can report which file failed whengetObjectthrows.parseStringEnumDeclarationthat parses a string enum over RPC and asserts the resultingJ.ClassDeclarationcarries aJavaType.ClasswithKind.Enumand the right FQN.Test plan
JavaScriptRewriteRpcTest.parseStringEnumDeclarationpassesJavaScriptRewriteRpcTestsuite passesnpm run testhelper -- test/javascript/parser/— 627 passed / 6 skippednashtech-garage/yas/backofficetree (206 source files) now completes withparseErrors=0, where previously it aborted mid-stream.