void ReturnStatement::inferTypes(AnalysisResultPtr ar) { assert(getFunctionScope().get() == getScope().get()); IMPLEMENT_INFER_AND_CHECK_ASSERT(getScope()); FunctionScopePtr funcScope = getFunctionScope(); if (m_exp) { if (funcScope) { TypePtr ret; if (funcScope->isOverriding()) { if (funcScope->getReturnType()) { ret = m_exp->inferAndCheck(ar, funcScope->getReturnType(), false); } else { ConstructPtr self = shared_from_this(); ret = m_exp->inferAndCheck(ar, Type::Some, false); } } else { ret = m_exp->inferAndCheck(ar, Type::Some, false); funcScope->setReturnType(ar, ret); funcScope->addRetExprToFix(m_exp); } } else { m_exp->inferAndCheck(ar, Type::Int64, false); } } else { funcScope->setReturnType(ar, TypePtr()); } }
FunctionScopePtr MethodStatement::onInitialParse(AnalysisResultConstPtr ar, FileScopePtr fs) { int minParam, maxParam; ConstructPtr self = shared_from_this(); minParam = maxParam = 0; bool hasRef = false; if (m_params) { std::set<string> names, allDeclNames; int i = 0; maxParam = m_params->getCount(); for (i = maxParam; i--; ) { ParameterExpressionPtr param = dynamic_pointer_cast<ParameterExpression>((*m_params)[i]); if (param->isRef()) hasRef = true; if (!param->isOptional()) { if (!minParam) minParam = i + 1; } else if (minParam && !param->hasTypeHint()) { Compiler::Error(Compiler::RequiredAfterOptionalParam, param); } allDeclNames.insert(param->getName()); } for (i = maxParam-1; i >= 0; i--) { ParameterExpressionPtr param = dynamic_pointer_cast<ParameterExpression>((*m_params)[i]); if (names.find(param->getName()) != names.end()) { Compiler::Error(Compiler::RedundantParameter, param); for (int j = 0; j < 1000; j++) { string name = param->getName() + lexical_cast<string>(j); if (names.find(name) == names.end() && allDeclNames.find(name) == allDeclNames.end()) { param->rename(name); break; } } } names.insert(param->getName()); } } if (hasRef || m_ref) { m_attribute |= FileScope::ContainsReference; } vector<UserAttributePtr> attrs; if (m_attrList) { for (int i = 0; i < m_attrList->getCount(); ++i) { UserAttributePtr a = dynamic_pointer_cast<UserAttribute>((*m_attrList)[i]); attrs.push_back(a); } } StatementPtr stmt = dynamic_pointer_cast<Statement>(shared_from_this()); FunctionScopePtr funcScope (new FunctionScope(ar, m_method, m_name, stmt, m_ref, minParam, maxParam, m_modifiers, m_attribute, m_docComment, fs, attrs)); if (!m_stmt) { funcScope->setVirtual(); } setBlockScope(funcScope); funcScope->setParamCounts(ar, -1, -1); if (funcScope->isNative()) { funcScope->setReturnType(ar, Type::GetType(m_retTypeAnnotation->dataType())); } return funcScope; }