mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-16 16:58:56 +00:00
[generator] Added new Xbase and Xtype fragments
Signed-off-by: Miro Spönemann <miro.spoenemann@itemis.de>
This commit is contained in:
parent
cbae054be0
commit
e3bd95a4f6
11 changed files with 797 additions and 14 deletions
|
@ -0,0 +1,24 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2014 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 org.eclipse.xtext.xtext.generator.IGeneratorFragment2
|
||||
import org.eclipse.emf.mwe.core.issues.Issues
|
||||
import com.google.inject.Injector
|
||||
|
||||
abstract class AbstractGeneratorFragment2 implements IGeneratorFragment2 {
|
||||
|
||||
override checkConfiguration(XtextGenerator generator, Issues issues) {
|
||||
// Override this method to check the configured properties of this fragment
|
||||
}
|
||||
|
||||
override initialize(Injector injector) {
|
||||
injector.injectMembers(this)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,170 @@
|
|||
/**
|
||||
* Copyright (c) 2011 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 org.eclipse.emf.codegen.ecore.genmodel.GenClass
|
||||
import org.eclipse.emf.codegen.ecore.genmodel.GenClassifier
|
||||
import org.eclipse.emf.codegen.ecore.genmodel.GenDataType
|
||||
import org.eclipse.emf.codegen.ecore.genmodel.GenEnum
|
||||
import org.eclipse.emf.codegen.ecore.genmodel.GenFeature
|
||||
import org.eclipse.emf.codegen.ecore.genmodel.GenModel
|
||||
import org.eclipse.emf.codegen.ecore.genmodel.GenPackage
|
||||
import org.eclipse.emf.ecore.EClass
|
||||
import org.eclipse.emf.ecore.EClassifier
|
||||
import org.eclipse.emf.ecore.EDataType
|
||||
import org.eclipse.emf.ecore.EEnum
|
||||
import org.eclipse.emf.ecore.EObject
|
||||
import org.eclipse.emf.ecore.EPackage
|
||||
import org.eclipse.emf.ecore.EStructuralFeature
|
||||
import org.eclipse.emf.ecore.EcorePackage
|
||||
import org.eclipse.emf.ecore.plugin.EcorePlugin
|
||||
import org.eclipse.emf.ecore.resource.Resource
|
||||
import org.eclipse.emf.ecore.resource.ResourceSet
|
||||
|
||||
class GenModelUtil {
|
||||
|
||||
def static GenClass getGenClass(EClass cls, ResourceSet resourceSet) {
|
||||
return getGenClassifier(cls, resourceSet) as GenClass
|
||||
}
|
||||
|
||||
def static GenClassifier getGenClassifier(EClassifier cls, ResourceSet resourceSet) {
|
||||
val genPackage = getGenPackage(cls.EPackage, resourceSet)
|
||||
for (genCls : genPackage.genClassifiers) {
|
||||
if (cls.name == genCls.ecoreClassifier.name) {
|
||||
return genCls
|
||||
}
|
||||
}
|
||||
throw new RuntimeException('''No GenClassifier named '«cls.name»' found in GenModel «genPackage.eResource.URI»''')
|
||||
}
|
||||
|
||||
def static GenDataType getGenDataType(EDataType dt, ResourceSet resourceSet) {
|
||||
return getGenClassifier(dt, resourceSet) as GenDataType
|
||||
}
|
||||
|
||||
def static GenEnum getGenEnum(EEnum en, ResourceSet resourceSet) {
|
||||
return getGenClassifier(en, resourceSet) as GenEnum
|
||||
}
|
||||
|
||||
def static GenFeature getGenFeature(EStructuralFeature feature, ResourceSet resourceSet) {
|
||||
val genCls = getGenClassifier(feature.EContainingClass, resourceSet) as GenClass
|
||||
for (genFeat : genCls.genFeatures) {
|
||||
if (feature.name == genFeat.ecoreFeature.name) {
|
||||
return genFeat
|
||||
}
|
||||
}
|
||||
throw new RuntimeException('''No GenFeature named '«feature.name»' found in GenClass '«genCls»' from GenModel«genCls.eResource.URI»''')
|
||||
}
|
||||
|
||||
def static String getGenIntLiteral(EClass clazz, EStructuralFeature feature, ResourceSet resourceSet) {
|
||||
val genFeature = getGenFeature(feature, resourceSet)
|
||||
val genClass = getGenClass(clazz, resourceSet)
|
||||
return genClass.genPackage.packageInterfaceName + '.' + genClass.getFeatureID(genFeature)
|
||||
}
|
||||
|
||||
def static String getGenIntLiteral(EClassifier classifier, ResourceSet resourceSet) {
|
||||
val genClassifier = getGenClassifier(classifier, resourceSet)
|
||||
return genClassifier.genPackage.packageInterfaceName + '.' + genClassifier.classifierID
|
||||
}
|
||||
|
||||
def static GenPackage getGenPackage(EPackage pkg, ResourceSet resourceSet) {
|
||||
val nsURI = pkg.nsURI
|
||||
var String location
|
||||
if (pkg.eResource?.URI !== null)
|
||||
location = pkg.eResource.URI.toString
|
||||
val genModelResource = getGenModelResource(location, nsURI, resourceSet)
|
||||
if (genModelResource !== null) {
|
||||
for (model : genModelResource.contents) {
|
||||
if (model instanceof GenModel) {
|
||||
val genPkg = model.findGenPackage(pkg)
|
||||
if (genPkg !== null) {
|
||||
genPkg.getEcorePackage.getEClassifiers()
|
||||
return genPkg
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new RuntimeException('''No GenPackage for NsURI «nsURI» found in «genModelResource.URI»''')
|
||||
}
|
||||
throw new RuntimeException('''No GenPackage for NsURI «nsURI».''')
|
||||
}
|
||||
|
||||
def static Resource getGenModelResource(String locationInfo, String nsURI, ResourceSet resourceSet) {
|
||||
val genModelURI = EcorePlugin.getEPackageNsURIToGenModelLocationMap(false).get(nsURI)
|
||||
if (genModelURI === null) {
|
||||
if (EcorePackage.eNS_URI.equals(nsURI)) // If we really want to use the registered ecore ...
|
||||
return null // look into the resource set to find a genpackage for the given URI
|
||||
for (res : resourceSet.resources) {
|
||||
// We only look into the first level, as genmodels are usually among the top level elements.
|
||||
// This is just to avoid traversing all eobjects in the resource set.
|
||||
for (obj : res.contents) {
|
||||
if (obj instanceof GenModel) {
|
||||
for (genPackage : obj.genPackages) {
|
||||
if (genPackage.NSURI.equals(nsURI)) {
|
||||
return genPackage.eResource
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
val buf = new StringBuilder
|
||||
var loc = locationInfo
|
||||
if (loc !== null && loc.length > 0)
|
||||
loc = ' from ' + loc
|
||||
else
|
||||
loc = ''
|
||||
buf.append("Could not find a GenModel for EPackage '").append(nsURI).append("'").append(loc).append("\n")
|
||||
// TODO replace with references to new fragments
|
||||
buf.append('''If the missing GenModel has been generated via EMFGeneratorFragment.class.getSimpleName() or org.eclipse.xtext.generator.ecore.EcoreGeneratorFragment.class.getSimpleName()''')
|
||||
buf.append(" make sure to run it first in the workflow.\n")
|
||||
buf.append('''If you have a *.genmodel-file, make sure to register it via StandaloneSetup.registerGenModelFile(String)''')
|
||||
throw new RuntimeException(buf.toString)
|
||||
}
|
||||
if (resourceSet === null)
|
||||
throw new RuntimeException('''There is no ResourceSet for EPackage '«nsURI»'. Please make sure the EPackage has been loaded from a .ecore file and not from the generated Java file.''')
|
||||
val genModelResource = resourceSet.getResource(genModelURI, true)
|
||||
if (genModelResource === null)
|
||||
throw new RuntimeException('''Error loading GenModel «genModelURI»''')
|
||||
for (EObject content : genModelResource.contents) {
|
||||
if (content instanceof GenModel)
|
||||
content.reconcile()
|
||||
}
|
||||
return genModelResource
|
||||
}
|
||||
|
||||
def static String getGenTypeLiteral(EClassifier classifier, ResourceSet resourceSet) {
|
||||
// inspired by org.eclipse.emf.codegen.ecore.genmodel.impl.GenClassifierImpl.getQualifiedClassifierAccessor()
|
||||
val genClassifier = getGenClassifier(classifier, resourceSet)
|
||||
var String pkg = genClassifier.genPackage.packageInterfaceName
|
||||
if (genClassifier.genPackage.isLiteralsInterface)
|
||||
return pkg + '.Literals.' + genClassifier.classifierID
|
||||
else
|
||||
return pkg + '.eINSTANCE.get' + genClassifier.classifierAccessorName + '()'
|
||||
}
|
||||
|
||||
def static String getGenTypeLiteral(EPackage pkg, ResourceSet resourceSet) {
|
||||
return getGenPackage(pkg, resourceSet).packageInterfaceName + '.eINSTANCE'
|
||||
}
|
||||
|
||||
def static String getGenTypeLiteral(EStructuralFeature feature, ResourceSet resourceSet) {
|
||||
// inspired by org.eclipse.emf.codegen.ecore.genmodel.impl.GenFeatureImpl.getQualifiedFeatureAccessor()
|
||||
val genFeature = getGenFeature(feature, resourceSet)
|
||||
val pkg = genFeature.genPackage.packageInterfaceName
|
||||
if (genFeature.genPackage.isLiteralsInterface)
|
||||
return pkg + '.Literals.' + genFeature.genClass.getFeatureID(genFeature)
|
||||
else
|
||||
return pkg + '.eINSTANCE.get' + genFeature.featureAccessorName + '()'
|
||||
}
|
||||
|
||||
def static String getJavaTypeName(EClassifier classifier, ResourceSet resourceSet) {
|
||||
val genClassifier = getGenClassifier(classifier, resourceSet)
|
||||
if (genClassifier instanceof GenClass)
|
||||
return genClassifier.qualifiedInterfaceName
|
||||
else
|
||||
return (genClassifier as GenDataType).qualifiedInstanceClassName
|
||||
}
|
||||
|
||||
}
|
|
@ -39,7 +39,7 @@ import org.eclipse.xtext.resource.impl.ResourceDescriptionsData
|
|||
import org.eclipse.xtext.util.internal.Log
|
||||
import org.eclipse.xtext.xtext.generator.model.GuiceModuleAccess
|
||||
import org.eclipse.xtext.xtext.generator.model.StandaloneSetupAccess
|
||||
import org.eclipse.xtext.xtext.generator.model.TypeReference
|
||||
import org.eclipse.xtext.xtext.generator.xbase.XbaseGeneratorFragment2
|
||||
|
||||
import static extension org.eclipse.xtext.xtext.generator.model.TypeReference.*
|
||||
|
||||
|
@ -83,7 +83,7 @@ class LanguageConfig2 extends CompositeGeneratorFragment2 {
|
|||
}
|
||||
|
||||
def void setFileExtensions(String fileExtensions) {
|
||||
this.fileExtensions = fileExtensions.trim.split("\\s*,\\s*").toList
|
||||
this.fileExtensions = fileExtensions.trim.split('\\s*,\\s*').toList
|
||||
}
|
||||
|
||||
def List<String> getFileExtensions() {
|
||||
|
@ -254,11 +254,11 @@ class LanguageConfig2 extends CompositeGeneratorFragment2 {
|
|||
}
|
||||
|
||||
override generate(LanguageConfig2 language) {
|
||||
addImplicitContributions()
|
||||
addImplicitContributions(language)
|
||||
super.generate(language)
|
||||
}
|
||||
|
||||
protected def void addImplicitContributions() {
|
||||
protected def void addImplicitContributions(LanguageConfig2 language) {
|
||||
if (projectConfig.runtimeManifest !== null) {
|
||||
projectConfig.runtimeManifest.requiredBundles.addAll(#[
|
||||
'org.eclipse.xtext', 'org.eclipse.xtext.util'
|
||||
|
@ -270,10 +270,19 @@ class LanguageConfig2 extends CompositeGeneratorFragment2 {
|
|||
'org.eclipse.xtext.ui', 'org.eclipse.xtext.ui.shared', 'org.eclipse.ui.editors', 'org.eclipse.ui'
|
||||
])
|
||||
}
|
||||
|
||||
val StringConcatenationClient expression = '''«'org.eclipse.xtext.ui.shared.Access'.typeRef».getJavaProjectsState()'''
|
||||
new GuiceModuleAccess.BindingFactory()
|
||||
.addTypeToProviderInstance(new TypeReference(IAllContainersState), expression)
|
||||
.contributeTo(eclipsePluginGenModule)
|
||||
val bindingFactory = new GuiceModuleAccess.BindingFactory()
|
||||
.addTypeToProviderInstance(IAllContainersState.typeRef, expression)
|
||||
if (XbaseGeneratorFragment2.inheritsXbase(language.grammar)) {
|
||||
bindingFactory.addTypeToType('org.eclipse.xtext.ui.editor.XtextEditor'.typeRef,
|
||||
'org.eclipse.xtext.xbase.ui.editor.XbaseEditor'.typeRef)
|
||||
.addTypeToType('org.eclipse.xtext.ui.editor.model.XtextDocumentProvider'.typeRef,
|
||||
'org.eclipse.xtext.xbase.ui.editor.XbaseDocumentProvider'.typeRef)
|
||||
.addTypeToType('org.eclipse.xtext.ui.generator.trace.OpenGeneratedFileHandler'.typeRef,
|
||||
'org.eclipse.xtext.xbase.ui.generator.trace.XbaseOpenGeneratedFileHandler'.typeRef)
|
||||
}
|
||||
bindingFactory.contributeTo(eclipsePluginGenModule)
|
||||
}
|
||||
|
||||
}
|
|
@ -29,6 +29,7 @@ import org.eclipse.xtext.Grammar
|
|||
import org.eclipse.xtext.XtextStandaloneSetup
|
||||
import org.eclipse.xtext.util.MergeableManifest
|
||||
import org.eclipse.xtext.util.internal.Log
|
||||
import org.eclipse.xtext.xtext.generator.model.FileSystemAccess
|
||||
import org.eclipse.xtext.xtext.generator.model.ManifestAccess
|
||||
import org.eclipse.xtext.xtext.generator.model.TypeReference
|
||||
|
||||
|
@ -53,6 +54,8 @@ class XtextGenerator extends AbstractWorkflowComponent2 implements IGuiceAwareGe
|
|||
|
||||
@Inject XtextGeneratorTemplates templates
|
||||
|
||||
@Inject extension FileSystemAccess.Extensions
|
||||
|
||||
new() {
|
||||
new XtextStandaloneSetup().createInjectorAndDoEMFRegistration()
|
||||
}
|
||||
|
@ -123,17 +126,17 @@ class XtextGenerator extends AbstractWorkflowComponent2 implements IGuiceAwareGe
|
|||
|
||||
protected def generateRuntimeSetup(LanguageConfig2 language) {
|
||||
templates.createRuntimeGenSetup(language).writeTo(projectConfig.runtimeSrcGen)
|
||||
if (!projectConfig.runtimeSrc.isFile(language.naming.runtimeSetup.path))
|
||||
if (!projectConfig.runtimeSrc.containsJavaFile(language.naming.runtimeSetup))
|
||||
templates.createRuntimeSetup(language).writeTo(projectConfig.runtimeSrc)
|
||||
}
|
||||
|
||||
protected def generateModules(LanguageConfig2 language) {
|
||||
templates.createRuntimeGenModule(language).writeTo(projectConfig.runtimeSrcGen)
|
||||
if (!projectConfig.runtimeSrc.isFile(language.naming.runtimeModule.path))
|
||||
if (!projectConfig.runtimeSrc.containsJavaFile(language.naming.runtimeModule))
|
||||
templates.createRuntimeModule(language).writeTo(projectConfig.runtimeSrc)
|
||||
if (projectConfig.eclipsePluginSrcGen !== null)
|
||||
templates.createEclipsePluginGenModule(language).writeTo(projectConfig.eclipsePluginSrcGen)
|
||||
if (projectConfig.eclipsePluginSrc !== null && !projectConfig.eclipsePluginSrc.isFile(language.naming.eclipsePluginModule.path))
|
||||
if (projectConfig.eclipsePluginSrc !== null && !projectConfig.eclipsePluginSrc.containsJavaFile(language.naming.eclipsePluginModule))
|
||||
templates.createEclipsePluginModule(language).writeTo(projectConfig.eclipsePluginSrc)
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,18 @@ import org.eclipse.xtext.xtext.generator.IGuiceAwareGeneratorComponent
|
|||
|
||||
class FileSystemAccess implements IFileSystemAccess2, IGuiceAwareGeneratorComponent {
|
||||
|
||||
static class Extensions {
|
||||
|
||||
def boolean containsJavaFile(IFileSystemAccess2 fsa, TypeReference typeRef) {
|
||||
fsa.isFile(typeRef.path + '.java')
|
||||
}
|
||||
|
||||
def boolean containsXtendFile(IFileSystemAccess2 fsa, TypeReference typeRef) {
|
||||
fsa.isFile(typeRef.path + '.xtend')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Inject IEncodingProvider encodingProvider
|
||||
|
||||
val URI baseUri
|
||||
|
|
|
@ -43,7 +43,11 @@ class JavaFileAccess extends TextFileAccess {
|
|||
throw new IllegalArgumentException('Nested type cannot be serialized: ' + typeRef)
|
||||
this.javaType = typeRef
|
||||
this.codeConfig = codeConfig
|
||||
setPath(typeRef.path)
|
||||
setPath(typeRef.path + '.' + fileExtension)
|
||||
}
|
||||
|
||||
protected def String getFileExtension() {
|
||||
'java'
|
||||
}
|
||||
|
||||
def String importType(TypeReference typeRef) {
|
||||
|
@ -83,6 +87,10 @@ class JavaFileAccess extends TextFileAccess {
|
|||
setContent(javaStringConcat)
|
||||
}
|
||||
|
||||
protected def boolean appendSemicolons() {
|
||||
true
|
||||
}
|
||||
|
||||
override generate() {
|
||||
val classAnnotations = annotations + codeConfig.classAnnotations.filter[appliesTo(this)]
|
||||
classAnnotations.forEach[importType(annotationImport)]
|
||||
|
@ -90,10 +98,10 @@ class JavaFileAccess extends TextFileAccess {
|
|||
Collections.sort(sortedImports)
|
||||
return '''
|
||||
«codeConfig.fileHeader»
|
||||
package «javaType.packageName»;
|
||||
package «javaType.packageName»«IF appendSemicolons»;«ENDIF»
|
||||
|
||||
«FOR importName : sortedImports»
|
||||
import «importName»;
|
||||
import «importName»«IF appendSemicolons»;«ENDIF»
|
||||
«ENDFOR»
|
||||
|
||||
«typeComment»
|
||||
|
|
|
@ -118,7 +118,7 @@ class TypeReference {
|
|||
}
|
||||
|
||||
def String getPath() {
|
||||
return packageName.replace('.', '/') + '/' + simpleNames.head + '.java'
|
||||
return packageName.replace('.', '/') + '/' + simpleNames.head
|
||||
}
|
||||
|
||||
}
|
|
@ -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.model
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
override protected getFileExtension() {
|
||||
'xtend'
|
||||
}
|
||||
|
||||
override protected appendSemicolons() {
|
||||
false
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,483 @@
|
|||
/*******************************************************************************
|
||||
* 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.xbase
|
||||
|
||||
import com.google.inject.Inject
|
||||
import com.google.inject.name.Names
|
||||
import java.util.Set
|
||||
import org.eclipse.xtend.lib.annotations.Accessors
|
||||
import org.eclipse.xtend2.lib.StringConcatenationClient
|
||||
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
|
||||
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.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.*
|
||||
|
||||
@Accessors(PUBLIC_SETTER)
|
||||
class XbaseGeneratorFragment2 extends AbstractGeneratorFragment2 {
|
||||
|
||||
static def boolean inheritsXbase(Grammar grammar) {
|
||||
GrammarUtil.inherits(grammar, 'org.eclipse.xtext.xbase.Xbase')
|
||||
}
|
||||
|
||||
static def boolean inheritsXbaseWithAnnotations(Grammar grammar) {
|
||||
GrammarUtil.inherits(grammar, 'org.eclipse.xtext.xbase.annotations.XbaseWithAnnotations')
|
||||
}
|
||||
|
||||
static def boolean usesXImportSection(Grammar grammar) {
|
||||
val Set<AbstractRule> usedRules = newHashSet
|
||||
new UsedRulesFinder(usedRules).compute(grammar)
|
||||
return usedRules.exists[name == 'XImportSection' && GrammarUtil.getGrammar(it).name == 'org.eclipse.xtext.xbase.Xtype']
|
||||
}
|
||||
|
||||
boolean generateXtendInferrer = true
|
||||
boolean useInferredJvmModel = true
|
||||
boolean jdtTypeHierarchy = true
|
||||
boolean jdtCallHierarchy = true
|
||||
boolean skipExportedPackage = false
|
||||
|
||||
@Inject IXtextProjectConfig projectConfig
|
||||
|
||||
@Inject CodeConfig codeConfig
|
||||
|
||||
@Inject IEncodingProvider encodingProvider
|
||||
|
||||
@Inject extension FileSystemAccess.Extensions
|
||||
|
||||
def TypeReference getJvmModelInferrer(LanguageConfig2 langConfig) {
|
||||
new TypeReference(langConfig.naming.runtimeBasePackage + '.jvmmodel.' + GrammarUtil.getName(langConfig.grammar) + 'JvmModelInferrer')
|
||||
}
|
||||
|
||||
def TypeReference getImportScopeProvider(LanguageConfig2 langConfig) {
|
||||
if (langConfig.grammar.usesXImportSection)
|
||||
'org.eclipse.xtext.xbase.scoping.XImportSectionNamespaceScopeProvider'.typeRef
|
||||
else
|
||||
'org.eclipse.xtext.xbase.scoping.XbaseImportedNamespaceScopeProvider'.typeRef
|
||||
}
|
||||
|
||||
override generate(LanguageConfig2 language) {
|
||||
if (!language.grammar.inheritsXbase)
|
||||
return;
|
||||
|
||||
addRuntimeGuiceBindings(language)
|
||||
addEclipsePluginGuiceBindings(language)
|
||||
if (projectConfig.eclipsePluginPluginXml !== null)
|
||||
addEclipsePluginExtensions(language)
|
||||
if (!projectConfig.runtimeSrc.containsXtendFile(language.jvmModelInferrer))
|
||||
doGenerateXtendInferrer(language)
|
||||
|
||||
if (projectConfig.runtimeManifest !== null) {
|
||||
projectConfig.runtimeManifest.requiredBundles.addAll(#[
|
||||
'org.eclipse.xtext.xbase', 'org.eclipse.xtext.xbase.lib'
|
||||
])
|
||||
if ((generateXtendInferrer || useInferredJvmModel) && !skipExportedPackage) {
|
||||
projectConfig.runtimeManifest.exportedPackages += language.jvmModelInferrer.packageName
|
||||
}
|
||||
}
|
||||
if (projectConfig.eclipsePluginManifest !== null) {
|
||||
projectConfig.eclipsePluginManifest.requiredBundles.addAll(#[
|
||||
'org.eclipse.xtext.xbase.ui', 'org.eclipse.jdt.debug.ui'
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
protected def addRuntimeGuiceBindings(LanguageConfig2 language) {
|
||||
val bindingFactory = new GuiceModuleAccess.BindingFactory()
|
||||
// overrides binding from org.eclipse.xtext.generator.exporting.QualifiedNamesFragment
|
||||
.addTypeToType(IQualifiedNameProvider.typeRef,
|
||||
'org.eclipse.xtext.xbase.scoping.XbaseQualifiedNameProvider'.typeRef)
|
||||
if (useInferredJvmModel) {
|
||||
bindingFactory
|
||||
.addTypeToType(ILocationInFileProvider.typeRef,
|
||||
'org.eclipse.xtext.xbase.jvmmodel.JvmLocationInFileProvider'.typeRef)
|
||||
.addTypeToType(IGlobalScopeProvider.typeRef,
|
||||
'org.eclipse.xtext.common.types.xtext.TypesAwareDefaultGlobalScopeProvider'.typeRef)
|
||||
.addTypeToType('org.eclipse.xtext.xbase.validation.FeatureNameValidator'.typeRef,
|
||||
'org.eclipse.xtext.xbase.validation.LogicalContainerAwareFeatureNameValidator'.typeRef)
|
||||
.addTypeToType('org.eclipse.xtext.xbase.typesystem.internal.DefaultBatchTypeResolver'.typeRef,
|
||||
'org.eclipse.xtext.xbase.typesystem.internal.LogicalContainerAwareBatchTypeResolver'.typeRef)
|
||||
.addTypeToType('org.eclipse.xtext.xbase.typesystem.internal.DefaultReentrantTypeResolver'.typeRef,
|
||||
'org.eclipse.xtext.xbase.typesystem.internal.LogicalContainerAwareReentrantTypeResolver'.typeRef)
|
||||
.addTypeToType(IResourceValidator.typeRef,
|
||||
'org.eclipse.xtext.xbase.annotations.validation.DerivedStateAwareResourceValidator'.typeRef)
|
||||
if (generateXtendInferrer) {
|
||||
bindingFactory
|
||||
.addTypeToType('org.eclipse.xtext.xbase.jvmmodel.IJvmModelInferrer'.typeRef, language.jvmModelInferrer)
|
||||
}
|
||||
} else {
|
||||
bindingFactory
|
||||
.addTypeToType(ILocationInFileProvider.typeRef,
|
||||
'org.eclipse.xtext.xbase.resource.XbaseLocationInFileProvider'.typeRef)
|
||||
|
||||
}
|
||||
if (language.grammar.usesXImportSection) {
|
||||
val StringConcatenationClient statement = '''
|
||||
binder.bind(«IScopeProvider».class).annotatedWith(«Names».named(«AbstractDeclarativeScopeProvider».NAMED_DELEGATE)).to(«language.importScopeProvider».class);
|
||||
'''
|
||||
bindingFactory
|
||||
.addConfiguredBinding(IScopeProvider.simpleName + 'Delegate', statement);
|
||||
}
|
||||
bindingFactory.contributeTo(language.runtimeGenModule)
|
||||
|
||||
if (language.grammar.inheritsXbaseWithAnnotations)
|
||||
language.runtimeGenModule.superClass = 'org.eclipse.xtext.xbase.annotations.DefaultXbaseWithAnnotationsRuntimeModule'.typeRef
|
||||
else
|
||||
language.runtimeGenModule.superClass = 'org.eclipse.xtext.xbase.DefaultXbaseRuntimeModule'.typeRef
|
||||
}
|
||||
|
||||
protected def addEclipsePluginGuiceBindings(LanguageConfig2 language) {
|
||||
val bindingFactory = new GuiceModuleAccess.BindingFactory()
|
||||
if (useInferredJvmModel) {
|
||||
val StringConcatenationClient statement = '''
|
||||
if («'org.eclipse.ui.PlatformUI'.typeRef».isWorkbenchRunning()) {
|
||||
binder.bind(«'org.eclipse.xtext.ui.editor.IURIEditorOpener'.typeRef».class).annotatedWith(«'org.eclipse.xtext.ui.LanguageSpecific'.typeRef».class).to(«'org.eclipse.xtext.xbase.ui.jvmmodel.navigation.DerivedMemberAwareEditorOpener'.typeRef».class);
|
||||
binder.bind(«'org.eclipse.xtext.common.types.ui.navigation.IDerivedMemberAwareEditorOpener'.typeRef».class).to(«'org.eclipse.xtext.xbase.ui.jvmmodel.navigation.DerivedMemberAwareEditorOpener'.typeRef».class);
|
||||
}
|
||||
'''
|
||||
// Rename refactoring
|
||||
bindingFactory
|
||||
.addTypeToType('org.eclipse.xtext.ui.editor.findrefs.FindReferencesHandler'.typeRef,
|
||||
'org.eclipse.xtext.xbase.ui.jvmmodel.findrefs.JvmModelFindReferenceHandler'.typeRef)
|
||||
.addTypeToType('org.eclipse.xtext.ui.editor.findrefs.ReferenceQueryExecutor'.typeRef,
|
||||
'org.eclipse.xtext.xbase.ui.jvmmodel.findrefs.JvmModelReferenceQueryExecutor'.typeRef)
|
||||
|
||||
// overrides binding from org.eclipse.xtext.generator.exporting.QualifiedNamesFragment
|
||||
.addTypeToType('org.eclipse.xtext.ui.refactoring.IDependentElementsCalculator'.typeRef,
|
||||
'org.eclipse.xtext.xbase.ui.jvmmodel.refactoring.JvmModelDependentElementsCalculator'.typeRef)
|
||||
// overrides binding from RefactorElementNameFragment
|
||||
.addTypeToType('org.eclipse.xtext.ui.refactoring.IRenameRefactoringProvider'.typeRef,
|
||||
'org.eclipse.xtext.xbase.ui.jvmmodel.refactoring.jdt.CombinedJvmJdtRenameRefactoringProvider'.typeRef)
|
||||
// overrides binding from RefactorElementNameFragment
|
||||
.addTypeToType('org.eclipse.xtext.ui.refactoring.IReferenceUpdater'.typeRef,
|
||||
'org.eclipse.xtext.xbase.ui.refactoring.XbaseReferenceUpdater'.typeRef)
|
||||
// overrides binding from RefactorElementNameFragment
|
||||
.addfinalTypeToType('org.eclipse.xtext.ui.refactoring.ui.IRenameContextFactory'.typeRef,
|
||||
'org.eclipse.xtext.xbase.ui.jvmmodel.refactoring.jdt.CombinedJvmJdtRenameContextFactory'.typeRef)
|
||||
// overrides binding from RefactorElementNameFragment
|
||||
.addTypeToType('org.eclipse.xtext.ui.refactoring.IRenameStrategy'.typeRef,
|
||||
'org.eclipse.xtext.xbase.ui.jvmmodel.refactoring.DefaultJvmModelRenameStrategy'.typeRef)
|
||||
|
||||
.addTypeToType('org.eclipse.xtext.common.types.ui.refactoring.participant.JdtRenameParticipant.ContextFactory'.typeRef,
|
||||
'org.eclipse.xtext.xbase.ui.jvmmodel.refactoring.JvmModelJdtRenameParticipantContext.ContextFactory'.typeRef)
|
||||
.addTypeToType('org.eclipse.xtext.ui.editor.outline.impl.OutlineNodeElementOpener'.typeRef,
|
||||
'org.eclipse.xtext.xbase.ui.jvmmodel.outline.JvmOutlineNodeElementOpener'.typeRef)
|
||||
.addTypeToType('org.eclipse.xtext.ui.editor.GlobalURIEditorOpener'.typeRef,
|
||||
'org.eclipse.xtext.common.types.ui.navigation.GlobalDerivedMemberAwareURIEditorOpener'.typeRef)
|
||||
.addTypeToType('org.eclipse.xtext.ui.editor.occurrences.IOccurrenceComputer'.typeRef,
|
||||
'org.eclipse.xtext.xbase.ui.jvmmodel.occurrence.JvmModelOccurrenceComputer'.typeRef)
|
||||
.addTypeToType('org.eclipse.xtext.common.types.ui.query.IJavaSearchParticipation'.typeRef,
|
||||
'org.eclipse.xtext.common.types.ui.query.IJavaSearchParticipation.No'.typeRef)
|
||||
// DerivedMemberAwareEditorOpener
|
||||
.addConfiguredBinding('LanguageSpecificURIEditorOpener', statement)
|
||||
} else {
|
||||
bindingFactory
|
||||
.addTypeToType('org.eclipse.xtext.ui.refactoring.IRenameStrategy'.typeRef,
|
||||
'org.eclipse.xtext.xbase.ui.refactoring.XbaseRenameStrategy'.typeRef)
|
||||
}
|
||||
if (language.grammar.usesXImportSection) {
|
||||
bindingFactory
|
||||
.addTypeToType('org.eclipse.xtext.xbase.imports.IUnresolvedTypeResolver'.typeRef,
|
||||
'org.eclipse.xtext.xbase.ui.imports.InteractiveUnresolvedTypeResolver'.typeRef)
|
||||
.addTypeToType('org.eclipse.xtext.common.types.xtext.ui.ITypesProposalProvider'.typeRef,
|
||||
'org.eclipse.xtext.xbase.ui.contentassist.ImportingTypesProposalProvider'.typeRef)
|
||||
.addTypeToType(' org.eclipse.xtext.ui.editor.templates.XtextTemplateContextType'.typeRef,
|
||||
'org.eclipse.xtext.xbase.ui.templates.XbaseTemplateContextType'.typeRef)
|
||||
} else {
|
||||
bindingFactory
|
||||
.addTypeToType('org.eclipse.xtext.xbase.ui.quickfix.JavaTypeQuickfixes'.typeRef,
|
||||
'org.eclipse.xtext.xbase.ui.quickfix.JavaTypeQuickfixesNoImportSection'.typeRef)
|
||||
}
|
||||
bindingFactory.contributeTo(language.eclipsePluginGenModule)
|
||||
|
||||
if (language.grammar.inheritsXbaseWithAnnotations)
|
||||
language.eclipsePluginGenModule.superClass = 'org.eclipse.xtext.xbase.annotations.ui.DefaultXbaseWithAnnotationsUiModule'.typeRef
|
||||
else
|
||||
language.eclipsePluginGenModule.superClass = 'org.eclipse.xtext.xbase.ui.DefaultXbaseUiModule'.typeRef
|
||||
}
|
||||
|
||||
protected def doGenerateXtendInferrer(LanguageConfig2 language) {
|
||||
val xtendFile = new XtendFileAccess(language.jvmModelInferrer, codeConfig)
|
||||
xtendFile.encodingProvider = encodingProvider
|
||||
|
||||
xtendFile.typeComment = '''
|
||||
/**
|
||||
* <p>Infers a JVM model from the source model.</p>
|
||||
*
|
||||
* <p>The JVM model should contain all elements that would appear in the Java code
|
||||
* which is generated from the source model. Other models link against the JVM model rather than the source model.</p>
|
||||
*/
|
||||
'''
|
||||
val firstRuleType = language.grammar.rules.head.type.classifier.getJavaTypeName(language.grammar.eResource.resourceSet).typeRef
|
||||
xtendFile.javaContent = '''
|
||||
class «language.jvmModelInferrer.simpleName» extends «'org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer'.typeRef» {
|
||||
|
||||
/**
|
||||
* convenience API to build and initialize JVM types and their members.
|
||||
*/
|
||||
@«Inject» extension «'org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder'.typeRef»
|
||||
|
||||
/**
|
||||
* The dispatch method {@code infer} is called for each instance of the
|
||||
* given element's type that is contained in a resource.
|
||||
*
|
||||
* @param element
|
||||
* the model to create one or more
|
||||
* {@link org.eclipse.xtext.common.types.JvmDeclaredType declared
|
||||
* types} from.
|
||||
* @param acceptor
|
||||
* each created
|
||||
* {@link org.eclipse.xtext.common.types.JvmDeclaredType type}
|
||||
* without a container should be passed to the acceptor in order
|
||||
* get attached to the current resource. The acceptor's
|
||||
* {@link IJvmDeclaredTypeAcceptor#accept(org.eclipse.xtext.common.types.JvmDeclaredType)
|
||||
* accept(..)} method takes the constructed empty type for the
|
||||
* pre-indexing phase. This one is further initialized in the
|
||||
* indexing phase using the closure you pass to the returned
|
||||
* {@link org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor.IPostIndexingInitializing#initializeLater(org.eclipse.xtext.xbase.lib.Procedures.Procedure1)
|
||||
* initializeLater(..)}.
|
||||
* @param isPreIndexingPhase
|
||||
* whether the method is called in a pre-indexing phase, i.e.
|
||||
* when the global index is not yet fully updated. You must not
|
||||
* rely on linking using the index if isPreIndexingPhase is
|
||||
* <code>true</code>.
|
||||
*/
|
||||
def dispatch void infer(«firstRuleType» element, «'org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor'.typeRef» acceptor, boolean isPreIndexingPhase) {
|
||||
// Here you explain how your model is mapped to Java elements, by writing the actual translation code.
|
||||
|
||||
// An implementation for the initial hello world example could look like this:
|
||||
// acceptor.accept(element.toClass("my.company.greeting.MyGreetings")) [
|
||||
// for (greeting : element.greetings) {
|
||||
// members += greeting.toMethod("hello" + greeting.name, typeRef(String)) [
|
||||
// body = «"'''"»
|
||||
// return "Hello «'«'»greeting.name«'»'»";
|
||||
// «"'''"»
|
||||
// ]
|
||||
// }
|
||||
// ]
|
||||
}
|
||||
}
|
||||
'''
|
||||
xtendFile.writeTo(projectConfig.runtimeSrc)
|
||||
}
|
||||
|
||||
protected def addEclipsePluginExtensions(LanguageConfig2 language) {
|
||||
val name = language.grammar.name
|
||||
if (jdtTypeHierarchy) {
|
||||
projectConfig.eclipsePluginPluginXml.entries += '''
|
||||
<!-- Type Hierarchy -->
|
||||
<extension point="org.eclipse.ui.handlers">
|
||||
<handler
|
||||
class="«language.naming.eclipsePluginExecutableExtensionFactory»:org.eclipse.xtext.xbase.ui.hierarchy.OpenTypeHierarchyHandler"
|
||||
commandId="org.eclipse.xtext.xbase.ui.hierarchy.OpenTypeHierarchy">
|
||||
<activeWhen>
|
||||
<reference
|
||||
definitionId="«name».Editor.opened">
|
||||
</reference>
|
||||
</activeWhen>
|
||||
</handler>
|
||||
<handler
|
||||
class="«language.naming.eclipsePluginExecutableExtensionFactory»:org.eclipse.xtext.xbase.ui.hierarchy.QuickTypeHierarchyHandler"
|
||||
commandId="org.eclipse.jdt.ui.edit.text.java.open.hierarchy">
|
||||
<activeWhen>
|
||||
<reference
|
||||
definitionId="«name».Editor.opened">
|
||||
</reference>
|
||||
</activeWhen>
|
||||
</handler>
|
||||
«IF language.grammar.usesXImportSection»
|
||||
<handler
|
||||
class="«language.naming.eclipsePluginExecutableExtensionFactory»:org.eclipse.xtext.xbase.ui.imports.OrganizeImportsHandler"
|
||||
commandId="org.eclipse.xtext.xbase.ui.organizeImports">
|
||||
<activeWhen>
|
||||
<reference
|
||||
definitionId="«name».Editor.opened">
|
||||
</reference>
|
||||
</activeWhen>
|
||||
</handler>
|
||||
«ENDIF»
|
||||
</extension>
|
||||
<extension point="org.eclipse.ui.menus">
|
||||
«IF language.grammar.usesXImportSection»
|
||||
<menuContribution
|
||||
locationURI="popup:#TextEditorContext?after=group.edit">
|
||||
<command
|
||||
commandId="org.eclipse.xtext.xbase.ui.organizeImports"
|
||||
style="push"
|
||||
tooltip="Organize Imports">
|
||||
<visibleWhen checkEnabled="false">
|
||||
<reference
|
||||
definitionId="«name».Editor.opened">
|
||||
</reference>
|
||||
</visibleWhen>
|
||||
</command>
|
||||
</menuContribution>
|
||||
«ENDIF»
|
||||
<menuContribution
|
||||
locationURI="popup:#TextEditorContext?after=group.open">
|
||||
<command commandId="org.eclipse.xtext.xbase.ui.hierarchy.OpenTypeHierarchy"
|
||||
style="push"
|
||||
tooltip="Open Type Hierarchy">
|
||||
<visibleWhen checkEnabled="false">
|
||||
<reference definitionId="«name».Editor.opened"/>
|
||||
</visibleWhen>
|
||||
</command>
|
||||
</menuContribution>
|
||||
<menuContribution
|
||||
locationURI="popup:#TextEditorContext?after=group.open">
|
||||
<command commandId="org.eclipse.jdt.ui.edit.text.java.open.hierarchy"
|
||||
style="push"
|
||||
tooltip="Quick Type Hierarchy">
|
||||
<visibleWhen checkEnabled="false">
|
||||
<reference definitionId="«name».Editor.opened"/>
|
||||
</visibleWhen>
|
||||
</command>
|
||||
</menuContribution>
|
||||
</extension>
|
||||
'''
|
||||
}
|
||||
if (jdtCallHierarchy) {
|
||||
projectConfig.eclipsePluginPluginXml.entries += '''
|
||||
<!-- Call Hierachy -->
|
||||
<extension point="org.eclipse.ui.handlers">
|
||||
<handler
|
||||
class="«language.naming.eclipsePluginExecutableExtensionFactory»:org.eclipse.xtext.xbase.ui.hierarchy.OpenCallHierachyHandler"
|
||||
commandId="org.eclipse.xtext.xbase.ui.hierarchy.OpenCallHierarchy">
|
||||
<activeWhen>
|
||||
<reference
|
||||
definitionId="«name».Editor.opened">
|
||||
</reference>
|
||||
</activeWhen>
|
||||
</handler>
|
||||
</extension>
|
||||
<extension point="org.eclipse.ui.menus">
|
||||
<menuContribution
|
||||
locationURI="popup:#TextEditorContext?after=group.open">
|
||||
<command commandId="org.eclipse.xtext.xbase.ui.hierarchy.OpenCallHierarchy"
|
||||
style="push"
|
||||
tooltip="Open Call Hierarchy">
|
||||
<visibleWhen checkEnabled="false">
|
||||
<reference definitionId="«name».Editor.opened"/>
|
||||
</visibleWhen>
|
||||
</command>
|
||||
</menuContribution>
|
||||
</extension>
|
||||
'''
|
||||
}
|
||||
projectConfig.eclipsePluginPluginXml.entries += '''
|
||||
<extension point="org.eclipse.core.runtime.adapters">
|
||||
<factory class="«language.naming.eclipsePluginExecutableExtensionFactory»:org.eclipse.xtext.builder.smap.StratumBreakpointAdapterFactory"
|
||||
adaptableType="org.eclipse.xtext.ui.editor.XtextEditor">
|
||||
<adapter type="org.eclipse.debug.ui.actions.IToggleBreakpointsTarget"/>
|
||||
</factory>
|
||||
</extension>
|
||||
<extension point="org.eclipse.ui.editorActions">
|
||||
<editorContribution targetID="«name»"
|
||||
id="«name».rulerActions">
|
||||
<action
|
||||
label="Not Used"
|
||||
class="«language.naming.eclipsePluginExecutableExtensionFactory»:org.eclipse.debug.ui.actions.RulerToggleBreakpointActionDelegate"
|
||||
style="push"
|
||||
actionID="RulerDoubleClick"
|
||||
id="«name».doubleClickBreakpointAction"/>
|
||||
</editorContribution>
|
||||
</extension>
|
||||
<extension point="org.eclipse.ui.popupMenus">
|
||||
<viewerContribution
|
||||
targetID="«name».RulerContext"
|
||||
id="«name».RulerPopupActions">
|
||||
<action
|
||||
label="Toggle Breakpoint"
|
||||
class="«language.naming.eclipsePluginExecutableExtensionFactory»:org.eclipse.debug.ui.actions.RulerToggleBreakpointActionDelegate"
|
||||
menubarPath="debug"
|
||||
id="«name».rulerContextMenu.toggleBreakpointAction">
|
||||
</action>
|
||||
<action
|
||||
label="Not used"
|
||||
class="«language.naming.eclipsePluginExecutableExtensionFactory»:org.eclipse.debug.ui.actions.RulerEnableDisableBreakpointActionDelegate"
|
||||
menubarPath="debug"
|
||||
id="«name».rulerContextMenu.enableDisableBreakpointAction">
|
||||
</action>
|
||||
<action
|
||||
label="Breakpoint Properties"
|
||||
helpContextId="breakpoint_properties_action_context"
|
||||
class="«language.naming.eclipsePluginExecutableExtensionFactory»:org.eclipse.jdt.debug.ui.actions.JavaBreakpointPropertiesRulerActionDelegate"
|
||||
menubarPath="group.properties"
|
||||
id="«name».rulerContextMenu.openBreapointPropertiesAction">
|
||||
</action>
|
||||
</viewerContribution>
|
||||
</extension>
|
||||
<!-- Introduce Local Variable Refactoring -->
|
||||
<extension point="org.eclipse.ui.handlers">
|
||||
<handler
|
||||
class="«language.naming.eclipsePluginExecutableExtensionFactory»:org.eclipse.xtext.xbase.ui.refactoring.ExtractVariableHandler"
|
||||
commandId="org.eclipse.xtext.xbase.ui.refactoring.ExtractLocalVariable">
|
||||
<activeWhen>
|
||||
<reference
|
||||
definitionId="«name».Editor.opened">
|
||||
</reference>
|
||||
</activeWhen>
|
||||
</handler>
|
||||
</extension>
|
||||
<extension point="org.eclipse.ui.menus">
|
||||
<menuContribution
|
||||
locationURI="popup:#TextEditorContext?after=group.edit">
|
||||
<command commandId="org.eclipse.xtext.xbase.ui.refactoring.ExtractLocalVariable"
|
||||
style="push">
|
||||
<visibleWhen checkEnabled="false">
|
||||
<reference
|
||||
definitionId="«name».Editor.opened">
|
||||
</reference>
|
||||
</visibleWhen>
|
||||
</command>
|
||||
</menuContribution>
|
||||
</extension>
|
||||
<!-- Open implementation -->
|
||||
<extension point="org.eclipse.ui.handlers">
|
||||
<handler
|
||||
class="«language.naming.eclipsePluginExecutableExtensionFactory»:org.eclipse.xtext.xbase.ui.navigation.OpenImplementationHandler"
|
||||
commandId="org.eclipse.xtext.xbase.ui.OpenImplementationCommand">
|
||||
<activeWhen>
|
||||
<reference
|
||||
definitionId="«name».Editor.opened">
|
||||
</reference>
|
||||
</activeWhen>
|
||||
</handler>
|
||||
</extension>
|
||||
<extension point="org.eclipse.ui.menus">
|
||||
<menuContribution
|
||||
locationURI="menu:navigate?after=open.ext4">
|
||||
<command commandId="org.eclipse.xtext.xbase.ui.OpenImplementationCommand">
|
||||
<visibleWhen checkEnabled="false">
|
||||
<reference
|
||||
definitionId="«name».Editor.opened">
|
||||
</reference>
|
||||
</visibleWhen>
|
||||
</command>
|
||||
</menuContribution>
|
||||
</extension>
|
||||
'''
|
||||
}
|
||||
|
||||
}
|
|
@ -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.xbase
|
||||
|
||||
import com.google.inject.Inject
|
||||
import org.eclipse.xtext.Grammar
|
||||
import org.eclipse.xtext.GrammarUtil
|
||||
import org.eclipse.xtext.xtext.generator.AbstractGeneratorFragment2
|
||||
import org.eclipse.xtext.xtext.generator.IXtextProjectConfig
|
||||
import org.eclipse.xtext.xtext.generator.LanguageConfig2
|
||||
|
||||
class XtypeGeneratorFragment2 extends AbstractGeneratorFragment2 {
|
||||
|
||||
static def boolean inheritsXtype(Grammar grammar) {
|
||||
GrammarUtil.inherits(grammar, 'org.eclipse.xtext.xbase.Xtype')
|
||||
}
|
||||
|
||||
@Inject IXtextProjectConfig projectConfig
|
||||
|
||||
override generate(LanguageConfig2 language) {
|
||||
if (language.grammar.inheritsXtype && projectConfig.eclipsePluginManifest !== null)
|
||||
projectConfig.eclipsePluginManifest.requiredBundles += 'org.eclipse.xtext.xbase.ui'
|
||||
}
|
||||
|
||||
}
|
|
@ -270,6 +270,20 @@ public class GrammarUtil {
|
|||
collectAllUsedGrammars(grammars, grammar);
|
||||
return grammars;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.9
|
||||
*/
|
||||
public static boolean inherits(Grammar grammar, String languageID) {
|
||||
if (grammar.getName().equals(languageID))
|
||||
return true;
|
||||
for (Grammar grammar2 : grammar.getUsedGrammars()) {
|
||||
if (inherits(grammar2, languageID)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void collectAllUsedGrammars(List<Grammar> grammars, Grammar grammar) {
|
||||
grammars.addAll(grammar.getUsedGrammars());
|
||||
|
|
Loading…
Reference in a new issue