1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-10 01:35:39 +02:00

Merge remote-tracking branch 'cdt/master' into sd90

This commit is contained in:
Andrew Gvozdev 2013-03-13 14:08:08 -04:00
commit 0ceace2943
26 changed files with 882 additions and 437 deletions

View file

@ -225,6 +225,7 @@ public class BuiltinSpecsDetectorTest extends BaseTestCase {
provider.execute(); provider.execute();
assertEquals(true, provider.isExecuted()); assertEquals(true, provider.isExecuted());
assertEquals(null, provider.getSettingEntries(null, null, null));
} }
} }
@ -307,7 +308,9 @@ public class BuiltinSpecsDetectorTest extends BaseTestCase {
// check entries // check entries
{ {
MockDetectorCloneable clone = provider.clone(); MockDetectorCloneable clone = provider.clone();
clone.setSettingEntries(null, null, null, null); List<ICLanguageSettingEntry> entries2 = new ArrayList<ICLanguageSettingEntry>();
entries2.add(new CMacroEntry("MACRO2", "VALUE2", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY));
clone.setSettingEntries(null, null, null, entries2);
assertFalse(provider.equals(clone)); assertFalse(provider.equals(clone));
} }

View file

@ -12,11 +12,13 @@ package org.eclipse.cdt.managedbuilder.internal.envvar;
import org.eclipse.cdt.core.cdtvariables.ICdtVariable; import org.eclipse.cdt.core.cdtvariables.ICdtVariable;
import org.eclipse.cdt.core.envvar.IEnvironmentVariable; import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.internal.core.cdtvariables.CdtVariableManager; import org.eclipse.cdt.internal.core.cdtvariables.CdtVariableManager;
import org.eclipse.cdt.internal.core.cdtvariables.ICoreVariableContextInfo; import org.eclipse.cdt.internal.core.cdtvariables.ICoreVariableContextInfo;
import org.eclipse.cdt.internal.core.envvar.EnvironmentVariableManager; import org.eclipse.cdt.internal.core.envvar.EnvironmentVariableManager;
import org.eclipse.cdt.internal.core.envvar.ICoreEnvironmentVariableSupplier; import org.eclipse.cdt.internal.core.envvar.ICoreEnvironmentVariableSupplier;
import org.eclipse.cdt.internal.core.envvar.IEnvironmentContextInfo; import org.eclipse.cdt.internal.core.envvar.IEnvironmentContextInfo;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.IToolChain; import org.eclipse.cdt.managedbuilder.core.IToolChain;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier; import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier;
@ -27,14 +29,17 @@ import org.eclipse.cdt.utils.cdtvariables.IVariableContextInfo;
/** /**
* Helper class to resolve environment variables directly from toolchain. The intention is * Helper class to resolve environment variables directly from toolchain. The intention is
* to use that in New Project Wizard and other scenarios when no configuration is available yet. * to use that in New Project Wizard and other scenarios when no configuration is available yet.
* *
* @noextend This class is not intended to be subclassed by clients. * @noextend This class is not intended to be subclassed by clients.
*/ */
public class EnvironmentVariableManagerToolChain extends EnvironmentVariableManager { public class EnvironmentVariableManagerToolChain extends EnvironmentVariableManager {
private final IToolChain toolChain; private final IToolChain toolChain;
private final ICConfigurationDescription cfgDescription;
public EnvironmentVariableManagerToolChain(IToolChain toolchain) { public EnvironmentVariableManagerToolChain(IToolChain toolchain) {
this.toolChain = toolchain; this.toolChain = toolchain;
IConfiguration cfg = toolChain.getParent();
cfgDescription = cfg != null ? ManagedBuildManager.getDescriptionForConfiguration(cfg) : null;
} }
/** /**
@ -154,6 +159,11 @@ public class EnvironmentVariableManagerToolChain extends EnvironmentVariableMana
*/ */
@Override @Override
public IEnvironmentContextInfo getContextInfo(Object level) { public IEnvironmentContextInfo getContextInfo(Object level) {
if (cfgDescription != null) {
// Use regular EnvironmentVariableManager when configuration is available
return super.getContextInfo(level);
}
return new ToolChainEnvironmentContextInfo(toolChain); return new ToolChainEnvironmentContextInfo(toolChain);
} }
@ -162,7 +172,15 @@ public class EnvironmentVariableManagerToolChain extends EnvironmentVariableMana
*/ */
@Override @Override
public ICoreVariableContextInfo getMacroContextInfoForContext(Object context) { public ICoreVariableContextInfo getMacroContextInfoForContext(Object context) {
if (cfgDescription != null) {
// Use regular EnvironmentVariableManager when configuration is available
return super.getMacroContextInfoForContext(context);
}
return new ToolChainCoreVariableContextInfo(toolChain); return new ToolChainCoreVariableContextInfo(toolChain);
} }
public IEnvironmentVariable getVariable(String variableName, boolean resolveMacros) {
return getVariable(variableName, cfgDescription, resolveMacros);
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009, 2012 Andrew Gvozdev and others. * Copyright (c) 2009, 2013 Andrew Gvozdev and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -12,10 +12,11 @@
package org.eclipse.cdt.managedbuilder.internal.language.settings.providers; package org.eclipse.cdt.managedbuilder.internal.language.settings.providers;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException;
import org.eclipse.cdt.core.EFSExtensionProvider;
import org.eclipse.cdt.internal.core.Cygwin;
import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
import org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector; import org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector;
import org.eclipse.core.resources.IResource;
/** /**
* Class to detect built-in compiler settings for Cygwin toolchain. * Class to detect built-in compiler settings for Cygwin toolchain.
@ -24,14 +25,36 @@ import org.eclipse.core.resources.IResource;
public class GCCBuiltinSpecsDetectorCygwin extends GCCBuiltinSpecsDetector { public class GCCBuiltinSpecsDetectorCygwin extends GCCBuiltinSpecsDetector {
// ID must match the tool-chain definition in org.eclipse.cdt.managedbuilder.core.buildDefinitions extension point // ID must match the tool-chain definition in org.eclipse.cdt.managedbuilder.core.buildDefinitions extension point
private static final String GCC_TOOLCHAIN_ID_CYGWIN = "cdt.managedbuild.toolchain.gnu.cygwin.base"; //$NON-NLS-1$ private static final String GCC_TOOLCHAIN_ID_CYGWIN = "cdt.managedbuild.toolchain.gnu.cygwin.base"; //$NON-NLS-1$
private static final String ENV_PATH = "PATH"; //$NON-NLS-1$
private static final URI CYGWIN_ROOT; /**
static { * EFSExtensionProvider for Cygwin translations
try { */
CYGWIN_ROOT = new URI("cygwin:/"); //$NON-NLS-1$ private class CygwinEFSExtensionProvider extends EFSExtensionProvider {
} catch (URISyntaxException e) { private String envPathValue;
// hey we know this URI works
throw new IllegalStateException(e); /**
* Constructor.
* @param envPathValue - Value of environment variable $PATH.
*/
public CygwinEFSExtensionProvider(String envPathValue) {
this.envPathValue = envPathValue;
}
@Override
public String getMappedPath(URI locationURI) {
String windowsPath = null;
try {
String cygwinPath = getPathFromURI(locationURI);
windowsPath = Cygwin.cygwinToWindowsPath(cygwinPath, envPathValue);
} catch (Exception e) {
ManagedBuilderCorePlugin.log(e);
}
if (windowsPath != null) {
return windowsPath;
}
return super.getMappedPath(locationURI);
} }
} }
@ -41,25 +64,9 @@ public class GCCBuiltinSpecsDetectorCygwin extends GCCBuiltinSpecsDetector {
} }
@Override @Override
protected URI getMappedRootURI(IResource sourceFile, String parsedResourceName) { protected EFSExtensionProvider getEFSProvider() {
if (mappedRootURI == null) { String envPathValue = environmentMap != null ? environmentMap.get(ENV_PATH) : null;
mappedRootURI = super.getMappedRootURI(sourceFile, parsedResourceName); return new CygwinEFSExtensionProvider(envPathValue);
if (mappedRootURI == null) {
mappedRootURI = CYGWIN_ROOT;
}
}
return mappedRootURI;
}
@Override
protected URI getBuildDirURI(URI mappedRootURI) {
if (buildDirURI == null) {
buildDirURI = super.getBuildDirURI(mappedRootURI);
if (buildDirURI == null) {
buildDirURI = CYGWIN_ROOT;
}
}
return buildDirURI;
} }
@Override @Override

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009, 2011 Andrew Gvozdev and others. * Copyright (c) 2009, 2013 Andrew Gvozdev and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -17,8 +17,11 @@ import java.net.URI;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
@ -46,7 +49,6 @@ import org.eclipse.cdt.internal.core.XmlUtil;
import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages; import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages;
import org.eclipse.cdt.utils.CommandLineUtil; import org.eclipse.cdt.utils.CommandLineUtil;
import org.eclipse.cdt.utils.envvar.EnvironmentCollector;
import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.IWorkspaceRoot;
@ -97,9 +99,11 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti
private static final String ATTR_PARAMETER = "parameter"; //$NON-NLS-1$ private static final String ATTR_PARAMETER = "parameter"; //$NON-NLS-1$
private static final String ATTR_CONSOLE = "console"; //$NON-NLS-1$ private static final String ATTR_CONSOLE = "console"; //$NON-NLS-1$
private static final String ATTR_ENV_HASH = "env-hash"; //$NON-NLS-1$
private static final String ENV_LANGUAGE = "LANGUAGE"; //$NON-NLS-1$ private static final String ENV_LANGUAGE = "LANGUAGE"; //$NON-NLS-1$
private static final String ENV_LC_ALL = "LC_ALL"; //$NON-NLS-1$ private static final String ENV_LC_ALL = "LC_ALL"; //$NON-NLS-1$
private static final String ENV_PATH = "PATH"; //$NON-NLS-1$
private static final int MONITOR_SCALE = 100; private static final int MONITOR_SCALE = 100;
private static final int TICKS_REMOVE_MARKERS = 1 * MONITOR_SCALE; private static final int TICKS_REMOVE_MARKERS = 1 * MONITOR_SCALE;
@ -112,9 +116,15 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti
protected URI buildDirURI = null; protected URI buildDirURI = null;
protected java.io.File specFile = null; protected java.io.File specFile = null;
protected boolean preserveSpecFile = false; protected boolean preserveSpecFile = false;
/** @since 8.2 */
protected IEnvironmentVariableManager envMngr = null;
/** @since 8.2 */
protected volatile Map<String, String> environmentMap = null;
protected List<ICLanguageSettingEntry> detectedSettingEntries = null; protected List<ICLanguageSettingEntry> detectedSettingEntries = null;
protected int collected = 0; protected int collected = 0;
protected boolean isExecuted = false; protected volatile boolean isExecuted = false;
private int envPathHash = 0;
private BuildRunnerHelper buildRunnerHelper; private BuildRunnerHelper buildRunnerHelper;
private SDMarkerGenerator markerGenerator = new SDMarkerGenerator(); private SDMarkerGenerator markerGenerator = new SDMarkerGenerator();
@ -348,6 +358,7 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti
mappedRootURI = null; mappedRootURI = null;
buildDirURI = getBuildDirURI(mappedRootURI); buildDirURI = getBuildDirURI(mappedRootURI);
environmentMap = createEnvironmentMap(currentCfgDescription);
} }
@Override @Override
@ -358,18 +369,46 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti
super.shutdown(); super.shutdown();
} }
/**
* This method does 2 related things:
* <br>
* 1. Validate environment, i.e. check that environment for running the command has not changed.
* If environment changed {@link #execute()} will rerun the command even if flag {@link #isExecuted}
* suggests that it was run already.
* <br>
* 2. The relevant environment is cached here so the new one is validated against it at the next call.
* {@link #validateEnvironment()} will be called right before running the job to execute the command.
*
* @since 8.2
*/
protected boolean validateEnvironment() {
String envPathValue = environmentMap.get(ENV_PATH);
int envPathValueHash = envPathValue != null ? envPathValue.hashCode() : 0;
if (envPathValueHash != envPathHash || envPathValueHash == 0) {
envPathHash = envPathValueHash;
return false;
}
return true;
}
/** /**
* Execute provider's command which is expected to print built-in compiler options (specs) to build output. * Execute provider's command which is expected to print built-in compiler options (specs) to build output.
* The parser will parse output and generate language settings for corresponding resources. * The parser will parse output and generate language settings for corresponding resources.
*/ */
protected void execute() { protected void execute() {
if (isExecuted) { environmentMap = createEnvironmentMap(currentCfgDescription);
if (validateEnvironment() && isExecuted) {
return; return;
} }
WorkspaceJob job = new WorkspaceJob(ManagedMakeMessages.getResourceString("AbstractBuiltinSpecsDetector.DiscoverBuiltInSettingsJobName")) { //$NON-NLS-1$ WorkspaceJob job = new WorkspaceJob(ManagedMakeMessages.getResourceString("AbstractBuiltinSpecsDetector.DiscoverBuiltInSettingsJobName")) { //$NON-NLS-1$
@Override @Override
public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException { public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
isExecuted = false;
if (!isEmpty()) {
clear();
serializeLanguageSettings(currentCfgDescription);
}
IStatus status; IStatus status;
try { try {
startup(currentCfgDescription, null); startup(currentCfgDescription, null);
@ -550,7 +589,7 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti
} }
} }
String[] envp = getEnvp(); String[] envp = toEnvp(environmentMap);
// Using GMAKE_ERROR_PARSER_ID as it can handle generated error messages // Using GMAKE_ERROR_PARSER_ID as it can handle generated error messages
ErrorParserManager epm = new ErrorParserManager(currentProject, buildDirURI, markerGenerator, new String[] {GMAKE_ERROR_PARSER_ID}); ErrorParserManager epm = new ErrorParserManager(currentProject, buildDirURI, markerGenerator, new String[] {GMAKE_ERROR_PARSER_ID});
@ -592,8 +631,10 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti
* @since 8.2 * @since 8.2
*/ */
protected List<IEnvironmentVariable> getEnvironmentVariables() { protected List<IEnvironmentVariable> getEnvironmentVariables() {
IEnvironmentVariableManager mngr = CCorePlugin.getDefault().getBuildEnvironmentManager(); if (envMngr == null) {
List<IEnvironmentVariable> vars = new ArrayList<IEnvironmentVariable>(Arrays.asList(mngr.getVariables(currentCfgDescription, true))); envMngr = CCorePlugin.getDefault().getBuildEnvironmentManager();
}
List<IEnvironmentVariable> vars = new ArrayList<IEnvironmentVariable>(Arrays.asList(envMngr.getVariables(currentCfgDescription, true)));
// On POSIX (Linux, UNIX) systems reset language variables to default (English) // On POSIX (Linux, UNIX) systems reset language variables to default (English)
// with UTF-8 encoding since GNU compilers can handle only UTF-8 characters. // with UTF-8 encoding since GNU compilers can handle only UTF-8 characters.
@ -608,16 +649,23 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti
} }
/** /**
* Get array of environment variables in format "var=value". * Create a handy map of environment variables.
*/ */
private String[] getEnvp() { private Map<String, String> createEnvironmentMap(ICConfigurationDescription cfgDescription) {
EnvironmentCollector collector = new EnvironmentCollector(); Map<String, String> envMap = new HashMap<String, String>();
List<IEnvironmentVariable> vars = getEnvironmentVariables(); for (IEnvironmentVariable var : getEnvironmentVariables()) {
collector.addVariables(vars.toArray(new IEnvironmentVariable[vars.size()])); envMap.put(var.getName(), var.getValue());
}
return envMap;
}
/**
* Convert map of environment variables to array in format "var=value".
*/
private String[] toEnvp(Map<String, String> environmentMap) {
Set<String> envp = new HashSet<String>(); Set<String> envp = new HashSet<String>();
for (IEnvironmentVariable var : collector.getVariables()) { for (Entry<String, String> var: environmentMap.entrySet()) {
envp.add(var.getName() + '=' + var.getValue()); envp.add(var.getKey() + '=' + var.getValue());
} }
return envp.toArray(new String[envp.size()]); return envp.toArray(new String[envp.size()]);
} }
@ -736,6 +784,9 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti
public Element serializeAttributes(Element parentElement) { public Element serializeAttributes(Element parentElement) {
Element elementProvider = super.serializeAttributes(parentElement); Element elementProvider = super.serializeAttributes(parentElement);
elementProvider.setAttribute(ATTR_CONSOLE, Boolean.toString(isConsoleEnabled)); elementProvider.setAttribute(ATTR_CONSOLE, Boolean.toString(isConsoleEnabled));
if (envPathHash != 0) {
elementProvider.setAttribute(ATTR_ENV_HASH, Integer.toString(envPathHash));
}
return elementProvider; return elementProvider;
} }
@ -747,6 +798,16 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti
if (consoleValue != null) { if (consoleValue != null) {
isConsoleEnabled = Boolean.parseBoolean(consoleValue); isConsoleEnabled = Boolean.parseBoolean(consoleValue);
} }
envPathHash = 0;
String envPathHashStr = XmlUtil.determineAttributeValue(providerNode, ATTR_ENV_HASH);
if (envPathHashStr != null) {
try {
envPathHash = Integer.parseInt(envPathHashStr);
} catch (Exception e) {
ManagedBuilderCorePlugin.log(new Status(IStatus.ERROR, ManagedBuilderCorePlugin.PLUGIN_ID, "Wrong integer format [" + envPathHashStr + "]", e)); //$NON-NLS-1$ //$NON-NLS-2$
}
}
} }
@Override @Override
@ -774,6 +835,9 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti
protected AbstractBuiltinSpecsDetector cloneShallow() throws CloneNotSupportedException { protected AbstractBuiltinSpecsDetector cloneShallow() throws CloneNotSupportedException {
AbstractBuiltinSpecsDetector clone = (AbstractBuiltinSpecsDetector) super.cloneShallow(); AbstractBuiltinSpecsDetector clone = (AbstractBuiltinSpecsDetector) super.cloneShallow();
clone.isExecuted = false; clone.isExecuted = false;
clone.envMngr = null;
clone.environmentMap = null;
clone.envPathHash = 0;
return clone; return clone;
} }
@ -783,6 +847,7 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti
int result = super.hashCode(); int result = super.hashCode();
result = prime * result + (isConsoleEnabled ? 1231 : 1237); result = prime * result + (isConsoleEnabled ? 1231 : 1237);
result = prime * result + (isExecuted ? 1231 : 1237); result = prime * result + (isExecuted ? 1231 : 1237);
result = prime * result + envPathHash;
return result; return result;
} }
@ -792,13 +857,15 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti
return true; return true;
if (!super.equals(obj)) if (!super.equals(obj))
return false; return false;
if (!(obj instanceof AbstractBuiltinSpecsDetector)) if (getClass() != obj.getClass())
return false; return false;
AbstractBuiltinSpecsDetector other = (AbstractBuiltinSpecsDetector) obj; AbstractBuiltinSpecsDetector other = (AbstractBuiltinSpecsDetector) obj;
if (isConsoleEnabled != other.isConsoleEnabled) if (isConsoleEnabled != other.isConsoleEnabled)
return false; return false;
if (isExecuted != other.isExecuted) if (isExecuted != other.isExecuted)
return false; return false;
if (envPathHash != other.envPathHash)
return false;
return true; return true;
} }
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009, 2012 Andrew Gvozdev and others. * Copyright (c) 2009, 2013 Andrew Gvozdev and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -25,6 +25,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.EFSExtensionProvider;
import org.eclipse.cdt.core.ErrorParserManager; import org.eclipse.cdt.core.ErrorParserManager;
import org.eclipse.cdt.core.cdtvariables.CdtVariableException; import org.eclipse.cdt.core.cdtvariables.CdtVariableException;
import org.eclipse.cdt.core.cdtvariables.ICdtVariableManager; import org.eclipse.cdt.core.cdtvariables.ICdtVariableManager;
@ -80,6 +81,37 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
protected String parsedResourceName = null; protected String parsedResourceName = null;
protected boolean isResolvingPaths = true; protected boolean isResolvingPaths = true;
/** @since 8.2 */
protected EFSExtensionProvider efsProvider = null;
private static final EFSExtensionProvider efsProviderDefault = new EFSExtensionProvider() {
final EFSExtensionManager efsManager = EFSExtensionManager.getDefault();
@Override
public String getPathFromURI(URI locationURI) {
return efsManager.getPathFromURI(locationURI);
}
@Override
public URI getLinkedURI(URI locationURI) {
return efsManager.getLinkedURI(locationURI);
}
@Override
public URI createNewURIFromPath(URI locationOnSameFilesystem, String path) {
return efsManager.createNewURIFromPath(locationOnSameFilesystem, path);
}
@Override
public String getMappedPath(URI locationURI) {
return efsManager.getMappedPath(locationURI);
}
@Override
public boolean isVirtual(URI locationURI) {
return efsManager.isVirtual(locationURI);
}
@Override
public URI append(URI baseURI, String extension) {
return efsManager.append(baseURI, extension);
}
};
/** /**
* Abstract class defining common functionality for option parsers. * Abstract class defining common functionality for option parsers.
* The purpose of this parser is to parse a portion of string representing * The purpose of this parser is to parse a portion of string representing
@ -373,6 +405,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
this.currentCfgDescription = cfgDescription; this.currentCfgDescription = cfgDescription;
this.currentProject = cfgDescription != null ? cfgDescription.getProjectDescription().getProject() : null; this.currentProject = cfgDescription != null ? cfgDescription.getProjectDescription().getProject() : null;
this.cwdTracker = cwdTracker; this.cwdTracker = cwdTracker;
this.efsProvider = getEFSProvider();
} }
@Override @Override
@ -429,7 +462,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
if (isResolvingPaths && (optionParser.isForFile() || optionParser.isForFolder())) { if (isResolvingPaths && (optionParser.isForFile() || optionParser.isForFolder())) {
URI baseURI = mappedRootURI; URI baseURI = mappedRootURI;
if (buildDirURI != null && !new Path(optionParser.parsedName).isAbsolute()) { if (buildDirURI != null && !new Path(optionParser.parsedName).isAbsolute()) {
baseURI = EFSExtensionManager.getDefault().append(mappedRootURI, buildDirURI.getPath()); baseURI = efsProvider.append(mappedRootURI, buildDirURI.getPath());
} }
entry = createResolvedPathEntry(optionParser, optionParser.parsedName, 0, baseURI); entry = createResolvedPathEntry(optionParser, optionParser.parsedName, 0, baseURI);
} else { } else {
@ -494,7 +527,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
} }
} }
// this creates URI with schema and other components from resourceURI but path as mappedRoot // this creates URI with schema and other components from resourceURI but path as mappedRoot
URI uri = EFSExtensionManager.getDefault().createNewURIFromPath(resourceURI, mappedRoot); URI uri = efsProvider.createNewURIFromPath(resourceURI, mappedRoot);
return uri; return uri;
} }
@ -513,9 +546,9 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
if (currentResource != null && parsedResourceName != null && !new Path(parsedResourceName).isAbsolute()) { if (currentResource != null && parsedResourceName != null && !new Path(parsedResourceName).isAbsolute()) {
cwdURI = findBaseLocationURI(currentResource.getLocationURI(), parsedResourceName); cwdURI = findBaseLocationURI(currentResource.getLocationURI(), parsedResourceName);
} }
String cwdPath = cwdURI != null ? EFSExtensionManager.getDefault().getPathFromURI(cwdURI) : null; String cwdPath = cwdURI != null ? efsProvider.getPathFromURI(cwdURI) : null;
if (cwdPath != null && mappedRootURI != null) { if (cwdPath != null && mappedRootURI != null) {
buildDirURI = EFSExtensionManager.getDefault().append(mappedRootURI, cwdPath); buildDirURI = efsProvider.append(mappedRootURI, cwdPath);
} else { } else {
buildDirURI = cwdURI; buildDirURI = cwdURI;
} }
@ -674,7 +707,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
if (sourceFile == null && cwdTracker != null) { if (sourceFile == null && cwdTracker != null) {
URI cwdURI = cwdTracker.getWorkingDirectoryURI(); URI cwdURI = cwdTracker.getWorkingDirectoryURI();
if (cwdURI != null) { if (cwdURI != null) {
URI uri = EFSExtensionManager.getDefault().append(cwdURI, parsedResourceName); URI uri = efsProvider.append(cwdURI, parsedResourceName);
sourceFile = findFileForLocationURI(uri, currentProject); sourceFile = findFileForLocationURI(uri, currentProject);
} }
} }
@ -804,7 +837,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
* @param baseURI - base {@link URI} where path to the resource is rooted * @param baseURI - base {@link URI} where path to the resource is rooted
* @return {@link URI} of the resource * @return {@link URI} of the resource
*/ */
private static URI determineMappedURI(String pathStr, URI baseURI) { private URI determineMappedURI(String pathStr, URI baseURI) {
URI uri = null; URI uri = null;
if (baseURI == null) { if (baseURI == null) {
@ -819,9 +852,9 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
} else { } else {
// location on a remote file-system // location on a remote file-system
IPath path = new Path(pathStr); // use canonicalized path here, in particular replace all '\' with '/' for Windows paths IPath path = new Path(pathStr); // use canonicalized path here, in particular replace all '\' with '/' for Windows paths
URI remoteUri = EFSExtensionManager.getDefault().append(baseURI, path.toString()); URI remoteUri = efsProvider.append(baseURI, path.toString());
if (remoteUri != null) { if (remoteUri != null) {
String localPath = EFSExtensionManager.getDefault().getMappedPath(remoteUri); String localPath = efsProvider.getMappedPath(remoteUri);
if (localPath != null) { if (localPath != null) {
uri = org.eclipse.core.filesystem.URIUtil.toURI(localPath); uri = org.eclipse.core.filesystem.URIUtil.toURI(localPath);
} }
@ -929,13 +962,13 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
} }
/** /**
* Get location on the local file-system considering possible mapping by {@link EFSExtensionManager}. * Get location on the local file-system considering possible mapping by EFS provider. See {@link EFSExtensionManager}.
*/ */
private static IPath getFilesystemLocation(URI uri) { private IPath getFilesystemLocation(URI uri) {
if (uri == null) if (uri == null)
return null; return null;
String pathStr = EFSExtensionManager.getDefault().getMappedPath(uri); String pathStr = efsProvider.getMappedPath(uri);
uri = org.eclipse.core.filesystem.URIUtil.toURI(pathStr); uri = org.eclipse.core.filesystem.URIUtil.toURI(pathStr);
if (uri != null && uri.isAbsolute()) { if (uri != null && uri.isAbsolute()) {
@ -1065,6 +1098,20 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
return pattern; return pattern;
} }
/**
* This {@link EFSExtensionProvider} is capable to translate EFS paths to and from local
* file-system. Added mostly for Cygwin translations.
*
* This usage of {@link EFSExtensionProvider} is somewhat a misnomer. This provider is not
* an "extension" provider but rather a wrapper on {@link EFSExtensionManager} which in fact
* will use genuine {@link EFSExtensionProvider}s defined as extensions.
*
* @since 8.2
*/
protected EFSExtensionProvider getEFSProvider() {
return efsProviderDefault;
}
@Override @Override
public Element serializeAttributes(Element parentElement) { public Element serializeAttributes(Element parentElement) {

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009, 2012 Andrew Gvozdev and others. * Copyright (c) 2009, 2013 Andrew Gvozdev and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -11,22 +11,17 @@
package org.eclipse.cdt.managedbuilder.language.settings.providers; package org.eclipse.cdt.managedbuilder.language.settings.providers;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.eclipse.cdt.core.envvar.IEnvironmentVariable; import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.IInputType; import org.eclipse.cdt.managedbuilder.core.IInputType;
import org.eclipse.cdt.managedbuilder.core.ITool; import org.eclipse.cdt.managedbuilder.core.ITool;
import org.eclipse.cdt.managedbuilder.core.IToolChain; import org.eclipse.cdt.managedbuilder.core.IToolChain;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable; import org.eclipse.cdt.managedbuilder.internal.envvar.EnvironmentVariableManagerToolChain;
import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier;
import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider;
/** /**
* Abstract parser capable to execute compiler command printing built-in compiler * Abstract parser capable to execute compiler command printing built-in compiler
@ -120,19 +115,12 @@ public abstract class ToolchainBuiltinSpecsDetector extends AbstractBuiltinSpecs
@Override @Override
protected List<IEnvironmentVariable> getEnvironmentVariables() { protected List<IEnvironmentVariable> getEnvironmentVariables() {
List<IEnvironmentVariable> vars = new ArrayList<IEnvironmentVariable>(super.getEnvironmentVariables()); if (envMngr == null && currentCfgDescription == null) {
// For global provider need to include toolchain in the equation
String toolchainId = getToolchainId(); IToolChain toolchain = ManagedBuildManager.getExtensionToolChain(getToolchainId());
for (IToolChain toolchain = ManagedBuildManager.getExtensionToolChain(toolchainId); toolchain != null; toolchain = toolchain.getSuperClass()) { envMngr = new EnvironmentVariableManagerToolChain(toolchain);
IConfigurationEnvironmentVariableSupplier envSupplier = toolchain.getEnvironmentVariableSupplier();
if (envSupplier != null) {
IConfiguration cfg = ManagedBuildManager.getConfigurationForDescription(currentCfgDescription);
IEnvironmentVariableProvider provider = ManagedBuildManager.getEnvironmentVariableProvider();
IBuildEnvironmentVariable[] added = envSupplier.getVariables(cfg, provider);
vars.addAll(Arrays.asList(added));
break;
}
} }
List<IEnvironmentVariable> vars = super.getEnvironmentVariables();
return vars; return vars;
} }

View file

@ -12,14 +12,9 @@
package org.eclipse.cdt.managedbuilder.gnu.cygwin; package org.eclipse.cdt.managedbuilder.gnu.cygwin;
import org.eclipse.cdt.core.envvar.IEnvironmentVariable; import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
import org.eclipse.cdt.core.envvar.IEnvironmentVariableManager;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.internal.core.Cygwin; import org.eclipse.cdt.internal.core.Cygwin;
import org.eclipse.cdt.internal.core.envvar.EnvironmentVariableManager;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.IManagedIsToolChainSupported; import org.eclipse.cdt.managedbuilder.core.IManagedIsToolChainSupported;
import org.eclipse.cdt.managedbuilder.core.IToolChain; import org.eclipse.cdt.managedbuilder.core.IToolChain;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.internal.envvar.EnvironmentVariableManagerToolChain; import org.eclipse.cdt.managedbuilder.internal.envvar.EnvironmentVariableManagerToolChain;
import org.osgi.framework.Version; import org.osgi.framework.Version;
@ -33,16 +28,7 @@ public class IsGnuCygwinToolChainSupported implements IManagedIsToolChainSupport
@Override @Override
public boolean isSupported(IToolChain toolChain, Version version, String instance) { public boolean isSupported(IToolChain toolChain, Version version, String instance) {
IConfiguration cfg = toolChain.getParent(); IEnvironmentVariable var = new EnvironmentVariableManagerToolChain(toolChain).getVariable(ENV_PATH, true);
ICConfigurationDescription cfgDescription = cfg != null ? ManagedBuildManager.getDescriptionForConfiguration(cfg) : null;
IEnvironmentVariableManager envMngr;
if (cfgDescription != null) {
envMngr = EnvironmentVariableManager.getDefault();
} else {
envMngr = new EnvironmentVariableManagerToolChain(toolChain);
}
IEnvironmentVariable var = envMngr.getVariable(ENV_PATH, cfgDescription, true);
String envPath = var != null ? var.getValue() : null; String envPath = var != null ? var.getValue() : null;
return Cygwin.isAvailable(envPath); return Cygwin.isAvailable(envPath);
} }

View file

@ -229,4 +229,25 @@ public class ArrayUtilTest extends TestCase {
assertSame(result[0], o1); assertSame(result[0], o1);
assertSame(result[1], o2); assertSame(result[1], o2);
} }
public void testRemoveDuplicates() {
String[] array = { "1", "2", null, "3", "2", "1", "4", "3" };
String[] result = ArrayUtil.removeDuplicates(array);
assertEquals(4, result.length);
assertEquals("1", result[0]);
assertEquals("2", result[1]);
assertEquals("3", result[2]);
assertEquals("4", result[3]);
// Test a long array.
array = new String[100];
for (int i = 0; i < array.length; i++) {
array[i] = (i + 1) % 11 == 0 ? null : String.valueOf(i % 17);
}
result = ArrayUtil.removeDuplicates(array);
assertEquals(17, result.length);
for (int i = 0; i < result.length - 1; i++) {
assertEquals(String.valueOf(i < 10 ? i : i < 16 ? i + 1 : 10), result[i]);
}
}
} }

View file

@ -42,7 +42,6 @@ import org.eclipse.cdt.core.dom.ast.IASTProblemStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IEnumerator;
@ -96,7 +95,6 @@ import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
@ -5891,11 +5889,8 @@ public class AST2TemplateTests extends AST2TestBase {
// auto x2 = begin2(v); // auto x2 = begin2(v);
public void testResolvingAutoTypeWithDependentExpression_402409a() throws Exception { public void testResolvingAutoTypeWithDependentExpression_402409a() throws Exception {
BindingAssertionHelper helper = new BindingAssertionHelper(getAboveComment(), true); BindingAssertionHelper helper = new BindingAssertionHelper(getAboveComment(), true);
ICPPVariable x1 = helper.assertNonProblem("x1", ICPPVariable.class); helper.assertVariableType("x1", CommonTypes.pointerToInt);
ICPPVariable x2 = helper.assertNonProblem("x2", ICPPVariable.class); helper.assertVariableType("x2", CommonTypes.pointerToInt);
IType pointerToInt = new CPPPointerType(new CPPBasicType(Kind.eInt, 0));
assertSameType(pointerToInt, x1.getType());
assertSameType(pointerToInt, x2.getType());
} }
// struct vector { // struct vector {
@ -6217,6 +6212,21 @@ public class AST2TemplateTests extends AST2TestBase {
public void testPointerToMemberAsDependentExpression_391001() throws Exception { public void testPointerToMemberAsDependentExpression_391001() throws Exception {
parseAndCheckBindings(getAboveComment(), CPP, true); parseAndCheckBindings(getAboveComment(), CPP, true);
} }
// template<typename>
// struct A {
// char x;
// };
//
// typedef A<int> B;
//
// template <char B::*PtrToMember>
// struct C {};
//
// typedef C<&B::x> T;
public void testPointerToMemberOfTemplateClass_402861() throws Exception {
parseAndCheckBindings();
}
// class Memory { }; // class Memory { };
// Memory memory; // Memory memory;
@ -7195,6 +7205,19 @@ public class AST2TemplateTests extends AST2TestBase {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template <typename T>
// struct waldo {
// typedef int type;
// };
//
// template <typename R>
// struct waldo<R (...)>;
//
// typedef waldo<int ()>::type Type;
public void testPartialSpecializationForVarargFunctionType_402807() throws Exception {
parseAndCheckBindings();
}
// template <typename> // template <typename>
// struct meta { // struct meta {
// static const bool value = 1; // static const bool value = 1;
@ -7519,4 +7542,25 @@ public class AST2TemplateTests extends AST2TestBase {
public void testUnqualifiedFunctionCallInTemplate_402498() throws Exception { public void testUnqualifiedFunctionCallInTemplate_402498() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template <typename>
// struct no_type {};
//
// struct type {};
//
// template <typename T>
// struct A {};
//
// template <typename T>
// int foo(T);
//
// template <typename T>
// typename no_type<T>::type const foo(A<T>);
//
// A<int> a;
// auto b = foo(a);
public void testQualifiedNameLookupInTemplate_402854() throws Exception {
BindingAssertionHelper helper = new BindingAssertionHelper(getAboveComment(), true);
helper.assertVariableType("b", CommonTypes.int_);
}
} }

View file

@ -57,6 +57,8 @@ import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.c.ICASTTypeIdInitializerExpression; import org.eclipse.cdt.core.dom.ast.c.ICASTTypeIdInitializerExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
@ -86,6 +88,8 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser; import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser;
import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor; import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
import org.eclipse.cdt.internal.core.dom.parser.c.GNUCSourceParser; import org.eclipse.cdt.internal.core.dom.parser.c.GNUCSourceParser;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.GNUCPPSourceParser; import org.eclipse.cdt.internal.core.dom.parser.cpp.GNUCPPSourceParser;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.model.ASTStringUtil; import org.eclipse.cdt.internal.core.model.ASTStringUtil;
@ -99,6 +103,11 @@ public class AST2TestBase extends BaseTestCase {
public final static String TEST_CODE = "<testcode>"; public final static String TEST_CODE = "<testcode>";
protected static final IParserLogService NULL_LOG = new NullLogService(); protected static final IParserLogService NULL_LOG = new NullLogService();
protected static boolean sValidateCopy; protected static boolean sValidateCopy;
protected static class CommonTypes {
public static IType int_ = new CPPBasicType(Kind.eInt, 0);
public static IType pointerToInt = new CPPPointerType(int_);
}
private static final ScannerInfo GNU_SCANNER_INFO = new ScannerInfo(getGnuMap()); private static final ScannerInfo GNU_SCANNER_INFO = new ScannerInfo(getGnuMap());
private static final ScannerInfo SCANNER_INFO = new ScannerInfo(getStdMap()); private static final ScannerInfo SCANNER_INFO = new ScannerInfo(getStdMap());
@ -739,6 +748,11 @@ public class AST2TestBase extends BaseTestCase {
assertTrue("ProblemBinding for name: " + name, !(binding instanceof IProblemBinding)); assertTrue("ProblemBinding for name: " + name, !(binding instanceof IProblemBinding));
return assertType(binding, cs); return assertType(binding, cs);
} }
public void assertVariableType(String variableName, IType expectedType) {
IVariable var = assertNonProblem(variableName, IVariable.class);
assertSameType(expectedType, var.getType());
}
public <T, U extends T> U assertType(T obj, Class... cs) { public <T, U extends T> U assertType(T obj, Class... cs) {
for (Class c : cs) { for (Class c : cs) {

View file

@ -31,7 +31,7 @@ import org.eclipse.core.runtime.CoreException;
/** /**
* Test insertion/deletion of records of a mock record type in a B-tree * Test insertion/deletion of records of a mock record type in a B-tree
* *
* @author aferguso * @author aferguso
* *
*/ */
@ -65,11 +65,11 @@ public class BTreeTests extends BaseTestCase {
dbFile.deleteOnExit(); dbFile.deleteOnExit();
} }
public void testBySortedSetMirrorLite() throws Exception { public void testBySortedSetMirrorLite() throws Exception {
sortedMirrorTest(8); sortedMirrorTest(8);
} }
/** /**
* Test random (but reproducible via known seed) sequences of insertions/deletions * Test random (but reproducible via known seed) sequences of insertions/deletions
* and use TreeSet as a reference implementation to check behaviour against. * and use TreeSet as a reference implementation to check behaviour against.
@ -103,13 +103,31 @@ public class BTreeTests extends BaseTestCase {
} }
/** /**
* Insert/Delete a random number of records into/from the B-tree * Bug 402177: BTree.insert should return the matching record if the new record was not inserted.
*/
public void testEquivalentRecordInsert_Bug402177() throws Exception {
init(8);
try {
BTMockRecord value1 = new BTMockRecord(db, 42);
BTMockRecord value2 = new BTMockRecord(db, 42);
long insert1 = btree.insert(value1.getRecord());
long insert2 = btree.insert(value2.getRecord());
assertEquals(insert1, insert2);
} finally {
finish();
}
}
/**
* Insert/Delete a random number of records into/from the B-tree
* @param seed the seed for obtaining the deterministic random testing * @param seed the seed for obtaining the deterministic random testing
* @param checkCorrectnessEachIteration if true, then on every single insertion/deletion check that the B-tree invariants * @param checkCorrectnessEachIteration if true, then on every single insertion/deletion check that the B-tree invariants
* still hold * still hold
* @throws Exception * @throws Exception
*/ */
protected void trial(int seed, final boolean checkCorrectnessEachIteration) throws Exception { protected void trial(int seed, final boolean checkCorrectnessEachIteration) throws Exception {
Random random = new Random(seed); Random random = new Random(seed);
// the probabilty that a particular iterations action will be an insertion // the probabilty that a particular iterations action will be an insertion
@ -123,9 +141,9 @@ public class BTreeTests extends BaseTestCase {
final int nIterations = random.nextInt(100000); final int nIterations = random.nextInt(100000);
final SortedSet expected = new TreeSet(); final SortedSet expected = new TreeSet();
final List history = new ArrayList(); final List history = new ArrayList();
init(degree); init(degree);
if (DEBUG > 0) if (DEBUG > 0)
System.out.print("\t "+seed+" "+(nIterations/1000)+"K: "); System.out.print("\t "+seed+" "+(nIterations/1000)+"K: ");
for(int i=0; i<nIterations; i++) { for(int i=0; i<nIterations; i++) {
@ -163,7 +181,7 @@ public class BTreeTests extends BaseTestCase {
assertBTreeMatchesSortedSet("[Trial end] ", btree, expected); assertBTreeMatchesSortedSet("[Trial end] ", btree, expected);
assertBTreeInvariantsHold("[Trial end]"); assertBTreeInvariantsHold("[Trial end]");
finish(); finish();
} }
@ -201,7 +219,7 @@ public class BTreeTests extends BaseTestCase {
} }
private static class BTMockRecord { private static class BTMockRecord {
public static final int VALUE_PTR = 0; public static final int VALUE_PTR = 0;
public static final int RECORD_SIZE = Database.INT_SIZE; public static final int RECORD_SIZE = Database.INT_SIZE;
long record; long record;
Database db; Database db;
@ -213,7 +231,7 @@ public class BTreeTests extends BaseTestCase {
this.db = db; this.db = db;
record = db.malloc(BTMockRecord.RECORD_SIZE); record = db.malloc(BTMockRecord.RECORD_SIZE);
db.putInt(record + VALUE_PTR, value); db.putInt(record + VALUE_PTR, value);
} }
/** /**
* Get an existing record * Get an existing record
@ -235,7 +253,7 @@ public class BTreeTests extends BaseTestCase {
private class BTMockRecordComparator implements IBTreeComparator { private class BTMockRecordComparator implements IBTreeComparator {
@Override @Override
public int compare(long record1, long record2) throws CoreException { public int compare(long record1, long record2) throws CoreException {
return db.getInt(record1) - db.getInt(record2); return db.getInt(record1) - db.getInt(record2);
} }
} }
} }

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Intel Corporation - Initial API and implementation * Intel Corporation - Initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.settings.model.util; package org.eclipse.cdt.core.settings.model.util;
@ -27,6 +27,7 @@ public class SettingsSet {
public static final int WRITABLE = 1 << 1; public static final int WRITABLE = 1 << 1;
private SettingLevel[] fLevels; private SettingLevel[] fLevels;
public class SettingLevel { public class SettingLevel {
private int fFlagsToSet; private int fFlagsToSet;
private int fFlagsToClear; private int fFlagsToClear;
@ -36,149 +37,149 @@ public class SettingsSet {
HashSet<String> fOverrideSet; HashSet<String> fOverrideSet;
private Object fContext; private Object fContext;
private SettingLevel(){ private SettingLevel() {
fEntries = new LinkedHashMap<EntryNameKey, EntryInfo>(); fEntries = new LinkedHashMap<EntryNameKey, EntryInfo>();
} }
public boolean isReadOnly(){ public boolean isReadOnly() {
return fIsReadOnly; return fIsReadOnly;
} }
public void setReadOnly(boolean readOnly){ public void setReadOnly(boolean readOnly) {
fIsReadOnly = readOnly; fIsReadOnly = readOnly;
} }
public boolean isOverrideSupported(){ public boolean isOverrideSupported() {
return fIsOverrideSupported; return fIsOverrideSupported;
} }
public void setOverrideSupported(boolean supported){ public void setOverrideSupported(boolean supported) {
fIsOverrideSupported = supported; fIsOverrideSupported = supported;
} }
public void setFlagsToSet(int flags){ public void setFlagsToSet(int flags) {
fFlagsToSet = flags; fFlagsToSet = flags;
} }
public boolean containsOverrideInfo(){ public boolean containsOverrideInfo() {
return fOverrideSet != null; return fOverrideSet != null;
} }
public void setFlagsToClear(int flags){ public void setFlagsToClear(int flags) {
fFlagsToClear = flags; fFlagsToClear = flags;
} }
public int getFlagsToSet(){ public int getFlagsToSet() {
return fFlagsToSet; return fFlagsToSet;
} }
public int getFlagsToClear(){ public int getFlagsToClear() {
return fFlagsToClear; return fFlagsToClear;
} }
public int getFlags(int baseFlags){ public int getFlags(int baseFlags) {
return (baseFlags | fFlagsToSet) & (~fFlagsToClear); return (baseFlags | fFlagsToSet) & (~fFlagsToClear);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Set<String> getOverrideSet(){ public Set<String> getOverrideSet() {
if(fOverrideSet != null) if (fOverrideSet != null)
return (HashSet<String>)fOverrideSet.clone(); return (HashSet<String>)fOverrideSet.clone();
return new HashSet<String>(); return new HashSet<String>();
} }
public void addEntries(ICLanguageSettingEntry entries[]){ public void addEntries(ICLanguageSettingEntry entries[]) {
if(entries != null){ if (entries != null) {
for(int i = 0; i < entries.length; i++){ for (int i = 0; i < entries.length; i++) {
addEntry(entries[i]); addEntry(entries[i]);
} }
} }
} }
public void addEntries(List<ICLanguageSettingEntry> list){ public void addEntries(List<ICLanguageSettingEntry> list) {
for(ICLanguageSettingEntry se : list) for (ICLanguageSettingEntry se : list)
addEntry(se); addEntry(se);
} }
public void addEntry(ICLanguageSettingEntry entry){ public void addEntry(ICLanguageSettingEntry entry) {
addEntry(entry, null); addEntry(entry, null);
} }
public void addEntry(ICLanguageSettingEntry entry, Object customInfo){ public void addEntry(ICLanguageSettingEntry entry, Object customInfo) {
entry = CDataUtil.createEntry(entry, fFlagsToSet, fFlagsToClear); entry = CDataUtil.createEntry(entry, fFlagsToSet, fFlagsToClear);
EntryInfo info = new EntryInfo(entry, customInfo); EntryInfo info = new EntryInfo(entry, customInfo);
fEntries.put(info.getContentsKey(), info); fEntries.put(info.getContentsKey(), info);
} }
public void addOverrideName(String name){ public void addOverrideName(String name) {
if(fOverrideSet == null) if (fOverrideSet == null)
fOverrideSet = new HashSet<String>(); fOverrideSet = new HashSet<String>();
fOverrideSet.add(name); fOverrideSet.add(name);
} }
public void addOverrideNameSet(Set<String> set){ public void addOverrideNameSet(Set<String> set) {
if(set == null) if (set == null)
return; return;
if(fOverrideSet != null){ if (fOverrideSet != null) {
fOverrideSet.addAll(set); fOverrideSet.addAll(set);
} else if(set.size() != 0){ } else if (set.size() != 0) {
fOverrideSet = new HashSet<String>(set); fOverrideSet = new HashSet<String>(set);
} }
} }
public void removeOverrideName(String name){ public void removeOverrideName(String name) {
if(fOverrideSet == null) if (fOverrideSet == null)
return; return;
fOverrideSet.remove(name); fOverrideSet.remove(name);
if(fOverrideSet.size() == 0) if (fOverrideSet.size() == 0)
fOverrideSet = null; fOverrideSet = null;
} }
public void clear(){ public void clear() {
fEntries.clear(); fEntries.clear();
fOverrideSet = null; fOverrideSet = null;
} }
public Map<EntryNameKey, EntryInfo> clearAndGetMap(){ public Map<EntryNameKey, EntryInfo> clearAndGetMap() {
Map<EntryNameKey, EntryInfo> map = fEntries; Map<EntryNameKey, EntryInfo> map = fEntries;
fEntries = new LinkedHashMap<EntryNameKey, EntryInfo>(); fEntries = new LinkedHashMap<EntryNameKey, EntryInfo>();
fOverrideSet = null; fOverrideSet = null;
return map; return map;
} }
public EntryInfo[] getInfos(){ public EntryInfo[] getInfos() {
return fEntries.values().toArray(new EntryInfo[fEntries.size()]); return fEntries.values().toArray(new EntryInfo[fEntries.size()]);
} }
public ICLanguageSettingEntry[] getEntries(){ public ICLanguageSettingEntry[] getEntries() {
List<ICLanguageSettingEntry> list = getEntriesList(false); List<ICLanguageSettingEntry> list = getEntriesList(false);
return list.toArray(new ICLanguageSettingEntry[list.size()]); return list.toArray(new ICLanguageSettingEntry[list.size()]);
} }
public ICLanguageSettingEntry[] getEntries(boolean includeOverridden){ public ICLanguageSettingEntry[] getEntries(boolean includeOverridden) {
List<ICLanguageSettingEntry> list = getEntriesList(includeOverridden); List<ICLanguageSettingEntry> list = getEntriesList(includeOverridden);
return list.toArray(new ICLanguageSettingEntry[list.size()]); return list.toArray(new ICLanguageSettingEntry[list.size()]);
} }
public List<ICLanguageSettingEntry> getEntriesList(boolean includeOverridden){ public List<ICLanguageSettingEntry> getEntriesList(boolean includeOverridden) {
List<ICLanguageSettingEntry> list = new ArrayList<ICLanguageSettingEntry>(); List<ICLanguageSettingEntry> list = new ArrayList<ICLanguageSettingEntry>();
EntryInfo infos[] = getInfos(); EntryInfo infos[] = getInfos();
for(EntryInfo info : infos){ for (EntryInfo info : infos) {
if(includeOverridden || !info.isOverridden()) if (includeOverridden || !info.isOverridden())
list.add(info.getEntry()); list.add(info.getEntry());
} }
return list; return list;
} }
public Object getContext(){ public Object getContext() {
return fContext; return fContext;
} }
public void setContext(Object context){ public void setContext(Object context) {
fContext = context; fContext = context;
} }
} }
@ -189,60 +190,60 @@ public class SettingsSet {
private boolean fIsOverRidden; private boolean fIsOverRidden;
private Object fCustomInfo; private Object fCustomInfo;
private EntryInfo(ICLanguageSettingEntry entry, Object customInfo){ private EntryInfo(ICLanguageSettingEntry entry, Object customInfo) {
fEntry = entry; fEntry = entry;
fCustomInfo = customInfo; fCustomInfo = customInfo;
} }
public EntryNameKey getContentsKey(){ public EntryNameKey getContentsKey() {
if(fNameKey == null){ if (fNameKey == null) {
fNameKey = new EntryNameKey(fEntry); fNameKey = new EntryNameKey(fEntry);
} }
return fNameKey; return fNameKey;
} }
private void makeOverridden(boolean overrridden){ private void makeOverridden(boolean overridden) {
fIsOverRidden = overrridden; fIsOverRidden = overridden;
} }
public ICLanguageSettingEntry getEntry(){ public ICLanguageSettingEntry getEntry() {
return fEntry; return fEntry;
} }
public boolean isOverridden(){ public boolean isOverridden() {
return fIsOverRidden; return fIsOverRidden;
} }
public Object getCustomInfo(){ public Object getCustomInfo() {
return fCustomInfo; return fCustomInfo;
} }
} }
public SettingsSet(int num){ public SettingsSet(int num) {
fLevels = new SettingLevel[num]; fLevels = new SettingLevel[num];
for(int i = 0; i < num; i++){ for (int i = 0; i < num; i++) {
fLevels[i] = new SettingLevel(); fLevels[i] = new SettingLevel();
} }
} }
public SettingLevel[] getLevels(){ public SettingLevel[] getLevels() {
return fLevels.clone(); return fLevels.clone();
} }
public void adjustOverrideState(){ public void adjustOverrideState() {
Set<String> set = new HashSet<String>(); Set<String> set = new HashSet<String>();
SettingLevel level; SettingLevel level;
for(int i = 0; i < fLevels.length; i++){ for (int i = 0; i < fLevels.length; i++) {
level = fLevels[i]; level = fLevels[i];
if(level.isOverrideSupported() && level.fOverrideSet != null) if (level.isOverrideSupported() && level.fOverrideSet != null)
set.addAll(level.fOverrideSet); set.addAll(level.fOverrideSet);
adjustOverrideState(fLevels[i], set); adjustOverrideState(fLevels[i], set);
} }
} }
private void adjustOverrideState(SettingLevel level, Set<String> overridenSet){ private void adjustOverrideState(SettingLevel level, Set<String> overridenSet) {
for(EntryInfo info : level.getInfos()){ for (EntryInfo info : level.getInfos()) {
if(overridenSet.add(info.getEntry().getName())){ if (overridenSet.add(info.getEntry().getName())) {
info.makeOverridden(false); info.makeOverridden(false);
} else { } else {
info.makeOverridden(true); info.makeOverridden(true);
@ -250,47 +251,47 @@ public class SettingsSet {
} }
} }
public ICLanguageSettingEntry[] getEntries(){ public ICLanguageSettingEntry[] getEntries() {
return getEntries(READ_ONLY | WRITABLE); return getEntries(READ_ONLY | WRITABLE);
} }
public ICLanguageSettingEntry[] getEntries(int types){ public ICLanguageSettingEntry[] getEntries(int types) {
adjustOverrideState(); adjustOverrideState();
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>(); List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
for(SettingLevel sl : fLevels){ for (SettingLevel sl : fLevels) {
if(isCompatible(sl, types)) if (isCompatible(sl, types))
getEntries(sl, entries); getEntries(sl, entries);
} }
return entries.toArray(new ICLanguageSettingEntry[entries.size()]); return entries.toArray(new ICLanguageSettingEntry[entries.size()]);
} }
private void getEntries(SettingLevel level, List<ICLanguageSettingEntry> list){ private void getEntries(SettingLevel level, List<ICLanguageSettingEntry> list) {
for(EntryInfo info : level.getInfos()) for (EntryInfo info : level.getInfos())
if(!info.isOverridden()) if (!info.isOverridden())
list.add(info.getEntry()); list.add(info.getEntry());
} }
private boolean isCompatible(SettingLevel level, int types){ private boolean isCompatible(SettingLevel level, int types) {
if((types & READ_ONLY) == 0 && level.isReadOnly()) if ((types & READ_ONLY) == 0 && level.isReadOnly())
return false; return false;
if((types & WRITABLE) == 0 && !level.isReadOnly()) if ((types & WRITABLE) == 0 && !level.isReadOnly())
return false; return false;
return true; return true;
} }
private int getWritableLevelNum(){ private int getWritableLevelNum() {
for(int i = 0; i <fLevels.length; i++){ for (int i = 0; i <fLevels.length; i++) {
if(!fLevels[i].isReadOnly()) if (!fLevels[i].isReadOnly())
return i; return i;
} }
return -1; return -1;
} }
private int getOverrideLevelNum(){ private int getOverrideLevelNum() {
for(int i = 0; i <fLevels.length; i++){ for (int i = 0; i <fLevels.length; i++) {
if(fLevels[i].isOverrideSupported()) if (fLevels[i].isOverrideSupported())
return i; return i;
} }
@ -298,13 +299,13 @@ public class SettingsSet {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void applyEntries(ICLanguageSettingEntry[] entries){ public void applyEntries(ICLanguageSettingEntry[] entries) {
HashMap<EntryNameKey, Object[]> map = getEntryLevelMap(WRITABLE | READ_ONLY); HashMap<EntryNameKey, Object[]> map = getEntryLevelMap(WRITABLE | READ_ONLY);
Map<EntryNameKey, Object[]> mapCopy = (HashMap<EntryNameKey, Object[]>)map.clone(); Map<EntryNameKey, Object[]> mapCopy = (HashMap<EntryNameKey, Object[]>)map.clone();
Map<EntryNameKey, EntryInfo>[] clearedInfos = new Map [fLevels.length]; Map<EntryNameKey, EntryInfo>[] clearedInfos = new Map [fLevels.length];
for(int i = 0; i < fLevels.length; i++){ for (int i = 0; i < fLevels.length; i++) {
if(!fLevels[i].isReadOnly()) if (!fLevels[i].isReadOnly())
clearedInfos[i] = fLevels[i].clearAndGetMap(); clearedInfos[i] = fLevels[i].clearAndGetMap();
} }
@ -314,13 +315,13 @@ public class SettingsSet {
int writableLevel = getWritableLevelNum(); int writableLevel = getWritableLevelNum();
SettingLevel level; SettingLevel level;
for(int i = 0; i < entries.length; i++){ for (int i = 0; i < entries.length; i++) {
entry = entries[i]; entry = entries[i];
EntryNameKey key = new EntryNameKey(entry); EntryNameKey key = new EntryNameKey(entry);
Object[] o = map.get(key); Object[] o = map.get(key);
if(o != null && valueMatches(entry, o[1])){ if (o != null && valueMatches(entry, o[1])) {
mapCopy.remove(key); mapCopy.remove(key);
levelInteger = (Integer)o[0]; levelInteger = (Integer)o[0];
if (! entry.isBuiltIn()) // allow overwrite existing entry, if (! entry.isBuiltIn()) // allow overwrite existing entry,
@ -330,14 +331,14 @@ public class SettingsSet {
} }
levelNum = levelInteger != null ? levelInteger.intValue() : writableLevel; levelNum = levelInteger != null ? levelInteger.intValue() : writableLevel;
if(levelNum >= 0){ if (levelNum >= 0) {
level = fLevels[levelNum]; level = fLevels[levelNum];
if(!level.isReadOnly()){ if (!level.isReadOnly()) {
Map<EntryNameKey, EntryInfo> clearedInfo = clearedInfos[levelNum]; Map<EntryNameKey, EntryInfo> clearedInfo = clearedInfos[levelNum];
Object customInfo = null; Object customInfo = null;
if(clearedInfo != null){ if (clearedInfo != null) {
EntryInfo info = clearedInfo.get(key); EntryInfo info = clearedInfo.get(key);
if(info != null && entry.equalsByContents(info.getEntry())) if (info != null && entry.equalsByContents(info.getEntry()))
customInfo = info.getCustomInfo(); customInfo = info.getCustomInfo();
} }
level.addEntry(entry, customInfo); level.addEntry(entry, customInfo);
@ -346,15 +347,15 @@ public class SettingsSet {
} }
int overrideLevel = getOverrideLevelNum(); int overrideLevel = getOverrideLevelNum();
if(overrideLevel >= 0){ if (overrideLevel >= 0) {
level = fLevels[overrideLevel]; level = fLevels[overrideLevel];
if(level.isOverrideSupported() && !mapCopy.isEmpty()){ if (level.isOverrideSupported() && !mapCopy.isEmpty()) {
for(EntryNameKey enk : mapCopy.keySet()){ for (EntryNameKey enk : mapCopy.keySet()) {
ICSettingEntry e = enk.getEntry(); ICSettingEntry e = enk.getEntry();
if ((e.getFlags() & ICSettingEntry.BUILTIN) == 0) if ((e.getFlags() & ICSettingEntry.BUILTIN) == 0)
continue; continue;
String str = e.getName(); String str = e.getName();
if(str != null) if (str != null)
level.addOverrideName(str); level.addOverrideName(str);
} }
} }
@ -362,19 +363,19 @@ public class SettingsSet {
adjustOverrideState(); adjustOverrideState();
} }
public HashMap<EntryNameKey, Object[]> getEntryLevelMap(int types){ public HashMap<EntryNameKey, Object[]> getEntryLevelMap(int types) {
HashMap<EntryNameKey, Object[]> map = new HashMap<EntryNameKey, Object[]>(); HashMap<EntryNameKey, Object[]> map = new HashMap<EntryNameKey, Object[]>();
for(int i = 0; i < fLevels.length; i++){ for (int i = 0; i < fLevels.length; i++) {
if(isCompatible(fLevels[i], types)) if (isCompatible(fLevels[i], types))
addLevelInfoToMap(fLevels[i], i, map); addLevelInfoToMap(fLevels[i], i, map);
} }
return map; return map;
} }
private void addLevelInfoToMap(SettingLevel level, int l, Map<EntryNameKey, Object[]> map){ private void addLevelInfoToMap(SettingLevel level, int l, Map<EntryNameKey, Object[]> map) {
for(EntryInfo info : level.getInfos()){ for (EntryInfo info : level.getInfos()) {
EntryNameKey key = info.getContentsKey(); EntryNameKey key = info.getContentsKey();
if(!map.containsKey(key)) if (!map.containsKey(key))
map.put(key, new Object[]{new Integer(l), info.getEntry()}); map.put(key, new Object[]{new Integer(l), info.getEntry()});
} }
} }
@ -385,15 +386,7 @@ public class SettingsSet {
if (!(o instanceof ICMacroEntry)) if (!(o instanceof ICMacroEntry))
return false; // cannot compare different entries return false; // cannot compare different entries
String s1 = e.getValue(); String s1 = e.getValue();
String s2 = ((ICMacroEntry)o).getValue(); String s2 = ((ICMacroEntry) o).getValue();
if (s1 == null && s2 == null) return s1 == null ? s2 == null : s1.equals(s2);
return true;
if (s1 != null)
return s1.equals(s2);
else
return s2.equals(s1);
} }
} }

View file

@ -18,6 +18,7 @@ import java.lang.reflect.Array;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet;
import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.Assert;
@ -28,9 +29,9 @@ public abstract class ArrayUtil {
private static final int DEFAULT_LENGTH = 2; private static final int DEFAULT_LENGTH = 2;
/** /**
* Assumes that array contains nulls at the end, only. * Assumes that array contains {@code null}s at the end, only.
* Appends element after the last non-null element. * Appends element after the last non-{@code null} element.
* If the array is null or not large enough, a larger one is allocated, using * If the array is {@code null} or not large enough, a larger one is allocated, using
* the given class object. * the given class object.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -56,8 +57,8 @@ public abstract class ArrayUtil {
} }
/** /**
* Assumes that array contains nulls at the end, only. * Assumes that array contains {@code null}s at the end, only.
* Appends element after the last non-null element. * Appends element after the last non-{@code null} element.
* If the array is not large enough, a larger one is allocated. * If the array is not large enough, a larger one is allocated.
* Null <code>array</code> is supported for backward compatibility only and only when T is * Null <code>array</code> is supported for backward compatibility only and only when T is
* Object. * Object.
@ -87,8 +88,8 @@ public abstract class ArrayUtil {
} }
/** /**
* Assumes that array contains nulls at the end, only. * Assumes that array contains {@code null}s at the end, only.
* @returns index of first null, or -1 * @returns index of first {@code null}, or -1
*/ */
private static int findFirstNull(Object[] array) { private static int findFirstNull(Object[] array) {
boolean haveNull= false; boolean haveNull= false;
@ -117,7 +118,7 @@ public abstract class ArrayUtil {
} }
/** /**
* Assumes that array contains nulls at the end, only. * Assumes that array contains {@code null}s at the end, only.
* Appends object using the current length of the array. * Appends object using the current length of the array.
* @since 5.1 * @since 5.1
*/ */
@ -145,7 +146,7 @@ public abstract class ArrayUtil {
} }
/** /**
* Assumes that array contains nulls at the end, only. * Assumes that array contains {@code null}s at the end, only.
* Appends object using the current length of the array. * Appends object using the current length of the array.
* @param array The array to append to. Not {@code null} * @param array The array to append to. Not {@code null}
* @param currentLength The number of non-{@code null} elements in the array * @param currentLength The number of non-{@code null} elements in the array
@ -166,12 +167,12 @@ public abstract class ArrayUtil {
} }
/** /**
* Trims the given array and returns a new array with no null entries. * Trims the given array and returns a new array with no {@code null} entries.
* Assumes that nulls can be found at the end, only. * Assumes that {@code null}s can be found at the end, only.
* if array == null, a new array of length 0 is returned * if {@code array} is {@code null}, a new array of length 0 is returned
* if forceNew == true, a new array will always be created. * if {@code forceNew} is {@code true}, a new array will always be created.
* if forceNew == false, a new array will only be created if the original array * if {@code forceNew} is {@code false}, a new array will only be created if the original array
* contained null entries. * contained {@code null} entries.
* *
* @param c the type of the new array * @param c the type of the new array
* @param array the array to be trimmed * @param array the array to be trimmed
@ -202,11 +203,11 @@ public abstract class ArrayUtil {
} }
/** /**
* Trims the given array and returns a new array with no null entries. * Trims the given array and returns a new array with no {@code null} entries.
* Assumes that nulls can be found at the end, only. * Assumes that {@code null}s can be found at the end, only.
* if forceNew == true, a new array will always be created. * if {@code forceNew} is {@code true}, a new array will always be created.
* if forceNew == false, a new array will only be created if the original array * if {@code forceNew} is {@code false}, a new array will only be created if the original array
* contained null entries. * contained {@code null} entries.
* *
* @param array the array to be trimmed * @param array the array to be trimmed
* @param forceNew * @param forceNew
@ -227,8 +228,8 @@ public abstract class ArrayUtil {
} }
/** /**
* Trims the given array and returns a new array with no null entries. * Trims the given array and returns a new array with no {@code null} entries.
* Assumes that nulls can be found at the end, only. * Assumes that {@code null}s can be found at the end, only.
* *
* @param array the array to be trimmed * @param array the array to be trimmed
* @since 5.2 * @since 5.2
@ -257,13 +258,13 @@ public abstract class ArrayUtil {
} }
/** /**
* Takes contents of the two arrays up to the first <code>null</code> element and concatenates * Takes contents of the two arrays up to the first {@code null} element and concatenates
* them. * them.
* @param c The type of the element of the returned array if there was not enough free space * @param c The type of the element of the returned array if there was not enough free space
* in the destination array. * in the destination array.
* @param dest The destination array. The elements of the source array are added to this array * @param dest The destination array. The elements of the source array are added to this array
* if there is enough free space in it. May be <code>null</code>. * if there is enough free space in it. May be {@code null}.
* @param source The source array. May not be <code>null</code>. * @param source The source array. May not be {@code null}.
* @return The concatenated array, which may be the same as the first parameter. * @return The concatenated array, which may be the same as the first parameter.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -300,11 +301,11 @@ public abstract class ArrayUtil {
} }
/** /**
* Takes contents of the two arrays up to the first <code>null</code> element and concatenates * Takes contents of the two arrays up to the first {@code null} element and concatenates them.
* them. *
* @param dest The destination array. The elements of the source array are added to this array * @param dest The destination array. The elements of the source array are added to this array
* if there is enough free space in it. May be <code>null</code>. * if there is enough free space in it. May be {@code null}.
* @param source The source array. May not be <code>null</code>. * @param source The source array. May not be {@code null}.
* @return The concatenated array, which may be the same as the first parameter. * @return The concatenated array, which may be the same as the first parameter.
* @since 5.2 * @since 5.2
*/ */
@ -359,10 +360,11 @@ public abstract class ArrayUtil {
/** /**
* Returns whether the specified array contains the specified object. Comparison is by * Returns whether the specified array contains the specified object. Comparison is by
* object identity. * object identity.
*
* @param array the array to search * @param array the array to search
* @param obj the object to search for * @param obj the object to search for
* @return <code>true</code> if the specified array contains the specified object, or * @return <code>true</code> if the specified array contains the specified object, or
* the specified array is <code>null</code> * the specified array is {@code null}
*/ */
public static <T> boolean contains(T[] array, T obj) { public static <T> boolean contains(T[] array, T obj) {
return indexOf(array, obj) >= 0; return indexOf(array, obj) >= 0;
@ -370,11 +372,12 @@ public abstract class ArrayUtil {
/** /**
* Returns the index into the specified array of the specified object, or -1 if the array does * Returns the index into the specified array of the specified object, or -1 if the array does
* not contain the object, or if the array is null. Comparison is by object identity. * not contain the object, or if the array is {@code null}. Comparison is by object identity.
*
* @param array the array to search * @param array the array to search
* @param obj the object to search for * @param obj the object to search for
* @return the index into the specified array of the specified object, or -1 if the array does * @return the index into the specified array of the specified object, or -1 if the array does
* not contain the object, or if the array is <code>null</code> * not contain the object, or if the array is {@code null}
*/ */
public static <T> int indexOf(T[] array, T obj) { public static <T> int indexOf(T[] array, T obj) {
int result = -1; int result = -1;
@ -388,32 +391,34 @@ public abstract class ArrayUtil {
} }
/** /**
* Assumes that array contains nulls at the end, only. * Assumes that array contains {@code null}s at the end, only.
* Returns whether the specified array contains the specified object. Comparison is by * Returns whether the specified array contains the specified object. Comparison is by
* object identity. * object identity.
*
* @param array the array to search * @param array the array to search
* @param obj the object to search for * @param obj the object to search for
* @return true if the specified array contains the specified object, or the specified array is * @return true if the specified array contains the specified object, or the specified array is
* <code>null</code> * {@code null}
*/ */
public static <T> boolean containsEqual(T[] array, T obj) { public static <T> boolean containsEqual(T[] array, T obj) {
return indexOfEqual(array, obj) != -1; return indexOfEqual(array, obj) != -1;
} }
/** /**
* Assumes that array contains nulls at the end, only. * Assumes that array contains {@code null}s at the end, only.
* Returns the index into the specified array of the specified object, or -1 if the array does * Returns the index into the specified array of the specified object, or -1 if the array does
* not contain the object, or if the array is null. Comparison is by equals(). * not contain the object, or if the array is {@code null}. Comparison is by equals().
* @param comments the array to search *
* @param comment the object to search for * @param array the array to search
* @param obj the object to search for
* @return the index into the specified array of the specified object, or -1 if the array does * @return the index into the specified array of the specified object, or -1 if the array does
* not contain an equal object, or if the array is <code>null</code> * not contain an equal object, or if the array is {@code null}
*/ */
public static <T> int indexOfEqual(T[] comments, T comment) { public static <T> int indexOfEqual(T[] array, T obj) {
int result = -1; int result = -1;
if (comments != null) { if (array != null) {
for (int i= 0; (i < comments.length) && (comments[i] != null); i++) { for (int i= 0; (i < array.length) && (array[i] != null); i++) {
if (comments[i].equals(comment)) if (array[i].equals(obj))
return i; return i;
} }
} }
@ -421,7 +426,9 @@ public abstract class ArrayUtil {
} }
/** /**
* Moves all null elements to the end of the array. The order of non-null elements is preserved. * Moves all {@code null} elements to the end of the array. The order of non-{@code null}
* elements is preserved.
*
* @since 5.4 * @since 5.4
*/ */
public static void compact(Object[] array) { public static void compact(Object[] array) {
@ -438,13 +445,13 @@ public abstract class ArrayUtil {
} }
/** /**
* Removes all of the nulls from the array and returns a new array that contains all * Removes all of the {@code null}s from the array and returns a new array that contains all
* of the non-null elements. * of the non-{@code null} elements.
* *
* If there are no nulls in the original array then the original array is returned. * If there are no {@code null}s in the original array then the original array is returned.
* Note that this method should only be used when the placement of nulls within the array * Note that this method should only be used when the placement of {@code null}s within
* is unknown (due to performance efficiency). * the array is unknown (due to performance efficiency).
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> T[] removeNulls(Class<T> c, T[] array) { public static <T> T[] removeNulls(Class<T> c, T[] array) {
@ -472,13 +479,13 @@ public abstract class ArrayUtil {
} }
/** /**
* Removes all of the nulls from the array and returns a new array that contains all * Removes all of the {@code null}s from the array and returns a new array that contains all
* of the non-null elements. * of the non-{@code null} elements.
* * <p>
* If there are no nulls in the original array then the original array is returned. * If there are no {@code null}s in the original array then the original array is returned.
* * <p>
* Note that this method should only be used when the placement of nulls within the array * Note that this method should only be used when the placement of {@code null}s within
* is unknown (due to performance efficiency). * the array is unknown (due to performance efficiency).
* @since 5.2 * @since 5.2
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -514,11 +521,11 @@ public abstract class ArrayUtil {
/** /**
* To improve performance, this method should be used instead of * To improve performance, this method should be used instead of
* {@link #removeNulls(Class, Object[])} when all of the non-{@code null} elements in * {@link #removeNulls(Class, Object[])} when all of the non-{@code null} elements in
* the array are grouped together at the beginning of the array and all of the nulls are at * the array are grouped together at the beginning of the array and all of the s are at
* the end of the array. The position of the last non-{@code null} element in the array must also * the end of the array. The position of the last non-{@code null} element in the array must
* be known. * also be known.
* <p> * <p>
* If you don't indend to pass {@code null} array, consider using {@link #trim(Object[], int)} * If you don't intend to pass {@code null} array, consider using {@link #trim(Object[], int)}
* instead. * instead.
* *
* @since 5.1 * @since 5.1
@ -536,8 +543,8 @@ public abstract class ArrayUtil {
} }
/** /**
* Inserts the obj at the beginning of the array, shifting the whole thing one index * Inserts the {@code obj} at the beginning of the array, shifting the whole thing one index
* Assumes that array contains nulls at the end, only. * Assumes that array contains {@code null}s at the end, only.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> T[] prepend(Class<T> c, T[] array, T obj) { public static <T> T[] prepend(Class<T> c, T[] array, T obj) {
@ -564,9 +571,9 @@ public abstract class ArrayUtil {
} }
/** /**
* Inserts the obj at the beginning of the array, shifting the whole thing one index * Inserts the {@code obj} at the beginning of the array, shifting the whole thing one index
* Assumes that array contains nulls at the end, only. * Assumes that array contains {@code null}s at the end, only.
* array must not be <code>null</code>. * array must not be {@code null}.
* @since 5.2 * @since 5.2
*/ */
public static <T> T[] prepend(T[] array, T obj) { public static <T> T[] prepend(T[] array, T obj) {
@ -621,7 +628,7 @@ public abstract class ArrayUtil {
* @param target the runtime type of the new array * @param target the runtime type of the new array
* @param source the source array * @param source the source array
* @return the current array stored in a new array with the specified runtime type, * @return the current array stored in a new array with the specified runtime type,
* or null if source is null. * or {@code null} if source is {@code null}.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <S, T> T[] convert(Class<T> target, S[] source) { public static <S, T> T[] convert(Class<T> target, S[] source) {
@ -646,6 +653,7 @@ public abstract class ArrayUtil {
/** /**
* Reverses order of elements in a subsection of an array. * Reverses order of elements in a subsection of an array.
*
* @param array the array * @param array the array
* @param fromIndex the index of the first affected element (inclusive) * @param fromIndex the index of the first affected element (inclusive)
* @param toIndex the index of the last affected element (exclusive) * @param toIndex the index of the last affected element (exclusive)
@ -660,26 +668,60 @@ public abstract class ArrayUtil {
} }
/** /**
* Returns a new array that contains all of the elements of the * Returns a new array that contains all of the elements of the given array except
* given array except the first one. * the first one.
* *
* @throws NullPointerException if {@code array} is {@code null}
* @throws IllegalArgumentException if {@code array} is empty
* @since 5.1 * @since 5.1
* @throws NullPointerException if args is null
* @throws IllegalArgumentException if args.length <= 0
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> T[] removeFirst(T[] args) { public static <T> T[] removeFirst(T[] array) {
int n = args.length; int n = array.length;
if (n <= 0) if (n <= 0)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
T[] newArgs = (T[]) Array.newInstance(args.getClass().getComponentType(), n - 1); T[] newArgs = (T[]) Array.newInstance(array.getClass().getComponentType(), n - 1);
for (int i = 1; i < n; i++) { for (int i = 1; i < n; i++) {
newArgs[i - 1] = args[i]; newArgs[i - 1] = array[i];
} }
return newArgs; return newArgs;
} }
/**
* Returns a new array that contains elements of the given array except duplicates and
* {@code null}s. Duplicates are determined by {@link Object#equals(Object)} method.
*
* @throws NullPointerException if {@code array} is {@code null}
* @since 5.5
*/
public static <T> T[] removeDuplicates(T[] array) {
int k = 0;
if (array.length >= 16) {
HashSet<T> set = new HashSet<T>(array.length);
for (int i = 0; i < array.length; i++) {
T obj = array[i];
if (obj != null && set.add(obj)) {
array[k++] = obj;
}
}
} else {
for (int i = 0; i < array.length; i++) {
T obj = array[i];
if (obj != null) {
array[k++] = obj;
for (int j = i + 1; j < array.length; j++) {
if (obj.equals(array[j]))
array[j] = null;
}
}
}
}
if (k == array.length)
return array;
return Arrays.copyOf(array, k);
}
public static int[] setInt(int[] array, int idx, int val) { public static int[] setInt(int[] array, int idx, int val) {
if (array == null) { if (array == null) {
array = new int[DEFAULT_LENGTH > idx + 1 ? DEFAULT_LENGTH : idx + 1]; array = new int[DEFAULT_LENGTH > idx + 1 ? DEFAULT_LENGTH : idx + 1];

View file

@ -44,7 +44,7 @@ public class CPPFieldSpecialization extends CPPSpecialization implements ICPPFie
@Override @Override
public ICPPClassType getClassOwner() { public ICPPClassType getClassOwner() {
return getField().getClassOwner(); return (ICPPClassType) getOwner();
} }
@Override @Override

View file

@ -3737,6 +3737,7 @@ public class CPPSemantics {
LookupData data = new LookupData(unknownName, null, point); LookupData data = new LookupData(unknownName, null, point);
data.setIgnorePointOfDeclaration(true); data.setIgnorePointOfDeclaration(true);
data.typesOnly= unknown instanceof IType; data.typesOnly= unknown instanceof IType;
data.qualified= true;
try { try {
// 2: Lookup // 2: Lookup

View file

@ -922,7 +922,7 @@ public class TemplateArgumentDeduction {
private boolean fromFunctionType(ICPPFunctionType ftp, ICPPFunctionType fta, IASTNode point) private boolean fromFunctionType(ICPPFunctionType ftp, ICPPFunctionType fta, IASTNode point)
throws DOMException { throws DOMException {
if (ftp.isConst() != fta.isConst() || ftp.isVolatile() != fta.isVolatile()) if (ftp.isConst() != fta.isConst() || ftp.isVolatile() != fta.isVolatile() || ftp.takesVarArgs() != fta.takesVarArgs())
return false; return false;
if (!fromType(ftp.getReturnType(), fta.getReturnType(), false, point)) if (!fromType(ftp.getReturnType(), fta.getReturnType(), false, point))

View file

@ -176,8 +176,8 @@ public class BTree {
} else if (compare < 0) { } else if (compare < 0) {
lower= middle + 1; lower= middle + 1;
} else { } else {
// Found it, no insert, just return the record. // Found it, no insert, just return the matched record.
return record; return checkRec;
} }
} }
} }

View file

@ -10,6 +10,9 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.cdtvariables; package org.eclipse.cdt.internal.core.cdtvariables;
/**
* Listener to listen to Build Variables changes events.
*/
public interface ICdtVariableChangeListener { public interface ICdtVariableChangeListener {
void variablesChanged(VariableChangeEvent event); void variablesChanged(VariableChangeEvent event);
} }

View file

@ -651,10 +651,20 @@ public class UserDefinedVariableSupplier extends CoreMacroSupplierBase {
// protected void updateProjectInfo(int type, Object context){ // protected void updateProjectInfo(int type, Object context){
// } // }
/**
* Adds a listener that will be notified of changes in Build Variables.
*
* @param listener - the listener to add
*/
public void addListener(ICdtVariableChangeListener listener){ public void addListener(ICdtVariableChangeListener listener){
fListeners.add(listener); fListeners.add(listener);
} }
/**
* Removes a Build Variables change listener.
*
* @param listener - the listener to remove.
*/
public void removeListener(ICdtVariableChangeListener listener){ public void removeListener(ICdtVariableChangeListener listener){
fListeners.remove(listener); fListeners.remove(listener);
} }

View file

@ -12,6 +12,9 @@ package org.eclipse.cdt.internal.core.cdtvariables;
import org.eclipse.cdt.core.cdtvariables.ICdtVariable; import org.eclipse.cdt.core.cdtvariables.ICdtVariable;
/**
* Event describing Build Variables changes.
*/
public class VariableChangeEvent { public class VariableChangeEvent {
private static final ICdtVariable[] EMPTY_VAR_ARRAY = new ICdtVariable[0]; private static final ICdtVariable[] EMPTY_VAR_ARRAY = new ICdtVariable[0];

View file

@ -788,4 +788,37 @@ public class ImplementMethodRefactoringTest extends RefactoringTestBase {
public void testExplicitConstructor_Bug363111() throws Exception { public void testExplicitConstructor_Bug363111() throws Exception {
assertRefactoringSuccess(); assertRefactoringSuccess();
} }
//A.h
//
//class TestClass {
//public:
// /*$*/void foo() throw ();/*$$*/
//};
//
//A.cpp
//====================
//void TestClass::foo() throw () {
//}
public void testEmptyThowsClause_Bug393833() throws Exception {
assertRefactoringSuccess();
}
//A.h
//
//class TestClass {
//public:
// /*$*/void foo() throw (TestClass);/*$$*/
//};
//
//A.cpp
//====================
//void TestClass::foo() throw (TestClass) {
//}
public void testNonEmptyThowsClause_Bug393833() throws Exception {
assertRefactoringSuccess();
}
} }

View file

@ -24,44 +24,70 @@ import org.eclipse.ltk.core.refactoring.RefactoringStatus;
*/ */
public class RenameTemplatesTests extends RenameTests { public class RenameTemplatesTests extends RenameTests {
public RenameTemplatesTests(String name) { public RenameTemplatesTests(String name) {
super(name); super(name);
} }
public static Test suite(){ public static Test suite() {
return suite(true); return suite(true);
} }
public static Test suite( boolean cleanup ) { public static Test suite(boolean cleanup) {
TestSuite suite = new TestSuite(RenameTemplatesTests.class); TestSuite suite = new TestSuite(RenameTemplatesTests.class);
if (cleanup) { if (cleanup) {
suite.addTest( new RefactoringTests("cleanupProject") ); //$NON-NLS-1$ suite.addTest(new RefactoringTests("cleanupProject"));
} }
return suite; return suite;
} }
public void testClassTemplate() throws Exception { public void testClassTemplate() throws Exception {
StringWriter writer = new StringWriter(); StringWriter writer = new StringWriter();
writer.write("template <class Type> \n"); //$NON-NLS-1$ writer.write("template <class Type> \n");
writer.write("class Array { \n"); //$NON-NLS-1$ writer.write("class Array { \n");
writer.write("public: \n"); //$NON-NLS-1$ writer.write("public: \n");
writer.write(" Array(unsigned sz) {} \n"); //$NON-NLS-1$ writer.write(" Array(unsigned sz) {} \n");
writer.write(" ~Array(){} \n"); //$NON-NLS-1$ writer.write(" ~Array(){} \n");
writer.write(" Type& operator[] (unsigned idx); \n"); //$NON-NLS-1$ writer.write(" Type& operator[] (unsigned idx); \n");
writer.write("}; \n"); //$NON-NLS-1$ writer.write("}; \n");
writer.write("template <class Type> \n"); //$NON-NLS-1$ writer.write("template <class Type> \n");
writer.write("inline Type& Array<Type>::operator[] (unsigned index) {\n"); //$NON-NLS-1$ writer.write("inline Type& Array<Type>::operator[] (unsigned index) {\n");
writer.write(" return 1; \n"); //$NON-NLS-1$ writer.write(" return 1; \n");
writer.write("}; \n"); //$NON-NLS-1$ writer.write("}; \n");
String contents = writer.toString(); String contents = writer.toString();
IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ IFile cpp = importFile("test.cpp", contents);
int offset1= contents.indexOf("Array"); //$NON-NLS-1$ int offset1 = contents.indexOf("Array");
RefactoringStatus stat= checkConditions(cpp, offset1, "WELT"); //$NON-NLS-1$ RefactoringStatus stat = checkConditions(cpp, offset1, "WELT");
assertRefactoringOk(stat); assertRefactoringOk(stat);
Change ch= getRefactorChanges(cpp, offset1, "WELT"); //$NON-NLS-1$ Change ch = getRefactorChanges(cpp, offset1, "WELT");
assertTotalChanges(4, ch); assertTotalChanges(4, ch);
} }
public void _testRenameSpecializations_bug240692() throws Exception {
StringWriter writer = new StringWriter();
writer.write("template <class T>\n");
writer.write("class CSome {\n");
writer.write("public:\n");
writer.write(" void Foo() {};\n");
writer.write("};\n");
writer.write("int main ()\n");
writer.write("{\n");
writer.write(" CSome <int> A;\n");
writer.write(" A.Foo();\n");
writer.write(" return 0;\n");
writer.write("}\n");
String contents = writer.toString();
IFile cpp = importFile("test.cpp", contents);
int offset1 = contents.indexOf("Foo");
RefactoringStatus stat = checkConditions(cpp, offset1, "Baz");
assertRefactoringOk(stat);
assertTotalChanges(2, getRefactorChanges(cpp, offset1, "Baz"));
}
} }

View file

@ -38,6 +38,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle; import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
@ -266,7 +267,13 @@ public class ImplementMethodRefactoring extends CRefactoring {
for (IASTPointerOperator pop : functionDeclarator.getPointerOperators()) { for (IASTPointerOperator pop : functionDeclarator.getPointerOperators()) {
createdMethodDeclarator.addPointerOperator(pop.copy(CopyStyle.withLocations)); createdMethodDeclarator.addPointerOperator(pop.copy(CopyStyle.withLocations));
} }
IASTTypeId[] exceptionSpecification = functionDeclarator.getExceptionSpecification();
if (exceptionSpecification != ICPPASTFunctionDeclarator.NO_EXCEPTION_SPECIFICATION) {
createdMethodDeclarator.setEmptyExceptionSpecification();
for (IASTTypeId typeId : exceptionSpecification) {
createdMethodDeclarator.addExceptionSpecificationTypeId(typeId == null ? null : typeId.copy(CopyStyle.withLocations));
}
}
IASTFunctionDefinition functionDefinition = nodeFactory.newFunctionDefinition(declSpecifier, createdMethodDeclarator, nodeFactory.newCompoundStatement()); IASTFunctionDefinition functionDefinition = nodeFactory.newFunctionDefinition(declSpecifier, createdMethodDeclarator, nodeFactory.newCompoundStatement());
functionDefinition.setParent(unit); functionDefinition.setParent(unit);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View file

@ -12,9 +12,9 @@
<div role="main"><h1>C/C++ Menubar</h1> <div role="main"><h1>C/C++ Menubar</h1>
<p>This section describes the menubar options available from the C/C++ perspective.</p> <p>This section describes the menubar options available from the C/C++ perspective.</p>
<p><img src="../images/cdt_menubar.png" <p><img src="../images/cdt_menubar.png"
alt="CDT main menu"> alt="C/C++ perspective main menu">
</p> </p>
<img src="../images/trans.gif" width="25" height="1" alt=""> <img src="../images/trans.gif" width="25" height="1" alt="">
<a style="text-decoration:none" href="cdt_u_m_file.htm">File Menu actions</a><br> <a style="text-decoration:none" href="cdt_u_m_file.htm">File Menu actions</a><br>
<img src="../images/trans.gif" width="25" height="1" alt=""> <img src="../images/trans.gif" width="25" height="1" alt="">
<a style="text-decoration:none" href="cdt_u_m_edit.htm">Edit Menu actions</a><br> <a style="text-decoration:none" href="cdt_u_m_edit.htm">Edit Menu actions</a><br>
@ -32,6 +32,8 @@ alt="CDT main menu">
<a style="text-decoration:none" href="cdt_u_m_run.htm">Run Menu actions</a><br> <a style="text-decoration:none" href="cdt_u_m_run.htm">Run Menu actions</a><br>
<img src="../images/trans.gif" width="25" height="1" alt=""> <img src="../images/trans.gif" width="25" height="1" alt="">
<a style="text-decoration:none" href="cdt_u_m_window.htm">Window Menu actions</a><br> <a style="text-decoration:none" href="cdt_u_m_window.htm">Window Menu actions</a><br>
<img src="../images/trans.gif" width="25" height="1" alt="">
<a style="text-decoration:none" href="PLUGINS_ROOT/org.eclipse.platform.doc.user/reference/ref-61.htm">Help Menu actions</a> (from Workbench User Guide)<br>
<p><img src="../images/ng00_04a.gif" ALT="IBM Copyright Statement" > <p><img src="../images/ng00_04a.gif" ALT="IBM Copyright Statement" >
</p> </p>
</div></body> </div></body>

View file

@ -1,122 +1,234 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en"> <html lang="en">
<head> <head>
<meta http-equiv="Content-Language" content="en-us"> <meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Window Menu actions</title> <title>Window Menu actions</title>
<link rel="stylesheet" type="text/css" href="../help.css"> <link rel="stylesheet" type="text/css" href="../help.css">
</head> </head>
<body> <body>
<div role="main"><h1>Window Menu actions</h1> <div role="main">
<h1>Window Menu actions</h1>
<p>
<img src="../images/cdt_menu_window.png" alt="Selecting Window Menu">
</p>
<table class="menu" border="1" cellspacing="0" cellpadding="3">
<thead>
<tr>
<th id="name">Name</th>
<th id="function">Function</th>
<th id="keyboard">Keyboard Shortcut</th>
</tr>
</thead>
<tbody>
<tr>
<td class="menu_name" headers="name">New Window</td>
<td headers="function">Opens a new Workbench window</td>
<td headers="keyboard">&nbsp;</td>
</tr>
<p><img src="../images/cdt_menu_window.png" alt="Window Menu" ></p> <tr>
<p> <td class="menu_name" headers="name">New Editor</td>
<table class="menu" border="1" cellspacing="0" cellpadding="3"> <td headers="function">Opens a new copy of the active editor</td>
<tr><th id="name">Name</th><th id="function">Function</th><th id="keyboard">Keyboard Shortcut</th></tr> <td headers="keyboard">&nbsp;</td>
</tr>
<tr> <tr>
<td class="menu_name" headers="name">New Window</td> <td class="menu_name" headers="name">Open Perspective
<td headers="function">Opens new Window </td> (submenu)</td>
<td headers="keyboard">&nbsp;</td> <td headers="function">Opens a new perspective (The contents
</tr> and order of entries in the submenu are dependent on the current
perspective. The <strong>Other...</strong> entry allows you to
open any perspective.)
</td>
<td headers="keyboard">&nbsp;</td>
</tr>
<tr>
<td class="menu_name" headers="name">Show View (submenu)</td>
<td headers="function">Displays a view in the current
perspective (The contents and order of entries in the submenu are
dependent on the current perspective. The <strong>Other...</strong>
entry allows you to open any view.)
</td>
<td headers="keyboard">&nbsp;</td>
</tr>
<tr> <tr>
<td class="menu_name" headers="name">New Editor</td> <td class="menu_name" headers="name">Customize Perspective...</td>
<td headers="function">This command opens a new empty editor in this Workbench window. </td> <td headers="function">Alters the visibility of various
<td headers="keyboard">&nbsp;</td> elements of the current perspective</td>
</tr> <td headers="keyboard">&nbsp;</td>
</tr>
<tr> <tr>
<td class="menu_name" headers="name">Open Perspective</td> <td class="menu_name" headers="name">Save Perspective As...</td>
<td headers="function">This command opens a new perspective in this Workbench window. <td headers="function">Saves the current perspective under a
This preference can be changed in the <strong>Window &gt; Preferences &gt; Workbench &gt; Perspectives</strong> page. new name (It can then be accessed through the <strong>Open
All of the perspectives that are open within the Workbench window are shown on the shortcut bar. Perspective &gt; Other...</strong> dialog.)
The perspectives you will likely want to open are listed first.This list is dependent on the current perspective. </td>
From the <strong>Other...</strong> submenu you can open any perspective.</td> <td headers="keyboard">&nbsp;</td>
<td headers="keyboard">&nbsp;</td> </tr>
</tr>
<tr>
<td class="menu_name" headers="name">Show View</td>
<td headers="function">This command displays the selected view in the current perspective.
You can configure how views are opened in the <strong>Window &gt; Preferences &gt; Workbench &gt; Perspectives page</strong>.
Views you are likely to want to open are listed first.This list is dependent on the current perspective.
From the <strong>Other...</strong> submenu you can open any view.
The views are sorted into categories in the Show View dialog.</td>
<td headers="keyboard">&nbsp;</td>
</tr>
<tr> <tr>
<td class="menu_name" headers="name">Customize Perspective</td> <td class="menu_name" headers="name">Reset Perspective</td>
<td headers="function">Each perspective includes a predefined set of actions that are accessible from the menu bar and Workbench toolbar. <td headers="function">Removes any customizations created by <strong>Customize
Related actions are grouped into action sets. Perspective...</strong>
This command allows you to customize the current perspective by showing or hiding various action sets. </td>
The first three (<strong>File &gt; New</strong>, <strong>Window &gt; Open Perspective</strong>, <strong>Window &gt; Show View</strong>) control which actions appear as top level items in their respective menus. <td headers="keyboard">&nbsp;</td>
The last category (<strong>Other</strong>) controls which action sets are visible in the perspective.</td> </tr>
<td headers="keyboard">&nbsp;</td>
</tr>
<tr> <tr>
<td class="menu_name" headers="name">Save Perspective As</td> <td class="menu_name" headers="name">Close Perspective</td>
<td headers="function">This command allows you to save the current perspective, creating your own custom perspective. <td headers="function">Closes the active perspective</td>
You can open more perspectives of this type using the <strong>Window &gt; Open Perspective &gt; Other</strong> menu item once you have saved a perspective.</td> <td headers="keyboard">&nbsp;</td>
<td headers="keyboard">&nbsp;</td> </tr>
</tr>
<tr> <tr>
<td class="menu_name" headers="name">Reset Perspective</td> <td class="menu_name" headers="name">Close All Perspectives</td>
<td headers="function">This command changes the layout of the current perspective to its original configuration.</td> <td headers="function">Closes all the open perspectives, which
<td headers="keyboard">&nbsp;</td> also closes all the Editors and Views</td>
</tr> <td headers="keyboard">&nbsp;</td>
</tr>
<tr> <tr>
<td class="menu_name" headers="name">Close Perspective</td> <td rowspan="13" class="menu_name" headers="name">Navigation</td>
<td headers="function">This command closes the active perspective.</td> <td headers="function">Navigates between views, perspectives,
<td headers="keyboard">&nbsp;</td> and editors in the following ways:
</tr> <td headers="keyboard">&nbsp;</td>
</tr>
<tr>
<td headers="function">
<dl>
<dt>Show System Menu</dt>
<dd>Displays the menu that is used for closing the current
view or editor</dd>
</dl>
</td>
<td headers="keyboard">Alt+(hyphen)</td>
</tr>
<tr>
<td headers="function">
<dl>
<dt>Show View Menu</dt>
<dd>Displays the drop-down menu accessible from the triangle
button in the current view's toolbar</dd>
</dl>
</td>
<td headers="keyboard">Ctrl-F10</td>
</tr>
<tr>
<td headers="function">
<dl>
<dt>Maximize Active View or Editor</dt>
<dd>Maximizes the current view or editor to fill the window</dd>
</dl>
</td>
<td headers="keyboard">Ctrl+M</td>
</tr>
<tr>
<td headers="function">
<dl>
<dt>Minimize Active View or Editor</dt>
<dd>Minimizes the current view or editor down to an icon on
the side of the window</dd>
</dl>
</td>
<td headers="keyboard">&nbsp;</td>
</tr>
<tr>
<td headers="function">
<dl>
<dt>Activate Editor</dt>
<dd>Switches from the current view to the current editor</dd>
</dl>
</td>
<td headers="keyboard">F12</td>
</tr>
<tr> <tr>
<td class="menu_name" headers="name">Close All Perspectives</td> <td headers="function">
<td headers="function">This command closes all open perspectives in the Workbench window.</td> <dl>
<td headers="keyboard">&nbsp;</td> <dt>Next Editor</dt>
</tr> <dd>Activates the most-recently-used editor (If held down,
displays the list of open editors, ordered by time.)</dd>
<tr> </dl>
<td class="menu_name" headers="name">Navigation</td> </td>
<td headers="function">This submenu contains shortcut keys for navigating between the views, perspectives, and editors in the Workbench window. <td headers="keyboard">Ctrl+F6</td>
<ul> </tr>
<li><strong>Show System Menu</strong>: Shows the menu that is used for resizing, closing or pinning the current view or editor.</li> <tr>
<li><strong>Show View Menu</strong>: Shows the drop down menu that is available in the toolbar of the active view.</li> <td headers="function">
<li><strong>Maximize Active View or Editor</strong>: Maximizes the current view or editor to fill the workbench.</li> <dl>
<li><strong>Activate Editor</strong>: Makes the current editor active.</li> <dt>Previous Editor</dt>
<li><strong>Next Editor</strong>: Activates the next open editor in the list of most recently used editors.</li> <dd>Activates least-recently-used editor (If held down,
<li><strong>Previous Editor</strong>: Activates the previous open editor in the list of most recently used editors.</li> displays the list of open editors, ordered by time.)</dd>
<li><strong>Next View</strong>: Activates the next open view in the list of most recently used views.</li> </dl>
<li><strong>Previous View</strong>: Activates the previous open view in the list of most recently used views.</li> </td>
<li><strong>Next Perspective</strong>: Activates the next open perspective in the list of most recently used perspectives.</li> <td headers="keyboard">Ctrl+Shift+F6</td>
<li><strong>Previous Perspective</strong>: Activates the previous open perspective in the list of most recently used perspectives.</li> </tr>
</ul> <tr>
<td headers="keyboard">&nbsp;</td> <td headers="function">
</tr> <dl>
<dt>Switch to Editor...</dt>
<tr> <dd>Displays a dialog that allows multiple editors to be
<td class="menu_name" headers="name">Working sets</td> saved or closed</dd>
<td headers="function">Dialog displayed to edit working sets</td> </dl>
<td headers="keyboard">&nbsp;</td> </td>
</tr> <td headers="keyboard">Ctrl+Shift+E</td>
</tr>
<tr> <tr>
<td class="menu_name" headers="name">Preferences</td> <td headers="function">
<td headers="function">This command allows you to indicate your preferences for using the Workbench. <dl>
There are a wide variety of preferences for configuring the appearance of the Workbench and its views, and for customizing the behavior of all tools that are installed in the Workbench. <dt>Next View</dt>
See the <a href="cdt_u_c_pref.htm">C/C++ Page Preference Window</a> section for more details on the CDT preferences.</td> <dd>Activates the most-recently-used view (If held down,
<td headers="keyboard">&nbsp;</td> displays the list of open views, ordered by time.)</dd>
</tr> </dl>
</table><p></p> </td>
<td headers="keyboard">Ctrl+F7</td>
<p> </tr>
<img src="../images/ng00_04a.gif" ALT="IBM Copyright Statement" > <tr>
</p> <td headers="function">
<dl>
</BODY> <dt>Previous View</dt>
</HTML> <dd>Activates least-recently-used view (If held down,
displays the list of open views, ordered by time.)</dd>
</dl>
</td>
<td headers="keyboard">Ctrl+Shift+F7</td>
</tr>
<tr>
<td headers="function">
<dl>
<dt>Next Perspective</dt>
<dd>Activates the most-recently-used perspective (If held
down, displays the list of open perspectives, ordered by time.)</dd>
</dl>
</td>
<td headers="keyboard">Ctrl+F8</td>
</tr>
<tr>
<td headers="function">
<dl>
<dt>Previous Perspective</dt>
<dd>Activates least-recently-used perspective (If held down,
displays the list of open perspective, ordered by time.)</dd>
</dl>
</td>
<td headers="keyboard">Ctrl+Shift+F8</td>
</tr>
<tr>
<td class="menu_name" headers="name">Preferences</td>
<td headers="function">Opens the Preferences dialog, where
workspace-wide preferences can be set (The <a
href="cdt_u_c_pref.htm">C/C++ Page Preference Window</a> section
documents the C/C++-specific preferences.)
</td>
<td headers="keyboard">&nbsp;</td>
</tr>
</tbody>
</table>
<p>
<img alt="IBM Copyright Statement" src="../images/ng00_04a.gif">
</p>
</div>
</body>
</html>