/****************************************************************************** * Copyright (c) 2002 - 2012 IBM Corporation. * 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 *****************************************************************************/ package com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices; import java.util.Iterator; import java.util.Set; import com.ibm.wala.cast.js.ipa.summaries.JavaScriptConstructorFunctions.JavaScriptConstructor; import com.ibm.wala.cast.js.types.JavaScriptMethods; import com.ibm.wala.cast.js.types.JavaScriptTypes; import com.ibm.wala.classLoader.CallSiteReference; import com.ibm.wala.classLoader.IClass; import com.ibm.wala.classLoader.NewSiteReference; import com.ibm.wala.ipa.callgraph.CGNode; import com.ibm.wala.ipa.callgraph.CallGraph; import com.ibm.wala.types.MethodReference; import com.ibm.wala.util.collections.EmptyIterator; import com.ibm.wala.util.collections.NonNullSingletonIterator; import com.ibm.wala.util.collections.Pair; /** * A function vertex represents a function object (or, more precisely, all function objects * arising from a single function expression or declaration). * * @author mschaefer */ public class FuncVertex extends Vertex implements ObjectVertex { // the IClass representing this function in the class hierarchy protected final IClass klass; FuncVertex(IClass method) { this.klass = method; } public String getFullName() { return klass.getName().toString(); } @Override public <T> T accept(VertexVisitor<T> visitor) { return visitor.visitFuncVertex(this); } @Override public String toString() { String methodName = klass.getName().toString(); return "Func(" + methodName.substring(methodName.lastIndexOf('/')+1) + ")"; } @Override public Iterator<Pair<CGNode, NewSiteReference>> getCreationSites(CallGraph CG) { MethodReference ctorRef = JavaScriptMethods.makeCtorReference(JavaScriptTypes.Function); Set<CGNode> f = CG.getNodes(ctorRef); CGNode ctor = null; for(CGNode n : f) { JavaScriptConstructor c = (JavaScriptConstructor) n.getMethod(); if (c.constructedType().equals(klass)) { ctor = n; break; } } // built in objects if (ctor == null) { return EmptyIterator.instance(); } Iterator<CGNode> callers = CG.getPredNodes(ctor); CGNode caller = callers.next(); assert !callers.hasNext(); Iterator<CallSiteReference> sites = CG.getPossibleSites(caller, ctor); CallSiteReference site = sites.next(); assert !sites.hasNext() : caller + " --> " + ctor + " @ " + site + " and " + sites.next() + "\n" + caller.getIR(); return NonNullSingletonIterator.make(Pair.make(caller, NewSiteReference.make(site.getProgramCounter(), klass.getReference()))); } @Override public IClass getConcreteType() { return klass; } }