Package org.eclipse.php.internal.core.typeinference.evaluators

Source Code of org.eclipse.php.internal.core.typeinference.evaluators.FieldAccessEvaluator

/*******************************************************************************
* Copyright (c) 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*     Zend Technologies
*******************************************************************************/
package org.eclipse.php.internal.core.typeinference.evaluators;

import org.eclipse.dltk.ast.expressions.Expression;
import org.eclipse.dltk.ast.references.SimpleReference;
import org.eclipse.dltk.ast.references.VariableReference;
import org.eclipse.dltk.evaluation.types.UnknownType;
import org.eclipse.dltk.ti.GoalState;
import org.eclipse.dltk.ti.ISourceModuleContext;
import org.eclipse.dltk.ti.goals.ExpressionTypeGoal;
import org.eclipse.dltk.ti.goals.GoalEvaluator;
import org.eclipse.dltk.ti.goals.IGoal;
import org.eclipse.dltk.ti.types.IEvaluatedType;
import org.eclipse.php.internal.core.compiler.ast.nodes.FieldAccess;
import org.eclipse.php.internal.core.compiler.ast.nodes.StaticFieldAccess;
import org.eclipse.php.internal.core.typeinference.context.IModelCacheContext;
import org.eclipse.php.internal.core.typeinference.context.TypeContext;
import org.eclipse.php.internal.core.typeinference.goals.ClassVariableDeclarationGoal;
import org.eclipse.php.internal.core.typeinference.goals.phpdoc.PHPDocClassVariableGoal;

public class FieldAccessEvaluator extends GoalEvaluator {

  private final static int STATE_INIT = 0;
  private final static int STATE_WAITING_RECEIVER = 1;
  private final static int STATE_GOT_RECEIVER = 2;
  private final static int STATE_WAITING_FIELD_PHPDOC = 3;
  private final static int STATE_WAITING_FIELD = 4;

  private int state = STATE_INIT;
  private IEvaluatedType receiverType;
  private IEvaluatedType result;

  public FieldAccessEvaluator(IGoal goal) {
    super(goal);
  }

  private IGoal[] produceNextSubgoal(IGoal previousGoal,
      IEvaluatedType previousResult, GoalState goalState) {

    ExpressionTypeGoal typedGoal = (ExpressionTypeGoal) goal;
    Expression expression = (Expression) typedGoal.getExpression();

    Expression receiver;
    Expression field;
    if (expression instanceof FieldAccess) {
      FieldAccess fieldAccess = (FieldAccess) expression;
      receiver = fieldAccess.getDispatcher();
      field = fieldAccess.getField();
    } else if (expression instanceof StaticFieldAccess) {
      StaticFieldAccess fieldAccess = (StaticFieldAccess) expression;
      receiver = fieldAccess.getDispatcher();
      field = fieldAccess.getField();
    } else {
      return null;
    }

    String variableName;
    int offset = 0;
    if (field instanceof VariableReference) { // static access
      variableName = ((VariableReference) field).getName();
      offset = ((VariableReference) field).sourceStart();
    } else if (field instanceof SimpleReference) { // object access
      variableName = '$' + ((SimpleReference) field).getName();
      offset = ((SimpleReference) field).sourceStart();
    } else {
      return null;
    }

    // just starting to evaluate method, evaluate method receiver first:
    if (state == STATE_INIT) {

      if (receiver == null) {
        state = STATE_GOT_RECEIVER;
      } else {
        state = STATE_WAITING_RECEIVER;
        return new IGoal[] { new ExpressionTypeGoal(goal.getContext(),
            receiver) };
      }
    }

    // receiver must been evaluated now:
    if (state == STATE_WAITING_RECEIVER) {
      receiverType = previousResult;
      if (receiverType == null) {
        return null;
      }
      state = STATE_GOT_RECEIVER;
    }

    // we've evaluated receiver, lets evaluate the method return type now
    // (using PHPDoc first):
    if (state == STATE_GOT_RECEIVER) {
      state = STATE_WAITING_FIELD_PHPDOC;
      TypeContext typeContext = new TypeContext(
          (ISourceModuleContext) goal.getContext(), receiverType);
      if (goal.getContext() instanceof IModelCacheContext) {
        typeContext.setCache(((IModelCacheContext) goal.getContext())
            .getCache());
      }
      return new IGoal[] { new PHPDocClassVariableGoal(typeContext,
          variableName, offset) };
    }

    if (state == STATE_WAITING_FIELD_PHPDOC) {
      if (goalState != GoalState.PRUNED && previousResult != null
          && previousResult != UnknownType.INSTANCE) {
        result = previousResult;
        return null;
      }
      state = STATE_WAITING_FIELD;
      TypeContext typeContext = new TypeContext(
          (ISourceModuleContext) goal.getContext(), receiverType);
      if (goal.getContext() instanceof IModelCacheContext) {
        typeContext.setCache(((IModelCacheContext) goal.getContext())
            .getCache());
      }
      return new IGoal[] { new ClassVariableDeclarationGoal(typeContext,
          variableName) };
    }

    if (state == STATE_WAITING_FIELD) {
      if (goalState != GoalState.PRUNED && previousResult != null
          && previousResult != UnknownType.INSTANCE) {
        result = previousResult;
      }
    }

    return null;
  }

  public Object produceResult() {
    return result;
  }

  public IGoal[] init() {
    IGoal[] goals = produceNextSubgoal(null, null, null);
    if (goals != null) {
      return goals;
    }
    return IGoal.NO_GOALS;
  }

  public IGoal[] subGoalDone(IGoal subgoal, Object result, GoalState state) {
    IGoal[] goals = produceNextSubgoal(subgoal, (IEvaluatedType) result,
        state);
    if (goals != null) {
      return goals;
    }
    return IGoal.NO_GOALS;
  }
}
TOP

Related Classes of org.eclipse.php.internal.core.typeinference.evaluators.FieldAccessEvaluator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.