<commit_before>import * as dom from "dts-dom";

export class JSDocTsdParser {

	private jsdocItems: TDoclet[];
	private resultItems: {
		[key: string]: dom.DeclarationBase[];
	};

	constructor() {
		this.resultItems = {};
	}

	public getResultItems() {
		return this.resultItems;
	}

	public parse(jsdocItems: TDoclet[]) {
		this.jsdocItems = jsdocItems;

		jsdocItems.forEach((item) => {
			this.resultItems[item.longname] = [];

			switch (item.kind) {
				case "function":
					this.parseFunction(item as IFunctionDoclet);
					break;

				case "member":
					if (item.isEnum) {
						this.parseEnum(item as IMemberDoclet);
					} else {
						this.parseMember(item as IMemberDoclet);
					}
					break;

				case "namespace":
					this.parseNamespace(item as INamespaceDoclet);
					break;

				case "typedef":
					this.parseTypeDefinition(item as ITypedefDoclet);
					break;

				case "file":
					// suppress warnings for this type
					break;

				case "class":
					this.parseClass(item as IClassDoclet);
					break;

				default:
					console.warn(`Unsupported jsdoc item kind: ${item.kind} (item name: ${item.longname})`);
					break;
			}
		});
	}

	public resolveResults(): string {
		let output = "";

		let results = this.prepareResults();
		Object.keys(results).forEach((key) => {
			output += dom.emit(results[key]);
		});

		return output;
	}

	private createDomParams(params: IDocletProp[]): dom.Parameter[] {
		let domParams: dom.Parameter[] = [];

		params.forEach((param) => {
			let domParam: dom.Parameter;

			if (param.type && param.type.names.length > 0) {
				domParam = dom.create.parameter(param.name, this.mapTypesToUnion(param.type.names));
			} else {
				// the param has no type => map to "any"
				domParam = dom.create.parameter(param.name, dom.type.any);
			}

			if (param.optional) {
				domParam.flags = dom.ParameterFlags.Optional;
			}

			domParams.push(domParam);
		});

		return domParams;
	}

	private cleanJSDocComment(comment: string | undefined): string {
		let cleanLines = [];

		if (comment) {
			for (let line of comment.split(/\r?\n/)) {
				let cleanedLine = line.trim()
					.replace(/^\/\*\*\s?/, "") // JSDoc-Header ("/**")
					.replace(/\s*\*\/\s?$/, "") // JSDoc-Footer ("*/")
					.replace(/^\*\s?/, "") // Line ("*")
					.replace(/@param\s\{[^\}]+\}/g, "@param") // Parameter-Types
					.trim();

				// ignore everything that is not part of the function description in tsd-files
				if (cleanedLine && (cleanedLine.startsWith("@param") || cleanedLine.startsWith("@throws") || !cleanedLine.startsWith("@"))) {
					cleanLines.push(cleanedLine);
				}
			}
		}

		return cleanLines.join("\n");
	}

	private mapVariableType(variableType: string) {
		let matches = variableType.match(/(?:Array\.<([^>]+)>)|(?:([^\[]*)\[\])/i);

		if (matches) {
			let type = matches[1] || matches[2];

			if (type === "*" || type === "") {
				// wrong type definition
				return dom.type.any;
			} else {
				if (type === "bool") {
					type = "boolean";
				}

				return dom.type.array(type as dom.Type);
			}
		} else {
			if (variableType.match(/array/i) || variableType === "*") {
				return dom.type.any;
			} else {
				if (variableType === "bool") {
					variableType = "boolean";
				}

				return variableType as dom.Type;
			}
		}
	}<commit_msg>function to map multiple type strings to unions<commit_after>import * as dom from "dts-dom";

export class JSDocTsdParser {

	private jsdocItems: TDoclet[];
	private resultItems: {
		[key: string]: dom.DeclarationBase[];
	};

	constructor() {
		this.resultItems = {};
	}

	public getResultItems() {
		return this.resultItems;
	}

	public parse(jsdocItems: TDoclet[]) {
		this.jsdocItems = jsdocItems;

		jsdocItems.forEach((item) => {
			this.resultItems[item.longname] = [];

			switch (item.kind) {
				case "function":
					this.parseFunction(item as IFunctionDoclet);
					break;

				case "member":
					if (item.isEnum) {
						this.parseEnum(item as IMemberDoclet);
					} else {
						this.parseMember(item as IMemberDoclet);
					}
					break;

				case "namespace":
					this.parseNamespace(item as INamespaceDoclet);
					break;

				case "typedef":
					this.parseTypeDefinition(item as ITypedefDoclet);
					break;

				case "file":
					// suppress warnings for this type
					break;

				case "class":
					this.parseClass(item as IClassDoclet);
					break;

				default:
					console.warn(`Unsupported jsdoc item kind: ${item.kind} (item name: ${item.longname})`);
					break;
			}
		});
	}

	public resolveResults(): string {
		let output = "";

		let results = this.prepareResults();
		Object.keys(results).forEach((key) => {
			output += dom.emit(results[key]);
		});

		return output;
	}

	private createDomParams(params: IDocletProp[]): dom.Parameter[] {
		let domParams: dom.Parameter[] = [];

		params.forEach((param) => {
			let domParam: dom.Parameter;

			if (param.type && param.type.names.length > 0) {
				domParam = dom.create.parameter(param.name, this.mapTypesToUnion(param.type.names));
			} else {
				// the param has no type => map to "any"
				domParam = dom.create.parameter(param.name, dom.type.any);
			}

			if (param.optional) {
				domParam.flags = dom.ParameterFlags.Optional;
			}

			domParams.push(domParam);
		});

		return domParams;
	}

	private cleanJSDocComment(comment: string | undefined): string {
		let cleanLines = [];

		if (comment) {
			for (let line of comment.split(/\r?\n/)) {
				let cleanedLine = line.trim()
					.replace(/^\/\*\*\s?/, "") // JSDoc-Header ("/**")
					.replace(/\s*\*\/\s?$/, "") // JSDoc-Footer ("*/")
					.replace(/^\*\s?/, "") // Line ("*")
					.replace(/@param\s\{[^\}]+\}/g, "@param") // Parameter-Types
					.trim();

				// ignore everything that is not part of the function description in tsd-files
				if (cleanedLine && (cleanedLine.startsWith("@param") || cleanedLine.startsWith("@throws") || !cleanedLine.startsWith("@"))) {
					cleanLines.push(cleanedLine);
				}
			}
		}

		return cleanLines.join("\n");
	}

	private mapTypesToUnion(types: string[]): dom.UnionType {
		let domTypes: dom.Type[] = [];

		types.forEach((type) => {
			domTypes.push(this.mapVariableType(type));
		});

		return dom.create.union(domTypes);
	}

	private mapVariableType(variableType: string) {
		let matches = variableType.match(/(?:Array\.<([^>]+)>)|(?:([^\[]*)\[\])/i);

		if (matches) {
			let type = matches[1] || matches[2];

			if (type === "*" || type === "") {
				// wrong type definition
				return dom.type.any;
			} else {
				if (type === "bool") {
					type = "boolean";
				}

				return dom.type.array(type as dom.Type);
			}
		} else {
			if (variableType.match(/array/i) || variableType === "*") {
				return dom.type.any;
			} else {
				if (variableType === "bool") {
					variableType = "boolean";
				}

				return variableType as dom.Type;
			}
		}
	}
{'fraction_non_alphanumeric': 0.1777745369695202, 'fraction_numerical': 0.0008750182295464489, 'mean_word_length': 2.912150598973189, 'pattern_counts': {'":': 12, '<': 5, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '333821', 'n_tokens_mistral': 2821, 'n_tokens_neox': 2273, 'n_words': 474}