Refactor HipHopSyntax and HackMode to play nice

Esse commit está contido em:
Drew Paroski
2013-05-08 21:42:45 -07:00
commit de Sara Golemon
commit a8d84e2f21
37 arquivos alterados com 960 adições e 937 exclusões
+6 -5
Ver Arquivo
@@ -5245,9 +5245,10 @@ void EmitterVisitor::emitPostponedMeths() {
dynamic_pointer_cast<ConstantExpression>(par->defaultValue());
bool nullable = ce && ce->isNull();
TypeConstraint tc =
TypeConstraint(StringData::GetStaticString(
par->getOriginalTypeHint()),
nullable);
TypeConstraint(
StringData::GetStaticString(par->getOriginalTypeHint()),
nullable,
par->hhType());
pi.setTypeConstraint(tc);
TRACE(1, "Added constraint to %s\n", fe->name()->data());
}
@@ -7375,7 +7376,7 @@ static void emitSystemLib() {
AnalysisResultPtr ar(new AnalysisResult());
Scanner scanner(slib.c_str(), slib.size(),
RuntimeOption::ScannerType, "/:systemlib.php");
RuntimeOption::GetScannerType(), "/:systemlib.php");
Parser parser(scanner, "/:systemlib.php", ar, slib.size());
parser.parse();
FileScopePtr fsp = parser.getFileScope();
@@ -7509,7 +7510,7 @@ Unit* hphp_compiler_parse(const char* code, int codeLen, const MD5& md5,
}
AnalysisResultPtr ar(new AnalysisResult());
Scanner scanner(code, codeLen, RuntimeOption::ScannerType, filename);
Scanner scanner(code, codeLen, RuntimeOption::GetScannerType(), filename);
Parser parser(scanner, filename, ar, codeLen);
parser.parse();
FileScopePtr fsp = parser.getFileScope();
+16 -12
Ver Arquivo
@@ -49,28 +49,32 @@ TypePtr Type::Any (new Type(Type::KindOfAny ));
TypePtr Type::Some (new Type(Type::KindOfSome ));
Type::TypePtrMap Type::s_TypeHintTypes;
Type::TypePtrMap Type::s_HHTypeHintTypes;
void Type::InitTypeHintMap() {
assert(s_TypeHintTypes.empty());
assert(s_HHTypeHintTypes.empty());
s_TypeHintTypes["array"] = Type::Array;
if (Option::EnableHipHopSyntax) {
s_TypeHintTypes["bool"] = Type::Boolean;
s_TypeHintTypes["boolean"] = Type::Boolean;
s_TypeHintTypes["int"] = Type::Int64;
s_TypeHintTypes["integer"] = Type::Int64;
s_TypeHintTypes["real"] = Type::Double;
s_TypeHintTypes["double"] = Type::Double;
s_TypeHintTypes["float"] = Type::Double;
s_TypeHintTypes["string"] = Type::String;
}
s_HHTypeHintTypes["array"] = Type::Array;
s_HHTypeHintTypes["bool"] = Type::Boolean;
s_HHTypeHintTypes["boolean"] = Type::Boolean;
s_HHTypeHintTypes["int"] = Type::Int64;
s_HHTypeHintTypes["integer"] = Type::Int64;
s_HHTypeHintTypes["real"] = Type::Double;
s_HHTypeHintTypes["double"] = Type::Double;
s_HHTypeHintTypes["float"] = Type::Double;
s_HHTypeHintTypes["string"] = Type::String;
}
const Type::TypePtrMap &Type::GetTypeHintTypes() {
return s_TypeHintTypes;
const Type::TypePtrMap &Type::GetTypeHintTypes(bool hhType) {
return hhType ? s_HHTypeHintTypes : s_TypeHintTypes;
}
void Type::ResetTypeHintTypes() {
s_TypeHintTypes.clear();
s_HHTypeHintTypes.clear();
}
TypePtr Type::CreateObjectType(const std::string &classname) {
+2 -1
Ver Arquivo
@@ -102,7 +102,7 @@ public:
static TypePtr Some;
typedef hphp_string_imap<TypePtr> TypePtrMap;
static const TypePtrMap &GetTypeHintTypes();
static const TypePtrMap &GetTypeHintTypes(bool hhType);
/**
* Uncertain types: types that are ambiguous yet.
@@ -267,6 +267,7 @@ private:
static void ResetTypeHintTypes();
static TypePtrMap s_TypeHintTypes;
static TypePtrMap s_HHTypeHintTypes;
const KindOf m_kindOf;
const std::string m_name;
+2 -2
Ver Arquivo
@@ -334,7 +334,7 @@ bool BuiltinSymbols::Load(AnalysisResultPtr ar, bool extOnly /* = false */) {
string slib = get_systemlib();
Scanner scanner(slib.c_str(), slib.size(),
Option::ScannerType, "systemlib.php");
Option::GetScannerType(), "systemlib.php");
Compiler::Parser parser(scanner, "systemlib.php", ar);
if (!parser.parse()) {
Logger::Error("Unable to parse systemlib.php: %s",
@@ -406,7 +406,7 @@ AnalysisResultPtr BuiltinSymbols::LoadGlobalSymbols(const char *fileName) {
fileName = s_strings.add(phpFileName.c_str());
try {
Scanner scanner(fileName, Option::ScannerType);
Scanner scanner(fileName, Option::GetScannerType());
Compiler::Parser parser(scanner, baseName, ar);
if (!parser.parse()) {
assert(false);
+1 -1
Ver Arquivo
@@ -702,7 +702,7 @@ int lintTarget(const CompilerOptions &po) {
for (unsigned int i = 0; i < po.inputs.size(); i++) {
string filename = po.inputDir + "/" + po.inputs[i];
try {
Scanner scanner(filename.c_str(), Option::ScannerType);
Scanner scanner(filename.c_str(), Option::GetScannerType());
Compiler::Parser parser(scanner, filename.c_str(),
AnalysisResultPtr(new AnalysisResult()));
if (!parser.parse()) {
@@ -32,10 +32,10 @@ using namespace HPHP;
ParameterExpression::ParameterExpression
(EXPRESSION_CONSTRUCTOR_PARAMETERS,
TypeAnnotationPtr type, const std::string &name, bool ref,
TypeAnnotationPtr type, bool hhType, const std::string &name, bool ref,
ExpressionPtr defaultValue, ExpressionPtr attributeList)
: Expression(EXPRESSION_CONSTRUCTOR_PARAMETER_VALUES(ParameterExpression)),
m_originalType(type), m_name(name), m_ref(ref),
m_originalType(type), m_name(name), m_hhType(hhType), m_ref(ref),
m_defaultValue(defaultValue), m_attributeList(attributeList) {
m_type = Util::toLower(type ? type->simpleName() : "");
if (m_defaultValue) {
@@ -150,7 +150,7 @@ TypePtr ParameterExpression::getTypeSpecForClass(AnalysisResultPtr ar,
TypePtr ParameterExpression::getTypeSpec(AnalysisResultPtr ar,
bool forInference) {
const Type::TypePtrMap &types = Type::GetTypeHintTypes();
const Type::TypePtrMap &types = Type::GetTypeHintTypes(m_hhType);
Type::TypePtrMap::const_iterator iter;
TypePtr ret;
@@ -231,7 +231,7 @@ void ParameterExpression::compatibleDefault() {
const char* msg = "Default value for parameter %s with type %s "
"needs to have the same type as the type hint %s";
if (Option::EnableHipHopSyntax) {
if (m_hhType) {
// Normally a named type like 'int' is compatable with Int but not integer
// Since the default value's type is inferred from the value itself it is
// ok to compare against the lower case version of the type hint in hint
+4 -1
Ver Arquivo
@@ -31,7 +31,8 @@ DECLARE_BOOST_TYPES(TypeAnnotation);
class ParameterExpression : public Expression {
public:
ParameterExpression(EXPRESSION_CONSTRUCTOR_PARAMETERS,
TypeAnnotationPtr type, const std::string &name,
TypeAnnotationPtr type, bool hhType,
const std::string &name,
bool ref, ExpressionPtr defaultValue,
ExpressionPtr attributeList);
@@ -56,12 +57,14 @@ public:
void parseHandler(ClassScopePtr cls);
void compatibleDefault();
void fixupSelfAndParentTypehints(ClassScopePtr cls);
bool hhType() { return m_hhType; }
private:
TypePtr getTypeSpecForClass(AnalysisResultPtr ar, bool forInference);
std::string m_type;
TypeAnnotationPtr m_originalType;
std::string m_name;
bool m_hhType;
bool m_ref;
ExpressionPtr m_defaultValue;
ExpressionPtr m_attributeList;
+8 -10
Ver Arquivo
@@ -120,9 +120,16 @@ bool Option::EnableShortTags = true;
bool Option::EnableAspTags = false;
bool Option::EnableXHP = true;
bool Option::EnableFinallyStatement = false;
int Option::ScannerType = Scanner::AllowShortTags;
int Option::ParserThreadCount = 0;
int Option::GetScannerType() {
int type = 0;
if (EnableShortTags) type |= Scanner::AllowShortTags;
if (EnableHipHopSyntax) type |= Scanner::AllowHipHopSyntax;
if (EnableAspTags) type |= Scanner::AllowAspTags;
return type;
}
int Option::InvokeFewArgsCount = 6;
bool Option::InvokeWithSpecificArgs = true;
bool Option::FlattenInvoke = true;
@@ -277,17 +284,8 @@ void Option::Load(Hdf &config) {
EnableHipHopExperimentalSyntax =
config["EnableHipHopExperimentalSyntax"].getBool();
EnableShortTags = config["EnableShortTags"].getBool(true);
if (EnableShortTags) ScannerType |= Scanner::AllowShortTags;
else ScannerType &= ~Scanner::AllowShortTags;
if (EnableHipHopExperimentalSyntax) {
ScannerType |= Scanner::EnableHipHopKeywords;
} else {
ScannerType &= ~Scanner::EnableHipHopKeywords;
}
EnableAspTags = config["EnableAspTags"].getBool();
if (EnableAspTags) ScannerType |= Scanner::AllowAspTags;
else ScannerType &= ~Scanner::AllowAspTags;
EnableXHP = config["EnableXHP"].getBool(true);
+2 -1
Ver Arquivo
@@ -235,9 +235,10 @@ public:
static bool EnableAspTags;
static bool EnableXHP;
static bool EnableFinallyStatement;
static int ScannerType;
static int ParserThreadCount;
static int GetScannerType();
/**
* "Dynamic" means a function or a method can be invoked dynamically.
* "Volatile" means a class or a function can be declared dynamically.
+1 -1
Ver Arquivo
@@ -297,7 +297,7 @@ bool Package::parseImpl(const char *fileName) {
int lines = 0;
try {
Logger::Verbose("parsing %s ...", fullPath.c_str());
Scanner scanner(fullPath.c_str(), Option::ScannerType, true);
Scanner scanner(fullPath.c_str(), Option::GetScannerType(), true);
Compiler::Parser parser(scanner, fileName, m_ar, sb.st_size);
parser.parse();
lines = parser.line1();
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+10 -12
Ver Arquivo
@@ -141,7 +141,7 @@ StatementListPtr Parser::ParseString(CStrRef input, AnalysisResultPtr ar,
if (!fileName || !*fileName) fileName = "string";
int len = input.size();
Scanner scanner(input.data(), len, Option::ScannerType, fileName, true);
Scanner scanner(input.data(), len, Option::GetScannerType(), fileName, true);
Parser parser(scanner, fileName, ar, len);
parser.m_lambdaMode = lambdaMode;
if (parser.parse()) {
@@ -209,10 +209,6 @@ bool Parser::enableXHP() {
return Option::EnableXHP;
}
bool Parser::enableHipHopSyntax() {
return Option::EnableHipHopSyntax;
}
bool Parser::enableFinallyStatement() {
return Option::EnableFinallyStatement;
}
@@ -686,7 +682,7 @@ void Parser::onQOp(Token &out, Token &exprCond, Token *expYes, Token &expNo) {
}
void Parser::onArray(Token &out, Token &pairs, int op /* = T_ARRAY */) {
if (op != T_ARRAY && !Option::EnableHipHopSyntax) {
if (op != T_ARRAY && !m_scanner.hipHopSyntaxEnabled()) {
PARSE_ERROR("Typed collection is not enabled");
return;
}
@@ -922,16 +918,18 @@ void Parser::onParam(Token &out, Token *params, Token &type, Token &var,
attrList = dynamic_pointer_cast<ExpressionList>(attr->exp);
}
TypeAnnotationPtr typeAnnotation = type.typeAnnotation;
expList->addElement(NEW_EXP(ParameterExpression, typeAnnotation, var->text(),
expList->addElement(NEW_EXP(ParameterExpression, typeAnnotation,
m_scanner.hipHopSyntaxEnabled(), var->text(),
ref, defValue ? defValue->exp : ExpressionPtr(),
attrList));
out->exp = expList;
}
void Parser::onClassStart(int type, Token &name) {
const Type::TypePtrMap& typeHintTypes =
Type::GetTypeHintTypes(m_scanner.hipHopSyntaxEnabled());
if (name.text() == "self" || name.text() == "parent" ||
Type::GetTypeHintTypes().find(name.text()) !=
Type::GetTypeHintTypes().end()) {
typeHintTypes.find(name.text()) != typeHintTypes.end()) {
PARSE_ERROR("Cannot use '%s' as class name as it is reserved",
name.text().c_str());
}
@@ -1589,8 +1587,8 @@ void Parser::onClosureParam(Token &out, Token *params, Token &param,
expList = NEW_EXP0(ExpressionList);
}
expList->addElement(NEW_EXP(ParameterExpression, TypeAnnotationPtr(),
param->text(), ref,
ExpressionPtr(), ExpressionPtr()));
m_scanner.hipHopSyntaxEnabled(), param->text(),
ref, ExpressionPtr(), ExpressionPtr()));
out->exp = expList;
}
@@ -1778,7 +1776,7 @@ TStatementPtr Parser::extractStatement(ScannerToken *stmt) {
bool Parser::hasType(Token &type) {
if (!type.text().empty()) {
if (!Option::EnableHipHopSyntax && !m_scanner.isHackMode()) {
if (!m_scanner.hipHopSyntaxEnabled()) {
PARSE_ERROR("Type hint is not enabled");
return false;
}
-1
Ver Arquivo
@@ -113,7 +113,6 @@ public:
bool parse();
virtual void error(const char* fmt, ...);
virtual bool enableXHP();
virtual bool enableHipHopSyntax();
virtual bool enableFinallyStatement();
IMPLEMENT_XHP_ATTRIBUTES;
+8 -8
Ver Arquivo
@@ -366,11 +366,18 @@ bool RuntimeOption::EnableEmitSwitch = true;
bool RuntimeOption::EnableEmitterStats = true;
bool RuntimeOption::EnableInstructionCounts = false;
bool RuntimeOption::CheckSymLink = false;
int RuntimeOption::ScannerType = 0;
int RuntimeOption::MaxUserFunctionId = (2 * 65536);
bool RuntimeOption::EnableFinallyStatement = false;
bool RuntimeOption::EnableArgsInBacktraces = true;
int RuntimeOption::GetScannerType() {
int type = 0;
if (EnableHipHopSyntax) type |= Scanner::AllowHipHopSyntax;
if (EnableShortTags) type |= Scanner::AllowShortTags;
if (EnableAspTags) type |= Scanner::AllowAspTags;
return type;
}
// Initializers for Eval flags.
static inline bool evalJitDefault() {
// --mode server or --mode daemon
@@ -1114,13 +1121,6 @@ void RuntimeOption::Load(Hdf &config, StringVec *overwrites /* = NULL */,
MaxUserFunctionId = eval["MaxUserFunctionId"].getInt32(2 * 65536);
CheckSymLink = eval["CheckSymLink"].getBool(false);
if (EnableHipHopSyntax) ScannerType |= Scanner::EnableHipHopKeywords;
else ScannerType &= ~Scanner::EnableHipHopKeywords;
if (EnableShortTags) ScannerType |= Scanner::AllowShortTags;
else ScannerType &= ~Scanner::AllowShortTags;
if (EnableAspTags) ScannerType |= Scanner::AllowAspTags;
else ScannerType &= ~Scanner::AllowAspTags;
EnableAlternative = eval["EnableAlternative"].getInt32(0);
EnableFinallyStatement = eval["EnableFinallyStatement"].getBool();
+2 -1
Ver Arquivo
@@ -369,11 +369,12 @@ public:
static bool EnableEmitterStats;
static bool EnableInstructionCounts;
static bool CheckSymLink;
static int ScannerType;
static int MaxUserFunctionId;
static bool EnableFinallyStatement;
static bool EnableArgsInBacktraces;
static int GetScannerType();
static std::set<std::string, stdltistr> DynamicInvokeFunctions;
#define EVALFLAGS() \
+1 -1
Ver Arquivo
@@ -303,7 +303,7 @@ Array f_sys_getloadavg() {
Array f_token_get_all(CStrRef source) {
Scanner scanner(source.data(), source.size(),
Scanner::AllowShortTags | Scanner::ReturnAllTokens);
RuntimeOption::GetScannerType() | Scanner::ReturnAllTokens);
ScannerToken tok;
Location loc;
int tokid;
+4 -5
Ver Arquivo
@@ -49,22 +49,21 @@ struct Func {
template<class SerDe>
void serde(SerDe& sd) {
const StringData* tcName = m_typeConstraint.typeName();
bool tcNullable = m_typeConstraint.nullable();
const StringData* tcName = m_typeConstraint.typeName();
TypeConstraint::Flags tcFlags = m_typeConstraint.flags();
sd(m_builtinType)
(m_funcletOff)
(m_defVal)
(m_phpCode)
(tcName)
(tcNullable)
(tcFlags)
(m_userAttributes)
(m_userType)
;
if (SerDe::deserializing) {
setTypeConstraint(TypeConstraint(tcName,
tcNullable));
setTypeConstraint(TypeConstraint(tcName, tcFlags));
}
}
+8 -8
Ver Arquivo
@@ -32,9 +32,9 @@ TRACE_SET_MOD(runtime);
TypeConstraint::TypeMap TypeConstraint::s_typeNamesToTypes;
TypeConstraint::TypeConstraint(const StringData* typeName /* = NULL */,
bool nullable /* = false */)
: m_nullable(nullable), m_typeName(typeName), m_namedEntity(0) {
void TypeConstraint::init() {
const StringData* typeName = m_typeName;
if (UNLIKELY(s_typeNamesToTypes.empty())) {
const struct Pair {
const StringData* name;
@@ -71,7 +71,7 @@ TypeConstraint::TypeConstraint(const StringData* typeName /* = NULL */,
Type dtype;
TRACE(5, "TypeConstraint: this %p type %s, nullable %d\n",
this, typeName->data(), nullable);
this, typeName->data(), nullable());
if (!mapGet(s_typeNamesToTypes, typeName, &dtype)) {
TRACE(5, "TypeConstraint: this %p no such type %s, treating as object\n",
this, typeName->data());
@@ -80,8 +80,8 @@ TypeConstraint::TypeConstraint(const StringData* typeName /* = NULL */,
TRACE(5, "TypeConstraint: NamedEntity: %p\n", m_namedEntity);
return;
}
if (RuntimeOption::EnableHipHopSyntax || dtype.m_dt == KindOfArray ||
dtype.isParent() || dtype.isSelf()) {
if (hhType() || dtype.m_dt == KindOfArray || dtype.isParent() ||
dtype.isSelf()) {
m_type = dtype;
} else {
m_type = { KindOfObject, Precise };
@@ -140,7 +140,7 @@ TypeConstraint::check(const TypedValue* tv, const Func* func) const {
if (tv->m_type == KindOfRef) {
tv = tv->m_data.pref->tv();
}
if (m_nullable && IS_NULL_TYPE(tv->m_type)) return true;
if (nullable() && IS_NULL_TYPE(tv->m_type)) return true;
if (tv->m_type == KindOfObject) {
if (!isObjectOrTypedef()) return false;
@@ -185,7 +185,7 @@ bool
TypeConstraint::checkPrimitive(DataType dt) const {
assert(m_type.m_dt != KindOfObject);
assert(dt != KindOfRef);
if (m_nullable && IS_NULL_TYPE(dt)) return true;
if (nullable() && IS_NULL_TYPE(dt)) return true;
return equivDataTypes(m_type.m_dt, dt);
}
+25 -3
Ver Arquivo
@@ -30,6 +30,13 @@ namespace VM {
class Func;
class TypeConstraint {
public:
enum Flags {
NoFlags = 0x0,
Nullable = 0x1,
HHType = 0x2
};
protected:
enum MetaType {
Precise,
@@ -57,24 +64,39 @@ protected:
// when this is set to KindOfObject we may have to look up a typedef
// name and test for a different DataType.
Type m_type;
bool m_nullable;
Flags m_flags;
const StringData* m_typeName;
const NamedEntity* m_namedEntity;
typedef hphp_hash_map<const StringData*, Type,
string_data_hash, string_data_isame> TypeMap;
static TypeMap s_typeNamesToTypes;
void init();
public:
void verifyFail(const Func* func, int paramNum, const TypedValue* tv) const;
explicit TypeConstraint(const StringData* typeName=nullptr, bool nullable=false);
explicit TypeConstraint(const StringData* typeName, Flags flags)
: m_flags(flags), m_typeName(typeName), m_namedEntity(0) {
init();
}
explicit TypeConstraint(const StringData* typeName = nullptr,
bool nullable = false, bool hhType = false)
: m_flags(NoFlags), m_typeName(typeName), m_namedEntity(0) {
if (nullable) m_flags = (Flags)(m_flags | Nullable);
if (hhType) m_flags = (Flags)(m_flags | HHType);
init();
}
bool exists() const { return m_typeName; }
const StringData* typeName() const { return m_typeName; }
const NamedEntity* namedEntity() const { return m_namedEntity; }
bool nullable() const { return m_nullable; }
bool nullable() const { return m_flags & Nullable; }
bool hhType() const { return m_flags & HHType; }
Flags flags() const { return m_flags; }
bool isSelf() const {
return m_type.isSelf();
+4
Ver Arquivo
@@ -0,0 +1,4 @@
<?php
function foo(Vector<int> $a) {}
function bar(string $x) { echo $x . "\n"; }
bar("Done");
+1
Ver Arquivo
@@ -0,0 +1 @@
Done
@@ -0,0 +1 @@
-vEnableHipHopSyntax=1
+1
Ver Arquivo
@@ -0,0 +1 @@
-vEval.EnableHipHopSyntax=1
+4
Ver Arquivo
@@ -0,0 +1,4 @@
<?hh
function foo(Vector<int> $a) {}
function bar(string $x) { echo $x . "\n"; }
bar("Done");
+1
Ver Arquivo
@@ -0,0 +1 @@
Done
+7
Ver Arquivo
@@ -0,0 +1,7 @@
<?php
eval(<<<'EOD'
function foo(Vector<int> $a) {}
function bar(string $x) { echo $x . "\n"; }
bar("Done");
EOD
);
+1
Ver Arquivo
@@ -0,0 +1 @@
Done
@@ -0,0 +1 @@
-vEnableHipHopSyntax=1
+1
Ver Arquivo
@@ -0,0 +1 @@
-vEval.EnableHipHopSyntax=1
-3
Ver Arquivo
@@ -387,9 +387,6 @@ bool TestParserExpr::TestClosure() {
}
bool TestParserExpr::TestXHP() {
//HPHP::Option::ScannerType |= HPHP::Scanner::PreprocessXHP;
//HPHP::RuntimeOption::ScannerType |= HPHP::Scanner::PreprocessXHP;
// basics
V("<?php $x = <thing />;",
"$x = new xhp_thing(array(), array());\n");
+3 -3
Ver Arquivo
@@ -32,7 +32,7 @@
#define HH_ONLY_KEYWORD(tok) do { \
SETTOKEN; \
return _scanner->hipHopKeywordsEnabled() ? tok : T_STRING; \
return _scanner->hipHopSyntaxEnabled() ? tok : T_STRING; \
} while (0)
#define IS_LABEL_START(c) \
@@ -435,7 +435,7 @@ BACKQUOTE_CHARS ("{"*([^$`\\{]|("\\"{ANY_CHAR}))|{BACKQUOTE_LITERAL_DOLLAR})
}
yyless(1);
STEPPOS;
if (_scanner->isHackMode() && (ntt & NextTokenType::TypeListMaybe)) {
if (_scanner->hipHopSyntaxEnabled() && (ntt & NextTokenType::TypeListMaybe)) {
// Return T_UNRESOLVED_LT; the scanner will inspect subseqent tokens
// to resolve this.
return T_UNRESOLVED_LT;
@@ -445,7 +445,7 @@ BACKQUOTE_CHARS ("{"*([^$`\\{]|("\\"{ANY_CHAR}))|{BACKQUOTE_LITERAL_DOLLAR})
<ST_IN_SCRIPTING>"<" {
STEPPOS;
if (_scanner->isHackMode()) {
if (_scanner->hipHopSyntaxEnabled()) {
int ntt = getNextTokenType(_scanner->lastToken());
if (ntt & NextTokenType::TypeListMaybe) {
// Return T_UNRESOLVED_LT; the scanner will inspect subseqent tokens
+23 -30
Ver Arquivo
@@ -248,7 +248,7 @@ void create_generator(Parser *_p, Token &out, Token &params,
///////////////////////////////////////////////////////////////////////////////
static void user_attribute_check(Parser *_p) {
if (!_p->enableHipHopSyntax()) {
if (!_p->scanner().hipHopSyntaxEnabled()) {
HPHP_PARSER_ERROR("User attributes are not enabled", _p);
}
}
@@ -646,17 +646,10 @@ static void xhp_children_stmt(Parser *_p, Token &out, Token &children) {
}
}
/* This is called from hack productions (hh_*) to throw an
* error if we're not in hack mode */
static void only_in_hack_mode(Parser *_p) {
if (!_p->scanner().isHackMode()) {
HPHP_PARSER_ERROR("Syntax only allowed in hack mode", _p);
}
}
static void only_in_hphp_syntax(Parser *_p) {
if (!_p->enableHipHopSyntax()) {
HPHP_PARSER_ERROR("Syntax only allowed with -v Eval.EnableHipHopSyntax=true", _p);
static void only_in_hh_syntax(Parser *_p) {
if (!_p->scanner().hipHopSyntaxEnabled()) {
HPHP_PARSER_ERROR(
"Syntax only allowed with -v Eval.EnableHipHopSyntax=true", _p);
}
}
@@ -1238,10 +1231,10 @@ new_else_single:
parameter_list:
non_empty_parameter_list ',' T_VARARG
{ only_in_hack_mode(_p); $$ = $1; }
{ only_in_hh_syntax(_p); $$ = $1; }
| non_empty_parameter_list
possible_comma_in_hphp_syntax { $$ = $1;}
| T_VARARG { only_in_hack_mode(_p); $$.reset(); }
| T_VARARG { only_in_hh_syntax(_p); $$.reset(); }
| { $$.reset();}
;
@@ -1680,7 +1673,7 @@ static_shape_pair_list:
;
shape_literal:
T_SHAPE '(' shape_pair_list ')' { only_in_hack_mode(_p);
T_SHAPE '(' shape_pair_list ')' { only_in_hh_syntax(_p);
_p->onArray($$, $3, T_ARRAY); }
;
@@ -1939,7 +1932,7 @@ static_scalar:
| T_ARRAY '('
static_array_pair_list ')' { _p->onArray($$,$3,T_ARRAY); }
| T_SHAPE '('
static_shape_pair_list ')' { only_in_hack_mode(_p);
static_shape_pair_list ')' { only_in_hh_syntax(_p);
_p->onArray($$,$3,T_ARRAY); }
| static_class_constant { $$ = $1;}
| static_collection_literal { $$ = $1;}
@@ -1976,7 +1969,7 @@ possible_comma:
| { $$.reset();}
;
possible_comma_in_hphp_syntax:
',' { only_in_hphp_syntax(_p); $$.reset();}
',' { only_in_hh_syntax(_p); $$.reset();}
| { $$.reset();}
;
@@ -2016,7 +2009,7 @@ static_scalar_ae:
static_array_pair_list_ae ')' { _p->onArray($$,$3,T_ARRAY);}
| '[' static_array_pair_list_ae ']' { _p->onArray($$,$2,T_ARRAY);}
| T_SHAPE '('
static_shape_pair_list_ae ')' { only_in_hack_mode(_p);
static_shape_pair_list_ae ')' { only_in_hh_syntax(_p);
_p->onArray($$,$3,T_ARRAY); }
;
@@ -2342,14 +2335,14 @@ class_constant:
hh_typedef_statement:
T_TYPE hh_name_with_typevar
'=' hh_type ';' { only_in_hack_mode(_p);
'=' hh_type ';' { only_in_hh_syntax(_p);
_p->onTypedef($$, $2, $4);
_p->popTypeScope(); }
;
hh_name_with_type: /* foo -> int foo */
ident { $$ = $1; }
| hh_type ident { only_in_hack_mode(_p); $$ = $2; }
| hh_type ident { only_in_hh_syntax(_p); $$ = $2; }
;
hh_name_with_typevar: /* foo -> foo<X,Y>; this adds a typevar scope
@@ -2360,13 +2353,13 @@ hh_name_with_typevar: /* foo -> foo<X,Y>; this adds a typevar scope
T_TYPELIST_LT
hh_typevar_list
T_TYPELIST_GT { _p->pushTypeScope(); $$ = $1;
only_in_hack_mode(_p); }
only_in_hh_syntax(_p); }
;
hh_typeargs_opt:
T_TYPELIST_LT
hh_type_list
T_TYPELIST_GT { only_in_hack_mode(_p); $$ = $2; }
T_TYPELIST_GT { only_in_hh_syntax(_p); $$ = $2; }
| { $$.reset(); }
;
@@ -2387,7 +2380,7 @@ hh_func_type_list:
hh_opt_return_type:
{ $$.reset(); }
| ':' hh_type { only_in_hack_mode(_p); $$ = $2; }
| ':' hh_type { only_in_hh_syntax(_p); $$ = $2; }
;
hh_typevar_list:
@@ -2425,7 +2418,7 @@ hh_shape_member_list:
hh_shape_type:
T_SHAPE
'(' hh_shape_member_list ')' { only_in_hack_mode(_p);
'(' hh_shape_member_list ')' { only_in_hh_syntax(_p);
$$.setText("array"); }
;
@@ -2433,10 +2426,10 @@ hh_shape_type:
hh_type:
/* double-optional types will be rejected by the typechecker; we
* already allow plenty of nonsense types anyway */
'?' hh_type { only_in_hack_mode(_p);
'?' hh_type { only_in_hh_syntax(_p);
_p->onTypeSpecialization($2, '?');
$$ = $2; }
| '@' hh_type { only_in_hack_mode(_p);
| '@' hh_type { only_in_hh_syntax(_p);
_p->onTypeSpecialization($2, '@');
$$ = $2; }
| namespace_string hh_typeargs_opt { _p->onTypeAnnotation($$, $1, $2); }
@@ -2445,11 +2438,11 @@ hh_type:
_p->onTypeAnnotation($$, $1, t); }
| hh_shape_type { $$ = $1; }
| T_ARRAY T_TYPELIST_LT hh_type
T_TYPELIST_GT { only_in_hack_mode(_p);
T_TYPELIST_GT { only_in_hh_syntax(_p);
$1.setText("array");
_p->onTypeAnnotation($$, $1, $3); }
| T_ARRAY T_TYPELIST_LT hh_type ','
hh_type T_TYPELIST_GT { only_in_hack_mode(_p);
hh_type T_TYPELIST_GT { only_in_hh_syntax(_p);
_p->onTypeList($3, $5);
$1.setText("array");
_p->onTypeAnnotation($$, $1, $3); }
@@ -2459,11 +2452,11 @@ hh_type:
_p->onTypeSpecialization($$, 'x'); }
| '(' T_FUNCTION
'(' hh_func_type_list ')'
':' hh_type ')' { only_in_hack_mode(_p);
':' hh_type ')' { only_in_hh_syntax(_p);
_p->onTypeList($7, $4);
_p->onTypeAnnotation($$, $2, $7);
_p->onTypeSpecialization($$, 'f'); }
| '(' hh_type_list ',' hh_type ')' { only_in_hack_mode(_p);
| '(' hh_type_list ',' hh_type ')' { only_in_hh_syntax(_p);
_p->onTypeList($2, $4);
Token t; t.reset(); t.setText("array");
_p->onTypeAnnotation($$, t, $2);
+3 -3
Ver Arquivo
@@ -77821,7 +77821,7 @@ static yyconst yy_state_type yy_NUL_trans[2432] =
#define HH_ONLY_KEYWORD(tok) do { \
SETTOKEN; \
return _scanner->hipHopKeywordsEnabled() ? tok : T_STRING; \
return _scanner->hipHopSyntaxEnabled() ? tok : T_STRING; \
} while (0)
#define IS_LABEL_START(c) \
@@ -78974,7 +78974,7 @@ YY_RULE_SETUP
}
yyless(1);
STEPPOS;
if (_scanner->isHackMode() && (ntt & NextTokenType::TypeListMaybe)) {
if (_scanner->hipHopSyntaxEnabled() && (ntt & NextTokenType::TypeListMaybe)) {
// Return T_UNRESOLVED_LT; the scanner will inspect subseqent tokens
// to resolve this.
return T_UNRESOLVED_LT;
@@ -78987,7 +78987,7 @@ YY_RULE_SETUP
#line 446 "hphp.ll"
{
STEPPOS;
if (_scanner->isHackMode()) {
if (_scanner->hipHopSyntaxEnabled()) {
int ntt = getNextTokenType(_scanner->lastToken());
if (ntt & NextTokenType::TypeListMaybe) {
// Return T_UNRESOLVED_LT; the scanner will inspect subseqent tokens
-5
Ver Arquivo
@@ -113,11 +113,6 @@ public:
*/
virtual bool enableXHP() = 0;
/**
* Check if HipHop syntax is enabled.
*/
virtual bool enableHipHopSyntax() = 0;
/**
* Public accessors.
*/
+3 -6
Ver Arquivo
@@ -171,7 +171,7 @@ public:
AllowShortTags = 0x01, // allow <?
AllowAspTags = 0x02, // allow <% %>
ReturnAllTokens = 0x08, // return comments and whitespaces
EnableHipHopKeywords = 0x10, // allow hip-hop specific reserved words
AllowHipHopSyntax = 0x10, // allow hip-hop specific reserved words
};
public:
@@ -285,11 +285,8 @@ public:
return m_isHackMode;
}
/*
* Returns: whether HipHop-extension keywords are enabled.
*/
bool hipHopKeywordsEnabled() const {
return m_type & EnableHipHopKeywords;
bool hipHopSyntaxEnabled() const {
return (m_type & AllowHipHopSyntax) || m_isHackMode;
}
int getLookaheadLtDepth() {
+1 -1
Ver Arquivo
@@ -56,7 +56,7 @@ int main(int argc, char** argv) try {
using HPHP::Scanner;
using HPHP::Test::Parser;
Scanner scan(in, Scanner::AllowShortTags |
Scanner::EnableHipHopKeywords);
Scanner::AllowHipHopSyntax);
Parser parser(scan, argv[1]);
parser.parse();
} catch (const std::exception& e) {
-1
Ver Arquivo
@@ -139,7 +139,6 @@ struct Parser : ParserBase {
void* extractStatement(ScannerToken*) { X(); return nullptr; }
bool enableFinallyStatement() { return true; }
bool enableHipHopSyntax() { return true; }
bool enableXHP() { return true; }
IMPLEMENT_XHP_ATTRIBUTES;