1 #region Copyright & License Information 2 /* 3 * Copyright 2007-2020 The OpenRA Developers (see AUTHORS) 4 * This file is part of OpenRA, which is free software. It is made 5 * available to you under the terms of the GNU General Public License 6 * as published by the Free Software Foundation, either version 3 of 7 * the License, or (at your option) any later version. For more 8 * information, see COPYING. 9 */ 10 #endregion 11 12 using System; 13 using System.Collections.Generic; 14 using System.Linq; 15 using OpenRA.Mods.Common.Traits; 16 using OpenRA.Traits; 17 18 namespace OpenRA.Mods.Common.Lint 19 { 20 public class CheckConditions : ILintRulesPass 21 { Run(Action<string> emitError, Action<string> emitWarning, Ruleset rules)22 public void Run(Action<string> emitError, Action<string> emitWarning, Ruleset rules) 23 { 24 foreach (var actorInfo in rules.Actors) 25 { 26 var granted = new HashSet<string>(); 27 var consumed = new HashSet<string>(); 28 29 foreach (var trait in actorInfo.Value.TraitInfos<ITraitInfo>()) 30 { 31 var fieldConsumed = trait.GetType().GetFields() 32 .Where(x => x.HasAttribute<ConsumedConditionReferenceAttribute>()) 33 .SelectMany(f => LintExts.GetFieldValues(trait, f, emitError)); 34 35 var propertyConsumed = trait.GetType().GetProperties() 36 .Where(x => x.HasAttribute<ConsumedConditionReferenceAttribute>()) 37 .SelectMany(p => LintExts.GetPropertyValues(trait, p, emitError)); 38 39 var fieldGranted = trait.GetType().GetFields() 40 .Where(x => x.HasAttribute<GrantedConditionReferenceAttribute>()) 41 .SelectMany(f => LintExts.GetFieldValues(trait, f, emitError)); 42 43 var propertyGranted = trait.GetType().GetProperties() 44 .Where(x => x.HasAttribute<GrantedConditionReferenceAttribute>()) 45 .SelectMany(f => LintExts.GetPropertyValues(trait, f, emitError)); 46 47 foreach (var c in fieldConsumed.Concat(propertyConsumed)) 48 if (!string.IsNullOrEmpty(c)) 49 consumed.Add(c); 50 51 foreach (var g in fieldGranted.Concat(propertyGranted)) 52 if (!string.IsNullOrEmpty(g)) 53 granted.Add(g); 54 } 55 56 var unconsumed = granted.Except(consumed); 57 if (unconsumed.Any()) 58 emitWarning("Actor type `{0}` grants conditions that are not consumed: {1}".F(actorInfo.Key, unconsumed.JoinWith(", "))); 59 60 var ungranted = consumed.Except(granted); 61 if (ungranted.Any()) 62 emitError("Actor type `{0}` consumes conditions that are not granted: {1}".F(actorInfo.Key, ungranted.JoinWith(", "))); 63 64 if ((consumed.Any() || granted.Any()) && actorInfo.Value.TraitInfoOrDefault<ConditionManagerInfo>() == null) 65 emitError("Actor type `{0}` defines conditions but does not include a ConditionManager".F(actorInfo.Key)); 66 } 67 } 68 } 69 } 70