@@ -238,7 +238,19 @@ static string GetTypeKind (TypeDefinition t)
238238 if ( t . IsEnum )
239239 return "enum" ;
240240 if ( t . IsValueType )
241- return "struct" ;
241+ {
242+ StringBuilder buf = new StringBuilder ( ) ;
243+ if ( DocUtils . HasCustomAttribute ( t , Consts . IsReadOnlyAttribute ) )
244+ {
245+ buf . Append ( "readonly " ) ;
246+ }
247+ if ( DocUtils . HasCustomAttribute ( t , Consts . IsByRefLikeAttribute ) )
248+ {
249+ buf . Append ( "ref " ) ;
250+ }
251+ buf . Append ( "struct" ) ;
252+ return buf . ToString ( ) ;
253+ }
242254 if ( t . IsClass || t . FullName == "System.Enum" )
243255 return "class" ;
244256 if ( t . IsInterface )
@@ -500,18 +512,9 @@ protected override StringBuilder AppendModifiers (StringBuilder buf, MethodDefin
500512 if ( method . IsAbstract && ! declType . IsInterface ) modifiers += " abstract" ;
501513 if ( method . IsFinal ) modifiers += " sealed" ;
502514 if ( modifiers == " virtual sealed" ) modifiers = "" ;
503-
504- if ( ( method . ReturnType . IsRequiredModifier
505- && ( ( RequiredModifierType ) method . ReturnType ) . ElementType . IsByReference )
506- || method . ReturnType . IsByReference )
515+ if ( declType . IsValueType && DocUtils . HasCustomAttribute ( method , Consts . IsReadOnlyAttribute ) )
507516 {
508- modifiers += " ref" ;
509- }
510-
511- if ( method . ReturnType . IsRequiredModifier
512- && method . MethodReturnType . CustomAttributes . Any ( attr => attr . AttributeType . FullName == "System.Runtime.CompilerServices.IsReadOnlyAttribute" ) )
513- {
514- modifiers += " readonly" ;
517+ modifiers += buf . Length == 0 ? "readonly" : " readonly" ;
515518 }
516519
517520 switch ( method . Name )
@@ -527,6 +530,24 @@ protected override StringBuilder AppendModifiers (StringBuilder buf, MethodDefin
527530 return buf . Append ( modifiers ) ;
528531 }
529532
533+ protected override StringBuilder AppendRefTypeName ( StringBuilder buf , ByReferenceType type , IAttributeParserContext context )
534+ {
535+ buf . Append ( "ref " ) ;
536+ return base . AppendRefTypeName ( buf , type , context ) ;
537+ }
538+
539+ protected override StringBuilder AppendRequiredModifierTypeName (
540+ StringBuilder buf , RequiredModifierType type , IAttributeParserContext context )
541+ {
542+ if ( type . ModifierType . FullName == Consts . InAttribute && type . ElementType is ByReferenceType refType )
543+ {
544+ buf . Append ( "ref readonly " ) ;
545+ return _AppendTypeName ( buf , refType . ElementType , context ) ;
546+ }
547+
548+ return base . AppendRequiredModifierTypeName ( buf , type , context ) ;
549+ }
550+
530551 protected override StringBuilder AppendGenericMethod ( StringBuilder buf , MethodDefinition method )
531552 {
532553 if ( method . IsGenericMethod ( ) )
@@ -570,19 +591,28 @@ private StringBuilder AppendParameters (StringBuilder buf, MethodDefinition meth
570591
571592 private StringBuilder AppendParameter ( StringBuilder buf , ParameterDefinition parameter )
572593 {
573- if ( parameter . ParameterType is ByReferenceType )
594+ TypeReference parameterType = parameter . ParameterType ;
595+
596+ if ( parameterType is RequiredModifierType requiredModifierType )
597+ {
598+ parameterType = requiredModifierType . ElementType ;
599+ }
600+
601+ if ( parameterType is ByReferenceType byReferenceType )
574602 {
575603 if ( parameter . IsOut )
576604 {
577605 buf . Append ( "out " ) ;
578606 }
607+ else if ( parameter . IsIn && DocUtils . HasCustomAttribute ( parameter , Consts . IsReadOnlyAttribute ) )
608+ {
609+ buf . Append ( "in " ) ;
610+ }
579611 else
580612 {
581- if ( parameter . HasCustomAttributes && parameter . CustomAttributes . Any ( ca => ca . AttributeType . Name == "IsReadOnlyAttribute" ) )
582- buf . Append ( "in " ) ;
583- else
584- buf . Append ( "ref " ) ;
613+ buf . Append ( "ref " ) ;
585614 }
615+ parameterType = byReferenceType . ElementType ;
586616 }
587617
588618 if ( parameter . HasCustomAttributes )
@@ -594,7 +624,7 @@ private StringBuilder AppendParameter (StringBuilder buf, ParameterDefinition pa
594624
595625 var context = AttributeParserContext . Create ( parameter ) ;
596626 var isNullableType = context . IsNullable ( ) ;
597- buf . Append ( GetTypeName ( parameter . ParameterType , context ) ) ;
627+ buf . Append ( GetTypeName ( parameterType , context ) ) ;
598628 buf . Append ( GetTypeNullableSymbol ( parameter . ParameterType , isNullableType ) ) ;
599629 buf . Append ( " " ) ;
600630 buf . Append ( parameter . Name ) ;
@@ -658,9 +688,6 @@ protected override string GetPropertyDeclaration (PropertyDefinition property)
658688 modifiers = "" ;
659689 buf . Append ( modifiers ) . Append ( ' ' ) ;
660690
661- if ( property . PropertyType . IsByReference )
662- buf . Append ( "ref " ) ;
663-
664691 var context = AttributeParserContext . Create ( property ) ;
665692 var isNullableType = context . IsNullable ( ) ;
666693 var propertyReturnTypeName = GetTypeName ( property . PropertyType , context ) ;
0 commit comments