diff --git a/types/tern/index.d.ts b/types/tern/index.d.ts index 7ef634e6a6..a5df150ce6 100644 --- a/types/tern/index.d.ts +++ b/types/tern/index.d.ts @@ -4,12 +4,5 @@ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.8 -// IMPORTANT Note: These type definitions adhere strictly to the official documentation, -// which does not seem to match the implementation exactly in some places. -// As a result, these type definitions may lack some parts of the API that are actually exposed. -// The type definitions are at a point where they are usable and match the documentation, -// thus if you want to use undocumented APIs, you should extends these definitions with -// ambient declaration merging: https://www.typescriptlang.org/docs/handbook/declaration-merging.html - export * from "./lib/infer"; export * from "./lib/tern"; diff --git a/types/tern/lib/infer/index.d.ts b/types/tern/lib/infer/index.d.ts index b8cc01e68f..c2d3a717f9 100644 --- a/types/tern/lib/infer/index.d.ts +++ b/types/tern/lib/infer/index.d.ts @@ -11,11 +11,11 @@ export interface Context { parent?: Server; topScope: Scope; /** The primitive number type. */ - num: Type; + num: Prim & { name: "number" }; /** The primitive string type. */ - str: Type; + str: Prim & { name: "string" }; /** The primitive boolean type. */ - bool: Type; + bool: Prim & { name: "bool" }; } /** Returns the current context object. */ export function cx(): Context; @@ -52,9 +52,11 @@ interface ObjConstructor { } /** Constructor for the type that represents JavaScript objects. `proto` may be another object, or `true` as a short-hand for `Object.prototype`, or `null` for prototype-less objects. */ export const Obj: ObjConstructor; -export interface Obj extends Type { +export interface Obj extends IType { + /** The name of the type, if any. */ + name: string | undefined; /** The prototype of the object, or null. */ - proto: any; + proto: (Obj & { name: string }) | null; /** An object mapping the object’s known properties to AVals. Don’t manipulate this directly (ever), only use it if you have to iterate over the properties. */ props: Readonly<{ [key: string]: AVal; @@ -63,7 +65,17 @@ export interface Obj extends Type { hasProp(prop: string): AVal | null; /** Looks up the given property, or defines it if it did not yet exist (in which case it will be associated with the given AST node). */ defProp(prop: string, originNode?: ESTree.Node): AVal; + /** + * Asks the AVal if it contains an Object type. Useful when + * you aren’t interested in other kinds of types. + */ + getObjType(): Obj; getType(): Obj; + /** Get an `AVal` that represents the named property of this type. */ + getProp(prop: string): AVal; + /** Call the given function for all properties of the object, including properties that are added in the future. */ + forAllProps(f: (prop: string, val: AVal, local: boolean) => void): void; + gatherProperties(f: (...args: any[]) => void, depth: number): void; } interface FnConstructor { @@ -76,22 +88,47 @@ export interface Fn extends Obj { readonly argNames?: string[]; self?: Type; readonly retval: AVal; + /** + * Asks the AVal if it contains a function type. Useful when + * you aren’t interested in other kinds of types. + */ + getFunctionType(): Fn; isArrowFn(): boolean; getType(): Fn; } +interface PrimConstructor { + new(proto: object | null, name?: string): Prim; +} +export const Prim: PrimConstructor; +export interface Prim extends IType { + /** The name of the type, if any. */ + name: "string" | "bool" | "number"; + /** The prototype of the object, or null. */ + proto: Obj & { name: string }; + /** Get an `AVal` that represents the named property of this type. */ + getProp(prop: string): AVal; + getType(): Prim; + gatherProperties(f: (...args: any[]) => void, depth: number): void; +} + interface ArrConstructor { /** Constructor that creates an array type with the given content type. */ new(contentType?: AVal): Arr; } export const Arr: ArrConstructor; export interface Arr extends Obj { + name: "Array"; getType(): Arr; } +interface TypeConstructor { + new(): Type; +} +export const Type: TypeConstructor; +export type Type = Obj | Prim; -export interface Type extends AVal { - /** The name of the type, if any. */ - name: string | undefined; +// tslint:disable-next-line: interface-name +export interface IType extends ANull { /** The origin file of the type. */ origin: string; /** @@ -102,8 +139,8 @@ export interface Type extends AVal { originNode?: ESTree.Node; /** Return a string that describes the type. maxDepth indicates the depth to which inner types should be shown. */ toString(maxDepth: number): string; - /** Call the given function for all properties of the object, including properties that are added in the future. */ - forAllProps(f: (prop: string, val: AVal, local: boolean) => void): void; + /** Queries whether the AVal _currently_ holds the given type. */ + hasType(type: Type): boolean; getType(): Type; } @@ -113,7 +150,21 @@ interface AValConstructor { new(): AVal; } export const AVal: AValConstructor; -export interface AVal { + +/** + * Abstract values are objects used to represent sets of types. Each variable + * and property has an abstract value associated with it, but they are also + * used for other purposes, such as tracking the return type of a function, + * or building up the type for some kinds of expressions. + * + * In a cleanly typed program where each thing has only a single type, + * abstract values will all have one type associated with them. When, + * for example, a variable can hold two different types of values, + * the associated abstract value will hold both these types. In some cases, + * no type can be assigned to something at all, + * in which case the abstract value remains empty. + */ +export interface AVal extends ANull { /** * Add a type to this abstract value. If the type is already in there, * this is a no-op. weight can be given to give this type a non-default @@ -147,6 +198,8 @@ export interface AVal { getFunctionType(): Fn | undefined; /** Get an `AVal` that represents the named property of this type. */ getProp(prop: string): AVal; + /** Call the given function for all properties of the object, including properties that are added in the future. */ + forAllProps(f: (prop: string, val: AVal, local: boolean) => void): void; /** * Asks the AVal if it contains an Object type. Useful when * you aren’t interested in other kinds of types. @@ -157,21 +210,38 @@ export interface AVal { * or properties will have, when possible, an `originNode` * property pointing to an AST node. */ + gatherProperties(f: (...args: any[]) => void, depth: number): void; originNode?: ESTree.Node; - + /** An object mapping the object’s known properties to AVals. Don’t manipulate this directly (ever), only use it if you have to iterate over the properties. */ + props: Partial>; readonly types: Type[]; readonly propertyOf?: Obj; } +/** + * A variant of AVal used for unknown, dead-end values. Also serves + * a prototype for AVals, Types, and Constraints because it + * implements 'empty' versions of all the methods that the code expects. + */ export const ANull: ANull; -export interface ANull extends AVal { - addType(): void; - propagate(target: never): void; - hasType(): false; - isEmpty(): true; - getFunctionType(): undefined; - getType(): null; - originNode: undefined; +export interface ANull { + addType(...args: any[]): void; + propagate(...args: any[]): void; + getProp(...args: any[]): ANull; + forAllProps(...args: any[]): void; + hasType(...args: any[]): boolean; + isEmpty(...args: any[]): boolean; + getFunctionType(...args: any[]): ANull | undefined; + getObjType(...args: any[]): ANull | undefined | null; + getSymbolType(...args: any[]): ANull | undefined; + getType(...args: any[]): ANull | undefined | null; + gatherProperties(...args: any[]): void; + propagatesTo(): any; + typeHint(...args: any[]): ANull | undefined | null; + propHint(...args: any[]): string | undefined; + toString(...args: any[]): string; } // #### Constraints #### @@ -184,11 +254,11 @@ interface ConstraintConstructor { * which will run its construct method on its arguments when instantiated. */ export const constraint: ConstraintConstructor; -export interface Constraint extends AVal { +export interface Constraint extends ANull { /** May return a type that `getType` can use to “guess” its type based on the fact that it propagates to this constraint. */ - typeHint?(): Type | undefined; + typeHint(): Type | undefined; /** May return a string when this constraint is indicative of the presence of a specific property in the source AVal. */ - propHint?(): string | undefined; + propHint(): string | undefined; } // #### Scopes ####