diff --git a/eclipse/tern.eclipse.ide.core/plugin.properties b/eclipse/tern.eclipse.ide.core/plugin.properties index 44e62c2ad..8e1e58b7c 100644 --- a/eclipse/tern.eclipse.ide.core/plugin.properties +++ b/eclipse/tern.eclipse.ide.core/plugin.properties @@ -14,6 +14,7 @@ providerName=Angelo ZERR # Extension point ternServerTypes.name=Tern Server Types. ternConsoleConnectors.name=Tern Console Connectors. +ternServerAdapters.name=Tern Nature Adapters # Nature ternNature.name=Tern Nature diff --git a/eclipse/tern.eclipse.ide.core/plugin.xml b/eclipse/tern.eclipse.ide.core/plugin.xml index c11ceba9d..aeefb7482 100644 --- a/eclipse/tern.eclipse.ide.core/plugin.xml +++ b/eclipse/tern.eclipse.ide.core/plugin.xml @@ -18,6 +18,8 @@ schema="schema/ternServerTypes.exsd" /> + diff --git a/eclipse/tern.eclipse.ide.core/schema/ternNatureAdapters.exsd b/eclipse/tern.eclipse.ide.core/schema/ternNatureAdapters.exsd new file mode 100644 index 000000000..ce47bb0b3 --- /dev/null +++ b/eclipse/tern.eclipse.ide.core/schema/ternNatureAdapters.exsd @@ -0,0 +1,87 @@ + + + + + + + + + Extension point to provide Natures that are to be treated as the Tern ones. + + + + + + + + + + + + + + + + + a fully-qualified name of the target extension point + + + + + + + an optional id + + + + + + + an optional name + + + + + + + + + + + + ID of the Nature to be treated as the Tern one + + + + + + + an optional name + + + + + + + + + + + + 2.0 + + + + + + + + + + + This plugin itself does not have any predefined builders. + + + + + diff --git a/eclipse/tern.eclipse.ide.core/src/tern/eclipse/ide/core/IDETernProject.java b/eclipse/tern.eclipse.ide.core/src/tern/eclipse/ide/core/IDETernProject.java index b4f069d87..59351dce8 100644 --- a/eclipse/tern.eclipse.ide.core/src/tern/eclipse/ide/core/IDETernProject.java +++ b/eclipse/tern.eclipse.ide.core/src/tern/eclipse/ide/core/IDETernProject.java @@ -23,7 +23,10 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.core.runtime.Status; import org.eclipse.jface.text.BadLocationException; @@ -79,6 +82,8 @@ public class IDETernProject extends TernProject { private static final QualifiedName TERN_PROJECT = new QualifiedName( TernCorePlugin.PLUGIN_ID + ".sessionprops", "TernProject"); + private static final String EXTENSION_TERN_PROJECT_DESCRIBERS = "ternNatureAdapters"; + private final IProject project; private ITernServer ternServer; @@ -91,6 +96,8 @@ public class IDETernProject extends TernProject { private final List listeners; + private static List ternNatureAdapters; + IDETernProject(IProject project) throws CoreException { super(project.getLocation().toFile()); this.project = project; @@ -184,11 +191,18 @@ public boolean isTernServerDisposed() { */ public static boolean hasTernNature(IProject project) { try { - return project.hasNature(TernNature.ID); + if (project.hasNature(TernNature.ID)) + return true; + + loadTernProjectDescribers(); + for (String adaptToNature : ternNatureAdapters) { + if (project.hasNature(adaptToNature)) + return true; + } } catch (CoreException e) { Trace.trace(Trace.SEVERE, "Error tern nature", e); - return false; } + return false; } @Override @@ -240,7 +254,48 @@ private void loadIDEInfos() { } } + + private static void loadTernProjectDescribers() { + if (ternNatureAdapters != null) + return; + + Trace.trace(Trace.EXTENSION_POINT, + "->- Loading .ternProjectDescribers extension point ->-"); + + IExtensionRegistry registry = Platform.getExtensionRegistry(); + IConfigurationElement[] cf = registry.getConfigurationElementsFor( + TernCorePlugin.PLUGIN_ID, EXTENSION_TERN_PROJECT_DESCRIBERS); + List list = new ArrayList( + cf.length); + addTernNatureAdapters(cf, list); + ternNatureAdapters = list; + + Trace.trace(Trace.EXTENSION_POINT, + "-<- Done loading .ternProjectDescribers extension point -<-"); + } + + /** + * Load the tern project describers. + */ + private static synchronized void addTernNatureAdapters( + IConfigurationElement[] cf, List list) { + for (IConfigurationElement ce : cf) { + try { + list.add(ce.getAttribute("id")); + Trace.trace( + Trace.EXTENSION_POINT, + " Loaded project describer: " + + ce.getAttribute("id")); + } catch (Throwable t) { + Trace.trace( + Trace.SEVERE, + " Could not load project describers: " + + ce.getAttribute("id"), t); + } + } + } + /** * Returns the resource of the given path and type. * diff --git a/eclipse/tern.eclipse.ide.ui/META-INF/MANIFEST.MF b/eclipse/tern.eclipse.ide.ui/META-INF/MANIFEST.MF index 1f8c38466..de3e94deb 100644 --- a/eclipse/tern.eclipse.ide.ui/META-INF/MANIFEST.MF +++ b/eclipse/tern.eclipse.ide.ui/META-INF/MANIFEST.MF @@ -16,7 +16,8 @@ Require-Bundle: org.eclipse.ui, org.eclipse.ui.editors, org.eclipse.jface.text, org.eclipse.ui.workbench.texteditor, - tern.eclipse;bundle-version="0.2.0" + tern.eclipse;bundle-version="0.2.0", + org.eclipse.core.expressions Bundle-ActivationPolicy: lazy Bundle-Activator: tern.eclipse.ide.ui.TernUIPlugin Import-Package: org.json.simple diff --git a/eclipse/tern.eclipse.ide.ui/plugin.xml b/eclipse/tern.eclipse.ide.ui/plugin.xml index 63c13d2c9..bc311eb77 100644 --- a/eclipse/tern.eclipse.ide.ui/plugin.xml +++ b/eclipse/tern.eclipse.ide.ui/plugin.xml @@ -13,6 +13,22 @@ ############################################################################### --> + + + + + + + + + + @@ -40,8 +56,7 @@ - + @@ -85,8 +100,7 @@ id="tern.eclipse.ide.internal.ui.properties.TernMainPropertyPage"> - + @@ -97,8 +111,7 @@ id="tern.eclipse.ide.internal.ui.properties.TernTypeDefinitionsPropertyPage"> - + @@ -109,8 +122,7 @@ id="tern.eclipse.ide.internal.ui.properties.TernPluginsPropertyPage"> - + @@ -121,8 +133,7 @@ id="tern.eclipse.ide.internal.ui.properties.TernScriptPathsPropertyPage"> - + @@ -133,8 +144,7 @@ id="tern.eclipse.ide.internal.ui.properties.TernConsolePropertyPage"> - + diff --git a/eclipse/tern.eclipse.ide.ui/src/tern/eclipse/ide/ui/internal/TernIDEStartup.java b/eclipse/tern.eclipse.ide.ui/src/tern/eclipse/ide/ui/internal/TernIDEStartup.java new file mode 100644 index 000000000..e148edf0d --- /dev/null +++ b/eclipse/tern.eclipse.ide.ui/src/tern/eclipse/ide/ui/internal/TernIDEStartup.java @@ -0,0 +1,17 @@ +package tern.eclipse.ide.ui.internal; + +import org.eclipse.ui.IStartup; + +/** + * Need this to make TernNatureTester work from early start + * + * @author Victor Rubezhny + */ +public class TernIDEStartup implements IStartup { + + @Override + public void earlyStartup() { + // Nothing really to do here, but need this to make TernNatureTester work from early start + } + +} diff --git a/eclipse/tern.eclipse.ide.ui/src/tern/eclipse/ide/ui/internal/TernNatureTester.java b/eclipse/tern.eclipse.ide.ui/src/tern/eclipse/ide/ui/internal/TernNatureTester.java new file mode 100644 index 000000000..1f210ed2b --- /dev/null +++ b/eclipse/tern.eclipse.ide.ui/src/tern/eclipse/ide/ui/internal/TernNatureTester.java @@ -0,0 +1,49 @@ +package tern.eclipse.ide.ui.internal; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IAdaptable; + +import tern.eclipse.ide.core.IDETernProject; + +/** + * Property Tester for a IProject receiver object + * + * Property to be tested: "isTernProject" + * + * @author Victor Rubezhny + */ +public class TernNatureTester extends org.eclipse.core.expressions.PropertyTester { + private static final String IS_TERN_PROJECT_PROPERTY = "isTernProject"; + + public TernNatureTester() { + // Default constructor is required for property tester + } + + /** + * Tests if the receiver object is a project is a Tern project + * + * @return true if the receiver object is a Project that has a nature that is treated as Tern nature, + * otherwise false is returned + */ + @Override + public boolean test(Object receiver, String property, Object[] args, + Object expectedValue) { + + if (IS_TERN_PROJECT_PROPERTY.equals(property)) + return testIsTernProject(receiver); + + return false; + } + + private boolean testIsTernProject(Object receiver) { + if (receiver instanceof IAdaptable) { + IProject project = (IProject)((IAdaptable)receiver).getAdapter(IProject.class); + if (project != null) { + return IDETernProject.hasTernNature(project); + } + } + + return false; + } + +}