PsiExpression (PsiElement @NotNull [] copy, @NotNull ExtractMethodProcessor originalProcessor) { if (copy.length != 1 || !(copy[0] instanceof PsiExpression expression)) return null; PsiType type = expression.getType(); if (type == null || PsiTypes.nullType().equals(type)) return null; PsiElement parent = expression.getParent(); PsiElementFactory factory = JavaPsiFacade.getElementFactory(expression.getProject()); PsiClass parentClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class); if (parentClass == null) return null; PsiElement parentClassStart = parentClass.getLBrace(); if (parentClassStart == null) return null; // It's syntactically correct to write "new Object() {void foo(){}}.foo()" - see JLS 15.9.5 @NonNls String wrapperBodyText = (PsiTypes.voidType().equals(type) ? "" : "return ") + expression.getText() + ";"; String wrapperClassImmediateCallText = "new " + CommonClassNames.JAVA_LANG_OBJECT + "() { " + type.getCanonicalText() + " wrapperMethod() {" + wrapperBodyText + "} " + "}.wrapperMethod()"; PsiExpression wrapperClassImmediateCall = factory.createExpressionFromText(wrapperClassImmediateCallText, parent); wrapperClassImmediateCall = (PsiExpression)expression.replace(wrapperClassImmediateCall); PsiMethod method = PsiTreeUtil.findChildOfType(wrapperClassImmediateCall, PsiMethod.class); LOG.assertTrue(method != null, "wrapper class method is null"); PsiCodeBlock body = method.getBody(); LOG.assertTrue(body != null, "wrapper class method's body is null"); PsiStatement[] statements = body.getStatements(); LOG.assertTrue(statements.length == 1, "wrapper class method's body statement count"); PsiStatement bodyStatement = statements[0]; Set<PsiVariable> effectivelyLocal = originalProcessor.getEffectivelyLocalVariables(); for (PsiVariable variable : effectivelyLocal) { String name = variable.getName(); LOG.assertTrue(name != null, "effectively local variable's name is null"); PsiDeclarationStatement declaration = factory.createVariableDeclarationStatement(name, variable.getType(), null); body.addBefore(declaration, bodyStatement); } PsiExpression wrapped = null; if (PsiTypes.voidType().equals(type) && bodyStatement instanceof PsiExpressionStatement) { wrapped = ((PsiExpressionStatement)bodyStatement).getExpression(); } else if (bodyStatement instanceof PsiReturnStatement) { wrapped = ((PsiReturnStatement)bodyStatement).getReturnValue(); } else { LOG.error("Unexpected statement in expression code block " + bodyStatement); } if (wrapped != null) { // this key is not copyable so replace() doesn't preserve it - have to do it here wrapped.putUserData(ElementToWorkOn.REPLACE_NON_PHYSICAL, expression.getUserData(ElementToWorkOn.REPLACE_NON_PHYSICAL)); } return wrapped; }