Skip to content

Commit

Permalink
Merge branch 'bodil/master' into beta
Browse files Browse the repository at this point in the history
Closes #2017
  • Loading branch information
Gerrit0 committed Aug 6, 2022
2 parents ac4c4e8 + 1be726c commit 2625cd0
Show file tree
Hide file tree
Showing 20 changed files with 1,091 additions and 417 deletions.
67 changes: 49 additions & 18 deletions src/lib/models/types.ts
@@ -1,3 +1,6 @@
import * as fs from "fs";
import * as path from "path";

import type * as ts from "typescript";
import type { Context } from "../converter";
import { Reflection } from "./reflections/abstract";
Expand Down Expand Up @@ -839,26 +842,30 @@ export class ReferenceType extends Type {
name ?? symbol.name,
symbol,
context.project,
getQualifiedName(context.checker, symbol)
getQualifiedName(symbol, name ?? symbol.name)
);

const symbolPath = symbol?.declarations?.[0]
?.getSourceFile()
.fileName.replace(/\\/g, "/");
if (!symbolPath) return ref;

// Attempt to decide package name from path if it contains "node_modules"
let startIndex = symbolPath.lastIndexOf("node_modules/");
if (startIndex === -1) return ref;
startIndex += "node_modules/".length;
let stopIndex = symbolPath.indexOf("/", startIndex);
// Scoped package, e.g. `@types/node`
if (symbolPath[startIndex] === "@") {
stopIndex = symbolPath.indexOf("/", stopIndex + 1);
if (startIndex !== -1) {
startIndex += "node_modules/".length;
let stopIndex = symbolPath.indexOf("/", startIndex);
// Scoped package, e.g. `@types/node`
if (symbolPath[startIndex] === "@") {
stopIndex = symbolPath.indexOf("/", stopIndex + 1);
}
const packageName = symbolPath.substring(startIndex, stopIndex);
ref.package = packageName;
return ref;
}

const packageName = symbolPath.substring(startIndex, stopIndex);
ref.package = packageName;

// Otherwise, look for a "package.json" file in a parent path
ref.package = findPackageForPath(symbolPath);
return ref;
}

Expand Down Expand Up @@ -887,19 +894,14 @@ export class ReferenceType extends Type {
}

override toObject(serializer: Serializer): JSONOutput.ReferenceType {
const result: JSONOutput.ReferenceType = {
return {
type: this.type,
id: this.reflection?.id,
typeArguments: serializer.toObjectsOptional(this.typeArguments),
name: this.name,
qualifiedName: this.qualifiedName,
package: this.package,
};

if (this.package) {
result.qualifiedName = this.qualifiedName;
result.package = this.package;
}

return result;
}
}

Expand Down Expand Up @@ -1287,3 +1289,32 @@ export class UnknownType extends Type {
};
}
}

const packageJsonLookupCache: Record<string, string> = {};

function findPackageForPath(sourcePath: string): string | undefined {
if (packageJsonLookupCache[sourcePath] !== undefined) {
return packageJsonLookupCache[sourcePath];
}
let basePath = sourcePath;
for (;;) {
const nextPath = path.dirname(basePath);
if (nextPath === basePath) {
return;
}
basePath = nextPath;
const projectPath = path.join(basePath, "package.json");
try {
const packageJsonData = fs.readFileSync(projectPath, {
encoding: "utf8",
});
const packageJson = JSON.parse(packageJsonData);
if (packageJson.name !== undefined) {
packageJsonLookupCache[sourcePath] = packageJson.name;
}
return packageJson.name;
} catch (err) {
continue;
}
}
}
6 changes: 4 additions & 2 deletions src/lib/serialization/schema.ts
Expand Up @@ -241,9 +241,11 @@ export interface QueryType extends Type, S<M.QueryType, "type" | "queryType"> {}

export interface ReferenceType
extends Type,
S<M.ReferenceType, "type" | "name" | "typeArguments" | "package"> {
S<
M.ReferenceType,
"type" | "name" | "typeArguments" | "package" | "qualifiedName"
> {
id?: number;
qualifiedName?: string;
}

export interface ReflectionType extends Type, S<M.ReflectionType, "type"> {
Expand Down
4 changes: 4 additions & 0 deletions src/lib/types/ts-internal/index.d.ts
Expand Up @@ -12,6 +12,10 @@ declare module "typescript" {
interface Symbol {
// https://github.com/microsoft/TypeScript/blob/v4.1.5/src/compiler/types.ts#L4734-L4737
checkFlags?: CheckFlags;

// https://github.com/microsoft/TypeScript/blob/v4.7.4/src/compiler/types.ts#L4941
// https://github.com/microsoft/TypeScript/issues/38344
parent?: ts.Symbol;
}

interface TypeChecker {
Expand Down
25 changes: 14 additions & 11 deletions src/lib/utils/tsutils.ts
@@ -1,14 +1,17 @@
import type * as ts from "typescript";
import * as ts from "typescript";

export function getQualifiedName(checker: ts.TypeChecker, symbol: ts.Symbol) {
const qualifiedName = checker.getFullyQualifiedName(symbol);
// I think this is less bad than depending on symbol.parent...
// https://github.com/microsoft/TypeScript/issues/38344
// It will break if someone names a directory with a quote in it, but so will lots
// of other things including other parts of TypeDoc. Until it *actually* breaks someone...
if (qualifiedName.startsWith('"') && qualifiedName.includes('".')) {
return qualifiedName.substring(qualifiedName.indexOf('".', 1) + 2);
} else {
return qualifiedName;
export function getQualifiedName(symbol: ts.Symbol, defaultName: string) {
// Two implementation options for this one:
// 1. Use the internal symbol.parent, to walk up until we hit a source file symbol (if in a module)
// or undefined (if in a global file)
// 2. Use checker.getFullyQualifiedName and parse out the name from the returned string.
// The symbol.parent method is easier to check for now.
let sym: ts.Symbol | undefined = symbol;
const parts: string[] = [];
while (sym && !sym.declarations?.some(ts.isSourceFile)) {
parts.unshift(sym.name);
sym = sym.parent;
}

return parts.join(".") || defaultName;
}
24 changes: 18 additions & 6 deletions src/test/converter/alias/specs.json
Expand Up @@ -38,7 +38,9 @@
"checkType": {
"type": "reference",
"id": 9,
"name": "T"
"name": "T",
"qualifiedName": "T",
"package": "typedoc"
},
"extendsType": {
"type": "intrinsic",
Expand Down Expand Up @@ -88,7 +90,9 @@
"checkType": {
"type": "reference",
"id": 11,
"name": "T"
"name": "T",
"qualifiedName": "T",
"package": "typedoc"
},
"extendsType": {
"type": "reference",
Expand All @@ -104,12 +108,16 @@
},
"trueType": {
"type": "reference",
"name": "U"
"name": "U",
"qualifiedName": "U",
"package": "typedoc"
},
"falseType": {
"type": "reference",
"id": 11,
"name": "T"
"name": "T",
"qualifiedName": "T",
"package": "typedoc"
}
}
},
Expand Down Expand Up @@ -172,7 +180,9 @@
"type": {
"type": "reference",
"id": 6,
"name": "T"
"name": "T",
"qualifiedName": "T",
"package": "typedoc"
}
},
{
Expand All @@ -183,7 +193,9 @@
"type": {
"type": "reference",
"id": 6,
"name": "T"
"name": "T",
"qualifiedName": "T",
"package": "typedoc"
}
}
],
Expand Down

0 comments on commit 2625cd0

Please sign in to comment.