/*******************************************************************************
* Copyright (c) 2008, 2013 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Institute for Software - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.utils;
import java.util.ArrayList;
import java.util.Collection;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
import org.eclipse.cdt.internal.ui.refactoring.extractfunction.TrailNodeEqualityChecker;
public class ASTHelper {
private ASTHelper() {
}
public static IASTNode getDeclarationForNode(IASTNode node) {
while (node != null && !(node instanceof IASTSimpleDeclaration) && !(node instanceof IASTParameterDeclaration)) {
node = node.getParent();
}
return node;
}
public static IASTDeclarator getDeclaratorForNode(IASTNode node) {
IASTNode tmpNode = getDeclarationForNode(node);
IASTDeclarator declarator = null;
if (tmpNode instanceof IASTSimpleDeclaration) {
IASTSimpleDeclaration decl = (IASTSimpleDeclaration) tmpNode;
if (decl.getDeclarators().length > 0) {
declarator = decl.getDeclarators()[0];
}
} else if (tmpNode instanceof IASTParameterDeclaration) {
IASTParameterDeclaration decl = (IASTParameterDeclaration) tmpNode;
declarator = decl.getDeclarator();
}
return declarator;
}
public static IASTDeclSpecifier getDeclarationSpecifier(IASTNode declaration) {
if (declaration != null) {
if (declaration instanceof IASTSimpleDeclaration) {
IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) declaration;
return simpleDecl.getDeclSpecifier();
} else if (declaration instanceof ICPPASTParameterDeclaration) {
ICPPASTParameterDeclaration paramDecl = (ICPPASTParameterDeclaration) declaration;
return paramDecl.getDeclSpecifier();
}
}
return null;
}
public static boolean samePointers(IASTPointerOperator[] pointerOperators1,
IASTPointerOperator[] pointerOperators2, TrailNodeEqualityChecker checker) {
if (pointerOperators2.length == pointerOperators1.length) {
for (int i = 0; i < pointerOperators2.length; i++) {
IASTPointerOperator operator1 = pointerOperators1[i];
IASTPointerOperator operator2 = pointerOperators2[i];
if (!checker.isEqual(operator1, operator2)) {
return false;
}
}
} else {
return false;
}
return true;
}
public static boolean isClassDeclarationName(IASTName astName) {
if (astName == null)
return false;
IASTNode parent = astName.getParent();
if (parent instanceof ICPPASTCompositeTypeSpecifier) {
ICPPASTCompositeTypeSpecifier typeSpecifier = (ICPPASTCompositeTypeSpecifier) parent;
return typeSpecifier.getKey() == ICPPASTCompositeTypeSpecifier.k_class;
}
return false;
}
public static Collection<IASTDeclSpecifier> getCompositeTypeSpecifiers(IASTNode baseNode) {
final Collection<IASTDeclSpecifier> specifiers = new ArrayList<IASTDeclSpecifier>();
ASTVisitor visitor = new ASTVisitor() {
@Override
public int visit(IASTDeclSpecifier declSpec) {
specifiers.add(declSpec);
return super.visit(declSpec);
}
};
visitor.shouldVisitDeclSpecifiers = true;
baseNode.accept(visitor);
return specifiers;
}
public static Collection<IASTPreprocessorStatement> getAllInFilePreprocessorStatements(
IASTTranslationUnit unit, String aktFileName) {
Collection<IASTPreprocessorStatement> statements = new ArrayList<IASTPreprocessorStatement>();
for (IASTPreprocessorStatement aktStatement : unit.getAllPreprocessorStatements()) {
if (aktStatement.getFileLocation() != null && aktStatement.getFileLocation().getFileName().equals(aktFileName)) {
statements.add(aktStatement);
}
}
return statements;
}
public static Collection<IASTDeclaration> getAllInFileDeclarations(IASTTranslationUnit unit, String aktFileName) {
Collection<IASTDeclaration> decls = new ArrayList<IASTDeclaration>();
for (IASTDeclaration aktDecl: unit.getDeclarations()) {
if (aktDecl.getFileLocation() != null && aktDecl.getFileLocation().getFileName().equals(aktFileName)) {
decls.add(aktDecl);
}
}
return decls;
}
public static ICPPASTUsingDirective getActiveUsingDirecitveForNode(IASTNode node, IASTTranslationUnit unit) {
ICPPASTUsingDirective activeDirective = null;
for (IASTDeclaration aktDeclaration : getAllInFileDeclarations(unit, node.getFileLocation().getFileName())) {
if (aktDeclaration.getFileLocation().getNodeOffset() >= node.getFileLocation().getNodeOffset()) {
break;
}
if (aktDeclaration instanceof ICPPASTUsingDirective) {
activeDirective = (ICPPASTUsingDirective) aktDeclaration;
}
}
return activeDirective;
}
public static Collection<ICPPASTUsingDeclaration> getUsingDeclarations(IASTTranslationUnit unit) {
Collection<ICPPASTUsingDeclaration> usingDecls = new ArrayList<ICPPASTUsingDeclaration>();
for (IASTDeclaration aktDecl : unit.getDeclarations()) {
if (aktDecl instanceof ICPPASTUsingDeclaration) {
usingDecls.add((ICPPASTUsingDeclaration) aktDecl);
}
}
return usingDecls;
}
public static IASTCompositeTypeSpecifier getCompositeTypeSpecifierForName(IASTName name) {
IBinding binding = name.resolveBinding();
for (IASTName aktName : name.getTranslationUnit().getDefinitionsInAST(binding)) {
if (aktName.getParent() instanceof IASTCompositeTypeSpecifier) {
return (IASTCompositeTypeSpecifier) aktName.getParent();
}
}
return null;
}
public static Collection<IASTFunctionDeclarator> getFunctionDeclaratorsForClass(IASTCompositeTypeSpecifier klass) {
Collection<IASTFunctionDeclarator> declarators = new ArrayList<IASTFunctionDeclarator>();
for (IASTDeclaration aktDeclaration : klass.getMembers()) {
if (aktDeclaration instanceof IASTSimpleDeclaration) {
for (IASTDeclarator aktDeclarator : ((IASTSimpleDeclaration) aktDeclaration).getDeclarators()) {
if (aktDeclarator instanceof IASTFunctionDeclarator) {
declarators.add((IASTFunctionDeclarator) aktDeclarator);
}
}
}
}
return declarators;
}
public static Collection<IASTFunctionDefinition> getFunctionDefinitionsForClass(IASTCompositeTypeSpecifier klass) {
Collection<IASTFunctionDefinition> definitions = new ArrayList<IASTFunctionDefinition>();
for (IASTFunctionDeclarator aktDeclarator : getFunctionDeclaratorsForClass(klass)) {
IBinding binding = aktDeclarator.getName().resolveBinding();
for (IASTName aktName : aktDeclarator.getTranslationUnit().getDefinitionsInAST(binding)) {
if (aktName.getParent().getParent().getParent() instanceof IASTFunctionDefinition) {
definitions.add((IASTFunctionDefinition) aktName.getParent().getParent().getParent());
}
}
}
return definitions;
}
}