Exemplo n.º 1
0
TypePtr ConstantTable::check(const std::string &name, TypePtr type,
                             bool coerce, AnalysisResultPtr ar,
                             ConstructPtr construct, bool &present) {
  TypePtr actualType;
  present = true;
  if (name == "true" || name == "false") {
    actualType = Type::Boolean;
  } else if (!ar->isFirstPass() && m_values.find(name) == m_values.end()) {
    ClassScopePtr parent = findParent(ar, name);
    if (parent) {
      return parent->checkConst(name, type, coerce, ar,
                                construct, present);
    }
    ar->getCodeError()->record(CodeError::UseUndeclaredConstant,
                               construct);
    if (m_blockScope.is(BlockScope::ClassScope)) {
      actualType = Type::Variant;
    } else {
      actualType = Type::String;
    }
    setType(ar, name, actualType, true);
    present = false;
  } else {
    StringToTypePtrMap::const_iterator iter = m_coerced.find(name);
    if (iter != m_coerced.end()) {
      actualType = iter->second;
      if (actualType->is(Type::KindOfSome) ||
          actualType->is(Type::KindOfAny)) {
        setType(ar, name, type, true);
        return type;
      }
    } else {
      ClassScopePtr parent = findParent(ar, name);
      if (parent) {
        return parent->checkConst(name, type, coerce, ar,
                                  construct, present);
      }
      present = false;
      actualType = NEW_TYPE(Some);
      setType(ar, name, actualType, true);
      m_declarations[name] = construct;
    }
  }

  if (Type::IsBadTypeConversion(ar, actualType, type, coerce)) {
    ar->getCodeError()->record(construct, type->getKindOf(),
                               actualType->getKindOf());
  }
  return actualType;
}
Exemplo n.º 2
0
TypePtr ConstantTable::checkBases(const std::string &name, TypePtr type,
                                  bool coerce, AnalysisResultConstPtr ar,
                                  ConstructPtr construct,
                                  const std::vector<std::string> &bases,
                                  BlockScope *&defScope) {
  TypePtr actualType;
  defScope = NULL;
  ClassScopePtr parent = findParent(ar, name);
  if (parent) {
    actualType = parent->checkConst(name, type, coerce, ar, construct,
                                    parent->getBases(), defScope);
    if (defScope) return actualType;
  }
  for (int i = bases.size() - 1; i >= (parent ? 1 : 0); i--) {
    const string &base = bases[i];
    ClassScopePtr super = ar->findClass(base);
    if (!super) continue;
    actualType = super->checkConst(name, type, coerce, ar, construct,
                                   super->getBases(), defScope);
    if (defScope) return actualType;
  }
  return actualType;
}
TypePtr ClassConstantExpression::inferTypes(AnalysisResultPtr ar,
                                            TypePtr type, bool coerce) {
  m_valid = false;
  ConstructPtr self = shared_from_this();
  ClassScopePtr cls = ar->resolveClass(m_className);
  if (!cls || cls->isRedeclaring()) {
    if (cls) {
      m_redeclared = true;
      ar->getScope()->getVariables()->
        setAttribute(VariableTable::NeedGlobalPointer);
    }
    if (!cls && ar->isFirstPass()) {
      ar->getCodeError()->record(self, CodeError::UnknownClass, self);
    }
    return type;
  }
  if (cls->getConstants()->isDynamic(m_varName)) {
    ar->getScope()->getVariables()->
      setAttribute(VariableTable::NeedGlobalPointer);
  }
  if (cls->getConstants()->isExplicitlyDeclared(m_varName)) {
    string name = m_className + "::" + m_varName;
    ConstructPtr decl = cls->getConstants()->getDeclaration(m_varName);
    if (decl) { // No decl means an extension class.
      ar->getDependencyGraph()->add(DependencyGraph::KindOfConstant,
                                    ar->getName(),
                                    name, shared_from_this(), name, decl);
    }
    m_valid = true;
  }
  bool present;
  TypePtr t = cls->checkConst(m_varName, type, coerce, ar,
                              shared_from_this(), present);
  if (present) {
    m_valid = true;
  }

  return t;
}