@no22/dison 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +15 -0
- package/README.md +194 -0
- package/dist/analysis.d.ts +21 -0
- package/dist/analysis.d.ts.map +1 -0
- package/dist/analysis.js +267 -0
- package/dist/analysis.js.map +1 -0
- package/dist/ast.d.ts +46 -0
- package/dist/ast.d.ts.map +1 -0
- package/dist/ast.js +5 -0
- package/dist/ast.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +98 -0
- package/dist/cli.js.map +1 -0
- package/dist/codegen.d.ts +10 -0
- package/dist/codegen.d.ts.map +1 -0
- package/dist/codegen.js +181 -0
- package/dist/codegen.js.map +1 -0
- package/dist/collisions.d.ts +26 -0
- package/dist/collisions.d.ts.map +1 -0
- package/dist/collisions.js +120 -0
- package/dist/collisions.js.map +1 -0
- package/dist/core.d.ts +229 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +247 -0
- package/dist/core.js.map +1 -0
- package/dist/generated-runtime.d.ts +7 -0
- package/dist/generated-runtime.d.ts.map +1 -0
- package/dist/generated-runtime.js +51 -0
- package/dist/generated-runtime.js.map +1 -0
- package/dist/lexer.d.ts +16 -0
- package/dist/lexer.d.ts.map +1 -0
- package/dist/lexer.js +93 -0
- package/dist/lexer.js.map +1 -0
- package/dist/parser.d.ts +39 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +594 -0
- package/dist/parser.js.map +1 -0
- package/dist/runtime.d.ts +3 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +79 -0
- package/dist/runtime.js.map +1 -0
- package/package.json +56 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 OHARA Hiroyuki
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Dison
|
|
2
|
+
|
|
3
|
+
Dison is an experimental DSL that transpiles to TypeScript. It builds
|
|
4
|
+
**property injection** directly into the language, so dependency
|
|
5
|
+
injection reads like ordinary class syntax instead of framework
|
|
6
|
+
boilerplate.
|
|
7
|
+
|
|
8
|
+
The transpiled output happens to look like a `ServiceLocator`-style
|
|
9
|
+
registry under the hood — but that's an implementation detail of the
|
|
10
|
+
generated code, hidden below Dison's own language semantics. As a
|
|
11
|
+
Dison user you write `injectable`, `override`, `bind`, and `configuration`
|
|
12
|
+
declarations; you never touch the registry directly.
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @no22/dison
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
(The package is published as `@no22/dison` — npm's name-similarity
|
|
21
|
+
policy rejected the unscoped name `dison` as too close to existing
|
|
22
|
+
packages. The CLI command itself is still just `dison`.)
|
|
23
|
+
|
|
24
|
+
This gives you the `dison` CLI (via `npx dison`) and, for multi-file
|
|
25
|
+
projects, a shared runtime importable as `@no22/dison/runtime`.
|
|
26
|
+
|
|
27
|
+
## Quick start
|
|
28
|
+
|
|
29
|
+
```dison
|
|
30
|
+
// user-service.dis
|
|
31
|
+
class SqlUserRepository {
|
|
32
|
+
findById(id: string) {
|
|
33
|
+
return { id, name: "real user" };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
class MockUserRepository extends SqlUserRepository {
|
|
38
|
+
findById(id: string) {
|
|
39
|
+
return { id, name: "mock user" };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
class UserService {
|
|
44
|
+
injectable repo: SqlUserRepository;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
configuration TestConfig {
|
|
48
|
+
override UserService {
|
|
49
|
+
repo = new MockUserRepository();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
activate TestConfig;
|
|
54
|
+
|
|
55
|
+
const service = new UserService();
|
|
56
|
+
console.log(service.repo.findById("42"));
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Transpile it:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npx dison user-service.dis
|
|
63
|
+
# 🎉 Success: user-service.dis ➔ user-service.ts
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The generated `user-service.ts` is plain TypeScript — compile and run
|
|
67
|
+
it with your normal toolchain (`tsc`, `tsx`, `ts-node`, ...).
|
|
68
|
+
|
|
69
|
+
## Syntax reference
|
|
70
|
+
|
|
71
|
+
Dison only interprets six keywords. Everything else in a `.dis` file
|
|
72
|
+
is ordinary TypeScript, passed through unchanged.
|
|
73
|
+
|
|
74
|
+
### `injectable`
|
|
75
|
+
|
|
76
|
+
Declares a lazily-resolved, overridable property inside a class body.
|
|
77
|
+
|
|
78
|
+
```dison
|
|
79
|
+
class UserService {
|
|
80
|
+
injectable repo: SqlUserRepository;
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
For types that can't be auto-constructed with `new`
|
|
85
|
+
(`interface`, `type` alias, `abstract class`, array/union/function
|
|
86
|
+
types), a default initializer is required:
|
|
87
|
+
|
|
88
|
+
```dison
|
|
89
|
+
class UserService {
|
|
90
|
+
injectable repo: IUserRepository = new SqlUserRepository();
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### `configuration` / `activate`
|
|
95
|
+
|
|
96
|
+
Groups a set of `override`/`bind` statements and activates them
|
|
97
|
+
explicitly:
|
|
98
|
+
|
|
99
|
+
```dison
|
|
100
|
+
configuration TestConfig {
|
|
101
|
+
override UserService { repo = new MockUserRepository(); }
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
activate TestConfig;
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`configuration` must be written at the top level. To activate a
|
|
108
|
+
configuration defined in another file:
|
|
109
|
+
|
|
110
|
+
```dison
|
|
111
|
+
activate TestConfig from "./configs";
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### `override`
|
|
115
|
+
|
|
116
|
+
Replaces a single property on a specific class:
|
|
117
|
+
|
|
118
|
+
```dison
|
|
119
|
+
override UserService {
|
|
120
|
+
repo = new MockUserRepository();
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`override` can also be written standalone (not wrapped in a
|
|
125
|
+
`configuration`), which desugars to an immediate assignment — useful
|
|
126
|
+
inside a function to capture a lexical variable:
|
|
127
|
+
|
|
128
|
+
```dison
|
|
129
|
+
function createHarness(label: string) {
|
|
130
|
+
class Tagged extends Base { tag = label; }
|
|
131
|
+
override S { dep = new Tagged(); }
|
|
132
|
+
return new S();
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### `bind`
|
|
137
|
+
|
|
138
|
+
Replaces every use of a type, wherever it's requested (not just one
|
|
139
|
+
property):
|
|
140
|
+
|
|
141
|
+
```dison
|
|
142
|
+
bind SqlUserRepository = MockUserRepository;
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
`bind` supports generics on both sides (`bind Repository<User> = MockRepository;`)
|
|
146
|
+
and can be written standalone or inside a `configuration`, same as
|
|
147
|
+
`override`.
|
|
148
|
+
|
|
149
|
+
### `token`
|
|
150
|
+
|
|
151
|
+
Disambiguates `bind`/`injectable` when the same interface or type
|
|
152
|
+
alias name exists in more than one file:
|
|
153
|
+
|
|
154
|
+
```dison
|
|
155
|
+
token RepoToken;
|
|
156
|
+
|
|
157
|
+
class S {
|
|
158
|
+
injectable dep: IRepository as RepoToken = new Impl();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
configuration Cfg {
|
|
162
|
+
bind IRepository as RepoToken = Mock;
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
If two files each declare their own `IRepository` interface and both
|
|
167
|
+
are used in `bind`/`injectable` without a token, the CLI reports a
|
|
168
|
+
build error instead of silently letting one collide with the other.
|
|
169
|
+
|
|
170
|
+
## Multiple files
|
|
171
|
+
|
|
172
|
+
Pass more than one file to the CLI to transpile a project as a unit:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
npx dison a.dis b.dis c.dis
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Input files can live in different directories. Their generated output
|
|
179
|
+
shares override/bind state through the `@no22/dison/runtime` package
|
|
180
|
+
export, so an `override`/`bind` activated in one file is visible from
|
|
181
|
+
classes defined in another — as long as they all resolve
|
|
182
|
+
`@no22/dison/runtime` to the same installed copy (in practice: they're part of the same project
|
|
183
|
+
and share a common `node_modules` ancestor, which is the normal case).
|
|
184
|
+
|
|
185
|
+
## Samples
|
|
186
|
+
|
|
187
|
+
See [`sample/`](sample/) for runnable, self-contained examples covering
|
|
188
|
+
`injectable`/`override`/`activate`, `bind` (including generics and
|
|
189
|
+
chaining), and a multi-file project using `token` to disambiguate
|
|
190
|
+
same-named interfaces across files.
|
|
191
|
+
|
|
192
|
+
## License
|
|
193
|
+
|
|
194
|
+
ISC
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Token } from "./lexer.js";
|
|
2
|
+
export declare function nextSignificantToken(tokens: Token[], fromIdx: number): Token | null;
|
|
3
|
+
export declare function prevSignificantToken(tokens: Token[], fromIdx: number): Token | null;
|
|
4
|
+
export declare function parseStringLiteralValue(tokenText: string): string;
|
|
5
|
+
export declare function collectConfigurationNames(tokens: Token[]): Set<string>;
|
|
6
|
+
export declare function collectImportedConfigurationNames(tokens: Token[]): Set<string>;
|
|
7
|
+
export declare function collectImportOrigins(tokens: Token[]): Map<string, string>;
|
|
8
|
+
export interface DeclaredTypeKinds {
|
|
9
|
+
classNames: Set<string>;
|
|
10
|
+
nonNewableTypeNames: Set<string>;
|
|
11
|
+
}
|
|
12
|
+
export declare function collectDeclaredTypeKinds(tokens: Token[]): DeclaredTypeKinds;
|
|
13
|
+
export declare function isSimpleTypeShape(typeName: string): boolean;
|
|
14
|
+
export declare function baseIdentifierOf(typeName: string): string;
|
|
15
|
+
export declare function isRiskyInjectableType(typeKey: string, typeKinds: DeclaredTypeKinds): boolean;
|
|
16
|
+
export interface BlockContext {
|
|
17
|
+
isTopLevel(idx: number): boolean;
|
|
18
|
+
isDirectClassBodyChild(idx: number): boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare function collectBlockContext(tokens: Token[]): BlockContext;
|
|
21
|
+
//# sourceMappingURL=analysis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analysis.d.ts","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGxC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAInF;AAKD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAInF;AAOD,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAcjE;AAOD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAatE;AAcD,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAyB9E;AAYD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA6DzE;AAeD,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACxB,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAClC;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,iBAAiB,CA6B3E;AAOD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE3D;AAID,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGzD;AAUD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,GAAG,OAAO,CAI5F;AAwBD,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC9C;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,YAAY,CA8BjE"}
|
package/dist/analysis.js
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
// =====================================================================
|
|
2
|
+
// トークン列に対する事前解析(Parser本体を経由せずに動く軽量な事前スキャン群)
|
|
3
|
+
// =====================================================================
|
|
4
|
+
//
|
|
5
|
+
// ここに集めた関数は、いずれも「トークン列を1回舐めるだけの、Parserを
|
|
6
|
+
// 構築しなくても呼べる」解析。Parserの補助(activateのタイプミス検出、
|
|
7
|
+
// injectableの危険な型判定、構文的な位置制約の判定)と、複数ファイルを
|
|
8
|
+
// 横断する衝突検出(collisions.ts)の両方から使われる。
|
|
9
|
+
// whitespace/comment を飛ばした上で「意味のある」トークンを覗き見る。
|
|
10
|
+
export function nextSignificantToken(tokens, fromIdx) {
|
|
11
|
+
let j = fromIdx;
|
|
12
|
+
while (j < tokens.length && (tokens[j].type === "whitespace" || tokens[j].type === "comment"))
|
|
13
|
+
j++;
|
|
14
|
+
return j < tokens.length ? tokens[j] : null;
|
|
15
|
+
}
|
|
16
|
+
// nextSignificantToken の逆方向版。あるトークンの直前にある「意味のある」
|
|
17
|
+
// トークン(whitespace/comment以外)を覗き見る。`abstract class X` の
|
|
18
|
+
// `abstract` を検出するために使う。
|
|
19
|
+
export function prevSignificantToken(tokens, fromIdx) {
|
|
20
|
+
let j = fromIdx;
|
|
21
|
+
while (j >= 0 && (tokens[j].type === "whitespace" || tokens[j].type === "comment"))
|
|
22
|
+
j--;
|
|
23
|
+
return j >= 0 ? tokens[j] : null;
|
|
24
|
+
}
|
|
25
|
+
// 文字列リテラルトークンの生テキスト(クォート込み)から実際の文字列値を
|
|
26
|
+
// 取り出す(クォートを剥がし、簡易的にエスケープを解決する)。
|
|
27
|
+
// "activate Name from '...';" のパス文字列を正規化されたキーとして扱う
|
|
28
|
+
// ために使う("./configs" と './configs' のようなクォートスタイルの
|
|
29
|
+
// 違いを同一視するため)。
|
|
30
|
+
export function parseStringLiteralValue(tokenText) {
|
|
31
|
+
const inner = tokenText.slice(1, -1);
|
|
32
|
+
return inner.replace(/\\(.)/g, (_match, ch) => {
|
|
33
|
+
switch (ch) {
|
|
34
|
+
case "n":
|
|
35
|
+
return "\n";
|
|
36
|
+
case "t":
|
|
37
|
+
return "\t";
|
|
38
|
+
case "r":
|
|
39
|
+
return "\r";
|
|
40
|
+
default:
|
|
41
|
+
return ch;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
// ソース全体のトークン列から、定義されている `configuration` の名前を
|
|
46
|
+
// あらかじめすべて収集しておく。`activate ConfigName;` のタイプミス検出のために使う。
|
|
47
|
+
// 生成後のTSでは `function activateXxx() {}` は巻き上げられるため、
|
|
48
|
+
// ソース内で activate が configuration より前に書かれていても問題なく動作する。
|
|
49
|
+
// そのため検証も「ファイル全体」を対象に行う。
|
|
50
|
+
export function collectConfigurationNames(tokens) {
|
|
51
|
+
const names = new Set();
|
|
52
|
+
for (let idx = 0; idx < tokens.length; idx++) {
|
|
53
|
+
const t = tokens[idx];
|
|
54
|
+
if (t.type === "keyword" && t.text === "configuration") {
|
|
55
|
+
let j = idx + 1;
|
|
56
|
+
while (j < tokens.length && (tokens[j].type === "whitespace" || tokens[j].type === "comment"))
|
|
57
|
+
j++;
|
|
58
|
+
if (j < tokens.length && tokens[j].type === "ident") {
|
|
59
|
+
names.add(tokens[j].text);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return names;
|
|
64
|
+
}
|
|
65
|
+
// 複数ファイル対応(docs/multi-file-support.md): `configuration`が別ファイルで
|
|
66
|
+
// 定義され、`import { activateTestConfig } from "./configs";`のように
|
|
67
|
+
// importされている場合も、`activate TestConfig;`を有効なものとして扱えるように
|
|
68
|
+
// する。importの波カッコの中に現れる識別子のうち "activate" で始まるものを
|
|
69
|
+
// 拾い、その接尾辞(ConfigName部分)を収集する。
|
|
70
|
+
//
|
|
71
|
+
// これはヒューリスティックであり、`import { activateFoo as bar }`のような
|
|
72
|
+
// エイリアス(実際にこのファイルで使えるローカルな名前は"bar"であって
|
|
73
|
+
// "activateFoo"ではない)までは正確に判定していない
|
|
74
|
+
// (他のヒューリスティックと同様の既知の限界)。存在しない名前を実際に
|
|
75
|
+
// importしてしまった場合の検出は、このDison独自のタイプミス検出ではなく
|
|
76
|
+
// tsc自身の「モジュールに該当するエクスポートがない」エラーに委ねる。
|
|
77
|
+
export function collectImportedConfigurationNames(tokens) {
|
|
78
|
+
const names = new Set();
|
|
79
|
+
const ACTIVATE_PREFIX = "activate";
|
|
80
|
+
for (let idx = 0; idx < tokens.length; idx++) {
|
|
81
|
+
const t = tokens[idx];
|
|
82
|
+
if (t.type !== "ident" || t.text !== "import")
|
|
83
|
+
continue;
|
|
84
|
+
let j = idx + 1;
|
|
85
|
+
while (j < tokens.length && !(tokens[j].type === "punct" && (tokens[j].text === "{" || tokens[j].text === ";"))) {
|
|
86
|
+
j++;
|
|
87
|
+
}
|
|
88
|
+
if (!(j < tokens.length && tokens[j].type === "punct" && tokens[j].text === "{"))
|
|
89
|
+
continue;
|
|
90
|
+
j++;
|
|
91
|
+
while (j < tokens.length && !(tokens[j].type === "punct" && tokens[j].text === "}")) {
|
|
92
|
+
const specTok = tokens[j];
|
|
93
|
+
if (specTok.type === "ident" && specTok.text.startsWith(ACTIVATE_PREFIX) && specTok.text.length > ACTIVATE_PREFIX.length) {
|
|
94
|
+
names.add(specTok.text.slice(ACTIVATE_PREFIX.length));
|
|
95
|
+
}
|
|
96
|
+
j++;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return names;
|
|
100
|
+
}
|
|
101
|
+
// 複数ファイルにまたがる bind/injectable の型名衝突検出(案D、
|
|
102
|
+
// docs/bind-interface-token.md)で使う。import文をスキャンし、
|
|
103
|
+
// "ローカルで使える名前 -> import specifier文字列" のマップを作る。
|
|
104
|
+
// import { X, Y as Z } from "spec"; の形から、Xは"spec"、Zも"spec"
|
|
105
|
+
// (エイリアス後のローカル名で記録する)というように収集する。
|
|
106
|
+
//
|
|
107
|
+
// これはヒューリスティックであり、`import * as NS from "spec"`のような
|
|
108
|
+
// 名前空間importや、`{ }`を伴わない形は捕捉できない(該当する名前は
|
|
109
|
+
// 「由来不明」として衝突検出の対象から除外される。誤検出を避けるため
|
|
110
|
+
// 安全側に倒す方針は他のヒューリスティックと同じ)。
|
|
111
|
+
export function collectImportOrigins(tokens) {
|
|
112
|
+
const origins = new Map();
|
|
113
|
+
for (let idx = 0; idx < tokens.length; idx++) {
|
|
114
|
+
const t = tokens[idx];
|
|
115
|
+
if (t.type !== "ident" || t.text !== "import")
|
|
116
|
+
continue;
|
|
117
|
+
let j = idx + 1;
|
|
118
|
+
while (j < tokens.length && !(tokens[j].type === "punct" && (tokens[j].text === "{" || tokens[j].text === ";"))) {
|
|
119
|
+
j++;
|
|
120
|
+
}
|
|
121
|
+
if (!(j < tokens.length && tokens[j].type === "punct" && tokens[j].text === "{"))
|
|
122
|
+
continue;
|
|
123
|
+
let depth = 1;
|
|
124
|
+
j++;
|
|
125
|
+
const specStart = j;
|
|
126
|
+
while (j < tokens.length && depth > 0) {
|
|
127
|
+
if (tokens[j].type === "punct" && tokens[j].text === "{")
|
|
128
|
+
depth++;
|
|
129
|
+
else if (tokens[j].type === "punct" && tokens[j].text === "}")
|
|
130
|
+
depth--;
|
|
131
|
+
if (depth > 0)
|
|
132
|
+
j++;
|
|
133
|
+
}
|
|
134
|
+
const braceEnd = j; // '}' のインデックス
|
|
135
|
+
let k = braceEnd + 1;
|
|
136
|
+
while (k < tokens.length && (tokens[k].type === "whitespace" || tokens[k].type === "comment"))
|
|
137
|
+
k++;
|
|
138
|
+
if (!(k < tokens.length && tokens[k].type === "ident" && tokens[k].text === "from"))
|
|
139
|
+
continue;
|
|
140
|
+
k++;
|
|
141
|
+
while (k < tokens.length && (tokens[k].type === "whitespace" || tokens[k].type === "comment"))
|
|
142
|
+
k++;
|
|
143
|
+
if (!(k < tokens.length && tokens[k].type === "string"))
|
|
144
|
+
continue;
|
|
145
|
+
const specifier = parseStringLiteralValue(tokens[k].text);
|
|
146
|
+
// specStart..braceEnd の中の "IDENT (as IDENT)?" をカンマ区切りで読む
|
|
147
|
+
let p = specStart;
|
|
148
|
+
let pendingName = null;
|
|
149
|
+
let pendingAlias = null;
|
|
150
|
+
const flush = () => {
|
|
151
|
+
if (pendingName !== null) {
|
|
152
|
+
origins.set(pendingAlias ?? pendingName, specifier);
|
|
153
|
+
}
|
|
154
|
+
pendingName = null;
|
|
155
|
+
pendingAlias = null;
|
|
156
|
+
};
|
|
157
|
+
while (p < braceEnd) {
|
|
158
|
+
const specTok = tokens[p];
|
|
159
|
+
if (specTok.type === "ident" && specTok.text === "as") {
|
|
160
|
+
p++;
|
|
161
|
+
while (p < braceEnd && (tokens[p].type === "whitespace" || tokens[p].type === "comment"))
|
|
162
|
+
p++;
|
|
163
|
+
if (p < braceEnd && tokens[p].type === "ident") {
|
|
164
|
+
pendingAlias = tokens[p].text;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
else if (specTok.type === "punct" && specTok.text === ",") {
|
|
168
|
+
flush();
|
|
169
|
+
}
|
|
170
|
+
else if (specTok.type === "ident" && pendingName === null) {
|
|
171
|
+
pendingName = specTok.text;
|
|
172
|
+
}
|
|
173
|
+
p++;
|
|
174
|
+
}
|
|
175
|
+
flush();
|
|
176
|
+
}
|
|
177
|
+
return origins;
|
|
178
|
+
}
|
|
179
|
+
export function collectDeclaredTypeKinds(tokens) {
|
|
180
|
+
const classNames = new Set();
|
|
181
|
+
const nonNewableTypeNames = new Set();
|
|
182
|
+
for (let idx = 0; idx < tokens.length; idx++) {
|
|
183
|
+
const t = tokens[idx];
|
|
184
|
+
if (t.type !== "ident")
|
|
185
|
+
continue;
|
|
186
|
+
if (t.text === "class") {
|
|
187
|
+
const nameTok = nextSignificantToken(tokens, idx + 1);
|
|
188
|
+
if (!nameTok || nameTok.type !== "ident")
|
|
189
|
+
continue;
|
|
190
|
+
const prevTok = prevSignificantToken(tokens, idx - 1);
|
|
191
|
+
const isAbstract = prevTok !== null && prevTok.type === "ident" && prevTok.text === "abstract";
|
|
192
|
+
if (isAbstract) {
|
|
193
|
+
// abstract class は new 不可能なので、interface/type と同じ扱いにする
|
|
194
|
+
// (classNames には入れない。同名の非abstract classが別途あれば
|
|
195
|
+
// 宣言マージとみなし、下の nonNewableTypeNames 側の判定で除外される)
|
|
196
|
+
nonNewableTypeNames.add(nameTok.text);
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
classNames.add(nameTok.text);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
else if (t.text === "interface" || t.text === "type") {
|
|
203
|
+
const nameTok = nextSignificantToken(tokens, idx + 1);
|
|
204
|
+
if (nameTok && nameTok.type === "ident")
|
|
205
|
+
nonNewableTypeNames.add(nameTok.text);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return { classNames, nonNewableTypeNames };
|
|
209
|
+
}
|
|
210
|
+
// 型注釈が「単純な型参照(+ジェネリクス)」の形かどうかを判定する。
|
|
211
|
+
// 例: "SqlUserRepository" / "IUserRepository" / "Repository<User>" は true。
|
|
212
|
+
// 一方 "User[]"(配列型)、"A | B"(ユニオン型)、"(x: number) => void"(関数型)
|
|
213
|
+
// などは false になる。これはあくまで構文上の形の判定であり、
|
|
214
|
+
// クラスかインターフェースかまでは区別しない(それは isRiskyInjectableType で行う)。
|
|
215
|
+
export function isSimpleTypeShape(typeName) {
|
|
216
|
+
return /^[A-Za-z_$][\w$]*(\s*<[\s\S]+>)?$/.test(typeName.trim());
|
|
217
|
+
}
|
|
218
|
+
// 型注釈の先頭の識別子部分だけを取り出す(ジェネリクス部分を除く)。
|
|
219
|
+
// 例: "Repository<User>" -> "Repository"
|
|
220
|
+
export function baseIdentifierOf(typeName) {
|
|
221
|
+
const m = typeName.trim().match(/^([A-Za-z_$][\w$]*)/);
|
|
222
|
+
return m ? m[1] : typeName.trim();
|
|
223
|
+
}
|
|
224
|
+
// injectableの型が「new で自動生成できない危険な型」かどうかを判定する。
|
|
225
|
+
// 危険な型は injectable 宣言で "= <式>" による既定初期化式が構文的に
|
|
226
|
+
// 必須になる(パーサがこの関数を使って強制する)。
|
|
227
|
+
//
|
|
228
|
+
// - 配列型・ユニオン型・関数型など(isSimpleTypeShapeがfalse)は常に危険。
|
|
229
|
+
// - 単純な識別子の形でも、このファイル内で interface / type エイリアス /
|
|
230
|
+
// abstract class として宣言されていると判定できた場合は危険
|
|
231
|
+
// (宣言マージで同名の非abstract classが別途あれば安全側に倒す)。
|
|
232
|
+
export function isRiskyInjectableType(typeKey, typeKinds) {
|
|
233
|
+
if (!isSimpleTypeShape(typeKey))
|
|
234
|
+
return true;
|
|
235
|
+
const base = baseIdentifierOf(typeKey);
|
|
236
|
+
return typeKinds.nonNewableTypeNames.has(base) && !typeKinds.classNames.has(base);
|
|
237
|
+
}
|
|
238
|
+
export function collectBlockContext(tokens) {
|
|
239
|
+
const depthAt = new Array(tokens.length);
|
|
240
|
+
const isClassBodyAt = new Array(tokens.length);
|
|
241
|
+
const blockStack = []; // 各要素: そのブロックがクラス本体ならtrue
|
|
242
|
+
let sawClassKeyword = false;
|
|
243
|
+
for (let idx = 0; idx < tokens.length; idx++) {
|
|
244
|
+
const t = tokens[idx];
|
|
245
|
+
depthAt[idx] = blockStack.length;
|
|
246
|
+
isClassBodyAt[idx] = blockStack.length > 0 ? blockStack[blockStack.length - 1] : false;
|
|
247
|
+
if (t.type === "ident" && t.text === "class") {
|
|
248
|
+
const next = nextSignificantToken(tokens, idx + 1);
|
|
249
|
+
const isObjectKeyShorthand = next !== null && next.type === "punct" && next.text === ":";
|
|
250
|
+
if (!isObjectKeyShorthand) {
|
|
251
|
+
sawClassKeyword = true;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
else if (t.type === "punct" && t.text === "{") {
|
|
255
|
+
blockStack.push(sawClassKeyword);
|
|
256
|
+
sawClassKeyword = false;
|
|
257
|
+
}
|
|
258
|
+
else if (t.type === "punct" && t.text === "}") {
|
|
259
|
+
blockStack.pop();
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
isTopLevel: (idx) => (depthAt[idx] ?? 0) === 0,
|
|
264
|
+
isDirectClassBodyChild: (idx) => isClassBodyAt[idx] ?? false,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=analysis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analysis.js","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"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"}
|
package/dist/ast.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export interface OverrideEntry {
|
|
2
|
+
kind: "override";
|
|
3
|
+
className: string;
|
|
4
|
+
assignments: {
|
|
5
|
+
prop: string;
|
|
6
|
+
valueExpr: string;
|
|
7
|
+
}[];
|
|
8
|
+
}
|
|
9
|
+
export interface BindEntry {
|
|
10
|
+
kind: "bind";
|
|
11
|
+
originalTypeName: string;
|
|
12
|
+
originalTypeKey: string;
|
|
13
|
+
replacementTypeName: string;
|
|
14
|
+
replacementTypeKey: string;
|
|
15
|
+
token?: string;
|
|
16
|
+
}
|
|
17
|
+
export type ConfigEntry = OverrideEntry | BindEntry;
|
|
18
|
+
export type Node = {
|
|
19
|
+
kind: "raw";
|
|
20
|
+
text: string;
|
|
21
|
+
} | {
|
|
22
|
+
kind: "configuration";
|
|
23
|
+
name: string;
|
|
24
|
+
entries: ConfigEntry[];
|
|
25
|
+
} | {
|
|
26
|
+
kind: "injectable";
|
|
27
|
+
propName: string;
|
|
28
|
+
typeName: string;
|
|
29
|
+
typeKey: string;
|
|
30
|
+
defaultExpr?: string;
|
|
31
|
+
token?: string;
|
|
32
|
+
} | {
|
|
33
|
+
kind: "token";
|
|
34
|
+
name: string;
|
|
35
|
+
} | {
|
|
36
|
+
kind: "activate";
|
|
37
|
+
name: string;
|
|
38
|
+
fromPath?: string;
|
|
39
|
+
} | {
|
|
40
|
+
kind: "standalone-override";
|
|
41
|
+
entry: OverrideEntry;
|
|
42
|
+
} | {
|
|
43
|
+
kind: "standalone-bind";
|
|
44
|
+
entry: BindEntry;
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=ast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACpD;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IAKb,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAK3B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,SAAS,CAAC;AAEpD,MAAM,MAAM,IAAI,GACZ;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,EAAE,CAAA;CAAE,GAE/D;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAGjH;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAI/B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAGrD;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,KAAK,EAAE,aAAa,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC"}
|
package/dist/ast.js
ADDED
package/dist/ast.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast.js","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,WAAW;AACX,wEAAwE"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|