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:
commit
303a22a13e
125 changed files with 4271 additions and 1855 deletions
|
@ -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$
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Andrew Ferguson (Symbian) - Initial implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Sergey Prigogin (Google)
|
||||
* Andrew Ferguson (Symbian) - Initial implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.index.tests;
|
||||
|
||||
|
@ -58,20 +58,122 @@ import org.eclipse.core.runtime.CoreException;
|
|||
public abstract class IndexCPPBindingResolutionTest extends IndexBindingResolutionTestBase {
|
||||
|
||||
public static class SingleProject extends IndexCPPBindingResolutionTest {
|
||||
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true));}
|
||||
public static TestSuite suite() {return suite(SingleProject.class);}
|
||||
public SingleProject() { setStrategy(new SinglePDOMTestStrategy(true)); }
|
||||
public static TestSuite suite() { return suite(SingleProject.class); }
|
||||
}
|
||||
|
||||
public static class ProjectWithDepProj extends IndexCPPBindingResolutionTest {
|
||||
public ProjectWithDepProj() {setStrategy(new ReferencedProject(true));}
|
||||
public static TestSuite suite() {return suite(ProjectWithDepProj.class);}
|
||||
public ProjectWithDepProj() { setStrategy(new ReferencedProject(true)); }
|
||||
public static TestSuite suite() { return suite(ProjectWithDepProj.class); }
|
||||
}
|
||||
|
||||
public static void addTests(TestSuite suite) {
|
||||
|
||||
public static void addTests(TestSuite suite) {
|
||||
suite.addTest(SingleProject.suite());
|
||||
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 {
|
||||
|
@ -81,7 +183,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
// void o(ns::T* a);
|
||||
// void p(ns::E a);
|
||||
// };
|
||||
|
||||
|
||||
// namespace ns {
|
||||
// class A {};
|
||||
// typedef int T;
|
||||
|
@ -91,7 +193,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
// using ns::E;
|
||||
// using ns::T;
|
||||
// using ns::E1;
|
||||
//
|
||||
//
|
||||
// void B::m(A* a) {}
|
||||
// void B::n(E* a) {}
|
||||
// void B::o(T* a) {}
|
||||
|
@ -110,7 +212,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
assertInstance(b1, ICPPMethod.class);
|
||||
assertInstance(b2, ICPPMethod.class);
|
||||
}
|
||||
|
||||
|
||||
// namespace n { class A{}; class B{}; class C{}; }
|
||||
|
||||
// namespace m {
|
||||
|
@ -123,7 +225,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
IBinding b0= getBindingFromASTName("C c", 1);
|
||||
IBinding b1= getBindingFromASTName("D d", 1);
|
||||
}
|
||||
|
||||
|
||||
// namespace n { class A{}; }
|
||||
// namespace m {
|
||||
// using namespace n;
|
||||
|
@ -158,7 +260,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
IBinding b4= getBindingFromASTName("CE1", 3);
|
||||
IBinding b5= getBindingFromASTName("f(2", 1);
|
||||
}
|
||||
|
||||
|
||||
// namespace a { class A {}; }
|
||||
// namespace b {
|
||||
// using a::A;
|
||||
|
@ -172,13 +274,13 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
IBinding b0= getBindingFromASTName("A aa", 1);
|
||||
IBinding b1= getBindingFromASTName("B bb", 1);
|
||||
}
|
||||
|
||||
|
||||
// namespace header {
|
||||
// class clh {
|
||||
// };
|
||||
// void fh();
|
||||
// void fh(int a);
|
||||
//
|
||||
//
|
||||
// class cl {
|
||||
// };
|
||||
// void f();
|
||||
|
@ -186,14 +288,14 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
// }
|
||||
// using header::clh;
|
||||
// using header::fh;
|
||||
|
||||
|
||||
// #include "header.h"
|
||||
// namespace source {
|
||||
// class cls {
|
||||
// };
|
||||
// void fs();
|
||||
// void fs(int a);
|
||||
//
|
||||
//
|
||||
// }
|
||||
// using header::cl;
|
||||
// using header::f;
|
||||
|
@ -204,10 +306,10 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
//
|
||||
// void test() {
|
||||
// fh();
|
||||
// fh(1);
|
||||
//
|
||||
// fh(1);
|
||||
//
|
||||
// clh c;
|
||||
//
|
||||
//
|
||||
// f();
|
||||
// f(1);
|
||||
// cl c1;
|
||||
|
@ -229,18 +331,18 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
b= getBindingFromASTName("cls c2", 3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// int (*f)(int);
|
||||
// int g(int n){return n;}
|
||||
// int g(int n, int m){ return n+m; }
|
||||
|
||||
|
||||
// void foo() {
|
||||
// f= g;
|
||||
// }
|
||||
public void testPointerToFunction() throws Exception {
|
||||
IBinding b0 = getBindingFromASTName("f= g;", 1);
|
||||
IBinding b0 = getBindingFromASTName("f= g;", 1);
|
||||
IBinding b1 = getBindingFromASTName("g;", 1);
|
||||
|
||||
|
||||
assertInstance(b0, ICPPVariable.class);
|
||||
ICPPVariable v0= (ICPPVariable) b0;
|
||||
assertInstance(v0.getType(), IPointerType.class);
|
||||
|
@ -250,7 +352,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
assertInstance(f0.getReturnType(), ICPPBasicType.class);
|
||||
assertEquals(1, f0.getParameterTypes().length);
|
||||
assertInstance(f0.getParameterTypes()[0], ICPPBasicType.class);
|
||||
|
||||
|
||||
assertInstance(b1, ICPPFunction.class);
|
||||
ICPPFunctionType f1= ((ICPPFunction)b1).getType();
|
||||
assertInstance(f1.getReturnType(), ICPPBasicType.class);
|
||||
|
@ -272,7 +374,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
|
||||
// // referencing file
|
||||
// #include "header.h"
|
||||
//
|
||||
//
|
||||
// C *cp = new C(); /*b0, b1*/
|
||||
// void references() {
|
||||
// long l = 5, *lp;
|
||||
|
@ -286,12 +388,12 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
public void testPointerToMemberFields() throws IOException, DOMException {
|
||||
IBinding b0 = getBindingFromASTName("C *cp", 1);
|
||||
assertClassType((ICPPClassType)b0, "C", ICPPClassType.k_class, 1, 6, 5, 9, 0, 1, 0, 2, 1);
|
||||
|
||||
|
||||
IBinding b1 = getBindingFromASTName("cp = new C()", 2);
|
||||
assertVariable(b1, "cp", IPointerType.class, null);
|
||||
IPointerType b1type = (IPointerType) ((ICPPVariable)b1).getType();
|
||||
assertClassType(b1type.getType(), "C", ICPPClassType.k_class, 1, 6, 5, 9, 0, 1, 0, 2, 1);
|
||||
|
||||
|
||||
IBinding b2 = getBindingFromASTName("cs.*cp->o", 2);
|
||||
ICPPField field0 = (ICPPField) b2;
|
||||
assertTrue(field0.getType() instanceof ICPPClassType);
|
||||
|
@ -407,9 +509,9 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
IBinding b20 = getBindingFromASTName("func(a);", 4);
|
||||
IBinding b21 = getBindingFromASTName("a); /*func5*/", 1);
|
||||
IBinding b22 = getBindingFromASTName("C2 : public", 2);
|
||||
IBinding b23 = getBindingFromASTName("C {}; /*base*/", 1);
|
||||
IBinding b23 = getBindingFromASTName("C {}; /*base*/", 1);
|
||||
IBinding b24 = getBindingFromASTName("S2 : public", 2);
|
||||
IBinding b25 = getBindingFromASTName("S {}; /*base*/", 1);
|
||||
IBinding b25 = getBindingFromASTName("S {}; /*base*/", 1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -420,14 +522,14 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
//// referencing content
|
||||
//namespace n1 {
|
||||
// class TopC {}; struct TopS {}; union TopU {}; enum TopE {TopER1,TopER2};
|
||||
// short topBasic; void *topPtr;/*A*/ TopC *topCPtr;/*A*/ TopU topFunc(){return *new TopU();}
|
||||
// short topBasic; void *topPtr;/*A*/ TopC *topCPtr;/*A*/ TopU topFunc(){return *new TopU();}
|
||||
// class C {
|
||||
// class TopC {}; struct TopS {}; union TopU {}; enum TopE {TopER1,TopER2};
|
||||
// short topBasic; void *topPtr;/*B*/ TopC *topCPtr;/*B*/ TopU topFunc(){return *new TopU();}
|
||||
// void references() {
|
||||
// ::TopC c; ::TopS s; ::TopU u; ::TopE e = ::TopER1;
|
||||
// ::topBasic++; ::topPtr = &::topBasic; ::topCPtr = &c; ::topFunc();
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
//}
|
||||
public void testSingletonQualifiedName() {
|
||||
|
@ -468,26 +570,26 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
// }
|
||||
// namespace n3 { c3::s3::u3::S _s10; }
|
||||
// namespace n1 { n2::S _s11; }
|
||||
// namespace n1 { namespace n2 { S _s12; }}
|
||||
// namespace n1 { namespace n2 { S _s12; }}
|
||||
public void testQualifiedNamesForStruct() throws DOMException {
|
||||
IBinding b0 = getBindingFromASTName("S _s0;", 1);
|
||||
assertTrue(b0.getScope() instanceof ICPPNamespaceScope);
|
||||
assertTrue(b0.getScope().getParent() instanceof ICPPNamespaceScope);
|
||||
assertTrue(b0.getScope().getParent().getParent() == null);
|
||||
assertQNEquals("n1::n2::S", b0);
|
||||
|
||||
|
||||
IBinding b1 = getBindingFromASTName("S _s1;", 1);
|
||||
assertTrue(b1.getScope() instanceof ICPPNamespaceScope);
|
||||
assertTrue(b1.getScope().getParent() instanceof ICPPNamespaceScope);
|
||||
assertTrue(b1.getScope().getParent().getParent() == null);
|
||||
assertQNEquals("n1::n2::S", b1);
|
||||
|
||||
|
||||
IBinding b2 = getBindingFromASTName("S _s2;", 1);
|
||||
assertTrue(b2.getScope() instanceof ICPPClassScope);
|
||||
assertTrue(b2.getScope().getParent() instanceof ICPPClassScope);
|
||||
assertTrue(b2.getScope().getParent().getParent() == null);
|
||||
assertQNEquals("c1::c2::S", b2);
|
||||
|
||||
|
||||
IBinding b3 = getBindingFromASTName("S _s3;", 1);
|
||||
assertQNEquals("c1::c2::S", b3);
|
||||
IBinding b4 = getBindingFromASTName("S _s4;", 1);
|
||||
|
@ -502,7 +604,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
assertQNEquals("n3::c3::s3::u3::S", b8);
|
||||
IBinding b9 = getBindingFromASTName("S _s9;", 1);
|
||||
assertQNEquals("n3::c3::s3::u3::S", b9);
|
||||
|
||||
|
||||
IBinding b10 = getBindingFromASTName("S _s10;", 1);
|
||||
assertTrue(b10.getScope() instanceof ICPPClassScope);
|
||||
assertTrue(b10.getScope().getParent() instanceof ICPPClassScope);
|
||||
|
@ -510,7 +612,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
assertTrue(b10.getScope().getParent().getParent().getParent() instanceof ICPPNamespaceScope);
|
||||
assertTrue(b10.getScope().getParent().getParent().getParent().getParent() == null);
|
||||
assertQNEquals("n3::c3::s3::u3::S", b10);
|
||||
|
||||
|
||||
IBinding b11 = getBindingFromASTName("S _s11;", 1);
|
||||
assertQNEquals("n1::n2::S", b11);
|
||||
IBinding b12 = getBindingFromASTName("S _s12;", 1);
|
||||
|
@ -519,7 +621,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
|
||||
// // header content
|
||||
// namespace n1 { namespace n2 { union U {}; } }
|
||||
// class c1 { public: class c2 { public: union U {}; }; };
|
||||
// class c1 { public: class c2 { public: union U {}; }; };
|
||||
// struct s1 { struct s2 { union U {}; }; };
|
||||
// union u1 { struct u2 { union U {}; }; };
|
||||
// namespace n3 { class c3 { public: struct s3 { union u3 { union U {}; }; }; }; }
|
||||
|
@ -535,7 +637,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
// }
|
||||
// namespace n3 { c3::s3::u3::U _u10; }
|
||||
// namespace n1 { n2::U _u11; }
|
||||
// namespace n1 { namespace n2 { U _u12; }}
|
||||
// namespace n1 { namespace n2 { U _u12; }}
|
||||
public void testQualifiedNamesForUnion() throws DOMException {
|
||||
IBinding b0 = getBindingFromASTName("U _u0;", 1);
|
||||
assertQNEquals("n1::n2::U", b0);
|
||||
|
@ -583,7 +685,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
// }
|
||||
// namespace n3 { c3::s3::u3::C _c10; }
|
||||
// namespace n1 { n2::C _c11; }
|
||||
// namespace n1 { namespace n2 { C _c12; }}
|
||||
// namespace n1 { namespace n2 { C _c12; }}
|
||||
public void testQualifiedNamesForClass() throws DOMException {
|
||||
IBinding b0 = getBindingFromASTName("C _c0;", 1);
|
||||
assertQNEquals("n1::n2::C", b0);
|
||||
|
@ -631,7 +733,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
// }
|
||||
// namespace n3 { c3::s3::u3::Int i10; }
|
||||
// namespace n1 { n2::Int i11; }
|
||||
// namespace n1 { namespace n2 { Int i12; }}
|
||||
// namespace n1 { namespace n2 { Int i12; }}
|
||||
public void testQualifiedNamesForTypedef() throws DOMException {
|
||||
IBinding b0 = getBindingFromASTName("Int i0;", 3);
|
||||
assertQNEquals("n1::n2::Int", b0);
|
||||
|
@ -778,7 +880,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
// class y { public:
|
||||
// static int j;
|
||||
// };
|
||||
// };
|
||||
// };
|
||||
// void method() {
|
||||
// ::x::y::i++;
|
||||
// x::y::j++;
|
||||
|
@ -818,7 +920,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
// (sp,sp)->i/*7*/++; (s,s).i/*8*/++; // IASTExpressionList
|
||||
// ss.sp->i/*9*/++; ss.s.i/*10*/++; // IASTFieldReference
|
||||
// ssp->sp->i/*11*/++; ssp->s.i/*12*/++; // IASTFieldReference
|
||||
// retsptr()->i/*13*/++; rets().i/*14*/++; // IASTFunctionCallExpression
|
||||
// retsptr()->i/*13*/++; rets().i/*14*/++; // IASTFunctionCallExpression
|
||||
// sp->i/*15*/++; s.i/*16*/++; // IASTIdExpression
|
||||
// /* not applicable */ // IASTLiteralExpression
|
||||
// /* not applicable */ // IASTTypeIdExpression
|
||||
|
@ -942,7 +1044,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
// void f(int);
|
||||
// void f(long);
|
||||
// void f(C); void f(C::i1); void f(C::lp1); void f(C::S1); void f(C::U1); void f(C::E1);
|
||||
// void f(S); void f(S::i2); void f(S::lp2); void f(S::S2); void f(S::U2); void f(S::E2);
|
||||
// void f(S); void f(S::i2); void f(S::lp2); void f(S::S2); void f(S::U2); void f(S::E2);
|
||||
// void f(U); void f(U::i3); void f(U::lp3); void f(U::S3); void f(U::U3); void f(U::E3);
|
||||
// void f(n::i4); void f(n::lp4); void f(n::S4); void f(n::U4); void f(n::E4);
|
||||
// void f(E);
|
||||
|
@ -962,7 +1064,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
// fU = &f;/*14*/ fUi3 = &f;/*15*/ fUlp3 = &f;/*16*/ fUS3 = &f;/*17*/ fUU3 = &f;/*18*/ fUE3 = &f;/*19*/
|
||||
// fni4 = &f;/*20*/ fnlp4 = &f;/*21*/ fnS4 = &f;/*22*/ fnU4 = &f;/*23*/ fnE4 = &f;/*24*/
|
||||
// fE = &f;/*25*/
|
||||
// }
|
||||
// }
|
||||
public void testAddressOfOverloadedFunction() throws DOMException {
|
||||
IBinding b0 = getBindingFromASTName("f;/*0*/", 1);
|
||||
IBinding b1 = getBindingFromASTName("f;/*1*/", 1);
|
||||
|
@ -994,7 +1096,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
// struct C {
|
||||
// int m1(int a);
|
||||
// int m2(int a) const;
|
||||
// };
|
||||
// };
|
||||
//
|
||||
// C* func(int (C::*m)(int) const);
|
||||
// C* func(int (C::*m)(int));
|
||||
|
@ -1015,7 +1117,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
// void f_int_ptr(int*);
|
||||
|
||||
// #include "header.h"
|
||||
// void ref() {
|
||||
// void ref() {
|
||||
// int i = 0;
|
||||
// const int const_int = 0;
|
||||
//
|
||||
|
@ -1027,7 +1129,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
//
|
||||
// void f_const_int(const int const_int) {
|
||||
// f_int_ptr(&const_int); // error
|
||||
// }
|
||||
// }
|
||||
public void testConstIntParameter() {
|
||||
getBindingFromASTName("f_int(i)", 5);
|
||||
getBindingFromASTName("f_int(const_int)", 5);
|
||||
|
@ -1045,7 +1147,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
// void f_int_const_ptr_const(int const*const);
|
||||
|
||||
// #include "header.h"
|
||||
// void ref() {
|
||||
// void ref() {
|
||||
// int* int_ptr = 0;
|
||||
// const int* const_int_ptr = 0;
|
||||
// int const* int_const_ptr = 0;
|
||||
|
@ -1259,7 +1361,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
// };
|
||||
|
||||
// // referencing content
|
||||
// struct myStruct;
|
||||
// struct myStruct;
|
||||
// union myUnion;
|
||||
// void test() {
|
||||
// struct myStruct* u;
|
||||
|
@ -1271,13 +1373,13 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
getBindingFromASTName("a= 1", 1);
|
||||
getBindingFromASTName("b= 1", 1);
|
||||
}
|
||||
|
||||
|
||||
// namespace x {
|
||||
// int a(int);
|
||||
// }
|
||||
// using namespace x;
|
||||
// using x::a;
|
||||
|
||||
|
||||
// #include "header.h"
|
||||
// void test() {
|
||||
// a(1);
|
||||
|
@ -1285,7 +1387,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
public void testLegalConflictWithUsingDeclaration() throws Exception {
|
||||
getBindingFromASTName("a(1)", 1);
|
||||
}
|
||||
|
||||
|
||||
// class A {};
|
||||
// class B {};
|
||||
// class C {
|
||||
|
@ -1294,7 +1396,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
// };
|
||||
// class D : public C {};
|
||||
// void foo(B b) {}
|
||||
|
||||
|
||||
// class E : public C {};
|
||||
// void refs() {
|
||||
// C c;
|
||||
|
@ -1307,12 +1409,12 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
public void testUserDefinedConversionOperator_224364() throws Exception {
|
||||
IBinding ca= getBindingFromASTName("C c;", 1);
|
||||
assertInstance(ca, ICPPClassType.class);
|
||||
|
||||
|
||||
IBinding foo1= getBindingFromASTName("foo(c)", 3);
|
||||
|
||||
|
||||
IBinding da= getBindingFromASTName("D d", 1);
|
||||
assertInstance(da, ICPPClassType.class);
|
||||
|
||||
|
||||
IBinding foo2= getBindingFromASTName("foo(d)", 3);
|
||||
IBinding foo3= getBindingFromASTName("foo(e)", 3);
|
||||
}
|
||||
|
@ -1349,7 +1451,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
// class A {};
|
||||
// }}
|
||||
// using namespace ns1::ns2;
|
||||
|
||||
|
||||
// #include "header.h"
|
||||
// A a;
|
||||
public void testUsingDirectiveWithQualifiedName_269727() throws Exception {
|
||||
|
@ -1358,7 +1460,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
|
||||
// void f(int (&v)[1]);
|
||||
// void f(int (&v)[2]);
|
||||
|
||||
|
||||
// void test() {
|
||||
// int a[1], b[2];
|
||||
// f(a); f(b);
|
||||
|
@ -1495,7 +1597,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
// int a;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// void test() {
|
||||
// ns::m::a; //1
|
||||
// ns::a; //2
|
||||
|
@ -1511,7 +1613,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
// int a;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// namespace ns {
|
||||
// void test() {
|
||||
// m::a; //1
|
||||
|
@ -1545,7 +1647,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
// using namespace out2;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// #include "header.h"
|
||||
// void test() {
|
||||
// ::f(1);
|
||||
|
@ -1570,7 +1672,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
// using namespace out2;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// #include "header.h"
|
||||
// namespace out {}
|
||||
// namespace out2 {}
|
||||
|
@ -1613,105 +1715,27 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
getBindingFromASTName("f(a)", 1, ICPPFunction.class);
|
||||
getBindingFromASTName("g(b)", 1, ICPPFunction.class);
|
||||
}
|
||||
|
||||
/* CPP 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);
|
||||
}
|
||||
}
|
||||
// namespace ns {
|
||||
// namespace {
|
||||
// const char str[] = "";
|
||||
// }
|
||||
// }
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ public class DBTest extends BaseTestCase {
|
|||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
db.close();
|
||||
if(!db.getLocation().delete()) {
|
||||
if (!db.getLocation().delete()) {
|
||||
db.getLocation().deleteOnExit();
|
||||
}
|
||||
db= null;
|
||||
|
@ -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
|
||||
|
@ -104,7 +104,7 @@ public class DBTest extends BaseTestCase {
|
|||
|
||||
public void testFreeBlockLinking() throws Exception {
|
||||
final int realsize = 42;
|
||||
final int deltas = (realsize+Database.BLOCK_HEADER_SIZE + Database.BLOCK_SIZE_DELTA - 1) / Database.BLOCK_SIZE_DELTA;
|
||||
final int deltas = (realsize + Database.BLOCK_HEADER_SIZE + Database.BLOCK_SIZE_DELTA - 1) / Database.BLOCK_SIZE_DELTA;
|
||||
final int blocksize = deltas * Database.BLOCK_SIZE_DELTA;
|
||||
final int freeDeltas= Database.MIN_BLOCK_DELTAS-deltas;
|
||||
|
||||
|
@ -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];
|
||||
|
@ -224,8 +224,8 @@ public class DBTest extends BaseTestCase {
|
|||
assertCMP("", EQ, "", true);
|
||||
assertCMP("", EQ, "", false);
|
||||
|
||||
doTrials(1000, 1, ShortString.MAX_BYTE_LENGTH/2, r, true);
|
||||
doTrials(1000, 1, ShortString.MAX_BYTE_LENGTH/2, r, false);
|
||||
doTrials(1000, 1, ShortString.MAX_BYTE_LENGTH / 2, r, true);
|
||||
doTrials(1000, 1, ShortString.MAX_BYTE_LENGTH / 2, r, false);
|
||||
doTrials(1000, 1, ShortString.MAX_BYTE_LENGTH, r, true);
|
||||
doTrials(1000, 1, ShortString.MAX_BYTE_LENGTH, r, false);
|
||||
|
||||
|
@ -243,13 +243,13 @@ public class DBTest extends BaseTestCase {
|
|||
|
||||
public void testLongStringComparison() throws CoreException {
|
||||
Random r= new Random(314159265);
|
||||
doTrials(100, ShortString.MAX_BYTE_LENGTH+1, ShortString.MAX_BYTE_LENGTH*2, r, true);
|
||||
doTrials(100, ShortString.MAX_BYTE_LENGTH+1, ShortString.MAX_BYTE_LENGTH*2, r, false);
|
||||
doTrials(100, ShortString.MAX_BYTE_LENGTH + 1, ShortString.MAX_BYTE_LENGTH * 2, r, true);
|
||||
doTrials(100, ShortString.MAX_BYTE_LENGTH + 1, ShortString.MAX_BYTE_LENGTH * 2, r, false);
|
||||
}
|
||||
|
||||
private void doTrials(int n, int min, int max, Random r, boolean caseSensitive) throws CoreException {
|
||||
long start = System.currentTimeMillis();
|
||||
for(int i=0; i<n; i++) {
|
||||
for(int i= 0; i < n; i++) {
|
||||
String a = randomString(min, max, r);
|
||||
String b = randomString(min, max, r);
|
||||
int expected = caseSensitive ? a.compareTo(b) : a.compareToIgnoreCase(b);
|
||||
|
@ -262,7 +262,7 @@ public class DBTest extends BaseTestCase {
|
|||
private String randomString(int min, int max, Random r) {
|
||||
StringBuffer result = new StringBuffer();
|
||||
int len = min + r.nextInt(max-min);
|
||||
for(int i=0; i<len; i++) {
|
||||
for(int i= 0; i < len; i++) {
|
||||
result.append(randomChar(r));
|
||||
}
|
||||
return result.toString();
|
||||
|
@ -317,8 +317,8 @@ public class DBTest extends BaseTestCase {
|
|||
}
|
||||
|
||||
private void assertSignEquals(int a, int b) {
|
||||
a= a<0 ? -1 : (a>0 ? 1 : 0);
|
||||
b= b<0 ? -1 : (b>0 ? 1 : 0);
|
||||
a= a < 0 ? -1 : (a > 0 ? 1 : 0);
|
||||
b= b < 0 ? -1 : (b > 0 ? 1 : 0);
|
||||
assertEquals(a, b);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.pdom.tests;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
@ -32,21 +31,20 @@ 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
|
||||
*/
|
||||
public class NamespaceTests extends PDOMTestBase {
|
||||
protected ICProject project;
|
||||
protected ICProject project;
|
||||
protected PDOM pdom;
|
||||
protected IProgressMonitor NULL_MONITOR = new NullProgressMonitor();
|
||||
protected IndexFilter INDEX_FILTER = IndexFilter.ALL;
|
||||
|
||||
|
||||
public static Test suite() {
|
||||
return suite(NamespaceTests.class);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
if (pdom == null) {
|
||||
|
@ -55,7 +53,7 @@ public class NamespaceTests extends PDOMTestBase {
|
|||
}
|
||||
pdom.acquireReadLock();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
pdom.releaseReadLock();
|
||||
|
@ -63,9 +61,9 @@ public class NamespaceTests extends PDOMTestBase {
|
|||
project.getProject().delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
@ -81,147 +79,136 @@ public class NamespaceTests extends PDOMTestBase {
|
|||
assertTrue(namespaces[0] instanceof ICPPNamespace);
|
||||
assertTrue(namespaces[0] instanceof ICPPNamespaceAlias);
|
||||
ICPPNamespaceAlias namespaceAlias = (ICPPNamespaceAlias) namespaces[0];
|
||||
|
||||
//TODO PDOM has no alias information
|
||||
|
||||
// TODO PDOM has no alias information
|
||||
// namespace2 and namespaceAlias should be referencing the same namespace
|
||||
assertEquals(namespace2, namespaceAlias.getBinding());
|
||||
}
|
||||
|
||||
public void testNested() throws Exception {
|
||||
|
||||
/* Find deeply nested namespace */
|
||||
public void testNested() throws Exception {
|
||||
// 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 */
|
||||
public void testMemberDefinition() throws Exception {
|
||||
// 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);
|
||||
assertTrue(members[0] instanceof ICPPFunction);
|
||||
|
||||
|
||||
IName[] decls = pdom.findNames(members[0], IIndex.FIND_DECLARATIONS);
|
||||
assertEquals(1, decls.length);
|
||||
IASTFileLocation loc = decls[0].getFileLocation();
|
||||
assertEquals(offset("namespace.cpp", "void foo()") + 5, loc.getNodeOffset()); //character offset
|
||||
assertEquals(offset("namespace.cpp", "void foo()") + 5, loc.getNodeOffset()); // character offset
|
||||
|
||||
IName[] defs = pdom.findNames(members[0], IIndex.FIND_DEFINITIONS);
|
||||
assertEquals(1, defs.length);
|
||||
loc = defs[0].getFileLocation();
|
||||
assertEquals(offset("namespace.cpp", "::foo()") + 2, loc.getNodeOffset()); //character offset
|
||||
|
||||
assertEquals(offset("namespace.cpp", "::foo()") + 2, loc.getNodeOffset()); // character offset
|
||||
}
|
||||
|
||||
public void testExtend() throws Exception {
|
||||
|
||||
/* Extending a namespace */
|
||||
public void testExtend() throws Exception {
|
||||
// Extending a namespace
|
||||
IBinding[] namespaces = pdom.findBindings(Pattern.compile("ns1"), false, INDEX_FILTER, NULL_MONITOR);
|
||||
assertEquals(1, namespaces.length);
|
||||
assertTrue(namespaces[0] instanceof ICPPNamespace);
|
||||
ICPPNamespace namespace1 = (ICPPNamespace) namespaces[0];
|
||||
Pattern[] patterns = {Pattern.compile("ns1"), Pattern.compile("c")};
|
||||
IBinding[] members = pdom.findBindings(patterns, false, INDEX_FILTER, NULL_MONITOR);
|
||||
assertEquals(1, members.length); //c was added by extending the namespace
|
||||
assertEquals(1, members.length); // c was added by extending the namespace
|
||||
}
|
||||
|
||||
|
||||
public void testOverload() throws Exception {
|
||||
|
||||
//Function overloading in namespace
|
||||
// Function overloading in namespace
|
||||
Pattern[] patterns = {Pattern.compile("ns3"), Pattern.compile("blah")};
|
||||
IBinding[] functions = pdom.findBindings(patterns, false, INDEX_FILTER, NULL_MONITOR);
|
||||
assertEquals(1, functions.length);
|
||||
assertTrue(functions[0] instanceof ICPPFunction);
|
||||
ICPPFunction function = (ICPPFunction) functions[0];
|
||||
|
||||
|
||||
IName[] defs = pdom.findNames(function, IIndex.FIND_DEFINITIONS);
|
||||
assertEquals(1, defs.length);
|
||||
IASTFileLocation loc = defs[0].getFileLocation();
|
||||
assertEquals(offset("overload.cpp","void blah(char)") + 5, loc.getNodeOffset()); //character offset
|
||||
|
||||
assertEquals(offset("overload.cpp", "void blah(char)") + 5, loc.getNodeOffset()); // character offset
|
||||
|
||||
IName[] decls = pdom.findNames(function, IIndex.FIND_DECLARATIONS_DEFINITIONS);
|
||||
assertEquals(1, decls.length);
|
||||
loc = decls[0].getFileLocation();
|
||||
assertEquals(offset("overload.cpp","void blah(char)") + 5, loc.getNodeOffset()); //character offset
|
||||
|
||||
assertEquals(offset("overload.cpp", "void blah(char)") + 5, loc.getNodeOffset()); // character offset
|
||||
|
||||
IName[] refs = pdom.findNames(function, IIndex.FIND_REFERENCES);
|
||||
assertEquals(1, refs.length);
|
||||
loc = refs[0].getFileLocation();
|
||||
assertEquals(offset("overload.cpp","blah('a')"), loc.getNodeOffset()); //character offset
|
||||
|
||||
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);
|
||||
ICPPFunction function = (ICPPFunction) functions[0];
|
||||
|
||||
|
||||
IName[] defs = pdom.findNames(function, IIndex.FIND_DEFINITIONS);
|
||||
assertEquals(1, defs.length);
|
||||
IASTFileLocation loc = defs[0].getFileLocation();
|
||||
assertEquals(offset("unnamed.cpp","void function1()") + 5, loc.getNodeOffset()); //character offset
|
||||
|
||||
assertEquals(offset("unnamed.cpp", "void function1()") + 5, loc.getNodeOffset()); // character offset
|
||||
|
||||
IName[] decls = pdom.findNames(function, IIndex.FIND_DECLARATIONS_DEFINITIONS);
|
||||
assertEquals(1, decls.length);
|
||||
loc = decls[0].getFileLocation();
|
||||
assertEquals(offset("unnamed.cpp","void function1()") + 5, loc.getNodeOffset()); //character offset
|
||||
|
||||
assertEquals(offset("unnamed.cpp", "void function1()") + 5, loc.getNodeOffset()); // character offset
|
||||
|
||||
IName[] refs = pdom.findNames(function, IIndex.FIND_REFERENCES);
|
||||
assertEquals(1, refs.length);
|
||||
loc = refs[0].getFileLocation();
|
||||
assertEquals(offset("unnamed.cpp","function1();"), loc.getNodeOffset()); //character offset
|
||||
|
||||
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);
|
||||
ICPPFunction function = (ICPPFunction) functions[0];
|
||||
|
||||
|
||||
IName[] defs = pdom.findNames(function, IIndex.FIND_DEFINITIONS);
|
||||
assertEquals(1, defs.length);
|
||||
IASTFileLocation loc = defs[0].getFileLocation();
|
||||
assertEquals(offset("friend.cpp","void function2(Class1){};") + 5, loc.getNodeOffset()); //character offset
|
||||
|
||||
assertEquals(offset("friend.cpp", "void function2(Class1){};") + 5, loc.getNodeOffset()); // character offset
|
||||
|
||||
IName[] decls = pdom.findNames(function, IIndex.FIND_DECLARATIONS);
|
||||
assertEquals(1, decls.length);
|
||||
loc = decls[0].getFileLocation();
|
||||
assertEquals(offset("friend.cpp","friend void function2(Class1);") + 12, loc.getNodeOffset()); //character offset
|
||||
assertEquals(offset("friend.cpp", "friend void function2(Class1);") + 12, loc.getNodeOffset()); // character offset
|
||||
|
||||
IName[] refs = pdom.findNames(function, IIndex.FIND_REFERENCES);
|
||||
assertEquals(1, refs.length);
|
||||
loc = refs[0].getFileLocation();
|
||||
assertEquals(offset("friend.cpp","ns4::function2(element)") + 5, loc.getNodeOffset()); //character offset
|
||||
|
||||
assertEquals(offset("friend.cpp", "ns4::function2(element)") + 5, loc.getNodeOffset()); // character offset
|
||||
}
|
||||
|
||||
|
||||
public void testUsingDirective() throws Exception {
|
||||
//TODO need to test for PDOM? or is it more for compiler?
|
||||
// TODO need to test for PDOM? or is it more for compiler?
|
||||
Pattern[] patterns = {Pattern.compile("ns4"), Pattern.compile("element")};
|
||||
IBinding[] variables = pdom.findBindings(patterns, false, INDEX_FILTER, NULL_MONITOR);
|
||||
assertEquals(1, variables.length);
|
||||
assertTrue(variables[0] instanceof ICPPVariable);
|
||||
ICPPVariable variable1 = (ICPPVariable) variables[0];
|
||||
|
||||
|
||||
IName[] defs = pdom.findNames(variable1, IIndex.FIND_DEFINITIONS);
|
||||
assertEquals(1, defs.length);
|
||||
IASTFileLocation loc = defs[0].getFileLocation();
|
||||
assertEquals(offset("friend.cpp","Class1 element;") + 7, loc.getNodeOffset()); //character offset
|
||||
assertEquals(offset("friend.cpp", "Class1 element;") + 7, loc.getNodeOffset()); // character offset
|
||||
|
||||
IName[] decls = pdom.findNames(variable1, IIndex.FIND_DECLARATIONS);
|
||||
assertEquals(0, decls.length);
|
||||
|
||||
|
||||
IName[] refs = pdom.findNames(variable1, IIndex.FIND_REFERENCES);
|
||||
assertEquals(2, refs.length);
|
||||
assertEquals(2, refs.length);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.model;
|
||||
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -19,23 +17,22 @@ 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.
|
||||
*
|
||||
*
|
||||
* This class is similar to the JDT CModelCache class.
|
||||
*/
|
||||
public class CModelCache {
|
||||
public static final int PROJ_CACHE_SIZE = 50;
|
||||
public static final int FOLDER_CACHE_SIZE = 500;
|
||||
public static final int PROJ_CACHE_SIZE = 50;
|
||||
public static final int FOLDER_CACHE_SIZE = 500;
|
||||
public static final int FILE_CACHE_SIZE = 2000;
|
||||
public static final int CHILDREN_CACHE_SIZE = FILE_CACHE_SIZE * 20;
|
||||
|
||||
|
||||
/**
|
||||
* Cache of open projects and roots.
|
||||
*/
|
||||
protected Map<ICElement, Object> projectAndRootCache;
|
||||
|
||||
|
||||
/**
|
||||
* Cache of open containers
|
||||
*/
|
||||
|
@ -50,62 +47,62 @@ public class CModelCache {
|
|||
* Cache of children of C elements
|
||||
*/
|
||||
protected Map<ICElement, Object> childrenCache;
|
||||
|
||||
public CModelCache() {
|
||||
this.projectAndRootCache = new HashMap<ICElement, Object>(PROJ_CACHE_SIZE);
|
||||
this.folderCache = new HashMap<ICElement, Object>(FOLDER_CACHE_SIZE);
|
||||
this.fileCache = new ElementCache<Object>(FILE_CACHE_SIZE);
|
||||
this.childrenCache = new HashMap<ICElement, Object>(CHILDREN_CACHE_SIZE); // average 20 children per openable
|
||||
}
|
||||
|
||||
public double openableFillingRatio() {
|
||||
return this.fileCache.fillingRatio();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the info for the element.
|
||||
*/
|
||||
public Object getInfo(ICElement element) {
|
||||
switch (element.getElementType()) {
|
||||
public CModelCache() {
|
||||
this.projectAndRootCache = new HashMap<ICElement, Object>(PROJ_CACHE_SIZE);
|
||||
this.folderCache = new HashMap<ICElement, Object>(FOLDER_CACHE_SIZE);
|
||||
this.fileCache = new ElementCache<Object>(FILE_CACHE_SIZE);
|
||||
this.childrenCache = new HashMap<ICElement, Object>(CHILDREN_CACHE_SIZE); // average 20 children per openable
|
||||
}
|
||||
|
||||
public double openableFillingRatio() {
|
||||
return this.fileCache.fillingRatio();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the info for the element.
|
||||
*/
|
||||
public Object getInfo(ICElement element) {
|
||||
switch (element.getElementType()) {
|
||||
case ICElement.C_MODEL:
|
||||
case ICElement.C_PROJECT:
|
||||
return this.projectAndRootCache.get(element);
|
||||
case ICElement.C_CCONTAINER:
|
||||
return this.folderCache.get(element);
|
||||
case ICElement.C_ARCHIVE:
|
||||
case ICElement.C_BINARY:
|
||||
case ICElement.C_BINARY:
|
||||
case ICElement.C_UNIT:
|
||||
return this.fileCache.get(element);
|
||||
default:
|
||||
return this.childrenCache.get(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the info for this element without
|
||||
* disturbing the cache ordering.
|
||||
*/
|
||||
protected Object peekAtInfo(ICElement element) {
|
||||
switch (element.getElementType()) {
|
||||
/**
|
||||
* Returns the info for this element without
|
||||
* disturbing the cache ordering.
|
||||
*/
|
||||
protected Object peekAtInfo(ICElement element) {
|
||||
switch (element.getElementType()) {
|
||||
case ICElement.C_MODEL:
|
||||
case ICElement.C_PROJECT:
|
||||
return this.projectAndRootCache.get(element);
|
||||
case ICElement.C_CCONTAINER:
|
||||
return this.folderCache.get(element);
|
||||
case ICElement.C_ARCHIVE:
|
||||
case ICElement.C_BINARY:
|
||||
case ICElement.C_BINARY:
|
||||
case ICElement.C_UNIT:
|
||||
return this.fileCache.peek((IOpenable) element);
|
||||
default:
|
||||
return this.childrenCache.get(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remember the info for the element.
|
||||
*/
|
||||
protected void putInfo(ICElement element, Object info) {
|
||||
switch (element.getElementType()) {
|
||||
/**
|
||||
* Remember the info for the element.
|
||||
*/
|
||||
protected void putInfo(ICElement element, Object info) {
|
||||
switch (element.getElementType()) {
|
||||
case ICElement.C_MODEL:
|
||||
case ICElement.C_PROJECT:
|
||||
this.projectAndRootCache.put(element, info);
|
||||
|
@ -114,19 +111,20 @@ protected void putInfo(ICElement element, Object info) {
|
|||
this.folderCache.put(element, info);
|
||||
break;
|
||||
case ICElement.C_ARCHIVE:
|
||||
case ICElement.C_BINARY:
|
||||
case ICElement.C_BINARY:
|
||||
case ICElement.C_UNIT:
|
||||
this.fileCache.put((IOpenable)element, info);
|
||||
break;
|
||||
default:
|
||||
this.childrenCache.put(element, info);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Removes the info of the element from the cache.
|
||||
*/
|
||||
protected void removeInfo(ICElement element) {
|
||||
switch (element.getElementType()) {
|
||||
|
||||
/**
|
||||
* Removes the info of the element from the cache.
|
||||
*/
|
||||
protected void removeInfo(ICElement element) {
|
||||
switch (element.getElementType()) {
|
||||
case ICElement.C_MODEL:
|
||||
case ICElement.C_PROJECT:
|
||||
this.projectAndRootCache.remove(element);
|
||||
|
@ -135,13 +133,12 @@ protected void removeInfo(ICElement element) {
|
|||
this.folderCache.remove(element);
|
||||
break;
|
||||
case ICElement.C_ARCHIVE:
|
||||
case ICElement.C_BINARY:
|
||||
case ICElement.C_BINARY:
|
||||
case ICElement.C_UNIT:
|
||||
this.fileCache.remove((IOpenable)element);
|
||||
break;
|
||||
default:
|
||||
this.childrenCache.remove(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,11 +6,10 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -6,18 +6,17 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* John Camelon (IBM Rational Software) - Initial API and implementation
|
||||
* John Camelon (IBM Rational Software) - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
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
|
||||
*/
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast;
|
||||
|
||||
|
@ -20,9 +20,9 @@ package org.eclipse.cdt.core.dom.ast;
|
|||
public interface IASTPreprocessorMacroExpansion extends IASTNode {
|
||||
public static final IASTPreprocessorMacroExpansion[] EMPTY_ARRAY = {};
|
||||
public static final ASTNodeProperty EXPANSION_NAME=
|
||||
new ASTNodeProperty("IASTPreprocessorMacroExpansion.EXPANSION_NAME - macro name"); //$NON-NLS-1$
|
||||
new ASTNodeProperty("IASTPreprocessorMacroExpansion.EXPANSION_NAME - macro name"); //$NON-NLS-1$
|
||||
public static final ASTNodeProperty NESTED_EXPANSION_NAME=
|
||||
new ASTNodeProperty("IASTPreprocessorMacroExpansion.NESTED_EXPANSION_NAME - nested macro name"); //$NON-NLS-1$
|
||||
new ASTNodeProperty("IASTPreprocessorMacroExpansion.NESTED_EXPANSION_NAME - nested macro name"); //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Returns the macro definition used for the expansion.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -19,39 +19,41 @@ package org.eclipse.cdt.core.parser;
|
|||
*/
|
||||
@SuppressWarnings("nls")
|
||||
public class GCCKeywords {
|
||||
public static final String TYPEOF = "typeof";
|
||||
public static final String __ALIGNOF__ = "__alignof__";
|
||||
public static final String __ATTRIBUTE__ = "__attribute__";
|
||||
public static final String __DECLSPEC = "__declspec";
|
||||
public static final String TYPEOF = "typeof";
|
||||
public static final String __ALIGNOF__ = "__alignof__";
|
||||
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";
|
||||
|
||||
public static final char[]
|
||||
public static final char[]
|
||||
cpTYPEOF = TYPEOF.toCharArray(),
|
||||
cp__ALIGNOF__ = __ALIGNOF__.toCharArray(),
|
||||
cp__ATTRIBUTE__ = __ATTRIBUTE__.toCharArray(),
|
||||
cp__DECLSPEC = __DECLSPEC.toCharArray(),
|
||||
cp__ALIGNOF = "__alignof".toCharArray(),
|
||||
cp__ATTRIBUTE = "__attribute".toCharArray(),
|
||||
cp__ASM= "__asm".toCharArray(),
|
||||
cp__ASM__= "__asm__".toCharArray(),
|
||||
cp__CONST= "__const".toCharArray(),
|
||||
cp__CONST__= "__const__".toCharArray(),
|
||||
cp__INLINE= "__inline".toCharArray(),
|
||||
cp__INLINE__= "__inline__".toCharArray(),
|
||||
cp__RESTRICT= "__restrict".toCharArray(),
|
||||
cp__RESTRICT__= "__restrict__".toCharArray(),
|
||||
cp__VOLATILE= "__volatile".toCharArray(),
|
||||
cp__VOLATILE__= "__volatile__".toCharArray(),
|
||||
cp__SIGNED= "__signed".toCharArray(),
|
||||
cp__SIGNED__= "__signed__".toCharArray(),
|
||||
cp__TYPEOF= "__typeof".toCharArray(),
|
||||
cp__ALIGNOF = "__alignof".toCharArray(),
|
||||
cp__ATTRIBUTE = "__attribute".toCharArray(),
|
||||
cp__ASM= "__asm".toCharArray(),
|
||||
cp__ASM__= "__asm__".toCharArray(),
|
||||
cp__CONST= "__const".toCharArray(),
|
||||
cp__CONST__= "__const__".toCharArray(),
|
||||
cp__INLINE= "__inline".toCharArray(),
|
||||
cp__INLINE__= "__inline__".toCharArray(),
|
||||
cp__RESTRICT= "__restrict".toCharArray(),
|
||||
cp__RESTRICT__= "__restrict__".toCharArray(),
|
||||
cp__VOLATILE= "__volatile".toCharArray(),
|
||||
cp__VOLATILE__= "__volatile__".toCharArray(),
|
||||
cp__SIGNED= "__signed".toCharArray(),
|
||||
cp__SIGNED__= "__signed__".toCharArray(),
|
||||
cp__TYPEOF= "__typeof".toCharArray(),
|
||||
cp__TYPEOF__= "__typeof__".toCharArray();
|
||||
|
||||
/** @since 5.3 */
|
||||
public static final char[]
|
||||
public static final char[]
|
||||
cp__has_nothrow_assign= "__has_nothrow_assign".toCharArray(),
|
||||
cp__has_nothrow_copy= "__has_nothrow_copy".toCharArray(),
|
||||
cp__has_nothrow_constructor= "__has_nothrow_constructor".toCharArray(),
|
||||
|
@ -70,7 +72,8 @@ public class GCCKeywords {
|
|||
cp__is_union= "__is_union".toCharArray();
|
||||
|
||||
/** @since 5.5 */
|
||||
public static final char[]
|
||||
public static final char[]
|
||||
cp__DECLTYPE= __DECLTYPE.toCharArray(),
|
||||
cp__float128= __FLOAT128.toCharArray(),
|
||||
cp__int128= __INT128.toCharArray(),
|
||||
cp__is_literal_type= "__is_literal_type".toCharArray(),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2010 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Devin Steffler (IBM Corporation) - initial API and implementation
|
||||
* 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);
|
||||
}
|
||||
|
@ -200,11 +200,11 @@ public class CArrayType implements ICArrayType, ITypeContainer, ISerializableTyp
|
|||
public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
|
||||
int flags= 0;
|
||||
IValue value= null;
|
||||
if ( (firstByte & ITypeMarshalBuffer.FLAG1) != 0) {
|
||||
if ((firstByte & ITypeMarshalBuffer.FLAG1) != 0) {
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* John Camelon (IBM) - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* John Camelon (IBM) - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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.putByte((byte) firstByte);
|
||||
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++) {
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Andrew Niefer (IBM Corporation) - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Andrew Niefer (IBM Corporation) - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
|
@ -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 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;
|
||||
|
@ -79,28 +84,22 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
|
|||
namespaceDefinitions = new IASTName[] { nsDef.getName() };
|
||||
}
|
||||
}
|
||||
|
||||
/* (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;
|
||||
|
||||
public NamespaceCollector(ICPPASTNamespaceDefinition ns ) {
|
||||
private ICPPASTNamespaceDefinition namespaceDef;
|
||||
private IASTName[] namespaces;
|
||||
|
||||
public NamespaceCollector(ICPPASTNamespaceDefinition ns) {
|
||||
shouldVisitNamespaces = true;
|
||||
shouldVisitDeclarations = true;
|
||||
this.namespaceDef = ns;
|
||||
|
@ -127,39 +126,41 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
|
|||
namespaces = ArrayUtil.append(IASTName.class, namespaces, namespace.getName());
|
||||
return PROCESS_SKIP;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int visit(IASTDeclaration declaration) {
|
||||
if (declaration instanceof ICPPASTLinkageSpecification)
|
||||
return PROCESS_CONTINUE;
|
||||
return PROCESS_SKIP;
|
||||
}
|
||||
|
||||
|
||||
public IASTName[] getNamespaces() {
|
||||
return ArrayUtil.trim(IASTName.class, namespaces);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static private class NamespaceMemberCollector extends ASTVisitor {
|
||||
public ObjectSet<IBinding> members = new ObjectSet<IBinding>(8);
|
||||
|
||||
public NamespaceMemberCollector() {
|
||||
shouldVisitNamespaces = true;
|
||||
shouldVisitDeclarators = true;
|
||||
shouldVisitDeclSpecifiers = true;
|
||||
shouldVisitDeclarations = true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int visit(IASTDeclarator declarator) {
|
||||
while(declarator.getNestedDeclarator() != null)
|
||||
declarator = declarator.getNestedDeclarator();
|
||||
|
||||
|
||||
IBinding binding = declarator.getName().resolveBinding();
|
||||
if (binding != null && !(binding instanceof IProblemBinding))
|
||||
members.put(binding);
|
||||
|
||||
|
||||
return PROCESS_SKIP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int visit(IASTDeclSpecifier declSpec) {
|
||||
if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
|
||||
|
@ -172,7 +173,7 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
|
|||
if (parent instanceof IASTSimpleDeclaration) {
|
||||
if (((IASTSimpleDeclaration)parent).getDeclarators().length > 0)
|
||||
return PROCESS_SKIP;
|
||||
|
||||
|
||||
IBinding binding = ((ICPPASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding();
|
||||
if (binding != null && !(binding instanceof IProblemBinding))
|
||||
members.put(binding);
|
||||
|
@ -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);
|
||||
|
@ -210,115 +214,68 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
|
|||
namespaceDefinition.setBinding(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public IASTName[] getNamespaceDefinitions() {
|
||||
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))
|
||||
return;
|
||||
|
||||
|
||||
IASTName name = (IASTName) node;
|
||||
if (namespaceDefinitions == null) {
|
||||
namespaceDefinitions = new IASTName[] { name };
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (namespaceDefinitions.length > 0 && ((ASTNode)name).getOffset() < ((ASTNode)namespaceDefinitions[0]).getOffset()) {
|
||||
namespaceDefinitions = ArrayUtil.prepend(IASTName.class, namespaceDefinitions, name);
|
||||
} else {
|
||||
|
@ -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,11 +324,17 @@ 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
|
||||
public IBinding getOwner() {
|
||||
if (namespaceDefinitions != null && namespaceDefinitions.length > 0) {
|
||||
|
|
|
@ -80,8 +80,8 @@ 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
|
||||
for (ICPPInternalNamespaceScope inline: getIndexInlineNamespaces()) {
|
||||
// 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));
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
consume(IToken.tGT, IToken.tGT_in_SHIFTR);
|
||||
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));
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 instanceof EvalFixed)
|
||||
return ((EvalFixed) eval).getValue();
|
||||
eval = new EvalFixed(getTypeOrFunctionSet(point), PRVALUE, eval.getValue(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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -6,9 +6,8 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* 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.
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* IBM - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
|
@ -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,14 +67,16 @@ 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;
|
||||
IASTFileLocation loc= lm.getMappedFileLocation(fSequenceNumber, sequenceEnd-fSequenceNumber);
|
||||
IASTFileLocation loc= lm.getMappedFileLocation(fSequenceNumber, sequenceEnd - fSequenceNumber);
|
||||
if (loc != null) {
|
||||
return new ASTImageLocation(IASTImageLocation.ARGUMENT_TO_MACRO_EXPANSION,
|
||||
loc.getFileName(), loc.getNodeOffset(), loc.getNodeLength());
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -46,40 +48,41 @@ abstract class LocationCtx implements ILocationCtx {
|
|||
parent.addChild(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getFilePath() {
|
||||
return fParent.getFilePath();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
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;
|
||||
|
@ -109,7 +112,7 @@ abstract class LocationCtx implements ILocationCtx {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the minimal file location containing the specified sequence number range, assuming
|
||||
* Returns the minimal file location containing the specified sequence number range, assuming
|
||||
* that it is contained in this context.
|
||||
*/
|
||||
public ASTFileLocation findMappedFileLocation(int sequenceNumber, int length) {
|
||||
|
@ -124,8 +127,8 @@ abstract class LocationCtx implements ILocationCtx {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the sequence of file locations spanning the given range.
|
||||
* Assumes that the range starts within this context.
|
||||
* Returns the sequence of file locations spanning the given range.
|
||||
* Assumes that the range starts within this context.
|
||||
*/
|
||||
public abstract boolean collectLocations(int sequenceNumber, int length, ArrayList<IASTNodeLocation> sofar);
|
||||
|
||||
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ class LocationCtxMacroExpansion extends LocationCtx {
|
|||
if (length == 0) {
|
||||
return null;
|
||||
}
|
||||
final int end= offset+length;
|
||||
final int end= offset + length;
|
||||
int nextToCheck= offset;
|
||||
ImageLocationInfo firstInfo= null;
|
||||
ImageLocationInfo lastInfo= null;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -45,22 +45,22 @@ public class MacroDefinitionParser {
|
|||
*/
|
||||
static class TokenParameterReference extends TokenWithImage {
|
||||
private final int fIndex;
|
||||
|
||||
|
||||
public TokenParameterReference(int type, int idx, Object source, int offset, int endOffset, char[] name) {
|
||||
super(type, source, offset, endOffset, name);
|
||||
fIndex= idx;
|
||||
}
|
||||
|
||||
|
||||
public int getIndex() {
|
||||
return fIndex;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[" + fIndex + "]"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static char[] getExpansion(AbstractCharArray expansionImage, int offset, int endOffset) {
|
||||
TokenList tl= new TokenList();
|
||||
Lexer lex= new Lexer(expansionImage, offset, endOffset, new LexerOptions(), ILexerLog.NULL, null);
|
||||
|
@ -83,7 +83,7 @@ public class MacroDefinitionParser {
|
|||
buf.append(t.getCharImage());
|
||||
endOffset= t.getEndOffset();
|
||||
}
|
||||
final int length= buf.length();
|
||||
final int length= buf.length();
|
||||
final char[] expansion= new char[length];
|
||||
buf.getChars(0, length, expansion, 0);
|
||||
return expansion;
|
||||
|
@ -93,10 +93,10 @@ public class MacroDefinitionParser {
|
|||
private int fExpansionOffset;
|
||||
private int fExpansionEndOffset;
|
||||
private Token fNameToken;
|
||||
|
||||
|
||||
MacroDefinitionParser() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* In case the name was successfully parsed, the name token is returned.
|
||||
* Otherwise the return value is undefined.
|
||||
|
@ -105,10 +105,10 @@ public class MacroDefinitionParser {
|
|||
return fNameToken;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Parses an entire macro definition. Name must be the next token of the lexer.
|
||||
*/
|
||||
public ObjectStyleMacro parseMacroDefinition(final Lexer lexer, final ILexerLog log)
|
||||
public ObjectStyleMacro parseMacroDefinition(final Lexer lexer, final ILexerLog log)
|
||||
throws OffsetLimitReachedException, InvalidMacroDefinitionException {
|
||||
final Token name = parseName(lexer);
|
||||
final AbstractCharArray source= lexer.getInput();
|
||||
|
@ -122,10 +122,10 @@ public class MacroDefinitionParser {
|
|||
return new FunctionStyleMacro(nameChars, paramList, fHasVarArgs, fExpansionOffset, fExpansionEndOffset, replacement, source);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Parses a macro definition without the replacement. Name must be the next token of the lexer.
|
||||
*/
|
||||
public PreprocessorMacro parseMacroDefinition(final Lexer lexer, final ILexerLog log, final char[] replacement)
|
||||
public PreprocessorMacro parseMacroDefinition(final Lexer lexer, final ILexerLog log, final char[] replacement)
|
||||
throws InvalidMacroDefinitionException, OffsetLimitReachedException {
|
||||
final Token name = parseName(lexer);
|
||||
|
||||
|
@ -135,14 +135,14 @@ public class MacroDefinitionParser {
|
|||
if (replacementToken.getType() != IToken.tEND_OF_INPUT) {
|
||||
throw new InvalidMacroDefinitionException(nameChars, replacementToken.getOffset(), replacementToken.getEndOffset());
|
||||
}
|
||||
|
||||
if (paramList == null) {
|
||||
|
||||
if (paramList == null) {
|
||||
return new ObjectStyleMacro(nameChars, replacement);
|
||||
}
|
||||
return new FunctionStyleMacro(nameChars, paramList, fHasVarArgs, replacement);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Parses a macro definition basically checking for var-args.
|
||||
*/
|
||||
public static PreprocessorMacro parseMacroDefinition(final char[] name, char[][] paramList, final char[] replacement) {
|
||||
|
@ -152,7 +152,7 @@ public class MacroDefinitionParser {
|
|||
if (length > 0) {
|
||||
char[] lastParam= paramList[length-1];
|
||||
final int lpl = lastParam.length;
|
||||
switch(lpl) {
|
||||
switch (lpl) {
|
||||
case 0: case 1: case 2:
|
||||
break;
|
||||
case 3:
|
||||
|
@ -176,8 +176,8 @@ public class MacroDefinitionParser {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (paramList == null) {
|
||||
|
||||
if (paramList == null) {
|
||||
return new ObjectStyleMacro(name, replacement);
|
||||
}
|
||||
return new FunctionStyleMacro(name, paramList, hasVarargs, replacement);
|
||||
|
@ -195,11 +195,11 @@ public class MacroDefinitionParser {
|
|||
fNameToken= name;
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
private char[][] parseParamList(Lexer lex, final Token name) throws OffsetLimitReachedException, InvalidMacroDefinitionException {
|
||||
final Token lparen= lex.nextToken();
|
||||
fHasVarArgs= FunctionStyleMacro.NO_VAARGS;
|
||||
if (lparen.getType() != IToken.tLPAREN || name.getEndOffset() != lparen.getOffset()) {
|
||||
if (lparen.getType() != IToken.tLPAREN || name.getEndOffset() != lparen.getOffset()) {
|
||||
return null;
|
||||
}
|
||||
ArrayList<char[]> paramList= new ArrayList<char[]>();
|
||||
|
@ -224,7 +224,7 @@ public class MacroDefinitionParser {
|
|||
paramList.add(Keywords.cVA_ARGS);
|
||||
next= lex.nextToken();
|
||||
break;
|
||||
|
||||
|
||||
case IToken.tRPAREN:
|
||||
if (next == null) {
|
||||
next= param;
|
||||
|
@ -255,10 +255,10 @@ public class MacroDefinitionParser {
|
|||
Token needAnotherToken= null;
|
||||
|
||||
Token candidate= lexer.currentToken();
|
||||
fExpansionOffset= fExpansionEndOffset= candidate.getOffset();
|
||||
fExpansionOffset= fExpansionEndOffset= candidate.getOffset();
|
||||
|
||||
loop: while(true) {
|
||||
switch(candidate.getType()) {
|
||||
switch (candidate.getType()) {
|
||||
case IToken.tCOMPLETION:
|
||||
throw new OffsetLimitReachedException(ORIGIN_PREPROCESSOR_DIRECTIVE, candidate);
|
||||
case IToken.tEND_OF_INPUT:
|
||||
|
@ -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;
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -35,9 +35,9 @@ public class MacroExpander {
|
|||
private static final class AbortMacroExpansionException extends Exception {}
|
||||
|
||||
private static final int ORIGIN = OffsetLimitReachedException.ORIGIN_MACRO_EXPANSION;
|
||||
private static final TokenList EMPTY_TOKEN_LIST = new TokenList();
|
||||
private static final TokenList EMPTY_TOKEN_LIST = new TokenList();
|
||||
|
||||
/**
|
||||
/**
|
||||
* Marks the beginning and the end of the scope of a macro expansion. Necessary to properly
|
||||
* handle recursive expansions and to figure out whether spaces are required during a stringify
|
||||
* operation across such boundaries.
|
||||
|
@ -56,7 +56,7 @@ public class MacroExpander {
|
|||
public char[] getCharImage() {
|
||||
return CharArrayUtils.EMPTY;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" + (fIsStart ? '+' : '-') + fMacro.getName() + '}'; //$NON-NLS-1$
|
||||
|
@ -70,8 +70,8 @@ public class MacroExpander {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Combines a list of tokens with the preprocessor to form the input for macro expansion.
|
||||
*/
|
||||
private class TokenSource extends TokenList {
|
||||
|
@ -112,7 +112,7 @@ public class MacroExpander {
|
|||
|
||||
if (fLexer != null) {
|
||||
t= fLexer.currentToken();
|
||||
while(t.getType() == Lexer.tNEWLINE) {
|
||||
while (t.getType() == Lexer.tNEWLINE) {
|
||||
t= fLexer.nextToken();
|
||||
}
|
||||
return t.getType() == IToken.tLPAREN;
|
||||
|
@ -131,25 +131,26 @@ public class MacroExpander {
|
|||
private boolean fCompletionMode;
|
||||
private int fStartOffset;
|
||||
private int fEndOffset;
|
||||
|
||||
|
||||
// for using the expander to track expansions
|
||||
private String fFixedCurrentFilename;
|
||||
private int fFixedLineNumber;
|
||||
private char[] fFixedInput;
|
||||
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();
|
||||
fLexOptions= lexOptions;
|
||||
fLog= log;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Expects that the identifier has been consumed, stores the result in the list provided.
|
||||
* @param scannerContext
|
||||
* @param scannerContext
|
||||
*/
|
||||
public TokenList expand(ITokenSequence lexer, final int ppOptions,
|
||||
PreprocessorMacro macro, Token identifier, boolean completionMode,
|
||||
|
@ -161,16 +162,16 @@ public class MacroExpander {
|
|||
} else {
|
||||
fReportMacros= null;
|
||||
}
|
||||
|
||||
|
||||
fImplicitMacroExpansions.clear();
|
||||
fImageLocationInfos.clear();
|
||||
|
||||
|
||||
fStartOffset= identifier.getOffset();
|
||||
fEndOffset= identifier.getEndOffset();
|
||||
fCompletionMode= completionMode;
|
||||
|
||||
|
||||
IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden= new IdentityHashMap<PreprocessorMacro, PreprocessorMacro>();
|
||||
|
||||
|
||||
// setup input sequence
|
||||
TokenSource input= new TokenSource(lexer);
|
||||
TokenList firstExpansion= new TokenList();
|
||||
|
@ -185,8 +186,8 @@ 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
|
||||
// parameter at the current cursor position and hope that they make sense if
|
||||
// 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
|
||||
// parameters and then check where the completion token ends up in the expansion.
|
||||
|
@ -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();
|
||||
|
@ -209,7 +211,7 @@ public class MacroExpander {
|
|||
fFixedLineNumber= lineNumber;
|
||||
fReportMacros= null;
|
||||
Lexer lexer= new Lexer(fFixedInput, fLexOptions, fLog, this);
|
||||
|
||||
|
||||
try {
|
||||
tracker.start(fFixedInput);
|
||||
Token identifier= lexer.nextToken();
|
||||
|
@ -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);
|
||||
|
@ -243,21 +246,21 @@ public class MacroExpander {
|
|||
} catch (OffsetLimitReachedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @throws AbortMacroExpansionException
|
||||
* 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)
|
||||
private Token expandOne(Token lastConsumed, PreprocessorMacro macro,
|
||||
IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden, TokenSource input,
|
||||
TokenList result, MacroExpansionTracker tracker)
|
||||
throws OffsetLimitReachedException {
|
||||
if (fReportMacros != null)
|
||||
fReportMacros.significantMacro(macro);
|
||||
|
||||
|
||||
if (macro.isFunctionStyle()) {
|
||||
final int paramCount = macro.getParameterPlaceholderList().length;
|
||||
final TokenSource[] argInputs= new TokenSource[paramCount];
|
||||
|
@ -268,13 +271,13 @@ 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) {
|
||||
tracker.setExpandedMacroArgument(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tracker != null) {
|
||||
if (tracker.isRequestedStep()) {
|
||||
tracker.storeFunctionStyleMacroReplacement(macro, new TokenList(), result);
|
||||
|
@ -285,13 +288,13 @@ public class MacroExpander {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
TokenList[] clonedArgs= new TokenList[paramCount];
|
||||
TokenList[] expandedArgs= new TokenList[paramCount];
|
||||
for (int i = 0; i < paramCount; i++) {
|
||||
final TokenSource argInput = argInputs[i];
|
||||
final boolean needCopy= paramUsage.get(2*i);
|
||||
final boolean needExpansion = paramUsage.get(2*i+1);
|
||||
final boolean needCopy= paramUsage.get(2 * i);
|
||||
final boolean needExpansion = paramUsage.get(2 * i + 1);
|
||||
clonedArgs[i]= needCopy ? argInput.cloneTokens() : EMPTY_TOKEN_LIST;
|
||||
expandedArgs[i]= needExpansion ? expandAll(argInput, forbidden, false, tracker) : EMPTY_TOKEN_LIST;
|
||||
if (!needExpansion) {
|
||||
|
@ -339,11 +342,11 @@ public class MacroExpander {
|
|||
|
||||
private void executeScopeMarkers(TokenSource input, IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden) {
|
||||
Token t= input.removeFirst();
|
||||
while(t != null) {
|
||||
while (t != null) {
|
||||
if (t.getType() == CPreprocessor.tSCOPE_MARKER) {
|
||||
((ExpansionBoundary) t).execute(forbidden);
|
||||
}
|
||||
t= input.removeFirst();
|
||||
t= input.removeFirst();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -353,8 +356,8 @@ public class MacroExpander {
|
|||
boolean protect= false;
|
||||
Token l= null;
|
||||
Token t= input.removeFirst();
|
||||
while(t != null) {
|
||||
switch(t.getType()) {
|
||||
while (t != null) {
|
||||
switch (t.getType()) {
|
||||
case CPreprocessor.tSCOPE_MARKER:
|
||||
((ExpansionBoundary) t).execute(forbidden);
|
||||
break;
|
||||
|
@ -392,7 +395,7 @@ public class MacroExpander {
|
|||
|
||||
addSpacemarker(l, t, replacement); // start expansion
|
||||
replacement.append(new ExpansionBoundary(macro, true));
|
||||
Token last= expandOne(t, macro, forbidden, input, replacement, tracker);
|
||||
Token last= expandOne(t, macro, forbidden, input, replacement, tracker);
|
||||
replacement.append(new ExpansionBoundary(macro, false));
|
||||
addSpacemarker(last, input.first(), replacement); // end expansion
|
||||
|
||||
|
@ -401,12 +404,12 @@ public class MacroExpander {
|
|||
break;
|
||||
case IToken.tLPAREN:
|
||||
case CPreprocessor.tNOSPACE:
|
||||
case CPreprocessor.tSPACE:
|
||||
case CPreprocessor.tSPACE:
|
||||
result.append(t);
|
||||
break;
|
||||
default:
|
||||
protect= false;
|
||||
result.append(t);
|
||||
result.append(t);
|
||||
break;
|
||||
}
|
||||
l= t;
|
||||
|
@ -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;
|
||||
|
@ -447,24 +458,26 @@ public class MacroExpander {
|
|||
}
|
||||
target.append(new Token(CPreprocessor.tNOSPACE, null, 0, 0));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
final int requiredArgs= hasVarargs ? argCount - 1 : argCount;
|
||||
int idx= 0;
|
||||
int nesting= -1;
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i]= new TokenSource(null);
|
||||
}
|
||||
|
||||
|
||||
boolean missingRParenthesis= false;
|
||||
boolean tooManyArgs= false;
|
||||
|
||||
|
||||
boolean isFirstOfArg= true;
|
||||
Token lastToken= null;
|
||||
TokenList spaceMarkers= new TokenList();
|
||||
|
@ -475,8 +488,8 @@ public class MacroExpander {
|
|||
break loop;
|
||||
}
|
||||
if (tracker != null) {
|
||||
switch(t.getType()) {
|
||||
case IToken.tEND_OF_INPUT:
|
||||
switch (t.getType()) {
|
||||
case IToken.tEND_OF_INPUT:
|
||||
case IToken.tCOMPLETION:
|
||||
case CPreprocessor.tSCOPE_MARKER:
|
||||
case Lexer.tNEWLINE:
|
||||
|
@ -487,7 +500,7 @@ public class MacroExpander {
|
|||
}
|
||||
}
|
||||
lastToken= t;
|
||||
switch(t.getType()) {
|
||||
switch (t.getType()) {
|
||||
case IToken.tEND_OF_INPUT:
|
||||
assert nesting >= 0;
|
||||
if (fCompletionMode) {
|
||||
|
@ -504,28 +517,28 @@ public class MacroExpander {
|
|||
throw new CompletionInMacroExpansionException(ORIGIN, t, result[idx]);
|
||||
}
|
||||
throw new OffsetLimitReachedException(ORIGIN, t);
|
||||
|
||||
|
||||
case Lexer.tNEWLINE:
|
||||
continue loop;
|
||||
|
||||
case IToken.tLPAREN:
|
||||
// the first one sets nesting to zero.
|
||||
// The first one sets nesting to zero.
|
||||
if (++nesting == 0) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case IToken.tRPAREN:
|
||||
assert nesting >= 0;
|
||||
if (--nesting < 0) {
|
||||
break loop;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
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++;
|
||||
|
@ -536,7 +549,7 @@ public class MacroExpander {
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case CPreprocessor.tSCOPE_MARKER:
|
||||
if (argCount == 0) {
|
||||
((ExpansionBoundary) t).execute(forbidden);
|
||||
|
@ -544,14 +557,14 @@ public class MacroExpander {
|
|||
result[idx].append(t);
|
||||
}
|
||||
continue loop;
|
||||
|
||||
|
||||
case CPreprocessor.tSPACE:
|
||||
case CPreprocessor.tNOSPACE:
|
||||
if (!isFirstOfArg) {
|
||||
spaceMarkers.append(t);
|
||||
}
|
||||
continue loop;
|
||||
|
||||
|
||||
default:
|
||||
assert nesting >= 0;
|
||||
}
|
||||
|
@ -564,34 +577,33 @@ public class MacroExpander {
|
|||
isFirstOfArg= false;
|
||||
}
|
||||
|
||||
|
||||
if (missingRParenthesis) {
|
||||
handleProblem(IProblem.PREPROCESSOR_MISSING_RPAREN_PARMLIST, macro.getNameCharArray());
|
||||
throw new AbortMacroExpansionException();
|
||||
}
|
||||
|
||||
|
||||
if (tooManyArgs) {
|
||||
handleProblem(IProblem.PREPROCESSOR_MACRO_USAGE_ERROR, macro.getNameCharArray());
|
||||
} else if (idx+1 < requiredArgs) {
|
||||
} else if (idx + 1 < requiredArgs) {
|
||||
handleProblem(IProblem.PREPROCESSOR_MACRO_USAGE_ERROR, macro.getNameCharArray());
|
||||
}
|
||||
return lastToken;
|
||||
}
|
||||
|
||||
|
||||
private void handleProblem(int problemID, char[] arg) {
|
||||
fLog.handleProblem(problemID, arg, fStartOffset, fEndOffset);
|
||||
}
|
||||
|
||||
private void replaceArgs(PreprocessorMacro macro, TokenList[] args, TokenList[] expandedArgs, TokenList result) {
|
||||
TokenList replacement= clone(macro.getTokens(fDefinitionParser, fLexOptions, this));
|
||||
|
||||
|
||||
Token l= null;
|
||||
Token n;
|
||||
Token pasteArg1= null;
|
||||
for (Token t= replacement.first(); t != null; l=t, t=n) {
|
||||
Token n;
|
||||
Token pasteArg1= null;
|
||||
for (Token t= replacement.first(); t != null; l= t, t= n) {
|
||||
n= (Token) t.getNext();
|
||||
|
||||
switch(t.getType()) {
|
||||
switch (t.getType()) {
|
||||
case CPreprocessor.tMACRO_PARAMETER:
|
||||
int idx= ((TokenParameterReference) t).getIndex();
|
||||
if (idx < args.length) { // be defensive
|
||||
|
@ -610,7 +622,7 @@ public class MacroExpander {
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case IToken.tPOUND:
|
||||
addSpacemarker(l, t, result); // start stringify
|
||||
StringBuilder buf= new StringBuilder();
|
||||
|
@ -624,19 +636,19 @@ public class MacroExpander {
|
|||
n= (Token) n.getNext();
|
||||
}
|
||||
buf.append('"');
|
||||
final int length= buf.length();
|
||||
final int length= buf.length();
|
||||
final char[] image= new char[length];
|
||||
buf.getChars(0, length, image, 0);
|
||||
|
||||
|
||||
Token generated= new TokenWithImage(IToken.tSTRING, null, 0, 0, image);
|
||||
if (isKind(n, IToken.tPOUNDPOUND)) { // start token paste, same as start stringify
|
||||
pasteArg1= generated;
|
||||
pasteArg1= generated;
|
||||
} else {
|
||||
result.append(generated);
|
||||
addSpacemarker(t, n, result); // end stringify
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case IToken.tPOUNDPOUND:
|
||||
Token pasteArg2= null;
|
||||
TokenList rest= null;
|
||||
|
@ -660,7 +672,7 @@ public class MacroExpander {
|
|||
idx= -1;
|
||||
pasteArg2= n;
|
||||
}
|
||||
|
||||
|
||||
t= n;
|
||||
n= (Token) n.getNext();
|
||||
final boolean pasteNext= isKind(n, IToken.tPOUNDPOUND);
|
||||
|
@ -672,7 +684,7 @@ public class MacroExpander {
|
|||
generated= pasteArg1;
|
||||
if (rest == null)
|
||||
rest= new TokenList();
|
||||
|
||||
|
||||
rest.prepend(pasteArg2);
|
||||
spaceDef0= generated;
|
||||
spaceDef1= pasteArg2;
|
||||
|
@ -703,15 +715,15 @@ public class MacroExpander {
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case IToken.tCOMMA:
|
||||
if (isKind(n, IToken.tPOUNDPOUND)) {
|
||||
final Token nn= (Token) n.getNext();
|
||||
if (isKind(nn, CPreprocessor.tMACRO_PARAMETER)) {
|
||||
idx= ((TokenParameterReference) nn).getIndex();
|
||||
|
||||
|
||||
// check for gcc-extension preventing the paste operation
|
||||
if (idx == args.length-1 && macro.hasVarArgs() != FunctionStyleMacro.NO_VAARGS &&
|
||||
if (idx == args.length - 1 && macro.hasVarArgs() != FunctionStyleMacro.NO_VAARGS &&
|
||||
!isKind(nn.getNext(), IToken.tPOUNDPOUND)) {
|
||||
final Token nnn= (Token) nn.getNext();
|
||||
TokenList arg= clone(expandedArgs[idx]);
|
||||
|
@ -729,14 +741,14 @@ public class MacroExpander {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
addSpacemarker(l, t, result);
|
||||
pasteArg1= t;
|
||||
} else {
|
||||
result.append(t);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
if (isKind(n, IToken.tPOUNDPOUND)) {
|
||||
addSpacemarker(l, t, result); // start token paste
|
||||
|
@ -748,64 +760,64 @@ public class MacroExpander {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean isKind(final IToken t, final int kind) {
|
||||
return t!=null && t.getType() == kind;
|
||||
return t != null && t.getType() == kind;
|
||||
}
|
||||
|
||||
private BitSet getParamUsage(PreprocessorMacro macro) {
|
||||
final BitSet result= new BitSet();
|
||||
final TokenList replacement= macro.getTokens(fDefinitionParser, fLexOptions, this);
|
||||
|
||||
|
||||
Token l= null;
|
||||
Token n;
|
||||
for (Token t= replacement.first(); t != null; l=t, t=n) {
|
||||
Token n;
|
||||
for (Token t= replacement.first(); t != null; l= t, t= n) {
|
||||
n= (Token) t.getNext();
|
||||
switch(t.getType()) {
|
||||
switch (t.getType()) {
|
||||
case CPreprocessor.tMACRO_PARAMETER:
|
||||
int idx= 2*((TokenParameterReference) t).getIndex();
|
||||
int idx= 2 * ((TokenParameterReference) t).getIndex();
|
||||
if (!isKind(n, IToken.tPOUNDPOUND)) {
|
||||
idx++;
|
||||
}
|
||||
result.set(idx);
|
||||
break;
|
||||
|
||||
|
||||
case IToken.tPOUND:
|
||||
if (isKind(n, CPreprocessor.tMACRO_PARAMETER)) {
|
||||
idx= ((TokenParameterReference) n).getIndex();
|
||||
result.set(2*idx);
|
||||
result.set(2 * idx);
|
||||
t= n; n= (Token) n.getNext();
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case IToken.tPOUNDPOUND:
|
||||
if (isKind(n, CPreprocessor.tMACRO_PARAMETER)) {
|
||||
idx= ((TokenParameterReference) n).getIndex();
|
||||
// gcc-extension
|
||||
if (isKind(l, IToken.tCOMMA) && macro.hasVarArgs() != FunctionStyleMacro.NO_VAARGS &&
|
||||
idx == macro.getParameterPlaceholderList().length-1 && !isKind(n.getNext(), IToken.tPOUNDPOUND)) {
|
||||
result.set(2*idx+1);
|
||||
idx == macro.getParameterPlaceholderList().length - 1 && !isKind(n.getNext(), IToken.tPOUNDPOUND)) {
|
||||
result.set(2 * idx + 1);
|
||||
} else {
|
||||
result.set(2*idx);
|
||||
result.set(2 * idx);
|
||||
}
|
||||
t= n; n= (Token) n.getNext();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void objStyleTokenPaste(PreprocessorMacro macro, TokenList result) {
|
||||
TokenList replacement= clone(macro.getTokens(fDefinitionParser, fLexOptions, this));
|
||||
|
||||
|
||||
Token l= null;
|
||||
Token n;
|
||||
Token pasteArg1= null;
|
||||
for (Token t= replacement.first(); t != null; l=t, t=n) {
|
||||
Token n;
|
||||
Token pasteArg1= null;
|
||||
for (Token t= replacement.first(); t != null; l= t, t= n) {
|
||||
n= (Token) t.getNext();
|
||||
|
||||
switch(t.getType()) {
|
||||
switch (t.getType()) {
|
||||
case IToken.tPOUNDPOUND:
|
||||
if (pasteArg1 != null) {
|
||||
Token pasteArg2= null;
|
||||
|
@ -813,7 +825,7 @@ public class MacroExpander {
|
|||
pasteArg2= n;
|
||||
n= (Token) n.getNext();
|
||||
}
|
||||
|
||||
|
||||
t= tokenpaste(pasteArg1, pasteArg2, macro);
|
||||
if (t != null) {
|
||||
if (isKind(n, IToken.tPOUNDPOUND)) {
|
||||
|
@ -825,7 +837,7 @@ public class MacroExpander {
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
if (isKind(n, IToken.tPOUNDPOUND)) {
|
||||
addSpacemarker(l, t, result); // start token paste
|
||||
|
@ -857,7 +869,7 @@ public class MacroExpander {
|
|||
final char[] image2= arg2.getCharImage();
|
||||
final int l1 = image1.length;
|
||||
final int l2 = image2.length;
|
||||
final char[] image= new char[l1+l2];
|
||||
final char[] image= new char[l1 + l2];
|
||||
System.arraycopy(image1, 0, image, 0, l1);
|
||||
System.arraycopy(image2, 0, image, l1, l2);
|
||||
Lexer lex= new Lexer(image, fLexOptions, ILexerLog.NULL, null);
|
||||
|
@ -882,13 +894,13 @@ public class MacroExpander {
|
|||
Token l= null;
|
||||
Token n;
|
||||
boolean space= false;
|
||||
for (; t != null; l=t, t=n) {
|
||||
for (; t != null; l= t, t= n) {
|
||||
n= (Token) t.getNext();
|
||||
if (!space && hasImplicitSpace(l, t)) {
|
||||
buf.append(' ');
|
||||
space= true;
|
||||
}
|
||||
switch(t.getType()) {
|
||||
switch (t.getType()) {
|
||||
case IToken.tSTRING:
|
||||
case IToken.tLSTRING:
|
||||
case IToken.tUTF16STRING:
|
||||
|
@ -906,7 +918,7 @@ public class MacroExpander {
|
|||
}
|
||||
space= false;
|
||||
break;
|
||||
|
||||
|
||||
case CPreprocessor.tSPACE:
|
||||
if (!space && l != null && n != null) {
|
||||
buf.append(' ');
|
||||
|
@ -916,7 +928,7 @@ public class MacroExpander {
|
|||
|
||||
case CPreprocessor.tNOSPACE:
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
buf.append(t.getCharImage());
|
||||
space= false;
|
||||
|
@ -924,7 +936,7 @@ public class MacroExpander {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public IASTName[] clearImplicitExpansions() {
|
||||
IASTName[] result= fImplicitMacroExpansions.toArray(new IASTName[fImplicitMacroExpansions.size()]);
|
||||
fImplicitMacroExpansions.clear();
|
||||
|
@ -941,25 +953,17 @@ public class MacroExpander {
|
|||
final boolean createImageLocations= fLexOptions.fCreateImageLocations;
|
||||
int offset= 0;
|
||||
Token l= null;
|
||||
for (Token t= replacement.first(); t!=null; t= (Token) t.getNext()) {
|
||||
switch(t.getType()) {
|
||||
for (Token t= replacement.first(); t != null; t= (Token) t.getNext()) {
|
||||
switch (t.getType()) {
|
||||
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,16 +974,22 @@ public class MacroExpander {
|
|||
continue;
|
||||
|
||||
case IToken.tCOMPLETION:
|
||||
// we need to preserve the length of the completion token.
|
||||
t.setOffset(offset, offset+t.getLength());
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int getCurrentLineNumber() {
|
||||
if (fFixedInput != null) {
|
||||
return fFixedLineNumber + countNewlines(fFixedInput);
|
||||
|
@ -992,7 +1002,7 @@ public class MacroExpander {
|
|||
|
||||
private int countNewlines(char[] input) {
|
||||
int nl= 0;
|
||||
for (int i = 0; i < input.length && i<fEndOffset; i++) {
|
||||
for (int i = 0; i < input.length && i < fEndOffset; i++) {
|
||||
if (input[i] == '\n') {
|
||||
nl++;
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||
|
@ -30,12 +30,12 @@ public class MacroExpansionStep implements IMacroExpansionStep {
|
|||
fMacroDefinition= def;
|
||||
fMacroLocation= macroLoc;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getCodeBeforeStep() {
|
||||
return fBefore;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getCodeAfterStep() {
|
||||
StringBuilder result= new StringBuilder();
|
||||
|
@ -49,7 +49,7 @@ public class MacroExpansionStep implements IMacroExpansionStep {
|
|||
result.append(fBefore, offset, fBefore.length());
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IMacroBinding getExpandedMacro() {
|
||||
return fMacroDefinition;
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -35,7 +35,7 @@ public class MacroExpansionTracker {
|
|||
}
|
||||
|
||||
private final int fStepToTrack;
|
||||
|
||||
|
||||
private int fStepCount;
|
||||
private String fPreStep;
|
||||
private ReplaceEdit fReplacement;
|
||||
|
@ -58,14 +58,14 @@ public class MacroExpansionTracker {
|
|||
public boolean isDone() {
|
||||
return fStepCount > fStepToTrack;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether we are currently looking at the requested step.
|
||||
*/
|
||||
public boolean isRequestedStep() {
|
||||
return fStepCount == fStepToTrack;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the total amount of steps encountered so far.
|
||||
*/
|
||||
|
@ -79,7 +79,7 @@ public class MacroExpansionTracker {
|
|||
public String getCodeBeforeStep() {
|
||||
return fPreStep;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the replacement that represents the change by the step that was tracked.
|
||||
*/
|
||||
|
@ -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();
|
||||
|
@ -133,7 +132,7 @@ public class MacroExpansionTracker {
|
|||
fReplacement= new ReplaceEdit(offset, replace.length(), fReplacementText);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* There was no macro at the beginning of the input.
|
||||
*/
|
||||
|
@ -141,8 +140,9 @@ public class MacroExpansionTracker {
|
|||
fPreStep= new String(fInput);
|
||||
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) {
|
||||
|
@ -150,17 +150,16 @@ public class MacroExpansionTracker {
|
|||
}
|
||||
Token l= null;
|
||||
Token n;
|
||||
for (; t != null; l=t, t=n) {
|
||||
for (; t != null; l= t, t= n) {
|
||||
n= (Token) t.getNext();
|
||||
if (l != null && MacroExpander.hasImplicitSpace(l, t)) {
|
||||
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);
|
||||
buf.append(input, from, to - from);
|
||||
}
|
||||
}
|
||||
if (t == fReplaceFrom) {
|
||||
|
@ -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) {
|
||||
|
@ -178,7 +176,7 @@ public class MacroExpansionTracker {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private char[] getInputForSource(Object source, char[] rootInput) {
|
||||
if (source instanceof MacroExpander) {
|
||||
return rootInput;
|
||||
|
@ -199,7 +197,7 @@ public class MacroExpansionTracker {
|
|||
public void startFunctionStyleMacro(Token identifier) {
|
||||
fMacroStack.add(new MacroInfo(identifier));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* All tokens defining a function-style macro expansion are reported.
|
||||
*/
|
||||
|
@ -237,14 +235,14 @@ public class MacroExpansionTracker {
|
|||
* Append the current function-style macro with the arguments substituted.
|
||||
*/
|
||||
public void appendFunctionStyleMacro(TokenList result) {
|
||||
MacroInfo minfo= fMacroStack.getLast();
|
||||
MacroInfo minfo= fMacroStack.getLast();
|
||||
boolean active= true;
|
||||
int nesting= -1;
|
||||
int pcount= 0;
|
||||
|
||||
Token n;
|
||||
Token l= null;
|
||||
for (Token t = minfo.fMacroCall.first(); t != null; l=t, t=n) {
|
||||
for (Token t = minfo.fMacroCall.first(); t != null; l= t, t= n) {
|
||||
n = (Token) t.getNext();
|
||||
switch (t.getType()) {
|
||||
case IToken.tLPAREN:
|
||||
|
@ -300,7 +298,7 @@ public class MacroExpansionTracker {
|
|||
result.append(t);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
if (active) {
|
||||
result.append(t);
|
||||
|
@ -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);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Sergey Prigogin (Google) - initial API and implementation
|
||||
* Sergey Prigogin (Google) - initial API and implementation
|
||||
*
|
||||
* Based on lookup3.c, by Bob Jenkins {@link "http://burtleburtle.net/bob/c/lookup3.c"}
|
||||
*
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
import org.eclipse.cdt.core.parser.IToken;
|
||||
|
@ -48,7 +48,7 @@ public class Token implements IToken, Cloneable {
|
|||
|
||||
@Override
|
||||
final public int getLength() {
|
||||
return fEndOffset-fOffset;
|
||||
return fEndOffset - fOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -56,7 +56,6 @@ public class Token implements IToken, Cloneable {
|
|||
return fNextToken;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
final public void setType(int kind) {
|
||||
fKind= kind;
|
||||
|
@ -73,8 +72,8 @@ public class Token implements IToken, Cloneable {
|
|||
}
|
||||
|
||||
public void shiftOffset(int shift) {
|
||||
fOffset+= shift;
|
||||
fEndOffset+= shift;
|
||||
fOffset += shift;
|
||||
fEndOffset += shift;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -86,7 +85,7 @@ public class Token implements IToken, Cloneable {
|
|||
public String toString() {
|
||||
return getImage();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
final public boolean isOperator() {
|
||||
return TokenUtil.isOperator(fKind);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
class TokenList {
|
||||
|
@ -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,38 +27,38 @@ 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;
|
||||
}
|
||||
t.setNext(null);
|
||||
}
|
||||
|
||||
|
||||
public final void appendAll(TokenList tl) {
|
||||
final Token t= tl.first();
|
||||
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) {
|
||||
Token t= tl.first();
|
||||
if (t != null) {
|
||||
for (Token n= (Token) t.getNext(); n != null; t=n, n= (Token) n.getNext()) {
|
||||
for (Token n= (Token) t.getNext(); n != null; t= n, n= (Token) n.getNext()) {
|
||||
append(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public final void prepend(Token t) {
|
||||
final Token first= t;
|
||||
if (first != null) {
|
||||
|
@ -81,7 +82,7 @@ class TokenList {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public final TokenList cloneTokens() {
|
||||
TokenList result= new TokenList();
|
||||
for (Token t= fFirst; t != null; t= (Token) t.getNext()) {
|
||||
|
@ -110,8 +111,7 @@ class TokenList {
|
|||
fLast= null;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
final Token r= (Token) l.getNext();
|
||||
if (r != null) {
|
||||
l.setNext(r.getNext());
|
||||
|
@ -124,19 +124,20 @@ 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() {
|
||||
return fFirst==null;
|
||||
return fFirst == null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
import org.eclipse.cdt.core.parser.IGCCToken;
|
||||
|
@ -20,7 +20,7 @@ public class TokenUtil {
|
|||
private static final char[] SPACE = {' '};
|
||||
private static final char[] IMAGE_POUND_POUND = "##".toCharArray(); //$NON-NLS-1$
|
||||
private static final char[] IMAGE_POUND = "#".toCharArray(); //$NON-NLS-1$
|
||||
|
||||
|
||||
private static final char[] DIGRAPH_LBRACE= "<%".toCharArray(); //$NON-NLS-1$
|
||||
private static final char[] DIGRAPH_RBRACE= "%>".toCharArray(); //$NON-NLS-1$
|
||||
private static final char[] DIGRAPH_LBRACKET= "<:".toCharArray(); //$NON-NLS-1$
|
||||
|
@ -40,7 +40,7 @@ public class TokenUtil {
|
|||
case IToken.tSHIFTL: case IToken.tSHIFTLASSIGN:
|
||||
case IToken.tSHIFTR: case IToken.tSHIFTRASSIGN:
|
||||
case IToken.tXOR: case IToken.tXORASSIGN:
|
||||
|
||||
|
||||
// logical operations
|
||||
case IToken.tNOT: case IToken.tAND: case IToken.tOR:
|
||||
|
||||
|
@ -52,25 +52,25 @@ public class TokenUtil {
|
|||
case IToken.tPLUS: case IToken.tPLUSASSIGN:
|
||||
case IToken.tSTAR: case IToken.tSTARASSIGN:
|
||||
case IGCCToken.tMAX: case IGCCToken.tMIN:
|
||||
|
||||
|
||||
// comparison
|
||||
case IToken.tEQUAL: case IToken.tNOTEQUAL:
|
||||
case IToken.tGT: case IToken.tGTEQUAL:
|
||||
case IToken.tLT: case IToken.tLTEQUAL:
|
||||
|
||||
|
||||
// other
|
||||
case IToken.tASSIGN: case IToken.tCOMMA:
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static char[] getImage(int type) {
|
||||
switch (type) {
|
||||
case IToken.tPOUND: return IMAGE_POUND;
|
||||
case IToken.tPOUNDPOUND: return IMAGE_POUND_POUND;
|
||||
case IToken.tCOLONCOLON: return Keywords.cpCOLONCOLON;
|
||||
case IToken.tPOUNDPOUND: return IMAGE_POUND_POUND;
|
||||
case IToken.tCOLONCOLON: return Keywords.cpCOLONCOLON;
|
||||
case IToken.tCOLON: return Keywords.cpCOLON;
|
||||
case IToken.tSEMI: return Keywords.cpSEMI;
|
||||
case IToken.tCOMMA: return Keywords.cpCOMMA;
|
||||
|
@ -120,34 +120,33 @@ public class TokenUtil {
|
|||
case IToken.tDOT: return Keywords.cpDOT;
|
||||
case IToken.tDIVASSIGN: return Keywords.cpDIVASSIGN;
|
||||
case IToken.tDIV: return Keywords.cpDIV;
|
||||
|
||||
|
||||
case IGCCToken.tMIN: return Keywords.cpMIN;
|
||||
case IGCCToken.tMAX: return Keywords.cpMAX;
|
||||
|
||||
case CPreprocessor.tSPACE: return SPACE;
|
||||
|
||||
case CPreprocessor.tSPACE: return SPACE;
|
||||
case CPreprocessor.tNOSPACE: return CharArrayUtils.EMPTY;
|
||||
|
||||
|
||||
default:
|
||||
return CharArrayUtils.EMPTY;
|
||||
return CharArrayUtils.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static char[] getDigraphImage(int type) {
|
||||
switch (type) {
|
||||
case IToken.tPOUND: return DIGRAPH_POUND;
|
||||
case IToken.tPOUNDPOUND: return DIGRAPH_POUNDPOUND;
|
||||
case IToken.tPOUNDPOUND: return DIGRAPH_POUNDPOUND;
|
||||
case IToken.tLBRACKET: return DIGRAPH_LBRACKET;
|
||||
case IToken.tRBRACKET: return DIGRAPH_RBRACKET;
|
||||
case IToken.tLBRACE: return DIGRAPH_LBRACE;
|
||||
case IToken.tRBRACE: return DIGRAPH_RBRACE;
|
||||
|
||||
|
||||
default:
|
||||
assert false: type;
|
||||
return CharArrayUtils.EMPTY;
|
||||
return CharArrayUtils.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the last token in the given token list.
|
||||
* @throws NullPointerException if the argument is null
|
||||
|
@ -156,8 +155,7 @@ public class TokenUtil {
|
|||
IToken last;
|
||||
do {
|
||||
last = tokenList;
|
||||
} while((tokenList = tokenList.getNext()) != null);
|
||||
} while ((tokenList = tokenList.getNext()) != null);
|
||||
return last;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -38,34 +38,34 @@ import com.ibm.icu.text.MessageFormat;
|
|||
*
|
||||
* @author Doug Schaefer
|
||||
*/
|
||||
/*
|
||||
/*
|
||||
* The file encapsulated is divided into Chunks of size CHUNK_SIZE, and a table of contents
|
||||
* mapping chunk index to chunk address is maintained. Chunk structure exists only conceptually -
|
||||
* it is not a structure that appears in the file.
|
||||
*
|
||||
*
|
||||
* ===== The first chunk is used by Database itself for house-keeping purposes and has structure
|
||||
*
|
||||
*
|
||||
* offset content
|
||||
* _____________________________
|
||||
* 0 | version number
|
||||
* INT_SIZE | pointer to head of linked list of blocks of size MIN_BLOCK_DELTAS*BLOCK_SIZE_DELTA
|
||||
* .. | ...
|
||||
* INT_SIZE * m (1) | pointer to head of linked list of blocks of size (m+MIN_BLOCK_DELTAS) * BLOCK_SIZE_DELTA
|
||||
* DATA_AREA | undefined (PDOM stores its own house-keeping data in this area)
|
||||
*
|
||||
* INT_SIZE * m (1) | pointer to head of linked list of blocks of size (m+MIN_BLOCK_DELTAS) * BLOCK_SIZE_DELTA
|
||||
* DATA_AREA | undefined (PDOM stores its own house-keeping data in this area)
|
||||
*
|
||||
* (1) where 2 <= m <= CHUNK_SIZE/BLOCK_SIZE_DELTA - MIN_BLOCK_DELTAS + 1
|
||||
*
|
||||
*
|
||||
* ===== block structure
|
||||
*
|
||||
*
|
||||
* offset content
|
||||
* _____________________________
|
||||
* 0 | size of block (negative indicates in use, positive unused) (2 bytes)
|
||||
* PREV_OFFSET | pointer to prev block (of same size) (only in free blocks)
|
||||
* NEXT_OFFSET | pointer to next block (of same size) (only in free blocks)
|
||||
*
|
||||
*
|
||||
*/
|
||||
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;
|
||||
|
@ -73,27 +73,28 @@ public class Database {
|
|||
public static final int BLOCK_SIZE_DELTA_BITS = 3;
|
||||
public static final int BLOCK_SIZE_DELTA= 1 << BLOCK_SIZE_DELTA_BITS;
|
||||
public static final int MIN_BLOCK_DELTAS = 2; // a block must at least be 2 + 2*4 bytes to link the free blocks.
|
||||
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
|
||||
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;
|
||||
|
||||
|
||||
private static final int BLOCK_PREV_OFFSET = BLOCK_HEADER_SIZE;
|
||||
private static final int BLOCK_NEXT_OFFSET = BLOCK_HEADER_SIZE + INT_SIZE;
|
||||
|
||||
|
||||
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;
|
||||
|
@ -102,15 +103,15 @@ public class Database {
|
|||
private int fChunksUsed;
|
||||
private int fChunksAllocated;
|
||||
private ChunkCache fCache;
|
||||
|
||||
|
||||
private long malloced;
|
||||
private long freed;
|
||||
private long cacheHits;
|
||||
private long cacheMisses;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new Database object, creating a backing file if necessary.
|
||||
* @param location the local file path for the database
|
||||
* @param location the local file path for the database
|
||||
* @param cache the cache to be used optimization
|
||||
* @param version the version number to store in the database (only applicable for new databases)
|
||||
* @param openReadOnly whether this Database object will ever need writing to
|
||||
|
@ -122,10 +123,10 @@ public class Database {
|
|||
fReadOnly= openReadOnly;
|
||||
fCache= cache;
|
||||
openFile();
|
||||
|
||||
|
||||
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];
|
||||
|
@ -140,7 +141,7 @@ public class Database {
|
|||
throw new CoreException(new DBStatus(e));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void openFile() throws FileNotFoundException {
|
||||
fFile = new RandomAccessFile(fLocation, fReadOnly ? "r" : "rw"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
|
@ -154,7 +155,7 @@ public class Database {
|
|||
} catch (ClosedChannelException e) {
|
||||
// Bug 219834 file may have be closed by interrupting a thread during an I/O operation.
|
||||
reopen(e, ++retries);
|
||||
}
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
||||
|
@ -167,7 +168,7 @@ public class Database {
|
|||
} catch (ClosedChannelException e) {
|
||||
// Bug 219834 file may have be closed by interrupting a thread during an I/O operation.
|
||||
reopen(e, ++retries);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,17 +189,17 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int getVersion() {
|
||||
return fVersion;
|
||||
}
|
||||
|
||||
|
||||
public void setVersion(int version) throws CoreException {
|
||||
assert fExclusiveLock;
|
||||
fHeaderChunk.putInt(VERSION_OFFSET, version);
|
||||
|
@ -212,28 +213,28 @@ public class Database {
|
|||
public void clear(int version) throws CoreException {
|
||||
assert fExclusiveLock;
|
||||
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);
|
||||
}
|
||||
malloced = freed = 0;
|
||||
/*
|
||||
* This is for debugging purposes in order to simulate having a very large PDOM database.
|
||||
* This is for debugging purposes in order to simulate having a very large PDOM database.
|
||||
* This will set aside the specified number of chunks.
|
||||
* Nothing uses these chunks so subsequent allocations come after these fillers.
|
||||
* The special function createNewChunks allocates all of these chunks at once.
|
||||
* 524288 for a file starting at 2G
|
||||
* 8388608 for a file starting at 32G
|
||||
*
|
||||
*
|
||||
*/
|
||||
long setasideChunks = Long.getLong("org.eclipse.cdt.core.parser.pdom.dense.recptr.setaside.chunks", 0); //$NON-NLS-1$
|
||||
if (setasideChunks != 0) {
|
||||
|
@ -254,17 +255,17 @@ public class Database {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the Chunk that contains the given offset.
|
||||
* @throws CoreException
|
||||
* @throws CoreException
|
||||
*/
|
||||
public Chunk getChunk(long offset) throws CoreException {
|
||||
if (offset < CHUNK_SIZE) {
|
||||
return fHeaderChunk;
|
||||
}
|
||||
long long_index = offset / CHUNK_SIZE;
|
||||
assert long_index < Integer.MAX_VALUE;
|
||||
assert long_index < Integer.MAX_VALUE;
|
||||
|
||||
synchronized (fCache) {
|
||||
assert fLocked;
|
||||
|
@ -293,17 +294,17 @@ public class Database {
|
|||
|
||||
/**
|
||||
* Allocate a block out of the database.
|
||||
*/
|
||||
*/
|
||||
public long malloc(final int datasize) throws CoreException {
|
||||
assert fExclusiveLock;
|
||||
assert datasize >=0 && datasize <= MAX_MALLOC_SIZE;
|
||||
|
||||
assert datasize >= 0 && datasize <= MAX_MALLOC_SIZE;
|
||||
|
||||
int needDeltas= (datasize + BLOCK_HEADER_SIZE + BLOCK_SIZE_DELTA - 1) / BLOCK_SIZE_DELTA;
|
||||
if (needDeltas < MIN_BLOCK_DELTAS) {
|
||||
needDeltas= MIN_BLOCK_DELTAS;
|
||||
}
|
||||
|
||||
// Which block size
|
||||
// Which block size.
|
||||
long freeblock = 0;
|
||||
int useDeltas;
|
||||
for (useDeltas= needDeltas; useDeltas <= MAX_BLOCK_DELTAS; useDeltas++) {
|
||||
|
@ -311,11 +312,11 @@ public class Database {
|
|||
if (freeblock != 0)
|
||||
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);
|
||||
|
@ -323,25 +324,25 @@ public class Database {
|
|||
chunk = getChunk(freeblock);
|
||||
removeBlock(chunk, useDeltas*BLOCK_SIZE_DELTA, freeblock);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
return freeblock + BLOCK_HEADER_SIZE;
|
||||
}
|
||||
|
||||
|
||||
private long createNewChunk() throws CoreException {
|
||||
assert fExclusiveLock;
|
||||
synchronized (fCache) {
|
||||
|
@ -402,37 +403,37 @@ public class Database {
|
|||
return (long) (oldLen + numChunks - 1) * CHUNK_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private long getFirstBlock(int blocksize) throws CoreException {
|
||||
assert fLocked;
|
||||
return fHeaderChunk.getFreeRecPtr((blocksize/BLOCK_SIZE_DELTA - MIN_BLOCK_DELTAS + 1) * INT_SIZE);
|
||||
}
|
||||
|
||||
|
||||
private void setFirstBlock(int blocksize, long block) throws CoreException {
|
||||
assert fExclusiveLock;
|
||||
fHeaderChunk.putFreeRecPtr((blocksize/BLOCK_SIZE_DELTA - MIN_BLOCK_DELTAS + 1) * INT_SIZE, block);
|
||||
}
|
||||
|
||||
|
||||
private void removeBlock(Chunk chunk, int blocksize, long block) throws CoreException {
|
||||
assert fExclusiveLock;
|
||||
long prevblock = chunk.getFreeRecPtr(block + BLOCK_PREV_OFFSET);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
if (nextblock != 0)
|
||||
putFreeRecPtr(nextblock + BLOCK_PREV_OFFSET, prevblock);
|
||||
}
|
||||
|
||||
|
||||
private void addBlock(Chunk chunk, int blocksize, long block) throws CoreException {
|
||||
assert fExclusiveLock;
|
||||
// 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);
|
||||
|
@ -440,21 +441,22 @@ public class Database {
|
|||
putFreeRecPtr(prevfirst + BLOCK_PREV_OFFSET, block);
|
||||
setFirstBlock(blocksize, block);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Free an allocated block.
|
||||
*
|
||||
*
|
||||
* @param offset
|
||||
*/
|
||||
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;
|
||||
|
@ -463,31 +465,31 @@ public class Database {
|
|||
public void putByte(long offset, byte value) throws CoreException {
|
||||
getChunk(offset).putByte(offset, value);
|
||||
}
|
||||
|
||||
|
||||
public byte getByte(long offset) throws CoreException {
|
||||
return getChunk(offset).getByte(offset);
|
||||
}
|
||||
|
||||
|
||||
public void putInt(long offset, int value) throws CoreException {
|
||||
getChunk(offset).putInt(offset, value);
|
||||
}
|
||||
|
||||
|
||||
public int getInt(long offset) throws CoreException {
|
||||
return getChunk(offset).getInt(offset);
|
||||
}
|
||||
|
||||
|
||||
public void putRecPtr(long offset, long value) throws CoreException {
|
||||
getChunk(offset).putRecPtr(offset, value);
|
||||
}
|
||||
|
||||
|
||||
public long getRecPtr(long offset) throws CoreException {
|
||||
return getChunk(offset).getRecPtr(offset);
|
||||
}
|
||||
|
||||
|
||||
private void putFreeRecPtr(long offset, long value) throws CoreException {
|
||||
getChunk(offset).putFreeRecPtr(offset, value);
|
||||
}
|
||||
|
||||
|
||||
private long getFreeRecPtr(long offset) throws CoreException {
|
||||
return getChunk(offset).getFreeRecPtr(offset);
|
||||
}
|
||||
|
@ -495,15 +497,15 @@ public class Database {
|
|||
public void put3ByteUnsignedInt(long offset, int value) throws CoreException {
|
||||
getChunk(offset).put3ByteUnsignedInt(offset, value);
|
||||
}
|
||||
|
||||
|
||||
public int get3ByteUnsignedInt(long offset) throws CoreException {
|
||||
return getChunk(offset).get3ByteUnsignedInt(offset);
|
||||
}
|
||||
|
||||
|
||||
public void putShort(long offset, short value) throws CoreException {
|
||||
getChunk(offset).putShort(offset, value);
|
||||
}
|
||||
|
||||
|
||||
public short getShort(long offset) throws CoreException {
|
||||
return getChunk(offset).getShort(offset);
|
||||
}
|
||||
|
@ -511,7 +513,7 @@ public class Database {
|
|||
public void putLong(long offset, long value) throws CoreException {
|
||||
getChunk(offset).putLong(offset, value);
|
||||
}
|
||||
|
||||
|
||||
public long getLong(long offset) throws CoreException {
|
||||
return getChunk(offset).getLong(offset);
|
||||
}
|
||||
|
@ -523,7 +525,7 @@ public class Database {
|
|||
public char getChar(long offset) throws CoreException {
|
||||
return getChunk(offset).getChar(offset);
|
||||
}
|
||||
|
||||
|
||||
public void clearBytes(long offset, int byteCount) throws CoreException {
|
||||
getChunk(offset).clear(offset, byteCount);
|
||||
}
|
||||
|
@ -557,14 +559,14 @@ public class Database {
|
|||
} else {
|
||||
bytelen= 2 * len;
|
||||
}
|
||||
|
||||
|
||||
if (bytelen > ShortString.MAX_BYTE_LENGTH) {
|
||||
return new LongString(this, chars, useBytes);
|
||||
} else {
|
||||
return new ShortString(this, chars, useBytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean useBytes(char[] chars) {
|
||||
for (char c : chars) {
|
||||
if ((c & 0xff00) != 0)
|
||||
|
@ -581,7 +583,7 @@ public class Database {
|
|||
}
|
||||
return new ShortString(this, offset);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* For debugging purposes, only.
|
||||
*/
|
||||
|
@ -602,19 +604,19 @@ public class Database {
|
|||
System.out.println("Block size: " + bs + "=" + count); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closes the database.
|
||||
* Closes the database.
|
||||
* <p>
|
||||
* The behavior of any further calls to the Database is undefined
|
||||
* @throws CoreException
|
||||
* @throws CoreException
|
||||
*/
|
||||
public void close() throws CoreException {
|
||||
assert fExclusiveLock;
|
||||
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 };
|
||||
|
@ -625,7 +627,7 @@ public class Database {
|
|||
throw new CoreException(new DBStatus(e));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method is public for testing purposes only.
|
||||
*/
|
||||
|
@ -639,7 +641,7 @@ public class Database {
|
|||
void releaseChunk(final Chunk chunk) {
|
||||
if (!chunk.fLocked) {
|
||||
fChunks[chunk.fSequenceNumber]= null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -662,7 +664,7 @@ public class Database {
|
|||
public void setLocked(boolean val) {
|
||||
fLocked= val;
|
||||
}
|
||||
|
||||
|
||||
public void giveUpExclusiveLock(final boolean flush) throws CoreException {
|
||||
if (fExclusiveLock) {
|
||||
try {
|
||||
|
@ -671,16 +673,16 @@ public class Database {
|
|||
for (int i= 1; i < fChunksUsed; i++) {
|
||||
Chunk chunk= fChunks[i];
|
||||
if (chunk != null) {
|
||||
if (chunk.fCacheIndex < 0) {
|
||||
// locked chunk that has been removed from cache.
|
||||
if (chunk.fCacheIndex < 0) {
|
||||
// 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,19 +691,19 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void flush() throws CoreException {
|
||||
assert fLocked;
|
||||
if (fExclusiveLock) {
|
||||
|
@ -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;
|
||||
|
@ -762,7 +764,7 @@ public class Database {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void markFileIncomplete() throws CoreException {
|
||||
if (!fIsMarkedIncomplete) {
|
||||
fIsMarkedIncomplete= true;
|
||||
|
@ -778,11 +780,11 @@ public class Database {
|
|||
public void resetCacheCounters() {
|
||||
cacheHits= cacheMisses= 0;
|
||||
}
|
||||
|
||||
|
||||
public long getCacheHits() {
|
||||
return cacheHits;
|
||||
}
|
||||
|
||||
|
||||
public long getCacheMisses() {
|
||||
return cacheMisses;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
@ -447,12 +447,14 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
|
|||
if (len > 0) {
|
||||
if (len <= maxInlineSize) {
|
||||
db.putBytes(offset, buf.getBuffer(), len);
|
||||
} else {
|
||||
} 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);
|
||||
chunkLength -= pos;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -167,7 +169,7 @@ public class PDOMCPPClassTemplate extends PDOMCPPClassType
|
|||
|
||||
if (additionalPars > 0 || reorder) {
|
||||
params= null;
|
||||
IPDOMCPPTemplateParameter[] newAllParams= new IPDOMCPPTemplateParameter[allParams.length+additionalPars];
|
||||
IPDOMCPPTemplateParameter[] newAllParams= new IPDOMCPPTemplateParameter[allParams.length + additionalPars];
|
||||
for (int j = 0; j < newParamLength; j++) {
|
||||
int idx= result[j];
|
||||
if (idx >= 0) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -37,10 +37,10 @@ class PDOMCPPVariable extends PDOMCPPBinding implements ICPPVariable {
|
|||
protected static final int ANNOTATIONS = VALUE_OFFSET + Database.VALUE_SIZE; // byte
|
||||
@SuppressWarnings("hiding")
|
||||
protected static final int RECORD_SIZE = ANNOTATIONS + 1;
|
||||
|
||||
|
||||
public PDOMCPPVariable(PDOMLinkage linkage, PDOMNode parent, IVariable variable) throws CoreException {
|
||||
super(linkage, parent, variable.getNameCharArray());
|
||||
|
||||
|
||||
// Find the type record
|
||||
Database db = getDB();
|
||||
setType(parent.getLinkage(), variable.getType());
|
||||
|
@ -73,11 +73,11 @@ class PDOMCPPVariable extends PDOMCPPBinding implements ICPPVariable {
|
|||
protected byte encodeFlags(IVariable variable) {
|
||||
return PDOMCPPAnnotation.encodeAnnotation(variable);
|
||||
}
|
||||
|
||||
|
||||
public PDOMCPPVariable(PDOMLinkage linkage, long record) {
|
||||
super(linkage, record);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int getRecordSize() {
|
||||
return RECORD_SIZE;
|
||||
|
@ -87,11 +87,11 @@ class PDOMCPPVariable extends PDOMCPPBinding implements ICPPVariable {
|
|||
public int getNodeType() {
|
||||
return IIndexCPPBindingConstants.CPPVARIABLE;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isMutable() {
|
||||
// ISO/IEC 14882:2003 7.1.1.8
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -103,7 +103,7 @@ class PDOMCPPVariable extends PDOMCPPBinding implements ICPPVariable {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IValue getInitialValue() {
|
||||
try {
|
||||
|
@ -146,4 +146,4 @@ class PDOMCPPVariable extends PDOMCPPBinding implements ICPPVariable {
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
|
||||
|
||||
|
@ -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 {
|
||||
/**
|
||||
|
@ -30,12 +30,12 @@ public class PDOMTemplateParameterArray {
|
|||
* @return the record by which the arguments can be referenced.
|
||||
*/
|
||||
public static long putArray(final Database db, IPDOMCPPTemplateParameter[] params) throws CoreException {
|
||||
final short len= (short) Math.min(params.length, (Database.MAX_MALLOC_SIZE-2)/8);
|
||||
final long block= db.malloc(2+8*len);
|
||||
final short len= (short) Math.min(params.length, (Database.MAX_MALLOC_SIZE - 2) / 8);
|
||||
final long block= db.malloc(2 + 8 * len);
|
||||
long p= block;
|
||||
|
||||
db.putShort(p, len); p+=2;
|
||||
for (int i=0; i<len; i++, p+=4) {
|
||||
db.putShort(p, len); p += 2;
|
||||
for (int i= 0; i < len; i++, p += 4) {
|
||||
final IPDOMCPPTemplateParameter elem= params[i];
|
||||
db.putRecPtr(p, elem == null ? 0 : elem.getRecord());
|
||||
}
|
||||
|
@ -50,15 +50,15 @@ public class PDOMTemplateParameterArray {
|
|||
final Database db= linkage.getDB();
|
||||
final short len= db.getShort(rec);
|
||||
|
||||
Assert.isTrue(len >= 0 && len <= (Database.MAX_MALLOC_SIZE-2)/8);
|
||||
Assert.isTrue(len >= 0 && len <= (Database.MAX_MALLOC_SIZE - 2) / 8);
|
||||
if (len == 0) {
|
||||
return IPDOMCPPTemplateParameter.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
rec+=2;
|
||||
rec += 2;
|
||||
IPDOMCPPTemplateParameter[] result= new IPDOMCPPTemplateParameter[len];
|
||||
for (int i=0; i<len; i++) {
|
||||
final long nodeRec= db.getRecPtr(rec); rec+=4;
|
||||
for (int i= 0; i < len; i++) {
|
||||
final long nodeRec= db.getRecPtr(rec); rec += 4;
|
||||
result[i]= nodeRec == 0 ? null : (IPDOMCPPTemplateParameter) linkage.getNode(nodeRec);
|
||||
}
|
||||
return result;
|
||||
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
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 {
|
||||
formatList(arguments, options, true, false, scribe.takeTailFormatter());
|
||||
} finally {
|
||||
fInsideMacroArguments = false;
|
||||
}
|
||||
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 {
|
||||
try {
|
||||
int fragment = 0;
|
||||
scribe.alignFragment(listAlignment, fragment);
|
||||
int parenLevel= 0;
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
boolean hasWhitespace= scribe.printComment();
|
||||
int token = peekNextToken();
|
||||
switch (token) {
|
||||
case Token.tLPAREN:
|
||||
++parenLevel;
|
||||
scribe.printNextToken(token, hasWhitespace);
|
||||
break;
|
||||
case Token.tRPAREN:
|
||||
if (parenLevel > 0) {
|
||||
--parenLevel;
|
||||
scribe.printNextToken(token, hasWhitespace);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
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));
|
||||
}
|
||||
int token = peekNextToken();
|
||||
if (token == Token.tSEMI) {
|
||||
scribe.printNextToken(token);
|
||||
scribe.startNewLine();
|
||||
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;
|
||||
break;
|
||||
case Token.tRPAREN:
|
||||
if (parenLevel > 0)
|
||||
--parenLevel;
|
||||
break;
|
||||
}
|
||||
ok = true;
|
||||
} catch (AlignmentException e) {
|
||||
scribe.redoAlignment(e);
|
||||
}
|
||||
} while (!ok);
|
||||
scribe.exitAlignment(listAlignment, true);
|
||||
}
|
||||
|
||||
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 {
|
||||
arguments.add(argument);
|
||||
}
|
||||
}
|
||||
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) {
|
||||
// Constructor chain initializer is a special case.
|
||||
visit((ICPPASTConstructorChainInitializer) node);
|
||||
if (element instanceof IASTNode) {
|
||||
if (element instanceof ICPPASTConstructorChainInitializer) {
|
||||
// Constructor chain initializer is a special case.
|
||||
visit((ICPPASTConstructorChainInitializer) element);
|
||||
} else {
|
||||
((IASTNode) element).accept(this);
|
||||
}
|
||||
} else {
|
||||
node.accept(this);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -148,7 +145,7 @@ public class Scanner extends SimpleScanner {
|
|||
do {
|
||||
getChar();
|
||||
++diff;
|
||||
} while(diff < 0);
|
||||
} while (diff < 0);
|
||||
} else if (diff == 0) {
|
||||
// no-op
|
||||
} else if (diff > fTokenBuffer.length()) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
@ -2892,7 +2918,7 @@ public class CodeFormatterTest extends BaseUITestCase {
|
|||
//void f() {
|
||||
// if (1) {
|
||||
// }
|
||||
// IF(1>0);
|
||||
// IF(1 > 0);
|
||||
//}
|
||||
public void testMacroAfterCompoundStatement_Bug356690() throws Exception {
|
||||
assertFormatterResult();
|
||||
|
|
|
@ -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
|
||||
|
@ -96,8 +96,8 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase {
|
|||
fCFile= null;
|
||||
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,10 +116,12 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase {
|
|||
long endTime= System.currentTimeMillis();
|
||||
assertTrue(results != null);
|
||||
|
||||
if(isTemplate) {
|
||||
results= filterResultsKeepTemplates(results);
|
||||
} else {
|
||||
results= filterResults(results, isCode);
|
||||
if (filterResults) {
|
||||
if (isTemplate) {
|
||||
results= filterResultsKeepTemplates(results);
|
||||
} else {
|
||||
results= filterResults(results, isCode);
|
||||
}
|
||||
}
|
||||
String[] resultStrings= toStringArray(results, compareType);
|
||||
Arrays.sort(expected);
|
||||
|
@ -160,6 +162,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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
|
@ -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>).
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* Copyright (c) 2000, 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Contributors:
|
||||
* 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) {
|
||||
|
|
|
@ -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,18 +80,19 @@ 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
|
||||
|
@ -107,7 +100,7 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
|
|||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
|
|
@ -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()) {
|
||||
|
@ -172,7 +169,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
|
|||
SemanticHighlighting semanticHighlighting= fJobSemanticHighlightings[i];
|
||||
if (fJobHighlightings[i].isEnabled() && semanticHighlighting.consumes(fToken)) {
|
||||
if (node instanceof IASTName) {
|
||||
addNameLocation((IASTName)node, fJobHighlightings[i]);
|
||||
addNameLocation((IASTName) node, fJobHighlightings[i]);
|
||||
} else {
|
||||
addNodeLocation(node.getFileLocation(), fJobHighlightings[i]);
|
||||
}
|
||||
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
/**
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
@ -117,8 +104,9 @@ public class CReconcilingStrategy implements IReconcilingStrategy, IReconcilingS
|
|||
if (canceled) {
|
||||
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$
|
||||
} catch (Exception e) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
fProcessNameToBinaryMap.put(fProcName, finalBinaryPath);
|
||||
// a path that is invalid.
|
||||
if (fProcName != null && !fProcName.isEmpty()) {
|
||||
fProcessNameToBinaryMap.put(fProcName, finalBinaryPath);
|
||||
}
|
||||
fRm.done();
|
||||
};
|
||||
});
|
||||
|
|
|
@ -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$
|
||||
|
||||
/**
|
||||
* 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$
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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,81 +483,162 @@ 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) {
|
||||
return true;
|
||||
}
|
||||
// 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>();
|
||||
|
||||
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) {
|
||||
IExpressionDMContext exprDmc = createExpression(parentDmc, expr);
|
||||
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,63 +735,96 @@ 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 ImmediateDataRequestMonitor<IRegisterDMContext[]>(rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
assert getData() instanceof MIRegisterDMC[];
|
||||
ArrayList<IExpressionDMContext> matches = new ArrayList<IExpressionDMContext>();
|
||||
for (MIRegisterDMC register : (MIRegisterDMC[])getData()) {
|
||||
String potentialMatch = "$"+register.getName(); //$NON-NLS-1$
|
||||
if (globMatches(fullExpr, potentialMatch)) {
|
||||
matches.add(createExpression(exprDmc, potentialMatch));
|
||||
}
|
||||
}
|
||||
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_PREFIX + register.getName();
|
||||
if (globMatches(fullExpr, potentialMatch)) {
|
||||
matches.add(createExpression(globDmc, potentialMatch));
|
||||
}
|
||||
}
|
||||
|
||||
rm.done(matches);
|
||||
}
|
||||
});
|
||||
rm.done(matches);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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,45 +844,239 @@ 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
|
||||
// Convert the glob-pattern into java regex to do the matching
|
||||
|
||||
boolean inBrackets = false;
|
||||
char[] patternArray = globPattern.toCharArray();
|
||||
|
|
|
@ -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) {
|
||||
id += " (" + details + ")"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
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$
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue