/* Soot - a J*va Optimization Framework
* Copyright (C) 2000 Patrice Pominville
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the Sable Research Group and others 1997-1999.
* See the 'credits' file distributed with Soot for the complete list of
* contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
*/
/* Modified By Marc Berndl May 17th */
package soot.jimple.parser;
import soot.*;
import soot.jimple.parser.node.*;
import java.util.*;
/*
Walks a jimple AST and extracts the fields, and method signatures and produces
a new squeleton SootClass instance.
*/
public class SkeletonExtractorWalker extends Walker
{
public SkeletonExtractorWalker(SootResolver aResolver, SootClass aSootClass)
{
super(aSootClass, aResolver);
}
public SkeletonExtractorWalker(SootResolver aResolver)
{
super(aResolver);
}
public void caseAFile(AFile node)
{
inAFile(node);
{
Object temp[] = node.getModifier().toArray();
for (Object element : temp) {
((PModifier) element).apply(this);
}
}
if(node.getFileType() != null)
{
node.getFileType().apply(this);
}
if(node.getClassName() != null)
{
node.getClassName().apply(this);
}
String className = (String) mProductions.removeLast();
if(mSootClass == null) {
mSootClass = new SootClass(className);
mSootClass.setResolvingLevel(SootClass.SIGNATURES);
} else {
if(!className.equals(mSootClass.getName()))
throw new RuntimeException("expected: " + className + ", but got: " + mSootClass.getName());
}
if(node.getExtendsClause() != null)
{
node.getExtendsClause().apply(this);
}
if(node.getImplementsClause() != null)
{
node.getImplementsClause().apply(this);
}
if(node.getFileBody() != null)
{
node.getFileBody().apply(this);
}
outAFile(node);
}
public void outAFile(AFile node)
{
List implementsList = null;
String superClass = null;
String classType = null;
if(node.getImplementsClause() != null) {
implementsList = (List) mProductions.removeLast();
}
if(node.getExtendsClause() != null) {
superClass = (String) mProductions.removeLast();
}
classType = (String) mProductions.removeLast();
int modifierFlags = processModifiers(node.getModifier());
if(classType.equals("interface"))
modifierFlags |= Modifier.INTERFACE;
mSootClass.setModifiers(modifierFlags);
if(superClass != null) {
mSootClass.setSuperclass(mResolver.makeClassRef(superClass));
}
if(implementsList != null) {
Iterator implIt = implementsList.iterator();
while(implIt.hasNext()) {
SootClass interfaceClass = mResolver.makeClassRef((String) implIt.next());
mSootClass.addInterface(interfaceClass);
}
}
mProductions.addLast(mSootClass);
}
/*
member =
{field} modifier* type name semicolon |
{method} modifier* type name l_paren parameter_list? r_paren throws_clause? method_body;
*/
public void caseAMethodMember(AMethodMember node)
{
inAMethodMember(node);
{
Object temp[] = node.getModifier().toArray();
for (Object element : temp) {
((PModifier) element).apply(this);
}
}
if(node.getType() != null)
{
node.getType().apply(this);
}
if(node.getName() != null)
{
node.getName().apply(this);
}
if(node.getLParen() != null)
{
node.getLParen().apply(this);
}
if(node.getParameterList() != null)
{
node.getParameterList().apply(this);
}
if(node.getRParen() != null)
{
node.getRParen().apply(this);
}
if(node.getThrowsClause() != null)
{
node.getThrowsClause().apply(this);
}
/*if(node.getMethodBody() != null)
{
node.getMethodBody().apply(this);
}*/
outAMethodMember(node);
}
public void outAMethodMember(AMethodMember node)
{
int modifier = 0;
Type type;
String name;
List parameterList = null;
List<SootClass> throwsClause = null;
if(node.getThrowsClause() != null)
throwsClause = (List<SootClass>) mProductions.removeLast();
if(node.getParameterList() != null) {
parameterList = (List) mProductions.removeLast();
}
else {
parameterList = new ArrayList();
}
Object o = mProductions.removeLast();
name = (String) o;
type = (Type) mProductions.removeLast();
modifier = processModifiers(node.getModifier());
SootMethod method;
if(throwsClause != null)
method = new SootMethod(name, parameterList, type, modifier, throwsClause);
else
method = new SootMethod(name, parameterList, type, modifier);
mSootClass.addMethod(method);
}
/*
throws_clause =
throws class_name_list;
*/
public void outAThrowsClause(AThrowsClause node)
{
List l = (List) mProductions.removeLast();
Iterator it = l.iterator();
List<SootClass> exceptionClasses = new ArrayList<SootClass>(l.size());
while(it.hasNext()) {
String className = (String) it.next();
exceptionClasses.add(mResolver.makeClassRef(className));
}
mProductions.addLast(exceptionClasses);
}
}