public void getOccuranceOfVariablesAux(IDictionary <ScriptVariable, int> map, IList <RefScriptVariable> variables, ScriptVariableType targetTypes, VariableNamedState ignoreState, ICollection <ScriptVariable> ignoreVariables) { foreach (var variable in variables) { if (variable.SatisfiesNamedState(ignoreState)) { continue; } if (variable.Value == null) { continue; } if (!variable.Value.IsTypeOf(targetTypes)) { continue; } if (!ignoreVariables.Contains(variable.Value)) { if (!map.ContainsKey(variable.Value)) { map[variable.Value] = 0; } map[variable.Value]++; } RefListVariable list = variable as RefListVariable; RefConcatStringVariable concat = variable as RefConcatStringVariable; if (list != null) { getOccuranceOfVariablesAux(map, list.List, targetTypes, ignoreState, ignoreVariables); } else if (concat != null) { if (concat.Strings.Count == 1 && concat.Strings[0].Word == concat.Value.ToString()) { continue; } foreach (var c in concat.Strings) { if (c.SatisfiesNamedState(ignoreState)) { continue; } StringVariable strVar = new StringVariable(c.Word); if (!ignoreVariables.Contains(strVar)) { if (!map.ContainsKey(strVar)) { map[strVar] = 0; } map[strVar]++; } } } } }
/// <summary> /// 値を変数に置き換える部分の,置き換えられる変数の中身も変数で置き換えたものを返します /// </summary> /// <param name="targetTypes"></param> /// <returns></returns> public IList <KeyValuePair <RefScriptVariable, string> > GetRecursivelyRenamedVariables(ScriptVariableType targetTypes) { Dictionary <string, IList <string> > dependencies = new Dictionary <string, IList <string> >(); // 変数一覧を作成 RefVariableByName variables = new RefVariableByName(); foreach (var pair in this) { RefScriptVariable refVar = RefScriptVariable.Create(pair.Key, ""); refVar.Name = pair.Value; variables.Add(refVar); } // 変数の値がリストだったら,各要素を名前付き変数で置き換えられるものは置き換える foreach (var variable in variables) { RefListVariable list = variable as RefListVariable; if (list != null) { foreach (var elem in list.List) { IList <string> replacers = elem.ReplaceByName(this, VariableNamedState.None); // 変換された変数から,変換に利用した変数を求められるようにする foreach (string replacer in replacers) { if (!dependencies.ContainsKey(variable.Name)) { dependencies[variable.Name] = new List <string>(); } dependencies[variable.Name].Add(replacer); } } } } HashSet <RefScriptVariable> used = new HashSet <RefScriptVariable>(); Stack <RefScriptVariable> subVariables = new Stack <RefScriptVariable>(variables); List <KeyValuePair <RefScriptVariable, string> > ret = new List <KeyValuePair <RefScriptVariable, string> >(); while (subVariables.Count > 0) { // 確認対象 RefScriptVariable targetVar = subVariables.Peek(); if (!used.Contains(targetVar) && targetVar.Name != null) { string name = targetVar.Name; // 対象の変数の部分または要素が他の変数で置き換えられているときには, // その置き換える変数の方を先に確認する IList <string> dependNames; if (dependencies.TryGetValue(name, out dependNames)) { bool dependExists = false; foreach (string dependName in dependNames) { RefScriptVariable dependVar = variables[dependName]; if (dependVar != null && !used.Contains(dependVar)) { subVariables.Push(dependVar); dependExists = true; } } if (dependExists) { continue; } } // targetVar.Name = null; ret.Add(new KeyValuePair <RefScriptVariable, string>(targetVar, name)); } used.Add(targetVar); subVariables.Pop(); continue; } return(ret); }