1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.ast;
12 
13 import org.eclipse.jdt.internal.compiler.ASTVisitor;
14 import org.eclipse.jdt.internal.compiler.impl.*;
15 import org.eclipse.jdt.internal.compiler.codegen.*;
16 import org.eclipse.jdt.internal.compiler.lookup.*;
17 
18 public class IntLiteral extends NumberLiteral {
19 	public int value;
20 
21 	public static final IntLiteral
22 		One = new IntLiteral(new char[]{'1'},0,0,1);//used for ++ and --
23 
24 	static final Constant FORMAT_ERROR = new DoubleConstant(1.0/0.0); // NaN;
IntLiteral(char[] token, int s, int e)25 public IntLiteral(char[] token, int s, int e) {
26 	super(token, s,e);
27 }
IntLiteral(char[] token, int s,int e, int value)28 public IntLiteral(char[] token, int s,int e, int value) {
29 	this(token, s,e);
30 	this.value = value;
31 }
IntLiteral(int intValue)32 public IntLiteral(int intValue) {
33 	//special optimized constructor : the cst is the argument
34 
35 	//value that should not be used
36 	//	tokens = null ;
37 	//	sourceStart = 0;
38 	//	sourceEnd = 0;
39 	super(null,0,0);
40 	constant = Constant.fromValue(intValue);
41 	value = intValue;
42 
43 }
computeConstant()44 public void computeConstant() {
45 	//a special constant is use for the potential Integer.MAX_VALUE+1
46 	//which is legal if used with a - as prefix....cool....
47 	//notice that Integer.MIN_VALUE  == -2147483648
48 
49 	long MAX = Integer.MAX_VALUE;
50 	if (this == One) {	constant = Constant.One; return ;}
51 
52 	int length = source.length;
53 	long computedValue = 0L;
54 	if (source[0] == '0')
55 	{	MAX = 0xFFFFFFFFL ; //a long in order to be positive !
56 		if (length == 1) {	constant = Constant.fromValue(0); return ;}
57 		final int shift,radix;
58 		int j ;
59 		if ( (source[1] == 'x') || (source[1] == 'X') )
60 		{	shift = 4 ; j = 2; radix = 16;}
61 		else
62 		{	shift = 3 ; j = 1; radix = 8;}
63 		while (source[j]=='0')
64 		{	j++; //jump over redondant zero
65 			if (j == length)
66 			{	//watch for 000000000000000000
67 				constant = Constant.fromValue(value = (int)computedValue);
68 				return ;}}
69 
70 		while (j<length)
71 		{	int digitValue ;
72 			if ((digitValue = Character.digit(source[j++],radix))	< 0 )
73 			{	constant = FORMAT_ERROR; return ;}
74 			computedValue = (computedValue<<shift) | digitValue ;
75 			if (computedValue > MAX) return /*constant stays null*/ ;}}
76 	else
77 	{	//-----------regular case : radix = 10-----------
78 		for (int i = 0 ; i < length;i++)
79 		{	int digitValue ;
80 			if ((digitValue = Character.digit(source[i],10))	< 0 )
81 			{	constant = FORMAT_ERROR; return ;}
82 			computedValue = 10*computedValue + digitValue;
83 			if (computedValue > MAX) return /*constant stays null*/ ; }}
84 
85 	constant = Constant.fromValue(value = (int)computedValue);
86 
87 }
88 /**
89  * Code generation for int literal
90  *
91  * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
92  * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
93  * @param valueRequired boolean
94  */
generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired)95 public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
96 	int pc = codeStream.position;
97 	if (valueRequired)
98 		if ((implicitConversion >> 4) == T_int)
99 			codeStream.generateInlinedValue(value);
100 		else
101 			codeStream.generateConstant(constant, implicitConversion);
102 	codeStream.recordPositionsFrom(pc, this.sourceStart);
103 }
literalType(BlockScope scope)104 public TypeBinding literalType(BlockScope scope) {
105 	return IntBinding;
106 }
mayRepresentMIN_VALUE()107 public final boolean mayRepresentMIN_VALUE(){
108 	//a special autorized int literral is 2147483648
109 	//which is ONE over the limit. This special case
110 	//only is used in combinaison with - to denote
111 	//the minimal value of int -2147483648
112 
113 	return ((source.length == 10) &&
114 			(source[0] == '2') &&
115 			(source[1] == '1') &&
116 			(source[2] == '4') &&
117 			(source[3] == '7') &&
118 			(source[4] == '4') &&
119 			(source[5] == '8') &&
120 			(source[6] == '3') &&
121 			(source[7] == '6') &&
122 			(source[8] == '4') &&
123 			(source[9] == '8'));}
resolveType(BlockScope scope)124 public TypeBinding resolveType(BlockScope scope) {
125 	// the format may be incorrect while the scanner could detect
126 	// such an error only on painfull tests...easier and faster here
127 
128 	TypeBinding tb = super.resolveType(scope);
129 	if (constant == FORMAT_ERROR) {
130 		constant = NotAConstant;
131 		scope.problemReporter().constantOutOfFormat(this);
132 		this.resolvedType = null;
133 		return null;
134 	}
135 	return tb;
136 }
printExpression(int indent, StringBuffer output)137 public StringBuffer printExpression(int indent, StringBuffer output){
138 
139 	if (source == null) {
140 	/* special optimized IntLiteral that are created by the compiler */
141 		return output.append(String.valueOf(value));
142 	}
143 	return super.printExpression(indent, output);
144 }
145 
traverse(ASTVisitor visitor, BlockScope scope)146 public void traverse(ASTVisitor visitor, BlockScope scope) {
147 	visitor.visit(this, scope);
148 	visitor.endVisit(this, scope);
149 }
150 }
151