15 * distributed under the License is distributed on an "AS IS" BASIS, |
14 * distributed under the License is distributed on an "AS IS" BASIS, |
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
17 * See the License for the specific language governing permissions and |
16 * See the License for the specific language governing permissions and |
18 * limitations under the License. |
17 * limitations under the License. |
19 */ |
18 */ |
20 /* |
|
21 * $Id: Sort.java,v 1.2.4.1 2005/09/12 11:08:12 pvedula Exp $ |
|
22 */ |
|
23 |
19 |
24 package com.sun.org.apache.xalan.internal.xsltc.compiler; |
20 package com.sun.org.apache.xalan.internal.xsltc.compiler; |
25 |
21 |
26 import java.text.Collator; |
|
27 import java.util.ArrayList; |
22 import java.util.ArrayList; |
28 import java.util.NoSuchElementException; |
|
29 import java.util.StringTokenizer; |
|
30 import java.util.Vector; |
23 import java.util.Vector; |
31 |
24 |
32 import com.sun.org.apache.bcel.internal.classfile.Field; |
25 import com.sun.org.apache.bcel.internal.classfile.Field; |
33 import com.sun.org.apache.bcel.internal.classfile.Method; |
|
34 import com.sun.org.apache.bcel.internal.generic.ALOAD; |
26 import com.sun.org.apache.bcel.internal.generic.ALOAD; |
35 import com.sun.org.apache.bcel.internal.generic.ANEWARRAY; |
27 import com.sun.org.apache.bcel.internal.generic.ANEWARRAY; |
36 import com.sun.org.apache.bcel.internal.generic.ASTORE; |
28 import com.sun.org.apache.bcel.internal.generic.ASTORE; |
37 import com.sun.org.apache.bcel.internal.generic.CHECKCAST; |
29 import com.sun.org.apache.bcel.internal.generic.CHECKCAST; |
38 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; |
30 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; |
39 import com.sun.org.apache.bcel.internal.generic.GETFIELD; |
31 import com.sun.org.apache.bcel.internal.generic.GETFIELD; |
40 import com.sun.org.apache.bcel.internal.generic.ICONST; |
|
41 import com.sun.org.apache.bcel.internal.generic.ILOAD; |
32 import com.sun.org.apache.bcel.internal.generic.ILOAD; |
42 import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; |
33 import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; |
43 import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL; |
34 import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL; |
44 import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC; |
|
45 import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; |
|
46 import com.sun.org.apache.bcel.internal.generic.InstructionHandle; |
35 import com.sun.org.apache.bcel.internal.generic.InstructionHandle; |
47 import com.sun.org.apache.bcel.internal.generic.InstructionList; |
36 import com.sun.org.apache.bcel.internal.generic.InstructionList; |
48 import com.sun.org.apache.bcel.internal.generic.LocalVariableGen; |
37 import com.sun.org.apache.bcel.internal.generic.LocalVariableGen; |
49 import com.sun.org.apache.bcel.internal.generic.NEW; |
38 import com.sun.org.apache.bcel.internal.generic.NEW; |
50 import com.sun.org.apache.bcel.internal.generic.NOP; |
39 import com.sun.org.apache.bcel.internal.generic.NOP; |
74 |
63 |
75 private Expression _select; |
64 private Expression _select; |
76 private AttributeValue _order; |
65 private AttributeValue _order; |
77 private AttributeValue _caseOrder; |
66 private AttributeValue _caseOrder; |
78 private AttributeValue _dataType; |
67 private AttributeValue _dataType; |
79 private String _lang; // bug! see 26869 |
68 private String _lang; // bug! see 26869 |
80 |
|
81 private String _data = null; |
|
82 |
|
83 |
69 |
84 private String _className = null; |
70 private String _className = null; |
85 private ArrayList _closureVars = null; |
71 private ArrayList<VariableRefBase> _closureVars = null; |
86 private boolean _needsSortRecordFactory = false; |
72 private boolean _needsSortRecordFactory = false; |
87 |
73 |
88 // -- Begin Closure interface -------------------- |
74 // -- Begin Closure interface -------------------- |
89 |
75 |
90 /** |
76 /** |
113 /** |
99 /** |
114 * Add new variable to the closure. |
100 * Add new variable to the closure. |
115 */ |
101 */ |
116 public void addVariable(VariableRefBase variableRef) { |
102 public void addVariable(VariableRefBase variableRef) { |
117 if (_closureVars == null) { |
103 if (_closureVars == null) { |
118 _closureVars = new ArrayList(); |
104 _closureVars = new ArrayList<>(); |
119 } |
105 } |
120 |
106 |
121 // Only one reference per variable |
107 // Only one reference per variable |
122 if (!_closureVars.contains(variableRef)) { |
108 if (!_closureVars.contains(variableRef)) { |
123 _closureVars.add(variableRef); |
109 _closureVars.add(variableRef); |
244 * and a node sort record producing objects as its parameters. |
230 * and a node sort record producing objects as its parameters. |
245 */ |
231 */ |
246 public static void translateSortIterator(ClassGenerator classGen, |
232 public static void translateSortIterator(ClassGenerator classGen, |
247 MethodGenerator methodGen, |
233 MethodGenerator methodGen, |
248 Expression nodeSet, |
234 Expression nodeSet, |
249 Vector sortObjects) |
235 Vector<Sort> sortObjects) |
250 { |
236 { |
251 final ConstantPoolGen cpg = classGen.getConstantPool(); |
237 final ConstantPoolGen cpg = classGen.getConstantPool(); |
252 final InstructionList il = methodGen.getInstructionList(); |
238 final InstructionList il = methodGen.getInstructionList(); |
253 |
239 |
254 // SortingIterator.SortingIterator(NodeIterator,NodeSortRecordFactory); |
240 // SortingIterator.SortingIterator(NodeIterator,NodeSortRecordFactory); |
310 |
296 |
311 /** |
297 /** |
312 * Compiles code that instantiates a NodeSortRecordFactory object which |
298 * Compiles code that instantiates a NodeSortRecordFactory object which |
313 * will produce NodeSortRecord objects of a specific type. |
299 * will produce NodeSortRecord objects of a specific type. |
314 */ |
300 */ |
315 public static void compileSortRecordFactory(Vector sortObjects, |
301 public static void compileSortRecordFactory(Vector<Sort> sortObjects, |
316 ClassGenerator classGen, MethodGenerator methodGen) |
302 ClassGenerator classGen, MethodGenerator methodGen) |
317 { |
303 { |
318 String sortRecordClass = |
304 String sortRecordClass = |
319 compileSortRecord(sortObjects, classGen, methodGen); |
305 compileSortRecord(sortObjects, classGen, methodGen); |
320 |
306 |
321 boolean needsSortRecordFactory = false; |
307 boolean needsSortRecordFactory = false; |
322 final int nsorts = sortObjects.size(); |
308 final int nsorts = sortObjects.size(); |
323 for (int i = 0; i < nsorts; i++) { |
309 for (int i = 0; i < nsorts; i++) { |
324 final Sort sort = (Sort) sortObjects.elementAt(i); |
310 final Sort sort = sortObjects.elementAt(i); |
325 needsSortRecordFactory |= sort._needsSortRecordFactory; |
311 needsSortRecordFactory |= sort._needsSortRecordFactory; |
326 } |
312 } |
327 |
313 |
328 String sortRecordFactoryClass = NODE_SORT_FACTORY; |
314 String sortRecordFactoryClass = NODE_SORT_FACTORY; |
329 if (needsSortRecordFactory) { |
315 if (needsSortRecordFactory) { |
427 + "[" + STRING_SIG |
413 + "[" + STRING_SIG |
428 + "[" + STRING_SIG |
414 + "[" + STRING_SIG |
429 + "[" + STRING_SIG + ")V"))); |
415 + "[" + STRING_SIG + ")V"))); |
430 |
416 |
431 // Initialize closure variables in sortRecordFactory |
417 // Initialize closure variables in sortRecordFactory |
432 final ArrayList dups = new ArrayList(); |
418 final ArrayList<VariableRefBase> dups = new ArrayList<>(); |
433 |
419 |
434 for (int j = 0; j < nsorts; j++) { |
420 for (int j = 0; j < nsorts; j++) { |
435 final Sort sort = (Sort) sortObjects.get(j); |
421 final Sort sort = (Sort) sortObjects.get(j); |
436 final int length = (sort._closureVars == null) ? 0 : |
422 final int length = (sort._closureVars == null) ? 0 : |
437 sort._closureVars.size(); |
423 sort._closureVars.size(); |
438 |
424 |
439 for (int i = 0; i < length; i++) { |
425 for (int i = 0; i < length; i++) { |
440 VariableRefBase varRef = (VariableRefBase) sort._closureVars.get(i); |
426 VariableRefBase varRef = sort._closureVars.get(i); |
441 |
427 |
442 // Discard duplicate variable references |
428 // Discard duplicate variable references |
443 if (dups.contains(varRef)) continue; |
429 if (dups.contains(varRef)) continue; |
444 |
430 |
445 final VariableBase var = varRef.getVariable(); |
431 final VariableBase var = varRef.getVariable(); |
453 dups.add(varRef); |
439 dups.add(varRef); |
454 } |
440 } |
455 } |
441 } |
456 } |
442 } |
457 |
443 |
458 public static String compileSortRecordFactory(Vector sortObjects, |
444 public static String compileSortRecordFactory(Vector<Sort> sortObjects, |
459 ClassGenerator classGen, MethodGenerator methodGen, |
445 ClassGenerator classGen, MethodGenerator methodGen, |
460 String sortRecordClass) |
446 String sortRecordClass) |
461 { |
447 { |
462 final XSLTC xsltc = ((Sort)sortObjects.firstElement()).getXSLTC(); |
448 final XSLTC xsltc = (sortObjects.firstElement()).getXSLTC(); |
463 final String className = xsltc.getHelperClassName(); |
449 final String className = xsltc.getHelperClassName(); |
464 |
450 |
465 final NodeSortRecordFactGenerator sortRecordFactory = |
451 final NodeSortRecordFactGenerator sortRecordFactory = |
466 new NodeSortRecordFactGenerator(className, |
452 new NodeSortRecordFactGenerator(className, |
467 NODE_SORT_FACTORY, |
453 NODE_SORT_FACTORY, |
472 |
458 |
473 ConstantPoolGen cpg = sortRecordFactory.getConstantPool(); |
459 ConstantPoolGen cpg = sortRecordFactory.getConstantPool(); |
474 |
460 |
475 // Add a new instance variable for each var in closure |
461 // Add a new instance variable for each var in closure |
476 final int nsorts = sortObjects.size(); |
462 final int nsorts = sortObjects.size(); |
477 final ArrayList dups = new ArrayList(); |
463 final ArrayList<VariableRefBase> dups = new ArrayList<>(); |
478 |
464 |
479 for (int j = 0; j < nsorts; j++) { |
465 for (int j = 0; j < nsorts; j++) { |
480 final Sort sort = (Sort) sortObjects.get(j); |
466 final Sort sort = sortObjects.get(j); |
481 final int length = (sort._closureVars == null) ? 0 : |
467 final int length = (sort._closureVars == null) ? 0 : |
482 sort._closureVars.size(); |
468 sort._closureVars.size(); |
483 |
469 |
484 for (int i = 0; i < length; i++) { |
470 for (int i = 0; i < length; i++) { |
485 final VariableRefBase varRef = (VariableRefBase) sort._closureVars.get(i); |
471 final VariableRefBase varRef = sort._closureVars.get(i); |
486 |
472 |
487 // Discard duplicate variable references |
473 // Discard duplicate variable references |
488 if (dups.contains(varRef)) continue; |
474 if (dups.contains(varRef)) continue; |
489 |
475 |
490 final VariableBase var = varRef.getVariable(); |
476 final VariableBase var = varRef.getVariable(); |
598 } |
584 } |
599 |
585 |
600 /** |
586 /** |
601 * Create a new auxillary class extending NodeSortRecord. |
587 * Create a new auxillary class extending NodeSortRecord. |
602 */ |
588 */ |
603 private static String compileSortRecord(Vector sortObjects, |
589 private static String compileSortRecord(Vector<Sort> sortObjects, |
604 ClassGenerator classGen, |
590 ClassGenerator classGen, |
605 MethodGenerator methodGen) { |
591 MethodGenerator methodGen) { |
606 final XSLTC xsltc = ((Sort)sortObjects.firstElement()).getXSLTC(); |
592 final XSLTC xsltc = sortObjects.firstElement().getXSLTC(); |
607 final String className = xsltc.getHelperClassName(); |
593 final String className = xsltc.getHelperClassName(); |
608 |
594 |
609 // This generates a new class for handling this specific sort |
595 // This generates a new class for handling this specific sort |
610 final NodeSortRecordGenerator sortRecord = |
596 final NodeSortRecordGenerator sortRecord = |
611 new NodeSortRecordGenerator(className, |
597 new NodeSortRecordGenerator(className, |
617 |
603 |
618 final ConstantPoolGen cpg = sortRecord.getConstantPool(); |
604 final ConstantPoolGen cpg = sortRecord.getConstantPool(); |
619 |
605 |
620 // Add a new instance variable for each var in closure |
606 // Add a new instance variable for each var in closure |
621 final int nsorts = sortObjects.size(); |
607 final int nsorts = sortObjects.size(); |
622 final ArrayList dups = new ArrayList(); |
608 final ArrayList<VariableRefBase> dups = new ArrayList<>(); |
623 |
609 |
624 for (int j = 0; j < nsorts; j++) { |
610 for (int j = 0; j < nsorts; j++) { |
625 final Sort sort = (Sort) sortObjects.get(j); |
611 final Sort sort = sortObjects.get(j); |
626 |
612 |
627 // Set the name of the inner class in this sort object |
613 // Set the name of the inner class in this sort object |
628 sort.setInnerClassName(className); |
614 sort.setInnerClassName(className); |
629 |
615 |
630 final int length = (sort._closureVars == null) ? 0 : |
616 final int length = (sort._closureVars == null) ? 0 : |
642 null, cpg.getConstantPool())); |
628 null, cpg.getConstantPool())); |
643 dups.add(varRef); |
629 dups.add(varRef); |
644 } |
630 } |
645 } |
631 } |
646 |
632 |
647 MethodGenerator init = compileInit(sortObjects, sortRecord, |
633 MethodGenerator init = compileInit(sortRecord, cpg, className); |
648 cpg, className); |
|
649 MethodGenerator extract = compileExtract(sortObjects, sortRecord, |
634 MethodGenerator extract = compileExtract(sortObjects, sortRecord, |
650 cpg, className); |
635 cpg, className); |
651 sortRecord.addMethod(init); |
636 sortRecord.addMethod(init); |
652 sortRecord.addMethod(extract); |
637 sortRecord.addMethod(extract); |
653 |
638 |
658 /** |
643 /** |
659 * Create a constructor for the new class. Updates the reference to the |
644 * Create a constructor for the new class. Updates the reference to the |
660 * collator in the super calls only when the stylesheet specifies a new |
645 * collator in the super calls only when the stylesheet specifies a new |
661 * language in xsl:sort. |
646 * language in xsl:sort. |
662 */ |
647 */ |
663 private static MethodGenerator compileInit(Vector sortObjects, |
648 private static MethodGenerator compileInit(NodeSortRecordGenerator sortRecord, |
664 NodeSortRecordGenerator sortRecord, |
|
665 ConstantPoolGen cpg, |
649 ConstantPoolGen cpg, |
666 String className) |
650 String className) |
667 { |
651 { |
668 final InstructionList il = new InstructionList(); |
652 final InstructionList il = new InstructionList(); |
669 final MethodGenerator init = |
653 final MethodGenerator init = |
728 } |
712 } |
729 |
713 |
730 // Append all the cases for the switch statment |
714 // Append all the cases for the switch statment |
731 for (int level = 0; level < levels; level++) { |
715 for (int level = 0; level < levels; level++) { |
732 match[level] = level; |
716 match[level] = level; |
733 final Sort sort = (Sort)sortObjects.elementAt(level); |
717 final Sort sort = sortObjects.elementAt(level); |
734 target[level] = il.append(NOP); |
718 target[level] = il.append(NOP); |
735 sort.translateSelect(sortRecord, extractMethod); |
719 sort.translateSelect(sortRecord, extractMethod); |
736 il.append(ARETURN); |
720 il.append(ARETURN); |
737 } |
721 } |
738 |
722 |