/****************************************************************************** * 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.Collection; import java.util.Map; import com.ibm.wala.cast.js.ssa.JavaScriptInvoke; import com.ibm.wala.classLoader.CallSiteReference; import com.ibm.wala.classLoader.IClass; import com.ibm.wala.classLoader.IMethod; import com.ibm.wala.types.TypeReference; import com.ibm.wala.util.collections.HashMapFactory; import com.ibm.wala.util.collections.Pair; /** * A vertex factory is associated with a flow graph. It manages its vertex set, making sure that * vertices aren't unnecessarily created twice. * * @author mschaefer * */ public class VertexFactory { private final Map<Pair<FuncVertex, CallSiteReference>, CallVertex> callVertexCache = HashMapFactory.make(); private final Map<IClass, FuncVertex> funcVertexCache = HashMapFactory.make(); private final Map<Pair<FuncVertex, Integer>, ParamVertex> paramVertexCache = HashMapFactory.make(); private final Map<String, PropVertex> propVertexCache = HashMapFactory.make(); private final Map<FuncVertex, RetVertex> retVertexCache = HashMapFactory.make(); private final Map<FuncVertex, ArgVertex> argVertexCache = HashMapFactory.make(); private final Map<Pair<FuncVertex, Integer>, VarVertex> varVertexCache = HashMapFactory.make(); private final Map<Pair<String, String>, LexicalVarVertex> lexicalAccessVertexCache = HashMapFactory.make(); private final Map<Pair<IMethod,Integer>, CreationSiteVertex> creationSites = HashMapFactory.make(); public CallVertex makeCallVertex(FuncVertex func, JavaScriptInvoke invk) { CallSiteReference site = invk.getCallSite(); Pair<FuncVertex, CallSiteReference> key = Pair.make(func, site); CallVertex value = callVertexCache.get(key); if(value == null) callVertexCache.put(key, value = new CallVertex(func, site, invk)); return value; } public Iterable<CallVertex> getCallVertices() { return callVertexCache.values(); } public CreationSiteVertex makeCreationSiteVertex(IMethod method, int instruction, TypeReference createdType) { Pair<IMethod, Integer> key = Pair.make(method, instruction); CreationSiteVertex value = creationSites.get(key); if (value == null) { creationSites.put(key, value = new CreationSiteVertex(method, instruction, createdType)); } return value; } public Collection<CreationSiteVertex> creationSites() { return creationSites.values(); } public FuncVertex makeFuncVertex(IClass klass) { FuncVertex value = funcVertexCache.get(klass); if(value == null) funcVertexCache.put(klass, value = new FuncVertex(klass)); return value; } public Collection<FuncVertex> getFuncVertices() { return funcVertexCache.values(); } public ParamVertex makeParamVertex(FuncVertex func, int index) { Pair<FuncVertex, Integer> key = Pair.make(func, index); ParamVertex value = paramVertexCache.get(key); if(value == null) paramVertexCache.put(key, value = new ParamVertex(func, index)); return value; } public PropVertex makePropVertex(String name) { PropVertex value = propVertexCache.get(name); if(value == null) propVertexCache.put(name, value = new PropVertex(name)); return value; } public Iterable<PropVertex> getPropVertices() { return propVertexCache.values(); } public RetVertex makeRetVertex(FuncVertex func) { RetVertex value = retVertexCache.get(func); if(value == null) retVertexCache.put(func, value = new RetVertex(func)); return value; } public ArgVertex makeArgVertex(FuncVertex func) { ArgVertex value = argVertexCache.get(func); if(value == null) argVertexCache.put(func, value = new ArgVertex(func)); return value; } public UnknownVertex makeUnknownVertex() { return UnknownVertex.INSTANCE; } public VarVertex makeVarVertex(FuncVertex func, int valueNumber) { Pair<FuncVertex, Integer> key = Pair.make(func, valueNumber); VarVertex value = varVertexCache.get(key); if(value == null) varVertexCache.put(key, value = new VarVertex(func, valueNumber)); return value; } public LexicalVarVertex makeLexicalAccessVertex(String definer, String name) { Pair<String, String> key = Pair.make(definer, name); LexicalVarVertex value = lexicalAccessVertexCache.get(key); if(value == null) lexicalAccessVertexCache.put(key, value = new LexicalVarVertex(definer, name)); return value; } private GlobalVertex global = GlobalVertex.instance(); public GlobalVertex global() { return global; } }