NewExpression.java :  » UnTagged » simplecompiler2 » com » google » devtools » simple » compiler » expressions » Android Open Source

Android Open Source » UnTagged » simplecompiler2 
simplecompiler2 » com » google » devtools » simple » compiler » expressions » NewExpression.java
/*
 * Copyright 2009 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.devtools.simple.compiler.expressions;

import com.google.devtools.simple.classfiles.Method;
import com.google.devtools.simple.compiler.Compiler;
import com.google.devtools.simple.compiler.Error;
import com.google.devtools.simple.compiler.symbols.FunctionSymbol;
import com.google.devtools.simple.compiler.types.ArrayType;
import com.google.devtools.simple.compiler.types.IntegerType;
import com.google.devtools.simple.compiler.types.ObjectType;
import com.google.devtools.simple.compiler.types.Type;

import java.util.List;

/**
 * Represents object and array instantiation expressions.
 *
 * @author Herbert Czymontek
 */
public final class NewExpression extends Expression {

  // Dimensions for New array expressions (otherwise null)
  List<Expression> dimensions;

  /**
   * Creates a new object or array instantiation expression.
   * 
   * @param position  source code start position of expression
   * @param type  type of object or array to instantiate
   * @param dimensions  dimensions for New array (otherwise {@code null}
   */
  public NewExpression(long position, Type type, List<Expression> dimensions) {
    super(position);

    this.type = type;
    this.dimensions = dimensions;
  }

  @Override
  public Expression resolve(Compiler compiler, FunctionSymbol currentFunction) {
    type.resolve(compiler);

    if (dimensions != null) {
      // Resolve dimensions for array
      if (!type.isArrayType()) {
        Compiler.internalError();  // COV_NF_LINE
      }

      int argDimensions = dimensions.size();
      int arrayDimensions = ((ArrayType) type).getDimensions(); 
      if (arrayDimensions != argDimensions) {
        compiler.error(getPosition(),
            argDimensions > arrayDimensions ? Error.errTooManyIndices : Error.errTooFewIndices);
      }

      for (int i = 0; i < dimensions.size(); i++) {
        Expression dimension = dimensions.get(i);
        if (dimension == null) {
          compiler.error(getPosition(), Error.errArrayDimensionExpected);
        } else {
          dimensions.set(i, dimension.resolve(compiler, currentFunction).checkType(compiler,
              IntegerType.integerType));
        }
      }
    } else if (!type.isObjectType()) {
      compiler.error(getPosition(), Error.errObjectOrArrayTypeNeeded);
    }

    return this;
  }

  @Override
  public void generate(Method m) {
    if (type.isArrayType()) {
      ArrayType arrayType = (ArrayType) type;
      for (Expression dimension : dimensions) {
        dimension.generate(m);
      }
      arrayType.generateAllocateArray(m);
    } else {
      m.generateInstrNew(type.internalName());
      m.generateInstrDup();
      m.generateInstrInvokespecial(type.internalName(), "<init>", "()V");
      // With the exception of forms we always invoke the property initializer immediately after the
      // constructor. This way properties will be initialized correctly regardless of  whether
      // the object was defined in Java or Simple. Forms need to be treated differently because
      // their initialization sequence is more complicated (see comments in ConstructorSymbol
      // class).
      if (!((ObjectType) type).getObjectSymbol().isForm()) {
        m.generateInstrDup();
        m.generateInstrInvokestatic(Compiler.RUNTIME_ROOT_INTERNAL + "/Objects",
            "initializeProperties", "(Ljava/lang/Object;)V");
      }
    }
  }

  @Override
  public String toString() {
    return "New " + type.toString();  // COV_NF_LINE
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.