@shapeshift-labs/frontier-lang-css 0.1.6 → 0.1.8
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/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export interface CssProjectionOptions {
|
|
|
13
13
|
readonly cssModuleCompositionGraphHash?: string;
|
|
14
14
|
readonly icssGraphHash?: string;
|
|
15
15
|
readonly scopedCascadeGraphHash?: string;
|
|
16
|
+
readonly selectorTargetGraphHash?: string;
|
|
16
17
|
readonly targetPath?: string;
|
|
17
18
|
readonly semanticIndexId?: string;
|
|
18
19
|
readonly sourceSpansBySemanticNodeId?: Readonly<Record<string, CssSourceSpan>>;
|
|
@@ -143,6 +144,7 @@ export interface CssSemanticRecord {
|
|
|
143
144
|
readonly scopeKey?: string;
|
|
144
145
|
readonly statementText?: string;
|
|
145
146
|
readonly scopedCascadeGraphHash?: string;
|
|
147
|
+
readonly selectorTargetGraphHash?: string;
|
|
146
148
|
readonly sourceSpan: CssSourceSpan;
|
|
147
149
|
readonly sourceHash: string;
|
|
148
150
|
readonly parser?: 'postcss' | string;
|
|
@@ -222,21 +224,14 @@ export interface CssSemanticSheet {
|
|
|
222
224
|
}
|
|
223
225
|
|
|
224
226
|
export interface CssSemanticMergeEvidence {
|
|
225
|
-
readonly kind: 'frontier.lang.cssSemanticMergeEvidence';
|
|
226
|
-
readonly
|
|
227
|
-
readonly status: 'ready' | 'needs-review' | string;
|
|
228
|
-
readonly sourcePath?: string;
|
|
229
|
-
readonly sourceHash: string;
|
|
230
|
-
readonly sheetHash: string;
|
|
227
|
+
readonly kind: 'frontier.lang.cssSemanticMergeEvidence'; readonly version: 1;
|
|
228
|
+
readonly status: 'ready' | 'needs-review' | string; readonly sourcePath?: string; readonly sourceHash: string; readonly sheetHash: string;
|
|
231
229
|
readonly records: readonly CssSemanticRecord[];
|
|
232
230
|
readonly cssModules?: CssModuleEvidence;
|
|
233
231
|
readonly proofGaps: readonly CssSemanticProofGap[];
|
|
234
|
-
readonly autoMergeClaim: false;
|
|
235
|
-
readonly
|
|
236
|
-
readonly
|
|
237
|
-
readonly cssModuleUseSiteEquivalenceClaim: false;
|
|
238
|
-
readonly browserCascadeEquivalenceClaim: false;
|
|
239
|
-
readonly browserRenderEquivalenceClaim: false;
|
|
232
|
+
readonly autoMergeClaim: false; readonly semanticEquivalenceClaim: false;
|
|
233
|
+
readonly cssModuleGeneratedNameEquivalenceClaim: false; readonly cssModuleUseSiteEquivalenceClaim: false;
|
|
234
|
+
readonly browserCascadeEquivalenceClaim: false; readonly browserRenderEquivalenceClaim: false;
|
|
240
235
|
}
|
|
241
236
|
|
|
242
237
|
export interface CssSafeMergeConflict {
|
|
@@ -247,66 +242,68 @@ export interface CssSafeMergeConflict {
|
|
|
247
242
|
}
|
|
248
243
|
|
|
249
244
|
export interface CssSafeMergeAdmission {
|
|
250
|
-
readonly status: 'auto-merge-candidate' | 'blocked' | string;
|
|
251
|
-
readonly
|
|
252
|
-
readonly reviewRequired: boolean;
|
|
253
|
-
readonly reasonCodes: readonly string[];
|
|
245
|
+
readonly status: 'auto-merge-candidate' | 'blocked' | string; readonly action: 'apply-css' | 'human-review' | string;
|
|
246
|
+
readonly reviewRequired: boolean; readonly reasonCodes: readonly string[];
|
|
254
247
|
}
|
|
255
248
|
|
|
256
249
|
export interface CssSafeMergeResult {
|
|
257
|
-
readonly kind: 'frontier.lang.cssSafeMerge';
|
|
258
|
-
readonly
|
|
259
|
-
readonly
|
|
260
|
-
readonly sourcePath?: string;
|
|
261
|
-
readonly status: 'merged' | 'blocked' | string;
|
|
262
|
-
readonly operation: string;
|
|
263
|
-
readonly mergedSourceText?: string;
|
|
264
|
-
readonly mergedSourceHash?: string;
|
|
250
|
+
readonly kind: 'frontier.lang.cssSafeMerge'; readonly version: 1; readonly id: string; readonly sourcePath?: string;
|
|
251
|
+
readonly status: 'merged' | 'blocked' | string; readonly operation: string;
|
|
252
|
+
readonly mergedSourceText?: string; readonly mergedSourceHash?: string;
|
|
265
253
|
readonly conflicts: readonly CssSafeMergeConflict[];
|
|
266
254
|
readonly admission: CssSafeMergeAdmission;
|
|
267
|
-
readonly autoMergeClaim: false;
|
|
268
|
-
readonly
|
|
269
|
-
readonly
|
|
270
|
-
readonly
|
|
271
|
-
readonly
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
readonly
|
|
255
|
+
readonly autoMergeClaim: false; readonly semanticEquivalenceClaim: false;
|
|
256
|
+
readonly baseSheetHash?: string; readonly workerSheetHash?: string; readonly headSheetHash?: string;
|
|
257
|
+
readonly workerChangedDeclarations?: number; readonly headChangedDeclarations?: number;
|
|
258
|
+
readonly workerChangedCssModuleContracts?: number; readonly headChangedCssModuleContracts?: number;
|
|
259
|
+
readonly parserEvidence?: CssSafeMergeParserEvidence; readonly selectorTargetEvidence?: CssSafeMergeSelectorTargetEvidence;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export interface CssSafeMergeParserEvidence {
|
|
263
|
+
readonly kind: 'frontier.lang.cssSafeMergeParserEvidence'; readonly version: 1; readonly parserNames: readonly string[];
|
|
264
|
+
readonly sourceCodeLocationInfo: boolean; readonly parserBackedSourceSpans: boolean; readonly parserBackedDeclarationSpans: boolean; readonly parserBackedTriviaHashes: boolean;
|
|
265
|
+
readonly scopedCascadeGraphHashPresent: boolean; readonly parseErrors: number;
|
|
266
|
+
readonly sides: Readonly<Record<string, CssSafeMergeParserSideEvidence>>;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export interface CssSafeMergeParserSideEvidence {
|
|
270
|
+
readonly parserName: string;
|
|
271
|
+
readonly sourceCodeLocationInfo: boolean; readonly parserBackedSourceSpans: boolean; readonly parserBackedDeclarationSpans: boolean; readonly parserBackedTriviaHashes: boolean;
|
|
272
|
+
readonly scopedCascadeGraphHashPresent: boolean; readonly parseErrors: number; readonly recordCount: number; readonly declarationCount: number;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export interface CssSafeMergeSelectorTargetEvidence {
|
|
276
|
+
readonly kind: 'frontier.lang.cssSafeMergeSelectorTargetEvidence'; readonly version: 1;
|
|
277
|
+
readonly selectorTargetGraphHashPresent: boolean; readonly parserBackedRuleSpans: boolean;
|
|
278
|
+
readonly selectorMoveCount: number; readonly workerSelectorMoves: number; readonly headSelectorMoves: number;
|
|
279
|
+
readonly sides: Readonly<Record<string, CssSafeMergeSelectorTargetSideEvidence>>;
|
|
280
|
+
readonly moves: Readonly<Record<'worker' | 'head', readonly CssSafeMergeSelectorMove[]>>;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export interface CssSafeMergeSelectorTargetSideEvidence {
|
|
284
|
+
readonly ruleCount: number; readonly selectorCount: number; readonly declarationCount: number; readonly scopedRuleCount: number;
|
|
285
|
+
readonly selectorTargetGraphHashPresent: boolean; readonly parserBackedRuleSpans: boolean; readonly selectorSpecificityRecords: number;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export interface CssSafeMergeSelectorMove {
|
|
289
|
+
readonly side: string; readonly property: string; readonly beforeRuleKey: string; readonly afterRuleKey: string;
|
|
290
|
+
readonly beforeSelectors?: readonly string[]; readonly afterSelectors?: readonly string[]; readonly beforeScopes?: readonly string[]; readonly afterScopes?: readonly string[];
|
|
291
|
+
readonly declarationHash: string; readonly selectorTargetGraphHashPresent: boolean;
|
|
276
292
|
}
|
|
277
293
|
|
|
278
294
|
export interface CssSafeMergeInput {
|
|
279
|
-
readonly id?: string;
|
|
280
|
-
readonly
|
|
281
|
-
readonly baseSourceText?: string;
|
|
282
|
-
readonly workerSourceText?: string;
|
|
283
|
-
readonly headSourceText?: string;
|
|
284
|
-
readonly cssModule?: boolean;
|
|
285
|
-
readonly cssModules?: boolean;
|
|
295
|
+
readonly id?: string; readonly sourcePath?: string; readonly baseSourceText?: string; readonly workerSourceText?: string; readonly headSourceText?: string;
|
|
296
|
+
readonly cssModule?: boolean; readonly cssModules?: boolean;
|
|
286
297
|
readonly generatedClassNameMap?: Readonly<Record<string, string>>;
|
|
287
|
-
readonly generatedClassNameMapHash?: string;
|
|
288
|
-
readonly
|
|
289
|
-
readonly
|
|
290
|
-
readonly
|
|
291
|
-
readonly
|
|
292
|
-
readonly
|
|
293
|
-
readonly
|
|
294
|
-
readonly
|
|
295
|
-
readonly
|
|
296
|
-
readonly workerGeneratedClassNameMapHash?: string;
|
|
297
|
-
readonly headGeneratedClassNameMapHash?: string;
|
|
298
|
-
readonly baseJsTsUseSiteGraphHash?: string;
|
|
299
|
-
readonly workerJsTsUseSiteGraphHash?: string;
|
|
300
|
-
readonly headJsTsUseSiteGraphHash?: string;
|
|
301
|
-
readonly baseCssModuleCompositionGraphHash?: string;
|
|
302
|
-
readonly workerCssModuleCompositionGraphHash?: string;
|
|
303
|
-
readonly headCssModuleCompositionGraphHash?: string;
|
|
304
|
-
readonly baseIcssGraphHash?: string;
|
|
305
|
-
readonly workerIcssGraphHash?: string;
|
|
306
|
-
readonly headIcssGraphHash?: string;
|
|
307
|
-
readonly baseScopedCascadeGraphHash?: string;
|
|
308
|
-
readonly workerScopedCascadeGraphHash?: string;
|
|
309
|
-
readonly headScopedCascadeGraphHash?: string;
|
|
298
|
+
readonly generatedClassNameMapHash?: string; readonly jsTsUseSiteGraphHash?: string; readonly cssModuleCompositionGraphHash?: string; readonly icssGraphHash?: string; readonly scopedCascadeGraphHash?: string;
|
|
299
|
+
readonly selectorTargetGraphHash?: string;
|
|
300
|
+
readonly baseGeneratedClassNameMap?: Readonly<Record<string, string>>; readonly workerGeneratedClassNameMap?: Readonly<Record<string, string>>; readonly headGeneratedClassNameMap?: Readonly<Record<string, string>>;
|
|
301
|
+
readonly baseGeneratedClassNameMapHash?: string; readonly workerGeneratedClassNameMapHash?: string; readonly headGeneratedClassNameMapHash?: string;
|
|
302
|
+
readonly baseJsTsUseSiteGraphHash?: string; readonly workerJsTsUseSiteGraphHash?: string; readonly headJsTsUseSiteGraphHash?: string;
|
|
303
|
+
readonly baseCssModuleCompositionGraphHash?: string; readonly workerCssModuleCompositionGraphHash?: string; readonly headCssModuleCompositionGraphHash?: string;
|
|
304
|
+
readonly baseIcssGraphHash?: string; readonly workerIcssGraphHash?: string; readonly headIcssGraphHash?: string;
|
|
305
|
+
readonly baseScopedCascadeGraphHash?: string; readonly workerScopedCascadeGraphHash?: string; readonly headScopedCascadeGraphHash?: string;
|
|
306
|
+
readonly baseSelectorTargetGraphHash?: string; readonly workerSelectorTargetGraphHash?: string; readonly headSelectorTargetGraphHash?: string;
|
|
310
307
|
}
|
|
311
308
|
|
|
312
309
|
export declare function toCssAst(document: FrontierLangDocument, options?: CssProjectionOptions): CssAstStylesheet;
|
|
@@ -61,6 +61,7 @@ function postcssRuleRecord(node, scopes, sourceHash, options) {
|
|
|
61
61
|
})),
|
|
62
62
|
customProperties: declarations.filter((declaration) => declaration.property.startsWith('--')).map((declaration) => declaration.property),
|
|
63
63
|
scopedCascadeGraphHash: scopes.length ? options.scopedCascadeGraphHash : undefined,
|
|
64
|
+
selectorTargetGraphHash: options.selectorTargetGraphHash,
|
|
64
65
|
sourceSpan: sourceSpanFromPostcss(node.source, options.sourcePath),
|
|
65
66
|
sourceHash,
|
|
66
67
|
rawTextHash: hashSemanticValue({ kind: 'frontier.lang.css.rawRuleText.v1', text: node.toString() }),
|
|
@@ -9,7 +9,8 @@ function sheetOptions(input, side, sourcePath) {
|
|
|
9
9
|
jsTsUseSiteGraphHash: input[`${prefix}JsTsUseSiteGraphHash`] ?? input.jsTsUseSiteGraphHash,
|
|
10
10
|
cssModuleCompositionGraphHash: input[`${prefix}CssModuleCompositionGraphHash`] ?? input.cssModuleCompositionGraphHash,
|
|
11
11
|
icssGraphHash: input[`${prefix}IcssGraphHash`] ?? input.icssGraphHash,
|
|
12
|
-
scopedCascadeGraphHash: input[`${prefix}ScopedCascadeGraphHash`] ?? input.scopedCascadeGraphHash
|
|
12
|
+
scopedCascadeGraphHash: input[`${prefix}ScopedCascadeGraphHash`] ?? input.scopedCascadeGraphHash,
|
|
13
|
+
selectorTargetGraphHash: input[`${prefix}SelectorTargetGraphHash`] ?? input.selectorTargetGraphHash
|
|
13
14
|
};
|
|
14
15
|
}
|
|
15
16
|
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
function mergeSelectorTargetEvidence(sheets, changed) {
|
|
2
|
+
const entries = Object.entries(sheets).map(([side, sheet]) => [side, sheetSelectorTargetEvidence(sheet)]);
|
|
3
|
+
const moves = { worker: selectorTargetMoves(changed.worker, 'worker'), head: selectorTargetMoves(changed.head, 'head') };
|
|
4
|
+
return {
|
|
5
|
+
kind: 'frontier.lang.cssSafeMergeSelectorTargetEvidence',
|
|
6
|
+
version: 1,
|
|
7
|
+
selectorTargetGraphHashPresent: entries.every(([, evidence]) => evidence.selectorTargetGraphHashPresent === true),
|
|
8
|
+
parserBackedRuleSpans: entries.every(([, evidence]) => evidence.parserBackedRuleSpans === true),
|
|
9
|
+
selectorMoveCount: moves.worker.length + moves.head.length,
|
|
10
|
+
workerSelectorMoves: moves.worker.length,
|
|
11
|
+
headSelectorMoves: moves.head.length,
|
|
12
|
+
sides: Object.fromEntries(entries),
|
|
13
|
+
moves
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function sheetSelectorTargetEvidence(sheet) {
|
|
18
|
+
const rules = (sheet.records ?? []).filter((record) => record.kind === 'rule');
|
|
19
|
+
return {
|
|
20
|
+
ruleCount: rules.length,
|
|
21
|
+
selectorCount: rules.reduce((sum, record) => sum + (record.selectors?.length ?? 0), 0),
|
|
22
|
+
declarationCount: rules.reduce((sum, record) => sum + (record.declarations?.length ?? 0), 0),
|
|
23
|
+
scopedRuleCount: rules.filter((record) => (record.scopes ?? []).length > 0).length,
|
|
24
|
+
selectorTargetGraphHashPresent: rules.length === 0 || rules.every((record) => Boolean(record.selectorTargetGraphHash)),
|
|
25
|
+
parserBackedRuleSpans: rules.every((record) => record.parser === 'postcss' && record.sourceSpan?.startOffset !== undefined),
|
|
26
|
+
selectorSpecificityRecords: rules.filter((record) => Array.isArray(record.specificity)).length
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function selectorTargetMoves(changes, side) {
|
|
31
|
+
const deletions = changes.filter((change) => change.kind === 'delete' && change.before);
|
|
32
|
+
const additions = changes.filter((change) => change.kind === 'add' && change.after);
|
|
33
|
+
const moves = [];
|
|
34
|
+
const usedAdditions = new Set();
|
|
35
|
+
for (const deletion of deletions) {
|
|
36
|
+
const addition = additions.find((candidate) => !usedAdditions.has(candidate) && sameDeclarationTargetSignature(deletion.before, candidate.after) && deletion.before.ruleKey !== candidate.after.ruleKey);
|
|
37
|
+
if (!addition) continue;
|
|
38
|
+
usedAdditions.add(addition);
|
|
39
|
+
moves.push({
|
|
40
|
+
side,
|
|
41
|
+
property: deletion.before.property,
|
|
42
|
+
beforeRuleKey: deletion.before.ruleKey,
|
|
43
|
+
afterRuleKey: addition.after.ruleKey,
|
|
44
|
+
beforeSelectors: deletion.before.selectors,
|
|
45
|
+
afterSelectors: addition.after.selectors,
|
|
46
|
+
beforeScopes: deletion.before.scopes,
|
|
47
|
+
afterScopes: addition.after.scopes,
|
|
48
|
+
declarationHash: addition.after.declarationHash,
|
|
49
|
+
selectorTargetGraphHashPresent: Boolean(deletion.before.selectorTargetGraphHash && addition.after.selectorTargetGraphHash)
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return moves;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function selectorTargetMoveConflicts(id, sourcePath, selectorTargetEvidence, changed) {
|
|
56
|
+
return [
|
|
57
|
+
...selectorTargetMoveSideConflicts(id, sourcePath, selectorTargetEvidence.moves.worker, selectorTargetEvidence.moves.head, changed.head),
|
|
58
|
+
...selectorTargetMoveSideConflicts(id, sourcePath, selectorTargetEvidence.moves.head, selectorTargetEvidence.moves.worker, changed.worker)
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function selectorTargetMoveSideConflicts(id, sourcePath, moves, oppositeMoves, oppositeChanges) {
|
|
63
|
+
return moves.flatMap((move) => {
|
|
64
|
+
if (oppositeMoves.some((oppositeMove) => sameSelectorMove(move, oppositeMove))) return [];
|
|
65
|
+
return oppositeChanges.filter((change) => selectorMoveTouchesChange(move, change)).map((change) => conflict(id, sourcePath, change.key, move, change));
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function conflict(id, sourcePath, cascadeKey, selectorMove, change) {
|
|
70
|
+
return {
|
|
71
|
+
code: 'css-selector-target-conflict',
|
|
72
|
+
gateId: 'css-semantic-merge',
|
|
73
|
+
sourcePath,
|
|
74
|
+
details: {
|
|
75
|
+
reasonCode: 'css-selector-target-rebase-unproved',
|
|
76
|
+
conflictKey: `css#${id}#css-selector-target-rebase-unproved#${cascadeKey ?? sourcePath ?? 'source'}`,
|
|
77
|
+
cascadeKey,
|
|
78
|
+
selectorMove,
|
|
79
|
+
opposite: changeDetails(change)
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function selectorMoveTouchesChange(move, change) {
|
|
85
|
+
const entry = change.after ?? change.before;
|
|
86
|
+
return entry?.ruleKey === move.beforeRuleKey || entry?.ruleKey === move.afterRuleKey;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function sameDeclarationTargetSignature(left, right) {
|
|
90
|
+
return Boolean(left && right && left.property === right.property && left.value === right.value && left.important === right.important);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function sameSelectorMove(left, right) {
|
|
94
|
+
return left.property === right.property && left.beforeRuleKey === right.beforeRuleKey && left.afterRuleKey === right.afterRuleKey && left.declarationHash === right.declarationHash;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function changeDetails(change) { return { kind: change.kind, property: (change.after ?? change.before)?.property, value: change.after?.value, important: change.after?.important }; }
|
|
98
|
+
|
|
99
|
+
export { mergeSelectorTargetEvidence, selectorTargetMoveConflicts };
|
package/dist/semantic-merge.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { cssModuleContractChanges, cssModuleContractConflicts, sheetOptions, unsupportedSourceShapeConflicts } from './semantic-merge-css-modules.js';
|
|
2
|
+
import { mergeSelectorTargetEvidence, selectorTargetMoveConflicts } from './semantic-merge-selector-targets.js';
|
|
2
3
|
|
|
3
4
|
function safeMergeCssSource(input = {}, context = {}) {
|
|
4
5
|
const parseSheet = context.parseCssSemanticSheet;
|
|
@@ -29,8 +30,11 @@ function safeMergeCssSource(input = {}, context = {}) {
|
|
|
29
30
|
];
|
|
30
31
|
const moduleConflicts = cssModuleContractConflicts(id, sourcePath, moduleChanges);
|
|
31
32
|
const sourceShapeConflicts = unsupportedSourceShapeConflicts(id, sourcePath, sheets, changed, hash);
|
|
32
|
-
const
|
|
33
|
-
|
|
33
|
+
const parserEvidence = mergeParserEvidence(sheets);
|
|
34
|
+
const selectorTargetEvidence = mergeSelectorTargetEvidence(sheets, changed);
|
|
35
|
+
const selectorTargetConflicts = selectorTargetMoveConflicts(id, sourcePath, selectorTargetEvidence, changed);
|
|
36
|
+
const conflicts = [...parserConflicts, ...proofConflicts, ...overlapConflicts, ...moduleConflicts, ...sourceShapeConflicts, ...selectorTargetConflicts];
|
|
37
|
+
if (conflicts.length) return blocked(id, sourcePath, 'css-semantic-merge-conflict', conflicts, { parserEvidence, selectorTargetEvidence });
|
|
34
38
|
const mergedIndex = applyDeclarationChanges(applyDeclarationChanges(indexes.base, changed.head), changed.worker);
|
|
35
39
|
return merged(id, sourcePath, renderDeclarationIndex(mergedIndex), 'semantic-declaration-merge', hash, {
|
|
36
40
|
baseSheetHash: sheets.base.sheetHash,
|
|
@@ -39,7 +43,9 @@ function safeMergeCssSource(input = {}, context = {}) {
|
|
|
39
43
|
workerChangedDeclarations: changed.worker.length,
|
|
40
44
|
headChangedDeclarations: changed.head.length,
|
|
41
45
|
workerChangedCssModuleContracts: moduleChanges.worker.length,
|
|
42
|
-
headChangedCssModuleContracts: moduleChanges.head.length
|
|
46
|
+
headChangedCssModuleContracts: moduleChanges.head.length,
|
|
47
|
+
parserEvidence,
|
|
48
|
+
selectorTargetEvidence
|
|
43
49
|
});
|
|
44
50
|
}
|
|
45
51
|
|
|
@@ -69,6 +75,7 @@ function declarationIndex(sheet) {
|
|
|
69
75
|
value: declaration.value,
|
|
70
76
|
important: declaration.important,
|
|
71
77
|
declarationHash: declaration.declarationHash,
|
|
78
|
+
selectorTargetGraphHash: record.selectorTargetGraphHash,
|
|
72
79
|
proofGaps: proofGapsForDeclaration(record, declaration)
|
|
73
80
|
};
|
|
74
81
|
declarations.set(entry.key, entry);
|
|
@@ -107,6 +114,38 @@ function parserErrorConflicts(id, sourcePath, sheets) {
|
|
|
107
114
|
.map((gap) => conflict(id, sourcePath, 'css-parser-error-blocked', gap.code, { side, proofGap: gap })));
|
|
108
115
|
}
|
|
109
116
|
|
|
117
|
+
function mergeParserEvidence(sheets) {
|
|
118
|
+
const entries = Object.entries(sheets).map(([side, sheet]) => [side, sheetParserEvidence(sheet)]);
|
|
119
|
+
return {
|
|
120
|
+
kind: 'frontier.lang.cssSafeMergeParserEvidence',
|
|
121
|
+
version: 1,
|
|
122
|
+
parserNames: unique(entries.map(([, evidence]) => evidence.parserName)),
|
|
123
|
+
sourceCodeLocationInfo: entries.every(([, evidence]) => evidence.sourceCodeLocationInfo === true),
|
|
124
|
+
parserBackedSourceSpans: entries.every(([, evidence]) => evidence.parserBackedSourceSpans === true),
|
|
125
|
+
parserBackedDeclarationSpans: entries.every(([, evidence]) => evidence.parserBackedDeclarationSpans === true),
|
|
126
|
+
parserBackedTriviaHashes: entries.every(([, evidence]) => evidence.parserBackedTriviaHashes === true),
|
|
127
|
+
scopedCascadeGraphHashPresent: entries.every(([, evidence]) => evidence.scopedCascadeGraphHashPresent === true),
|
|
128
|
+
parseErrors: entries.reduce((sum, [, evidence]) => sum + evidence.parseErrors, 0),
|
|
129
|
+
sides: Object.fromEntries(entries)
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function sheetParserEvidence(sheet) {
|
|
134
|
+
const records = sheet.records ?? [];
|
|
135
|
+
const declarations = records.flatMap((record) => record.declarations ?? []);
|
|
136
|
+
return {
|
|
137
|
+
parserName: sheet.parser?.name ?? 'unknown',
|
|
138
|
+
sourceCodeLocationInfo: sheet.parser?.sourceCodeLocationInfo === true,
|
|
139
|
+
parserBackedSourceSpans: records.some((record) => record.parser === 'postcss' && record.sourceSpan?.startOffset !== undefined),
|
|
140
|
+
parserBackedDeclarationSpans: declarations.some((declaration) => declaration.sourceSpan?.startOffset !== undefined),
|
|
141
|
+
parserBackedTriviaHashes: records.some((record) => record.parser === 'postcss' && typeof record.rawTextHash === 'string'),
|
|
142
|
+
scopedCascadeGraphHashPresent: records.every((record) => !(record.scopes?.length) || Boolean(record.scopedCascadeGraphHash)),
|
|
143
|
+
parseErrors: sheet.parser?.parseErrors?.length ?? 0,
|
|
144
|
+
recordCount: records.length,
|
|
145
|
+
declarationCount: declarations.length
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
110
149
|
function overlapDeclarationConflicts(id, sourcePath, workerChanges, headChanges) {
|
|
111
150
|
const headByKey = new Map(headChanges.map((change) => [change.key, change]));
|
|
112
151
|
return workerChanges.flatMap((workerChange) => {
|
|
@@ -217,10 +256,11 @@ function merged(id, sourcePath, sourceText, operation, hash, extra = {}) {
|
|
|
217
256
|
});
|
|
218
257
|
}
|
|
219
258
|
|
|
220
|
-
function blocked(id, sourcePath, reasonCode, conflicts = []) {
|
|
259
|
+
function blocked(id, sourcePath, reasonCode, conflicts = [], extra = {}) {
|
|
221
260
|
return result(id, sourcePath, 'blocked', {
|
|
222
261
|
operation: 'blocked',
|
|
223
|
-
conflicts: conflicts.length ? conflicts : [conflict(id, sourcePath, reasonCode, reasonCode)]
|
|
262
|
+
conflicts: conflicts.length ? conflicts : [conflict(id, sourcePath, reasonCode, reasonCode)],
|
|
263
|
+
...extra
|
|
224
264
|
});
|
|
225
265
|
}
|
|
226
266
|
|
package/package.json
CHANGED