function addItemsToArrayNode()

in language-service/src/parser/yamlParser.ts [200:248]


function addItemsToArrayNode(node: ArrayASTNode, items: Yaml.YAMLNode[]): void {
	let count = 0;
	for (const item of items) {
		// TODO: What the heck is this check
		if (item === null && count === items.length - 1) {
			break;
		}

		let itemNode: ASTNode;
		if (item === null) {
			// Be aware of https://github.com/nodeca/js-yaml/issues/321
			// Cannot simply work around it here because we need to know if we are in Flow or Block
			itemNode = new NullASTNode(node.parent, null, node.end, node.end);
		} else {
			if (item.kind === Yaml.Kind.MAP &&
				item.mappings[0].key.value.startsWith("${{") &&
				item.mappings[0].key.value.endsWith("}}")) {
				const value = item.mappings[0].value;
				if (value === null) {
					continue;
				}

				if (value.kind === Yaml.Kind.SEQ) {
					// e.g. conditionally adding steps to a job.
					addItemsToArrayNode(node, item.mappings[0].value.items);
					count++;
					continue;
				} else if (value.kind === Yaml.Kind.MAP) {
					// e.g. looping through a stepList parameter and checking each value.
					// NOTE: We don't have a great story for this as we can't validate
					// the resulting ${{ pair.key }}: ${{ pair.value }} against the schema,
					// so we currently just create an empty object with no properties.
					// We might need to revisit this if we start providing LSP capabilities
					// for expressions.
					itemNode = recursivelyBuildAst(node, value);
				} else {
					throw new Error(`Unexpected kind ${value.kind}`);
				}
			} else {
				itemNode = recursivelyBuildAst(node, item);
			}
		}

		itemNode.location = node.items.length;
		node.addItem(itemNode);

		count++;
	}
}