1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Patch for Jeff Overbey PR133386. Allow contributions to the C Model from external plugins using the ILanguage mechansim.

This commit is contained in:
Doug Schaefer 2006-03-29 16:16:02 +00:00
parent 7d1e89a9fa
commit 5e45aa56e8
11 changed files with 187 additions and 32 deletions

View file

@ -11,6 +11,8 @@
package org.eclipse.cdt.core.model; package org.eclipse.cdt.core.model;
import java.util.ArrayList;
import org.eclipse.cdt.core.CCProjectNature; import org.eclipse.cdt.core.CCProjectNature;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CProjectNature; 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.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.content.IContentType; import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.ISchedulingRule;
@ -185,13 +188,10 @@ public class CoreModel {
* @return String[] ids * @return String[] ids
*/ */
public static String[] getRegistedContentTypeIds() { public static String[] getRegistedContentTypeIds() {
return new String[] { ArrayList a = LanguageManager.getInstance().getAllContentTypes();
CCorePlugin.CONTENT_TYPE_ASMSOURCE, String[] result = new String[a.size()];
CCorePlugin.CONTENT_TYPE_CHEADER, a.toArray(result);
CCorePlugin.CONTENT_TYPE_CSOURCE, return result;
CCorePlugin.CONTENT_TYPE_CXXHEADER,
CCorePlugin.CONTENT_TYPE_CXXSOURCE
};
} }
/** /**
@ -201,17 +201,12 @@ public class CoreModel {
IContentType contentType = CCorePlugin.getContentType(project, name); IContentType contentType = CCorePlugin.getContentType(project, name);
if (contentType != null) { if (contentType != null) {
String id = contentType.getId(); String id = contentType.getId();
if (CCorePlugin.CONTENT_TYPE_CHEADER.equals(id)) { return CCorePlugin.CONTENT_TYPE_CHEADER.equals(id)
return true; || CCorePlugin.CONTENT_TYPE_CXXHEADER.equals(id)
} else if (CCorePlugin.CONTENT_TYPE_CXXHEADER.equals(id)) { || CCorePlugin.CONTENT_TYPE_CSOURCE.equals(id)
return true; || CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(id)
} else if (CCorePlugin.CONTENT_TYPE_CSOURCE.equals(id)) { || CCorePlugin.CONTENT_TYPE_ASMSOURCE.equals(id)
return true; || LanguageManager.getInstance().isContributedContentType(id);
} else if (CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(id)) {
return true;
} else if (CCorePlugin.CONTENT_TYPE_ASMSOURCE.equals(id)) {
return true;
}
} }
return false; return false;
} }
@ -239,13 +234,10 @@ public class CoreModel {
IContentType contentType = CCorePlugin.getContentType(project, name); IContentType contentType = CCorePlugin.getContentType(project, name);
if (contentType != null) { if (contentType != null) {
String id = contentType.getId(); String id = contentType.getId();
if (CCorePlugin.CONTENT_TYPE_CSOURCE.equals(id)) { return CCorePlugin.CONTENT_TYPE_CSOURCE.equals(id)
return true; || CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(id)
} else if (CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(id)) { || CCorePlugin.CONTENT_TYPE_ASMSOURCE.equals(id)
return true; || LanguageManager.getInstance().isContributedContentType(id);
} else if (CCorePlugin.CONTENT_TYPE_ASMSOURCE.equals(id)) {
return true;
}
} }
return false; return false;
} }

View file

@ -0,0 +1,17 @@
package org.eclipse.cdt.core.model;
import org.eclipse.core.runtime.IAdaptable;
/**
* Additions to the <code>ICElement</code> hierarchy provided by
* contributed languages.
*
* Contributed elements are required to be adaptable to an
* <code>ImageDescriptor</code>.
*
* @author Jeff Overbey
* @see ICElement
* @see IAdaptable
*/
public interface IContributedCElement extends ICElement {
}

View file

@ -0,0 +1,26 @@
package org.eclipse.cdt.core.model;
/**
* Interface supported by model builders for contributed languages.
*
* Model builders parse a <code>TranslationUnit</code> (i.e., a file) and
* return a hierarchy of <code>ICElement</code>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
* <code>IAdditionalLanguage#createModelBuilder</code>, which will presumably
* pass that information on to the model builder constructor.
*
* @author Jeff Overbey
*/
public interface IContributedModelBuilder {
/**
* Callback used when a <code>TranslationUnit</code> needs to be parsed.
*
* The translation unit to parse is given to
* <code>ILanguage#createModelBuilder</code>, which will presumably
* pass it on to the model builder constructor.
*/
public abstract void parse(boolean quickParseMode) throws Exception;
}

View file

@ -95,4 +95,13 @@ public interface ILanguage extends IAdaptable {
*/ */
public ASTCompletionNode getCompletionNode(IWorkingCopy workingCopy, int offset); public ASTCompletionNode getCompletionNode(IWorkingCopy workingCopy, int offset);
/**
* Used to override the default model building behavior for a translation unit.
*
* @param tu the <code>ITranslationUnit</code> to be parsed (non-<code>null</code>)
* @return an <code>IModelBuilder</code>, which parses the given translation unit and
* returns the <code>ICElement</code>s of its model, or <code>null</code>
* to parse using the default CDT model builder
*/
public IContributedModelBuilder createModelBuilder(ITranslationUnit tu);
} }

View file

@ -12,7 +12,6 @@ package org.eclipse.cdt.core.model;
import java.util.Map; import java.util.Map;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.internal.core.model.IBufferFactory; import org.eclipse.cdt.internal.core.model.IBufferFactory;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
@ -375,4 +374,16 @@ public interface ITranslationUnit extends ICElement, IParent, IOpenable, ISource
* @return * @return
*/ */
ILanguage getLanguage() throws CoreException; 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);
} }

View file

@ -11,7 +11,10 @@
package org.eclipse.cdt.core.model; package org.eclipse.cdt.core.model;
import java.util.ArrayList;
import org.eclipse.cdt.core.CCorePlugin; 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.CoreException;
import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtension;
@ -70,4 +73,43 @@ public class LanguageManager {
} }
return null; return null;
} }
public ArrayList/*<String>*/ getAllContentTypes() {
ArrayList/*<String>*/ 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;
}
}
} }

View file

@ -20,6 +20,7 @@ import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.IBuffer; import org.eclipse.cdt.core.model.IBuffer;
import org.eclipse.cdt.core.model.ICElement; 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.IInclude;
import org.eclipse.cdt.core.model.ILanguage; import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.model.INamespace; import org.eclipse.cdt.core.model.INamespace;
@ -279,7 +280,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
return location; return location;
} }
protected IFile getFile() { public IFile getFile() {
IResource res = getResource(); IResource res = getResource();
if (res instanceof IFile) { if (res instanceof IFile) {
return (IFile)res; return (IFile)res;
@ -580,10 +581,22 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
/** /**
* Parse the buffer contents of this element. * 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 { try {
CModelBuilder modelBuilder = new CModelBuilder(this, newElements); CModelBuilder modelBuilder = new CModelBuilder(this, newElements);
boolean quickParseMode = ! (CCorePlugin.getDefault().useStructuralParseMode());
modelBuilder.parse(quickParseMode); modelBuilder.parse(quickParseMode);
} catch (Exception e) { } catch (Exception e) {
// use the debug log for this exception. // 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() { public IProblemRequestor getProblemRequestor() {
return problemRequestor; return problemRequestor;
} }
@ -613,6 +635,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
CCorePlugin.CONTENT_TYPE_CSOURCE.equals(contentTypeId) CCorePlugin.CONTENT_TYPE_CSOURCE.equals(contentTypeId)
|| CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(contentTypeId) || CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(contentTypeId)
|| CCorePlugin.CONTENT_TYPE_ASMSOURCE.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); 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 <code>CElementInfo</code> object associated with the translation unit
*
* @param wasSuccessful
*/
public void setIsStructureKnown(boolean wasSuccessful) {
try {
this.getElementInfo().setIsStructureKnown(wasSuccessful);
} catch (CModelException e) {
;
}
}
} }

View file

@ -17,7 +17,9 @@ import org.eclipse.cdt.core.dom.IPDOM;
import org.eclipse.cdt.core.dom.PDOM; import org.eclipse.cdt.core.dom.PDOM;
import org.eclipse.cdt.core.dom.ast.ASTCompletionNode; import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; 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.ILanguage;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.IScanner; 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) { public ASTCompletionNode getCompletionNode(IWorkingCopy workingCopy, int offset) {
return null; return null;
} }
public IContributedModelBuilder createModelBuilder(ITranslationUnit tu) {
// Use the default CDT model builder
return null;
}
} }

View file

@ -17,7 +17,9 @@ import org.eclipse.cdt.core.dom.IPDOM;
import org.eclipse.cdt.core.dom.PDOM; import org.eclipse.cdt.core.dom.PDOM;
import org.eclipse.cdt.core.dom.ast.ASTCompletionNode; import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; 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.ILanguage;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.IScanner; import org.eclipse.cdt.core.parser.IScanner;
@ -128,4 +130,9 @@ public class GPPLanguage extends PlatformObject implements ILanguage {
return null; return null;
} }
public IContributedModelBuilder createModelBuilder(ITranslationUnit tu) {
// Use the default CDT model builder
return null;
}
} }

View file

@ -882,11 +882,13 @@ public class CCorePlugin extends Plugin {
* @return * @return
*/ */
public static IContentType getContentType(IProject project, String filename) { public static IContentType getContentType(IProject project, String filename) {
// Always try in the workspace (for multi-language support)
// try with the project settings // try with the project settings
if (project != null) { if (project != null) {
try { try {
IContentTypeMatcher matcher = project.getContentTypeMatcher(); IContentTypeMatcher matcher = project.getContentTypeMatcher();
return matcher.findContentTypeFor(filename); IContentType ct = matcher.findContentTypeFor(filename);
if (ct != null) return ct;
} catch (CoreException e) { } catch (CoreException e) {
// ignore. // ignore.
} }

View file

@ -17,10 +17,11 @@ import org.eclipse.cdt.core.model.IBinary;
import org.eclipse.cdt.core.model.IBinaryModule; import org.eclipse.cdt.core.model.IBinaryModule;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject; 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.IDeclaration;
import org.eclipse.cdt.core.model.IField; 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.IIncludeReference;
import org.eclipse.cdt.core.model.ILibraryReference;
import org.eclipse.cdt.core.model.IMethodDeclaration; import org.eclipse.cdt.core.model.IMethodDeclaration;
import org.eclipse.cdt.core.model.ISourceRoot; import org.eclipse.cdt.core.model.ISourceRoot;
import org.eclipse.cdt.core.model.ITemplate; 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. * Returns an image descriptor for a C element. This is the base image, no overlays.
*/ */
public ImageDescriptor getBaseImageDescriptor(ICElement celement, int renderFlags) { 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(); int type = celement.getElementType();
switch (type) { switch (type) {
case ICElement.C_VCONTAINER: case ICElement.C_VCONTAINER: