347 return new BooleanLiteralNode(parent.getToken(), parent.getFinish(), value);
348 }
349
350 @Immutable
351 private static final class NumberLiteralNode extends PrimitiveLiteralNode<Number> {
352 private static final long serialVersionUID = 1L;
353
354 private final Type type = numberGetType(value);
355
356 private NumberLiteralNode(final long token, final int finish, final Number value) {
357 super(Token.recast(token, TokenType.DECIMAL), finish, value);
358 }
359
360 private NumberLiteralNode(final NumberLiteralNode literalNode) {
361 super(literalNode);
362 }
363
364 private static Type numberGetType(final Number number) {
365 if (number instanceof Integer) {
366 return Type.INT;
367 } else if (number instanceof Long) {
368 return Type.LONG;
369 } else if (number instanceof Double) {
370 return Type.NUMBER;
371 } else {
372 assert false;
373 }
374
375 return null;
376 }
377
378 @Override
379 public Type getType() {
380 return type;
381 }
382
383 @Override
384 public Type getWidestOperationType() {
385 return getType();
386 }
387
388 }
389 /**
390 * Create a new number literal
391 *
392 * @param token token
393 * @param finish finish
394 * @param value literal value
395 *
396 * @return the new literal node
397 */
398 public static LiteralNode<Number> newInstance(final long token, final int finish, final Number value) {
399 return new NumberLiteralNode(token, finish, value);
400 }
401
402 /**
403 * Create a new number literal based on a parent node (source, token, finish)
404 *
405 * @param parent parent node
406 * @param value literal value
407 *
408 * @return the new literal node
409 */
410 public static LiteralNode<?> newInstance(final Node parent, final Number value) {
411 return new NumberLiteralNode(parent.getToken(), parent.getFinish(), value);
412 }
413
414 private static class UndefinedLiteralNode extends PrimitiveLiteralNode<Undefined> {
415 private static final long serialVersionUID = 1L;
416
417 private UndefinedLiteralNode(final long token, final int finish) {
418 super(Token.recast(token, TokenType.OBJECT), finish, ScriptRuntime.UNDEFINED);
731 assert postsets[nComputed++] == i;
732 continue;
733 }
734 final Object element = objectAsConstant(node);
735
736 if (element != POSTSET_MARKER) {
737 array[i] = element;
738 } else {
739 assert postsets[nComputed++] == i;
740 }
741 }
742
743 assert postsets.length == nComputed;
744 return array;
745 }
746
747 static Object computePresets(final Expression[] value, final Type elementType, final int[] postsets) {
748 assert !elementType.isUnknown();
749 if (elementType.isInteger()) {
750 return presetIntArray(value, postsets);
751 } else if (elementType.isLong()) {
752 return presetLongArray(value, postsets);
753 } else if (elementType.isNumeric()) {
754 return presetDoubleArray(value, postsets);
755 } else {
756 return presetObjectArray(value, postsets);
757 }
758 }
759 }
760
761 /**
762 * Constructor
763 *
764 * @param token token
765 * @param finish finish
766 * @param value array literal value, a Node array
767 */
768 protected ArrayLiteralNode(final long token, final int finish, final Expression[] value) {
769 super(Token.recast(token, TokenType.ARRAY), finish, value);
770 this.elementType = Type.UNKNOWN;
771 this.presets = null;
772 this.postsets = null;
801 *
802 * @param lc lexical context
803 * @return new array literal node with postsets, presets and element types initialized
804 */
805 @Override
806 public ArrayLiteralNode initialize(final LexicalContext lc) {
807 return Node.replaceInLexicalContext(lc, this, ArrayLiteralInitializer.initialize(this));
808 }
809
810 /**
811 * Get the array element type as Java format, e.g. [I
812 * @return array element type
813 */
814 public ArrayType getArrayType() {
815 return getArrayType(getElementType());
816 }
817
818 private static ArrayType getArrayType(final Type elementType) {
819 if (elementType.isInteger()) {
820 return Type.INT_ARRAY;
821 } else if (elementType.isLong()) {
822 return Type.LONG_ARRAY;
823 } else if (elementType.isNumeric()) {
824 return Type.NUMBER_ARRAY;
825 } else {
826 return Type.OBJECT_ARRAY;
827 }
828 }
829
830 @Override
831 public Type getType() {
832 return Type.typeFor(NativeArray.class);
833 }
834
835 /**
836 * Get the element type of this array literal
837 * @return element type
838 */
839 public Type getElementType() {
840 assert !elementType.isUnknown() : this + " has elementType=unknown";
841 return elementType;
842 }
843
844 /**
845 * Get indices of arrays containing computed post sets. post sets
846 * are things like non literals e.g. "x+y" instead of i or 17
847 * @return post set indices
848 */
849 public int[] getPostsets() {
850 assert postsets != null : this + " elementType=" + elementType + " has no postsets";
851 return postsets;
852 }
853
854 private boolean presetsMatchElementType() {
855 if (elementType == Type.INT) {
856 return presets instanceof int[];
857 } else if (elementType == Type.LONG) {
858 return presets instanceof long[];
859 } else if (elementType == Type.NUMBER) {
860 return presets instanceof double[];
861 } else {
862 return presets instanceof Object[];
863 }
864 }
865
866 /**
867 * Get presets constant array
868 * @return presets array, always returns an array type
869 */
870 public Object getPresets() {
871 assert presets != null && presetsMatchElementType() : this + " doesn't have presets, or invalid preset type: " + presets;
872 return presets;
873 }
874
875 /**
876 * Get the split ranges for this ArrayLiteral, or null if this array does not have to be split.
877 * @see Splittable.SplitRange
878 * @return list of split ranges
|
347 return new BooleanLiteralNode(parent.getToken(), parent.getFinish(), value);
348 }
349
350 @Immutable
351 private static final class NumberLiteralNode extends PrimitiveLiteralNode<Number> {
352 private static final long serialVersionUID = 1L;
353
354 private final Type type = numberGetType(value);
355
356 private NumberLiteralNode(final long token, final int finish, final Number value) {
357 super(Token.recast(token, TokenType.DECIMAL), finish, value);
358 }
359
360 private NumberLiteralNode(final NumberLiteralNode literalNode) {
361 super(literalNode);
362 }
363
364 private static Type numberGetType(final Number number) {
365 if (number instanceof Integer) {
366 return Type.INT;
367 } else if (number instanceof Double) {
368 return Type.NUMBER;
369 } else {
370 assert false;
371 }
372
373 return null;
374 }
375
376 @Override
377 public Type getType() {
378 return type;
379 }
380
381 @Override
382 public Type getWidestOperationType() {
383 return getType();
384 }
385
386 }
387 /**
388 * Create a new number literal
389 *
390 * @param token token
391 * @param finish finish
392 * @param value literal value
393 *
394 * @return the new literal node
395 */
396 public static LiteralNode<Number> newInstance(final long token, final int finish, final Number value) {
397 assert !(value instanceof Long);
398 return new NumberLiteralNode(token, finish, value);
399 }
400
401 /**
402 * Create a new number literal based on a parent node (source, token, finish)
403 *
404 * @param parent parent node
405 * @param value literal value
406 *
407 * @return the new literal node
408 */
409 public static LiteralNode<?> newInstance(final Node parent, final Number value) {
410 return new NumberLiteralNode(parent.getToken(), parent.getFinish(), value);
411 }
412
413 private static class UndefinedLiteralNode extends PrimitiveLiteralNode<Undefined> {
414 private static final long serialVersionUID = 1L;
415
416 private UndefinedLiteralNode(final long token, final int finish) {
417 super(Token.recast(token, TokenType.OBJECT), finish, ScriptRuntime.UNDEFINED);
730 assert postsets[nComputed++] == i;
731 continue;
732 }
733 final Object element = objectAsConstant(node);
734
735 if (element != POSTSET_MARKER) {
736 array[i] = element;
737 } else {
738 assert postsets[nComputed++] == i;
739 }
740 }
741
742 assert postsets.length == nComputed;
743 return array;
744 }
745
746 static Object computePresets(final Expression[] value, final Type elementType, final int[] postsets) {
747 assert !elementType.isUnknown();
748 if (elementType.isInteger()) {
749 return presetIntArray(value, postsets);
750 } else if (elementType.isNumeric()) {
751 return presetDoubleArray(value, postsets);
752 } else {
753 return presetObjectArray(value, postsets);
754 }
755 }
756 }
757
758 /**
759 * Constructor
760 *
761 * @param token token
762 * @param finish finish
763 * @param value array literal value, a Node array
764 */
765 protected ArrayLiteralNode(final long token, final int finish, final Expression[] value) {
766 super(Token.recast(token, TokenType.ARRAY), finish, value);
767 this.elementType = Type.UNKNOWN;
768 this.presets = null;
769 this.postsets = null;
798 *
799 * @param lc lexical context
800 * @return new array literal node with postsets, presets and element types initialized
801 */
802 @Override
803 public ArrayLiteralNode initialize(final LexicalContext lc) {
804 return Node.replaceInLexicalContext(lc, this, ArrayLiteralInitializer.initialize(this));
805 }
806
807 /**
808 * Get the array element type as Java format, e.g. [I
809 * @return array element type
810 */
811 public ArrayType getArrayType() {
812 return getArrayType(getElementType());
813 }
814
815 private static ArrayType getArrayType(final Type elementType) {
816 if (elementType.isInteger()) {
817 return Type.INT_ARRAY;
818 } else if (elementType.isNumeric()) {
819 return Type.NUMBER_ARRAY;
820 } else {
821 return Type.OBJECT_ARRAY;
822 }
823 }
824
825 @Override
826 public Type getType() {
827 return Type.typeFor(NativeArray.class);
828 }
829
830 /**
831 * Get the element type of this array literal
832 * @return element type
833 */
834 public Type getElementType() {
835 assert !elementType.isUnknown() : this + " has elementType=unknown";
836 return elementType;
837 }
838
839 /**
840 * Get indices of arrays containing computed post sets. post sets
841 * are things like non literals e.g. "x+y" instead of i or 17
842 * @return post set indices
843 */
844 public int[] getPostsets() {
845 assert postsets != null : this + " elementType=" + elementType + " has no postsets";
846 return postsets;
847 }
848
849 private boolean presetsMatchElementType() {
850 if (elementType == Type.INT) {
851 return presets instanceof int[];
852 } else if (elementType == Type.NUMBER) {
853 return presets instanceof double[];
854 } else {
855 return presets instanceof Object[];
856 }
857 }
858
859 /**
860 * Get presets constant array
861 * @return presets array, always returns an array type
862 */
863 public Object getPresets() {
864 assert presets != null && presetsMatchElementType() : this + " doesn't have presets, or invalid preset type: " + presets;
865 return presets;
866 }
867
868 /**
869 * Get the split ranges for this ArrayLiteral, or null if this array does not have to be split.
870 * @see Splittable.SplitRange
871 * @return list of split ranges
|