/** * Copyright 2008 Anders Hessellund * * 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. * * $Id: DefUseChain.java,v 1.1 2008/01/17 18:48:18 hessellund Exp $ */ package org.ofbiz.plugin.analysis; import java.util.HashSet; import java.util.Set; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.Assignment; import org.eclipse.jdt.core.dom.IVariableBinding; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.SimpleName; import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.Statement; class DefUseChain { private ReachingDefinitionAnalysis rda; private MethodDeclaration method; DefUseChain(ReachingDefinitionAnalysis rda, MethodDeclaration method) { assert rda != null; assert rda.isDone : "analysis must have been performed initially"; assert rda.cfg.method == method : "wrong method"; this.rda = rda; this.method = method; } // inspired by StaticAnalysisFor JavaInEclipse p.87 Set<Statement> findRefsToDef(ASTNode def) { final Set<Statement> result = new HashSet<Statement>(); final SimpleName name; if(def instanceof SingleVariableDeclaration) { SingleVariableDeclaration svd = (SingleVariableDeclaration) def; name = svd.getName(); } else if (def instanceof Assignment) { //TODO: impl ref2def for assigment throw new RuntimeException("not implemented yet"); } else { //TODO: impl andre typer ref2def throw new RuntimeException("not implemented yet"); } final IVariableBinding defBinding = (IVariableBinding) name.resolveBinding(); method.accept(new ASTVisitor() { @Override public boolean visit(SimpleName node) { // why is this necessary? if(node.resolveBinding()!=defBinding) return false; Statement stmt = getContainingStatement(node); if (stmt==null) return false; for (Pair<String, ASTNode> pair : rda.getInSet(stmt)) { if(pair.first.equals(name.getIdentifier())) { result.add(stmt); // stmt contains node, ok? } } return false; } }); return result; } // inspired by StaticAnalysisFor JavaInEclipse p.88 Set<ASTNode> findDefsForRef(SimpleName ref) { final Set<ASTNode> result = new HashSet<ASTNode>(); Statement stmt = getContainingStatement(ref); if (stmt==null) throw new RuntimeException("invalid reference "+Util.getFirstLine(ref)); // if the variable is in the entry-set of the statement // then add the corresponding ASTNode. for (Pair<String, ASTNode> pair : rda.getInSet(stmt)) { if(pair.first.equals(ref.getIdentifier())) { result.add(pair.second); // stmt contains node, ok? } } return result; } /** returns the statement that contains the given node or null if no such statement can be found */ private Statement getContainingStatement(ASTNode node) { assert node != null; while(!(node instanceof Statement)) { node = node.getParent(); if (node==null) return null; } return (Statement) node; } }