369 return new BooleanLiteralNode(parent.getToken(), parent.getFinish(), value);
370 }
371
372 @Immutable
373 private static final class NumberLiteralNode extends PrimitiveLiteralNode<Number> {
374 private static final long serialVersionUID = 1L;
375
376 private final Type type = numberGetType(value);
377
378 private NumberLiteralNode(final long token, final int finish, final Number value) {
379 super(Token.recast(token, TokenType.DECIMAL), finish, value);
380 }
381
382 private NumberLiteralNode(final NumberLiteralNode literalNode) {
383 super(literalNode);
384 }
385
386 private static Type numberGetType(final Number number) {
387 if (number instanceof Integer) {
388 return Type.INT;
389 } else if (number instanceof Long) {
390 return Type.LONG;
391 } else if (number instanceof Double) {
392 return Type.NUMBER;
393 } else {
394 assert false;
395 }
396
397 return null;
398 }
399
400 @Override
401 public Type getType() {
402 return type;
403 }
404
405 @Override
406 public Type getWidestOperationType() {
407 return getType();
408 }
409
410 }
411 /**
412 * Create a new number literal
413 *
414 * @param token token
415 * @param finish finish
416 * @param value literal value
417 *
418 * @return the new literal node
419 */
420 public static LiteralNode<Number> newInstance(final long token, final int finish, final Number value) {
421 return new NumberLiteralNode(token, finish, value);
422 }
423
424 /**
425 * Create a new number literal based on a parent node (source, token, finish)
426 *
427 * @param parent parent node
428 * @param value literal value
429 *
430 * @return the new literal node
431 */
432 public static LiteralNode<?> newInstance(final Node parent, final Number value) {
433 return new NumberLiteralNode(parent.getToken(), parent.getFinish(), value);
434 }
435
436 private static class UndefinedLiteralNode extends PrimitiveLiteralNode<Undefined> {
437 private static final long serialVersionUID = 1L;
438
439 private UndefinedLiteralNode(final long token, final int finish) {
440 super(Token.recast(token, TokenType.OBJECT), finish, ScriptRuntime.UNDEFINED);
759 assert postsets[nComputed++] == i;
760 continue;
761 }
762 final Object element = objectAsConstant(node);
763
764 if (element != POSTSET_MARKER) {
765 array[i] = element;
766 } else {
767 assert postsets[nComputed++] == i;
768 }
769 }
770
771 assert postsets.length == nComputed;
772 return array;
773 }
774
775 static Object computePresets(final Expression[] value, final Type elementType, final int[] postsets) {
776 assert !elementType.isUnknown();
777 if (elementType.isInteger()) {
778 return presetIntArray(value, postsets);
779 } else if (elementType.isLong()) {
780 return presetLongArray(value, postsets);
781 } else if (elementType.isNumeric()) {
782 return presetDoubleArray(value, postsets);
783 } else {
784 return presetObjectArray(value, postsets);
785 }
786 }
787 }
788
789 /**
790 * Constructor
791 *
792 * @param token token
793 * @param finish finish
794 * @param value array literal value, a Node array
795 */
796 protected ArrayLiteralNode(final long token, final int finish, final Expression[] value) {
797 super(Token.recast(token, TokenType.ARRAY), finish, value);
798 this.elementType = Type.UNKNOWN;
799 this.presets = null;
800 this.postsets = null;
830 *
831 * @param lc lexical context
832 * @return new array literal node with postsets, presets and element types initialized
833 */
834 @Override
835 public ArrayLiteralNode initialize(final LexicalContext lc) {
836 return Node.replaceInLexicalContext(lc, this, ArrayLiteralInitializer.initialize(this));
837 }
838
839 /**
840 * Get the array element type as Java format, e.g. [I
841 * @return array element type
842 */
843 public ArrayType getArrayType() {
844 return getArrayType(getElementType());
845 }
846
847 private static ArrayType getArrayType(final Type elementType) {
848 if (elementType.isInteger()) {
849 return Type.INT_ARRAY;
850 } else if (elementType.isLong()) {
851 return Type.LONG_ARRAY;
852 } else if (elementType.isNumeric()) {
853 return Type.NUMBER_ARRAY;
854 } else {
855 return Type.OBJECT_ARRAY;
856 }
857 }
858
859 @Override
860 public Type getType() {
861 return Type.typeFor(NativeArray.class);
862 }
863
864 /**
865 * Get the element type of this array literal
866 * @return element type
867 */
868 public Type getElementType() {
869 assert !elementType.isUnknown() : this + " has elementType=unknown";
870 return elementType;
871 }
872
873 /**
874 * Get indices of arrays containing computed post sets. post sets
875 * are things like non literals e.g. "x+y" instead of i or 17
876 * @return post set indices
877 */
878 public int[] getPostsets() {
879 assert postsets != null : this + " elementType=" + elementType + " has no postsets";
880 return postsets;
881 }
882
883 private boolean presetsMatchElementType() {
884 if (elementType == Type.INT) {
885 return presets instanceof int[];
886 } else if (elementType == Type.LONG) {
887 return presets instanceof long[];
888 } else if (elementType == Type.NUMBER) {
889 return presets instanceof double[];
890 } else {
891 return presets instanceof Object[];
892 }
893 }
894
895 /**
896 * Get presets constant array
897 * @return presets array, always returns an array type
898 */
899 public Object getPresets() {
900 assert presets != null && presetsMatchElementType() : this + " doesn't have presets, or invalid preset type: " + presets;
901 return presets;
902 }
903
904 /**
905 * Get the split ranges for this ArrayLiteral, or null if this array does not have to be split.
906 * @see Splittable.SplitRange
907 * @return list of split ranges
|
369 return new BooleanLiteralNode(parent.getToken(), parent.getFinish(), value);
370 }
371
372 @Immutable
373 private static final class NumberLiteralNode extends PrimitiveLiteralNode<Number> {
374 private static final long serialVersionUID = 1L;
375
376 private final Type type = numberGetType(value);
377
378 private NumberLiteralNode(final long token, final int finish, final Number value) {
379 super(Token.recast(token, TokenType.DECIMAL), finish, value);
380 }
381
382 private NumberLiteralNode(final NumberLiteralNode literalNode) {
383 super(literalNode);
384 }
385
386 private static Type numberGetType(final Number number) {
387 if (number instanceof Integer) {
388 return Type.INT;
389 } else if (number instanceof Double) {
390 return Type.NUMBER;
391 } else {
392 assert false;
393 }
394
395 return null;
396 }
397
398 @Override
399 public Type getType() {
400 return type;
401 }
402
403 @Override
404 public Type getWidestOperationType() {
405 return getType();
406 }
407
408 }
409 /**
410 * Create a new number literal
411 *
412 * @param token token
413 * @param finish finish
414 * @param value literal value
415 *
416 * @return the new literal node
417 */
418 public static LiteralNode<Number> newInstance(final long token, final int finish, final Number value) {
419 assert !(value instanceof Long);
420 return new NumberLiteralNode(token, finish, value);
421 }
422
423 /**
424 * Create a new number literal based on a parent node (source, token, finish)
425 *
426 * @param parent parent node
427 * @param value literal value
428 *
429 * @return the new literal node
430 */
431 public static LiteralNode<?> newInstance(final Node parent, final Number value) {
432 return new NumberLiteralNode(parent.getToken(), parent.getFinish(), value);
433 }
434
435 private static class UndefinedLiteralNode extends PrimitiveLiteralNode<Undefined> {
436 private static final long serialVersionUID = 1L;
437
438 private UndefinedLiteralNode(final long token, final int finish) {
439 super(Token.recast(token, TokenType.OBJECT), finish, ScriptRuntime.UNDEFINED);
758 assert postsets[nComputed++] == i;
759 continue;
760 }
761 final Object element = objectAsConstant(node);
762
763 if (element != POSTSET_MARKER) {
764 array[i] = element;
765 } else {
766 assert postsets[nComputed++] == i;
767 }
768 }
769
770 assert postsets.length == nComputed;
771 return array;
772 }
773
774 static Object computePresets(final Expression[] value, final Type elementType, final int[] postsets) {
775 assert !elementType.isUnknown();
776 if (elementType.isInteger()) {
777 return presetIntArray(value, postsets);
778 } else if (elementType.isNumeric()) {
779 return presetDoubleArray(value, postsets);
780 } else {
781 return presetObjectArray(value, postsets);
782 }
783 }
784 }
785
786 /**
787 * Constructor
788 *
789 * @param token token
790 * @param finish finish
791 * @param value array literal value, a Node array
792 */
793 protected ArrayLiteralNode(final long token, final int finish, final Expression[] value) {
794 super(Token.recast(token, TokenType.ARRAY), finish, value);
795 this.elementType = Type.UNKNOWN;
796 this.presets = null;
797 this.postsets = null;
827 *
828 * @param lc lexical context
829 * @return new array literal node with postsets, presets and element types initialized
830 */
831 @Override
832 public ArrayLiteralNode initialize(final LexicalContext lc) {
833 return Node.replaceInLexicalContext(lc, this, ArrayLiteralInitializer.initialize(this));
834 }
835
836 /**
837 * Get the array element type as Java format, e.g. [I
838 * @return array element type
839 */
840 public ArrayType getArrayType() {
841 return getArrayType(getElementType());
842 }
843
844 private static ArrayType getArrayType(final Type elementType) {
845 if (elementType.isInteger()) {
846 return Type.INT_ARRAY;
847 } else if (elementType.isNumeric()) {
848 return Type.NUMBER_ARRAY;
849 } else {
850 return Type.OBJECT_ARRAY;
851 }
852 }
853
854 @Override
855 public Type getType() {
856 return Type.typeFor(NativeArray.class);
857 }
858
859 /**
860 * Get the element type of this array literal
861 * @return element type
862 */
863 public Type getElementType() {
864 assert !elementType.isUnknown() : this + " has elementType=unknown";
865 return elementType;
866 }
867
868 /**
869 * Get indices of arrays containing computed post sets. post sets
870 * are things like non literals e.g. "x+y" instead of i or 17
871 * @return post set indices
872 */
873 public int[] getPostsets() {
874 assert postsets != null : this + " elementType=" + elementType + " has no postsets";
875 return postsets;
876 }
877
878 private boolean presetsMatchElementType() {
879 if (elementType == Type.INT) {
880 return presets instanceof int[];
881 } else if (elementType == Type.NUMBER) {
882 return presets instanceof double[];
883 } else {
884 return presets instanceof Object[];
885 }
886 }
887
888 /**
889 * Get presets constant array
890 * @return presets array, always returns an array type
891 */
892 public Object getPresets() {
893 assert presets != null && presetsMatchElementType() : this + " doesn't have presets, or invalid preset type: " + presets;
894 return presets;
895 }
896
897 /**
898 * Get the split ranges for this ArrayLiteral, or null if this array does not have to be split.
899 * @see Splittable.SplitRange
900 * @return list of split ranges
|