/******************************************************************************* * Copyright (c) 2008, 2011 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 org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle; import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNamedTypeSpecifier; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleTypeTemplateParameter; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTemplateId; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypeId; import org.eclipse.cdt.internal.ui.refactoring.RefactoringASTCache; /** * Helper class to find Namespace informations. * @author Mirko Stocker */ public class NamespaceHelper { /** * Returns the qualified name of all namespaces that are defined at the specified translation unit and offset. * * @param translationUnit * @param offset * @param astCache * @return ICPPASTQualifiedName with the names of all namespaces * @throws CoreException */ public static ICPPASTQualifiedName getSurroundingNamespace(final ITranslationUnit translationUnit, final int offset, RefactoringASTCache astCache) throws CoreException { final CPPASTQualifiedName qualifiedName = new CPPASTQualifiedName(); astCache.getAST(translationUnit, null).accept(new CPPASTAllVisitor() { @Override public int visit(IASTDeclSpecifier declSpec) { if (declSpec instanceof ICPPASTCompositeTypeSpecifier && checkFileNameAndLocation(translationUnit.getLocation(), offset, declSpec)) { qualifiedName.addName(createNameWithTemplates(declSpec)); } return super.visit(declSpec); } @Override public int visit(ICPPASTNamespaceDefinition namespace) { if (checkFileNameAndLocation(translationUnit.getLocation(), offset, namespace)) { qualifiedName.addName((namespace).getName().copy()); } return super.visit(namespace); } }); return qualifiedName; } private static boolean checkFileNameAndLocation(final IPath path, final int offset, IASTNode namespace) { boolean fileNameOk = namespace.getFileLocation().getFileName().endsWith(path.toOSString()); if (!fileNameOk) { return false; } for (IASTNodeLocation nodeLocation : namespace.getNodeLocations()) { int nodeOffset = nodeLocation.getNodeOffset(); boolean locationOk = offset >= nodeOffset && offset < nodeOffset + nodeLocation.getNodeLength(); if (locationOk) { return true; } } return false; } private static IASTName createNameWithTemplates(IASTNode declarationParent) { IASTName parentName; parentName = ((ICPPASTCompositeTypeSpecifier) declarationParent).getName().copy( CopyStyle.withLocations); if (classHasTemplates(declarationParent)) { CPPASTTemplateId templateId = new CPPASTTemplateId(); templateId.setTemplateName(parentName); for (ICPPASTTemplateParameter templateParameter : ((ICPPASTTemplateDeclaration) declarationParent.getParent().getParent() ).getTemplateParameters()) { if (templateParameter instanceof CPPASTSimpleTypeTemplateParameter) { CPPASTSimpleTypeTemplateParameter simpleTypeTemplateParameter = (CPPASTSimpleTypeTemplateParameter) templateParameter; CPPASTTypeId id = new CPPASTTypeId(); CPPASTNamedTypeSpecifier namedTypeSpecifier = new CPPASTNamedTypeSpecifier(); namedTypeSpecifier.setName(simpleTypeTemplateParameter.getName().copy( CopyStyle.withLocations)); id.setDeclSpecifier(namedTypeSpecifier); templateId.addTemplateArgument(id); } } parentName = templateId; } return parentName; } private static boolean classHasTemplates(IASTNode declarationParent) { return declarationParent.getParent() != null && declarationParent.getParent().getParent() instanceof ICPPASTTemplateDeclaration; } }