/** * PropertyName : * IdentifierName * StringLiteral * NumericLiteral * * See 11.1.5 * * @return PropertyName node */ @SuppressWarnings("fallthrough") private PropertyKey propertyName() { switch (type) { case IDENT: return getIdent().setIsPropertyName(); case OCTAL: if (isStrictMode) { throw error(AbstractParser.message("strict.no.octal"), token); } case STRING: case ESCSTRING: case DECIMAL: case HEXADECIMAL: case FLOATING: return getLiteral(); default: return getIdentifierName().setIsPropertyName(); } }
private PropertyFunction propertySetterFunction(final long getSetToken, final int functionLine) { final PropertyKey setIdent = propertyName(); final String setterName = setIdent.getPropertyName(); final IdentNode setNameNode = createIdentNode(((Node)setIdent).getToken(), finish, NameCodec.encode("set " + setterName)); expect(LPAREN); // be sloppy and allow missing setter parameter even though // spec does not permit it! final IdentNode argIdent; if (type == IDENT || isNonStrictModeIdent()) { argIdent = getIdent(); verifyStrictIdent(argIdent, "setter argument"); } else { argIdent = null; } expect(RPAREN); final List<IdentNode> parameters = new ArrayList<>(); if (argIdent != null) { parameters.add(argIdent); } final FunctionNode functionNode = functionBody(getSetToken, setNameNode, parameters, FunctionNode.Kind.SETTER, functionLine); return new PropertyFunction(setIdent, functionNode); }
/** * LiteralPropertyName : * IdentifierName * StringLiteral * NumericLiteral * * @return PropertyName node */ @SuppressWarnings("fallthrough") private PropertyKey literalPropertyName() { switch (type) { case IDENT: return getIdent().setIsPropertyName(); case OCTAL_LEGACY: if (isStrictMode) { throw error(AbstractParser.message("strict.no.octal"), token); } case STRING: case ESCSTRING: case DECIMAL: case HEXADECIMAL: case OCTAL: case BINARY_NUMBER: case FLOATING: return getLiteral(); default: return getIdentifierName().setIsPropertyName(); } }
private PropertyFunction propertyGetterFunction(final long getSetToken, final int functionLine) { final PropertyKey getIdent = propertyName(); final String getterName = getIdent.getPropertyName(); final IdentNode getNameNode = createIdentNode(((Node)getIdent).getToken(), finish, NameCodec.encode("get " + getterName)); expect(LPAREN); expect(RPAREN); final FunctionNode functionNode = functionBody(getSetToken, getNameNode, new ArrayList<IdentNode>(), FunctionNode.Kind.GETTER, functionLine); return new PropertyFunction(getIdent, functionNode); }
private String getDefaultFunctionName() { if(!defaultNames.isEmpty()) { final Object nameExpr = defaultNames.peek(); if(nameExpr instanceof PropertyKey) { markDefaultNameUsed(); return ((PropertyKey)nameExpr).getPropertyName(); } else if(nameExpr instanceof AccessNode) { markDefaultNameUsed(); return ((AccessNode)nameExpr).getProperty(); } } return null; }
/** * ES6 14.5.1 Static Semantics: Early Errors. */ private void verifyAllowedMethodName(final Expression key, final boolean isStatic, final boolean computed, final boolean generator, final boolean accessor) { if (!computed) { if (!isStatic && generator && ((PropertyKey) key).getPropertyName().equals(CONSTRUCTOR_NAME)) { throw error(AbstractParser.message("generator.constructor"), key.getToken()); } if (!isStatic && accessor && ((PropertyKey) key).getPropertyName().equals(CONSTRUCTOR_NAME)) { throw error(AbstractParser.message("accessor.constructor"), key.getToken()); } if (isStatic && ((PropertyKey) key).getPropertyName().equals("prototype")) { throw error(AbstractParser.message("static.prototype.method"), key.getToken()); } } }
private PropertyFunction propertyGetterFunction(final long getSetToken, final int functionLine, final int flags) { final boolean computed = type == LBRACKET; final Expression propertyName = propertyName(); final String getterName = propertyName instanceof PropertyKey ? ((PropertyKey) propertyName).getPropertyName() : getDefaultValidFunctionName(functionLine, false); final IdentNode getNameNode = createIdentNode((propertyName).getToken(), finish, NameCodec.encode("get " + getterName)); expect(LPAREN); expect(RPAREN); final ParserContextFunctionNode functionNode = createParserContextFunctionNode(getNameNode, getSetToken, FunctionNode.Kind.GETTER, functionLine, Collections.<IdentNode>emptyList()); functionNode.setFlag(flags); if (computed) { functionNode.setFlag(FunctionNode.IS_ANONYMOUS); } lc.push(functionNode); Block functionBody; try { functionBody = functionBody(functionNode); } finally { lc.pop(functionNode); } final FunctionNode function = createFunctionNode( functionNode, getSetToken, getNameNode, Collections.<IdentNode>emptyList(), FunctionNode.Kind.GETTER, functionLine, functionBody); return new PropertyFunction(propertyName, function, computed); }
private String getDefaultFunctionName() { if (!defaultNames.isEmpty()) { final Object nameExpr = defaultNames.peek(); if (nameExpr instanceof PropertyKey) { markDefaultNameUsed(); return ((PropertyKey)nameExpr).getPropertyName(); } else if (nameExpr instanceof AccessNode) { markDefaultNameUsed(); return ((AccessNode)nameExpr).getProperty(); } } return null; }
/** * ES6 14.5.1 Static Semantics: Early Errors. */ private void verifyAllowedMethodName(final Expression key, final boolean isStatic, final boolean computed, final boolean generator, final boolean accessor) { if (!computed) { if (!isStatic && generator && ((PropertyKey) key).getPropertyName().equals("constructor")) { throw error(AbstractParser.message("generator.constructor"), key.getToken()); } if (!isStatic && accessor && ((PropertyKey) key).getPropertyName().equals("constructor")) { throw error(AbstractParser.message("accessor.constructor"), key.getToken()); } if (isStatic && ((PropertyKey) key).getPropertyName().equals("prototype")) { throw error(AbstractParser.message("static.prototype.method"), key.getToken()); } } }
/** * PropertyAssignment : * PropertyName : AssignmentExpression * get PropertyName ( ) { FunctionBody } * set PropertyName ( PropertySetParameterList ) { FunctionBody } * * PropertySetParameterList : * Identifier * * PropertyName : * IdentifierName * StringLiteral * NumericLiteral * * See 11.1.5 * * Parse an object literal property. * @return Property or reference node. */ private PropertyNode propertyAssignment() { // Capture firstToken. final long propertyToken = token; final int functionLine = line; PropertyKey propertyName; if (type == IDENT) { // Get IDENT. final String ident = (String)expectValue(IDENT); if (type != COLON) { final long getSetToken = propertyToken; switch (ident) { case "get": final PropertyFunction getter = propertyGetterFunction(getSetToken, functionLine); return new PropertyNode(propertyToken, finish, getter.ident, null, getter.functionNode, null); case "set": final PropertyFunction setter = propertySetterFunction(getSetToken, functionLine); return new PropertyNode(propertyToken, finish, setter.ident, null, null, setter.functionNode); default: break; } } propertyName = createIdentNode(propertyToken, finish, ident).setIsPropertyName(); } else { propertyName = propertyName(); } expect(COLON); defaultNames.push(propertyName); try { return new PropertyNode(propertyToken, finish, propertyName, assignmentExpression(false), null, null); } finally { defaultNames.pop(); } }
PropertyFunction(final PropertyKey ident, final FunctionNode function) { this.ident = ident; this.functionNode = function; }
private PropertyFunction propertySetterFunction(final long getSetToken, final int functionLine, final int flags) { final boolean computed = type == LBRACKET; final Expression propertyName = propertyName(); final String setterName = propertyName instanceof PropertyKey ? ((PropertyKey) propertyName).getPropertyName() : getDefaultValidFunctionName(functionLine, false); final IdentNode setNameNode = createIdentNode((propertyName).getToken(), finish, NameCodec.encode("set " + setterName)); expect(LPAREN); // be sloppy and allow missing setter parameter even though // spec does not permit it! final IdentNode argIdent; if (isBindingIdentifier()) { argIdent = getIdent(); verifyIdent(argIdent, "setter argument"); } else { argIdent = null; } expect(RPAREN); final List<IdentNode> parameters = new ArrayList<>(); if (argIdent != null) { parameters.add(argIdent); } final ParserContextFunctionNode functionNode = createParserContextFunctionNode(setNameNode, getSetToken, FunctionNode.Kind.SETTER, functionLine, parameters); functionNode.setFlag(flags); if (computed) { functionNode.setFlag(FunctionNode.IS_ANONYMOUS); } lc.push(functionNode); Block functionBody; try { functionBody = functionBody(functionNode); } finally { lc.pop(functionNode); } final FunctionNode function = createFunctionNode( functionNode, getSetToken, setNameNode, parameters, FunctionNode.Kind.SETTER, functionLine, functionBody); return new PropertyFunction(propertyName, function, computed); }
private PropertyFunction propertyMethodFunction(final Expression key, final long methodToken, final int methodLine, final boolean generator, final int flags, final boolean computed) { final String methodName = key instanceof PropertyKey ? ((PropertyKey) key).getPropertyName() : getDefaultValidFunctionName(methodLine, false); final IdentNode methodNameNode = createIdentNode(((Node)key).getToken(), finish, methodName); final FunctionNode.Kind functionKind = generator ? FunctionNode.Kind.GENERATOR : FunctionNode.Kind.NORMAL; final ParserContextFunctionNode functionNode = createParserContextFunctionNode(methodNameNode, methodToken, functionKind, methodLine, null); functionNode.setFlag(flags); if (computed) { functionNode.setFlag(FunctionNode.IS_ANONYMOUS); } lc.push(functionNode); try { final ParserContextBlockNode parameterBlock = newBlock(); final List<IdentNode> parameters; try { expect(LPAREN); parameters = formalParameterList(generator); functionNode.setParameters(parameters); expect(RPAREN); } finally { restoreBlock(parameterBlock); } Block functionBody = functionBody(functionNode); functionBody = maybeWrapBodyInParameterBlock(functionBody, parameterBlock); final FunctionNode function = createFunctionNode( functionNode, methodToken, methodNameNode, parameters, functionKind, methodLine, functionBody); return new PropertyFunction(key, function, computed); } finally { lc.pop(functionNode); } }
private PropertyFunction propertyMethodFunction(Expression key, final long methodToken, final int methodLine, final boolean generator, final int flags, boolean computed) { final String methodName = key instanceof PropertyKey ? ((PropertyKey) key).getPropertyName() : getDefaultValidFunctionName(methodLine, false); final IdentNode methodNameNode = createIdentNode(((Node)key).getToken(), finish, methodName); FunctionNode.Kind functionKind = generator ? FunctionNode.Kind.GENERATOR : FunctionNode.Kind.NORMAL; final ParserContextFunctionNode functionNode = createParserContextFunctionNode(methodNameNode, methodToken, functionKind, methodLine, null); functionNode.setFlag(flags); if (computed) { functionNode.setFlag(FunctionNode.IS_ANONYMOUS); } lc.push(functionNode); try { final ParserContextBlockNode parameterBlock = newBlock(); final List<IdentNode> parameters; try { expect(LPAREN); parameters = formalParameterList(generator); functionNode.setParameters(parameters); expect(RPAREN); } finally { restoreBlock(parameterBlock); } Block functionBody = functionBody(functionNode); functionBody = maybeWrapBodyInParameterBlock(functionBody, parameterBlock); final FunctionNode function = createFunctionNode( functionNode, methodToken, methodNameNode, parameters, functionKind, methodLine, functionBody); return new PropertyFunction(key, function, computed); } finally { lc.pop(functionNode); } }