blob: 6215f3bd8aa9b05221426253028341ec657af691 [file] [log] [blame]
package org.eclipse.photran.internal.core.analysis.binding;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.photran.core.IFortranAST;
import org.eclipse.photran.internal.core.lexer.Token;
import org.eclipse.photran.internal.core.vpg.PhotranVPG;
import org.eclipse.photran.internal.core.vpg.PhotranVPGBuilder;
/**
* Performs name-binding analysis on a Fortran file, storing the results in the VPG.
* <p>
* This class should only be invoked by {@link PhotranVPGBuilder}; clients should use
* {@link Token#resolveBinding()} and related methods to look up binding information.
*
* @author Jeff Overbey
*/
public class Binder
{
private Binder() {}
private static Map<Class<?>, Long> avgTimes = new HashMap<Class<?>, Long>();
private static Map<Class<?>, Long> counts = new HashMap<Class<?>, Long>();
private static Map<Class<?>, Long> maxTimes = new HashMap<Class<?>, Long>();
private static Map<Class<?>, String> maxFiles = new HashMap<Class<?>, String>();
public static void bind(IFortranAST ast, IFile file)
{
// Name-binding analysis Logging/timing
// ======================================= ===========================================================
PhotranVPG vpg = PhotranVPG.getInstance(); String filename = file.getName();
StringBuilder sb = new StringBuilder(" - Binder#bind: "); //$NON-NLS-1$
long start = System.currentTimeMillis();
ast.accept(new ImplicitSpecCollector()); logTime(start, ImplicitSpecCollector.class, filename);
start = System.currentTimeMillis();
ast.accept(new PrivateCollector()); logTime(start, PrivateCollector.class, filename);
start = System.currentTimeMillis();
ast.accept(new DefinitionCollector(file)); logTime(start, DefinitionCollector.class, filename);
start = System.currentTimeMillis();
ast.accept(new SpecificationCollector()); logTime(start, SpecificationCollector.class, filename);
start = System.currentTimeMillis();
ast.accept(new ModuleLoader(file)); logTime(start, ModuleLoader.class, filename);
// TODO: Type check here so derived type components can be resolved
start = System.currentTimeMillis();
vpg.enableDefinitionCaching();
ast.accept(new ReferenceCollector());
vpg.disableDefinitionCaching(); logTime(start, ReferenceCollector.class, filename);
vpg.debug(sb.toString(), ""); //$NON-NLS-1$
}
private static void logTime(long start, Class<?> clazz, String filename)
{
long elapsed = System.currentTimeMillis() - start;
long oldCount = counts.containsKey(clazz) ? counts.get(clazz) : 0L;
long oldAvgTime = avgTimes.containsKey(clazz) ? avgTimes.get(clazz) : 0L;
/* a + b
* oldAvgTime = -----
* 2
* ( a + b )
* ( ----- ) * 2 + c
* a + b + c ( 2 )
* newAvgTime = --------- = ------------------
* 3 3
*/
long newAvgTime = (oldAvgTime * oldCount + elapsed) / (oldCount + 1);
counts.put(clazz, oldCount+1);
avgTimes.put(clazz, newAvgTime);
long oldMaxTime = maxTimes.containsKey(clazz) ? maxTimes.get(clazz) : 0L;
if (elapsed > oldMaxTime)
{
maxTimes.put(clazz, elapsed);
maxFiles.put(clazz, filename);
}
}
public static long getAvgTime(Class<?> clazz)
{
return avgTimes.containsKey(clazz) ? avgTimes.get(clazz) : 0L;
}
public static void printStatisticsOn(PrintStream ps)
{
ps.println("Name Binding Analysis Statistics:"); //$NON-NLS-1$
ps.println();
ps.println(" Average Times:"); //$NON-NLS-1$
for (Class<?> clazz : avgTimes.keySet())
ps.println(" " + clazz.getSimpleName() + ": " + avgTimes.get(clazz) + " ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
ps.println();
ps.println(" Maximum Times:"); //$NON-NLS-1$
for (Class<?> clazz : maxTimes.keySet())
ps.println(" " + clazz.getSimpleName() + ": " + maxTimes.get(clazz) + " ms (" + maxFiles.get(clazz) + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
public static void resetStatistics()
{
counts.clear();
avgTimes.clear();
}
}