private async processSymbol()

in src/goTest/resolve.ts [400:477]


	private async processSymbol(
		doc: TextDocument,
		file: TestItem,
		seen: Set<string>,
		importsTestify: boolean,
		symbol: DocumentSymbol
	) {
		// Skip TestMain(*testing.M) - allow TestMain(*testing.T)
		if (symbol.name === 'TestMain' && /\*testing.M\)/.test(symbol.detail)) {
			return;
		}

		// Recursively process symbols that are nested
		if (symbol.kind !== SymbolKind.Function) {
			for (const sym of symbol.children) await this.processSymbol(doc, file, seen, importsTestify, sym);
			return;
		}

		const match = symbol.name.match(testFuncRegex) || (importsTestify && symbol.name.match(testMethodRegex));
		if (!match) {
			return;
		}

		seen.add(symbol.name);

		const kind = match.groups.kind.toLowerCase() as GoTestKind;
		const suite = match.groups.type ? this.getTestSuite(match.groups.type) : undefined;
		const existing =
			this.getItem(file, doc.uri, kind, symbol.name) ||
			(suite?.func && this.getItem(suite?.func, doc.uri, kind, symbol.name));

		if (existing) {
			if (!existing.range.isEqual(symbol.range)) {
				existing.range = symbol.range;
				this.relocateChildren(existing);
			}
			return existing;
		}

		const item = this.getOrCreateItem(suite?.func || file, match.groups.name, doc.uri, kind, symbol.name);
		item.range = symbol.range;

		if (suite) {
			this.isTestMethod.add(item);
			if (!suite.func) suite.methods.add(item);
			return;
		}

		if (!importsTestify) {
			return;
		}

		// Runs any suite
		const text = doc.getText(symbol.range);
		if (text.includes('suite.Run(')) {
			this.isTestSuiteFunc.add(item);
		}

		// Runs a specific suite
		// - suite.Run(t, new(MySuite))
		// - suite.Run(t, MySuite{})
		// - suite.Run(t, &MySuite{})
		const matchRunSuite = text.match(runTestSuiteRegex);
		if (matchRunSuite) {
			const g = matchRunSuite.groups;
			const suite = this.getTestSuite(g.type1 || g.type2);
			suite.func = item;

			for (const method of suite.methods) {
				if (GoTest.parseId(method.parent.id).kind !== 'file') {
					continue;
				}

				method.parent.children.delete(method.id);
				item.children.add(method);
			}
		}
	}