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.lookup.ArrayBinding;
 
  17 import net.sourceforge.phpdt.internal.compiler.lookup.BaseTypeBinding;
 
  18 import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
 
  19 import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding;
 
  21 public class ArrayInitializer extends Expression {
 
  22         public Expression[] expressions;
 
  23         public ArrayBinding binding; //the type of the { , , , }
 
  26  * ArrayInitializer constructor comment.
 
  28 public ArrayInitializer() {
 
  31 public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
 
  32         if (expressions != null) {
 
  33                 for (int i = 0, max = expressions.length; i < max; i++) {
 
  34                         flowInfo = expressions[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
 
  40  * Code generation for a array initializer
 
  42 //public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
 
  43 //      // Flatten the values and compute the dimensions, by iterating in depth into nested array initializers
 
  45 //      int pc = codeStream.position;
 
  46 //      int expressionLength = (expressions == null) ? 0: expressions.length;
 
  47 //      codeStream.generateInlinedValue(expressionLength);
 
  48 //      codeStream.newArray(currentScope, binding);
 
  49 //      if (expressions != null) {
 
  50 //              // binding is an ArrayType, so I can just deal with the dimension
 
  51 //              int elementsTypeID = binding.dimensions > 1 ? -1 : binding.leafComponentType.id;
 
  52 //              for (int i = 0; i < expressionLength; i++) {
 
  54 //                      if ((expr = expressions[i]).constant != NotAConstant) {
 
  55 //                              switch (elementsTypeID) { // filter out initializations to default values
 
  61 //                                              if (expr.constant.longValue() != 0) {
 
  63 //                                                      codeStream.generateInlinedValue(i);
 
  64 //                                                      expr.generateCode(currentScope, codeStream, true);
 
  65 //                                                      codeStream.arrayAtPut(elementsTypeID, false);
 
  70 //                                              double constantValue = expr.constant.doubleValue();
 
  71 //                                              if (constantValue == -0.0 || constantValue != 0) {
 
  73 //                                                      codeStream.generateInlinedValue(i);
 
  74 //                                                      expr.generateCode(currentScope, codeStream, true);
 
  75 //                                                      codeStream.arrayAtPut(elementsTypeID, false);
 
  79 //                                              if (expr.constant.booleanValue() != false) {
 
  81 //                                                      codeStream.generateInlinedValue(i);
 
  82 //                                                      expr.generateCode(currentScope, codeStream, true);
 
  83 //                                                      codeStream.arrayAtPut(elementsTypeID, false);
 
  87 //                                              if (!(expr instanceof NullLiteral)) {
 
  89 //                                                      codeStream.generateInlinedValue(i);
 
  90 //                                                      expr.generateCode(currentScope, codeStream, true);
 
  91 //                                                      codeStream.arrayAtPut(elementsTypeID, false);
 
  94 //                      } else if (!(expr instanceof NullLiteral)) {
 
  96 //                              codeStream.generateInlinedValue(i);
 
  97 //                              expr.generateCode(currentScope, codeStream, true);
 
  98 //                              codeStream.arrayAtPut(elementsTypeID, false);
 
 102 //      if (!valueRequired) {
 
 105 //      codeStream.recordPositionsFrom(pc, this.sourceStart);
 
 107 public TypeBinding resolveTypeExpecting(BlockScope scope, TypeBinding expectedTb) {
 
 108         // Array initializers can only occur on the right hand side of an assignment
 
 109         // expression, therefore the expected type contains the valid information
 
 110         // concerning the type that must be enforced by the elements of the array initializer.
 
 112         // this method is recursive... (the test on isArrayType is the stop case)
 
 114         constant = NotAConstant;
 
 115         if (expectedTb.isArrayType()) {
 
 116                 binding = (ArrayBinding) expectedTb;
 
 117                 if (expressions == null)
 
 119                 TypeBinding expectedElementsTb = binding.elementsType(scope);
 
 120                 if (expectedElementsTb.isBaseType()) {
 
 121                         for (int i = 0, length = expressions.length; i < length; i++) {
 
 122                                 Expression expression = expressions[i];
 
 123                                 TypeBinding expressionTb =
 
 124                                         (expression instanceof ArrayInitializer)
 
 125                                                 ? expression.resolveTypeExpecting(scope, expectedElementsTb)
 
 126                                                 : expression.resolveType(scope);
 
 127                                 if (expressionTb == null)
 
 130                                 // Compile-time conversion required?
 
 131                                 if (expression.isConstantValueOfTypeAssignableToType(expressionTb, expectedElementsTb)) {
 
 132                                         expression.implicitWidening(expectedElementsTb, expressionTb);
 
 133                                 } else if (BaseTypeBinding.isWidening(expectedElementsTb.id, expressionTb.id)) {
 
 134                                         expression.implicitWidening(expectedElementsTb, expressionTb);
 
 136                                         scope.problemReporter().typeMismatchErrorActualTypeExpectedType(expression, expressionTb, expectedElementsTb);
 
 141                         for (int i = 0, length = expressions.length; i < length; i++)
 
 142                                 if (expressions[i].resolveTypeExpecting(scope, expectedElementsTb) == null)
 
 148         // infer initializer type for error reporting based on first element
 
 149         TypeBinding leafElementType = null;
 
 151         if (expressions == null) {
 
 152                 leafElementType = scope.getJavaLangObject();
 
 154                 Expression currentExpression = expressions[0];
 
 155                 while(currentExpression != null && currentExpression instanceof ArrayInitializer) {
 
 157                         Expression[] subExprs = ((ArrayInitializer) currentExpression).expressions;
 
 158                         if (subExprs == null){
 
 159                                 leafElementType = scope.getJavaLangObject();
 
 160                                 currentExpression = null;
 
 163                         currentExpression = ((ArrayInitializer) currentExpression).expressions[0];
 
 165                 if (currentExpression != null) {
 
 166                         leafElementType = currentExpression.resolveType(scope);
 
 169         if (leafElementType != null) {
 
 170                 TypeBinding probableTb = scope.createArray(leafElementType, dim);
 
 171                 scope.problemReporter().typeMismatchErrorActualTypeExpectedType(this, probableTb, expectedTb);
 
 175 public String toStringExpression() {
 
 177         String s = "{" ; //$NON-NLS-1$
 
 178         if (expressions != null)
 
 180                 for (int i = 0 ; i < expressions.length ; i++)
 
 181                 {       s = s + expressions[i].toStringExpression() + "," ; //$NON-NLS-1$
 
 184                         {       s = s + "\n                "; j = 20;}}}; //$NON-NLS-1$
 
 185         s = s + "}"; //$NON-NLS-1$
 
 188 public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
 
 189         if (visitor.visit(this, scope)) {
 
 190                 if (expressions != null) {
 
 191                         int expressionsLength = expressions.length;
 
 192                         for (int i = 0; i < expressionsLength; i++)
 
 193                                 expressions[i].traverse(visitor, scope);
 
 196         visitor.endVisit(this, scope);