TypeScriptコンパイラとそのAPI
コンパイラのソースを見ているが、
- /src/compiler/types.ts の export const enum SyntaxKind に、構文範疇が列挙されている。機能性に直接影響しない構文範疇をトリビアと呼んでいる。
- SingleLineCommentTrivia,
- MultiLineCommentTrivia,
- NewLineTrivia,
- WhitespaceTrivia,
- ShebangTrivia, // We detect and preserve #! on the first line
- ConflictMarkerTrivia, // We detect and provide better error recovery when we encounter a git merge marker. This
// allows us to edit files with git-conflict markers in them in a much more pleasant manner.
- さらにJSDocスタイルのドキュメンテーションコメントは特別扱いして、パーザーが見ている。
- JSDocTypeExpression,
- JSDocAllType,
- JSDocUnknownType,
- その他イッパイ
- 実質的にJSDocパーザーを含み、ASTにJSDoc構文が反映される。
- 構文範疇〈SyntaxKind〉は、トークン種別と文法要素の両方が含まれる。トークンは*Tokenという名前になっている。
- 予約語は*Keywordという名前。
- BreakKeyword,
- CaseKeyword,
- CatchKeyword,
- その他イッパイ
TypeScriptはもともとグローバル(c:/Users/hiyama/AppData/Local/Yarn/)にあるのだけど、プロジェクト内に入れてみる。
- yarn add typescript
これだと、link機構とかは不要。
typescriptはNode.jsで実行するから、Node.jsの型宣言が必要。
- yarn add @types/node
これで、プロジェクトのnode_modules/@types配下にNode.jsに関する型宣言が入る。
"A minimal compiler"をとりあえずやってみる。ソースをコピーしてtscでコンパイル、nodeで実行。
import * as ts from "typescript"; function compile(fileNames: string[], options: ts.CompilerOptions): void { let program = ts.createProgram(fileNames, options); let emitResult = program.emit(); let allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics); allDiagnostics.forEach(diagnostic => { if (diagnostic.file) { let { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!); let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); } else { console.log(`${ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')}`); } }); let exitCode = emitResult.emitSkipped ? 1 : 0; console.log(`Process exiting with code '${exitCode}'.`); process.exit(exitCode); } compile(process.argv.slice(2), { noEmitOnError: true, noImplicitAny: true, target: ts.ScriptTarget.ES5, module: ts.ModuleKind.CommonJS });
この例は、トランスレートしないで、エラーをチェックするだけだ。
ts.transpileModuleという関数がトランスパイルを実行するようなので、この関数を眺めないとダメか。
[追記]transpileModuleは、
src/services/が外部に出しているAPIのエントリーポイントらしい。
[/追記]