public static PsiElement[] parsePattern( Project project, String context, String pattern, FileType fileType, Language language, String extension, boolean physical) { int offset = context.indexOf(PATTERN_PLACEHOLDER); final int patternLength = pattern.length(); final String patternInContext = context.replace(PATTERN_PLACEHOLDER, pattern); final String ext = extension != null ? extension : fileType.getDefaultExtension(); final String name = "__dummy." + ext; final PsiFileFactory factory = PsiFileFactory.getInstance(project); final PsiFile file = language == null ? factory.createFileFromText( name, fileType, patternInContext, LocalTimeCounter.currentTime(), physical, true) : factory.createFileFromText(name, language, patternInContext, physical, true); if (file == null) { return PsiElement.EMPTY_ARRAY; } final List<PsiElement> result = new ArrayList<PsiElement>(); PsiElement element = file.findElementAt(offset); if (element == null) { return PsiElement.EMPTY_ARRAY; } PsiElement topElement = element; element = element.getParent(); while (element != null) { if (element.getTextRange().getStartOffset() == offset && element.getTextLength() <= patternLength) { topElement = element; } element = element.getParent(); } if (topElement instanceof PsiFile) { return topElement.getChildren(); } final int endOffset = offset + patternLength; result.add(topElement); topElement = topElement.getNextSibling(); while (topElement != null && topElement.getTextRange().getEndOffset() <= endOffset) { result.add(topElement); topElement = topElement.getNextSibling(); } return result.toArray(new PsiElement[result.size()]); }
private void initTopLevelElement(PsiElement element) { CompiledPattern pattern = myGlobalVisitor.getContext().getPattern(); PsiElement newElement = SkippingHandler.skipNodeIfNeccessary(element); if (element != newElement && newElement != null) { // way to support partial matching (ex. if ($condition$) ) newElement.accept(this); pattern.setHandler(element, new LightTopLevelMatchingHandler(pattern.getHandler(element))); } else { myGlobalVisitor.setCodeBlockLevel(myGlobalVisitor.getCodeBlockLevel() + 1); for (PsiElement el = element.getFirstChild(); el != null; el = el.getNextSibling()) { if (GlobalCompilingVisitor.getFilter().accepts(el)) { if (el instanceof PsiWhiteSpace) { myGlobalVisitor.addLexicalNode(el); } } else { el.accept(this); MatchingHandler matchingHandler = pattern.getHandler(el); pattern.setHandler( el, element == myTopElement ? new TopLevelMatchingHandler(matchingHandler) : new LightTopLevelMatchingHandler(matchingHandler)); /* do not assign light-top-level handlers through skipping, because it is incorrect; src: if (...) { st1; st2; } pattern: if (...) {$a$;} $a$ will have top-level handler, so matching will be considered as correct, although "st2;" is left! */ } } myGlobalVisitor.setCodeBlockLevel(myGlobalVisitor.getCodeBlockLevel() - 1); pattern.setHandler(element, new TopLevelMatchingHandler(pattern.getHandler(element))); } }