MatchData (@NotNull StringWithId string, int byteOffset, int gosOffset, boolean matchBeginOfString, @Nullable Runnable checkCancelledCallback) { gosOffset = gosOffset != byteOffset ? Integer.MAX_VALUE : byteOffset; int options = matchBeginOfString ? Option.NONE : Option.NOTBOS; LastMatch lastResult = matchResult.get(); Object lastId = lastResult != null ? lastResult.lastId : null; int lastOffset = lastResult != null ? lastResult.lastOffset : Integer.MAX_VALUE; int lastGosOffset = lastResult != null ? lastResult.lastGosOffset : -1; int lastOptions = lastResult != null ? lastResult.lastOptions : -1; MatchData lastMatch = lastResult != null ? lastResult.lastMatch : MatchData.NOT_MATCHED; if (lastId == string.id && lastOffset <= byteOffset && lastOptions == options && (!hasGMatch || lastGosOffset == gosOffset)) { if (!lastMatch.matched() || lastMatch.byteOffset().start >= byteOffset) { checkMatched(lastMatch, string); return lastMatch; } } if (checkCancelledCallback != null) { checkCancelledCallback.run(); } final Matcher matcher = myRegex.matcher(string.bytes); try { final int matchIndex = matcher.search(gosOffset, byteOffset, string.bytes.length, options); final MatchData matchData = matchIndex > -1 ? MatchData.fromRegion(matcher.getEagerRegion()) : MatchData.NOT_MATCHED; checkMatched(matchData, string); matchResult.set(new LastMatch(string.id, byteOffset, gosOffset, options, matchData)); return matchData; } catch (JOniException // We catch AIOOBE here because of a bug in joni, // apparently the lengths of code units are not calculated correctly in UnicodeEncoding.mbcCaseFold | ArrayIndexOutOfBoundsException e) { LOGGER.info("Failed to match textmate regex", e); return MatchData.NOT_MATCHED; } }