1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-05 08:46:02 +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.ICDescriptionDelta;
import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionListener; 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.IQMakeEnv;
import org.eclipse.cdt.qt.core.index.IQMakeEnvProvider; import org.eclipse.cdt.qt.core.index.IQMakeEnvProvider;
import org.eclipse.cdt.qt.core.index.IQMakeProjectInfo; 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 // called by QtPlugin activator to clean up this class
public static final void stop() { public static final void stop() {
ResourcesPlugin.getWorkspace().removeResourceChangeListener(LISTENER); ResourcesPlugin.getWorkspace().removeResourceChangeListener(LISTENER);
List<QMakeProjectInfo> infos;
synchronized (SYNC) { synchronized (SYNC) {
while (true) { infos = new ArrayList<QMakeProjectInfo>(CACHE.values());
Iterator<IProject> iterator = CACHE.keySet().iterator(); CACHE.clear();
if (!iterator.hasNext()) { }
break; for (QMakeProjectInfo info : infos) {
} if (info != null) {
removeProjectFromCache(iterator.next()); 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 * @return the QMakeProjectInfo; or null if the project does not have QtNature
*/ */
public static QMakeProjectInfo getQMakeProjectInfoFor(IProject project) { public static QMakeProjectInfo getQMakeProjectInfoFor(IProject project) {
QMakeProjectInfo info;
synchronized (SYNC) { synchronized (SYNC) {
QMakeProjectInfo info = CACHE.get(project); info = CACHE.get(project);
if (info == null) { if (info != null) {
if (QtNature.hasNature(project)) { return info;
info = new QMakeProjectInfo(project);
CACHE.put(project,info);
}
} }
return info; info = new QMakeProjectInfo(project);
CACHE.put(project,info);
} }
info.updateActiveConfiguration();
return info;
} }
// removes the project from the CACHE // removes the project from the CACHE
@ -125,7 +126,6 @@ public final class QMakeProjectInfo implements IQMakeProjectInfo, ICProjectDescr
private QMakeProjectInfo(IProject project) { private QMakeProjectInfo(IProject project) {
this.project = project; this.project = project;
CoreModel.getDefault().addCProjectDescriptionListener(this, ICDescriptionDelta.ACTIVE_CFG); CoreModel.getDefault().addCProjectDescriptionListener(this, ICDescriptionDelta.ACTIVE_CFG);
updateActiveConfiguration();
} }
// called from removeProjectFromCache only // 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() { private void updateActiveConfiguration() {
synchronized (sync) { synchronized (sync) {
if (! live) { if (! live) {
@ -181,6 +182,10 @@ public final class QMakeProjectInfo implements IQMakeProjectInfo, ICProjectDescr
listeners.remove(listener); listeners.remove(listener);
} }
private IProject getProject() {
return project;
}
// calculates (if does not exist) and returns actual QMake info // calculates (if does not exist) and returns actual QMake info
@Override @Override
public IQMakeInfo getActualInfo() { public IQMakeInfo getActualInfo() {
@ -356,6 +361,7 @@ public final class QMakeProjectInfo implements IQMakeProjectInfo, ICProjectDescr
private static final class RDVisitor implements IResourceDeltaVisitor { private static final class RDVisitor implements IResourceDeltaVisitor {
private final Set<IResource> projectsToDelete = new HashSet<IResource>(); private final Set<IResource> projectsToDelete = new HashSet<IResource>();
private final Set<IResource> projectsToUpdate = new HashSet<IResource>();
private final Set<IPath> changedFiles = new HashSet<IPath>(); private final Set<IPath> changedFiles = new HashSet<IPath>();
@Override @Override
@ -367,7 +373,13 @@ public final class QMakeProjectInfo implements IQMakeProjectInfo, ICProjectDescr
addChangedFile(resource); addChangedFile(resource);
return false; return false;
case IResource.PROJECT: 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); addProjectToDelete(resource);
return false; return false;
} }
@ -377,6 +389,10 @@ public final class QMakeProjectInfo implements IQMakeProjectInfo, ICProjectDescr
return true; return true;
} }
private void addProjectToUpdate(IResource project) {
projectsToUpdate.add(project);
}
private void addProjectToDelete(IResource project) { private void addProjectToDelete(IResource project) {
projectsToDelete.add(project); projectsToDelete.add(project);
} }
@ -399,6 +415,10 @@ public final class QMakeProjectInfo implements IQMakeProjectInfo, ICProjectDescr
infos = new ArrayList<QMakeProjectInfo>(CACHE.values()); infos = new ArrayList<QMakeProjectInfo>(CACHE.values());
} }
for (QMakeProjectInfo info : infos) { 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 // checking if any of the changed files affects QMakeProjectInfo
if (info.containsAnySensitiveFile(changedFiles)) { if (info.containsAnySensitiveFile(changedFiles)) {
// if so then scheduling update // if so then scheduling update

View file

@ -8,11 +8,13 @@
package org.eclipse.cdt.qt.core; package org.eclipse.cdt.qt.core;
import org.eclipse.cdt.core.model.CModelException; 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.CoreException;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin; import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.QualifiedName; import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
import org.osgi.framework.BundleContext;
public class QtPlugin extends Plugin { public class QtPlugin extends Plugin {
@ -43,6 +45,18 @@ public class QtPlugin extends Plugin {
instance = this; 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) { public static CoreException coreException(String msg) {
return new CoreException(new Status(IStatus.INFO, ID, msg)); return new CoreException(new Status(IStatus.INFO, ID, msg));
} }