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 ;
4951use TheCodingMachine \GraphQLite \Utils \DescriptionResolver ;
5052
5153use function array_map ;
@@ -179,6 +181,19 @@ public function mapParameter(
179181 return new DefaultValueParameter ($ parameter ->getDefaultValue ());
180182 }
181183
184+ $ parameterType = $ parameter ->getType ();
185+ $ allowsNull = $ parameterType === null || $ parameterType ->allowsNull ();
186+
187+ if ($ parameterType === null ) {
188+ $ phpdocType = new Mixed_ ();
189+ $ allowsNull = false ;
190+ //throw MissingTypeHintException::missingTypeHint($parameter);
191+ } else {
192+ $ declaringClass = $ parameter ->getDeclaringClass ();
193+ assert ($ declaringClass !== null );
194+ $ phpdocType = $ this ->reflectionTypeToPhpDocType ($ parameterType , $ declaringClass );
195+ }
196+
182197 $ useInputType = $ parameterAnnotations ->getAnnotationByType (UseInputType::class);
183198 if ($ useInputType !== null ) {
184199 try {
@@ -188,19 +203,6 @@ public function mapParameter(
188203 throw $ e ;
189204 }
190205 } else {
191- $ parameterType = $ parameter ->getType ();
192- $ allowsNull = $ parameterType === null || $ parameterType ->allowsNull ();
193-
194- if ($ parameterType === null ) {
195- $ phpdocType = new Mixed_ ();
196- $ allowsNull = false ;
197- //throw MissingTypeHintException::missingTypeHint($parameter);
198- } else {
199- $ declaringClass = $ parameter ->getDeclaringClass ();
200- assert ($ declaringClass !== null );
201- $ phpdocType = $ this ->reflectionTypeToPhpDocType ($ parameterType , $ declaringClass );
202- }
203-
204206 try {
205207 $ declaringFunction = $ parameter ->getDeclaringFunction ();
206208 if (! $ declaringFunction instanceof ReflectionMethod) {
@@ -228,20 +230,31 @@ public function mapParameter(
228230
229231 $ hasDefaultValue = false ;
230232 $ defaultValue = null ;
231- if ($ parameter ->allowsNull ()) {
232- $ hasDefaultValue = true ;
233- }
233+
234234 if ($ parameter ->isDefaultValueAvailable ()) {
235235 $ hasDefaultValue = true ;
236236 $ defaultValue = $ parameter ->getDefaultValue ();
237237 }
238238
239+ if (! $ hasDefaultValue && UndefinedTypeMapper::containsUndefined ($ phpdocType )) {
240+ $ hasDefaultValue = true ;
241+ $ defaultValue = Undefined::VALUE ;
242+ }
243+
244+ if (! $ hasDefaultValue && $ parameter ->allowsNull ()) {
245+ $ hasDefaultValue = true ;
246+ $ defaultValue = null ;
247+ }
248+
249+ $ description = $ this ->getParameterDescriptionFromDocBlock ($ docBlock , $ parameter );
250+
239251 return new InputTypeParameter (
240252 name: $ parameter ->getName (),
241253 type: $ type ,
242254 description: $ description ,
243255 hasDefaultValue: $ hasDefaultValue ,
244256 defaultValue: $ defaultValue ,
257+ defaultValueImplicit: $ defaultValue === Undefined::VALUE ,
245258 argumentResolver: $ this ->argumentResolver ,
246259 );
247260 }
@@ -311,6 +324,7 @@ public function mapInputProperty(
311324 string |null $ inputTypeName = null ,
312325 mixed $ defaultValue = null ,
313326 bool |null $ isNullable = null ,
327+ bool $ hasDefaultValue = false ,
314328 ): InputTypeProperty
315329 {
316330 $ docBlockDescription = $ docBlock ->getSummary () . PHP_EOL . $ docBlock ->getDescription ()->render ();
@@ -333,14 +347,30 @@ public function mapInputProperty(
333347 $ isNullable = $ refProperty ->getType ()?->allowsNull() ?? false ;
334348 }
335349
350+ $ propertyType = $ refProperty ->getType ();
351+ if ($ propertyType !== null ) {
352+ $ phpdocType = $ this ->reflectionTypeToPhpDocType ($ propertyType , $ refProperty ->getDeclaringClass ());
353+ } else {
354+ $ phpdocType = new Mixed_ ();
355+ }
356+
336357 if ($ inputTypeName ) {
337358 $ inputType = $ this ->typeResolver ->mapNameToInputType ($ inputTypeName );
338359 } else {
339360 $ inputType = $ this ->mapPropertyType ($ refProperty , $ docBlock , true , $ argumentName , $ isNullable );
340361 assert ($ inputType instanceof InputType);
341362 }
342363
343- $ hasDefault = $ defaultValue !== null || $ isNullable ;
364+ if (! $ hasDefaultValue && $ isNullable ) {
365+ $ hasDefaultValue = true ;
366+ $ defaultValue = null ;
367+ }
368+
369+ if (! $ hasDefaultValue && UndefinedTypeMapper::containsUndefined ($ phpdocType )) {
370+ $ hasDefaultValue = true ;
371+ $ defaultValue = Undefined::VALUE ;
372+ }
373+
344374 $ fieldName = $ argumentName ?? $ refProperty ->getName ();
345375
346376 $ resolvedDescription = $ this ->descriptionResolver ->resolve (null , $ docBlockDescription );
@@ -350,8 +380,9 @@ public function mapInputProperty(
350380 fieldName: $ fieldName ,
351381 type: $ inputType ,
352382 description: $ resolvedDescription !== null ? trim ($ resolvedDescription ) : '' ,
353- hasDefaultValue: $ hasDefault ,
383+ hasDefaultValue: $ hasDefaultValue ,
354384 defaultValue: $ defaultValue ,
385+ defaultValueImplicit: $ defaultValue === Undefined::VALUE ,
355386 argumentResolver: $ this ->argumentResolver ,
356387 );
357388 }
0 commit comments