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:
parent
eb5c0c8a55
commit
81ebdf8e82
2 changed files with 50 additions and 16 deletions
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue