summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Ridge2013-07-09 01:27:28 (EDT)
committerSergey Prigogin2013-07-09 21:58:36 (EDT)
commit8f78f34f192c998c81eb72b8f49e79d24f7f2a95 (patch)
tree5fa2536fcba6a98e122de7b133b320438c4f92e7
parent6df967d0d40701ba0c09ad943286f332fec4ae87 (diff)
downloadorg.eclipse.cdt-8f78f34f192c998c81eb72b8f49e79d24f7f2a95.zip
org.eclipse.cdt-8f78f34f192c998c81eb72b8f49e79d24f7f2a95.tar.gz
org.eclipse.cdt-8f78f34f192c998c81eb72b8f49e79d24f7f2a95.tar.bz2
Bug 412463 - Code completion stops working in the presence of predefinedrefs/changes/99/14399/3
macro Change-Id: Iabeb0742ce5564a150f859185c0f8eb64805955a Signed-off-by: Nathan Ridge <zeratul976@hotmail.com> Reviewed-on: https://git.eclipse.org/r/14399 Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com> IP-Clean: Sergey Prigogin <eclipse.sprigogin@gmail.com> Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
-rw-r--r--core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java10
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java11
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java78
-rw-r--r--core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java21
4 files changed, 87 insertions, 33 deletions
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java
index 7325f61..d0a2a33 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java
@@ -915,7 +915,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
for (IIndexFile indexFile : index.getFiles(linkageID, ifl)) {
int score= indexFile.getMacros().length * 2;
IIndexFile context= getParsedInContext(indexFile);
- if (isSourceFile(context))
+ if (isSourceFile(context, getCProject().getProject()))
score++;
if (score > bestScore) {
bestScore= score;
@@ -936,7 +936,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
return null;
}
- private IIndexFile getParsedInContext(IIndexFile indexFile) throws CoreException {
+ public static IIndexFile getParsedInContext(IIndexFile indexFile) throws CoreException {
HashSet<IIndexFile> visited= new HashSet<IIndexFile>();
// Bug 199412, may recurse.
while (visited.add(indexFile)) {
@@ -949,12 +949,12 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
}
/**
- * Returns <code>true</code> if the given file was parsed in a context of a source file.
+ * Returns <code>true</code> if the given file is a source file.
* @throws CoreException
*/
- private boolean isSourceFile(IIndexFile indexFile) throws CoreException {
+ public static boolean isSourceFile(IIndexFile indexFile, IProject project) throws CoreException {
String path = indexFile.getLocation().getURI().getPath();
- IContentType cType = CCorePlugin.getContentType(getCProject().getProject(), path);
+ IContentType cType = CCorePlugin.getContentType(project, path);
if (cType == null)
return false;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java
index 7a2bc0c..9bc0b4b 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java
@@ -97,7 +97,7 @@ public interface IIndexFragment {
* <p>
* When a header file is stored in the index in multiple variants for different sets of macro
* definitions, this method will return an arbitrary one of these variants.
- *
+ *
* @param linkageID the id of the linkage in which the file has been parsed.
* @param location the IIndexFileLocation representing the location of the file
* @return the file for the location, or <code>null</code> if the file is not present in
@@ -114,7 +114,7 @@ public interface IIndexFragment {
* May return <code>null</code>, if no such file exists.
* This method may only return files that are actually managed by this fragment.
* This method returns files without content, also.
- *
+ *
* @param linkageID the id of the linkage in which the file has been parsed.
* @param location the IIndexFileLocation representing the location of the file
* @param macroDictionary The names and definitions of the macros used to disambiguate between
@@ -132,10 +132,7 @@ public interface IIndexFragment {
* for different sets of macro definitions.
* This method may only return files that are actually managed by this fragment.
* This method returns files without content, also.
- * <p>
- * When a header file is stored in the index in multiple variants for different sets of macro
- * definitions, this method will return an arbitrary one of these variants.
- *
+ *
* @param linkageID the id of the linkage in which the file has been parsed.
* @param location the IIndexFileLocation representing the location of the file
* @return the files for the location and the linkage.
@@ -224,7 +221,7 @@ public interface IIndexFragment {
* Searches for all names that resolve to the given binding. You can limit the result to
* references, declarations or definitions, or a combination of those.
* @param binding a binding for which names are searched for
- * @param flags a combination of {@link #FIND_DECLARATIONS}, {@link #FIND_DEFINITIONS},
+ * @param flags a combination of {@link #FIND_DECLARATIONS}, {@link #FIND_DEFINITIONS},
* {@link #FIND_REFERENCES} and {@link #FIND_NON_LOCAL_ONLY}
* @return an array of names
* @throws CoreException
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java
index 89b1b26..6e75095 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java
@@ -9,7 +9,7 @@
* Markus Schorn - initial API and implementation
* Andrew Ferguson (Symbian)
* Sergey Prigogin (Google)
- *******************************************************************************/
+ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom;
import java.io.File;
@@ -23,14 +23,17 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.index.IIndexLocationConverter;
+import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.ISignificantMacros;
import org.eclipse.cdt.internal.core.index.FileContentKey;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
+import org.eclipse.cdt.internal.core.model.TranslationUnit;
import org.eclipse.cdt.internal.core.pdom.db.ChunkCache;
import org.eclipse.cdt.internal.core.pdom.db.DBProperties;
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
@@ -43,7 +46,7 @@ import org.eclipse.cdt.internal.core.pdom.dom.PDOMMacroReferenceName;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
import org.eclipse.core.runtime.CoreException;
-public class WritablePDOM extends PDOM implements IWritableIndexFragment {
+public class WritablePDOM extends PDOM implements IWritableIndexFragment {
private boolean fClearedBecauseOfVersionMismatch= false;
private boolean fCreatedFromScratch= false;
private ASTFilePathResolver fPathResolver;
@@ -55,12 +58,12 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
Map<String, IPDOMLinkageFactory> linkageFactoryMappings) throws CoreException {
this(dbPath, locationConverter, ChunkCache.getSharedInstance(), linkageFactoryMappings);
}
-
+
public WritablePDOM(File dbPath, IIndexLocationConverter locationConverter, ChunkCache cache,
Map<String, IPDOMLinkageFactory> linkageFactoryMappings) throws CoreException {
super(dbPath, locationConverter, cache, linkageFactoryMappings);
}
-
+
public void setASTFilePathResolver(ASTFilePathResolver resolver) {
fPathResolver= resolver;
}
@@ -69,7 +72,7 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
public IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location, ISignificantMacros sigMacros) throws CoreException {
if (uncommittedKey != null && uncommittedKey.equals(new FileContentKey(linkageID, location, sigMacros)))
return uncommittedFile;
-
+
return super.addFile(linkageID, location, sigMacros);
}
@@ -138,11 +141,11 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
}
@Override
- public void addFileContent(IIndexFragmentFile sourceFile, IncludeInformation[] includes,
+ public void addFileContent(IIndexFragmentFile sourceFile, IncludeInformation[] includes,
IASTPreprocessorStatement[] macros, IASTName[][] names, ASTFilePathResolver pathResolver,
YieldableIndexLock lock) throws CoreException, InterruptedException {
assert sourceFile.getIndexFragment() == this;
-
+
PDOMFile pdomFile = (PDOMFile) sourceFile;
pdomFile.addMacros(macros);
final ASTFilePathResolver origResolver= fPathResolver;
@@ -154,7 +157,7 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
}
// Includes expose the temporary file in the index, we must not yield the lock beyond this point.
pdomFile.addIncludesTo(includes);
-
+
final IIndexFileLocation location = pdomFile.getLocation();
if (location != null) {
fEvent.fClearedFiles.remove(location);
@@ -167,37 +170,37 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
assert file.getIndexFragment() == this;
IIndexFileLocation location = file.getLocation();
PDOMFile pdomFile = (PDOMFile) file;
- pdomFile.clear();
+ pdomFile.clear();
fEvent.fClearedFiles.add(location);
}
-
+
@Override
public void clear() throws CoreException {
super.clear();
}
-
+
@Override
public void flush() throws CoreException {
super.flush();
}
-
+
@Override
public void setProperty(String propertyName, String value) throws CoreException {
- if (IIndexFragment.PROPERTY_FRAGMENT_FORMAT_ID.equals(propertyName)
+ if (IIndexFragment.PROPERTY_FRAGMENT_FORMAT_ID.equals(propertyName)
|| IIndexFragment.PROPERTY_FRAGMENT_FORMAT_VERSION.equals(propertyName)) {
throw new IllegalArgumentException("Property " + value + " may not be written to"); //$NON-NLS-1$ //$NON-NLS-2$
}
new DBProperties(db, PROPERTIES).setProperty(propertyName, value);
}
-
+
/**
* Uses the specified location converter to update each internal representation of a file
* location. The file index is rebuilt with the new representations. Individual PDOMFile records
* are unmoved so as to maintain referential integrity with other PDOM records.
- *
+ *
* <b>A write-lock must be obtained before calling this method</b>
- *
+ *
* @param newConverter the converter to use to update internal file representations
* @throws CoreException
*/
@@ -250,12 +253,47 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
void setCreatedFromScratch(boolean createdFromScratch) {
fCreatedFromScratch = createdFromScratch;
}
-
+
@Override
protected final boolean isPermanentlyReadOnly() {
return false;
}
+ /**
+ * Returns the best file for the given location, linkage, and translation unit.
+ * May return <code>null</code>, if no such file exists.
+ *
+ * The "best" file (variant) is the one with the most content, as measured
+ * by the total number of macros defined in the file. The rationale is that
+ * often one of the variants will contain most of the code and the others
+ * just small pieces, and we are usually interested in the one with most of
+ * the code. As a tiebreaker, a variant that was parsed in the context of a
+ * source file is preferred, since a header parsed outside of the context of
+ * a code file may not represent code that a compiler actually sees.
+ *
+ * @param linkageID the id of the linkage in which the file has been parsed.
+ * @param location the IIndexFileLocation representing the location of the file
+ * @param tu the translation unit from which 'location' originates
+ * @return the best file for the location, or <code>null</code> if the file is not
+ * present in the index
+ * @throws CoreException
+ */
+ private PDOMFile getBestFile(int linkageID, IIndexFileLocation location, ITranslationUnit tu) throws CoreException {
+ IIndexFile[] files = getFiles(linkageID, location);
+ IIndexFile best = null;
+ int bestScore = -1;
+ for (IIndexFile file : files) {
+ int score = file.getMacros().length * 2;
+ if (TranslationUnit.isSourceFile(TranslationUnit.getParsedInContext(file), tu.getCProject().getProject()))
+ score++;
+ if (score > bestScore) {
+ bestScore = score;
+ best = file;
+ }
+ }
+ return (PDOMFile) best;
+ }
+
public PDOMFile getFileForASTNode(int linkageID, IASTNode node) throws CoreException {
if (fPathResolver != null && node != null) {
IASTFileLocation loc= node.getFileLocation();
@@ -265,7 +303,7 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
IIndexFileLocation location = fPathResolver.resolveASTPath(loc.getFileName());
if (uncommittedKey != null && uncommittedKey.equals(new FileContentKey(linkageID, location, sigMacros)))
return fileBeingUpdated != null ? fileBeingUpdated : uncommittedFile;
- return getFile(linkageID, location, sigMacros);
+ return getBestFile(linkageID, location, node.getTranslationUnit().getOriginatingTranslationUnit());
}
}
}
@@ -274,13 +312,13 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
private ISignificantMacros getSignificantMacros(IASTNode node, IASTFileLocation loc) throws CoreException {
IASTPreprocessorIncludeStatement owner= loc.getContextInclusionStatement();
- if (owner != null)
+ if (owner != null)
return owner.getSignificantMacros();
IASTTranslationUnit tu = node.getTranslationUnit();
if (tu != null)
return tu.getSignificantMacros();
-
+
return null;
}
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 271d87b..fb91840 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
@@ -1308,8 +1308,27 @@ public class CompletionTests extends AbstractContentAssistTest {
// void foo() {
// __LINE__;
// }
- public void testLineMacro_Bug412463() throws Exception {
+ public void testPreprocessorProvidedMacro_Bug412463() throws Exception {
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;
+ // };
+ //
+ // int x = __CDT_PARSER__;
+ public void testPredefinedMacro_Bug412463() throws Exception {
+ final String[] expected = { "Cat", "meow(void)" };
+ assertContentAssistResults(fCursorOffset, expected, true, COMPARE_ID_STRINGS);
+ }
+
} \ No newline at end of file