3939use TheCodingMachine \GraphQLite \Mappers \CannotMapTypeException ;
4040use TheCodingMachine \GraphQLite \Mappers \CannotMapTypeExceptionInterface ;
4141use TheCodingMachine \GraphQLite \Mappers \Root \RootTypeMapperInterface ;
42+ use TheCodingMachine \GraphQLite \Mappers \Root \UndefinedTypeMapper ;
4243use TheCodingMachine \GraphQLite \Parameters \DefaultValueParameter ;
4344use TheCodingMachine \GraphQLite \Parameters \InputTypeParameter ;
4445use TheCodingMachine \GraphQLite \Parameters \InputTypeProperty ;
4546use TheCodingMachine \GraphQLite \Parameters \ParameterInterface ;
4647use TheCodingMachine \GraphQLite \Reflection \DocBlock \DocBlockFactory ;
4748use TheCodingMachine \GraphQLite \Types \ArgumentResolver ;
4849use TheCodingMachine \GraphQLite \Types \TypeResolver ;
50+ use TheCodingMachine \GraphQLite \Undefined ;
4951
5052use function array_map ;
5153use function array_unique ;
@@ -177,6 +179,19 @@ public function mapParameter(
177179 return new DefaultValueParameter ($ parameter ->getDefaultValue ());
178180 }
179181
182+ $ parameterType = $ parameter ->getType ();
183+ $ allowsNull = $ parameterType === null || $ parameterType ->allowsNull ();
184+
185+ if ($ parameterType === null ) {
186+ $ phpdocType = new Mixed_ ();
187+ $ allowsNull = false ;
188+ //throw MissingTypeHintException::missingTypeHint($parameter);
189+ } else {
190+ $ declaringClass = $ parameter ->getDeclaringClass ();
191+ assert ($ declaringClass !== null );
192+ $ phpdocType = $ this ->reflectionTypeToPhpDocType ($ parameterType , $ declaringClass );
193+ }
194+
180195 $ useInputType = $ parameterAnnotations ->getAnnotationByType (UseInputType::class);
181196 if ($ useInputType !== null ) {
182197 try {
@@ -186,19 +201,6 @@ public function mapParameter(
186201 throw $ e ;
187202 }
188203 } else {
189- $ parameterType = $ parameter ->getType ();
190- $ allowsNull = $ parameterType === null || $ parameterType ->allowsNull ();
191-
192- if ($ parameterType === null ) {
193- $ phpdocType = new Mixed_ ();
194- $ allowsNull = false ;
195- //throw MissingTypeHintException::missingTypeHint($parameter);
196- } else {
197- $ declaringClass = $ parameter ->getDeclaringClass ();
198- assert ($ declaringClass !== null );
199- $ phpdocType = $ this ->reflectionTypeToPhpDocType ($ parameterType , $ declaringClass );
200- }
201-
202204 try {
203205 $ declaringFunction = $ parameter ->getDeclaringFunction ();
204206 if (! $ declaringFunction instanceof ReflectionMethod) {
@@ -220,24 +222,33 @@ public function mapParameter(
220222 }
221223 }
222224
223- $ description = $ this ->getParameterDescriptionFromDocBlock ($ docBlock , $ parameter );
224-
225225 $ hasDefaultValue = false ;
226226 $ defaultValue = null ;
227- if ($ parameter ->allowsNull ()) {
228- $ hasDefaultValue = true ;
229- }
227+
230228 if ($ parameter ->isDefaultValueAvailable ()) {
231229 $ hasDefaultValue = true ;
232230 $ defaultValue = $ parameter ->getDefaultValue ();
233231 }
234232
233+ if (! $ hasDefaultValue && UndefinedTypeMapper::containsUndefined ($ phpdocType )) {
234+ $ hasDefaultValue = true ;
235+ $ defaultValue = Undefined::VALUE ;
236+ }
237+
238+ if (! $ hasDefaultValue && $ parameter ->allowsNull ()) {
239+ $ hasDefaultValue = true ;
240+ $ defaultValue = null ;
241+ }
242+
243+ $ description = $ this ->getParameterDescriptionFromDocBlock ($ docBlock , $ parameter );
244+
235245 return new InputTypeParameter (
236246 name: $ parameter ->getName (),
237247 type: $ type ,
238248 description: $ description ,
239249 hasDefaultValue: $ hasDefaultValue ,
240250 defaultValue: $ defaultValue ,
251+ defaultValueImplicit: $ defaultValue === Undefined::VALUE ,
241252 argumentResolver: $ this ->argumentResolver ,
242253 );
243254 }
@@ -307,6 +318,7 @@ public function mapInputProperty(
307318 string |null $ inputTypeName = null ,
308319 mixed $ defaultValue = null ,
309320 bool |null $ isNullable = null ,
321+ bool $ hasDefaultValue = false ,
310322 ): InputTypeProperty
311323 {
312324 $ docBlockComment = $ docBlock ->getSummary () . PHP_EOL . $ docBlock ->getDescription ()->render ();
@@ -329,23 +341,40 @@ public function mapInputProperty(
329341 $ isNullable = $ refProperty ->getType ()?->allowsNull() ?? false ;
330342 }
331343
344+ $ propertyType = $ refProperty ->getType ();
345+ if ($ propertyType !== null ) {
346+ $ phpdocType = $ this ->reflectionTypeToPhpDocType ($ propertyType , $ refProperty ->getDeclaringClass ());
347+ } else {
348+ $ phpdocType = new Mixed_ ();
349+ }
350+
332351 if ($ inputTypeName ) {
333352 $ inputType = $ this ->typeResolver ->mapNameToInputType ($ inputTypeName );
334353 } else {
335354 $ inputType = $ this ->mapPropertyType ($ refProperty , $ docBlock , true , $ argumentName , $ isNullable );
336355 assert ($ inputType instanceof InputType);
337356 }
338357
339- $ hasDefault = $ defaultValue !== null || $ isNullable ;
358+ if (! $ hasDefaultValue && $ isNullable ) {
359+ $ hasDefaultValue = true ;
360+ $ defaultValue = null ;
361+ }
362+
363+ if (! $ hasDefaultValue && UndefinedTypeMapper::containsUndefined ($ phpdocType )) {
364+ $ hasDefaultValue = true ;
365+ $ defaultValue = Undefined::VALUE ;
366+ }
367+
340368 $ fieldName = $ argumentName ?? $ refProperty ->getName ();
341369
342370 return new InputTypeProperty (
343371 propertyName: $ refProperty ->getName (),
344372 fieldName: $ fieldName ,
345373 type: $ inputType ,
346374 description: trim ($ docBlockComment ),
347- hasDefaultValue: $ hasDefault ,
375+ hasDefaultValue: $ hasDefaultValue ,
348376 defaultValue: $ defaultValue ,
377+ defaultValueImplicit: $ defaultValue === Undefined::VALUE ,
349378 argumentResolver: $ this ->argumentResolver ,
350379 );
351380 }
0 commit comments