blob: 1294a8e982ff0d55da936edb24bc9e182c17fe77 [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
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
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.Willink393222a2013-06-08 17:12:00 +010019
Ed Willink82adc702014-12-10 14:46:20 +000020public abstract class GenerateVisitorsXtend extends GenerateVisitors
Ed.Willink393222a2013-06-08 17:12:00 +010021{
Ed.Willink9ad6ca72013-08-24 14:21:42 +010022 /*
23 * Abstract«projectPrefix»«generic»Visitor
24 */
Ed Willink70051092015-12-23 19:11:07 +000025 protected def void generateAbstractGenericVisitor(/*@NonNull*/ EPackage ePackage, /*@NonNull*/ String generic, /*@NonNull*/ Class<?> returnClass, /*@NonNull*/ Class<?> contextClass) {
Ed.Willink9ad6ca72013-08-24 14:21:42 +010026 var boolean isDerived = isDerived();
Ed Willink83d1bdf2014-01-18 21:13:27 +000027 var boolean needsOverride = needsOverride();
Ed.Willink9ad6ca72013-08-24 14:21:42 +010028 var MergeWriter writer = new MergeWriter(outputFolder + "Abstract" + projectPrefix + generic + "Visitor.java");
29 writer.append('''
30 «ePackage.generateHeader(visitorPackageName)»
31
32 import «returnClass.getName()»;
33 import org.eclipse.jdt.annotation.NonNull;
34 import org.eclipse.jdt.annotation.Nullable;
35 import «contextClass.getName()»;
36 «IF isDerived»import «superVisitorPackageName»ities.«superProjectPrefix»«generic»Visitor;«ENDIF»
37
38 /**
39 * An Abstract«projectPrefix»«generic»Visitor provides a default implementation for each
40 * visitXxx method that delegates to the visitYyy method of the first
41 * super class, (or transitively its first super class' first super class
42 * until a non-interface super-class is found). In the absence of any
43 * suitable first super class, the method delegates to visiting().
44 */
45 public abstract class Abstract«projectPrefix»«generic»Visitor
46 «IF isDerived»extends «superProjectPrefix»«generic»Visitor«ENDIF»
47 implements «visitorClassName»<«returnClass.getSimpleName()»>
48 {
49 /**
50 * Initializes me with an initial value for my result.
51 *
52 * @param context my initial result value
53 */
54 protected Abstract«projectPrefix»«generic»Visitor(@NonNull «contextClass.getSimpleName()» context) {
55 super(context);
56 }
57 «FOR eClass : getSortedEClasses(ePackage
58 «var EClass firstSuperClass = eClass.firstSuperClass(eClass
59
Ed Willink83d1bdf2014-01-18 21:13:27 +000060 «IF needsOverride»
61 @Override
62 «ENDIF»
Ed.Willink9ad6ca72013-08-24 14:21:42 +010063 public @Nullable «returnClass.getSimpleName()» visit«eClass.name»(@NonNull «modelPackageName».«getTemplatedName(eClass object) {
64 «IF firstSuperClass == eClass»
65 return visiting(object);
66 «ELSE»
67 return visit«firstSuperClass.name»(object);
68 «ENDIF»
69 }
70 «ENDFOR»
71 }
72 ''');
73 writer.close();
74 }
75
Ed.Willink393222a2013-06-08 17:12:00 +010076 /*
77 * AbstractDelegatingVisitor
78 */
Ed Willink70051092015-12-23 19:11:07 +000079 protected def void generateAbstractDelegatingVisitor(/*@NonNull*/ EPackage ePackage) {
Ed Willink5a6db182013-07-10 18:07:52 +010080 var boolean isDerived = isDerived();
Ed Willink83d1bdf2014-01-18 21:13:27 +000081 var boolean needsOverride = needsOverride();
Ed.Willink393222a2013-06-08 17:12:00 +010082 var MergeWriter writer = new MergeWriter(outputFolder + "AbstractDelegating" + visitorClassName + ".java");
83 writer.append('''
84 «ePackage.generateHeader(visitorPackageName
85
86 import org.eclipse.jdt.annotation.NonNull;
87 import org.eclipse.jdt.annotation.Nullable;
88
89 /**
90 * An AbstractDelegating«visitorClassName» delegates all visits.
91 */
92 public abstract class AbstractDelegating«visitorClassName»<R, C, 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»
97 protected AbstractDelegating«visitorClassName»(@NonNull D delegate, @NonNull C context) {
98 super(delegate, context);
99 }
100 «ELSE»
101 protected final D delegate;
102
103 protected AbstractDelegating«visitorClassName»(@NonNull D delegate, @NonNull C context) {
104 super(context);
105 // assert delegate != null : "cannot decorate a null visitor"; //$NON-NLS-1$
106 this.delegate = delegate;
107 // 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.
119 *
120 * @return my decorated visitor
121 */
122 @SuppressWarnings("null")
123 protected final @NonNull D getDelegate() {
124 return delegate;
125 }
126 «ENDIF»
127
Ed Willink9cb4ea62014-12-04 19:35:50 +0000128 «IF isDerived || needsOverride»
Ed.Willink393222a2013-06-08 17:12:00 +0100129 @Override
130 «ENDIF»
131 public @Nullable R visiting(@NonNull «visitablePackageName».«visitableClassName» visitable) {
132 return delegate.visiting(visitable);
133 }
134 «FOR eClass : getSortedEClasses(ePackage
135
Ed Willink83d1bdf2014-01-18 21:13:27 +0000136 «IF needsOverride»
137 @Override
138 «ENDIF»
Ed Willink6db59132013-07-19 13:20:52 +0100139 public @Nullable R visit«eClass.name»(@NonNull «modelPackageName».«getTemplatedName(eClass object) {
Ed.Willink393222a2013-06-08 17:12:00 +0100140 return delegate.visit«eClass.name»(object);
141 }
142 «ENDFOR»
143 }
144 ''');
145 writer.close();
146 }
147
148 /*
Ed Willink28812522013-11-23 12:57:41 +0000149 * AbstractExtendingDelegatingVisitor
Ed.Willink393222a2013-06-08 17:12:00 +0100150 */
Ed Willink70051092015-12-23 19:11:07 +0000151 protected def void generateAbstractExtendingDelegatingVisitor(/*@NonNull*/ EPackage ePackage) {
Ed.Willink393222a2013-06-08 17:12:00 +0100152 var MergeWriter writer = new MergeWriter(outputFolder + "AbstractExtendingDelegating" + visitorClassName + ".java");
153 writer.append('''
154 «ePackage.generateHeader(visitorPackageName
155
156 import org.eclipse.jdt.annotation.NonNull;
157 import org.eclipse.jdt.annotation.Nullable;
158 import «superVisitorPackageName».AbstractDelegating«superVisitorClassName»;
Ed Willink5a6db182013-07-10 18:07:52 +0100159 import «superVisitorPackageName».«superVisitorClassName»;
Ed.Willink393222a2013-06-08 17:12:00 +0100160
161 /**
Ed.Willinkf1ec73c2013-07-10 11:36:49 +0100162 * An AbstractExtendingDelegating«visitorClassName» provides a default implementation for each
163 * visitXxx method that delegates to the supertype if the supertype is in the same package as
164 * the visited type, otherwise it delegates to the delegate.
Ed.Willink393222a2013-06-08 17:12:00 +0100165 */
Adolfo SBHbddb3c72013-08-15 10:13:10 +0100166 public abstract class AbstractExtendingDelegating«visitorClassName»<R, C, D extends «superVisitorClassName»<R>>
Ed.Willink393222a2013-06-08 17:12:00 +0100167 extends AbstractDelegating«superVisitorClassName»<R, C, D>
168 implements «visitorClassName»<R>
169 {
170 «IF true»
171 protected AbstractExtendingDelegating«visitorClassName»(@NonNull D delegate, @NonNull C context) {
172 super(delegate, context);
173 }
174 «ELSE»
175 protected final D delegate;
176
177 protected AbstractExtendingDelegating«visitorClassName»(@NonNull D delegate, @NonNull C context) {
178 super(context);
179 // assert delegate != null : "cannot decorate a null visitor"; //$NON-NLS-1$
180 this.delegate = delegate;
181 // delegate.setUndecoratedVisitor(this);
182 }
183
184 /**
185 * Delegates to my decorated visitor.
186 */
187 // public Decorable«visitorClassName»<R> createNestedVisitor() {
188 // return delegate.createNestedVisitor();
189 // }
190
191 /**
192 * Obtains the visitor that I decorate.
193 *
194 * @return my decorated visitor
195 */
196 protected final D getDelegate() {
197 return delegate;
198 }
199 «ENDIF»
200
201 @Override
202 public @Nullable R visiting(@NonNull «visitablePackageName».«visitableClassName» visitable) {
203 return delegate.visiting(visitable);
204 }
205 «FOR eClass : getSortedEClasses(ePackage
206 «var EClass firstSuperClass = eClass.firstSuperClass(eClass
207
Ed Willink83d1bdf2014-01-18 21:13:27 +0000208 «IF needsOverride»
209 @Override
210 «ENDIF»
Ed Willink6db59132013-07-19 13:20:52 +0100211 public @Nullable R visit«eClass.name»(@NonNull «modelPackageName».«getTemplatedName(eClass object) {
Ed.Willink393222a2013-06-08 17:12:00 +0100212 «IF firstSuperClass == eClass»
213 return visiting(object);
214 «ELSEIF firstSuperClass.getEPackage() == eClass.getEPackage()»
215 return visit«firstSuperClass.name»(object);
216 «ELSE»
Adolfo SBHbddb3c72013-08-15 10:13:10 +0100217 return delegate.visit«firstSuperClass.name»(object);
Ed.Willink393222a2013-06-08 17:12:00 +0100218 «ENDIF»
219 }
220 «ENDFOR»
221 }
222 ''');
223 writer.close();
224 }
225
226 /*
227 * AbstractExtendingVisitor
228 */
Ed Willink70051092015-12-23 19:11:07 +0000229 protected def void generateAbstractExtendingVisitor(/*@NonNull*/ EPackage ePackage) {
Ed Willink5a6db182013-07-10 18:07:52 +0100230 var boolean isDerived = isDerived();
Ed Willink83d1bdf2014-01-18 21:13:27 +0000231 var boolean needsOverride = needsOverride();
Ed.Willink393222a2013-06-08 17:12:00 +0100232 var MergeWriter writer = new MergeWriter(outputFolder + "AbstractExtending" + visitorClassName + ".java");
233 writer.append('''
234 «ePackage.generateHeader(visitorPackageName
235
236 import org.eclipse.jdt.annotation.NonNull;
237 import org.eclipse.jdt.annotation.Nullable;
238
239 /**
240 * An AbstractExtending«visitorClassName» provides a default implementation for each
241 * visitXxx method that delegates to the visitYyy method of the first
Ed.Willink9ad6ca72013-08-24 14:21:42 +0100242 * super class, (or transitively its first super class' first super class
Ed.Willink393222a2013-06-08 17:12:00 +0100243 * until a non-interface super-class is found). In the absence of any
244 * suitable first super class, the method delegates to visiting().
245 */
246 public abstract class AbstractExtending«visitorClassName»<R, C>
Ed Willink5a6db182013-07-10 18:07:52 +0100247 extends «IF isDerived»«superVisitorPackageName».AbstractExtending«superVisitorClassName»«ELSE»Abstract«visitorClassName»«ENDIF»<R, C>
Ed.Willink393222a2013-06-08 17:12:00 +0100248 implements «visitorClassName»<R>
249 {
250 /**
251 * Initializes me with an initial value for my result.
252 *
253 * @param context my initial result value
254 */
255 protected AbstractExtending«visitorClassName»(@NonNull C context) {
256 super(context);
257 }
258 «FOR eClass : getSortedEClasses(ePackage
259 «var EClass firstSuperClass = eClass.firstSuperClass(eClass
260
Ed Willink83d1bdf2014-01-18 21:13:27 +0000261 «IF needsOverride»
262 @Override
263 «ENDIF»
Ed Willink6db59132013-07-19 13:20:52 +0100264 public @Nullable R visit«eClass.name»(@NonNull «modelPackageName».«getTemplatedName(eClass object) {
Ed.Willink393222a2013-06-08 17:12:00 +0100265 «IF firstSuperClass == eClass»
266 return visiting(object);
267 «ELSE»
268 return visit«firstSuperClass.name»(object);
269 «ENDIF»
270 }
271 «ENDFOR»
272 }
273 ''');
274 writer.close();
275 }
Ed Willink0100b5f2015-06-13 17:41:07 +0100276
277 /*
278 * AbstractMergedVisitor
279 */
Ed Willink70051092015-12-23 19:11:07 +0000280 protected def void generateAbstractMergedVisitor(/*@NonNull*/ EPackage ePackage) {
Ed Willink0100b5f2015-06-13 17:41:07 +0100281 var boolean isDerived = isDerived();
282 var boolean needsOverride = needsOverride();
283 var MergeWriter writer = new MergeWriter(outputFolder + "AbstractMerged" + visitorClassName + ".java");
284 writer.append('''
285 «ePackage.generateHeader(visitorPackageName
286
287 import org.eclipse.jdt.annotation.NonNull;
288 import org.eclipse.jdt.annotation.Nullable;
289
290 /**
291 * An AbstractMerged«visitorClassName» merges all visits direct to visiting().
292 * This can be used by a decorating visitor to execute shared code before redispatching to a decorated visitor.
293 */
294 public abstract class AbstractMerged«visitorClassName»<R, C>
295 extends «IF isDerived»«superVisitorPackageName».AbstractMerged«superVisitorClassName»<R, CELSE»«IF isDerived»«superVisitorClassName»«ELSE»Abstract«visitorClassName»«ENDIF»<R, CENDIF»
296 implements «visitorClassName»<R>
297 {
298 protected AbstractMerged«visitorClassName»(@NonNull C context) {
299 super(context);
300 }
301 «FOR eClass : getSortedEClasses(ePackage
302
303 «IF needsOverride»
304 @Override
305 «ENDIF»
306 public @Nullable R visit«eClass.name»(@NonNull «modelPackageName».«getTemplatedName(eClass object) {
307 return visiting(object);
308 }
309 «ENDFOR»
310 }
311 ''');
312 writer.close();
313 }
314
Ed.Willink393222a2013-06-08 17:12:00 +0100315 /*
Ed Willink8f454a62013-07-30 18:07:23 +0100316 * AbstractNonNullExtendingVisitor
317 */
Ed Willink70051092015-12-23 19:11:07 +0000318 protected def void generateAbstractNonNullExtendingVisitor(/*@NonNull*/ EPackage ePackage) {
Ed Willink8f454a62013-07-30 18:07:23 +0100319 var boolean isDerived = isDerived();
Ed Willink83d1bdf2014-01-18 21:13:27 +0000320 var boolean needsOverride = needsOverride();
Ed Willink8f454a62013-07-30 18:07:23 +0100321 var MergeWriter writer = new MergeWriter(outputFolder + "AbstractNonNullExtending" + visitorClassName + ".java");
322 writer.append('''
323 «ePackage.generateHeader(visitorPackageName
324
325 import org.eclipse.jdt.annotation.NonNull;
326
327 /**
328 * An AbstractExtendingNonNull«visitorClassName» provides a default implementation for each
329 * visitXxx method that delegates to the visitYyy method of the first
330 * super class, (or transitively its first super class first super class
331 * until a non-interface super-class is found). In the absence of any
332 * suitable first super class, the method delegates to visiting().
333 * The return in annotated as @NonNull.
334 */
335 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.
341 *
342 * @param context my initial result value
343 */
344 protected AbstractNonNullExtending«visitorClassName»(@NonNull C context) {
345 super(context);
346 }
347 «IF !isDerived»
348
349 /**
350 * Perform a visit to the specified visitable.
351 *
352 * @param visitable a visitable
353 * @return the non-null result of visiting it
354 */
355 @Override
356 public @NonNull R visit(@NonNull «visitablePackageName».«visitableClassName» visitable) {
357 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
366
Ed Willink83d1bdf2014-01-18 21:13:27 +0000367 «IF needsOverride»
368 @Override
369 «ENDIF»
Ed Willink8f454a62013-07-30 18:07:23 +0100370 public @NonNull R visit«eClass.name»(@NonNull «modelPackageName».«getTemplatedName(eClass object) {
371 «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 Willink8f454a62013-07-30 18:07:23 +0100387 public abstract @NonNull R visiting(@NonNull «visitablePackageName».«visitableClassName» visitable);
388 «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.
410 */
411 public abstract class AbstractNull«visitorClassName»<R, C>
Ed Willink5a6db182013-07-10 18:07:52 +0100412 «IF !isDerived»
Ed.Willink393222a2013-06-08 17:12:00 +0100413 extends Abstract«visitorClassName»<R, C>
414 «ELSE»
415 extends «superVisitorPackageName».AbstractNull«superVisitorClassName»<R, C> implements «visitorClassName»<R>
416 «ENDIF»
417 {
418 /**
419 * Initializes me with an initial value for my result.
420 *
421 * @param context my initial result value
422 */
423 protected AbstractNull«visitorClassName»(@NonNull C context) {
424 super(context);
425 }
426 «FOR eClass : getSortedEClasses(ePackage
427
Ed Willink83d1bdf2014-01-18 21:13:27 +0000428 «IF needsOverride»
429 @Override
430 «ENDIF»
Ed Willink6db59132013-07-19 13:20:52 +0100431 public @Nullable R visit«eClass.name»(@NonNull «modelPackageName».«getTemplatedName(eClass object) {
Ed.Willink393222a2013-06-08 17:12:00 +0100432 return null;
433 }
434 «ENDFOR»
435 }
436 ''');
437 writer.close();
438 }
Ed Willinkfc3d1982015-11-23 11:26:40 +0000439 /*
440 * Abstract«projectPrefix»«generic»Visitor
441 */
Ed Willink70051092015-12-23 19:11:07 +0000442 protected def void generateAbstractTemplateParameterSubstitutionVisitor(/*@NonNull*/ EPackage ePackage, /*@NonNull*/ String generic, /*@NonNull*/ Class<?> returnClass, /*@NonNull*/ Class<?> contextClass) {
Ed Willinkfc3d1982015-11-23 11:26:40 +0000443 var boolean isDerived = isDerived();
444 var boolean needsOverride = needsOverride();
445 var MergeWriter writer = new MergeWriter(outputFolder + "Abstract" + projectPrefix + generic + "Visitor.java");
446 writer.append('''
447 «ePackage.generateHeader(visitorPackageName
448
449 import «returnClass.getName()»;
450 import org.eclipse.jdt.annotation.NonNull;
451 import org.eclipse.jdt.annotation.Nullable;
452 import «Type.getName()»;
453 import «contextClass.getName()»;
454 «IF isDerived && !superProjectPrefix.equals(""import «superVisitorPackageName»itiessuperProjectPrefix»«generic»VisitorENDIF»
455 «IF isDerived && superProjectPrefix.equals(""import «TemplateParameterSubstitutionVisitor.getName()»;«ENDIF»
456
457 /**
458 * An Abstract«projectPrefix»«generic»Visitor provides a default implementation for each
459 * visitXxx method that delegates to the visitYyy method of the first
460 * super class, (or transitively its first super class' first super class
461 * until a non-interface super-class is found). In the absence of any
462 * suitable first super class, the method delegates to visiting().
463 */
464 public abstract class Abstract«projectPrefix»«generic»Visitor
465 «IF isDerived»extends «superProjectPrefix»«generic»Visitor«ENDIF»
466 implements «visitorClassName»<«returnClass.getSimpleName()»>
467 {
468 /**
469 * Initializes me with an initial value for my result.
470 *
471 * @param context my initial result value
472 */
473 protected Abstract«projectPrefix»«generic»Visitor(@NonNull «contextClass.getSimpleName()» environmentFactory, @Nullable Type selfType, @Nullable Type selfTypeValue) {
474 super(environmentFactory, selfType, selfTypeValue);
475 }
476 «FOR eClass : getSortedEClasses(ePackage
477 «var EClass firstSuperClass = eClass.firstSuperClass(eClass
478
479 «IF needsOverride»
480 @Override
481 «ENDIF»
482 public @Nullable «returnClass.getSimpleName()» visit«eClass.name»(@NonNull «modelPackageName».«getTemplatedName(eClass object) {
483 «IF firstSuperClass == eClass»
484 return visiting(object);
485 «ELSE»
486 return visit«firstSuperClass.name»(object);
487 «ENDIF»
488 }
489 «ENDFOR»
490 }
491 ''');
492 writer.close();
493 }
Ed.Willink393222a2013-06-08 17:12:00 +0100494
495 /*
496 *AbstractVisitor
497 */
Ed Willink70051092015-12-23 19:11:07 +0000498 protected def void generateAbstractVisitor(/*@NonNull*/ EPackage ePackage) {
Ed Willink5a6db182013-07-10 18:07:52 +0100499 var boolean isDerived = isDerived();
Ed Willink83d1bdf2014-01-18 21:13:27 +0000500 var boolean needsOverride = needsOverride();
Ed.Willink393222a2013-06-08 17:12:00 +0100501 var MergeWriter writer = new MergeWriter(outputFolder + "Abstract" + visitorClassName + ".java");
502 writer.append('''
503 «ePackage.generateHeader(visitorPackageName
504
505 import org.eclipse.jdt.annotation.NonNull;
Ed Willink5a6db182013-07-10 18:07:52 +0100506 «IF !isDerived»
Ed.Willink393222a2013-06-08 17:12:00 +0100507 import org.eclipse.jdt.annotation.Nullable;
508 «ENDIF»
509
510 /*
511 * An Abstract«visitorClassName» provides a default implementation of the visitor framework
512 * but n implementations of the visitXXX methods..
513 */
514 public abstract class Abstract«visitorClassName»<R, C>
Ed Willink5a6db182013-07-10 18:07:52 +0100515 «IF isDerived»
Ed.Willink393222a2013-06-08 17:12:00 +0100516 extends «superVisitorPackageName».Abstract«superVisitorClassName»<R, C>
517 «ENDIF»
518 implements «visitorClassName»<R>
519 {
Ed Willink5a6db182013-07-10 18:07:52 +0100520 «IF !isDerived»
Ed.Willink393222a2013-06-08 17:12:00 +0100521 /**
522 * Context for the AST visitation.
523 */
524 protected final @NonNull C context;
525
526 «ENDIF»
527 /**
528 * Initializes me with an initial value for my result.
529 *
530 * @param context my initial result value
531 */
532 protected Abstract«visitorClassName»(@NonNull C context) {
Ed Willink5a6db182013-07-10 18:07:52 +0100533 «IF !isDerived»
Ed.Willink393222a2013-06-08 17:12:00 +0100534 this.context = context;
535 «ELSE»
536 super(context);
537 «ENDIF»
538 }
Ed Willink5a6db182013-07-10 18:07:52 +0100539 «IF !isDerived»
Ed.Willink393222a2013-06-08 17:12:00 +0100540
541 @SuppressWarnings("unchecked")
Ed Willink83d1bdf2014-01-18 21:13:27 +0000542 «IF needsOverride»
543 @Override
544 «ENDIF»
Ed.Willink393222a2013-06-08 17:12:00 +0100545 public <A> A getAdapter(@NonNull Class<A> adapter) {
546 if (adapter.isAssignableFrom(getClass())) {
547 return (A) this;
548 }
549 else {
550 return null;
551 }
552 }
553
554 /**
555 * A null-safe visitation of the specified visitable.
556 *
557 * @param v a visitable, or <code>null</code>
558 * @return <code>null</code> if the visitable is <code>null</code>;
559 * otherwise, the result of visiting it
560 */
561 public @Nullable R safeVisit(@Nullable «visitablePackageName».«visitableClassName» v) {
562 return (v == null) ? null : v.accept(this);
563 }
564
565 /**
566 * Perform a visit to the specified visitable.
567 *
568 * @param v a visitable, or <code>null</code>
569 * @return <code>null</code> if the visitable is <code>null</code>;
570 * otherwise, the result of visiting it
571 */
572 public @Nullable R visit(@NonNull «visitablePackageName».«visitableClassName» v) {
573 return v.accept(this);
574 }
575
576 // public @Nullable R visiting(@NonNull «visitablePackageName».«visitableClassName» visitable) {
577 // return null;
578 // }
579 «ENDIF»
580 }
581 ''');
582 writer.close();
583 }
Ed Willink28812522013-11-23 12:57:41 +0000584
585 /*
586 * AbstractWrappingVisitor
587 */
Ed Willink70051092015-12-23 19:11:07 +0000588 protected def void generateAbstractWrappingVisitor(/*@NonNull*/ EPackage ePackage) {
Ed Willink28812522013-11-23 12:57:41 +0000589 var boolean isDerived = isDerived();
Ed Willink83d1bdf2014-01-18 21:13:27 +0000590 var boolean needsOverride = needsOverride();
Ed Willink28812522013-11-23 12:57:41 +0000591 var MergeWriter writer = new MergeWriter(outputFolder + "AbstractWrapping" + visitorClassName + ".java");
592 writer.append('''
593 «ePackage.generateHeader(visitorPackageName
594
595 import org.eclipse.jdt.annotation.NonNull;
596 import org.eclipse.jdt.annotation.Nullable;
597
598 /**
599 * An AbstractWrapping«visitorClassName» delegates all visits wrapping the delegation in a call to a preVisit function and a postVisit function.
600 */
601 public abstract class AbstractWrapping«visitorClassName»<R, C, D extends «visitorClassName»<R>, P>
602 extends «IF isDerived»«superVisitorPackageName».AbstractWrapping«superVisitorClassName»<R, C, D, PELSE»«IF isDerived»«superVisitorClassName»«ELSE»Abstract«visitorClassName»«ENDIF»<R, CENDIF»
603 implements «visitorClassName»<R>
604 {
605 «IF isDerived»
606 protected AbstractWrapping«visitorClassName»(@NonNull D delegate, @NonNull C context) {
607 super(delegate, context);
608 }
609 «ELSE»
610 protected final D delegate;
611
612 protected AbstractWrapping«visitorClassName»(@NonNull D delegate, @NonNull C context) {
613 super(context);
614 this.delegate = delegate;
615 // delegate.setUndecoratedVisitor(this);
616 }
617
618 /**
Ed Willinkd8d8f312014-03-17 13:55:48 +0000619 * Intercept an exception thrown by the delegated visit to perform some post-functionality that may use the visitable object,
620 * the result of preVisit and the thrown exception to determine the overall wrapped result.
621 *
622 * @return a rethrown RuntimeException or a RuntimeException-wrapped non-RuntimeException.
623 */
624 protected @Nullable R badVisit(@NonNull «visitablePackageName».«visitableClassName» visitable, @Nullable P prologue, @NonNull Throwable e) throws RuntimeException {
625 if (e instanceof Exception) {
626 throw (RuntimeException)e;
627 }
628 else {
629 throw new RuntimeException(e);
630 }
631 }
632
633 /**
Ed Willink28812522013-11-23 12:57:41 +0000634 * Obtains the visitor that I wrap.
635 *
636 * @return my wrapped visitor
637 */
638 @SuppressWarnings("null")
639 protected @NonNull D getDelegate() {
640 return delegate;
641 }
642
643 /**
644 * Intercept the result of the delegated visit to perform some post-functionality that may use the visitable object,
645 * the result of preVisit and the result of the delegated visit to determine the overall wrapped result.
646 *
647 * @return the epilogue result, which defaults to the delegated result.
648 */
649 protected @Nullable R postVisit(@NonNull «visitablePackageName».«visitableClassName» visitable, @Nullable P prologue, @Nullable R result) {
650 return result;
651 }
652
653 /**
654 * Compute and return some value before performing the delegated visit.
655 *
656 * @return the prologue result, which defauilts to null.
657 */
658 protected @Nullable P preVisit(@NonNull «visitablePackageName».«visitableClassName» visitable) {
659 return null;
660 }
661
Ed Willink9cb4ea62014-12-04 19:35:50 +0000662 «IF needsOverride»
663 @Override
664 «ENDIF»
Ed Willink28812522013-11-23 12:57:41 +0000665 public @Nullable R visiting(@NonNull «visitablePackageName».«visitableClassName» visitable) {
666 throw new UnsupportedOperationException(); // Cannot happen since all methods delegate.
667 }
668 «ENDIF»
669 «FOR eClass : getSortedEClasses(ePackage
670
Ed Willink83d1bdf2014-01-18 21:13:27 +0000671 «IF needsOverride»
672 @Override
673 «ENDIF»
Ed Willink28812522013-11-23 12:57:41 +0000674 public @Nullable R visit«eClass.name»(@NonNull «modelPackageName».«getTemplatedName(eClass object) {
675 P prologue = preVisit(object);
Ed Willinkd8d8f312014-03-17 13:55:48 +0000676 try {
677 R result = delegate.visit«eClass.name»(object);
678 return postVisit(object, prologue, result);
679 }
680 catch (Throwable e) {
681 return badVisit(object, prologue, e);
682 }
Ed Willink28812522013-11-23 12:57:41 +0000683 }
684 «ENDFOR»
685 }
686 ''');
687 writer.close();
688 }
Ed.Willink393222a2013-06-08 17:12:00 +0100689
690 /*
691 * DecorableVisitorInterface
692 */
Ed Willink70051092015-12-23 19:11:07 +0000693 protected def void generateDecorableVisitorInterface(/*@NonNull*/ EPackage ePackage, String visitorRootClass) {
Ed Willink5a6db182013-07-10 18:07:52 +0100694 var boolean isDerived = isDerived();
Ed Willink9cb4ea62014-12-04 19:35:50 +0000695 var boolean needsOverride = needsOverride();
Ed.Willink393222a2013-06-08 17:12:00 +0100696 var MergeWriter writer = new MergeWriter(outputFolder + "Decorable" + visitorClassName + ".java");
697 writer.append('''
698 «ePackage.generateHeader(visitorPackageName
699
700 import org.eclipse.jdt.annotation.NonNull;
701
702 /**
703 */
Ed Willink5a6db182013-07-10 18:07:52 +0100704 public interface Decorable«visitorClassName»<R> extends «visitorClassName»<RIF isDerived», «superVisitorPackageName».Decorable«superVisitorClassName»<RENDIF»
Ed.Willink393222a2013-06-08 17:12:00 +0100705 {
Ed Willink9cb4ea62014-12-04 19:35:50 +0000706 «IF isDerived && needsOverride»
707 @Override
708 «ENDIF»
Ed.Willink393222a2013-06-08 17:12:00 +0100709 void setUndecoratedVisitor(@NonNull «visitorRootClass»<R> visitor);
710 }
711 ''');
712 writer.close();
713 }
714
Ed Willink70051092015-12-23 19:11:07 +0000715 protected def String generateHeader(/*@NonNull*/ EPackage ePackage, String javaPackage) {
Ed.Willink393222a2013-06-08 17:12:00 +0100716 '''
Ed Willinkf4f5ac82014-05-20 12:12:50 +0100717 /*******************************************************************************
Ed.Willink393222a2013-06-08 17:12:00 +0100718 * «MergeWriter.getCopyright(copyright).replace("\n", "\n* ")»
719 *
720 * This code is auto-generated
Ed Willink5a6db182013-07-10 18:07:52 +0100721 * from: «projectName»/«sourceFile»
Ed.Willink393222a2013-06-08 17:12:00 +0100722 *
Ed Willinkf4f5ac82014-05-20 12:12:50 +0100723 * Only the copyright statement is editable.
724 *******************************************************************************/
Ed.Willink393222a2013-06-08 17:12:00 +0100725 package «javaPackage»;
726 '''
727 }
728
Ed Willink70051092015-12-23 19:11:07 +0000729 protected def void generateVisitableInterface(/*@NonNull*/ GenPackage genPackage) {
Ed Willink82adc702014-12-10 14:46:20 +0000730 var genModel = genPackage.getGenModel();
731 var String directoryURI = getInterfaceModelDirectory(genModel);
732 var visitableClassName2 = getVisitableClassName(genModel);
733 var visitablePackageName2 = getVisitablePackageName(genModel);
734 var EPackage ePackage = genPackage.getEcorePackage();
735 var MergeWriter writer = new MergeWriter(directoryURI + visitablePackageName2.replace(".", "/") + "/" + visitableClassName2 + ".java");
Ed.Willink393222a2013-06-08 17:12:00 +0100736 writer.append('''
Ed Willink82adc702014-12-10 14:46:20 +0000737 «ePackage.generateHeader(visitablePackageName2
Ed.Willink393222a2013-06-08 17:12:00 +0100738
739 import org.eclipse.emf.ecore.EClass;
740 import org.eclipse.jdt.annotation.NonNull;
741 import org.eclipse.jdt.annotation.Nullable;
742
Ed Willink82adc702014-12-10 14:46:20 +0000743 public interface «visitableClassName2»
Ed.Willink393222a2013-06-08 17:12:00 +0100744 {
745 /**
746 * Returns the result of accepting a visit from a visitor.
747 * Implementations typically invoke a derived-class-specific
748 * variant of visitXXX() to facilitate derived-class-specific
749 * processing or just visit() when no such method is available.
750 * <p>
751 * Implementations of visit() may use the EcoreSwitch to perform
752 * derived-class-specific processing.
753 * <p>
754 * Derived implementations of accept() may use getAdapter() to obtain
755 * richer visitor interfaces.
Ed Willink519e0f82014-06-15 14:50:35 +0100756 * @param <R>
Ed.Willink393222a2013-06-08 17:12:00 +0100757 * @param visitor
758 * @return the result of the visit.
759 */
760 @Nullable <R> R accept(@NonNull «visitorPackageName».«visitorClassName»<R> visitor);
761
762 EClass eClass();
763 }
764 ''');
765 writer.close();
766 }
767
Ed Willink70051092015-12-23 19:11:07 +0000768 protected def void generateVisitorInterface(/*@NonNull*/ GenPackage genPackage) {
Ed Willink82adc702014-12-10 14:46:20 +0000769 var genModel = genPackage.getGenModel();
770 var String directoryURI = getInterfaceModelDirectory(genModel);
771 var visitableClassName2 = getVisitableClassName(genModel);
772 var visitablePackageName2 = getVisitablePackageName(genModel);
773 var visitorClassName2 = visitorClassName; //getVisitableClassName(genModel);
774 var visitorPackageName2 = visitorPackageName; //getVisitablePackageName(genModel);
Ed Willink5a6db182013-07-10 18:07:52 +0100775 var boolean isDerived = isDerived();
Ed Willink82adc702014-12-10 14:46:20 +0000776 var EPackage ePackage = genPackage.getEcorePackage();
777 var MergeWriter writer = new MergeWriter(directoryURI + visitorPackageName2.replace(".", "/") + "/" + visitorClassName2 + ".java");
Ed.Willink393222a2013-06-08 17:12:00 +0100778 writer.append('''
779 «ePackage.generateHeader(visitorPackageName
780
781 import org.eclipse.jdt.annotation.NonNull;
782 import org.eclipse.jdt.annotation.Nullable;
783
784 /**
785 */
Ed Willink82adc702014-12-10 14:46:20 +0000786 public interface «visitorClassName2»<RIF isDerived» extends «superVisitorPackageName».«superVisitorClassName»<RENDIF»
Ed.Willink393222a2013-06-08 17:12:00 +0100787 {
Ed Willink5a6db182013-07-10 18:07:52 +0100788 «IF !isDerived»
Ed.Willink393222a2013-06-08 17:12:00 +0100789 /**
790 * Returns an object which is an instance of the given class
791 * associated with this object. Returns <code>null</code> if
792 * no such object can be found.
793 *
794 * @param adapter the adapter class to look up
795 * @return an object of the given class,
796 * or <code>null</code> if this object does not
797 * have an adapter for the given class
798 */
799 @Nullable <A> A getAdapter(@NonNull Class<A> adapter);
800
801 /**
802 * Return the result of visiting a visitable for which no more specific pivot type method
803 * is available.
804 */
Ed Willink82adc702014-12-10 14:46:20 +0000805 @Nullable R visiting(@NonNull «visitablePackageName2».«visitableClassName2» visitable);
Ed.Willink393222a2013-06-08 17:12:00 +0100806
807 «ENDIF»
808 «FOR eClass : getSortedEClasses(ePackage
Ed Willink6db59132013-07-19 13:20:52 +0100809 @Nullable R visit«eClass.name»(@NonNull «modelPackageName».«getTemplatedName(eClass object);
Ed.Willink393222a2013-06-08 17:12:00 +0100810 «ENDFOR»
811 }
812 ''')
813 writer.close();
814 }
815}