1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 22:52:11 +02:00

Bug 422797 - API for retrieving QMake information from Qt project

Changes:
* QtPlugin calls QMakeProjectInfo.start/stop to start/stop listening
  on resource changes
* QMakeProjectInfo listens on changes in project description
  e.g. changing natures
* QMakeProjectInfo.getQMakeProjectInfoFor() returns info even for
  project without QtNature - this prevents race-condition that happens
  when opening legacy QML projects where QtNature is added lazily after
  the project is opened and somebody already asks for QMakeProjectInfo
* Fixing QMakeProjectInfo.stop() and
  QMakeProjectInfo.getQMakeProjectInfoFor() to fire notification outside
  of synchronized blocks

Change-Id: Ib49238f252a249d2b5936b6d8344aae93e0ef583
Signed-off-by: David Kaspar <dkaspar@blackberry.com>
Reviewed-on: https://git.eclipse.org/r/20722
Tested-by: Hudson CI
Reviewed-by: Doug Schaefer <dschaefer@qnx.com>
IP-Clean: Doug Schaefer <dschaefer@qnx.com>
This commit is contained in:
David Kaspar 2014-01-16 18:35:02 +01:00 committed by Doug Schaefer
parent eb5c0c8a55
commit 81ebdf8e82
2 changed files with 50 additions and 16 deletions

View file

@ -24,7 +24,6 @@ import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICDescriptionDelta;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionListener;
import org.eclipse.cdt.qt.core.QtNature;
import org.eclipse.cdt.qt.core.index.IQMakeEnv;
import org.eclipse.cdt.qt.core.index.IQMakeEnvProvider;
import org.eclipse.cdt.qt.core.index.IQMakeProjectInfo;
@ -66,13 +65,14 @@ public final class QMakeProjectInfo implements IQMakeProjectInfo, ICProjectDescr
// called by QtPlugin activator to clean up this class
public static final void stop() {
ResourcesPlugin.getWorkspace().removeResourceChangeListener(LISTENER);
List<QMakeProjectInfo> infos;
synchronized (SYNC) {
while (true) {
Iterator<IProject> iterator = CACHE.keySet().iterator();
if (!iterator.hasNext()) {
break;
}
removeProjectFromCache(iterator.next());
infos = new ArrayList<QMakeProjectInfo>(CACHE.values());
CACHE.clear();
}
for (QMakeProjectInfo info : infos) {
if (info != null) {
info.destroy();
}
}
}
@ -84,16 +84,17 @@ public final class QMakeProjectInfo implements IQMakeProjectInfo, ICProjectDescr
* @return the QMakeProjectInfo; or null if the project does not have QtNature
*/
public static QMakeProjectInfo getQMakeProjectInfoFor(IProject project) {
QMakeProjectInfo info;
synchronized (SYNC) {
QMakeProjectInfo info = CACHE.get(project);
if (info == null) {
if (QtNature.hasNature(project)) {
info = new QMakeProjectInfo(project);
CACHE.put(project,info);
}
info = CACHE.get(project);
if (info != null) {
return info;
}
return info;
info = new QMakeProjectInfo(project);
CACHE.put(project,info);
}
info.updateActiveConfiguration();
return info;
}
// removes the project from the CACHE
@ -125,7 +126,6 @@ public final class QMakeProjectInfo implements IQMakeProjectInfo, ICProjectDescr
private QMakeProjectInfo(IProject project) {
this.project = project;
CoreModel.getDefault().addCProjectDescriptionListener(this, ICDescriptionDelta.ACTIVE_CFG);
updateActiveConfiguration();
}
// called from removeProjectFromCache only
@ -141,6 +141,7 @@ public final class QMakeProjectInfo implements IQMakeProjectInfo, ICProjectDescr
}
}
// must not be called under synchronized (SYNC) or synchronized (sync)
private void updateActiveConfiguration() {
synchronized (sync) {
if (! live) {
@ -181,6 +182,10 @@ public final class QMakeProjectInfo implements IQMakeProjectInfo, ICProjectDescr
listeners.remove(listener);
}
private IProject getProject() {
return project;
}
// calculates (if does not exist) and returns actual QMake info
@Override
public IQMakeInfo getActualInfo() {
@ -356,6 +361,7 @@ public final class QMakeProjectInfo implements IQMakeProjectInfo, ICProjectDescr
private static final class RDVisitor implements IResourceDeltaVisitor {
private final Set<IResource> projectsToDelete = new HashSet<IResource>();
private final Set<IResource> projectsToUpdate = new HashSet<IResource>();
private final Set<IPath> changedFiles = new HashSet<IPath>();
@Override
@ -367,7 +373,13 @@ public final class QMakeProjectInfo implements IQMakeProjectInfo, ICProjectDescr
addChangedFile(resource);
return false;
case IResource.PROJECT:
if (delta.getKind() == IResourceDelta.REMOVED) {
switch (delta.getKind()) {
case IResourceDelta.CHANGED:
if ((delta.getFlags() & IResourceDelta.DESCRIPTION) != 0) {
addProjectToUpdate(resource);
}
return true;
case IResourceDelta.REMOVED:
addProjectToDelete(resource);
return false;
}
@ -377,6 +389,10 @@ public final class QMakeProjectInfo implements IQMakeProjectInfo, ICProjectDescr
return true;
}
private void addProjectToUpdate(IResource project) {
projectsToUpdate.add(project);
}
private void addProjectToDelete(IResource project) {
projectsToDelete.add(project);
}
@ -399,6 +415,10 @@ public final class QMakeProjectInfo implements IQMakeProjectInfo, ICProjectDescr
infos = new ArrayList<QMakeProjectInfo>(CACHE.values());
}
for (QMakeProjectInfo info : infos) {
// checking if any project description change affects QMakeProjectInfo
if (projectsToUpdate.contains(info.getProject())) {
info.updateActiveConfiguration();
}
// checking if any of the changed files affects QMakeProjectInfo
if (info.containsAnySensitiveFile(changedFiles)) {
// if so then scheduling update

View file

@ -8,11 +8,13 @@
package org.eclipse.cdt.qt.core;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.internal.qt.core.index.QMakeProjectInfo;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.osgi.framework.BundleContext;
public class QtPlugin extends Plugin {
@ -43,6 +45,18 @@ public class QtPlugin extends Plugin {
instance = this;
}
@Override
public void start(BundleContext context) throws Exception {
super.start(context);
QMakeProjectInfo.start();
}
@Override
public void stop(BundleContext context) throws Exception {
QMakeProjectInfo.stop();
super.stop(context);
}
public static CoreException coreException(String msg) {
return new CoreException(new Status(IStatus.INFO, ID, msg));
}