Extend ProposalProvider in external Eclipse Project via Extension Point - eclipse-rcp

I try to extend my MyDSLProposalProvider from an external Eclipse RCP Project. I created an extension point schema which requires a class property which extends my ProposalProvider. In the new project I extend the class an overrode some methods justs to give me some output so I can see that the external method is called. But this is currently not happening. Is there anything I have to consider?
Currently the hirachy looks like:
MyDSLProposalProvider extends AbstractMyDSLProposalProvider
ExternalProposalProvider extends MyDSLProposalProvider
I rewrote a Method generated in the AbstractMyDSLProposalProvider but when its triggered the predefined Method in the AbstractMyDSLProposalProvider is called and not my new implementation.
public class ExternalMyDSLProposalPovider extends MyDSLProposalProvider
{
#Override
public void completeComponent_Name(EObject model, Assignment
assignment, ContentAssistContext context,
ICompletionProposalAcceptor acceptor) {
System.err.println("extern");
if(model instanceof Component)
{
createProposal("foo", "foo", context, acceptor);
}
super.completeComponent_Name(model, assignment, context, acceptor);
}
}
This is the class in the external Eclipse Project.
Thanks for the help.

When you declare an extension point using a schema that you have defined Eclipse puts that declaration in the extension point registry. That is all that is does, you must then write code to make uses of those declarations.
You read the extension point registry using something like:
IExtensionRegistry extRegistry = Platform.getExtensionRegistry();
IExtensionPoint extPoint = extRegistry.getExtensionPoint("your extension point id");
IConfigurationElement [] elements = extPoint.getConfigurationElements();
elements is now an array of the declarations in the various plugins using the extension point.
IConfigurationElement has various methods to get the values of the attributes of the declaration.
If you have defined a class in one of the attributes you can create an instance of the class using:
IConfigurationElement element = .... a config element
Object obj = element.createExecutableExtension("attribute name");
In your case the result should be your ExternalMyDSLProposalPovider.
You will then need to hook this object up with whatever is doing to proposals.

Related

Can I define a reusable subroutine/function/method within a Cake script?

I'm trying out Cake (C# Make). So far all the examples and documentation have the script file declaring all of its code inside delegates, like this:
Task("Clean")
.Does(() =>
{
// Delete a file.
DeleteFile("./file.txt");
// Clean a directory.
CleanDirectory("./temp");
});
However, one of the reasons I'm interested in using Cake is the possibility of writing my build scripts in a similar way to how I write code, as the scripts use a C#-based DSL. Included in this possibility is the ability to separate code that I use into methods (or functions / subroutines, whatever terminology is appropriate) so I can separate concerns and reuse code. For example, I may want to run the same set of steps for a multiple SKUs.
While I realize that I could create my own separate DLL with Script Aliases, I would like to avoid having to recompile a separate project every time I want to change these bits of shared code when working on the build script. Is there a way to define, inline with the normal build.cake file, methods that can still run the Cake aliases (e.g., DeleteFile) and can themselves be called from my Cake tasks?
Cake is C#, so you can create classes, methods, just like in regular C#
I.e. declare a class in a cake file
public class MyClass
{
public void MyMethod()
{
}
public static void MyStaticMethod()
{
}
}
and then use it a script like
var myClass = new MyClass();
// Call instance method
myClass.MyMethod();
//Call static method
MyClass.MyStaticMethod();
The Cake DSL is based on Roslyn scripting so there are some differences, code is essentially already in a type so you can declare a method without a class for reuse
public void MyMethod()
{
}
and then it can be called like a global methods
MyMethod();
A few gotchas, doing class will change scoping so you won't have access to aliases / context and global methods. You can get around this by i.e. passing ICakeContext as a parameter to class
public class MyClass
{
ICakeContext Context { get; }
public MyClass(ICakeContext context)
{
Context = context;
}
public void MyMethod()
{
Context.Information("Hello");
}
}
then used like this
// pass reference to Cake context
var myClass = new MyClass(Context);
// Call instance method which uses an Cake alias.
myClass.MyMethod();
You can have extension methods, but these can't be in a class, example:
public static void MyMethod(this ICakeContext context, string message)
{
context.Information(message);
}
Context.MyMethod("Hello");

Unable to replace implements with extends in eclipse JDT

The bug that I'm currently dealing with requires me to replace implements with extends upon selection of the associated quick fix.
For example:
public class R{
}
class Q implements R{ //error here
}
The quick fix will be to change implements to extends (That's what I am focusing on). But to do this I need to have TypeDeclaration.SUPERCLASS_TYPE as a ChildListPropertyDiscriptor whereas it's now a ChildPropertyDiscriptor. Which makes it unable to be supplied as a parameter to getListRewrite.
I want to know if there is any way I can make TypeDeclaration.SUPERCLASS_TYPE as a ChildListPropertyDiscriptor. Or else some other way exists to do this.
My full code snippet is the following:
TypeDeclaration typeDecl= (TypeDeclaration) selectedNode.getParent();
{
ASTRewrite rewrite= ASTRewrite.create(root.getAST());
ASTNode placeHolder= rewrite.createMoveTarget(selectedNode);
ListRewrite interfaces= rewrite.getListRewrite(typeDecl, TypeDeclaration.SUPERCLASS_TYPE_PROPERTY); //problem here
interfaces.insertFirst(placeHolder, null);
String label= CorrectionMessages.LocalCorrectionsSubProcessor_implementstoextends_description;
Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, IProposalRelevance.CHANGE_EXTENDS_TO_IMPLEMENTS, image);
proposals.add(proposal);
}
Java does not support multi-inheritance so there is only one type for extends supported. This explains why TypeDeclaration.SUPERCLASS_TYPE is no list and so has no ChildListPropertyDescriptior (for possible use with ListRewrite).
What you want instead is ASTRewrite.set():
rewrite.set(typeDecl, TypeDeclaration.SUPERCLASS_TYPE_PROPERTY, placeHolder, null);

TypeScript: Access global type hidden by local class definition?

Lets assume i have a class which has the same name as an previously defined type which is defined inside lib.d.ts. How would i make use of that type within this class.
For example, i have the class Event, which has to deal with the browsers Event object, which is defined as an interface in lib.d.ts.
export class Event { // own definition of Event which hides original Event
public dealWithBrowserEvent(event: Event): void { // Event object defined by lib.d.ts
// deal with it
}
}
How would i tell Typescript that this are two different types. Of course i could simply rename my class, but i don't want to do that, because the name is perfect for my use case.
You can archive this by doing so:
E.ts:
class CustomEvent
{
public dealWithBrowserEvent(event: Event): void
{
}
}
export default CustomEvent;
A.ts:
import Event from './E'
export class SomeClass
{
//Parameter e here is instance of your CustomEvent class
public someMethod(e: Event): void
{
let be: any;
//get browser event here
e.dealWithBrowserEvent(be)
}
}
More on declaration merging, and what can be merged and what not: link
I strongly recommend you not doing so. This code will lead to a lot of confusion for your colleagues reading/modifying it later, let alone headache of not being able to use in the same file standard class for Event.
In the meantime i found a quite doable solution. I defined an additional module which exports renamed interfaces. If i import this module, i can use the renamed types as if they would be original types.
browser.ts
// Event will be the one from lib.d.ts, because the compiler does not know anything about
// the class Event inside this module/file.
// All defined properties will be inherited for code completion.
export interface BrowserEvent extends Event {
additionalProperty1: SomeType;
additionalProperty2: SomeType;
}
If you don't need additional properties you can just do type aliasing:
browser.ts
// Alias for Event
export type BrowserEvent = Event;
event.ts
import {BrowserEvent} from './browser.ts';
export class Event { // Definition of Event hides original Event, but not BrowserEvent
public dealWithBrowserEvent(event: BrowserEvent): void {
// deal with it
}
}
I'm quite happy with this solution, but maybe there is a even better solution.

AS3 Eclipse: How to create template to extends myClass?

How do I create a template that each time when I create a class that extends MyClass, it will automatically add 3 functions.
EDIT:
In other words I am trying to implement Abstract functionality in AS3. Assume that MyClass have both private and protected methods.
I see the only way to write own code template and call it every time you need, in Flash Builder: window->preference->flash builder->editors->code template->action script->new and give the name to the template, for instance myclass.
You can use existed templates as an example for template syntax.
Template code for MyClass child class with three methods:
import my.package.MyClass
/**
* #author ${user}
*/
public class ${enclosing_type} extends MyClass
{
public function ${enclosing_type}()
{
}
override public function publicMethod():void
{
}
override protected function protectedMethod():void
{
}
override private function privateMethod():void
{
}
${cursor}
}
Usage:
Create new "action script file" or "new class",
remove all file content
type myclass and choose from auto-complete options template myclass
If you are actually extending MyClass, all of MyClass's functions are already available to your descendants. You can also override either of them with old header and desired new body, and still be able to call older versions of those functions via super qualifier. So, you add those functions to MyClass and let them be.
Another way is to make an interface - it's a set of declarations without any function bodies, which you have to implement in any class that wants this interface in its content. A short introduction to interfaces. Then your MyClass will be an interface, with 3 function declarations in it, and whichever class will be declared as implements MyClass will have to provide bodies for these functions.
Check other keywords on that page, including extends and implements.
Hope this helps.
EDIT: There are no abstract classes in AS3, however you can emulate abstract functions in a normal class via exception throwing:
protected function abstractFunction(...params):void {
throw new Error("Abstract!");
}

Groovy getProperty() on a static member

This question is probably going to illustrate a lack of knowledge on my part about how Groovy classes work, but I have tried to figure this out on my own with no luck. I want to create a getProperty() method on a class so I can reference member variables in a Groovyish way. This is NOT the same as just making them public because I do want some logic done when they are referenced. Basically, I'm trying to create a configuration Groovy class that uses ConfigSlurper:
class Configuration implements GroovyObject {
private static ConfigObject config = new ConfigSlurper().parse(new File("testing.conf").toURI().toURL())
//This method is illegal, but it illustrates what I want to do
public static String getProperty(String prop){
config.getProperty(prop)
}
}
If the above class were legal, I could then reference config items like so:
Configuration.dbUser
instead of this, which would require making the ConfigObject available:
Configuration.config.dbUser
I know, it would be worlds easier to just make the config object public, but knowing how to do this (or know why it's impossible) would help me understand Groovy a little better.
The only way I can get it to work is via the metaClass:
class Configuration {
private static ConfigObject config = new ConfigSlurper().parse( "foo = 'bar'" )
}
Configuration.metaClass.static.propertyMissing = { name ->
delegate.config[ name ]
}
println Configuration.foo
There may be a better way however...