/*******************************************************************************
* Copyright (c) 2000, 2012 IBM Corporation 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:
* IBM Corporation - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.corext.refactoring.code.flow;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
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.IASTReturnStatement;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTRangeBasedForStatement;
import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
public class InOutFlowAnalyzer extends FlowAnalyzer {
public InOutFlowAnalyzer(FlowContext context) {
super(context);
}
public FlowInfo perform(IASTNode[] selectedNodes) {
FlowContext context= getFlowContext();
GenericSequentialFlowInfo result= createSequential();
for (int i= 0; i < selectedNodes.length; i++) {
IASTNode node= selectedNodes[i];
node.accept(this);
result.merge(getFlowInfo(node), context);
}
return result;
}
@Override
protected boolean traverseNode(IASTNode node) {
// We are only traversing the selected nodes.
return true;
}
@Override
protected boolean shouldCreateReturnFlowInfo(IASTReturnStatement node) {
// We are only traversing selected nodes.
return true;
}
@Override
public int leave(IASTCompoundStatement node) {
super.leave(node);
clearAccessMode(accessFlowInfo(node), node.getStatements());
return PROCESS_SKIP;
}
@Override
public int leave(ICPPASTCatchHandler node) {
super.leave(node);
clearAccessMode(accessFlowInfo(node), node.getDeclaration());
return PROCESS_SKIP;
}
@Override
public int leave(IASTForStatement node) {
super.leave(node);
clearAccessMode(accessFlowInfo(node), node.getInitializerStatement());
return PROCESS_SKIP;
}
@Override
public int leave(ICPPASTRangeBasedForStatement node) {
super.leave(node);
clearAccessMode(accessFlowInfo(node), node.getDeclaration());
return PROCESS_SKIP;
}
@Override
public int leave(IASTFunctionDefinition node) {
super.leave(node);
FlowInfo info= accessFlowInfo(node);
IASTFunctionDeclarator declarator = node.getDeclarator();
if (declarator instanceof IASTStandardFunctionDeclarator) {
for (IASTParameterDeclaration param : ((IASTStandardFunctionDeclarator) declarator).getParameters()) {
clearAccessMode(info, param.getDeclarator());
}
} else if (declarator instanceof ICASTKnRFunctionDeclarator) {
for (IASTDeclaration param : ((ICASTKnRFunctionDeclarator) declarator).getParameterDeclarations()) {
clearAccessMode(info, param);
}
}
return PROCESS_SKIP;
}
private void clearAccessMode(FlowInfo info, IASTStatement[] statements) {
if (statements == null || statements.length == 0 || info == null)
return;
for (IASTStatement statement : statements) {
clearAccessMode(info, statement);
}
}
private void clearAccessMode(FlowInfo info, IASTStatement statement) {
if (statement instanceof IASTDeclarationStatement) {
IASTDeclaration declaration = ((IASTDeclarationStatement) statement).getDeclaration();
clearAccessMode(info, declaration);
}
}
private void clearAccessMode(FlowInfo info, IASTDeclaration declaration) {
if (declaration instanceof IASTSimpleDeclaration) {
IASTDeclarator[] declarators = ((IASTSimpleDeclaration) declaration).getDeclarators();
for (IASTDeclarator declarator : declarators) {
clearAccessMode(info, declarator);
}
}
}
private void clearAccessMode(FlowInfo info, IASTDeclarator declarator) {
declarator = CPPVisitor.findInnermostDeclarator(declarator);
IASTName name = declarator.getName();
IBinding binding= name.resolveBinding();
if (binding instanceof IVariable && !(binding instanceof IField))
info.clearAccessMode((IVariable) binding, fFlowContext);
}
}