[generator] Added exporting fragments, added factory for Java and Xtend files

Signed-off-by: Miro Spönemann <miro.spoenemann@itemis.de>
This commit is contained in:
Miro Spönemann 2015-07-10 15:20:54 +02:00
parent 03d9f55611
commit ca7fff0d32
10 changed files with 158 additions and 49 deletions

View file

@ -27,10 +27,10 @@ import org.eclipse.xtext.Constants
import org.eclipse.xtext.ISetup
import org.eclipse.xtext.ISetupExtension
import org.eclipse.xtext.XtextPackage
import org.eclipse.xtext.parser.IEncodingProvider
import org.eclipse.xtext.resource.impl.BinaryGrammarResourceFactoryImpl
import org.eclipse.xtext.service.SingletonBinding
import org.eclipse.xtext.util.Modules2
import org.eclipse.xtext.xtext.generator.model.FileAccessFactory
import org.eclipse.xtext.xtext.generator.model.GuiceModuleAccess
import org.eclipse.xtext.xtext.generator.model.JavaFileAccess
import org.eclipse.xtext.xtext.generator.model.ManifestAccess
@ -45,13 +45,10 @@ import static extension org.eclipse.xtext.xtext.generator.model.TypeReference.*
@Singleton
class XtextGeneratorTemplates {
@Inject CodeConfig codeConfig
@Inject IEncodingProvider encodingProvider
@Inject FileAccessFactory fileAccessFactory
def TextFileAccess createPluginXml(PluginXmlAccess pluginXml) {
val file = new TextFileAccess
file.encodingProvider = encodingProvider
val file = fileAccessFactory.createTextFile()
file.path = pluginXml.path
file.content = '''
<?xml version="1.0" encoding="UTF-8"?>
@ -68,8 +65,7 @@ class XtextGeneratorTemplates {
def JavaFileAccess createRuntimeSetup(LanguageConfig2 langConfig) {
val it = langConfig.naming
val javaFile = new JavaFileAccess(runtimeSetup, codeConfig)
javaFile.encodingProvider = encodingProvider
val javaFile = fileAccessFactory.createJavaFile(runtimeSetup)
javaFile.typeComment = '''
/**
@ -90,8 +86,7 @@ class XtextGeneratorTemplates {
def JavaFileAccess createRuntimeGenSetup(LanguageConfig2 langConfig) {
val it = langConfig.naming
val javaFile = new JavaFileAccess(runtimeGenSetup, codeConfig)
javaFile.encodingProvider = encodingProvider
val javaFile = fileAccessFactory.createJavaFile(runtimeGenSetup)
for (type : langConfig.runtimeGenSetup.imports) {
javaFile.importType(type)
}
@ -186,8 +181,7 @@ class XtextGeneratorTemplates {
def JavaFileAccess createRuntimeModule(LanguageConfig2 langConfig) {
val it = langConfig.naming
val javaFile = new JavaFileAccess(runtimeModule, codeConfig)
javaFile.encodingProvider = encodingProvider
val javaFile = fileAccessFactory.createJavaFile(runtimeModule)
javaFile.typeComment = '''
/**
* Use this class to register components to be used at runtime / without the Equinox extension registry.
@ -204,8 +198,7 @@ class XtextGeneratorTemplates {
def JavaFileAccess createRuntimeGenModule(LanguageConfig2 langConfig) {
val it = langConfig.naming
val superClass = langConfig.runtimeGenModule.superClass ?: runtimeDefaultModule
val javaFile = new JavaFileAccess(runtimeGenModule, codeConfig)
javaFile.encodingProvider = encodingProvider
val javaFile = fileAccessFactory.createJavaFile(runtimeGenModule)
javaFile.importNestedTypeThreshold = JavaFileAccess.DONT_IMPORT_NESTED_TYPES
javaFile.typeComment = '''
@ -246,8 +239,7 @@ class XtextGeneratorTemplates {
def JavaFileAccess createEclipsePluginModule(LanguageConfig2 langConfig) {
val it = langConfig.naming
val javaFile = new JavaFileAccess(eclipsePluginModule, codeConfig)
javaFile.encodingProvider = encodingProvider
val javaFile = fileAccessFactory.createJavaFile(eclipsePluginModule)
javaFile.typeComment = '''
/**
* Use this class to register components to be used within the Eclipse IDE.
@ -266,8 +258,7 @@ class XtextGeneratorTemplates {
def JavaFileAccess createEclipsePluginGenModule(LanguageConfig2 langConfig) {
val it = langConfig.naming
val superClass = langConfig.eclipsePluginGenModule.superClass ?: eclipsePluginDefaultModule
val javaFile = new JavaFileAccess(eclipsePluginGenModule, codeConfig)
javaFile.encodingProvider = encodingProvider
val javaFile = fileAccessFactory.createJavaFile(eclipsePluginGenModule)
javaFile.importNestedTypeThreshold = JavaFileAccess.DONT_IMPORT_NESTED_TYPES
javaFile.typeComment = '''
@ -294,8 +285,7 @@ class XtextGeneratorTemplates {
}
def TextFileAccess createManifest(ManifestAccess manifest, TypeReference activator) {
val file = new TextFileAccess
file.encodingProvider = encodingProvider
val file = fileAccessFactory.createTextFile()
file.path = manifest.path
file.content = '''
Manifest-Version: 1.0
@ -324,8 +314,7 @@ class XtextGeneratorTemplates {
}
def JavaFileAccess createEclipsePluginExecutableExtensionFactory(LanguageConfig2 langConfig, LanguageConfig2 activatorLanguage) {
val javaFile = new JavaFileAccess(langConfig.naming.eclipsePluginExecutableExtensionFactory, codeConfig)
javaFile.encodingProvider = encodingProvider
val javaFile = fileAccessFactory.createJavaFile(langConfig.naming.eclipsePluginExecutableExtensionFactory)
javaFile.typeComment = '''
/**
@ -354,8 +343,7 @@ class XtextGeneratorTemplates {
def JavaFileAccess createEclipsePluginActivator(List<LanguageConfig2> langConfigs) {
val activator = langConfigs.head.naming.eclipsePluginActivator
val javaFile = new JavaFileAccess(activator, codeConfig)
javaFile.encodingProvider = encodingProvider
val javaFile = fileAccessFactory.createJavaFile(activator)
javaFile.typeComment = '''
/**

View file

@ -44,14 +44,14 @@ class BuilderIntegrationFragment2 extends AbstractGeneratorFragment2 {
'''binder.bind(«IResourceDescriptions».class).to(«ResourceSetBasedResourceDescriptions».class);'''
val StringConcatenationClient statement2 =
'''binder.bind(«IResourceDescriptions».class).annotatedWith(«Names».named(«ResourceDescriptionsProvider».PERSISTED_DESCRIPTIONS)).to(«ResourceSetBasedResourceDescriptions».class);'''
val bindingFactory = new GuiceModuleAccess.BindingFactory()
new GuiceModuleAccess.BindingFactory()
.addTypeToType(IContainer.Manager.typeRef,
StateBasedContainerManager.typeRef)
.addTypeToType(IAllContainersState.Provider.typeRef,
ResourceSetBasedAllContainersStateProvider.typeRef)
.addConfiguredBinding(IResourceDescriptions.simpleName, statement1)
.addConfiguredBinding(IResourceDescriptions.simpleName + 'Persisted', statement2)
bindingFactory.contributeTo(language.runtimeGenModule)
.contributeTo(language.runtimeGenModule)
}
protected def addEclipsePluginGuiceBindings(LanguageConfig2 language) {
@ -59,7 +59,7 @@ class BuilderIntegrationFragment2 extends AbstractGeneratorFragment2 {
'''binder.bind(«IResourceDescriptions».class).annotatedWith(«Names».named(«ResourceDescriptionsProvider».NAMED_BUILDER_SCOPE)).to(«'org.eclipse.xtext.builder.clustering.CurrentDescriptions.ResourceSetAware'.typeRef».class);'''
val StringConcatenationClient statement2 =
'''binder.bind(«IResourceDescriptions».class).annotatedWith(«Names».named(«ResourceDescriptionsProvider».PERSISTED_DESCRIPTIONS)).to(«'org.eclipse.xtext.builder.builderState.IBuilderState'.typeRef».class);'''
val bindingFactory = new GuiceModuleAccess.BindingFactory()
new GuiceModuleAccess.BindingFactory()
.addConfiguredBinding(IResourceDescriptions.simpleName + 'BuilderScope', statement1)
.addTypeToType('org.eclipse.xtext.ui.editor.IXtextEditorCallback'.typeRef,
'org.eclipse.xtext.builder.nature.NatureAddingEditorCallback'.typeRef)
@ -68,7 +68,7 @@ class BuilderIntegrationFragment2 extends AbstractGeneratorFragment2 {
.addConfiguredBinding(IResourceDescriptions.simpleName + 'Persisted', statement2)
.addTypeToType('org.eclipse.xtext.ui.editor.DocumentBasedDirtyResource'.typeRef,
'org.eclipse.xtext.builder.impl.PersistentDataAwareDirtyResource'.typeRef)
bindingFactory.contributeTo(language.eclipsePluginGenModule)
.contributeTo(language.eclipsePluginGenModule)
}
}

View file

@ -0,0 +1,32 @@
/*******************************************************************************
* 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.exporting
import org.eclipse.xtext.naming.DefaultDeclarativeQualifiedNameProvider
import org.eclipse.xtext.naming.IQualifiedNameProvider
import org.eclipse.xtext.xtext.generator.AbstractGeneratorFragment2
import org.eclipse.xtext.xtext.generator.LanguageConfig2
import org.eclipse.xtext.xtext.generator.model.GuiceModuleAccess
import static extension org.eclipse.xtext.xtext.generator.model.TypeReference.*
class QualifiedNamesFragment2 extends AbstractGeneratorFragment2 {
override generate(LanguageConfig2 language) {
new GuiceModuleAccess.BindingFactory()
.addTypeToType(IQualifiedNameProvider.typeRef, DefaultDeclarativeQualifiedNameProvider.typeRef)
.contributeTo(language.runtimeGenModule)
new GuiceModuleAccess.BindingFactory()
.addTypeToType('org.eclipse.xtext.ui.editor.contentassist.PrefixMatcher'.typeRef,
'org.eclipse.xtext.ui.editor.contentassist.FQNPrefixMatcher'.typeRef)
.addTypeToType('org.eclipse.xtext.ui.refactoring.IDependentElementsCalculator'.typeRef,
'org.eclipse.xtext.ui.refactoring.impl.DefaultDependentElementsCalculator'.typeRef)
.contributeTo(language.eclipsePluginGenModule)
}
}

View file

@ -0,0 +1,30 @@
/*******************************************************************************
* 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.exporting
import org.eclipse.xtext.naming.IQualifiedNameProvider
import org.eclipse.xtext.naming.SimpleNameProvider
import org.eclipse.xtext.xtext.generator.AbstractGeneratorFragment2
import org.eclipse.xtext.xtext.generator.LanguageConfig2
import org.eclipse.xtext.xtext.generator.model.GuiceModuleAccess
import static extension org.eclipse.xtext.xtext.generator.model.TypeReference.*
class SimpleNamesFragment2 extends AbstractGeneratorFragment2 {
override generate(LanguageConfig2 language) {
new GuiceModuleAccess.BindingFactory()
.addfinalTypeToType(IQualifiedNameProvider.typeRef, SimpleNameProvider.typeRef)
.contributeTo(language.runtimeGenModule)
new GuiceModuleAccess.BindingFactory()
.addTypeToType('org.eclipse.xtext.ui.refactoring.IDependentElementsCalculator'.typeRef,
'org.eclipse.xtext.ui.refactoring.impl.DefaultDependentElementsCalculator'.typeRef)
.contributeTo(language.eclipsePluginGenModule)
}
}

View file

@ -0,0 +1,44 @@
/*******************************************************************************
* 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.model
import com.google.inject.Inject
import com.google.inject.Provider
import org.eclipse.emf.ecore.resource.ResourceSet
import org.eclipse.xtend.lib.annotations.Accessors
import org.eclipse.xtext.parser.IEncodingProvider
import org.eclipse.xtext.xtext.generator.CodeConfig
class FileAccessFactory {
@Inject CodeConfig codeConfig
@Inject IEncodingProvider encodingProvider
@Inject Provider<ResourceSet> resourceSetProvider
@Accessors(PUBLIC_SETTER)
ResourceSet resourceSet
def TextFileAccess createTextFile() {
new TextFileAccess(encodingProvider)
}
def JavaFileAccess createJavaFile(TypeReference typeRef) {
val file = new JavaFileAccess(typeRef, codeConfig, encodingProvider)
file.resourceSet = resourceSet ?: resourceSetProvider.get
return file
}
def XtendFileAccess createXtendFile(TypeReference typeRef) {
val file = new XtendFileAccess(typeRef, codeConfig, encodingProvider)
file.resourceSet = resourceSet ?: resourceSetProvider.get
return file
}
}

View file

@ -12,9 +12,12 @@ import java.util.Collections
import java.util.List
import java.util.Map
import org.eclipse.emf.codegen.util.CodeGenUtil
import org.eclipse.emf.ecore.EClass
import org.eclipse.emf.ecore.resource.ResourceSet
import org.eclipse.xtend.lib.annotations.Accessors
import org.eclipse.xtend2.lib.StringConcatenation
import org.eclipse.xtend2.lib.StringConcatenationClient
import org.eclipse.xtext.parser.IEncodingProvider
import org.eclipse.xtext.xtext.generator.CodeConfig
class JavaFileAccess extends TextFileAccess {
@ -39,11 +42,11 @@ class JavaFileAccess extends TextFileAccess {
@Accessors
val List<IClassAnnotation> annotations = newArrayList
new(String qualifiedName, CodeConfig codeConfig) {
this(new TypeReference(qualifiedName), codeConfig)
}
@Accessors(PROTECTED_SETTER)
ResourceSet resourceSet
new(TypeReference typeRef, CodeConfig codeConfig) {
protected new(TypeReference typeRef, CodeConfig codeConfig, IEncodingProvider encodingProvider) {
super(encodingProvider)
if (typeRef.simpleNames.length > 1)
throw new IllegalArgumentException('Nested type cannot be serialized: ' + typeRef)
this.javaType = typeRef
@ -131,6 +134,8 @@ class JavaFileAccess extends TextFileAccess {
access.importType(object)
else if (object instanceof Class<?>)
access.importType(new TypeReference(object))
else if (object instanceof EClass)
access.importType(new TypeReference(object, access.resourceSet))
else
object.toString
}

View file

@ -18,14 +18,17 @@ import org.eclipse.xtext.parser.IEncodingProvider
class TextFileAccess {
val IEncodingProvider encodingProvider
@Accessors
String path
@Accessors
CharSequence content
@Accessors
IEncodingProvider encodingProvider
protected new(IEncodingProvider encodingProvider) {
this.encodingProvider = encodingProvider
}
def CharSequence generate() {
return content

View file

@ -9,9 +9,12 @@ package org.eclipse.xtext.xtext.generator.model
import java.util.Collections
import java.util.List
import java.util.regex.Pattern
import org.eclipse.emf.ecore.EClass
import org.eclipse.emf.ecore.resource.ResourceSet
import org.eclipse.xtend.lib.annotations.Accessors
import org.eclipse.xtend.lib.annotations.EqualsHashCode
import java.util.regex.Pattern
import org.eclipse.xtext.xtext.generator.GenModelUtil
@Accessors
@EqualsHashCode
@ -25,6 +28,10 @@ class TypeReference {
new TypeReference(clazz, arguments.map[new TypeReference(it)])
}
static def TypeReference typeRef(EClass clazz, ResourceSet resourceSet, EClass... arguments) {
new TypeReference(clazz, resourceSet, arguments.map[new TypeReference(it, resourceSet)])
}
static val PACKAGE_MATCHER = Pattern.compile('[a-z][a-zA-Z0-9_]*(\\.[a-z][a-zA-Z0-9_]*)*')
static val CLASS_MATCHER = Pattern.compile('[A-Z][a-zA-Z0-9_]*(\\.[A-Z][a-zA-Z0-9_]*)*')
@ -77,6 +84,14 @@ class TypeReference {
} while (c !== null)
}
new(EClass clazz, ResourceSet resourceSet) {
this(clazz, resourceSet, null)
}
new(EClass clazz, ResourceSet resourceSet, List<TypeReference> arguments) {
this(GenModelUtil.getGenClass(clazz, resourceSet).qualifiedInterfaceName, arguments)
}
private static def getPackageName(String qualifiedName) {
var packageEnd = qualifiedName.length
for (var i = qualifiedName.length - 1; i >= 0; i--) {

View file

@ -7,16 +7,13 @@
*******************************************************************************/
package org.eclipse.xtext.xtext.generator.model
import org.eclipse.xtext.parser.IEncodingProvider
import org.eclipse.xtext.xtext.generator.CodeConfig
class XtendFileAccess extends JavaFileAccess {
new(String qualifiedName, CodeConfig codeConfig) {
super(qualifiedName, codeConfig)
}
new(TypeReference typeRef, CodeConfig codeConfig) {
super(typeRef, codeConfig)
protected new(TypeReference typeRef, CodeConfig codeConfig, IEncodingProvider encodingProvider) {
super(typeRef, codeConfig, encodingProvider)
}
override protected getFileExtension() {

View file

@ -16,7 +16,6 @@ import org.eclipse.xtext.AbstractRule
import org.eclipse.xtext.Grammar
import org.eclipse.xtext.GrammarUtil
import org.eclipse.xtext.naming.IQualifiedNameProvider
import org.eclipse.xtext.parser.IEncodingProvider
import org.eclipse.xtext.resource.ILocationInFileProvider
import org.eclipse.xtext.scoping.IGlobalScopeProvider
import org.eclipse.xtext.scoping.IScopeProvider
@ -24,13 +23,12 @@ import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider
import org.eclipse.xtext.validation.IResourceValidator
import org.eclipse.xtext.xtext.UsedRulesFinder
import org.eclipse.xtext.xtext.generator.AbstractGeneratorFragment2
import org.eclipse.xtext.xtext.generator.CodeConfig
import org.eclipse.xtext.xtext.generator.IXtextProjectConfig
import org.eclipse.xtext.xtext.generator.LanguageConfig2
import org.eclipse.xtext.xtext.generator.model.FileAccessFactory
import org.eclipse.xtext.xtext.generator.model.FileSystemAccess
import org.eclipse.xtext.xtext.generator.model.GuiceModuleAccess
import org.eclipse.xtext.xtext.generator.model.TypeReference
import org.eclipse.xtext.xtext.generator.model.XtendFileAccess
import static extension org.eclipse.xtext.xtext.generator.GenModelUtil.*
import static extension org.eclipse.xtext.xtext.generator.model.TypeReference.*
@ -60,9 +58,7 @@ class XbaseGeneratorFragment2 extends AbstractGeneratorFragment2 {
@Inject IXtextProjectConfig projectConfig
@Inject CodeConfig codeConfig
@Inject IEncodingProvider encodingProvider
@Inject FileAccessFactory fileAccessFactory
@Inject extension FileSystemAccess.Extensions
@ -218,8 +214,7 @@ class XbaseGeneratorFragment2 extends AbstractGeneratorFragment2 {
}
protected def doGenerateXtendInferrer(LanguageConfig2 language) {
val xtendFile = new XtendFileAccess(language.jvmModelInferrer, codeConfig)
xtendFile.encodingProvider = encodingProvider
val xtendFile = fileAccessFactory.createXtendFile(language.jvmModelInferrer)
xtendFile.typeComment = '''
/**