mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 362148: Support for __COUNTER__ macro.
This commit is contained in:
parent
09874c7c09
commit
058e14d32c
5 changed files with 88 additions and 11 deletions
|
@ -354,4 +354,13 @@ public class PreprocessorBugsTests extends PreprocessorTestsBase {
|
||||||
validateIdentifier("B");
|
validateIdentifier("B");
|
||||||
validateProblemCount(0);
|
validateProblemCount(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// __COUNTER__
|
||||||
|
// __COUNTER__
|
||||||
|
public void testCounter_Bug362148() throws Exception {
|
||||||
|
initializeScanner();
|
||||||
|
validateInteger("0");
|
||||||
|
validateInteger("1");
|
||||||
|
validateProblemCount(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,6 +99,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
private static final DynamicMacro __DATE__= new DateMacro("__DATE__".toCharArray()); //$NON-NLS-1$
|
private static final DynamicMacro __DATE__= new DateMacro("__DATE__".toCharArray()); //$NON-NLS-1$
|
||||||
private static final DynamicMacro __TIME__ = new TimeMacro("__TIME__".toCharArray()); //$NON-NLS-1$
|
private static final DynamicMacro __TIME__ = new TimeMacro("__TIME__".toCharArray()); //$NON-NLS-1$
|
||||||
private static final DynamicMacro __LINE__ = new LineMacro("__LINE__".toCharArray()); //$NON-NLS-1$
|
private static final DynamicMacro __LINE__ = new LineMacro("__LINE__".toCharArray()); //$NON-NLS-1$
|
||||||
|
private static final char[] __COUNTER__ = "__COUNTER__".toCharArray(); //$NON-NLS-1$
|
||||||
private static final char[] ONCE = "once".toCharArray(); //$NON-NLS-1$
|
private static final char[] ONCE = "once".toCharArray(); //$NON-NLS-1$
|
||||||
|
|
||||||
static final int NO_EXPANSION = 0x01;
|
static final int NO_EXPANSION = 0x01;
|
||||||
|
@ -114,18 +115,22 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
|
|
||||||
|
|
||||||
private final class MacroDictionary implements IMacroDictionary, ISignificantMacros.IVisitor {
|
private final class MacroDictionary implements IMacroDictionary, ISignificantMacros.IVisitor {
|
||||||
|
@Override
|
||||||
public boolean satisfies(ISignificantMacros significantMacros) {
|
public boolean satisfies(ISignificantMacros significantMacros) {
|
||||||
return significantMacros.accept(this);
|
return significantMacros.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean visitDefined(char[] macro) {
|
public boolean visitDefined(char[] macro) {
|
||||||
return isDefined(macro);
|
return isDefined(macro);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean visitUndefined(char[] macro) {
|
public boolean visitUndefined(char[] macro) {
|
||||||
return !isDefined(macro);
|
return !isDefined(macro);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean visitValue(char[] macro, char[] value) {
|
public boolean visitValue(char[] macro, char[] value) {
|
||||||
PreprocessorMacro m = fMacroDictionary.get(macro);
|
PreprocessorMacro m = fMacroDictionary.get(macro);
|
||||||
return m != null && CharArrayUtils.equals(m.getExpansion(), value);
|
return m != null && CharArrayUtils.equals(m.getExpansion(), value);
|
||||||
|
@ -141,7 +146,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
}
|
}
|
||||||
|
|
||||||
final private IIncludeFileTester<InternalFileContent> createCodeReaderTester= new IIncludeFileTester<InternalFileContent>() {
|
final private IIncludeFileTester<InternalFileContent> createCodeReaderTester= new IIncludeFileTester<InternalFileContent>() {
|
||||||
public InternalFileContent checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath) {
|
@Override
|
||||||
|
public InternalFileContent checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath) {
|
||||||
final InternalFileContent fc;
|
final InternalFileContent fc;
|
||||||
IFileNomination once= fFileContentProvider.isIncludedWithPragmaOnceSemantics(path);
|
IFileNomination once= fFileContentProvider.isIncludedWithPragmaOnceSemantics(path);
|
||||||
if (once != null) {
|
if (once != null) {
|
||||||
|
@ -163,7 +169,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
}
|
}
|
||||||
|
|
||||||
final private IIncludeFileTester<IncludeResolution> createPathTester= new IIncludeFileTester<IncludeResolution>() {
|
final private IIncludeFileTester<IncludeResolution> createPathTester= new IIncludeFileTester<IncludeResolution>() {
|
||||||
public IncludeResolution checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath) {
|
@Override
|
||||||
|
public IncludeResolution checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath) {
|
||||||
if (fFileContentProvider.getInclusionExists(path)) {
|
if (fFileContentProvider.getInclusionExists(path)) {
|
||||||
IncludeResolution res= new IncludeResolution();
|
IncludeResolution res= new IncludeResolution();
|
||||||
res.fHeuristic= isHeuristicMatch;
|
res.fHeuristic= isHeuristicMatch;
|
||||||
|
@ -181,6 +188,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
fStopAtNewline= stopAtNewline;
|
fStopAtNewline= stopAtNewline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Token nextToken() throws OffsetLimitReachedException {
|
public Token nextToken() throws OffsetLimitReachedException {
|
||||||
final Lexer lexer= fCurrentContext.getLexer();
|
final Lexer lexer= fCurrentContext.getLexer();
|
||||||
Token t= lexer.nextToken();
|
Token t= lexer.nextToken();
|
||||||
|
@ -194,10 +202,12 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getLastEndOffset() {
|
public int getLastEndOffset() {
|
||||||
return fCurrentContext.getLexer().getLastEndOffset();
|
return fCurrentContext.getLexer().getLastEndOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Token currentToken() {
|
public Token currentToken() {
|
||||||
Token t= fCurrentContext.currentLexerToken();
|
Token t= fCurrentContext.currentLexerToken();
|
||||||
if (fStopAtNewline && t.getType() == Lexer.tNEWLINE)
|
if (fStopAtNewline && t.getType() == Lexer.tNEWLINE)
|
||||||
|
@ -323,14 +333,17 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setSplitShiftROperator(boolean val) {
|
public void setSplitShiftROperator(boolean val) {
|
||||||
fSplitShiftRightOperator= val;
|
fSplitShiftRightOperator= val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setComputeImageLocations(boolean val) {
|
public void setComputeImageLocations(boolean val) {
|
||||||
fLexOptions.fCreateImageLocations= val;
|
fLexOptions.fCreateImageLocations= val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setContentAssistMode(int offset) {
|
public void setContentAssistMode(int offset) {
|
||||||
fContentAssistLimit= offset;
|
fContentAssistLimit= offset;
|
||||||
fRootLexer.setContentAssistMode(offset);
|
fRootLexer.setContentAssistMode(offset);
|
||||||
|
@ -340,13 +353,16 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
return fRootLexer.isContentAssistMode();
|
return fRootLexer.isContentAssistMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setProcessInactiveCode(boolean val) {
|
public void setProcessInactiveCode(boolean val) {
|
||||||
fRootContext.setParseInactiveCode(val);
|
fRootContext.setParseInactiveCode(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setScanComments(boolean val) {
|
public void setScanComments(boolean val) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public ILocationResolver getLocationResolver() {
|
public ILocationResolver getLocationResolver() {
|
||||||
return fLocationMap;
|
return fLocationMap;
|
||||||
}
|
}
|
||||||
|
@ -413,7 +429,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
fMacroDictionary.put(__DATE__.getNameCharArray(), __DATE__);
|
fMacroDictionary.put(__DATE__.getNameCharArray(), __DATE__);
|
||||||
fMacroDictionary.put(__TIME__.getNameCharArray(), __TIME__);
|
fMacroDictionary.put(__TIME__.getNameCharArray(), __TIME__);
|
||||||
fMacroDictionary.put(__LINE__.getNameCharArray(), __LINE__);
|
fMacroDictionary.put(__LINE__.getNameCharArray(), __LINE__);
|
||||||
|
fMacroDictionary.put(__COUNTER__, new CounterMacro(__COUNTER__));
|
||||||
|
|
||||||
if (lang == ParserLanguage.CPP) {
|
if (lang == ParserLanguage.CPP) {
|
||||||
fMacroDictionary.put(__cplusplus.getNameCharArray(), __cplusplus);
|
fMacroDictionary.put(__cplusplus.getNameCharArray(), __cplusplus);
|
||||||
} else {
|
} else {
|
||||||
|
@ -520,7 +537,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, IMacroBinding> getMacroDefinitions() {
|
@Override
|
||||||
|
public Map<String, IMacroBinding> getMacroDefinitions() {
|
||||||
Map<String, IMacroBinding> hashMap = new HashMap<String, IMacroBinding>(fMacroDictionary.size());
|
Map<String, IMacroBinding> hashMap = new HashMap<String, IMacroBinding>(fMacroDictionary.size());
|
||||||
for (char[] key : fMacroDictionary.keys()) {
|
for (char[] key : fMacroDictionary.keys()) {
|
||||||
hashMap.put(String.valueOf(key), fMacroDictionary.get(key));
|
hashMap.put(String.valueOf(key), fMacroDictionary.get(key));
|
||||||
|
@ -528,7 +546,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
return hashMap;
|
return hashMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isOnTopContext() {
|
@Override
|
||||||
|
public boolean isOnTopContext() {
|
||||||
ScannerContext ctx= fCurrentContext;
|
ScannerContext ctx= fCurrentContext;
|
||||||
while (ctx != null && ctx.getLocationCtx() instanceof LocationCtxMacroExpansion) {
|
while (ctx != null && ctx.getLocationCtx() instanceof LocationCtxMacroExpansion) {
|
||||||
ctx= ctx.getParent();
|
ctx= ctx.getParent();
|
||||||
|
@ -536,7 +555,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
return ctx == fRootContext;
|
return ctx == fRootContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cancel() {
|
@Override
|
||||||
|
public void cancel() {
|
||||||
isCancelled= true;
|
isCancelled= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -648,7 +668,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
* @throws EndOfFileException when the end of the translation unit has been reached.
|
* @throws EndOfFileException when the end of the translation unit has been reached.
|
||||||
* @throws OffsetLimitReachedException see {@link Lexer}.
|
* @throws OffsetLimitReachedException see {@link Lexer}.
|
||||||
*/
|
*/
|
||||||
public IToken nextToken() throws EndOfFileException {
|
@Override
|
||||||
|
public IToken nextToken() throws EndOfFileException {
|
||||||
if (isCancelled) {
|
if (isCancelled) {
|
||||||
throw new ParseError(ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
|
throw new ParseError(ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
|
||||||
}
|
}
|
||||||
|
@ -746,7 +767,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
return t1;
|
return t1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void skipInactiveCode() throws OffsetLimitReachedException {
|
@Override
|
||||||
|
public void skipInactiveCode() throws OffsetLimitReachedException {
|
||||||
final Lexer lexer= fCurrentContext.getLexer();
|
final Lexer lexer= fCurrentContext.getLexer();
|
||||||
if (lexer != null) {
|
if (lexer != null) {
|
||||||
CodeState state= fCurrentContext.getCodeState();
|
CodeState state= fCurrentContext.getCodeState();
|
||||||
|
@ -758,6 +780,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getCodeBranchNesting() {
|
public int getCodeBranchNesting() {
|
||||||
return fCurrentContext.getCodeBranchNesting();
|
return fCurrentContext.getCodeBranchNesting();
|
||||||
}
|
}
|
||||||
|
@ -1142,11 +1165,13 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
return fLocationMap;
|
return fLocationMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void handleComment(boolean isBlockComment, int offset, int endOffset) {
|
public void handleComment(boolean isBlockComment, int offset, int endOffset) {
|
||||||
fLocationMap.encounteredComment(offset, endOffset, isBlockComment);
|
fLocationMap.encounteredComment(offset, endOffset, isBlockComment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleProblem(int id, char[] arg, int offset, int endOffset) {
|
@Override
|
||||||
|
public void handleProblem(int id, char[] arg, int offset, int endOffset) {
|
||||||
fLocationMap.encounterProblem(id, arg, offset, endOffset);
|
fLocationMap.encounterProblem(id, arg, offset, endOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1856,6 +1881,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
public Object getAdapter(Class adapter) {
|
public Object getAdapter(Class adapter) {
|
||||||
if (adapter.isAssignableFrom(fMacroExpander.getClass())) {
|
if (adapter.isAssignableFrom(fMacroExpander.getClass())) {
|
||||||
|
|
|
@ -12,8 +12,6 @@ package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
import com.ibm.icu.text.DateFormatSymbols;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ILinkage;
|
import org.eclipse.cdt.core.dom.ILinkage;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||||
|
@ -24,6 +22,8 @@ import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
|
||||||
import org.eclipse.cdt.internal.core.dom.Linkage;
|
import org.eclipse.cdt.internal.core.dom.Linkage;
|
||||||
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
|
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
|
||||||
|
|
||||||
|
import com.ibm.icu.text.DateFormatSymbols;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Models macros used by the preprocessor
|
* Models macros used by the preprocessor
|
||||||
* @since 5.0
|
* @since 5.0
|
||||||
|
@ -35,38 +35,47 @@ abstract class PreprocessorMacro implements IMacroBinding {
|
||||||
fName= name;
|
fName= name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
final public ILinkage getLinkage() {
|
final public ILinkage getLinkage() {
|
||||||
return Linkage.NO_LINKAGE;
|
return Linkage.NO_LINKAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
final public char[] getNameCharArray() {
|
final public char[] getNameCharArray() {
|
||||||
return fName;
|
return fName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
final public String getName() {
|
final public String getName() {
|
||||||
return new String(fName);
|
return new String(fName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public IScope getScope() {
|
public IScope getScope() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public IBinding getOwner() {
|
public IBinding getOwner() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isFunctionStyle() {
|
public boolean isFunctionStyle() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public char[][] getParameterList() {
|
public char[][] getParameterList() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public char[][] getParameterPlaceholderList() {
|
public char[][] getParameterPlaceholderList() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
public Object getAdapter(Class clazz) {
|
public Object getAdapter(Class clazz) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -139,10 +148,12 @@ class ObjectStyleMacro extends PreprocessorMacro {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public char[] getExpansion() {
|
public char[] getExpansion() {
|
||||||
return MacroDefinitionParser.getExpansion(fExpansion, fExpansionOffset, fEndOffset);
|
return MacroDefinitionParser.getExpansion(fExpansion, fExpansionOffset, fEndOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public char[] getExpansionImage() {
|
public char[] getExpansionImage() {
|
||||||
final int length = fEndOffset - fExpansionOffset;
|
final int length = fEndOffset - fExpansionOffset;
|
||||||
char[] result= new char[length];
|
char[] result= new char[length];
|
||||||
|
@ -164,6 +175,7 @@ class ObjectStyleMacro extends PreprocessorMacro {
|
||||||
return fExpansionTokens;
|
return fExpansionTokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public final boolean isDynamic() {
|
public final boolean isDynamic() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -283,14 +295,17 @@ final class UndefinedMacro extends PreprocessorMacro {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public char[] getExpansion() {
|
public char[] getExpansion() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public char[] getExpansionImage() {
|
public char[] getExpansionImage() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isDynamic() {
|
public boolean isDynamic() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -301,6 +316,7 @@ abstract class DynamicMacro extends PreprocessorMacro {
|
||||||
public DynamicMacro(char[] name) {
|
public DynamicMacro(char[] name) {
|
||||||
super(name);
|
super(name);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public final char[] getExpansion() {
|
public final char[] getExpansion() {
|
||||||
return getExpansionImage();
|
return getExpansionImage();
|
||||||
}
|
}
|
||||||
|
@ -319,6 +335,7 @@ abstract class DynamicMacro extends PreprocessorMacro {
|
||||||
buffer.append(value);
|
buffer.append(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public final boolean isDynamic() {
|
public final boolean isDynamic() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -349,6 +366,7 @@ final class DateMacro extends DynamicMacro {
|
||||||
return charArray;
|
return charArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public char[] getExpansionImage() {
|
public char[] getExpansionImage() {
|
||||||
return createDate();
|
return createDate();
|
||||||
}
|
}
|
||||||
|
@ -367,6 +385,7 @@ final class FileMacro extends DynamicMacro {
|
||||||
return new TokenWithImage(IToken.tSTRING, null, 0, 0, buffer.toString().toCharArray());
|
return new TokenWithImage(IToken.tSTRING, null, 0, 0, buffer.toString().toCharArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public char[] getExpansionImage() {
|
public char[] getExpansionImage() {
|
||||||
return "\"file\"".toCharArray(); //$NON-NLS-1$
|
return "\"file\"".toCharArray(); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
@ -383,6 +402,7 @@ final class LineMacro extends DynamicMacro {
|
||||||
return new TokenWithImage(IToken.tINTEGER, null, 0, 0, Long.toString(lineNumber).toCharArray());
|
return new TokenWithImage(IToken.tINTEGER, null, 0, 0, Long.toString(lineNumber).toCharArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public char[] getExpansionImage() {
|
public char[] getExpansionImage() {
|
||||||
return new char[] {'1'};
|
return new char[] {'1'};
|
||||||
}
|
}
|
||||||
|
@ -410,7 +430,27 @@ final class TimeMacro extends DynamicMacro {
|
||||||
return buffer.toString().toCharArray();
|
return buffer.toString().toCharArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public char[] getExpansionImage() {
|
public char[] getExpansionImage() {
|
||||||
return createDate();
|
return createDate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class CounterMacro extends DynamicMacro {
|
||||||
|
private static final char[] ZERO = {'0'};
|
||||||
|
|
||||||
|
private long fValue= 0;
|
||||||
|
CounterMacro(char[] name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Token execute(MacroExpander expander) {
|
||||||
|
return new TokenWithImage(IToken.tINTEGER, null, 0, 0, String.valueOf(fValue++).toCharArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[] getExpansionImage() {
|
||||||
|
return ZERO;
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,6 +31,7 @@ public class CompletionTest_MacroRef_NoPrefix extends CompletionProposalsBaseTe
|
||||||
"DEBUG",
|
"DEBUG",
|
||||||
"XMacro(x, y)",
|
"XMacro(x, y)",
|
||||||
"__CDT_PARSER__",
|
"__CDT_PARSER__",
|
||||||
|
"__COUNTER__",
|
||||||
"__DATE__",
|
"__DATE__",
|
||||||
"__FILE__",
|
"__FILE__",
|
||||||
"__LINE__",
|
"__LINE__",
|
||||||
|
|
|
@ -358,6 +358,7 @@ public class CompletionTests_PlainC extends AbstractContentAssistTest {
|
||||||
"DEBUG",
|
"DEBUG",
|
||||||
"XMacro(x, y)",
|
"XMacro(x, y)",
|
||||||
"__CDT_PARSER__",
|
"__CDT_PARSER__",
|
||||||
|
"__COUNTER__",
|
||||||
"__DATE__",
|
"__DATE__",
|
||||||
"__FILE__",
|
"__FILE__",
|
||||||
"__LINE__",
|
"__LINE__",
|
||||||
|
|
Loading…
Add table
Reference in a new issue