@likec4/language-server 1.15.1 → 1.17.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/contrib/likec4.tmLanguage.json +1 -1
- package/dist/browser.cjs +1 -1
- package/dist/browser.d.cts +2 -2
- package/dist/browser.d.mts +2 -2
- package/dist/browser.d.ts +2 -2
- package/dist/browser.mjs +2 -2
- package/dist/index.cjs +35 -5
- package/dist/index.d.cts +17 -4
- package/dist/index.d.mts +17 -4
- package/dist/index.d.ts +17 -4
- package/dist/index.mjs +34 -5
- package/dist/model-graph/index.cjs +1 -1
- package/dist/model-graph/index.d.cts +4 -2
- package/dist/model-graph/index.d.mts +4 -2
- package/dist/model-graph/index.d.ts +4 -2
- package/dist/model-graph/index.mjs +1 -1
- package/dist/shared/{language-server.BuChFlda.mjs → language-server.B8qSDsWW.mjs} +211 -96
- package/dist/shared/language-server.BGGRJRnr.d.mts +1338 -0
- package/dist/shared/{language-server.BT4WTbFI.mjs → language-server.BXFhlTPo.mjs} +139 -76
- package/dist/shared/{language-server.DfMwkd2l.d.mts → language-server.BgDKnNok.d.mts} +45 -11
- package/dist/shared/language-server.Bmpq16Gw.d.ts +1338 -0
- package/dist/shared/language-server.C1ZfM22X.d.cts +1338 -0
- package/dist/shared/{language-server.U2piOAVt.d.cts → language-server.DJo88TnT.d.cts} +45 -11
- package/dist/shared/{language-server.DfjkvknB.cjs → language-server.DZRuJVSg.cjs} +209 -94
- package/dist/shared/{language-server.B8s2wfT_.cjs → language-server.N8HLDQqz.cjs} +137 -74
- package/dist/shared/{language-server.j-ShR6as.d.ts → language-server.PEjk7U9s.d.ts} +45 -11
- package/package.json +7 -7
- package/src/LikeC4FileSystem.ts +36 -0
- package/src/Rpc.ts +2 -2
- package/src/ast.ts +11 -3
- package/src/generated/ast.ts +112 -11
- package/src/generated/grammar.ts +1 -1
- package/src/index.ts +3 -3
- package/src/like-c4.langium +20 -1
- package/src/lsp/SemanticTokenProvider.ts +26 -8
- package/src/model/fqn-computation.ts +6 -2
- package/src/model/model-builder.ts +25 -30
- package/src/model/model-parser.ts +91 -18
- package/src/model-graph/LikeC4ModelGraph.ts +22 -11
- package/src/model-graph/compute-view/__test__/fixture.ts +69 -19
- package/src/model-graph/compute-view/compute.ts +85 -73
- package/src/model-graph/dynamic-view/compute.ts +12 -2
- package/src/model-graph/utils/applyCustomElementProperties.ts +1 -3
- package/src/model-graph/utils/applyViewRuleStyles.ts +0 -4
- package/src/references/scope-computation.ts +10 -0
- package/src/validation/index.ts +3 -0
- package/src/validation/specification.ts +21 -0
- package/src/view-utils/index.ts +0 -1
- package/src/view-utils/resolve-global-rules.ts +66 -50
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
ElementKind,
|
|
9
9
|
type ElementPredicateExpression,
|
|
10
10
|
type ElementView,
|
|
11
|
+
type Fqn,
|
|
11
12
|
type NodeId,
|
|
12
13
|
type NonEmptyArray,
|
|
13
14
|
type Relation,
|
|
@@ -54,6 +55,7 @@ import {
|
|
|
54
55
|
sort,
|
|
55
56
|
unique
|
|
56
57
|
} from 'remeda'
|
|
58
|
+
import { resolveGlobalRulesInElementView } from '../../view-utils/resolve-global-rules'
|
|
57
59
|
import { calcViewLayoutHash } from '../../view-utils/view-hash'
|
|
58
60
|
import type { LikeC4ModelGraph } from '../LikeC4ModelGraph'
|
|
59
61
|
import { applyCustomElementProperties } from '../utils/applyCustomElementProperties'
|
|
@@ -181,6 +183,29 @@ export class ComputeCtx {
|
|
|
181
183
|
return this.activeGroupStack[0] ?? this.__rootGroup
|
|
182
184
|
}
|
|
183
185
|
|
|
186
|
+
protected get includedElements() {
|
|
187
|
+
return new Set([
|
|
188
|
+
...this.explicits,
|
|
189
|
+
...this.ctxEdges.flatMap(e => [e.source, e.target])
|
|
190
|
+
]) as ReadonlySet<Element>
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
protected get resolvedElements() {
|
|
194
|
+
return new Set([
|
|
195
|
+
...this.explicits,
|
|
196
|
+
...this.implicits,
|
|
197
|
+
...this.ctxEdges.flatMap(e => [e.source, e.target])
|
|
198
|
+
]) as ReadonlySet<Element>
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
protected get edges() {
|
|
202
|
+
return this.ctxEdges
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
protected get root() {
|
|
206
|
+
return isScopedElementView(this.view) ? this.view.viewOf : null
|
|
207
|
+
}
|
|
208
|
+
|
|
184
209
|
public static elementView(view: ElementView, graph: LikeC4ModelGraph) {
|
|
185
210
|
return new ComputeCtx(view, graph).compute()
|
|
186
211
|
}
|
|
@@ -194,10 +219,12 @@ export class ComputeCtx {
|
|
|
194
219
|
this.reset()
|
|
195
220
|
const {
|
|
196
221
|
docUri: _docUri, // exclude docUri
|
|
197
|
-
rules,
|
|
222
|
+
rules: _rules, // exclude rules
|
|
198
223
|
...view
|
|
199
224
|
} = this.view
|
|
200
225
|
|
|
226
|
+
const rules = resolveGlobalRulesInElementView(this.view, this.graph.globals)
|
|
227
|
+
|
|
201
228
|
const viewPredicates = rules.filter(anyPass([isViewRulePredicate, isViewRuleGroup])) as Array<
|
|
202
229
|
ViewRulePredicate | ViewRuleGroup
|
|
203
230
|
>
|
|
@@ -213,56 +240,10 @@ export class ComputeCtx {
|
|
|
213
240
|
const elements = [...this.includedElements]
|
|
214
241
|
const nodesMap = buildComputeNodes(elements, this.groups)
|
|
215
242
|
|
|
216
|
-
const ancestorsOf = (node: ComputedNode) => {
|
|
217
|
-
const ancestors = [] as ComputedNode[]
|
|
218
|
-
let parent = node.parent
|
|
219
|
-
while (parent) {
|
|
220
|
-
const parentNode = nodesMap.get(parent)
|
|
221
|
-
if (!parentNode) {
|
|
222
|
-
break
|
|
223
|
-
}
|
|
224
|
-
ancestors.push(parentNode)
|
|
225
|
-
parent = parentNode.parent
|
|
226
|
-
}
|
|
227
|
-
return ancestors
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
const edgesMap = new Map<EdgeId, ComputedEdge>()
|
|
231
243
|
const edges = this.computeEdges()
|
|
232
|
-
|
|
233
|
-
edgesMap.set(edge.id, edge)
|
|
234
|
-
const source = nodesMap.get(edge.source)
|
|
235
|
-
const target = nodesMap.get(edge.target)
|
|
236
|
-
invariant(source, `Source node ${edge.source} not found`)
|
|
237
|
-
invariant(target, `Target node ${edge.target} not found`)
|
|
238
|
-
// These ancestors are reversed: from bottom to top
|
|
239
|
-
const sourceAncestors = ancestorsOf(source)
|
|
240
|
-
const targetAncestors = ancestorsOf(target)
|
|
244
|
+
const edgesMap = new Map<EdgeId, ComputedEdge>(edges.map(edge => [edge.id, edge]))
|
|
241
245
|
|
|
242
|
-
|
|
243
|
-
commonHead(
|
|
244
|
-
reverse(sourceAncestors),
|
|
245
|
-
reverse(targetAncestors)
|
|
246
|
-
)
|
|
247
|
-
)
|
|
248
|
-
edge.parent = edgeParent?.id ?? null
|
|
249
|
-
source.outEdges.push(edge.id)
|
|
250
|
-
target.inEdges.push(edge.id)
|
|
251
|
-
// Process edge source ancestors
|
|
252
|
-
for (const sourceAncestor of sourceAncestors) {
|
|
253
|
-
if (sourceAncestor === edgeParent) {
|
|
254
|
-
break
|
|
255
|
-
}
|
|
256
|
-
sourceAncestor.outEdges.push(edge.id)
|
|
257
|
-
}
|
|
258
|
-
// Process target hierarchy
|
|
259
|
-
for (const targetAncestor of targetAncestors) {
|
|
260
|
-
if (targetAncestor === edgeParent) {
|
|
261
|
-
break
|
|
262
|
-
}
|
|
263
|
-
targetAncestor.inEdges.push(edge.id)
|
|
264
|
-
}
|
|
265
|
-
}
|
|
246
|
+
this.linkNodesAndEdges(nodesMap, edges)
|
|
266
247
|
|
|
267
248
|
// nodesMap sorted hierarchically,
|
|
268
249
|
// but we need to keep the initial sort
|
|
@@ -302,7 +283,14 @@ export class ComputeCtx {
|
|
|
302
283
|
...(autoLayoutRule?.nodeSep && { nodeSep: autoLayoutRule.nodeSep }),
|
|
303
284
|
...(autoLayoutRule?.rankSep && { rankSep: autoLayoutRule.rankSep })
|
|
304
285
|
},
|
|
305
|
-
nodes: map(nodes,
|
|
286
|
+
nodes: map(nodes, n => {
|
|
287
|
+
// omit notation
|
|
288
|
+
delete n.notation
|
|
289
|
+
if (n.icon === 'none') {
|
|
290
|
+
delete n.icon
|
|
291
|
+
}
|
|
292
|
+
return n
|
|
293
|
+
}),
|
|
306
294
|
edges: applyCustomRelationProperties(rules, nodes, sortedEdges),
|
|
307
295
|
...(elementNotations.length > 0 && {
|
|
308
296
|
notation: {
|
|
@@ -312,10 +300,6 @@ export class ComputeCtx {
|
|
|
312
300
|
})
|
|
313
301
|
}
|
|
314
302
|
|
|
315
|
-
protected get root() {
|
|
316
|
-
return isScopedElementView(this.view) ? this.view.viewOf : null
|
|
317
|
-
}
|
|
318
|
-
|
|
319
303
|
protected computeEdges(): ComputedEdge[] {
|
|
320
304
|
return this.ctxEdges.map((e): ComputedEdge => {
|
|
321
305
|
invariant(hasAtLeast(e.relations, 1), 'Edge must have at least one relation')
|
|
@@ -428,23 +412,40 @@ export class ComputeCtx {
|
|
|
428
412
|
})
|
|
429
413
|
}
|
|
430
414
|
|
|
431
|
-
protected
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
...this.explicits,
|
|
441
|
-
...this.implicits,
|
|
442
|
-
...this.ctxEdges.flatMap(e => [e.source, e.target])
|
|
443
|
-
]) as ReadonlySet<Element>
|
|
444
|
-
}
|
|
415
|
+
protected linkNodesAndEdges(nodesMap: ReadonlyMap<Fqn, ComputedNode>, edges: ComputedEdge[]) {
|
|
416
|
+
for (const edge of edges) {
|
|
417
|
+
const source = nodesMap.get(edge.source)
|
|
418
|
+
const target = nodesMap.get(edge.target)
|
|
419
|
+
invariant(source, `Source node ${edge.source} not found`)
|
|
420
|
+
invariant(target, `Target node ${edge.target} not found`)
|
|
421
|
+
// These ancestors are reversed: from bottom to top
|
|
422
|
+
const sourceAncestors = this.ancestorsOf(source, nodesMap)
|
|
423
|
+
const targetAncestors = this.ancestorsOf(target, nodesMap)
|
|
445
424
|
|
|
446
|
-
|
|
447
|
-
|
|
425
|
+
const edgeParent = last(
|
|
426
|
+
commonHead(
|
|
427
|
+
reverse(sourceAncestors),
|
|
428
|
+
reverse(targetAncestors)
|
|
429
|
+
)
|
|
430
|
+
)
|
|
431
|
+
edge.parent = edgeParent?.id ?? null
|
|
432
|
+
source.outEdges.push(edge.id)
|
|
433
|
+
target.inEdges.push(edge.id)
|
|
434
|
+
// Process edge source ancestors
|
|
435
|
+
for (const sourceAncestor of sourceAncestors) {
|
|
436
|
+
if (sourceAncestor === edgeParent) {
|
|
437
|
+
break
|
|
438
|
+
}
|
|
439
|
+
sourceAncestor.outEdges.push(edge.id)
|
|
440
|
+
}
|
|
441
|
+
// Process target hierarchy
|
|
442
|
+
for (const targetAncestor of targetAncestors) {
|
|
443
|
+
if (targetAncestor === edgeParent) {
|
|
444
|
+
break
|
|
445
|
+
}
|
|
446
|
+
targetAncestor.inEdges.push(edge.id)
|
|
447
|
+
}
|
|
448
|
+
}
|
|
448
449
|
}
|
|
449
450
|
|
|
450
451
|
protected addEdges(edges: ComputeCtx.Edge[]) {
|
|
@@ -539,9 +540,6 @@ export class ComputeCtx {
|
|
|
539
540
|
}),
|
|
540
541
|
filter(isNonNull)
|
|
541
542
|
)
|
|
542
|
-
if (excludedImplicits.size === 0) {
|
|
543
|
-
return
|
|
544
|
-
}
|
|
545
543
|
this.ctxEdges = ctxEdges
|
|
546
544
|
const remaining = this.includedElements
|
|
547
545
|
if (remaining.size === 0) {
|
|
@@ -755,6 +753,20 @@ export class ComputeCtx {
|
|
|
755
753
|
nonexhaustive(expr)
|
|
756
754
|
}
|
|
757
755
|
|
|
756
|
+
private ancestorsOf(node: ComputedNode, nodesMap: ReadonlyMap<Fqn, ComputedNode>): ComputedNode[] {
|
|
757
|
+
const ancestors = [] as ComputedNode[]
|
|
758
|
+
let parent = node.parent
|
|
759
|
+
while (parent) {
|
|
760
|
+
const parentNode = nodesMap.get(parent)
|
|
761
|
+
if (!parentNode) {
|
|
762
|
+
break
|
|
763
|
+
}
|
|
764
|
+
ancestors.push(parentNode)
|
|
765
|
+
parent = parentNode.parent
|
|
766
|
+
}
|
|
767
|
+
return ancestors
|
|
768
|
+
}
|
|
769
|
+
|
|
758
770
|
protected getEdgeLabel(
|
|
759
771
|
relation: {
|
|
760
772
|
title: string
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
StepEdgeId
|
|
27
27
|
} from '@likec4/core'
|
|
28
28
|
import { filter, flatMap, hasAtLeast, isTruthy, map, omit, only, pipe, unique } from 'remeda'
|
|
29
|
+
import { resolveGlobalRulesInDynamicView } from '../../view-utils/resolve-global-rules'
|
|
29
30
|
import { calcViewLayoutHash } from '../../view-utils/view-hash'
|
|
30
31
|
import type { LikeC4ModelGraph } from '../LikeC4ModelGraph'
|
|
31
32
|
import { applyCustomElementProperties } from '../utils/applyCustomElementProperties'
|
|
@@ -111,7 +112,7 @@ export class DynamicViewComputeCtx {
|
|
|
111
112
|
protected compute(): ComputedDynamicView {
|
|
112
113
|
const {
|
|
113
114
|
docUri: _docUri, // exclude docUri
|
|
114
|
-
rules,
|
|
115
|
+
rules: _rules, // exclude rules
|
|
115
116
|
steps: viewSteps,
|
|
116
117
|
...view
|
|
117
118
|
} = this.view
|
|
@@ -133,6 +134,8 @@ export class DynamicViewComputeCtx {
|
|
|
133
134
|
stepNum++
|
|
134
135
|
}
|
|
135
136
|
|
|
137
|
+
const rules = resolveGlobalRulesInDynamicView(this.view, this.graph.globals)
|
|
138
|
+
|
|
136
139
|
for (const rule of rules) {
|
|
137
140
|
if (isDynamicViewIncludeRule(rule)) {
|
|
138
141
|
for (const expr of rule.include) {
|
|
@@ -205,7 +208,14 @@ export class DynamicViewComputeCtx {
|
|
|
205
208
|
...(autoLayoutRule?.nodeSep && { nodeSep: autoLayoutRule.nodeSep }),
|
|
206
209
|
...(autoLayoutRule?.rankSep && { rankSep: autoLayoutRule.rankSep })
|
|
207
210
|
},
|
|
208
|
-
nodes: map(nodes,
|
|
211
|
+
nodes: map(nodes, n => {
|
|
212
|
+
// omit notation
|
|
213
|
+
delete n.notation
|
|
214
|
+
if (n.icon === 'none') {
|
|
215
|
+
delete n.icon
|
|
216
|
+
}
|
|
217
|
+
return n
|
|
218
|
+
}),
|
|
209
219
|
edges,
|
|
210
220
|
...(elementNotations.length > 0 && {
|
|
211
221
|
notation: {
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { ComputedNode, type Expression, type ViewRule } from '@likec4/core'
|
|
2
|
-
import { Expr, isViewRuleGroup, isViewRulePredicate } from '@likec4/core'
|
|
1
|
+
import { ComputedNode, Expr, type Expression, isViewRuleGroup, isViewRulePredicate, type ViewRule } from '@likec4/core'
|
|
3
2
|
import { isEmpty, isNullish, omitBy } from 'remeda'
|
|
4
|
-
import { NodesGroup } from '../compute-view/compute'
|
|
5
3
|
import { elementExprToPredicate } from './elementExpressionToPredicate'
|
|
6
4
|
|
|
7
5
|
export function flattenGroupRules<T extends Expression>(guard: (expr: Expression) => expr is T) {
|
|
@@ -13,10 +13,6 @@ export function applyViewRuleStyles(_rules: ViewRule[], nodes: ComputedNode[]) {
|
|
|
13
13
|
for (const rule of rules) {
|
|
14
14
|
const predicates = [] as Predicate<ComputedNode>[]
|
|
15
15
|
for (const target of rule.targets) {
|
|
16
|
-
if (Expr.isWildcard(target)) {
|
|
17
|
-
predicates.push(() => true)
|
|
18
|
-
break
|
|
19
|
-
}
|
|
20
16
|
predicates.push(elementExprToPredicate(target) as Predicate<ComputedNode>)
|
|
21
17
|
}
|
|
22
18
|
pipe(
|
|
@@ -69,6 +69,16 @@ export class LikeC4ScopeComputation extends DefaultScopeComputation {
|
|
|
69
69
|
if (isNullish(globals) || globals.length === 0) {
|
|
70
70
|
return
|
|
71
71
|
}
|
|
72
|
+
for (const globalPredicateAst of globals.flatMap(g => g.predicates)) {
|
|
73
|
+
try {
|
|
74
|
+
const id = globalPredicateAst
|
|
75
|
+
if (isTruthy(id.name)) {
|
|
76
|
+
docExports.push(this.descriptions.createDescription(id, id.name, document))
|
|
77
|
+
}
|
|
78
|
+
} catch (e) {
|
|
79
|
+
logError(e)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
72
82
|
for (const globalStyleAst of globals.flatMap(g => g.styles)) {
|
|
73
83
|
try {
|
|
74
84
|
const id = globalStyleAst.id
|
package/src/validation/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { iconPropertyRuleChecks, notesPropertyRuleChecks, opacityPropertyRuleChe
|
|
|
8
8
|
import { relationBodyChecks, relationChecks } from './relation'
|
|
9
9
|
import {
|
|
10
10
|
elementKindChecks,
|
|
11
|
+
globalPredicateChecks,
|
|
11
12
|
globalsChecks,
|
|
12
13
|
globalStyleIdChecks,
|
|
13
14
|
modelRuleChecks,
|
|
@@ -34,6 +35,8 @@ export function registerValidationChecks(services: LikeC4Services) {
|
|
|
34
35
|
SpecificationRule: specificationRuleChecks(services),
|
|
35
36
|
Model: modelRuleChecks(services),
|
|
36
37
|
Globals: globalsChecks(services),
|
|
38
|
+
GlobalPredicateGroup: globalPredicateChecks(services),
|
|
39
|
+
GlobalDynamicPredicateGroup: globalPredicateChecks(services),
|
|
37
40
|
GlobalStyleId: globalStyleIdChecks(services),
|
|
38
41
|
DynamicViewStep: dynamicViewStep(services),
|
|
39
42
|
LikeC4View: viewChecks(services),
|
|
@@ -130,6 +130,27 @@ export const relationshipChecks = (
|
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
export const globalPredicateChecks = (
|
|
134
|
+
services: LikeC4Services
|
|
135
|
+
): ValidationCheck<ast.GlobalPredicateGroup | ast.GlobalDynamicPredicateGroup> => {
|
|
136
|
+
const index = services.shared.workspace.IndexManager
|
|
137
|
+
return (node, accept) => {
|
|
138
|
+
const predicateGroups = index.allElements(ast.GlobalPredicateGroup)
|
|
139
|
+
const dynamicPredicateGroups = index.allElements(ast.GlobalDynamicPredicateGroup)
|
|
140
|
+
const sameName = predicateGroups
|
|
141
|
+
.concat(dynamicPredicateGroups)
|
|
142
|
+
.filter(s => s.name === node.name)
|
|
143
|
+
.limit(2)
|
|
144
|
+
.count()
|
|
145
|
+
if (sameName > 1) {
|
|
146
|
+
accept('error', `Duplicate GlobalPredicateGroup or GlobalDynamicPredicateGroup name '${node.name}'`, {
|
|
147
|
+
node: node,
|
|
148
|
+
property: 'name'
|
|
149
|
+
})
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
133
154
|
export const globalStyleIdChecks = (
|
|
134
155
|
services: LikeC4Services
|
|
135
156
|
): ValidationCheck<ast.GlobalStyleId> => {
|
package/src/view-utils/index.ts
CHANGED
|
@@ -1,72 +1,88 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type DynamicView,
|
|
3
|
+
type DynamicViewRule,
|
|
3
4
|
type ElementView,
|
|
4
|
-
type GlobalStyle,
|
|
5
|
-
type GlobalStyleID,
|
|
6
5
|
isDynamicView,
|
|
7
6
|
isElementView,
|
|
7
|
+
isViewRuleGlobalPredicateRef,
|
|
8
8
|
isViewRuleGlobalStyle,
|
|
9
|
-
type
|
|
10
|
-
nonexhaustive
|
|
9
|
+
type ModelGlobals,
|
|
10
|
+
nonexhaustive,
|
|
11
|
+
type ViewRule,
|
|
12
|
+
type ViewRuleGlobalPredicateRef,
|
|
13
|
+
type ViewRuleGlobalStyle
|
|
11
14
|
} from '@likec4/core'
|
|
12
15
|
import { logger } from '@likec4/log'
|
|
16
|
+
import { isNullish } from 'remeda'
|
|
13
17
|
|
|
14
|
-
export function resolveGlobalRules(
|
|
15
|
-
view:
|
|
16
|
-
|
|
17
|
-
):
|
|
18
|
+
export function resolveGlobalRules<V extends DynamicView | ElementView>(
|
|
19
|
+
view: V,
|
|
20
|
+
globals: ModelGlobals
|
|
21
|
+
): V {
|
|
18
22
|
if (isElementView(view)) {
|
|
19
|
-
return
|
|
23
|
+
return {
|
|
24
|
+
...view,
|
|
25
|
+
rules: resolveGlobalRulesInElementView(view, globals)
|
|
26
|
+
}
|
|
20
27
|
} else if (isDynamicView(view)) {
|
|
21
|
-
return
|
|
28
|
+
return {
|
|
29
|
+
...view,
|
|
30
|
+
rules: resolveGlobalRulesInDynamicView(view, globals)
|
|
31
|
+
}
|
|
22
32
|
}
|
|
23
33
|
nonexhaustive(view)
|
|
24
34
|
}
|
|
25
35
|
|
|
26
|
-
|
|
36
|
+
type ViewRuleGlobal = ViewRuleGlobalPredicateRef | ViewRuleGlobalStyle
|
|
37
|
+
|
|
38
|
+
export function resolveGlobalRulesInElementView(
|
|
27
39
|
view: ElementView,
|
|
28
|
-
|
|
29
|
-
):
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return []
|
|
37
|
-
}
|
|
38
|
-
return globalStyle.styles
|
|
39
|
-
} else {
|
|
40
|
-
return rule
|
|
40
|
+
globals: ModelGlobals
|
|
41
|
+
): Array<Exclude<ViewRule, ViewRuleGlobal>> {
|
|
42
|
+
return view.rules.reduce((acc, rule) => {
|
|
43
|
+
if (isViewRuleGlobalPredicateRef(rule)) {
|
|
44
|
+
const globalPredicates = globals.predicates[rule.predicateId]
|
|
45
|
+
if (isNullish(globalPredicates)) {
|
|
46
|
+
logger.warn(`Global predicate not found: ${rule.predicateId}`)
|
|
47
|
+
return acc
|
|
41
48
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
return acc.concat(globalPredicates)
|
|
50
|
+
}
|
|
51
|
+
if (isViewRuleGlobalStyle(rule)) {
|
|
52
|
+
const globalStyles = globals.styles[rule.styleId]
|
|
53
|
+
if (isNullish(globalStyles)) {
|
|
54
|
+
logger.warn(`Global style not found: ${rule.styleId}`)
|
|
55
|
+
return acc
|
|
56
|
+
}
|
|
57
|
+
return acc.concat(globalStyles)
|
|
58
|
+
}
|
|
59
|
+
acc.push(rule)
|
|
60
|
+
return acc
|
|
61
|
+
}, [] as Array<Exclude<ViewRule, ViewRuleGlobal>>)
|
|
48
62
|
}
|
|
49
63
|
|
|
50
|
-
function
|
|
64
|
+
export function resolveGlobalRulesInDynamicView(
|
|
51
65
|
view: DynamicView,
|
|
52
|
-
|
|
53
|
-
):
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return []
|
|
61
|
-
}
|
|
62
|
-
return globalStyle.styles
|
|
63
|
-
} else {
|
|
64
|
-
return rule
|
|
66
|
+
globals: ModelGlobals
|
|
67
|
+
): Array<Exclude<DynamicViewRule, ViewRuleGlobal>> {
|
|
68
|
+
return view.rules.reduce((acc, rule) => {
|
|
69
|
+
if (isViewRuleGlobalPredicateRef(rule)) {
|
|
70
|
+
const globalPredicates = globals.dynamicPredicates[rule.predicateId]
|
|
71
|
+
if (isNullish(globalPredicates)) {
|
|
72
|
+
logger.warn(`Global predicate not found: ${rule.predicateId}`)
|
|
73
|
+
return acc
|
|
65
74
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
75
|
+
return acc.concat(globalPredicates)
|
|
76
|
+
}
|
|
77
|
+
if (isViewRuleGlobalStyle(rule)) {
|
|
78
|
+
const globalStyles = globals.styles[rule.styleId]
|
|
79
|
+
if (isNullish(globalStyles)) {
|
|
80
|
+
logger.warn(`Global style not found: ${rule.styleId}`)
|
|
81
|
+
return acc
|
|
82
|
+
}
|
|
83
|
+
return acc.concat(globalStyles)
|
|
84
|
+
}
|
|
85
|
+
acc.push(rule)
|
|
86
|
+
return acc
|
|
87
|
+
}, [] as Array<Exclude<DynamicViewRule, ViewRuleGlobal>>)
|
|
72
88
|
}
|