code-template needs new context type
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / 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.phpeclipse.internal.compiler.ast;
12
13 import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor;
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
163         public TypeBinding resolveType(BlockScope scope) {
164
165                 constant = Constant.NotAConstant;
166                 TypeBinding arrayType = receiver.resolveType(scope);
167                 if (arrayType != null) {
168                         if (arrayType.isArrayType()) {
169                                 this.resolvedType = ((ArrayBinding) arrayType).elementsType(scope);
170                         } else {
171                                 scope.problemReporter().referenceMustBeArrayTypeAt(arrayType, this);
172                         }
173                 }
174                 TypeBinding positionType = position.resolveTypeExpecting(scope, IntBinding);
175                 if (positionType != null) {
176                         position.implicitWidening(IntBinding, positionType);
177                 }
178                 return this.resolvedType;
179         }
180
181         public String toStringExpression() {
182
183                 return receiver.toStringExpression() + "[" //$NON-NLS-1$
184                 +position.toStringExpression() + "]"; //$NON-NLS-1$
185         } 
186
187         public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
188                 
189                 if (visitor.visit(this, scope)) {
190                         receiver.traverse(visitor, scope);
191                         position.traverse(visitor, scope);
192                 }
193                 visitor.endVisit(this, scope);
194         }
195 }