Skip to content

Handle object literal default values on custom scalar input fields - #985

Open
reginaldalfret wants to merge 1 commit into
Netflix:masterfrom
reginaldalfret:fix/object-literal-default-on-custom-scalar
Open

reginaldalfret wants to merge 1 commit into
Netflix:masterfrom
reginaldalfret:fix/object-literal-default-on-custom-scalar

Conversation

@reginaldalfret

Copy link
Copy Markdown

Fixes #982

Problem

When an input field type is a custom scalar with an object literal default value (for example: \metadata: JSON = {}), the default value generators in \DataTypeGenerator.kt\ (Java) and \GenerateKotlinCode.kt\ (Kotlin) assumed the field type was an input object and called \inputTypeDefinitions.first { ... }. This threw \NoSuchElementException: Collection contains no element matching the predicate.\ because custom scalars are not present in \inputTypeDefinitions.

Furthermore, \JavaTypeName.className\ and \TypeName.className\ assumed any \ParameterizedTypeName\ was a \List\ and grabbed \ ypeArguments().first().className, which extracted the key type (e.g. \String) instead of the raw type \Map\ when mapped to a \Map<String, Object>.

Solution

  1. In \DataTypeGenerator.kt\ and \GenerateKotlinCode.kt, use \ irstOrNull\ when looking up input object definitions. If none matches (such as for custom scalars), handle gracefully: emit \Collections.emptyMap()\ (Java) / \emptyMap()\ (Kotlin) when mapped to a \Map\ type, or fallback without raising an unhandled exception.
  2. In \JavaTypeName.className\ and \TypeName.className, only unwrap \ ypeArguments[0]\ for \List\ parameterized types, preserving the raw type for other parameterized types such as \Map.
  3. In \TestUtils.kt, use \File.pathSeparator\ instead of hardcoding :\ so tests run reliably on all platforms.
  4. Added regression tests in \CodeGenTest\ and \KotlinCodeGenTest\ verifying that input fields with custom scalar types and object literal defaults generate valid Java and Kotlin code.

When an input field type is a custom scalar with an object literal default value (e.g. metadata: JSON = {}), the default value generators in DataTypeGenerator (Java) and GenerateKotlinCode (Kotlin) previously assumed the field type was an input object and invoked inputTypeDefinitions.first { ... }, throwing NoSuchElementException because no input type definition matches.

Additionally, JavaTypeName.className and TypeName.className assumed ParameterizedTypeName was always a List and accessed the first type argument, which returned the key type rather than raw Map when mapped to a Map.

This change:
1. Uses firstOrNull in DataTypeGenerator and GenerateKotlinCode to gracefully handle non-input-object types, emitting emptyMap() or fallback initializers for Map scalars.
2. Updates JavaTypeName.className and TypeName.className to preserve rawType for non-List parameterized types like Map.
3. Uses cross-platform File.pathSeparator in TestUtils.classpath().
4. Adds regression tests for both Java and Kotlin code generation.

Signed-off-by: reginaldalfret <reginaldalfret@gmail.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Object literal default value on a custom scalar fails with NoSuchElementException

1 participant