splitAutoCompletingMatches method
Match wd10 to width_10 matchMode: 1 // all rules match at least one splitText 2 // fast match one and don't match other splitTexts 3 // strict mode, all splitTexts must have match.
Implementation
List<List<RegExpMatch>> splitAutoCompletingMatches(
List<String> splitText, String stateName,
{int matchMode = 3}) {
assert(_runtimeContext != null);
/// 一个 rule 对应 每个splitText在该rule中对应的 text 位置
var matches = <List<RegExpMatch>>[];
_runtimeContext![stateName]?.whereType<JParse>().forEach((jparse) {
if (jparse.isConst && jparse is! GroupJParse) {
matches.addAll(enumSplitMatches(splitText, jparse.constants!,
matchMode: matchMode));
} else if (jparse is GroupJParse &&
jparse.groupDTokens.any((dtoken) => dtoken?.isEnum ?? false)) {
// print(element.pattern);
var constantRules = jparse.groupDTokens
.map<List<String>>((dtoken) => _enumAllGiven(dtoken, stateName))
.toList(growable: false);
if (jparse.groupDTokens.any((dtoken) => dtoken is Templates)) {
// List<List<Map<String, dynamic>>> message = [];
var templateRes = <List<List<dynamic>>>[];
//处理模板
jparse.groupDTokens.forEach((dtoken) {
var temp = <List<dynamic>>[];
if (dtoken is Templates) {
/// 处理变量
var enumStrings = <int, Map<String, List<String>>>{};
var dtokenVars = dtoken.vars;
if (dtokenVars != null) {
final enumvars = dtokenVars.enumvars;
final enumnone = dtokenVars.enumnone;
final patterns = dtokenVars.patterns;
for (var i = 0; i < enumvars.length; i++) {
// step1: 优先根据 pattern 从 splittext 提取
if (patterns != null) {
var range =
splitTextRange(patterns[i] as String, splitText);
if (range.isNotEmpty) {
enumStrings[i] = {
'value': [range.join()],
'depart': range
};
}
}
// step2: 其次从枚举值中提取
if (enumStrings[i] == null) {
var enums = _enumAllGiven(enumvars[i], stateName);
if (enums.isNotEmpty) {
enumStrings[i] = {'value': enums, 'depart': []};
}
}
// step3: 最后从enumnone中提取兜底数据
if (enumStrings[i] == null && enumnone != null) {
enumStrings[i] = {
'value': [enumnone[i]],
'depart': []
};
}
}
}
/// 替换变量
dtoken.templates.forEach((template) {
List<String> splits;
/// 情况1: 没有变量直接添加
if ((splits = template.split(r'\$'))
.every((item) => !item.contains(r'$'))) {
temp.add([splits.join(r'$'), []]);
return;
}
/// 情况2:有变量但没有定义变量则退出
if (dtoken.vars == null) return;
var splitExpands = <List<List<String>>>[
[splits, []]
];
/// 情况3:有变量有定义
/// 从 enumStrings 中去取
/// ($/$1)对应第一个 $2对应第二个 $3对应第三个 依次类推..
/// index 0 1 2 ..
final varLength = dtokenVars?.enumvars.length ?? 0;
for (var varIndex = varLength - 1; varIndex >= 0; varIndex--) {
var _splitExpands =
splitExpands.expand<List<List<String>>>((splitSL) {
var parts = splitSL[0];
var matched = splitSL[1];
if (parts.any((part) =>
part.contains(varName(varIndex, varLength)))) {
// 情况3.1:定义了变量但是 enumStrings没有 则去除该条规则
if (enumStrings[varIndex] == null) return [];
var res = <List<List<String>>>[];
enumStrings[varIndex]?['value']?.forEach((varValue) {
res.add([
parts
.map((part) => part.replaceAll(
varName(varIndex, varLength), varValue))
.toList(),
[...matched, ...enumStrings[varIndex]!['depart']!]
]);
});
// []..add([splitSL[0], splitSL[1]]);
return res;
} else {
return [splitSL];
}
}).toList();
splitExpands = _splitExpands;
temp.addAll(splitExpands
.map<List<dynamic>>((splitItem) =>
[splitItem[0].join(r'$'), splitItem[1]])
.toList());
}
});
// return [[_inject(dtoken.templates[0],listVars), departVars]]
}
/// 占位
templateRes.add(temp);
});
matches.addAll(enumSplitMatches(splitText, constantRules,
matchMode: matchMode,
templates: templateRes
.map((e) => e.map<String>((e) => e[0] as String).toList())
.toList(),
matchedFromTemplate: templateRes
.map((e) => e
.map<List<String>>((e) =>
e[1].isEmpty ? <String>[] : e[1] as List<String>)
.toList())
.toList()));
}
matches.addAll(
enumSplitMatches(splitText, constantRules, matchMode: matchMode));
}
});
return matches;
}