Add ParseNode::as<T>(). Bug 788220, r=luke.

--HG--
extra : rebase_source : 41510e3bdc3f13f891ab0019c5c467534d0aca50
This commit is contained in:
Jason Orendorff 2012-09-06 07:58:29 -05:00
parent 4683090a74
commit 543e60fb97
5 changed files with 94 additions and 65 deletions

View File

@ -6161,11 +6161,11 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
break;
case PNK_BREAK:
ok = EmitBreak(cx, bce, pn->asBreakStatement().label());
ok = EmitBreak(cx, bce, pn->as<BreakStatement>().label());
break;
case PNK_CONTINUE:
ok = EmitContinue(cx, bce, pn->asContinueStatement().label());
ok = EmitContinue(cx, bce, pn->as<ContinueStatement>().label());
break;
case PNK_WITH:
@ -6280,7 +6280,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
break;
case PNK_CONDITIONAL:
ok = EmitConditionalExpression(cx, bce, pn->asConditionalExpression());
ok = EmitConditionalExpression(cx, bce, pn->as<ConditionalExpression>());
break;
case PNK_OR:
@ -6616,7 +6616,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
break;
case PNK_XMLPI:
if (!EmitXMLProcessingInstruction(cx, bce, pn->asXMLProcessingInstruction()))
if (!EmitXMLProcessingInstruction(cx, bce, pn->as<XMLProcessingInstruction>()))
return false;
break;
#endif /* JS_HAS_XML_SUPPORT */

View File

@ -245,7 +245,7 @@ FoldXMLConstants(JSContext *cx, ParseNode *pn, Parser *parser)
break;
case PNK_XMLPI: {
XMLProcessingInstruction &pi = pn2->asXMLProcessingInstruction();
XMLProcessingInstruction &pi = pn2->as<XMLProcessingInstruction>();
str = js_MakeXMLPIString(cx, pi.target(), pi.data());
if (!str)
return false;

View File

@ -879,13 +879,17 @@ struct ParseNode {
inline bool isConstant();
/* Casting operations. */
inline BreakStatement &asBreakStatement();
inline ContinueStatement &asContinueStatement();
#if JS_HAS_XML_SUPPORT
inline XMLProcessingInstruction &asXMLProcessingInstruction();
#endif
inline ConditionalExpression &asConditionalExpression();
inline PropertyAccess &asPropertyAccess();
template <class NodeType>
inline NodeType &as() {
JS_ASSERT(NodeType::test(*this));
return *static_cast<NodeType *>(this);
}
template <class NodeType>
inline const NodeType &as() const {
JS_ASSERT(NodeType::test(*this));
return *static_cast<const NodeType *>(this);
}
#ifdef DEBUG
inline void dump(int indent);
@ -894,7 +898,11 @@ struct ParseNode {
struct NullaryNode : public ParseNode {
static inline NullaryNode *create(ParseNodeKind kind, Parser *parser) {
return (NullaryNode *)ParseNode::create(kind, PN_NULLARY, parser);
return (NullaryNode *) ParseNode::create(kind, PN_NULLARY, parser);
}
static bool test(const ParseNode &node) {
return node.isArity(PN_NULLARY);
}
#ifdef DEBUG
@ -910,7 +918,11 @@ struct UnaryNode : public ParseNode {
}
static inline UnaryNode *create(ParseNodeKind kind, Parser *parser) {
return (UnaryNode *)ParseNode::create(kind, PN_UNARY, parser);
return (UnaryNode *) ParseNode::create(kind, PN_UNARY, parser);
}
static bool test(const ParseNode &node) {
return node.isArity(PN_UNARY);
}
#ifdef DEBUG
@ -934,7 +946,11 @@ struct BinaryNode : public ParseNode {
}
static inline BinaryNode *create(ParseNodeKind kind, Parser *parser) {
return (BinaryNode *)ParseNode::create(kind, PN_BINARY, parser);
return (BinaryNode *) ParseNode::create(kind, PN_BINARY, parser);
}
static bool test(const ParseNode &node) {
return node.isArity(PN_BINARY);
}
#ifdef DEBUG
@ -954,7 +970,11 @@ struct TernaryNode : public ParseNode {
}
static inline TernaryNode *create(ParseNodeKind kind, Parser *parser) {
return (TernaryNode *)ParseNode::create(kind, PN_TERNARY, parser);
return (TernaryNode *) ParseNode::create(kind, PN_TERNARY, parser);
}
static bool test(const ParseNode &node) {
return node.isArity(PN_TERNARY);
}
#ifdef DEBUG
@ -964,7 +984,11 @@ struct TernaryNode : public ParseNode {
struct ListNode : public ParseNode {
static inline ListNode *create(ParseNodeKind kind, Parser *parser) {
return (ListNode *)ParseNode::create(kind, PN_LIST, parser);
return (ListNode *) ParseNode::create(kind, PN_LIST, parser);
}
static bool test(const ParseNode &node) {
return node.isArity(PN_LIST);
}
#ifdef DEBUG
@ -974,7 +998,11 @@ struct ListNode : public ParseNode {
struct FunctionNode : public ParseNode {
static inline FunctionNode *create(ParseNodeKind kind, Parser *parser) {
return (FunctionNode *)ParseNode::create(kind, PN_FUNC, parser);
return (FunctionNode *) ParseNode::create(kind, PN_FUNC, parser);
}
static bool test(const ParseNode &node) {
return node.isArity(PN_FUNC);
}
#ifdef DEBUG
@ -987,6 +1015,10 @@ struct NameNode : public ParseNode {
inline void initCommon(ParseContext *pc);
static bool test(const ParseNode &node) {
return node.isArity(PN_NAME);
}
#ifdef DEBUG
inline void dump(int indent);
#endif
@ -994,7 +1026,7 @@ struct NameNode : public ParseNode {
struct LexicalScopeNode : public ParseNode {
static inline LexicalScopeNode *create(ParseNodeKind kind, Parser *parser) {
return (LexicalScopeNode *)ParseNode::create(kind, PN_NAME, parser);
return (LexicalScopeNode *) ParseNode::create(kind, PN_NAME, parser);
}
};
@ -1013,6 +1045,13 @@ class LoopControlStatement : public ParseNode {
PropertyName *label() const {
return pn_u.loopControl.label;
}
static bool test(const ParseNode &node) {
bool match = node.isKind(PNK_BREAK) || node.isKind(PNK_CONTINUE);
JS_ASSERT_IF(match, node.isArity(PN_NULLARY));
JS_ASSERT_IF(match, node.isOp(JSOP_NOP));
return match;
}
};
class BreakStatement : public LoopControlStatement {
@ -1020,32 +1059,28 @@ class BreakStatement : public LoopControlStatement {
BreakStatement(PropertyName *label, const TokenPtr &begin, const TokenPtr &end)
: LoopControlStatement(PNK_BREAK, label, begin, end)
{ }
};
inline BreakStatement &
ParseNode::asBreakStatement()
{
JS_ASSERT(isKind(PNK_BREAK));
JS_ASSERT(isOp(JSOP_NOP));
JS_ASSERT(pn_arity == PN_NULLARY);
return *static_cast<BreakStatement *>(this);
}
static bool test(const ParseNode &node) {
bool match = node.isKind(PNK_BREAK);
JS_ASSERT_IF(match, node.isArity(PN_NULLARY));
JS_ASSERT_IF(match, node.isOp(JSOP_NOP));
return match;
}
};
class ContinueStatement : public LoopControlStatement {
public:
ContinueStatement(PropertyName *label, TokenPtr &begin, TokenPtr &end)
: LoopControlStatement(PNK_CONTINUE, label, begin, end)
{ }
};
inline ContinueStatement &
ParseNode::asContinueStatement()
{
JS_ASSERT(isKind(PNK_CONTINUE));
JS_ASSERT(isOp(JSOP_NOP));
JS_ASSERT(pn_arity == PN_NULLARY);
return *static_cast<ContinueStatement *>(this);
}
static bool test(const ParseNode &node) {
bool match = node.isKind(PNK_CONTINUE);
JS_ASSERT_IF(match, node.isArity(PN_NULLARY));
JS_ASSERT_IF(match, node.isOp(JSOP_NOP));
return match;
}
};
class DebuggerStatement : public ParseNode {
public:
@ -1064,6 +1099,13 @@ class XMLProcessingInstruction : public ParseNode {
pn_u.xmlpi.data = data;
}
static bool test(const ParseNode &node) {
bool match = node.isKind(PNK_XMLPI);
JS_ASSERT_IF(match, node.isArity(PN_NULLARY));
JS_ASSERT_IF(match, node.isOp(JSOP_NOP));
return match;
}
PropertyName *target() const {
return pn_u.xmlpi.target;
}
@ -1072,15 +1114,6 @@ class XMLProcessingInstruction : public ParseNode {
return pn_u.xmlpi.data;
}
};
inline XMLProcessingInstruction &
ParseNode::asXMLProcessingInstruction()
{
JS_ASSERT(isKind(PNK_XMLPI));
JS_ASSERT(isOp(JSOP_NOP));
JS_ASSERT(pn_arity == PN_NULLARY);
return *static_cast<XMLProcessingInstruction *>(this);
}
#endif
class ConditionalExpression : public ParseNode {
@ -1108,16 +1141,14 @@ class ConditionalExpression : public ParseNode {
ParseNode &elseExpression() const {
return *pn_u.ternary.kid3;
}
};
inline ConditionalExpression &
ParseNode::asConditionalExpression()
{
JS_ASSERT(isKind(PNK_CONDITIONAL));
JS_ASSERT(isOp(JSOP_NOP));
JS_ASSERT(pn_arity == PN_TERNARY);
return *static_cast<ConditionalExpression *>(this);
}
static bool test(const ParseNode &node) {
bool match = node.isKind(PNK_CONDITIONAL);
JS_ASSERT_IF(match, node.isArity(PN_TERNARY));
JS_ASSERT_IF(match, node.isOp(JSOP_NOP));
return match;
}
};
class ThisLiteral : public ParseNode {
public:
@ -1206,6 +1237,12 @@ class PropertyAccess : public ParseNode {
pn_u.name.atom = name;
}
static bool test(const ParseNode &node) {
bool match = node.isKind(PNK_DOT);
JS_ASSERT_IF(match, node.isArity(PN_NAME));
return match;
}
ParseNode &expression() const {
return *pn_u.name.expr;
}
@ -1215,14 +1252,6 @@ class PropertyAccess : public ParseNode {
}
};
inline PropertyAccess &
ParseNode::asPropertyAccess()
{
JS_ASSERT(isKind(PNK_DOT));
JS_ASSERT(pn_arity == PN_NAME);
return *static_cast<PropertyAccess *>(this);
}
class PropertyByValue : public ParseNode {
public:
PropertyByValue(ParseNode *lhs, ParseNode *propExpr,

View File

@ -2910,7 +2910,7 @@ ASTSerializer::xml(ParseNode *pn, Value *dst)
return builder.xmlComment(atomContents(pn->pn_atom), &pn->pn_pos, dst);
case PNK_XMLPI: {
XMLProcessingInstruction &pi = pn->asXMLProcessingInstruction();
XMLProcessingInstruction &pi = pn->as<XMLProcessingInstruction>();
return builder.xmlPI(atomContents(pi.target()),
atomContents(pi.data()),
&pi.pn_pos,

View File

@ -1578,7 +1578,7 @@ ParseNodeToXML(Parser *parser, ParseNode *pn,
goto skip_child;
xml_class = JSXML_CLASS_COMMENT;
} else if (pn->isKind(PNK_XMLPI)) {
XMLProcessingInstruction &pi = pn->asXMLProcessingInstruction();
XMLProcessingInstruction &pi = pn->as<XMLProcessingInstruction>();
if (IS_XML(str)) {
Value v = StringValue(str);
JSAutoByteString bytes;