()
| 3231 | } |
| 3232 | |
| 3233 | func (p *Parser) parseTypeParameter() *ast.Node { |
| 3234 | pos := p.nodePos() |
| 3235 | modifiers := p.parseModifiersEx(false /*allowDecorators*/, true /*permitConstAsModifier*/, false /*stopOnStartOfClassStaticBlock*/) |
| 3236 | name := p.parseIdentifier() |
| 3237 | var constraint *ast.TypeNode |
| 3238 | var expression *ast.Expression |
| 3239 | if p.parseOptional(ast.KindExtendsKeyword) { |
| 3240 | // It's not uncommon for people to write improper constraints to a generic. If the |
| 3241 | // user writes a constraint that is an expression and not an actual type, then parse |
| 3242 | // it out as an expression (so we can recover well), but report that a type is needed |
| 3243 | // instead. |
| 3244 | if p.isStartOfType(false /*inStartOfParameter*/) || !p.isStartOfExpression() { |
| 3245 | constraint = p.parseType() |
| 3246 | } else { |
| 3247 | // It was not a type, and it looked like an expression. Parse out an expression |
| 3248 | // here so we recover well. Note: it is important that we call parseUnaryExpression |
| 3249 | // and not parseExpression here. If the user has: |
| 3250 | // |
| 3251 | // <T extends ""> |
| 3252 | // |
| 3253 | // We do *not* want to consume the `>` as we're consuming the expression for "". |
| 3254 | expression = p.parseUnaryExpressionOrHigher() |
| 3255 | } |
| 3256 | } |
| 3257 | var defaultType *ast.TypeNode |
| 3258 | if p.parseOptional(ast.KindEqualsToken) { |
| 3259 | defaultType = p.parseType() |
| 3260 | } |
| 3261 | result := p.factory.NewTypeParameterDeclaration(modifiers, name, constraint, expression, defaultType) |
| 3262 | return p.finishNode(result, pos) |
| 3263 | } |
| 3264 | |
| 3265 | func (p *Parser) parseParameters(flags ParseFlags) *ast.NodeList { |
| 3266 | // FormalParameters [Yield,Await]: (modified) |
nothing calls this directly
no test coverage detected