feat: richer hover info (signature, deprecation, defaults) - #411
Open
JoviDeCroock wants to merge 1 commit into
Open
feat: richer hover info (signature, deprecation, defaults)#411JoviDeCroock wants to merge 1 commit into
JoviDeCroock wants to merge 1 commit into
Conversation
Rework getGraphQLQuickInfo to resolve the hovered token via getTokenAtPosition/getTypeInfo directly instead of the flat string returned by getHoverInformation, and structure the ts.QuickInfo properly: - displayParts now carry a signature line, e.g. `Query.pokemons(limit: Int = 10, skip: Int): [Pokemon]`, with argument default values printed via astFromValue/print - deprecated fields/arguments/enum values render an `@deprecated: <reason>` documentation line (falling back to the spec default "No longer supported") plus a `deprecated` JSDocTagInfo so editors can render strikethrough - the schema description remains as documentation - hover now also resolves field/directive arguments, enum values, directives, and named types (fragment type conditions like `on Pokemon`) - unsupported tokens now return undefined so the original language service quick info shows through instead of an empty tooltip Adds e2e coverage for a field with arguments and a default value, a deprecated field (including tags), an argument hover, and a fragment type condition, and updates existing quickinfo assertions to the new displayString/documentation split. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 15ac3d5 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
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.
What / Why
Hovering a GraphQL field previously showed a single flat string (produced by
graphql-language-service'sgetHoverInformation) stuffed into the quick-infodocumentation, with nodisplayString, no argument info, and no deprecation notice. This PR upgradesgetGraphQLQuickInfoso hovers are structured like regular TypeScript quick info:displayParts→displayString):ParentType.fieldName: ReturnType, and for fields with argumentsParentType.fieldName(arg: ArgType = default): ReturnType. Types are printed as proper GraphQL types (String!,[Pokemon]), default values viaastFromValue+print.documentation+ adeprecatedJSDoc tag so editors can render strikethrough):@deprecated: <reason>, falling back to the GraphQL spec defaultNo longer supportedwhen the reason is empty.Hover now also resolves:
Query.pokemons(limit: Int = 10))PokemonType.Grassplus description/deprecation@includeplus descriptionon Pokemonshows the type and its descriptionImplementation notes
getHoverInformation(which returns a pre-joined string), the hover now uses the same underlying helpers —getTokenAtPosition+getTypeInfofromgraphql-language-service— and renders the pieces itself, so signature/deprecation/description can be placed into the rightts.QuickInfoslots (displayParts,documentation,tags). The token/cursor resolution code (call expression vs. tagged template, span math) is unchanged.getHoverInformation's:Field/AliasedField,Argument,Directive,EnumValue,NamedType. All of the requested positions (arguments, enum values, type conditions) were resolvable with the existing helpers, so no follow-ups were needed there.undefinedso theguard()fallback lets the original language service respond — previously an empty tooltip was returned.test/e2e/fixture-project-tada/schema.graphqlgained a default value (pokemons(limit: Int = 10, ...)) to cover default-value printing; this doesn't affect the generated gql.tada introspection (argument info isn't part of it).Before / After examples
Hovering
pokemonsinquery { pokemons(limit: $limit) { ... } }:Query.pokemons: [Pokemon]List out all Pokémon, optionally in pagesQuery.pokemons(limit: Int = 10, skip: Int): [Pokemon]List out all Pokémon, optionally in pagesHovering the deprecated
classificationfield:Pokemon.classification: StringDeprecated: And this is the reason whyPokemon.classification: String@deprecated: And this is the reason why[{ name: 'deprecated', text: 'And this is the reason why' }]Hovering the
limitargument (new — previously renderedQuery.pokemons(limit: Int)without the default):Query.pokemons(limit: Int = 10)Hovering
Pokemoninfragment pokemonFields on Pokemon(new): displayStringPokemon.Existing assertions in
tada.test.ts,graphqlsp.test.ts,combinations.test.ts,client-preset.test.ts, andmulti-schema-tada.test.tswere updated accordingly — e.g.documentation === 'Query.posts: [Post]\n\nList out all posts'becamedisplayString === 'Query.posts: [Post]'+documentation === 'List out all posts'.Test plan
pnpm --filter @0no-co/graphqlsp run build— passespnpm run test:e2e(full suite, forks a real tsserver) — 11 files / 55 tests, all passing, including new assertions for:deprecatedtag)Note: the pre-commit husky bootstrap (
.husky/_/husky.sh) is missing in fresh checkouts afterpnpm install, so the hook was bypassed after runningprettier --writeon all touched files manually (the hook only runs lint-staged/prettier).🤖 Generated with Claude Code