(fileName: string, sourceFile: ts.SourceFile)
| 66 | } |
| 67 | |
| 68 | parseSourceFile(fileName: string, sourceFile: ts.SourceFile): CppFile { |
| 69 | const fileNameInProject = path.relative(this.project.sourceRootDir, fileName); |
| 70 | const fileNameInFileSystem = path.relative(this.project.rootDir, fileName); |
| 71 | const cppFile = new CppFile(fileNameInFileSystem, |
| 72 | this.project.getFileType(fileNameInFileSystem), |
| 73 | this.typer.interfaceRegistry); |
| 74 | // For multi-file project add namespace for each file. |
| 75 | if (this.project.fileNames.length > 1) |
| 76 | cppFile.namespace = getNamespaceFromFileName(fileNameInProject); |
| 77 | // Parse root nodes in the file. |
| 78 | ts.forEachChild(sourceFile, (node: ts.Node) => { |
| 79 | switch (node.kind) { |
| 80 | case ts.SyntaxKind.ImportDeclaration: |
| 81 | cppFile.addImport(this.parseImportDeclaration(node as ts.ImportDeclaration)); |
| 82 | return; |
| 83 | case ts.SyntaxKind.ClassDeclaration: |
| 84 | if (!cppFile.canAddDeclaration()) |
| 85 | throw new UnsupportedError(node, 'Can not add class declaration after statements'); |
| 86 | cppFile.addDeclaration(this.parseClassDeclaration(node as ts.ClassDeclaration)); |
| 87 | return; |
| 88 | case ts.SyntaxKind.FunctionDeclaration: |
| 89 | if (!cppFile.canAddDeclaration()) |
| 90 | throw new UnsupportedError(node, 'Can not add function declaration after statements'); |
| 91 | cppFile.addDeclaration(this.parseFunctionDeclaration(node as ts.FunctionDeclaration)); |
| 92 | return; |
| 93 | case ts.SyntaxKind.VariableStatement: |
| 94 | cppFile.addVariableStatement(this.parseStatement(node as ts.Statement) as syntax.VariableStatement); |
| 95 | return; |
| 96 | case ts.SyntaxKind.Block: |
| 97 | case ts.SyntaxKind.ExpressionStatement: |
| 98 | case ts.SyntaxKind.IfStatement: |
| 99 | case ts.SyntaxKind.DoStatement: |
| 100 | case ts.SyntaxKind.WhileStatement: |
| 101 | case ts.SyntaxKind.ForStatement: |
| 102 | case ts.SyntaxKind.ReturnStatement: |
| 103 | if (cppFile.type == 'lib') |
| 104 | throw new UnsupportedError(node, 'In C++ only class and function declarations can be made top-level, unless it is the main script'); |
| 105 | cppFile.addStatement(this.parseStatement(node as ts.Statement)); |
| 106 | return; |
| 107 | case ts.SyntaxKind.EndOfFileToken: |
| 108 | cppFile.endOfFile(); |
| 109 | return; |
| 110 | // The interfaces are parsed on the fly when we see object literals. |
| 111 | case ts.SyntaxKind.InterfaceDeclaration: |
| 112 | // We don't need to parse type alias, typeChecker does it for us. |
| 113 | case ts.SyntaxKind.TypeAliasDeclaration: |
| 114 | // This is for the ; added on unnecessary places. |
| 115 | case ts.SyntaxKind.EmptyStatement: |
| 116 | return; |
| 117 | } |
| 118 | throw new UnimplementedError(node, 'Unsupported top-level node'); |
| 119 | }); |
| 120 | return cppFile; |
| 121 | } |
| 122 | |
| 123 | parseExpression(node: ts.Expression): syntax.Expression { |
| 124 | switch (node.kind) { |
no test coverage detected