@matter/model 0.16.0-alpha.0-20251018-dd1ea6a8a → 0.16.0-alpha.0-20251020-3f6e46245
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/dist/cjs/common/Metatype.d.ts +1 -1
- package/dist/cjs/decoration/decorators/attribute.d.ts +11 -0
- package/dist/cjs/decoration/decorators/attribute.d.ts.map +1 -0
- package/dist/cjs/decoration/decorators/attribute.js +32 -0
- package/dist/cjs/decoration/decorators/attribute.js.map +6 -0
- package/dist/cjs/decoration/decorators/cluster.d.ts +11 -0
- package/dist/cjs/decoration/decorators/cluster.d.ts.map +1 -0
- package/dist/cjs/decoration/decorators/cluster.js +32 -0
- package/dist/cjs/decoration/decorators/cluster.js.map +6 -0
- package/dist/cjs/decoration/decorators/command.d.ts +12 -0
- package/dist/cjs/decoration/decorators/command.d.ts.map +1 -0
- package/dist/cjs/decoration/decorators/command.js +34 -0
- package/dist/cjs/decoration/decorators/command.js.map +6 -0
- package/dist/cjs/decoration/decorators/datatype.d.ts +11 -0
- package/dist/cjs/decoration/decorators/datatype.d.ts.map +1 -0
- package/dist/cjs/decoration/decorators/datatype.js +32 -0
- package/dist/cjs/decoration/decorators/datatype.js.map +6 -0
- package/dist/cjs/decoration/decorators/element.d.ts +40 -0
- package/dist/cjs/decoration/decorators/element.d.ts.map +1 -0
- package/dist/cjs/decoration/decorators/element.js +101 -0
- package/dist/cjs/decoration/decorators/element.js.map +6 -0
- package/dist/cjs/decoration/decorators/event.d.ts +14 -0
- package/dist/cjs/decoration/decorators/event.d.ts.map +1 -0
- package/dist/cjs/decoration/decorators/event.js +32 -0
- package/dist/cjs/decoration/decorators/event.js.map +6 -0
- package/dist/cjs/decoration/decorators/field.d.ts +14 -0
- package/dist/cjs/decoration/decorators/field.d.ts.map +1 -0
- package/dist/cjs/decoration/decorators/field.js +32 -0
- package/dist/cjs/decoration/decorators/field.js.map +6 -0
- package/dist/cjs/decoration/decorators/index.d.ts +16 -0
- package/dist/cjs/decoration/decorators/index.d.ts.map +1 -0
- package/dist/cjs/decoration/decorators/index.js +33 -0
- package/dist/cjs/decoration/decorators/index.js.map +6 -0
- package/dist/cjs/decoration/decorators/listOf.d.ts +12 -0
- package/dist/cjs/decoration/decorators/listOf.d.ts.map +1 -0
- package/dist/cjs/decoration/decorators/listOf.js +47 -0
- package/dist/cjs/decoration/decorators/listOf.js.map +6 -0
- package/dist/cjs/decoration/decorators/mandatory.d.ts +11 -0
- package/dist/cjs/decoration/decorators/mandatory.d.ts.map +1 -0
- package/dist/cjs/decoration/decorators/mandatory.js +41 -0
- package/dist/cjs/decoration/decorators/mandatory.js.map +6 -0
- package/dist/cjs/decoration/decorators/nonvolatile.d.ts +11 -0
- package/dist/cjs/decoration/decorators/nonvolatile.d.ts.map +1 -0
- package/dist/cjs/decoration/decorators/nonvolatile.js +41 -0
- package/dist/cjs/decoration/decorators/nonvolatile.js.map +6 -0
- package/dist/cjs/decoration/decorators/nullable.d.ts +11 -0
- package/dist/cjs/decoration/decorators/nullable.d.ts.map +1 -0
- package/dist/cjs/decoration/decorators/nullable.js +41 -0
- package/dist/cjs/decoration/decorators/nullable.js.map +6 -0
- package/dist/cjs/decoration/decorators/response.d.ts +12 -0
- package/dist/cjs/decoration/decorators/response.d.ts.map +1 -0
- package/dist/cjs/decoration/decorators/response.js +49 -0
- package/dist/cjs/decoration/decorators/response.js.map +6 -0
- package/dist/cjs/decoration/errors.d.ts +29 -0
- package/dist/cjs/decoration/errors.d.ts.map +1 -0
- package/dist/cjs/decoration/errors.js +44 -0
- package/dist/cjs/decoration/errors.js.map +6 -0
- package/dist/cjs/decoration/index.d.ts +9 -0
- package/dist/cjs/decoration/index.d.ts.map +1 -0
- package/dist/cjs/decoration/index.js +26 -0
- package/dist/cjs/decoration/index.js.map +6 -0
- package/dist/cjs/decoration/semantics/ClassSemantics.d.ts +84 -0
- package/dist/cjs/decoration/semantics/ClassSemantics.d.ts.map +1 -0
- package/dist/cjs/decoration/semantics/ClassSemantics.js +266 -0
- package/dist/cjs/decoration/semantics/ClassSemantics.js.map +6 -0
- package/dist/cjs/decoration/semantics/FieldSemantics.d.ts +21 -0
- package/dist/cjs/decoration/semantics/FieldSemantics.d.ts.map +1 -0
- package/dist/cjs/decoration/semantics/FieldSemantics.js +57 -0
- package/dist/cjs/decoration/semantics/FieldSemantics.js.map +6 -0
- package/dist/cjs/decoration/semantics/Semantics.d.ts +68 -0
- package/dist/cjs/decoration/semantics/Semantics.d.ts.map +1 -0
- package/dist/cjs/decoration/semantics/Semantics.js +156 -0
- package/dist/cjs/decoration/semantics/Semantics.js.map +6 -0
- package/dist/cjs/decoration/semantics/index.d.ts +9 -0
- package/dist/cjs/decoration/semantics/index.d.ts.map +1 -0
- package/dist/cjs/decoration/semantics/index.js +26 -0
- package/dist/cjs/decoration/semantics/index.js.map +6 -0
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/models/AttributeModel.d.ts +1 -0
- package/dist/cjs/models/AttributeModel.d.ts.map +1 -1
- package/dist/cjs/models/AttributeModel.js +1 -0
- package/dist/cjs/models/AttributeModel.js.map +1 -1
- package/dist/cjs/models/Children.js +3 -3
- package/dist/cjs/models/Children.js.map +1 -1
- package/dist/cjs/models/CommandModel.d.ts +1 -0
- package/dist/cjs/models/CommandModel.d.ts.map +1 -1
- package/dist/cjs/models/CommandModel.js +1 -0
- package/dist/cjs/models/CommandModel.js.map +1 -1
- package/dist/cjs/models/EventModel.d.ts +1 -0
- package/dist/cjs/models/EventModel.d.ts.map +1 -1
- package/dist/cjs/models/EventModel.js +1 -0
- package/dist/cjs/models/EventModel.js.map +1 -1
- package/dist/cjs/models/Globals.d.ts +1 -1
- package/dist/cjs/models/Model.d.ts +12 -3
- package/dist/cjs/models/Model.d.ts.map +1 -1
- package/dist/cjs/models/Model.js +16 -10
- package/dist/cjs/models/Model.js.map +1 -1
- package/dist/cjs/models/Schema.d.ts +14 -0
- package/dist/cjs/models/Schema.d.ts.map +1 -1
- package/dist/cjs/models/Schema.js +29 -1
- package/dist/cjs/models/Schema.js.map +1 -1
- package/dist/cjs/models/ScopeModel.d.ts +1 -1
- package/dist/cjs/models/ScopeModel.d.ts.map +1 -1
- package/dist/cjs/models/ScopeModel.js +2 -2
- package/dist/cjs/models/ScopeModel.js.map +1 -1
- package/dist/cjs/standard/elements/definitions.d.ts +1 -1
- package/dist/cjs/standard/elements/definitions.js +1 -1
- package/dist/cjs/standard/elements/{interval.element.d.ts → duration.element.d.ts} +1 -1
- package/dist/cjs/standard/elements/duration.element.d.ts.map +1 -0
- package/dist/cjs/standard/elements/{interval.element.js → duration.element.js} +4 -4
- package/dist/cjs/standard/elements/{interval.element.js.map → duration.element.js.map} +1 -1
- package/dist/cjs/standard/elements/models.d.ts +1 -1
- package/dist/cjs/standard/elements/models.js +2 -2
- package/dist/esm/common/Metatype.d.ts +1 -1
- package/dist/esm/decoration/decorators/attribute.d.ts +11 -0
- package/dist/esm/decoration/decorators/attribute.d.ts.map +1 -0
- package/dist/esm/decoration/decorators/attribute.js +12 -0
- package/dist/esm/decoration/decorators/attribute.js.map +6 -0
- package/dist/esm/decoration/decorators/cluster.d.ts +11 -0
- package/dist/esm/decoration/decorators/cluster.d.ts.map +1 -0
- package/dist/esm/decoration/decorators/cluster.js +12 -0
- package/dist/esm/decoration/decorators/cluster.js.map +6 -0
- package/dist/esm/decoration/decorators/command.d.ts +12 -0
- package/dist/esm/decoration/decorators/command.d.ts.map +1 -0
- package/dist/esm/decoration/decorators/command.js +14 -0
- package/dist/esm/decoration/decorators/command.js.map +6 -0
- package/dist/esm/decoration/decorators/datatype.d.ts +11 -0
- package/dist/esm/decoration/decorators/datatype.d.ts.map +1 -0
- package/dist/esm/decoration/decorators/datatype.js +12 -0
- package/dist/esm/decoration/decorators/datatype.js.map +6 -0
- package/dist/esm/decoration/decorators/element.d.ts +40 -0
- package/dist/esm/decoration/decorators/element.d.ts.map +1 -0
- package/dist/esm/decoration/decorators/element.js +81 -0
- package/dist/esm/decoration/decorators/element.js.map +6 -0
- package/dist/esm/decoration/decorators/event.d.ts +14 -0
- package/dist/esm/decoration/decorators/event.d.ts.map +1 -0
- package/dist/esm/decoration/decorators/event.js +12 -0
- package/dist/esm/decoration/decorators/event.js.map +6 -0
- package/dist/esm/decoration/decorators/field.d.ts +14 -0
- package/dist/esm/decoration/decorators/field.d.ts.map +1 -0
- package/dist/esm/decoration/decorators/field.js +12 -0
- package/dist/esm/decoration/decorators/field.js.map +6 -0
- package/dist/esm/decoration/decorators/index.d.ts +16 -0
- package/dist/esm/decoration/decorators/index.d.ts.map +1 -0
- package/dist/esm/decoration/decorators/index.js +16 -0
- package/dist/esm/decoration/decorators/index.js.map +6 -0
- package/dist/esm/decoration/decorators/listOf.d.ts +12 -0
- package/dist/esm/decoration/decorators/listOf.d.ts.map +1 -0
- package/dist/esm/decoration/decorators/listOf.js +27 -0
- package/dist/esm/decoration/decorators/listOf.js.map +6 -0
- package/dist/esm/decoration/decorators/mandatory.d.ts +11 -0
- package/dist/esm/decoration/decorators/mandatory.d.ts.map +1 -0
- package/dist/esm/decoration/decorators/mandatory.js +21 -0
- package/dist/esm/decoration/decorators/mandatory.js.map +6 -0
- package/dist/esm/decoration/decorators/nonvolatile.d.ts +11 -0
- package/dist/esm/decoration/decorators/nonvolatile.d.ts.map +1 -0
- package/dist/esm/decoration/decorators/nonvolatile.js +21 -0
- package/dist/esm/decoration/decorators/nonvolatile.js.map +6 -0
- package/dist/esm/decoration/decorators/nullable.d.ts +11 -0
- package/dist/esm/decoration/decorators/nullable.d.ts.map +1 -0
- package/dist/esm/decoration/decorators/nullable.js +21 -0
- package/dist/esm/decoration/decorators/nullable.js.map +6 -0
- package/dist/esm/decoration/decorators/response.d.ts +12 -0
- package/dist/esm/decoration/decorators/response.d.ts.map +1 -0
- package/dist/esm/decoration/decorators/response.js +29 -0
- package/dist/esm/decoration/decorators/response.js.map +6 -0
- package/dist/esm/decoration/errors.d.ts +29 -0
- package/dist/esm/decoration/errors.d.ts.map +1 -0
- package/dist/esm/decoration/errors.js +24 -0
- package/dist/esm/decoration/errors.js.map +6 -0
- package/dist/esm/decoration/index.d.ts +9 -0
- package/dist/esm/decoration/index.d.ts.map +1 -0
- package/dist/esm/decoration/index.js +9 -0
- package/dist/esm/decoration/index.js.map +6 -0
- package/dist/esm/decoration/semantics/ClassSemantics.d.ts +84 -0
- package/dist/esm/decoration/semantics/ClassSemantics.d.ts.map +1 -0
- package/dist/esm/decoration/semantics/ClassSemantics.js +246 -0
- package/dist/esm/decoration/semantics/ClassSemantics.js.map +6 -0
- package/dist/esm/decoration/semantics/FieldSemantics.d.ts +21 -0
- package/dist/esm/decoration/semantics/FieldSemantics.d.ts.map +1 -0
- package/dist/esm/decoration/semantics/FieldSemantics.js +37 -0
- package/dist/esm/decoration/semantics/FieldSemantics.js.map +6 -0
- package/dist/esm/decoration/semantics/Semantics.d.ts +68 -0
- package/dist/esm/decoration/semantics/Semantics.d.ts.map +1 -0
- package/dist/esm/decoration/semantics/Semantics.js +126 -0
- package/dist/esm/decoration/semantics/Semantics.js.map +6 -0
- package/dist/esm/decoration/semantics/index.d.ts +9 -0
- package/dist/esm/decoration/semantics/index.d.ts.map +1 -0
- package/dist/esm/decoration/semantics/index.js +9 -0
- package/dist/esm/decoration/semantics/index.js.map +6 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/models/AttributeModel.d.ts +1 -0
- package/dist/esm/models/AttributeModel.d.ts.map +1 -1
- package/dist/esm/models/AttributeModel.js +1 -0
- package/dist/esm/models/AttributeModel.js.map +1 -1
- package/dist/esm/models/Children.js +3 -3
- package/dist/esm/models/Children.js.map +1 -1
- package/dist/esm/models/CommandModel.d.ts +1 -0
- package/dist/esm/models/CommandModel.d.ts.map +1 -1
- package/dist/esm/models/CommandModel.js +1 -0
- package/dist/esm/models/CommandModel.js.map +1 -1
- package/dist/esm/models/EventModel.d.ts +1 -0
- package/dist/esm/models/EventModel.d.ts.map +1 -1
- package/dist/esm/models/EventModel.js +1 -0
- package/dist/esm/models/EventModel.js.map +1 -1
- package/dist/esm/models/Globals.d.ts +1 -1
- package/dist/esm/models/Model.d.ts +12 -3
- package/dist/esm/models/Model.d.ts.map +1 -1
- package/dist/esm/models/Model.js +16 -10
- package/dist/esm/models/Model.js.map +1 -1
- package/dist/esm/models/Schema.d.ts +14 -0
- package/dist/esm/models/Schema.d.ts.map +1 -1
- package/dist/esm/models/Schema.js +29 -1
- package/dist/esm/models/Schema.js.map +1 -1
- package/dist/esm/models/ScopeModel.d.ts +1 -1
- package/dist/esm/models/ScopeModel.d.ts.map +1 -1
- package/dist/esm/models/ScopeModel.js +2 -2
- package/dist/esm/models/ScopeModel.js.map +1 -1
- package/dist/esm/standard/elements/definitions.d.ts +1 -1
- package/dist/esm/standard/elements/definitions.js +1 -1
- package/dist/esm/standard/elements/{interval.element.d.ts → duration.element.d.ts} +1 -1
- package/dist/esm/standard/elements/duration.element.d.ts.map +1 -0
- package/dist/esm/standard/elements/{interval.element.js → duration.element.js} +1 -1
- package/dist/esm/standard/elements/{interval.element.js.map → duration.element.js.map} +1 -1
- package/dist/esm/standard/elements/models.d.ts +1 -1
- package/dist/esm/standard/elements/models.js +2 -2
- package/package.json +4 -4
- package/src/decoration/decorators/attribute.ts +13 -0
- package/src/decoration/decorators/cluster.ts +13 -0
- package/src/decoration/decorators/command.ts +16 -0
- package/src/decoration/decorators/datatype.ts +13 -0
- package/src/decoration/decorators/element.ts +128 -0
- package/src/decoration/decorators/event.ts +16 -0
- package/src/decoration/decorators/field.ts +16 -0
- package/src/decoration/decorators/index.ts +16 -0
- package/src/decoration/decorators/listOf.ts +30 -0
- package/src/decoration/decorators/mandatory.ts +22 -0
- package/src/decoration/decorators/nonvolatile.ts +22 -0
- package/src/decoration/decorators/nullable.ts +22 -0
- package/src/decoration/decorators/response.ts +34 -0
- package/src/decoration/errors.ts +29 -0
- package/src/decoration/index.ts +9 -0
- package/src/decoration/semantics/ClassSemantics.ts +374 -0
- package/src/decoration/semantics/FieldSemantics.ts +49 -0
- package/src/decoration/semantics/Semantics.ts +170 -0
- package/src/decoration/semantics/index.ts +9 -0
- package/src/index.ts +1 -0
- package/src/models/AttributeModel.ts +1 -0
- package/src/models/Children.ts +3 -3
- package/src/models/CommandModel.ts +1 -0
- package/src/models/EventModel.ts +1 -0
- package/src/models/Model.ts +34 -12
- package/src/models/Schema.ts +51 -0
- package/src/models/ScopeModel.ts +2 -2
- package/src/standard/elements/definitions.ts +1 -1
- package/src/standard/elements/models.ts +1 -1
- package/dist/cjs/standard/elements/interval.element.d.ts.map +0 -1
- package/dist/esm/standard/elements/interval.element.d.ts.map +0 -1
- /package/src/standard/elements/{interval.element.ts → duration.element.ts} +0 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { FieldSemantics } from "#decoration/semantics/FieldSemantics.js";
|
|
8
|
+
import { CommandElement } from "#elements/CommandElement.js";
|
|
9
|
+
import { Decorator } from "#general";
|
|
10
|
+
import { CommandModel } from "#models/CommandModel.js";
|
|
11
|
+
import { DatatypeModel } from "#models/DatatypeModel.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Specify the response type for a command.
|
|
15
|
+
*/
|
|
16
|
+
export function response(type: DatatypeModel): Decorator.ClassMethod {
|
|
17
|
+
return Decorator((_target, context) => {
|
|
18
|
+
const requestSemantics = FieldSemantics.of(context);
|
|
19
|
+
|
|
20
|
+
requestSemantics.modelType = CommandModel;
|
|
21
|
+
const request = requestSemantics.mutableModel as CommandModel;
|
|
22
|
+
|
|
23
|
+
const name = `${request.name}Response`;
|
|
24
|
+
new CommandModel({
|
|
25
|
+
name,
|
|
26
|
+
id: request.id,
|
|
27
|
+
parent: request.parent,
|
|
28
|
+
direction: CommandElement.Direction.Response,
|
|
29
|
+
operationalBase: type,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
request.response = name;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { ImplementationError } from "#general";
|
|
8
|
+
|
|
9
|
+
export class MetadataError extends ImplementationError {}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Thrown when a type is assigned to a class or property that is already typed.
|
|
13
|
+
*/
|
|
14
|
+
export class MetadataConflictError extends MetadataError {}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Thrown when metadata is inappropriate for the decorated language element.
|
|
18
|
+
*/
|
|
19
|
+
export class InvalidMetadataError extends MetadataError {}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Thrown when an error occurs instantiating a dummy instance of a class for introspection purposes.
|
|
23
|
+
*/
|
|
24
|
+
export class ClassIntrospectionError extends MetadataError {}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Thrown when required metadata is missing.
|
|
28
|
+
*/
|
|
29
|
+
export class MissingMetadataError extends MetadataError {}
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Must import these via index to ensure proper initialization
|
|
8
|
+
import { DatatypeModel, FieldModel, Model } from "#models/index.js";
|
|
9
|
+
|
|
10
|
+
import { camelize } from "#general";
|
|
11
|
+
import { Scope } from "#logic/Scope.js";
|
|
12
|
+
import { any, struct } from "#standard/elements/models.js";
|
|
13
|
+
import { InvalidMetadataError, MetadataConflictError } from "../errors.js";
|
|
14
|
+
import { FieldSemantics } from "./FieldSemantics.js";
|
|
15
|
+
import { Semantics } from "./Semantics.js";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Our key into {@link DecoratorContext.metadata}.
|
|
19
|
+
*
|
|
20
|
+
* This is where we store the {@link ClassSemantics} associated with a decorated class.
|
|
21
|
+
*/
|
|
22
|
+
const matter = Symbol("matter");
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Our view of {@link DecoratorContext.metadata}.
|
|
26
|
+
*
|
|
27
|
+
* Note that in the case of class inheritance, the metadata also inherits from the parent metadata. So we need to use
|
|
28
|
+
* {@link Object.hasOwn} to differentiate between the {@link ClassSemantics} for a class and that of its base class.
|
|
29
|
+
*/
|
|
30
|
+
interface MatterMetadata {
|
|
31
|
+
[matter]?: ClassSemantics;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Matter semantic metadata attached to a class via decorators.
|
|
36
|
+
*
|
|
37
|
+
* We use decorators to allow for definition of model elements in the context of a specific type.
|
|
38
|
+
*
|
|
39
|
+
* Currently there are JavaScript/TypeScript limitations to be aware of when decorating type definitions:
|
|
40
|
+
*
|
|
41
|
+
* * Decorators may only be applied to JavaScript classes. So if you want to define an interface without
|
|
42
|
+
* implementation, you must implement as a class and use as an interface. That's why this is "class" metadata.
|
|
43
|
+
*
|
|
44
|
+
* * Decorators may not affect the TypeScript type of an object. This means that you must define both the Matter type
|
|
45
|
+
* (e.g. {@link uint32}) and TypeScript type (e.g. `number`).
|
|
46
|
+
*/
|
|
47
|
+
export class ClassSemantics extends Semantics {
|
|
48
|
+
#new?: ClassSemantics.Constructor;
|
|
49
|
+
#definedFields?: Map<string, FieldSemantics>;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The model that represents the semantics for this class.
|
|
53
|
+
*
|
|
54
|
+
* This may be {@link localModel} or {@link prototypeBaseModel}
|
|
55
|
+
*/
|
|
56
|
+
get semanticModel() {
|
|
57
|
+
if (this.localModel) {
|
|
58
|
+
// Model is defined here
|
|
59
|
+
return this.localModel;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (this.#definedFields) {
|
|
63
|
+
// Model has not been defined but should be due to decoration, so define it now
|
|
64
|
+
return this.mutableModel;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Return model inherited via prototype, if any. Otherwise we do not express semantics
|
|
68
|
+
return this.prototypeBaseModel;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Get the class constructor
|
|
73
|
+
*/
|
|
74
|
+
get new(): ClassSemantics.Constructor | undefined {
|
|
75
|
+
return this.#new;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Assign the constructor for the class.
|
|
80
|
+
*/
|
|
81
|
+
set new(fn: ClassSemantics.Constructor) {
|
|
82
|
+
if (this.#new === fn) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (this.isFinal) {
|
|
87
|
+
throw new MetadataConflictError(
|
|
88
|
+
`Cannot install semantic constructor ${fn.name} because semantics are final`,
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
this.#new = fn;
|
|
93
|
+
|
|
94
|
+
// Set name to match class
|
|
95
|
+
if (this.localModel && !this.localModel.isFinal && this.localModel.name !== this.#new?.name) {
|
|
96
|
+
this.localModel.name = this.#new?.name;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Update local semantics based on inherited semantics
|
|
100
|
+
if (this.localModel) {
|
|
101
|
+
// I have a model defined already so update according to base semantics
|
|
102
|
+
this.#applyBaseSemantics();
|
|
103
|
+
} else {
|
|
104
|
+
// I have no model defined yet so I am semantically equivalent to my base
|
|
105
|
+
const base = this.prototypeBaseModel;
|
|
106
|
+
if (base !== undefined) {
|
|
107
|
+
this.mutableModel = base;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* The class {@link Model} inherited from {@link new}'s prototype chain, if any.
|
|
114
|
+
*/
|
|
115
|
+
get prototypeBaseModel(): Model | undefined {
|
|
116
|
+
let current = this.#new?.prototype;
|
|
117
|
+
let base;
|
|
118
|
+
|
|
119
|
+
while (current) {
|
|
120
|
+
current = Object.getPrototypeOf(current) as unknown;
|
|
121
|
+
if (typeof current !== "object" || current === null) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const constructor = current.constructor;
|
|
125
|
+
if (constructor === Object) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
base = ClassSemantics.maybeOf(constructor);
|
|
129
|
+
|
|
130
|
+
if (base?.localModel) {
|
|
131
|
+
// Semantics and model may not mutate once acting as a base
|
|
132
|
+
base.finalize();
|
|
133
|
+
|
|
134
|
+
return base.localModel;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Obtain a {@link FieldSemantics} for the named field.
|
|
141
|
+
*/
|
|
142
|
+
fieldFor(name: string | symbol) {
|
|
143
|
+
if (typeof name !== "string") {
|
|
144
|
+
throw new InvalidMetadataError(`Cannot decorate symbolic function ${String(name)}`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (this.#definedFields === undefined) {
|
|
148
|
+
this.#definedFields = new Map();
|
|
149
|
+
}
|
|
150
|
+
let field = this.#definedFields.get(name);
|
|
151
|
+
if (field === undefined) {
|
|
152
|
+
if (this.isFinal) {
|
|
153
|
+
throw new MetadataConflictError(`Cannot install field ${name} because semantics are final`);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
this.#definedFields.set(name, (field = new FieldSemantics(this, name)));
|
|
157
|
+
}
|
|
158
|
+
return field;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Add logical fields for unrecognized members of an object.
|
|
163
|
+
*
|
|
164
|
+
* This extends the model with untyped fields for properties that are not otherwise typed.
|
|
165
|
+
*/
|
|
166
|
+
defineUnknownMembers(instance: unknown) {
|
|
167
|
+
if (instance === undefined || instance === null) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const known = this.semanticModel
|
|
172
|
+
? new Set(
|
|
173
|
+
Scope(this.semanticModel)
|
|
174
|
+
.membersOf(this.semanticModel)
|
|
175
|
+
.map(model => camelize(model.name)),
|
|
176
|
+
)
|
|
177
|
+
: new Set();
|
|
178
|
+
|
|
179
|
+
const descriptors = Object.getOwnPropertyDescriptors(instance);
|
|
180
|
+
|
|
181
|
+
for (const name in descriptors) {
|
|
182
|
+
// Skip if name is already known
|
|
183
|
+
if (known.has(camelize(name))) {
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// We only model string properties
|
|
188
|
+
if (typeof name !== "string") {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// We do not support write-only fields
|
|
193
|
+
const descriptor = descriptors[name];
|
|
194
|
+
if (descriptor.set && !descriptor.get) {
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Methods are not fields
|
|
199
|
+
try {
|
|
200
|
+
if (typeof (instance as Record<string, unknown>)[name] === "function") {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
} catch (e) {
|
|
204
|
+
// We do not support inaccessible fields
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const model = this.fieldFor(name).mutableModel as FieldModel;
|
|
209
|
+
|
|
210
|
+
model.operationalBase = any;
|
|
211
|
+
|
|
212
|
+
// Default to fixed if read-only
|
|
213
|
+
if (!descriptor.writable && !descriptor.set) {
|
|
214
|
+
model.quality = { ...model.quality, fixed: true };
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
this.fieldFor(name).mutableModel.operationalBase = any;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Obtain the {@link ClassSemantics} for {@link source}.
|
|
223
|
+
*/
|
|
224
|
+
static override of(source: ClassSemantics.Source) {
|
|
225
|
+
// Source is the semantics
|
|
226
|
+
if (source instanceof ClassSemantics) {
|
|
227
|
+
return source;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Source is decorator context
|
|
231
|
+
if (typeof source !== "function") {
|
|
232
|
+
const metadata = source.metadata as MatterMetadata;
|
|
233
|
+
if (Object.hasOwn(metadata, matter)) {
|
|
234
|
+
return metadata[matter]!;
|
|
235
|
+
}
|
|
236
|
+
return (metadata[matter] = new ClassSemantics());
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Source is a constructor
|
|
240
|
+
let metadata: MatterMetadata;
|
|
241
|
+
if (!Object.hasOwn(source, Symbol.metadata)) {
|
|
242
|
+
metadata = source[Symbol.metadata] = {};
|
|
243
|
+
} else {
|
|
244
|
+
metadata = source[Symbol.metadata] as MatterMetadata;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
let semantics: ClassSemantics;
|
|
248
|
+
if (!Object.hasOwn(metadata, matter)) {
|
|
249
|
+
semantics = metadata[matter] = new ClassSemantics();
|
|
250
|
+
} else {
|
|
251
|
+
semantics = metadata[matter] as ClassSemantics;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// If the parent class is not decorated then this may be the first time we've seen the constructor associated
|
|
255
|
+
// with the metadata. So always inform the metadata of its constructor
|
|
256
|
+
if (!semantics.new) {
|
|
257
|
+
semantics.new = source;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return semantics;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Determine {@link new} has semantic decoration.
|
|
265
|
+
*/
|
|
266
|
+
static hasOwnSemantics(source: ClassSemantics.Constructor) {
|
|
267
|
+
return Object.hasOwn(source, Symbol.metadata) && Object.hasOwn(source[Symbol.metadata]!, matter);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Access the {@link ClassSemantics} of {@link new} if it is defined.
|
|
272
|
+
*/
|
|
273
|
+
static maybeOf(source: ClassSemantics.Constructor) {
|
|
274
|
+
if (this.hasOwnSemantics(source)) {
|
|
275
|
+
return ClassSemantics.of(source);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
static {
|
|
280
|
+
Semantics.classOf = this.of;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
override finalize() {
|
|
284
|
+
if (this.isFinal) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Invoke any custom extension logic
|
|
289
|
+
this.#new?.[ClassSemantics.extend]?.(this);
|
|
290
|
+
|
|
291
|
+
// Apply base finalization
|
|
292
|
+
super.finalize();
|
|
293
|
+
|
|
294
|
+
// Finalize fields
|
|
295
|
+
if (this.#definedFields) {
|
|
296
|
+
for (const field of this.#definedFields.values()) {
|
|
297
|
+
field.finalize();
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
#applyBaseSemantics() {
|
|
303
|
+
const base = this.prototypeBaseModel;
|
|
304
|
+
if (base === undefined) {
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// If my model does not yet have an explicit base, I extend my parent class's model
|
|
309
|
+
const { type, base: currentBase } = this.mutableModel;
|
|
310
|
+
if (type === undefined && (currentBase === undefined || currentBase === struct)) {
|
|
311
|
+
const operationalBase = this.prototypeBaseModel;
|
|
312
|
+
if (operationalBase) {
|
|
313
|
+
this.mutableModel.operationalBase = operationalBase;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// If my base is not a datatype, it forces the type of my model
|
|
318
|
+
if (base && base.tag !== "datatype" && this.mutableModel.tag !== base.tag) {
|
|
319
|
+
this.modelType = base.constructor as Model.ConcreteType;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// If ID is not already set, force ID to match base
|
|
323
|
+
if (this.mutableModel.id === undefined && base.id !== undefined) {
|
|
324
|
+
this.mutableModel.id = base.id;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
protected override integrateModel(model: Model) {
|
|
329
|
+
// If local model is not yet set or is final, we have not extended; this is "swap base with no decoration" case
|
|
330
|
+
if (this.localModel === undefined || this.localModel.isFinal) {
|
|
331
|
+
return model;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// If incoming model is final, replace operational base of local model. This is "swap base with decoration"
|
|
335
|
+
// case
|
|
336
|
+
if (model.isFinal) {
|
|
337
|
+
this.localModel.operationalBase = model;
|
|
338
|
+
return this.localModel;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Neither model is final. Move any children to new model. This is "replace temporary model created by
|
|
342
|
+
// decorators" case
|
|
343
|
+
model.children.push(...this.localModel.children);
|
|
344
|
+
|
|
345
|
+
return model;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
protected override createModel(type: Model.ConcreteType = DatatypeModel) {
|
|
349
|
+
let name = this.#new?.name;
|
|
350
|
+
if (name === undefined || name === "") {
|
|
351
|
+
name = "Unnamed";
|
|
352
|
+
}
|
|
353
|
+
return new type({ name, operationalBase: struct });
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
export namespace ClassSemantics {
|
|
358
|
+
/**
|
|
359
|
+
* A standard constructor with an optional decoration extension point.
|
|
360
|
+
*/
|
|
361
|
+
export interface Constructor extends NewableFunction {
|
|
362
|
+
/**
|
|
363
|
+
* If present, invoked for custom decoration after installing constructor.
|
|
364
|
+
*/
|
|
365
|
+
[extend]?: (semantics: ClassSemantics) => void;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* An object for which you may obtain {@link ClassSemantics}.
|
|
370
|
+
*/
|
|
371
|
+
export type Source = Constructor | DecoratorContext | ClassSemantics;
|
|
372
|
+
|
|
373
|
+
export const extend = Symbol("extend");
|
|
374
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { InvalidMetadataError } from "#decoration/errors.js";
|
|
8
|
+
import { InternalError } from "#general";
|
|
9
|
+
import { FieldModel } from "#models/FieldModel.js";
|
|
10
|
+
import type { Model } from "#models/Model.js";
|
|
11
|
+
import type { ClassSemantics } from "./ClassSemantics.js";
|
|
12
|
+
import { Semantics } from "./Semantics.js";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Decorator metadata associated with a specific class field.
|
|
16
|
+
*/
|
|
17
|
+
export class FieldSemantics extends Semantics {
|
|
18
|
+
constructor(owner: ClassSemantics, name: string) {
|
|
19
|
+
super();
|
|
20
|
+
|
|
21
|
+
this.mutableModel = new FieldModel({ name, parent: owner.mutableModel });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
protected override createModel(): Model {
|
|
25
|
+
// We create our model unconditionally so this shouldn't happen
|
|
26
|
+
throw new InternalError("Unexpected FieldSemantics.createModel");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
protected override integrateModel(model: Model): Model {
|
|
30
|
+
if (this.localModel === undefined) {
|
|
31
|
+
return model;
|
|
32
|
+
}
|
|
33
|
+
this.mutableModel.operationalBase = model;
|
|
34
|
+
return this.mutableModel;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static override of(source: FieldSemantics.Source) {
|
|
38
|
+
if (source.kind === "class") {
|
|
39
|
+
throw new InvalidMetadataError(
|
|
40
|
+
`Cannot retrieve field semantics for class decorator ${source.name ?? "of anonymous class"}`,
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return Semantics.classOf(source).fieldFor(source.name);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export namespace FieldSemantics {
|
|
48
|
+
export type Source = DecoratorContext;
|
|
49
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { MetadataConflictError } from "#decoration/errors.js";
|
|
8
|
+
import { InternalError } from "#general";
|
|
9
|
+
import type { Model } from "#models/Model.js";
|
|
10
|
+
import * as models from "#standard/elements/models.js";
|
|
11
|
+
import type { ClassSemantics } from "./ClassSemantics.js";
|
|
12
|
+
|
|
13
|
+
const standardModels = new Set(Object.values(models) as Model[]);
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Base class for Matter semantics associated with JavaScript classes and properties.
|
|
17
|
+
*
|
|
18
|
+
* We model semantics using {@link Model}. The model may be built declaratively with decorators or programmatically
|
|
19
|
+
* using this interface directly.
|
|
20
|
+
*/
|
|
21
|
+
export abstract class Semantics {
|
|
22
|
+
#localModel?: Model;
|
|
23
|
+
#isFinal = false;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Determine whether these semantics are final.
|
|
27
|
+
*
|
|
28
|
+
* Once final no further mutation is allowed.
|
|
29
|
+
*/
|
|
30
|
+
get isFinal(): boolean {
|
|
31
|
+
return this.#isFinal;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Finalize the model.
|
|
36
|
+
*/
|
|
37
|
+
finalize() {
|
|
38
|
+
if (this.#isFinal) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
this.#isFinal = true;
|
|
43
|
+
Object.freeze(this);
|
|
44
|
+
this.#localModel?.finalize();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The {@link Model} defined by local decoration, if any.
|
|
49
|
+
*/
|
|
50
|
+
get localModel() {
|
|
51
|
+
return this.#localModel;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Set the model.
|
|
56
|
+
*
|
|
57
|
+
* When "setting" the model we need to merge semantics coming from decorators, the prototype hierarchy, and models
|
|
58
|
+
* provided programmatically.
|
|
59
|
+
*
|
|
60
|
+
* This may set the local model, change it or set its operational base. We use local state and the finalization
|
|
61
|
+
* status of the model to determine how to integrate.
|
|
62
|
+
*/
|
|
63
|
+
set mutableModel(model: Model) {
|
|
64
|
+
if (this.#isFinal) {
|
|
65
|
+
throw new MetadataConflictError(`Cannot modify final semantics of ${this.#localModel?.name ?? "(none)"}`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (this.#localModel === model) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// We don't finalize global models by default for performance reasons, but do finalize them here to prevent
|
|
73
|
+
// accidental mutation
|
|
74
|
+
if (standardModels.has(model)) {
|
|
75
|
+
model.finalize();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
this.#localModel = this.integrateModel(model);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Replace the "base" of {@link localModel} and return an updated model.
|
|
83
|
+
*/
|
|
84
|
+
protected abstract integrateModel(model: Model): Model;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Obtain a model unconditionally for mutation purposes.
|
|
88
|
+
*/
|
|
89
|
+
get mutableModel() {
|
|
90
|
+
if (this.#isFinal) {
|
|
91
|
+
throw new MetadataConflictError(`Cannot modify final semantics of ${this.#localModel?.name ?? "(none)"}`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (this.#localModel === undefined) {
|
|
95
|
+
this.#localModel = this.createModel();
|
|
96
|
+
} else if (this.#localModel.isFinal) {
|
|
97
|
+
this.#localModel = this.#localModel.extend();
|
|
98
|
+
}
|
|
99
|
+
return this.#localModel;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* The model's {@link Model.Type}.
|
|
104
|
+
*
|
|
105
|
+
* Field decorators operate prior to class decorators, so we may need to transition the model to a new type when the
|
|
106
|
+
* class is decorated. This is slightly lossy so type-specific decoration should always occur after assigning kind.
|
|
107
|
+
*/
|
|
108
|
+
get modelType(): Model.Type | undefined {
|
|
109
|
+
if (this.#localModel === undefined) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
return this.mutableModel.constructor as Model.ConcreteType;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
set modelType(type: Model.ConcreteType) {
|
|
116
|
+
if (this.#localModel === undefined) {
|
|
117
|
+
this.#localModel = this.createModel(type);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (this.#localModel instanceof type) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Detach original model
|
|
126
|
+
const original = this.#localModel as Model;
|
|
127
|
+
const { parent } = original;
|
|
128
|
+
original.parent = undefined;
|
|
129
|
+
|
|
130
|
+
// Create replacement
|
|
131
|
+
const replacement = new type({
|
|
132
|
+
name: original.name,
|
|
133
|
+
id: original.id,
|
|
134
|
+
type: original.type,
|
|
135
|
+
parent,
|
|
136
|
+
operationalBase: original.operationalBase,
|
|
137
|
+
children: original.children,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
if ("quality" in original && "quality" in replacement) {
|
|
141
|
+
replacement.quality = original.quality;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
this.#localModel = replacement;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
protected abstract createModel(type?: Model.ConcreteType): Model;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export namespace Semantics {
|
|
151
|
+
/**
|
|
152
|
+
* Access the {@link Semantics} of a {@link DecoratorContext}.
|
|
153
|
+
*/
|
|
154
|
+
export function of(context: DecoratorContext) {
|
|
155
|
+
const classSemantics = classOf(context);
|
|
156
|
+
if (context.kind === "class") {
|
|
157
|
+
return classSemantics;
|
|
158
|
+
}
|
|
159
|
+
return classSemantics.fieldFor(context.name);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Access the {@link ClassSemantics} of a constructor or decorator context.
|
|
164
|
+
*/
|
|
165
|
+
// eslint-disable-next-line prefer-const
|
|
166
|
+
export let classOf = (_source: ClassSemantics.Source): ClassSemantics => {
|
|
167
|
+
// This should be replaced by ClassSemantics
|
|
168
|
+
throw new InternalError(`Class decoration lookup not installed`);
|
|
169
|
+
};
|
|
170
|
+
}
|
package/src/index.ts
CHANGED