diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModel.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModel.java
index eef4b681bc2..2ac6a848c40 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModel.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModel.java
@@ -11,6 +11,8 @@
package org.eclipse.cdt.core.model;
+import java.util.ArrayList;
+
import org.eclipse.cdt.core.CCProjectNature;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CProjectNature;
@@ -41,6 +43,7 @@ import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
@@ -185,13 +188,10 @@ public class CoreModel {
* @return String[] ids
*/
public static String[] getRegistedContentTypeIds() {
- return new String[] {
- CCorePlugin.CONTENT_TYPE_ASMSOURCE,
- CCorePlugin.CONTENT_TYPE_CHEADER,
- CCorePlugin.CONTENT_TYPE_CSOURCE,
- CCorePlugin.CONTENT_TYPE_CXXHEADER,
- CCorePlugin.CONTENT_TYPE_CXXSOURCE
- };
+ ArrayList a = LanguageManager.getInstance().getAllContentTypes();
+ String[] result = new String[a.size()];
+ a.toArray(result);
+ return result;
}
/**
@@ -201,17 +201,12 @@ public class CoreModel {
IContentType contentType = CCorePlugin.getContentType(project, name);
if (contentType != null) {
String id = contentType.getId();
- if (CCorePlugin.CONTENT_TYPE_CHEADER.equals(id)) {
- return true;
- } else if (CCorePlugin.CONTENT_TYPE_CXXHEADER.equals(id)) {
- return true;
- } else if (CCorePlugin.CONTENT_TYPE_CSOURCE.equals(id)) {
- return true;
- } else if (CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(id)) {
- return true;
- } else if (CCorePlugin.CONTENT_TYPE_ASMSOURCE.equals(id)) {
- return true;
- }
+ return CCorePlugin.CONTENT_TYPE_CHEADER.equals(id)
+ || CCorePlugin.CONTENT_TYPE_CXXHEADER.equals(id)
+ || CCorePlugin.CONTENT_TYPE_CSOURCE.equals(id)
+ || CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(id)
+ || CCorePlugin.CONTENT_TYPE_ASMSOURCE.equals(id)
+ || LanguageManager.getInstance().isContributedContentType(id);
}
return false;
}
@@ -239,13 +234,10 @@ public class CoreModel {
IContentType contentType = CCorePlugin.getContentType(project, name);
if (contentType != null) {
String id = contentType.getId();
- if (CCorePlugin.CONTENT_TYPE_CSOURCE.equals(id)) {
- return true;
- } else if (CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(id)) {
- return true;
- } else if (CCorePlugin.CONTENT_TYPE_ASMSOURCE.equals(id)) {
- return true;
- }
+ return CCorePlugin.CONTENT_TYPE_CSOURCE.equals(id)
+ || CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(id)
+ || CCorePlugin.CONTENT_TYPE_ASMSOURCE.equals(id)
+ || LanguageManager.getInstance().isContributedContentType(id);
}
return false;
}
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IContributedCElement.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IContributedCElement.java
new file mode 100644
index 00000000000..dd415e4ceff
--- /dev/null
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IContributedCElement.java
@@ -0,0 +1,17 @@
+package org.eclipse.cdt.core.model;
+
+import org.eclipse.core.runtime.IAdaptable;
+
+/**
+ * Additions to the ICElement
hierarchy provided by
+ * contributed languages.
+ *
+ * Contributed elements are required to be adaptable to an
+ * ImageDescriptor
.
+ *
+ * @author Jeff Overbey
+ * @see ICElement
+ * @see IAdaptable
+ */
+public interface IContributedCElement extends ICElement {
+}
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IContributedModelBuilder.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IContributedModelBuilder.java
new file mode 100644
index 00000000000..f51fe72ad1d
--- /dev/null
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IContributedModelBuilder.java
@@ -0,0 +1,26 @@
+package org.eclipse.cdt.core.model;
+
+/**
+ * Interface supported by model builders for contributed languages.
+ *
+ * Model builders parse a TranslationUnit
(i.e., a file) and
+ * return a hierarchy of ICElement
s which represent the high-level
+ * structure of that file (what modules, classes, functions, and similar
+ * constructs are contained in it, and on what line(s) the definition occurs).
+ *
+ * The translation unit to parse and the initial element map are given to
+ * IAdditionalLanguage#createModelBuilder
, which will presumably
+ * pass that information on to the model builder constructor.
+ *
+ * @author Jeff Overbey
+ */
+public interface IContributedModelBuilder {
+ /**
+ * Callback used when a TranslationUnit
needs to be parsed.
+ *
+ * The translation unit to parse is given to
+ * ILanguage#createModelBuilder
, which will presumably
+ * pass it on to the model builder constructor.
+ */
+ public abstract void parse(boolean quickParseMode) throws Exception;
+}
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ILanguage.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ILanguage.java
index e992b628572..cdf18021e24 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ILanguage.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ILanguage.java
@@ -95,4 +95,13 @@ public interface ILanguage extends IAdaptable {
*/
public ASTCompletionNode getCompletionNode(IWorkingCopy workingCopy, int offset);
+ /**
+ * Used to override the default model building behavior for a translation unit.
+ *
+ * @param tu the ITranslationUnit
to be parsed (non-null
)
+ * @return an IModelBuilder
, which parses the given translation unit and
+ * returns the ICElement
s of its model, or null
+ * to parse using the default CDT model builder
+ */
+ public IContributedModelBuilder createModelBuilder(ITranslationUnit tu);
}
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnit.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnit.java
index 9f3a0100032..715480fc7b9 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnit.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnit.java
@@ -12,7 +12,6 @@ package org.eclipse.cdt.core.model;
import java.util.Map;
-import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.internal.core.model.IBufferFactory;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
@@ -375,4 +374,16 @@ public interface ITranslationUnit extends ICElement, IParent, IOpenable, ISource
* @return
*/
ILanguage getLanguage() throws CoreException;
+
+ /**
+ * Used by contributed languages' model builders to indicate whether or
+ * not the parse of a translation unit was successful.
+ *
+ * @param wasSuccessful
+ *
+ * TODO (DS) I'm not sure it's a good idea to put a setter in this
+ * interface. We should revisit this.
+ *
+ */
+ public void setIsStructureKnown(boolean wasSuccessful);
}
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/LanguageManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/LanguageManager.java
index be811320db0..b0bf756c6aa 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/LanguageManager.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/LanguageManager.java
@@ -11,7 +11,10 @@
package org.eclipse.cdt.core.model;
+import java.util.ArrayList;
+
import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.internal.core.model.TranslationUnit;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
@@ -70,4 +73,43 @@ public class LanguageManager {
}
return null;
}
+
+ public ArrayList/**/ getAllContentTypes() {
+ ArrayList/**/ allTypes = new ArrayList();
+ allTypes.add(CCorePlugin.CONTENT_TYPE_ASMSOURCE);
+ allTypes.add(CCorePlugin.CONTENT_TYPE_CHEADER);
+ allTypes.add(CCorePlugin.CONTENT_TYPE_CSOURCE);
+ allTypes.add(CCorePlugin.CONTENT_TYPE_CXXHEADER);
+ allTypes.add(CCorePlugin.CONTENT_TYPE_CXXSOURCE);
+
+ IContentTypeManager manager = Platform.getContentTypeManager();
+ IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, ILanguage.KEY);
+ IExtension[] extensions = point.getExtensions();
+ for (int i = 0; i < extensions.length; ++i) {
+ IConfigurationElement[] languages = extensions[i].getConfigurationElements();
+ for (int j = 0; j < languages.length; ++j) {
+ IConfigurationElement language = languages[j];
+ IConfigurationElement[] contentTypes = language.getChildren("contentType"); //$NON-NLS-1$
+ for (int k = 0; k < contentTypes.length; ++k) {
+ IContentType langContType = manager.getContentType(contentTypes[k].getAttribute("id")); //$NON-NLS-1$
+ allTypes.add(langContType.getId());
+ }
+ }
+ }
+
+ return allTypes;
+ }
+
+ public boolean isContributedContentType(String contentTypeId) {
+ return getAllContentTypes().contains(contentTypeId);
+ }
+
+ public IContributedModelBuilder getContributedModelBuilderFor(TranslationUnit tu) {
+ try {
+ ILanguage lang = tu.getLanguage();
+ return lang == null ? null : lang.createModelBuilder(tu);
+ } catch (CoreException e) {
+ return null;
+ }
+ }
}
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 9db160ecb8b..d243ca0a92c 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
@@ -20,6 +20,7 @@ import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.IBuffer;
import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.IContributedModelBuilder;
import org.eclipse.cdt.core.model.IInclude;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.model.INamespace;
@@ -279,7 +280,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
return location;
}
- protected IFile getFile() {
+ public IFile getFile() {
IResource res = getResource();
if (res instanceof IFile) {
return (IFile)res;
@@ -580,10 +581,22 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
/**
* Parse the buffer contents of this element.
*/
- private void parse(Map newElements){
+ private void parse(Map newElements) {
+ boolean quickParseMode = ! (CCorePlugin.getDefault().useStructuralParseMode());
+ IContributedModelBuilder mb = LanguageManager.getInstance().getContributedModelBuilderFor(this);
+ if (mb == null) {
+ parseUsingCModelBuilder(newElements, quickParseMode);
+ } else {
+ parseUsingContributedModelBuilder(mb, quickParseMode);
+ }
+ }
+
+ /**
+ * Parse the buffer contents of this element.
+ */
+ private void parseUsingCModelBuilder(Map newElements, boolean quickParseMode) {
try {
CModelBuilder modelBuilder = new CModelBuilder(this, newElements);
- boolean quickParseMode = ! (CCorePlugin.getDefault().useStructuralParseMode());
modelBuilder.parse(quickParseMode);
} catch (Exception e) {
// use the debug log for this exception.
@@ -591,6 +604,15 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
}
}
+ private void parseUsingContributedModelBuilder(IContributedModelBuilder mb, boolean quickParseMode) {
+ try {
+ mb.parse(quickParseMode);
+ } catch (Exception e) {
+ // use the debug log for this exception.
+ Util.debugLog( "Exception in contributed model builder", IDebugLogConstants.MODEL); //$NON-NLS-1$
+ }
+ }
+
public IProblemRequestor getProblemRequestor() {
return problemRequestor;
}
@@ -613,6 +635,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
CCorePlugin.CONTENT_TYPE_CSOURCE.equals(contentTypeId)
|| CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(contentTypeId)
|| CCorePlugin.CONTENT_TYPE_ASMSOURCE.equals(contentTypeId)
+ || LanguageManager.getInstance().isContributedContentType(contentTypeId)
);
}
@@ -695,4 +718,19 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
}
super.closing(info);
}
+
+ /**
+ * Contributed languages' model builders need to be able to indicate whether or
+ * not the parse of a translation unit was successful without having access to
+ * the CElementInfo
object associated with the translation unit
+ *
+ * @param wasSuccessful
+ */
+ public void setIsStructureKnown(boolean wasSuccessful) {
+ try {
+ this.getElementInfo().setIsStructureKnown(wasSuccessful);
+ } catch (CModelException e) {
+ ;
+ }
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java
index 196f5819a05..d208007b83e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java
@@ -17,7 +17,9 @@ import org.eclipse.cdt.core.dom.IPDOM;
import org.eclipse.cdt.core.dom.PDOM;
import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.model.IContributedModelBuilder;
import org.eclipse.cdt.core.model.ILanguage;
+import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.IScanner;
@@ -129,5 +131,9 @@ public class GCCLanguage extends PlatformObject implements ILanguage {
public ASTCompletionNode getCompletionNode(IWorkingCopy workingCopy, int offset) {
return null;
}
-
+
+ public IContributedModelBuilder createModelBuilder(ITranslationUnit tu) {
+ // Use the default CDT model builder
+ return null;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java
index 9509cbbd694..e272f9b9a8d 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java
@@ -17,7 +17,9 @@ import org.eclipse.cdt.core.dom.IPDOM;
import org.eclipse.cdt.core.dom.PDOM;
import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.model.IContributedModelBuilder;
import org.eclipse.cdt.core.model.ILanguage;
+import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.IScanner;
@@ -128,4 +130,9 @@ public class GPPLanguage extends PlatformObject implements ILanguage {
return null;
}
+
+ public IContributedModelBuilder createModelBuilder(ITranslationUnit tu) {
+ // Use the default CDT model builder
+ return null;
+ }
}
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java
index 856dca21f79..db8cd366d81 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java
@@ -882,11 +882,13 @@ public class CCorePlugin extends Plugin {
* @return
*/
public static IContentType getContentType(IProject project, String filename) {
+ // Always try in the workspace (for multi-language support)
// try with the project settings
if (project != null) {
try {
IContentTypeMatcher matcher = project.getContentTypeMatcher();
- return matcher.findContentTypeFor(filename);
+ IContentType ct = matcher.findContentTypeFor(filename);
+ if (ct != null) return ct;
} catch (CoreException e) {
// ignore.
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/CElementImageProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/CElementImageProvider.java
index 65e90c44b4c..5d2370f0e92 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/CElementImageProvider.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/CElementImageProvider.java
@@ -17,10 +17,11 @@ import org.eclipse.cdt.core.model.IBinary;
import org.eclipse.cdt.core.model.IBinaryModule;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.model.IContributedCElement;
import org.eclipse.cdt.core.model.IDeclaration;
import org.eclipse.cdt.core.model.IField;
-import org.eclipse.cdt.core.model.ILibraryReference;
import org.eclipse.cdt.core.model.IIncludeReference;
+import org.eclipse.cdt.core.model.ILibraryReference;
import org.eclipse.cdt.core.model.IMethodDeclaration;
import org.eclipse.cdt.core.model.ISourceRoot;
import org.eclipse.cdt.core.model.ITemplate;
@@ -267,6 +268,10 @@ public class CElementImageProvider {
* Returns an image descriptor for a C element. This is the base image, no overlays.
*/
public ImageDescriptor getBaseImageDescriptor(ICElement celement, int renderFlags) {
+ // Allow contributed languages to provide icons for their extensions to the ICElement hierarchy
+ if (celement instanceof IContributedCElement)
+ return (ImageDescriptor)((IContributedCElement)celement).getAdapter(ImageDescriptor.class);
+
int type = celement.getElementType();
switch (type) {
case ICElement.C_VCONTAINER: