( member: string, fromFile: string, context: ResolutionContext )
| 210 | } |
| 211 | |
| 212 | function resolveCobolCopybook( |
| 213 | member: string, |
| 214 | fromFile: string, |
| 215 | context: ResolutionContext |
| 216 | ): string | null { |
| 217 | let index = cobolCopybookIndexes.get(context); |
| 218 | if (!index) { |
| 219 | index = new Map(); |
| 220 | for (const fileNode of context.getNodesByKind('file')) { |
| 221 | const normalized = fileNode.filePath.replace(/\\/g, '/'); |
| 222 | const base = normalized.split('/').pop() ?? ''; |
| 223 | const dot = base.lastIndexOf('.'); |
| 224 | const stem = (dot > 0 ? base.slice(0, dot) : base).toLowerCase(); |
| 225 | const paths = index.get(stem); |
| 226 | if (paths) paths.push(fileNode.filePath); |
| 227 | else index.set(stem, [fileNode.filePath]); |
| 228 | } |
| 229 | cobolCopybookIndexes.set(context, index); |
| 230 | } |
| 231 | |
| 232 | const candidates = index.get(member.toLowerCase()); |
| 233 | if (!candidates || candidates.length === 0) return null; |
| 234 | |
| 235 | const fromDir = fromFile.replace(/\\/g, '/').split('/').slice(0, -1).join('/'); |
| 236 | let best: string | null = null; |
| 237 | let bestScore = -1; |
| 238 | for (const candidate of candidates) { |
| 239 | const normalized = candidate.replace(/\\/g, '/'); |
| 240 | const ext = normalized.slice(normalized.lastIndexOf('.')).toLowerCase(); |
| 241 | let score = 0; |
| 242 | if (ext === '.cpy') score += 4; |
| 243 | else if (ext === '.cbl' || ext === '.cob' || ext === '.cobol') score += 2; |
| 244 | if (normalized.split('/').slice(0, -1).join('/') === fromDir) score += 1; |
| 245 | if (score > bestScore) { |
| 246 | bestScore = score; |
| 247 | best = candidate; |
| 248 | } |
| 249 | } |
| 250 | return best; |
| 251 | } |
| 252 | |
| 253 | /** |
| 254 | * C and C++ standard library header names (without delimiters). |
no test coverage detected