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.phpdt.internal.compiler.ast;
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;
21 public class ArrayReference extends Reference {
23 public Expression receiver;
25 public Expression position;
27 public ArrayReference(Expression rec, Expression pos) {
30 sourceStart = rec.sourceStart;
33 public FlowInfo analyseAssignment(BlockScope currentScope,
34 FlowContext flowContext, FlowInfo flowInfo, Assignment assignment,
35 boolean compoundAssignment) {
37 if (assignment.expression == null) {
38 return analyseCode(currentScope, flowContext, flowInfo)
39 .unconditionalInits();
41 return assignment.expression.analyseCode(
44 analyseCode(currentScope, flowContext, flowInfo)
45 .unconditionalInits()).unconditionalInits();
49 public FlowInfo analyseCode(BlockScope currentScope,
50 FlowContext flowContext, FlowInfo flowInfo) {
52 return position.analyseCode(currentScope, flowContext, receiver
53 .analyseCode(currentScope, flowContext, flowInfo));
56 // public void generateAssignment(
57 // BlockScope currentScope,
58 // CodeStream codeStream,
59 // Assignment assignment,
60 // boolean valueRequired) {
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);
72 * Code generation for a array reference
74 // public void generateCode(
75 // BlockScope currentScope,
76 // CodeStream codeStream,
77 // boolean valueRequired) {
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);
87 // if (this.resolvedType == LongBinding
88 // || this.resolvedType == DoubleBinding) {
94 // codeStream.recordPositionsFrom(pc, this.sourceStart);
97 // public void generateCompoundAssignment(
98 // BlockScope currentScope,
99 // CodeStream codeStream,
100 // Expression expression,
102 // int assignmentImplicitConversion,
103 // boolean valueRequired) {
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);
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
117 // if (expression == IntLiteral.One) { // prefix operation
118 // codeStream.generateConstant(expression.constant, implicitConversion);
120 // expression.generateCode(currentScope, codeStream, true);
122 // // perform the operation
123 // codeStream.sendOperator(operator, operationTypeID);
124 // // cast the value back to the array reference type
125 // codeStream.generateImplicitConversion(assignmentImplicitConversion);
127 // codeStream.arrayAtPut(this.resolvedType.id, valueRequired);
130 // public void generatePostIncrement(
131 // BlockScope currentScope,
132 // CodeStream codeStream,
133 // CompoundAssignment postIncrement,
134 // boolean valueRequired) {
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();
145 // codeStream.dup_x2();
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);
156 public StringBuffer printExpression(int indent, StringBuffer output) {
158 receiver.printExpression(0, output).append('[');
159 return position.printExpression(0, output).append(']');
162 public TypeBinding resolveType(BlockScope scope) {
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);
171 scope.problemReporter().referenceMustBeArrayTypeAt(arrayType,
175 TypeBinding positionType = position.resolveTypeExpecting(scope,
177 if (positionType != null) {
178 position.implicitWidening(IntBinding, positionType);
180 return this.resolvedType;
183 public String toStringExpression() {
185 return receiver.toStringExpression() + "[" //$NON-NLS-1$
186 + position.toStringExpression() + "]"; //$NON-NLS-1$
189 public void traverse(ASTVisitor visitor, BlockScope scope) {
191 if (visitor.visit(this, scope)) {
192 receiver.traverse(visitor, scope);
193 position.traverse(visitor, scope);
195 visitor.endVisit(this, scope);