KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > ast > LongLiteral


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-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 import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
18
19 public class LongLiteral extends NumberLiteral {
20     static final Constant FORMAT_ERROR = DoubleConstant.fromValue(1.0/0.0); // NaN;
21

22 public LongLiteral(char[] token, int s,int e) {
23     super(token, s,e);
24 }
25 public void computeConstant() {
26     //the overflow (when radix=10) is tested using the fact that
27
//the value should always grow during its computation
28
int length = source.length - 1; //minus one because the last char is 'l' or 'L'
29

30     long computedValue ;
31     if (source[0] == '0') {
32         if (length == 1) {
33             constant = LongConstant.fromValue(0L);
34             return;
35         }
36         final int shift,radix;
37         int j ;
38         if ( (source[1] == 'x') || (source[1] == 'X') ) {
39             shift = 4 ; j = 2; radix = 16;
40         } else {
41             shift = 3 ; j = 1; radix = 8;
42         }
43         int nbDigit = 0;
44         while (source[j]=='0') {
45             j++; //jump over redondant zero
46
if ( j == length) {
47                 //watch for 0000000000000L
48
constant = LongConstant.fromValue(0L);
49                 return ;
50             }
51         }
52                 
53         int digitValue ;
54         if ((digitValue = ScannerHelper.digit(source[j++],radix)) < 0 ) {
55             constant = FORMAT_ERROR; return ;
56         }
57         if (digitValue >= 8)
58             nbDigit = 4;
59         else if (digitValue >= 4)
60             nbDigit = 3;
61         else if (digitValue >= 2)
62             nbDigit = 2;
63         else
64             nbDigit = 1; //digitValue is not 0
65
computedValue = digitValue ;
66         while (j<length) {
67             if ((digitValue = ScannerHelper.digit(source[j++],radix)) < 0) {
68                 constant = FORMAT_ERROR; return ;
69             }
70             if ((nbDigit += shift) > 64)
71                 return /*constant stays null*/ ;
72             computedValue = (computedValue<<shift) | digitValue ;
73         }
74     } else {
75         //-----------case radix=10-----------------
76
long previous = 0;
77         computedValue = 0;
78         final long limit = Long.MAX_VALUE / 10; // needed to check prior to the multiplication
79
for (int i = 0 ; i < length; i++) {
80             int digitValue ;
81             if ((digitValue = ScannerHelper.digit(source[i], 10)) < 0 ) return /*constant stays null*/;
82             previous = computedValue;
83             if (computedValue > limit)
84                 return /*constant stays null*/;
85             computedValue *= 10;
86             if ((computedValue + digitValue) > Long.MAX_VALUE)
87                 return /*constant stays null*/;
88             computedValue += digitValue;
89             if (previous > computedValue)
90                 return /*constant stays null*/;
91         }
92     }
93     constant = LongConstant.fromValue(computedValue);
94 }
95 /**
96  * Code generation for long literal
97  *
98  * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
99  * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
100  * @param valueRequired boolean
101  */

102 public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
103     int pc = codeStream.position;
104     if (valueRequired) {
105         codeStream.generateConstant(constant, implicitConversion);
106     }
107     codeStream.recordPositionsFrom(pc, this.sourceStart);
108 }
109 public TypeBinding literalType(BlockScope scope) {
110     return TypeBinding.LONG;
111 }
112 public final boolean mayRepresentMIN_VALUE(){
113     //a special autorized int literral is 9223372036854775808L
114
//which is ONE over the limit. This special case
115
//only is used in combinaison with - to denote
116
//the minimal value of int -9223372036854775808L
117

118     return ((source.length == 20) &&
119             (source[0] == '9') &&
120             (source[1] == '2') &&
121             (source[2] == '2') &&
122             (source[3] == '3') &&
123             (source[4] == '3') &&
124             (source[5] == '7') &&
125             (source[6] == '2') &&
126             (source[7] == '0') &&
127             (source[8] == '3') &&
128             (source[9] == '6') &&
129             (source[10] == '8') &&
130             (source[11] == '5') &&
131             (source[12] == '4') &&
132             (source[13] == '7') &&
133             (source[14] == '7') &&
134             (source[15] == '5') &&
135             (source[16] == '8') &&
136             (source[17] == '0') &&
137             (source[18] == '8') &&
138             (((this.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) == 0));
139 }
140 public TypeBinding resolveType(BlockScope scope) {
141     // the format may be incorrect while the scanner could detect
142
// such error only on painfull tests...easier and faster here
143

144     TypeBinding tb = super.resolveType(scope);
145     if (constant == FORMAT_ERROR) {
146         constant = Constant.NotAConstant;
147         scope.problemReporter().constantOutOfFormat(this);
148         this.resolvedType = null;
149         return null;
150     }
151     return tb;
152 }
153 public void traverse(ASTVisitor visitor, BlockScope scope) {
154     visitor.visit(this, scope);
155     visitor.endVisit(this, scope);
156 }
157 }
158
Popular Tags