public String getExpectedString(InvalidInputError error) { // In non recovery-mode there is no complexity in the error and start indices since they are all stable. // However, in recovery-mode the RecoveringParseRunner inserts characters into the InputBuffer, which requires // for all indices taken before to be shifted. The RecoveringParseRunner does this by changing the indexDelta // of the parse runner. All users of the ParseError will then automatically see shifted start and end indices // matching the state of the underlying InputBuffer. However, since the failed MatcherPaths still carry the // "original" indices we need to unapply the IndexDelta in order to be able to compare with them. int pathStartIndex = error.getStartIndex() - error.getIndexDelta(); List<String> labelList = new ArrayList<String>(); for (MatcherPath path : error.getFailedMatchers()) { Matcher labelMatcher = ErrorUtils.findProperLabelMatcher(path, pathStartIndex); if (labelMatcher == null) continue; String[] labels = getLabels(labelMatcher); for (String label : labels) { if (label != null && !labelList.contains(label)) { labelList.add(label); } } } return join(labelList); }
for (MatcherPath path : error.getFailedMatchers()) { Matcher labelMatcher = findProperLabelMatcher(path, pathStartIndex); if (labelMatcher == null) {
public String explain(InvalidInputError error) { ErrorInfo known = findKnownError(error.getFailedMatchers()); if (known == null) return "Unknown Error"; else { switch (known.getKnownError()) { case Keyword: return "Expecting one of keywords (" + StringUtils.join(JtwigKeyword.keywords(), ", ") + ")"; case SpecificKeyword: return specificKeyword(known.getChild().element.matcher.getLabel()); } throw new RuntimeException("Expecting explanation"); } }
public String explain(InvalidInputError error) { ErrorInfo known = findKnownError(error.getFailedMatchers()); if (known == null) return "Unknown Error"; else { switch (known.getKnownError()) { case Keyword: return "Expecting one of keywords (" + StringUtils.join(JtwigKeyword.keywords(), ", ") + ")"; case SpecificKeyword: return specificKeyword(known.getChild().element.matcher.getLabel()); } throw new RuntimeException("Expecting explanation"); } }
protected Localizable localize(ParseError error) { String match = match(error); Position position = getPosition(error); int line = position.line; int start = position.column; int end = start + error.getEndIndex() - error.getStartIndex(); if (error instanceof InvalidInputError) { InvalidInputError inputError = (InvalidInputError) error; MultiLocalizable failedMatchers = new MultiLocalizable( Collections2.transform( inputError.getFailedMatchers(), new Function<MatcherPath, Localizable> () { @Override public Localizable apply(MatcherPath matcherPath) { return localize(matcherPath); } } ) ); return new SidoParseInvalidInputException(match, line, start, end, failedMatchers); } else { return new SidoParseExceptionDetail(match, line, start, end, error.getErrorMessage()); } }
@SuppressWarnings( {"ConstantConditions"}) private Character findBestSingleCharInsertion(int fixIndex) { GetStarterCharVisitor getStarterCharVisitor = new GetStarterCharVisitor(); int bestNextErrorIndex = -1; Character bestChar = '\u0000'; // non-null default for (MatcherPath failedMatcherPath : currentError.getFailedMatchers()) { Character starterChar = failedMatcherPath.element.matcher.accept(getStarterCharVisitor); checkState(starterChar != null); // we should only have single character matchers if (starterChar == EOI) { continue; // we should never conjure up an EOI character (that would be cheating :) } buffer.insertChar(fixIndex, starterChar); buffer.insertChar(fixIndex, INS_ERROR); if (performLocatingRun(buffer)) { currentError.shiftIndexDeltaBy(2); // compensate for the inserted chars return null; // success, exit immediately } buffer.undoCharInsertion(fixIndex); buffer.undoCharInsertion(fixIndex); errorIndex = Math.max(errorIndex - 2, 0); if (bestNextErrorIndex < errorIndex) { bestNextErrorIndex = errorIndex; bestChar = starterChar; } } errorIndex = bestNextErrorIndex; return bestChar; }