blob: fd25a24eda1bfe772345951d55dbebb84253653b [file] [log] [blame]
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.unwrap;
import com.intellij.codeInsight.unwrap.AbstractUnwrapper;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrBlockStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrIfStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock;
import java.util.List;
public abstract class GroovyUnwrapper extends AbstractUnwrapper<GroovyUnwrapper.Context> {
public GroovyUnwrapper(String description) {
super(description);
}
@Override
protected Context createContext() {
return new Context();
}
public static boolean isElseBlock(@Nullable final PsiElement element) {
if (element == null) return false;
final PsiElement parent = element.getParent();
return parent instanceof GrIfStatement && element == ((GrIfStatement)parent).getElseBranch();
}
@Override
public List<PsiElement> unwrap(Editor editor, PsiElement element) throws IncorrectOperationException {
List<PsiElement> res = super.unwrap(editor, element);
for (PsiElement e : res) {
if (PsiImplUtil.isLeafElementOfType(e, GroovyTokenTypes.mNLS)) {
CodeEditUtil.setNodeGenerated(e.getNode(), true);
}
}
return res;
}
protected static class Context extends AbstractUnwrapper.AbstractContext {
public void extractFromBlockOrSingleStatement(GrStatement block, PsiElement from) throws IncorrectOperationException {
if (block instanceof GrBlockStatement) {
extractFromCodeBlock(((GrBlockStatement)block).getBlock(), from);
}
else if (block != null) {
extract(block, block, from);
}
}
public void extractFromCodeBlock(GrCodeBlock block, PsiElement from) throws IncorrectOperationException {
if (block == null) return;
PsiElement rBrace = block.getRBrace();
PsiElement lBrace = block.getLBrace();
PsiElement firstBodyElement;
if (lBrace == null) {
firstBodyElement = null;
}
else {
firstBodyElement = lBrace.getNextSibling();
if (firstBodyElement == rBrace) {
firstBodyElement = null;
}
}
PsiElement lastBodyElement;
if (rBrace == null) {
lastBodyElement = null;
}
else {
lastBodyElement = rBrace.getPrevSibling();
if (lastBodyElement == lBrace) {
lastBodyElement = null;
}
}
extract(firstBodyElement, lastBodyElement, from);
}
@Override
protected boolean isWhiteSpace(PsiElement element) {
return org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil.isWhiteSpaceOrNls(element);
}
public void setElseBranch(GrIfStatement ifStatement, GrStatement elseBranch) throws IncorrectOperationException {
GrStatement toExtract = elseBranch;
if (myIsEffective) {
ifStatement.replaceElseBranch(copyElement(elseBranch));
toExtract = ifStatement.getElseBranch();
}
addElementToExtract(toExtract);
}
private static GrStatement copyElement(GrStatement e) throws IncorrectOperationException {
// We cannot call el.copy() for 'else' since it sets context to parent 'if'.
// This causes copy to be invalidated after parent 'if' is removed by setElseBranch method.
GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(e.getProject());
return factory.createStatementFromText(e.getText(), null);
}
}
}