Add special lookups test case, rename helper

This commit is contained in:
Wesley Wigham 2020-05-07 18:02:38 -07:00
parent 128ef9370b
commit a90f97c6f6
No known key found for this signature in database
GPG key ID: D59F87F60C5400C9
5 changed files with 285 additions and 3 deletions

View file

@ -5505,7 +5505,7 @@ namespace ts {
return symbol.declarations && find(symbol.declarations, s => !!getEffectiveTypeAnnotationNode(s) && (!enclosingDeclaration || !!findAncestor(s, n => n === enclosingDeclaration)));
}
function getExistingNodeHasNoTypeParametersOrMatchingTypeParameters(existing: TypeNode, type: Type) {
function existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(existing: TypeNode, type: Type) {
return !(getObjectFlags(type) & ObjectFlags.Reference) || !isTypeReferenceNode(existing) || length(existing.typeArguments) >= getMinTypeArgumentCount((type as TypeReference).target.typeParameters);
}
@ -5519,7 +5519,7 @@ namespace ts {
if (declWithExistingAnnotation && !isFunctionLikeDeclaration(declWithExistingAnnotation)) {
// try to reuse the existing annotation
const existing = getEffectiveTypeAnnotationNode(declWithExistingAnnotation)!;
if (getTypeFromTypeNode(existing) === type && getExistingNodeHasNoTypeParametersOrMatchingTypeParameters(existing, type)) {
if (getTypeFromTypeNode(existing) === type && existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(existing, type)) {
const result = serializeExistingTypeNode(context, existing, includePrivateSymbol, bundled);
if (result) {
return result;
@ -5540,7 +5540,7 @@ namespace ts {
function serializeReturnTypeForSignature(context: NodeBuilderContext, type: Type, signature: Signature, includePrivateSymbol?: (s: Symbol) => void, bundled?: boolean) {
if (type !== errorType && context.enclosingDeclaration) {
const annotation = signature.declaration && getEffectiveReturnTypeNode(signature.declaration);
if (!!findAncestor(annotation, n => n === context.enclosingDeclaration) && annotation && instantiateType(getTypeFromTypeNode(annotation), signature.mapper) === type && getExistingNodeHasNoTypeParametersOrMatchingTypeParameters(annotation, type)) {
if (!!findAncestor(annotation, n => n === context.enclosingDeclaration) && annotation && instantiateType(getTypeFromTypeNode(annotation), signature.mapper) === type && existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(annotation, type)) {
const result = serializeExistingTypeNode(context, annotation, includePrivateSymbol, bundled);
if (result) {
return result;
@ -5647,6 +5647,9 @@ namespace ts {
);
}
}
if (isTypeReferenceNode(node) && isInJSDoc(node) && (getIntendedTypeFromJSDocTypeReference(node) || unknownSymbol === resolveTypeReferenceName(getTypeReferenceName(node), SymbolFlags.Type, /*ignoreErrors*/ true))) {
return setOriginalNode(typeToTypeNodeHelper(getTypeFromTypeNode(node), context), node);
}
if (isLiteralImportTypeNode(node)) {
return updateImportTypeNode(
node,

View file

@ -0,0 +1,82 @@
//// [index.js]
// these are recognized as TS concepts by the checker
/** @type {String} */const a = "";
/** @type {Number} */const b = 0;
/** @type {Boolean} */const c = true;
/** @type {Void} */const d = undefined;
/** @type {Undefined} */const e = undefined;
/** @type {Null} */const f = null;
/** @type {Function} */const g = () => void 0;
/** @type {function} */const h = () => void 0;
/** @type {array} */const i = [];
/** @type {promise} */const j = Promise.resolve(0);
/** @type {Object<string, string>} */const k = {x: "x"};
// these are not recognized as anything and should just be lookup failures
// ignore the errors to try to ensure they're emitted as `any` in declaration emit
// @ts-ignore
/** @type {class} */const l = true;
// @ts-ignore
/** @type {bool} */const m = true;
// @ts-ignore
/** @type {int} */const n = true;
// @ts-ignore
/** @type {float} */const o = true;
// @ts-ignore
/** @type {integer} */const p = true;
// or, in the case of `event` likely erroneously refers to the type of the global Event object
/** @type {event} */const q = undefined;
//// [index.js]
"use strict";
// these are recognized as TS concepts by the checker
/** @type {String} */ const a = "";
/** @type {Number} */ const b = 0;
/** @type {Boolean} */ const c = true;
/** @type {Void} */ const d = undefined;
/** @type {Undefined} */ const e = undefined;
/** @type {Null} */ const f = null;
/** @type {Function} */ const g = () => void 0;
/** @type {function} */ const h = () => void 0;
/** @type {array} */ const i = [];
/** @type {promise} */ const j = Promise.resolve(0);
/** @type {Object<string, string>} */ const k = { x: "x" };
// these are not recognized as anything and should just be lookup failures
// ignore the errors to try to ensure they're emitted as `any` in declaration emit
// @ts-ignore
/** @type {class} */ const l = true;
// @ts-ignore
/** @type {bool} */ const m = true;
// @ts-ignore
/** @type {int} */ const n = true;
// @ts-ignore
/** @type {float} */ const o = true;
// @ts-ignore
/** @type {integer} */ const p = true;
// or, in the case of `event` likely erroneously refers to the type of the global Event object
/** @type {event} */ const q = undefined;
//// [index.d.ts]
/** @type {String} */ declare const a: string;
/** @type {Number} */ declare const b: number;
/** @type {Boolean} */ declare const c: boolean;
/** @type {Void} */ declare const d: void;
/** @type {Undefined} */ declare const e: undefined;
/** @type {Null} */ declare const f: null;
/** @type {Function} */ declare const g: Function;
/** @type {function} */ declare const h: Function;
/** @type {array} */ declare const i: any[];
/** @type {promise} */ declare const j: Promise<any>;
/** @type {Object<string, string>} */ declare const k: {
[x: string]: string;
};
/** @type {class} */ declare const l: any;
/** @type {bool} */ declare const m: any;
/** @type {int} */ declare const n: any;
/** @type {float} */ declare const o: any;
/** @type {integer} */ declare const p: any;
/** @type {event} */ declare const q: Event | undefined;

View file

@ -0,0 +1,69 @@
=== tests/cases/conformance/jsdoc/declarations/index.js ===
// these are recognized as TS concepts by the checker
/** @type {String} */const a = "";
>a : Symbol(a, Decl(index.js, 1, 26))
/** @type {Number} */const b = 0;
>b : Symbol(b, Decl(index.js, 2, 26))
/** @type {Boolean} */const c = true;
>c : Symbol(c, Decl(index.js, 3, 27))
/** @type {Void} */const d = undefined;
>d : Symbol(d, Decl(index.js, 4, 24))
>undefined : Symbol(undefined)
/** @type {Undefined} */const e = undefined;
>e : Symbol(e, Decl(index.js, 5, 29))
>undefined : Symbol(undefined)
/** @type {Null} */const f = null;
>f : Symbol(f, Decl(index.js, 6, 24))
/** @type {Function} */const g = () => void 0;
>g : Symbol(g, Decl(index.js, 8, 28))
/** @type {function} */const h = () => void 0;
>h : Symbol(h, Decl(index.js, 9, 28))
/** @type {array} */const i = [];
>i : Symbol(i, Decl(index.js, 10, 25))
/** @type {promise} */const j = Promise.resolve(0);
>j : Symbol(j, Decl(index.js, 11, 27))
>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
/** @type {Object<string, string>} */const k = {x: "x"};
>k : Symbol(k, Decl(index.js, 12, 42))
>x : Symbol(x, Decl(index.js, 12, 48))
// these are not recognized as anything and should just be lookup failures
// ignore the errors to try to ensure they're emitted as `any` in declaration emit
// @ts-ignore
/** @type {class} */const l = true;
>l : Symbol(l, Decl(index.js, 18, 25))
// @ts-ignore
/** @type {bool} */const m = true;
>m : Symbol(m, Decl(index.js, 20, 24))
// @ts-ignore
/** @type {int} */const n = true;
>n : Symbol(n, Decl(index.js, 22, 23))
// @ts-ignore
/** @type {float} */const o = true;
>o : Symbol(o, Decl(index.js, 24, 25))
// @ts-ignore
/** @type {integer} */const p = true;
>p : Symbol(p, Decl(index.js, 26, 27))
// or, in the case of `event` likely erroneously refers to the type of the global Event object
/** @type {event} */const q = undefined;
>q : Symbol(q, Decl(index.js, 29, 25))
>undefined : Symbol(undefined)

View file

@ -0,0 +1,89 @@
=== tests/cases/conformance/jsdoc/declarations/index.js ===
// these are recognized as TS concepts by the checker
/** @type {String} */const a = "";
>a : string
>"" : ""
/** @type {Number} */const b = 0;
>b : number
>0 : 0
/** @type {Boolean} */const c = true;
>c : boolean
>true : true
/** @type {Void} */const d = undefined;
>d : void
>undefined : undefined
/** @type {Undefined} */const e = undefined;
>e : undefined
>undefined : undefined
/** @type {Null} */const f = null;
>f : null
>null : null
/** @type {Function} */const g = () => void 0;
>g : Function
>() => void 0 : () => undefined
>void 0 : undefined
>0 : 0
/** @type {function} */const h = () => void 0;
>h : Function
>() => void 0 : () => undefined
>void 0 : undefined
>0 : 0
/** @type {array} */const i = [];
>i : any[]
>[] : never[]
/** @type {promise} */const j = Promise.resolve(0);
>j : Promise<any>
>Promise.resolve(0) : Promise<number>
>Promise.resolve : { <T>(value: T | PromiseLike<T>): Promise<T>; (): Promise<void>; }
>Promise : PromiseConstructor
>resolve : { <T>(value: T | PromiseLike<T>): Promise<T>; (): Promise<void>; }
>0 : 0
/** @type {Object<string, string>} */const k = {x: "x"};
>k : { [x: string]: string; }
>{x: "x"} : { x: string; }
>x : string
>"x" : "x"
// these are not recognized as anything and should just be lookup failures
// ignore the errors to try to ensure they're emitted as `any` in declaration emit
// @ts-ignore
/** @type {class} */const l = true;
>l : error
>true : true
// @ts-ignore
/** @type {bool} */const m = true;
>m : error
>true : true
// @ts-ignore
/** @type {int} */const n = true;
>n : error
>true : true
// @ts-ignore
/** @type {float} */const o = true;
>o : error
>true : true
// @ts-ignore
/** @type {integer} */const p = true;
>p : error
>true : true
// or, in the case of `event` likely erroneously refers to the type of the global Event object
/** @type {event} */const q = undefined;
>q : Event | undefined
>undefined : undefined

View file

@ -0,0 +1,39 @@
// @allowJs: true
// @checkJs: true
// @target: es6
// @outDir: ./out
// @declaration: true
// @strict: true
// @noImplicitAny: false
// @filename: index.js
// these are recognized as TS concepts by the checker
/** @type {String} */const a = "";
/** @type {Number} */const b = 0;
/** @type {Boolean} */const c = true;
/** @type {Void} */const d = undefined;
/** @type {Undefined} */const e = undefined;
/** @type {Null} */const f = null;
/** @type {Function} */const g = () => void 0;
/** @type {function} */const h = () => void 0;
/** @type {array} */const i = [];
/** @type {promise} */const j = Promise.resolve(0);
/** @type {Object<string, string>} */const k = {x: "x"};
// these are not recognized as anything and should just be lookup failures
// ignore the errors to try to ensure they're emitted as `any` in declaration emit
// @ts-ignore
/** @type {class} */const l = true;
// @ts-ignore
/** @type {bool} */const m = true;
// @ts-ignore
/** @type {int} */const n = true;
// @ts-ignore
/** @type {float} */const o = true;
// @ts-ignore
/** @type {integer} */const p = true;
// or, in the case of `event` likely erroneously refers to the type of the global Event object
/** @type {event} */const q = undefined;