本文整理汇总了C++中FunctionScopePtr类的典型用法代码示例。如果您正苦于以下问题:C++ FunctionScopePtr类的具体用法?C++ FunctionScopePtr怎么用?C++ FunctionScopePtr使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了FunctionScopePtr类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: labelScope
// Rewrite the outermost select clause so that it references properties of
// a result tuple constructed by the query provider. Then wrap this expression
// in a lambda so that the query provider can invoke it as a call back every
// time it produces a result tuple (row).
ClosureExpressionPtr QueryExpression::clientSideRewrite(
AnalysisResultPtr ar, FileScopePtr fileScope) {
// Rewrite the select expression into an expression that refers to
// table columns (including computed columns) via properties of an
// object produced by the query provider at runtime.
ClientSideSelectRewriter cs;
cs.rewriteQuery(static_pointer_cast<QueryExpression>(shared_from_this()));
auto csSelect = cs.getClientSideSelectClause();
// null if there is no select clause.
if (csSelect == nullptr) return nullptr;
ExpressionPtr selectExpr = csSelect->getExpression();
// Now wrap up the rewritten expression into a lambda expression that
// is passed to the query provider. When the query result is iterated,
// the closure is called for each row in the query result in order to
// produce the value specified by this select expression.
// Create a return statement for the lambda body
LabelScopePtr labelScope(new LabelScope());
ReturnStatementPtr returnStatement(
new ReturnStatement(BlockScopePtr(), labelScope, getRange(), selectExpr)
);
// Wrap up the return statement in a list for the lambda body
StatementListPtr stmt(
new StatementList(BlockScopePtr(), labelScope, getRange())
);
stmt->addElement(returnStatement);
// Create a function statement for the lambda:
// First create a formal parameter list, consisting of a single
// parameter that will receive an object from the query provider
// with a property for each table column that is referenced in the
// expression of this select clause.
TypeAnnotationPtr type;
bool hhType = true;
std::string paramName = "__query_result_row__";
bool byRefParam = false;
TokenID modifier = 0;
ExpressionPtr defaultValue;
ExpressionPtr attributeList;
ParameterExpressionPtr parameter (
new ParameterExpression(BlockScopePtr(), getRange(), type, hhType,
paramName, byRefParam, modifier, defaultValue, attributeList)
);
ExpressionListPtr params(new ExpressionList(BlockScopePtr(), getRange()));
params->addElement(parameter);
// Now create a function statement object
ModifierExpressionPtr modifiers(
new ModifierExpression(BlockScopePtr(), getRange())
);
bool ref = false;
static int counter = 0;
std::string name = "__select__#" + std::to_string(counter++);
TypeAnnotationPtr retTypeAnnotation;
int attr = 0;
std::string docComment;
ExpressionListPtr attrList;
FunctionStatementPtr func(
new FunctionStatement(BlockScopePtr(), labelScope, getRange(), modifiers,
ref, name, params, retTypeAnnotation, stmt, attr,
docComment, attrList)
);
// The function statement needs a scope
std::vector<UserAttributePtr> uattrs;
FunctionScopePtr funcScope
(new FunctionScope(ar, false, name, func, false, 1, 1,
nullptr, attr, docComment, fileScope, uattrs));
fileScope->addFunction(ar, funcScope);
func->resetScope(funcScope);
funcScope->setOuterScope(fileScope);
// Now construct a closure expression to create the closure value to
// pass to the query provider.
ExpressionListPtr captures;
ClosureExpressionPtr closure(
new ClosureExpression(BlockScopePtr(), getRange(), ClosureType::Short,
func, captures)
);
closure->getClosureFunction()->setContainingClosure(closure);
return closure;
}
示例2: ParseExtFunction
FunctionScopePtr BuiltinSymbols::ParseHelperFunction(AnalysisResultPtr ar,
const char** &p) {
FunctionScopePtr f = ParseExtFunction(ar, p);
f->setHelperFunction();
return f;
}
示例3: getClassScope
//.........这里部分代码省略.........
cg_indentBegin(" {%s",
hasGet || hasSet || hasCall || hasCallStatic ?
"\n" : "");
if (hasGet) cg_printf("setAttribute(UseGet);\n");
if (hasSet) cg_printf("setAttribute(UseSet);\n");
if (hasCall) cg_printf("setAttribute(HasCall);\n");
if (hasCallStatic) cg_printf("setAttribute(HasCallStatic);\n");
cg_indentEnd("}\n");
hasEmitCppCtor = true;
}
}
if (needsCppCtor && !hasEmitCppCtor) {
cg_printf("%s%s() : ", Option::ClassPrefix, clsName);
cg.setContext(CodeGenerator::CppConstructor);
ASSERT(!cg.hasInitListFirstElem());
m_stmt->outputCPP(cg, ar);
cg.clearInitListFirstElem();
cg.setContext(CodeGenerator::CppDeclaration);
cg_printf(" {}\n");
}
if (needsInit) {
cg_printf("void init();\n");
}
if (classScope->needLazyStaticInitializer()) {
cg_printf("static GlobalVariables *lazy_initializer"
"(GlobalVariables *g);\n");
}
if (!classScope->getAttribute(ClassScope::HasConstructor)) {
FunctionScopePtr func = classScope->findFunction(ar, "__construct",
false);
if (func && !func->isAbstract() && !classScope->isInterface()) {
func->outputCPPCreateDecl(cg, ar);
}
}
// doCall
if (classScope->getAttribute(ClassScope::HasUnknownMethodHandler)) {
cg_printf("Variant doCall(Variant v_name, Variant v_arguments, "
"bool fatal);\n");
}
if (classScope->getAttribute(ClassScope::HasInvokeMethod)) {
FunctionScopePtr func =
classScope->findFunction(ar, "__invoke", false);
ASSERT(func);
if (!func->isAbstract()) {
cg_printf("const CallInfo *"
"t___invokeCallInfoHelper(void *&extra);\n");
}
}
if (classScope->isRedeclaring() &&
!classScope->derivesFromRedeclaring() &&
classScope->derivedByDynamic()) {
cg_printf("Variant doRootCall(Variant v_name, Variant v_arguments, "
"bool fatal);\n");
}
if (m_stmt) m_stmt->outputCPP(cg, ar);
{
set<string> done;
示例4: shared_from_this
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);
return funcScope;
}
示例5: reset
TypePtr NewObjectExpression::inferTypes(AnalysisResultPtr ar, TypePtr type,
bool coerce) {
reset();
m_classScope.reset();
FunctionScopePtr prev = m_funcScope;
m_funcScope.reset();
ConstructPtr self = shared_from_this();
if (!m_name.empty() && !isStatic()) {
ClassScopePtr cls = resolveClass();
m_name = m_className;
if (!cls) {
if (isRedeclared()) {
getScope()->getVariables()->
setAttribute(VariableTable::NeedGlobalPointer);
} else if (getScope()->isFirstPass()) {
Compiler::Error(Compiler::UnknownClass, self);
}
if (m_params) m_params->inferAndCheck(ar, Type::Any, false);
return Type::Object;
}
if (cls->isVolatile() && !isPresent()) {
getScope()->getVariables()->
setAttribute(VariableTable::NeedGlobalPointer);
}
m_dynamic = cls->derivesFromRedeclaring();
bool valid = true;
FunctionScopePtr func = cls->findConstructor(ar, true);
if (!func) {
if (m_params) {
if (!m_dynamic && m_params->getCount()) {
if (getScope()->isFirstPass()) {
Compiler::Error(Compiler::BadConstructorCall, self);
}
m_params->setOutputCount(0);
}
m_params->inferAndCheck(ar, Type::Some, false);
}
} else {
if (func != prev) func->addCaller(getScope());
m_extraArg = func->inferParamTypes(ar, self, m_params,
valid);
m_variableArgument = func->isVariableArgument();
}
if (valid) {
m_classScope = cls;
m_funcScope = func;
}
if (!valid || m_dynamic) {
m_implementedType = Type::Object;
} else {
m_implementedType.reset();
}
return Type::CreateObjectType(m_name);
} else {
ar->containsDynamicClass();
if (m_params) {
m_params->markParams(canInvokeFewArgs());
}
}
m_implementedType.reset();
m_nameExp->inferAndCheck(ar, Type::String, false);
if (m_params) m_params->inferAndCheck(ar, Type::Any, false);
return Type::Object;
}
示例6: while
void BuiltinSymbols::ParseExtClasses(AnalysisResultPtr ar, const char **p,
bool sep) {
while (*p) {
// Parse name
const char *cname = *p++;
// Parse parent
const char *cparent = *p++;
// Parse list of interfaces
vector<string> ifaces;
while (*p) ifaces.push_back(*p++);
p++;
// Parse methods
vector<FunctionScopePtr> methods;
while (*p) {
FunctionScopePtr fs = ParseExtFunction(ar, p);
if (sep) {
fs->setSepExtension();
}
bool abstract = (bool)*p++;
if (abstract) {
fs->addModifier(T_ABSTRACT);
}
int visibility = (long)*p++;
int vismod = 0;
if (visibility == 1) {
vismod = T_PROTECTED;
} else if (visibility == 2) {
vismod = T_PRIVATE;
}
fs->addModifier(vismod);
bool stat = (bool)*p++;
if (stat) {
fs->addModifier(T_STATIC);
}
methods.push_back(fs);
}
if (cparent && *cparent && (ifaces.empty() || ifaces[0] != cparent)) {
ifaces.insert(ifaces.begin(), cparent);
}
ClassScopePtr cl(new ClassScope(ar, string(cname), string(cparent),
ifaces, methods));
p++;
// Parse properties
while (*p) {
*p++; // TODO, support visibility
const char *name = *p++;
TypePtr type = ParseType(p);
cl->getVariables()->add(name, type, false, ar, ExpressionPtr(),
ModifierExpressionPtr());
}
p++;
// Parse consts
while (*p) {
const char *name = *p++;
TypePtr type = ParseType(p);
cl->getConstants()->add(name, type, ExpressionPtr(), ar, ConstructPtr());
}
p++;
cl->setSystem();
if (sep) {
cl->setSepExtension();
}
s_classes[cl->getName()] = cl;
}
}
示例7: outputCPPObjProperty
void ObjectPropertyExpression::outputCPPObjProperty(CodeGenerator &cg,
AnalysisResultPtr ar,
bool directVariant,
int doExist) {
bool bThis = m_object->isThis();
bool useGetThis = false;
FunctionScopePtr funcScope = ar->getFunctionScope();
if (bThis) {
if (funcScope && funcScope->isStatic()) {
cg_printf("GET_THIS_ARROW()");
} else {
// in order for __set() and __get() to be called
useGetThis = true;
}
}
const char *op = ".";
string func = Option::ObjectPrefix;
const char *error = ", true";
ClassScopePtr cls = ar->getClassScope();
const char *context = "";
if (cg.getOutput() != CodeGenerator::SystemCPP) {
if (cls) {
context = ", s_class_name";
} else if (funcScope && !funcScope->inPseudoMain()) {
context = ", empty_string";
}
}
if (doExist) {
func = doExist > 0 ? "doIsSet" : "doEmpty";
error = "";
} else {
if (bThis && funcScope && funcScope->isStatic()) {
func = Option::ObjectStaticPrefix;
error = "";
context = "";
} else if (m_context & ExistContext) {
error = ", false";
}
if (m_context & (LValue | RefValue | UnsetContext)) {
func += "lval";
error = "";
} else {
func += "get";
}
}
if (m_property->getKindOf() == Expression::KindOfScalarExpression) {
ScalarExpressionPtr name =
dynamic_pointer_cast<ScalarExpression>(m_property);
const char *propName = name->getString().c_str();
if (m_valid && m_object->getType()->isSpecificObject()) {
if (m_static) {
if (!bThis) {
ASSERT(m_class);
if (doExist) cg_printf(doExist > 0 ? "isset(" : "empty(");
cg_printf("g->%s%s%s%s",
Option::StaticPropertyPrefix, m_class->getName().c_str(),
Option::IdPrefix.c_str(), propName);
if (doExist) cg_printf(")");
} else {
// if $val is a class static variable (static $val), then $val
// cannot be declared as a class variable (var $val), $this->val
// refers to a non-static class variable and has to use get/lval.
uint64 hash = hash_string(propName);
if (useGetThis) cg_printf("GET_THIS_DOT()");
cg_printf("%s(", func.c_str());
cg_printString(propName, ar);
cg_printf(", 0x%016llXLL%s%s)", hash, error, context);
}
} else {
if (doExist) cg_printf(doExist > 0 ? "isset(" : "empty(");
if (!bThis) {
ASSERT(!directVariant);
m_object->outputCPP(cg, ar);
cg_printf("->");
}
cg_printf("%s%s", Option::PropertyPrefix, propName);
if (doExist) cg_printf(")");
}
} else {
if (!bThis) {
if (directVariant) {
TypePtr expectedType = m_object->getExpectedType();
ASSERT(expectedType->is(Type::KindOfObject));
// Clear m_expectedType to avoid type cast (toObject).
m_object->setExpectedType(TypePtr());
m_object->outputCPP(cg, ar);
m_object->setExpectedType(expectedType);
} else {
m_object->outputCPP(cg, ar);
}
cg_printf(op);
} else {
if (useGetThis) cg_printf("GET_THIS_DOT()");
}
uint64 hash = hash_string(propName);
cg_printf("%s(", func.c_str());
cg_printString(propName, ar);
cg_printf(", 0x%016llXLL%s%s)", hash, error, context);
//.........这里部分代码省略.........
示例8: reset
TypePtr ObjectMethodExpression::inferAndCheck(AnalysisResultPtr ar,
TypePtr type, bool coerce) {
reset();
ConstructPtr self = shared_from_this();
TypePtr objectType = m_object->inferAndCheck(ar, Type::Object, false);
m_valid = true;
m_bindClass = true;
if (m_name.empty()) {
m_nameExp->inferAndCheck(ar, Type::String, false);
setInvokeParams(ar);
// we have to use a variant to hold dynamic value
return checkTypesImpl(ar, type, Type::Variant, coerce);
}
ClassScopePtr cls;
if (objectType && !objectType->getName().empty()) {
if (m_classScope && !strcasecmp(objectType->getName().c_str(),
m_classScope->getName().c_str())) {
cls = m_classScope;
} else {
cls = ar->findExactClass(shared_from_this(), objectType->getName());
}
}
if (!cls) {
if (getScope()->isFirstPass()) {
if (!ar->classMemberExists(m_name, AnalysisResult::MethodName)) {
Compiler::Error(Compiler::UnknownObjectMethod, self);
}
}
m_classScope.reset();
m_funcScope.reset();
setInvokeParams(ar);
return checkTypesImpl(ar, type, Type::Variant, coerce);
}
if (m_classScope != cls) {
m_classScope = cls;
m_funcScope.reset();
}
FunctionScopePtr func = m_funcScope;
if (!func) {
func = cls->findFunction(ar, m_name, true, true);
if (!func) {
if (!cls->hasAttribute(ClassScope::HasUnknownMethodHandler, ar)) {
if (ar->classMemberExists(m_name, AnalysisResult::MethodName)) {
setDynamicByIdentifier(ar, m_name);
} else {
Compiler::Error(Compiler::UnknownObjectMethod, self);
}
}
m_valid = false;
setInvokeParams(ar);
return checkTypesImpl(ar, type, Type::Variant, coerce);
}
m_funcScope = func;
func->addCaller(getScope());
}
bool valid = true;
m_bindClass = func->isStatic();
// use $this inside a static function
if (m_object->isThis()) {
FunctionScopePtr localfunc = getFunctionScope();
if (localfunc->isStatic()) {
if (getScope()->isFirstPass()) {
Compiler::Error(Compiler::MissingObjectContext, self);
}
valid = false;
}
}
// invoke() will return Variant
if (!m_object->getType()->isSpecificObject() ||
(func->isVirtual() && !func->isPerfectVirtual())) {
valid = false;
}
if (!valid) {
setInvokeParams(ar);
checkTypesImpl(ar, type, Type::Variant, coerce);
m_valid = false; // so we use invoke() syntax
func->setDynamic();
return m_actualType;
}
return checkParamsAndReturn(ar, type, coerce, func, false);
}
示例9: assert
TypePtr ObjectMethodExpression::inferAndCheck(AnalysisResultPtr ar,
TypePtr type, bool coerce) {
assert(type);
IMPLEMENT_INFER_AND_CHECK_ASSERT(getScope());
resetTypes();
reset();
ConstructPtr self = shared_from_this();
TypePtr objectType = m_object->inferAndCheck(ar, Type::Some, false);
m_valid = true;
m_bindClass = true;
if (m_name.empty()) {
m_nameExp->inferAndCheck(ar, Type::Some, false);
setInvokeParams(ar);
// we have to use a variant to hold dynamic value
return checkTypesImpl(ar, type, Type::Variant, coerce);
}
ClassScopePtr cls;
if (objectType && !objectType->getName().empty()) {
if (m_classScope && !strcasecmp(objectType->getName().c_str(),
m_classScope->getName().c_str())) {
cls = m_classScope;
} else {
cls = ar->findExactClass(shared_from_this(), objectType->getName());
}
}
if (!cls) {
m_classScope.reset();
m_funcScope.reset();
m_valid = false;
setInvokeParams(ar);
return checkTypesImpl(ar, type, Type::Variant, coerce);
}
if (m_classScope != cls) {
m_classScope = cls;
m_funcScope.reset();
}
FunctionScopePtr func = m_funcScope;
if (!func) {
func = cls->findFunction(ar, m_name, true, true);
if (!func) {
if (!cls->isTrait() &&
!cls->getAttribute(ClassScope::MayHaveUnknownMethodHandler) &&
!cls->getAttribute(ClassScope::HasUnknownMethodHandler) &&
!cls->getAttribute(ClassScope::InheritsUnknownMethodHandler)) {
if (ar->classMemberExists(m_name, AnalysisResult::MethodName)) {
if (!Option::AllDynamic) {
setDynamicByIdentifier(ar, m_name);
}
} else {
Compiler::Error(Compiler::UnknownObjectMethod, self);
}
}
m_valid = false;
setInvokeParams(ar);
return checkTypesImpl(ar, type, Type::Variant, coerce);
}
m_funcScope = func;
func->addCaller(getScope(), !type->is(Type::KindOfAny));
}
bool valid = true;
m_bindClass = func->isStatic();
// use $this inside a static function
if (m_object->isThis()) {
FunctionScopePtr localfunc = getFunctionScope();
if (localfunc->isStatic()) {
if (getScope()->isFirstPass()) {
Compiler::Error(Compiler::MissingObjectContext, self);
}
valid = false;
}
}
// invoke() will return Variant
if (cls->isInterface() ||
(func->isVirtual() &&
(!Option::WholeProgram || func->isAbstract() ||
(func->hasOverride() && cls->getAttribute(ClassScope::NotFinal))) &&
!func->isPerfectVirtual())) {
valid = false;
}
if (!valid) {
setInvokeParams(ar);
checkTypesImpl(ar, type, Type::Variant, coerce);
m_valid = false; // so we use invoke() syntax
if (!Option::AllDynamic) {
func->setDynamic();
}
assert(m_actualType);
return m_actualType;
//.........这里部分代码省略.........
示例10: reset
TypePtr ObjectMethodExpression::inferAndCheck(AnalysisResultPtr ar,
TypePtr type, bool coerce) {
reset();
ConstructPtr self = shared_from_this();
TypePtr objectType = m_object->inferAndCheck(ar, NEW_TYPE(Object), true);
m_valid = true;
m_bindClass = true;
if (m_name.empty()) {
// if dynamic property or method, we have nothing to find out
if (ar->isFirstPass()) {
ar->getCodeError()->record(self, CodeError::UseDynamicMethod, self);
}
m_nameExp->inferAndCheck(ar, Type::String, false);
setInvokeParams(ar);
// we have to use a variant to hold dynamic value
return checkTypesImpl(ar, type, Type::Variant, coerce);
}
ClassScopePtr cls = m_classScope;
if (objectType && !objectType->getName().empty()) {
cls = ar->findExactClass(objectType->getName());
}
if (!cls) {
if (ar->isFirstPass()) {
// call resolveClass to mark functions as dynamic
// but we cant do anything else with the result.
resolveClass(ar, m_name);
if (!ar->classMemberExists(m_name, AnalysisResult::MethodName)) {
ar->getCodeError()->record(self, CodeError::UnknownObjectMethod, self);
}
}
m_classScope.reset();
m_funcScope.reset();
setInvokeParams(ar);
return checkTypesImpl(ar, type, Type::Variant, coerce);
}
if (m_classScope != cls) {
m_classScope = cls;
m_funcScope.reset();
}
FunctionScopePtr func = m_funcScope;
if (!func) {
func = cls->findFunction(ar, m_name, true, true);
if (!func) {
if (!cls->hasAttribute(ClassScope::HasUnknownMethodHandler, ar)) {
if (ar->classMemberExists(m_name, AnalysisResult::MethodName)) {
// TODO: we could try to find out class derivation is present...
ar->getCodeError()->record(self,
CodeError::DerivedObjectMethod, self);
// we have to make sure the method is in invoke list
setDynamicByIdentifier(ar, m_name);
} else {
ar->getCodeError()->record(self,
CodeError::UnknownObjectMethod, self);
}
}
m_valid = false;
setInvokeParams(ar);
return checkTypesImpl(ar, type, Type::Variant, coerce);
}
m_funcScope = func;
}
bool valid = true;
m_bindClass = func->isStatic();
// use $this inside a static function
if (m_object->isThis()) {
FunctionScopePtr localfunc = ar->getFunctionScope();
if (localfunc->isStatic()) {
if (ar->isFirstPass()) {
ar->getCodeError()->record(self, CodeError::MissingObjectContext,
self);
}
valid = false;
}
}
// invoke() will return Variant
if (func->isVirtual() || !m_object->getType()->isSpecificObject()) {
valid = false;
}
if (!valid) {
setInvokeParams(ar);
checkTypesImpl(ar, type, Type::Variant, coerce);
m_valid = false; // so we use invoke() syntax
func->setDynamic();
return m_actualType;
}
return checkParamsAndReturn(ar, type, coerce, func);
//.........这里部分代码省略.........
示例11: shared_from_this
TypePtr ObjectPropertyExpression::inferTypes(AnalysisResultPtr ar,
TypePtr type, bool coerce) {
m_valid = false;
ConstructPtr self = shared_from_this();
TypePtr objectType = m_object->inferAndCheck(ar, Type::Some, false);
if (!m_property->is(Expression::KindOfScalarExpression)) {
m_property->inferAndCheck(ar, Type::String, false);
// we also lost track of which class variable an expression is about, hence
// any type inference could be wrong. Instead, we just force variants on
// all class variables.
if (m_context & (LValue | RefValue)) {
ar->forceClassVariants(getOriginalClass(), false);
}
return Type::Variant; // we have to use a variant to hold dynamic value
}
ScalarExpressionPtr exp = dynamic_pointer_cast<ScalarExpression>(m_property);
string name = exp->getString();
ASSERT(!name.empty());
m_property->inferAndCheck(ar, Type::String, false);
ClassScopePtr cls;
if (objectType && !objectType->getName().empty()) {
// what object-> has told us
cls = ar->findExactClass(shared_from_this(), objectType->getName());
} else {
if ((m_context & LValue) && objectType &&
!objectType->is(Type::KindOfObject) &&
!objectType->is(Type::KindOfVariant) &&
!objectType->is(Type::KindOfSome) &&
!objectType->is(Type::KindOfAny)) {
m_object->inferAndCheck(ar, Type::Object, true);
}
}
if (!cls) {
if (m_context & (LValue | RefValue | DeepReference | UnsetContext)) {
ar->forceClassVariants(name, getOriginalClass(), false);
}
return Type::Variant;
}
int prop = hasContext(AssignmentLHS) ? ClassScope::MayHaveUnknownPropSetter :
hasContext(ExistContext) ? ClassScope::MayHaveUnknownPropTester :
hasContext(UnsetContext) && hasContext(LValue) ?
ClassScope::MayHavePropUnsetter : ClassScope::MayHaveUnknownPropGetter;
if ((m_context & (AssignmentLHS|OprLValue)) ||
!cls->implementsAccessor(prop)) {
clearEffect(AccessorEffect);
}
// resolved to this class
if (m_context & RefValue) {
type = Type::Variant;
coerce = true;
}
// use $this inside a static function
if (m_object->isThis()) {
FunctionScopePtr func = m_object->getOriginalFunction();
if (!func || func->isStatic()) {
if (getScope()->isFirstPass()) {
Compiler::Error(Compiler::MissingObjectContext, self);
}
m_actualType = Type::Variant;
return m_actualType;
}
}
if (!m_propSym || cls != m_objectClass.lock()) {
m_objectClass = cls;
ClassScopePtr parent;
m_propSym = cls->findProperty(parent, name, ar, self);
assert(m_propSym);
if (!parent) {
parent = cls;
}
m_propSymValid = m_propSym->isPresent() &&
(!m_propSym->isPrivate() ||
getOriginalClass() == parent) &&
!m_propSym->isStatic();
if (m_propSymValid) {
parent->addUse(getScope(), BlockScope::UseKindNonStaticRef);
}
}
TypePtr ret;
if (m_propSymValid && (!cls->derivesFromRedeclaring() ||
m_propSym->isPrivate())) {
ret = cls->checkProperty(m_propSym, type, coerce, ar);
assert(m_object->getType()->isSpecificObject());
m_valid = true;
clearEffect(AccessorEffect);
//.........这里部分代码省略.........
示例12: ClassStaticsPtr
//.........这里部分代码省略.........
if (!dyn && !idyn) cg.printf("private: ObjectData* root;\n");
cg.printf("public:\n");
}
string conInit = ":";
if (dyn) {
conInit += "DynamicObjectData(\"" + m_parent + "\", r)";
} else if (idyn) {
conInit += string(Option::ClassPrefix) + parCls->getId() +
"(r?r:this)";
} else {
conInit += "root(r?r:this)";
}
cg.printf("%s%s(ObjectData* r = NULL)%s {}\n",
Option::ClassPrefix, clsName,
conInit.c_str());
}
}
cg.printf("void init();\n",
Option::ClassPrefix, clsName);
if (classScope->needLazyStaticInitializer()) {
cg.printf("static GlobalVariables *lazy_initializer"
"(GlobalVariables *g);\n");
}
if (!classScope->derivesFromRedeclaring()){
classScope->getVariables()->outputCPPPropertyDecl(cg, ar);
}
if (!classScope->getAttribute(ClassScope::HasConstructor)) {
FunctionScopePtr func = classScope->findFunction(ar, "__construct",
false);
if (func && !func->isAbstract() && !classScope->isInterface()) {
ar->pushScope(func);
func->outputCPPCreateDecl(cg, ar);
ar->popScope();
}
}
if (classScope->getAttribute(ClassScope::HasDestructor)) {
cg.printf("public: virtual void destruct();\n");
}
// doCall
if (classScope->getAttribute(ClassScope::HasUnknownMethodHandler)) {
cg.printf("Variant doCall(Variant v_name, Variant v_arguments, "
"bool fatal);\n");
}
if (m_stmt) m_stmt->outputCPP(cg, ar);
{
set<string> done;
classScope->outputCPPStaticMethodWrappers(cg, ar, done, clsName);
}
if (cg.getOutput() == CodeGenerator::SystemCPP &&
ar->isBaseSysRsrcClass(clsName) &&
!classScope->hasProperty("rsrc")) {
cg.printf("public: Variant %srsrc;\n", Option::PropertyPrefix);
}
cg.indentEnd("};\n");
if (redeclared) {
示例13: onInitialParse
void FunctionStatement::onParse(AnalysisResultConstPtr ar, FileScopePtr scope) {
// Correctness checks are normally done before adding function to scope.
if (m_params) {
for (int i = 0; i < m_params->getCount(); i++) {
ParameterExpressionPtr param =
dynamic_pointer_cast<ParameterExpression>((*m_params)[i]);
if (param->hasTypeHint() && param->defaultValue()) {
param->compatibleDefault();
}
}
}
// note it's important to add to scope, not a pushed FunctionContainer,
// as a function may be declared inside a class's method, yet this function
// is a global function, not a class method.
FunctionScopePtr fs = onInitialParse(ar, scope);
FunctionScope::RecordFunctionInfo(m_name, fs);
if (!scope->addFunction(ar, fs)) {
m_ignored = true;
return;
}
if (Option::PersistenceHook) {
fs->setPersistent(Option::PersistenceHook(fs, scope));
}
if (m_name == "__autoload") {
if (m_params && m_params->getCount() != 1) {
parseTimeFatal(Compiler::InvalidMagicMethod,
"__autoload() must take exactly 1 argument");
}
}
if (fs->isNative()) {
if (getStmts()) {
parseTimeFatal(Compiler::InvalidAttribute,
"Native functions must not have an implementation body");
}
if (m_params) {
int nParams = m_params->getCount();
for (int i = 0; i < nParams; ++i) {
// Variadic capture params don't need types
// since they'll be Arrays as far as HNI is concerned.
auto param = dynamic_pointer_cast<ParameterExpression>((*m_params)[i]);
if (!param->hasUserType() && !param->isVariadic()) {
parseTimeFatal(Compiler::InvalidAttribute,
"Native function calls must have type hints "
"on all args");
}
}
}
if (getReturnTypeConstraint().empty()) {
parseTimeFatal(Compiler::InvalidAttribute,
"Native function %s() must have a return type hint",
getOriginalName().c_str());
}
} else if (!getStmts()) {
parseTimeFatal(Compiler::InvalidAttribute,
"Global function %s() must contain a body",
getOriginalName().c_str());
}
}
示例14: outputCPPImpl
void FunctionStatement::outputCPPImpl(CodeGenerator &cg,
AnalysisResultPtr ar) {
CodeGenerator::Context context = cg.getContext();
FunctionScopePtr funcScope = m_funcScope.lock();
string fname = funcScope->getId(cg).c_str();
bool pseudoMain = funcScope->inPseudoMain();
string origFuncName = !pseudoMain ? funcScope->getOriginalName() :
("run_init::" + funcScope->getFileScope()->getName());
string funcSection;
if (outputFFI(cg, ar)) return;
if (context == CodeGenerator::NoContext) {
string rname = cg.formatLabel(m_name);
if (funcScope->isRedeclaring()) {
cg.printf("g->%s%s = &%s%s;\n", Option::CallInfoPrefix, m_name.c_str(),
Option::CallInfoPrefix, fname.c_str());
}
if (funcScope->isVolatile()) {
cg_printf("g->declareFunctionLit(");
cg_printString(m_name, ar);
cg_printf(");\n");
cg_printf("g->FVF(%s) = true;\n", rname.c_str());
}
return;
}
if (context == CodeGenerator::CppDeclaration &&
!funcScope->isInlined()) return;
if (context == CodeGenerator::CppPseudoMain &&
!pseudoMain) return;
if (context == CodeGenerator::CppImplementation &&
(funcScope->isInlined() || pseudoMain)) return;
ar->pushScope(funcScope);
cg.setPHPLineNo(-1);
if (pseudoMain && !Option::GenerateCPPMain) {
if (context == CodeGenerator::CppPseudoMain) {
if (cg.getOutput() != CodeGenerator::SystemCPP) {
cg.setContext(CodeGenerator::NoContext); // no inner functions/classes
funcScope->getVariables()->setAttribute(VariableTable::ForceGlobal);
outputCPPStmt(cg, ar);
funcScope->getVariables()->clearAttribute(VariableTable::ForceGlobal);
cg.setContext(CodeGenerator::CppPseudoMain);
ar->popScope();
return;
}
} else if (context == CodeGenerator::CppForwardDeclaration &&
cg.getOutput() != CodeGenerator::SystemCPP) {
return;
}
}
if (context == CodeGenerator::CppImplementation) {
printSource(cg);
} else if (context == CodeGenerator::CppForwardDeclaration &&
Option::GenerateCppLibCode) {
cg_printf("\n");
printSource(cg);
cg.printDocComment(funcScope->getDocComment());
}
if (funcScope->isInlined()) cg_printf("inline ");
TypePtr type = funcScope->getReturnType();
if (type) {
type->outputCPPDecl(cg, ar);
} else {
cg_printf("void");
}
funcSection = Option::FunctionSections[origFuncName];
if (!funcSection.empty()) {
cg_printf(" __attribute__ ((section (\".text.%s\")))",
funcSection.c_str());
}
if (pseudoMain) {
cg_printf(" %s%s(", Option::PseudoMainPrefix,
funcScope->getFileScope()->pseudoMainName().c_str());
} else {
cg_printf(" %s%s(", Option::FunctionPrefix, fname.c_str());
}
switch (context) {
case CodeGenerator::CppForwardDeclaration:
funcScope->outputCPPParamsDecl(cg, ar, m_params, true);
cg_printf(");\n");
if (funcScope->hasDirectInvoke()) {
cg_printf("Variant %s%s(void *extra, CArrRef params);\n",
Option::InvokePrefix, fname.c_str());
}
break;
case CodeGenerator::CppDeclaration:
case CodeGenerator::CppImplementation:
case CodeGenerator::CppPseudoMain:
{
//.........这里部分代码省略.........
示例15: outputLineMap
void SimpleFunctionCall::outputCPPImpl(CodeGenerator &cg,
AnalysisResultPtr ar) {
bool linemap = outputLineMap(cg, ar, true);
if (!m_lambda.empty()) {
cg.printf("\"%s\"", m_lambda.c_str());
if (linemap) cg.printf(")");
return;
}
if (!m_class && m_className.empty()) {
if (m_type == DefineFunction && m_params && m_params->getCount() >= 2) {
ScalarExpressionPtr name =
dynamic_pointer_cast<ScalarExpression>((*m_params)[0]);
string varName;
if (name) {
varName = name->getIdentifier();
ExpressionPtr value = (*m_params)[1];
if (varName.empty()) {
cg.printf("throw_fatal(\"bad define\")");
} else if (m_dynamicConstant) {
cg.printf("g->declareConstant(\"%s\", g->%s%s, ",
varName.c_str(), Option::ConstantPrefix,
varName.c_str());
value->outputCPP(cg, ar);
cg.printf(")");
} else {
bool needAssignment = true;
bool isSystem = ar->getConstants()->isSystem(varName);
if (isSystem ||
((!ar->isConstantRedeclared(varName)) && value->isScalar())) {
needAssignment = false;
}
if (needAssignment) {
cg.printf("%s%s = ", Option::ConstantPrefix, varName.c_str());
value->outputCPP(cg, ar);
}
}
} else {
cg.printf("throw_fatal(\"bad define\")");
}
if (linemap) cg.printf(")");
return;
}
if (m_name == "func_num_args") {
cg.printf("num_args");
if (linemap) cg.printf(")");
return;
}
switch (m_type) {
case VariableArgumentFunction:
{
FunctionScopePtr func =
dynamic_pointer_cast<FunctionScope>(ar->getScope());
if (func) {
cg.printf("%s(", m_name.c_str());
func->outputCPPParamsCall(cg, ar, true);
if (m_params) {
cg.printf(",");
m_params->outputCPP(cg, ar);
}
cg.printf(")");
if (linemap) cg.printf(")");
return;
}
}
break;
case FunctionExistsFunction:
case ClassExistsFunction:
case InterfaceExistsFunction:
{
bool literalString = false;
string symbol;
if (m_params && m_params->getCount() == 1) {
ExpressionPtr value = (*m_params)[0];
if (value->isScalar()) {
ScalarExpressionPtr name =
dynamic_pointer_cast<ScalarExpression>(value);
if (name && name->isLiteralString()) {
literalString = true;
symbol = name->getLiteralString();
}
}
}
if (literalString) {
switch (m_type) {
case FunctionExistsFunction:
{
const std::string &lname = Util::toLower(symbol);
bool dynInvoke = Option::DynamicInvokeFunctions.find(lname) !=
Option::DynamicInvokeFunctions.end();
if (!dynInvoke) {
FunctionScopePtr func = ar->findFunction(lname);
if (func) {
if (!func->isDynamic()) {
if (func->isRedeclaring()) {
const char *name = func->getName().c_str();
cg.printf("(%s->%s%s != invoke_failed_%s)",
cg.getGlobals(ar), Option::InvokePrefix,
//.........这里部分代码省略.........