Пример #1
0
bool ClosureExpression::preOutputCPP(CodeGenerator &cg, AnalysisResultPtr ar,
                                     int state) {
  FunctionScopeRawPtr cfunc(m_func->getFunctionScope());
  bool output = false;
  for (BlockScopePtr sc = cfunc->getOuterScope(); sc;
       sc = sc->getOuterScope()) {
    if (sc->is(BlockScope::ClassScope)) {
      ClassScopePtr cls = boost::static_pointer_cast<ClassScope>(sc);
      if (cls->isTrait()) {
        output = true;
        break;
      }
    }
  }

  if (!cg.inExpression()) {
    return output || Expression::preOutputCPP(cg, ar, state);
  }

  if (output) {
    cg.wrapExpressionBegin();
    cfunc->outputCPPPreface(cg, ar);
  }
  return Expression::preOutputCPP(cg, ar, state) || output;
}
Пример #2
0
TypePtr SimpleVariable::inferAndCheck(AnalysisResultPtr ar, TypePtr type,
                                      bool coerce) {
  TypePtr ret;
  ConstructPtr construct = shared_from_this();
  BlockScopePtr scope = getScope();
  VariableTablePtr variables = scope->getVariables();

  // check function parameter that can occur in lval context
  if (m_sym && m_sym->isParameter() &&
      m_context & (LValue | RefValue | DeepReference |
                   UnsetContext | InvokeArgument | OprLValue | DeepOprLValue)) {
    m_sym->setLvalParam();
  }
  if (m_this) {
    ClassScopePtr cls = getOriginalClass();
    if (!hasContext(ObjectContext) && cls->derivedByDynamic()) {
      ret = Type::Object;
    } else {
      ret = Type::CreateObjectType(cls->getName());
    }
    if (!hasContext(ObjectContext) &&
        variables->getAttribute(VariableTable::ContainsDynamicVariable)) {
      ret = variables->add(m_sym, ret, true, ar,
                           construct, scope->getModifiers());
    }
  } else if ((m_context & (LValue|Declaration)) &&
             !(m_context & (ObjectContext|RefValue))) {
    if (m_globals) {
      ret = Type::Variant;
    } else if (m_superGlobal) {
      ret = m_superGlobalType;
    } else if (m_superGlobalType) { // For system
      ret = variables->add(m_sym, m_superGlobalType,
                           ((m_context & Declaration) != Declaration), ar,
                           construct, scope->getModifiers());
    } else {
      ret = variables->add(m_sym, type,
                           ((m_context & Declaration) != Declaration), ar,
                           construct, scope->getModifiers());
    }
  } else {
    if (m_superGlobalType) {
      ret = m_superGlobalType;
    } else if (m_globals) {
      ret = Type::Array;
    } else if (scope->is(BlockScope::ClassScope)) {
      // ClassVariable expression will come to this block of code
      ret = getClassScope()->checkProperty(m_sym, type, true, ar);
    } else {
      TypePtr tmpType = type;
      if (m_context & RefValue) {
        tmpType = Type::Variant;
        coerce = true;
      }
      int p;
      ret = variables->checkVariable(m_sym, tmpType, coerce,
                                     ar, construct, p);
    }
  }

  TypePtr actual = propagateTypes(ar, ret);
  setTypes(ar, actual, type);
  if (Type::SameType(actual, ret)) {
    m_implementedType.reset();
  } else {
    m_implementedType = ret;
  }
  return actual;
}
TypePtr SimpleVariable::inferAndCheck(AnalysisResultPtr ar, TypePtr type,
                                      bool coerce) {
  IMPLEMENT_INFER_AND_CHECK_ASSERT(getScope());

  resetTypes();
  TypePtr ret;
  ConstructPtr construct = shared_from_this();
  BlockScopePtr scope = getScope();
  VariableTablePtr variables = scope->getVariables();

  // check function parameter that can occur in lval context
  if (m_sym && m_sym->isParameter() &&
      m_context & (LValue | RefValue | DeepReference |
                   UnsetContext | InvokeArgument | OprLValue | DeepOprLValue)) {
    m_sym->setLvalParam();
  }

  if (coerce && m_sym && type && type->is(Type::KindOfAutoSequence)) {
    TypePtr t = m_sym->getType();
    if (!t || t->is(Type::KindOfVoid) ||
        t->is(Type::KindOfSome) || t->is(Type::KindOfArray)) {
      type = Type::Array;
    }
  }

  if (m_this) {
    ret = Type::Object;
    ClassScopePtr cls = getOriginalClass();
    if (cls && (hasContext(ObjectContext) || !cls->derivedByDynamic())) {
      ret = Type::CreateObjectType(cls->getName());
    }
    if (!hasContext(ObjectContext) &&
        variables->getAttribute(VariableTable::ContainsDynamicVariable)) {
      if (variables->getAttribute(VariableTable::ContainsLDynamicVariable)) {
        ret = Type::Variant;
      }
      ret = variables->add(m_sym, ret, true, ar,
                           construct, scope->getModifiers());
    }
  } else if ((m_context & (LValue|Declaration)) &&
             !(m_context & (ObjectContext|RefValue))) {
    if (m_globals) {
      ret = Type::Array;
    } else if (m_superGlobal) {
      ret = m_superGlobalType;
    } else if (m_superGlobalType) { // For system
      ret = variables->add(m_sym, m_superGlobalType,
                           ((m_context & Declaration) != Declaration), ar,
                           construct, scope->getModifiers());
    } else {
      ret = variables->add(m_sym, type,
                           ((m_context & Declaration) != Declaration), ar,
                           construct, scope->getModifiers());
    }
  } else {
    if (m_superGlobalType) {
      ret = m_superGlobalType;
    } else if (m_globals) {
      ret = Type::Array;
    } else if (scope->is(BlockScope::ClassScope)) {
      assert(getClassScope().get() == scope.get());
      // ClassVariable expression will come to this block of code
      ret = getClassScope()->checkProperty(getScope(), m_sym, type, true, ar);
    } else {
      TypePtr tmpType = type;
      if (m_context & RefValue) {
        tmpType = Type::Variant;
        coerce = true;
      }
      ret = variables->checkVariable(m_sym, tmpType, coerce, ar, construct);
      if (ret && (ret->is(Type::KindOfSome) || ret->is(Type::KindOfAny))) {
        ret = Type::Variant;
      }
    }
  }

  // if m_assertedType is set, then this is a type assertion node
  TypePtr inType = m_assertedType ?
    GetAssertedInType(ar, m_assertedType, ret) : ret;
  TypePtr actual = propagateTypes(ar, inType);
  setTypes(ar, actual, type);
  if (Type::SameType(actual, ret)) {
    m_implementedType.reset();
  } else {
    m_implementedType = ret;
  }
  return actual;
}
Пример #4
0
TypePtr SimpleVariable::inferAndCheck(AnalysisResultPtr ar, TypePtr type,
                                      bool coerce) {
  TypePtr ret;
  ConstructPtr construct = shared_from_this();
  BlockScopePtr scope = ar->getScope();
  VariableTablePtr variables = scope->getVariables();

  // check function parameter that can occur in lval context
  if (m_context & (LValue | RefValue | UnsetContext | InvokeArgument)) {
    FunctionScopePtr func = dynamic_pointer_cast<FunctionScope>(scope);
    if (func) {
      if (variables->isParameter(m_name)) {
        variables->addLvalParam(m_name);
      }
    }
  }
  if (m_name == "this") {
    ClassScopePtr cls = getOriginalScope(ar);
    if (cls) {
      bool isStaticFunc = false;
      FunctionScopePtr func = dynamic_pointer_cast<FunctionScope>(scope);
      if (func->isStatic()) isStaticFunc = true;
      if (cls->isRedeclaring()) {
        ret = Type::Variant;
      } else {
        ret = Type::CreateObjectType(cls->getName());
      }
      if (!isStaticFunc || (m_context & ObjectContext)) m_this = true;
    }
  }
  if ((m_context & (LValue|Declaration)) && !(m_context & ObjectContext)) {
    if (m_superGlobal) {
      ret = m_superGlobalType;
    } else if (m_superGlobalType) { // For system
      if (!m_this) {
        ret = variables->add(m_name, m_superGlobalType,
                             ((m_context & Declaration) != Declaration), ar,
                             construct, scope->getModifiers());
      }
    } else {
      if (m_globals) {
        ret = Type::Variant; // this can happen with "unset($GLOBALS)"
      } else if (!m_this) {
        ret = variables->add(m_name, type,
                             ((m_context & Declaration) != Declaration), ar,
                             construct, scope->getModifiers());
      }
    }
  } else {
    if (!m_this) {
      if (m_superGlobalType) {
        ret = m_superGlobalType;
      } else if (m_globals) {
        ret = Type::Array;
      } else if (scope->is(BlockScope::ClassScope)) {
        // ClassVariable expression will come to this block of code
        int properties;
        ret = variables->checkProperty(m_name, type, true, ar, construct,
                                       properties);
      } else {
        TypePtr tmpType = type;
        if (m_context & RefValue) {
          tmpType = Type::Variant;
          coerce = true;
        }
        int p;
        ret = variables->checkVariable(m_name, tmpType, coerce, ar, construct,
                                       p);
      }
    }
  }

  TypePtr actual = propagateTypes(ar, ret);
  setTypes(actual, type);
  if (Type::SameType(actual, ret)) {
    m_implementedType.reset();
  } else {
    m_implementedType = ret;
  }
  return actual;
}