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