Skip to content

Commit 2ba61a7

Browse files
committed
add quotes in scan.ts and add process details in Details.md
1 parent 07d2e13 commit 2ba61a7

File tree

3 files changed

+115
-7
lines changed

3 files changed

+115
-7
lines changed

Details.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
Why not use OOP? TS 早期是使用面向对象的类开发的,从 1.0 开始,为了适配 JS 引擎的性能,所有源码已经没有类了,全部改用函数闭包
2+
3+
4+
相关关系如下所示:
5+
6+
流程
7+
> SourceCode(源码) ~~ 扫描器 ~~> Token 流 ~~ 解析器 ~~> AST(抽象语法树)~~ 绑定器 ~~> Symbols(符号)
8+
9+
验证
10+
> AST + 符号 ~~ 检查器 ~~> 类型验证
11+
12+
输出JS
13+
> AST + 检查器 ~~ 发射器 ~~> JavaScript 代码
14+
15+
> SourceFile + Context ~~> Program
16+
17+
> Program ~~ CompilerHost ~~> Program
18+
19+
`tsc ...`调用顺序
20+
```
21+
// tsc folder
22+
ts.executeCommandLine 获取sys,调用执行函数
23+
24+
// executeCommandLine folder
25+
调用 executeCommandLine 执行tsc
26+
1. createDiagnosticReporter 错误报告
27+
2. parseConfigFileWithSystem tsconfig.json
28+
调用 performCompilation 编译过程
29+
1. createCompilerHostWorker 编译监视器
30+
2. createProgram 创建Program
31+
3. emitFilesAndReportErrorsAndGetExitStatus emit并捕获编译时错误
32+
4. sys.exit 退出
33+
34+
// compiler/program.ts
35+
调用 createProgram 编译,并解析项目的结构
36+
1. createCompilerHost 解析SourceFile
37+
2. processRootFile 解析main指向的文件
38+
39+
反复处理文件、文件夹编译
40+
1. processSourceFile
41+
2. findSourceFile
42+
3. processImportedModules
43+
44+
调用 findSourceFile 处理单个文件
45+
2. host.getSourceFile 编译
46+
47+
// compiler/parser.ts
48+
调用 getSourceFile
49+
1. Parser.parseSourceFile 解析
50+
51+
调用 parseSourceFile
52+
1. parseJsonText 解析Json文件
53+
1. initializeState 初始化状态,注册scanner需要的内容(文字等)
54+
2. parseSourceFileWorker worker
55+
56+
调用 parseSourceFileWorker
57+
1. createSourceFile 绑定SourceFile的文件的通用属性(版本、文字等)
58+
2. nextToken 激活scanner
59+
3. processCommentPragmas 处理注释
60+
4. processPragmasIntoFields 处理语法
61+
5. addJSDocComment 处理JSDoc
62+
63+
调用 nextToken
64+
1. nextTokenWithoutCheck 将工作移交给scanner
65+
66+
// compiler/scanner.ts
67+
1. scan Scanner的Gatway
68+
69+
// compiler/watch.ts
70+
调用 emitFilesAndReportErrorsAndGetExitStatus
71+
1. emitFilesAndReportErrors 生成js并报告错误
72+
2. program.emit emit js
73+
```

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939

4040
<img src="./asset/158732-20200113115412762-1000035138.png" width="432px" height="361.2px" />
4141

42+
See: [More Details](./Details.md)
43+
4244
## More Info
4345

4446
* [microsoft/TypeScript/README](https://github.com/microsoft/TypeScript/blob/master/README.md)

src/compiler/scanner.ts

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,15 @@ namespace ts {
279279
*/
280280
const commentDirectiveRegExMultiLine = /^\s*(?:\/|\*)*\s*@(ts-expect-error|ts-ignore)/;
281281

282+
/**
283+
* Rather than recording all the characters, we record the beginning and end of each paragraph, it saves memory.
284+
*
285+
* Put all start and end positions in the same `map`. Use odd bits to indicate the beginning of each paragraph, and even bits to indicate the end of each paragraph.
286+
*
287+
* When you need to find whether a `code` is an identifier, use the binary search algorithm to confirm whether it is a valid Unicode identifier.
288+
* @param code
289+
* @param map unicodeESNextIdentifierPart | unicodeESNextIdentifierStart
290+
*/
282291
function lookupInUnicodeMap(code: number, map: readonly number[]): boolean {
283292
// Bail out quickly if it couldn't possibly be in the map.
284293
if (code < map[0]) {
@@ -342,6 +351,7 @@ namespace ts {
342351
}
343352

344353
/* @internal */
354+
/** 计算出每一行是从哪一个Position开始的 */
345355
export function computeLineStarts(text: string): number[] {
346356
const result: number[] = new Array();
347357
let pos = 0;
@@ -381,6 +391,7 @@ namespace ts {
381391
}
382392

383393
/* @internal */
394+
/** Query position from row and column number */
384395
export function computePositionOfLineAndCharacter(lineStarts: readonly number[], line: number, character: number, debugText?: string, allowEdits?: true): number {
385396
if (line < 0 || line >= lineStarts.length) {
386397
if (allowEdits) {
@@ -414,6 +425,7 @@ namespace ts {
414425
}
415426

416427
/* @internal */
428+
/** Retrieve position table query row and column number, used such as show error postion */
417429
export function computeLineAndCharacterOfPosition(lineStarts: readonly number[], position: number): LineAndCharacter {
418430
const lineNumber = computeLineOfPosition(lineStarts, position);
419431
return {
@@ -458,13 +470,14 @@ namespace ts {
458470
return computeLineAndCharacterOfPosition(getLineStarts(sourceFile), position);
459471
}
460472

473+
/** Include line breaks and white space */
461474
export function isWhiteSpaceLike(ch: number): boolean {
462475
return isWhiteSpaceSingleLine(ch) || isLineBreak(ch);
463476
}
464477

465478
/** Does not include line breaks. For that, see isWhiteSpaceLike. */
466479
export function isWhiteSpaceSingleLine(ch: number): boolean {
467-
// Note: nextLine is in the Zs space, and should be considered to be a whitespace.
480+
// Note: nextLine is in the [Zs space](https://en.wikipedia.org/wiki/Template:Whitespace_(Unicode)), and should be considered to be a whitespace.
468481
// It is explicitly not a line-break as it isn't in the exact set specified by EcmaScript.
469482
return ch === CharacterCodes.space ||
470483
ch === CharacterCodes.tab ||
@@ -607,7 +620,7 @@ namespace ts {
607620
break;
608621

609622
case CharacterCodes.hash:
610-
if (pos === 0 && isShebangTrivia(text, pos)) {
623+
if (pos === 0 && isShebangTrivia(text, pos)) { // #! Shebang - TC39_Stage 2
611624
pos = scanShebangTrivia(text, pos);
612625
continue;
613626
}
@@ -881,6 +894,12 @@ namespace ts {
881894
}
882895

883896
/* @internal */
897+
/**
898+
* Determine whether a string is a legal identifier
899+
* @param name The string to be searched
900+
* @param languageVersion Compiled target ES version
901+
* @param identifierVariant Because of JSX, we need to use this parameter to distinguish
902+
*/
884903
export function isIdentifierText(name: string, languageVersion: ScriptTarget | undefined, identifierVariant?: LanguageVariant): boolean {
885904
let ch = codePointAt(name, 0);
886905
if (!isIdentifierStart(ch, languageVersion)) {
@@ -943,7 +962,7 @@ namespace ts {
943962
isUnterminated: () => (tokenFlags & TokenFlags.Unterminated) !== 0,
944963
getCommentDirectives: () => commentDirectives,
945964
getTokenFlags: () => tokenFlags,
946-
reScanGreaterToken,
965+
reScanGreaterToken, // We have to reScan it and something below. Because some token is context-sensitive
947966
reScanSlashToken,
948967
reScanTemplateToken,
949968
reScanTemplateHeadOrNoSubstitutionTemplate,
@@ -1644,15 +1663,15 @@ namespace ts {
16441663
}
16451664
return token = SyntaxKind.WhitespaceTrivia;
16461665
}
1647-
case CharacterCodes.exclamation:
1666+
case CharacterCodes.exclamation: // !
16481667
if (text.charCodeAt(pos + 1) === CharacterCodes.equals) {
16491668
if (text.charCodeAt(pos + 2) === CharacterCodes.equals) {
1650-
return pos += 3, token = SyntaxKind.ExclamationEqualsEqualsToken;
1669+
return pos += 3, token = SyntaxKind.ExclamationEqualsEqualsToken; // !==
16511670
}
1652-
return pos += 2, token = SyntaxKind.ExclamationEqualsToken;
1671+
return pos += 2, token = SyntaxKind.ExclamationEqualsToken; // !=
16531672
}
16541673
pos++;
1655-
return token = SyntaxKind.ExclamationToken;
1674+
return token = SyntaxKind.ExclamationToken; // !
16561675
case CharacterCodes.doubleQuote:
16571676
case CharacterCodes.singleQuote:
16581677
tokenValue = scanString();
@@ -2444,10 +2463,24 @@ namespace ts {
24442463
return result;
24452464
}
24462465

2466+
/**
2467+
* Sometimes we don’t need to look back, but we need to look ahead. For example, the keywords of TS: interface, enum etc.
2468+
*
2469+
* Unlike `tryScan`, It will unconditionally restore us to where we were.
2470+
*
2471+
* Also see: interface Scan
2472+
*/
24472473
function lookAhead<T>(callback: () => T): T {
24482474
return speculationHelper(callback, /*isLookahead*/ true);
24492475
}
24502476

2477+
/**
2478+
* Sometimes we don’t need to look back, but we need to look ahead. For example, the keywords of TS: interface, enum etc.
2479+
*
2480+
* Unlike `lookAhead`, It will not "unconditionally" restore us to where we were.
2481+
*
2482+
* Also see: interface Scan
2483+
*/
24512484
function tryScan<T>(callback: () => T): T {
24522485
return speculationHelper(callback, /*isLookahead*/ false);
24532486
}

0 commit comments

Comments
 (0)