@@ -43,16 +43,17 @@ void ILintMapPass.Run(Action<string> emitError, Action<string> emitWarning, ModD
43
43
44
44
var mapTranslations = FieldLoader . GetValue < string [ ] > ( "value" , map . TranslationDefinitions . Value ) ;
45
45
46
- foreach ( var language in GetModLanguages ( modData ) )
46
+ var allModTranslations = modData . Manifest . Translations . Append ( modData . Manifest . Get < ModContent > ( ) . Translation ) . ToArray ( ) ;
47
+ foreach ( var language in GetModLanguages ( allModTranslations ) )
47
48
{
48
49
// Check keys and variables are not missing across all language files.
49
50
// But for maps we don't warn on unused keys. They might be unused on *this* map,
50
51
// but the mod or another map may use them and we don't have sight of that.
51
52
CheckKeys (
52
- modData . Manifest . Translations . Concat ( mapTranslations ) , map . Open , usedKeys ,
53
+ allModTranslations . Concat ( mapTranslations ) , map . Open , usedKeys ,
53
54
language , _ => false , emitError , emitWarning ) ;
54
55
55
- var modFluentBundle = new FluentBundle ( language , modData . Manifest . Translations , modData . DefaultFileSystem , _ => { } ) ;
56
+ var modFluentBundle = new FluentBundle ( language , allModTranslations , modData . DefaultFileSystem , _ => { } ) ;
56
57
var mapFluentBundle = new FluentBundle ( language , mapTranslations , map , error => emitError ( error . Message ) ) ;
57
58
58
59
foreach ( var group in usedKeys . KeysWithContext )
@@ -78,14 +79,15 @@ void ILintPass.Run(Action<string> emitError, Action<string> emitWarning, ModData
78
79
foreach ( var context in usedKeys . EmptyKeyContexts )
79
80
emitWarning ( $ "Empty key in mod translation files required by { context } ") ;
80
81
81
- foreach ( var language in GetModLanguages ( modData ) )
82
+ var allModTranslations = modData . Manifest . Translations . Append ( modData . Manifest . Get < ModContent > ( ) . Translation ) . ToArray ( ) ;
83
+ foreach ( var language in GetModLanguages ( allModTranslations ) )
82
84
{
83
85
Console . WriteLine ( $ "Testing language: { language } ") ;
84
86
CheckModWidgets ( modData , usedKeys , testedFields ) ;
85
87
86
88
// With the fully populated keys, check keys and variables are not missing and not unused across all language files.
87
89
var keyWithAttrs = CheckKeys (
88
- modData . Manifest . Translations , modData . DefaultFileSystem . Open , usedKeys ,
90
+ allModTranslations , modData . DefaultFileSystem . Open , usedKeys ,
89
91
language ,
90
92
file =>
91
93
! modData . Manifest . AllowUnusedTranslationsInExternalPackages ||
@@ -113,9 +115,9 @@ void ILintPass.Run(Action<string> emitError, Action<string> emitWarning, ModData
113
115
$ "`{ field . ReflectedType . Name } .{ field . Name } ` - previous warnings may be incorrect") ;
114
116
}
115
117
116
- static IEnumerable < string > GetModLanguages ( ModData modData )
118
+ static IEnumerable < string > GetModLanguages ( IEnumerable < string > translations )
117
119
{
118
- return modData . Manifest . Translations
120
+ return translations
119
121
. Select ( filename => FilenameRegex . Match ( filename ) . Groups [ "language" ] . Value )
120
122
. Distinct ( )
121
123
. OrderBy ( l => l ) ;
@@ -249,51 +251,55 @@ static Keys GetUsedFluentKeysInMap(Map map, Action<string> emitWarning)
249
251
. Where ( t => t . IsSubclassOf ( typeof ( TraitInfo ) ) || t . IsSubclassOf ( typeof ( Warhead ) ) )
250
252
. SelectMany ( t => t . GetFields ( ) . Where ( f => f . HasAttribute < FluentReferenceAttribute > ( ) ) ) ) ;
251
253
252
- // HACK: Need to hardcode the custom loader for GameSpeeds.
253
- var gameSpeeds = modData . Manifest . Get < GameSpeeds > ( ) ;
254
- var gameSpeedNameField = typeof ( GameSpeed ) . GetField ( nameof ( GameSpeed . Name ) ) ;
255
- var gameSpeedFluentReference = Utility . GetCustomAttributes < FluentReferenceAttribute > ( gameSpeedNameField , true ) [ 0 ] ;
256
- testedFields . Add ( gameSpeedNameField ) ;
257
- foreach ( var speed in gameSpeeds . Speeds . Values )
258
- usedKeys . Add ( speed . Name , gameSpeedFluentReference , $ "`{ nameof ( GameSpeed ) } .{ nameof ( GameSpeed . Name ) } `") ;
254
+ // TODO: linter does not work with LoadUsing
255
+ GetUsedTranslationKeysFromFieldsWithTranslationReferenceAttribute (
256
+ usedKeys , testedFields , Utility . GetFields ( typeof ( GameSpeed ) ) , modData . Manifest . Get < GameSpeeds > ( ) . Speeds . Values ) ;
259
257
260
258
// TODO: linter does not work with LoadUsing
261
- foreach ( var actorInfo in modData . DefaultRules . Actors )
262
- {
263
- foreach ( var info in actorInfo . Value . TraitInfos < ResourceRendererInfo > ( ) )
264
- {
265
- var resourceTypeNameField = typeof ( ResourceRendererInfo . ResourceTypeInfo ) . GetField ( nameof ( ResourceRendererInfo . ResourceTypeInfo . Name ) ) ;
266
- var resourceTypeFluentReference = Utility . GetCustomAttributes < FluentReferenceAttribute > ( resourceTypeNameField , true ) [ 0 ] ;
267
- testedFields . Add ( resourceTypeNameField ) ;
268
- foreach ( var resourceTypes in info . ResourceTypes )
269
- usedKeys . Add (
270
- resourceTypes . Value . Name ,
271
- resourceTypeFluentReference ,
272
- $ "`{ nameof ( ResourceRendererInfo . ResourceTypeInfo ) } .{ nameof ( ResourceRendererInfo . ResourceTypeInfo . Name ) } `") ;
273
- }
274
- }
259
+ GetUsedTranslationKeysFromFieldsWithTranslationReferenceAttribute (
260
+ usedKeys , testedFields ,
261
+ Utility . GetFields ( typeof ( ResourceRendererInfo . ResourceTypeInfo ) ) ,
262
+ modData . DefaultRules . Actors
263
+ . SelectMany ( actorInfo => actorInfo . Value . TraitInfos < ResourceRendererInfo > ( ) )
264
+ . SelectMany ( info => info . ResourceTypes . Values ) ) ;
265
+
266
+ const BindingFlags Binding = BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . Static ;
267
+ var constFields = modData . ObjectCreator . GetTypes ( ) . SelectMany ( modType => modType . GetFields ( Binding ) ) . Where ( f => f . IsLiteral ) ;
268
+ GetUsedTranslationKeysFromFieldsWithTranslationReferenceAttribute (
269
+ usedKeys , testedFields , constFields , new [ ] { ( object ) null } ) ;
270
+
271
+ var modMetadataFields = typeof ( ModMetadata ) . GetFields ( BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . Instance ) ;
272
+ GetUsedTranslationKeysFromFieldsWithTranslationReferenceAttribute (
273
+ usedKeys , testedFields , modMetadataFields , new [ ] { modData . Manifest . Metadata } ) ;
274
+
275
+ var modContent = modData . Manifest . Get < ModContent > ( ) ;
276
+ GetUsedTranslationKeysFromFieldsWithTranslationReferenceAttribute (
277
+ usedKeys , testedFields , Utility . GetFields ( typeof ( ModContent ) ) , new [ ] { modContent } ) ;
278
+ GetUsedTranslationKeysFromFieldsWithTranslationReferenceAttribute (
279
+ usedKeys , testedFields , Utility . GetFields ( typeof ( ModContent . ModPackage ) ) , modContent . Packages . Values ) ;
280
+
281
+ return ( usedKeys , testedFields ) ;
282
+ }
275
283
276
- foreach ( var modType in modData . ObjectCreator . GetTypes ( ) )
284
+ static void GetUsedTranslationKeysFromFieldsWithTranslationReferenceAttribute (
285
+ Keys usedKeys , List < FieldInfo > testedFields ,
286
+ IEnumerable < FieldInfo > newFields , IEnumerable < object > objects )
287
+ {
288
+ var fieldsWithAttribute =
289
+ newFields
290
+ . Select ( f => ( Field : f , FluentReference : Utility . GetCustomAttributes < FluentReferenceAttribute > ( f , true ) . SingleOrDefault ( ) ) )
291
+ . Where ( x => x . FluentReference != null )
292
+ . ToArray ( ) ;
293
+ testedFields . AddRange ( fieldsWithAttribute . Select ( x => x . Field ) ) ;
294
+ foreach ( var obj in objects )
277
295
{
278
- const BindingFlags Binding = BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . Static ;
279
- foreach ( var field in modType . GetFields ( Binding ) )
296
+ foreach ( var ( field , fluentReference ) in fieldsWithAttribute )
280
297
{
281
- // Checking for constant string fields.
282
- if ( ! field . IsLiteral )
283
- continue ;
284
-
285
- var fluentReference = Utility . GetCustomAttributes < FluentReferenceAttribute > ( field , true ) . SingleOrDefault ( ) ;
286
- if ( fluentReference == null )
287
- continue ;
288
-
289
- testedFields . Add ( field ) ;
290
- var keys = LintExts . GetFieldValues ( null , field , fluentReference . DictionaryReference ) ;
298
+ var keys = LintExts . GetFieldValues ( obj , field , fluentReference . DictionaryReference ) ;
291
299
foreach ( var key in keys )
292
300
usedKeys . Add ( key , fluentReference , $ "`{ field . ReflectedType . Name } .{ field . Name } `") ;
293
301
}
294
302
}
295
-
296
- return ( usedKeys , testedFields ) ;
297
303
}
298
304
299
305
static void CheckModWidgets ( ModData modData , Keys usedKeys , List < FieldInfo > testedFields )
0 commit comments