@@ -1116,7 +1116,10 @@ public GrammarResult VisitClassDecl(CILParser.ClassDeclContext context)
11161116 bool isStandaloneCustomAttribute =
11171117 context . customAttrDecl ( ) . Length == 1 &&
11181118 context . PARAM ( ) is null ;
1119- if ( ! isStandaloneCustomAttribute )
1119+ bool isTrailingCustomAttribute =
1120+ isStandaloneCustomAttribute &&
1121+ context . customAttrDecl ( ) [ 0 ] . dottedName ( ) is null ;
1122+ if ( ! isTrailingCustomAttribute )
11201123 {
11211124 _pendingClassCustomAttributeOwner = null ;
11221125 }
@@ -1126,7 +1129,7 @@ public GrammarResult VisitClassDecl(CILParser.ClassDeclContext context)
11261129 _currentTypeDefinition . Push ( VisitClassHead ( classHead ) . Value ) ;
11271130 VisitClassDecls ( context . classDecls ( ) ) ;
11281131 _currentTypeDefinition . Pop ( ) ;
1129- _lastFieldDefinition = null ;
1132+ _pendingClassCustomAttributeOwner = null ;
11301133 }
11311134 else if ( context . methodHead ( ) is CILParser . MethodHeadContext methodHead )
11321135 {
@@ -1218,31 +1221,45 @@ public GrammarResult VisitClassDecl(CILParser.ClassDeclContext context)
12181221 ? VisitGenArity ( genericArities [ bodySignatureIndex ] ) . Value
12191222 : 0 ) ;
12201223
1224+ EntityRegistry . TypeEntity bodyOwner = VisitTypeSpec ( typeSpecs [ 1 ] ) . Value ;
12211225 string bodyName = VisitMethodName ( methodNames [ 1 ] ) . Value ;
1222- EntityRegistry . MethodDefinitionEntity [ ] bodyMethods = currentType . Methods
1223- . Where ( method =>
1224- method . Name == bodyName &&
1225- method . MethodSignature is not null &&
1226- method . MethodSignature . ContentEquals ( bodySignature ) )
1227- . Take ( 2 )
1228- . ToArray ( ) ;
1229- if ( bodyMethods . Length != 1 )
1230- {
1231- ReportError (
1232- DiagnosticIds . InvalidMetadataToken ,
1233- $ "Override body method '{ bodyName } ' could not be resolved uniquely",
1234- context ) ;
1235- return GrammarResult . SentinelValue . Result ;
1236- }
1237-
1238- EntityRegistry . MethodDefinitionEntity bodyMethod = bodyMethods [ 0 ] ;
12391226 EntityRegistry . MemberReferenceEntity declaration =
12401227 _entityRegistry . CreateLazilyRecordedMemberReference (
12411228 VisitTypeSpec ( typeSpecs [ 0 ] ) . Value ,
12421229 VisitMethodName ( methodNames [ 0 ] ) . Value ,
12431230 declarationSignature ) ;
1244- currentType . MethodImplementations . Add (
1245- EntityRegistry . CreateUnrecordedMethodImplementation ( bodyMethod , declaration ) ) ;
1231+
1232+ if ( ReferenceEquals ( bodyOwner , currentType ) )
1233+ {
1234+ EntityRegistry . MethodDefinitionEntity [ ] bodyMethods = currentType . Methods
1235+ . Where ( method =>
1236+ method . Name == bodyName &&
1237+ method . MethodSignature is not null &&
1238+ method . MethodSignature . ContentEquals ( bodySignature ) )
1239+ . Take ( 2 )
1240+ . ToArray ( ) ;
1241+ if ( bodyMethods . Length != 1 )
1242+ {
1243+ ReportError (
1244+ DiagnosticIds . InvalidMetadataToken ,
1245+ $ "Override body method '{ bodyName } ' could not be resolved uniquely",
1246+ context ) ;
1247+ return GrammarResult . SentinelValue . Result ;
1248+ }
1249+
1250+ currentType . MethodImplementations . Add (
1251+ EntityRegistry . CreateUnrecordedMethodImplementation ( bodyMethods [ 0 ] , declaration ) ) ;
1252+ }
1253+ else
1254+ {
1255+ EntityRegistry . MemberReferenceEntity body =
1256+ _entityRegistry . CreateLazilyRecordedMemberReference (
1257+ bodyOwner ,
1258+ bodyName ,
1259+ bodySignature ) ;
1260+ currentType . MethodImplementations . Add (
1261+ EntityRegistry . CreateUnrecordedMethodImplementation ( currentType , body , declaration ) ) ;
1262+ }
12461263 }
12471264 }
12481265 else if ( context . int32 ( ) is { } int32 )
@@ -1491,7 +1508,31 @@ private BlobBuilder BuildMethodReferenceSignature(
14911508 return signature ;
14921509 }
14931510
1494- public GrammarResult VisitClassDecls ( CILParser . ClassDeclsContext context ) => VisitChildren ( context ) ;
1511+ public GrammarResult VisitClassDecls ( CILParser . ClassDeclsContext context )
1512+ {
1513+ CILParser . ClassDeclContext [ ] declarations = context . classDecl ( ) ;
1514+ foreach ( CILParser . ClassDeclContext declaration in declarations )
1515+ {
1516+ if ( declaration . OVERRIDE ( ) is null )
1517+ {
1518+ VisitClassDecl ( declaration ) ;
1519+ }
1520+ else
1521+ {
1522+ _pendingClassCustomAttributeOwner = null ;
1523+ }
1524+ }
1525+
1526+ foreach ( CILParser . ClassDeclContext declaration in declarations )
1527+ {
1528+ if ( declaration . OVERRIDE ( ) is not null )
1529+ {
1530+ VisitClassDecl ( declaration ) ;
1531+ }
1532+ }
1533+
1534+ return GrammarResult . SentinelValue . Result ;
1535+ }
14951536
14961537
14971538 GrammarResult ICILVisitor < GrammarResult > . VisitClassHead( CILParser . ClassHeadContext context ) => VisitClassHead ( context ) ;
@@ -2200,10 +2241,12 @@ public GrammarResult VisitDdItemList(CILParser.DdItemListContext context)
22002241
22012242 public GrammarResult VisitDecl ( CILParser . DeclContext context )
22022243 {
2203- bool isTrailingCustomAttribute = context . customAttrDecl ( ) is not null ;
2244+ bool isTrailingCustomAttribute =
2245+ context . customAttrDecl ( ) is { } customAttribute &&
2246+ customAttribute . dottedName ( ) is null ;
22042247 if ( context . fieldDecl ( ) is null && ! isTrailingCustomAttribute )
22052248 {
2206- _lastFieldDefinition = null ;
2249+ _pendingClassCustomAttributeOwner = null ;
22072250 }
22082251
22092252 if ( context . nameSpaceHead ( ) is CILParser . NameSpaceHeadContext ns )
@@ -2213,15 +2256,15 @@ public GrammarResult VisitDecl(CILParser.DeclContext context)
22132256 _currentNamespace . Push ( string . IsNullOrEmpty ( outer ) ? namespaceName : $ "{ outer } .{ namespaceName } ") ;
22142257 VisitDecls ( context . decls ( ) ) ;
22152258 _currentNamespace . Pop ( ) ;
2216- _lastFieldDefinition = null ;
2259+ _pendingClassCustomAttributeOwner = null ;
22172260 return GrammarResult . SentinelValue . Result ;
22182261 }
22192262 if ( context . classHead ( ) is CILParser . ClassHeadContext classHead )
22202263 {
22212264 _currentTypeDefinition . Push ( VisitClassHead ( classHead ) . Value ) ;
22222265 VisitClassDecls ( context . classDecls ( ) ) ;
22232266 _currentTypeDefinition . Pop ( ) ;
2224- _lastFieldDefinition = null ;
2267+ _pendingClassCustomAttributeOwner = null ;
22252268 return GrammarResult . SentinelValue . Result ;
22262269 }
22272270 if ( context . methodHead ( ) is CILParser . MethodHeadContext methodHead )
@@ -2386,7 +2429,7 @@ public GrammarResult VisitDecl(CILParser.DeclContext context)
23862429 {
23872430 if ( VisitCustomAttrDecl ( topLevelCustomAttr ) . Value is { } customAttr )
23882431 {
2389- customAttr . Owner = ( EntityRegistry . EntityBase ? ) _lastFieldDefinition ?? _entityRegistry . Module ;
2432+ customAttr . Owner = ( EntityRegistry . EntityBase ? ) _pendingClassCustomAttributeOwner ?? _entityRegistry . Module ;
23902433 }
23912434 }
23922435 if ( context . secDecl ( ) is { } topSecDecl )
@@ -3059,7 +3102,7 @@ public GrammarResult VisitFieldDecl(CILParser.FieldDeclContext context)
30593102 fieldType . WriteContentTo ( signature . Builder ) ;
30603103
30613104 var field = EntityRegistry . CreateUnrecordedFieldDefinition ( fieldAttrs , _currentTypeDefinition . PeekOrDefault ( ) ?? _entityRegistry . ModuleType , name , signature . Builder ) ;
3062- _lastFieldDefinition = field ;
3105+ _pendingClassCustomAttributeOwner = field ;
30633106
30643107 if ( field is not null )
30653108 {
0 commit comments