/** * Inspects all lines of the given document and wraps all of them that exceed {@link * CodeStyleSettings#RIGHT_MARGIN right margin}. * * <p>I.e. the algorithm is to do the following for every line: * * <p> * * <pre> * <ol> * <li> * Check if the line exceeds {@link CodeStyleSettings#RIGHT_MARGIN right margin}. Go to the next line in the case of * negative answer; * </li> * <li>Determine line wrap position; </li> * <li> * Perform 'smart wrap', i.e. not only wrap the line but insert additional characters over than line feed if necessary. * For example consider that we wrap a single-line comment - we need to insert comment symbols on a start of the wrapped * part as well. Generally, we get the same behavior as during pressing 'Enter' at wrap position during editing document; * </li> * </ol> * </pre> * * @param file file that holds parsed document tree * @param document target document * @param startOffset start offset of the first line to check for wrapping (inclusive) * @param endOffset end offset of the first line to check for wrapping (exclusive) */ private void wrapLongLinesIfNecessary( @NotNull final PsiFile file, @Nullable final Document document, final int startOffset, final int endOffset) { if (!mySettings.getCommonSettings(file.getLanguage()).WRAP_LONG_LINES || PostprocessReformattingAspect.getInstance(file.getProject()) .isViewProviderLocked(file.getViewProvider()) || document == null) { return; } final VirtualFile vFile = FileDocumentManager.getInstance().getFile(document); if ((vFile == null || vFile instanceof LightVirtualFile) && !ApplicationManager.getApplication().isUnitTestMode()) { // we assume that control flow reaches this place when the document is backed by a "virtual" // file so any changes made by // a formatter affect only PSI and it is out of sync with a document text return; } Editor editor = PsiUtilBase.findEditor(file); EditorFactory editorFactory = null; if (editor == null) { if (!ApplicationManager.getApplication().isDispatchThread()) { return; } editorFactory = EditorFactory.getInstance(); editor = editorFactory.createEditor(document, file.getProject()); } try { final Editor editorToUse = editor; ApplicationManager.getApplication() .runWriteAction( new Runnable() { @Override public void run() { final CaretModel caretModel = editorToUse.getCaretModel(); final int caretOffset = caretModel.getOffset(); final RangeMarker caretMarker = editorToUse.getDocument().createRangeMarker(caretOffset, caretOffset); doWrapLongLinesIfNecessary( editorToUse, file.getProject(), editorToUse.getDocument(), startOffset, endOffset); if (caretMarker.isValid() && caretModel.getOffset() != caretMarker.getStartOffset()) { caretModel.moveToOffset(caretMarker.getStartOffset()); } } }); } finally { PsiDocumentManager documentManager = PsiDocumentManager.getInstance(file.getProject()); if (documentManager.isUncommited(document)) documentManager.commitDocument(document); if (editorFactory != null) { editorFactory.releaseEditor(editor); } } }
@Override protected void performRefactoring(UsageInfo[] usages) { GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject); PsiType initializerType = mySettings.getSelectedType(); // Changing external occurrences (the tricky part) IntroduceParameterUtil.processUsages(usages, this); final GrMethod toReplaceIn = (GrMethod) mySettings.getToReplaceIn(); final PsiMethod toSearchFor = (PsiMethod) mySettings.getToSearchFor(); final boolean methodsToProcessAreDifferent = toReplaceIn != toSearchFor; if (mySettings.generateDelegate()) { GroovyIntroduceParameterUtil.generateDelegate(toReplaceIn, myParameterInitializer, myProject); if (methodsToProcessAreDifferent) { final GrMethod method = GroovyIntroduceParameterUtil.generateDelegate( toSearchFor, myParameterInitializer, myProject); final PsiClass containingClass = method.getContainingClass(); if (containingClass != null && containingClass.isInterface()) { final GrOpenBlock block = method.getBlock(); if (block != null) { block.delete(); } } } } // Changing signature of initial method // (signature of myMethodToReplaceIn will be either changed now or have already been changed) LOG.assertTrue(initializerType == null || initializerType.isValid()); final FieldConflictsResolver fieldConflictsResolver = new FieldConflictsResolver(mySettings.getName(), toReplaceIn.getBlock()); IntroduceParameterUtil.changeMethodSignatureAndResolveFieldConflicts( new UsageInfo(toReplaceIn), usages, this); if (methodsToProcessAreDifferent) { IntroduceParameterUtil.changeMethodSignatureAndResolveFieldConflicts( new UsageInfo(toSearchFor), usages, this); } // Replacing expression occurrences for (UsageInfo usage : usages) { if (usage instanceof ChangedMethodCallInfo) { PsiElement element = usage.getElement(); GroovyIntroduceParameterUtil.processChangedMethodCall(element, mySettings, myProject); } else if (usage instanceof InternalUsageInfo) { PsiElement element = usage.getElement(); if (element == null) continue; GrExpression newExpr = factory.createExpressionFromText(mySettings.getName()); if (element instanceof GrExpression) { ((GrExpression) element).replaceWithExpression(newExpr, true); } else { element.replace(newExpr); } } } final StringPartInfo stringPartInfo = mySettings.getStringPartInfo(); if (stringPartInfo != null) { final GrExpression expr = GrIntroduceHandlerBase.processLiteral( mySettings.getName(), mySettings.getStringPartInfo(), mySettings.getProject()); final Editor editor = PsiUtilBase.findEditor(expr); if (editor != null) { editor.getSelectionModel().removeSelection(); editor.getCaretModel().moveToOffset(expr.getTextRange().getEndOffset()); } } final GrVariable var = mySettings.getVar(); if (var != null && mySettings.removeLocalVariable()) { var.delete(); } fieldConflictsResolver.fix(); }