| /******************************************************************************* |
| * Copyright (c) 2013 RCP Vision (http://www.rcp-vision.com) 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 |
| * |
| * Contributors: |
| * Lorenzo Bettini - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.emf.parsley.dsl.jvmmodel |
| |
| import com.google.inject.Inject |
| import com.google.inject.Provider |
| import java.util.List |
| import org.eclipse.core.databinding.DataBindingContext |
| import org.eclipse.core.databinding.observable.value.IObservableValue |
| import org.eclipse.emf.common.notify.AdapterFactory |
| import org.eclipse.emf.ecore.EObject |
| import org.eclipse.emf.ecore.EStructuralFeature |
| import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider |
| import org.eclipse.emf.parsley.EmfParsleyGuiceModule |
| import org.eclipse.emf.parsley.binding.DialogControlFactory |
| import org.eclipse.emf.parsley.binding.FormControlFactory |
| import org.eclipse.emf.parsley.binding.ProposalCreator |
| import org.eclipse.emf.parsley.dsl.model.AbstractControlFactory |
| import org.eclipse.emf.parsley.dsl.model.AbstractFeatureCaptionProviderWithLabel |
| import org.eclipse.emf.parsley.dsl.model.AbstractFeatureProvider |
| import org.eclipse.emf.parsley.dsl.model.BindingsSpecification |
| import org.eclipse.emf.parsley.dsl.model.ControlFactorySpecification |
| import org.eclipse.emf.parsley.dsl.model.FeatureAssociatedExpression |
| import org.eclipse.emf.parsley.dsl.model.LabelSpecification |
| import org.eclipse.emf.parsley.dsl.model.Module |
| import org.eclipse.emf.parsley.dsl.model.ProviderBinding |
| import org.eclipse.emf.parsley.dsl.model.TypeBinding |
| import org.eclipse.emf.parsley.dsl.model.ValueBinding |
| import org.eclipse.emf.parsley.dsl.model.WithExtendsClause |
| import org.eclipse.emf.parsley.dsl.model.WithFields |
| import org.eclipse.emf.parsley.edit.action.EditingMenuBuilder |
| import org.eclipse.emf.parsley.edit.action.IMenuContributionSpecification |
| import org.eclipse.emf.parsley.edit.ui.provider.ViewerContentProvider |
| import org.eclipse.emf.parsley.ui.provider.DialogFeatureCaptionProvider |
| import org.eclipse.emf.parsley.ui.provider.EClassToEStructuralFeatureAsStringsMap |
| import org.eclipse.emf.parsley.ui.provider.FeatureCaptionProvider |
| import org.eclipse.emf.parsley.ui.provider.FeaturesProvider |
| import org.eclipse.emf.parsley.ui.provider.FormFeatureCaptionProvider |
| import org.eclipse.emf.parsley.ui.provider.TableColumnLabelProvider |
| import org.eclipse.emf.parsley.ui.provider.TableFeaturesProvider |
| import org.eclipse.emf.parsley.ui.provider.ViewerLabelProvider |
| import org.eclipse.jface.viewers.IContentProvider |
| import org.eclipse.jface.viewers.ILabelProvider |
| import org.eclipse.swt.widgets.Composite |
| import org.eclipse.swt.widgets.Control |
| import org.eclipse.swt.widgets.Label |
| import org.eclipse.ui.plugin.AbstractUIPlugin |
| import org.eclipse.xtext.common.types.JvmAnnotationTarget |
| import org.eclipse.xtext.common.types.JvmDeclaredType |
| import org.eclipse.xtext.common.types.JvmExecutable |
| import org.eclipse.xtext.common.types.JvmGenericType |
| import org.eclipse.xtext.common.types.JvmOperation |
| import org.eclipse.xtext.common.types.JvmTypeReference |
| import org.eclipse.xtext.common.types.JvmVisibility |
| import org.eclipse.xtext.common.types.TypesFactory |
| import org.eclipse.xtext.common.types.util.TypeReferences |
| import org.eclipse.xtext.naming.IQualifiedNameProvider |
| import org.eclipse.xtext.util.IAcceptor |
| import org.eclipse.xtext.xbase.XExpression |
| import org.eclipse.xtext.xbase.annotations.xAnnotations.XAnnotation |
| import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer |
| import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor |
| import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder |
| |
| /** |
| * <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> |
| */ |
| class EmfParsleyDslJvmModelInferrer extends AbstractModelInferrer { |
| |
| /** |
| * convenience API to build and initialize JVM types and their members. |
| */ |
| @Inject extension JvmTypesBuilder |
| |
| @Inject extension IQualifiedNameProvider |
| |
| @Inject extension TypeReferences |
| |
| @Inject extension TypesFactory |
| |
| @Inject extension GeneratorUtils |
| |
| /** |
| * 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 JvmDeclaredType declared |
| * types} from. |
| * @param acceptor |
| * each created |
| * {@link 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 as the last argument. |
| * @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(Module element, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) { |
| if (element.name.empty) |
| return |
| |
| val moduleClass = element.toClass(element.moduleQN) |
| |
| val labelProviderClass = element.inferLabelProvider(acceptor) |
| val tableLabelProviderClass = element.inferTableLabelProvider(acceptor) |
| val featureCaptionProviderClass = element.inferFeatureCaptionProvider(acceptor) |
| val formFeatureCaptionProviderClass = element.inferFormFeatureCaptionProvider(acceptor) |
| val dialogFeatureCaptionProviderClass = element.inferDialogFeatureCaptionProvider(acceptor) |
| val featureProviderClass = element.inferFeatureProvider(acceptor) |
| val tableFeatureProviderClass = element.inferTableFeatureProvider(acceptor) |
| val formControlFactoryClass = element.inferFormControlFactory(acceptor) |
| val dialogControlFactoryClass = element.inferDialogControlFactory(acceptor) |
| val viewerContentProviderClass = element.inferViewerContentProvider(acceptor) |
| val proposalCreatorClass = element.inferProposalCreator(acceptor) |
| val menuBuilderClass = element.inferMenuBuilder(acceptor) |
| |
| acceptor.accept(moduleClass) [ |
| documentation = element.documentation |
| moduleClass.setSuperClassType(element, typeof(EmfParsleyGuiceModule)) |
| |
| members += element.toConstructor() [ |
| parameters += element.toParameter("plugin", typeRef(AbstractUIPlugin)) |
| body = [it.append("super(plugin);")] |
| ] |
| |
| val bindingsSpecification = element.bindingsSpecification |
| if (element.bindingsSpecification != null) { |
| handleBindingsSpecification(it, bindingsSpecification) |
| } |
| |
| if (labelProviderClass != null) |
| members += element.labelProvider.genBindMethod(labelProviderClass, typeof(ILabelProvider)) |
| if (tableLabelProviderClass != null) |
| members += element.tableLabelProvider.genBindMethod(tableLabelProviderClass, typeof(TableColumnLabelProvider) |
| ) |
| if (featureCaptionProviderClass != null) |
| members += element.featureCaptionProvider.genBindMethod(featureCaptionProviderClass, typeof(FeatureCaptionProvider)) |
| if (formFeatureCaptionProviderClass != null) |
| members += element.formFeatureCaptionProvider.genBindMethod(formFeatureCaptionProviderClass, typeof(FormFeatureCaptionProvider)) |
| if (dialogFeatureCaptionProviderClass != null) |
| members += element.dialogFeatureCaptionProvider.genBindMethod(dialogFeatureCaptionProviderClass, typeof(DialogFeatureCaptionProvider)) |
| if (featureProviderClass != null) |
| members += element.featuresProvider.genBindMethod(featureProviderClass, typeof(FeaturesProvider)) |
| if (tableFeatureProviderClass != null) |
| members += element.tableFeaturesProvider.genBindMethod(tableFeatureProviderClass, typeof(TableFeaturesProvider)) |
| if (formControlFactoryClass != null) |
| members += element.formControlFactory.genBindMethod(formControlFactoryClass, typeof(FormControlFactory)) |
| if (dialogControlFactoryClass != null) |
| members += element.dialogControlFactory.genBindMethod(dialogControlFactoryClass, typeof(DialogControlFactory)) |
| if (viewerContentProviderClass != null) |
| members += element.viewerContentProvider.genBindMethod(viewerContentProviderClass, typeof(IContentProvider)) |
| if (proposalCreatorClass != null) |
| members += element.proposalCreator.genBindMethod(proposalCreatorClass, typeof(ProposalCreator)) |
| if (menuBuilderClass != null) |
| members += element.menuBuilder.genBindMethod(menuBuilderClass, typeof(EditingMenuBuilder)) |
| ] |
| |
| } |
| |
| def private setSuperClassType(JvmGenericType e, WithExtendsClause dslElement, Class<?> defaultSuperClass) { |
| if (dslElement.extendsClause != null) |
| e.superTypes += dslElement.extendsClause.superType.cloneWithProxies |
| else |
| e.superTypes += typeRef(defaultSuperClass) |
| } |
| |
| def private setSuperClassTypeAndFields(JvmGenericType e, WithFields dslElement, Class<?> defaultSuperClass) { |
| e.setSuperClassType(dslElement, defaultSuperClass) |
| e.processFields(dslElement) |
| } |
| |
| def private processFields(JvmGenericType it, WithFields dslElement) { |
| for (f : dslElement.fields) { |
| var type = f.type |
| val name = f.name |
| val initialExp = f.right |
| members += f.toField(name, type) => [ |
| final = !f.writeable |
| visibility = JvmVisibility.PRIVATE |
| translateAnnotations(f.annotations) |
| if (f.extension) { |
| annotations += annotationRef(Extension) |
| } |
| initializer = initialExp |
| ] |
| members += f.toGetter(name, type) |
| if (f.writeable) { |
| members += f.toSetter(name, type) |
| } |
| } |
| } |
| |
| def private void translateAnnotations(JvmAnnotationTarget target, List<XAnnotation> annotations) { |
| target.addAnnotations(annotations.filterNull.filter[annotationType != null]) |
| } |
| |
| def private moduleQN(Module element) { |
| element.fullyQualifiedName + ".EmfParsleyGuiceModuleGen" |
| } |
| |
| def private labelProviderQN(Module element) { |
| element.fullyQualifiedName + ".ui.provider.LabelProviderGen" |
| } |
| |
| def private tableLabelProviderQN(Module element) { |
| element.fullyQualifiedName + ".ui.provider.TableLabelProviderGen" |
| } |
| |
| def private featureCaptionProviderQN(Module element) { |
| element.fullyQualifiedName + ".ui.provider.FeatureCaptionProviderGen" |
| } |
| |
| def private formFeatureCaptionProviderQN(Module element) { |
| element.fullyQualifiedName + ".ui.provider.FormFeatureCaptionProviderGen" |
| } |
| |
| def private dialogFeatureCaptionProviderQN(Module element) { |
| element.fullyQualifiedName + ".ui.provider.DialogFeatureCaptionProviderGen" |
| } |
| |
| def private featuresProviderQN(Module element) { |
| element.fullyQualifiedName + ".ui.provider.FeaturesProviderGen" |
| } |
| |
| def private tableFeaturesProviderQN(Module element) { |
| element.fullyQualifiedName + ".ui.provider.TableFeaturesProviderGen" |
| } |
| |
| def private formControlFactoryQN(Module element) { |
| element.fullyQualifiedName + ".binding.FormControlFactoryGen" |
| } |
| |
| def private dialogControlFactoryQN(Module element) { |
| element.fullyQualifiedName + ".binding.DialogControlFactoryGen" |
| } |
| |
| def private viewerContentProviderQN(Module element) { |
| element.fullyQualifiedName + ".edit.ui.provider.ViewerContentProviderGen" |
| } |
| |
| def private proposalCreatorQN(Module element) { |
| element.fullyQualifiedName + ".binding.ProposalCreatorGen" |
| } |
| |
| def private menuBuilderQN(Module element) { |
| element.fullyQualifiedName + ".edit.action.MenuBuilderGen" |
| } |
| |
| def private inferLabelProvider(Module element, IJvmDeclaredTypeAcceptor acceptor) { |
| if (element.labelProvider == null) |
| null |
| else { |
| val labelProvider = element.labelProvider |
| val labelProviderClass = labelProvider.toClass(element.labelProviderQN) |
| acceptor.accept(labelProviderClass) [ |
| setSuperClassTypeAndFields(labelProvider, typeof(ViewerLabelProvider)) |
| |
| members += labelProvider.toConstructor() [ |
| parameters += labelProvider. |
| toParameter("delegate", |
| typeRef(AdapterFactoryLabelProvider) |
| ) |
| body = [it.append("super(delegate);")] |
| annotations += annotationRef(Inject) |
| ] |
| |
| for (labelSpecification : labelProvider.labelSpecifications) { |
| members += labelSpecification.specificationToMethod("text", typeRef(String)) |
| } |
| |
| for (imageSpecification : labelProvider.imageSpecifications) { |
| members += imageSpecification.specificationToMethod("image", typeRef(Object)) |
| } |
| ] |
| labelProviderClass |
| } |
| } |
| |
| def private inferTableLabelProvider(Module element, IJvmDeclaredTypeAcceptor acceptor) { |
| if (element.tableLabelProvider == null) |
| null |
| else { |
| val tableLabelProvider = element.tableLabelProvider |
| val tableLabelProviderClass = tableLabelProvider.toClass(element.tableLabelProviderQN) |
| acceptor.accept(tableLabelProviderClass) [ |
| setSuperClassTypeAndFields(tableLabelProvider, typeof(TableColumnLabelProvider)) |
| |
| for (labelSpecification : tableLabelProvider.labelSpecifications) { |
| if (labelSpecification.feature?.simpleName != null) { |
| members += labelSpecification.toMethod("text_" + |
| labelSpecification.parameterType.simpleName + "_" + |
| labelSpecification.feature.simpleName.propertyNameForGetterSetterMethod |
| , typeRef(String) |
| ) [ |
| parameters += labelSpecification.toParameter( |
| "it" |
| , labelSpecification.parameterType |
| ) |
| body = labelSpecification.expression |
| ] |
| } |
| } |
| |
| for (imageSpecification : tableLabelProvider.imageSpecifications) { |
| if (imageSpecification.feature?.simpleName != null) { |
| members += imageSpecification.toMethod("image_" + |
| imageSpecification.parameterType.simpleName + "_" + |
| imageSpecification.feature.simpleName.propertyNameForGetterSetterMethod |
| , typeRef(Object)) [ |
| parameters += imageSpecification.toParameter( |
| "it" |
| , imageSpecification.parameterType |
| ) |
| body = imageSpecification.expression |
| ] |
| } |
| } |
| ] |
| tableLabelProviderClass |
| } |
| } |
| |
| def private inferFeatureCaptionProvider(Module element, IJvmDeclaredTypeAcceptor acceptor) { |
| if (element.featureCaptionProvider == null) |
| null |
| else { |
| val featureCaptionProvider = element.featureCaptionProvider |
| val propertyDescriptionProviderClass = featureCaptionProvider.toClass(element.featureCaptionProviderQN) |
| acceptor.accept(propertyDescriptionProviderClass) [ |
| setSuperClassTypeAndFields(featureCaptionProvider, typeof(FeatureCaptionProvider)) |
| |
| inferMethodsForTextCaptionSpecifications(element, it, featureCaptionProvider.specifications) |
| ] |
| propertyDescriptionProviderClass |
| } |
| } |
| |
| def private inferFormFeatureCaptionProvider(Module element, IJvmDeclaredTypeAcceptor acceptor) { |
| element.formFeatureCaptionProvider.inferDialogFeatureCaptionProviderWithLabel( |
| element.formFeatureCaptionProviderQN, typeof(FormFeatureCaptionProvider), acceptor) |
| } |
| |
| def private inferDialogFeatureCaptionProvider(Module element, IJvmDeclaredTypeAcceptor acceptor) { |
| element.dialogFeatureCaptionProvider.inferDialogFeatureCaptionProviderWithLabel( |
| element.dialogFeatureCaptionProviderQN, typeof(DialogFeatureCaptionProvider), acceptor) |
| } |
| |
| def private inferDialogFeatureCaptionProviderWithLabel(AbstractFeatureCaptionProviderWithLabel element, String name, Class<?> superClass, IJvmDeclaredTypeAcceptor acceptor) { |
| if (element == null) |
| null |
| else { |
| val descriptionProviderClass = element.toClass(name) |
| acceptor.accept(descriptionProviderClass) [ |
| setSuperClassTypeAndFields(element, superClass) |
| |
| inferMethodsForTextCaptionSpecifications(element, it, element.specifications) |
| |
| inferMethodsForLabelCaptionSpecifications(element, it, element.labelSpecifications) |
| ] |
| descriptionProviderClass |
| } |
| } |
| |
| def private inferMethodsForTextCaptionSpecifications(EObject element, JvmGenericType it, Iterable<FeatureAssociatedExpression> specifications) { |
| inferMethodsForCaptionSpecifications( |
| it, specifications, "text_", typeRef(String) |
| ) [ |
| it, spec | |
| parameters += spec.toParameter( |
| "it", typeRef(EStructuralFeature) |
| ) |
| ] |
| } |
| |
| def private inferMethodsForLabelCaptionSpecifications(EObject element, JvmGenericType it, Iterable<FeatureAssociatedExpression> specifications) { |
| inferMethodsForCaptionSpecifications( |
| it, specifications, "label_", typeRef(Label) |
| ) [ |
| it, spec | |
| parameters += spec.toParameter( |
| "parent", typeRef(Composite) |
| ) |
| parameters += spec.toParameter( |
| "it", typeRef(EStructuralFeature) |
| ) |
| ] |
| } |
| |
| def private inferMethodsForCaptionSpecifications(JvmGenericType it, Iterable<FeatureAssociatedExpression> specifications, |
| String prefix, JvmTypeReference returnType, (JvmOperation, FeatureAssociatedExpression) => void parameterCreator |
| ) { |
| for (spec : specifications) { |
| featureAssociatedExpressionToMethod(spec, prefix, returnType, parameterCreator) |
| } |
| } |
| |
| def private featureAssociatedExpressionToMethod(JvmGenericType it, FeatureAssociatedExpression spec, |
| String prefix, JvmTypeReference returnType, (JvmOperation, FeatureAssociatedExpression) => void parameterCreator) { |
| if (spec.feature?.simpleName != null) { |
| // associate the method to the expression, not to the whole |
| // spec, otherwise the 'feature' is logically |
| // contained in a method which should return a label |
| // and the validator would complain |
| members += spec.expression.toMethod |
| (prefix + |
| spec.parameterType.simpleName + "_" + |
| spec.feature.simpleName.propertyNameForGetterSetterMethod, |
| returnType |
| ) [ |
| parameterCreator.apply(it, spec) |
| body = spec.expression |
| ] |
| } |
| } |
| |
| def private inferFeatureProvider(Module element, IJvmDeclaredTypeAcceptor acceptor) { |
| element.featuresProvider.inferFeatureProviderCommon( |
| element.featuresProviderQN, typeof(FeaturesProvider), acceptor) |
| } |
| |
| def private inferTableFeatureProvider(Module element, IJvmDeclaredTypeAcceptor acceptor) { |
| element.tableFeaturesProvider. |
| inferFeatureProviderCommon(element.tableFeaturesProviderQN, typeof(TableFeaturesProvider), acceptor) |
| } |
| |
| def private inferFeatureProviderCommon(AbstractFeatureProvider element, String name, Class<?> superClass, IJvmDeclaredTypeAcceptor acceptor) { |
| if (element == null) |
| null |
| else { |
| val featureProviderClass = element.toClass(name) |
| acceptor.accept(featureProviderClass) [ |
| setSuperClassTypeAndFields(element, superClass) |
| |
| documentation = element.documentation |
| members += element. |
| toMethod("buildStringMap", Void::TYPE.getTypeForName(element)) [ |
| annotations += annotationRef(Override) |
| parameters += element.toParameter("stringMap", |
| typeRef(EClassToEStructuralFeatureAsStringsMap) |
| ) |
| body = [ |
| append("super.buildStringMap(stringMap);").newLine |
| for (featureSpecification : element.featureSpecifications) { |
| newLine. |
| append('''stringMap.mapTo("«featureSpecification.parameterType.identifier»",'''). |
| increaseIndentation.newLine |
| val fs = featureSpecification.features.map [ |
| feature | |
| '"' + feature.simpleName.propertyNameForGetterSetterMethod |
| + '"' |
| ] |
| append(fs.join(", ")) |
| append(");").decreaseIndentation |
| } |
| ] |
| ] |
| ] |
| featureProviderClass |
| } |
| } |
| |
| def private inferFormControlFactory(Module e, IJvmDeclaredTypeAcceptor acceptor) { |
| e.formControlFactory.inferControlFactory(e.formControlFactoryQN, typeof(FormControlFactory), acceptor) |
| } |
| |
| def private inferDialogControlFactory(Module e, IJvmDeclaredTypeAcceptor acceptor) { |
| e.dialogControlFactory.inferControlFactory(e.dialogControlFactoryQN, typeof(DialogControlFactory), acceptor) |
| } |
| |
| def private inferControlFactory(AbstractControlFactory e, String name, Class<?> superClass, IJvmDeclaredTypeAcceptor acceptor) { |
| if (e == null) |
| null |
| else { |
| val controlFactoryClass = e.toClass(name) |
| acceptor.accept(controlFactoryClass) [ |
| setSuperClassTypeAndFields(e, superClass) |
| |
| documentation = e.documentation |
| |
| inferMethodsForControlFactory(e, it, e.controlSpecifications) |
| ] |
| controlFactoryClass |
| } |
| } |
| |
| def private inferMethodsForControlFactory(AbstractControlFactory e, JvmGenericType it, Iterable<ControlFactorySpecification> specifications) { |
| for (spec: specifications) { |
| if (spec.feature?.simpleName != null) { |
| if (spec.target == null) |
| members += spec. |
| control_EClass_EStructuralFeature(spec.expression) [ |
| parameters += spec.toParameter( |
| "it", spec.parameterType |
| ) |
| body = spec.expression |
| ] |
| else { |
| val createControlMethodName = spec.methodNameForFormFeatureSpecification("createControl_") |
| val createTargetMethodName = spec.methodNameForFormFeatureSpecification("createTarget_") |
| members += spec. |
| control_EClass_EStructuralFeature(spec.expression) [ |
| parameters += spec.toParameter( |
| "dataBindingContext", typeRef(DataBindingContext) |
| ) |
| parameters += spec.toParameter( |
| "observableValue", typeRef(IObservableValue) |
| ) |
| body = [ |
| append(typeRef(Control).type) |
| append(''' control = «createControlMethodName»();''').newLine |
| append( |
| ''' |
| dataBindingContext.bindValue( |
| «createTargetMethodName»(control), |
| observableValue);''' |
| ).newLine |
| append('''return control;''') |
| ] |
| ] |
| |
| members += spec.toMethod |
| (createControlMethodName, |
| typeRef(Control)) [ |
| visibility = JvmVisibility::PROTECTED |
| body = spec.expression |
| ] |
| |
| members += spec.toMethod |
| (createTargetMethodName, |
| typeRef(IObservableValue)) [ |
| visibility = JvmVisibility::PROTECTED |
| parameters += spec.toParameter( |
| "it", typeRef(Control) |
| ) |
| body = spec.target |
| ] |
| } |
| } |
| } |
| } |
| |
| def private inferViewerContentProvider(Module element, IJvmDeclaredTypeAcceptor acceptor) { |
| if (element.viewerContentProvider == null) |
| null |
| else { |
| val viewerContentProvider = element.viewerContentProvider |
| val viewerContentProviderClass = viewerContentProvider.toClass(element.viewerContentProviderQN) |
| acceptor.accept(viewerContentProviderClass) [ |
| setSuperClassTypeAndFields(viewerContentProvider, typeof(ViewerContentProvider)) |
| |
| members += viewerContentProvider.toConstructor() [ |
| parameters += element.viewerContentProvider. |
| toParameter("adapterFactory", |
| typeRef(AdapterFactory) |
| ) |
| body = [it.append("super(adapterFactory);")] |
| annotations += annotationRef(Inject) |
| ] |
| |
| for (specification : viewerContentProvider.elementsSpecifications) { |
| members += specification.specificationToMethod("elements", typeRef(Object)) |
| } |
| |
| for (specification : viewerContentProvider.childrenSpecifications) { |
| members += specification.specificationToMethod("children", typeRef(Object)) |
| } |
| ] |
| viewerContentProviderClass |
| } |
| } |
| |
| def private inferProposalCreator(Module element, IJvmDeclaredTypeAcceptor acceptor) { |
| if (element.proposalCreator == null) |
| null |
| else { |
| val proposalCreator = element.proposalCreator |
| val proposalCreatorClass = proposalCreator.toClass(element.proposalCreatorQN) |
| acceptor.accept(proposalCreatorClass) [ |
| setSuperClassTypeAndFields(proposalCreator, typeof(ProposalCreator)) |
| |
| for (specification : proposalCreator.proposalsSpecifications) { |
| featureAssociatedExpressionToMethod(specification, "proposals_", typeRef(List).type.createTypeRef(wildCard)) [ |
| it, spec | |
| parameters += spec.toParameter( |
| "it", spec.parameterType |
| ) |
| parameters += spec.toParameter( |
| "feature", typeRef(EStructuralFeature) |
| ) |
| ] |
| } |
| ] |
| proposalCreatorClass |
| } |
| } |
| |
| def private inferMenuBuilder(Module element, IJvmDeclaredTypeAcceptor acceptor) { |
| if (element.menuBuilder == null) |
| null |
| else { |
| val menuBuilder = element.menuBuilder |
| val menuBuilderClass = menuBuilder.toClass(element.menuBuilderQN) |
| acceptor.accept(menuBuilderClass) [ |
| setSuperClassTypeAndFields(menuBuilder, EditingMenuBuilder) |
| |
| val returnType = typeRef(List, typeRef(IMenuContributionSpecification)) |
| |
| for (specification : menuBuilder.menuSpecifications) { |
| members += specification.specificationToMethod("menuContributions", returnType) |
| } |
| |
| for (specification : menuBuilder.emfMenuSpecifications) { |
| members += specification.specificationToMethod("emfMenuContributions", returnType) |
| } |
| ] |
| menuBuilderClass |
| } |
| } |
| |
| def private specificationToMethod(LabelSpecification specification, String methodName, JvmTypeReference returnType) { |
| specification.toMethod(methodName, returnType) [ |
| parameters += specification.specificationParameter |
| body = specification.expression |
| ] |
| } |
| |
| def private specificationParameter(LabelSpecification specification) { |
| specification.toParameter( |
| if (specification.name != null) |
| specification.name |
| else |
| "it" |
| , specification.parameterType |
| ) |
| } |
| |
| def private control_EClass_EStructuralFeature( |
| ControlFactorySpecification spec, XExpression exp, (JvmOperation)=>void init |
| ) { |
| exp.toMethod |
| (spec.methodNameForFormFeatureSpecification("control_"), |
| typeRef(Control) |
| , init) |
| } |
| |
| def private methodNameForFormFeatureSpecification(ControlFactorySpecification spec, String prefix) { |
| prefix + |
| spec.parameterType.simpleName + "_" + |
| spec.feature.simpleName.propertyNameForGetterSetterMethod |
| } |
| |
| def private genBindMethod(EObject element, JvmGenericType type, Class<?> clazz) { |
| genBindMethod(element, typeRef(clazz), true) [ |
| body = [ |
| append("return ") |
| append(type) |
| append(".class;") |
| ] |
| ] |
| } |
| |
| def private handleBindingsSpecification(JvmGenericType it, BindingsSpecification bindingsSpecification) { |
| for (binding : bindingsSpecification.bindings) { |
| var JvmOperation method = null |
| if (binding instanceof TypeBinding) { |
| method = genBindMethod(binding) |
| } else if (binding instanceof ProviderBinding) { |
| method = genProvideMethod(binding) |
| } else if (binding instanceof ValueBinding) { |
| method = genValueMethod(binding) |
| } |
| |
| if (method != null) { |
| members += method |
| } |
| } |
| } |
| |
| def private genBindMethod(JvmGenericType it, TypeBinding typeBinding) { |
| if (typeBinding.typeToBind == null) { |
| return null |
| } |
| |
| // we must trigger resolution of JvmTypeReference |
| // otherwise the parameterized Class type with wildcard |
| // will contain an unresolved type reference |
| genBindMethod(typeBinding, typeBinding.typeToBind.type.typeRef) [ |
| body = typeBinding.getTo |
| ] |
| } |
| |
| def private genProvideMethod(JvmGenericType it, ProviderBinding binding) { |
| if (binding.type == null) { |
| return null |
| } |
| |
| // we must trigger resolution of JvmTypeReference |
| // otherwise the parameterized Class type with wildcard |
| // will contain an unresolved type reference |
| genProvideMethod(binding, binding.type.type.typeRef) [ |
| body = binding.getTo |
| ] |
| } |
| |
| def private genValueMethod(JvmGenericType it, ValueBinding binding) { |
| if (binding.typeDecl == null || binding.id == null) { |
| return null |
| } |
| |
| genValueMethod(binding, binding.id, binding.typeDecl) [ |
| body = binding.getTo |
| ] |
| } |
| |
| |
| def private genBindMethod(EObject element, JvmTypeReference typeRefToBind, boolean shouldOverride, IAcceptor<JvmExecutable> acceptor) { |
| element.genMethodForGuiceModuleWithWildcard("bind" + typeRefToBind.simpleName, |
| typeRefToBind.cloneWithProxies, shouldOverride, acceptor |
| ) |
| } |
| |
| def private genBindMethod(JvmGenericType it, EObject element, JvmTypeReference typeRefToBind, IAcceptor<JvmExecutable> acceptor) { |
| val methodName = "bind" + typeRefToBind.simpleName |
| element.genMethodForGuiceModuleWithWildcard(methodName, |
| typeRefToBind.cloneWithProxies, shouldOverride(methodName), acceptor |
| ) |
| } |
| |
| def private genProvideMethod(JvmGenericType it, EObject element, JvmTypeReference typeRefToBind, IAcceptor<JvmExecutable> acceptor) { |
| val methodName = "provide" + typeRefToBind.simpleName |
| element.genMethodForGuiceModuleWithWildcard(methodName, |
| typeRef(Provider, typeRefToBind.cloneWithProxies), shouldOverride(methodName), acceptor |
| ) |
| } |
| |
| def private genValueMethod(JvmGenericType it, EObject element, String name, JvmTypeReference typeRefToBind, IAcceptor<JvmExecutable> acceptor) { |
| val methodName = "value" + name |
| element.genMethodForGuiceModule(methodName, typeRefToBind.cloneWithProxies, shouldOverride(methodName), acceptor) |
| } |
| |
| def private genMethodForGuiceModuleWithWildcard(EObject element, String methodName, |
| JvmTypeReference typeRefToBind, boolean shouldOverride, IAcceptor<JvmExecutable> acceptor |
| ) { |
| val wildCard = createJvmWildcardTypeReference |
| val upperBound = createJvmUpperBound |
| upperBound.typeReference = typeRefToBind.cloneWithProxies |
| wildCard.constraints += upperBound |
| element.genMethodForGuiceModule(methodName, typeRef(Class, wildCard), shouldOverride, acceptor) |
| } |
| |
| def private genMethodForGuiceModule(EObject element, String methodName, JvmTypeReference typeRefToBind, boolean shouldOverride, IAcceptor<JvmExecutable> acceptor) { |
| element.toMethod(methodName, typeRefToBind) [ |
| if (shouldOverride) { |
| annotations += annotationRef(Override) |
| } |
| acceptor.accept(it) |
| ] |
| } |
| |
| def private shouldOverride(JvmGenericType it, String methodName) { |
| allFeatures.filter(JvmOperation).exists[simpleName == methodName] |
| } |
| } |
| |