1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-01 06:05:24 +02:00

Made languages more dynamic. No more hard coding. The PDOM records and manages the mapping from language id used in the bindings to ILanguage instance. Added a LanguageManager to help with the mapping and move all access to the extension there.

This commit is contained in:
Doug Schaefer 2005-12-01 20:46:57 +00:00
parent d4bc99f45d
commit df627e7739
11 changed files with 252 additions and 58 deletions

View file

@ -17,7 +17,7 @@ import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ILanguage;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.LanguageManager;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.IBuffer;
import org.eclipse.cdt.core.model.ICElement;
@ -33,14 +33,9 @@ import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.content.IContentTypeManager;
@ -664,22 +659,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
// content type string
IContentTypeManager manager = Platform.getContentTypeManager();
IContentType contentType = manager.getContentType(contentTypeId);
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$
if (contentType.equals(langContType)) {
this.language = (ILanguage)language.createExecutableExtension("class"); //$NON-NLS-1$
return this.language;
}
}
}
}
language = LanguageManager.getInstance().getLanguage(contentType);
}
return language;

View file

@ -48,21 +48,13 @@ public interface ILanguage {
public static final int AST_SKIP_INDEXED_HEADERS = 4;
/**
* Return the language id for this language. This is used in the PDOM database
* to differentiate languages from eachother.
* Return the language id for this language in the given PDOM.
* This is to differentiate languages from eachother.
*
* @return
* @return language id
*/
public int getId();
public String getId();
// Language ID registry. This is here mainly to avoid languages trampling
// over eachother. It is not critical that language ids be put here, but it
// is critical that two languages in a given installion do not have the same
// id.
public static final int GCC_ID = 1; // gnu C
public static final int GPP_ID = 2; // gnu C++
public static final int GNAT_ID = 3; // gnu Ada
/**
* Create the AST for the given translation unit with the given style.
*
@ -89,7 +81,7 @@ public interface ILanguage {
* @param binding
* @return
*/
public PDOMBinding getPDOMBinding(PDOMDatabase pdom, IASTName name) throws CoreException;
public PDOMBinding getPDOMBinding(PDOMDatabase pdom, int languageId, IASTName name) throws CoreException;
/**
* Creates a language specific binding given the generic binding extracted

View file

@ -0,0 +1,73 @@
/*******************************************************************************
* Copyright (c) 2005 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.dom;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.content.IContentTypeManager;
/**
* @author Doug Schaefer
*
*/
public class LanguageManager {
private static LanguageManager instance;
public static LanguageManager getInstance() {
if (instance == null)
instance = new LanguageManager();
return instance;
}
public ILanguage getLanguage(String id) throws CoreException {
IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, ILanguage.KEY);
IExtension[] extensions = point.getExtensions();
for (int i = 0; i < extensions.length; ++i) {
IExtension extension = extensions[i];
IConfigurationElement[] languages = extension.getConfigurationElements();
for (int j = 0; j < languages.length; ++j) {
IConfigurationElement language = languages[j];
String langId = extension.getNamespace() + "." + language.getAttribute("id"); //$NON-NLS-1$ $NON-NLS-2$
if (langId.equals(id))
return (ILanguage)language.createExecutableExtension("class"); //$NON-NLS-1$
}
}
return null;
}
public ILanguage getLanguage(IContentType contentType) throws CoreException {
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$
if (contentType.equals(langContType)) {
return (ILanguage)language.createExecutableExtension("class"); //$NON-NLS-1$
}
}
}
}
return null;
}
}

View file

@ -50,8 +50,9 @@ public class GCCLanguage implements ILanguage {
protected static final GCCScannerExtensionConfiguration C_GNU_SCANNER_EXTENSION = new GCCScannerExtensionConfiguration();
public int getId() {
return GCC_ID;
public String getId() {
// Must match the id in the extension
return CCorePlugin.PLUGIN_ID + ".gcc"; //$NON-NLS-1$
}
public IASTTranslationUnit getTranslationUnit(ITranslationUnit tu, int style) {
@ -96,7 +97,7 @@ public class GCCLanguage implements ILanguage {
return null;
}
public PDOMBinding getPDOMBinding(PDOMDatabase pdom, IASTName name) throws CoreException {
public PDOMBinding getPDOMBinding(PDOMDatabase pdom, int languageId, IASTName name) throws CoreException {
IBinding binding = name.resolveBinding();
if (binding == null)
return null;

View file

@ -57,9 +57,9 @@ import org.eclipse.core.runtime.CoreException;
public class GPPLanguage implements ILanguage {
protected static final GPPScannerExtensionConfiguration CPP_GNU_SCANNER_EXTENSION = new GPPScannerExtensionConfiguration();
public int getId() {
return GPP_ID;
public String getId() {
return CCorePlugin.PLUGIN_ID + ".g++"; //$NON-NLS-1$
}
public IASTTranslationUnit getTranslationUnit(ITranslationUnit tu, int style) {
@ -107,7 +107,7 @@ public class GPPLanguage implements ILanguage {
public static final int CPPVARIABLE = 1;
public static final int CPPFUNCTION = 2;
public PDOMBinding getPDOMBinding(PDOMDatabase pdom, IASTName name) throws CoreException {
public PDOMBinding getPDOMBinding(PDOMDatabase pdom, int languageId, IASTName name) throws CoreException {
IBinding binding = name.resolveBinding();
if (binding == null)
return null;
@ -117,11 +117,11 @@ public class GPPLanguage implements ILanguage {
} else if (binding instanceof CPPVariable) {
IScope scope = binding.getScope();
if (!(scope instanceof CPPBlockScope))
return new PDOMCPPVariable(pdom, name, (CPPVariable)binding);
return new PDOMCPPVariable(pdom, languageId, name, (CPPVariable)binding);
} else if (binding instanceof CPPMethod) {
return null;
} else if (binding instanceof CPPFunction) {
return new PDOMCPPFunction(pdom, name, (CPPFunction)binding);
return new PDOMCPPFunction(pdom, languageId, name, (CPPFunction)binding);
}
return null;

View file

@ -10,10 +10,15 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
import org.eclipse.cdt.core.dom.ILanguage;
import org.eclipse.cdt.core.dom.IPDOM;
import org.eclipse.cdt.core.dom.LanguageManager;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
@ -27,10 +32,7 @@ import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
/**
* The PDOM Database.
@ -43,11 +45,15 @@ public class PDOMDatabase implements IPDOM {
private Database db;
private static final int VERSION = 0;
public static final int FILE_INDEX = Database.DATA_AREA + 1 * Database.INT_SIZE;
private BTree fileIndex;
public static final int BINDING_INDEX = Database.DATA_AREA + 2 * Database.INT_SIZE;
public static final int LANGUAGES = Database.DATA_AREA;
public static final int FILE_INDEX = Database.DATA_AREA + 4;
public static final int BINDING_INDEX = Database.DATA_AREA + 8;
private Map languageCache;
private ILanguage[] languages;
private BTree fileIndex;
private BTree bindingIndex;
private static final QualifiedName dbNameProperty
@ -89,6 +95,7 @@ public class PDOMDatabase implements IPDOM {
if (language == null)
return;
final int languageId = getLanguageId(language);
IASTTranslationUnit ast = language.getTranslationUnit(tu,
ILanguage.AST_USE_INDEX |
ILanguage.AST_SKIP_INDEXED_HEADERS);
@ -102,7 +109,7 @@ public class PDOMDatabase implements IPDOM {
public int visit(IASTName name) {
try {
if (name.toCharArray().length > 0) {
PDOMBinding binding = language.getPDOMBinding(PDOMDatabase.this, name);
PDOMBinding binding = language.getPDOMBinding(PDOMDatabase.this, languageId, name);
if (binding != null)
new PDOMName(PDOMDatabase.this, name, binding);
}
@ -155,4 +162,49 @@ public class PDOMDatabase implements IPDOM {
return new IBinding[0];
}
private void initLanguageMap() throws CoreException {
// load in the languages
languageCache = new HashMap();
int record = db.getInt(LANGUAGES);
PDOMLanguage lang = null;
if (record != 0)
lang = new PDOMLanguage(this, record);
while (lang != null) {
languageCache.put(lang.getName(), lang);
lang = lang.getNext();
}
// map language ids to ILanguage impls.
languages = new ILanguage[languageCache.size() + 1]; // + 1 for the empty zero
Iterator i = languageCache.values().iterator();
while (i.hasNext()) {
lang = (PDOMLanguage)i.next();
languages[lang.getId()] = LanguageManager.getInstance().getLanguage(lang.getName());
}
}
public int getLanguageId(ILanguage language) throws CoreException {
if (languageCache == null)
initLanguageMap();
PDOMLanguage pdomLang = (PDOMLanguage)languageCache.get(language.getId());
if (pdomLang == null) {
// add it in
int next = db.getInt(LANGUAGES);
int id = next == 0 ? 1 : new PDOMLanguage(this, next).getId() + 1;
pdomLang = new PDOMLanguage(this, language.getId(), id, next);
db.putInt(LANGUAGES, pdomLang.getRecord());
ILanguage[] oldlangs = languages;
languages = new ILanguage[id + 1];
System.arraycopy(oldlangs, 0, languages, 0, id);
languages[id] = language;
return id;
} else
return pdomLang.getId();
}
public ILanguage getLanguage(int id) throws CoreException {
if (languages == null)
initLanguageMap();
return languages[id];
}
}

View file

@ -0,0 +1,64 @@
/*******************************************************************************
* Copyright (c) 2005 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.core.runtime.CoreException;
/**
* @author Doug Schaefer
*
*/
public class PDOMLanguage {
private PDOMDatabase pdom;
private int record;
private static final int NEXT = 0; // int
private static final int ID = 4; // char
private static final int NAME = 6; // string
public PDOMLanguage(PDOMDatabase pdom, int record) {
this.pdom = pdom;
this.record = record;
}
public PDOMLanguage(PDOMDatabase pdom, String name, int id, int next) throws CoreException {
this.pdom = pdom;
Database db = pdom.getDB();
record = db.malloc(6 + (name.length() + 1) * 2);
db.putInt(record + NEXT, next);
db.putChar(record + ID, (char)id);
db.putString(record + NAME, name);
}
public int getRecord() {
return record;
}
public int getId() throws CoreException {
return pdom.getDB().getChar(record + ID);
}
public String getName() throws CoreException {
return pdom.getDB().getString(record + NAME);
}
public PDOMLanguage getNext() throws CoreException {
int nextrec = pdom.getDB().getInt(record + NEXT);
return nextrec != 0 ? new PDOMLanguage(pdom, nextrec) : null;
}
public boolean equals(String id) throws CoreException {
return PDOMUtils.stringCompare(pdom.getDB(), record + NAME, id) == 0;
}
}

View file

@ -70,4 +70,35 @@ public class PDOMUtils {
return 1;
}
public static int stringCompare(Database db, int record1, String record2) throws CoreException {
Chunk chunk1 = db.getChunk(record1);
int i1 = record1;
int i2 = 0;
int n2 = record2.length();
char c1 = chunk1.getChar(i1);
char c2 = i2 < n2 ? record2.charAt(i2) : 0;
while (c1 != 0 && c2 != 0) {
if (c1 < c2)
return -1;
if (c1 > c2)
return 1;
i1 += 2;
++i2;
c1 = chunk1.getChar(i1);
c2 = i2 < n2 ? record2.charAt(i2) : 0;
}
if (c1 == c2)
return 0;
else if (c1 == 0)
return -1;
else
return 1;
}
}

View file

@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.pdom.dom;
import java.io.IOException;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ILanguage;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
@ -136,8 +137,8 @@ public class PDOMBinding implements IBinding {
return record;
}
public int getLanguage() throws CoreException {
return pdom.getDB().getChar(record + LANGUAGE_OFFSET);
public ILanguage getLanguage() throws CoreException {
return pdom.getLanguage(pdom.getDB().getChar(record + LANGUAGE_OFFSET));
}
public int getBindingType() throws CoreException {

View file

@ -37,8 +37,8 @@ public class PDOMCPPFunction extends PDOMBinding implements ICPPFunction {
* @param type
* @throws CoreException
*/
public PDOMCPPFunction(PDOMDatabase pdom, IASTName name, CPPFunction binding) throws CoreException {
super(pdom, name, GPPLanguage.GPP_ID, GPPLanguage.CPPFUNCTION);
public PDOMCPPFunction(PDOMDatabase pdom, int languageId, IASTName name, CPPFunction binding) throws CoreException {
super(pdom, name, languageId, GPPLanguage.CPPFUNCTION);
}
/**

View file

@ -34,9 +34,9 @@ public class PDOMCPPVariable extends PDOMBinding implements ICPPVariable {
* @param binding
* @throws CoreException
*/
public PDOMCPPVariable(PDOMDatabase pdom, IASTName name, CPPVariable binding)
public PDOMCPPVariable(PDOMDatabase pdom, int languageId, IASTName name, CPPVariable binding)
throws CoreException {
super(pdom, name, GPPLanguage.GPP_ID, GPPLanguage.CPPVARIABLE);
super(pdom, name, languageId, GPPLanguage.CPPVARIABLE);
}
/**