From 652d4f7bc0c1c58f15eb5dbe04f33b4c4e59cd68 Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Mon, 8 Jul 2013 01:22:58 -0400 Subject: [PATCH] Bug 412463 - Code completion stops working in the presence of preprocessor-provided macros Change-Id: Ifc5621133ac1ad55276e3d0c1ea8f99d9101938a Signed-off-by: Nathan Ridge Reviewed-on: https://git.eclipse.org/r/14354 Reviewed-by: Sergey Prigogin IP-Clean: Sergey Prigogin Tested-by: Sergey Prigogin --- .../core/parser/scanner/CPreprocessor.java | 13 +++++++++- .../core/parser/scanner/ScannerContext.java | 25 +++++++++++-------- .../text/contentassist2/CompletionTests.java | 20 +++++++++++++++ 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java index 1b1166f3e75..e401083a55f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java @@ -1951,5 +1951,16 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable { return fMacroExpander; } return null; - } + } + + /** + * Return whether 'name' is a macro whose definition is provided by the + * preprocessor, like __LINE__, __FILE__, __DATE__ or __TIME__. + */ + public static boolean isPreprocessorProvidedMacro(char[] name) { + return CharArrayUtils.equals(__LINE__.getNameCharArray(), name) + || CharArrayUtils.equals(__FILE__.getNameCharArray(), name) + || CharArrayUtils.equals(__DATE__.getNameCharArray(), name) + || CharArrayUtils.equals(__TIME__.getNameCharArray(), name); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ScannerContext.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ScannerContext.java index 6a5a8a8431e..4ad40a589d7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ScannerContext.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ScannerContext.java @@ -356,7 +356,7 @@ final class ScannerContext { if (fInternalModifications != null && !fInternalModifications.containsKey(macroName)) { final char[] expansion = macro.getExpansion(); if (expansion != null) - fSignificantMacros.put(macroName, SignificantMacros.shortenValue(expansion)); + addSignificantMacro(macroName, SignificantMacros.shortenValue(expansion)); } } @@ -367,16 +367,16 @@ final class ScannerContext { } private void addSignificantMacroDefined(char[] macroName) { - char[] old= fSignificantMacros.put(macroName, SignificantMacros.DEFINED); + char[] old= addSignificantMacro(macroName, SignificantMacros.DEFINED); if (old != null && old != SignificantMacros.DEFINED) { // Put back more detailed condition - fSignificantMacros.put(macroName, old); + addSignificantMacro(macroName, old); } } public void significantMacroUndefined(char[] macroName) { if (fInternalModifications != null && !fInternalModifications.containsKey(macroName)) { - fSignificantMacros.put(macroName, SignificantMacros.UNDEFINED); + addSignificantMacro(macroName, SignificantMacros.UNDEFINED); } } @@ -396,7 +396,6 @@ final class ScannerContext { // Propagate significant macros to direct parent, if it is interested. if (collector == fParent.fInternalModifications) { - final CharArrayObjectMap significant = fParent.fSignificantMacros; for (int i= 0; i < fSignificantMacros.size(); i++) { final char[] name = fSignificantMacros.keyAt(i); if (!collector.containsKey(name)) { @@ -406,7 +405,7 @@ final class ScannerContext { fParent.addSignificantMacroDefined(name); } } else { - significant.put(name, value); + fParent.addSignificantMacro(name, value); } } } @@ -425,7 +424,7 @@ final class ScannerContext { @Override public boolean visitValue(char[] macro, char[] value) { if (!fInternalModifications.containsKey(macro)) { - fSignificantMacros.put(macro, value); + addSignificantMacro(macro, value); } return true; } @@ -433,7 +432,7 @@ final class ScannerContext { @Override public boolean visitUndefined(char[] macro) { if (!fInternalModifications.containsKey(macro)) { - fSignificantMacros.put(macro, SignificantMacros.UNDEFINED); + addSignificantMacro(macro, SignificantMacros.UNDEFINED); } return true; } @@ -441,13 +440,19 @@ final class ScannerContext { @Override public boolean visitDefined(char[] macro) { if (!fInternalModifications.containsKey(macro)) { - fSignificantMacros.put(macro, SignificantMacros.DEFINED); + addSignificantMacro(macro, SignificantMacros.DEFINED); } return true; } }); } - + + private char[] addSignificantMacro(char[] macro, char[] value) { + if (CPreprocessor.isPreprocessorProvidedMacro(macro)) + return null; + return fSignificantMacros.put(macro, value); + } + public int getLoadedVersionCount() { return fLoadedVersionCount; } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java index 8a53b7cfff6..271d87b219a 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java @@ -1292,4 +1292,24 @@ public class CompletionTests extends AbstractContentAssistTest { final String[] expected = { "Cat", "meow(void)" }; assertContentAssistResults(fCursorOffset, expected, true, COMPARE_ID_STRINGS); } + + // struct Cat { + // void meow(); + // }; + // + // struct Waldo { + // void bar() { + // c./*cursor*/ + // } + // + // Cat c; + // }; + // + // void foo() { + // __LINE__; + // } + public void testLineMacro_Bug412463() throws Exception { + final String[] expected = { "Cat", "meow(void)" }; + assertContentAssistResults(fCursorOffset, expected, true, COMPARE_ID_STRINGS); + } } \ No newline at end of file