public static TextWithImports getEditorText(final Editor editor) { if (editor == null) { return null; } final Project project = editor.getProject(); if (project == null) return null; String defaultExpression = editor.getSelectionModel().getSelectedText(); if (defaultExpression == null) { int offset = editor.getCaretModel().getOffset(); PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); if (psiFile != null) { PsiElement elementAtCursor = psiFile.findElementAt(offset); if (elementAtCursor != null) { final EditorTextProvider textProvider = EditorTextProvider.EP.forLanguage(elementAtCursor.getLanguage()); if (textProvider != null) { final TextWithImports editorText = textProvider.getEditorText(elementAtCursor); if (editorText != null) return editorText; } } } } else { return new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, defaultExpression); } return null; }
public static List<PsiLambdaExpression> collectLambdas( @NotNull SourcePosition position, final boolean onlyOnTheLine) { ApplicationManager.getApplication().assertReadAccessAllowed(); PsiFile file = position.getFile(); final int line = position.getLine(); final Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file); if (document == null || line >= document.getLineCount()) { return Collections.emptyList(); } PsiElement element = position.getElementAt(); final TextRange lineRange = DocumentUtil.getLineTextRange(document, line); do { PsiElement parent = element.getParent(); if (parent == null || (parent.getTextOffset() < lineRange.getStartOffset())) { break; } element = parent; } while (true); final List<PsiLambdaExpression> lambdas = new ArrayList<PsiLambdaExpression>(3); final PsiElementVisitor lambdaCollector = new JavaRecursiveElementVisitor() { @Override public void visitLambdaExpression(PsiLambdaExpression expression) { super.visitLambdaExpression(expression); if (!onlyOnTheLine || getFirstElementOnTheLine(expression, document, line) != null) { lambdas.add(expression); } } }; element.accept(lambdaCollector); // add initial lambda if we're inside already PsiElement method = getContainingMethod(element); if (method instanceof PsiLambdaExpression) { lambdas.add((PsiLambdaExpression) method); } for (PsiElement sibling = getNextElement(element); sibling != null; sibling = getNextElement(sibling)) { if (!intersects(lineRange, sibling)) { break; } sibling.accept(lambdaCollector); } return lambdas; }
/** Decompiler aware version */ @Nullable public static PsiElement findElementAt(@Nullable PsiFile file, int offset) { if (file instanceof PsiCompiledFile) { file = ((PsiCompiledFile) file).getDecompiledPsiFile(); } if (file == null) return null; return file.findElementAt(offset); }
public static PsiMethod findPsiMethod(PsiFile file, int offset) { PsiElement element = null; while (offset >= 0) { element = file.findElementAt(offset); if (element != null) break; offset--; } for (; element != null; element = element.getParent()) { if (element instanceof PsiClass) return null; if (element instanceof PsiMethod) return (PsiMethod) element; } return null; }
private static TextRange calculateLimitRange( final PsiFile file, final Document doc, final int line) { final int offset = doc.getLineStartOffset(line); if (offset > 0) { PsiMethod method = PsiTreeUtil.getParentOfType(file.findElementAt(offset), PsiMethod.class, false); if (method != null) { final TextRange elemRange = method.getTextRange(); return new TextRange( doc.getLineNumber(elemRange.getStartOffset()), doc.getLineNumber(elemRange.getEndOffset())); } } return new TextRange(0, doc.getLineCount() - 1); }
public static PsiMethod findPsiMethod(PsiFile file, int offset) { PsiElement element = null; while (offset >= 0) { element = file.findElementAt(offset); if (element != null) { break; } offset--; } for (; element != null; element = element.getParent()) { if (element instanceof PsiClass || element instanceof PsiLambdaExpression) { return null; } if (element instanceof PsiMethod) { return (PsiMethod) element; } } return null; }
private static boolean shouldSkipLine(final PsiFile file, Document doc, int line) { final int start = doc.getLineStartOffset(line); final int end = doc.getLineEndOffset(line); final int _start = CharArrayUtil.shiftForward(doc.getCharsSequence(), start, " \n\t"); if (_start >= end) { return true; } TextRange alreadyChecked = null; for (PsiElement elem = file.findElementAt(_start); elem != null && elem.getTextOffset() <= end && (alreadyChecked == null || !alreadyChecked.contains(elem.getTextRange())); elem = elem.getNextSibling()) { for (PsiElement _elem = elem; _elem.getTextOffset() >= _start; _elem = _elem.getParent()) { alreadyChecked = _elem.getTextRange(); if (_elem instanceof PsiDeclarationStatement) { final PsiElement[] declared = ((PsiDeclarationStatement) _elem).getDeclaredElements(); for (PsiElement declaredElement : declared) { if (declaredElement instanceof PsiVariable) { return false; } } } if (_elem instanceof PsiJavaCodeReferenceElement) { final PsiElement resolved = ((PsiJavaCodeReferenceElement) _elem).resolve(); if (resolved instanceof PsiVariable) { return false; } } } } return true; }
private static Pair<Set<String>, Set<TextWithImports>> findReferencedVars( Set<String> visibleVars, SourcePosition position) { final int line = position.getLine(); if (line < 0) { return Pair.create(Collections.<String>emptySet(), Collections.<TextWithImports>emptySet()); } final PsiFile positionFile = position.getFile(); if (!positionFile.getLanguage().isKindOf(JavaLanguage.INSTANCE)) { return Pair.create(visibleVars, Collections.<TextWithImports>emptySet()); } final VirtualFile vFile = positionFile.getVirtualFile(); final Document doc = vFile != null ? FileDocumentManager.getInstance().getDocument(vFile) : null; if (doc == null || doc.getLineCount() == 0 || line > (doc.getLineCount() - 1)) { return Pair.create(Collections.<String>emptySet(), Collections.<TextWithImports>emptySet()); } final TextRange limit = calculateLimitRange(positionFile, doc, line); int startLine = Math.max(limit.getStartOffset(), line - 1); startLine = Math.min(startLine, limit.getEndOffset()); while (startLine > limit.getStartOffset() && shouldSkipLine(positionFile, doc, startLine)) { startLine--; } final int startOffset = doc.getLineStartOffset(startLine); int endLine = Math.min(line + 2, limit.getEndOffset()); while (endLine < limit.getEndOffset() && shouldSkipLine(positionFile, doc, endLine)) { endLine++; } final int endOffset = doc.getLineEndOffset(endLine); final TextRange lineRange = new TextRange(startOffset, endOffset); if (!lineRange.isEmpty()) { final int offset = CharArrayUtil.shiftForward(doc.getCharsSequence(), doc.getLineStartOffset(line), " \t"); PsiElement element = positionFile.findElementAt(offset); if (element != null) { PsiMethod method = PsiTreeUtil.getNonStrictParentOfType(element, PsiMethod.class); if (method != null) { element = method; } else { PsiField field = PsiTreeUtil.getNonStrictParentOfType(element, PsiField.class); if (field != null) { element = field; } else { final PsiClassInitializer initializer = PsiTreeUtil.getNonStrictParentOfType(element, PsiClassInitializer.class); if (initializer != null) { element = initializer; } } } //noinspection unchecked if (element instanceof PsiCompiledElement) { return Pair.create(visibleVars, Collections.<TextWithImports>emptySet()); } else { VariablesCollector collector = new VariablesCollector(visibleVars, adjustRange(element, lineRange)); element.accept(collector); return Pair.create(collector.getVars(), collector.getExpressions()); } } } return Pair.create(Collections.<String>emptySet(), Collections.<TextWithImports>emptySet()); }