This commit is contained in:
Alexey Andreev 2015-06-30 13:50:09 +04:00
parent fb086d5b26
commit d5da4964c4

View File

@ -48,10 +48,8 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder {
private IContainer[] sourceContainers; private IContainer[] sourceContainers;
private IContainer[] classFileContainers; private IContainer[] classFileContainers;
private SourceFileProvider[] sourceProviders; private SourceFileProvider[] sourceProviders;
private Set<IProject> usedProjects = new HashSet<>(); private static Map<TeaVMProfile, ProfileData> profileDataStore = new WeakHashMap<>();
private static Map<TeaVMProfile, Set<String>> profileClasses = new WeakHashMap<>(); private static Pattern newLinePattern = Pattern.compile("\\r\\n|\\r|\\n");
private static Map<TeaVMProfile, Set<IProject>> profileDependencies = new WeakHashMap<>();
private static Pattern newLinePattern = Pattern.compile("\\r|\\n|\\r\\n");
@Override @Override
protected IProject[] build(int kind, Map<String, String> args, IProgressMonitor monitor) throws CoreException { protected IProject[] build(int kind, Map<String, String> args, IProgressMonitor monitor) throws CoreException {
@ -59,24 +57,22 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder {
projectSettings.load(); projectSettings.load();
TeaVMProfile profiles[] = getEnabledProfiles(projectSettings); TeaVMProfile profiles[] = getEnabledProfiles(projectSettings);
monitor.beginTask("Running TeaVM", profiles.length * TICKS_PER_PROFILE); monitor.beginTask("Running TeaVM", profiles.length * TICKS_PER_PROFILE);
usedProjects = new HashSet<>(); Set<IProject> usedProjects = new HashSet<>();
Set<IProject> localUsedProjects = usedProjects;
try { try {
prepareClassPath(); prepareClassPath();
ClassLoader classLoader = new URLClassLoader(classPath, TeaVMProjectBuilder.class.getClassLoader()); ClassLoader classLoader = new URLClassLoader(classPath, TeaVMProjectBuilder.class.getClassLoader());
for (TeaVMProfile profile : profiles) { for (TeaVMProfile profile : profiles) {
SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, TICKS_PER_PROFILE); SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, TICKS_PER_PROFILE);
buildProfile(kind, subMonitor, profile, classLoader); ProfileData profileData = buildProfile(kind, subMonitor, profile, classLoader);
usedProjects.addAll(profileData.usedProjects);
} }
localUsedProjects.addAll(usedProjects);
} finally { } finally {
monitor.done(); monitor.done();
sourceContainers = null; sourceContainers = null;
classFileContainers = null; classFileContainers = null;
classPath = null; classPath = null;
usedProjects = null;
} }
return !localUsedProjects.isEmpty() ? localUsedProjects.toArray(new IProject[0]) : null; return !usedProjects.isEmpty() ? usedProjects.toArray(new IProject[0]) : null;
} }
private TeaVMProfile[] getEnabledProfiles(TeaVMProjectSettings settings) { private TeaVMProfile[] getEnabledProfiles(TeaVMProjectSettings settings) {
@ -91,17 +87,26 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder {
return Arrays.copyOf(profiles, sz); return Arrays.copyOf(profiles, sz);
} }
private void buildProfile(int kind, IProgressMonitor monitor, TeaVMProfile profile, ClassLoader classLoader) private ProfileData buildProfile(int kind, IProgressMonitor monitor, TeaVMProfile profile,
throws CoreException { ClassLoader classLoader) throws CoreException {
if ((kind == AUTO_BUILD || kind == INCREMENTAL_BUILD)) { ProfileData profileData;
if (!shouldBuild(profile)) { synchronized (profileDataStore) {
Set<IProject> dependencies = profileDependencies.get(profile); profileData = profileDataStore.get(profile);
if (dependencies != null) { if (profileData == null) {
usedProjects.addAll(dependencies); profileData = new ProfileData(profile);
} profileDataStore.put(profile, profileData);
return;
} }
} }
if (kind == AUTO_BUILD || kind == INCREMENTAL_BUILD) {
if (!shouldBuild(profileData)) {
return profileData;
}
}
profileData.cancelled = false;
profileData.usedProjects.clear();
profileData.usedResources.clear();
IStringVariableManager varManager = VariablesPlugin.getDefault().getStringVariableManager(); IStringVariableManager varManager = VariablesPlugin.getDefault().getStringVariableManager();
TeaVMTool tool = new TeaVMTool(); TeaVMTool tool = new TeaVMTool();
tool.setClassLoader(classLoader); tool.setClassLoader(classLoader);
@ -139,16 +144,17 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder {
removeMarkers(profile); removeMarkers(profile);
putMarkers(tool.getDependencyInfo().getCallGraph(), tool.getProblemProvider().getProblems(), putMarkers(tool.getDependencyInfo().getCallGraph(), tool.getProblemProvider().getProblems(),
profile); profile);
profileDependencies.put(profile, new HashSet<IProject>(usedProjects)); classesToResources(profileData, tool);
classesToResources(profile, tool);
refreshTarget(tool.getTargetDirectory()); refreshTarget(tool.getTargetDirectory());
} }
if (!monitor.isCanceled()) { if (!monitor.isCanceled()) {
monitor.done(); monitor.done();
} }
profileData.cancelled = monitor.isCanceled();
} catch (TeaVMToolException e) { } catch (TeaVMToolException e) {
throw new CoreException(TeaVMEclipsePlugin.makeError(e)); throw new CoreException(TeaVMEclipsePlugin.makeError(e));
} }
return profileData;
} }
private void refreshTarget(File targetDirectory) { private void refreshTarget(File targetDirectory) {
@ -184,14 +190,14 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder {
} }
} }
private void classesToResources(TeaVMProfile profile, TeaVMTool tool) { private void classesToResources(ProfileData profileData, TeaVMTool tool) {
Set<String> resourcePaths = new HashSet<>(); Set<String> resourcePaths = new HashSet<>();
for (String className : tool.getClasses()) { for (String className : tool.getClasses()) {
for (IContainer clsContainer : classFileContainers) { for (IContainer clsContainer : classFileContainers) {
IResource res = clsContainer.findMember(className.replace('.', '/') + ".class"); IResource res = clsContainer.findMember(className.replace('.', '/') + ".class");
if (res != null) { if (res != null) {
resourcePaths.add(res.getFullPath().toString()); resourcePaths.add(res.getFullPath().toString());
usedProjects.add(res.getProject()); profileData.usedProjects.add(res.getProject());
} }
} }
} }
@ -200,15 +206,18 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder {
IResource res = clsContainer.findMember(resourceName); IResource res = clsContainer.findMember(resourceName);
if (res != null) { if (res != null) {
resourcePaths.add(res.getFullPath().toString()); resourcePaths.add(res.getFullPath().toString());
usedProjects.add(res.getProject()); profileData.usedProjects.add(res.getProject());
} }
} }
} }
setClasses(profile, resourcePaths); profileData.usedResources.addAll(resourcePaths);
} }
private boolean shouldBuild(TeaVMProfile profile) throws CoreException { private boolean shouldBuild(ProfileData profileData) throws CoreException {
Collection<String> classes = getClasses(profile); if (profileData.cancelled) {
return true;
}
Collection<String> classes = profileData.usedResources;
if (classes.isEmpty()) { if (classes.isEmpty()) {
return true; return true;
} }
@ -233,18 +242,6 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder {
return false; return false;
} }
private Collection<String> getClasses(TeaVMProfile profile) {
Set<String> classes;
synchronized (profileClasses) {
classes = profileClasses.get(profile);
}
return classes != null ? new HashSet<>(classes) : new HashSet<String>();
}
private void setClasses(TeaVMProfile profile, Collection<String> classes) {
profileClasses.put(profile, new HashSet<>(classes));
}
private void removeMarkers(TeaVMProfile profile) throws CoreException { private void removeMarkers(TeaVMProfile profile) throws CoreException {
for (IProject project : getProject().getWorkspace().getRoot().getProjects()) { for (IProject project : getProject().getWorkspace().getRoot().getProjects()) {
IMarker[] markers = project.findMarkers(TeaVMEclipsePlugin.PROBLEM_MARKER_ID, true, IMarker[] markers = project.findMarkers(TeaVMEclipsePlugin.PROBLEM_MARKER_ID, true,
@ -724,4 +721,15 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder {
return containers.toArray(new IContainer[containers.size()]); return containers.toArray(new IContainer[containers.size()]);
} }
} }
static class ProfileData {
final TeaVMProfile profile;
final Set<String> usedResources = new HashSet<>();
final Set<IProject> usedProjects = new HashSet<>();
boolean cancelled;
public ProfileData(TeaVMProfile profile) {
this.profile = profile;
}
}
} }