217 lines
5.8 KiB
Java
217 lines
5.8 KiB
Java
/*******************************************************************************
|
|
* Copyright (c) 2013 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.loader;
|
|
|
|
import java.io.IOException;
|
|
import java.io.Reader;
|
|
import java.util.Collection;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.Iterator;
|
|
import java.util.Map;
|
|
import java.util.Map.Entry;
|
|
import java.util.Set;
|
|
|
|
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
|
import com.ibm.wala.classLoader.IClass;
|
|
import com.ibm.wala.classLoader.IClassLoader;
|
|
import com.ibm.wala.classLoader.IMethod;
|
|
import com.ibm.wala.classLoader.ModuleEntry;
|
|
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
|
import com.ibm.wala.types.TypeName;
|
|
import com.ibm.wala.util.collections.Filter;
|
|
import com.ibm.wala.util.collections.FilterIterator;
|
|
import com.ibm.wala.util.collections.HashMapFactory;
|
|
import com.ibm.wala.util.collections.HashSetFactory;
|
|
import com.ibm.wala.util.collections.MapIterator;
|
|
import com.ibm.wala.util.functions.Function;
|
|
import com.ibm.wala.util.strings.Atom;
|
|
import com.ibm.wala.util.warnings.Warning;
|
|
|
|
/**
|
|
* basic abstract class loader implementation
|
|
*
|
|
*/
|
|
public abstract class CAstAbstractLoader implements IClassLoader {
|
|
|
|
/**
|
|
* types loaded by this
|
|
*/
|
|
protected final Map<TypeName,IClass> types = HashMapFactory.make();
|
|
|
|
protected final IClassHierarchy cha;
|
|
|
|
protected final IClassLoader parent;
|
|
|
|
/**
|
|
* warnings generated while loading each module
|
|
*/
|
|
private final Map<ModuleEntry, Set<Warning>> errors = new HashMap<ModuleEntry, Set<Warning>>();
|
|
|
|
public CAstAbstractLoader(IClassHierarchy cha, IClassLoader parent) {
|
|
this.cha = cha;
|
|
this.parent = parent;
|
|
}
|
|
|
|
public CAstAbstractLoader(IClassHierarchy cha) {
|
|
this(cha, null);
|
|
}
|
|
|
|
public void addMessage(ModuleEntry module, Set<Warning> message) {
|
|
if (! errors.containsKey(module)) {
|
|
errors.put(module, new HashSet<Warning>());
|
|
}
|
|
|
|
errors.get(module).addAll(message);
|
|
}
|
|
|
|
public void addMessage(ModuleEntry module, Warning message) {
|
|
if (! errors.containsKey(module)) {
|
|
errors.put(module, new HashSet<Warning>());
|
|
}
|
|
|
|
errors.get(module).add(message);
|
|
}
|
|
|
|
private Iterator<ModuleEntry> getMessages(final byte severity) {
|
|
return new MapIterator<Map.Entry<ModuleEntry,Set<Warning>>, ModuleEntry>(new FilterIterator<Map.Entry<ModuleEntry,Set<Warning>>>(errors.entrySet().iterator(), new Filter<Map.Entry<ModuleEntry,Set<Warning>>>() {
|
|
@Override
|
|
public boolean accepts(Entry<ModuleEntry, Set<Warning>> o) {
|
|
for(Warning w : o.getValue()) {
|
|
if (w.getLevel() == severity) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}), new Function<Map.Entry<ModuleEntry,Set<Warning>>, ModuleEntry>() {
|
|
@Override
|
|
public ModuleEntry apply(Entry<ModuleEntry, Set<Warning>> object) {
|
|
return object.getKey();
|
|
}
|
|
});
|
|
}
|
|
|
|
public Iterator<ModuleEntry> getModulesWithParseErrors() {
|
|
return getMessages(Warning.SEVERE);
|
|
}
|
|
|
|
public Iterator<ModuleEntry> getModulesWithWarnings() {
|
|
return getMessages(Warning.MILD);
|
|
}
|
|
|
|
public Set<Warning> getMessages(ModuleEntry m) {
|
|
return errors.get(m);
|
|
}
|
|
|
|
|
|
public void clearMessages() {
|
|
errors.clear();
|
|
}
|
|
|
|
public IClass lookupClass(String className, IClassHierarchy cha) {
|
|
assert this.cha == cha;
|
|
return types.get(TypeName.string2TypeName(className));
|
|
}
|
|
|
|
@Override
|
|
public IClass lookupClass(TypeName className) {
|
|
return types.get(className);
|
|
}
|
|
|
|
@Override
|
|
public Iterator<IClass> iterateAllClasses() {
|
|
return types.values().iterator();
|
|
}
|
|
|
|
@Override
|
|
public int getNumberOfClasses() {
|
|
return types.size();
|
|
}
|
|
|
|
@Override
|
|
public Atom getName() {
|
|
return getReference().getName();
|
|
}
|
|
|
|
@Override
|
|
public int getNumberOfMethods() {
|
|
int i = 0;
|
|
for (Iterator cls = types.values().iterator(); cls.hasNext();) {
|
|
for (Iterator ms = ((IClass) cls.next()).getDeclaredMethods().iterator();
|
|
ms.hasNext(); )
|
|
{
|
|
i++;
|
|
ms.next();
|
|
}
|
|
}
|
|
|
|
return i;
|
|
}
|
|
|
|
@Override
|
|
public String getSourceFileName(IMethod method, int bcOffset) {
|
|
if (!(method instanceof AstMethod)){
|
|
return null;
|
|
}
|
|
Position pos = ((AstMethod)method).getSourcePosition(bcOffset);
|
|
if (null == pos){
|
|
return null;
|
|
}
|
|
return pos.getURL().getFile();
|
|
}
|
|
|
|
@Override
|
|
public String getSourceFileName(IClass klass) {
|
|
return ((AstClass)klass).getSourcePosition().getURL().getFile();
|
|
}
|
|
|
|
@Override
|
|
public Reader getSource(IClass klass) {
|
|
try {
|
|
return ((AstClass)klass).getSourcePosition().getReader();
|
|
} catch (IOException e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Reader getSource(IMethod method, int bcOffset) {
|
|
try {
|
|
return ((AstMethod)method).getSourcePosition(bcOffset).getReader();
|
|
} catch (IOException e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public IClassLoader getParent() {
|
|
assert parent != null;
|
|
return parent;
|
|
}
|
|
|
|
@Override
|
|
public void removeAll(Collection<IClass> toRemove) {
|
|
Set<TypeName> keys = HashSetFactory.make();
|
|
|
|
for (Iterator<Map.Entry<TypeName,IClass>> EE = types.entrySet().iterator(); EE.hasNext();) {
|
|
Map.Entry<TypeName,IClass> E = EE.next();
|
|
if (toRemove.contains(E.getValue())) {
|
|
keys.add(E.getKey());
|
|
}
|
|
}
|
|
|
|
for (Iterator KK = keys.iterator(); KK.hasNext();) {
|
|
types.remove(KK.next());
|
|
}
|
|
}
|
|
|
|
} |