TypePtr AssignmentExpression:: inferTypesImpl(AnalysisResultPtr ar, TypePtr type, bool coerce, ExpressionPtr variable, ExpressionPtr value /* = ExpressionPtr() */) { TypePtr ret = type; if (value) { if (coerce) { ret = value->inferAndCheck(ar, type, coerce); } else { ret = value->inferAndCheck(ar, NEW_TYPE(Some), coerce); } } BlockScopePtr scope = ar->getScope(); if (variable->is(Expression::KindOfConstantExpression)) { // ...as in ClassConstant statement ConstantExpressionPtr exp = dynamic_pointer_cast<ConstantExpression>(variable); bool p; scope->getConstants()->check(exp->getName(), ret, true, ar, variable, p); } else if (variable->is(Expression::KindOfDynamicVariable)) { // simptodo: not too sure about this ar->getFileScope()->setAttribute(FileScope::ContainsLDynamicVariable); } else if (variable->is(Expression::KindOfSimpleVariable)) { SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(variable); if (var->getName() == "this" && ar->getClassScope()) { if (ar->isFirstPass()) { ar->getCodeError()->record(variable, CodeError::ReassignThis, variable); } } if (ar->getPhase() == AnalysisResult::LastInference && value) { if (!value->getExpectedType()) { value->setExpectedType(variable->getActualType()); } } } // if the value may involve object, consider the variable as "referenced" // so that objects are not destructed prematurely. bool referenced = true; if (value && value->isScalar()) referenced = false; if (ret && ret->isNoObjectInvolved()) referenced = false; if (referenced && variable->is(Expression::KindOfSimpleVariable)) { SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(variable); const std::string &name = var->getName(); VariableTablePtr variables = ar->getScope()->getVariables(); variables->addReferenced(name); } TypePtr vt = variable->inferAndCheck(ar, ret, true); if (!coerce && type->is(Type::KindOfAny)) { ret = vt; } return ret; }
void ConstantTable::outputCPP(CodeGenerator &cg, AnalysisResultPtr ar) { bool decl = true; if (cg.getContext() == CodeGenerator::CppConstantsDecl) { decl = false; } bool printed = false; for (StringToSymbolMap::iterator iter = m_symbolMap.begin(), end = m_symbolMap.end(); iter != end; ++iter) { Symbol *sym = &iter->second; if (!sym->declarationSet() || sym->isDynamic()) continue; if (sym->isSystem() && cg.getOutput() != CodeGenerator::SystemCPP) continue; const string &name = sym->getName(); ConstructPtr value = sym->getValue(); printed = true; cg_printf(decl ? "extern const " : "const "); TypePtr type = sym->getFinalType(); bool isString = type->is(Type::KindOfString); if (isString) { cg_printf("StaticString"); } else { type->outputCPPDecl(cg, ar); } if (decl) { cg_printf(" %s%s", Option::ConstantPrefix, cg.formatLabel(name).c_str()); } else { cg_printf(" %s%s", Option::ConstantPrefix, cg.formatLabel(name).c_str()); cg_printf(isString ? "(" : " = "); if (value) { ExpressionPtr exp = dynamic_pointer_cast<Expression>(value); ASSERT(!exp->getExpectedType()); ScalarExpressionPtr scalarExp = dynamic_pointer_cast<ScalarExpression>(exp); if (isString && scalarExp) { cg_printf("LITSTR_INIT(%s)", scalarExp->getCPPLiteralString(cg).c_str()); } else { exp->outputCPP(cg, ar); } } else { cg_printf("\"%s\"", cg.escapeLabel(name).c_str()); } if (isString) { cg_printf(")"); } } cg_printf(";\n"); } if (printed) { cg_printf("\n"); } }
static void outputStringExpr(CodeGenerator &cg, AnalysisResultPtr ar, ExpressionPtr exp, bool asLitStr) { if (asLitStr && exp->isLiteralString()) { const std::string &s = exp->getLiteralString(); std::string enc = string_cplus_escape(s.c_str(), s.size()); cg_printf("\"%s\", %d", enc.c_str(), (int)s.size()); return; } TypePtr et(exp->getExpectedType()); exp->setExpectedType(Type::String); exp->outputCPP(cg, ar); exp->setExpectedType(et); }
void ConstantTable::outputCPP(CodeGenerator &cg, AnalysisResultPtr ar) { bool decl = true; if (cg.getContext() == CodeGenerator::CppConstantsDecl) { decl = false; } bool printed = false; for (StringToConstructPtrMap::const_iterator iter = m_declarations.begin(); iter != m_declarations.end(); ++iter) { const string &name = iter->first; if (isSystem(name) && cg.getOutput() != CodeGenerator::SystemCPP) continue; ConstructPtr value = getValue(name); if (isDynamic(name)) continue; printed = true; cg.printf(decl ? "extern const " : "const "); TypePtr type = getFinalType(name); if (type->is(Type::KindOfString)) { cg.printf("StaticString"); } else { type->outputCPPDecl(cg, ar); } const char *nameStr = name.c_str(); if (decl) { cg.printf(" %s%s", Option::ConstantPrefix, nameStr); } else { cg.printf(" %s%s = ", Option::ConstantPrefix, nameStr); if (value) { ExpressionPtr exp = dynamic_pointer_cast<Expression>(value); ASSERT(!exp->getExpectedType()); exp->outputCPP(cg, ar); } else { cg.printf("\"%s\"", nameStr); } } cg.printf(";\n"); } if (printed) { cg.printf("\n"); } }
void UnaryOpExpression::SetExpTypeForExistsContext(AnalysisResultPtr ar, ExpressionPtr e, bool allowPrimitives) { if (!e) return; TypePtr at(e->getActualType()); if (!allowPrimitives && at && at->isExactType() && at->isPrimitive()) { at = e->inferAndCheck(ar, Type::Variant, true); } TypePtr it(e->getImplementedType()); TypePtr et(e->getExpectedType()); if (et && et->is(Type::KindOfVoid)) e->setExpectedType(TypePtr()); if (at && (!it || Type::IsMappedToVariant(it)) && ((allowPrimitives && Type::HasFastCastMethod(at)) || (!allowPrimitives && (at->is(Type::KindOfObject) || at->is(Type::KindOfArray) || at->is(Type::KindOfString))))) { e->setExpectedType(it ? at : TypePtr()); } }
void Type::Dump(ExpressionPtr exp) { Dump(exp->getExpectedType(), "Expected: %s\t"); Dump(exp->getActualType(), "Actual: %s\n"); }