mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Reporting locations of macro-definitions in macro-explorer, bug 23540.
This commit is contained in:
parent
5a4a75db93
commit
008d8cf1d3
5 changed files with 145 additions and 32 deletions
|
@ -294,4 +294,54 @@ public class ExpansionExplorerTests extends BaseTestCase {
|
|||
public void testStringify() throws Exception {
|
||||
performTest(3);
|
||||
}
|
||||
|
||||
// #define vararg(x, y...) bla(x, y)
|
||||
// #define _p p
|
||||
|
||||
// vararg( _p );
|
||||
|
||||
// vararg( p );
|
||||
|
||||
// bla(p, );
|
||||
public void testVararg1() throws Exception {
|
||||
performTest(2);
|
||||
}
|
||||
|
||||
// #define vararg(x, y...) bla(x, ##y)
|
||||
// #define _p p
|
||||
|
||||
// vararg( _p );
|
||||
|
||||
// vararg( p );
|
||||
|
||||
// bla(p);
|
||||
public void testVararg1x() throws Exception {
|
||||
performTest(2);
|
||||
}
|
||||
|
||||
// #define vararg(x, y...) bla(x, y)
|
||||
// #define _p p
|
||||
|
||||
// vararg( _p , _p );
|
||||
|
||||
// vararg( p , _p );
|
||||
|
||||
// vararg( p , p );
|
||||
|
||||
// bla(p, p);
|
||||
public void testVararg2() throws Exception {
|
||||
performTest(3);
|
||||
}
|
||||
|
||||
// #define func2(x,y) (x,y)
|
||||
// #define _p p
|
||||
|
||||
// func2(_p);
|
||||
|
||||
// func2(p);
|
||||
|
||||
// (p,);
|
||||
public void testTooFewArgs() throws Exception {
|
||||
performTest(2);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,12 @@ public abstract class MacroExpansionExplorer {
|
|||
* a step representing a full expansion.
|
||||
*/
|
||||
IMacroBinding getExpandedMacro();
|
||||
|
||||
/**
|
||||
* Returns the location of the macro-definition that gets expanded in this step,
|
||||
* or <code>null</code> for built-in macros or for a step representing a full expansion.
|
||||
*/
|
||||
IASTFileLocation getLocationOfExpandedMacroDefinition();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||
import org.eclipse.cdt.core.dom.rewrite.MacroExpansionExplorer.IMacroExpansionStep;
|
||||
import org.eclipse.text.edits.ReplaceEdit;
|
||||
|
@ -21,11 +22,13 @@ public class MacroExpansionStep implements IMacroExpansionStep {
|
|||
private final String fBefore;
|
||||
private final IMacroBinding fMacroDefinition;
|
||||
private final ReplaceEdit[] fReplacements;
|
||||
private final IASTFileLocation fMacroLocation;
|
||||
|
||||
public MacroExpansionStep(String before, IMacroBinding def, ReplaceEdit[] replacements) {
|
||||
public MacroExpansionStep(String before, IMacroBinding def, IASTFileLocation macroLoc, ReplaceEdit[] replacements) {
|
||||
fBefore= before;
|
||||
fReplacements= replacements;
|
||||
fMacroDefinition= def;
|
||||
fMacroLocation= macroLoc;
|
||||
}
|
||||
|
||||
public String getCodeBeforeStep() {
|
||||
|
@ -51,4 +54,7 @@ public class MacroExpansionStep implements IMacroExpansionStep {
|
|||
public ReplaceEdit[] getReplacements() {
|
||||
return fReplacements;
|
||||
}
|
||||
public IASTFileLocation getLocationOfExpandedMacroDefinition() {
|
||||
return fMacroLocation;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,12 +11,18 @@
|
|||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansion;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||
import org.eclipse.cdt.core.dom.rewrite.MacroExpansionExplorer;
|
||||
import org.eclipse.jface.text.IRegion;
|
||||
import org.eclipse.text.edits.ReplaceEdit;
|
||||
|
@ -49,17 +55,55 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer {
|
|||
private final char[] fSource;
|
||||
private final int[] fBoundaries;
|
||||
private final SingleMacroExpansionExplorer[] fDelegates;
|
||||
private String fFilePath;
|
||||
private final String fFilePath;
|
||||
private final Map<IMacroBinding, IASTFileLocation> fMacroLocations;
|
||||
|
||||
public MultiMacroExpansionExplorer(IASTTranslationUnit tu, IASTFileLocation loc) {
|
||||
if (tu == null || loc == null || loc.getNodeLength() == 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
final ILocationResolver resolver = getResolver(tu);
|
||||
final IASTMacroExpansion[] expansions= resolver.getMacroExpansions(loc);
|
||||
final int count= expansions.length;
|
||||
|
||||
loc = extendLocation(loc, expansions);
|
||||
fMacroLocations= getMacroLocations(resolver);
|
||||
fFilePath= tu.getFilePath();
|
||||
fSource= resolver.getUnpreprocessedSignature(loc);
|
||||
fBoundaries= new int[count*2+1];
|
||||
fDelegates= new SingleMacroExpansionExplorer[count];
|
||||
|
||||
final int firstOffset= loc.getNodeOffset();
|
||||
int bidx= -1;
|
||||
int didx= -1;
|
||||
for (IASTMacroExpansion expansion : expansions) {
|
||||
IASTName ref= expansion.getMacroReference();
|
||||
if (ref != null) {
|
||||
ArrayList<IASTName> refs= new ArrayList<IASTName>();
|
||||
refs.add(ref);
|
||||
refs.addAll(Arrays.asList(resolver.getImplicitMacroReferences(ref)));
|
||||
IASTFileLocation refLoc= expansion.asFileLocation();
|
||||
int from= refLoc.getNodeOffset()-firstOffset;
|
||||
int to= from+refLoc.getNodeLength();
|
||||
fBoundaries[++bidx]= from;
|
||||
fBoundaries[++bidx]= to;
|
||||
fDelegates[++didx]= new SingleMacroExpansionExplorer(new String(fSource, from, to-from),
|
||||
refs.toArray(new IASTName[refs.size()]), fMacroLocations,
|
||||
fFilePath, refLoc.getStartingLineNumber());
|
||||
}
|
||||
}
|
||||
fBoundaries[++bidx]= fSource.length;
|
||||
}
|
||||
|
||||
private ILocationResolver getResolver(IASTTranslationUnit tu) {
|
||||
final ILocationResolver resolver = (ILocationResolver) tu.getAdapter(ILocationResolver.class);
|
||||
if (resolver == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
final IASTMacroExpansion[] expansions = resolver.getMacroExpansions(loc);
|
||||
return resolver;
|
||||
}
|
||||
|
||||
private IASTFileLocation extendLocation(IASTFileLocation loc, final IASTMacroExpansion[] expansions) {
|
||||
final int count= expansions.length;
|
||||
if (count > 0) {
|
||||
int from= loc.getNodeOffset();
|
||||
|
@ -75,28 +119,28 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer {
|
|||
loc= new ASTFileLocation(loc.getFileName(), from, to-from);
|
||||
}
|
||||
}
|
||||
|
||||
fFilePath= tu.getFilePath();
|
||||
fSource= resolver.getUnpreprocessedSignature(loc);
|
||||
fBoundaries= new int[count*2+1];
|
||||
fDelegates= new SingleMacroExpansionExplorer[count];
|
||||
return loc;
|
||||
}
|
||||
|
||||
final int firstOffset= loc.getNodeOffset();
|
||||
int bidx= -1;
|
||||
int didx= -1;
|
||||
for (IASTMacroExpansion expansion : expansions) {
|
||||
IASTName ref= expansion.getMacroReference();
|
||||
if (ref != null) {
|
||||
IASTFileLocation refLoc= expansion.asFileLocation();
|
||||
int from= refLoc.getNodeOffset()-firstOffset;
|
||||
int to= from+refLoc.getNodeLength();
|
||||
fBoundaries[++bidx]= from;
|
||||
fBoundaries[++bidx]= to;
|
||||
fDelegates[++didx]= new SingleMacroExpansionExplorer(new String(fSource, from, to-from), ref,
|
||||
resolver.getImplicitMacroReferences(ref), fFilePath, refLoc.getStartingLineNumber());
|
||||
private Map<IMacroBinding, IASTFileLocation> getMacroLocations(final ILocationResolver resolver) {
|
||||
final Map<IMacroBinding, IASTFileLocation> result= new HashMap<IMacroBinding, IASTFileLocation>();
|
||||
addLocations(resolver.getBuiltinMacroDefinitions(), result);
|
||||
addLocations(resolver.getMacroDefinitions(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void addLocations(IASTPreprocessorMacroDefinition[] defs,
|
||||
final Map<IMacroBinding, IASTFileLocation> result) {
|
||||
for (IASTPreprocessorMacroDefinition def : defs) {
|
||||
IASTFileLocation loc= def.getFileLocation();
|
||||
if (loc != null) {
|
||||
final IBinding binding= def.getName().getBinding();
|
||||
if (binding instanceof IMacroBinding) {
|
||||
loc= new ASTFileLocation(loc.getFileName(), loc.getNodeOffset(), loc.getNodeLength());
|
||||
result.put((IMacroBinding) binding, loc);
|
||||
}
|
||||
}
|
||||
}
|
||||
fBoundaries[++bidx]= fSource.length;
|
||||
}
|
||||
|
||||
public MultiMacroExpansionExplorer(final IASTTranslationUnit tu, final IRegion loc) {
|
||||
|
@ -106,7 +150,7 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer {
|
|||
@Override
|
||||
public IMacroExpansionStep getFullExpansion() {
|
||||
List<ReplaceEdit> edits = combineReplaceEdits(fDelegates.length);
|
||||
return new MacroExpansionStep(new String(fSource), null, edits.toArray(new ReplaceEdit[edits.size()]));
|
||||
return new MacroExpansionStep(new String(fSource), null, null, edits.toArray(new ReplaceEdit[edits.size()]));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -174,7 +218,7 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer {
|
|||
|
||||
List<ReplaceEdit> replacements= new ArrayList<ReplaceEdit>();
|
||||
shiftAndAddEdits(shift, dresult.getReplacements(), replacements);
|
||||
return new MacroExpansionStep(before.toString(), dresult.getExpandedMacro(), replacements.toArray(new ReplaceEdit[replacements.size()]));
|
||||
return new MacroExpansionStep(before.toString(), dresult.getExpandedMacro(), dresult.getLocationOfExpandedMacroDefinition(), replacements.toArray(new ReplaceEdit[replacements.size()]));
|
||||
}
|
||||
|
||||
private void appendGap(StringBuilder result, int i) {
|
||||
|
|
|
@ -10,8 +10,12 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||
import org.eclipse.cdt.core.dom.rewrite.MacroExpansionExplorer;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayMap;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
|
||||
|
@ -34,18 +38,20 @@ public class SingleMacroExpansionExplorer extends MacroExpansionExplorer {
|
|||
private int fExpansionCount;
|
||||
private String fFilePath;
|
||||
private int fLineNumber;
|
||||
private final Map<IMacroBinding, IASTFileLocation> fMacroLocationMap;
|
||||
|
||||
public SingleMacroExpansionExplorer(String input, IASTName ref, IASTName[] implicitRefs, String filePath, int lineNumber) {
|
||||
public SingleMacroExpansionExplorer(String input, IASTName[] refs,
|
||||
Map<IMacroBinding, IASTFileLocation> macroDefinitionLocationMap, String filePath, int lineNumber) {
|
||||
fInput= input;
|
||||
fDictionary= createDictionary(ref, implicitRefs);
|
||||
fDictionary= createDictionary(refs);
|
||||
fMacroLocationMap= macroDefinitionLocationMap;
|
||||
fFilePath= filePath;
|
||||
fLineNumber= lineNumber;
|
||||
}
|
||||
|
||||
private CharArrayMap<PreprocessorMacro> createDictionary(IASTName ref, IASTName[] implicitRefs) {
|
||||
CharArrayMap<PreprocessorMacro> map= new CharArrayMap<PreprocessorMacro>(implicitRefs.length+1);
|
||||
addMacroDefinition(map, ref);
|
||||
for (IASTName name : implicitRefs) {
|
||||
private CharArrayMap<PreprocessorMacro> createDictionary(IASTName[] refs) {
|
||||
CharArrayMap<PreprocessorMacro> map= new CharArrayMap<PreprocessorMacro>(refs.length);
|
||||
for (IASTName name : refs) {
|
||||
addMacroDefinition(map, name);
|
||||
}
|
||||
return map;
|
||||
|
@ -78,7 +84,7 @@ public class SingleMacroExpansionExplorer extends MacroExpansionExplorer {
|
|||
fExpansionCount= tracker.getStepCount();
|
||||
ReplaceEdit r= tracker.getReplacement();
|
||||
ReplaceEdit[] replacements= r==null ? new ReplaceEdit[0] : new ReplaceEdit[]{r};
|
||||
fFullExpansion= new MacroExpansionStep(fInput, null, replacements);
|
||||
fFullExpansion= new MacroExpansionStep(fInput, null, null, replacements);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -94,6 +100,7 @@ public class SingleMacroExpansionExplorer extends MacroExpansionExplorer {
|
|||
fExpansionCount= tracker.getStepCount();
|
||||
ReplaceEdit r= tracker.getReplacement();
|
||||
ReplaceEdit[] replacements= r==null ? new ReplaceEdit[0] : new ReplaceEdit[]{r};
|
||||
return new MacroExpansionStep(tracker.getCodeBeforeStep(), tracker.getExpandedMacro(), replacements);
|
||||
final IMacroBinding macro = tracker.getExpandedMacro();
|
||||
return new MacroExpansionStep(tracker.getCodeBeforeStep(), macro, fMacroLocationMap.get(macro), replacements);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue