blob: 5bcd90501b8427f3483d8076b3328bb3c4504321 [file] [log] [blame]
Ed Willink17785c52014-05-20 12:29:51 +01001/*******************************************************************************
Ed Willink52e3d062015-05-19 10:14:44 +01002 * Copyright (c) 2013 Willink Transformations and others.
Ed.Willink393222a2013-06-08 17:12:00 +01003 * All rights reserved. This program and the accompanying materials
Ed Willink2b4d8be2018-06-13 11:53:02 +01004 * are made available under the terms of the Eclipse Public License v2.0
Ed.Willink393222a2013-06-08 17:12:00 +01005 * which accompanies this distribution, and is available at
Ed Willink2b4d8be2018-06-13 11:53:02 +01006 * http://www.eclipse.org/legal/epl-v20.html
Ed.Willink393222a2013-06-08 17:12:00 +01007 *
8 * Contributors:
9 * E.D.Willink - initial API and implementation
Ed Willink5a6db182013-07-10 18:07:52 +010010 * Adolfo Sanchez-Barbudo Herrera (University of York) - bug397429
Ed Willink17785c52014-05-20 12:29:51 +010011 *******************************************************************************/
Ed.Willink393222a2013-06-08 17:12:00 +010012package org.eclipse.ocl.examples.build.xtend
13
Ed Willink82adc702014-12-10 14:46:20 +000014import org.eclipse.emf.codegen.ecore.genmodel.GenPackage
Ed.Willink393222a2013-06-08 17:12:00 +010015import org.eclipse.emf.ecore.EClass
Ed.Willink393222a2013-06-08 17:12:00 +010016import org.eclipse.emf.ecore.EPackage
Ed Willinkfc3d1982015-11-23 11:26:40 +000017import org.eclipse.ocl.pivot.Type
18import org.eclipse.ocl.pivot.internal.manager.TemplateParameterSubstitutionVisitor
Ed Willinkdaed9682019-02-23 22:16:31 +000019import org.eclipse.ocl.pivot.internal.manager.FlowAnalysis
Ed.Willink393222a2013-06-08 17:12:00 +010020
Ed Willinkdaed9682019-02-23 22:16:31 +000021abstract class GenerateVisitorsXtend extends GenerateVisitors
Ed.Willink393222a2013-06-08 17:12:00 +010022{
Ed.Willink9ad6ca72013-08-24 14:21:42 +010023 /*
24 * Abstract«projectPrefix»«generic»Visitor
25 */
Ed Willink70051092015-12-23 19:11:07 +000026 protected def void generateAbstractGenericVisitor(/*@NonNull*/ EPackage ePackage, /*@NonNull*/ String generic, /*@NonNull*/ Class<?> returnClass, /*@NonNull*/ Class<?> contextClass) {
Ed.Willink9ad6ca72013-08-24 14:21:42 +010027 var boolean isDerived = isDerived();
Ed Willink83d1bdf2014-01-18 21:13:27 +000028 var boolean needsOverride = needsOverride();
Ed.Willink9ad6ca72013-08-24 14:21:42 +010029 var MergeWriter writer = new MergeWriter(outputFolder + "Abstract" + projectPrefix + generic + "Visitor.java");
30 writer.append('''
31 «ePackage.generateHeader(visitorPackageName)»
Ed Willink841cda92016-11-19 09:48:34 +000032
Ed.Willink9ad6ca72013-08-24 14:21:42 +010033 import «returnClass.getName()»;
34 import org.eclipse.jdt.annotation.NonNull;
35 import org.eclipse.jdt.annotation.Nullable;
36 import «contextClass.getName()»;
37 «IF isDerived»import «superVisitorPackageName»ities.«superProjectPrefix»«generic»Visitor;«ENDIF»
Ed Willink841cda92016-11-19 09:48:34 +000038
Ed.Willink9ad6ca72013-08-24 14:21:42 +010039 /**
40 * An Abstract«projectPrefix»«generic»Visitor provides a default implementation for each
41 * visitXxx method that delegates to the visitYyy method of the first
42 * super class, (or transitively its first super class' first super class
43 * until a non-interface super-class is found). In the absence of any
44 * suitable first super class, the method delegates to visiting().
45 */
46 public abstract class Abstract«projectPrefix»«generic»Visitor
47 «IF isDerived»extends «superProjectPrefix»«generic»Visitor«ENDIF»
48 implements «visitorClassName»<«returnClass.getSimpleName()»>
49 {
50 /**
51 * Initializes me with an initial value for my result.
Ed Willink841cda92016-11-19 09:48:34 +000052 *
Ed.Willink9ad6ca72013-08-24 14:21:42 +010053 * @param context my initial result value
54 */
Ed Willinkda0fc682016-01-05 13:04:43 +000055 protected Abstract«projectPrefix»«generic»VisitoremitNonNull(contextClass.getSimpleName())» context) {
Ed.Willink9ad6ca72013-08-24 14:21:42 +010056 super(context);
Ed Willink841cda92016-11-19 09:48:34 +000057 }
Ed.Willink9ad6ca72013-08-24 14:21:42 +010058 «FOR eClass : getSortedEClasses(ePackage
59 «var EClass firstSuperClass = eClass.firstSuperClass(eClass
Ed Willink841cda92016-11-19 09:48:34 +000060
Ed Willink83d1bdf2014-01-18 21:13:27 +000061 «IF needsOverride»
62 @Override
63 «ENDIF»
Ed Willinkda0fc682016-01-05 13:04:43 +000064 public «emitNullable(returnClass.getSimpleName())» visit«eClass.name»(«emitNonNull(modelPackageName + "." + getTemplatedName(eClass))» object) {
Ed.Willink9ad6ca72013-08-24 14:21:42 +010065 «IF firstSuperClass == eClass»
66 return visiting(object);
67 «ELSE»
68 return visit«firstSuperClass.name»(object);
69 «ENDIF»
70 }
71 «ENDFOR»
72 }
73 ''');
74 writer.close();
75 }
76
Ed.Willink393222a2013-06-08 17:12:00 +010077 /*
78 * AbstractDelegatingVisitor
79 */
Ed Willink70051092015-12-23 19:11:07 +000080 protected def void generateAbstractDelegatingVisitor(/*@NonNull*/ EPackage ePackage) {
Ed Willink5a6db182013-07-10 18:07:52 +010081 var boolean isDerived = isDerived();
Ed Willink83d1bdf2014-01-18 21:13:27 +000082 var boolean needsOverride = needsOverride();
Ed.Willink393222a2013-06-08 17:12:00 +010083 var MergeWriter writer = new MergeWriter(outputFolder + "AbstractDelegating" + visitorClassName + ".java");
84 writer.append('''
85 «ePackage.generateHeader(visitorPackageName
Ed Willink841cda92016-11-19 09:48:34 +000086
Ed.Willink393222a2013-06-08 17:12:00 +010087 import org.eclipse.jdt.annotation.NonNull;
Ed Willink841cda92016-11-19 09:48:34 +000088
Ed.Willink393222a2013-06-08 17:12:00 +010089 /**
90 * An AbstractDelegating«visitorClassName» delegates all visits.
91 */
Ed Willink2319fa42016-03-24 10:33:45 +000092 public abstract class AbstractDelegating«visitorClassName»<R, C, @NonNull D extends «visitorClassName»<R>>
Ed Willink5a6db182013-07-10 18:07:52 +010093 extends «IF isDerived»«superVisitorPackageName».AbstractDelegating«superVisitorClassName»<R, C, DELSE»«IF isDerived»«superVisitorClassName»«ELSE»Abstract«visitorClassName»«ENDIF»<R, CENDIF»
Ed.Willink393222a2013-06-08 17:12:00 +010094 implements «visitorClassName»<R>
95 {
96 «IF isDerived»
Ed Willinkda0fc682016-01-05 13:04:43 +000097 protected AbstractDelegating«visitorClassName»(@NonNull D delegate, C context) {
Ed.Willink393222a2013-06-08 17:12:00 +010098 super(delegate, context);
99 }
100 «ELSE»
Ed Willink2319fa42016-03-24 10:33:45 +0000101 protected final @NonNull D delegate;
Ed Willink841cda92016-11-19 09:48:34 +0000102
Ed Willinkda0fc682016-01-05 13:04:43 +0000103 protected AbstractDelegating«visitorClassName»(@NonNull D delegate, C context) {
Ed.Willink393222a2013-06-08 17:12:00 +0100104 super(context);
105 // assert delegate != null : "cannot decorate a null visitor"; //$NON-NLS-1$
Ed Willink841cda92016-11-19 09:48:34 +0000106 this.delegate = delegate;
Ed.Willink393222a2013-06-08 17:12:00 +0100107 // delegate.setUndecoratedVisitor(this);
108 }
109
110 /**
111 * Delegates to my decorated visitor.
112 */
113 // public @NonNull Decorable«visitorClassName»<R> createNestedVisitor() {
114 // return delegate.createNestedVisitor();
115 // }
116
117 /**
118 * Obtains the visitor that I decorate.
Ed Willink841cda92016-11-19 09:48:34 +0000119 *
Ed.Willink393222a2013-06-08 17:12:00 +0100120 * @return my decorated visitor
121 */
Ed.Willink393222a2013-06-08 17:12:00 +0100122 protected final @NonNull D getDelegate() {
123 return delegate;
124 }
125 «ENDIF»
Ed Willink841cda92016-11-19 09:48:34 +0000126
Ed Willink9cb4ea62014-12-04 19:35:50 +0000127 «IF isDerived || needsOverride»
Ed.Willink393222a2013-06-08 17:12:00 +0100128 @Override
129 «ENDIF»
Ed Willinkda0fc682016-01-05 13:04:43 +0000130 public R visitingemitNonNull(visitablePackageName + "." + visitableClassName visitable) {
Ed.Willink393222a2013-06-08 17:12:00 +0100131 return delegate.visiting(visitable);
132 }
133 «FOR eClass : getSortedEClasses(ePackage
134
Ed Willink83d1bdf2014-01-18 21:13:27 +0000135 «IF needsOverride»
136 @Override
137 «ENDIF»
Ed Willinkda0fc682016-01-05 13:04:43 +0000138 public R visit«eClass.name»(«emitNonNull(modelPackageName + "." + getTemplatedName(eClass))» object) {
Ed.Willink393222a2013-06-08 17:12:00 +0100139 return delegate.visit«eClass.name»(object);
140 }
141 «ENDFOR»
142 }
143 ''');
144 writer.close();
145 }
146
147 /*
Ed Willink28812522013-11-23 12:57:41 +0000148 * AbstractExtendingDelegatingVisitor
Ed.Willink393222a2013-06-08 17:12:00 +0100149 */
Ed Willink70051092015-12-23 19:11:07 +0000150 protected def void generateAbstractExtendingDelegatingVisitor(/*@NonNull*/ EPackage ePackage) {
Ed.Willink393222a2013-06-08 17:12:00 +0100151 var MergeWriter writer = new MergeWriter(outputFolder + "AbstractExtendingDelegating" + visitorClassName + ".java");
152 writer.append('''
153 «ePackage.generateHeader(visitorPackageName
Ed Willink841cda92016-11-19 09:48:34 +0000154
Ed.Willink393222a2013-06-08 17:12:00 +0100155 import org.eclipse.jdt.annotation.NonNull;
156 import org.eclipse.jdt.annotation.Nullable;
157 import «superVisitorPackageName».AbstractDelegating«superVisitorClassName»;
Ed Willink5a6db182013-07-10 18:07:52 +0100158 import «superVisitorPackageName».«superVisitorClassName»;
Ed Willink841cda92016-11-19 09:48:34 +0000159
Ed.Willink393222a2013-06-08 17:12:00 +0100160 /**
Ed.Willinkf1ec73c2013-07-10 11:36:49 +0100161 * An AbstractExtendingDelegating«visitorClassName» provides a default implementation for each
162 * visitXxx method that delegates to the supertype if the supertype is in the same package as
163 * the visited type, otherwise it delegates to the delegate.
Ed.Willink393222a2013-06-08 17:12:00 +0100164 */
Adolfo SBHbddb3c72013-08-15 10:13:10 +0100165 public abstract class AbstractExtendingDelegating«visitorClassName»<R, C, D extends «superVisitorClassName»<R>>
Ed.Willink393222a2013-06-08 17:12:00 +0100166 extends AbstractDelegating«superVisitorClassName»<R, C, D>
167 implements «visitorClassName»<R>
168 {
169 «IF true»
Ed Willinkda0fc682016-01-05 13:04:43 +0000170 protected AbstractExtendingDelegating«visitorClassName»(@NonNull D delegate, C context) {
Ed.Willink393222a2013-06-08 17:12:00 +0100171 super(delegate, context);
172 }
173 «ELSE»
174 protected final D delegate;
Ed Willink841cda92016-11-19 09:48:34 +0000175
Ed Willinkda0fc682016-01-05 13:04:43 +0000176 protected AbstractExtendingDelegating«visitorClassName»(@NonNull D delegate, C context) {
Ed.Willink393222a2013-06-08 17:12:00 +0100177 super(context);
Ed Willink841cda92016-11-19 09:48:34 +0000178 // assert delegate != null : "cannot decorate a null visitor"; //$NON-NLS-1$
179 this.delegate = delegate;
Ed.Willink393222a2013-06-08 17:12:00 +0100180 // delegate.setUndecoratedVisitor(this);
181 }
182
183 /**
184 * Delegates to my decorated visitor.
185 */
186 // public Decorable«visitorClassName»<R> createNestedVisitor() {
187 // return delegate.createNestedVisitor();
188 // }
189
190 /**
191 * Obtains the visitor that I decorate.
Ed Willink841cda92016-11-19 09:48:34 +0000192 *
Ed.Willink393222a2013-06-08 17:12:00 +0100193 * @return my decorated visitor
194 */
195 protected final D getDelegate() {
196 return delegate;
197 }
198 «ENDIF»
199
200 @Override
Ed Willinkda0fc682016-01-05 13:04:43 +0000201 public R visitingemitNonNull(visitablePackageName + "." + visitableClassName visitable) {
Ed.Willink393222a2013-06-08 17:12:00 +0100202 return delegate.visiting(visitable);
203 }
204 «FOR eClass : getSortedEClasses(ePackage
205 «var EClass firstSuperClass = eClass.firstSuperClass(eClass
206
Ed Willink83d1bdf2014-01-18 21:13:27 +0000207 «IF needsOverride»
208 @Override
209 «ENDIF»
Ed Willinkda0fc682016-01-05 13:04:43 +0000210 public R visit«eClass.name»(«emitNonNull(modelPackageName + "." + getTemplatedName(eClass))» object) {
Ed.Willink393222a2013-06-08 17:12:00 +0100211 «IF firstSuperClass == eClass»
212 return visiting(object);
213 «ELSEIF firstSuperClass.getEPackage() == eClass.getEPackage()»
214 return visit«firstSuperClass.name»(object);
215 «ELSE»
Adolfo SBHbddb3c72013-08-15 10:13:10 +0100216 return delegate.visit«firstSuperClass.name»(object);
Ed.Willink393222a2013-06-08 17:12:00 +0100217 «ENDIF»
218 }
219 «ENDFOR»
220 }
221 ''');
222 writer.close();
223 }
224
225 /*
226 * AbstractExtendingVisitor
227 */
Ed Willink70051092015-12-23 19:11:07 +0000228 protected def void generateAbstractExtendingVisitor(/*@NonNull*/ EPackage ePackage) {
Ed Willink5a6db182013-07-10 18:07:52 +0100229 var boolean isDerived = isDerived();
Ed Willink83d1bdf2014-01-18 21:13:27 +0000230 var boolean needsOverride = needsOverride();
Ed.Willink393222a2013-06-08 17:12:00 +0100231 var MergeWriter writer = new MergeWriter(outputFolder + "AbstractExtending" + visitorClassName + ".java");
232 writer.append('''
233 «ePackage.generateHeader(visitorPackageName
Ed Willink841cda92016-11-19 09:48:34 +0000234
Ed.Willink393222a2013-06-08 17:12:00 +0100235 import org.eclipse.jdt.annotation.NonNull;
Ed Willink841cda92016-11-19 09:48:34 +0000236
Ed.Willink393222a2013-06-08 17:12:00 +0100237 /**
238 * An AbstractExtending«visitorClassName» provides a default implementation for each
239 * visitXxx method that delegates to the visitYyy method of the first
Ed.Willink9ad6ca72013-08-24 14:21:42 +0100240 * super class, (or transitively its first super class' first super class
Ed.Willink393222a2013-06-08 17:12:00 +0100241 * until a non-interface super-class is found). In the absence of any
242 * suitable first super class, the method delegates to visiting().
243 */
244 public abstract class AbstractExtending«visitorClassName»<R, C>
Ed Willink5a6db182013-07-10 18:07:52 +0100245 extends «IF isDerived»«superVisitorPackageName».AbstractExtending«superVisitorClassName»«ELSE»Abstract«visitorClassName»«ENDIF»<R, C>
Ed.Willink393222a2013-06-08 17:12:00 +0100246 implements «visitorClassName»<R>
247 {
248 /**
249 * Initializes me with an initial value for my result.
Ed Willink841cda92016-11-19 09:48:34 +0000250 *
Ed.Willink393222a2013-06-08 17:12:00 +0100251 * @param context my initial result value
252 */
Ed Willinkda0fc682016-01-05 13:04:43 +0000253 protected AbstractExtending«visitorClassName»(C context) {
Ed.Willink393222a2013-06-08 17:12:00 +0100254 super(context);
Ed Willink841cda92016-11-19 09:48:34 +0000255 }
Ed.Willink393222a2013-06-08 17:12:00 +0100256 «FOR eClass : getSortedEClasses(ePackage
257 «var EClass firstSuperClass = eClass.firstSuperClass(eClass
Ed Willink841cda92016-11-19 09:48:34 +0000258
Ed Willink83d1bdf2014-01-18 21:13:27 +0000259 «IF needsOverride»
260 @Override
261 «ENDIF»
Ed Willinkda0fc682016-01-05 13:04:43 +0000262 public R visit«eClass.name»(«emitNonNull(modelPackageName + "." + getTemplatedName(eClass))» object) {
Ed.Willink393222a2013-06-08 17:12:00 +0100263 «IF firstSuperClass == eClass»
264 return visiting(object);
265 «ELSE»
266 return visit«firstSuperClass.name»(object);
267 «ENDIF»
268 }
269 «ENDFOR»
270 }
271 ''');
272 writer.close();
273 }
Ed Willink0100b5f2015-06-13 17:41:07 +0100274
275 /*
276 * AbstractMergedVisitor
277 */
Ed Willink70051092015-12-23 19:11:07 +0000278 protected def void generateAbstractMergedVisitor(/*@NonNull*/ EPackage ePackage) {
Ed Willink0100b5f2015-06-13 17:41:07 +0100279 var boolean isDerived = isDerived();
280 var boolean needsOverride = needsOverride();
281 var MergeWriter writer = new MergeWriter(outputFolder + "AbstractMerged" + visitorClassName + ".java");
282 writer.append('''
283 «ePackage.generateHeader(visitorPackageName
Ed Willink841cda92016-11-19 09:48:34 +0000284
Ed Willink0100b5f2015-06-13 17:41:07 +0100285 import org.eclipse.jdt.annotation.NonNull;
Ed Willink841cda92016-11-19 09:48:34 +0000286
Ed Willink0100b5f2015-06-13 17:41:07 +0100287 /**
288 * An AbstractMerged«visitorClassName» merges all visits direct to visiting().
289 * This can be used by a decorating visitor to execute shared code before redispatching to a decorated visitor.
290 */
291 public abstract class AbstractMerged«visitorClassName»<R, C>
292 extends «IF isDerived»«superVisitorPackageName».AbstractMerged«superVisitorClassName»<R, CELSE»«IF isDerived»«superVisitorClassName»«ELSE»Abstract«visitorClassName»«ENDIF»<R, CENDIF»
293 implements «visitorClassName»<R>
294 {
Ed Willinkda0fc682016-01-05 13:04:43 +0000295 protected AbstractMerged«visitorClassName»(C context) {
Ed Willink0100b5f2015-06-13 17:41:07 +0100296 super(context);
297 }
298 «FOR eClass : getSortedEClasses(ePackage
299
300 «IF needsOverride»
301 @Override
302 «ENDIF»
Ed Willinkda0fc682016-01-05 13:04:43 +0000303 public R visit«eClass.name»(«emitNonNull(modelPackageName + "." + getTemplatedName(eClass))» object) {
Ed Willink0100b5f2015-06-13 17:41:07 +0100304 return visiting(object);
305 }
306 «ENDFOR»
307 }
308 ''');
309 writer.close();
310 }
311
Ed.Willink393222a2013-06-08 17:12:00 +0100312 /*
Ed Willink8f454a62013-07-30 18:07:23 +0100313 * AbstractNonNullExtendingVisitor
314 */
Ed Willink70051092015-12-23 19:11:07 +0000315 protected def void generateAbstractNonNullExtendingVisitor(/*@NonNull*/ EPackage ePackage) {
Ed Willink8f454a62013-07-30 18:07:23 +0100316 var boolean isDerived = isDerived();
Ed Willink83d1bdf2014-01-18 21:13:27 +0000317 var boolean needsOverride = needsOverride();
Ed Willink8f454a62013-07-30 18:07:23 +0100318 var MergeWriter writer = new MergeWriter(outputFolder + "AbstractNonNullExtending" + visitorClassName + ".java");
319 writer.append('''
320 «ePackage.generateHeader(visitorPackageName
Ed Willink841cda92016-11-19 09:48:34 +0000321
Ed Willink8f454a62013-07-30 18:07:23 +0100322 import org.eclipse.jdt.annotation.NonNull;
Ed Willink841cda92016-11-19 09:48:34 +0000323
Ed Willink8f454a62013-07-30 18:07:23 +0100324 /**
325 * An AbstractExtendingNonNull«visitorClassName» provides a default implementation for each
326 * visitXxx method that delegates to the visitYyy method of the first
327 * super class, (or transitively its first super class first super class
328 * until a non-interface super-class is found). In the absence of any
329 * suitable first super class, the method delegates to visiting().
Ed Willinkda0fc682016-01-05 13:04:43 +0000330 * The return is annotated as @NonNull.
331 *
Ed Willink841cda92016-11-19 09:48:34 +0000332 * @deprecated Explicit 'NonNull' functionality is obsolete with Java 8 @NonNull annotations.
Ed Willink8f454a62013-07-30 18:07:23 +0100333 */
Ed Willinkda0fc682016-01-05 13:04:43 +0000334 @Deprecated
Ed Willink8f454a62013-07-30 18:07:23 +0100335 public abstract class AbstractNonNullExtending«visitorClassName»<R, C>
336 extends «IF isDerived»«superVisitorPackageName».AbstractNonNullExtending«superVisitorClassName»«ELSE»Abstract«visitorClassName»«ENDIF»<R, C>
337 implements «visitorClassName»<R>
338 {
339 /**
340 * Initializes me with an initial value for my result.
Ed Willink841cda92016-11-19 09:48:34 +0000341 *
Ed Willink8f454a62013-07-30 18:07:23 +0100342 * @param context my initial result value
343 */
Ed Willinkda0fc682016-01-05 13:04:43 +0000344 protected AbstractNonNullExtending«visitorClassName»(C context) {
Ed Willink8f454a62013-07-30 18:07:23 +0100345 super(context);
Ed Willink841cda92016-11-19 09:48:34 +0000346 }
Ed Willink8f454a62013-07-30 18:07:23 +0100347 «IF !isDerived»
Ed Willink841cda92016-11-19 09:48:34 +0000348
Ed Willink8f454a62013-07-30 18:07:23 +0100349 /**
350 * Perform a visit to the specified visitable.
Ed Willink841cda92016-11-19 09:48:34 +0000351 *
Ed Willink8f454a62013-07-30 18:07:23 +0100352 * @param visitable a visitable
353 * @return the non-null result of visiting it
354 */
355 @Override
Ed Willinkda0fc682016-01-05 13:04:43 +0000356 public @NonNull R visitemitNonNull(visitablePackageName + "." + visitableClassName visitable) {
Ed Willink8f454a62013-07-30 18:07:23 +0100357 R result = visitable.accept(this);
358 if (result == null) {
359 throw new IllegalStateException("null return from non-null " + getClass().getName());
360 }
361 return result;
362 }
363 «ENDIF»
364 «FOR eClass : getSortedEClasses(ePackage
365 «var EClass firstSuperClass = eClass.firstSuperClass(eClass
Ed Willink841cda92016-11-19 09:48:34 +0000366
Ed Willink83d1bdf2014-01-18 21:13:27 +0000367 «IF needsOverride»
368 @Override
369 «ENDIF»
Ed Willinkda0fc682016-01-05 13:04:43 +0000370 public @NonNull R visit«eClass.name»(«emitNonNull(modelPackageName+ "." + getTemplatedName(eClass))» object) {
Ed Willink8f454a62013-07-30 18:07:23 +0100371 «IF firstSuperClass == eClass»
372 return visiting(object);
373 «ELSE»
374 return visit«firstSuperClass.name»(object);
375 «ENDIF»
376 }
377 «ENDFOR»
378 «IF !isDerived»
379
380 /**
381 * Return the result of visiting a visitable for which no more specific pivot type method
382 * is available.
383 */
Ed Willink83d1bdf2014-01-18 21:13:27 +0000384 «IF needsOverride»
385 @Override
386 «ENDIF»
Ed Willinkda0fc682016-01-05 13:04:43 +0000387 public abstract @NonNull R visitingemitNonNull(visitablePackageName+ "." + visitableClassName visitable);
Ed Willink8f454a62013-07-30 18:07:23 +0100388 «ENDIF»
389 }
390 ''');
391 writer.close();
392 }
393
394 /*
Ed.Willink393222a2013-06-08 17:12:00 +0100395 * AbstractNullVisitor
396 */
Ed Willink70051092015-12-23 19:11:07 +0000397 protected def void generateAbstractNullVisitor(/*@NonNull*/ EPackage ePackage) {
Ed Willink5a6db182013-07-10 18:07:52 +0100398 var boolean isDerived = isDerived();
Ed Willink83d1bdf2014-01-18 21:13:27 +0000399 var boolean needsOverride = needsOverride();
Ed.Willink393222a2013-06-08 17:12:00 +0100400 var MergeWriter writer = new MergeWriter(outputFolder + "AbstractNull" + visitorClassName + ".java");
401 writer.append('''
402 «ePackage.generateHeader(visitorPackageName
403
404 import org.eclipse.jdt.annotation.NonNull;
405 import org.eclipse.jdt.annotation.Nullable;
406
407 /**
408 * An AbstractNull«visitorClassName» provides a default implementation for each
409 * visitXxx method that returns null.
Ed Willinkda0fc682016-01-05 13:04:43 +0000410 *
Ed Willink841cda92016-11-19 09:48:34 +0000411 * @deprecated Explicit 'Null' functionality is obsolete with Java 8 @Nullable annotations.
Ed.Willink393222a2013-06-08 17:12:00 +0100412 */
Ed Willinkda0fc682016-01-05 13:04:43 +0000413 @Deprecated
414 public abstract class AbstractNull«visitorClassName»<@Nullable R, C>
Ed Willink5a6db182013-07-10 18:07:52 +0100415 «IF !isDerived»
Ed.Willink393222a2013-06-08 17:12:00 +0100416 extends Abstract«visitorClassName»<R, C>
417 «ELSE»
418 extends «superVisitorPackageName».AbstractNull«superVisitorClassName»<R, C> implements «visitorClassName»<R>
419 «ENDIF»
420 {
421 /**
422 * Initializes me with an initial value for my result.
Ed Willink841cda92016-11-19 09:48:34 +0000423 *
Ed.Willink393222a2013-06-08 17:12:00 +0100424 * @param context my initial result value
425 */
Ed Willinkda0fc682016-01-05 13:04:43 +0000426 protected AbstractNull«visitorClassName»(C context) {
Ed.Willink393222a2013-06-08 17:12:00 +0100427 super(context);
Ed Willink841cda92016-11-19 09:48:34 +0000428 }
Ed.Willink393222a2013-06-08 17:12:00 +0100429 «FOR eClass : getSortedEClasses(ePackage
430
Ed Willink83d1bdf2014-01-18 21:13:27 +0000431 «IF needsOverride»
432 @Override
433 «ENDIF»
Ed Willinkda0fc682016-01-05 13:04:43 +0000434 public R visit«eClass.name»(«emitNonNull(modelPackageName + "." + getTemplatedName(eClass))» object) {
Ed.Willink393222a2013-06-08 17:12:00 +0100435 return null;
436 }
437 «ENDFOR»
438 }
439 ''');
440 writer.close();
441 }
Ed Willinkdaed9682019-02-23 22:16:31 +0000442
Ed Willinkfc3d1982015-11-23 11:26:40 +0000443 /*
Ed Willinkdaed9682019-02-23 22:16:31 +0000444 * Abstract«projectPrefix»«generic»FlowAnalysisDeducerFromTrueVisitor
445 */
446 protected def void generateAbstractFlowAnalysisDeducerVisitor(/*@NonNull*/ EPackage ePackage, /*@NonNull*/ String generic, /*@NonNull*/ Class<?> returnClass, /*@NonNull*/ Class<?> contextClass, boolean isNull) {
447 var boolean isDerived = isDerived();
448 var boolean needsOverride = needsOverride();
449 var MergeWriter writer = new MergeWriter(outputFolder + "Abstract" + projectPrefix + generic + "Visitor.java");
450 writer.append('''
451 «ePackage.generateHeader(visitorPackageName
452
453 import «returnClass.getName()»;
454 import org.eclipse.jdt.annotation.NonNull;
455 import org.eclipse.jdt.annotation.Nullable;
456 import «contextClass.getName()»;
457 «IF isDerived && !superProjectPrefix.equals(""import «superVisitorPackageName»itiessuperProjectPrefix»«generic»VisitorENDIF»
458 «IF isDerived && superProjectPrefix.equals(""import «FlowAnalysis.getName()»;«ENDIF»
459
460 /**
461 * An Abstract«projectPrefix»«generic»Visitor provides a default implementation for each
462 * visitXxx method that delegates to the visitYyy method of the first
463 * super class, (or transitively its first super class' first super class
464 * until a non-interface super-class is found). In the absence of any
465 * suitable first super class, the method delegates to visiting().
466 */
467 public abstract class Abstract«projectPrefix»«generic»Visitor
468 «IF isDerived»extends «superProjectPrefix»«generic»Visitor«ENDIF»
469 implements «visitorClassName»<«returnClass.getSimpleName()»>
470 {
471 /**
472 * Initializes me with an initial value for my result.
473 *
474 * @param context my initial result value
475 */
476 protected Abstract«projectPrefix»«generic»VisitoremitNonNull(contextClass.getSimpleName())» flowAnalysis«IF isNull», boolean isNull«ENDIF») {
477 super(flowAnalysis«IF isNull», isNull«ENDIF»);
478 }
479 «FOR eClass : getSortedEClasses(ePackage
480 «var EClass firstSuperClass = eClass.firstSuperClass(eClass
481
482 «IF needsOverride»
483 @Override
484 «ENDIF»
485 public «emitNullable(returnClass.getSimpleName())» visit«eClass.name»(«emitNonNull(modelPackageName + "." + getTemplatedName(eClass))» object) {
486 «IF firstSuperClass == eClass»
487 return visiting(object);
488 «ELSE»
489 return visit«firstSuperClass.name»(object);
490 «ENDIF»
491 }
492 «ENDFOR»
493 }
494 ''');
495 writer.close();
496 }
497
498 /*
499 * Abstract«projectPrefix»«generic»TemplateParameterSubstitutionVisitor
Ed Willinkfc3d1982015-11-23 11:26:40 +0000500 */
Ed Willink70051092015-12-23 19:11:07 +0000501 protected def void generateAbstractTemplateParameterSubstitutionVisitor(/*@NonNull*/ EPackage ePackage, /*@NonNull*/ String generic, /*@NonNull*/ Class<?> returnClass, /*@NonNull*/ Class<?> contextClass) {
Ed Willinkfc3d1982015-11-23 11:26:40 +0000502 var boolean isDerived = isDerived();
503 var boolean needsOverride = needsOverride();
504 var MergeWriter writer = new MergeWriter(outputFolder + "Abstract" + projectPrefix + generic + "Visitor.java");
505 writer.append('''
506 «ePackage.generateHeader(visitorPackageName
Ed Willink841cda92016-11-19 09:48:34 +0000507
Ed Willinkfc3d1982015-11-23 11:26:40 +0000508 import «returnClass.getName()»;
509 import org.eclipse.jdt.annotation.NonNull;
510 import org.eclipse.jdt.annotation.Nullable;
511 import «Type.getName()»;
512 import «contextClass.getName()»;
513 «IF isDerived && !superProjectPrefix.equals(""import «superVisitorPackageName»itiessuperProjectPrefix»«generic»VisitorENDIF»
514 «IF isDerived && superProjectPrefix.equals(""import «TemplateParameterSubstitutionVisitor.getName()»;«ENDIF»
Ed Willink841cda92016-11-19 09:48:34 +0000515
Ed Willinkfc3d1982015-11-23 11:26:40 +0000516 /**
517 * An Abstract«projectPrefix»«generic»Visitor provides a default implementation for each
518 * visitXxx method that delegates to the visitYyy method of the first
519 * super class, (or transitively its first super class' first super class
520 * until a non-interface super-class is found). In the absence of any
521 * suitable first super class, the method delegates to visiting().
522 */
523 public abstract class Abstract«projectPrefix»«generic»Visitor
524 «IF isDerived»extends «superProjectPrefix»«generic»Visitor«ENDIF»
525 implements «visitorClassName»<«returnClass.getSimpleName()»>
526 {
527 /**
528 * Initializes me with an initial value for my result.
Ed Willink841cda92016-11-19 09:48:34 +0000529 *
Ed Willinkfc3d1982015-11-23 11:26:40 +0000530 * @param context my initial result value
531 */
Ed Willinkda0fc682016-01-05 13:04:43 +0000532 protected Abstract«projectPrefix»«generic»VisitoremitNonNull(contextClass.getSimpleName())» environmentFactory, @Nullable Type selfType, @Nullable Type selfTypeValue) {
Ed Willinkfc3d1982015-11-23 11:26:40 +0000533 super(environmentFactory, selfType, selfTypeValue);
Ed Willink841cda92016-11-19 09:48:34 +0000534 }
Ed Willinkfc3d1982015-11-23 11:26:40 +0000535 «FOR eClass : getSortedEClasses(ePackage
536 «var EClass firstSuperClass = eClass.firstSuperClass(eClass
Ed Willink841cda92016-11-19 09:48:34 +0000537
Ed Willinkfc3d1982015-11-23 11:26:40 +0000538 «IF needsOverride»
539 @Override
540 «ENDIF»
Ed Willinkda0fc682016-01-05 13:04:43 +0000541 public «emitNullable(returnClass.getSimpleName())» visit«eClass.name»(«emitNonNull(modelPackageName + "." + getTemplatedName(eClass))» object) {
Ed Willinkfc3d1982015-11-23 11:26:40 +0000542 «IF firstSuperClass == eClass»
543 return visiting(object);
544 «ELSE»
545 return visit«firstSuperClass.name»(object);
546 «ENDIF»
547 }
548 «ENDFOR»
549 }
550 ''');
551 writer.close();
552 }
Ed.Willink393222a2013-06-08 17:12:00 +0100553
554 /*
555 *AbstractVisitor
556 */
Ed Willink70051092015-12-23 19:11:07 +0000557 protected def void generateAbstractVisitor(/*@NonNull*/ EPackage ePackage) {
Ed Willink5a6db182013-07-10 18:07:52 +0100558 var boolean isDerived = isDerived();
Ed Willink83d1bdf2014-01-18 21:13:27 +0000559 var boolean needsOverride = needsOverride();
Ed.Willink393222a2013-06-08 17:12:00 +0100560 var MergeWriter writer = new MergeWriter(outputFolder + "Abstract" + visitorClassName + ".java");
561 writer.append('''
562 «ePackage.generateHeader(visitorPackageName
Ed Willink841cda92016-11-19 09:48:34 +0000563
Ed Willink5a6db182013-07-10 18:07:52 +0100564 «IF !isDerived»
Ed Willinkda0fc682016-01-05 13:04:43 +0000565 import org.eclipse.jdt.annotation.NonNull;
Ed.Willink393222a2013-06-08 17:12:00 +0100566 import org.eclipse.jdt.annotation.Nullable;
567 «ENDIF»
Ed Willink841cda92016-11-19 09:48:34 +0000568
Ed.Willink393222a2013-06-08 17:12:00 +0100569 /*
570 * An Abstract«visitorClassName» provides a default implementation of the visitor framework
571 * but n implementations of the visitXXX methods..
572 */
573 public abstract class Abstract«visitorClassName»<R, C>
Ed Willink5a6db182013-07-10 18:07:52 +0100574 «IF isDerived»
Ed.Willink393222a2013-06-08 17:12:00 +0100575 extends «superVisitorPackageName».Abstract«superVisitorClassName»<R, C>
576 «ENDIF»
577 implements «visitorClassName»<R>
578 {
Ed Willink5a6db182013-07-10 18:07:52 +0100579 «IF !isDerived»
Ed.Willink393222a2013-06-08 17:12:00 +0100580 /**
581 * Context for the AST visitation.
582 */
Ed Willinkda0fc682016-01-05 13:04:43 +0000583 protected final C context;
Ed.Willink393222a2013-06-08 17:12:00 +0100584
Ed Willink841cda92016-11-19 09:48:34 +0000585 «ENDIF»
Ed.Willink393222a2013-06-08 17:12:00 +0100586 /**
587 * Initializes me with an initial value for my result.
Ed Willink841cda92016-11-19 09:48:34 +0000588 *
Ed.Willink393222a2013-06-08 17:12:00 +0100589 * @param context my initial result value
590 */
Ed Willinkda0fc682016-01-05 13:04:43 +0000591 protected Abstract«visitorClassName»(C context) {
Ed Willink5a6db182013-07-10 18:07:52 +0100592 «IF !isDerived»
Ed.Willink393222a2013-06-08 17:12:00 +0100593 this.context = context;
594 «ELSE»
595 super(context);
596 «ENDIF»
597 }
Ed Willink5a6db182013-07-10 18:07:52 +0100598 «IF !isDerived»
Ed.Willink393222a2013-06-08 17:12:00 +0100599
600 @SuppressWarnings("unchecked")
Ed Willink83d1bdf2014-01-18 21:13:27 +0000601 «IF needsOverride»
602 @Override
603 «ENDIF»
Ed Willinkda0fc682016-01-05 13:04:43 +0000604 public <A> @Nullable A getAdapter(@NonNull Class<A> adapter) {
Ed.Willink393222a2013-06-08 17:12:00 +0100605 if (adapter.isAssignableFrom(getClass())) {
606 return (A) this;
607 }
608 else {
609 return null;
610 }
611 }
Ed Willink841cda92016-11-19 09:48:34 +0000612
Ed.Willink393222a2013-06-08 17:12:00 +0100613 /**
614 * A null-safe visitation of the specified visitable.
Ed Willink841cda92016-11-19 09:48:34 +0000615 *
Ed.Willink393222a2013-06-08 17:12:00 +0100616 * @param v a visitable, or <code>null</code>
617 * @return <code>null</code> if the visitable is <code>null</code>;
618 * otherwise, the result of visiting it
619 */
Ed Willinkda0fc682016-01-05 13:04:43 +0000620 public @Nullable R safeVisitemitNullable(visitablePackageName + "." + visitableClassName v) {
Ed.Willink393222a2013-06-08 17:12:00 +0100621 return (v == null) ? null : v.accept(this);
622 }
Ed Willink841cda92016-11-19 09:48:34 +0000623
Ed.Willink393222a2013-06-08 17:12:00 +0100624 /**
625 * Perform a visit to the specified visitable.
Ed Willink841cda92016-11-19 09:48:34 +0000626 *
Ed.Willink393222a2013-06-08 17:12:00 +0100627 * @param v a visitable, or <code>null</code>
628 * @return <code>null</code> if the visitable is <code>null</code>;
629 * otherwise, the result of visiting it
630 */
Ed Willinkda0fc682016-01-05 13:04:43 +0000631 public R visitemitNonNull(visitablePackageName + "." + visitableClassName v) {
Ed.Willink393222a2013-06-08 17:12:00 +0100632 return v.accept(this);
633 }
634
Ed Willinkda0fc682016-01-05 13:04:43 +0000635 // public R visiting(«emitNonNull(visitablePackageName + "." + visitableClassName)» visitable) {
Ed.Willink393222a2013-06-08 17:12:00 +0100636 // return null;
637 // }
638 «ENDIF»
639 }
640 ''');
641 writer.close();
642 }
Ed Willink841cda92016-11-19 09:48:34 +0000643
Ed Willink28812522013-11-23 12:57:41 +0000644 /*
645 * AbstractWrappingVisitor
646 */
Ed Willink70051092015-12-23 19:11:07 +0000647 protected def void generateAbstractWrappingVisitor(/*@NonNull*/ EPackage ePackage) {
Ed Willink28812522013-11-23 12:57:41 +0000648 var boolean isDerived = isDerived();
Ed Willink83d1bdf2014-01-18 21:13:27 +0000649 var boolean needsOverride = needsOverride();
Ed Willink28812522013-11-23 12:57:41 +0000650 var MergeWriter writer = new MergeWriter(outputFolder + "AbstractWrapping" + visitorClassName + ".java");
651 writer.append('''
652 «ePackage.generateHeader(visitorPackageName
Ed Willink841cda92016-11-19 09:48:34 +0000653
Ed Willink28812522013-11-23 12:57:41 +0000654 import org.eclipse.jdt.annotation.NonNull;
655 import org.eclipse.jdt.annotation.Nullable;
Ed Willink841cda92016-11-19 09:48:34 +0000656
Ed Willink28812522013-11-23 12:57:41 +0000657 /**
658 * An AbstractWrapping«visitorClassName» delegates all visits wrapping the delegation in a call to a preVisit function and a postVisit function.
659 */
Ed Willink2319fa42016-03-24 10:33:45 +0000660 public abstract class AbstractWrapping«visitorClassName»<R, C, @NonNull D extends «visitorClassName»<R>, P>
Ed Willink28812522013-11-23 12:57:41 +0000661 extends «IF isDerived»«superVisitorPackageName».AbstractWrapping«superVisitorClassName»<R, C, D, PELSE»«IF isDerived»«superVisitorClassName»«ELSE»Abstract«visitorClassName»«ENDIF»<R, CENDIF»
662 implements «visitorClassName»<R>
663 {
664 «IF isDerived»
Ed Willinkda0fc682016-01-05 13:04:43 +0000665 protected AbstractWrapping«visitorClassName»(@NonNull D delegate, C context) {
Ed Willink28812522013-11-23 12:57:41 +0000666 super(delegate, context);
667 }
668 «ELSE»
Ed Willink2319fa42016-03-24 10:33:45 +0000669 protected final @NonNull D delegate;
Ed Willink841cda92016-11-19 09:48:34 +0000670
Ed Willinkda0fc682016-01-05 13:04:43 +0000671 protected AbstractWrapping«visitorClassName»(@NonNull D delegate, C context) {
Ed Willink28812522013-11-23 12:57:41 +0000672 super(context);
Ed Willink841cda92016-11-19 09:48:34 +0000673 this.delegate = delegate;
Ed Willink28812522013-11-23 12:57:41 +0000674 // delegate.setUndecoratedVisitor(this);
675 }
676
677 /**
Ed Willinkd8d8f312014-03-17 13:55:48 +0000678 * Intercept an exception thrown by the delegated visit to perform some post-functionality that may use the visitable object,
679 * the result of preVisit and the thrown exception to determine the overall wrapped result.
Ed Willink841cda92016-11-19 09:48:34 +0000680 *
Ed Willinkd8d8f312014-03-17 13:55:48 +0000681 * @return a rethrown RuntimeException or a RuntimeException-wrapped non-RuntimeException.
682 */
Ed Willinkda0fc682016-01-05 13:04:43 +0000683 protected R badVisitemitNonNull(visitablePackageName + "." + visitableClassName visitable, @Nullable P prologue, @NonNull Throwable e) throws RuntimeException {
Ed Willinkd8d8f312014-03-17 13:55:48 +0000684 if (e instanceof Exception) {
685 throw (RuntimeException)e;
686 }
687 else {
688 throw new RuntimeException(e);
689 }
690 }
691
692 /**
Ed Willink28812522013-11-23 12:57:41 +0000693 * Obtains the visitor that I wrap.
Ed Willink841cda92016-11-19 09:48:34 +0000694 *
Ed Willink28812522013-11-23 12:57:41 +0000695 * @return my wrapped visitor
696 */
Ed Willink28812522013-11-23 12:57:41 +0000697 protected @NonNull D getDelegate() {
698 return delegate;
699 }
700
701 /**
702 * Intercept the result of the delegated visit to perform some post-functionality that may use the visitable object,
703 * the result of preVisit and the result of the delegated visit to determine the overall wrapped result.
Ed Willink841cda92016-11-19 09:48:34 +0000704 *
Ed Willink28812522013-11-23 12:57:41 +0000705 * @return the epilogue result, which defaults to the delegated result.
706 */
Ed Willinkda0fc682016-01-05 13:04:43 +0000707 protected R postVisitemitNonNull(visitablePackageName + "." + visitableClassName visitable, @Nullable P prologue, R result) {
Ed Willink28812522013-11-23 12:57:41 +0000708 return result;
709 }
710
711 /**
712 * Compute and return some value before performing the delegated visit.
Ed Willink841cda92016-11-19 09:48:34 +0000713 *
Ed Willink28812522013-11-23 12:57:41 +0000714 * @return the prologue result, which defauilts to null.
715 */
Ed Willinkda0fc682016-01-05 13:04:43 +0000716 protected @Nullable P preVisitemitNonNull(visitablePackageName + "." + visitableClassName visitable) {
Ed Willink28812522013-11-23 12:57:41 +0000717 return null;
718 }
719
Ed Willink9cb4ea62014-12-04 19:35:50 +0000720 «IF needsOverride»
721 @Override
722 «ENDIF»
Ed Willinkda0fc682016-01-05 13:04:43 +0000723 public R visitingemitNonNull(visitablePackageName + "." + visitableClassName visitable) {
Ed Willink28812522013-11-23 12:57:41 +0000724 throw new UnsupportedOperationException(); // Cannot happen since all methods delegate.
725 }
726 «ENDIF»
727 «FOR eClass : getSortedEClasses(ePackage
728
Ed Willink83d1bdf2014-01-18 21:13:27 +0000729 «IF needsOverride»
730 @Override
731 «ENDIF»
Ed Willinkda0fc682016-01-05 13:04:43 +0000732 public R visit«eClass.name»(«emitNonNull(modelPackageName + "." + getTemplatedName(eClass))» object) {
733 @Nullable P prologue = preVisit(object);
Ed Willinkd8d8f312014-03-17 13:55:48 +0000734 try {
735 R result = delegate.visit«eClass.name»(object);
736 return postVisit(object, prologue, result);
737 }
738 catch (Throwable e) {
739 return badVisit(object, prologue, e);
740 }
Ed Willink28812522013-11-23 12:57:41 +0000741 }
742 «ENDFOR»
743 }
744 ''');
745 writer.close();
746 }
Ed.Willink393222a2013-06-08 17:12:00 +0100747
748 /*
749 * DecorableVisitorInterface
750 */
Ed Willink70051092015-12-23 19:11:07 +0000751 protected def void generateDecorableVisitorInterface(/*@NonNull*/ EPackage ePackage, String visitorRootClass) {
Ed Willink5a6db182013-07-10 18:07:52 +0100752 var boolean isDerived = isDerived();
Ed Willink9cb4ea62014-12-04 19:35:50 +0000753 var boolean needsOverride = needsOverride();
Ed.Willink393222a2013-06-08 17:12:00 +0100754 var MergeWriter writer = new MergeWriter(outputFolder + "Decorable" + visitorClassName + ".java");
755 writer.append('''
756 «ePackage.generateHeader(visitorPackageName
Ed Willink841cda92016-11-19 09:48:34 +0000757
Ed.Willink393222a2013-06-08 17:12:00 +0100758 import org.eclipse.jdt.annotation.NonNull;
Ed Willink841cda92016-11-19 09:48:34 +0000759
Ed.Willink393222a2013-06-08 17:12:00 +0100760 /**
761 */
Ed Willink5a6db182013-07-10 18:07:52 +0100762 public interface Decorable«visitorClassName»<R> extends «visitorClassName»<RIF isDerived», «superVisitorPackageName».Decorable«superVisitorClassName»<RENDIF»
Ed.Willink393222a2013-06-08 17:12:00 +0100763 {
Ed Willink9cb4ea62014-12-04 19:35:50 +0000764 «IF isDerived && needsOverride»
765 @Override
766 «ENDIF»
Ed Willinkda0fc682016-01-05 13:04:43 +0000767 void setUndecoratedVisitoremitNonNull(visitorRootClass)»<R> visitor);
Ed.Willink393222a2013-06-08 17:12:00 +0100768 }
769 ''');
770 writer.close();
771 }
772
Ed Willink70051092015-12-23 19:11:07 +0000773 protected def String generateHeader(/*@NonNull*/ EPackage ePackage, String javaPackage) {
Adolfo SBHfd78c5f2016-01-27 17:22:24 +0000774 generateHeader(ePackage,javaPackage, null);
775 }
Ed Willink841cda92016-11-19 09:48:34 +0000776
Adolfo SBHfd78c5f2016-01-27 17:22:24 +0000777 protected def String generateHeaderWithTemplate(/*@NonNull*/ EPackage ePackage, String javaPackage) {
778 generateHeader(ePackage,javaPackage, class.canonicalName);
779 }
Ed Willink841cda92016-11-19 09:48:34 +0000780
Adolfo SBHfd78c5f2016-01-27 17:22:24 +0000781 protected def String generateHeader(EPackage ePackage, String javaPackage, String template) {
Ed.Willink393222a2013-06-08 17:12:00 +0100782 '''
Ed Willinkf4f5ac82014-05-20 12:12:50 +0100783 /*******************************************************************************
Ed Willink841cda92016-11-19 09:48:34 +0000784 * «MergeWriter.getCopyright(copyright).replace("\n", "\n* ").replace("\n* \n", "\n*\n")»
Ed.Willink393222a2013-06-08 17:12:00 +0100785 *
786 * This code is auto-generated
Ed Willink5a6db182013-07-10 18:07:52 +0100787 * from: «projectName»/«sourceFile»
Ed Willink01526762018-01-13 16:50:52 +0000788 «IF template !== null»
Adolfo SBHfd78c5f2016-01-27 17:22:24 +0000789 * template: «template»
790 «ENDIF»
Ed.Willink393222a2013-06-08 17:12:00 +0100791 *
Ed Willinkf4f5ac82014-05-20 12:12:50 +0100792 * Only the copyright statement is editable.
793 *******************************************************************************/
Ed.Willink393222a2013-06-08 17:12:00 +0100794 package «javaPackage»;
Ed Willink841cda92016-11-19 09:48:34 +0000795 '''
Ed.Willink393222a2013-06-08 17:12:00 +0100796 }
797
Ed Willink70051092015-12-23 19:11:07 +0000798 protected def void generateVisitableInterface(/*@NonNull*/ GenPackage genPackage) {
Ed Willink82adc702014-12-10 14:46:20 +0000799 var genModel = genPackage.getGenModel();
800 var String directoryURI = getInterfaceModelDirectory(genModel);
801 var visitableClassName2 = getVisitableClassName(genModel);
802 var visitablePackageName2 = getVisitablePackageName(genModel);
803 var EPackage ePackage = genPackage.getEcorePackage();
804 var MergeWriter writer = new MergeWriter(directoryURI + visitablePackageName2.replace(".", "/") + "/" + visitableClassName2 + ".java");
Ed.Willink393222a2013-06-08 17:12:00 +0100805 writer.append('''
Ed Willink82adc702014-12-10 14:46:20 +0000806 «ePackage.generateHeader(visitablePackageName2
Ed.Willink393222a2013-06-08 17:12:00 +0100807
808 import org.eclipse.emf.ecore.EClass;
809 import org.eclipse.jdt.annotation.NonNull;
Ed.Willink393222a2013-06-08 17:12:00 +0100810
Ed Willink82adc702014-12-10 14:46:20 +0000811 public interface «visitableClassName2»
Ed.Willink393222a2013-06-08 17:12:00 +0100812 {
813 /**
814 * Returns the result of accepting a visit from a visitor.
815 * Implementations typically invoke a derived-class-specific
816 * variant of visitXXX() to facilitate derived-class-specific
817 * processing or just visit() when no such method is available.
818 * <p>
819 * Implementations of visit() may use the EcoreSwitch to perform
820 * derived-class-specific processing.
821 * <p>
822 * Derived implementations of accept() may use getAdapter() to obtain
823 * richer visitor interfaces.
Ed Willink519e0f82014-06-15 14:50:35 +0100824 * @param <R>
Ed.Willink393222a2013-06-08 17:12:00 +0100825 * @param visitor
826 * @return the result of the visit.
827 */
Ed Willinkda0fc682016-01-05 13:04:43 +0000828 <R> R acceptemitNonNull(visitorPackageName +"." + visitorClassName)»<R> visitor);
Ed Willink841cda92016-11-19 09:48:34 +0000829
Ed.Willink393222a2013-06-08 17:12:00 +0100830 EClass eClass();
831 }
832 ''');
833 writer.close();
834 }
835
Ed Willink70051092015-12-23 19:11:07 +0000836 protected def void generateVisitorInterface(/*@NonNull*/ GenPackage genPackage) {
Ed Willink82adc702014-12-10 14:46:20 +0000837 var genModel = genPackage.getGenModel();
838 var String directoryURI = getInterfaceModelDirectory(genModel);
839 var visitableClassName2 = getVisitableClassName(genModel);
840 var visitablePackageName2 = getVisitablePackageName(genModel);
841 var visitorClassName2 = visitorClassName; //getVisitableClassName(genModel);
842 var visitorPackageName2 = visitorPackageName; //getVisitablePackageName(genModel);
Ed Willink5a6db182013-07-10 18:07:52 +0100843 var boolean isDerived = isDerived();
Ed Willink82adc702014-12-10 14:46:20 +0000844 var EPackage ePackage = genPackage.getEcorePackage();
845 var MergeWriter writer = new MergeWriter(directoryURI + visitorPackageName2.replace(".", "/") + "/" + visitorClassName2 + ".java");
Ed.Willink393222a2013-06-08 17:12:00 +0100846 writer.append('''
847 «ePackage.generateHeader(visitorPackageName
848
849 import org.eclipse.jdt.annotation.NonNull;
Ed Willinkda0fc682016-01-05 13:04:43 +0000850 «IF !isDerived»
Ed.Willink393222a2013-06-08 17:12:00 +0100851 import org.eclipse.jdt.annotation.Nullable;
Ed Willinkda0fc682016-01-05 13:04:43 +0000852 «ENDIF»
Ed.Willink393222a2013-06-08 17:12:00 +0100853
854 /**
Ed Willink4f934b22016-11-18 10:01:31 +0000855 * @noimplement This interface is not intended to be implemented by clients.
Ed.Willink393222a2013-06-08 17:12:00 +0100856 */
Ed Willink82adc702014-12-10 14:46:20 +0000857 public interface «visitorClassName2»<RIF isDerived» extends «superVisitorPackageName».«superVisitorClassName»<RENDIF»
Ed.Willink393222a2013-06-08 17:12:00 +0100858 {
Ed Willink5a6db182013-07-10 18:07:52 +0100859 «IF !isDerived»
Ed.Willink393222a2013-06-08 17:12:00 +0100860 /**
861 * Returns an object which is an instance of the given class
862 * associated with this object. Returns <code>null</code> if
863 * no such object can be found.
864 *
865 * @param adapter the adapter class to look up
Ed Willink841cda92016-11-19 09:48:34 +0000866 * @return an object of the given class,
Ed.Willink393222a2013-06-08 17:12:00 +0100867 * or <code>null</code> if this object does not
868 * have an adapter for the given class
869 */
870 @Nullable <A> A getAdapter(@NonNull Class<A> adapter);
871
872 /**
873 * Return the result of visiting a visitable for which no more specific pivot type method
874 * is available.
875 */
Ed Willinkda0fc682016-01-05 13:04:43 +0000876 R visitingemitNonNull(visitablePackageName2 + "." + visitableClassName2 visitable);
Ed.Willink393222a2013-06-08 17:12:00 +0100877
878 «ENDIF»
879 «FOR eClass : getSortedEClasses(ePackage
Ed Willinkda0fc682016-01-05 13:04:43 +0000880 R visit«eClass.name»(«emitNonNull(modelPackageName + "." + getTemplatedName(eClass))» object);
Ed.Willink393222a2013-06-08 17:12:00 +0100881 «ENDFOR»
882 }
883 ''')
884 writer.close();
885 }
886}