Fix #1501248 - Parser error in new self::$_class()
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / ast / ArrayReference.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 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 net.sourceforge.phpdt.internal.compiler.ast;
12
13 import net.sourceforge.phpdt.internal.compiler.ASTVisitor;
14 import net.sourceforge.phpdt.internal.compiler.flow.FlowContext;
15 import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo;
16 import net.sourceforge.phpdt.internal.compiler.impl.Constant;
17 import net.sourceforge.phpdt.internal.compiler.lookup.ArrayBinding;
18 import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
19 import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding;
20
21 public class ArrayReference extends Reference {
22
23         public Expression receiver;
24
25         public Expression position;
26
27         public ArrayReference(Expression rec, Expression pos) {
28                 this.receiver = rec;
29                 this.position = pos;
30                 sourceStart = rec.sourceStart;
31         }
32
33         public FlowInfo analyseAssignment(BlockScope currentScope,
34                         FlowContext flowContext, FlowInfo flowInfo, Assignment assignment,
35                         boolean compoundAssignment) {
36
37                 if (assignment.expression == null) {
38                         return analyseCode(currentScope, flowContext, flowInfo)
39                                         .unconditionalInits();
40                 } else {
41                         return assignment.expression.analyseCode(
42                                         currentScope,
43                                         flowContext,
44                                         analyseCode(currentScope, flowContext, flowInfo)
45                                                         .unconditionalInits()).unconditionalInits();
46                 }
47         }
48
49         public FlowInfo analyseCode(BlockScope currentScope,
50                         FlowContext flowContext, FlowInfo flowInfo) {
51
52                 return position.analyseCode(currentScope, flowContext, receiver
53                                 .analyseCode(currentScope, flowContext, flowInfo));
54         }
55
56         // public void generateAssignment(
57         // BlockScope currentScope,
58         // CodeStream codeStream,
59         // Assignment assignment,
60         // boolean valueRequired) {
61         //
62         // receiver.generateCode(currentScope, codeStream, true);
63         // position.generateCode(currentScope, codeStream, true);
64         // assignment.expression.generateCode(currentScope, codeStream, true);
65         // codeStream.arrayAtPut(this.resolvedType.id, valueRequired);
66         // if (valueRequired) {
67         // codeStream.generateImplicitConversion(assignment.implicitConversion);
68         // }
69         // }
70
71         /**
72          * Code generation for a array reference
73          */
74         // public void generateCode(
75         // BlockScope currentScope,
76         // CodeStream codeStream,
77         // boolean valueRequired) {
78         //
79         // int pc = codeStream.position;
80         // receiver.generateCode(currentScope, codeStream, true);
81         // position.generateCode(currentScope, codeStream, true);
82         // codeStream.arrayAt(this.resolvedType.id);
83         // // Generating code for the potential runtime type checking
84         // if (valueRequired) {
85         // codeStream.generateImplicitConversion(implicitConversion);
86         // } else {
87         // if (this.resolvedType == LongBinding
88         // || this.resolvedType == DoubleBinding) {
89         // codeStream.pop2();
90         // } else {
91         // codeStream.pop();
92         // }
93         // }
94         // codeStream.recordPositionsFrom(pc, this.sourceStart);
95         // }
96         //
97         // public void generateCompoundAssignment(
98         // BlockScope currentScope,
99         // CodeStream codeStream,
100         // Expression expression,
101         // int operator,
102         // int assignmentImplicitConversion,
103         // boolean valueRequired) {
104         //
105         // receiver.generateCode(currentScope, codeStream, true);
106         // position.generateCode(currentScope, codeStream, true);
107         // codeStream.dup2();
108         // codeStream.arrayAt(this.resolvedType.id);
109         // int operationTypeID;
110         // if ((operationTypeID = implicitConversion >> 4) == T_String) {
111         // codeStream.generateStringAppend(currentScope, null, expression);
112         // } else {
113         // // promote the array reference to the suitable operation type
114         // codeStream.generateImplicitConversion(implicitConversion);
115         // // generate the increment value (will by itself be promoted to the
116         // operation value)
117         // if (expression == IntLiteral.One) { // prefix operation
118         // codeStream.generateConstant(expression.constant, implicitConversion);
119         // } else {
120         // expression.generateCode(currentScope, codeStream, true);
121         // }
122         // // perform the operation
123         // codeStream.sendOperator(operator, operationTypeID);
124         // // cast the value back to the array reference type
125         // codeStream.generateImplicitConversion(assignmentImplicitConversion);
126         // }
127         // codeStream.arrayAtPut(this.resolvedType.id, valueRequired);
128         // }
129         //
130         // public void generatePostIncrement(
131         // BlockScope currentScope,
132         // CodeStream codeStream,
133         // CompoundAssignment postIncrement,
134         // boolean valueRequired) {
135         //
136         // receiver.generateCode(currentScope, codeStream, true);
137         // position.generateCode(currentScope, codeStream, true);
138         // codeStream.dup2();
139         // codeStream.arrayAt(this.resolvedType.id);
140         // if (valueRequired) {
141         // if ((this.resolvedType == LongBinding)
142         // || (this.resolvedType == DoubleBinding)) {
143         // codeStream.dup2_x2();
144         // } else {
145         // codeStream.dup_x2();
146         // }
147         // }
148         // codeStream.generateConstant(
149         // postIncrement.expression.constant,
150         // implicitConversion);
151         // codeStream.sendOperator(postIncrement.operator, this.resolvedType.id);
152         // codeStream.generateImplicitConversion(
153         // postIncrement.assignmentImplicitConversion);
154         // codeStream.arrayAtPut(this.resolvedType.id, false);
155         // }
156         public StringBuffer printExpression(int indent, StringBuffer output) {
157
158                 receiver.printExpression(0, output).append('[');
159                 return position.printExpression(0, output).append(']');
160         }
161
162         public TypeBinding resolveType(BlockScope scope) {
163
164                 constant = Constant.NotAConstant;
165                 TypeBinding arrayType = receiver.resolveType(scope);
166                 if (arrayType != null) {
167                         if (arrayType.isArrayType()) {
168                                 this.resolvedType = ((ArrayBinding) arrayType)
169                                                 .elementsType(scope);
170                         } else {
171                                 scope.problemReporter().referenceMustBeArrayTypeAt(arrayType,
172                                                 this);
173                         }
174                 }
175                 TypeBinding positionType = position.resolveTypeExpecting(scope,
176                                 IntBinding);
177                 if (positionType != null) {
178                         position.implicitWidening(IntBinding, positionType);
179                 }
180                 return this.resolvedType;
181         }
182
183         public String toStringExpression() {
184
185                 return receiver.toStringExpression() + "[" //$NON-NLS-1$
186                                 + position.toStringExpression() + "]"; //$NON-NLS-1$
187         }
188
189         public void traverse(ASTVisitor visitor, BlockScope scope) {
190
191                 if (visitor.visit(this, scope)) {
192                         receiver.traverse(visitor, scope);
193                         position.traverse(visitor, scope);
194                 }
195                 visitor.endVisit(this, scope);
196         }
197 }