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
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpeclipse.internal.compiler.ast;
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;
21 public class ArrayReference extends Reference {
23 public Expression receiver;
24 public Expression position;
26 public ArrayReference(Expression rec, Expression pos) {
29 sourceStart = rec.sourceStart;
32 public FlowInfo analyseAssignment(
33 BlockScope currentScope,
34 FlowContext flowContext,
36 Assignment assignment,
37 boolean compoundAssignment) {
39 if (assignment.expression == null) {
40 return analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
47 analyseCode(currentScope, flowContext, flowInfo).unconditionalInits())
48 .unconditionalInits();
52 public FlowInfo analyseCode(
53 BlockScope currentScope,
54 FlowContext flowContext,
57 return position.analyseCode(
60 receiver.analyseCode(currentScope, flowContext, flowInfo));
63 // public void generateAssignment(
64 // BlockScope currentScope,
65 // CodeStream codeStream,
66 // Assignment assignment,
67 // boolean valueRequired) {
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);
79 * Code generation for a array reference
81 // public void generateCode(
82 // BlockScope currentScope,
83 // CodeStream codeStream,
84 // boolean valueRequired) {
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);
94 // if (this.resolvedType == LongBinding
95 // || this.resolvedType == DoubleBinding) {
101 // codeStream.recordPositionsFrom(pc, this.sourceStart);
104 // public void generateCompoundAssignment(
105 // BlockScope currentScope,
106 // CodeStream codeStream,
107 // Expression expression,
109 // int assignmentImplicitConversion,
110 // boolean valueRequired) {
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);
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);
126 // expression.generateCode(currentScope, codeStream, true);
128 // // perform the operation
129 // codeStream.sendOperator(operator, operationTypeID);
130 // // cast the value back to the array reference type
131 // codeStream.generateImplicitConversion(assignmentImplicitConversion);
133 // codeStream.arrayAtPut(this.resolvedType.id, valueRequired);
136 // public void generatePostIncrement(
137 // BlockScope currentScope,
138 // CodeStream codeStream,
139 // CompoundAssignment postIncrement,
140 // boolean valueRequired) {
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();
151 // codeStream.dup_x2();
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);
163 public TypeBinding resolveType(BlockScope scope) {
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);
171 scope.problemReporter().referenceMustBeArrayTypeAt(arrayType, this);
174 TypeBinding positionType = position.resolveTypeExpecting(scope, IntBinding);
175 if (positionType != null) {
176 position.implicitWidening(IntBinding, positionType);
178 return this.resolvedType;
181 public String toStringExpression() {
183 return receiver.toStringExpression() + "[" //$NON-NLS-1$
184 +position.toStringExpression() + "]"; //$NON-NLS-1$
187 public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
189 if (visitor.visit(this, scope)) {
190 receiver.traverse(visitor, scope);
191 position.traverse(visitor, scope);
193 visitor.endVisit(this, scope);