diff --git a/packages/compiler-cli/src/ngtsc/core/src/compiler.ts b/packages/compiler-cli/src/ngtsc/core/src/compiler.ts index 55a95097fb1..17753a25b55 100644 --- a/packages/compiler-cli/src/ngtsc/core/src/compiler.ts +++ b/packages/compiler-cli/src/ngtsc/core/src/compiler.ts @@ -734,7 +734,10 @@ export class NgCompiler { throw new Error(`Entry point "${entryPoint}" not found in program sources.`); } - return docsExtractor.extractAll(entryPointSourceFile); + // TODO: Technically the current directory is not the root dir. + // Should probably be derived from the config. + const rootDir = this.inputProgram.getCurrentDirectory(); + return docsExtractor.extractAll(entryPointSourceFile, rootDir); } /** diff --git a/packages/compiler-cli/src/ngtsc/docs/src/entities.ts b/packages/compiler-cli/src/ngtsc/docs/src/entities.ts index d53d0189fef..e4c80139f5c 100644 --- a/packages/compiler-cli/src/ngtsc/docs/src/entities.ts +++ b/packages/compiler-cli/src/ngtsc/docs/src/entities.ts @@ -64,6 +64,16 @@ export interface GenericEntry { default: string|undefined; } +export interface SourceEntry { + filePath: string; + startLine: number; + endLine: number; +} + +export interface DocEntryWithSourceInfo extends DocEntry { + source: SourceEntry; +} + /** Base type for all documentation entities. */ export interface DocEntry { entryType: EntryType; @@ -195,3 +205,7 @@ export interface InitializerApiFunctionEntry extends DocEntry { showTypesInSignaturePreview?: boolean; }; } + +export function isDocEntryWithSourceInfo(entry: DocEntry): entry is DocEntryWithSourceInfo { + return 'source' in entry; +} diff --git a/packages/compiler-cli/src/ngtsc/docs/src/extractor.ts b/packages/compiler-cli/src/ngtsc/docs/src/extractor.ts index c662968623a..81de69e8ad4 100644 --- a/packages/compiler-cli/src/ngtsc/docs/src/extractor.ts +++ b/packages/compiler-cli/src/ngtsc/docs/src/extractor.ts @@ -14,7 +14,7 @@ import {isNamedClassDeclaration, TypeScriptReflectionHost} from '../../reflectio import {extractClass, extractInterface} from './class_extractor'; import {extractConstant, isSyntheticAngularConstant} from './constant_extractor'; import {extractorDecorator, isDecoratorDeclaration, isDecoratorOptionsInterface} from './decorator_extractor'; -import {DocEntry} from './entities'; +import {DocEntry, DocEntryWithSourceInfo} from './entities'; import {extractEnum} from './enum_extractor'; import {isAngularPrivateName} from './filters'; import {FunctionExtractor} from './function_extractor'; @@ -36,7 +36,7 @@ export class DocsExtractor { * * @param sourceFile The file from which to extract documentable entries. */ - extractAll(sourceFile: ts.SourceFile): DocEntry[] { + extractAll(sourceFile: ts.SourceFile, rootDir: string): DocEntry[] { const entries: DocEntry[] = []; const exportedDeclarations = this.getExportedDeclarations(sourceFile); @@ -48,6 +48,17 @@ export class DocsExtractor { const entry = this.extractDeclaration(node); if (entry && !isIgnoredDocEntry(entry)) { + // The source file parameter is the package entry: the index.ts + // We want the real source file of the declaration. + const realSourceFile = node.getSourceFile(); + + // Set the source code references for the extracted entry. + (entry as DocEntryWithSourceInfo).source = { + filePath: getRelativeFilePath(realSourceFile, rootDir), + startLine: ts.getLineAndCharacterOfPosition(realSourceFile, node.getFullStart()).line, + endLine: ts.getLineAndCharacterOfPosition(realSourceFile, node.getEnd()).line, + }; + // The exported name of an API may be different from its declaration name, so // use the declaration name. entries.push({...entry, name: exportName}); @@ -157,3 +168,11 @@ function isIgnoredDocEntry(entry: DocEntry): boolean { return isDocsPrivate !== undefined; } + + +function getRelativeFilePath(sourceFile: ts.SourceFile, rootDir: string): string { + const fullPath = sourceFile.fileName; + const relativePath = fullPath.replace(rootDir, ''); + + return relativePath; +} diff --git a/tools/manual_api_docs/generate_block_api_json.ts b/tools/manual_api_docs/generate_block_api_json.ts index 6595258a8a1..7777bd6e4c0 100644 --- a/tools/manual_api_docs/generate_block_api_json.ts +++ b/tools/manual_api_docs/generate_block_api_json.ts @@ -23,6 +23,11 @@ function main() { entryType: EntryType.Block, description: fileContent, rawComment: fileContent, + source: { + filePath: sourceFilePath, + startLine: 0, + endLine: 0, + }, jsdocTags: [], }; }); diff --git a/tools/manual_api_docs/generate_element_api_json.ts b/tools/manual_api_docs/generate_element_api_json.ts index 2be1e921e11..05873894c08 100644 --- a/tools/manual_api_docs/generate_element_api_json.ts +++ b/tools/manual_api_docs/generate_element_api_json.ts @@ -20,6 +20,11 @@ function main() { return { name: basename(sourceFilePath, '.md'), + source: { + filePath: sourceFilePath, + startLine: 0, + endLine: 0, + }, entryType: EntryType.Element, description: fileContent, rawComment: fileContent,