Skip to content

Commit a52e37e

Browse files
committed
JsModules: updated after the meeting; added some thoughts and the alternative solution.
1 parent af35c13 commit a52e37e

File tree

1 file changed

+49
-73
lines changed

1 file changed

+49
-73
lines changed

proposals/js/consume-js-modules.md

+49-73
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,12 @@ It can be achieved by adding yet another parameter to the annotation or add a ne
6060
```kotlin
6161
@Retention(AnnotationRetention.BINARY)
6262
@Target(AnnotationTarget.FILE)
63-
annotation class JsPackage(val path: String)
63+
annotation class JsQualifier(val value: String)
6464
```
65-
[TODO] think up a better name.
65+
66+
Other possible names:
67+
* JsPackage(val qualifier: String)
68+
* JsPackagePrefix(val value: String)
6669

6770
The new annotation prefered because it can be reused in two cases:
6871
1. _Major:_ for native declarations inside nested namespaces / packages.
@@ -80,8 +83,6 @@ Possible solutions:
8083
1. Add additional parameter to `JsModule` annotation
8184
Pros:
8285
- minor: simpler to discover
83-
Cons:
84-
- it makes harder to reuse `JsModule` annotation for non-external declaration in the future
8586
- maybe it'll strange to see a parameter about declaration in the annotation about module
8687

8788
2. Add separate annotation
@@ -94,9 +95,16 @@ Note:
9495
- the annotation allowed only on native declarations
9596
- the annotation w/o `JsModule` doesn't change anything
9697

98+
3. JsModule + native
99+
Pros:
100+
- simple, no extra annotation (?)
101+
Cons:
102+
- prevents the replacement of `@native` by `external`
103+
97104
Another problem is to think up a good name for that.
98105

99106
Some name candidates:
107+
- JsPlainAccess (Calls)
100108
- JsSimpleModule
101109
- JsNonModule
102110
- JsPlainModule
@@ -107,8 +115,7 @@ Some name candidates:
107115
- existsOutsideOfModule
108116
- availableOutsideOfModule
109117

110-
111-
**NOTE: In following code fragments temporary used `JsNonModule` annotation.**
118+
_**Decision:** use `JsNonModule` annotations in prototype_
112119

113120
## Use cases (based on TypeScript declarations)
114121

@@ -196,83 +203,52 @@ package SomeModule
196203
@native var prop: MyClass = noImpl
197204
```
198205

199-
## Implementation details
206+
## Frontend
207+
- Native declarations w/o both annotations (`JsNonModule`, `JsNonModule`) available when compile with any module kind.
208+
- Prohibit to use native declarations annotated by `JsModule` and not annotated by `JsNonModule` when compile with module kind == PLAIN.
209+
- Prohibit to use native declarations annotated by `JsNonModule` and not annotated by `JsModule` when compile with module kind != PLAIN.
210+
- Prohibit to use declarations annotated by only `JsNonModule` or `JsNonModule` when compile with module kind == UMD.
211+
- Prohibit to apply `JsModule` and `JsNonModule` annotation to non-native declarations, except files.
200212

201-
### Backend
202213

203-
Let's consider the following files:
214+
## Open questions
215+
1. Can we introduce default value for `import` parameter of `JsModule` and use the name of declaration as import string when argument not provided?<br/>
216+
If so, how it should work when the annotation used on file?
204217

205-
**declarations1.kt**
206-
```kotlin
207-
@file:JsModule("first-module")
218+
_**Decision:** not now_
208219

209-
var a: Int = noImpl
210-
```
220+
2. How import/export modules in non module kinds when import string is not valid identifier (it's possible for IDEA modules)?
221+
<br/>
222+
Right now we valid identifiers use as is and generate something like `this["module-name"]` otherwise. But:
223+
- it looks asymmetric;
224+
- nobody use `this["module-name"]`.
211225

212-
**declarations2.kt**
213-
```kotlin
214-
@JsModule("second-module")
215-
var b: Int = noImpl
216-
```
226+
Possible solutions:
227+
- always use `sanitized_name`;
228+
- always use `this[module-name]`;
229+
- always use both.
217230

218-
**declarations3.kt**
219-
```kotlin
220-
@file: JsModule("thirdModule")
231+
_**Propose:** decide it later._
221232

222-
var c: Int = noImpl
223-
```
224233

225-
**declarations4.kt**
226-
```kotlin
227-
@JsModule("fourthModule")
228-
var d: Int = noImpl
229-
```
234+
## Alternative solution
235+
Use the one annotation instead of two:
230236

231-
**usage.kt**
232237
```kotlin
233-
fun test() {
234-
println(a)
235-
println(b)
236-
println(c)
237-
println(d)
238-
}
239-
```
240-
241-
Use import value as is to declare dependencies when translate them with **module kind COMMON_JS or AMD**.
242-
<br/>E.g. for CommonJS generate following:
243-
```javascript
244-
var first_module = require("first-module");
245-
var b = require("second-module");
246-
var thirdModule = require("thirdModule");
247-
var d = require("fourthModule");
248-
//...
249-
```
250-
251-
When **module kind is SIMPLE**
252-
- If import value is valid JS identifier use it as is as name of identifier;
253-
- Otherwise, try to get from `this` using import value as is (as string).
238+
@Retention(AnnotationRetention.BINARY)
239+
@Target(
240+
AnnotationTarget.CLASS,
241+
AnnotationTarget.PROPERTY,
242+
AnnotationTarget.FUNCTION,
243+
AnnotationTarget.FILE)
244+
@Repeatable
245+
annotation class JsAccessible(from: ModuleType, import: String)
254246

255-
```javascript
256-
(function(first_module, b, thirdModule, d) {
257-
// ...
258-
println(first_module.a, b, thirdModule.c, d);
259-
// ...
260-
}(this["first-module"], this["second-module"], thirdModule, fourthModule));
247+
// alternative names: JsModule, Module
248+
enum class ModuleType {
249+
NONE, // NON_MODULE
250+
SYSTEM // MODULE_SYSTEM
251+
}
261252
```
262253

263-
And for **module kind is UMD** compiler should use relevant rule for each block.
264-
265-
### Frontend
266-
- Prohibit to apply `JsModule` annotation to non-native declarations, except files.<br/>
267-
It can be relaxed later e.g. to reuse this annotation to allow translate a file to separate JS module,
268-
it can be useful to interop with some frameworks (see [KT-12093](https://youtrack.jetbrains.com/issue/KT-12093))
269-
270-
### IDE
271-
- Add inspection for the case when some declarations with the same fq-name
272-
Consider next cases:
273-
- function overloads
274-
- package and functions
275-
276-
## Open questions
277-
1. Can we introduce default value for `import` parameter of `JsModule` and use the name of declaration as import string when argument not provided?<br/>
278-
If so, how it should work when the annotation used on file?
254+
So, current default PLAIN requires NON_MODULE type; AMD, CommonJS, SystemJS and ES2016 -- MODULE_SYSTEM; and UMD -- MODULE_SYSTEM & NON_MODULE

0 commit comments

Comments
 (0)