mirror of
https://github.com/denoland/std.git
synced 2024-11-21 12:40:03 +00:00
parent
745c4a61ae
commit
0a71a4d3db
@ -388,7 +388,7 @@ export class LoaderState {
|
||||
}
|
||||
|
||||
line = this.line;
|
||||
composeNode(this, nodeIndent, CONTEXT_BLOCK_IN, false, true);
|
||||
this.composeNode(nodeIndent, CONTEXT_BLOCK_IN, false, true);
|
||||
result.push(this.result);
|
||||
this.skipSeparationSpace(true, -1);
|
||||
|
||||
@ -884,7 +884,7 @@ export class LoaderState {
|
||||
}
|
||||
|
||||
line = this.line;
|
||||
composeNode(this, nodeIndent, CONTEXT_FLOW_IN, false, true);
|
||||
this.composeNode(nodeIndent, CONTEXT_FLOW_IN, false, true);
|
||||
keyTag = this.tag || null;
|
||||
keyNode = this.result;
|
||||
this.skipSeparationSpace(true, nodeIndent);
|
||||
@ -895,7 +895,7 @@ export class LoaderState {
|
||||
isPair = true;
|
||||
ch = this.next();
|
||||
this.skipSeparationSpace(true, nodeIndent);
|
||||
composeNode(this, nodeIndent, CONTEXT_FLOW_IN, false, true);
|
||||
this.composeNode(nodeIndent, CONTEXT_FLOW_IN, false, true);
|
||||
valueNode = this.result;
|
||||
}
|
||||
|
||||
@ -1156,7 +1156,7 @@ export class LoaderState {
|
||||
//
|
||||
// Implicit notation case. Flow-style node as the key first, then ":", and the value.
|
||||
//
|
||||
} else if (composeNode(this, flowIndent, CONTEXT_FLOW_OUT, false, true)) {
|
||||
} else if (this.composeNode(flowIndent, CONTEXT_FLOW_OUT, false, true)) {
|
||||
if (this.line === line) {
|
||||
ch = this.peek();
|
||||
|
||||
@ -1216,7 +1216,7 @@ export class LoaderState {
|
||||
//
|
||||
if (this.line === line || this.lineIndent > nodeIndent) {
|
||||
if (
|
||||
composeNode(this, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)
|
||||
this.composeNode(nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)
|
||||
) {
|
||||
if (atExplicitKey) {
|
||||
keyNode = this.result;
|
||||
@ -1431,6 +1431,171 @@ export class LoaderState {
|
||||
return true;
|
||||
}
|
||||
|
||||
composeNode(
|
||||
parentIndent: number,
|
||||
nodeContext: number,
|
||||
allowToSeek: boolean,
|
||||
allowCompact: boolean,
|
||||
): boolean {
|
||||
let allowBlockScalars: boolean;
|
||||
let allowBlockCollections: boolean;
|
||||
let indentStatus = 1; // 1: this>parent, 0: this=parent, -1: this<parent
|
||||
let atNewLine = false;
|
||||
let hasContent = false;
|
||||
let type: Type<KindType>;
|
||||
let flowIndent: number;
|
||||
let blockIndent: number;
|
||||
|
||||
this.tag = null;
|
||||
this.anchor = null;
|
||||
this.kind = null;
|
||||
this.result = null;
|
||||
|
||||
const allowBlockStyles = (allowBlockScalars =
|
||||
allowBlockCollections =
|
||||
CONTEXT_BLOCK_OUT === nodeContext || CONTEXT_BLOCK_IN === nodeContext);
|
||||
|
||||
if (allowToSeek) {
|
||||
if (this.skipSeparationSpace(true, -1)) {
|
||||
atNewLine = true;
|
||||
|
||||
if (this.lineIndent > parentIndent) {
|
||||
indentStatus = 1;
|
||||
} else if (this.lineIndent === parentIndent) {
|
||||
indentStatus = 0;
|
||||
} else if (this.lineIndent < parentIndent) {
|
||||
indentStatus = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (indentStatus === 1) {
|
||||
while (this.readTagProperty() || this.readAnchorProperty()) {
|
||||
if (this.skipSeparationSpace(true, -1)) {
|
||||
atNewLine = true;
|
||||
allowBlockCollections = allowBlockStyles;
|
||||
|
||||
if (this.lineIndent > parentIndent) {
|
||||
indentStatus = 1;
|
||||
} else if (this.lineIndent === parentIndent) {
|
||||
indentStatus = 0;
|
||||
} else if (this.lineIndent < parentIndent) {
|
||||
indentStatus = -1;
|
||||
}
|
||||
} else {
|
||||
allowBlockCollections = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allowBlockCollections) {
|
||||
allowBlockCollections = atNewLine || allowCompact;
|
||||
}
|
||||
|
||||
if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) {
|
||||
const cond = CONTEXT_FLOW_IN === nodeContext ||
|
||||
CONTEXT_FLOW_OUT === nodeContext;
|
||||
flowIndent = cond ? parentIndent : parentIndent + 1;
|
||||
|
||||
blockIndent = this.position - this.lineStart;
|
||||
|
||||
if (indentStatus === 1) {
|
||||
if (
|
||||
(allowBlockCollections &&
|
||||
(this.readBlockSequence(blockIndent) ||
|
||||
this.readBlockMapping(blockIndent, flowIndent))) ||
|
||||
this.readFlowCollection(flowIndent)
|
||||
) {
|
||||
hasContent = true;
|
||||
} else {
|
||||
if (
|
||||
(allowBlockScalars && this.readBlockScalar(flowIndent)) ||
|
||||
this.readSingleQuotedScalar(flowIndent) ||
|
||||
this.readDoubleQuotedScalar(flowIndent)
|
||||
) {
|
||||
hasContent = true;
|
||||
} else if (this.readAlias()) {
|
||||
hasContent = true;
|
||||
|
||||
if (this.tag !== null || this.anchor !== null) {
|
||||
return this.throwError(
|
||||
"Cannot compose node: alias node should not have any properties",
|
||||
);
|
||||
}
|
||||
} else if (
|
||||
this.readPlainScalar(flowIndent, CONTEXT_FLOW_IN === nodeContext)
|
||||
) {
|
||||
hasContent = true;
|
||||
|
||||
if (this.tag === null) {
|
||||
this.tag = "?";
|
||||
}
|
||||
}
|
||||
|
||||
if (this.anchor !== null) {
|
||||
this.anchorMap.set(this.anchor, this.result);
|
||||
}
|
||||
}
|
||||
} else if (indentStatus === 0) {
|
||||
// Special case: block sequences are allowed to have same indentation level as the parent.
|
||||
// http://www.yaml.org/spec/1.2/spec.html#id2799784
|
||||
hasContent = allowBlockCollections &&
|
||||
this.readBlockSequence(blockIndent);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.tag !== null && this.tag !== "!") {
|
||||
if (this.tag === "?") {
|
||||
for (
|
||||
let typeIndex = 0;
|
||||
typeIndex < this.implicitTypes.length;
|
||||
typeIndex++
|
||||
) {
|
||||
type = this.implicitTypes[typeIndex]!;
|
||||
|
||||
// Implicit resolving is not allowed for non-scalar types, and '?'
|
||||
// non-specific tag is only assigned to plain scalars. So, it isn't
|
||||
// needed to check for 'kind' conformity.
|
||||
|
||||
if (type.resolve(this.result)) {
|
||||
// `state.result` updated in resolver if matched
|
||||
this.result = type.construct(this.result);
|
||||
this.tag = type.tag;
|
||||
if (this.anchor !== null) {
|
||||
this.anchorMap.set(this.anchor, this.result);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (this.typeMap[this.kind ?? "fallback"].has(this.tag)) {
|
||||
const map = this.typeMap[this.kind ?? "fallback"];
|
||||
type = map.get(this.tag)!;
|
||||
|
||||
if (this.result !== null && type.kind !== this.kind) {
|
||||
return this.throwError(
|
||||
`Unacceptable node kind for !<${this.tag}> tag: it should be "${type.kind}", not "${this.kind}"`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!type.resolve(this.result)) {
|
||||
// `state.result` updated in resolver if matched
|
||||
return this.throwError(
|
||||
`Cannot resolve a node with !<${this.tag}> explicit tag`,
|
||||
);
|
||||
} else {
|
||||
this.result = type.construct(this.result);
|
||||
if (this.anchor !== null) {
|
||||
this.anchorMap.set(this.anchor, this.result);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return this.throwError(`Cannot resolve unknown tag !<${this.tag}>`);
|
||||
}
|
||||
}
|
||||
|
||||
return this.tag !== null || this.anchor !== null || hasContent;
|
||||
}
|
||||
|
||||
readDocument() {
|
||||
const documentStart = this.position;
|
||||
let position: number;
|
||||
@ -1526,7 +1691,7 @@ export class LoaderState {
|
||||
);
|
||||
}
|
||||
|
||||
composeNode(this, this.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);
|
||||
this.composeNode(this.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);
|
||||
this.skipSeparationSpace(true, -1);
|
||||
|
||||
if (
|
||||
@ -1558,169 +1723,3 @@ export class LoaderState {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function composeNode(
|
||||
state: LoaderState,
|
||||
parentIndent: number,
|
||||
nodeContext: number,
|
||||
allowToSeek: boolean,
|
||||
allowCompact: boolean,
|
||||
): boolean {
|
||||
let allowBlockScalars: boolean;
|
||||
let allowBlockCollections: boolean;
|
||||
let indentStatus = 1; // 1: this>parent, 0: this=parent, -1: this<parent
|
||||
let atNewLine = false;
|
||||
let hasContent = false;
|
||||
let type: Type<KindType>;
|
||||
let flowIndent: number;
|
||||
let blockIndent: number;
|
||||
|
||||
state.tag = null;
|
||||
state.anchor = null;
|
||||
state.kind = null;
|
||||
state.result = null;
|
||||
|
||||
const allowBlockStyles = (allowBlockScalars =
|
||||
allowBlockCollections =
|
||||
CONTEXT_BLOCK_OUT === nodeContext || CONTEXT_BLOCK_IN === nodeContext);
|
||||
|
||||
if (allowToSeek) {
|
||||
if (state.skipSeparationSpace(true, -1)) {
|
||||
atNewLine = true;
|
||||
|
||||
if (state.lineIndent > parentIndent) {
|
||||
indentStatus = 1;
|
||||
} else if (state.lineIndent === parentIndent) {
|
||||
indentStatus = 0;
|
||||
} else if (state.lineIndent < parentIndent) {
|
||||
indentStatus = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (indentStatus === 1) {
|
||||
while (state.readTagProperty() || state.readAnchorProperty()) {
|
||||
if (state.skipSeparationSpace(true, -1)) {
|
||||
atNewLine = true;
|
||||
allowBlockCollections = allowBlockStyles;
|
||||
|
||||
if (state.lineIndent > parentIndent) {
|
||||
indentStatus = 1;
|
||||
} else if (state.lineIndent === parentIndent) {
|
||||
indentStatus = 0;
|
||||
} else if (state.lineIndent < parentIndent) {
|
||||
indentStatus = -1;
|
||||
}
|
||||
} else {
|
||||
allowBlockCollections = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allowBlockCollections) {
|
||||
allowBlockCollections = atNewLine || allowCompact;
|
||||
}
|
||||
|
||||
if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) {
|
||||
const cond = CONTEXT_FLOW_IN === nodeContext ||
|
||||
CONTEXT_FLOW_OUT === nodeContext;
|
||||
flowIndent = cond ? parentIndent : parentIndent + 1;
|
||||
|
||||
blockIndent = state.position - state.lineStart;
|
||||
|
||||
if (indentStatus === 1) {
|
||||
if (
|
||||
(allowBlockCollections &&
|
||||
(state.readBlockSequence(blockIndent) ||
|
||||
state.readBlockMapping(blockIndent, flowIndent))) ||
|
||||
state.readFlowCollection(flowIndent)
|
||||
) {
|
||||
hasContent = true;
|
||||
} else {
|
||||
if (
|
||||
(allowBlockScalars && state.readBlockScalar(flowIndent)) ||
|
||||
state.readSingleQuotedScalar(flowIndent) ||
|
||||
state.readDoubleQuotedScalar(flowIndent)
|
||||
) {
|
||||
hasContent = true;
|
||||
} else if (state.readAlias()) {
|
||||
hasContent = true;
|
||||
|
||||
if (state.tag !== null || state.anchor !== null) {
|
||||
return state.throwError(
|
||||
"Cannot compose node: alias node should not have any properties",
|
||||
);
|
||||
}
|
||||
} else if (
|
||||
state.readPlainScalar(flowIndent, CONTEXT_FLOW_IN === nodeContext)
|
||||
) {
|
||||
hasContent = true;
|
||||
|
||||
if (state.tag === null) {
|
||||
state.tag = "?";
|
||||
}
|
||||
}
|
||||
|
||||
if (state.anchor !== null) {
|
||||
state.anchorMap.set(state.anchor, state.result);
|
||||
}
|
||||
}
|
||||
} else if (indentStatus === 0) {
|
||||
// Special case: block sequences are allowed to have same indentation level as the parent.
|
||||
// http://www.yaml.org/spec/1.2/spec.html#id2799784
|
||||
hasContent = allowBlockCollections &&
|
||||
state.readBlockSequence(blockIndent);
|
||||
}
|
||||
}
|
||||
|
||||
if (state.tag !== null && state.tag !== "!") {
|
||||
if (state.tag === "?") {
|
||||
for (
|
||||
let typeIndex = 0;
|
||||
typeIndex < state.implicitTypes.length;
|
||||
typeIndex++
|
||||
) {
|
||||
type = state.implicitTypes[typeIndex]!;
|
||||
|
||||
// Implicit resolving is not allowed for non-scalar types, and '?'
|
||||
// non-specific tag is only assigned to plain scalars. So, it isn't
|
||||
// needed to check for 'kind' conformity.
|
||||
|
||||
if (type.resolve(state.result)) {
|
||||
// `state.result` updated in resolver if matched
|
||||
state.result = type.construct(state.result);
|
||||
state.tag = type.tag;
|
||||
if (state.anchor !== null) {
|
||||
state.anchorMap.set(state.anchor, state.result);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (state.typeMap[state.kind ?? "fallback"].has(state.tag)) {
|
||||
const map = state.typeMap[state.kind ?? "fallback"];
|
||||
type = map.get(state.tag)!;
|
||||
|
||||
if (state.result !== null && type.kind !== state.kind) {
|
||||
return state.throwError(
|
||||
`Unacceptable node kind for !<${state.tag}> tag: it should be "${type.kind}", not "${state.kind}"`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!type.resolve(state.result)) {
|
||||
// `state.result` updated in resolver if matched
|
||||
return state.throwError(
|
||||
`Cannot resolve a node with !<${state.tag}> explicit tag`,
|
||||
);
|
||||
} else {
|
||||
state.result = type.construct(state.result);
|
||||
if (state.anchor !== null) {
|
||||
state.anchorMap.set(state.anchor, state.result);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return state.throwError(`Cannot resolve unknown tag !<${state.tag}>`);
|
||||
}
|
||||
}
|
||||
|
||||
return state.tag !== null || state.anchor !== null || hasContent;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user