diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/BuiltinSpecsDetectorTest.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/BuiltinSpecsDetectorTest.java index c10adce4907..27e40a598f2 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/BuiltinSpecsDetectorTest.java +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/BuiltinSpecsDetectorTest.java @@ -225,6 +225,7 @@ public class BuiltinSpecsDetectorTest extends BaseTestCase { provider.execute(); assertEquals(true, provider.isExecuted()); + assertEquals(null, provider.getSettingEntries(null, null, null)); } } @@ -307,7 +308,9 @@ public class BuiltinSpecsDetectorTest extends BaseTestCase { // check entries { MockDetectorCloneable clone = provider.clone(); - clone.setSettingEntries(null, null, null, null); + List entries2 = new ArrayList(); + entries2.add(new CMacroEntry("MACRO2", "VALUE2", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY)); + clone.setSettingEntries(null, null, null, entries2); assertFalse(provider.equals(clone)); } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/envvar/EnvironmentVariableManagerToolChain.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/envvar/EnvironmentVariableManagerToolChain.java index 451b6918fbb..e5d52a004fb 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/envvar/EnvironmentVariableManagerToolChain.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/envvar/EnvironmentVariableManagerToolChain.java @@ -12,11 +12,13 @@ package org.eclipse.cdt.managedbuilder.internal.envvar; import org.eclipse.cdt.core.cdtvariables.ICdtVariable; 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.ICoreVariableContextInfo; import org.eclipse.cdt.internal.core.envvar.EnvironmentVariableManager; import org.eclipse.cdt.internal.core.envvar.ICoreEnvironmentVariableSupplier; 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.ManagedBuildManager; 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 * 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. */ public class EnvironmentVariableManagerToolChain extends EnvironmentVariableManager { private final IToolChain toolChain; + private final ICConfigurationDescription cfgDescription; public EnvironmentVariableManagerToolChain(IToolChain 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 public IEnvironmentContextInfo getContextInfo(Object level) { + if (cfgDescription != null) { + // Use regular EnvironmentVariableManager when configuration is available + return super.getContextInfo(level); + } + return new ToolChainEnvironmentContextInfo(toolChain); } @@ -162,7 +172,15 @@ public class EnvironmentVariableManagerToolChain extends EnvironmentVariableMana */ @Override public ICoreVariableContextInfo getMacroContextInfoForContext(Object context) { + if (cfgDescription != null) { + // Use regular EnvironmentVariableManager when configuration is available + return super.getMacroContextInfoForContext(context); + } + return new ToolChainCoreVariableContextInfo(toolChain); } + public IEnvironmentVariable getVariable(String variableName, boolean resolveMacros) { + return getVariable(variableName, cfgDescription, resolveMacros); + } } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/GCCBuiltinSpecsDetectorCygwin.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/GCCBuiltinSpecsDetectorCygwin.java index 715d2f26964..d2a4b86ed7b 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/GCCBuiltinSpecsDetectorCygwin.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/GCCBuiltinSpecsDetectorCygwin.java @@ -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 * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -12,10 +12,11 @@ package org.eclipse.cdt.managedbuilder.internal.language.settings.providers; 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.core.resources.IResource; /** * 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 { // 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 ENV_PATH = "PATH"; //$NON-NLS-1$ - private static final URI CYGWIN_ROOT; - static { - try { - CYGWIN_ROOT = new URI("cygwin:/"); //$NON-NLS-1$ - } catch (URISyntaxException e) { - // hey we know this URI works - throw new IllegalStateException(e); + /** + * EFSExtensionProvider for Cygwin translations + */ + private class CygwinEFSExtensionProvider extends EFSExtensionProvider { + private String envPathValue; + + /** + * 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 - protected URI getMappedRootURI(IResource sourceFile, String parsedResourceName) { - if (mappedRootURI == null) { - mappedRootURI = super.getMappedRootURI(sourceFile, parsedResourceName); - 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; + protected EFSExtensionProvider getEFSProvider() { + String envPathValue = environmentMap != null ? environmentMap.get(ENV_PATH) : null; + return new CygwinEFSExtensionProvider(envPathValue); } @Override diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java index 7bf95aca69b..b67eb9c7a56 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java @@ -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 * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -17,8 +17,11 @@ import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import java.util.Set; 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.internal.core.ManagedMakeMessages; import org.eclipse.cdt.utils.CommandLineUtil; -import org.eclipse.cdt.utils.envvar.EnvironmentCollector; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; 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_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_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 TICKS_REMOVE_MARKERS = 1 * MONITOR_SCALE; @@ -112,9 +116,15 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti protected URI buildDirURI = null; protected java.io.File specFile = null; protected boolean preserveSpecFile = false; + /** @since 8.2 */ + protected IEnvironmentVariableManager envMngr = null; + /** @since 8.2 */ + protected volatile Map environmentMap = null; + protected List detectedSettingEntries = null; protected int collected = 0; - protected boolean isExecuted = false; + protected volatile boolean isExecuted = false; + private int envPathHash = 0; private BuildRunnerHelper buildRunnerHelper; private SDMarkerGenerator markerGenerator = new SDMarkerGenerator(); @@ -348,6 +358,7 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti mappedRootURI = null; buildDirURI = getBuildDirURI(mappedRootURI); + environmentMap = createEnvironmentMap(currentCfgDescription); } @Override @@ -358,18 +369,46 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti super.shutdown(); } + /** + * This method does 2 related things: + *
+ * 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. + *
+ * 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. * The parser will parse output and generate language settings for corresponding resources. */ protected void execute() { - if (isExecuted) { + environmentMap = createEnvironmentMap(currentCfgDescription); + if (validateEnvironment() && isExecuted) { return; } WorkspaceJob job = new WorkspaceJob(ManagedMakeMessages.getResourceString("AbstractBuiltinSpecsDetector.DiscoverBuiltInSettingsJobName")) { //$NON-NLS-1$ @Override public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException { + isExecuted = false; + if (!isEmpty()) { + clear(); + serializeLanguageSettings(currentCfgDescription); + } IStatus status; try { 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 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 */ protected List getEnvironmentVariables() { - IEnvironmentVariableManager mngr = CCorePlugin.getDefault().getBuildEnvironmentManager(); - List vars = new ArrayList(Arrays.asList(mngr.getVariables(currentCfgDescription, true))); + if (envMngr == null) { + envMngr = CCorePlugin.getDefault().getBuildEnvironmentManager(); + } + List vars = new ArrayList(Arrays.asList(envMngr.getVariables(currentCfgDescription, true))); // On POSIX (Linux, UNIX) systems reset language variables to default (English) // 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() { - EnvironmentCollector collector = new EnvironmentCollector(); - List vars = getEnvironmentVariables(); - collector.addVariables(vars.toArray(new IEnvironmentVariable[vars.size()])); + private Map createEnvironmentMap(ICConfigurationDescription cfgDescription) { + Map envMap = new HashMap(); + for (IEnvironmentVariable var : getEnvironmentVariables()) { + envMap.put(var.getName(), var.getValue()); + } + return envMap; + } + /** + * Convert map of environment variables to array in format "var=value". + */ + private String[] toEnvp(Map environmentMap) { Set envp = new HashSet(); - for (IEnvironmentVariable var : collector.getVariables()) { - envp.add(var.getName() + '=' + var.getValue()); + for (Entry var: environmentMap.entrySet()) { + envp.add(var.getKey() + '=' + var.getValue()); } return envp.toArray(new String[envp.size()]); } @@ -736,6 +784,9 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti public Element serializeAttributes(Element parentElement) { Element elementProvider = super.serializeAttributes(parentElement); elementProvider.setAttribute(ATTR_CONSOLE, Boolean.toString(isConsoleEnabled)); + if (envPathHash != 0) { + elementProvider.setAttribute(ATTR_ENV_HASH, Integer.toString(envPathHash)); + } return elementProvider; } @@ -747,6 +798,16 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti if (consoleValue != null) { 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 @@ -774,6 +835,9 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti protected AbstractBuiltinSpecsDetector cloneShallow() throws CloneNotSupportedException { AbstractBuiltinSpecsDetector clone = (AbstractBuiltinSpecsDetector) super.cloneShallow(); clone.isExecuted = false; + clone.envMngr = null; + clone.environmentMap = null; + clone.envPathHash = 0; return clone; } @@ -783,6 +847,7 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti int result = super.hashCode(); result = prime * result + (isConsoleEnabled ? 1231 : 1237); result = prime * result + (isExecuted ? 1231 : 1237); + result = prime * result + envPathHash; return result; } @@ -792,13 +857,15 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti return true; if (!super.equals(obj)) return false; - if (!(obj instanceof AbstractBuiltinSpecsDetector)) + if (getClass() != obj.getClass()) return false; AbstractBuiltinSpecsDetector other = (AbstractBuiltinSpecsDetector) obj; if (isConsoleEnabled != other.isConsoleEnabled) return false; if (isExecuted != other.isExecuted) return false; + if (envPathHash != other.envPathHash) + return false; return true; } } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractLanguageSettingsOutputScanner.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractLanguageSettingsOutputScanner.java index 9d8d5347644..f11ec08a8ea 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractLanguageSettingsOutputScanner.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractLanguageSettingsOutputScanner.java @@ -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 * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -25,6 +25,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.EFSExtensionProvider; import org.eclipse.cdt.core.ErrorParserManager; import org.eclipse.cdt.core.cdtvariables.CdtVariableException; import org.eclipse.cdt.core.cdtvariables.ICdtVariableManager; @@ -80,6 +81,37 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett protected String parsedResourceName = null; 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. * 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.currentProject = cfgDescription != null ? cfgDescription.getProjectDescription().getProject() : null; this.cwdTracker = cwdTracker; + this.efsProvider = getEFSProvider(); } @Override @@ -429,7 +462,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett if (isResolvingPaths && (optionParser.isForFile() || optionParser.isForFolder())) { URI baseURI = mappedRootURI; 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); } 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 - URI uri = EFSExtensionManager.getDefault().createNewURIFromPath(resourceURI, mappedRoot); + URI uri = efsProvider.createNewURIFromPath(resourceURI, mappedRoot); return uri; } @@ -513,9 +546,9 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett if (currentResource != null && parsedResourceName != null && !new Path(parsedResourceName).isAbsolute()) { 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) { - buildDirURI = EFSExtensionManager.getDefault().append(mappedRootURI, cwdPath); + buildDirURI = efsProvider.append(mappedRootURI, cwdPath); } else { buildDirURI = cwdURI; } @@ -674,7 +707,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett if (sourceFile == null && cwdTracker != null) { URI cwdURI = cwdTracker.getWorkingDirectoryURI(); if (cwdURI != null) { - URI uri = EFSExtensionManager.getDefault().append(cwdURI, parsedResourceName); + URI uri = efsProvider.append(cwdURI, parsedResourceName); 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 * @return {@link URI} of the resource */ - private static URI determineMappedURI(String pathStr, URI baseURI) { + private URI determineMappedURI(String pathStr, URI baseURI) { URI uri = null; if (baseURI == null) { @@ -819,9 +852,9 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett } else { // location on a remote file-system 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) { - String localPath = EFSExtensionManager.getDefault().getMappedPath(remoteUri); + String localPath = efsProvider.getMappedPath(remoteUri); if (localPath != null) { 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) return null; - String pathStr = EFSExtensionManager.getDefault().getMappedPath(uri); + String pathStr = efsProvider.getMappedPath(uri); uri = org.eclipse.core.filesystem.URIUtil.toURI(pathStr); if (uri != null && uri.isAbsolute()) { @@ -1065,6 +1098,20 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett 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 public Element serializeAttributes(Element parentElement) { diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/ToolchainBuiltinSpecsDetector.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/ToolchainBuiltinSpecsDetector.java index 8d4d6b7cb1a..2a2322d3aa7 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/ToolchainBuiltinSpecsDetector.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/ToolchainBuiltinSpecsDetector.java @@ -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 * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -11,22 +11,17 @@ package org.eclipse.cdt.managedbuilder.language.settings.providers; -import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; 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.ITool; import org.eclipse.cdt.managedbuilder.core.IToolChain; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; -import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable; -import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier; -import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider; +import org.eclipse.cdt.managedbuilder.internal.envvar.EnvironmentVariableManagerToolChain; /** * Abstract parser capable to execute compiler command printing built-in compiler @@ -120,19 +115,12 @@ public abstract class ToolchainBuiltinSpecsDetector extends AbstractBuiltinSpecs @Override protected List getEnvironmentVariables() { - List vars = new ArrayList(super.getEnvironmentVariables()); - - String toolchainId = getToolchainId(); - for (IToolChain toolchain = ManagedBuildManager.getExtensionToolChain(toolchainId); toolchain != null; toolchain = toolchain.getSuperClass()) { - 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; - } + if (envMngr == null && currentCfgDescription == null) { + // For global provider need to include toolchain in the equation + IToolChain toolchain = ManagedBuildManager.getExtensionToolChain(getToolchainId()); + envMngr = new EnvironmentVariableManagerToolChain(toolchain); } + List vars = super.getEnvironmentVariables(); return vars; } diff --git a/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/IsGnuCygwinToolChainSupported.java b/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/IsGnuCygwinToolChainSupported.java index 21998a342dc..5ef738e1572 100644 --- a/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/IsGnuCygwinToolChainSupported.java +++ b/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/IsGnuCygwinToolChainSupported.java @@ -12,14 +12,9 @@ package org.eclipse.cdt.managedbuilder.gnu.cygwin; 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.envvar.EnvironmentVariableManager; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IManagedIsToolChainSupported; import org.eclipse.cdt.managedbuilder.core.IToolChain; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.internal.envvar.EnvironmentVariableManagerToolChain; import org.osgi.framework.Version; @@ -33,16 +28,7 @@ public class IsGnuCygwinToolChainSupported implements IManagedIsToolChainSupport @Override public boolean isSupported(IToolChain toolChain, Version version, String instance) { - IConfiguration cfg = toolChain.getParent(); - 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); + IEnvironmentVariable var = new EnvironmentVariableManagerToolChain(toolChain).getVariable(ENV_PATH, true); String envPath = var != null ? var.getValue() : null; return Cygwin.isAvailable(envPath); } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ArrayUtilTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ArrayUtilTest.java index 234723a336d..cdab81aa5d8 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ArrayUtilTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ArrayUtilTest.java @@ -229,4 +229,25 @@ public class ArrayUtilTest extends TestCase { assertSame(result[0], o1); 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]); + } + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index 7ec52522513..9d6a65a6de9 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -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.IASTTypeId; 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.ICompositeType; 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.cpp.CPPASTNameBase; 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.ClassTypeHelper; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; @@ -5891,11 +5889,8 @@ public class AST2TemplateTests extends AST2TestBase { // auto x2 = begin2(v); public void testResolvingAutoTypeWithDependentExpression_402409a() throws Exception { BindingAssertionHelper helper = new BindingAssertionHelper(getAboveComment(), true); - ICPPVariable x1 = helper.assertNonProblem("x1", ICPPVariable.class); - ICPPVariable x2 = helper.assertNonProblem("x2", ICPPVariable.class); - IType pointerToInt = new CPPPointerType(new CPPBasicType(Kind.eInt, 0)); - assertSameType(pointerToInt, x1.getType()); - assertSameType(pointerToInt, x2.getType()); + helper.assertVariableType("x1", CommonTypes.pointerToInt); + helper.assertVariableType("x2", CommonTypes.pointerToInt); } // struct vector { @@ -6217,6 +6212,21 @@ public class AST2TemplateTests extends AST2TestBase { public void testPointerToMemberAsDependentExpression_391001() throws Exception { parseAndCheckBindings(getAboveComment(), CPP, true); } + + // template + // struct A { + // char x; + // }; + // + // typedef A B; + // + // template + // struct C {}; + // + // typedef C<&B::x> T; + public void testPointerToMemberOfTemplateClass_402861() throws Exception { + parseAndCheckBindings(); + } // class Memory { }; // Memory memory; @@ -7195,6 +7205,19 @@ public class AST2TemplateTests extends AST2TestBase { parseAndCheckBindings(); } + // template + // struct waldo { + // typedef int type; + // }; + // + // template + // struct waldo; + // + // typedef waldo::type Type; + public void testPartialSpecializationForVarargFunctionType_402807() throws Exception { + parseAndCheckBindings(); + } + // template // struct meta { // static const bool value = 1; @@ -7519,4 +7542,25 @@ public class AST2TemplateTests extends AST2TestBase { public void testUnqualifiedFunctionCallInTemplate_402498() throws Exception { parseAndCheckBindings(); } + + // template + // struct no_type {}; + // + // struct type {}; + // + // template + // struct A {}; + // + // template + // int foo(T); + // + // template + // typename no_type::type const foo(A); + // + // A a; + // auto b = foo(a); + public void testQualifiedNameLookupInTemplate_402854() throws Exception { + BindingAssertionHelper helper = new BindingAssertionHelper(getAboveComment(), true); + helper.assertVariableType("b", CommonTypes.int_); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java index 6dd95c5dce1..fa6c2a07227 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java @@ -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.IProblemBinding; 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.cpp.ICPPASTLinkageSpecification; 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.c.CVisitor; 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.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.model.ASTStringUtil; @@ -99,6 +103,11 @@ public class AST2TestBase extends BaseTestCase { public final static String TEST_CODE = ""; protected static final IParserLogService NULL_LOG = new NullLogService(); 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 SCANNER_INFO = new ScannerInfo(getStdMap()); @@ -739,6 +748,11 @@ public class AST2TestBase extends BaseTestCase { assertTrue("ProblemBinding for name: " + name, !(binding instanceof IProblemBinding)); return assertType(binding, cs); } + + public void assertVariableType(String variableName, IType expectedType) { + IVariable var = assertNonProblem(variableName, IVariable.class); + assertSameType(expectedType, var.getType()); + } public U assertType(T obj, Class... cs) { for (Class c : cs) { diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/BTreeTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/BTreeTests.java index 967720e93cb..389694a61f9 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/BTreeTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/BTreeTests.java @@ -31,7 +31,7 @@ import org.eclipse.core.runtime.CoreException; /** * Test insertion/deletion of records of a mock record type in a B-tree - * + * * @author aferguso * */ @@ -65,11 +65,11 @@ public class BTreeTests extends BaseTestCase { dbFile.deleteOnExit(); } - + public void testBySortedSetMirrorLite() throws Exception { sortedMirrorTest(8); } - + /** * Test random (but reproducible via known seed) sequences of insertions/deletions * 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 checkCorrectnessEachIteration if true, then on every single insertion/deletion check that the B-tree invariants * still hold * @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); // 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 SortedSet expected = new TreeSet(); final List history = new ArrayList(); - + init(degree); - + if (DEBUG > 0) System.out.print("\t "+seed+" "+(nIterations/1000)+"K: "); for(int i=0; i fOverrideSet; private Object fContext; - private SettingLevel(){ + private SettingLevel() { fEntries = new LinkedHashMap(); } - public boolean isReadOnly(){ + public boolean isReadOnly() { return fIsReadOnly; } - public void setReadOnly(boolean readOnly){ + public void setReadOnly(boolean readOnly) { fIsReadOnly = readOnly; } - public boolean isOverrideSupported(){ + public boolean isOverrideSupported() { return fIsOverrideSupported; } - public void setOverrideSupported(boolean supported){ + public void setOverrideSupported(boolean supported) { fIsOverrideSupported = supported; } - public void setFlagsToSet(int flags){ + public void setFlagsToSet(int flags) { fFlagsToSet = flags; } - public boolean containsOverrideInfo(){ + public boolean containsOverrideInfo() { return fOverrideSet != null; } - public void setFlagsToClear(int flags){ + public void setFlagsToClear(int flags) { fFlagsToClear = flags; } - public int getFlagsToSet(){ + public int getFlagsToSet() { return fFlagsToSet; } - public int getFlagsToClear(){ + public int getFlagsToClear() { return fFlagsToClear; } - public int getFlags(int baseFlags){ + public int getFlags(int baseFlags) { return (baseFlags | fFlagsToSet) & (~fFlagsToClear); } @SuppressWarnings("unchecked") - public Set getOverrideSet(){ - if(fOverrideSet != null) + public Set getOverrideSet() { + if (fOverrideSet != null) return (HashSet)fOverrideSet.clone(); return new HashSet(); } - public void addEntries(ICLanguageSettingEntry entries[]){ - if(entries != null){ - for(int i = 0; i < entries.length; i++){ + public void addEntries(ICLanguageSettingEntry entries[]) { + if (entries != null) { + for (int i = 0; i < entries.length; i++) { addEntry(entries[i]); } } } - public void addEntries(List list){ - for(ICLanguageSettingEntry se : list) + public void addEntries(List list) { + for (ICLanguageSettingEntry se : list) addEntry(se); } - public void addEntry(ICLanguageSettingEntry entry){ + public void addEntry(ICLanguageSettingEntry entry) { addEntry(entry, null); } - public void addEntry(ICLanguageSettingEntry entry, Object customInfo){ + public void addEntry(ICLanguageSettingEntry entry, Object customInfo) { entry = CDataUtil.createEntry(entry, fFlagsToSet, fFlagsToClear); EntryInfo info = new EntryInfo(entry, customInfo); fEntries.put(info.getContentsKey(), info); } - public void addOverrideName(String name){ - if(fOverrideSet == null) + public void addOverrideName(String name) { + if (fOverrideSet == null) fOverrideSet = new HashSet(); fOverrideSet.add(name); } - public void addOverrideNameSet(Set set){ - if(set == null) + public void addOverrideNameSet(Set set) { + if (set == null) return; - if(fOverrideSet != null){ + if (fOverrideSet != null) { fOverrideSet.addAll(set); - } else if(set.size() != 0){ + } else if (set.size() != 0) { fOverrideSet = new HashSet(set); } } - public void removeOverrideName(String name){ - if(fOverrideSet == null) + public void removeOverrideName(String name) { + if (fOverrideSet == null) return; fOverrideSet.remove(name); - if(fOverrideSet.size() == 0) + if (fOverrideSet.size() == 0) fOverrideSet = null; } - public void clear(){ + public void clear() { fEntries.clear(); fOverrideSet = null; } - public Map clearAndGetMap(){ + public Map clearAndGetMap() { Map map = fEntries; fEntries = new LinkedHashMap(); fOverrideSet = null; return map; } - public EntryInfo[] getInfos(){ + public EntryInfo[] getInfos() { return fEntries.values().toArray(new EntryInfo[fEntries.size()]); } - public ICLanguageSettingEntry[] getEntries(){ + public ICLanguageSettingEntry[] getEntries() { List list = getEntriesList(false); return list.toArray(new ICLanguageSettingEntry[list.size()]); } - public ICLanguageSettingEntry[] getEntries(boolean includeOverridden){ + public ICLanguageSettingEntry[] getEntries(boolean includeOverridden) { List list = getEntriesList(includeOverridden); return list.toArray(new ICLanguageSettingEntry[list.size()]); } - public List getEntriesList(boolean includeOverridden){ + public List getEntriesList(boolean includeOverridden) { List list = new ArrayList(); EntryInfo infos[] = getInfos(); - for(EntryInfo info : infos){ - if(includeOverridden || !info.isOverridden()) + for (EntryInfo info : infos) { + if (includeOverridden || !info.isOverridden()) list.add(info.getEntry()); } return list; } - public Object getContext(){ + public Object getContext() { return fContext; } - public void setContext(Object context){ + public void setContext(Object context) { fContext = context; } } @@ -189,60 +190,60 @@ public class SettingsSet { private boolean fIsOverRidden; private Object fCustomInfo; - private EntryInfo(ICLanguageSettingEntry entry, Object customInfo){ + private EntryInfo(ICLanguageSettingEntry entry, Object customInfo) { fEntry = entry; fCustomInfo = customInfo; } - public EntryNameKey getContentsKey(){ - if(fNameKey == null){ + public EntryNameKey getContentsKey() { + if (fNameKey == null) { fNameKey = new EntryNameKey(fEntry); } return fNameKey; } - private void makeOverridden(boolean overrridden){ - fIsOverRidden = overrridden; + private void makeOverridden(boolean overridden) { + fIsOverRidden = overridden; } - public ICLanguageSettingEntry getEntry(){ + public ICLanguageSettingEntry getEntry() { return fEntry; } - public boolean isOverridden(){ + public boolean isOverridden() { return fIsOverRidden; } - public Object getCustomInfo(){ + public Object getCustomInfo() { return fCustomInfo; } } - public SettingsSet(int num){ + public SettingsSet(int num) { fLevels = new SettingLevel[num]; - for(int i = 0; i < num; i++){ + for (int i = 0; i < num; i++) { fLevels[i] = new SettingLevel(); } } - public SettingLevel[] getLevels(){ + public SettingLevel[] getLevels() { return fLevels.clone(); } - public void adjustOverrideState(){ + public void adjustOverrideState() { Set set = new HashSet(); SettingLevel level; - for(int i = 0; i < fLevels.length; i++){ + for (int i = 0; i < fLevels.length; i++) { level = fLevels[i]; - if(level.isOverrideSupported() && level.fOverrideSet != null) + if (level.isOverrideSupported() && level.fOverrideSet != null) set.addAll(level.fOverrideSet); adjustOverrideState(fLevels[i], set); } } - private void adjustOverrideState(SettingLevel level, Set overridenSet){ - for(EntryInfo info : level.getInfos()){ - if(overridenSet.add(info.getEntry().getName())){ + private void adjustOverrideState(SettingLevel level, Set overridenSet) { + for (EntryInfo info : level.getInfos()) { + if (overridenSet.add(info.getEntry().getName())) { info.makeOverridden(false); } else { info.makeOverridden(true); @@ -250,47 +251,47 @@ public class SettingsSet { } } - public ICLanguageSettingEntry[] getEntries(){ + public ICLanguageSettingEntry[] getEntries() { return getEntries(READ_ONLY | WRITABLE); } - public ICLanguageSettingEntry[] getEntries(int types){ + public ICLanguageSettingEntry[] getEntries(int types) { adjustOverrideState(); List entries = new ArrayList(); - for(SettingLevel sl : fLevels){ - if(isCompatible(sl, types)) + for (SettingLevel sl : fLevels) { + if (isCompatible(sl, types)) getEntries(sl, entries); } return entries.toArray(new ICLanguageSettingEntry[entries.size()]); } - private void getEntries(SettingLevel level, List list){ - for(EntryInfo info : level.getInfos()) - if(!info.isOverridden()) + private void getEntries(SettingLevel level, List list) { + for (EntryInfo info : level.getInfos()) + if (!info.isOverridden()) list.add(info.getEntry()); } - private boolean isCompatible(SettingLevel level, int types){ - if((types & READ_ONLY) == 0 && level.isReadOnly()) + private boolean isCompatible(SettingLevel level, int types) { + if ((types & READ_ONLY) == 0 && level.isReadOnly()) return false; - if((types & WRITABLE) == 0 && !level.isReadOnly()) + if ((types & WRITABLE) == 0 && !level.isReadOnly()) return false; return true; } - private int getWritableLevelNum(){ - for(int i = 0; i map = getEntryLevelMap(WRITABLE | READ_ONLY); Map mapCopy = (HashMap)map.clone(); Map[] clearedInfos = new Map [fLevels.length]; - for(int i = 0; i < fLevels.length; i++){ - if(!fLevels[i].isReadOnly()) + for (int i = 0; i < fLevels.length; i++) { + if (!fLevels[i].isReadOnly()) clearedInfos[i] = fLevels[i].clearAndGetMap(); } @@ -314,13 +315,13 @@ public class SettingsSet { int writableLevel = getWritableLevelNum(); SettingLevel level; - for(int i = 0; i < entries.length; i++){ + for (int i = 0; i < entries.length; i++) { entry = entries[i]; EntryNameKey key = new EntryNameKey(entry); Object[] o = map.get(key); - if(o != null && valueMatches(entry, o[1])){ + if (o != null && valueMatches(entry, o[1])) { mapCopy.remove(key); levelInteger = (Integer)o[0]; if (! entry.isBuiltIn()) // allow overwrite existing entry, @@ -330,14 +331,14 @@ public class SettingsSet { } levelNum = levelInteger != null ? levelInteger.intValue() : writableLevel; - if(levelNum >= 0){ + if (levelNum >= 0) { level = fLevels[levelNum]; - if(!level.isReadOnly()){ + if (!level.isReadOnly()) { Map clearedInfo = clearedInfos[levelNum]; Object customInfo = null; - if(clearedInfo != null){ + if (clearedInfo != null) { EntryInfo info = clearedInfo.get(key); - if(info != null && entry.equalsByContents(info.getEntry())) + if (info != null && entry.equalsByContents(info.getEntry())) customInfo = info.getCustomInfo(); } level.addEntry(entry, customInfo); @@ -346,15 +347,15 @@ public class SettingsSet { } int overrideLevel = getOverrideLevelNum(); - if(overrideLevel >= 0){ + if (overrideLevel >= 0) { level = fLevels[overrideLevel]; - if(level.isOverrideSupported() && !mapCopy.isEmpty()){ - for(EntryNameKey enk : mapCopy.keySet()){ + if (level.isOverrideSupported() && !mapCopy.isEmpty()) { + for (EntryNameKey enk : mapCopy.keySet()) { ICSettingEntry e = enk.getEntry(); if ((e.getFlags() & ICSettingEntry.BUILTIN) == 0) continue; String str = e.getName(); - if(str != null) + if (str != null) level.addOverrideName(str); } } @@ -362,19 +363,19 @@ public class SettingsSet { adjustOverrideState(); } - public HashMap getEntryLevelMap(int types){ + public HashMap getEntryLevelMap(int types) { HashMap map = new HashMap(); - for(int i = 0; i < fLevels.length; i++){ - if(isCompatible(fLevels[i], types)) + for (int i = 0; i < fLevels.length; i++) { + if (isCompatible(fLevels[i], types)) addLevelInfoToMap(fLevels[i], i, map); } return map; } - private void addLevelInfoToMap(SettingLevel level, int l, Map map){ - for(EntryInfo info : level.getInfos()){ + private void addLevelInfoToMap(SettingLevel level, int l, Map map) { + for (EntryInfo info : level.getInfos()) { EntryNameKey key = info.getContentsKey(); - if(!map.containsKey(key)) + if (!map.containsKey(key)) map.put(key, new Object[]{new Integer(l), info.getEntry()}); } } @@ -385,15 +386,7 @@ public class SettingsSet { if (!(o instanceof ICMacroEntry)) return false; // cannot compare different entries String s1 = e.getValue(); - String s2 = ((ICMacroEntry)o).getValue(); - if (s1 == null && s2 == null) - return true; - if (s1 != null) - return s1.equals(s2); - else - return s2.equals(s1); + String s2 = ((ICMacroEntry) o).getValue(); + return s1 == null ? s2 == null : s1.equals(s2); } - - - } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java index 8c560e483a1..96860d9c8aa 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java @@ -18,6 +18,7 @@ import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.HashSet; import org.eclipse.core.runtime.Assert; @@ -28,9 +29,9 @@ public abstract class ArrayUtil { private static final int DEFAULT_LENGTH = 2; /** - * Assumes that array contains nulls at the end, only. - * Appends element after the last non-null element. - * If the array is null or not large enough, a larger one is allocated, using + * Assumes that array contains {@code null}s at the end, only. + * Appends element after the last non-{@code null} element. + * If the array is {@code null} or not large enough, a larger one is allocated, using * the given class object. */ @SuppressWarnings("unchecked") @@ -56,8 +57,8 @@ public abstract class ArrayUtil { } /** - * Assumes that array contains nulls at the end, only. - * Appends element after the last non-null element. + * Assumes that array contains {@code null}s at the end, only. + * Appends element after the last non-{@code null} element. * If the array is not large enough, a larger one is allocated. * Null array is supported for backward compatibility only and only when T is * Object. @@ -87,8 +88,8 @@ public abstract class ArrayUtil { } /** - * Assumes that array contains nulls at the end, only. - * @returns index of first null, or -1 + * Assumes that array contains {@code null}s at the end, only. + * @returns index of first {@code null}, or -1 */ private static int findFirstNull(Object[] array) { 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. * @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. * @param array The array to append to. Not {@code null} * @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. - * Assumes that nulls can be found at the end, only. - * if array == null, a new array of length 0 is returned - * if forceNew == true, a new array will always be created. - * if forceNew == false, a new array will only be created if the original array - * contained null entries. + * Trims the given array and returns a new array with no {@code null} entries. + * Assumes that {@code null}s can be found at the end, only. + * if {@code array} is {@code null}, a new array of length 0 is returned + * if {@code forceNew} is {@code true}, a new array will always be created. + * if {@code forceNew} is {@code false}, a new array will only be created if the original array + * contained {@code null} entries. * * @param c the type of the new array * @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. - * Assumes that nulls can be found at the end, only. - * if forceNew == true, a new array will always be created. - * if forceNew == false, a new array will only be created if the original array - * contained null entries. + * Trims the given array and returns a new array with no {@code null} entries. + * Assumes that {@code null}s can be found at the end, only. + * if {@code forceNew} is {@code true}, a new array will always be created. + * if {@code forceNew} is {@code false}, a new array will only be created if the original array + * contained {@code null} entries. * * @param array the array to be trimmed * @param forceNew @@ -227,8 +228,8 @@ public abstract class ArrayUtil { } /** - * Trims the given array and returns a new array with no null entries. - * Assumes that nulls can be found at the end, only. + * Trims the given array and returns a new array with no {@code null} entries. + * Assumes that {@code null}s can be found at the end, only. * * @param array the array to be trimmed * @since 5.2 @@ -257,13 +258,13 @@ public abstract class ArrayUtil { } /** - * Takes contents of the two arrays up to the first null element and concatenates + * Takes contents of the two arrays up to the first {@code null} element and concatenates * them. * @param c The type of the element of the returned array if there was not enough free space * in the destination 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 null. - * @param source The source array. May not be null. + * if there is enough free space in it. May be {@code null}. + * @param source The source array. May not be {@code null}. * @return The concatenated array, which may be the same as the first parameter. */ @SuppressWarnings("unchecked") @@ -300,11 +301,11 @@ public abstract class ArrayUtil { } /** - * Takes contents of the two arrays up to the first null element and concatenates - * them. + * Takes contents of the two arrays up to the first {@code null} element and concatenates them. + * * @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 null. - * @param source The source array. May not be null. + * if there is enough free space in it. May be {@code null}. + * @param source The source array. May not be {@code null}. * @return The concatenated array, which may be the same as the first parameter. * @since 5.2 */ @@ -359,10 +360,11 @@ public abstract class ArrayUtil { /** * Returns whether the specified array contains the specified object. Comparison is by * object identity. + * * @param array the array to search * @param obj the object to search for * @return true if the specified array contains the specified object, or - * the specified array is null + * the specified array is {@code null} */ public static boolean contains(T[] array, T obj) { 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 - * 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 obj the object to search for * @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 null + * not contain the object, or if the array is {@code null} */ public static int indexOf(T[] array, T obj) { 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 * object identity. + * * @param array the array to search * @param obj the object to search for * @return true if the specified array contains the specified object, or the specified array is - * null + * {@code null} */ public static boolean containsEqual(T[] array, T obj) { 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 - * not contain the object, or if the array is null. Comparison is by equals(). - * @param comments the array to search - * @param comment the object to search for + * not contain the object, or if the array is {@code null}. Comparison is by equals(). + * + * @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 - * not contain an equal object, or if the array is null + * not contain an equal object, or if the array is {@code null} */ - public static int indexOfEqual(T[] comments, T comment) { + public static int indexOfEqual(T[] array, T obj) { int result = -1; - if (comments != null) { - for (int i= 0; (i < comments.length) && (comments[i] != null); i++) { - if (comments[i].equals(comment)) + if (array != null) { + for (int i= 0; (i < array.length) && (array[i] != null); i++) { + if (array[i].equals(obj)) 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 */ 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 - * of the non-null elements. + * Removes all of the {@code null}s from the array and returns a new array that contains all + * 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 - * is unknown (due to performance efficiency). + * Note that this method should only be used when the placement of {@code null}s within + * the array is unknown (due to performance efficiency). */ @SuppressWarnings("unchecked") public static T[] removeNulls(Class 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 - * of the non-null elements. - * - * If there are no nulls 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 - * is unknown (due to performance efficiency). + * Removes all of the {@code null}s from the array and returns a new array that contains all + * of the non-{@code null} elements. + *

+ * 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 {@code null}s within + * the array is unknown (due to performance efficiency). * @since 5.2 */ @SuppressWarnings("unchecked") @@ -514,11 +521,11 @@ public abstract class ArrayUtil { /** * To improve performance, this method should be used instead of * {@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 end of the array. The position of the last non-{@code null} element in the array must also - * be known. + * 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 be known. *

- * 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. * * @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 - * Assumes that array contains nulls at the end, only. + * Inserts the {@code obj} at the beginning of the array, shifting the whole thing one index + * Assumes that array contains {@code null}s at the end, only. */ @SuppressWarnings("unchecked") public static T[] prepend(Class 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 - * Assumes that array contains nulls at the end, only. - * array must not be null. + * Inserts the {@code obj} at the beginning of the array, shifting the whole thing one index + * Assumes that array contains {@code null}s at the end, only. + * array must not be {@code null}. * @since 5.2 */ public static T[] prepend(T[] array, T obj) { @@ -621,7 +628,7 @@ public abstract class ArrayUtil { * @param target the runtime type of the new array * @param source the source array * @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") public static T[] convert(Class target, S[] source) { @@ -646,6 +653,7 @@ public abstract class ArrayUtil { /** * Reverses order of elements in a subsection of an array. + * * @param array the array * @param fromIndex the index of the first affected element (inclusive) * @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 - * given array except the first one. + * Returns a new array that contains all of the elements of the given array except + * the first one. * + * @throws NullPointerException if {@code array} is {@code null} + * @throws IllegalArgumentException if {@code array} is empty * @since 5.1 - * @throws NullPointerException if args is null - * @throws IllegalArgumentException if args.length <= 0 */ @SuppressWarnings("unchecked") - public static T[] removeFirst(T[] args) { - int n = args.length; + public static T[] removeFirst(T[] array) { + int n = array.length; if (n <= 0) 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++) { - newArgs[i - 1] = args[i]; + newArgs[i - 1] = array[i]; } 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[] removeDuplicates(T[] array) { + int k = 0; + if (array.length >= 16) { + HashSet set = new HashSet(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) { if (array == null) { array = new int[DEFAULT_LENGTH > idx + 1 ? DEFAULT_LENGTH : idx + 1]; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldSpecialization.java index 39b4c496cd9..ebc64913b07 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldSpecialization.java @@ -44,7 +44,7 @@ public class CPPFieldSpecialization extends CPPSpecialization implements ICPPFie @Override public ICPPClassType getClassOwner() { - return getField().getClassOwner(); + return (ICPPClassType) getOwner(); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index d9154a68c6a..6dd5c3bab52 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -3737,6 +3737,7 @@ public class CPPSemantics { LookupData data = new LookupData(unknownName, null, point); data.setIgnorePointOfDeclaration(true); data.typesOnly= unknown instanceof IType; + data.qualified= true; try { // 2: Lookup diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java index f03403601e6..6dd0f7bb428 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java @@ -922,7 +922,7 @@ public class TemplateArgumentDeduction { private boolean fromFunctionType(ICPPFunctionType ftp, ICPPFunctionType fta, IASTNode point) 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; if (!fromType(ftp.getReturnType(), fta.getReturnType(), false, point)) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/BTree.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/BTree.java index dd0642e2e09..92ae16f2ef6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/BTree.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/BTree.java @@ -176,8 +176,8 @@ public class BTree { } else if (compare < 0) { lower= middle + 1; } else { - // Found it, no insert, just return the record. - return record; + // Found it, no insert, just return the matched record. + return checkRec; } } } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/cdtvariables/ICdtVariableChangeListener.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/cdtvariables/ICdtVariableChangeListener.java index 79740cd4bef..eda0e2096d4 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/cdtvariables/ICdtVariableChangeListener.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/cdtvariables/ICdtVariableChangeListener.java @@ -10,6 +10,9 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.cdtvariables; +/** + * Listener to listen to Build Variables changes events. + */ public interface ICdtVariableChangeListener { void variablesChanged(VariableChangeEvent event); } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/cdtvariables/UserDefinedVariableSupplier.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/cdtvariables/UserDefinedVariableSupplier.java index b823a917e0a..c098d01fba3 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/cdtvariables/UserDefinedVariableSupplier.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/cdtvariables/UserDefinedVariableSupplier.java @@ -651,10 +651,20 @@ public class UserDefinedVariableSupplier extends CoreMacroSupplierBase { // 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){ fListeners.add(listener); } + /** + * Removes a Build Variables change listener. + * + * @param listener - the listener to remove. + */ public void removeListener(ICdtVariableChangeListener listener){ fListeners.remove(listener); } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/cdtvariables/VariableChangeEvent.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/cdtvariables/VariableChangeEvent.java index e42425b2ada..fbf7db1dd2c 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/cdtvariables/VariableChangeEvent.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/cdtvariables/VariableChangeEvent.java @@ -12,6 +12,9 @@ package org.eclipse.cdt.internal.core.cdtvariables; import org.eclipse.cdt.core.cdtvariables.ICdtVariable; +/** + * Event describing Build Variables changes. + */ public class VariableChangeEvent { private static final ICdtVariable[] EMPTY_VAR_ARRAY = new ICdtVariable[0]; diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/implementmethod/ImplementMethodRefactoringTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/implementmethod/ImplementMethodRefactoringTest.java old mode 100644 new mode 100755 index 9071317e29f..9233b1798d8 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/implementmethod/ImplementMethodRefactoringTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/implementmethod/ImplementMethodRefactoringTest.java @@ -788,4 +788,37 @@ public class ImplementMethodRefactoringTest extends RefactoringTestBase { public void testExplicitConstructor_Bug363111() throws Exception { 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(); + } + } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameTemplatesTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameTemplatesTests.java index 1adde370a20..fa30925b358 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameTemplatesTests.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameTemplatesTests.java @@ -24,44 +24,70 @@ import org.eclipse.ltk.core.refactoring.RefactoringStatus; */ public class RenameTemplatesTests extends RenameTests { - public RenameTemplatesTests(String name) { - super(name); - } + public RenameTemplatesTests(String name) { + super(name); + } - public static Test suite(){ - return suite(true); - } + public static Test suite() { + return suite(true); + } - public static Test suite( boolean cleanup ) { - TestSuite suite = new TestSuite(RenameTemplatesTests.class); - if (cleanup) { - suite.addTest( new RefactoringTests("cleanupProject") ); //$NON-NLS-1$ - } - return suite; - } - - public void testClassTemplate() throws Exception { - StringWriter writer = new StringWriter(); - writer.write("template \n"); //$NON-NLS-1$ - writer.write("class Array { \n"); //$NON-NLS-1$ - writer.write("public: \n"); //$NON-NLS-1$ - writer.write(" Array(unsigned sz) {} \n"); //$NON-NLS-1$ - writer.write(" ~Array(){} \n"); //$NON-NLS-1$ - writer.write(" Type& operator[] (unsigned idx); \n"); //$NON-NLS-1$ - writer.write("}; \n"); //$NON-NLS-1$ - writer.write("template \n"); //$NON-NLS-1$ - writer.write("inline Type& Array::operator[] (unsigned index) {\n"); //$NON-NLS-1$ - writer.write(" return 1; \n"); //$NON-NLS-1$ - writer.write("}; \n"); //$NON-NLS-1$ - String contents = writer.toString(); - IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ - - int offset1= contents.indexOf("Array"); //$NON-NLS-1$ - - RefactoringStatus stat= checkConditions(cpp, offset1, "WELT"); //$NON-NLS-1$ - assertRefactoringOk(stat); - - Change ch= getRefactorChanges(cpp, offset1, "WELT"); //$NON-NLS-1$ - assertTotalChanges(4, ch); - } + public static Test suite(boolean cleanup) { + TestSuite suite = new TestSuite(RenameTemplatesTests.class); + if (cleanup) { + suite.addTest(new RefactoringTests("cleanupProject")); + } + return suite; + } + + public void testClassTemplate() throws Exception { + StringWriter writer = new StringWriter(); + writer.write("template \n"); + writer.write("class Array { \n"); + writer.write("public: \n"); + writer.write(" Array(unsigned sz) {} \n"); + writer.write(" ~Array(){} \n"); + writer.write(" Type& operator[] (unsigned idx); \n"); + writer.write("}; \n"); + writer.write("template \n"); + writer.write("inline Type& Array::operator[] (unsigned index) {\n"); + writer.write(" return 1; \n"); + writer.write("}; \n"); + String contents = writer.toString(); + IFile cpp = importFile("test.cpp", contents); + + int offset1 = contents.indexOf("Array"); + + RefactoringStatus stat = checkConditions(cpp, offset1, "WELT"); + assertRefactoringOk(stat); + + Change ch = getRefactorChanges(cpp, offset1, "WELT"); + assertTotalChanges(4, ch); + } + + public void _testRenameSpecializations_bug240692() throws Exception { + StringWriter writer = new StringWriter(); + + writer.write("template \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 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")); + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodRefactoring.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodRefactoring.java old mode 100644 new mode 100755 index 0fef24d8eee..5385fd8fabc --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodRefactoring.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodRefactoring.java @@ -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.IASTName; 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.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; @@ -266,7 +267,13 @@ public class ImplementMethodRefactoring extends CRefactoring { for (IASTPointerOperator pop : functionDeclarator.getPointerOperators()) { 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()); functionDefinition.setParent(unit); diff --git a/doc/org.eclipse.cdt.doc.user/images/cdt_menu_window.png b/doc/org.eclipse.cdt.doc.user/images/cdt_menu_window.png index aafdd4c29b7..7be77728849 100644 Binary files a/doc/org.eclipse.cdt.doc.user/images/cdt_menu_window.png and b/doc/org.eclipse.cdt.doc.user/images/cdt_menu_window.png differ diff --git a/doc/org.eclipse.cdt.doc.user/reference/cdt_o_menu.htm b/doc/org.eclipse.cdt.doc.user/reference/cdt_o_menu.htm index 06217f65a24..1afd5a0f200 100755 --- a/doc/org.eclipse.cdt.doc.user/reference/cdt_o_menu.htm +++ b/doc/org.eclipse.cdt.doc.user/reference/cdt_o_menu.htm @@ -12,9 +12,9 @@

C/C++ Menubar

This section describes the menubar options available from the C/C++ perspective.

+alt="C/C++ perspective main menu">

- + File Menu actions
Edit Menu actions
@@ -32,6 +32,8 @@ alt="CDT main menu"> Run Menu actions
Window Menu actions
+ +Help Menu actions (from Workbench User Guide)

IBM Copyright Statement

diff --git a/doc/org.eclipse.cdt.doc.user/reference/cdt_u_m_window.htm b/doc/org.eclipse.cdt.doc.user/reference/cdt_u_m_window.htm index eb02caa34f3..66ed08dbd34 100755 --- a/doc/org.eclipse.cdt.doc.user/reference/cdt_u_m_window.htm +++ b/doc/org.eclipse.cdt.doc.user/reference/cdt_u_m_window.htm @@ -1,122 +1,234 @@ - + - - + Window Menu actions -

Window Menu actions

+
+

Window Menu actions

+

+ Selecting Window Menu +

+ + + + + + + + + + + + + + -

Window Menu

-

-

- + + + + + - - - - - + + + + + + + + + + - - - - - + + + + + - - - - - - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - -

- -

-IBM Copyright Statement -

- - - \ No newline at end of file + + +
+
Next Editor
+
Activates the most-recently-used editor (If held down, + displays the list of open editors, ordered by time.)
+
+ + Ctrl+F6 + + + +
+
Previous Editor
+
Activates least-recently-used editor (If held down, + displays the list of open editors, ordered by time.)
+
+ + Ctrl+Shift+F6 + + + +
+
Switch to Editor...
+
Displays a dialog that allows multiple editors to be + saved or closed
+
+ + Ctrl+Shift+E + + + +
+
Next View
+
Activates the most-recently-used view (If held down, + displays the list of open views, ordered by time.)
+
+ + Ctrl+F7 + + + +
+
Previous View
+
Activates least-recently-used view (If held down, + displays the list of open views, ordered by time.)
+
+ + Ctrl+Shift+F7 + + + +
+
Next Perspective
+
Activates the most-recently-used perspective (If held + down, displays the list of open perspectives, ordered by time.)
+
+ + Ctrl+F8 + + + +
+
Previous Perspective
+
Activates least-recently-used perspective (If held down, + displays the list of open perspective, ordered by time.)
+
+ + Ctrl+Shift+F8 + + + Preferences + Opens the Preferences dialog, where + workspace-wide preferences can be set (The C/C++ Page Preference Window section + documents the C/C++-specific preferences.) + +   + + + +

+ IBM Copyright Statement +

+
+ +