dependencyAnalyze method

void dependencyAnalyze()

Implementation

void dependencyAnalyze() {
  var defined = <String, Object>{};
  var undefined = <String, List>{};
  String _oSymbol(Object o) => '${o.runtimeType}(${o.hashCode})';
  var lib =
      _libraries?.reversed.cast<RegexLexer>().toList() ?? <RegexLexer>[];
  if (_rootLexer != null) lib.add(_rootLexer!);
  if (lib.isNotEmpty) {
    lib.forEach((element) {
      defined[_oSymbol(element)] = {'override': [], 'unused': []};
      var it = element == _rootLexer
          ? {...element.parses, ...element.commonparses(null)}
          : element.commonparses(null);
      it.keys.forEach((state) {
        if (defined.keys.contains(state)) {
          var oldElement = defined[state];
          print(
              'WARNING:${_oSymbol(element)} defined a override state $state already defined in $oldElement\n');
          (defined[oldElement] as Map<String, List>)['override']!.add(state);
          (defined[oldElement] as Map<String, List>)['unused']!.remove(state);
          defined[state] = _oSymbol(element);
          (defined[_oSymbol(element)] as Map<String, List>)['unused']!
              .add(state);
        } else {
          defined[state] = _oSymbol(element);
          (defined[_oSymbol(element)] as Map<String, List>)['unused']!
              .add(state);
        }
      });
    });
    lib.forEach((element) {
      undefined[_oSymbol(element)] = [];
      var it = element == _rootLexer
          ? {...element.parses, ...element.commonparses(null)}
          : element.commonparses(null);
      it.values.forEach((e) {
        var _growableEValues = <Parse>[...e];
        while (_growableEValues.isNotEmpty) {
          var parser = _growableEValues.removeAt(0);
          // }
          // e.forEach((parser) {
          // 解包压平
          if (parser is JParsePackage) {
            _growableEValues.insertAll(0, parser.package);
            break;
          }
          // 检查包含关系
          if (parser.token == Token.IncludeOtherParse) {
            // 包含未定义
            if (defined[parser.pattern] == null) {
              undefined[_oSymbol(element)]!.add(parser.pattern);
            } else {
              // 包含已定义
              var usedElement = defined[parser.pattern];
              (defined[usedElement] as Map<String, List>)['unused']!
                  .remove(parser.pattern);
            }
          }
          // 检查跳转关系
          if (parser.newStates?.isNotEmpty ?? false) {
            parser.newStates!.forEach((jump) {
              // 排除跳转动作
              if (RegExp(r'#(on|pop|push|clear|break|event|inside)')
                      .matchAsPrefix(jump) !=
                  null) return;
              // 跳转未定义
              if (defined[jump] == null) {
                undefined[_oSymbol(element)]!.add(jump);
                // 跳转已定义
              } else {
                var usedElement = defined[jump];
                (defined[usedElement] as Map<String, List>)['unused']!
                    .remove(jump);
              }
            });
          }
        }
        // );
      });
    });
    var out = '';
    undefined.keys.forEach((key) => out += '$key >> ');
    out += 'root';
    print('''
Loading order:
=============================
$out
=============================
''');
    // undefined;
    out = '';
    var total = 0;
    undefined.forEach((key, value) {
      if (value.isNotEmpty) {
        value.forEach((element) {
          out += '$key:$element\n';
          total++;
        });
      }
    });
    if (out.isNotEmpty) {
      var totalPadding = 'total: $total'.padLeft(29);
      print('''
Undefined states:
=============================
$out
=============================
$totalPadding

''');
    }
    // override;
    out = '';
    total = 0;
    undefined.keys.forEach((key) {
      var c = defined[key] as Map<String, List>;
      if (c['override']!.isNotEmpty) {
        c['override']!.forEach((value) {
          out += '$key:$value\n';
          total++;
        });
      }
    });
    if (out.isNotEmpty) {
      var totalPadding = 'total: $total'.padLeft(29);
      print('''Override states:
=============================
$out
=============================
$totalPadding

''');
    }
    out = '';
    total = 0;
    undefined.keys.forEach((key) {
      var c = defined[key] as Map<String, List>;
      if (c['unused']!.isNotEmpty) {
        c['unused']!.forEach((value) {
          out += '$key:$value\n';
          total++;
        });
      }
    });
    if (out.isNotEmpty) {
      var totalPadding = 'total: $total'.padLeft(29);
      print('''Unused states:
=============================
$out
=============================
$totalPadding

''');
    }
    if (configDebuggable) {
      print('\n$defined\n$undefined');
    }
  }
}