private static boolean isPossibleEmptyAttrs(PsiElement attrs) { if (!(attrs instanceof BnfParenExpression)) return false; if (attrs.getFirstChild().getNode().getElementType() != BnfTypes.BNF_LEFT_BRACE) return false; if (!(((BnfParenExpression) attrs).getExpression() instanceof BnfReferenceOrToken)) return false; return isLastInRuleOrFree(attrs); }
private static Collection<String> suggestKeywords(PsiElement position) { TextRange posRange = position.getTextRange(); BnfFile posFile = (BnfFile) position.getContainingFile(); BnfRule statement = PsiTreeUtil.getTopmostParentOfType(position, BnfRule.class); final TextRange range; if (statement != null) { range = new TextRange(statement.getTextRange().getStartOffset(), posRange.getStartOffset()); } else { int offset = posRange.getStartOffset(); for (PsiElement cur = GrammarUtil.getDummyAwarePrevSibling(position); cur != null; cur = GrammarUtil.getDummyAwarePrevSibling(cur)) { if (cur instanceof BnfAttrs) offset = cur.getTextRange().getEndOffset(); else if (cur instanceof BnfRule) offset = cur.getTextRange().getStartOffset(); else continue; break; } range = new TextRange(offset, posRange.getStartOffset()); } final String text = range.isEmpty() ? CompletionInitializationContext.DUMMY_IDENTIFIER : range.substring(posFile.getText()); PsiFile file = PsiFileFactory.getInstance(posFile.getProject()) .createFileFromText("a.bnf", BnfLanguage.INSTANCE, text, true, false); int completionOffset = posRange.getStartOffset() - range.getStartOffset(); GeneratedParserUtilBase.CompletionState state = new GeneratedParserUtilBase.CompletionState(completionOffset) { @Override public String convertItem(Object o) { // we do not have other keywords return o instanceof String ? (String) o : null; } }; file.putUserData(GeneratedParserUtilBase.COMPLETION_STATE_KEY, state); TreeUtil.ensureParsed(file.getNode()); return state.items; }
private static boolean isLastInRuleOrFree(PsiElement element) { PsiElement parent = PsiTreeUtil.getParentOfType( element, BnfRule.class, GeneratedParserUtilBase.DummyBlock.class); if (parent instanceof GeneratedParserUtilBase.DummyBlock) return true; if (!(parent instanceof BnfRule)) return false; for (PsiElement cur = element, next = cur.getNextSibling(); next == null || next instanceof PsiComment || next instanceof PsiWhiteSpace; cur = next, next = cur.getNextSibling()) { if (next == null) { PsiElement curParent = cur.getParent(); while (next == null && curParent != parent) { next = curParent.getNextSibling(); curParent = curParent.getParent(); } if (curParent == parent) return true; next = PsiTreeUtil.getDeepestFirst(next); } } return false; }