private static void addCompletionVariant( @NotNull PsiBuilder builder, @NotNull CompletionState completionState, Object o) { int offset = builder.getCurrentOffset(); if (!builder.eof() && offset == builder.rawTokenTypeStart(1)) return; // suppress for zero-length tokens boolean add = false; int diff = completionState.offset - offset; String text = completionState.convertItem(o); int length = text == null ? 0 : text.length(); if (length == 0) return; if (diff == 0) { add = true; } else if (diff > 0 && diff <= length) { CharSequence fragment = builder.getOriginalText().subSequence(offset, completionState.offset); add = completionState.prefixMatches(fragment.toString(), text); } else if (diff < 0) { for (int i = -1; ; i--) { IElementType type = builder.rawLookup(i); int tokenStart = builder.rawTokenTypeStart(i); if (isWhitespaceOrComment(builder, type)) { diff = completionState.offset - tokenStart; } else if (type != null && tokenStart < completionState.offset) { CharSequence fragment = builder.getOriginalText().subSequence(tokenStart, completionState.offset); if (completionState.prefixMatches(fragment.toString(), text)) { diff = completionState.offset - tokenStart; } break; } else break; } add = diff >= 0 && diff < length; } add = add && length > 1 && !(text.charAt(0) == '<' && text.charAt(length - 1) == '>') && !(text.charAt(0) == '\'' && text.charAt(length - 1) == '\'' && length < 5); if (add) { completionState.addItem(builder, text); } }
public static int nextTokenIsFast(PsiBuilder builder, String tokenText, boolean caseSensitive) { CharSequence sequence = builder.getOriginalText(); int offset = builder.getCurrentOffset(); int endOffset = offset + tokenText.length(); CharSequence subSequence = sequence.subSequence(offset, Math.min(endOffset, sequence.length())); if (!Comparing.equal(subSequence, tokenText, caseSensitive)) return 0; int count = 0; while (true) { int nextOffset = builder.rawTokenTypeStart(++count); if (nextOffset > endOffset) { return -count; } else if (nextOffset == endOffset) { break; } } return count; }
private static void addCompletionVariant( ErrorState state, CompletionState completionState, PsiBuilder builder_, Object o, int offset) { boolean add = false; int diff = completionState.offset - offset; String text = completionState.convertItem(o); int length = text == null ? 0 : text.length(); if (length == 0) return; if (diff == 0) { add = true; } else if (diff > 0 && diff <= length) { CharSequence fragment = builder_.getOriginalText().subSequence(offset, completionState.offset); add = StringUtil.startsWithIgnoreCase(text, fragment.toString()); } else if (diff < 0) { for (int i = -1; ; i--) { IElementType type = builder_.rawLookup(i); int tokenStart = builder_.rawTokenTypeStart(i); if (state.whitespaceTokens.contains(type) || state.commentTokens.contains(type)) { diff = completionState.offset - tokenStart; } else if (type != null && tokenStart < completionState.offset) { CharSequence fragment = builder_.getOriginalText().subSequence(tokenStart, completionState.offset); if (StringUtil.startsWithIgnoreCase(text, fragment.toString())) { diff = completionState.offset - tokenStart; } break; } else break; } add = diff >= 0 && diff < length; } add = add && length > 1 && !(text.charAt(0) == '<' && text.charAt(length - 1) == '>') && !(text.charAt(0) == '\'' && text.charAt(length - 1) == '\'' && length < 5); if (add) { completionState.items.add(text); } }
public static boolean consumeTokenInner(PsiBuilder builder_, String text, boolean caseSensitive) { final CharSequence sequence = builder_.getOriginalText(); final int offset = builder_.getCurrentOffset(); final int endOffset = offset + text.length(); CharSequence tokenText = sequence.subSequence(offset, Math.min(endOffset, sequence.length())); if (Comparing.equal(text, tokenText, caseSensitive)) { int count = 0; while (true) { final int nextOffset = builder_.rawTokenTypeStart(++count); if (nextOffset > endOffset) { return false; } else if (nextOffset == endOffset) { break; } } while (count-- > 0) builder_.advanceLexer(); return true; } return false; }
public static boolean parseAsTree( ErrorState state, final PsiBuilder builder, int level, final IElementType chunkType, boolean checkBraces, final Parser parser, final Parser eatMoreCondition) { final LinkedList<Pair<PsiBuilder.Marker, PsiBuilder.Marker>> parenList = new LinkedList<Pair<PsiBuilder.Marker, PsiBuilder.Marker>>(); final LinkedList<Pair<PsiBuilder.Marker, Integer>> siblingList = new LinkedList<Pair<PsiBuilder.Marker, Integer>>(); PsiBuilder.Marker marker = null; final Runnable checkSiblingsRunnable = new Runnable() { @Override public void run() { main: while (!siblingList.isEmpty()) { final Pair<PsiBuilder.Marker, PsiBuilder.Marker> parenPair = parenList.peek(); final int rating = siblingList.getFirst().second; int count = 0; for (Pair<PsiBuilder.Marker, Integer> pair : siblingList) { if (pair.second != rating || parenPair != null && pair.first == parenPair.second) break main; if (++count >= MAX_CHILDREN_IN_TREE) { PsiBuilder.Marker parentMarker = pair.first.precede(); parentMarker.setCustomEdgeTokenBinders( WhitespacesBinders.GREEDY_LEFT_BINDER, null); while (count-- > 0) { siblingList.removeFirst(); } parentMarker.done(chunkType); siblingList.addFirst(Pair.create(parentMarker, rating + 1)); continue main; } } break; } } }; boolean checkParens = state.braces != null && checkBraces; int totalCount = 0; int tokenCount = 0; if (checkParens) { int tokenIdx = -1; while (builder.rawLookup(tokenIdx) == TokenType.WHITE_SPACE) tokenIdx--; LighterASTNode doneMarker = builder.rawLookup(tokenIdx) == state.braces[0].getLeftBraceType() ? builder.getLatestDoneMarker() : null; if (doneMarker != null && doneMarker.getStartOffset() == builder.rawTokenTypeStart(tokenIdx) && doneMarker.getTokenType() == TokenType.ERROR_ELEMENT) { parenList.add( Pair.create(((PsiBuilder.Marker) doneMarker).precede(), (PsiBuilder.Marker) null)); } } while (true) { final IElementType tokenType = builder.getTokenType(); if (checkParens && (tokenType == state.braces[0].getLeftBraceType() || tokenType == state.braces[0].getRightBraceType() && !parenList.isEmpty())) { if (marker != null) { marker.done(chunkType); siblingList.addFirst(Pair.create(marker, 1)); marker = null; tokenCount = 0; } if (tokenType == state.braces[0].getLeftBraceType()) { final Pair<PsiBuilder.Marker, Integer> prev = siblingList.peek(); parenList.addFirst(Pair.create(builder.mark(), prev == null ? null : prev.first)); } checkSiblingsRunnable.run(); builder.advanceLexer(); if (tokenType == state.braces[0].getRightBraceType()) { final Pair<PsiBuilder.Marker, PsiBuilder.Marker> pair = parenList.removeFirst(); pair.first.done(chunkType); // drop all markers inside parens while (!siblingList.isEmpty() && siblingList.getFirst().first != pair.second) { siblingList.removeFirst(); } siblingList.addFirst(Pair.create(pair.first, 1)); checkSiblingsRunnable.run(); } } else { if (marker == null) { marker = builder.mark(); marker.setCustomEdgeTokenBinders(WhitespacesBinders.GREEDY_LEFT_BINDER, null); } final boolean result = (!parenList.isEmpty() || eatMoreCondition.parse(builder, level + 1)) && parser.parse(builder, level + 1); if (result) { tokenCount++; totalCount++; } if (!result) { break; } } if (tokenCount >= MAX_CHILDREN_IN_TREE && marker != null) { marker.done(chunkType); siblingList.addFirst(Pair.create(marker, 1)); checkSiblingsRunnable.run(); marker = null; tokenCount = 0; } } if (marker != null) { marker.drop(); } for (Pair<PsiBuilder.Marker, PsiBuilder.Marker> pair : parenList) { pair.first.drop(); } return totalCount != 0; }
public static int getIndentationOfPreviousToken(PsiBuilder builder) { // getTokenType has some side effects. Do not remove the call. builder.getTokenType(); int end = builder.rawTokenTypeStart(0); return getLastIndentation(builder.getOriginalText().subSequence(0, end)); }