1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

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

This commit is contained in:
Andrew Gvozdev 2013-01-06 06:16:54 -05:00
commit 303a22a13e
125 changed files with 4271 additions and 1855 deletions

View file

@ -221,7 +221,7 @@ public class ScannerInfoConsoleParserUtility extends AbstractGCCBOPConsoleParser
// appending fileName to cwd should yield file path
filePath = cwd.append(fileName);
}
if (!filePath.toString().equalsIgnoreCase(EFSExtensionManager.getDefault().getPathFromURI(file.getLocationURI()))) {
if (!filePath.toOSString().equalsIgnoreCase(EFSExtensionManager.getDefault().getPathFromURI(file.getLocationURI()))) {
// must be the cwd is wrong
// check if file name starts with ".."
if (fileName.startsWith("..")) { //$NON-NLS-1$

View file

@ -18,6 +18,7 @@ import junit.framework.TestSuite;
import org.eclipse.cdt.build.core.scannerconfig.CfgInfoContext;
import org.eclipse.cdt.build.core.scannerconfig.ICfgScannerConfigBuilderInfo2Set;
import org.eclipse.cdt.build.internal.core.scannerconfig2.CfgScannerConfigProfileManager;
import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
@ -106,6 +107,7 @@ public class CfgScannerConfigProfileManagerTests extends BaseTestCase {
Assert.isTrue("dummyFile".equals(scbi.getBuildOutputFilePath()));
// Test restore defaults
ScannerDiscoveryLegacySupport.setLanguageSettingsProvidersFunctionalityEnabled(fProject, false);
scbis.applyInfo(cic, null);
// Save the project description
CoreModel.getDefault().setProjectDescription(fProject, prjDesc);

View file

@ -563,7 +563,7 @@ public class ConfigurationDataProvider extends CConfigurationDataProvider implem
private static List<ILanguageSettingsProvider> getDefaultLanguageSettingsProviders(IConfiguration cfg) {
List<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
String[] ids = cfg.getDefaultLanguageSettingsProviderIds();
String[] ids = cfg != null ? cfg.getDefaultLanguageSettingsProviderIds() : null;
if (ids != null) {
for (String id : ids) {
ILanguageSettingsProvider provider = null;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010, 2011 Gil Barash
* Copyright (c) 2010, 2013 Gil Barash
* 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
@ -116,7 +116,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
if (str.toLowerCase().contains(fNoBreakComment.toLowerCase()))
continue;
}
reportProblem(curr, prevCase);
reportProblem(curr);
}
}
}
@ -159,7 +159,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
}
}
private void reportProblem(IASTStatement curr, IASTStatement prevCase) {
private void reportProblem(IASTStatement curr) {
reportProblem(ER_ID, getProblemLocationAtEndOfNode(curr));
}
@ -218,7 +218,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
super.initPreferences(problem);
addPreference(problem, PARAM_NO_BREAK_COMMENT, CheckersMessages.CaseBreakChecker_DefaultNoBreakCommentDescription,
DEFAULT_NO_BREAK_COMMENT);
addPreference(problem, PARAM_LAST_CASE, CheckersMessages.CaseBreakChecker_LastCaseDescription, Boolean.TRUE);
addPreference(problem, PARAM_LAST_CASE, CheckersMessages.CaseBreakChecker_LastCaseDescription, Boolean.FALSE);
addPreference(problem, PARAM_EMPTY_CASE, CheckersMessages.CaseBreakChecker_EmptyCaseDescription, Boolean.FALSE);
}

View file

@ -29,34 +29,22 @@ public class CaseBreakQuickFixTest extends QuickFixTestCase {
// break;
// }
//}
public void testMiddleCase() throws Exception {
public void testSimpleCase() throws Exception {
loadcode(getAboveComment());
String result = runQuickFixOneFile();
assertContainedIn("break;\tcase 2:", result);
}
//void func() {
// int a;
// switch(a) {
// case 1:
// hello();
// }
//}
public void testLastCase() throws Exception {
loadcode(getAboveComment());
String result = runQuickFixOneFile();
assertContainedIn("break;\t}", result);
}
//void func() {
// int a;
// switch(a) {
// case 1: {
// hello();
// }
// default:
// }
//}
public void testLastCaseComp() throws Exception {
public void testCompositeStatementCase() throws Exception {
loadcode(getAboveComment());
String result = runQuickFixOneFile();
assertContainedIn("hello();\t\tbreak;", result);

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2009, 2011 Alena Laskavaia
* Copyright (c) 2009, 2013 Alena Laskavaia
* 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
@ -417,9 +417,7 @@ public class CheckersRegistry implements Iterable<IChecker>, ICheckersRegistry {
IProblem problem = resourceProfile.findProblem(p.getId());
if (problem == null)
throw new IllegalArgumentException(p.getId() + " is not registered"); //$NON-NLS-1$
if (!problem.isEnabled())
return false;
if (checker instanceof AbstractCheckerWithProblemPreferences) {
if (problem.isEnabled() && checker instanceof AbstractCheckerWithProblemPreferences) {
LaunchModeProblemPreference pref =
((AbstractCheckerWithProblemPreferences) checker).getLaunchModePreference(problem);
if (pref.isRunningInMode(mode)) {

View file

@ -11,31 +11,17 @@
*******************************************************************************/
package org.eclipse.cdt.codan.internal.core;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.cdt.codan.core.CodanCorePlugin;
import org.eclipse.cdt.codan.core.model.CheckerLaunchMode;
import org.eclipse.cdt.codan.core.model.IChecker;
import org.eclipse.cdt.codan.core.model.ICheckerInvocationContext;
import org.eclipse.cdt.codan.core.model.ICodanProblemMarker;
import org.eclipse.cdt.codan.core.model.IProblem;
import org.eclipse.cdt.codan.core.model.IProblemProfile;
import org.eclipse.cdt.codan.core.model.IRunnableInEditorChecker;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceRuleFactory;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.osgi.util.NLS;
/**
@ -45,7 +31,6 @@ public class CodanRunner {
/** Do not instantiate. All methods are static */
private CodanRunner() {}
/**
* Runs all checkers that support "run as you type" mode.
*
@ -135,71 +120,4 @@ public class CodanRunner {
monitor.done();
}
}
public static void asynchronouslyRemoveMarkersForDisabledProblems(final IResource resource) {
Job job = new Job(Messages.CodanRunner_Update_markers) {
@Override
protected IStatus run(IProgressMonitor monitor) {
removeMarkersForDisabledProblems(resource, monitor);
return Status.OK_STATUS;
}
};
IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace().getRuleFactory();
job.setRule(ruleFactory.markerRule(resource));
job.setSystem(true);
job.schedule();
}
public static void removeMarkersForDisabledProblems(IResource resource, IProgressMonitor monitor) {
CheckersRegistry chegistry = CheckersRegistry.getInstance();
Set<String> markerTypes = new HashSet<String>();
for (IChecker checker : chegistry) {
Collection<IProblem> problems = chegistry.getRefProblems(checker);
for (IProblem problem : problems) {
markerTypes.add(problem.getMarkerType());
}
}
try {
removeMarkersForDisabledProblems(chegistry, markerTypes, resource, monitor);
} catch (CoreException e) {
CodanCorePlugin.log(e);
}
}
private static void removeMarkersForDisabledProblems(CheckersRegistry chegistry,
Set<String> markerTypes, IResource resource, IProgressMonitor monitor) throws CoreException {
if (!resource.isAccessible()) {
return;
}
IResource[] children = null;
if (resource instanceof IContainer) {
children = ((IContainer) resource).members();
}
int numChildren = children == null ? 0 : children.length;
int childWeight = 10;
SubMonitor progress = SubMonitor.convert(monitor, 1 + numChildren * childWeight);
IProblemProfile resourceProfile = null;
for (String markerType : markerTypes) {
IMarker[] markers = resource.findMarkers(markerType, false, IResource.DEPTH_ZERO);
for (IMarker marker : markers) {
String problemId = (String) marker.getAttribute(ICodanProblemMarker.ID);
if (resourceProfile == null) {
resourceProfile = chegistry.getResourceProfile(resource);
}
IProblem problem = resourceProfile.findProblem(problemId);
if (problem != null && !problem.isEnabled()) {
marker.delete();
}
}
}
progress.worked(1);
if (children != null) {
for (IResource child : children) {
if (monitor.isCanceled())
return;
removeMarkersForDisabledProblems(chegistry, markerTypes, child,
progress.newChild(childWeight));
}
}
}
}

View file

@ -26,7 +26,6 @@ class Messages extends NLS {
public static String CodanApplication_Usage;
public static String CodanApplication_verbose_option;
public static String CodanRunner_Code_analysis_on;
public static String CodanRunner_Update_markers;
static {
NLS.initializeMessages(Messages.class.getName(), Messages.class);

View file

@ -18,4 +18,3 @@ CodanApplication_Options=Options:
CodanApplication_all_option= -all - run on all projects in workspace
CodanApplication_verbose_option= -verbose - print verbose build information
CodanRunner_Code_analysis_on=Code analysis on {0}
CodanRunner_Update_markers=Updating error markers

View file

@ -66,7 +66,7 @@ class CodanPartListener implements IPartListener2 {
}
}
private void processResource(final IResource resource, final CheckerLaunchMode launchMode) {
private static void processResource(final IResource resource, final CheckerLaunchMode launchMode) {
if (resource != null) {
Job job = new Job(NLS.bind(Messages.Startup_AnalyzingFile, resource.getName())) {
@Override

View file

@ -1,5 +1,9 @@
#Sun Feb 27 22:29:21 EST 2011
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
@ -18,6 +22,7 @@ org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
@ -25,12 +30,15 @@ org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
@ -39,20 +47,31 @@ org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warni
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
org.eclipse.jdt.core.compiler.problem.nullReference=error
org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
@ -65,7 +84,8 @@ org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverridin
org.eclipse.jdt.core.compiler.problem.unusedImport=error
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled

View file

@ -5,17 +5,18 @@ Bundle-SymbolicName: org.eclipse.cdt.codan.ui; singleton:=true
Bundle-Version: 3.2.0.qualifier
Bundle-Activator: org.eclipse.cdt.codan.internal.ui.CodanUIActivator
Bundle-Vendor: %Bundle-Vendor
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.core.resources,
org.eclipse.ui.workbench.texteditor,
org.eclipse.cdt.codan.core,
org.eclipse.jface.text,
org.eclipse.ui.ide,
Require-Bundle: org.eclipse.cdt.codan.core,
org.eclipse.cdt.core,
org.eclipse.cdt.ui,
org.eclipse.core.filesystem,
org.eclipse.core.resources,
org.eclipse.core.runtime,
org.eclipse.jface.text,
org.eclipse.ui,
org.eclipse.ui.console,
org.eclipse.ui.editors
org.eclipse.ui.editors,
org.eclipse.ui.ide,
org.eclipse.ui.workbench.texteditor
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.cdt.codan.internal.ui;x-friends:="org.eclipse.cdt.codan.ui.cxx",

View file

@ -30,6 +30,7 @@ public class CodanUIMessages extends NLS {
public static String CodanPreferencePage_MessageLabel;
public static String CodanPreferencePage_NoInfo;
public static String CodanPreferencePage_Parameters;
public static String CodanPreferencePage_Update_markers;
public static String ProblemsTreeEditor_NameColumn;
public static String ProblemsTreeEditor_Problems;
public static String ProblemsTreeEditor_SeverityColumn;

View file

@ -22,6 +22,7 @@ CodanPreferencePage_Info=Info
CodanPreferencePage_MessageLabel=Message:
CodanPreferencePage_NoInfo=No description
CodanPreferencePage_Parameters=Parameters:
CodanPreferencePage_Update_markers=Updating error markers
CustomizeProblemComposite_LaunchingTab=Launching
CustomizeProblemComposite_TabParameters=Preferences
CustomizeProblemComposite_TabScope=Scope

View file

@ -8,23 +8,49 @@
* Contributors:
* Alena Laskavaia - initial API and implementation
* Alex Ruiz (Google)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.codan.internal.ui.preferences;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.eclipse.cdt.codan.core.CodanCorePlugin;
import org.eclipse.cdt.codan.core.CodanRuntime;
import org.eclipse.cdt.codan.core.model.CheckerLaunchMode;
import org.eclipse.cdt.codan.core.model.IChecker;
import org.eclipse.cdt.codan.core.model.ICheckersRegistry;
import org.eclipse.cdt.codan.core.model.ICodanProblemMarker;
import org.eclipse.cdt.codan.core.model.IProblem;
import org.eclipse.cdt.codan.core.model.IProblemProfile;
import org.eclipse.cdt.codan.internal.core.CheckersRegistry;
import org.eclipse.cdt.codan.internal.core.CodanRunner;
import org.eclipse.cdt.codan.internal.ui.CodanUIActivator;
import org.eclipse.cdt.codan.internal.ui.CodanUIMessages;
import org.eclipse.cdt.codan.internal.ui.dialogs.CustomizeProblemDialog;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.model.CoreModelUtil;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
import org.eclipse.cdt.internal.corext.util.CModelUtil;
import org.eclipse.cdt.internal.ui.editor.ASTProvider;
import org.eclipse.cdt.ui.ICEditor;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceRuleFactory;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.layout.GridDataFactory;
@ -42,8 +68,13 @@ import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.preferences.ScopedPreferenceStore;
/**
@ -163,7 +194,7 @@ public class CodanPreferencePage extends FieldEditorOverlayPage implements IWork
if (resource == null) {
resource = ResourcesPlugin.getWorkspace().getRoot();
}
CodanRunner.asynchronouslyRemoveMarkersForDisabledProblems(resource);
asynchronouslyUpdateMarkers(resource);
}
return success;
}
@ -215,4 +246,111 @@ public class CodanPreferencePage extends FieldEditorOverlayPage implements IWork
private boolean hasSelectedProblems() {
return selectedProblems != null && !selectedProblems.isEmpty();
}
private static void asynchronouslyUpdateMarkers(final IResource resource) {
final Set<IFile> filesToUpdate = new HashSet<IFile>();
final IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow active = workbench.getActiveWorkbenchWindow();
final IWorkbenchPage page = active.getActivePage();
// Get the files open C/C++ editors.
for (IEditorReference partRef : page.getEditorReferences()) {
IEditorPart editor = partRef.getEditor(false);
if (editor instanceof ICEditor) {
IFile file = (IFile) editor.getEditorInput().getAdapter(IFile.class);
if (file != null && resource.getFullPath().isPrefixOf(file.getFullPath())) {
filesToUpdate.add(file);
}
}
}
Job job = new Job(CodanUIMessages.CodanPreferencePage_Update_markers) {
@Override
protected IStatus run(IProgressMonitor monitor) {
final SubMonitor submonitor = SubMonitor.convert(monitor, 1 + 2 * filesToUpdate.size());
removeMarkersForDisabledProblems(resource, submonitor.newChild(1));
if (filesToUpdate.isEmpty())
return Status.OK_STATUS;
// Run checkers on the currently open files to update the problem markers.
for (final IFile file : filesToUpdate) {
ITranslationUnit tu = CoreModelUtil.findTranslationUnit(file);
if (tu != null) {
tu = CModelUtil.toWorkingCopy(tu);
ASTProvider.getASTProvider().runOnAST(
tu, ASTProvider.WAIT_ACTIVE_ONLY, submonitor.newChild(1),
new ASTRunnable() {
@Override
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) {
if (ast != null) {
CodanRunner.runInEditor(ast, file, submonitor.newChild(1));
} else {
CodanRunner.processResource(file, CheckerLaunchMode.RUN_ON_FILE_OPEN,
submonitor.newChild(1));
}
return Status.OK_STATUS;
}
});
}
}
return Status.OK_STATUS;
}
};
IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace().getRuleFactory();
job.setRule(ruleFactory.markerRule(resource));
job.setSystem(true);
job.schedule();
}
private static void removeMarkersForDisabledProblems(IResource resource, IProgressMonitor monitor) {
CheckersRegistry chegistry = CheckersRegistry.getInstance();
Set<String> markerTypes = new HashSet<String>();
for (IChecker checker : chegistry) {
Collection<IProblem> problems = chegistry.getRefProblems(checker);
for (IProblem problem : problems) {
markerTypes.add(problem.getMarkerType());
}
}
try {
removeMarkersForDisabledProblems(chegistry, markerTypes, resource, monitor);
} catch (CoreException e) {
CodanUIActivator.log(e);
}
}
private static void removeMarkersForDisabledProblems(CheckersRegistry chegistry,
Set<String> markerTypes, IResource resource, IProgressMonitor monitor) throws CoreException {
if (!resource.isAccessible()) {
return;
}
IResource[] children = null;
if (resource instanceof IContainer) {
children = ((IContainer) resource).members();
}
int numChildren = children == null ? 0 : children.length;
int childWeight = 10;
SubMonitor progress = SubMonitor.convert(monitor, 1 + numChildren * childWeight);
IProblemProfile resourceProfile = null;
for (String markerType : markerTypes) {
IMarker[] markers = resource.findMarkers(markerType, false, IResource.DEPTH_ZERO);
for (IMarker marker : markers) {
String problemId = (String) marker.getAttribute(ICodanProblemMarker.ID);
if (resourceProfile == null) {
resourceProfile = chegistry.getResourceProfile(resource);
}
IProblem problem = resourceProfile.findProblem(problemId);
if (problem != null && !problem.isEnabled()) {
marker.delete();
}
}
}
progress.worked(1);
if (children != null) {
for (IResource child : children) {
if (monitor.isCanceled())
return;
removeMarkersForDisabledProblems(chegistry, markerTypes, child,
progress.newChild(childWeight));
}
}
}
}

View file

@ -15,7 +15,6 @@ import java.util.Arrays;
import java.util.List;
import org.eclipse.cdt.codan.core.param.FileScopeProblemPreference;
import org.eclipse.cdt.codan.internal.ui.CodanUIActivator;
import org.eclipse.cdt.codan.internal.ui.CodanUIMessages;
import org.eclipse.cdt.codan.internal.ui.dialogs.ExclusionInclusionEntryDialog;
import org.eclipse.cdt.codan.internal.ui.widgets.BasicElementLabels;
@ -33,7 +32,6 @@ import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.window.Window;
@ -43,7 +41,6 @@ import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
public class FileScopePreferencePage extends PreferencePage {
private ListDialogField<String> fInclusionPatternList;
@ -106,18 +103,13 @@ public class FileScopePreferencePage extends PreferencePage {
}
private static class ExclusionInclusionLabelProvider extends LabelProvider {
private Image fElementImage;
public ExclusionInclusionLabelProvider(String descriptorPath) {
if (descriptorPath != null) {
ImageDescriptor d = CodanUIActivator.getImageDescriptor(descriptorPath);
}
fElementImage = null; // XXX
}
@Override
public Image getImage(Object element) {
return fElementImage;
return null;
}
@Override
@ -126,10 +118,11 @@ public class FileScopePreferencePage extends PreferencePage {
}
}
private ListDialogField<String> createListContents(FileScopeProblemPreference entryToEdit, String key, String label, String descriptor,
String[] buttonLabels) {
private ListDialogField<String> createListContents(FileScopeProblemPreference entryToEdit,
String key, String label, String descriptor, String[] buttonLabels) {
ExclusionPatternAdapter adapter = new ExclusionPatternAdapter();
ListDialogField<String> patternList = new ListDialogField<String>(adapter, buttonLabels, new ExclusionInclusionLabelProvider(descriptor));
ListDialogField<String> patternList =
new ListDialogField<String>(adapter, buttonLabels, new ExclusionInclusionLabelProvider(descriptor));
patternList.setDialogFieldListener(adapter);
patternList.setLabelText(label);
patternList.enableButton(IDX_EDIT, false);
@ -265,12 +258,6 @@ public class FileScopePreferencePage extends PreferencePage {
return getPattern(fInclusionPatternList);
}
/*
* @see org.eclipse.jface.window.Window#configureShell(Shell)
*/
protected void configureShell(Shell newShell) {
}
private void addMultipleEntries(ListDialogField<String> field) {
String title, message;
if (isExclusion(field)) {
@ -280,7 +267,8 @@ public class FileScopePreferencePage extends PreferencePage {
title = CodanUIMessages.ExclusionInclusionDialog_ChooseInclusionPattern_title;
message = CodanUIMessages.ExclusionInclusionDialog_ChooseInclusionPattern_description;
}
IPath[] res = ExclusionInclusionEntryDialog.chooseExclusionPattern(getShell(), fCurrSourceFolder, title, message, null, true);
IPath[] res = ExclusionInclusionEntryDialog.chooseExclusionPattern(getShell(),
fCurrSourceFolder, title, message, null, true);
if (res != null) {
for (int i = 0; i < res.length; i++) {
field.addElement(res[i].toString());

View file

@ -587,8 +587,8 @@ public class AST2BaseTest extends BaseTestCase {
return problemBinding;
}
public <T extends IBinding> T assertNonProblemOnFirstIdentifier(String section, Class<T> type, Class... cs) {
return assertNonProblem(section, getIdentifierLength(section), type, cs);
public <T extends IBinding> T assertNonProblemOnFirstIdentifier(String section, Class... cs) {
return assertNonProblem(section, getIdentifierLength(section), cs);
}
public IBinding assertNonProblemOnFirstIdentifier(String section) {
@ -678,7 +678,7 @@ public class AST2BaseTest extends BaseTestCase {
return selector.findImplicitName(offset, len);
}
public <T extends IASTNode> T assertNode(String context, String nodeText, Class<T> type, Class... cs) {
public <T extends IASTNode> T assertNode(String context, String nodeText, Class... cs) {
if (context == null) {
context = contents;
}
@ -688,11 +688,11 @@ public class AST2BaseTest extends BaseTestCase {
assertTrue("Node \"" + nodeText + "\" not found", nodeOffset >= 0);
IASTNodeSelector selector = tu.getNodeSelector(null);
IASTNode node = selector.findNode(offset + nodeOffset, nodeText.length());
return assertType(node, type, cs);
return assertType(node, cs);
}
public <T extends IASTNode> T assertNode(String nodeText, Class<T> type, Class... cs) {
return assertNode(contents, nodeText, type, cs);
public <T extends IASTNode> T assertNode(String nodeText, Class... cs) {
return assertNode(contents, nodeText, cs);
}
private String renderProblemID(int i) {
@ -713,31 +713,30 @@ public class AST2BaseTest extends BaseTestCase {
return "Unknown problem ID";
}
public <T extends IBinding> T assertNonProblem(String section, int len, Class<T> type, Class... cs) {
public <T extends IBinding> T assertNonProblem(String section, int len, Class... cs) {
if (len <= 0)
len += section.length();
IBinding binding= binding(section, len);
assertTrue("ProblemBinding for name: " + section.substring(0, len),
!(binding instanceof IProblemBinding));
return assertType(binding, type, cs);
return assertType(binding, cs);
}
public <T extends IBinding> T assertNonProblem(String section, Class<T> type, Class... cs) {
return assertNonProblem(section, section.length(), type, cs);
public <T extends IBinding> T assertNonProblem(String section, Class... cs) {
return assertNonProblem(section, section.length(), cs);
}
public <T extends IBinding> T assertNonProblem(String context, String name, Class<T> type, Class... cs) {
public <T extends IBinding> T assertNonProblem(String context, String name, Class... cs) {
IBinding binding= binding(context, name);
assertTrue("ProblemBinding for name: " + name, !(binding instanceof IProblemBinding));
return assertType(binding, type, cs);
return assertType(binding, cs);
}
public <T, U extends T> U assertType(T obj, Class<U> type, Class... cs) {
assertInstance(obj, type);
public <T, U extends T> U assertType(T obj, Class... cs) {
for (Class c : cs) {
assertInstance(obj, c);
}
return type.cast(obj);
return (U) obj;
}
private IBinding binding(String section, int len) {

View file

@ -261,6 +261,7 @@ public class AST2CPPTests extends AST2BaseTest {
assertEquals(defNames.length, j);
}
@Override
protected void assertSameType(IType first, IType second){
assertNotNull(first);
assertNotNull(second);
@ -8404,6 +8405,7 @@ public class AST2CPPTests extends AST2BaseTest {
// }
// struct A {};
// A a;
// auto c(a);
// auto b = a;
// const auto *p = &b, q = "";
// static auto d = 0.0;
@ -8417,6 +8419,8 @@ public class AST2CPPTests extends AST2BaseTest {
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
ICPPVariable b= bh.assertNonProblem("b =", 1);
assertEquals("A", ASTTypeUtil.getType(b.getType()));
ICPPVariable c= bh.assertNonProblem("c(a)", "c");
assertEquals("A", ASTTypeUtil.getType(c.getType()));
ICPPVariable p= bh.assertNonProblem("p =", 1);
assertEquals("const A *", ASTTypeUtil.getType(p.getType()));
ICPPVariable q= bh.assertNonProblem("q =", 1);
@ -10079,4 +10083,42 @@ public class AST2CPPTests extends AST2BaseTest {
helper.assertNonProblemOnFirstIdentifier("fint({vbool");
helper.assertNonProblemOnFirstIdentifier("fint({vchar");
}
// namespace std {
// struct string {};
// struct exception {};
// }
// void f(){}
//
// int problemA(int i) {
// return i ? throw 7 : i;
// }
// int problemB(int i) {
// return i ? throw std::string{} : i;
// }
// void ploblemC(int i) {
// return i ? throw std::exception() : throw 3;
// }
// void ploblemD(int i) {
// return i ? throw std::exception() : f();
// }
// std::string ploblemE(int i) {
// return i ? throw 3 : "a";
// }
// std::string ploblemF(int i) {
// return (i<2 ? throw 2 : "x") ? (i>2 ? throw 3 : "d") : (i>22 ? throw 4 : "e");
// }
// auto ploblemG(int i) ->decltype(i ? throw 3 : "d"){
// return i ? throw 3 : "d" ;
// }
// void fine1(int i) {
// return i ? f() : f();
// }
// std::string fine2(int i) {
// return i ? "a" : "b";
// }
public void testThrowExpressionInConditional_396663() throws Exception {
parseAndCheckBindings(getAboveComment(), CPP, true);
}
}

View file

@ -4692,7 +4692,7 @@ public class AST2Tests extends AST2BaseTest {
// void test() {
// a= b ? : c;
// }
public void testOmittedPositiveExpression_Bug212905() throws Exception {
public void testOmittedPositiveExpression_212905() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C);
parseAndCheckBindings(code, ParserLanguage.CPP);
@ -4703,7 +4703,7 @@ public class AST2Tests extends AST2BaseTest {
// static __inline__ __u32 f(int x) {
// return x;
// }
public void testRedefinedGCCKeywords_Bug226112() throws Exception {
public void testRedefinedGCCKeywords_226112() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true);
@ -4711,7 +4711,7 @@ public class AST2Tests extends AST2BaseTest {
// int foo asm ("myfoo") __attribute__((__used__)), ff asm("ss") = 2;
// extern void func () asm ("FUNC") __attribute__((__used__));
public void testASMLabels_Bug226121() throws Exception {
public void testASMLabels_226121() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true);
@ -4720,7 +4720,7 @@ public class AST2Tests extends AST2BaseTest {
// void test() {
// ({1;}) != 0;
// }
public void testCompoundStatementExpression_Bug226274() throws Exception {
public void testCompoundStatementExpression_226274() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true);
@ -4730,7 +4730,7 @@ public class AST2Tests extends AST2BaseTest {
// __typeof__(count) a= 1;
// int ret0 = ((__typeof__(count)) 1);
// }
public void testTypeofUnaryExpression_Bug226492() throws Exception {
public void testTypeofUnaryExpression_226492() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true);
@ -4739,7 +4739,7 @@ public class AST2Tests extends AST2BaseTest {
// void test(int count) {
// typeof(count==1) a= 1;
// }
public void testTypeofExpression_Bug226492() throws Exception {
public void testTypeofExpression_226492() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true);
@ -4748,7 +4748,7 @@ public class AST2Tests extends AST2BaseTest {
// void func() {
// typeof(__attribute__((regparm(3)))void (*)(int *)) a;
// }
public void testTypeofExpressionWithAttribute_Bug226492() throws Exception {
public void testTypeofExpressionWithAttribute_226492() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true);
@ -4759,7 +4759,7 @@ public class AST2Tests extends AST2BaseTest {
// case 1 ... 3: break;
// }
// }
public void testCaseRange_Bug211882() throws Exception {
public void testCaseRange_211882() throws Exception {
final String code = getAboveComment();
{
IASTTranslationUnit tu = parseAndCheckBindings(code, ParserLanguage.C, true);
@ -4786,7 +4786,7 @@ public class AST2Tests extends AST2BaseTest {
// typedef int* TIntPtr;
// int x(int (int * a));
// int x(int(TIntPtr));
public void testInfiniteRecursion_Bug269052() throws Exception {
public void testInfiniteRecursion_269052() throws Exception {
final String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true);
@ -4803,7 +4803,7 @@ public class AST2Tests extends AST2BaseTest {
}
// struct __attribute__((declspec)) bla;
public void testAttributeInElaboratedTypeSpecifier_Bug227085() throws Exception {
public void testAttributeInElaboratedTypeSpecifier_227085() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true);
@ -4811,14 +4811,14 @@ public class AST2Tests extends AST2BaseTest {
// struct X;
// void test(struct X* __restrict result);
public void testRestrictReference_Bug227110() throws Exception {
public void testRestrictReference_227110() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP, true);
}
// char buf[256];
// int x= sizeof(buf)[0];
public void testSizeofUnaryWithParenthesis_Bug227122() throws Exception {
public void testSizeofUnaryWithParenthesis_227122() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C);
parseAndCheckBindings(code, ParserLanguage.CPP);
@ -4833,7 +4833,7 @@ public class AST2Tests extends AST2BaseTest {
// void test1() {
// X* it = buffer == 0 ? new (buffer) X : 0;
// }
public void testPlacementNewInConditionalExpression_Bug227104() throws Exception {
public void testPlacementNewInConditionalExpression_227104() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
}
@ -4910,7 +4910,7 @@ public class AST2Tests extends AST2BaseTest {
// void function2() {
// function1(); // ref
// }
public void testOutOfOrderResolution_Bug232300() throws Exception {
public void testOutOfOrderResolution_232300() throws Exception {
String code= getAboveComment();
for (ParserLanguage lang: ParserLanguage.values()) {
BindingAssertionHelper ba= new BindingAssertionHelper(code, lang);
@ -4924,7 +4924,7 @@ public class AST2Tests extends AST2BaseTest {
// #define foo __typeof__((int*)0 - (int*)0)
// typedef foo ptrdiff_t;
public void testRedefinePtrdiff_Bug230895() throws Exception {
public void testRedefinePtrdiff_230895() throws Exception {
String code= getAboveComment();
for (ParserLanguage lang: ParserLanguage.values()) {
BindingAssertionHelper ba= new BindingAssertionHelper(code, lang);
@ -4958,7 +4958,7 @@ public class AST2Tests extends AST2BaseTest {
// void test() {
// checkLong(__builtin_expect(1, 1));
// }
public void testReturnTypeOfBuiltin_Bug234309() throws Exception {
public void testReturnTypeOfBuiltin_234309() throws Exception {
String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true);
@ -4967,7 +4967,7 @@ public class AST2Tests extends AST2BaseTest {
// typedef void VOID;
// VOID func(VOID) {
// }
public void testTypedefVoid_Bug221567() throws Exception {
public void testTypedefVoid_221567() throws Exception {
String code= getAboveComment();
for (ParserLanguage lang: ParserLanguage.values()) {
BindingAssertionHelper ba= new BindingAssertionHelper(code, lang);
@ -4999,7 +4999,7 @@ public class AST2Tests extends AST2BaseTest {
// printf(str(this is a // this should go away
// string));
// }
public void testCommentInExpansion_Bug84276() throws Exception {
public void testCommentInExpansion_84276() throws Exception {
IASTTranslationUnit tu= parseAndCheckBindings(getAboveComment());
IASTFunctionDefinition func= (IASTFunctionDefinition) tu.getDeclarations()[0];
@ -5014,7 +5014,7 @@ public class AST2Tests extends AST2BaseTest {
// int f3(int (tint));
// int f4(int (identifier));
// int f5(int *(tint[10]));
public void testParamWithFunctionType_Bug84242() throws Exception {
public void testParamWithFunctionType_84242() throws Exception {
final String comment= getAboveComment();
for (ParserLanguage lang: ParserLanguage.values()) {
BindingAssertionHelper ba= new BindingAssertionHelper(comment, lang);
@ -5038,7 +5038,7 @@ public class AST2Tests extends AST2BaseTest {
// class C { };
// void f1(int(C)) { }
public void testParamWithFunctionTypeCpp_Bug84242() throws Exception {
public void testParamWithFunctionTypeCpp_84242() throws Exception {
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
IFunction f= ba.assertNonProblem("f1", 2, IFunction.class);
@ -5047,7 +5047,7 @@ public class AST2Tests extends AST2BaseTest {
// int (*f1(int par))[5] {};
// int (*f1 (int par))[5];
public void testFunctionReturningPtrToArray_Bug216609() throws Exception {
public void testFunctionReturningPtrToArray_216609() throws Exception {
final String comment= getAboveComment();
for (ParserLanguage lang: ParserLanguage.values()) {
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), lang);
@ -5122,7 +5122,7 @@ public class AST2Tests extends AST2BaseTest {
// int a,b;
// { b; a; int a; }
// }
public void testLocalVariableResolution_Bug235831() throws Exception {
public void testLocalVariableResolution_235831() throws Exception {
final String comment= getAboveComment();
final boolean[] isCpps= {false, true};
for (ParserLanguage lang: ParserLanguage.values()) {
@ -5138,7 +5138,7 @@ public class AST2Tests extends AST2BaseTest {
}
// int foo(int (*ptr) (int, int));
public void testComplexParameterBinding_Bug214482() throws Exception {
public void testComplexParameterBinding_214482() throws Exception {
final String comment= getAboveComment();
for (ParserLanguage lang: ParserLanguage.values()) {
BindingAssertionHelper ba= new BindingAssertionHelper(comment, lang);
@ -5216,7 +5216,7 @@ public class AST2Tests extends AST2BaseTest {
// foux= 0;
// foux= 1;
// }
public void testSwitchWithoutCompound_Bug105334() throws Exception {
public void testSwitchWithoutCompound_105334() throws Exception {
final String comment= getAboveComment();
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit tu= parse(comment, lang);
@ -5251,7 +5251,7 @@ public class AST2Tests extends AST2BaseTest {
// a*a*(t)+a*a*a // a,a,*,t,a,unary+,cast,*,a,*,a,*
// (typeof a)(t)-a // typeof a,t,a,unary-,cast,cast
// (typeof a)(a)-a // typeof a,a,cast,a,-
public void testBinaryVsCastAmbiguities_Bug237057() throws Exception {
public void testBinaryVsCastAmbiguities_237057() throws Exception {
CharSequence[] input= getContents(2);
String code= input[0].toString();
String[] samples= input[1].toString().split("\n");
@ -5291,7 +5291,7 @@ public class AST2Tests extends AST2BaseTest {
// (t)(a)+1 // t,a,cast,1,+
// (f)(a)+1 // f,a,(),1,+
// (t)(t)+1 // t,t,1,unary+,cast,cast
public void testCastVsFunctionCallAmbiguities_Bug237057() throws Exception {
public void testCastVsFunctionCallAmbiguities_237057() throws Exception {
CharSequence[] input= getContents(2);
String code= input[0].toString();
String[] samples= input[1].toString().split("\n");
@ -5488,13 +5488,13 @@ public class AST2Tests extends AST2BaseTest {
// int x;
// } spinlock_t;
// spinlock_t _lock = (spinlock_t) { };
public void testCompoundInitializer_bug145387() throws Exception {
public void testCompoundInitializer_145387() throws Exception {
// valid in C99, not in C++.
parseAndCheckBindings(getAboveComment(), ParserLanguage.C, true);
}
// enum __declspec(uuid("uuid")) bla { a, b};
public void testDeclspecInEnumSpecifier_bug241203() throws Exception {
public void testDeclspecInEnumSpecifier_241203() throws Exception {
for (ParserLanguage lang : ParserLanguage.values()) {
parseAndCheckBindings(getAboveComment(), lang, true);
}
@ -5523,7 +5523,7 @@ public class AST2Tests extends AST2BaseTest {
// if (__builtin_types_compatible_p(typeof(p), char[])) {
// }
// }
public void testBuiltinTypesCompatible_bug241570() throws Exception {
public void testBuiltinTypesCompatible_241570() throws Exception {
for (ParserLanguage lang : ParserLanguage.values()) {
parseAndCheckBindings(getAboveComment(), lang, true);
}
@ -5533,7 +5533,7 @@ public class AST2Tests extends AST2BaseTest {
// void test() {
// alloc(__func__);
// }
public void testPredefinedFunctionName_Bug247747() throws Exception {
public void testPredefinedFunctionName_247747() throws Exception {
parseAndCheckBindings(getAboveComment(), ParserLanguage.C, false);
parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP, false);
}
@ -5544,7 +5544,7 @@ public class AST2Tests extends AST2BaseTest {
// alloc(__FUNCTION__);
// alloc(__PRETTY_FUNCTION__);
// }
public void testPredefinedFunctionNameGcc_Bug247747() throws Exception {
public void testPredefinedFunctionNameGcc_247747() throws Exception {
parseAndCheckBindings(getAboveComment(), ParserLanguage.C, true);
parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP, true);
}
@ -5552,7 +5552,7 @@ public class AST2Tests extends AST2BaseTest {
// int foo = 42;
// typedef char StupidType;
// StupidType const *bar = (StupidType const*)&foo;
public void testUnusualDeclSpecOrdering_Bug251514() throws Exception {
public void testUnusualDeclSpecOrdering_251514() throws Exception {
parseAndCheckBindings(getAboveComment(), ParserLanguage.C, true);
parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP, true);
}
@ -5563,7 +5563,7 @@ public class AST2Tests extends AST2BaseTest {
// #define SEMI_IF ; if
// #define IF_COND if (1)
// void test() {
public void testLeadingSyntax_Bug250251() throws Exception {
public void testLeadingSyntax_250251() throws Exception {
String code= getAboveComment();
IASTTranslationUnit tu= parseAndCheckBindings(code + "if (1) {};}");
@ -5629,7 +5629,7 @@ public class AST2Tests extends AST2BaseTest {
// #define P_BLOCK ){}
// #define IF_COND if (1)
// void test() {
public void testTrailingSyntax_Bug250251() throws Exception {
public void testTrailingSyntax_250251() throws Exception {
String code= getAboveComment();
IASTTranslationUnit tu= parseAndCheckBindings(code + "if (1) {};}");
@ -5693,7 +5693,7 @@ public class AST2Tests extends AST2BaseTest {
// #define SEMI_IF ; if
// #define IF_COND if (1)
// void test() {
public void testSyntax_Bug250251() throws Exception {
public void testSyntax_250251() throws Exception {
String code= getAboveComment();
IASTTranslationUnit tu= parseAndCheckBindings(code + "if (1) {};}");
@ -5751,7 +5751,7 @@ public class AST2Tests extends AST2BaseTest {
// <<
// y;
// }
public void testSyntaxWithNL_Bug280175() throws Exception {
public void testSyntaxWithNL_280175() throws Exception {
String code= getAboveComment();
int offsetX= code.indexOf('x', code.indexOf('x')+1);
int offsetShift= code.indexOf('<');
@ -5819,7 +5819,7 @@ public class AST2Tests extends AST2BaseTest {
// void caller() {
// myfunc("");
// }
public void testReferencesInInitializer_Bug251514() throws Exception {
public void testReferencesInInitializer_251514() throws Exception {
final String code = getAboveComment();
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit tu= parseAndCheckBindings(code, lang, true);
@ -5832,7 +5832,7 @@ public class AST2Tests extends AST2BaseTest {
// void test() {
// const void* p = &"string";
// }
public void testAdressOfStringLiteral_Bug252970() throws Exception {
public void testAdressOfStringLiteral_252970() throws Exception {
final String code = getAboveComment();
for (ParserLanguage lang : ParserLanguage.values()) {
parseAndCheckBindings(code, lang);
@ -5844,7 +5844,7 @@ public class AST2Tests extends AST2BaseTest {
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// };
public void testScalabilityOfLargeTrivialInitializer_Bug253690() throws Exception {
public void testScalabilityOfLargeTrivialInitializer_253690() throws Exception {
sValidateCopy= false;
final int AMOUNT= 250000;
final CharSequence[] input = getContents(3);
@ -5877,7 +5877,7 @@ public class AST2Tests extends AST2BaseTest {
// }
// };
public void testLargeTrivialAggregateInitializer_Bug253690() throws Exception {
public void testLargeTrivialAggregateInitializer_253690() throws Exception {
sValidateCopy= false;
final int AMOUNT= 250000;
final CharSequence[] input = getContents(3);
@ -5916,7 +5916,7 @@ public class AST2Tests extends AST2BaseTest {
// int n= 0;
// int a[]= {0x00, sizeof(n)};
public void testNonTrivialInitializer_Bug253690() throws Exception {
public void testNonTrivialInitializer_253690() throws Exception {
final String code= getAboveComment();
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit tu= parse(code, lang, false, true, true);
@ -5930,7 +5930,7 @@ public class AST2Tests extends AST2BaseTest {
// void test() {
// const void* p = 1+2;
// }
public void testGetChildren_Bug256127() throws Exception {
public void testGetChildren_256127() throws Exception {
final String code = getAboveComment();
for (ParserLanguage lang : ParserLanguage.values()) {
IASTNode node= parseAndCheckBindings(code, lang);
@ -5976,7 +5976,7 @@ public class AST2Tests extends AST2BaseTest {
// struct s v;
// v.mem = 1;
// }
public void testNestedDeclarator_Bug257540() throws Exception {
public void testNestedDeclarator_257540() throws Exception {
final String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C);
parseAndCheckBindings(code, ParserLanguage.CPP);
@ -5990,7 +5990,7 @@ public class AST2Tests extends AST2BaseTest {
// cs foo;
// foo = ((cs) {1.2,1});
// }
public void testCompoundLiterals_Bug258496() throws Exception {
public void testCompoundLiterals_258496() throws Exception {
final String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C);
parseAndCheckBindings(code, ParserLanguage.CPP);
@ -5999,7 +5999,7 @@ public class AST2Tests extends AST2BaseTest {
// __thread int i;
// static __thread int j;
// extern __thread int k;
public void testThreadLocalVariables_Bug260387() throws Exception {
public void testThreadLocalVariables_260387() throws Exception {
final String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true);
@ -6009,7 +6009,7 @@ public class AST2Tests extends AST2BaseTest {
// int a,b;
// if ((a)+b);
// }
public void testAmbiguityResolutionInIfCondition_Bug261043() throws Exception {
public void testAmbiguityResolutionInIfCondition_261043() throws Exception {
final String code= getAboveComment();
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit tu= parseAndCheckBindings(code, lang, true);
@ -6025,7 +6025,7 @@ public class AST2Tests extends AST2BaseTest {
// const TInt; // declaration without name
// const a; // declares a;
// };
public void testAmbiguousDeclaration_Bug259373() throws Exception {
public void testAmbiguousDeclaration_259373() throws Exception {
final String code= getAboveComment();
IASTTranslationUnit tu= parseAndCheckBindings(code, ParserLanguage.C, true);
BindingAssertionHelper bh= new BindingAssertionHelper(code, false);
@ -6047,7 +6047,7 @@ public class AST2Tests extends AST2BaseTest {
// pg->glob= 0;
// pl->loc= 1;
// }
public void testLocalVsGlobalStruct_Bug255973() throws Exception {
public void testLocalVsGlobalStruct_255973() throws Exception {
final String code= getAboveComment();
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit tu= parseAndCheckBindings(code, lang, true);
@ -7363,7 +7363,7 @@ public class AST2Tests extends AST2BaseTest {
// sizeof(10); // wrong - getExpressionType returns float
// sizeof(int); // wrong - getExpressionType returns float
// }
public void testTypeOfSizeof_Bug355052() throws Exception {
public void testTypeOfSizeof_355052() throws Exception {
final String code = getAboveComment();
IASTTranslationUnit tu= parseAndCheckBindings(code, ParserLanguage.CPP);
IASTFunctionDefinition a= getDeclaration(tu, 0);
@ -7384,12 +7384,12 @@ public class AST2Tests extends AST2BaseTest {
// typedef int foobar_t;
// foobar_t *a = 0, *b = a;
// }
public void testAmbiguousStatement_Bug360541() throws Exception {
public void testAmbiguousStatement_360541() throws Exception {
parseAndCheckBindings();
}
// typedef int T[sizeof(int)];
public void testSizeofExpression_Bug362464() throws Exception {
public void testSizeofExpression_362464() throws Exception {
String code= getAboveComment();
for (ParserLanguage l : ParserLanguage.values()) {
IASTTranslationUnit tu= parseAndCheckBindings(code, l);
@ -7411,4 +7411,13 @@ public class AST2Tests extends AST2BaseTest {
assertEquals("//comment", new String(comment.getComment()));
assertEquals("//comment", comment.getRawSignature());
}
// template<typename T>
// void test(T n) {
// for (__decltype(n + 0) i = 0; i < n; i++) {
// }
// }
public void testGCCDecltype_397227() throws Exception {
parseAndCheckBindings(getAboveComment(), CPP, true);
}
}

View file

@ -72,6 +72,108 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
suite.addTest(ProjectWithDepProj.suite());
}
/* Assertion helpers */
/* ##################################################################### */
static protected void assertField(
IBinding binding,
String qn,
Class expType,
String expTypeQN) {
assertTrue(binding instanceof ICPPField);
ICPPField field = (ICPPField) binding;
assertQNEquals(qn, field);
assertTrue(expType.isInstance(field.getType()));
if (expTypeQN != null) {
assert(field.getType() instanceof ICPPBinding);
ICPPBinding tyBinding = (ICPPBinding) field.getType();
assertQNEquals(expTypeQN, tyBinding);
}
}
static protected void assertClassTypeBinding(IBinding binding,
String qn,
int key,
int bases,
int fields,
int declaredFields,
int methods,
int declaredMethods,
int allDeclaredMethods,
int friends,
int constructors,
int nestedClasses) {
assertTrue(binding instanceof ICPPClassType);
assertClassType((ICPPClassType) binding, qn, key, bases, fields, declaredFields, methods,
declaredMethods, allDeclaredMethods, friends, constructors, nestedClasses);
}
static protected void assertClassType(
IType type,
String qn,
int key,
int bases,
int fields,
int declaredFields,
int methods,
int declaredMethods,
int allDeclaredMethods,
int friends,
int constructors,
int nestedClasses) {
assertTrue(type instanceof ICPPClassType);
ICPPClassType classType = (ICPPClassType) type;
assertQNEquals(qn, classType);
assertEquals(key, classType.getKey());
assertEquals(bases, classType.getBases().length);
assertEquals(fields, classType.getFields().length);
assertEquals(declaredFields, classType.getDeclaredFields().length);
assertEquals(methods, classType.getMethods().length);
assertEquals(declaredMethods, classType.getDeclaredMethods().length);
assertEquals(allDeclaredMethods, classType.getAllDeclaredMethods().length);
assertEquals(friends, classType.getFriends().length);
assertEquals(constructors, classType.getConstructors().length);
assertEquals(nestedClasses, classType.getNestedClasses().length);
}
public void assertEnumeration(IBinding binding, String name, String[] enumerators) throws DOMException {
assertTrue(binding instanceof IEnumeration);
assertEquals(name, binding.getName());
IEnumerator[] aEnumerators = ((IEnumeration)binding).getEnumerators();
Set expectedEnumerators = new HashSet();
expectedEnumerators.addAll(Arrays.asList(enumerators));
Set actualEnumerators = new HashSet();
for (IEnumerator enumerator : aEnumerators) {
actualEnumerators.add(enumerator.getName());
}
assertEquals(expectedEnumerators, actualEnumerators);
}
/**
* @param type
* @param cqn
* @param qn may be null
*/
static protected void assertPTM(IType type, String cqn, String qn) {
assertTrue(type instanceof ICPPPointerToMemberType);
ICPPPointerToMemberType ptmt = (ICPPPointerToMemberType) type;
ICPPClassType classType = (ICPPClassType) ptmt.getMemberOfClass();
assertQNEquals(cqn, classType);
if (qn != null) {
assert(ptmt.getType() instanceof ICPPBinding);
ICPPBinding tyBinding = (ICPPBinding) ptmt.getType();
assertQNEquals(qn, tyBinding);
}
}
private void asserValueEquals(IValue initialValue, long i) {
assertNotNull(initialValue);
final Long numericalValue = initialValue.numericalValue();
assertNotNull(numericalValue);
assertEquals(i, numericalValue.longValue());
}
// namespace ns { class A; enum E {E1}; typedef int T; }
//
// class B {
@ -1614,104 +1716,26 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
getBindingFromASTName("g(b)", 1, ICPPFunction.class);
}
/* CPP assertion helpers */
/* ##################################################################### */
// namespace ns {
// namespace {
// const char str[] = "";
// }
// }
static protected void assertField(
IBinding binding,
String qn,
Class expType,
String expTypeQN) {
assertTrue(binding instanceof ICPPField);
ICPPField field = (ICPPField) binding;
assertQNEquals(qn, field);
assertTrue(expType.isInstance(field.getType()));
if (expTypeQN != null) {
assert(field.getType() instanceof ICPPBinding);
ICPPBinding tyBinding = (ICPPBinding) field.getType();
assertQNEquals(expTypeQN, tyBinding);
}
}
static protected void assertClassTypeBinding(IBinding binding,
String qn,
int key,
int bases,
int fields,
int declaredFields,
int methods,
int declaredMethods,
int allDeclaredMethods,
int friends,
int constructors,
int nestedClasses) {
assertTrue(binding instanceof ICPPClassType);
assertClassType((ICPPClassType) binding, qn, key, bases, fields, declaredFields, methods,
declaredMethods, allDeclaredMethods, friends, constructors, nestedClasses);
}
static protected void assertClassType(
IType type,
String qn,
int key,
int bases,
int fields,
int declaredFields,
int methods,
int declaredMethods,
int allDeclaredMethods,
int friends,
int constructors,
int nestedClasses) {
assertTrue(type instanceof ICPPClassType);
ICPPClassType classType = (ICPPClassType) type;
assertQNEquals(qn, classType);
assertEquals(key, classType.getKey());
assertEquals(bases, classType.getBases().length);
assertEquals(fields, classType.getFields().length);
assertEquals(declaredFields, classType.getDeclaredFields().length);
assertEquals(methods, classType.getMethods().length);
assertEquals(declaredMethods, classType.getDeclaredMethods().length);
assertEquals(allDeclaredMethods, classType.getAllDeclaredMethods().length);
assertEquals(friends, classType.getFriends().length);
assertEquals(constructors, classType.getConstructors().length);
assertEquals(nestedClasses, classType.getNestedClasses().length);
}
public void assertEnumeration(IBinding binding, String name, String[] enumerators) throws DOMException {
assertTrue(binding instanceof IEnumeration);
assertEquals(name, binding.getName());
IEnumerator[] aEnumerators = ((IEnumeration)binding).getEnumerators();
Set expectedEnumerators = new HashSet();
expectedEnumerators.addAll(Arrays.asList(enumerators));
Set actualEnumerators = new HashSet();
for (IEnumerator enumerator : aEnumerators) {
actualEnumerators.add(enumerator.getName());
}
assertEquals(expectedEnumerators, actualEnumerators);
}
/**
* @param type
* @param cqn
* @param qn may be null
*/
static protected void assertPTM(IType type, String cqn, String qn) {
assertTrue(type instanceof ICPPPointerToMemberType);
ICPPPointerToMemberType ptmt = (ICPPPointerToMemberType) type;
ICPPClassType classType = (ICPPClassType) ptmt.getMemberOfClass();
assertQNEquals(cqn, classType);
if (qn != null) {
assert(ptmt.getType() instanceof ICPPBinding);
ICPPBinding tyBinding = (ICPPBinding) ptmt.getType();
assertQNEquals(qn, tyBinding);
}
}
private void asserValueEquals(IValue initialValue, long i) {
assertNotNull(initialValue);
final Long numericalValue = initialValue.numericalValue();
assertNotNull(numericalValue);
assertEquals(i, numericalValue.longValue());
// namespace {
// const char str[] = "";
// }
//
// namespace ns {
//
// void f(const char* s);
//
// void test() {
// f(str);
// }
//
// }
public void testAnonymousNamespaces_392577() throws Exception {
getBindingFromASTName("f(str)", 1, ICPPFunction.class);
}
}

View file

@ -87,15 +87,15 @@ public class DBTest extends BaseTestCase {
try {
new Database(tmp, ChunkCache.getSharedInstance(), 0, false);
fail("A readonly file should not be openable with write-access");
} catch(CoreException ioe) {
} catch (CoreException e) {
// we expect to get a failure here
}
/* check opening a readonly file for read access does not fail */
try {
new Database(tmp, ChunkCache.getSharedInstance(), 0, true);
} catch(CoreException ce) {
fail("A readonly file should be readable by a permanently readonly database "+ce);
} catch (CoreException e) {
fail("A readonly file should be readable by a permanently readonly database "+e);
}
} finally {
tmp.delete(); // this may be pointless on some platforms
@ -150,7 +150,6 @@ public class DBTest extends BaseTestCase {
public long getRecord() {
return record;
}
}
public void testStringsInBTree() throws Exception {
@ -194,6 +193,7 @@ public class DBTest extends BaseTestCase {
return string1.compare(string2, true);
}
};
BTree btree = new BTree(db, Database.DATA_AREA, comparator);
for (int i = 0; i < names.length; ++i) {
String name = names[i];

View file

@ -8,7 +8,6 @@
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.pdom.tests;
import java.util.regex.Pattern;
@ -32,8 +31,7 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
/**
* Tests for verifying whether the PDOM correctly stores information about
* C++ namespaces.
* Tests for verifying whether the PDOM correctly stores information about C++ namespaces.
*
* @author Vivian Kong
*/
@ -65,7 +63,7 @@ public class NamespaceTests extends PDOMTestBase {
}
public void testAlias() throws Exception {
/* Find all the namespace */
// Find all the namespace
IBinding[] namespaces = pdom.findBindings(Pattern.compile("namespace1"), false, INDEX_FILTER, NULL_MONITOR);
assertEquals(1, namespaces.length);
assertTrue(namespaces[0] instanceof ICPPNamespace);
@ -88,18 +86,15 @@ public class NamespaceTests extends PDOMTestBase {
}
public void testNested() throws Exception {
/* Find deeply nested namespace */
// Find deeply nested namespace
Pattern[] patterns = {Pattern.compile("namespace1"), Pattern.compile("namespace2"), Pattern.compile("namespace3")};
IBinding[] namespaces = pdom.findBindings(patterns, false, INDEX_FILTER, NULL_MONITOR);
assertEquals(1, namespaces.length);
assertTrue(namespaces[0] instanceof ICPPNamespace);
}
public void testMemberDefinition() throws Exception {
/* Find the definition of a member declared in a namespace */
// Find the definition of a member declared in a namespace
Pattern[] patterns = {Pattern.compile("namespace1"), Pattern.compile("namespace2"), Pattern.compile("foo")};
IBinding[] members = pdom.findBindings(patterns, false, INDEX_FILTER, NULL_MONITOR);
assertEquals(1, members.length);
@ -114,12 +109,10 @@ public class NamespaceTests extends PDOMTestBase {
assertEquals(1, defs.length);
loc = defs[0].getFileLocation();
assertEquals(offset("namespace.cpp", "::foo()") + 2, loc.getNodeOffset()); // character offset
}
public void testExtend() throws Exception {
/* Extending a namespace */
// Extending a namespace
IBinding[] namespaces = pdom.findBindings(Pattern.compile("ns1"), false, INDEX_FILTER, NULL_MONITOR);
assertEquals(1, namespaces.length);
assertTrue(namespaces[0] instanceof ICPPNamespace);
@ -130,7 +123,6 @@ public class NamespaceTests extends PDOMTestBase {
}
public void testOverload() throws Exception {
// Function overloading in namespace
Pattern[] patterns = {Pattern.compile("ns3"), Pattern.compile("blah")};
IBinding[] functions = pdom.findBindings(patterns, false, INDEX_FILTER, NULL_MONITOR);
@ -152,12 +144,10 @@ public class NamespaceTests extends PDOMTestBase {
assertEquals(1, refs.length);
loc = refs[0].getFileLocation();
assertEquals(offset("overload.cpp", "blah('a')"), loc.getNodeOffset()); // character offset
}
public void testUnnamed() throws Exception {
// test case for Bugzilla 162226
/* Unnamed Namespace */
public void testUnnamed_162226() throws Exception {
// Unnamed Namespace
IBinding[] functions = pdom.findBindings(Pattern.compile("function1"), true, INDEX_FILTER, NULL_MONITOR);
assertEquals(1, functions.length);
assertTrue(functions[0] instanceof ICPPFunction);
@ -177,12 +167,10 @@ public class NamespaceTests extends PDOMTestBase {
assertEquals(1, refs.length);
loc = refs[0].getFileLocation();
assertEquals(offset("unnamed.cpp", "function1();"), loc.getNodeOffset()); // character offset
}
public void testFriend() throws Exception {
/* Friend in namespace - function2 is not in Class1*/
// Bugzilla 162011
public void testFriend_162011() throws Exception {
// Friend in namespace - function2 is not in Class1
IBinding[] functions = pdom.findBindings(Pattern.compile("function2"), false, INDEX_FILTER, NULL_MONITOR);
assertEquals(1, functions.length);
assertTrue(functions[0] instanceof ICPPFunction);
@ -202,7 +190,6 @@ public class NamespaceTests extends PDOMTestBase {
assertEquals(1, refs.length);
loc = refs[0].getFileLocation();
assertEquals(offset("friend.cpp", "ns4::function2(element)") + 5, loc.getNodeOffset()); // character offset
}
public void testUsingDirective() throws Exception {

View file

@ -70,7 +70,7 @@ Export-Package: org.eclipse.cdt.core,
org.eclipse.cdt.internal.core.indexer;x-internal:=true,
org.eclipse.cdt.internal.core.language;x-friends:="org.eclipse.cdt.ui",
org.eclipse.cdt.internal.core.language.settings.providers;x-internal:=true,
org.eclipse.cdt.internal.core.model;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.debug.core,org.eclipse.cdt.debug.ui",
org.eclipse.cdt.internal.core.model;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.debug.core,org.eclipse.cdt.debug.ui,org.eclipse.cdt.codan.ui",
org.eclipse.cdt.internal.core.model.ext;x-friends:="org.eclipse.cdt.ui",
org.eclipse.cdt.internal.core.parser;x-internal:=true,
org.eclipse.cdt.internal.core.parser.problem;x-internal:=true,

View file

@ -10,8 +10,6 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.model;
import java.util.HashMap;
import java.util.Map;
@ -19,7 +17,6 @@ import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.IOpenable;
import org.eclipse.cdt.internal.core.util.OverflowingLRUCache;
/**
* The cache of C elements to their respective info.
*
@ -122,6 +119,7 @@ protected void putInfo(ICElement element, Object info) {
this.childrenCache.put(element, info);
}
}
/**
* Removes the info of the element from the cache.
*/
@ -143,5 +141,4 @@ protected void removeInfo(ICElement element) {
this.childrenCache.remove(element);
}
}
}

View file

@ -10,7 +10,6 @@
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
/**
* An image location explains how a name made it into the translation unit.
* @since 5.0
@ -19,7 +18,6 @@ package org.eclipse.cdt.core.dom.ast;
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface IASTImageLocation extends IASTFileLocation {
/**
* The image is part of the code that has not been modified by the preprocessor.
*/
@ -34,8 +32,8 @@ public interface IASTImageLocation extends IASTFileLocation {
final int ARGUMENT_TO_MACRO_EXPANSION= 3;
/**
* Returns the kind of image-location, one of {@link #REGULAR_CODE}, {@link #MACRO_DEFINITION} or
* {@link #ARGUMENT_TO_MACRO_EXPANSION}.
* Returns the kind of image-location, one of {@link #REGULAR_CODE}, {@link #MACRO_DEFINITION}
* or {@link #ARGUMENT_TO_MACRO_EXPANSION}.
*/
public int getLocationKind();
}

View file

@ -57,7 +57,7 @@ public interface IASTName extends IASTNode, IName {
/**
* Get the role of this name. If the name needs to be resolved to determine that and
* <code>allowResolution</code> is set to <code>false</code>, then {@link IASTNameOwner#r_unclear}
* {@code allowResolution} is set to {@code false}, then {@link IASTNameOwner#r_unclear}
* is returned.
*
* @param allowResolution whether or not resolving the name is allowed.
@ -80,21 +80,24 @@ public interface IASTName extends IASTNode, IName {
public ILinkage getLinkage();
/**
* Returns the image location for this name or <code>null</code> if the information is not available.
* Returns the image location for this name or <code>null</code> if the information is not
* available.
* <p>
* An image location can be computed when the name is either found directly in the code, is (part of)
* an argument to a macro expansion or is (part of) a macro definition found in the source code.
* An image location can be computed when the name is either found directly in the code, is
* (part of) an argument to a macro expansion or is (part of) a macro definition found in
* the source code.
* <p>
* The image location is <code>null</code>, when the name consists of multiple tokens (qualified names)
* and the tokens are not found side by side in the code, or if the name is the result of
* a token-paste operation or the name is found in the definition of a built-in macro.
* The image location is <code>null</code>, when the name consists of multiple tokens
* (qualified names) and the tokens are not found side by side in the code, or if the name is
* the result of a token-paste operation or the name is found in the definition of a built-in
* macro.
* @since 5.0
*/
public IASTImageLocation getImageLocation();
/**
* For convenience this method returns the last name of a qualified name or this if this is not a
* qualified name.
* For convenience this method returns the last name of a qualified name or this if this is not
* a qualified name.
* @since 5.1
*/
public IASTName getLastName();

View file

@ -27,19 +27,20 @@ public interface IASTNodeSelector {
IASTName findName(int offset, int length);
/**
* Returns the smallest name enclosing the given range, or <code>null</code> if there is no such node.
* Will not return an implicit name.
* Returns the smallest name enclosing the given range, or <code>null</code> if there is
* no such node. Will not return an implicit name.
*/
IASTName findEnclosingName(int offset, int length);
/**
* Returns the first name contained in the given range, or <code>null</code> if there is no such node.
* Will not return an implicit name.
* Returns the first name contained in the given range, or <code>null</code> if there is
* no such node. Will not return an implicit name.
*/
IASTName findFirstContainedName(int offset, int length);
/**
* Returns the implicit name for the exact given range, or <code>null</code> if there is no such node.
* Returns the implicit name for the exact given range, or <code>null</code> if there is
* no such node.
*
* Note that there can be more than one implicit name in the same location.
* The implicit name's parent can be used to get all the names at the location.
@ -61,41 +62,45 @@ public interface IASTNodeSelector {
/**
* Returns the node for the exact given range, or <code>null</code> if there is no such node.
* <p>
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion}) are preferred
* over c/c++-nodes and children are preferred over their parents.
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion})
* are preferred over c/c++-nodes and children are preferred over their parents.
*/
IASTNode findNode(int offset, int length);
/**
* Returns the smallest node enclosing the given range, or <code>null</code> if there is no such node.
* Returns the smallest node enclosing the given range, or <code>null</code> if there is
* no such node.
* <p>
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion}) are preferred
* over c/c++-nodes nodes and children are preferred over their parents.
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion})
* are preferred over c/c++-nodes nodes and children are preferred over their parents.
*/
IASTNode findEnclosingNode(int offset, int length);
/**
* Returns the smallest node strictly enclosing the given range, or <code>null</code> if there is no such node.
* Returns the smallest node strictly enclosing the given range, or <code>null</code> if there
* is no such node.
* <p>
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion}) are preferred
* over c/c++-nodes nodes and children are preferred over their parents.
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion})
* are preferred over c/c++-nodes nodes and children are preferred over their parents.
* @since 5.3
*/
IASTNode findStrictlyEnclosingNode(int offset, int length);
/**
* Returns the first node contained in the given range, or <code>null</code> if there is no such node.
* Returns the first node contained in the given range, or <code>null</code> if there is
* no such node.
* <p>
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion}) are preferred
* over c/c++-nodes nodes and children are preferred over their parents.
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion})
* are preferred over c/c++-nodes nodes and children are preferred over their parents.
*/
IASTNode findFirstContainedNode(int offset, int length);
/**
* Returns the node for the exact given range, or <code>null</code> if there is no such node.
* <p>
* The method never returns a macro expansion ({@link IASTPreprocessorMacroExpansion}) or the name for
* an expansion. Rather than that the expansion itself is searched for a matching node.
* The method never returns a macro expansion ({@link IASTPreprocessorMacroExpansion}) or
* the name for an expansion. Rather than that the expansion itself is searched for a matching
* node.
* @since 5.1
*/
IASTNode findNodeInExpansion(int offset, int length);
@ -103,17 +108,20 @@ public interface IASTNodeSelector {
/**
* Returns the smallest node enclosing the range, or <code>null</code> if there is no such node.
* <p>
* The method never returns a macro expansion ({@link IASTPreprocessorMacroExpansion}) or the name for
* an expansion. Rather than that the expansion itself is searched for a matching node.
* The method never returns a macro expansion ({@link IASTPreprocessorMacroExpansion}) or
* the name for an expansion. Rather than that the expansion itself is searched for a matching
* node.
* @since 5.1
*/
IASTNode findEnclosingNodeInExpansion(int offset, int length);
/**
* Returns the first node contained in the given expansion, or <code>null</code> if there is no such node.
* Returns the first node contained in the given expansion, or <code>null</code> if there is
* no such node.
* <p>
* The method never returns a macro expansion ({@link IASTPreprocessorMacroExpansion}) or the name for
* an expansion. Rather than that the expansion itself is searched for a matching node.
* The method never returns a macro expansion ({@link IASTPreprocessorMacroExpansion}) or
* the name for an expansion. Rather than that the expansion itself is searched for a matching
* node.
* @since 5.1
*/
IASTNode findFirstContainedNodeInExpansion(int offset, int length);

View file

@ -11,13 +11,12 @@
package org.eclipse.cdt.core.dom.ast;
/**
* This node represents a null statement. ';'
* This node represents a null statement, ';'
*
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface IASTNullStatement extends IASTStatement {
/**
* @since 5.1
*/

View file

@ -254,24 +254,22 @@ public interface IASTTranslationUnit extends IASTDeclarationListOwner, IFileNomi
/**
* Return the set of files that have been skipped because they have been part of the index
* prior to creating this AST, or <code>null</code> if not available.
* Applies only, if AST was created with an index and the option to skip headers found in the
* index.
* Applies only, if AST was created with an index and the option to skip headers found in
* the index.
* @since 5.1
*/
IIndexFileSet getIndexFileSet();
/**
* Return the set of files in the index that are superseded by this AST,
* or <code>null</code> if not available.
* Applies only, if AST was created with an index.
* Return the set of files in the index that are superseded by this AST, or <code>null</code>
* if not available. Applies only, if AST was created with an index.
* @since 5.3
*/
IIndexFileSet getASTFileSet();
/**
* In case the AST was created in a way that supports comment parsing,
* all comments of the translation unit are returned. Otherwise an
* empty array will be supplied.
* In case the AST was created in a way that supports comment parsing, all comments of
* the translation unit are returned. Otherwise an empty array will be supplied.
*
* @return <code>IASTComment[]</code>
* @since 4.0

View file

@ -66,6 +66,7 @@ public abstract class GNUScannerExtensionConfiguration extends AbstractScannerEx
addKeyword(GCCKeywords.cp__CONST, IToken.t_const);
addKeyword(GCCKeywords.cp__CONST__, IToken.t_const);
addKeyword(GCCKeywords.cp__DECLSPEC, IGCCToken.t__declspec);
addKeyword(GCCKeywords.cp__DECLTYPE, IToken.t_decltype);
addKeyword(GCCKeywords.cp__INLINE, IToken.t_inline);
addKeyword(GCCKeywords.cp__INLINE__, IToken.t_inline);
addKeyword(GCCKeywords.cp__RESTRICT, IToken.t_restrict);

View file

@ -24,6 +24,8 @@ public class GCCKeywords {
public static final String __ATTRIBUTE__ = "__attribute__";
public static final String __DECLSPEC = "__declspec";
/** @since 5.5 */
public static final String __DECLTYPE = "__decltype";
/** @since 5.5 */
public static final String __INT128 = "__int128";
/** @since 5.5 */
public static final String __FLOAT128 = "__float128";
@ -71,6 +73,7 @@ public class GCCKeywords {
/** @since 5.5 */
public static final char[]
cp__DECLTYPE= __DECLTYPE.toCharArray(),
cp__float128= __FLOAT128.toCharArray(),
cp__int128= __INT128.toCharArray(),
cp__is_literal_type= "__is_literal_type".toCharArray(),

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2009, 2010 Wind River Systems, Inc. and others.
* Copyright (c) 2009, 2012 Wind River Systems, Inc. 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
@ -8,6 +8,7 @@
* Contributors:
* Markus Schorn - initial API and implementation
* Thomas Corbat
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
@ -69,9 +70,18 @@ public interface ITypeMarshalBuffer {
ISerializableEvaluation unmarshalEvaluation() throws CoreException;
ICPPTemplateArgument unmarshalTemplateArgument() throws CoreException;
int getByte() throws CoreException;
int getShort() throws CoreException;
int getInt() throws CoreException;
long getLong() throws CoreException;
int getFixedInt() throws CoreException;
/**
* Reads a 32-bit integer stored in the variable length base-128 encoding.
*/
public int getInt() throws CoreException;
/**
* Reads a 64-bit integer stored in the variable length base-128 encoding.
*/
public long getLong() throws CoreException;
char[] getCharArray() throws CoreException;
void marshalType(IType type) throws CoreException;
@ -80,8 +90,53 @@ public interface ITypeMarshalBuffer {
void marshalEvaluation(ISerializableEvaluation eval, boolean includeValue) throws CoreException;
void marshalTemplateArgument(ICPPTemplateArgument arg) throws CoreException;
void putByte(byte data);
void putShort(short data);
void putInt(int data);
void putLong(long data);
void putFixedInt(int data);
/**
* Writes a 32-bit integer in the variable length base-128 encoding. Each byte, except the last
* byte, has the most significant bit set this indicates that there are further bytes to come.
* The lower 7 bits of each byte are used to store the two-complement representation of
* the number in groups of 7 bits, least significant group first.
*
* <p>Here is number of bytes depending on the encoded value:
* <pre>
* Value Number of bytes
* [0,127] 1
* [128,16383] 2
* [16384,2097151] 3
* [2097152,268435455] 4
* [268435456,Integer.MAX_VALUE] 5
* negative 5
* </pre>
*
* @param value the value to write
*/
public void putInt(int value);
/**
* Writes a 64-bit integer in the variable length base-128 encoding. Each byte, except the last
* byte, has the most significant bit set this indicates that there are further bytes to come.
* The lower 7 bits of each byte are used to store the two-complement representation of
* the number in groups of 7 bits, least significant group first.
*
* <p>Here is number of bytes depending on the encoded value:
* <pre>
* Value Number of bytes
* [0,127] 1
* [128,16383] 2
* [16384,2097151] 3
* [2097152,268435455] 4
* [268435456,2^35-1] 5
* [2^35,2^42-1] 6
* [2^42,2^49-1] 7
* [2^49,2^56-1] 8
* [2^56,2^63-1] 9
* negative 10
* </pre>
*
* @param value the value to write
*/
public void putLong(long value);
void putCharArray(char[] data);
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010 Wind River Systems, Inc. and others.
* Copyright (c) 2010, 2012 Wind River Systems, Inc. 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
@ -7,6 +7,7 @@
*
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
@ -28,11 +29,11 @@ public class ProblemFunctionType extends ProblemType implements ICPPFunctionType
@Override
public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
buffer.putByte((byte) (ITypeMarshalBuffer.PROBLEM_TYPE | ITypeMarshalBuffer.FLAG1));
buffer.putShort((short) getID());
buffer.putInt(getID());
}
public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
return new ProblemFunctionType(buffer.getShort());
return new ProblemFunctionType(buffer.getInt());
}
@Override

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010 Wind River Systems, Inc. and others.
* Copyright (c) 2010, 2012 Wind River Systems, Inc. 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
@ -7,6 +7,7 @@
*
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
@ -56,13 +57,13 @@ public class ProblemType implements IProblemType, ISerializableType {
@Override
public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
buffer.putByte(ITypeMarshalBuffer.PROBLEM_TYPE);
buffer.putShort((short) getID());
buffer.putInt(getID());
}
public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
if ((firstByte & ITypeMarshalBuffer.FLAG1) != 0)
return ProblemFunctionType.unmarshal(firstByte, buffer);
return new ProblemType(buffer.getShort());
return new ProblemType(buffer.getInt());
}
}

View file

@ -154,12 +154,12 @@ public class Value implements IValue {
Long num= numericalValue();
if (num != null) {
long lv= num;
if (lv >= Integer.MIN_VALUE && lv <= Integer.MAX_VALUE) {
if (lv >= 0) {
buf.putByte((byte) (ITypeMarshalBuffer.VALUE | ITypeMarshalBuffer.FLAG2));
buf.putInt((int) lv);
buf.putLong(lv);
} else {
buf.putByte((byte) (ITypeMarshalBuffer.VALUE | ITypeMarshalBuffer.FLAG3));
buf.putLong(lv);
buf.putLong(-lv);
}
} else if (fFixedValue != null) {
buf.putByte((byte) (ITypeMarshalBuffer.VALUE | ITypeMarshalBuffer.FLAG4));
@ -177,18 +177,13 @@ public class Value implements IValue {
return null;
if ((firstByte & ITypeMarshalBuffer.FLAG1) != 0)
return Value.UNKNOWN;
if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0) {
int val= buf.getInt();
return Value.create(val);
}
if ((firstByte & ITypeMarshalBuffer.FLAG3) != 0) {
long val= buf.getLong();
return Value.create(val);
}
if ((firstByte & ITypeMarshalBuffer.FLAG4) != 0) {
char[] fixedValue = buf.getCharArray();
return new Value(fixedValue, null);
}
if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0)
return Value.create(buf.getLong());
if ((firstByte & ITypeMarshalBuffer.FLAG3) != 0)
return Value.create(-buf.getLong());
if ((firstByte & ITypeMarshalBuffer.FLAG4) != 0)
return new Value(buf.getCharArray(), null);
ISerializableEvaluation eval= buf.unmarshalEvaluation();
if (eval instanceof ICPPEvaluation)
return new Value(null, (ICPPEvaluation) eval);

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2010 IBM Corporation and others.
* Copyright (c) 2004, 2012 IBM Corporation 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
@ -7,6 +7,7 @@
*
* Contributors:
* Devin Steffler (IBM Corporation) - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
@ -161,7 +162,7 @@ public class CArrayType implements ICArrayType, ITypeContainer, ISerializableTyp
public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
int firstByte= ITypeMarshalBuffer.ARRAY_TYPE;
int flags= 0;
short nval= -1;
long nval= -1;
IValue val= null;
if (isConst()) flags |= 0x01;
@ -178,9 +179,8 @@ public class CArrayType implements ICArrayType, ITypeContainer, ISerializableTyp
firstByte |= ITypeMarshalBuffer.FLAG2;
Long num= val.numericalValue();
if (num != null) {
long l= num;
if (l >= 0 && l <= Short.MAX_VALUE) {
nval= (short) l;
nval= num;
if (nval >= 0) {
firstByte |= ITypeMarshalBuffer.FLAG3;
}
}
@ -190,7 +190,7 @@ public class CArrayType implements ICArrayType, ITypeContainer, ISerializableTyp
buffer.putByte((byte) flags);
}
if (nval >= 0) {
buffer.putShort(nval);
buffer.putLong(nval);
} else if (val != null) {
buffer.marshalValue(val);
}
@ -204,7 +204,7 @@ public class CArrayType implements ICArrayType, ITypeContainer, ISerializableTyp
flags= buffer.getByte();
}
if ((firstByte & ITypeMarshalBuffer.FLAG3) != 0) {
value = Value.create(buffer.getShort());
value = Value.create(buffer.getLong());
} else if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0) {
value = buffer.unmarshalValue();
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2011 IBM Corporation and others.
* Copyright (c) 2004, 2012 IBM Corporation 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
@ -8,6 +8,7 @@
* Contributors:
* Devin Steffler (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
@ -87,7 +88,7 @@ public class CFunctionType implements IFunctionType, ISerializableType {
} else {
firstByte |= ITypeMarshalBuffer.FLAG4;
buffer.putByte((byte) firstByte);
buffer.putShort((short) len);
buffer.putInt(len);
}
buffer.marshalType(returnType);
@ -99,7 +100,7 @@ public class CFunctionType implements IFunctionType, ISerializableType {
public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int len;
if (((firstByte & ITypeMarshalBuffer.FLAG4) != 0)) {
len= buffer.getShort();
len= buffer.getInt();
} else {
len= (firstByte & (ITypeMarshalBuffer.FLAG4-1))/ITypeMarshalBuffer.FLAG1;
}

View file

@ -23,9 +23,8 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
/**
* Initializer list in parenthesis.
*/
public class CPPASTConstructorInitializer extends ASTNode implements ICPPASTConstructorInitializer,
IASTAmbiguityParent {
public class CPPASTConstructorInitializer extends ASTNode
implements ICPPASTConstructorInitializer, IASTAmbiguityParent {
private IASTInitializerClause[] fArguments;
public CPPASTConstructorInitializer() {
@ -51,11 +50,7 @@ public class CPPASTConstructorInitializer extends ASTNode implements ICPPASTCons
}
}
CPPASTConstructorInitializer copy = new CPPASTConstructorInitializer(args);
copy.setOffsetAndLength(this);
if (style == CopyStyle.withLocations) {
copy.setCopyLocation(this);
}
return copy;
return copy(copy, style);
}
@Override

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2010 IBM Corporation and others.
* Copyright (c) 2004, 2012 IBM Corporation 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
@ -8,6 +8,7 @@
* Contributors:
* Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -122,9 +123,9 @@ public class CPPArrayType implements IArrayType, ITypeContainer, ISerializableTy
Long num= val.numericalValue();
if (num != null) {
long lnum= num;
if (lnum >= 0 && lnum <= Short.MAX_VALUE) {
if (lnum >= 0) {
buffer.putByte((byte) (firstByte | ITypeMarshalBuffer.FLAG1));
buffer.putShort((short) lnum);
buffer.putLong(lnum);
buffer.marshalType(getType());
return;
}
@ -137,7 +138,7 @@ public class CPPArrayType implements IArrayType, ITypeContainer, ISerializableTy
public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
IValue value= null;
if ((firstByte & ITypeMarshalBuffer.FLAG1) != 0) {
value = Value.create(buffer.getShort());
value = Value.create(buffer.getLong());
} else if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0) {
value = buffer.unmarshalValue();
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2011 IBM Corporation and others.
* Copyright (c) 2005, 2012 IBM Corporation 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
@ -230,15 +230,16 @@ public class CPPDeferredClassInstance extends CPPUnknownBinding implements ICPPD
int firstByte= ITypeMarshalBuffer.DEFERRED_CLASS_INSTANCE;
buffer.putByte((byte) firstByte);
buffer.marshalBinding(fClassTemplate);
buffer.putShort((short) fArguments.length);
buffer.putInt(fArguments.length);
for (ICPPTemplateArgument arg : fArguments) {
buffer.marshalTemplateArgument(arg);
}
}
public static ICPPDeferredClassInstance unmarshal(IIndexFragment fragment, int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
public static ICPPDeferredClassInstance unmarshal(IIndexFragment fragment, int firstByte,
ITypeMarshalBuffer buffer) throws CoreException {
IBinding template= buffer.unmarshalBinding();
int argcount= buffer.getShort() & 0xffff;
int argcount= buffer.getInt();
ICPPTemplateArgument[] args = new ICPPTemplateArgument[argcount];
for (int i = 0; i < argcount; i++) {
args[i]= buffer.unmarshalTemplateArgument();

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2011 IBM Corporation and others.
* Copyright (c) 2004, 2012 IBM Corporation 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
@ -8,6 +8,7 @@
* Contributors:
* Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -140,29 +141,17 @@ public class CPPFunctionType implements ICPPFunctionType, ISerializableType {
if (isVolatile()) firstByte |= ITypeMarshalBuffer.FLAG2;
if (takesVarArgs()) firstByte |= ITypeMarshalBuffer.FLAG3;
int len= (parameters.length & 0xffff);
if (len > 0xff) {
firstByte |= ITypeMarshalBuffer.FLAG4;
buffer.putByte((byte) firstByte);
buffer.putShort((short) len);
} else {
buffer.putByte((byte) firstByte);
buffer.putByte((byte) len);
}
buffer.putInt(parameters.length);
buffer.marshalType(returnType);
for (int i = 0; i < len; i++) {
for (int i = 0; i < parameters.length; i++) {
buffer.marshalType(parameters[i]);
}
}
public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int len;
if (((firstByte & ITypeMarshalBuffer.FLAG4) != 0)) {
len= buffer.getShort();
} else {
len= buffer.getByte();
}
int len= buffer.getInt();
IType rt= buffer.unmarshalType();
IType[] pars= new IType[len];
for (int i = 0; i < pars.length; i++) {

View file

@ -40,29 +40,34 @@ import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.model.ASTStringUtil;
import org.eclipse.core.runtime.PlatformObject;
public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPInternalBinding {
public static class CPPNamespaceProblem extends ProblemBinding implements ICPPNamespace, ICPPNamespaceScope {
public CPPNamespaceProblem(IASTNode node, int id, char[] arg) {
super(node, id, arg);
}
@Override
public ICPPNamespaceScope getNamespaceScope() {
return this;
}
@Override
public IBinding[] getMemberBindings() {
return IBinding.EMPTY_BINDING_ARRAY;
}
@Override
public void addUsingDirective(ICPPUsingDirective usingDirective) {
}
@Override
public ICPPUsingDirective[] getUsingDirectives() {
return ICPPUsingDirective.EMPTY_ARRAY;
}
@Override
public ICPPNamespaceScope[] getInlineNamespaces() {
return ICPPNamespaceScope.EMPTY_NAMESPACE_SCOPE_ARRAY;
@ -80,25 +85,19 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPBinding#getDeclarations()
*/
@Override
public IASTNode[] getDeclarations() {
return namespaceDefinitions;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPBinding#getDefinition()
*/
@Override
public IASTNode getDefinition() {
return (tu != null) ? tu : (IASTNode) namespaceDefinitions[0];
return tu != null ? tu : (IASTNode) namespaceDefinitions[0];
}
static private class NamespaceCollector extends ASTVisitor {
private ICPPASTNamespaceDefinition namespaceDef = null;
private IASTName[] namespaces = null;
private ICPPASTNamespaceDefinition namespaceDef;
private IASTName[] namespaces;
public NamespaceCollector(ICPPASTNamespaceDefinition ns) {
shouldVisitNamespaces = true;
@ -142,6 +141,7 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
static private class NamespaceMemberCollector extends ASTVisitor {
public ObjectSet<IBinding> members = new ObjectSet<IBinding>(8);
public NamespaceMemberCollector() {
shouldVisitNamespaces = true;
shouldVisitDeclarators = true;
@ -160,6 +160,7 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
return PROCESS_SKIP;
}
@Override
public int visit(IASTDeclSpecifier declSpec) {
if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
@ -181,6 +182,7 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
}
return PROCESS_SKIP;
}
@Override
public int visit(ICPPASTNamespaceDefinition namespace) {
IBinding binding = namespace.getName().resolveBinding();
@ -188,6 +190,7 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
members.put(binding);
return PROCESS_SKIP;
}
@Override
public int visit(IASTDeclaration declaration) {
if (declaration instanceof ICPPASTUsingDeclaration) {
@ -201,6 +204,7 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
return PROCESS_CONTINUE;
}
}
private void findAllDefinitions(ICPPASTNamespaceDefinition namespaceDef) {
NamespaceCollector collector = new NamespaceCollector(namespaceDef);
namespaceDef.getTranslationUnit().accept(collector);
@ -215,99 +219,52 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
return namespaceDefinitions;
}
/**
* @param unit
*/
public CPPNamespace(CPPASTTranslationUnit unit) {
tu = unit;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace#getNamespaceScope()
*/
@Override
public ICPPNamespaceScope getNamespaceScope() {
if (scope == null) {
if (tu != null)
if (tu != null) {
scope = (ICPPNamespaceScope) tu.getScope();
else
} else {
scope = new CPPNamespaceScope(namespaceDefinitions[0].getParent());
}
}
return scope;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getName()
*/
@Override
public String getName() {
return new String(getNameCharArray());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray()
*/
@Override
public char[] getNameCharArray() {
return tu != null ? CharArrayUtils.EMPTY_CHAR_ARRAY : namespaceDefinitions[0].getSimpleID();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getScope()
*/
@Override
public IScope getScope() {
return tu != null ? null : CPPVisitor.getContainingScope(namespaceDefinitions[0]);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode()
*/
public IASTNode getPhysicalNode() {
return tu != null ? (IASTNode) tu : namespaceDefinitions[0];
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getFullyQualifiedName()
*/
public String[] getFullyQualifiedName() {
return CPPVisitor.getQualifiedName(this);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getFullyQualifiedNameCharArray()
*/
public char[][] getFullyQualifiedNameCharArray() {
return CPPVisitor.getQualifiedNameCharArray(this);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding#getQualifiedName()
*/
@Override
public String[] getQualifiedName() {
return CPPVisitor.getQualifiedName(this);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding#getQualifiedNameCharArray()
*/
@Override
public char[][] getQualifiedNameCharArray() {
return CPPVisitor.getQualifiedNameCharArray(this);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding#isGloballyQualified()
*/
@Override
public boolean isGloballyQualified() {
return true;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDefinition(org.eclipse.cdt.core.dom.ast.IASTNode)
*/
@Override
public void addDefinition(IASTNode node) {
if (!(node instanceof IASTName))
@ -326,9 +283,6 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDeclaration(org.eclipse.cdt.core.dom.ast.IASTNode)
*/
@Override
public void addDeclaration(IASTNode node) {
addDefinition(node);
@ -370,9 +324,15 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
public String toString() {
String[] names = getQualifiedName();
if (names.length == 0) {
return "<unnamed namespace>"; //$NON-NLS-1$
return "<global namespace>"; //$NON-NLS-1$
}
return ASTStringUtil.join(names, String.valueOf(Keywords.cpCOLONCOLON));
StringBuilder buf = new StringBuilder();
for (String name : names) {
if (buf.length() != 0)
buf.append(Keywords.cpCOLONCOLON);
buf.append(name.isEmpty() ? "<anonymous>" : name); //$NON-NLS-1$
}
return buf.toString();
}
@Override

View file

@ -80,7 +80,7 @@ public class CPPNamespaceScope extends CPPScope implements ICPPInternalNamespace
private void initUsingDirectives() {
if (fUsingDirectives == null) {
fUsingDirectives= new ArrayList<ICPPUsingDirective>(1);
// Insert a using directive for every inline namespace found in the index
// Insert a using directive for every inline namespace found in the index.
for (ICPPInternalNamespaceScope inline : getIndexInlineNamespaces()) {
if (!(inline instanceof CPPNamespaceScope)) {
fUsingDirectives.add(new InlineNamespaceDirective(this, inline));

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2010 Google, Inc and others.
* Copyright (c) 2008, 2012 Google, Inc 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
@ -86,7 +86,7 @@ public class CPPUnknownClassInstance extends CPPUnknownMemberClass implements IC
buffer.putByte((byte) firstByte);
buffer.marshalType(getOwnerType());
buffer.putCharArray(getNameCharArray());
buffer.putShort((short) arguments.length);
buffer.putInt(arguments.length);
for (ICPPTemplateArgument arg : arguments) {
buffer.marshalTemplateArgument(arg);
}
@ -95,7 +95,7 @@ public class CPPUnknownClassInstance extends CPPUnknownMemberClass implements IC
public static ICPPUnknownMemberClassInstance unmarshal(IIndexFragment fragment, int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
IType owner= buffer.unmarshalType();
char[] name = buffer.getCharArray();
int argcount= buffer.getShort() & 0xffff;
int argcount= buffer.getInt();
ICPPTemplateArgument[] args = new ICPPTemplateArgument[argcount];
for (int i = 0; i < argcount; i++) {
args[i]= buffer.unmarshalTemplateArgument();

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2002, 2012 IBM Corporation and others.
* Copyright (c) 2002, 2013 IBM Corporation 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
@ -942,7 +942,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
lt1= LT(1);
if (lt1 != IToken.tCOLON && lt1 != IToken.tCOMMA)
stopWithNextOperator= true;
break;
} else if (allowBraceInitializer && LT(1) == IToken.tLBRACE) {
// Brace initializer
expr= bracedInitList(true);
@ -2058,7 +2057,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
List<ICPPASTTemplateParameter> parms= outerTemplateParameterList();
if (LT(1) != IToken.tEOC) {
consume(IToken.tGT, IToken.tGT_in_SHIFTR);
}
IASTDeclaration d = declaration(option);
ICPPASTTemplateDeclaration templateDecl = nodeFactory.newTemplateDeclaration(d);
setRange(templateDecl, offset, calculateEndOffset(d));

View file

@ -126,7 +126,7 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
}
@Override
public void putShort(short value) {
public void putFixedInt(int value) {
appendSeparator();
fBuffer.append(value);
}
@ -192,7 +192,7 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
}
@Override
public int getShort() throws CoreException {
public int getFixedInt() throws CoreException {
throw new UnsupportedOperationException();
}

View file

@ -663,7 +663,9 @@ public class CPPTemplates {
IBinding owner = template.getOwner();
ICPPClassSpecialization within = getSpecializationContext(owner);
IType instantiatedType = instantiateType(aliasedType, parameterMap, -1, within, id);
return new CPPAliasTemplateInstance(id.toCharArray(), aliasTemplate, instantiatedType);
StringBuilder buf= new StringBuilder();
buf.append(id.getSimpleID()).append(ASTTypeUtil.getArgumentListString(args, false));
return new CPPAliasTemplateInstance(buf.toString().toCharArray(), aliasTemplate, instantiatedType);
}
// Class template.

View file

@ -2038,6 +2038,10 @@ public class CPPVisitor extends ASTQueries {
IASTInitializer initClause= declarator.getInitializer();
if (initClause instanceof IASTEqualsInitializer) {
autoInitClause= (ICPPASTInitializerClause) ((IASTEqualsInitializer) initClause).getInitializerClause();
} else if (initClause instanceof ICPPASTConstructorInitializer) {
IASTInitializerClause[] arguments = ((ICPPASTConstructorInitializer) initClause).getArguments();
if (arguments.length == 1)
autoInitClause = (ICPPASTInitializerClause) arguments[0];
} else if (initClause instanceof ICPPASTInitializerClause) {
autoInitClause= (ICPPASTInitializerClause) initClause;
}

View file

@ -300,7 +300,7 @@ public class EvalBinding extends CPPEvaluation {
// function and the parameter position instead.
buffer.putByte((byte) (ITypeMarshalBuffer.EVAL_BINDING | ITypeMarshalBuffer.FLAG1));
buffer.marshalBinding(parameterOwner);
buffer.putShort((short) getFunctionParameterPosition());
buffer.putInt(getFunctionParameterPosition());
} else {
buffer.putByte(firstByte);
buffer.marshalBinding(fBinding);
@ -311,7 +311,7 @@ public class EvalBinding extends CPPEvaluation {
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
if ((firstByte & ITypeMarshalBuffer.FLAG1) != 0) {
ICPPFunction parameterOwner= (ICPPFunction) buffer.unmarshalBinding();
int parameterPosition= buffer.getShort();
int parameterPosition= buffer.getInt();
IType type= buffer.unmarshalType();
return new EvalBinding(parameterOwner, parameterPosition, type);
} else {

View file

@ -155,14 +155,14 @@ public class EvalComma extends CPPEvaluation {
@Override
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
buffer.putByte(ITypeMarshalBuffer.EVAL_COMMA);
buffer.putShort((short) fArguments.length);
buffer.putInt(fArguments.length);
for (ICPPEvaluation arg : fArguments) {
buffer.marshalEvaluation(arg, includeValue);
}
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int len= buffer.getShort();
int len= buffer.getInt();
ICPPEvaluation[] args = new ICPPEvaluation[len];
for (int i = 0; i < args.length; i++) {
args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation();

View file

@ -143,9 +143,11 @@ public class EvalFunctionCall extends CPPEvaluation {
@Override
public IValue getValue(IASTNode point) {
ICPPEvaluation eval = computeForFunctionCall(Value.MAX_RECURSION_DEPTH, point);
if (eval != this) {
if (eval instanceof EvalFixed)
return ((EvalFixed) eval).getValue();
eval = new EvalFixed(getTypeOrFunctionSet(point), PRVALUE, eval.getValue(point));
}
return Value.create(eval);
}
@ -168,14 +170,14 @@ public class EvalFunctionCall extends CPPEvaluation {
@Override
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
buffer.putByte(ITypeMarshalBuffer.EVAL_FUNCTION_CALL);
buffer.putShort((short) fArguments.length);
buffer.putInt(fArguments.length);
for (ICPPEvaluation arg : fArguments) {
buffer.marshalEvaluation(arg, includeValue);
}
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int len= buffer.getShort();
int len= buffer.getInt();
ICPPEvaluation[] args = new ICPPEvaluation[len];
for (int i = 0; i < args.length; i++) {
args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation();

View file

@ -110,12 +110,12 @@ public class EvalFunctionSet extends CPPEvaluation {
firstByte |= ITypeMarshalBuffer.FLAG2;
buffer.putByte((byte) firstByte);
buffer.putShort((short) bindings.length);
buffer.putInt(bindings.length);
for (ICPPFunction binding : bindings) {
buffer.marshalBinding(binding);
}
if (args != null) {
buffer.putShort((short) args.length);
buffer.putInt(args.length);
for (ICPPTemplateArgument arg : args) {
buffer.marshalTemplateArgument(arg);
}
@ -124,14 +124,14 @@ public class EvalFunctionSet extends CPPEvaluation {
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
final boolean addressOf= (firstByte & ITypeMarshalBuffer.FLAG1) != 0;
int bindingCount= buffer.getShort();
int bindingCount= buffer.getInt();
ICPPFunction[] bindings= new ICPPFunction[bindingCount];
for (int i = 0; i < bindings.length; i++) {
bindings[i]= (ICPPFunction) buffer.unmarshalBinding();
}
ICPPTemplateArgument[] args= null;
if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0) {
int len= buffer.getShort();
int len= buffer.getInt();
args = new ICPPTemplateArgument[len];
for (int i = 0; i < args.length; i++) {
args[i]= buffer.unmarshalTemplateArgument();

View file

@ -151,7 +151,7 @@ public class EvalID extends CPPEvaluation {
buffer.putCharArray(fName);
buffer.marshalBinding(fNameOwner);
if (fTemplateArgs != null) {
buffer.putShort((short) fTemplateArgs.length);
buffer.putInt(fTemplateArgs.length);
for (ICPPTemplateArgument arg : fTemplateArgs) {
buffer.marshalTemplateArgument(arg);
}
@ -166,7 +166,7 @@ public class EvalID extends CPPEvaluation {
IBinding nameOwner= buffer.unmarshalBinding();
ICPPTemplateArgument[] args= null;
if ((firstByte & ITypeMarshalBuffer.FLAG3) != 0) {
int len= buffer.getShort();
int len= buffer.getInt();
args = new ICPPTemplateArgument[len];
for (int i = 0; i < args.length; i++) {
args[i]= buffer.unmarshalTemplateArgument();

View file

@ -87,14 +87,14 @@ public class EvalInitList extends CPPEvaluation {
@Override
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
buffer.putByte(ITypeMarshalBuffer.EVAL_INIT_LIST);
buffer.putShort((short) fClauses.length);
buffer.putInt(fClauses.length);
for (ICPPEvaluation arg : fClauses) {
buffer.marshalEvaluation(arg, includeValue);
}
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int len= buffer.getShort();
int len= buffer.getInt();
ICPPEvaluation[] args = new ICPPEvaluation[len];
for (int i = 0; i < args.length; i++) {
args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation();

View file

@ -123,7 +123,7 @@ public class EvalTypeId extends CPPEvaluation {
buffer.putByte((byte) firstByte);
buffer.marshalType(fInputType);
if (includeValue) {
buffer.putShort((short) fArguments.length);
buffer.putInt(fArguments.length);
for (ICPPEvaluation arg : fArguments) {
buffer.marshalEvaluation(arg, includeValue);
}
@ -134,7 +134,7 @@ public class EvalTypeId extends CPPEvaluation {
IType type= buffer.unmarshalType();
ICPPEvaluation[] args= null;
if ((firstByte & ITypeMarshalBuffer.FLAG1) != 0) {
int len= buffer.getShort();
int len= buffer.getInt();
args = new ICPPEvaluation[len];
for (int i = 0; i < args.length; i++) {
args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation();

View file

@ -8,7 +8,6 @@
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
/**
@ -18,7 +17,6 @@ package org.eclipse.cdt.internal.core.parser.scanner;
* @since 5.0
*/
public interface ILocationCtx {
/**
* If this is a file context the filename of this context is returned,
* otherwise the filename of the first enclosing context that is a file context is returned.

View file

@ -23,20 +23,19 @@ import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeSpecification;
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
/**
* Interface between the ast and the location-resolver for resolving offsets.
* Interface between the AST and the location-resolver for resolving offsets.
* @since 5.0
*/
public interface ILocationResolver {
/**
* Introduces the ast translation unit to the location resolver. Must be called before any tokens from the
* scanner are obtained.
* Introduces the AST translation unit to the location resolver. Must be called before any
* tokens from the scanner are obtained.
*/
void setRootNode(IASTTranslationUnit tu);
@ -103,15 +102,17 @@ public interface ILocationResolver {
/**
* Returns the smallest file location, that encloses the given global range. In case the range
* spans over multiple files, the files are mapped to include statements until all of them are
* found in the same file. So the resulting location contains the include directives that actually
* cause the range to be part of the AST.
* found in the same file. So the resulting location contains the include directives that
* actually cause the range to be part of the AST.
* @param offset sequence number as stored in the ASTNodes.
* @param length
*/
IASTFileLocation getMappedFileLocation(int offset, int length);
/**
* Returns an array of locations. This is a sequence of file locations and macro-expansion locations.
* Returns an array of locations. This is a sequence of file locations and macro-expansion
* locations.
*
* @param offset sequence number as stored in the ast nodes.
* @param length
* @return and array of locations.
@ -124,8 +125,8 @@ public interface ILocationResolver {
IASTImageLocation getImageLocation(int offset, int length);
/**
* Returns the sequence-number for the given file-path and offset, or <code>-1</code> if this file
* is not part of the translation-unit.
* Returns the sequence-number for the given file-path and offset, or <code>-1</code> if this
* file is not part of the translation-unit.
* @param filePath a file path or <code>null</code> to specify the root of the translation unit.
* @param fileOffset an offset into the source of the file, or <code>-1</code>.
*/
@ -158,7 +159,8 @@ public interface ILocationResolver {
boolean isPartOfSourceFile(int sequenceNumber);
/**
* Same as {@link #getMappedFileLocation(int, int)} for the given array of consecutive node locations.
* Same as {@link #getMappedFileLocation(int, int)} for the given array of consecutive node
* locations.
*/
IASTFileLocation flattenLocations(IASTNodeLocation[] nodeLocations);

View file

@ -15,13 +15,13 @@ import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
/**
* Information needed for computing image-locations. An image location exists for a name and describes where the name
* came from. This can be: source code, macro-expansion, parameter to macro-expansion or synthetic.
* Information needed for computing image-locations. An image location exists for a name and
* describes where the name came from. This can be: source code, macro-expansion, parameter to
* macro-expansion or synthetic.
*
* @since 5.0
*/
public abstract class ImageLocationInfo {
public static final ImageLocationInfo[] NO_LOCATION_INFOS= {};
int fTokenOffsetInExpansion= -1;
@ -33,6 +33,7 @@ public abstract class ImageLocationInfo {
private final ObjectStyleMacro fMacro;
private final int fOffset;
private final int fEndOffset;
public MacroImageLocationInfo(ObjectStyleMacro macro, int offset, int endOffset) {
fMacro= macro;
fOffset= offset;
@ -66,10 +67,12 @@ public abstract class ImageLocationInfo {
public static class ParameterImageLocationInfo extends ImageLocationInfo {
public int fSequenceNumber;
public int fSequenceEndNumber;
public ParameterImageLocationInfo(int sequenceNumber, int sequenceEndNumber) {
fSequenceNumber= sequenceNumber;
fSequenceEndNumber= sequenceEndNumber;
}
@Override
public IASTImageLocation createLocation(LocationMap lm, ImageLocationInfo upto) {
int sequenceEnd= ((ParameterImageLocationInfo) upto).fSequenceEndNumber;

View file

@ -19,7 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree.IASTIncl
/**
* Various location contexts which are suitable for interpreting local offsets. These offsets are
* converted in a global sequence-number to make all ast nodes comparable with each other.
* converted in a global sequence-number to make all AST nodes comparable with each other.
* @since 5.0
*/
abstract class LocationCtx implements ILocationCtx {
@ -29,11 +29,13 @@ abstract class LocationCtx implements ILocationCtx {
*/
final int fSequenceNumber;
/**
* The offset of the denotation of this context in the parent's source. This is no sequence number.
* The offset of the denotation of this context in the parent's source. This is no sequence
* number.
*/
final int fOffsetInParent;
/**
* The end-offset of the denotation of this context in the parent's source. This is no sequence number.
* The end-offset of the denotation of this context in the parent's source. This is no sequence
* number.
*/
final int fEndOffsetInParent;
@ -56,30 +58,31 @@ abstract class LocationCtx implements ILocationCtx {
final public ILocationCtx getParent() {
return fParent;
}
/**
* Returns the amount of sequence numbers occupied by this context including its children.
*/
public abstract int getSequenceLength();
/**
* Converts an offset within this context to the sequence number. In case there are child-contexts
* behind the given offset, you need to set checkChildren to <code>true</code>.
* Converts an offset within this context to the sequence number. In case there are
* child-contexts behind the given offset, you need to set checkChildren to <code>true</code>.
*/
public int getSequenceNumberForOffset(int offset, boolean checkChildren) {
return fSequenceNumber+offset;
}
/**
* When a child-context is finished it reports its total sequence length, such that offsets in this
* context can be converted to sequence numbers.
* When a child-context is finished it reports its total sequence length, such that offsets in
* this context can be converted to sequence numbers.
*/
public void addChildSequenceLength(int childLength) {
assert false;
}
/**
* Returns the line number for an offset within this context. Not all contexts support line numbers,
* so this may return 0.
* Returns the line number for an offset within this context. Not all contexts support line
* numbers, so this may return 0.
*/
public int getLineNumber(int offset) {
return 0;
@ -136,7 +139,8 @@ abstract class LocationCtx implements ILocationCtx {
}
/**
* Support for the dependency tree, returns inclusion statement that created this context, or <code>null</code>.
* Support for the dependency tree, returns inclusion statement that created this context,
* or <code>null</code>.
*/
@Override
public ASTInclusionStatement getInclusionStatement() {

View file

@ -35,7 +35,8 @@ class LocationCtxContainer extends LocationCtx {
private AbstractCharArray fSource;
private int[] fLineOffsets;
public LocationCtxContainer(LocationCtxContainer parent, AbstractCharArray source, int parentOffset, int parentEndOffset, int sequenceNumber) {
public LocationCtxContainer(LocationCtxContainer parent, AbstractCharArray source,
int parentOffset, int parentEndOffset, int sequenceNumber) {
super(parent, parentOffset, parentEndOffset, sequenceNumber);
fSource= source;
}

View file

@ -266,18 +266,16 @@ public class MacroDefinitionParser {
break loop;
case IToken.tIDENTIFIER:
if (paramList != null) {
// convert the parameters to special tokens
// Convert the parameters to special tokens.
final char[] image = candidate.getCharImage();
int idx= CharArrayUtils.indexOf(image, paramList);
if (idx >= 0) {
candidate= new TokenParameterReference(CPreprocessor.tMACRO_PARAMETER, idx, lexer.getSource(), candidate.getOffset(), candidate.getEndOffset(), paramList[idx]);
needParam= false;
}
else {
} else {
if (needParam) {
log.handleProblem(IProblem.PREPROCESSOR_MACRO_PASTING_ERROR, name, fExpansionOffset, candidate.getEndOffset());
}
else if (CharArrayUtils.equals(Keywords.cVA_ARGS, image)) {
} else if (CharArrayUtils.equals(Keywords.cVA_ARGS, image)) {
log.handleProblem(IProblem.PREPROCESSOR_INVALID_VA_ARGS, null, fExpansionOffset, candidate.getEndOffset());
}
needParam= false;

View file

@ -139,7 +139,8 @@ public class MacroExpander {
private ScannerContext fReportMacros;
private boolean fReportUndefined;
public MacroExpander(ILexerLog log, CharArrayMap<PreprocessorMacro> macroDictionary, LocationMap locationMap, LexerOptions lexOptions) {
public MacroExpander(ILexerLog log, CharArrayMap<PreprocessorMacro> macroDictionary,
LocationMap locationMap, LexerOptions lexOptions) {
fDictionary= macroDictionary;
fLocationMap= locationMap;
fDefinitionParser= new MacroDefinitionParser();
@ -185,7 +186,7 @@ public class MacroExpander {
result= expandAll(input, forbidden, protectDefined, null);
} catch (CompletionInMacroExpansionException e) {
// for content assist in macro expansions, we return the list of tokens of the
// For content assist in macro expansions, we return the list of tokens of the
// parameter at the current cursor position and hope that they make sense if
// they are inserted at the position of the expansion.
// For a better solution one would have to perform the expansion with artificial
@ -201,7 +202,8 @@ public class MacroExpander {
* Method for tracking macro expansions.
* @since 5.0
*/
public void expand(String beforeExpansion, MacroExpansionTracker tracker, String filePath, int lineNumber, boolean protectDefinedConstructs) {
public void expand(String beforeExpansion, MacroExpansionTracker tracker, String filePath,
int lineNumber, boolean protectDefinedConstructs) {
fImplicitMacroExpansions.clear();
fImageLocationInfos.clear();
fFixedInput= beforeExpansion.toCharArray();
@ -227,7 +229,8 @@ public class MacroExpander {
fStartOffset= identifier.getOffset();
fEndOffset= identifier.getEndOffset();
fCompletionMode= false;
IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden= new IdentityHashMap<PreprocessorMacro, PreprocessorMacro>();
IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden=
new IdentityHashMap<PreprocessorMacro, PreprocessorMacro>();
// setup input sequence
TokenSource input= new TokenSource(lexer);
@ -245,15 +248,15 @@ public class MacroExpander {
}
/**
* Expects that the identifier of the macro expansion has been consumed. Expands the macro consuming
* tokens from the input (to read the parameters) and stores the resulting tokens together
* with boundary markers in the result token list.
* Returns the last token of the expansion.
* Expects that the identifier of the macro expansion has been consumed. Expands the macro
* consuming tokens from the input (to read the parameters) and stores the resulting tokens
* together with boundary markers in the result token list.
* @return the last token of the expansion.
* @throws AbortMacroExpansionException
*/
private Token expandOne(Token lastConsumed, PreprocessorMacro macro,
IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden, TokenSource input, TokenList result,
MacroExpansionTracker tracker)
IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden, TokenSource input,
TokenList result, MacroExpansionTracker tracker)
throws OffsetLimitReachedException {
if (fReportMacros != null)
fReportMacros.significantMacro(macro);
@ -268,7 +271,7 @@ public class MacroExpander {
try {
lastConsumed= parseArguments(input, (FunctionStyleMacro) macro, forbidden, argInputs, tracker);
} catch (AbortMacroExpansionException e) {
// ignore this macro expansion
// Ignore this macro expansion.
for (TokenSource argInput : argInputs) {
executeScopeMarkers(argInput, forbidden);
if (tracker != null) {
@ -415,6 +418,14 @@ public class MacroExpander {
return result;
}
private void addImageLocationInfo(int offset, Token t) {
ImageLocationInfo info= createImageLocationInfo(t);
if (info != null) {
info.fTokenOffsetInExpansion= offset;
fImageLocationInfos.add(info);
}
}
private ImageLocationInfo createImageLocationInfo(Token t) {
if (fLocationMap != null) {
final Object s= t.fSource;
@ -451,8 +462,10 @@ public class MacroExpander {
/**
* Expects that the identifier has been consumed.
*/
private Token parseArguments(TokenSource input, FunctionStyleMacro macro, IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden,
TokenSource[] result, MacroExpansionTracker tracker) throws OffsetLimitReachedException, AbortMacroExpansionException {
private Token parseArguments(TokenSource input, FunctionStyleMacro macro,
IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden,
TokenSource[] result, MacroExpansionTracker tracker)
throws OffsetLimitReachedException, AbortMacroExpansionException {
final int argCount= macro.getParameterPlaceholderList().length;
final boolean hasVarargs= macro.hasVarArgs() != FunctionStyleMacro.NO_VAARGS;
final int requiredArgs= hasVarargs ? argCount - 1 : argCount;
@ -509,7 +522,7 @@ public class MacroExpander {
continue loop;
case IToken.tLPAREN:
// the first one sets nesting to zero.
// The first one sets nesting to zero.
if (++nesting == 0) {
continue;
}
@ -525,7 +538,7 @@ public class MacroExpander {
case IToken.tCOMMA:
assert nesting >= 0;
if (nesting == 0) {
if (idx < argCount-1) { // next argument
if (idx < argCount - 1) { // Next argument.
isFirstOfArg= true;
spaceMarkers.clear();
idx++;
@ -564,7 +577,6 @@ public class MacroExpander {
isFirstOfArg= false;
}
if (missingRParenthesis) {
handleProblem(IProblem.PREPROCESSOR_MISSING_RPAREN_PARMLIST, macro.getNameCharArray());
throw new AbortMacroExpansionException();
@ -946,20 +958,12 @@ public class MacroExpander {
case CPreprocessor.tEXPANDED_IDENTIFIER:
t.setType(IToken.tIDENTIFIER);
if (createImageLocations) {
ImageLocationInfo info= createImageLocationInfo(t);
if (info != null) {
info.fTokenOffsetInExpansion= offset;
fImageLocationInfos.add(info);
}
addImageLocationInfo(offset, t);
}
break;
case IToken.tIDENTIFIER:
if (createImageLocations) {
ImageLocationInfo info= createImageLocationInfo(t);
if (info != null) {
info.fTokenOffsetInExpansion= offset;
fImageLocationInfos.add(info);
}
addImageLocationInfo(offset, t);
}
break;
@ -970,10 +974,16 @@ public class MacroExpander {
continue;
case IToken.tCOMPLETION:
// we need to preserve the length of the completion token.
// We need to preserve the length of the completion token.
t.setOffset(offset, offset + t.getLength());
t.setNext(null);
return;
default:
if (createImageLocations && t.fSource instanceof CPreprocessor) {
addImageLocationInfo(offset, t);
}
break;
}
t.setOffset(offset, ++offset);
l= t;

View file

@ -116,8 +116,7 @@ public class MacroExpansionTracker {
toString(result, lexInput, replacementText, replacementText, replacementText);
fPreStep= new String(lexInput);
fReplacement= new ReplaceEdit(0, endOffset, replacementText.toString());
}
else {
} else {
// the regular case the result contains the text before the step
StringBuilder before= new StringBuilder();
StringBuilder replace= new StringBuilder();
@ -142,7 +141,8 @@ public class MacroExpansionTracker {
fReplacement= new ReplaceEdit(0, 0, ""); //$NON-NLS-1$
}
private void toString(TokenList tokenList, char[] rootInput, StringBuilder before, StringBuilder replace, StringBuilder after) {
private void toString(TokenList tokenList, char[] rootInput, StringBuilder before,
StringBuilder replace, StringBuilder after) {
StringBuilder buf= before;
Token t= tokenList.first();
if (t == null) {
@ -156,8 +156,7 @@ public class MacroExpansionTracker {
char[] input= getInputForSource(l.fSource, rootInput);
if (input == null) {
buf.append(' ');
}
else {
} else {
final int from = l.getEndOffset();
final int to = t.getOffset();
buf.append(input, from, to - from);
@ -169,8 +168,7 @@ public class MacroExpansionTracker {
char[] input= getInputForSource(t.fSource, rootInput);
if (input == null) {
buf.append(t.getCharImage());
}
else {
} else {
buf.append(input, t.getOffset(), t.getLength());
}
if (t == fReplaceTo) {
@ -324,7 +322,8 @@ public class MacroExpansionTracker {
* @param replacement the replacement
* @param result a list to store the macro in.
*/
public void storeObjectStyleMacroReplacement(PreprocessorMacro macro, Token identifier, TokenList replacement, TokenList result) {
public void storeObjectStyleMacroReplacement(PreprocessorMacro macro, Token identifier,
TokenList replacement, TokenList result) {
fMacroDefinition= macro;
fReplaceFrom= fReplaceTo= identifier;
result.append(identifier);

View file

@ -44,7 +44,6 @@
* mixing with 12*3 instructions on 3 integers than you can with 3 instructions
* on 1 byte), but shoehorning those bytes into integers efficiently is messy.
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
/**

View file

@ -56,7 +56,6 @@ public class Token implements IToken, Cloneable {
return fNextToken;
}
@Override
final public void setType(int kind) {
fKind= kind;

View file

@ -17,7 +17,8 @@ class TokenList {
final Token removeFirst() {
final Token first= fFirst;
if (first == fLast) {
fFirst= fLast= null;
fFirst= null;
fLast= null;
return first;
}
fFirst= (Token) first.getNext();
@ -26,9 +27,9 @@ class TokenList {
public final void append(Token t) {
if (fFirst == null) {
fFirst= fLast= t;
}
else {
fFirst= t;
fLast= t;
} else {
fLast.setNext(t);
fLast= t;
}
@ -40,13 +41,13 @@ class TokenList {
if (t != null) {
if (fFirst == null) {
fFirst= tl.fFirst;
}
else {
} else {
fLast.setNext(tl.fFirst);
}
fLast= tl.fLast;
}
tl.fFirst= tl.fLast= null;
tl.fFirst= null;
tl.fLast= null;
}
public final void appendAllButLast(TokenList tl) {
@ -110,8 +111,7 @@ class TokenList {
fLast= null;
}
}
}
else {
} else {
final Token r= (Token) l.getNext();
if (r != null) {
l.setNext(r.getNext());
@ -124,16 +124,17 @@ class TokenList {
void cutAfter(Token l) {
if (l == null) {
fFirst= fLast= null;
}
else {
fFirst= null;
fLast= null;
} else {
l.setNext(null);
fLast= l;
}
}
public void clear() {
fFirst= fLast= null;
fFirst= null;
fLast= null;
}
public boolean isEmpty() {

View file

@ -147,7 +147,6 @@ public class TokenUtil {
}
}
/**
* Returns the last token in the given token list.
* @throws NullPointerException if the argument is null
@ -159,5 +158,4 @@ public class TokenUtil {
} while ((tokenList = tokenList.getNext()) != null);
return last;
}
}

View file

@ -228,10 +228,11 @@ public class PDOM extends PlatformObject implements IPDOM {
* 136.0 - Extended CPPTemplateTypeArgument to include the original type, bug 392278.
* 137.0 - Fixed serialization of very large types and template arguments, bug 392278.
* 138.0 - Constexpr functions, bug 395238.
* 139.0 - More efficient and robust storage of types and template arguments, bug 395243.
*/
private static final int MIN_SUPPORTED_VERSION= version(138, 0);
private static final int MAX_SUPPORTED_VERSION= version(138, Short.MAX_VALUE);
private static final int DEFAULT_VERSION = version(138, 0);
private static final int MIN_SUPPORTED_VERSION= version(139, 0);
private static final int MAX_SUPPORTED_VERSION= version(139, Short.MAX_VALUE);
private static final int DEFAULT_VERSION = version(139, 0);
private static int version(int major, int minor) {
return (major << 16) + minor;

View file

@ -65,7 +65,7 @@ import com.ibm.icu.text.MessageFormat;
*
*/
public class Database {
// public for tests only, you shouldn't need these
// Public for tests only, you shouldn't need these.
public static final int INT_SIZE = 4;
public static final int CHUNK_SIZE = 1024 * 4;
public static final int OFFSET_IN_CHUNK_MASK= CHUNK_SIZE-1;
@ -76,13 +76,14 @@ public class Database {
public static final int MAX_BLOCK_DELTAS = CHUNK_SIZE / BLOCK_SIZE_DELTA;
public static final int MAX_MALLOC_SIZE = MAX_BLOCK_DELTAS * BLOCK_SIZE_DELTA - BLOCK_HEADER_SIZE;
public static final int PTR_SIZE = 4; // size of a pointer in the database in bytes
// The lower bound for TYPE_SIZE is 1 + PTR_SIZE, but a slightly larger space for types stored
// inline produces in a slightly smaller overall database size.
public static final int TYPE_SIZE = 2 + PTR_SIZE; // size of a type in the database in bytes
public static final int VALUE_SIZE = TYPE_SIZE; // size of a value in the database in bytes
public static final int EVALUATION_SIZE = TYPE_SIZE; // size of an evaluation in the database in bytes
public static final int ARGUMENT_SIZE = TYPE_SIZE; // size of a template argument in the database in bytes
public static final long MAX_DB_SIZE= ((long) 1 << (Integer.SIZE + BLOCK_SIZE_DELTA_BITS));
public static final int VERSION_OFFSET = 0;
public static final int DATA_AREA = (CHUNK_SIZE / BLOCK_SIZE_DELTA - MIN_BLOCK_DELTAS + 2) * INT_SIZE;
@ -92,8 +93,8 @@ public class Database {
private final File fLocation;
private final boolean fReadOnly;
private RandomAccessFile fFile;
private boolean fExclusiveLock; // necessary for any write operation
private boolean fLocked; // necessary for any operation.
private boolean fExclusiveLock; // Necessary for any write operation.
private boolean fLocked; // Necessary for any operation.
private boolean fIsMarkedIncomplete;
private int fVersion;
@ -125,7 +126,7 @@ public class Database {
int nChunksOnDisk = (int) (fFile.length() / CHUNK_SIZE);
fHeaderChunk= new Chunk(this, 0);
fHeaderChunk.fLocked= true; // never makes it into the cache, needed to satisfy assertions
fHeaderChunk.fLocked= true; // Never makes it into the cache, needed to satisfy assertions.
if (nChunksOnDisk <= 0) {
fVersion= version;
fChunks= new Chunk[1];
@ -188,7 +189,7 @@ public class Database {
while (position < size) {
nRead = from.transferTo(position, 4096 * 16, target);
if (nRead == 0) {
break; // Should not happen
break; // Should not happen.
} else {
position+= nRead;
}
@ -214,14 +215,14 @@ public class Database {
removeChunksFromCache();
fVersion= version;
// clear the first chunk.
// Clear the first chunk.
fHeaderChunk.clear(0, CHUNK_SIZE);
// chunks have been removed from the cache, so we may just reset the array of chunks.
// Chunks have been removed from the cache, so we may just reset the array of chunks.
fChunks = new Chunk[] {null};
fChunksUsed = fChunksAllocated = fChunks.length;
try {
fHeaderChunk.flush(); // zero out header chunk
fFile.getChannel().truncate(CHUNK_SIZE); // truncate database
fHeaderChunk.flush(); // Zero out header chunk.
fFile.getChannel().truncate(CHUNK_SIZE); // Truncate database.
} catch (IOException e) {
CCorePlugin.log(e);
}
@ -303,7 +304,7 @@ public class Database {
needDeltas= MIN_BLOCK_DELTAS;
}
// Which block size
// Which block size.
long freeblock = 0;
int useDeltas;
for (useDeltas= needDeltas; useDeltas <= MAX_BLOCK_DELTAS; useDeltas++) {
@ -312,10 +313,10 @@ public class Database {
break;
}
// get the block
// Get the block.
Chunk chunk;
if (freeblock == 0) {
// allocate a new chunk
// Allocate a new chunk.
freeblock= createNewChunk();
useDeltas = MAX_BLOCK_DELTAS;
chunk = getChunk(freeblock);
@ -326,16 +327,16 @@ public class Database {
final int unusedDeltas = useDeltas-needDeltas;
if (unusedDeltas >= MIN_BLOCK_DELTAS) {
// Add in the unused part of our block
// Add in the unused part of our block.
addBlock(chunk, unusedDeltas*BLOCK_SIZE_DELTA, freeblock + needDeltas*BLOCK_SIZE_DELTA);
useDeltas= needDeltas;
}
// Make our size negative to show in use
// Make our size negative to show in use.
final int usedSize= useDeltas*BLOCK_SIZE_DELTA;
chunk.putShort(freeblock, (short) -usedSize);
// Clear out the block, lots of people are expecting this
// Clear out the block, lots of people are expecting this.
chunk.clear(freeblock + BLOCK_HEADER_SIZE, usedSize-BLOCK_HEADER_SIZE);
malloced+= usedSize;
@ -419,7 +420,7 @@ public class Database {
long nextblock = chunk.getFreeRecPtr(block + BLOCK_NEXT_OFFSET);
if (prevblock != 0) {
putFreeRecPtr(prevblock + BLOCK_NEXT_OFFSET, nextblock);
} else { // we were the head
} else { // We were the head.
setFirstBlock(blocksize, nextblock);
}
@ -432,7 +433,7 @@ public class Database {
// Mark our size
chunk.putShort(block, (short) blocksize);
// Add us to the head of the list
// Add us to the head of the list.
long prevfirst = getFirstBlock(blocksize);
chunk.putFreeRecPtr(block + BLOCK_PREV_OFFSET, 0);
chunk.putFreeRecPtr(block + BLOCK_NEXT_OFFSET, prevfirst);
@ -448,13 +449,14 @@ public class Database {
*/
public void free(long offset) throws CoreException {
assert fExclusiveLock;
// TODO - look for opportunities to merge blocks
// TODO Look for opportunities to merge blocks
long block = offset - BLOCK_HEADER_SIZE;
Chunk chunk = getChunk(block);
int blocksize = - chunk.getShort(block);
if (blocksize < 0) {
// already freed
throw new CoreException(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, 0, "Already Freed", new Exception())); //$NON-NLS-1$
// Already freed.
throw new CoreException(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, 0,
"Already freed", new Exception())); //$NON-NLS-1$
}
addBlock(chunk, blocksize, block);
freed += blocksize;
@ -614,7 +616,7 @@ public class Database {
flush();
removeChunksFromCache();
// chunks have been removed from the cache, so we are fine
// Chunks have been removed from the cache, so we are fine.
fHeaderChunk.clear(0, CHUNK_SIZE);
fHeaderChunk.fDirty= false;
fChunks= new Chunk[] { null };
@ -672,15 +674,15 @@ public class Database {
Chunk chunk= fChunks[i];
if (chunk != null) {
if (chunk.fCacheIndex < 0) {
// locked chunk that has been removed from cache.
// Locked chunk that has been removed from cache.
if (chunk.fDirty) {
dirtyChunks.add(chunk); // keep in fChunks until it is flushed.
dirtyChunks.add(chunk); // Keep in fChunks until it is flushed.
} else {
chunk.fLocked= false;
fChunks[i]= null;
}
} else if (chunk.fLocked) {
// locked chunk, still in cache.
// Locked chunk, still in cache.
if (chunk.fDirty) {
if (flush) {
dirtyChunks.add(chunk);
@ -689,12 +691,12 @@ public class Database {
chunk.fLocked= false;
}
} else {
assert !chunk.fDirty; // dirty chunks must be locked.
assert !chunk.fDirty; // Dirty chunks must be locked.
}
}
}
}
// also handles header chunk
// Also handles header chunk.
flushAndUnlockChunks(dirtyChunks, flush);
} finally {
fExclusiveLock= false;
@ -713,7 +715,7 @@ public class Database {
return;
}
// be careful as other readers may access chunks concurrently
// Be careful as other readers may access chunks concurrently.
ArrayList<Chunk> dirtyChunks= new ArrayList<Chunk>();
synchronized (fCache) {
for (int i= 1; i < fChunksUsed ; i++) {
@ -724,7 +726,7 @@ public class Database {
}
}
// also handles header chunk
// Also handles header chunk.
flushAndUnlockChunks(dirtyChunks, true);
}
@ -742,7 +744,7 @@ public class Database {
}
}
// only after the chunks are flushed we may unlock and release them.
// Only after the chunks are flushed we may unlock and release them.
synchronized (fCache) {
for (Chunk chunk : dirtyChunks) {
chunk.fLocked= false;

View file

@ -33,7 +33,7 @@ import org.eclipse.core.runtime.CoreException;
/**
* For marshalling types to byte arrays.
*/
public class TypeMarshalBuffer implements ITypeMarshalBuffer {
public final class TypeMarshalBuffer implements ITypeMarshalBuffer {
public static final byte[] EMPTY= { 0, 0, 0, 0, 0, 0 };
public static final byte NULL_TYPE= 0;
public static final byte INDIRECT_TYPE= (byte) -1;
@ -69,6 +69,11 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
return fPos;
}
public void setPosition(int pos) {
assert 0 <= pos && pos <= fPos;
fPos = pos;
}
public byte[] getBuffer() {
return fBuffer;
}
@ -257,23 +262,7 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
}
@Override
public void putShort(short value) {
request(2);
fBuffer[fPos++]= (byte) (value >> 8);
fBuffer[fPos++]= (byte) (value);
}
@Override
public int getShort() throws CoreException {
if (fPos + 2 > fBuffer.length)
throw unmarshallingError();
final int byte1 = 0xff & fBuffer[fPos++];
final int byte2 = 0xff & fBuffer[fPos++];
return (((byte1 << 8) | (byte2 & 0xff)));
}
@Override
public void putInt(int value) {
public void putFixedInt(int value) {
request(4);
fPos += 4;
int p= fPos;
@ -284,7 +273,7 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
}
@Override
public int getInt() throws CoreException {
public int getFixedInt() throws CoreException {
if (fPos + 4 > fBuffer.length)
throw unmarshallingError();
int result= 0;
@ -295,35 +284,48 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
return result;
}
@Override
public void putInt(int value) {
do {
int b = value & 0x7F;
value >>>= 7;
if (value != 0)
b |= 0x80;
putByte((byte) b);
} while (value != 0);
}
@Override
public void putLong(long value) {
request(8);
fPos += 8;
int p= fPos;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value);
do {
int b = (int) value & 0x7F;
value >>>= 7;
if (value != 0)
b |= 0x80;
putByte((byte) b);
} while (value != 0);
}
@Override
public int getInt() throws CoreException {
int b = getByte();
int value = b & 0x7F;
for (int shift = 7; (b & 0x80) != 0; shift += 7) {
b = getByte();
value |= (b & 0x7F) << shift;
}
return value;
}
@Override
public long getLong() throws CoreException {
if (fPos + 8 > fBuffer.length)
throw unmarshallingError();
long result= 0;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
result |= fBuffer[fPos++] & 0xff;
return result;
int b = getByte();
long value = b & 0x7F;
for (int shift = 7; (b & 0x80) != 0; shift += 7) {
b = getByte();
value |= (b & 0x7F) << shift;
}
return value;
}
private void putRecordPointer(long record) {
@ -344,19 +346,19 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
@Override
public void putCharArray(char[] chars) {
putShort((short) chars.length);
putInt(chars.length);
for (char c : chars) {
putShort((short) c);
putInt(c & 0xFFFF);
}
}
@Override
public char[] getCharArray() throws CoreException {
int len= getShort();
char[] expr= new char[len];
for (int i = 0; i < expr.length; i++) {
expr[i]= (char) getShort();
int len= getInt();
char[] chars= new char[len];
for (int i = 0; i < chars.length; i++) {
chars[i]= (char) getInt();
}
return expr;
return chars;
}
}

View file

@ -60,7 +60,7 @@ import org.eclipse.core.runtime.IProgressMonitor;
* link time. These are generally global symbols specific to a given language.
*/
public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage, IIndexBindingConstants {
// record offsets
// Record offsets.
private static final int ID_OFFSET = PDOMNamedNode.RECORD_SIZE + 0;
private static final int NEXT_OFFSET = PDOMNamedNode.RECORD_SIZE + 4;
private static final int INDEX_OFFSET = PDOMNamedNode.RECORD_SIZE + 8;
@ -71,7 +71,7 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
protected static final int RECORD_SIZE = PDOMNamedNode.RECORD_SIZE + 20;
protected static final long[] FILE_LOCAL_REC_DUMMY = new long[]{0};
// node types
// Node types
protected static final int LINKAGE= 0; // special one for myself
private BTree fMacroIndex= null; // No need for volatile, all fields of BTree are final.
@ -450,9 +450,11 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
} else {
db.putByte(offset, TypeMarshalBuffer.INDIRECT_TYPE);
long chainOffset = offset + 1;
buf.putInt(len);
int lenSize = buf.getPosition() - len;
int bufferPos = 0;
while (bufferPos < len) {
int chunkLength = len - bufferPos + 2;
int chunkLength = bufferPos == 0 ? len + lenSize : len - bufferPos;
boolean chainingRequired = false;
if (chunkLength > Database.MAX_MALLOC_SIZE) {
chunkLength = Database.MAX_MALLOC_SIZE;
@ -460,36 +462,52 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
}
long ptr = db.malloc(chunkLength);
db.putRecPtr(chainOffset, ptr);
db.putShort(ptr, (short) len);
int pos = 2;
if (bufferPos == 0) {
// Write length.
db.putBytes(ptr, buf.getBuffer(), len, lenSize);
ptr += lenSize;
chunkLength -= lenSize;
}
if (chainingRequired) {
// Reserve space for the chaining pointer.
chainOffset = ptr + 2; pos += Database.PTR_SIZE;
chainOffset = ptr;
ptr += Database.PTR_SIZE;
chunkLength -= Database.PTR_SIZE;
}
chunkLength -= pos;
db.putBytes(ptr + pos, buf.getBuffer(), bufferPos, chunkLength);
db.putBytes(ptr, buf.getBuffer(), bufferPos, chunkLength);
bufferPos += chunkLength;
}
buf.setPosition(len); // Restore buffer position.
}
}
}
private byte[] loadLinkedSerializedData(final Database db, long offset) throws CoreException {
long ptr= db.getRecPtr(offset);
int len= db.getShort(ptr) & 0xffff;
// Read the length in variable-length base-128 encoding, see ITypeMarshalBuffer.putInt(int).
int pos = 0;
int b = db.getByte(ptr + pos++);
int len = b & 0x7F;
for (int shift = 7; (b & 0x80) != 0; shift += 7) {
b = db.getByte(ptr + pos++);
len |= (b & 0x7F) << shift;
}
byte[] data= new byte[len];
int bufferPos = 0;
while (bufferPos < len) {
int chunkLength = len - bufferPos + 2;
int pos = 2;
long chunkPtr = ptr;
int chunkLength = len + pos - bufferPos;
long chunkPtr = ptr + pos;
if (chunkLength > Database.MAX_MALLOC_SIZE) {
chunkLength = Database.MAX_MALLOC_SIZE;
ptr= db.getRecPtr(chunkPtr + pos); pos += Database.PTR_SIZE;
ptr= db.getRecPtr(chunkPtr);
chunkPtr += Database.PTR_SIZE;
chunkLength -= Database.PTR_SIZE;
}
chunkLength -= pos;
db.getBytes(chunkPtr + pos, data, bufferPos, chunkLength);
db.getBytes(chunkPtr, data, bufferPos, chunkLength);
bufferPos += chunkLength;
pos = 0;
}
return data;
}
@ -497,18 +515,26 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
private void deleteSerializedData(Database db, long offset, int maxInlineSize) throws CoreException {
byte firstByte= db.getByte(offset);
if (firstByte == TypeMarshalBuffer.INDIRECT_TYPE) {
long ptr= db.getRecPtr(offset + 1);
int len= db.getShort(ptr) & 0xffff;
long chunkPtr= db.getRecPtr(offset + 1);
long ptr = chunkPtr;
// Read the length in variable-length base-128 encoding, see ITypeMarshalBuffer.putInt(int).
int b = db.getByte(ptr++);
int len = b & 0x7F;
for (int shift = 7; (b & 0x80) != 0; shift += 7) {
b = db.getByte(ptr++);
len |= (b & 0x7F) << shift;
}
len += ptr - chunkPtr;
while (len > 0) {
int chunkLength = len + 2;
int pos = 2;
long chunkPtr = ptr;
int chunkLength = len;
if (chunkLength > Database.MAX_MALLOC_SIZE) {
chunkLength = Database.MAX_MALLOC_SIZE;
ptr= db.getRecPtr(chunkPtr + pos); pos += Database.PTR_SIZE;
ptr= db.getRecPtr(ptr);
chunkLength -= Database.PTR_SIZE;
}
chunkLength -= pos;
db.free(chunkPtr);
chunkPtr = ptr;
len -= chunkLength;
}
}

View file

@ -60,7 +60,8 @@ public class PDOMCPPClassTemplate extends PDOMCPPClassType
private volatile ICPPTemplateParameter[] params; // Cached template parameters.
public PDOMCPPClassTemplate(PDOMCPPLinkage linkage, PDOMNode parent, ICPPClassTemplate template) throws CoreException, DOMException {
public PDOMCPPClassTemplate(PDOMCPPLinkage linkage, PDOMNode parent, ICPPClassTemplate template)
throws CoreException, DOMException {
super(linkage, parent, template);
final Database db = getDB();
@ -127,7 +128,8 @@ public class PDOMCPPClassTemplate extends PDOMCPPClassType
}
}
private void updateTemplateParameters(PDOMLinkage linkage, ICPPTemplateParameter[] newParams) throws CoreException, DOMException {
private void updateTemplateParameters(PDOMLinkage linkage, ICPPTemplateParameter[] newParams)
throws CoreException, DOMException {
final Database db = getDB();
long rec= db.getRecPtr(record + PARAMETERS);
IPDOMCPPTemplateParameter[] allParams;

View file

@ -1057,7 +1057,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
IBinding owner= binding.getOwner();
if (owner instanceof ICPPNamespace) {
if (owner.getNameCharArray().length == 0) {
IASTNode node= ASTInternal.getDeclaredInSourceFileOnly(getPDOM(), owner, false, glob);
IASTNode node= ASTInternal.getDeclaredInSourceFileOnly(getPDOM(), binding, false, glob);
if (node != null) {
file= wpdom.getFileForASTNode(getLinkageID(), node);
}

View file

@ -50,7 +50,6 @@ import org.eclipse.core.runtime.CoreException;
*/
class PDOMCPPNamespace extends PDOMCPPBinding
implements ICPPNamespace, ICPPNamespaceScope, IIndexScope {
private static final int INDEX_OFFSET = PDOMCPPBinding.RECORD_SIZE;
private static final int FIRST_NAMESPACE_CHILD_OFFSET = INDEX_OFFSET + Database.PTR_SIZE;
private static final int NEXT_NAMESPACE_SIBBLING_OFFSET = FIRST_NAMESPACE_CHILD_OFFSET + Database.PTR_SIZE;

View file

@ -22,7 +22,7 @@ import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
/**
* Collects methods to store an argument list in the database
* Collects methods to store an argument list in the database.
*/
public class PDOMTemplateParameterArray {
/**
@ -67,7 +67,8 @@ public class PDOMTemplateParameterArray {
/**
* Creates template parameters in the pdom
*/
public static IPDOMCPPTemplateParameter[] createPDOMTemplateParameters(PDOMLinkage linkage, PDOMNode parent, ICPPTemplateParameter[] origParams) throws CoreException, DOMException {
public static IPDOMCPPTemplateParameter[] createPDOMTemplateParameters(PDOMLinkage linkage,
PDOMNode parent, ICPPTemplateParameter[] origParams) throws CoreException, DOMException {
IPDOMCPPTemplateParameter[] params= new IPDOMCPPTemplateParameter[origParams.length];
for (int i = 0; i < origParams.length; i++) {
params[i]= createPDOMTemplateParameter(linkage, parent, origParams[i]);
@ -78,7 +79,8 @@ public class PDOMTemplateParameterArray {
/**
* Creates a template parameter in the pdom
*/
public static IPDOMCPPTemplateParameter createPDOMTemplateParameter(PDOMLinkage linkage, PDOMNode parent, ICPPTemplateParameter origParam) throws CoreException, DOMException {
public static IPDOMCPPTemplateParameter createPDOMTemplateParameter(PDOMLinkage linkage,
PDOMNode parent, ICPPTemplateParameter origParam) throws CoreException, DOMException {
IPDOMCPPTemplateParameter param= null;
if (origParam instanceof ICPPTemplateNonTypeParameter) {
param= new PDOMCPPTemplateNonTypeParameter(linkage, parent, (ICPPTemplateNonTypeParameter) origParam);

View file

@ -66,6 +66,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
@ -143,6 +144,7 @@ import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator;
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterOptions;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.formatter.align.Alignment;
import org.eclipse.cdt.internal.formatter.align.AlignmentException;
@ -232,6 +234,28 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
}
}
private static class TokenRange {
private int offset;
private int endOffset;
TokenRange(int offset, int endOffset) {
this.offset = offset;
this.endOffset = endOffset;
}
int getOffset() {
return offset;
}
int getEndOffset() {
return endOffset;
}
int getLength() {
return endOffset - offset;
}
}
/**
* Formats a trailing semicolon.
* @see #formatList(List, ListOptions, boolean, boolean, Runnable)
@ -360,6 +384,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
private final Scribe scribe;
private boolean fInsideFor;
private boolean fInsideMacroArguments;
private boolean fExpectSemicolonAfterDeclaration= true;
private MultiStatus fStatus;
@ -540,97 +565,79 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
if (fileLocation != null) {
scribe.printRaw(fileLocation.getNodeOffset(), fileLocation.getNodeLength());
}
fileLocation = macroExpansion.getFileLocation();
scribe.printNextToken(Token.tLPAREN);
IMacroBinding binding = (IMacroBinding) name.resolveBinding();
if (preferences.insert_space_after_opening_paren_in_method_invocation) {
scribe.space();
}
final int continuationIndentation = preferences.continuation_indentation;
Alignment listAlignment = scribe.createAlignment(
Alignment.MACRO_ARGUMENTS,
preferences.alignment_for_arguments_in_method_invocation,
Alignment.R_OUTERMOST,
binding.getParameterList().length,
getCurrentPosition(),
continuationIndentation,
false);
scribe.enterAlignment(listAlignment);
boolean ok = false;
do {
List<Object> arguments = getMacroArguments(binding.getParameterList().length);
final ListOptions options= new ListOptions(preferences.alignment_for_arguments_in_method_invocation);
options.fSeparatorToken = Token.tCOMMA;
options.fSpaceAfterOpeningParen= preferences.insert_space_after_opening_paren_in_method_invocation;
options.fSpaceBeforeClosingParen= preferences.insert_space_before_closing_paren_in_method_invocation;
options.fSpaceBetweenEmptyParen= preferences.insert_space_between_empty_parens_in_method_invocation;
options.fSpaceBeforeSeparator= preferences.insert_space_before_comma_in_method_invocation_arguments;
options.fSpaceAfterSeparator= preferences.insert_space_after_comma_in_method_invocation_arguments;
options.fTieBreakRule = Alignment.R_OUTERMOST;
fInsideMacroArguments = true;
try {
int fragment = 0;
scribe.alignFragment(listAlignment, fragment);
formatList(arguments, options, true, false, scribe.takeTailFormatter());
} finally {
fInsideMacroArguments = false;
}
}
/**
* Scans macro expansion arguments starting from the current position and returns a list of
* arguments where each argument is represented either by a {@link IASTNode} or, if not
* possible, by a {@link TokenRange}.
*/
private List<Object> getMacroArguments(int expectedNumberOfArguments) {
List<TokenRange> argumentRanges = new ArrayList<TokenRange>(expectedNumberOfArguments);
TokenRange currentArgument = null;
localScanner.resetTo(getCurrentPosition(), scribe.scannerEndPosition);
localScanner.getNextToken(); // Skip the opening parenthesis.
int parenLevel = 0;
boolean done = false;
while (!done) {
boolean hasWhitespace= scribe.printComment();
int token = peekNextToken();
int token;
while ((token = localScanner.getNextToken()) != Token.tBADCHAR) {
int tokenOffset = localScanner.getCurrentTokenStartPosition();
if (parenLevel == 0 && (token == Token.tCOMMA || token == Token.tRPAREN)) {
if (currentArgument != null) {
argumentRanges.add(currentArgument);
currentArgument = null;
} else {
argumentRanges.add(new TokenRange(tokenOffset, tokenOffset));
}
if (token == Token.tRPAREN)
break;
} else {
int tokenEndOffset = localScanner.getCurrentPosition();
if (currentArgument == null) {
currentArgument = new TokenRange(tokenOffset, tokenEndOffset);
} else {
currentArgument.endOffset = tokenEndOffset;
}
switch (token) {
case Token.tLPAREN:
++parenLevel;
scribe.printNextToken(token, hasWhitespace);
break;
case Token.tRPAREN:
if (parenLevel > 0) {
if (parenLevel > 0)
--parenLevel;
scribe.printNextToken(token, hasWhitespace);
break;
}
}
}
List<Object> arguments = new ArrayList<Object>(argumentRanges.size());
IASTNodeSelector nodeSelector = ast.getNodeSelector(null);
for (TokenRange argument : argumentRanges) {
IASTNode node = nodeSelector.findNodeInExpansion(argument.getOffset(), argument.getLength());
if (node != null) {
arguments.add(node);
} else {
if (preferences.insert_space_before_closing_paren_in_method_invocation) {
scribe.space();
}
scribe.printNextToken(token);
done = true;
}
break;
case Token.tCOMMA:
if (parenLevel == 0 && preferences.insert_space_before_comma_in_method_invocation_arguments) {
scribe.space();
}
scribe.printNextToken(token);
if (parenLevel == 0) {
if (preferences.insert_space_after_comma_in_method_invocation_arguments) {
scribe.space();
}
scribe.printComment();
++fragment;
if (fragment < listAlignment.fragmentCount) {
scribe.alignFragment(listAlignment, fragment);
arguments.add(argument);
}
}
break;
case Token.tSTRING:
case Token.tLSTRING:
case Token.tRSTRING:
boolean needSpace= hasWhitespace;
while (true) {
scribe.printNextToken(token, needSpace);
if (peekNextToken() != token) {
break;
}
scribe.printCommentPreservingNewLines();
needSpace= true;
}
break;
case Token.tBADCHAR:
// Avoid infinite loop if something bad happened.
scribe.exitAlignment(listAlignment, true);
return;
default:
scribe.printNextToken(token, hasWhitespace);
}
}
int token = peekNextToken();
if (token == Token.tSEMI) {
scribe.printNextToken(token);
scribe.startNewLine();
}
ok = true;
} catch (AlignmentException e) {
scribe.redoAlignment(e);
}
} while (!ok);
scribe.exitAlignment(listAlignment, true);
return arguments;
}
@Override
@ -2077,15 +2084,16 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
/**
* Format a given list of elements according alignment options.
*
* @param elements the elements to format
* @param elements the elements to format, which can be either {@link IASTNode}s or
* {@link TokenRange}s.
* @param options formatting options
* @param encloseInParen indicates whether the list should be enclosed in parentheses
* @param addEllipsis indicates whether ellipsis should be added after the last element
* @param tailFormatter formatter for the trailing text that should be kept together with
* the last element of the list.
*/
private void formatList(List<? extends IASTNode> elements, ListOptions options,
boolean encloseInParen, boolean addEllipsis, Runnable tailFormatter) {
private void formatList(List<?> elements, ListOptions options, boolean encloseInParen,
boolean addEllipsis, Runnable tailFormatter) {
if (encloseInParen)
scribe.printNextToken(Token.tLPAREN, options.fSpaceBeforeOpeningParen);
@ -2118,22 +2126,26 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
try {
int i;
for (i = 0; i < elementsLength; i++) {
final IASTNode node= elements.get(i);
final Object element = elements.get(i);
if (i < elementsLength - 1) {
scribe.setTailFormatter(
new TrailingTokenFormatter(options.fSeparatorToken,
findTokenAfterNode(options.fSeparatorToken, node),
findTokenAfterNodeOrTokenRange(options.fSeparatorToken, element),
options.fSpaceBeforeSeparator,
options.fSpaceAfterSeparator));
} else {
scribe.setTailFormatter(tailFormatter);
}
scribe.alignFragment(alignment, i);
if (node instanceof ICPPASTConstructorChainInitializer) {
if (element instanceof IASTNode) {
if (element instanceof ICPPASTConstructorChainInitializer) {
// Constructor chain initializer is a special case.
visit((ICPPASTConstructorChainInitializer) node);
visit((ICPPASTConstructorChainInitializer) element);
} else {
node.accept(this);
((IASTNode) element).accept(this);
}
} else {
formatTokenRange((TokenRange) element);
}
if (i < elementsLength - 1) {
scribe.runTailFormatter();
@ -2163,6 +2175,15 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
}
}
private void formatTokenRange(TokenRange tokenRange) {
scribe.restartAtOffset(tokenRange.getOffset());
while (getCurrentPosition() < tokenRange.getEndOffset()) {
boolean hasWhitespace= scribe.printComment();
int token = peekNextToken();
scribe.printNextToken(token, hasWhitespace);
}
}
private int visit(ICPPASTTryBlockStatement node) {
scribe.printNextToken(Token.t_try, scribe.printComment());
final IASTStatement tryBody= node.getTryBody();
@ -3782,18 +3803,23 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
}
IASTNodeLocation[] locations= node.getNodeLocations();
if (locations.length == 0) {
} else if (locations[0] instanceof IASTMacroExpansionLocation) {
} else if (!fInsideMacroArguments && locations[0] instanceof IASTMacroExpansionLocation) {
IASTMacroExpansionLocation location = (IASTMacroExpansionLocation) locations[0];
if (locations.length <= 2 && node instanceof IASTStatement) {
IASTPreprocessorMacroExpansion macroExpansion = location.getExpansion();
IASTFileLocation macroLocation = macroExpansion.getFileLocation();
IASTFileLocation nodeLocation = node.getFileLocation();
IASTFileLocation nodeLocation = getFileLocation(node);
if (macroLocation.getNodeOffset() >= getCurrentPosition() &&
!scribe.shouldSkip(macroLocation.getNodeOffset()) &&
(nodeLocation.getNodeOffset() + nodeLocation.getNodeLength() ==
macroLocation.getNodeOffset() + macroLocation.getNodeLength() ||
locations.length == 2 && isSemicolonLocation(locations[1])) &&
isFunctionStyleMacroExpansion(macroExpansion)) {
if (locations.length == 2 && isSemicolonLocation(locations[1])) {
scribe.setTailFormatter(
new TrailingTokenFormatter(Token.tSEMI, locations[1].getNodeOffset(),
preferences.insert_space_before_semicolon, false));
}
formatFunctionStyleMacroExpansion(macroExpansion);
return false;
}
@ -3808,12 +3834,16 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
return false;
}
} else {
IASTFileLocation fileLocation= node.getFileLocation();
IASTFileLocation fileLocation= getFileLocation(node);
scribe.restartAtOffset(fileLocation.getNodeOffset());
}
return true;
}
private IASTFileLocation getFileLocation(IASTNode node) {
return fInsideMacroArguments ? ((ASTNode) node).getImageLocation() : node.getFileLocation();
}
/**
* Formatting of node is complete. Undo skip region if any.
*
@ -3824,7 +3854,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
return;
}
if (scribe.skipRange()) {
IASTFileLocation fileLocation= node.getFileLocation();
IASTFileLocation fileLocation= getFileLocation(node);
if (fileLocation != null) {
int nodeEndOffset= fileLocation.getNodeOffset() + fileLocation.getNodeLength();
scribe.restartAtOffset(nodeEndOffset);
@ -3845,7 +3875,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
if (node instanceof IASTProblemHolder || node instanceof IASTTranslationUnit) {
return;
}
IASTFileLocation fileLocation= node.getFileLocation();
IASTFileLocation fileLocation= getFileLocation(node);
if (fileLocation == null) {
return;
}
@ -3881,7 +3911,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
}
private void skipNode(IASTNode node) {
final IASTNodeLocation fileLocation= node.getFileLocation();
final IASTNodeLocation fileLocation= getFileLocation(node);
if (fileLocation != null && fileLocation.getNodeLength() > 0) {
final int endOffset= fileLocation.getNodeOffset() + fileLocation.getNodeLength();
final int currentOffset= getCurrentPosition();
@ -3893,7 +3923,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
}
private void skipToNode(IASTNode node) {
final IASTNodeLocation fileLocation= node.getFileLocation();
final IASTNodeLocation fileLocation= getFileLocation(node);
if (fileLocation != null) {
final int startOffset= fileLocation.getNodeOffset();
final int currentOffset= getCurrentPosition();
@ -3905,7 +3935,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
}
private void skipNonWhitespaceToNode(IASTNode node) {
final IASTNodeLocation fileLocation= node.getFileLocation();
final IASTNodeLocation fileLocation= getFileLocation(node);
if (fileLocation != null) {
final int startOffset= fileLocation.getNodeOffset();
final int nextTokenOffset= getNextTokenOffset();
@ -3985,18 +4015,22 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
}
}
private static boolean startsWithMacroExpansion(IASTNode node) {
private boolean startsWithMacroExpansion(IASTNode node) {
if (fInsideMacroArguments)
return false;
IASTNodeLocation[] locations= node.getNodeLocations();
if (!(node instanceof IASTProblemHolder) && locations.length != 0 &&
locations[0] instanceof IASTMacroExpansionLocation) {
IASTFileLocation expansionLocation= locations[0].asFileLocation();
IASTFileLocation fileLocation= node.getFileLocation();
IASTFileLocation fileLocation= getFileLocation(node);
return expansionLocation.getNodeOffset() == fileLocation.getNodeOffset();
}
return false;
}
private static boolean endsWithMacroExpansion(IASTNode node) {
private boolean endsWithMacroExpansion(IASTNode node) {
if (fInsideMacroArguments)
return false;
IASTNodeLocation[] locations= node.getNodeLocations();
if (!(node instanceof IASTProblemHolder) && locations.length != 0 &&
locations[locations.length - 1] instanceof IASTMacroExpansionLocation) {
@ -4005,13 +4039,17 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
return false;
}
private static boolean enclosedInMacroExpansion(IASTNode node) {
private boolean enclosedInMacroExpansion(IASTNode node) {
if (fInsideMacroArguments)
return false;
IASTNodeLocation[] locations= node.getNodeLocations();
return locations.length == 1 && locations[0] instanceof IASTMacroExpansionLocation;
}
private static boolean withinMacroExpansion(IASTNode node, int offset) {
IASTFileLocation loc = node.getFileLocation();
private boolean withinMacroExpansion(IASTNode node, int offset) {
if (fInsideMacroArguments)
return false;
IASTFileLocation loc = getFileLocation(node);
if (loc == null || offset < loc.getNodeOffset() || offset >= loc.getNodeOffset() + loc.getNodeLength()) {
return false;
}
@ -4061,9 +4099,9 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
* normally separated by other tokens this is an indication that they were produced by the same
* macro expansion.
*/
private static boolean doNodeLocationsOverlap(IASTNode node1, IASTNode node2) {
IASTFileLocation loc1 = node1.getFileLocation();
IASTFileLocation loc2 = node2.getFileLocation();
private boolean doNodeLocationsOverlap(IASTNode node1, IASTNode node2) {
IASTFileLocation loc1 = getFileLocation(node1);
IASTFileLocation loc2 = getFileLocation(node2);
return loc1.getNodeOffset() + loc1.getNodeLength() > loc2.getNodeOffset() &&
loc1.getNodeOffset() < loc2.getNodeOffset() + loc2.getNodeLength();
}
@ -4073,16 +4111,16 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
* separated by other tokens this is an indication that they were produced by the same macro
* expansion.
*/
private static boolean doNodesHaveSameOffset(IASTNode node1, IASTNode node2) {
private boolean doNodesHaveSameOffset(IASTNode node1, IASTNode node2) {
return nodeOffset(node1) == nodeOffset(node2);
}
private static int nodeOffset(IASTNode node) {
return node.getFileLocation().getNodeOffset();
private int nodeOffset(IASTNode node) {
return getFileLocation(node).getNodeOffset();
}
private static int nodeEndOffset(IASTNode node) {
IASTFileLocation loc = node.getFileLocation();
private int nodeEndOffset(IASTNode node) {
IASTFileLocation loc = getFileLocation(node);
return loc.getNodeOffset() + loc.getNodeLength();
}
@ -4407,14 +4445,19 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
}
private int findTokenWithinNode(int tokenType, IASTNode node) {
IASTFileLocation location = node.getFileLocation();
IASTFileLocation location = getFileLocation(node);
int endOffset = location.getNodeOffset() + location.getNodeLength();
return scribe.findToken(tokenType, endOffset);
}
private int findTokenAfterNode(int tokenType, IASTNode node) {
IASTFileLocation location = node.getFileLocation();
int startOffset = location.getNodeOffset() + location.getNodeLength();
private int findTokenAfterNodeOrTokenRange(int tokenType, Object nodeOrTokenRange) {
int startOffset;
if (nodeOrTokenRange instanceof IASTNode) {
IASTFileLocation location = getFileLocation((IASTNode) nodeOrTokenRange);
startOffset = location.getNodeOffset() + location.getNodeLength();
} else {
startOffset = ((TokenRange) nodeOrTokenRange).getEndOffset();
}
return scribe.findToken(tokenType, startOffset, scribe.scannerEndPosition - 1);
}
}

View file

@ -31,9 +31,6 @@ public class Scanner extends SimpleScanner {
setSplitPreprocessor(false);
}
/*
* @see org.eclipse.cdt.internal.formatter.scanner.SimpleScanner#init(java.io.Reader, java.lang.String)
*/
@Override
protected void init(Reader reader, String filename) {
// not allowed

View file

@ -51,7 +51,6 @@ import org.eclipse.cdt.internal.ui.editor.SemanticHighlightings;
public class AbstractSemanticHighlightingTest extends TestCase {
protected static class SemanticHighlightingTestSetup extends TestSetup {
private ICProject fCProject;
private final String fTestFilename;
private File fExternalFile;

View file

@ -1765,7 +1765,6 @@ public class CodeFormatterTest extends BaseUITestCase {
// }
//#endif
//}
public void testMacroAsFunctionArguments_Bug253039() throws Exception {
assertFormatterResult();
}
@ -1901,6 +1900,33 @@ public class CodeFormatterTest extends BaseUITestCase {
assertFormatterResult();
}
//#define MACRO(a,b) f(a,b)
//void f(bool b, int i);
//int function_with_loooooooooooooooong_name();
//int another_function_with_loooooong_name();
//
//void test(){
// MACRO("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"=="bbbbbbbbbbbbbbbbbbbbbbbbbbb",function_with_loooooooooooooooong_name()+another_function_with_loooooong_name());
//}
//#define MACRO(a,b) f(a,b)
//void f(bool b, int i);
//int function_with_loooooooooooooooong_name();
//int another_function_with_loooooong_name();
//
//void test() {
// MACRO("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
// == "bbbbbbbbbbbbbbbbbbbbbbbbbbb",
// function_with_loooooooooooooooong_name()
// + another_function_with_loooooong_name());
//}
public void testMacroArguments() throws Exception {
fOptions.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, CCorePlugin.SPACE);
fOptions.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION,
Integer.toString(Alignment.M_COMPACT_SPLIT | Alignment.M_INDENT_ON_COLUMN));
assertFormatterResult();
}
//bool member __attribute__ ((__unused__)) = false;
//bool member __attribute__ ((__unused__)) = false;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2012 IBM Corporation and others.
* Copyright (c) 2004, 2013 IBM Corporation 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
@ -97,7 +97,7 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase {
super.tearDown();
}
protected void assertContentAssistResults(int offset, int length, String[] expected, boolean isCompletion, boolean isTemplate, int compareType) throws Exception {
protected void assertContentAssistResults(int offset, int length, String[] expected, boolean isCompletion, boolean isTemplate, boolean filterResults, int compareType) throws Exception {
if (CTestPlugin.getDefault().isDebugging()) {
System.out.println("\n\n\n\n\nTesting "+this.getClass().getName());
}
@ -116,11 +116,13 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase {
long endTime= System.currentTimeMillis();
assertTrue(results != null);
if (filterResults) {
if (isTemplate) {
results= filterResultsKeepTemplates(results);
} else {
results= filterResults(results, isCode);
}
}
String[] resultStrings= toStringArray(results, compareType);
Arrays.sort(expected);
Arrays.sort(resultStrings);
@ -161,6 +163,10 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase {
}
protected void assertContentAssistResults(int offset, int length, String[] expected, boolean isCompletion, boolean isTemplate, int compareType) throws Exception {
assertContentAssistResults(offset, length, expected, isCompletion, isTemplate, true, compareType);
}
protected void assertContentAssistResults(int offset, String[] expected, boolean isCompletion, int compareType) throws Exception {
assertContentAssistResults(offset, 0, expected, isCompletion, false, compareType);
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2012 Wind River Systems, Inc. and others.
* Copyright (c) 2006, 2013 Wind River Systems, Inc. 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
@ -1374,4 +1374,10 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= { "foo;" };
assertCompletionResults(fCursorOffset, expected, COMPARE_REP_STRINGS);
}
// template <typen/*cursor*/
public void testTemplateDeclaration_Bug397288() throws Exception {
final String[] expected= { "typename" };
assertContentAssistResults(fCursorOffset, 0, expected, true, false, false, COMPARE_REP_STRINGS);
}
}

View file

@ -10,7 +10,7 @@ Export-Package: org.eclipse.cdt.internal.corext;x-internal:=true,
org.eclipse.cdt.internal.corext.codemanipulation;x-internal:=true,
org.eclipse.cdt.internal.corext.fix;x-internal:=true,
org.eclipse.cdt.internal.corext.template.c;x-internal:=true,
org.eclipse.cdt.internal.corext.util;x-internal:=true,
org.eclipse.cdt.internal.corext.util;x-friends:="org.eclipse.cdt.codan.ui",
org.eclipse.cdt.internal.ui;x-friends:="org.eclipse.cdt.debug.edc.tests",
org.eclipse.cdt.internal.ui.actions;x-internal:=true,
org.eclipse.cdt.internal.ui.browser.opentype;x-internal:=true,
@ -22,7 +22,7 @@ Export-Package: org.eclipse.cdt.internal.corext;x-internal:=true,
org.eclipse.cdt.internal.ui.dialogs;x-internal:=true,
org.eclipse.cdt.internal.ui.dialogs.cpaths;x-internal:=true,
org.eclipse.cdt.internal.ui.dnd;x-internal:=true,
org.eclipse.cdt.internal.ui.editor;x-friends:="org.eclipse.cdt.codan.ui.cxx",
org.eclipse.cdt.internal.ui.editor;x-friends:="org.eclipse.cdt.codan.ui,org.eclipse.cdt.codan.ui.cxx",
org.eclipse.cdt.internal.ui.editor.asm;x-internal:=true,
org.eclipse.cdt.internal.ui.filters;x-internal:=true,
org.eclipse.cdt.internal.ui.help;x-internal:=true,
@ -65,7 +65,7 @@ Export-Package: org.eclipse.cdt.internal.corext;x-internal:=true,
org.eclipse.cdt.internal.ui.viewsupport;x-internal:=true,
org.eclipse.cdt.internal.ui.wizards;x-internal:=true,
org.eclipse.cdt.internal.ui.wizards.classwizard;x-internal:=true,
org.eclipse.cdt.internal.ui.wizards.dialogfields;x-internal:=true,
org.eclipse.cdt.internal.ui.wizards.dialogfields;x-friends:="org.eclipse.cdt.codan.ui",
org.eclipse.cdt.internal.ui.wizards.filewizard;x-internal:=true,
org.eclipse.cdt.internal.ui.wizards.folderwizard;x-internal:=true,
org.eclipse.cdt.internal.ui.wizards.indexwizards;x-internal:=true,

View file

@ -5,6 +5,7 @@ anchor,,
arg,,
attention,,
author,,
authors,,
b,,
brief,,
bug,,
@ -12,12 +13,15 @@ c,,
callgraph,,
callergraph,,
category,,
cite,,
class,,
code,,
cond,,
condnot,,
copybrief,,
copydetails,,
copydoc,,
copyright,,
date,,
def,,
defgroup,,
@ -36,15 +40,18 @@ endcond,,
enddot,,
endhtmlonly,,
endif,,
endinternal,,
endlatexonly,,
endlink,,
endmanonly,,
endmsc,,
endrtfonly,,
endverbatim,,
endxmlonly,,
enum,,
example,,
exception,,
extends,,
f$,,
f[,,
f],,
@ -59,6 +66,7 @@ htmlonly,,
if,,
ifnot,,
image,,
implements,,
include,,
includelineno,,
ingroup,,
@ -73,6 +81,7 @@ mainpage,,
manonly,,
memberof,,
msc,,
mscfile,,
n,,
name,,
namespace,,
@ -96,24 +105,34 @@ protocol,,
public,,
publicsection,,
ref,,
related,,
relates,,
relatedalso,,
relatesalso,,
remark,,
remarks,,
result,,
return,,
returns,,
retval,,
rtfonly,,
sa,,
section,,
see,,
short,,
showinitializer,,
since,,
skip,,
skipline,,
snippet,,
struct,,
subpage,,
subsection,,
subsubsection,,
tableofcontents,,
test,,
throw,,
throws,,
todo,,
tparam,,
typedef,,
@ -127,12 +146,15 @@ warning,,
weakgroup,,
xmlonly,,
xrefitem,,
&,,
$,,
@,,
\,,
&,,
~,,
<,,
>,,
#,,
%,,
",,
.,,
::,,
Can't render this file because it contains an unexpected character in line 160 and column 5.

View file

@ -13,7 +13,6 @@
* Sergey Prigogin (Google)
* Tomasz Wesolowski
*******************************************************************************/
package org.eclipse.cdt.internal.ui.editor;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
@ -27,7 +26,6 @@ import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
* @noextend This interface is not intended to be extended by clients.
*/
public interface ICEditorActionDefinitionIds extends ITextEditorActionDefinitionIds {
/**
* Action definition ID of the source -> toggle comment action
* (value <code>"org.eclipse.cdt.ui.edit.text.c.toggle.comment"</code>).

View file

@ -9,7 +9,6 @@
* IBM Corporation - initial API and implementation
* Anton Leherbauer (Wind River Systems) - Adapted for CDT
*******************************************************************************/
package org.eclipse.cdt.internal.ui.editor;
import java.util.ArrayList;
@ -42,12 +41,10 @@ import org.eclipse.cdt.internal.ui.text.CSourceViewerScalableConfiguration;
* @since 4.0
*/
public class SemanticHighlightingManager implements IPropertyChangeListener {
/**
* Highlighting style.
*/
public static class HighlightingStyle {
/** Text attribute */
private TextAttribute fTextAttribute;
/** Enabled state */
@ -96,7 +93,6 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
* Highlighted Positions.
*/
public static class HighlightedPosition extends Position {
/** Highlighting of the position */
private HighlightingStyle fStyle;
@ -169,9 +165,6 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
}
}
/*
* @see org.eclipse.jface.text.Position#setLength(int)
*/
@Override
public void setLength(int length) {
synchronized (fLock) {
@ -179,9 +172,6 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
}
}
/*
* @see org.eclipse.jface.text.Position#setOffset(int)
*/
@Override
public void setOffset(int offset) {
synchronized (fLock) {
@ -189,9 +179,6 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
}
}
/*
* @see org.eclipse.jface.text.Position#delete()
*/
@Override
public void delete() {
synchronized (fLock) {
@ -199,9 +186,6 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
}
}
/*
* @see org.eclipse.jface.text.Position#undelete()
*/
@Override
public void undelete() {
synchronized (fLock) {
@ -314,14 +298,16 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
}
/**
* Install the semantic highlighting on the given source viewer infrastructure. No reconciliation will be performed.
* Installs the semantic highlighting on the given source viewer infrastructure.
* No reconciliation will be performed.
*
* @param sourceViewer the source viewer
* @param colorManager the color manager
* @param preferenceStore the preference store
* @param hardcodedRanges the hard-coded ranges to be highlighted
*/
public void install(CSourceViewer sourceViewer, IColorManager colorManager, IPreferenceStore preferenceStore, HighlightedRange[][] hardcodedRanges) {
public void install(CSourceViewer sourceViewer, IColorManager colorManager,
IPreferenceStore preferenceStore, HighlightedRange[][] hardcodedRanges) {
fHardcodedRanges= hardcodedRanges;
install(null, sourceViewer, colorManager, preferenceStore);
}
@ -383,7 +369,7 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
}
/**
* Uninstall the semantic highlighting
* Uninstalls the semantic highlighting
*/
public void uninstall() {
disable();
@ -402,7 +388,7 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
}
/**
* Disable semantic highlighting.
* Disables semantic highlighting.
*/
private void disable() {
if (fReconciler != null) {
@ -427,7 +413,7 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
}
/**
* Initialize semantic highlightings.
* Initializes semantic highlightings.
*/
protected void initializeHighlightings() {
fSemanticHighlightings= SemanticHighlightings.getSemanticHighlightings();
@ -460,7 +446,7 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
}
/**
* Dispose the semantic highlightings.
* Disposes the semantic highlightings.
*/
protected void disposeHighlightings() {
for (int i= 0, n= fSemanticHighlightings.length; i < n; i++)
@ -470,9 +456,6 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
fHighlightings= null;
}
/*
* @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
*/
@Override
public void propertyChange(PropertyChangeEvent event) {
handlePropertyChangeEvent(event);
@ -626,7 +609,7 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
}
/**
* Force refresh of highlighting.
* Forces refresh of highlighting.
*/
public void refresh() {
if (fReconciler != null) {

View file

@ -9,7 +9,6 @@
* IBM Corporation - initial API and implementation
* Anton Leherbauer (Wind River Systems) - Adapted for CDT
*******************************************************************************/
package org.eclipse.cdt.internal.ui.editor;
import java.util.ArrayList;
@ -37,7 +36,6 @@ import org.eclipse.cdt.internal.ui.editor.SemanticHighlightingManager.Highlighte
import org.eclipse.cdt.internal.ui.editor.SemanticHighlightingManager.HighlightingStyle;
import org.eclipse.cdt.internal.ui.text.CPresentationReconciler;
/**
* Semantic highlighting presenter - UI thread implementation.
* Cloned from JDT.
@ -45,12 +43,10 @@ import org.eclipse.cdt.internal.ui.text.CPresentationReconciler;
* @since 4.0
*/
public class SemanticHighlightingPresenter implements ITextPresentationListener, ITextInputListener, IDocumentListener {
/**
* Semantic highlighting position updater.
*/
private class HighlightingPositionUpdater implements IPositionUpdater {
/** The position category. */
private final String fCategory;
@ -63,12 +59,8 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
fCategory= category;
}
/*
* @see org.eclipse.jface.text.IPositionUpdater#update(org.eclipse.jface.text.DocumentEvent)
*/
@Override
public void update(DocumentEvent event) {
int eventOffset= event.getOffset();
int eventOldLength= event.getLength();
int eventEnd= eventOffset + eventOldLength;
@ -77,10 +69,10 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
Position[] positions= event.getDocument().getPositions(fCategory);
for (int i= 0; i != positions.length; i++) {
HighlightedPosition position= (HighlightedPosition) positions[i];
// Also update deleted positions because they get deleted by the background thread and removed/invalidated only in the UI runnable
// Also update deleted positions because they get deleted by the background
// thread and removed/invalidated only in the UI runnable.
// if (position.isDeleted())
// continue;
@ -88,26 +80,27 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
int length= position.getLength();
int end= offset + length;
if (offset > eventEnd)
if (offset > eventEnd) {
updateWithPrecedingEvent(position, event);
else if (end < eventOffset)
} else if (end < eventOffset) {
updateWithSucceedingEvent(position, event);
else if (offset <= eventOffset && end >= eventEnd)
} else if (offset <= eventOffset && end >= eventEnd) {
updateWithIncludedEvent(position, event);
else if (offset <= eventOffset)
} else if (offset <= eventOffset) {
updateWithOverEndEvent(position, event);
else if (end >= eventEnd)
} else if (end >= eventEnd) {
updateWithOverStartEvent(position, event);
else
} else {
updateWithIncludingEvent(position, event);
}
}
} catch (BadPositionCategoryException e) {
// ignore and return
}
}
/**
* Update the given position with the given event. The event precedes the position.
* Updates the given position with the given event. The event precedes the position.
*
* @param position The position
* @param event The event
@ -121,7 +114,7 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
}
/**
* Update the given position with the given event. The event succeeds the position.
* Updates the given position with the given event. The event succeeds the position.
*
* @param position The position
* @param event The event
@ -130,7 +123,7 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
}
/**
* Update the given position with the given event. The event is included by the position.
* Updates the given position with the given event. The event is included by the position.
*
* @param position The position
* @param event The event
@ -151,9 +144,9 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
int includedLength= 0;
while (includedLength < eventNewLength && Character.isJavaIdentifierPart(newText.charAt(includedLength)))
includedLength++;
if (includedLength == eventNewLength)
if (includedLength == eventNewLength) {
position.setLength(length + deltaLength);
else {
} else {
int newLeftLength= eventOffset - offset + includedLength;
int excludedLength= eventNewLength;
@ -176,7 +169,8 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
}
/**
* Update the given position with the given event. The event overlaps with the end of the position.
* Updates the given position with the given event. The event overlaps with the end of
* the position.
*
* @param position The position
* @param event The event
@ -194,7 +188,8 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
}
/**
* Update the given position with the given event. The event overlaps with the start of the position.
* Updates the given position with the given event. The event overlaps with the start of
* the position.
*
* @param position The position
* @param event The event
@ -353,12 +348,14 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
}
/**
* Invalidate the presentation of the positions based on the given added positions and the existing deleted positions.
* Also unregisters the deleted positions from the document and patches the positions of this presenter.
* Invalidates the presentation of the positions based on the given added positions and
* the existing deleted positions. Also unregisters the deleted positions from the document
* and patches the positions of this presenter.
* <p>
* NOTE: Indirectly called from background thread by UI runnable.
* </p>
* @param textPresentation the text presentation or <code>null</code>, if the presentation should computed in the UI thread
* @param textPresentation the text presentation or <code>null</code>, if the presentation
* should computed in the UI thread
* @param addedPositions the added positions
* @param removedPositions the removed positions
*/
@ -398,7 +395,8 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
List<HighlightedPosition> newPositions= new ArrayList<HighlightedPosition>(newSize);
HighlightedPosition position= null;
HighlightedPosition addedPosition= null;
for (int i= 0, j= 0, n= oldPositions.size(), m= addedPositions.length; i < n || position != null || j < m || addedPosition != null;) {
for (int i= 0, j= 0, n= oldPositions.size(), m= addedPositions.length;
i < n || position != null || j < m || addedPosition != null;) {
// loop variant: i + j < old(i + j)
// a) find the next non-deleted Position from the old list
@ -489,7 +487,7 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
}
/**
* Insert the given position in <code>fPositions</code>, s.t. the offsets remain in linear order.
* Inserts the given position in <code>fPositions</code>, s.t. the offsets remain in linear order.
*
* @param position The position for insertion
*/
@ -540,13 +538,11 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
return j;
}
/*
* @see org.eclipse.jface.text.ITextPresentationListener#applyTextPresentation(org.eclipse.jface.text.TextPresentation)
*/
@Override
public void applyTextPresentation(TextPresentation textPresentation) {
IRegion region= textPresentation.getExtent();
int i= computeIndexAtOffset(fPositions, region.getOffset()), n= computeIndexAtOffset(fPositions, region.getOffset() + region.getLength());
int i= computeIndexAtOffset(fPositions, region.getOffset());
int n= computeIndexAtOffset(fPositions, region.getOffset() + region.getLength());
if (n - i > 2) {
List<StyleRange> ranges= new ArrayList<StyleRange>(n - i);
for (; i < n; i++) {
@ -566,9 +562,6 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
}
}
/*
* @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
*/
@Override
public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
setCanceled(true);
@ -576,25 +569,16 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
resetState();
}
/*
* @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
*/
@Override
public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
manageDocument(newInput);
}
/*
* @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
*/
@Override
public void documentAboutToBeChanged(DocumentEvent event) {
setCanceled(true);
}
/*
* @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
*/
@Override
public void documentChanged(DocumentEvent event) {
}
@ -664,7 +648,7 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
}
/**
* Uninstall this presenter.
* Uninstalls this presenter.
*/
public void uninstall() {
setCanceled(true);

View file

@ -81,7 +81,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
@Override
public int visit(IASTTranslationUnit tu) {
// visit macro definitions
// Visit macro definitions.
IASTPreprocessorMacroDefinition[] macroDefs= tu.getMacroDefinitions();
for (IASTPreprocessorMacroDefinition macroDef : macroDefs) {
if (macroDef.isPartOfTranslationUnitFile()) {
@ -90,7 +90,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
}
fMinLocation= -1;
// visit macro expansions
// Visit macro expansions.
IASTPreprocessorMacroExpansion[] macroExps= tu.getMacroExpansions();
for (IASTPreprocessorMacroExpansion macroExp : macroExps) {
if (macroExp.isPartOfTranslationUnitFile()) {
@ -104,7 +104,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
}
fMinLocation= -1;
// visit ordinary code
// Visit ordinary code.
return super.visit(tu);
}
@ -130,9 +130,6 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
return PROCESS_CONTINUE;
}
/*
* @see org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor#visit(org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition)
*/
@Override
public int visit(ICPPASTNamespaceDefinition namespace) {
if (!namespace.isPartOfTranslationUnitFile()) {
@ -197,14 +194,14 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
int offset= imageLocation.getNodeOffset();
if (offset >= fMinLocation) {
int length= imageLocation.getNodeLength();
if (offset > -1 && length > 0) {
if (offset >= 0 && length > 0) {
fMinLocation= offset + length;
addPosition(offset, length, highlightingStyle);
}
}
}
} else {
// Fallback in case no image location available
// Fallback in case no image location available.
IASTNodeLocation[] nodeLocations= name.getNodeLocations();
if (nodeLocations.length == 1 && !(nodeLocations[0] instanceof IASTMacroExpansionLocation)) {
addNodeLocation(nodeLocations[0], highlightingStyle);
@ -213,7 +210,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
}
/**
* Add the a location range for the given highlighting.
* Adds the a location range for the given highlighting.
*
* @param nodeLocation The node location
* @param highlighting The highlighting
@ -233,7 +230,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
}
/**
* Add a position with the given range and highlighting iff it does not exist already.
* Adds a position with the given range and highlighting iff it does not exist already.
*
* @param offset The range offset
* @param length The range length
@ -290,11 +287,20 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
*/
private boolean fIsReconciling= false;
/** The semantic highlighting presenter - cache for background thread, only valid during {@link #reconciled(IASTTranslationUnit, boolean, IProgressMonitor)} */
/**
* The semantic highlighting presenter - cache for background thread, only valid during
* {@link #reconciled(IASTTranslationUnit, boolean, IProgressMonitor)}
*/
protected SemanticHighlightingPresenter fJobPresenter;
/** Semantic highlightings - cache for background thread, only valid during {@link #reconciled(IASTTranslationUnit, boolean, IProgressMonitor)} */
/**
* Semantic highlightings - cache for background thread, only valid during
* {@link #reconciled(IASTTranslationUnit, boolean, IProgressMonitor)}
*/
protected SemanticHighlighting[] fJobSemanticHighlightings;
/** Highlightings - cache for background thread, only valid during {@link #reconciled(IASTTranslationUnit, boolean, IProgressMonitor)} */
/**
* Highlightings - cache for background thread, only valid during
* {@link #reconciled(IASTTranslationUnit, boolean, IProgressMonitor)}
*/
private HighlightingStyle[] fJobHighlightings;
@Override
@ -304,7 +310,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
@Override
public void reconciled(IASTTranslationUnit ast, boolean force, IProgressMonitor progressMonitor) {
// Ensure at most one thread can be reconciling at any time
// Ensure at most one thread can be reconciling at any time.
synchronized (fReconcileLock) {
if (fIsReconciling)
return;
@ -359,7 +365,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
}
/**
* Start reconciling positions.
* Starts reconciling positions.
*/
protected void startReconcilingPositions() {
fJobPresenter.addAllPositions(fRemovedPositions);
@ -367,7 +373,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
}
/**
* Reconcile positions based on the AST.
* Reconciles positions based on the AST.
*
* @param ast the AST
* @param visitor the AST visitor
@ -392,7 +398,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
}
/**
* Update the presentation.
* Updates the presentation.
*
* @param textPresentation the text presentation
* @param addedPositions the added positions
@ -452,7 +458,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
}
/**
* Uninstalsl this reconciler from the editor
* Uninstalls this reconciler from the editor
*/
public void uninstall() {
if (fPresenter != null)

View file

@ -67,7 +67,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
* @since 4.0
*/
public class SemanticHighlightings {
private static final RGB RGB_BLACK = new RGB(0, 0, 0);
/**

View file

@ -29,7 +29,7 @@ public final class SemanticToken {
/** Binding */
private IBinding fBinding;
/** Is the binding resolved? */
private boolean fIsBindingResolved= false;
private boolean fIsBindingResolved;
/** AST root */
private IASTTranslationUnit fRoot;
@ -69,7 +69,7 @@ public final class SemanticToken {
}
/**
* Update this token with the given AST node.
* Updates this token with the given AST node.
* <p>
* NOTE: Allowed to be used by {@link SemanticHighlightingReconciler} only.
* </p>

View file

@ -9,7 +9,6 @@
* IBM Corporation - initial API and implementation
* Anton Leherbauer (Wind River Systems) - Adapted for CDT
*******************************************************************************/
package org.eclipse.cdt.internal.ui.text;
import org.eclipse.jface.text.IDocument;
@ -17,7 +16,6 @@ import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.jface.text.presentation.PresentationReconciler;
/**
* Presentation reconciler, adding functionality for operation without a viewer.
* Cloned from JDT.
@ -25,7 +23,6 @@ import org.eclipse.jface.text.presentation.PresentationReconciler;
* @since 4.0
*/
public class CPresentationReconciler extends PresentationReconciler {
/** Last used document */
private IDocument fLastDocument;

View file

@ -32,9 +32,7 @@ import org.eclipse.cdt.ui.IWorkingCopyManager;
import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit;
public class CReconcilingStrategy implements IReconcilingStrategy, IReconcilingStrategyExtension {
private ITextEditor fEditor;
private IWorkingCopyManager fManager;
private IProgressMonitor fProgressMonitor;
@ -46,32 +44,20 @@ public class CReconcilingStrategy implements IReconcilingStrategy, IReconcilingS
fManager= CUIPlugin.getDefault().getWorkingCopyManager();
}
/*
* @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#setDocument(org.eclipse.jface.text.IDocument)
*/
@Override
public void setDocument(IDocument document) {
}
/*
* @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.reconciler.DirtyRegion, org.eclipse.jface.text.IRegion)
*/
@Override
public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
// only called for incremental reconciler
}
/*
* @see IReconcilingStrategyExtension#setProgressMonitor(IProgressMonitor)
*/
@Override
public void setProgressMonitor(IProgressMonitor monitor) {
fProgressMonitor= monitor;
}
/*
* @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.IRegion)
*/
@Override
public void reconcile(IRegion region) {
reconcile(false);
@ -91,10 +77,11 @@ public class CReconcilingStrategy implements IReconcilingStrategy, IReconcilingS
forced= workingCopy.isConsistent();
ast= workingCopy.reconcile(computeAST, true, fProgressMonitor);
}
} catch (OperationCanceledException oce) {
} catch (OperationCanceledException e) {
// document was modified while parsing
} catch (CModelException e) {
IStatus status= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, IStatus.OK, "Error in CDT UI during reconcile", e); //$NON-NLS-1$
IStatus status= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, IStatus.OK,
"Error in CDT UI during reconcile", e); //$NON-NLS-1$
CUIPlugin.log(status);
} finally {
if (computeAST) {
@ -118,7 +105,8 @@ public class CReconcilingStrategy implements IReconcilingStrategy, IReconcilingS
aboutToBeReconciled();
}
} catch (Exception e) {
IStatus status= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, IStatus.OK, "Error in CDT UI during reconcile", e); //$NON-NLS-1$
IStatus status= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, IStatus.OK,
"Error in CDT UI during reconcile", e); //$NON-NLS-1$
CUIPlugin.log(status);
} finally {
if (index != null) {
@ -129,9 +117,6 @@ public class CReconcilingStrategy implements IReconcilingStrategy, IReconcilingS
}
}
/*
* @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#initialReconcile()
*/
@Override
public void initialReconcile() {
reconcile(true);
@ -143,5 +128,4 @@ public class CReconcilingStrategy implements IReconcilingStrategy, IReconcilingS
((ICReconcilingListener)fEditor).aboutToBeReconciled();
}
}
}

View file

@ -164,6 +164,9 @@ public class GdbConnectCommand extends AbstractDebugCommand implements IConnectH
fRequestMonitor.cancel();
} else if (result instanceof IProcessExtendedInfo[] || result instanceof String) {
fRequestMonitor.setData(result);
} else if (result instanceof Integer) {
// This is the case where the user typed in a pid number directly
fRequestMonitor.setData(new IProcessExtendedInfo[] { new ProcessInfo((Integer)result, "")}); //$NON-NLS-1$
} else {
fRequestMonitor.setStatus(NO_PID_STATUS);
}
@ -231,8 +234,10 @@ public class GdbConnectCommand extends AbstractDebugCommand implements IConnectH
protected void handleSuccess() {
// Store the path of the binary so we can use it again for another process
// with the same name. Only do this on success, to avoid being stuck with
// a path that is invalid
// a path that is invalid.
if (fProcName != null && !fProcName.isEmpty()) {
fProcessNameToBinaryMap.put(fProcName, finalBinaryPath);
}
fRm.done();
};
});

View file

@ -8,6 +8,7 @@
* Contributors:
* Marc Khouzam (Ericsson) - initial API and implementation
* Grzegorz Kuligowski - Cannot cast to type that contain commas (bug 393474)
* Marc Khouzam (Ericsson) - Support for glob-expressions for local variables (bug 394408)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
@ -44,7 +45,6 @@ import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.cdt.dsf.debug.service.IStack.IVariableDMContext;
import org.eclipse.cdt.dsf.debug.service.IStack.IVariableDMData;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.mi.service.IGDBPatternMatchingExpressions;
import org.eclipse.cdt.dsf.mi.service.IMIExpressions;
import org.eclipse.cdt.dsf.mi.service.MIRegisters.MIRegisterDMC;
import org.eclipse.cdt.dsf.service.AbstractDsfService;
@ -57,80 +57,65 @@ import com.ibm.icu.text.MessageFormat;
/**
* Expressions service added as a layer above the standard Expressions service.
* This layer allows to support group-expressions and glob-pattern matching.
* Group-expressions give the user the ability to create a comma-separated
* list of expressions in a single entry.
* This layer allows to support expression-groups and glob-pattern matching.
* Expression-groups give the user the ability to create a separated list
* of expressions in a single entry.
* Glob-patterns are a way to specify a set of expressions that match the
* pattern.
* @since 4.2
*/
public class GDBPatternMatchingExpressions extends AbstractDsfService implements IGDBPatternMatchingExpressions, ICachingService {
public class GDBPatternMatchingExpressions extends AbstractDsfService implements IMIExpressions, ICachingService {
/**
* A regex representing each character that can be used to separate
* the different expressions contained in a group-expression.
* n the different expressions contained in an expression-group.
* The [] are not part the characters, but are used in the regex format.
* Note that we don't allow a space separator because spaces are valid within
* an expression (e.g., i + 1).
* We also don't allow a comma because they are used in templates (bug 393474)
* We also don't allow a comma because they are used in C/C++ templates (bug 393474)
* Furthermore, commas are used within array-index matches as well.
*/
private final static String GROUP_EXPRESSION_SEPARATORS_REGEXP = "[;]"; //$NON-NLS-1$
private final static String EXPRESSION_GROUP_SEPARATORS_REGEXP = "[;]"; //$NON-NLS-1$
private final static String REGISTER_PREFIX = "$"; //$NON-NLS-1$
private final static String GLOB_EXPRESSION_PREFIX = "="; //$NON-NLS-1$
/**
* A group-expression is an expression that requires expansion into a (potentially empty)
* list of sub-expressions. Using a group-expression allows the user to create groups
* This regular expression describes the supported content of an array index range.
* Valid range formats are are numbers, possibly separated by - and/or ,.
* E.g, "23-56" or "32" or "23, 45-67, 12-15"
*/
private static final String ARRAY_INDEX_RANGE_REGEXP = "^*\\d+(\\s*-\\s*\\d+)?(\\s*,\\s*\\d+(\\s*-\\s*\\d+)?)*$";//$NON-NLS-1$
/**
* An expression-group is an expression that requires expansion into a (potentially empty)
* list of sub-expressions. Using an expression-group allows the user to create groups
* of expressions very quickly.
*
* We support two aspects for group-expressions:
* We support two aspects for expression-goups:
* 1- The glob syntax (http://www.kernel.org/doc/man-pages/online/pages/man7/glob.7.html)
* This allows to user to specify glob-patterns to match different expressions.
* 2- Comma-separated expressions, each potentially using the glob-syntax
* 2- Separated expressions, each potentially using the glob-syntax
*/
protected static class GroupExpressionDMC implements IExpressionDMContext {
protected static class ExpressionGroupDMC implements IExpressionGroupDMContext {
/**
* The expression context, as created by the main Expression service.
* We delegate the handling of the expression to it.
*/
private IExpressionDMContext fExprDelegate;
/**
* The set of expressions making up the group expression.
* This list is the result of splitting the original expression
* and then trimming each resulting expression.
*/
private List<String> fExpressionsInGroup = null;
public GroupExpressionDMC(IExpressionDMContext exprDmc) {
public ExpressionGroupDMC(IExpressionDMContext exprDmc) {
fExprDelegate = exprDmc;
}
protected IExpressionDMContext getExprDelegate() {
return fExprDelegate;
}
@Override
public String getExpression() {
return fExprDelegate.getExpression();
}
/**
* Returns an array representing the different expressions
* that make up this group-expression.
*/
public List<String> getExpressionsInGroup() {
if (fExpressionsInGroup == null) {
// Split the list
String[] splitExpressions = getExpression().split(GROUP_EXPRESSION_SEPARATORS_REGEXP);
// Remove any extra whitespace from each resulting expression,
// and ignore any empty expressions.
fExpressionsInGroup = new ArrayList<String>(splitExpressions.length);
for (String expr : splitExpressions) {
expr = expr.trim();
if (!expr.isEmpty()) {
fExpressionsInGroup.add(expr);
}
}
}
return fExpressionsInGroup;
}
@Override
public String getSessionId() {
return fExprDelegate.getSessionId();
@ -150,25 +135,30 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof GroupExpressionDMC)) return false;
if (!(obj instanceof ExpressionGroupDMC)) return false;
return ((GroupExpressionDMC)obj).fExprDelegate.equals(fExprDelegate);
return ((ExpressionGroupDMC)obj).fExprDelegate.equals(fExprDelegate);
}
@Override
public int hashCode() {
return fExprDelegate.hashCode();
}
@Override
public String toString() {
return "Group: " + getExprDelegate().toString(); //$NON-NLS-1$
}
}
/**
* The model data interface for group-expressions
* The model data interface for expression-groups
*/
protected static class GroupExpressionDMData implements IExpressionDMDataExtension {
protected static class ExpressionGroupDMData implements IExpressionDMDataExtension {
private final String fRelativeExpression;
private final int fNumChildren;
public GroupExpressionDMData(String expr, int numChildren) {
public ExpressionGroupDMData(String expr, int numChildren) {
assert expr != null;
fRelativeExpression = expr;
@ -218,8 +208,8 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public boolean equals(Object other) {
if (this == other) return true;
if (!(other instanceof GroupExpressionDMData)) return false;
return fRelativeExpression.equals(((GroupExpressionDMData)other).fRelativeExpression);
if (!(other instanceof ExpressionGroupDMData)) return false;
return fRelativeExpression.equals(((ExpressionGroupDMData)other).fRelativeExpression);
}
@Override
@ -229,18 +219,18 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public String toString() {
return "GroupExpr: " + fRelativeExpression; //$NON-NLS-1$
return "ExprGroup: " + fRelativeExpression; //$NON-NLS-1$
}
}
/**
* The base expression service to which we delegate all non-group-expression logic.
* The base expression service to which we delegate all non-expression-group logic.
*/
private IMIExpressions fDelegate;
public GDBPatternMatchingExpressions(DsfSession session, IExpressions delegate) {
public GDBPatternMatchingExpressions(DsfSession session, IMIExpressions delegate) {
super(session);
fDelegate = (IMIExpressions)delegate;
fDelegate = delegate;
}
@Override
@ -290,8 +280,8 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
public IExpressionDMContext createExpression(IDMContext ctx, String expression) {
IExpressionDMContext expressionDmc = fDelegate.createExpression(ctx, expression);
if (isGroupExpression(expression)) {
return new GroupExpressionDMC(expressionDmc);
if (isExpressionGroup(expression)) {
return new ExpressionGroupDMC(expressionDmc);
} else {
return expressionDmc;
}
@ -299,19 +289,19 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public ICastedExpressionDMContext createCastedExpression(IExpressionDMContext context, CastInfo castInfo) {
// Cannot cast a GroupExpression
assert (!(context instanceof GroupExpressionDMC));
// Cannot cast an expression-group
assert (!(context instanceof IExpressionGroupDMContext));
return fDelegate.createCastedExpression(context, castInfo);
}
@Override
public void getExpressionDataExtension(final IExpressionDMContext dmc, final DataRequestMonitor<IExpressionDMDataExtension> rm) {
if (dmc instanceof GroupExpressionDMC) {
if (dmc instanceof IExpressionGroupDMContext) {
getSubExpressionCount(dmc, new ImmediateDataRequestMonitor<Integer>(rm) {
@Override
protected void handleSuccess() {
rm.done(new GroupExpressionDMData(((GroupExpressionDMC)dmc).getExpression(), getData()));
rm.done(new ExpressionGroupDMData(((IExpressionGroupDMContext)dmc).getExpression(), getData()));
}
});
return;
@ -323,11 +313,11 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public void getExpressionData(final IExpressionDMContext dmc, final DataRequestMonitor<IExpressionDMData> rm) {
if (dmc instanceof GroupExpressionDMC) {
if (dmc instanceof IExpressionGroupDMContext) {
getSubExpressionCount(dmc, new ImmediateDataRequestMonitor<Integer>(rm) {
@Override
protected void handleSuccess() {
rm.done(new GroupExpressionDMData(((GroupExpressionDMC)dmc).getExpression(), getData()));
rm.done(new ExpressionGroupDMData(((IExpressionGroupDMContext)dmc).getExpression(), getData()));
}
});
return;
@ -338,8 +328,8 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public void getExpressionAddressData(IExpressionDMContext dmc, DataRequestMonitor<IExpressionDMAddress> rm) {
// A GroupExpression does not have an address
if (dmc instanceof GroupExpressionDMC) {
// An expression-group does not have an address
if (dmc instanceof IExpressionGroupDMContext) {
rm.done(new IExpressionDMLocation() {
@Override
public IAddress getAddress() {
@ -362,8 +352,8 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public void getSubExpressions(IExpressionDMContext exprCtx, DataRequestMonitor<IExpressionDMContext[]> rm) {
if (exprCtx instanceof GroupExpressionDMC) {
matchGroupExpression((GroupExpressionDMC)exprCtx, -1, -1, rm);
if (exprCtx instanceof IExpressionGroupDMContext) {
matchExpressionGroup((IExpressionGroupDMContext)exprCtx, -1, -1, rm);
} else {
fDelegate.getSubExpressions(exprCtx, rm);
}
@ -371,8 +361,8 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public void getSubExpressions(IExpressionDMContext exprCtx, int startIndex, int length, DataRequestMonitor<IExpressionDMContext[]> rm) {
if (exprCtx instanceof GroupExpressionDMC) {
matchGroupExpression((GroupExpressionDMC)exprCtx, startIndex, length, rm);
if (exprCtx instanceof IExpressionGroupDMContext) {
matchExpressionGroup((IExpressionGroupDMContext)exprCtx, startIndex, length, rm);
} else {
fDelegate.getSubExpressions(exprCtx, startIndex, length, rm);
}
@ -380,8 +370,8 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public void getSubExpressionCount(IExpressionDMContext dmc, final DataRequestMonitor<Integer> rm) {
if (dmc instanceof GroupExpressionDMC) {
matchGroupExpression((GroupExpressionDMC)dmc, -1, -1, new ImmediateDataRequestMonitor<IExpressionDMContext[]>(rm) {
if (dmc instanceof IExpressionGroupDMContext) {
matchExpressionGroup((IExpressionGroupDMContext)dmc, -1, -1, new ImmediateDataRequestMonitor<IExpressionDMContext[]>(rm) {
@Override
protected void handleSuccess() {
rm.done(getData().length);
@ -394,10 +384,10 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public void getSubExpressionCount(IExpressionDMContext dmc, int maxNumberOfChildren, final DataRequestMonitor<Integer> rm) {
if (dmc instanceof GroupExpressionDMC) {
// No need to worry about maxNumberOfChildren for the case of a group-expression, since there won't be
if (dmc instanceof IExpressionGroupDMContext) {
// No need to worry about maxNumberOfChildren for the case of an expression-group, since there won't be
// a very large amount of them.
matchGroupExpression((GroupExpressionDMC)dmc, -1, -1, new ImmediateDataRequestMonitor<IExpressionDMContext[]>(rm) {
matchExpressionGroup((IExpressionGroupDMContext)dmc, -1, -1, new ImmediateDataRequestMonitor<IExpressionDMContext[]>(rm) {
@Override
protected void handleSuccess() {
rm.done(getData().length);
@ -415,8 +405,8 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public void canWriteExpression(IExpressionDMContext dmc, DataRequestMonitor<Boolean> rm) {
// A GroupExpression's value cannot be modified
if (dmc instanceof GroupExpressionDMC) {
// An expression-group's value cannot be modified
if (dmc instanceof IExpressionGroupDMContext) {
rm.done(false);
return;
}
@ -426,15 +416,15 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public void writeExpression(IExpressionDMContext dmc, String expressionValue, String formatId, RequestMonitor rm) {
// A GroupExpression's value cannot be modified
assert !(dmc instanceof GroupExpressionDMC);
// An expression-group's value cannot be modified
assert !(dmc instanceof IExpressionGroupDMContext);
fDelegate.writeExpression(dmc, expressionValue, formatId, rm);
}
@Override
public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor<String[]> rm) {
//For a group expression, we only show the NATURAL format
if (dmc instanceof GroupExpressionDMC) {
// For an expression-group, we only show the NATURAL format
if (dmc instanceof IExpressionGroupDMContext) {
rm.done(new String[] { IFormattedValues.NATURAL_FORMAT });
return;
}
@ -444,15 +434,15 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext dmc, String formatId) {
// No special handling for GroupExpressions
// No special handling for expression-groups
return fDelegate.getFormattedValueContext(dmc, formatId);
}
@Override
public void getFormattedExpressionValue(FormattedValueDMContext dmc, final DataRequestMonitor<FormattedValueDMData> rm) {
GroupExpressionDMC groupExpr = DMContexts.getAncestorOfType(dmc, GroupExpressionDMC.class);
if (groupExpr != null) {
getSubExpressionCount(groupExpr, new ImmediateDataRequestMonitor<Integer>(rm) {
IExpressionGroupDMContext exprGroup = DMContexts.getAncestorOfType(dmc, IExpressionGroupDMContext.class);
if (exprGroup != null) {
getSubExpressionCount(exprGroup, new ImmediateDataRequestMonitor<Integer>(rm) {
@Override
protected void handleSuccess() {
int numChildren = getData();
@ -475,9 +465,9 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public void safeToAskForAllSubExpressions(IExpressionDMContext dmc, DataRequestMonitor<Boolean> rm) {
// Always safe to ask for all sub-expression of a group expression, since we don't expect large
// amounts of children
if (dmc instanceof GroupExpressionDMC) {
// Always safe to ask for all sub-expression of an expression-group,
// since we don't expect large amounts of children
if (dmc instanceof IExpressionGroupDMContext) {
rm.done(true);
return;
}
@ -493,73 +483,154 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
}
/**
* Verify if we are dealing with a group expression.
* Verify if we are dealing with an expression-group.
* @param expr The expression to verify
* @return True if expr is a group expression. A group
* expression is either a comma-separated list of
* @return True if expr is an expression-group. An
* expression-group is either a separated list of
* expressions, or an expression using a glob-pattern
*/
protected boolean isGroupExpression(String expr) {
// First check for a comma separated list of expression
protected boolean isExpressionGroup(String expr) {
// First check for a separated list of expression
// We want to re-use the regex that defines our separators, and we need to check
// if the expression contains that regex. I didn't find a method that
// checks if a string contains a regex, so instead we all any character before
// checks if a string contains a regex, so instead we add any character before
// and after the regex, which achieves what we want.
// Note that checking if expr.split(regex) is bigger than 1, will not notice
// Note that checking if (expr.split(regex) > 1), will not notice
// an expression that has a separator only at the end.
if (expr.matches(".*" + GROUP_EXPRESSION_SEPARATORS_REGEXP +".*")) { //$NON-NLS-1$ //$NON-NLS-2$
// We are dealing with a group expression.
if (expr.matches(".*" + EXPRESSION_GROUP_SEPARATORS_REGEXP +".*")) { //$NON-NLS-1$ //$NON-NLS-2$
// We are dealing with a group of expressions.
// It may not be a valid one, but it is one nonetheless.
return true;
}
// Not a comma-separated list. Check if we are dealing with a glob-pattern.
return isGlobPattern(expr);
// Not a list. Check if we are dealing with a glob-pattern.
return isGlobExpression(expr);
}
/**
* Verify if we are dealing with a glob-pattern.
* We support the expression * which will match all local variables.
* We support glob-patterns for registers (must start with $)
* We support the expression '*' which will match all local variables
* as well as the expression '$*' which will match all registers.
* We support glob-patterns for any expression starting with '='
*
* @param expr The expression to verify
* @return True if expr is a glob-pattern we support.
*/
protected boolean isGlobPattern(String expr) {
protected boolean isGlobExpression(String expr) {
// Get rid of useless whitespace
expr = expr.trim();
// We support the glob-pattern '*' to indicate all local variables
if (expr.equals("*")) { //$NON-NLS-1$
// and $* for all registers
if (expr.equals("*") || expr.equals("$*")) { //$NON-NLS-1$ //$NON-NLS-2$
return true;
}
// We only support glob-expressions for registers at this time
if (expr.startsWith("$")) { //$NON-NLS-1$
// see: 'man glob'
if (expr.indexOf('*') != -1 || expr.indexOf('?') != -1 || expr.indexOf('[') != -1) {
// Glob-expressions must start with '='
if (expr.startsWith(GLOB_EXPRESSION_PREFIX)) {
return true;
}
}
return false;
}
/**
* Find all expressions that match the specified group-expression.
* This method retains the order of the expressions in the group-expression, to show them
* in the same order as the one specified by the user. The match of each expression in the group
* is sorted alphabetically however.
* Verify if the glob-pattern represents a register.
*
* @param groupExprDmc The group-expression context for which we want the matches (sub-expressions)
* @param expr The glob-pattern that may be a register-pattern
* @return True if expr follows the rules of an register-pattern
*/
protected boolean isRegisterPattern(String expr) {
// Get rid of useless whitespace
expr = expr.trim();
if (expr.startsWith(REGISTER_PREFIX)) {
return true;
}
return false;
}
/**
* Verify if the glob-pattern should be handled as an array index range.
* When dealing with variables (on contrast to registers), the [] will
* map to array indices instead of ranges within the array name.
* For example =array[1-2] will map to array[1] and array[2] instead of
* array1 and array2.
*
* If the range contains non-digits, the matching will not be handled
* as array indices.
*
* @param expr The glob-pattern that may be an array-pattern
* @return True if expr follows the rules of an array-pattern
*/
protected boolean isArrayPattern(String expr) {
// Get rid of useless whitespace
expr = expr.trim();
int openBracketIndex = expr.indexOf('[');
// There must be an open bracket and it cannot be in the first position
// (as we need some indication of the array name before the brackets)
if (openBracketIndex < 1) {
return false;
}
// We don't support any characters after the closing bracket
// since we don't support any operations on an expression-group.
if (!expr.endsWith("]")) { //$NON-NLS-1$
return false;
}
// We have a match for a variable which uses brackets.
// Check if the indices are integer ranges (using - or commas).
try {
Pattern pattern = Pattern.compile(ARRAY_INDEX_RANGE_REGEXP, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(expr.substring(openBracketIndex+1, expr.length()-1));
if (!matcher.find()) {
return false;
}
} catch(Exception e) {
// If the user put an invalid pattern, we just ignore it
return false;
}
return true;
}
/**
* Split the expression-group into a list of individual expression strings.
*/
protected List<String> splitExpressionsInGroup(IExpressionGroupDMContext groupDmc) {
// Split the list of expressions
String[] splitExpressions = groupDmc.getExpression().split(EXPRESSION_GROUP_SEPARATORS_REGEXP);
// Remove any extra whitespace from each resulting expression,
// and ignore any empty expressions.
List<String> expressions = new ArrayList<String>(splitExpressions.length);
for (String expr : splitExpressions) {
expr = expr.trim();
if (!expr.isEmpty()) {
expressions.add(expr);
}
}
return expressions;
}
/**
* Find all expressions that match the specified expression-group.
* This method retains the order of the expressions in the expression-group, to show them
* in the same order as the one specified by the user. The matches of each expression within the group
* are sorted alphabetically however.
*
* @param exprGroupDmc The expression-group context for which we want the matches (sub-expressions)
* @param startIndex The beginning of the range of matches (-1 means all matches)
* @param length The length of the range of matches (-1 means all matches)
* @param rm RequestMonitor that will contain the range of found matches.
*/
protected void matchGroupExpression(final GroupExpressionDMC groupExprDmc, int startIndex, int length,
protected void matchExpressionGroup(final IExpressionGroupDMContext exprGroupDmc, int startIndex, int length,
final DataRequestMonitor<IExpressionDMContext[]> rm) {
// First separate the group into different expressions.
// We need to create a new list, as we will modify it during our processing.
final List<String> exprList = new ArrayList<String>(groupExprDmc.getExpressionsInGroup());
final List<String> exprList = new ArrayList<String>(splitExpressionsInGroup(exprGroupDmc));
// List to store the final result, which is all the sub-expressions of this group
final ArrayList<IExpressionDMContext> subExprList = new ArrayList<IExpressionDMContext>();
@ -567,7 +638,7 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
final int startIndex1 = (startIndex < 0) ? 0 : startIndex;
final int length1 = (length < 0) ? Integer.MAX_VALUE : length;
matchExpressionList(exprList, subExprList, groupExprDmc, new ImmediateRequestMonitor(rm) {
matchExpressionList(exprList, subExprList, exprGroupDmc, new ImmediateRequestMonitor(rm) {
@Override
protected void handleSuccess() {
// It would be nice to allow identical elements, so that the user
@ -608,9 +679,9 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
// and sort the result alphabetically in that case.
String expr = exprList.remove(0);
if (isGlobPattern(expr)) {
IExpressionDMContext exprDmc = createExpression(parentDmc, expr);
matchGlobExpression(exprDmc, new ImmediateDataRequestMonitor<List<IExpressionDMContext>>(rm) {
if (exprDmc instanceof IExpressionGroupDMContext) {
matchGlobExpression((IExpressionGroupDMContext)exprDmc, new ImmediateDataRequestMonitor<List<IExpressionDMContext>>(rm) {
@Override
protected void handleSuccess() {
List<IExpressionDMContext> matches = getData();
@ -618,6 +689,31 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
Collections.sort(matches, new Comparator<IExpressionDMContext>() {
@Override
public int compare(IExpressionDMContext o1, IExpressionDMContext o2) {
// For elements of the same array, we need to sort by index
if (isArrayPattern(o1.getExpression()) && isArrayPattern(o2.getExpression())) {
// Extract the array names and the array indices specification.
// The regex used will remove both [ and ]
String[] arrayExprParts1 = o1.getExpression().split("[\\[\\]]"); //$NON-NLS-1$
assert arrayExprParts1 != null && arrayExprParts1.length == 2;
String[] arrayExprParts2 = o2.getExpression().split("[\\[\\]]"); //$NON-NLS-1$
assert arrayExprParts2 != null && arrayExprParts2.length == 2;
// Compare array names
if (arrayExprParts1[0].compareTo(arrayExprParts2[0]) == 0) {
// We are dealing with the same array
try {
int arrayIndex1 = Integer.parseInt(arrayExprParts1[1]);
int arrayIndex2 = Integer.parseInt(arrayExprParts2[1]);
if (arrayIndex1 == arrayIndex2) return 0;
if (arrayIndex1 > arrayIndex2) return 1;
return -1;
} catch (NumberFormatException e) {
// Invalid array index. Fall-back to sorting lexically.
}
}
}
return o1.getExpression().compareTo(o2.getExpression());
}
});
@ -629,7 +725,7 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
});
} else {
// Just a normal expression
subExprList.add(createExpression(parentDmc, expr));
subExprList.add(exprDmc);
// Match the next expression from the list
matchExpressionList(exprList, subExprList, parentDmc, rm);
}
@ -639,41 +735,79 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
* Find all expressions that match the specified glob-pattern.
*
* @param exprDmc The expression context for which we want the matches (sub-expressions)
* @param rm RequestMonitor that will contain the matches.
* @param rm RequestMonitor that will contain the unsorted matches.
*/
protected void matchGlobExpression(final IExpressionDMContext exprDmc, final DataRequestMonitor<List<IExpressionDMContext>> rm) {
final String fullExpr = exprDmc.getExpression().trim();
protected void matchGlobExpression(final IExpressionGroupDMContext exprDmc, final DataRequestMonitor<List<IExpressionDMContext>> rm) {
String fullExpr = exprDmc.getExpression().trim();
if (fullExpr.equals("*")) { //$NON-NLS-1$
matchLocals(exprDmc, rm);
return;
if (fullExpr.startsWith(GLOB_EXPRESSION_PREFIX)) {
// Strip the leading '=' and any extra spaces
fullExpr = fullExpr.substring(1).trim();
}
// Currently, we only support glob-expressions for registers, so
// we only need to match the glob-expression with register names.
// We should not arrive here if we are not handling a register
assert fullExpr.startsWith("$"); //$NON-NLS-1$
if (isRegisterPattern(fullExpr)) {
matchRegisters(exprDmc, rm);
} else {
if (!isArrayPattern(fullExpr)) {
matchLocals(exprDmc, rm);
} else {
// If we are dealing with an expression that could represent an array, we must
// try to match arrays and non-arrays. The reason is that a pattern such as
// =a[1-2] can be a valid match for both a[1], a[2] and a1, a2.
matchArrays(exprDmc, new ImmediateDataRequestMonitor<List<IExpressionDMContext>>(rm) {
@Override
protected void handleSuccess() {
final List<IExpressionDMContext> exprList =
getData() != null ? getData() : new ArrayList<IExpressions.IExpressionDMContext>();
matchLocals(exprDmc, new ImmediateDataRequestMonitor<List<IExpressionDMContext>>(rm) {
@Override
protected void handleSuccess() {
if (getData() != null) {
exprList.addAll(getData());
}
rm.done(exprList);
}
});
}
});
}
}
}
/**
* Find all registers that match the specified glob-pattern.
*
* @param globDmc The glob-expression context for which we want the matches (sub-expressions)
* @param rm RequestMonitor that will contain the unsorted matches.
*/
protected void matchRegisters(final IExpressionGroupDMContext globDmc, final DataRequestMonitor<List<IExpressionDMContext>> rm) {
final IRegisters registerService = getServicesTracker().getService(IRegisters.class);
if (registerService == null) {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Register service unavailable", null)); //$NON-NLS-1$
return;
}
registerService.getRegisterGroups(exprDmc, new ImmediateDataRequestMonitor<IRegisterGroupDMContext[]>(rm) {
registerService.getRegisterGroups(globDmc, new ImmediateDataRequestMonitor<IRegisterGroupDMContext[]>(rm) {
@Override
protected void handleSuccess() {
registerService.getRegisters(
new CompositeDMContext(new IDMContext[] { getData()[0], exprDmc } ),
new CompositeDMContext(new IDMContext[] { getData()[0], globDmc } ),
new ImmediateDataRequestMonitor<IRegisterDMContext[]>(rm) {
@Override
protected void handleSuccess() {
assert getData() instanceof MIRegisterDMC[];
ArrayList<IExpressionDMContext> matches = new ArrayList<IExpressionDMContext>();
String fullExpr = globDmc.getExpression().trim();
if (fullExpr.startsWith(GLOB_EXPRESSION_PREFIX)) {
// Strip the leading '=' and any extra spaces
fullExpr = fullExpr.substring(1).trim();
}
for (MIRegisterDMC register : (MIRegisterDMC[])getData()) {
String potentialMatch = "$"+register.getName(); //$NON-NLS-1$
String potentialMatch = REGISTER_PREFIX + register.getName();
if (globMatches(fullExpr, potentialMatch)) {
matches.add(createExpression(exprDmc, potentialMatch));
matches.add(createExpression(globDmc, potentialMatch));
}
}
@ -684,18 +818,13 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
});
}
/**
* Find all local variables that match the specified glob-pattern.
* We currently only support matching all local variables using the '*' pattern.
*
* @param globDmc The glob-expression context for which we want the matches (sub-expressions)
* @param rm RequestMonitor that will contain the matches.
* @param rm RequestMonitor that will contain the unsorted matches.
*/
protected void matchLocals(final IExpressionDMContext globDmc, final DataRequestMonitor<List<IExpressionDMContext>> rm) {
// We only support '*' for local variables at this time
assert globDmc.getExpression().equals("*"); //$NON-NLS-1$
protected void matchLocals(final IExpressionGroupDMContext globDmc, final DataRequestMonitor<List<IExpressionDMContext>> rm) {
final IStack stackService = getServicesTracker().getService(IStack.class);
if (stackService == null) {
@ -715,42 +844,236 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
IVariableDMContext[] localsDMCs = getData();
final IVariableDMData[] localsDMData = new IVariableDMData[localsDMCs.length];
final CountingRequestMonitor crm = new CountingRequestMonitor(getExecutor(), rm) {
final CountingRequestMonitor varNameCRM = new CountingRequestMonitor(getExecutor(), rm) {
@Override
public void handleSuccess() {
ArrayList<IExpressionDMContext> expressionDMCs = new ArrayList<IExpressionDMContext>(localsDMData.length);
ArrayList<IExpressionDMContext> matches = new ArrayList<IExpressionDMContext>(localsDMData.length);
String fullExpr = globDmc.getExpression().trim();
if (fullExpr.startsWith(GLOB_EXPRESSION_PREFIX)) {
// Strip the leading '=' and any extra spaces
fullExpr = fullExpr.substring(1).trim();
}
for (IVariableDMData localDMData : localsDMData) {
expressionDMCs.add(createExpression(globDmc, localDMData.getName()));
String potentialMatch = localDMData.getName();
if (globMatches(fullExpr, potentialMatch)) {
matches.add(createExpression(globDmc, potentialMatch));
}
rm.done(expressionDMCs);
}
rm.done(matches);
}
};
int countRM = 0;
// Get all the names of the variables
int count = 0;
for (int index=0; index < localsDMCs.length; index++) {
final int finalIndex = index;
stackService.getVariableData(localsDMCs[finalIndex], new ImmediateDataRequestMonitor<IVariableDMData>(crm) {
stackService.getVariableData(localsDMCs[finalIndex], new ImmediateDataRequestMonitor<IVariableDMData>(varNameCRM) {
@Override
public void handleSuccess() {
localsDMData[finalIndex] = getData();
crm.done();
varNameCRM.done();
}
});
countRM++;
count++;
}
crm.setDoneCount(countRM);
varNameCRM.setDoneCount(count);
}
});
}
/**
* Find all arrays elements that match the specified glob-pattern.
*
* @param globDmc The glob-expression context for which we want the matches (sub-expressions)
* @param rm RequestMonitor that will contain the unsorted matches.
*/
protected void matchArrays(final IExpressionGroupDMContext globDmc, final DataRequestMonitor<List<IExpressionDMContext>> rm) {
final IStack stackService = getServicesTracker().getService(IStack.class);
if (stackService == null) {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Stack service unavailable", null)); //$NON-NLS-1$
return;
}
IFrameDMContext frameCtx = DMContexts.getAncestorOfType(globDmc, IFrameDMContext.class);
if (frameCtx == null) {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Stack frame unavailable", null)); //$NON-NLS-1$
return;
}
String fullExpr = globDmc.getExpression().trim();
if (fullExpr.startsWith(GLOB_EXPRESSION_PREFIX)) {
// Strip the leading '=' and any extra spaces
fullExpr = fullExpr.substring(1).trim();
}
// Extract the array name and the array index specification.
// The regex used will remove both [ and ]
String[] arrayExprParts = fullExpr.split("[\\[\\]]"); //$NON-NLS-1$
assert arrayExprParts != null && arrayExprParts.length == 2;
if (arrayExprParts == null || arrayExprParts.length < 2) {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Error parsing array expression", null)); //$NON-NLS-1$
return;
}
final String arrayName = arrayExprParts[0].trim();
final String arrayIndexSpec = arrayExprParts[1].trim();
stackService.getLocals(frameCtx, new ImmediateDataRequestMonitor<IVariableDMContext[]>(rm) {
@Override
protected void handleSuccess() {
IVariableDMContext[] localsDMCs = getData();
final IVariableDMData[] localsDMData = new IVariableDMData[localsDMCs.length];
final CountingRequestMonitor varNameCRM = new CountingRequestMonitor(getExecutor(), rm) {
@Override
public void handleSuccess() {
final ArrayList<IExpressionDMContext> matches = new ArrayList<IExpressionDMContext>();
final CountingRequestMonitor elementMatchesCRM = new CountingRequestMonitor(getExecutor(), rm) {
@Override
public void handleSuccess() {
rm.done(matches);
}
};
int count = 0;
for (IVariableDMData localDMData : localsDMData) {
final String potentialMatch = localDMData.getName();
if (globMatches(arrayName, potentialMatch)) {
// We have a variable that matches the name part of the array.
// Let's create the matching elements if that variable is an array.
createPotentialArrayMatches(createExpression(globDmc, potentialMatch), arrayIndexSpec,
new ImmediateDataRequestMonitor<List<IExpressionDMContext>>(elementMatchesCRM){
@Override
protected void handleSuccess() {
if (getData() != null) {
matches.addAll(getData());
}
elementMatchesCRM.done();
}
});
count++;
}
}
elementMatchesCRM.setDoneCount(count);
}
};
// Get all the names of the variables
int count = 0;
for (int index=0; index < localsDMCs.length; index++) {
final int finalIndex = index;
stackService.getVariableData(localsDMCs[finalIndex], new ImmediateDataRequestMonitor<IVariableDMData>(varNameCRM) {
@Override
public void handleSuccess() {
localsDMData[finalIndex] = getData();
varNameCRM.done();
}
});
count++;
}
varNameCRM.setDoneCount(count);
}
});
}
/**
* Creates requested array elements if exprDmc is indeed an array.
*
* @param exprDmc The potential array expression to be used
* @param indexSpec The specification of the element indices
* @param rm The list of created element expressions.
* If exprDmc is not an array, the list will be empty but not null.
*/
protected void createPotentialArrayMatches(final IExpressionDMContext exprDmc, final String indexSpec,
final DataRequestMonitor<List<IExpressionDMContext>> rm) {
// We check if the variable is an array or not. If it is an array,
// we create the elements based on the specified indices.
// If it is not an array, we don't need to handle it in this method
getExpressionData(exprDmc, new ImmediateDataRequestMonitor<IExpressionDMData>(rm) {
@Override
protected void handleCompleted() {
boolean isArray =
isSuccess() &&
getData().getBasicType().equals(IExpressionDMData.BasicType.array);
final ArrayList<IExpressionDMContext> elements = new ArrayList<IExpressionDMContext>();
if (isArray) {
// we must now create the elements based on the indices
List<IExpressionDMContext> indicesDmcs =
createArrayIndicesExpression(exprDmc, indexSpec);
if (indicesDmcs != null) {
elements.addAll(indicesDmcs);
}
}
rm.done(elements);
}
});
}
/**
* Create all the expressions characterizing the specified arrayDmc and
* indexSpec pattern.
*
* @param arrayDmc The expression context that represents the array itself
* @param indexSpec A string describing the range of indexes to be used.
* Valid range formats are described by {@code ARRAY_INDEX_RANGE_REGEXP}
* The string should not contain the index [] characters.
* @return A list of expression contexts representing all the different
* array elements possible using the name of the array and indexSpec.
* If the indexSpec is invalid (e.g, 3-2) it will be used as-is which
* could be a valid expression (i.e., the index 3-2=1 in this case)
*/
protected List<IExpressionDMContext> createArrayIndicesExpression(IExpressionDMContext arrayDmc, String indexSpec) {
ArrayList<IExpressionDMContext> expressionDMCs = new ArrayList<IExpressionDMContext>();
String arrayName = arrayDmc.getExpression();
IDMContext parentDmc = arrayDmc.getParents()[0];
// First split the indexRange by comma
String[] ranges = indexSpec.split(","); //$NON-NLS-1$
for (String range : ranges) {
// Get rid of any useless spaces
range = range.trim();
// Try to split the range with the - separator
String[] rangeNumbers = range.split("-");//$NON-NLS-1$
if (rangeNumbers.length == 2) {
try {
int lowIndex = Integer.parseInt(rangeNumbers[0]);
int highIndex = Integer.parseInt(rangeNumbers[1]);
if (lowIndex <= highIndex) {
for (int i = lowIndex; i <= highIndex; i++) {
expressionDMCs.add(createExpression(parentDmc, arrayName + "[" + i + "]")); //$NON-NLS-1$ //$NON-NLS-2$
}
continue;
}
} catch (NumberFormatException e) {
// Ignore and fall back on using range as-is below
}
}
// Leave range as-is, which could be a single digit, or some non-expected expression
expressionDMCs.add(createExpression(parentDmc, arrayName + "[" + range + "]")); //$NON-NLS-1$ //$NON-NLS-2$
}
return expressionDMCs;
}
/**
* Verify if the potentialMatch variable matches the glob-pattern.
*
* @param globPattern The glob-pattern to match
* @param potentialMatch The string that must match globPattern.
* @return True of potentialMatch does match globPattern.
* @return True if potentialMatch does match globPattern.
*/
protected boolean globMatches(String globPattern, String potentialMatch) {
// Convert the glob-pattern into java regex to do the matching

View file

@ -10,6 +10,7 @@
* Onur Akdemir (TUBITAK BILGEM-ITI) - Multi-process debugging (Bug 237306)
* John Dallaway - GDB 7.x MI thread details field ignored (Bug 325556)
* Marc Khouzam (Ericsson) - Make each thread an IDisassemblyDMContext (bug 352748)
* Andy Jin (QNX) - Not output thread osId as a string when it is null (Bug 397039)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
@ -774,13 +775,20 @@ public class GDBProcesses_7_0 extends AbstractDsfService
if (getData().getThreadList().length != 0) {
MIThread thread = getData().getThreadList()[0];
if (thread.getThreadId().equals(threadDmc.getId())) {
String id = thread.getOsId();
String id = ""; //$NON-NLS-1$
if (thread.getOsId() != null) {
id = thread.getOsId();
}
// append thread details (if any) to the thread ID
// as for GDB 6.x with CLIInfoThreadsInfo#getOsId()
final String details = thread.getDetails();
if (details != null && details.length() > 0) {
if (!id.isEmpty()) id += " "; //$NON-NLS-1$
id += "(" + details + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}
// We must indicate and empty id by using null
if (id.isEmpty()) id = null;
threadData = new MIThreadDMData("", id); //$NON-NLS-1$
}
}

View file

@ -7,6 +7,7 @@
*
* Contributors:
* Ericsson - initial API and implementation
* Andy Jin (QNX) - Not output thread osId as a string when it is null (Bug 397039)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
@ -175,13 +176,19 @@ public class GDBProcesses_7_1 extends GDBProcesses_7_0 {
if (getData().getThreadList().length != 0) {
MIThread thread = getData().getThreadList()[0];
if (thread.getThreadId().equals(threadDmc.getId())) {
String id = thread.getOsId();
String id = ""; //$NON-NLS-1$
if (thread.getOsId() != null) {
id = thread.getOsId();
}
// append thread details (if any) to the thread ID
// as for GDB 6.x with CLIInfoThreadsInfo#getOsId()
final String details = thread.getDetails();
if (details != null && details.length() > 0) {
if (!id.isEmpty()) id += " "; //$NON-NLS-1$
id += "(" + details + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}
// We must indicate and empty id by using null
if (id.isEmpty()) id = null;
String core = thread.getCore();
threadData = new MIThreadDMData_7_1("", id, //$NON-NLS-1$

View file

@ -35,6 +35,7 @@ import org.eclipse.cdt.dsf.gdb.service.command.GDBControl_7_2;
import org.eclipse.cdt.dsf.gdb.service.command.GDBControl_7_4;
import org.eclipse.cdt.dsf.mi.service.CSourceLookup;
import org.eclipse.cdt.dsf.mi.service.IMIBackend;
import org.eclipse.cdt.dsf.mi.service.IMIExpressions;
import org.eclipse.cdt.dsf.mi.service.MIBreakpoints;
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager;
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsSynchronizer;
@ -165,7 +166,7 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
// Pass in the original service which will be used as a delegate.
// This way of doing things allows to keep the pattern matching aspect isolated
// and easy to remove.
IExpressions originialExpressionService = new MIExpressions(session);
IMIExpressions originialExpressionService = new MIExpressions(session);
return new GDBPatternMatchingExpressions(session, originialExpressionService);
}

View file

@ -1,20 +0,0 @@
/*******************************************************************************
* Copyright (c) 2012 Ericsson 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service;
/**
* Interface that will indicate that the implementing service supports
* Glob-style expression pattern matching.
* @since 4.2
*/
public interface IGDBPatternMatchingExpressions extends IMIExpressions {
}

View file

@ -549,7 +549,8 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
/**
* Install a platform breakpoint on the back-end. For a given context, a
* platform breakpoint can resolve into multiple back-end breakpoints when
* threads are taken into account.
* threads are taken into account or if multiple breakpoints are created
* on the target using the console.
*
* @param dmc
* @param breakpoint
@ -572,13 +573,6 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
final Map<ICBreakpoint, Set<String>> threadsIDs = fBreakpointThreads.get(dmc);
assert threadsIDs != null;
// Minimal validation
if (breakpointIDs.containsKey(breakpoint) || targetBPs.containsValue(breakpoint)) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, BREAKPOINT_ALREADY_INSTALLED, null));
rm.done();
return;
}
// Ensure the breakpoint has a valid debugger source path
if (breakpoint instanceof ICLineBreakpoint
&& !(breakpoint instanceof ICAddressBreakpoint)

View file

@ -2,10 +2,28 @@
int foo(int firstarg, bool secondarg) {
bool firstvar = true;
int secondvar = 18;
int* ptrvar = &secondvar;
int var = 1;
int var2 = 2;
return 0;
}
int testArrayMatching() {
int array[20];
int arrayInt[10];
bool arrayBool[20];
int arrayNot,array2,array3;
array[0] = 20;
array[1] = 21;
array[2] = 22;
array[3] = 23;
array[4] = 24;
array[5] = 25;
return 0;
}
int main (int argc, char *argv[])
{
int intvar = 80;
@ -13,6 +31,7 @@ int main (int argc, char *argv[])
char chararray[201];
foo(15, true);
testArrayMatching();
return 0;
}

View file

@ -0,0 +1,584 @@
/*******************************************************************************
* Copyright (c) 2012 Mentor Graphics 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Mentor Graphics - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint;
import org.eclipse.cdt.debug.core.model.ICBreakpoint;
import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint;
import org.eclipse.cdt.debug.core.model.ICLineBreakpoint;
import org.eclipse.cdt.debug.core.model.ICWatchpoint;
import org.eclipse.cdt.debug.internal.core.breakpoints.CBreakpoint;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.Query;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsAddedEvent;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsChangedEvent;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsRemovedEvent;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsUpdatedEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakListInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakpoint;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.framework.BaseTestCase;
import org.eclipse.cdt.tests.dsf.gdb.framework.SyncUtil;
import org.eclipse.cdt.tests.dsf.gdb.launching.TestsPlugin;
import org.eclipse.cdt.utils.Addr64;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.model.IBreakpoint;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* This test case verifies whether breakpoints or watchpoints set from GDB console
* are properly synchronized with platform breakpoints.
*/
@SuppressWarnings( "restriction" )
@RunWith(BackgroundRunner.class)
public class GDBConsoleBreakpointsTest extends BaseTestCase {
final static private int DEFAULT_TIMEOUT = 20000;
final static private TimeUnit DEFAULT_TIME_UNIT = TimeUnit.MILLISECONDS;
final static private String FILE_NAME_VALID = new Path("data/launch/src/GDBMIGenericTestApp.cc").toFile().getAbsolutePath();
final static private int LINE_NUMBER_VALID = 8;
final static private String FILE_NAME_INVALID = new Path("x.c").toFile().getAbsolutePath();
final static private int LINE_NUMBER_INVALID = 2;
final static private String FUNCTION_VALID = "main()";
final static private String FUNCTION_INVALID = "xxx";
final static private String EXPRESSION_VALID = "path";
final static private String ATTR_FILE_NAME = "FILE_NAME";
final static private String ATTR_LINE_NUMBER = "LINE_NUMBER";
final static private String ATTR_FUNCTION = "FUNCTION";
final static private String ATTR_ADDRESS = "ADDRESS";
final static private String ATTR_EXPRESSION = "EXPRESSION";
final static private String ATTR_READ = "READ";
final static private String ATTR_WRITE = "WRITE";
private DsfSession fSession;
private DsfServicesTracker fServicesTracker;
protected IBreakpointsTargetDMContext fBreakpointsDmc;
private IGDBControl fCommandControl;
private List<IBreakpointsChangedEvent> fBreakpointEvents = new ArrayList<IBreakpointsChangedEvent>();
@Override
@Before
public void doBeforeTest() throws Exception {
deleteAllPlatformBreakpoints();
super.doBeforeTest();
Runnable runnable = new Runnable() {
@Override
public void run() {
fServicesTracker = new DsfServicesTracker(TestsPlugin.getBundleContext(), fSession.getId());
Assert.assertTrue(fServicesTracker != null);
fCommandControl = fServicesTracker.getService(IGDBControl.class);
Assert.assertTrue(fCommandControl != null);
// Register to breakpoint events
fSession.addServiceEventListener(GDBConsoleBreakpointsTest.this, null);
}
};
fSession = getGDBLaunch().getSession();
fSession.getExecutor().submit(runnable).get();
IContainerDMContext containerDmc = SyncUtil.getContainerContext();
fBreakpointsDmc = DMContexts.getAncestorOfType(containerDmc, IBreakpointsTargetDMContext.class);
Assert.assertTrue(fBreakpointsDmc != null);
}
@Override
@After
public void doAfterTest() throws Exception {
Runnable runnable = new Runnable() {
@Override
public void run() {
fSession.removeServiceEventListener(GDBConsoleBreakpointsTest.this);
}
};
fSession.getExecutor().submit(runnable).get();
fBreakpointEvents.clear();
fServicesTracker.dispose();
fServicesTracker = null;
super.doAfterTest();
deleteAllPlatformBreakpoints();
}
@Test
public void testValidLineBreakpoints() throws Throwable {
testConsoleBreakpoint(
ICLineBreakpoint.class,
getLocationBreakpointAttributes(ICLineBreakpoint.class, true));
}
@Test
public void testInvalidLineBreakpoints() throws Throwable {
testConsoleBreakpoint(
ICLineBreakpoint.class,
getLocationBreakpointAttributes(ICLineBreakpoint.class, false));
}
@Test
public void testValidFunctionBreakpoints() throws Throwable {
testConsoleBreakpoint(
ICFunctionBreakpoint.class,
getLocationBreakpointAttributes(ICFunctionBreakpoint.class, true));
}
@Test
public void testInvalidFunctionBreakpoints() throws Throwable {
testConsoleBreakpoint(
ICFunctionBreakpoint.class,
getLocationBreakpointAttributes(ICFunctionBreakpoint.class, false));
}
@Test
public void testValidAddressBreakpoints() throws Throwable {
testConsoleBreakpoint(
ICAddressBreakpoint.class,
getLocationBreakpointAttributes(ICAddressBreakpoint.class, true));
}
@Test
public void testAddressBreakpointsAtZeroAddress() throws Throwable {
testConsoleBreakpoint(
ICAddressBreakpoint.class,
getLocationBreakpointAttributes(ICAddressBreakpoint.class, false));
}
@Test
public void testWriteWatchpoints() throws Throwable {
testConsoleBreakpoint(
ICWatchpoint.class,
getWatchpointAttributes(ICWatchpoint.class, false, true));
}
@Test
public void testReadWatchpoints() throws Throwable {
testConsoleBreakpoint(
ICWatchpoint.class,
getWatchpointAttributes(ICWatchpoint.class, true, false));
}
@Test
public void testAccessWatchpoints() throws Throwable {
testConsoleBreakpoint(
ICWatchpoint.class,
getWatchpointAttributes(ICWatchpoint.class, true, true));
}
@DsfServiceEventHandler
public void eventDispatched(IBreakpointsChangedEvent e) {
synchronized(this) {
fBreakpointEvents.add(e);
notifyAll();
}
}
private void testConsoleBreakpoint(Class<? extends ICBreakpoint> type, Map<String, Object> attributes) throws Throwable {
// Set a console breakpoint and verify that
// the corresponding platform breakpoint is created
// and its install count is 1 if the breakpoint is installed
// and 0 if the breakpoint is pending.
// Check for a duplicate target breakpoint.
setConsoleBreakpoint(type, attributes);
MIBreakpoint[] miBpts = getTargetBreakpoints();
Assert.assertTrue(miBpts.length == 1);
waitForBreakpointEvent(IBreakpointsAddedEvent.class);
Assert.assertTrue(getPlatformBreakpointCount() == 1);
ICBreakpoint plBpt = findPlatformBreakpoint(type, attributes);
Assert.assertTrue(plBpt instanceof CBreakpoint);
// We can't rely on IBreakpointsAddedEvent because it is fired
// before the install count is incremented.
if (!miBpts[0].isPending()) {
// If the target breakpoint is not pending wait
// until the install count becomes 1.
waitForInstallCountChange((CBreakpoint)plBpt, 1);
}
else {
// For pending breakpoints the install count is expected to remain
// unchanged. Give it some time and verify that it is 0.
Thread.sleep(1000);
Assert.assertTrue(((CBreakpoint)plBpt).getInstallCount() == 0);
}
// Disable the console breakpoint and verify that
// the platform breakpoint is disabled.
enableConsoleBreakpoint(miBpts[0].getNumber(), false);
waitForBreakpointEvent(IBreakpointsUpdatedEvent.class);
Assert.assertTrue(!plBpt.isEnabled());
// Enable the console breakpoint and verify that
// the platform breakpoint is enabled.
enableConsoleBreakpoint(miBpts[0].getNumber(), true);
waitForBreakpointEvent(IBreakpointsUpdatedEvent.class);
Assert.assertTrue(plBpt.isEnabled());
// Set the ignore count of the console breakpoint and
// verify that the platform breakpoint's ignore count
// is updated.
setConsoleBreakpointIgnoreCount(miBpts[0].getNumber(), 5);
waitForBreakpointEvent(IBreakpointsUpdatedEvent.class);
Assert.assertTrue(plBpt.getIgnoreCount() == 5);
// Reset the ignore count of the console breakpoint and
// verify that the platform breakpoint's ignore count
// is updated.
setConsoleBreakpointIgnoreCount(miBpts[0].getNumber(), 0);
waitForBreakpointEvent(IBreakpointsUpdatedEvent.class);
Assert.assertTrue(plBpt.getIgnoreCount() == 0);
// Set the condition of the console breakpoint and
// verify that the platform breakpoint's condition
// is updated.
setConsoleBreakpointCondition(miBpts[0].getNumber(), "path==0");
waitForBreakpointEvent(IBreakpointsUpdatedEvent.class);
Assert.assertTrue(plBpt.getCondition().equals("path==0"));
// Reset the condition of the console breakpoint and
// verify that the platform breakpoint's condition
// is updated.
setConsoleBreakpointCondition(miBpts[0].getNumber(), "");
waitForBreakpointEvent(IBreakpointsUpdatedEvent.class);
Assert.assertTrue(plBpt.getCondition().isEmpty());
// Delete the console breakpoint and verify that
// the install count of the platform breakpoint is 0.
deleteConsoleBreakpoint(miBpts[0].getNumber());
waitForBreakpointEvent(IBreakpointsRemovedEvent.class);
Assert.assertTrue(getPlatformBreakpointCount() == 1);
plBpt = findPlatformBreakpoint(type, attributes);
Assert.assertTrue(plBpt instanceof CBreakpoint);
waitForInstallCountChange((CBreakpoint)plBpt, 0);
// Set the console breakpoint again and verify that
// the install count of the platform breakpoint is 1
// for installed breakpoints and 0 for pending breakpoints.
setConsoleBreakpoint(type, attributes);
miBpts = getTargetBreakpoints();
Assert.assertTrue(miBpts.length == 1);
waitForBreakpointEvent(IBreakpointsAddedEvent.class);
Assert.assertTrue(getPlatformBreakpointCount() == 1);
plBpt = findPlatformBreakpoint(type, attributes);
Assert.assertTrue(plBpt instanceof CBreakpoint);
if (!miBpts[0].isPending()) {
waitForInstallCountChange((CBreakpoint)plBpt, 1);
}
else {
// For pending breakpoints the install count is expected to remain
// unchanged. Give it some time and verify that it is 0.
Thread.sleep(1000);
Assert.assertTrue(((CBreakpoint)plBpt).getInstallCount() == 0);
}
// Remove the platform breakpoint and verify that
// the target breakpoint is deleted.
deletePlatformBreakpoint(plBpt);
waitForBreakpointEvent(IBreakpointsRemovedEvent.class);
Assert.assertTrue(getPlatformBreakpointCount() == 0);
miBpts = getTargetBreakpoints();
Assert.assertTrue(miBpts.length == 0);
}
private void setConsoleLineBreakpoint(String fileName, int lineNumber) throws Throwable {
queueConsoleCommand(String.format("break %s:%d", fileName, lineNumber));
}
private void setConsoleFunctionBreakpoint(String fileName, String function) throws Throwable {
queueConsoleCommand(String.format("break %s:%s", fileName, function));
}
private void setConsoleAddressBreakpoint(String address) throws Throwable {
queueConsoleCommand(String.format("break *%s", address));
}
private void setConsoleWatchpoint(String expression, boolean read, boolean write) throws Throwable {
String command = (write) ? ((read) ? "awatch" : "watch") : "rwatch";
queueConsoleCommand(String.format("%s %s", command, expression));
}
private void deleteConsoleBreakpoint(int bpId) throws Throwable {
queueConsoleCommand(String.format("delete %d", bpId));
}
private void enableConsoleBreakpoint(int bpId, boolean enable) throws Throwable {
String cmd = (enable) ? "enable" : "disable";
queueConsoleCommand(String.format("%s %d", cmd, bpId));
}
private void setConsoleBreakpointIgnoreCount(int bpId, int ignoreCount) throws Throwable {
Assert.assertTrue(ignoreCount >= 0);
queueConsoleCommand(String.format("ignore %d %d", bpId, ignoreCount));
}
private void setConsoleBreakpointCondition(int bpId, String condition) throws Throwable {
queueConsoleCommand(String.format("condition %d %s", bpId, condition));
}
private MIBreakpoint[] getTargetBreakpoints() throws Throwable {
return getTargetBreakpoints(DEFAULT_TIMEOUT, DEFAULT_TIME_UNIT);
}
private MIBreakpoint[] getTargetBreakpoints(int timeout, TimeUnit unit) throws Throwable {
Query<MIBreakListInfo> query = new Query<MIBreakListInfo>() {
@Override
protected void execute(DataRequestMonitor<MIBreakListInfo> rm) {
fCommandControl.queueCommand(
fCommandControl.getCommandFactory().createMIBreakList(fBreakpointsDmc),
rm);
}
};
fSession.getExecutor().execute(query);
return query.get(timeout, unit).getMIBreakpoints();
}
private void waitForBreakpointEvent(Class<? extends IBreakpointsChangedEvent> eventType) throws Exception {
waitForBreakpointEvent(eventType, DEFAULT_TIMEOUT);
}
private void waitForBreakpointEvent(Class<? extends IBreakpointsChangedEvent> eventType, int timeout) throws Exception {
if (!breakpointEventReceived(eventType)) {
synchronized(this) {
try {
wait(timeout);
}
catch (InterruptedException ex) {
}
}
if (!breakpointEventReceived(eventType)) {
throw new Exception(String.format("Timed out waiting for '%s' to occur.", eventType.getName()));
}
}
}
private void queueConsoleCommand(String command) throws Throwable {
queueConsoleCommand(command, DEFAULT_TIMEOUT, DEFAULT_TIME_UNIT);
}
private void queueConsoleCommand(final String command, int timeout, TimeUnit unit) throws Throwable {
Query<MIInfo> query = new Query<MIInfo>() {
@Override
protected void execute(DataRequestMonitor<MIInfo> rm) {
fCommandControl.queueCommand(
fCommandControl.getCommandFactory().createMIInterpreterExecConsole(
fCommandControl.getContext(),
command),
rm);
}
};
fSession.getExecutor().execute(query);
query.get(timeout, unit);
}
private ICLineBreakpoint findPlatformLineBreakpoint(String fileName, int lineNumber) throws Throwable {
for(IBreakpoint b : DebugPlugin.getDefault().getBreakpointManager().getBreakpoints()) {
if (b instanceof ICLineBreakpoint
&& fileName.equals(((ICLineBreakpoint)b).getSourceHandle())
&& lineNumber == ((ICLineBreakpoint)b).getLineNumber()) {
return (ICLineBreakpoint)b;
}
}
return null;
}
private ICFunctionBreakpoint findPlatformFunctionBreakpoint(String fileName, String function) throws Throwable {
for(IBreakpoint b : DebugPlugin.getDefault().getBreakpointManager().getBreakpoints()) {
if (b instanceof ICFunctionBreakpoint
&& fileName.equals(((ICLineBreakpoint)b).getSourceHandle())
&& function.equals(((ICLineBreakpoint)b).getFunction())) {
return (ICFunctionBreakpoint)b;
}
}
return null;
}
private ICAddressBreakpoint findPlatformAddressBreakpoint(String address) throws Throwable {
Addr64 a = new Addr64(address);
for(IBreakpoint b : DebugPlugin.getDefault().getBreakpointManager().getBreakpoints()) {
if (b instanceof ICAddressBreakpoint
&& a.toHexAddressString().equals(((ICAddressBreakpoint)b).getAddress())) {
return (ICAddressBreakpoint)b;
}
}
return null;
}
private ICWatchpoint findPlatformWatchpoint(String expression, boolean read, boolean write) throws Throwable {
for(IBreakpoint b : DebugPlugin.getDefault().getBreakpointManager().getBreakpoints()) {
if (b instanceof ICWatchpoint
&& ((ICWatchpoint)b).isReadType() == read
&& ((ICWatchpoint)b).isWriteType() == write) {
return (ICWatchpoint)b;
}
}
return null;
}
private void deletePlatformBreakpoint(final IBreakpoint plBpt) throws Throwable {
new Job("") {
@Override
protected IStatus run(IProgressMonitor monitor) {
IStatus result = Status.OK_STATUS;
try {
DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(plBpt, true);
}
catch(CoreException e) {
result = e.getStatus();
}
return result;
}
}.schedule();
}
private int getPlatformBreakpointCount() {
return DebugPlugin.getDefault().getBreakpointManager().getBreakpoints().length;
}
private void waitForInstallCountChange(CBreakpoint plBpt, int expected) throws Throwable {
waitForInstallCountChange(plBpt, expected, DEFAULT_TIMEOUT);
}
private void waitForInstallCountChange(CBreakpoint plBpt, int expected, long timeout) throws Throwable {
long startMs = System.currentTimeMillis();
while(plBpt.getInstallCount() != expected) {
synchronized(this) {
try {
wait(30);
}
catch (InterruptedException ex) {
}
if (System.currentTimeMillis() - startMs > timeout) {
throw new Exception("Timed out waiting for breakpoint's install count to change");
}
}
}
}
private synchronized boolean breakpointEventReceived(Class<? extends IBreakpointsChangedEvent> eventType) {
for (IBreakpointsChangedEvent e : fBreakpointEvents) {
if (eventType.isAssignableFrom(e.getClass())) {
return fBreakpointEvents.remove(e);
}
}
return false;
}
private Map<String, Object> getLocationBreakpointAttributes(Class<? extends ICBreakpoint> type, boolean valid) {
Map<String, Object> map = new HashMap<String, Object>();
if (ICFunctionBreakpoint.class.equals(type)) {
map.put(ATTR_FILE_NAME, (valid) ? FILE_NAME_VALID : FILE_NAME_INVALID);
map.put(ATTR_FUNCTION, (valid) ? FUNCTION_VALID : FUNCTION_INVALID);
}
else if (ICAddressBreakpoint.class.equals(type)) {
// '0x0" is not invalid address
map.put(ATTR_ADDRESS, (valid) ?
getInitialStoppedEvent().getFrame().getAddress() :
new Addr64("0x0").toHexAddressString());
}
else if (ICLineBreakpoint.class.equals(type)) {
map.put(ATTR_FILE_NAME, (valid) ? FILE_NAME_VALID : FILE_NAME_INVALID);
map.put(ATTR_LINE_NUMBER, (valid) ? LINE_NUMBER_VALID : LINE_NUMBER_INVALID);
}
return map;
}
public Map<String, Object> getWatchpointAttributes(Class<? extends ICWatchpoint> type, boolean read, boolean write) throws Throwable {
Assert.assertTrue(read || write);
Map<String, Object> map = new HashMap<String, Object>();
map.put(ATTR_EXPRESSION, EXPRESSION_VALID);
map.put(ATTR_READ, Boolean.valueOf(read));
map.put(ATTR_WRITE, Boolean.valueOf(write));
return map;
}
private void setConsoleBreakpoint(Class<? extends ICBreakpoint> type, Map<String, Object> attributes) throws Throwable {
if (ICFunctionBreakpoint.class.equals(type)) {
setConsoleFunctionBreakpoint(
(String)attributes.get(ATTR_FILE_NAME),
(String)attributes.get(ATTR_FUNCTION));
}
else if (ICAddressBreakpoint.class.equals(type)) {
setConsoleAddressBreakpoint((String)attributes.get(ATTR_ADDRESS));
}
else if (ICLineBreakpoint.class.equals(type)) {
setConsoleLineBreakpoint(
(String)attributes.get(ATTR_FILE_NAME),
((Integer)attributes.get(ATTR_LINE_NUMBER)).intValue());
}
else if (ICWatchpoint.class.equals(type)) {
setConsoleWatchpoint(
(String)attributes.get(ATTR_EXPRESSION),
((Boolean)attributes.get(ATTR_READ)).booleanValue(),
((Boolean)attributes.get(ATTR_WRITE)).booleanValue());
}
}
private ICBreakpoint findPlatformBreakpoint(Class<? extends ICBreakpoint> type, Map<String, Object> attributes) throws Throwable {
if (ICFunctionBreakpoint.class.equals(type)) {
return findPlatformFunctionBreakpoint(
(String)attributes.get(ATTR_FILE_NAME),
(String)attributes.get(ATTR_FUNCTION));
}
else if (ICAddressBreakpoint.class.equals(type)) {
return findPlatformAddressBreakpoint((String)attributes.get(ATTR_ADDRESS));
}
else if (ICLineBreakpoint.class.equals(type)) {
return findPlatformLineBreakpoint(
(String)attributes.get(ATTR_FILE_NAME),
((Integer)attributes.get(ATTR_LINE_NUMBER)).intValue());
}
else if (ICWatchpoint.class.equals(type)) {
return findPlatformWatchpoint(
(String)attributes.get(ATTR_EXPRESSION),
((Boolean)attributes.get(ATTR_READ)).booleanValue(),
((Boolean)attributes.get(ATTR_WRITE)).booleanValue());
}
throw new Exception(String.format("Invalid breakpoint type: %s", type.getName()));
}
private void deleteAllPlatformBreakpoints() throws Exception {
IBreakpointManager bm = DebugPlugin.getDefault().getBreakpointManager();
for (IBreakpoint b : bm.getBreakpoints()) {
bm.removeBreakpoint(b, true);
}
}
}

Some files were not shown because too many files have changed in this diff Show more