static int findCodeTokens(L tok, S... tokens) { ret findCodeTokens(tok, 1, false, tokens); } static int findCodeTokens(L tok, boolean ignoreCase, S... tokens) { ret findCodeTokens(tok, 1, ignoreCase, tokens); } static int findCodeTokens(L tok, int startIdx, boolean ignoreCase, S... tokens) { ret findCodeTokens(tok, startIdx, ignoreCase, tokens, null); } static HashSet findCodeTokens_specials = lithashset("*", "", "", "", "\\*"); static int findCodeTokens_bails, findCodeTokens_nonbails; sinterface findCodeTokens_Matcher { bool get(S token); } static int findCodeTokens(L tok, int startIdx, boolean ignoreCase, S[] tokens, O condition) { int end = tok.size()-tokens.length*2+2, nTokens = tokens.length; int i = startIdx | 1; findCodeTokens_Matcher[] matchers = new[nTokens]; IContentsIndexedList2 indexedList = tok instanceof IContentsIndexedList2 ? (IContentsIndexedList2) tok : null; ifdef findCodeTokens_debug print("fct " + joinWithSpace(tokens) + " have indexed list: " + (indexedList != null)); endifdef TreeSet indices = null; int indicesOfs = 0; for j to nTokens: { S p = tokens[j]; findCodeTokens_Matcher matcher; if (p.equals("*")) matcher = t -> true; else if (p.equals("")) matcher = t -> isQuoted(t); else if (p.equals("")) matcher = t -> isIdentifier(t); else if (p.equals("")) matcher = t -> isInteger(t); else if (p.equals("\\*")) matcher = t -> t.equals("*"); else if (ignoreCase) matcher = t -> eqic(p, t); else { matcher = t -> t.equals(p); if (indexedList != null) { TreeSet indices2 = indexedList.indicesOf_treeSetOfHasIndex(p); ifdef findCodeTokens_debug print("fct indices for token " + p + ": " + indices2); endifdef if (indices2 == null) ret -1; if (indices == null || indices2.size() < indices.size()) { // found shorter list indices = indices2; indicesOfs = j; } } } matchers[j] = matcher; } // go over shortest index if (indices != null) { int min = i+indicesOfs*2; SortedSet tailSet = min == 1 ? indices : indices.tailSet(HasIndex(min)); ifdef findCodeTokens_debug print("fct i=" + i + ", tailSet: " + tailSet); endifdef outer: for (HasIndex h : tailSet) { int idx = h.idx-indicesOfs*2; if (idx >= end) break; ifdef findCodeTokens_debug print("fct have first token " + idx + ", indicesOfs=" + indicesOfs + ": " + tok.get(idx)); endifdef for (int j = 0; j < nTokens; j++) try { if (!matchers[j].get(tok.get(idx+j*2))) continue outer; } catch (IndexOutOfBoundsException e) { print("fct indicesOfs=" + indicesOfs + ", h=" + h + ", idx=" + idx); throw e; } if (condition == null || checkTokCondition(condition, tok, idx-1)) ret idx; } ret -1; } outer: for (; i < end; i += 2) { for (int j = 0; j < nTokens; j++) if (!matchers[j].get(tok.get(i+j*2))) continue outer; if (condition == null || checkTokCondition(condition, tok, i-1)) // pass N index ret i; } ret -1; }