Scanner
TypeScript/scanner.ts at 3cd9f3d2d4afc1c817ea53b3e40d9598197e9aaa · Microsoft/TypeScript · GitHub
export interface Scanner {
getStartPos(): number;
getToken(): SyntaxKind;
getTextPos(): number;
getTokenPos(): number;
getTokenText(): string;
getTokenValue(): string;
hasExtendedUnicodeEscape(): boolean;
hasPrecedingLineBreak(): boolean;
isIdentifier(): boolean;
isReservedWord(): boolean;
isUnterminated(): boolean;
getNumericLiteralFlags(): NumericLiteralFlags;
reScanGreaterToken(): SyntaxKind;
reScanSlashToken(): SyntaxKind;
reScanTemplateToken(): SyntaxKind;
scanJsxIdentifier(): SyntaxKind;
scanJsxAttributeValue(): SyntaxKind;
reScanJsxToken(): SyntaxKind;
scanJsxToken(): SyntaxKind;
scanJSDocToken(): SyntaxKind;
scan(): SyntaxKind;
getText(): string;
setText(text: string, start?: number, length?: number): void;
setOnError(onError: ErrorCallback): void;
setScriptTarget(scriptTarget: ScriptTarget): void;
setLanguageVariant(variant: LanguageVariant): void;
setTextPos(textPos: number): void;
lookAhead<T>(callback: () => T): T;
scanRange<T>(start: number, length: number, callback: () => T): T;
tryScan<T>(callback: () => T): T;
}
Interfaceとしてはこんな感じ。与えられた文字列に対して scan()
で1文字ずつ舐めていって token( SyntaxKind
) を取得する。
TypeScript/types.ts at 3cd9f3d2d4afc1c817ea53b3e40d9598197e9aaa · Microsoft/TypeScript · GitHub
tokenが識別子(keyword)かどうかは token > SyntaxKind.Identifer
で判定できるようになっている。最近入ったJSDocの解釈に対応するつため JSDoc*Type
みたいな SyntaxKind
もある。以前だったら単なるコメントなので *CommentTrivia
扱いされていたはず。はず。
scan()
自体は普通に pos
を進めていきながら token
を判定していく感じ。
TypeScript/scanner.ts at 3cd9f3d2d4afc1c817ea53b3e40d9598197e9aaa · Microsoft/TypeScript · GitHub
TypeScriptはあんまり独自のキーワードいれない(実JSに影響及ぼすものに関しては)方針だと思われるけどその中でも enum
だけは存在しているのは多分
switch (ch) {
case CharacterCodes.lineFeed:
みたいなのを書きやすくするためなんじゃないかなぁと思ってる。セルフホスティングだからね。
jsxだったりテンプレートリテラルだったりする場合は特別対応してるんだけど、正直なにやってるかよくわからない。
import * as ts from 'typescript';
let text = `let a = 'm';`;
let scanner = ts.createScanner(ts.ScriptTarget.Latest, false,ts.LanguageVariant.Standard, text);
console.log(scanner.scan());
console.log(scanner.getTokenValue());
みたいなの書いていけば理解できそうだけどparser読んだほうが良さそうなので今は置いとく。 reScan
系とか使ってる側見たいとイメージ沸かない。
ちなみに ConflictMarkerTrivia
みたいのもあって親切。