[generator2] provide a simpler alternative to StandaloneSetup

This commit is contained in:
Stefan Oehme 2015-10-07 13:49:55 +02:00
parent 0d2e953795
commit 8764c05e56
10 changed files with 211 additions and 112 deletions

View file

@ -19,7 +19,6 @@ import java.util.List
import org.eclipse.emf.common.util.Diagnostic
import org.eclipse.emf.common.util.DiagnosticChain
import org.eclipse.emf.common.util.URI
import org.eclipse.emf.common.util.WrappedException
import org.eclipse.emf.ecore.EValidator
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.emf.ecore.resource.ResourceSet
@ -30,7 +29,6 @@ import org.eclipse.xtext.Grammar
import org.eclipse.xtext.GrammarUtil
import org.eclipse.xtext.ReferencedMetamodel
import org.eclipse.xtext.XtextPackage
import org.eclipse.xtext.ecore.EcoreSupportStandaloneSetup
import org.eclipse.xtext.nodemodel.util.NodeModelUtils
import org.eclipse.xtext.resource.IResourceServiceProvider
import org.eclipse.xtext.resource.XtextResource
@ -59,10 +57,10 @@ class LanguageConfig2 extends CompositeGeneratorFragment2 implements ILanguageCo
ResourceSet resourceSet
@Accessors
Module guiceModule = []
XtextLanguageStandaloneSetup standaloneSetup = new XtextLanguageStandaloneSetup
@Accessors
val List<String> loadedResources = newArrayList
Module guiceModule = []
@Accessors
val runtimeGenSetup = new StandaloneSetupAccess
@ -99,65 +97,13 @@ class LanguageConfig2 extends CompositeGeneratorFragment2 implements ILanguageCo
return fileExtensions
}
def void addLoadedResource(String uri) {
this.loadedResources.add(uri)
}
override initialize(Injector injector) {
fragments.add(0, new ImplicitFragment)
injector.injectMembers(this)
if (resourceSet === null)
resourceSet = resourceSetProvider.get()
for (String loadedResource : loadedResources) {
val loadedResourceUri = URI.createURI(loadedResource)
switch (loadedResourceUri.fileExtension) {
case 'genmodel': {
val resourceServiceProvider = IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(loadedResourceUri)
if (resourceServiceProvider === null) {
try {
val genModelSupport = Class.forName('org.eclipse.emf.codegen.ecore.xtext.GenModelSupport')
val instance = genModelSupport.newInstance()
genModelSupport.getDeclaredMethod('createInjectorAndDoEMFRegistration').invoke(instance)
} catch (ClassNotFoundException e) {
LOG.error("Couldn't initialize GenModel support. Is it on the classpath?")
LOG.debug(e.getMessage(), e)
} catch (Exception e) {
LOG.error("Couldn't initialize GenModel support.", e)
}
}
}
case 'ecore': {
val resourceServiceProvider = IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(loadedResourceUri)
if (resourceServiceProvider === null) {
EcoreSupportStandaloneSetup.setup()
}
}
case 'xcore': {
val resourceServiceProvider = IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(loadedResourceUri)
if (resourceServiceProvider === null) {
try {
val xcore = Class.forName('org.eclipse.emf.ecore.xcore.XcoreStandaloneSetup')
xcore.getDeclaredMethod('doSetup', #[]).invoke(null)
} catch (ClassNotFoundException e) {
LOG.error("Couldn't initialize Xcore support. Is it on the classpath?")
LOG.debug(e.getMessage(), e)
} catch (Exception e) {
LOG.error("Couldn't initialize Xcore support.", e)
}
}
val xcoreLangURI = URI.createPlatformResourceURI('/org.eclipse.emf.ecore.xcore.lib/model/XcoreLang.xcore', true)
try {
resourceSet.getResource(xcoreLangURI, true)
} catch (WrappedException e) {
LOG.error("Could not load XcoreLang.xcore.", e)
val brokenResource = resourceSet.getResource(xcoreLangURI, false)
resourceSet.resources.remove(brokenResource)
}
}
}
resourceSet.getResource(loadedResourceUri, true)
}
standaloneSetup.initialize(injector)
if (!resourceSet.resources.isEmpty) {
installIndex()
for (var i = 0, var size = resourceSet.resources.size; i < size; i++) {

View file

@ -53,6 +53,9 @@ class XtextGenerator extends AbstractWorkflowComponent2 {
@Accessors
XtextDirectoryCleaner cleaner = new XtextDirectoryCleaner
@Accessors
XtextGeneratorStandaloneSetup standaloneSetup = new XtextGeneratorStandaloneSetup
Injector injector
@Inject IXtextProjectConfig projectConfig
@ -100,6 +103,7 @@ class XtextGenerator extends AbstractWorkflowComponent2 {
injector.getInstance(CodeConfig) => [initialize(injector)]
projectConfig.initialize(injector)
cleaner.initialize(injector)
standaloneSetup.initialize(injector)
for (language : languageConfigs) {
val languageInjector = injector.createLanguageInjector(language)
language.initialize(languageInjector)

View file

@ -0,0 +1,53 @@
/*******************************************************************************
* Copyright (c) 2015 itemis AG (http://www.itemis.eu) 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
*******************************************************************************/
package org.eclipse.xtext.xtext.generator
import com.google.inject.Inject
import com.google.inject.Injector
import org.eclipse.emf.mwe.utils.ProjectMapping
import org.eclipse.emf.mwe.utils.StandaloneSetup
import org.eclipse.xtend.lib.annotations.Accessors
import org.eclipse.xtext.util.internal.Log
@Log
class XtextGeneratorStandaloneSetup implements IGuiceAwareGeneratorComponent {
@Inject IXtextProjectConfig projectConfig
@Accessors boolean scanClasspath = true
override initialize(Injector injector) {
injector.injectMembers(this)
setup
}
private def void setup() {
val delegate = new StandaloneSetup
delegate.scanClassPath = scanClasspath
projectMappings.forEach [ mapping |
delegate.addProjectMapping(new ProjectMapping => [
projectName = mapping.key
path = mapping.value.path
])
]
}
private def getProjectMappings() {
#[
projectConfig.runtimeProjectName -> projectConfig.runtimeRoot,
projectConfig.runtimeTestProjectName -> projectConfig.runtimeTestRoot,
projectConfig.genericIdeProjectName -> projectConfig.genericIdeRoot,
projectConfig.genericIdeTestProjectName -> projectConfig.genericIdeTestRoot,
projectConfig.eclipsePluginProjectName -> projectConfig.eclipsePluginRoot,
projectConfig.eclipsePluginTestProjectName -> projectConfig.eclipsePluginTestRoot,
projectConfig.ideaPluginProjectName -> projectConfig.ideaPluginRoot,
projectConfig.ideaPluginTestProjectName -> projectConfig.ideaPluginTestRoot,
projectConfig.webProjectName -> projectConfig.webRoot,
projectConfig.webTestProjectName -> projectConfig.webTestRoot
].filter[key != null && value != null]
}
}

View file

@ -0,0 +1,123 @@
/*******************************************************************************
* Copyright (c) 2015 itemis AG (http://www.itemis.eu) 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
*******************************************************************************/
package org.eclipse.xtext.xtext.generator
import com.google.inject.Injector
import java.util.List
import org.eclipse.emf.codegen.ecore.genmodel.GenModel
import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage
import org.eclipse.emf.common.util.URI
import org.eclipse.emf.common.util.WrappedException
import org.eclipse.emf.ecore.EPackage
import org.eclipse.emf.ecore.resource.ResourceSet
import org.eclipse.emf.mwe.utils.GenModelHelper
import org.eclipse.emf.mwe.utils.StandaloneSetup
import org.eclipse.xtend.lib.annotations.Accessors
import org.eclipse.xtext.ecore.EcoreSupportStandaloneSetup
import org.eclipse.xtext.resource.IResourceServiceProvider
import org.eclipse.xtext.util.internal.Log
import com.google.inject.Inject
@Log
class XtextLanguageStandaloneSetup implements IGuiceAwareGeneratorComponent {
@Accessors List<String> loadedResources = newArrayList
@Inject ILanguageConfig language
def void addLoadedResource(String uri) {
loadedResources += uri
}
override initialize(Injector injector) {
injector.injectMembers(this)
setup(language.resourceSet)
}
private def void setup(ResourceSet resourceSet) {
val delegate = new StandaloneSetup
delegate.resourceSet = resourceSet
loadedResources.forEach[
loadResource(resourceSet)
]
registerGenModels(resourceSet)
registerEPackages(resourceSet)
}
private def loadResource(String loadedResource, ResourceSet resourceSet) {
val loadedResourceUri = URI.createURI(loadedResource)
ensureResourceCanBeLoaded(loadedResourceUri, resourceSet)
resourceSet.getResource(loadedResourceUri, true)
}
private def ensureResourceCanBeLoaded(URI loadedResource, ResourceSet resourceSet) {
switch (loadedResource.fileExtension) {
case 'genmodel': {
GenModelPackage.eINSTANCE.getEFactoryInstance
val resourceServiceProvider = IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(loadedResource)
if (resourceServiceProvider === null) {
try {
val genModelSupport = Class.forName('org.eclipse.emf.codegen.ecore.xtext.GenModelSupport')
val instance = genModelSupport.newInstance()
genModelSupport.getDeclaredMethod('createInjectorAndDoEMFRegistration').invoke(instance)
} catch (ClassNotFoundException e) {
LOG.debug("org.eclipse.emf.codegen.ecore.xtext.GenModelSupport not found, GenModels will not be indexed")
} catch (Exception e) {
LOG.error("Couldn't initialize GenModel support.", e)
}
}
}
case 'ecore': {
val resourceServiceProvider = IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(loadedResource)
if (resourceServiceProvider === null) {
EcoreSupportStandaloneSetup.setup()
}
}
case 'xcore': {
val resourceServiceProvider = IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(loadedResource)
if (resourceServiceProvider === null) {
try {
val xcore = Class.forName('org.eclipse.emf.ecore.xcore.XcoreStandaloneSetup')
xcore.getDeclaredMethod('doSetup', #[]).invoke(null)
} catch (ClassNotFoundException e) {
LOG.error("Couldn't initialize Xcore support. Is it on the classpath?")
LOG.debug(e.getMessage(), e)
} catch (Exception e) {
LOG.error("Couldn't initialize Xcore support.", e)
}
}
val xcoreLangURI = URI.createPlatformResourceURI('/org.eclipse.emf.ecore.xcore.lib/model/XcoreLang.xcore', true)
try {
resourceSet.getResource(xcoreLangURI, true)
} catch (WrappedException e) {
LOG.error("Could not load XcoreLang.xcore.", e)
val brokenResource = resourceSet.getResource(xcoreLangURI, false)
resourceSet.resources.remove(brokenResource)
}
}
}
}
private def registerEPackages(ResourceSet resourceSet) {
resourceSet.resources.map[contents].flatten.filter(EPackage).forEach[registerEPackage]
}
private def registerGenModels(ResourceSet resourceSet) {
resourceSet.resources.map[contents].flatten.filter(GenModel).forEach[registerGenModel]
}
private def registerGenModel(GenModel genModel) {
new GenModelHelper().registerGenModel(genModel)
}
private def registerEPackage(EPackage ePackage) {
val registry = ePackage.eResource.resourceSet.packageRegistry
if (registry.get(ePackage.nsURI) === null) {
registry.put(ePackage.nsURI, ePackage)
}
}
}

View file

@ -162,22 +162,6 @@ class RuntimeProjectDescriptor extends TestedProjectDescriptor {
var fileExtensions = "«config.language.fileExtensions»"
Workflow {
bean = StandaloneSetup {
scanClassPath = true
platformUri = rootPath
«IF fromExistingEcoreModels»
«FOR ePackageInfo : config.ecore2Xtext.EPackageInfos.filter[genmodelURI.fileExtension != "xcore"].map[EPackageJavaFQN].filterNull»
registerGeneratedEPackage = "«ePackageInfo»"
«ENDFOR»
«FOR genmodelURI : config.ecore2Xtext.EPackageInfos.filter[genmodelURI.fileExtension != "xcore"].map[genmodelURI.toString].toSet»
registerGenModelFile = "«genmodelURI»"
«ENDFOR»
«ELSE»
// The following two lines can be removed, if Xbase is not used.
registerGeneratedEPackage = "org.eclipse.xtext.xbase.XbasePackage"
registerGenModelFile = "platform:/resource/org.eclipse.xtext.xbase/model/Xbase.genmodel"
«ENDIF»
}
component = XtextGenerator auto-inject {
configuration = {
@ -209,9 +193,13 @@ class RuntimeProjectDescriptor extends TestedProjectDescriptor {
}
language = auto-inject {
uri = "platform:/resource/${baseName}/«Outlet.MAIN_JAVA.sourceFolder»/«grammarFilePath»"
«FOR genmodelURI : config.ecore2Xtext.EPackageInfos.filter[genmodelURI.fileExtension == "xcore"].map[genmodelURI.toString].toSet»
loadedResource = "«genmodelURI»"
«ENDFOR»
standaloneSetup = {
//can be removed if Xbase is not used
loadedResource = "platform:/resource/org.eclipse.xtext.xbase/model/Xbase.genmodel"
«FOR genmodelURI : config.ecore2Xtext.EPackageInfos.map[genmodelURI.toString].toSet»
loadedResource = "«genmodelURI»"
«ENDFOR»
}
// Java API to access grammar elements (required by several other fragments)
fragment = grammarAccess.GrammarAccessFragment2 auto-inject {}

View file

@ -11,13 +11,6 @@ var rootPath = ".."
var fileExtensions = "mydsl"
Workflow {
bean = StandaloneSetup {
scanClassPath = true
platformUri = rootPath
// The following two lines can be removed, if Xbase is not used.
registerGeneratedEPackage = "org.eclipse.xtext.xbase.XbasePackage"
registerGenModelFile = "platform:/resource/org.eclipse.xtext.xbase/model/Xbase.genmodel"
}
component = XtextGenerator auto-inject {
configuration = {
@ -33,6 +26,10 @@ Workflow {
}
language = auto-inject {
uri = "platform:/resource/${baseName}/src/org/xtext/example/mydsl/MyDsl.xtext"
standaloneSetup = {
//can be removed if Xbase is not used
loadedResource = "platform:/resource/org.eclipse.xtext.xbase/model/Xbase.genmodel"
}
// Java API to access grammar elements (required by several other fragments)
fragment = grammarAccess.GrammarAccessFragment2 auto-inject {}

View file

@ -11,13 +11,6 @@ var rootPath = ".."
var fileExtensions = "mydsl"
Workflow {
bean = StandaloneSetup {
scanClassPath = true
platformUri = rootPath
// The following two lines can be removed, if Xbase is not used.
registerGeneratedEPackage = "org.eclipse.xtext.xbase.XbasePackage"
registerGenModelFile = "platform:/resource/org.eclipse.xtext.xbase/model/Xbase.genmodel"
}
component = XtextGenerator auto-inject {
configuration = {
@ -35,6 +28,10 @@ Workflow {
}
language = auto-inject {
uri = "platform:/resource/${baseName}/src/org/xtext/example/mydsl/MyDsl.xtext"
standaloneSetup = {
//can be removed if Xbase is not used
loadedResource = "platform:/resource/org.eclipse.xtext.xbase/model/Xbase.genmodel"
}
// Java API to access grammar elements (required by several other fragments)
fragment = grammarAccess.GrammarAccessFragment2 auto-inject {}

View file

@ -11,13 +11,6 @@ var rootPath = ".."
var fileExtensions = "mydsl"
Workflow {
bean = StandaloneSetup {
scanClassPath = true
platformUri = rootPath
// The following two lines can be removed, if Xbase is not used.
registerGeneratedEPackage = "org.eclipse.xtext.xbase.XbasePackage"
registerGenModelFile = "platform:/resource/org.eclipse.xtext.xbase/model/Xbase.genmodel"
}
component = XtextGenerator auto-inject {
configuration = {
@ -37,6 +30,10 @@ Workflow {
}
language = auto-inject {
uri = "platform:/resource/${baseName}/src/main/java/org/xtext/example/mydsl/MyDsl.xtext"
standaloneSetup = {
//can be removed if Xbase is not used
loadedResource = "platform:/resource/org.eclipse.xtext.xbase/model/Xbase.genmodel"
}
// Java API to access grammar elements (required by several other fragments)
fragment = grammarAccess.GrammarAccessFragment2 auto-inject {}

View file

@ -11,13 +11,6 @@ var rootPath = ".."
var fileExtensions = "mydsl"
Workflow {
bean = StandaloneSetup {
scanClassPath = true
platformUri = rootPath
// The following two lines can be removed, if Xbase is not used.
registerGeneratedEPackage = "org.eclipse.xtext.xbase.XbasePackage"
registerGenModelFile = "platform:/resource/org.eclipse.xtext.xbase/model/Xbase.genmodel"
}
component = XtextGenerator auto-inject {
configuration = {
@ -34,6 +27,10 @@ Workflow {
}
language = auto-inject {
uri = "platform:/resource/${baseName}/src/org/xtext/example/mydsl/MyDsl.xtext"
standaloneSetup = {
//can be removed if Xbase is not used
loadedResource = "platform:/resource/org.eclipse.xtext.xbase/model/Xbase.genmodel"
}
// Java API to access grammar elements (required by several other fragments)
fragment = grammarAccess.GrammarAccessFragment2 auto-inject {}

View file

@ -11,13 +11,6 @@ var rootPath = ".."
var fileExtensions = "mydsl"
Workflow {
bean = StandaloneSetup {
scanClassPath = true
platformUri = rootPath
// The following two lines can be removed, if Xbase is not used.
registerGeneratedEPackage = "org.eclipse.xtext.xbase.XbasePackage"
registerGenModelFile = "platform:/resource/org.eclipse.xtext.xbase/model/Xbase.genmodel"
}
component = XtextGenerator auto-inject {
configuration = {
@ -36,6 +29,10 @@ Workflow {
}
language = auto-inject {
uri = "platform:/resource/${baseName}/src/main/java/org/xtext/example/mydsl/MyDsl.xtext"
standaloneSetup = {
//can be removed if Xbase is not used
loadedResource = "platform:/resource/org.eclipse.xtext.xbase/model/Xbase.genmodel"
}
// Java API to access grammar elements (required by several other fragments)
fragment = grammarAccess.GrammarAccessFragment2 auto-inject {}