1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package com.unitesk.atp.treedl;
33
34 import java.io.File;
35 import java.io.FileOutputStream;
36 import java.io.IOException;
37 import java.io.PrintWriter;
38
39 import com.unitesk.atp.tool.PluginClass;
40 import com.unitesk.atp.treedl.ParameterVariantMatrix.Variant;
41 import com.unitesk.atp.treedl.TDL.*;
42
43 /***
44 * @author <A href="mailto:demakov@ispras.ru">Alexey Demakov</A>
45 * @version $Id: JavaNodeGenerator.java,v 1.68 2006/02/16 11:19:49 all-x Exp $
46 */
47 public class JavaNodeGenerator extends JavaTextGenerator implements TDL_Visitor
48 {
49 /***
50 * {@inheritDoc}
51 */
52 public String getVersion()
53 {
54 return PluginClass.getRevision( "$Revision: 1.68 $" ) + "-beta";
55 }
56
57 protected PrintWriter smap;
58
59 public static final String PROPERTY_NODE_CLASS = "node.class";
60 public static final String DEFAULT_NODE_CLASS = "com.unitesk.atp.tree.TreeClass.NodeClass";
61
62 public static final String PROPERTY_SMAP_GENERATE = "smap.generate";
63 public static final String DEFAULT_SMAP_GENERATE = "false";
64
65 public static final String PROPERTY_NODE_DEFAULT_CONSTRUCTOR = "node.default.constructor";
66 public static final String DEFAULT_NODE_DEFAULT_CONSTRUCTOR = "false";
67
68 public static final String PROPERTY_ATTRIBUTE_CHECK_SETONCE = "attribute.check.setonce";
69 public static final String DEFAULT_ATTRIBUTE_CHECK_SETONCE = "true";
70
71 public static final String PROPERTY_ATTRIBUTE_CHECK_NULL = "attribute.check.null";
72 public static final String DEFAULT_ATTRIBUTE_CHECK_NULL = "true";
73
74 public static final String PROPERTY_ATTRIBUTE_CHECK_SIZE = "attribute.check.size";
75 public static final String DEFAULT_ATTRIBUTE_CHECK_SIZE = "true";
76
77 public static final String PROPERTY_ATTRIBUTE_BOOL_IS = "attribute.bool.is";
78 public static final String DEFAULT_ATTRIBUTE_BOOL_IS = "false";
79
80 public static final String PROPERTY_ATTRIBUTE_LIST_ADD = "attribute.list.add";
81 public static final String DEFAULT_ATTRIBUTE_LIST_ADD = "false";
82
83 public static final String PROPERTY_ATTRIBUTE_LIST_REMOVE = "attribute.list.remove";
84 public static final String DEFAULT_ATTRIBUTE_LIST_REMOVE = "false";
85
86 public static final String PROPERTY_ATTRIBUTE_LIST_SIZE = "attribute.list.size";
87 public static final String DEFAULT_ATTRIBUTE_LIST_SIZE = "true";
88
89 public static final String PROPERTY_ATTRIBUTE_LIST_GET = "attribute.list.get";
90 public static final String DEFAULT_ATTRIBUTE_LIST_GET = "true";
91
92 public static final String PROPERTY_ATTRIBUTE_LIST_MIN = "attribute.list.min";
93 public static final String DEFAULT_ATTRIBUTE_LIST_MIN = "0";
94
95 public static final String PROPERTY_ATTRIBUTE_LIST_MAX = "attribute.list.max";
96 public static final String DEFAULT_ATTRIBUTE_LIST_MAX = "-1";
97
98 public static final String PROPERTY_ATTRIBUTE_ENUM_CHECK = "attribute.enum.check";
99 public static final String DEFAULT_ATTRIBUTE_ENUM_CHECK = "true";
100
101 public static final String PROPERTY_OPERATION_PUBLIC = "operation.public";
102 public static final String DEFAULT_OPERATION_PUBLIC = "true";
103
104 public static final String PROPERTY_OPERATION_STATIC = "operation.static";
105 public static final String DEFAULT_OPERATION_STATIC = "true";
106
107 protected void openSmap()
108 {
109 if( Boolean.getBoolean( getProperty( PROPERTY_SMAP_GENERATE, DEFAULT_SMAP_GENERATE ) ) )
110 {
111 String outFile = getOutFile().toString();
112 outFile = outFile.substring( 0, outFile.length() - ".java".length() );
113 File smapFileName = new File( outFile + ".smap" );
114 outFile = getOutFile().getName();
115 outFile = outFile.substring( 0, outFile.length() - ".java".length() );
116 try
117 {
118 smap = new PrintWriter( new FileOutputStream( smapFileName.getCanonicalPath() ) );
119 smap.println( "SMAP" );
120 smap.println( outFile + ".java" );
121 smap.println( "TDL" );
122 smap.println( "*S TDL" );
123 smap.println( "*F" );
124 smap.println( "+ 0 " + outFile + ".tdl" );
125 smap.println( outFile + ".tdl" );
126 smap.println( "*L" );
127 }
128 catch( IOException e )
129 {
130 process( e );
131 }
132 }
133 }
134
135 protected void closeSmap()
136 {
137 if( smap != null )
138 {
139 smap.println( "*E" );
140 smap.close();
141 }
142 }
143
144 protected void putMapping( int inputLine, int outputLine, int repeatCount )
145 {
146 if( smap != null )
147 {
148 smap.println( inputLine + "," + repeatCount + ":" + outputLine );
149 }
150 }
151
152 public void visitModule( Module node )
153 {
154 openSmap();
155
156 setFunction( "PredefinedTypeName", new PredefinedTypeNameFunction() );
157 setFunction( "Up", new NameFunction() );
158 setFunction( "ElementType", new ElementTypeFunction() );
159 setFunction( "ElementObjectType", new ElementObjectTypeFunction() );
160
161 generateHeader();
162
163 if( node.getName().sizeIdList() > 1 )
164 {
165 nl();
166 txt( "package " );
167 list( "i", 0, node.getName().sizeIdList() - 1, "${name.idList[i]}", "." );
168 txt( ";" ); nl();
169 }
170
171 if( node.getOptHeader() != null )
172 {
173 nl();
174 txt( "//-----------------------------------------------------------------------------" ); nl();
175 txt( "// tree header" ); nl();
176 int outputLine = getLine();
177 int inputLine = node.getOptHeader().getPosition().getLine();
178 txt( "${optHeader}" ); nl();
179 int repeatCount=getLine()-outputLine;
180 putMapping(inputLine,outputLine,repeatCount);
181 txt( "//-----------------------------------------------------------------------------" ); nl();
182 }
183
184 if( node.getOptDocomment() != null )
185 {
186 nl();
187 txt( "${optDocomment}" ); nl();
188 }
189
190 nl();
191 txt( "public class ${name.idList[-1]} extends " );
192 if( node.sizeOptBaseCustomTypeList() > 0 )
193 {
194 txt( "${optBaseCustomTypeList[0]}" ); nl();
195 if( node.sizeOptBaseCustomTypeList() > 1 )
196 {
197 txt( "implements " );
198 list( "i"
199 , 1
200 , node.sizeOptBaseCustomTypeList()
201 , "${optBaseCustomTypeList[i]}"
202 , ", "
203 );
204 nl();
205 }
206 } else {
207 txt( "com.unitesk.atp.tree.TreeClass" ); nl();
208 }
209 block();
210
211 if( node.getOptRootNodeType() != null )
212 {
213 nl();
214 txt( "//-----------------------------------------------------------------------------" ); nl();
215 txt( "// root of tree" ); nl();
216 nl();
217 txt( "public ${optRootNodeType.name} getRoot()" ); nl();
218 block_nl();
219 txt( "return (${optRootNodeType.name})getRootNode();" ); nl();
220 unblock_nl();
221 nl();
222 txt( "public void setRoot( ${optRootNodeType.name} node )" ); nl();
223 block_nl();
224 txt( "setRootNode( node );" ); nl();
225 unblock_nl();
226 }
227
228 if( node.getOptBody() != null )
229 {
230 nl();
231 txt( "//-----------------------------------------------------------------------------" ); nl();
232 txt( "// tree body" ); nl();
233 int outputLine = getLine();
234 int inputLine = node.getOptBody().getPosition().getLine();
235 txt( "${optBody}" ); nl();
236 int repeatCount=getLine()-outputLine;
237 putMapping(inputLine,outputLine,repeatCount);
238 txt( "//-----------------------------------------------------------------------------" ); nl();
239 nl();
240 }
241
242 list( "memberIndex", 0, node.sizeOptMemberList(), "${optMemberList[memberIndex]}", null );
243
244 if( node.getVisitorName().length() > 0 )
245 {
246 nl();
247 txt( "public static interface ${visitorName}" ); nl();
248 txt( "extends ${.Visitor}" ); nl();
249 list( "i"
250 , 0
251 , node.sizeOptBaseModuleList()
252 , " , ${optBaseModuleList[i].module.root.name}.${optBaseModuleList[i].module.root.visitorName}" + endl
253 , null
254 );
255 block_nl();
256 for( int i = 0; i < node.sizeOptMemberList(); i++ )
257 {
258 ModuleMember member = node.getOptMemberList( i );
259 if( member instanceof NodeTypeDecl
260 && !((NodeTypeDecl)member).isAbstract()
261 )
262 {
263 pushNode( member );
264 txt( "void visit${name}( ${name} node );" ); nl();
265 popNode();
266 }
267 }
268 unblock_nl();
269 }
270
271 unblock_nl();
272
273 closeSmap();
274 }
275
276 public void visitBaseModule( BaseModule node )
277 {
278
279 throw new UnsupportedOperationException();
280 }
281
282 public void visitConstTypeDecl( ConstTypeDecl node )
283 {
284 nl();
285 txt( "public static final class ${name} extends ${.EnumClass}" ); nl();
286 block_nl();
287 txt( "public interface Key" );
288 txtif( node.getOptBaseType(), " extends ${optBaseType}.Key" ); nl();
289 block_nl();
290 Object old_i = getVariable( "i" );
291 for( int i = 0
292 ; i < node.sizeFullConstantList()
293 ; i++
294 )
295 {
296 setVariable( "i", new Integer( i ) );
297 txt( "public static final int ${fullConstantList[i]} = " );
298 if( i > 0 )
299 {
300 txtAsIs( node.getFullConstantList( i - 1 ).toString() );
301 txtif( node.isFlags(), " << ", " + " );
302 }
303 txt( "1;" ); nl();
304 }
305 unblock_nl();
306 setVariable( "i", old_i );
307 nl();
308 list( "i"
309 , 0
310 , node.sizeFullConstantList()
311 , "public static final ${name} ${fullConstantList[i]} = new ${name}( Key.${fullConstantList[i]} );"
312 , endl
313 ); nl();
314 nl();
315 txt( "private static java.util.Map/*Integer,${name}*/ keyConstantMap = new java.util.HashMap/*Integer,${name}*/();" ); nl();
316 nl();
317 txt( "static" ); nl();
318 block_nl();
319 list( "i"
320 , 0
321 , node.sizeFullConstantList()
322 , "keyConstantMap.put( new Integer( Key.${fullConstantList[i]} ), ${fullConstantList[i]} );"
323 , endl
324 ); nl();
325 unblock_nl();
326 nl();
327 txt( "public static int min()" ); nl();
328 block_nl();
329 txtif( node.isFlags()
330 , "return 0;"
331 , "return Key.${fullConstantList[0]};"
332 ); nl();
333 unblock_nl();
334 nl();
335 txt( "public static int max()" ); nl();
336 block_nl();
337 txtif( node.isFlags()
338 , "return (Key.${fullConstantList[-1]} << 1) - 1;"
339 , "return Key.${fullConstantList[-1]};"
340 ); nl();
341 unblock_nl();
342 nl();
343 txt( "public static ${name} get( int key )" ); nl();
344 block_nl();
345 txt( "if( key < min() || max() < key )" ); nl();
346 block_nl();
347
348 txt( "throw new java.lang.IllegalArgumentException( \"${name}.get(\" + key + \")\" );" ); nl();
349 unblock_nl();
350
351 txt( "Integer keyObject = new Integer( key );" ); nl();
352 txt( "${name} constant = (${name})keyConstantMap.get( keyObject );" ); nl();
353 txt( "if( constant == null )" ); nl();
354 block_nl();
355 txt( "constant = new ${name}( key );" ); nl();
356 txt( "keyConstantMap.put( keyObject, constant );" ); nl();
357 unblock_nl();
358 txt( "return constant;" ); nl();
359 unblock_nl();
360 nl();
361 txt( "private ${name}( int key ) { super( key ); }" ); nl();
362 nl();
363 txt( "private Object readResolve() { return get( key() ); }" ); nl();
364 unblock_nl();
365 }
366
367 public void visitNodeTypeDecl( NodeTypeDecl node )
368 {
369
370 if( node.getOptDocomment() != null )
371 {
372 nl();
373 txt( "${optDocomment}" );
374 }
375 nl();
376 txt( "public" );
377 txtif( node.isAbstract(), " abstract" );
378 txt( " static class ${name}" );
379
380 boolean hasBaseClass = false;
381
382 String defaultClass = getProperty( node, PROPERTY_NODE_CLASS, DEFAULT_NODE_CLASS, true );
383 if( defaultClass.length() != 0 )
384 {
385 setVariable( "defaultClass", defaultClass );
386 } else {
387 defaultClass = null;
388 }
389
390 if( node.getOptBaseType() != null )
391 {
392 if( node.getOptBaseType().getType() != TDL_Module.getRootNodeType() )
393 {
394 txt( " extends ${optBaseType}" );
395 } else {
396 txtif( defaultClass != null, " extends ${.defaultClass}" );
397 }
398 hasBaseClass = true;
399 } else {
400 if( defaultClass != null )
401 {
402 txt( " extends ${.defaultClass}" );
403 hasBaseClass = true;
404 }
405 }
406
407 if( node.sizeOptBaseCustomTypeList() > 0 )
408 {
409 int implementsStart = 0;
410 if( !hasBaseClass )
411 {
412 txt( " extends ${optBaseCustomTypeList[0]}" );
413 implementsStart++;
414 }
415
416 if( node.sizeOptBaseCustomTypeList() > implementsStart )
417 {
418 txt( " implements " );
419 list( "i"
420 , implementsStart
421 , node.sizeOptBaseCustomTypeList()
422 , "${optBaseCustomTypeList[i]}"
423 , ", "
424 );
425 }
426 }
427
428 nl();
429 block_nl();
430
431
432 list( "i", 0, node.sizeOptMemberList(), "${optMemberList[i]}", null );
433
434
435 txt( "//-------------------------------------------------------------------------" ); nl();
436 txt( "// constructor" ); nl();
437 nl();
438 txt( "public" ); nl();
439 txt( "${name}" );
440
441 int constructorParametersCount = 0;
442 for( int i = 0; i < node.sizeFullFieldList(); i++ )
443 {
444 Field field = node.getFullFieldList( i );
445
446 if( TDL_Module.isConstructorParameter( field ) )
447 {
448 pushNode( field );
449
450 nl();
451 txtif( constructorParametersCount == 0, "(", "," );
452 txt( " ${type} ${name}" );
453 constructorParametersCount++;
454
455 popNode();
456 }
457 }
458
459 switch( constructorParametersCount )
460 {
461 case 0:
462 txt( "()" );
463 break;
464 case 1:
465 txt( " )" );
466 break;
467 default:
468 nl();
469 txt( ")" );
470 break;
471 }
472 nl();
473 block_nl();
474 txt( "super" );
475
476 int parentConstructorParametersCount = 0;
477
478 for( int i = 0; i < node.getBaseNodeType().sizeFullFieldList(); i++ )
479 {
480 Field field = node.getBaseNodeType().getFullFieldList( i );
481
482 if( TDL_Module.isConstructorParameter( field ) )
483 {
484 pushNode( field );
485
486 nl();
487 txtif( parentConstructorParametersCount == 0, "(", "," );
488
489 txt( " ${name}" );
490 parentConstructorParametersCount++;
491
492 popNode();
493 }
494 }
495
496 switch( parentConstructorParametersCount )
497 {
498 case 0:
499 txt( "();" );
500 break;
501 case 1:
502 txt( " );" );
503 break;
504 default:
505 nl();
506 txt( ");" );
507 break;
508 }
509 nl();
510 nl();
511
512 for( int i = node.getBaseNodeType().sizeFullFieldList()
513 ; i < node.sizeFullFieldList()
514 ; i++
515 )
516 {
517 Field field = node.getFullFieldList( i );
518
519 if( TDL_Module.isConstructorParameter( field ) )
520 {
521 pushNode( field );
522
523 txt( "set${Up:name}( ${name} );" ); nl();
524
525 popNode();
526 } else if( field.getOptInitCode() != null )
527 {
528 pushNode( field );
529 int outputLine = getLine();
530 int inputLine = field.getOptInitCode().getPosition().getLine();
531
532 txt( "set${Up:name}( ${optInitCode} );" ); nl();
533 int repeatCount=getLine()-outputLine;
534 putMapping(inputLine,outputLine,repeatCount);
535
536 popNode();
537 }
538 }
539
540 for( int i = 0; i < node.sizeOptMemberList(); i++ )
541 {
542 NodeMember member = node.getOptMemberList( i );
543
544 if( member instanceof ConstructorCodeMember )
545 {
546 pushNode( member );
547 txt( "//---------------------------------------------------------------------" ); nl();
548 txt( "// constructor code" ); nl();
549 int outputLine = getLine();
550 int inputLine = member.getPosition().getLine();
551 txt( "${code}" );
552 int repeatCount=getLine()-outputLine+1;
553 putMapping(inputLine,outputLine,repeatCount);
554
555 popNode();
556 }
557 }
558
559 unblock_nl();
560
561 if( getBooleanProperty( node
562 , PROPERTY_NODE_DEFAULT_CONSTRUCTOR
563 , DEFAULT_NODE_DEFAULT_CONSTRUCTOR
564 , true
565 )
566 )
567 {
568 if( constructorParametersCount > 0 )
569 {
570 nl();
571 txt( "//-------------------------------------------------------------------------" ); nl();
572 txt( "// default constructor" ); nl();
573 txt( "public ${name}() {}" ); nl();
574 }
575 }
576
577
578 if( node.getBaseNodeType() == TDL_Module.getRootNodeType()
579 || node.getBaseNodeType().getParent() != node.getParent()
580 )
581 {
582
583 nl();
584 txt( "public Class keyClass()" ); nl();
585 block_nl();
586 txt( "return ${parent.name.idList[-1]}.class;" ); nl();
587 unblock_nl();
588 }
589 if( !node.isAbstract() )
590 {
591 nl();
592 txt( "public static final int KEY = ${.memberIndex};" ); nl();
593 nl();
594 txt( "public int key()" ); nl();
595 block_nl();
596 txt( "return KEY;" ); nl();
597 unblock_nl();
598 }
599
600
601 String visitorName = ((Module)node.getParent()).getVisitorName();
602 if( visitorName.length() > 0 && !node.isAbstract() )
603 {
604 nl();
605 txt( "//-------------------------------------------------------------------------" ); nl();
606 txt( "// visitor design pattern" ); nl();
607 nl();
608 txt( "public void accept( ${.Visitor} visitor )" ); nl();
609 block_nl();
610 txt( "((${parent.visitorName})visitor).visit${name}( this );" ); nl();
611 unblock_nl();
612 }
613 unblock_nl();
614 }
615
616 public void visitConstructorCodeMember( ConstructorCodeMember node )
617 {
618 }
619
620 public void visitBodyCodeMember( BodyCodeMember node )
621 {
622 nl();
623 txt( "//---------------------------------------------------------------------" ); nl();
624 txt( "// body code" ); nl();
625 int outputLine = getLine();
626 int inputLine = node.getPosition().getLine();
627 txt( "${code}" );nl();
628 int repeatCount=getLine()-outputLine;
629 putMapping(inputLine,outputLine,repeatCount);
630 }
631
632 public void visitField( Field node )
633 {
634 Field baseField = node.getBaseField();
635
636 txt( "//-------------------------------------------------------------------------" ); nl();
637 txtif( node.isChild()
638 , "// child"
639 , "// attribute"
640 ); nl();
641
642 if( TDL_Module.getStorageType( node ) == StorageType.DEFAULT )
643 {
644 nl();
645 txt( "private ${type} ${name};" ); nl();
646 }
647
648
649 if( baseField == null && !TDL_Module.hasGet( node ) )
650 {
651 nl();
652 if( node.getOptDocomment() != null )
653 {
654 txt( "${optDocomment}" ); nl();
655 }
656
657
658
659
660 txt( "public abstract ${type} get${Up:name}();" ); nl();
661 nl();
662 } else
663 if( TDL_Module.getStorageType( node ) == StorageType.DEFAULT
664 || node.getOptGetCode() != null
665 )
666 {
667 nl();
668 if( node.getOptDocomment() != null )
669 {
670 txt( "${optDocomment}" ); nl();
671 }
672
673
674
675
676
677 txt( "public ${type} get${Up:name}()" ); nl();
678 block_nl();
679 if( baseField != null && TDL_Module.hasGet( baseField ) )
680 {
681
682 txt( "${type} ${name} = super.get${Up:name}();" ); nl();
683 } else
684 if( TDL_Module.getStorageType( node ) != StorageType.DEFAULT )
685 {
686
687 txt( "${type} ${name};" ); nl();
688 }
689
690 if( node.getOptGetCode() != null )
691 {
692 int outputLine = getLine();
693 int inputLine = node.getOptGetCode().getPosition().getLine();
694 txt( "${optGetCode}" ); nl();
695 int repeatCount=getLine()-outputLine;
696 putMapping(inputLine,outputLine,repeatCount);
697 }
698 txt( "return ${name};" ); nl();
699 unblock_nl();
700 }
701
702
703 if( !node.checkModifiers( Modifiers.NOSET ) )
704 {
705 if( baseField == null && !TDL_Module.hasSet( node ) )
706 {
707 nl();
708
709
710
711 txt( "public abstract void set${Up:name}( ${type} ${name} );" ); nl();
712 nl();
713 } else
714 if( TDL_Module.getStorageType( node ) == StorageType.DEFAULT
715 || node.getOptSetCode() != null
716 )
717 {
718 boolean setonceCheck = false;
719 if( getBooleanProperty( node
720 , PROPERTY_ATTRIBUTE_CHECK_SETONCE
721 , DEFAULT_ATTRIBUTE_CHECK_SETONCE
722 , true
723 )
724 && node.checkModifiers( Modifiers.SETONCE )
725 && ( baseField == null
726 || !TDL_Module.hasSet( baseField )
727 )
728 )
729 {
730 nl();
731 txt( "private boolean __is${Up:name}Inited__ = false;" ); nl();
732 setonceCheck = true;
733 }
734
735 nl();
736 txt( "public void set${Up:name}( ${type} ${name} )" ); nl();
737 block_nl();
738
739
740 if( setonceCheck )
741 {
742 txt( "if( __is${Up:name}Inited__ )" ); nl();
743 block_nl();
744 txt( "throw new java.lang.IllegalArgumentException( \"${name}\" );" ); nl();
745 unblock_nl();
746 }
747
748 if( TDL_Module.getStorageType( node ) == StorageType.DEFAULT
749 || TDL_Module.getStorageType( node ) == StorageType.CUSTOM
750 )
751 {
752
753 Type type = node.getType();
754 switch( type.getCardinality().key() )
755 {
756 case 0:
757 if( JavaLanguageDescription.isPrimitiveType( type ) )
758 {
759
760 break;
761 }
762
763 case Cardinality.Key.LIST | Cardinality.Key.OPTIONAL:
764
765 if( getBooleanProperty( node
766 , PROPERTY_ATTRIBUTE_CHECK_NULL
767 , DEFAULT_ATTRIBUTE_CHECK_NULL
768 , true
769 )
770 )
771 {
772 generateListCheck( getProperty( node, PROPERTY_ATTRIBUTE_LIST_MIN, "0", true )
773 , getProperty( node, PROPERTY_ATTRIBUTE_LIST_MAX, DEFAULT_ATTRIBUTE_LIST_MAX, true )
774 );
775 }
776 break;
777 case Cardinality.Key.LIST:
778
779 if( getBooleanProperty( node
780 , PROPERTY_ATTRIBUTE_CHECK_SIZE
781 , DEFAULT_ATTRIBUTE_CHECK_SIZE
782 , true
783 )
784 )
785 {
786 generateListCheck( getProperty( node, PROPERTY_ATTRIBUTE_LIST_MIN, "1", true )
787 , getProperty( node, PROPERTY_ATTRIBUTE_LIST_MAX, DEFAULT_ATTRIBUTE_LIST_MAX, true )
788 );
789 }
790 break;
791 case Cardinality.Key.OPTIONAL:
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806 break;
807 }
808 } else
809 if( TDL_Module.hasSet( baseField ) )
810 {
811
812 txt( "super.set${Up:name}( ${name} );" ); nl();
813 }
814
815 if( node.getOptSetCode() != null )
816 {
817 int outputLine = getLine();
818 int inputLine = node.getOptSetCode().getPosition().getLine();
819 txt( "${optSetCode}" ); nl();
820 int repeatCount=getLine()-outputLine;
821 putMapping(inputLine,outputLine,repeatCount);
822 }
823
824
825 if( setonceCheck )
826 {
827 txt( "__is${Up:name}Inited__ = true;" ); nl();
828 }
829
830 if( TDL_Module.getStorageType( node ) == StorageType.DEFAULT )
831 {
832 txt( "this.${name} = ${name};" ); nl();
833 if( node.isChild() )
834 {
835 txt( "makeChild( \"${name}\" );" ); nl();
836 }
837 }
838 unblock_nl();
839 }
840 }
841 if( baseField == null )
842 {
843 if( node.getType().checkCardinality( Cardinality.LIST ) )
844 {
845
846 if( getBooleanProperty( node
847 , PROPERTY_ATTRIBUTE_LIST_GET
848 , DEFAULT_ATTRIBUTE_LIST_GET
849 , true
850 )
851 )
852 {
853
854 nl();
855 txt( "public final ${ElementType:type} get${Up:name}( int i )" ); nl();
856 block_nl();
857 if( JavaLanguageDescription.isPrimitiveType( node.getType() ) )
858 {
859 txt( "return ((${ElementObjectType:type})get${Up:name}().get( i )).${ElementType:type}Value();" ); nl();
860 } else {
861 txt( "return (${ElementType:type})get${Up:name}().get( i );" ); nl();
862 }
863 unblock_nl();
864 }
865
866 if( getBooleanProperty( node
867 , PROPERTY_ATTRIBUTE_LIST_SIZE
868 , DEFAULT_ATTRIBUTE_LIST_SIZE
869 , true
870 )
871 )
872 {
873
874 nl();
875 txt( "public final int size${Up:name}()" ); nl();
876 block_nl();
877 txt( "return get${Up:name}().size();" ); nl();
878 unblock_nl();
879 }
880
881 if( getBooleanProperty( node
882 , PROPERTY_ATTRIBUTE_LIST_ADD
883 , DEFAULT_ATTRIBUTE_LIST_ADD
884 , true
885 )
886 )
887 {
888
889 nl();
890 txt( "public final void add${Up:name}( ${ElementType:type} elem )" ); nl();
891 block_nl();
892 txt( "get${Up:name}().add( elem );" ); nl();
893 if( node.isChild() )
894 {
895 txt( "elem.setParent( this );" ); nl();
896 }
897 unblock_nl();
898 }
899 if( getBooleanProperty( node
900 , PROPERTY_ATTRIBUTE_LIST_REMOVE
901 , DEFAULT_ATTRIBUTE_LIST_REMOVE
902 , true
903 )
904 )
905 {
906
907 nl();
908 txt( "public final void remove${Up:name}( int index )" ); nl();
909 block_nl();
910 if( node.isChild() )
911 {
912 txt( "((${.Node})get${Up:name}().remove( index )).resetParent();" ); nl();
913 } else {
914 txt( "get${Up:name}().remove( index );" ); nl();
915 }
916 unblock_nl();
917 }
918 nl();
919 } else {
920
921 if( node.getType() instanceof PredefinedType
922 && ((PredefinedType)node.getType()).checkKind( PredefinedTypeKind.BOOL)
923 )
924 {
925 if( getBooleanProperty( node
926 , PROPERTY_ATTRIBUTE_BOOL_IS
927 , DEFAULT_ATTRIBUTE_BOOL_IS
928 , true
929 )
930 )
931 {
932 nl();
933 if( node.getName().getValue().startsWith( "is" ) )
934 {
935 txt( "public final boolean ${name}()" ); nl();
936 } else {
937 txt( "public final boolean is${Up:name}()" ); nl();
938 }
939 block_nl();
940 txt( "return get${Up:name}();" ); nl();
941 unblock_nl();
942 nl();
943 }
944 }
945
946 if( node.getType() instanceof NodeType
947 && ((NodeType)node.getType()).getType().getType() instanceof ConstTypeDecl
948 )
949 {
950 if( getBooleanProperty( node
951 , PROPERTY_ATTRIBUTE_ENUM_CHECK
952 , DEFAULT_ATTRIBUTE_ENUM_CHECK
953 , true
954 )
955 )
956 {
957 nl();
958 generateEnumCheck( node );
959 }
960 }
961 }
962 }
963 }
964
965 protected void generateListCheck( String min, String max )
966 {
967 boolean nullChecked = false;
968 if( !min.equals( DEFAULT_ATTRIBUTE_LIST_MIN ) )
969 {
970 setVariable( "min", min );
971 txt( "if( ${name}.size() < ${.min} )" ); nl();
972 block_nl();
973 txt( "throw new java.lang.IllegalArgumentException( \"${name}.size() < ${.min}\" );" ); nl();
974 unblock_nl();
975 nl();
976 nullChecked = true;
977 }
978 if( !max.equals( DEFAULT_ATTRIBUTE_LIST_MAX ) )
979 {
980 setVariable( "max", max );
981 txt( "if( ${name}.size() > ${.max} )" ); nl();
982 block_nl();
983 txt( "throw new java.lang.IllegalArgumentException( \"${name}.size() > ${.max}\" );" ); nl();
984 unblock_nl();
985 nl();
986 nullChecked = true;
987 }
988 if( !nullChecked )
989 {
990 txt( "if( ${name} == null )" ); nl();
991 block_nl();
992 txt( "throw new java.lang.IllegalArgumentException( \"${name} == null\" );" ); nl();
993 unblock_nl();
994 nl();
995 }
996 }
997 /***
998 * check( int ) for the first attribute of constant type
999 */
1000 protected void generateEnumCheck( Field node )
1001 {
1002 if( ((ConstTypeDecl)((NodeType)node.getType()).getType().getType()).isFlags() )
1003 {
1004 txt( "public boolean check${Up:name}( int mask )" ); nl();
1005 block_nl();
1006 txt( "return (get${Up:name}().key() & mask) == mask;" ); nl();
1007 unblock_nl();
1008 } else {
1009 txt( "public boolean check${Up:name}( int value )" ); nl();
1010 block_nl();
1011 txt( "return get${Up:name}().key() == value;" ); nl();
1012 unblock_nl();
1013 }
1014 nl();
1015 txt( "public boolean check${Up:name}( ${type} value )" ); nl();
1016 block_nl();
1017 txt( "return check${Up:name}( value.key() );" ); nl();
1018 unblock_nl();
1019 nl();
1020 }
1021
1022 /***
1023 * Generate variant methods for all combinations of virtual node types parameters
1024 *
1025 * @param operationDecl operation declaration to generate variants for
1026 * @param paramMatrix matrix to generate variants for
1027 */
1028 protected void generateVariants( OperationDecl operationDecl, ParameterVariantMatrix paramMatrix )
1029 {
1030 ModuleMatrix moduleMatrix = operationDecl.getModuleMatrix();
1031 for( Index variant = paramMatrix.createIndex()
1032 ; variant.has()
1033 ; variant.next()
1034 )
1035 {
1036 nl();
1037 pushNode( operationDecl );
1038 txt( "private final " );
1039 txtif( getBooleanProperty( operationDecl
1040 , PROPERTY_OPERATION_STATIC
1041 , DEFAULT_OPERATION_STATIC
1042 , true
1043 )
1044 , "static "
1045 );
1046 txt( "${returnType?void} _${.memberIndex}_${name}( " );
1047 popNode();
1048 Object old_i = getVariable( "i" );
1049 for( int i = 0, vi = -1; i < operationDecl.sizeOptParameterDeclList(); i++ )
1050 {
1051 setVariable( "i", new Integer( i ) );
1052 txtif( i > 0, ", " );
1053 ParameterDecl paramDecl = operationDecl.getOptParameterDeclList( i );
1054 if( paramDecl instanceof VirtualParameterDecl )
1055 {
1056 vi++;
1057 if( moduleMatrix.isNodeType( vi ) )
1058 {
1059
1060 Variant v = paramMatrix.getVariant( vi, variant.getIndex( vi ) );
1061 setVariable( "variant", v );
1062 txtif( ((Module)v.getType().getParent()) != module.getRoot()
1063 , "${.variant.type.parent.name}."
1064 );
1065 txt( "${.variant.type.name} ${optParameterDeclList[i].name}" );
1066 continue;
1067 }
1068 }
1069 txt( "${optParameterDeclList[i]}" );
1070 }
1071 setVariable( "i", old_i );
1072 txt( " )" ); nl();
1073 block_nl();
1074 if( moduleMatrix.getDimType() == moduleMatrix.getDim() )
1075 {
1076 generateCaseCode( operationDecl, paramMatrix, variant );
1077 } else {
1078 generateEnumSwitch( operationDecl, 0, paramMatrix, variant );
1079 }
1080 unblock_nl();
1081 }
1082 }
1083
1084 /***
1085 * Generate case code for the given variant.
1086 */
1087 protected void generateCaseCode( OperationDecl operationDecl
1088 , ParameterVariantMatrix paramMatrix
1089 , Index paramIndex
1090 )
1091 {
1092 pushNode( paramMatrix.getCase( paramIndex ) );
1093 txt( "${parent.code}" ); nl();
1094 popNode();
1095 }
1096
1097 /***
1098 * Generate variant call.
1099 */
1100 protected void generateCall( OperationDecl operationDecl, ParameterVariantMatrix paramMatrix, Index paramIndex )
1101 {
1102 ModuleMatrix moduleMatrix = operationDecl.getModuleMatrix();
1103 pushNode( operationDecl );
1104 txtif( operationDecl.getReturnType(), "return " );
1105 txt( "_${.memberIndex}_${name}( " );
1106 Object old_i = getVariable( "i" );
1107 Object old_variant = getVariable( "variant" );
1108 for( int i = 0, vi = 0; i < operationDecl.sizeOptParameterDeclList(); i++ )
1109 {
1110 txtif( i > 0, ", " );
1111 setVariable( "i", new Integer( i ) );
1112 ParameterDecl paramDecl = operationDecl.getOptParameterDeclList( i );
1113 if( paramDecl instanceof VirtualParameterDecl )
1114 {
1115 if( moduleMatrix.isNodeType( vi ) )
1116 {
1117
1118 Variant v = paramMatrix.getVariant( vi, paramIndex.getIndex( vi ) );
1119 setVariable( "variant", v );
1120 txt( "(" );
1121 txtif( ((Module)v.getType().getParent()) != module.getRoot()
1122 , "${.variant.type.parent.name}."
1123 );
1124 txt( "${.variant.type.name})" );
1125 }
1126 vi++;
1127 }
1128 txt( "${optParameterDeclList[i].name}" );
1129 }
1130 setVariable( "variant", old_variant );
1131 setVariable( "i", old_i );
1132 txt( " );" ); nl();
1133 if( operationDecl.getReturnType() == null )
1134 {
1135 txt( "break;" ); nl();
1136 }
1137 popNode();
1138 }
1139
1140 /***
1141 * Generate switch by enum type of virtual parameter
1142 *
1143 * @param index index of virtual parameter
1144 */
1145 protected void generateEnumSwitch( OperationDecl operationDecl
1146 , int index
1147 , ParameterVariantMatrix paramMatrix
1148 , Index paramIndex
1149 )
1150 {
1151 ModuleMatrix moduleMatrix = operationDecl.getModuleMatrix();
1152 if( index < moduleMatrix.getDim() )
1153 {
1154 if( moduleMatrix.isNodeType( index ) )
1155 {
1156 generateEnumSwitch( operationDecl, index + 1, paramMatrix, paramIndex );
1157 return;
1158 }
1159 pushNode( operationDecl.getOptParameterDeclList( moduleMatrix.getIndex( index ) ) );
1160 txt( "switch( ${name}.key() )" ); nl();
1161 block_nl();
1162 Object old_variant = getVariable( "variant" );
1163 for( int i = 0; i < paramMatrix.getSize( index ); i++ )
1164 {
1165 Variant v = paramMatrix.getVariant( index, i );
1166 setVariable( "variant", v );
1167 Module m = (Module)v.getConstant().getParent().getParent();
1168 txt( "case " );
1169 txtif( m != module.getRoot()
1170 , "${.variant.constant.parent.parent.name}."
1171 );
1172 txt( "${.variant.constant.parent.name}.Key.${.variant.constant}:" ); nl();
1173 block_nl();
1174 paramIndex.setIndex( index, i );
1175 generateEnumSwitch( operationDecl, index + 1, paramMatrix, paramIndex );
1176 unblock_nl();
1177 }
1178 setVariable( "variant", old_variant );
1179 txt( "default:" ); nl(); incIndent();
1180 txt( "throw new IllegalArgumentException( \"${name}\" );" ); nl(); popIndent();
1181 unblock_nl();
1182 popNode();
1183 } else {
1184 generateCaseCode( operationDecl, paramMatrix, paramIndex );
1185 if( operationDecl.getReturnType() == null )
1186 {
1187 txt( "break;" ); nl();
1188 }
1189 }
1190 }
1191
1192 /***
1193 * Generate switch by key of virtual parameter
1194 *
1195 * @param index index of virtual parameter
1196 */
1197 protected void generateKeySwitch( OperationDecl operationDecl
1198 , int index
1199 , ParameterVariantMatrix paramMatrix
1200 , Index paramIndex
1201 )
1202 {
1203 ModuleMatrix moduleMatrix = operationDecl.getModuleMatrix();
1204 if( index < moduleMatrix.getDim() )
1205 {
1206 if( !moduleMatrix.isNodeType( index ) )
1207 {
1208 generateKeySwitch( operationDecl, index + 1, paramMatrix, paramIndex );
1209 return;
1210 }
1211 VirtualParameterDecl paramDecl
1212 = (VirtualParameterDecl)operationDecl
1213 .getOptParameterDeclList( moduleMatrix.getIndex( index ) );
1214 pushNode( paramDecl );
1215 txt( "switch( ${name}.key() )" ); nl();
1216 block_nl();
1217 Object old_variant = getVariable( "variant" );
1218 for( int i = 0; i < paramMatrix.getSize( index ); i++ )
1219 {
1220 Variant v = paramMatrix.getVariant( index, i );
1221 Module m = (Module)v.getType().getParent();
1222 setVariable( "variant", v );
1223 txt( "case " );
1224 txtif( m != module.getRoot()
1225 , "${.variant.type.parent.name}."
1226 );
1227 txt( "${.variant.type.name}.KEY:" ); nl();
1228 block_nl();
1229 paramIndex.setIndex( index, i );
1230 generateKeySwitch( operationDecl, index + 1, paramMatrix, paramIndex );
1231 unblock_nl();
1232 }
1233 setVariable( "variant", old_variant );
1234 txt( "default:" ); nl(); incIndent();
1235 txt( "throw new IllegalArgumentException( \"${name}\" );" ); nl(); popIndent();
1236 unblock_nl();
1237 popNode();
1238 } else {
1239 generateCall( operationDecl, paramMatrix, paramIndex );
1240 }
1241 }
1242
1243 /***
1244 * Generate switch (if-else-if) by key class of virtual parameter
1245 *
1246 * @param index index of virtual parameter
1247 */
1248 protected void generateKeyClassSwitch( OperationDecl operationDecl
1249 , int index
1250 , Index moduleIndex
1251 )
1252 {
1253 ModuleMatrix matrix = operationDecl.getModuleMatrix();
1254 if( index < matrix.getDim() )
1255 {
1256 if( !matrix.isNodeType( index ) )
1257 {
1258 generateKeyClassSwitch( operationDecl, index + 1, moduleIndex );
1259 return;
1260 }
1261 VirtualParameterDecl paramDecl
1262 = (VirtualParameterDecl)operationDecl.getOptParameterDeclList( matrix.getIndex( index ) );
1263 pushNode( paramDecl );
1264 Module[] domain = matrix.getDomain();
1265 for( int i = 0 ; i < domain.length; i++ )
1266 {
1267 Module m = domain[i];
1268 if( matrix.variantsExist( m, index ) )
1269 {
1270 setVariable( "module", m.getName().getValue() );
1271 nl();
1272 txt( "if( ${name}.keyClass() == ${.module}.class )" ); nl();
1273 block_nl();
1274 moduleIndex.setIndex( index, i );
1275 generateKeyClassSwitch( operationDecl, index + 1, moduleIndex );
1276 unblock();
1277 txt( " else" );
1278 }
1279 }
1280 txtAsIs( " " );
1281 block_nl();
1282 txt( "throw new IllegalArgumentException( \"${name}\" );" ); nl();
1283 unblock_nl();
1284 popNode();
1285 } else {
1286 ParameterVariantMatrix paramMatrix = operationDecl.getModuleMatrix().getParamMatrix( moduleIndex );
1287 if( paramMatrix != null )
1288 {
1289 generateKeySwitch( operationDecl, 0, paramMatrix, paramMatrix.createIndex() );
1290 } else {
1291 OperationDecl opDecl = operationDecl.getModuleMatrix().getOperationDecl( moduleIndex );
1292 pushNode( opDecl );
1293 txtif( opDecl.getReturnType(), "return " );
1294 txtif( opDecl.getParent() != module, "${parent.name}." );
1295 txt( "${name}( " );
1296 popNode();
1297 pushNode( operationDecl );
1298 list( "i", 0, operationDecl.sizeOptParameterDeclList(), "${optParameterDeclList[i].name}", ", " );
1299 popNode();
1300 txt( " );" ); nl();
1301 if( operationDecl.getReturnType() == null )
1302 {
1303 txt( "break;" ); nl();
1304 }
1305 }
1306 }
1307 }
1308
1309 public void visitOperationDecl( OperationDecl node )
1310 {
1311 nl();
1312 txt( "//-----------------------------------------------------------------------------" ); nl();
1313 txt( "// operation ${name}" ); nl();
1314
1315 ModuleMatrix matrix = node.getModuleMatrix();
1316 for( Index variant = matrix.createIndex()
1317 ; variant.has()
1318 ; variant.next()
1319 )
1320 {
1321 ParameterVariantMatrix paramMatrix = matrix.getParamMatrix( variant );
1322 if( paramMatrix != null )
1323 {
1324 generateVariants( node, paramMatrix );
1325 }
1326 }
1327 nl();
1328 txtif( getBooleanProperty( node
1329 , PROPERTY_OPERATION_PUBLIC
1330 , DEFAULT_OPERATION_PUBLIC
1331 , true
1332 )
1333 , "public "
1334 );
1335 txtif( getBooleanProperty( node
1336 , PROPERTY_OPERATION_STATIC
1337 , DEFAULT_OPERATION_STATIC
1338 , true
1339 )
1340 , "static "
1341 );
1342 txt( "${returnType?void} ${name}( " );
1343 list( "i", 0, node.sizeOptParameterDeclList(), "${optParameterDeclList[i]}", ", " );
1344 txt( " )" ); nl();
1345 block_nl();
1346
1347 generateKeyClassSwitch( node, 0, matrix.createIndex() );
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357 unblock_nl();
1358 }
1359
1360 public void visitNonVirtualParameterDecl( NonVirtualParameterDecl node )
1361 {
1362 txt( "${type} ${name}" );
1363 }
1364
1365 public void visitVirtualParameterDecl( VirtualParameterDecl node )
1366 {
1367 txt( "${type} ${name}" );
1368 }
1369
1370 public void visitCase( Case node )
1371 {
1372
1373 throw new UnsupportedOperationException();
1374 }
1375
1376 public void visitCaseSignature( CaseSignature node )
1377 {
1378
1379 throw new UnsupportedOperationException();
1380 }
1381
1382 public void visitParameter( Parameter node )
1383 {
1384 ParameterDecl paramDecl
1385 = ((OperationDecl)node.getParent().getParent().getParent())
1386 .getOptParameterDeclList( ((Integer)getVariable( "paramNum" )).intValue() );
1387
1388 setVariable( "paramDecl", paramDecl );
1389 if( paramDecl instanceof NonVirtualParameterDecl )
1390 {
1391 txt( "${.paramDecl}" );
1392 } else if( paramDecl instanceof VirtualParameterDecl )
1393 {
1394 if( ((VirtualParameterDecl)paramDecl).getType().getType() instanceof ConstTypeDecl )
1395 {
1396 txt( "${.paramDecl}" );
1397 } else {
1398 txt( "${optType} ${name}" );
1399 }
1400 } else {
1401 throw new InternalError( paramDecl.getClass().getName() );
1402 }
1403 }
1404 }