(classDeclaration: ts.ClassDeclaration,
node: ts.ClassElement)
| 524 | } |
| 525 | |
| 526 | parseClassElement(classDeclaration: ts.ClassDeclaration, |
| 527 | node: ts.ClassElement): syntax.ClassElement { |
| 528 | switch (node.kind) { |
| 529 | case ts.SyntaxKind.Constructor: { |
| 530 | // constructor(xxx) { yyy } |
| 531 | return this.parseConstructorDeclaration(classDeclaration, node as ts.ConstructorDeclaration); |
| 532 | } |
| 533 | case ts.SyntaxKind.PropertyDeclaration: { |
| 534 | // prop: type = xxx; |
| 535 | const {modifiers, name, initializer} = node as ts.PropertyDeclaration; |
| 536 | if (!ts.isIdentifier(name)) |
| 537 | throw new UnimplementedError(name, 'Only identifier can be used as property name'); |
| 538 | return new syntax.PropertyDeclaration(name.text, |
| 539 | modifiers?.map(modifierToString) ?? [], |
| 540 | this.typer.parseNodeType(name), |
| 541 | initializer ? this.parseExpression(initializer) : undefined); |
| 542 | } |
| 543 | case ts.SyntaxKind.MethodDeclaration: { |
| 544 | // method() { xxx } |
| 545 | const {modifiers, name, body, parameters, questionToken, typeParameters} = node as ts.MethodDeclaration; |
| 546 | if (!ts.isIdentifier(name)) |
| 547 | throw new UnsupportedError(name, 'Only identifier can be used as method name'); |
| 548 | if (questionToken) |
| 549 | throw new UnsupportedError(name, 'Can not use question token in method'); |
| 550 | if (typeParameters) |
| 551 | throw new UnimplementedError(name, 'Generic method is not supported'); |
| 552 | if (modifiers?.find(m => m.kind == ts.SyntaxKind.AsyncKeyword)) |
| 553 | throw new UnimplementedError(node, 'Async function is not supported'); |
| 554 | this.typer.forbidClosure(node as ts.MethodDeclaration); |
| 555 | const cppModifiers = modifiers?.map(modifierToString) ?? []; |
| 556 | cppModifiers.push(...parseHint(node)); |
| 557 | // In TypeScript every method is "virtual", while it is possible to |
| 558 | // lookup all derived classes to decide whether to make the method |
| 559 | // virtual, it is not worth the efforts. |
| 560 | if (!cppModifiers.includes('static') && |
| 561 | !cppModifiers.includes('override') && |
| 562 | !cppModifiers.includes('destructor')) { |
| 563 | cppModifiers.push('virtual'); |
| 564 | } |
| 565 | return new syntax.MethodDeclaration(this.typer.parseNodeType(node) as syntax.FunctionType, |
| 566 | name.text, |
| 567 | cppModifiers, |
| 568 | this.parseParameters(parameters), |
| 569 | body ? this.parseStatement(body) as syntax.Block : undefined); |
| 570 | } |
| 571 | case ts.SyntaxKind.SemicolonClassElement: |
| 572 | return new syntax.SemicolonClassElement(); |
| 573 | } |
| 574 | throw new UnimplementedError(node, 'Unsupported class element'); |
| 575 | } |
| 576 | |
| 577 | parseConstructorDeclaration(classDeclaration: ts.ClassDeclaration, node: ts.ConstructorDeclaration): syntax.ConstructorDeclaration { |
| 578 | let {body, parameters} = node; |
nothing calls this directly
no test coverage detected