/* * Copyright 2012 Phil Pratt-Szeliga and other contributors * http://chirrup.org/ * * See the file LICENSE for copying permission. */ package org.trifort.rootbeer.generate.bytecode; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.trifort.rootbeer.compiler.FindMethodCalls; import soot.Body; import soot.SootClass; import soot.SootField; import soot.SootMethod; import soot.Unit; import soot.Value; import soot.jimple.AssignStmt; import soot.jimple.FieldRef; public class ReadOnlyTypes { private SootClass m_RootClass; private Set<String> m_WrittenClasses; private Set<String> m_Inspected; public ReadOnlyTypes(SootMethod gpuMethod) { m_RootClass = gpuMethod.getDeclaringClass(); m_WrittenClasses = new HashSet<String>(); m_Inspected = new HashSet<String>(); inspectMethod(gpuMethod); } public boolean isRootReadOnly(){ return isReadOnly(m_RootClass); } public boolean isReadOnly(SootClass soot_class){ String name = soot_class.getName(); if(m_WrittenClasses.contains(name)) return false; return true; } private void inspectMethod(SootMethod method) { String sig = method.getSignature(); if(m_Inspected.contains(sig)) return; m_Inspected.add(sig); if(method.isConcrete() == false){ return; } if(method.hasActiveBody() == false){ return; } Body body = method.getActiveBody(); if(body == null) return; inspectBody(body); FindMethodCalls finder = new FindMethodCalls(); Set<SootMethod> calls = finder.findForMethod(method); Iterator<SootMethod> iter = calls.iterator(); while(iter.hasNext()){ SootMethod curr = iter.next(); inspectMethod(curr); } } private void inspectBody(Body body) { Iterator<Unit> iter = body.getUnits().iterator(); while(iter.hasNext()){ Unit curr = iter.next(); if(curr instanceof AssignStmt == false) continue; AssignStmt assign = (AssignStmt) curr; Value lhs = assign.getLeftOp(); if(lhs instanceof FieldRef == false) continue; FieldRef ref = (FieldRef) lhs; SootField field = ref.getField(); String name = field.getDeclaringClass().getName(); if(m_WrittenClasses.contains(name) == false) m_WrittenClasses.add(name); } } }