Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [cdt-dev] weird scanner discovery behaviour

Ok... I found a way to skin the cat another way that works...

Basically, I do not rely on the scanner discovery infrastructure at all to update the project description, nor do I try to get the infrastructure to automagically try to update the cache by reloading the project description. Rather, in my job that already serializes the scanner info to the .sc file (via the DiscoveredPathManager), I added some code to directly take the newly discovered scanner info, and directly write it to the ICLanguageSettingEntries myself, then set the project description to get the new data to take.

The only weird behaviour I have remaining is that when I create the settings, I specify that the discovered info is built-in and read only, which is what the project level settings were already populated as. This is supposed to ensure that they do not show up unless you specify in the UI to show the built-in info, and you cannot delete or modify them. Despite setting those flags when creating the settings from the user's build output, when the data is read later from the project description, the flags are blank, so the discovered info shows up in the UI as user-defined info, and is deletable/modifiable. I would still like to fix that, but I can live with that for now. It is far better to have data the user can accidentally delete (and will get recreated when they build again), as opposed to no data at all.

Note that one thing that also seems to be missing from DiscoveredPathManager is the ability to handle changes to include files (i.e. explictitly included via command line options) and macro files, as opposed to the include paths and macro definitions, which it does handle. Hence, my code below doesn't handle include/macro files, because this part of discovery system is not tracking that data anyway. Since overall the scanner info system is supposed to handle that type of data, it would be nice at some point when this part of scanner discovery is overhauled to make sure that those features are supported. The build output parser already supports it, but there's no way to do anything with the data given the current infrastructure. It is rather weird that the lowest software layer supports it, as does the top-most layer, but the middle layer doesn't.

Here is a snippet of some of the code. When I get more time in a week or two I will have a look at doing this for the GNU scanner discovery if required. I suspect it has the same issues but I have not tested for sure that that is the case.

protected class ScannerConfigUpdateJob extends Job {

private InfoContext fContext;
private IDiscoveredPathInfo fPathInfo;
private boolean fIsDefaultContext;
private List<IResource> fChangedResources;

public ScannerConfigUpdateJob(InfoContext context, IDiscoveredPathInfo pathInfo, boolean isDefaultContext, List<IResource> changedResources) {
super(Messages.getString("PerFileXLCScannerInfoCollector.0")); //$NON-NLS-1$);
fContext = context;
fPathInfo = pathInfo;
fIsDefaultContext = isDefaultContext;
fChangedResources = changedResources;
}

@Override
protected IStatus run(IProgressMonitor monitor) {
try {

// get the scanner info profile ID

IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project);
IConfiguration config = info.getDefaultConfiguration();

String profileID = config.getToolChain().getScannerConfigDiscoveryProfileId();
IDiscoveredPathManager manager = MakeCorePlugin.getDefault().getDiscoveryManager();

if(manager instanceof DiscoveredPathManager) {
((DiscoveredPathManager)manager).updateDiscoveredInfo(fContext, fPathInfo, fIsDefaultContext, fChangedResources, profileID);
}

// reload project description to hopefully get the data to take
ICProjectDescriptionManager descriptionManager = CoreModel.getDefault().getProjectDescriptionManager();
ICProjectDescription cProjectDescription = descriptionManager.getProjectDescription(project, true /* writable */);
ICConfigurationDescription configDes = cProjectDescription.getActiveConfiguration();

boolean changedDes = false;

IToolChain toolchain = config.getToolChain();
for(ITool tool : toolchain.getTools()) {
for(IInputType inputType : tool.getInputTypes()) {
IContentType contentType = inputType.getSourceContentType();
if(contentType != null) {
for(IResource resource : fChangedResources) {
// get language settings for the resource
ICLanguageSetting langSetting = configDes.getLanguageSettingForFile(resource.getProjectRelativePath(), false);

if(langSetting == null) {
continue;
}

// get content type IDs for the setting
String[] contentTypeIDs = langSetting.getSourceContentTypeIds();

// if the setting doesn't handle our content type ID, then go to the next resource
boolean found = false;
for(String id : contentTypeIDs) {
if(id.equals(contentType.getId())) {
found = true;
break;
}
}

if(!found) {
continue;
}

// update all the scanner config entries on the setting
changedDes |= updateIncludeSettings(langSetting);
changedDes |= updateMacroSettings(langSetting);

}
}

}
}

if(changedDes) {
descriptionManager.setProjectDescription(project, cProjectDescription, true /* force */, monitor);
}

} catch (CoreException e) {
Activator.log(e);
return Activator.createStatus(Messages.getString("PerFileXLCScannerInfoCollector.1")); //$NON-NLS-1$
}
return Status.OK_STATUS;
}

private boolean updateMacroSettings(ICLanguageSetting langSetting) {
ICLanguageSettingEntry[] entries = langSetting.getSettingEntries(ICSettingEntry.MACRO);
List<ICLanguageSettingEntry> newEntries = new LinkedList<ICLanguageSettingEntry>();
for(ICLanguageSettingEntry entry : entries) {
newEntries.add(entry);
}


boolean entriesChanged = false;

// look for settings corresponding to each path we discovered
Map<String, String> discSymbols = fPathInfo.getSymbols();
for (String symbol : discSymbols.keySet()) {
boolean symbolFound = false;

for (ICLanguageSettingEntry entry : entries) {
if (((CMacroEntry) entry).getName().equals(symbol)) {
int flags = entry.getFlags();
symbolFound = true; // it's already there, so don't set it
break;
}
}

// if we didn't find the path, add it
if(!symbolFound) {
entriesChanged = true;
CMacroEntry newEntry = new CMacroEntry(symbol, discSymbols.get(symbol), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY | ICSettingEntry.RESOLVED);
newEntries.add(newEntry);
}
}

// if we changed the entries, then set the new ones
if(entriesChanged) {
langSetting.setSettingEntries(ICSettingEntry.MACRO, newEntries.toArray(new ICLanguageSettingEntry[0]));
}

return entriesChanged;
}

private boolean updateIncludeSettings(ICLanguageSetting langSetting) {
ICLanguageSettingEntry[] entries = langSetting.getSettingEntries(ICSettingEntry.INCLUDE_PATH);
List<ICLanguageSettingEntry> newEntries = new LinkedList<ICLanguageSettingEntry>();
for(ICLanguageSettingEntry entry : entries) {
newEntries.add(entry);
}


boolean entriesChanged = false;

// look for settings corresponding to each path we discovered
IPath[] discPaths = fPathInfo.getIncludePaths();
for (IPath path : discPaths) {
boolean pathFound = false;

for (ICLanguageSettingEntry entry : entries) {
if (((CIncludePathEntry) entry).getLocation().equals(path)) {
pathFound = true; // it's already there, so don't set it
break;
}
}

// if we didn't find the path, add it
if(!pathFound) {
entriesChanged = true;
CIncludePathEntry newEntry = new CIncludePathEntry(path, ICSettingEntry.BUILTIN | ICSettingEntry.READONLY | ICSettingEntry.RESOLVED);
newEntries.add(newEntry);
}
}

// if we changed the entries, then set the new ones
if(entriesChanged) {
langSetting.setSettingEntries(ICSettingEntry.INCLUDE_PATH, newEntries.toArray(new ICLanguageSettingEntry[0]));
}

return entriesChanged;
}
}
===========================
Chris Recoskie
Team Lead, IBM CDT and RDT
IBM Toronto
Inactive hide details for Chris Recoskie/Toronto/IBM@IBMCAChris Recoskie/Toronto/IBM@IBMCA


          Chris Recoskie/Toronto/IBM@IBMCA
          Sent by: cdt-dev-bounces@xxxxxxxxxxx

          11/24/2009 07:43 PM

          Please respond to
          "CDT General developers list." <cdt-dev@xxxxxxxxxxx>

To

"CDT General developers list." <cdt-dev@xxxxxxxxxxx>

cc


Subject

Re: [cdt-dev] weird scanner discovery behaviour

> A hacky way would be to get... and set... it. This would force through
> and reconcile all the external changes. You could do this at the end
> of your scanner discovery build while the workspace lock is held.

Did the following:

// reload project description to hopefully get the data to take

ICProjectDescriptionManager descriptionManager = CoreModel.
getDefault().getProjectDescriptionManager();
ICProjectDescription cProjectDescription = descriptionManager.getProjectDescription(
project, ICProjectDescriptionManager.GET_IF_LOADDED);
// setting the same project description again is supposed to reconcile all the changes

descriptionManager.setProjectDescription(
project, cProjectDescription, true /*force it*/, monitor);
// pray...


Didn't work :-(

I tried hacking AbstractCExtensionProxy to try to get it to force an update when the new project description is applied, but that didn't help either.

protected
boolean doHandleEvent(CProjectDescriptionEvent event){
boolean
force = false;
switch
(event.getEventType()){
case
CProjectDescriptionEvent.LOADED:
force =
true;
case
CProjectDescriptionEvent.APPLIED:
force =
true; // changed to see if we can force scanner info to update
ICProjectDescription des = event.getNewCProjectDescription();

if
(des != null){
updateProject(des.getProject());

return
checkUpdateProvider(des, force, true);
}

break
;
}


return
false;
}


I'll keep digging I guess. Any further thoughts you have would be appreciated.

===========================
Chris Recoskie
Team Lead, IBM CDT and RDT
IBM Toronto
Inactive hide details for James Blackburn <jamesblackburn@xxxxxxxxx>James Blackburn <jamesblackburn@xxxxxxxxx>

                  James Blackburn <jamesblackburn@xxxxxxxxx>
                  Sent by: cdt-dev-bounces@xxxxxxxxxxx

                  11/24/2009 05:38 PM

Please respond to
"CDT General developers list." <cdt-dev@xxxxxxxxxxx>
To

"CDT General developers list." <cdt-dev@xxxxxxxxxxx>
cc
Subject

Re: [cdt-dev] weird scanner discovery behaviour

Hi Chris,

I don't use scanner discovery (other than to provide the built-ins), but...

2009/11/24 Chris Recoskie <recoskie@xxxxxxxxxx>:
> The problem is that any scanner info that is created after the
> ICProjectDescription has been loaded does not properly show up in the Paths
> & Symbols information, nor does it seem to be in the scanner info that is
> passed to the parser. The info on the built-ins, which is created by the
> scanner config builder during the load of the project description, is
> properly there, but the per-file info from the user's build is not there.
>
> If I close and reopen the project, the new info that was serialized
> previously to the .sc file then shows up everywhere it ought to.
>
> So basically, it seems that the ICLanguageSettingEntry data in the project
> description doesn't get updated at all except when the ICProjectDescription
> is being loaded fresh.

A lot of the contributions hang off and contribute via the
ICProjectDescriptionListener interface tweaking the description as its
loaded / changed. Having a quick poke at the code, there's the
DescriptionScannerInfoProvider and created from
ScannerInfoProviderProxy -- both of these inherit from
IScannerInfoProvider.

> Is there a way to refresh the ICLanguageSettingEntry data?

This is one of the big problems with the model. It caches everything
which is bad for memory and consistency. I had a little bit of a
battle to make it adapt to external changes to the environment.

> Failing that, is
> there a way to force the ICProjectDescription to reload? I am at my wits end
> as far as how to get the contributed scanner info to show up otherwise.

A hacky way would be to get... and set... it. This would force through
and reconcile all the external changes. You could do this at the end
of your scanner discovery build while the workspace lock is held.
There is so much broken in Scanner Discovery (and no documentation)
that fixing it is a serious challenge.

Cheers,
James
_______________________________________________
cdt-dev mailing list
cdt-dev@xxxxxxxxxxx

https://dev.eclipse.org/mailman/listinfo/cdt-dev
_______________________________________________
cdt-dev mailing list
cdt-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/cdt-dev

GIF image

GIF image

GIF image

GIF image


Back to the top