Is it possible to use the xtend compiler as a library?

126 views
Skip to first unread message

Carl Perfect

unread,
Jun 25, 2015, 9:29:01 AM6/25/15
to xtend...@googlegroups.com
Hello,

I'm thinking about writing a little plugin for a web framework (ninja) that would let me
code with xtend instead of java.

For that I would need to be able to reference the xtend compiling backend as a library
in the plugin so it can build xtend files (like org.eclipse.jdt is an embeddable java compiler).

Do you know if that's possible?
I guess it is becase there is a maven plugin available (among many other things)

How would I use xtend compliling backend in my plugin?
Is there code I could learn from?

Carl.

Stefan Oehme

unread,
Jun 26, 2015, 3:38:39 AM6/26/15
to xtend...@googlegroups.com
Hey Carl,

have a look at the implementation of the xtend-maven-plugin:


Be aware though that this API will change in 2.9, because we are working on a new, incremental standalone compiler for all Xtext languages.

Cheers,
Stefan

Carl Perfect

unread,
Jun 26, 2015, 3:45:24 AM6/26/15
to xtend...@googlegroups.com


On Friday, June 26, 2015 at 9:38:39 AM UTC+2, Stefan Oehme wrote:
Hey Carl,

have a look at the implementation of the xtend-maven-plugin:


Be aware though that this API will change in 2.9, because we are working on a new, incremental standalone compiler for all Xtext languages.


Thanks!

This is exactly what I needed.
For reference, the class to use seem to be org.eclipse.xtend.core.compiler.batch.XtendBatchCompiler

Stefan Oehme

unread,
Jun 26, 2015, 3:55:33 AM6/26/15
to xtend...@googlegroups.com
That's right

--
You received this message because you are subscribed to a topic in the Google Groups "Xtend Programming Language" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/xtend-lang/3gcjaPWyudM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to xtend-lang+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Carl Perfect

unread,
Jul 8, 2015, 4:20:57 PM7/8/15
to xtend...@googlegroups.com


On Friday, June 26, 2015 at 9:55:33 AM UTC+2, Stefan Oehme wrote:
That's right

Am I forced to use some dependency injection mechanism to initialize the Compiler?

I am asking because I got a NPE at this point in the code

         } finally {
   --->         annotationProcessorFactory.setClassLoader(null);
            destroyClassLoader(jvmTypesClassLoader);
            destroyClassLoader(annotationProcessingClassLoader);
            if (isDeleteTempDirectory()) {
                deleteTmpFolders();
            }
        }



I haven't found how to initialize the annotationProcessorFactory yet.

Cheers,
Carl.

Carl Perfect

unread,
Jul 8, 2015, 4:33:05 PM7/8/15
to xtend...@googlegroups.com


On Wednesday, July 8, 2015 at 10:20:57 PM UTC+2, Carl Perfect wrote:


On Friday, June 26, 2015 at 9:55:33 AM UTC+2, Stefan Oehme wrote:
That's right

Am I forced to use some dependency injection mechanism to initialize the Compiler?


When I tried the following;

        Injector injector = Guice.createInjector(new org.eclipse.xtend.core.XtendRuntimeModule());
        XtendBatchCompiler compiler = injector.getInstance(XtendBatchCompiler.class);

I got the following error:


1) Error injecting constructor, org.eclipse.emf.common.util.WrappedException: java.lang.RuntimeException: Cannot create a resource for 'classpath:/org/eclipse/xtend/core/Xtend.xtextbin'; a registered resource factory is needed
  at org.eclipse.xtext.xbase.services.XtypeGrammarAccess.<init>(XtypeGrammarAccess.java:734)
  at org.eclipse.xtext.xbase.services.XtypeGrammarAccess.class(XtypeGrammarAccess.java:734)
  while locating org.eclipse.xtext.xbase.services.XtypeGrammarAccess
    for parameter 1 at org.eclipse.xtext.xbase.services.XbaseGrammarAccess.<init>(XbaseGrammarAccess.java:3369)
  at org.eclipse.xtext.xbase.services.XbaseGrammarAccess.class(XbaseGrammarAccess.java:3369)
  while locating org.eclipse.xtext.xbase.services.XbaseGrammarAccess
    for field at org.eclipse.xtext.xbase.validation.XbaseJavaValidator.grammarAccess(XbaseJavaValidator.java:153)
  at org.eclipse.xtext.service.MethodBasedModule.configure(MethodBasedModule.java:56)
  while locating org.eclipse.xtend.core.validation.XtendJavaValidator
Caused by: org.eclipse.emf.common.util.WrappedException: java.lang.RuntimeException: Cannot create a resource for 'classpath:/org/eclipse/xtend/core/Xtend.xtextbin'; a registered resource factory is needed
    at org.eclipse.xtext.parser.BaseEPackageAccess.loadResource(BaseEPackageAccess.java:57)
    at org.eclipse.xtext.parser.BaseEPackageAccess.loadGrammarFile(BaseEPackageAccess.java:44)
    at org.eclipse.xtext.service.GrammarProvider.getGrammar(GrammarProvider.java:61)
    at org.eclipse.xtext.xbase.services.XtypeGrammarAccess.internalFindGrammar(XtypeGrammarAccess.java:762)
    at org.eclipse.xtext.xbase.services.XtypeGrammarAccess.<init>(XtypeGrammarAccess.java:735)
    at org.eclipse.xtext.xbase.services.XtypeGrammarAccess$$FastClassByGuice$$c92f962a.newInstance(<generated>)
    at com.google.inject.internal.cglib.reflect.$FastConstructor.newInstance(FastConstructor.java:40)
    at com.google.inject.internal.DefaultConstructionProxyFactory$1.newInstance(DefaultConstructionProxyFactory.java:60)
    at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:85)
    at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254)
    at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
    at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1031)
    at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
    at com.google.inject.Scopes$1$1.get(Scopes.java:65)
    at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40)
    at com.google.inject.internal.SingleParameterInjector.inject(SingleParameterInjector.java:38)
    at com.google.inject.internal.SingleParameterInjector.getAll(SingleParameterInjector.java:62)
    at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:84)
    at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254)
    at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
    at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1031)
    at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
    at com.google.inject.Scopes$1$1.get(Scopes.java:65)
    at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40)
    at com.google.inject.internal.SingleFieldInjector.inject(SingleFieldInjector.java:53)
    at com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:110)
    at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:94)
    at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254)
    at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
    at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1031)
    at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
    at com.google.inject.Scopes$1$1.get(Scopes.java:65)
    at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40)
    at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:204)
    at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:198)
    at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1024)
    at com.google.inject.internal.InternalInjectorCreator.loadEagerSingletons(InternalInjectorCreator.java:198)
    at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:179)
    at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:109)
    at com.google.inject.Guice.createInjector(Guice.java:95)
    at com.google.inject.Guice.createInjector(Guice.java:72)
    at com.google.inject.Guice.createInjector(Guice.java:62)
    at ninja.command.CompileCommand.compileXtend(CompileCommand.java:32)
    at ninja.command.CompileCommand.execute(CompileCommand.java:25)
    at ninja.cmd.Main.execute(Main.java:55)
    at ninja.cmd.Main.main(Main.java:25)
Caused by: java.lang.RuntimeException: Cannot create a resource for 'classpath:/org/eclipse/xtend/core/Xtend.xtextbin'; a registered resource factory is needed
    at org.eclipse.xtext.resource.XtextResourceSet.getResource(XtextResourceSet.java:258)
    at org.eclipse.xtext.resource.SynchronizedXtextResourceSet.getResource(SynchronizedXtextResourceSet.java:24)
    at org.eclipse.xtext.parser.BaseEPackageAccess.loadResource(BaseEPackageAccess.java:52)
    ... 45 more
 

Stefan Oehme

unread,
Jul 8, 2015, 4:50:01 PM7/8/15
to xtend...@googlegroups.com

Please use the Xtendstandalonesetup to get the injector. See the maven plug-in I linked for code pointers

--

Carl Perfect

unread,
Jul 8, 2015, 5:02:43 PM7/8/15
to xtend...@googlegroups.com
Thanks, it worked.

For reference, here's the code I used:

    private XtendBatchCompiler setupXtendCompiler() {
        XbaseWithAnnotationsStandaloneSetup.doSetup();
        EPackage.Registry.INSTANCE.put(XtendPackage.eINSTANCE.getNsURI(), XtendPackage.eINSTANCE);
        Injector injector = Guice.createInjector(new XtendRuntimeModule());
        new XtendStandaloneSetupGenerated().register(injector);
        XtendBatchCompiler compiler = injector.getInstance(XtendBatchCompiler.class);
        return compiler;
    }

Carl Perfect

unread,
Jul 8, 2015, 5:58:29 PM7/8/15
to xtend...@googlegroups.com


On Wednesday, July 8, 2015 at 11:02:43 PM UTC+2, Carl Perfect wrote:
Thanks, it worked.


What is the proper way to get the compilation errors?

I see that setErrorWriter is deprecated....

Cheers,
Carl.

Sebastian Zarnekow

unread,
Jul 8, 2015, 7:02:44 PM7/8/15
to xtend...@googlegroups.com
Hi,

most of it can be reduced to new XtendStandaloneSetup().createInjectorAndDoEMFRegistration(), e.g the dance with the EPackage.Registry and XbaseWithAnnotationsStandaloneSetup will be done for you.

To obtain the compiler errors, you may want to use your own subtype of the XtendBatchCompiler and override reportIssues(..).

And just because it has been the cause for trouble in the past:
Please do never ever use the StandaloneSetup in an Equinox OSGi container, e.g. when running in Eclipse. It will be the cause for a bunch of funny effects.

Best,
Sebastian

--
You received this message because you are subscribed to the Google Groups "Xtend Programming Language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to xtend-lang+...@googlegroups.com.

Carl Perfect

unread,
Jul 9, 2015, 10:36:15 AM7/9/15
to xtend...@googlegroups.com


On Thursday, July 9, 2015 at 1:02:44 AM UTC+2, Sebastian Zarnekow wrote:
To obtain the compiler errors, you may want to use your own subtype of the XtendBatchCompiler and override reportIssues(..).


Very helpful, thanks!
Reply all
Reply to author
Forward
0 new messages