blob: 9d261f9263c8bd1e57f3181f8d0f34b5faf88db8 [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.lang.psi.impl;
import com.intellij.extapi.psi.ASTDelegatePsiElement;
import com.intellij.extapi.psi.ASTWrapperPsiElement;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiInvalidElementAccessException;
import com.intellij.psi.impl.CheckUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
/**
* @author ilyas
*/
public abstract class GroovyPsiElementImpl extends ASTWrapperPsiElement implements GroovyPsiElement {
public GroovyPsiElementImpl(@NotNull ASTNode node) {
super(node);
}
@Override
public void delete() throws IncorrectOperationException {
if (getParent() instanceof ASTDelegatePsiElement) {
CheckUtil.checkWritable(this);
((ASTDelegatePsiElement) getParent()).deleteChildInternal(getNode());
} else {
getParent().deleteChildRange(this, this);
}
}
@Override
public void accept(GroovyElementVisitor visitor) {
visitor.visitElement(this);
}
@Override
public void acceptChildren(GroovyElementVisitor visitor) {
acceptGroovyChildren(this, visitor);
}
@Nullable
public static GrExpression findExpressionChild(final PsiElement element) {
for (PsiElement cur = element.getFirstChild(); cur != null; cur = cur.getNextSibling()) {
if (cur instanceof GrExpression) return (GrExpression)cur;
}
return null;
}
public static void acceptGroovyChildren(PsiElement parent, GroovyElementVisitor visitor) {
PsiElement child = parent.getFirstChild();
while (child != null) {
ProgressManager.checkCanceled();
if (child instanceof GroovyPsiElement) {
((GroovyPsiElement) child).accept(visitor);
}
child = child.getNextSibling();
}
}
/**
* don't remove. it is used by inheritors
*/
@SuppressWarnings({"UnusedDeclaration"})
public void removeElements(PsiElement[] elements) throws IncorrectOperationException {
removeElements(this, elements);
}
public static void removeElements(PsiElement from, PsiElement[] elements) {
ASTNode parentNode = from.getNode();
for (PsiElement element : elements) {
if (element.isValid()) {
ASTNode node = element.getNode();
if (node == null || node.getTreeParent() != parentNode) {
throw new IncorrectOperationException();
}
parentNode.removeChild(node);
}
}
}
/**
* don't remove. it is used by inheritors
*/
@SuppressWarnings({"UnusedDeclaration"})
public void removeStatement() throws IncorrectOperationException {
removeStatement(this);
}
public static void removeStatement(GroovyPsiElement element) {
if (element.getParent() == null ||
element.getParent().getNode() == null) {
throw new IncorrectOperationException();
}
ASTNode parentNode = element.getParent().getNode();
ASTNode prevNode = element.getNode().getTreePrev();
parentNode.removeChild(element.getNode());
if (prevNode != null && TokenSets.SEPARATORS.contains(prevNode.getElementType())) {
parentNode.removeChild(prevNode);
}
}
public <T extends GrStatement> T replaceWithStatement(@NotNull T newStmt) {
return replaceWithStatement(this, newStmt);
}
public static <T extends GrStatement> T replaceWithStatement(GroovyPsiElement element, @NotNull T newStmt) {
PsiElement parent = element.getParent();
if (parent == null) {
throw new PsiInvalidElementAccessException(element);
}
return (T)element.replace(newStmt);
}
}