use of org.mozilla.javascript.ast.Name in project HL4A by HL4A.
the class Parser method variables.
/**
* Parse a 'var' or 'const' statement, or a 'var' init list in a for
* statement.
* @param declType A token value: either VAR, CONST, or LET depending on
* context.
* @param pos the position where the node should start. It's sometimes
* the var/const/let keyword, and other times the beginning of the first
* token in the first variable declaration.
* @return the parsed variable list
*/
private VariableDeclaration variables(int declType, int pos, boolean isStatement) throws IOException {
int end;
VariableDeclaration pn = new VariableDeclaration(pos);
pn.setType(declType);
pn.setLineno(ts.lineno);
Comment varjsdocNode = getAndResetJsDoc();
if (varjsdocNode != null) {
pn.setJsDocNode(varjsdocNode);
}
// var {b: s2, a: s1} = foo, x = 6, y, [s3, s4] = bar;
for (; ; ) {
AstNode destructuring = null;
Name name = null;
int tt = peekToken(), kidPos = ts.tokenBeg;
end = ts.tokenEnd;
if (tt == Token.LB || tt == Token.LC) {
// Destructuring assignment, e.g., var [a,b] = ...
destructuring = destructuringPrimaryExpr();
end = getNodeEnd(destructuring);
if (!(destructuring instanceof DestructuringForm))
reportError("msg.bad.assign.left", kidPos, end - kidPos);
markDestructuring(destructuring);
} else {
// Simple variable name
mustMatchToken(Token.NAME, "msg.bad.var");
name = createNameNode();
name.setLineno(ts.getLineno());
if (inUseStrictDirective) {
String id = ts.getString();
if ("eval".equals(id) || "arguments".equals(ts.getString())) {
reportError("msg.bad.id.strict", id);
}
}
defineSymbol(declType, ts.getString(), inForInit);
}
int lineno = ts.lineno;
Comment jsdocNode = getAndResetJsDoc();
AstNode init = null;
if (matchToken(Token.ASSIGN)) {
init = assignExpr();
end = getNodeEnd(init);
}
VariableInitializer vi = new VariableInitializer(kidPos, end - kidPos);
if (destructuring != null) {
if (init == null && !inForInit) {
reportError("msg.destruct.assign.no.init");
}
vi.setTarget(destructuring);
} else {
vi.setTarget(name);
}
vi.setInitializer(init);
vi.setType(declType);
vi.setJsDocNode(jsdocNode);
vi.setLineno(lineno);
pn.addVariable(vi);
if (!matchToken(Token.COMMA))
break;
}
pn.setLength(end - pos);
pn.setIsStatement(isStatement);
return pn;
}
use of org.mozilla.javascript.ast.Name in project HL4A by HL4A.
the class Parser method createNameNode.
/**
* Create a {@code Name} node using the token info from the
* last scanned name. In some cases we need to either synthesize
* a name node, or we lost the name token information by peeking.
* If the {@code token} parameter is not {@link Token#NAME}, then
* we use token info saved in instance vars.
*/
private Name createNameNode(boolean checkActivation, int token) {
int beg = ts.tokenBeg;
String s = ts.getString();
int lineno = ts.lineno;
if (!"".equals(prevNameTokenString)) {
beg = prevNameTokenStart;
s = prevNameTokenString;
lineno = prevNameTokenLineno;
prevNameTokenStart = 0;
prevNameTokenString = "";
prevNameTokenLineno = 0;
}
if (s == null) {
if (compilerEnv.isIdeMode()) {
s = "";
} else {
codeBug();
}
}
Name name = new Name(beg, s);
name.setLineno(lineno);
if (checkActivation) {
checkActivationName(s, token);
}
return name;
}
use of org.mozilla.javascript.ast.Name in project HL4A by HL4A.
the class Parser method simpleAssignment.
// Quickie tutorial for some of the interpreter bytecodes.
//
// GETPROP - for normal foo.bar prop access; right side is a name
// GETELEM - for normal foo[bar] element access; rhs is an expr
// SETPROP - for assignment when left side is a GETPROP
// SETELEM - for assignment when left side is a GETELEM
// DELPROP - used for delete foo.bar or foo[bar]
//
// GET_REF, SET_REF, DEL_REF - in general, these mean you're using
// get/set/delete on a right-hand side expression (possibly with no
// explicit left-hand side) that doesn't use the normal JavaScript
// Object (i.e. ScriptableObject) get/set/delete functions, but wants
// to provide its own versions instead. It will ultimately implement
// Ref, and currently SpecialRef (for __proto__ etc.) and XmlName
// (for E4X XML objects) are the only implementations. The runtime
// notices these bytecodes and delegates get/set/delete to the object.
//
// BINDNAME: used in assignments. LHS is evaluated first to get a
// specific object containing the property ("binding" the property
// to the object) so that it's always the same object, regardless of
// side effects in the RHS.
protected Node simpleAssignment(Node left, Node right) {
int nodeType = left.getType();
switch(nodeType) {
case Token.NAME:
String name = ((Name) left).getIdentifier();
if (inUseStrictDirective && ("eval".equals(name) || "arguments".equals(name))) {
reportError("msg.bad.id.strict", name);
}
left.setType(Token.BINDNAME);
return new Node(Token.SETNAME, left, right);
case Token.GETPROP:
case Token.GETELEM:
{
Node obj, id;
// field, but that seems just as ugly as this casting.
if (left instanceof PropertyGet) {
obj = ((PropertyGet) left).getTarget();
id = ((PropertyGet) left).getProperty();
} else if (left instanceof ElementGet) {
obj = ((ElementGet) left).getTarget();
id = ((ElementGet) left).getElement();
} else {
// This branch is called during IRFactory transform pass.
obj = left.getFirstChild();
id = left.getLastChild();
}
int type;
if (nodeType == Token.GETPROP) {
type = Token.SETPROP;
// TODO(stevey) - see https://bugzilla.mozilla.org/show_bug.cgi?id=492036
// The new AST code generates NAME tokens for GETPROP ids where the old parser
// generated STRING nodes. If we don't set the type to STRING below, this will
// cause java.lang.VerifyError in codegen for code like
// "var obj={p:3};[obj.p]=[9];"
id.setType(Token.STRING);
} else {
type = Token.SETELEM;
}
return new Node(type, obj, id, right);
}
case Token.GET_REF:
{
Node ref = left.getFirstChild();
checkMutableReference(ref);
return new Node(Token.SET_REF, ref, right);
}
}
throw codeBug();
}
use of org.mozilla.javascript.ast.Name in project HL4A by HL4A.
the class Parser method returnOrYield.
private AstNode returnOrYield(int tt, boolean exprContext) throws IOException {
if (!insideFunction()) {
reportError(tt == Token.RETURN ? "msg.bad.return" : "msg.bad.yield");
}
consumeToken();
int lineno = ts.lineno, pos = ts.tokenBeg, end = ts.tokenEnd;
AstNode e = null;
// This is ugly, but we don't want to require a semicolon.
switch(peekTokenOrEOL()) {
case Token.SEMI:
case Token.RC:
case Token.RB:
case Token.RP:
case Token.EOF:
case Token.EOL:
case Token.ERROR:
case Token.YIELD:
break;
default:
e = expr();
end = getNodeEnd(e);
}
int before = endFlags;
AstNode ret;
if (tt == Token.RETURN) {
endFlags |= e == null ? Node.END_RETURNS : Node.END_RETURNS_VALUE;
ret = new ReturnStatement(pos, end - pos, e);
// see if we need a strict mode warning
if (nowAllSet(before, endFlags, Node.END_RETURNS | Node.END_RETURNS_VALUE))
addStrictWarning("msg.return.inconsistent", "", pos, end - pos);
} else {
if (!insideFunction())
reportError("msg.bad.yield");
endFlags |= Node.END_YIELDS;
ret = new Yield(pos, end - pos, e);
setRequiresActivation();
setIsGenerator();
if (!exprContext) {
ret = new ExpressionStatement(ret);
}
}
// see if we are mixing yields and value returns.
if (insideFunction() && nowAllSet(before, endFlags, Node.END_YIELDS | Node.END_RETURNS_VALUE)) {
Name name = ((FunctionNode) currentScriptOrFn).getFunctionName();
if (name == null || name.length() == 0)
addError("msg.anon.generator.returns", "");
else
addError("msg.generator.returns", name.getIdentifier());
}
ret.setLineno(lineno);
return ret;
}
use of org.mozilla.javascript.ast.Name in project HL4A by HL4A.
the class Parser method propertyAccess.
/**
* Handles any construct following a "." or ".." operator.
* @param pn the left-hand side (target) of the operator. Never null.
* @return a PropertyGet, XmlMemberGet, or ErrorNode
*/
private AstNode propertyAccess(int tt, AstNode pn) throws IOException {
if (pn == null)
codeBug();
int memberTypeFlags = 0, lineno = ts.lineno, dotPos = ts.tokenBeg;
consumeToken();
if (tt == Token.DOTDOT) {
mustHaveXML();
memberTypeFlags = Node.DESCENDANTS_FLAG;
}
if (!compilerEnv.isXmlAvailable()) {
int maybeName = nextToken();
if (maybeName != Token.NAME && !(compilerEnv.isReservedKeywordAsIdentifier() && TokenStream.isKeyword(ts.getString(), compilerEnv.getLanguageVersion(), inUseStrictDirective))) {
reportError("msg.no.name.after.dot");
}
Name name = createNameNode(true, Token.GETPROP);
PropertyGet pg = new PropertyGet(pn, name, dotPos);
pg.setLineno(lineno);
return pg;
}
// right side of . or .. operator
AstNode ref = null;
int token = nextToken();
switch(token) {
case Token.THROW:
// needed for generator.throw();
saveNameTokenData(ts.tokenBeg, "throw", ts.lineno);
ref = propertyName(-1, "throw", memberTypeFlags);
break;
case Token.NAME:
// handles: name, ns::name, ns::*, ns::[expr]
ref = propertyName(-1, ts.getString(), memberTypeFlags);
break;
case Token.MUL:
// handles: *, *::name, *::*, *::[expr]
saveNameTokenData(ts.tokenBeg, "*", ts.lineno);
ref = propertyName(-1, "*", memberTypeFlags);
break;
case Token.XMLATTR:
// handles: '@attr', '@ns::attr', '@ns::*', '@ns::*',
// '@::attr', '@::*', '@*', '@*::attr', '@*::*'
ref = attributeAccess();
break;
case Token.RESERVED:
{
String name = ts.getString();
saveNameTokenData(ts.tokenBeg, name, ts.lineno);
ref = propertyName(-1, name, memberTypeFlags);
break;
}
default:
if (compilerEnv.isReservedKeywordAsIdentifier()) {
// allow keywords as property names, e.g. ({if: 1})
String name = Token.keywordToName(token);
if (name != null) {
saveNameTokenData(ts.tokenBeg, name, ts.lineno);
ref = propertyName(-1, name, memberTypeFlags);
break;
}
}
reportError("msg.no.name.after.dot");
return makeErrorNode();
}
boolean xml = ref instanceof XmlRef;
InfixExpression result = xml ? new XmlMemberGet() : new PropertyGet();
if (xml && tt == Token.DOT)
result.setType(Token.DOT);
int pos = pn.getPosition();
result.setPosition(pos);
result.setLength(getNodeEnd(ref) - pos);
result.setOperatorPosition(dotPos - pos);
result.setLineno(pn.getLineno());
// do this after setting position
result.setLeft(pn);
result.setRight(ref);
return result;
}
Aggregations