From fe75250080390f3142a81da349a74899ee9aca69 Mon Sep 17 00:00:00 2001 From: leushkin Date: Sat, 2 May 2020 13:28:09 +0300 Subject: [PATCH 1/7] fix(typo): wrong symbol fix --- packages/docs/src/docs/docs/installation.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docs/src/docs/docs/installation.mdx b/packages/docs/src/docs/docs/installation.mdx index df298360..05417ea5 100644 --- a/packages/docs/src/docs/docs/installation.mdx +++ b/packages/docs/src/docs/docs/installation.mdx @@ -35,7 +35,7 @@ $ npm install -D @hegel/cli $ hegel No errors! -o locally +# locally $ npx hegel No errors! ``` From a6aac2f724492b2e3675639b1336af814dcac76e Mon Sep 17 00:00:00 2001 From: Anastasiya Lopatina Date: Sun, 3 May 2020 00:57:58 +0300 Subject: [PATCH 2/7] fix(Issue #195): replace HegelError property 'path' by 'source'. --- packages/core/src/type-graph/type-graph.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/type-graph/type-graph.js b/packages/core/src/type-graph/type-graph.js index 7cd30eb5..ce8e8e98 100644 --- a/packages/core/src/type-graph/type-graph.js +++ b/packages/core/src/type-graph/type-graph.js @@ -855,7 +855,7 @@ export async function createModuleScope( throw e; } if (Array.isArray(e)) { - errors.push(...e.map(e => Object.assign(e, { path: file.path }))); + errors.push(...e.map(e => Object.assign(e, { source: file.path }))); } else { e.source = file.path; errors.push(e); From c6955b53c3e5f9672d8d054b131407b437bd8f55 Mon Sep 17 00:00:00 2001 From: Artem Kobzar Date: Sun, 3 May 2020 20:49:52 +0300 Subject: [PATCH 3/7] fix(Issue #168): fix PromiseConstructor type definition. --- packages/core/src/inference/function-type.js | 16 ++++-- packages/core/src/type-graph/call.js | 50 +++++++++++-------- packages/core/src/type-graph/type-scope.js | 2 +- .../core/src/type-graph/types/bottom-type.js | 15 ++++-- packages/core/tests/preparation.js | 2 +- packages/core/tests/type-inference.test.js | 32 ++++++++++++ packages/typings/standard/index.d.ts | 2 +- 7 files changed, 89 insertions(+), 30 deletions(-) diff --git a/packages/core/src/inference/function-type.js b/packages/core/src/inference/function-type.js index c0fb3a9c..7a815664 100644 --- a/packages/core/src/inference/function-type.js +++ b/packages/core/src/inference/function-type.js @@ -388,7 +388,9 @@ function resolveOuterTypeVarsFromCall( actualType = Type.getTypeRoot(actualType, true); declaratedType = Type.getTypeRoot(declaratedType); // $FlowIssue - const difference = declaratedType.getDifference(actualType, true); + let difference = declaratedType.parent.priority > actualType.parent.priority + ? actualType.getDifference(declaratedType, true) + : declaratedType.getDifference(actualType, true); for (let j = 0; j < difference.length; j++) { let { root, variable } = difference[j]; if (TypeVar.isSelf(root)) { @@ -580,7 +582,7 @@ export function getRawFunctionType( fn.root = result; return result; } - const result = + let result = genericArguments != null ? // $FlowIssue fn.applyGeneric(genericArguments, loc, true, false, initializing) @@ -592,8 +594,14 @@ export function getRawFunctionType( withClean, dropUnknown ); + if (result instanceof $BottomType) { + result = result.unpack(); + } + if (result instanceof $BottomType) { + result = result.subordinateMagicType; + } if (result instanceof GenericType) { - return result.subordinateType; + result = result.subordinateType; } return result; } @@ -707,7 +715,7 @@ export function inferenceFunctionTypeByScope( continue; } const oldRoot = Type.getTypeRoot(returnType); - if (returnType.root === undefined) { + if (returnType.root === undefined || newOneRoot.isPrincipalTypeFor(oldRoot)) { returnType.root = newOneRoot; } else if (!oldRoot.isPrincipalTypeFor(newOneRoot)) { const variants: any = (oldRoot instanceof UnionType diff --git a/packages/core/src/type-graph/call.js b/packages/core/src/type-graph/call.js index 45a1b158..bdcd656c 100644 --- a/packages/core/src/type-graph/call.js +++ b/packages/core/src/type-graph/call.js @@ -786,14 +786,40 @@ export function addCallToTypeGraph( targetType = /*::target.type !== undefined ?*/ target.type /*:: : targetType*/; } - let fnType = - targetType instanceof GenericType - ? targetType.subordinateType - : targetType; + genericArguments = + node.typeArguments && + node.typeArguments.params.map(arg => + getTypeFromTypeAnnotation( + { typeAnnotation: arg }, + typeScope, + currentScope, + false, + null, + parentNode, + moduleScope, + pre, + middle, + post + ) + ); const localTypeScope = targetType instanceof GenericType ? targetType.localTypeScope : typeScope; + if (targetType instanceof GenericType && genericArguments != null) { + targetType = getRawFunctionType( + // $FlowIssue + targetType, + [], + genericArguments, + localTypeScope, + node.loc + ); + } + let fnType = + targetType instanceof GenericType + ? targetType.subordinateType + : targetType; if ( fnType != undefined && !(fnType instanceof FunctionType) && @@ -826,22 +852,6 @@ export function addCallToTypeGraph( { ...meta, isImmutable: defaultArg instanceof $AppliedImmutable } ).result; }); - genericArguments = - node.typeArguments && - node.typeArguments.params.map(arg => - getTypeFromTypeAnnotation( - { typeAnnotation: arg }, - typeScope, - currentScope, - false, - null, - parentNode, - moduleScope, - pre, - middle, - post - ) - ); targetType.asNotUserDefined(); args = node.arguments.map((n, i) => { if ( diff --git a/packages/core/src/type-graph/type-scope.js b/packages/core/src/type-graph/type-scope.js index 10cf3526..6fec4613 100644 --- a/packages/core/src/type-graph/type-scope.js +++ b/packages/core/src/type-graph/type-scope.js @@ -7,7 +7,7 @@ import type { Node, TSInterfaceDeclaration } from "@babel/core"; export class TypeScope { static GLOBAL_SCOPE_PRIORITY = 0; - static MODULE_SCOPE_PRIORITY = 0; + static MODULE_SCOPE_PRIORITY = 1; priority: number; parent: TypeScope | null; diff --git a/packages/core/src/type-graph/types/bottom-type.js b/packages/core/src/type-graph/types/bottom-type.js index d71ad22a..d6cbce65 100644 --- a/packages/core/src/type-graph/types/bottom-type.js +++ b/packages/core/src/type-graph/types/bottom-type.js @@ -167,10 +167,19 @@ export class $BottomType extends Type { ? Type.getTypeRoot(this.subordinateMagicType) : this.subordinateMagicType; if ("subordinateType" in target) { + const parameters = this.genericArguments.map( + t => { + if (t instanceof $BottomType) { + t = t.unpack(); + } + if (t instanceof TypeVar && t.root !== undefined) { + t = Type.getTypeRoot(t); + } + return t; + } + ); return target.applyGeneric( - this.genericArguments.map( - a => (a instanceof TypeVar && a.root != undefined ? a.root : a) - ), + parameters, this.loc, true, true, diff --git a/packages/core/tests/preparation.js b/packages/core/tests/preparation.js index 495b7f7e..dbc53135 100644 --- a/packages/core/tests/preparation.js +++ b/packages/core/tests/preparation.js @@ -5,7 +5,7 @@ const { createModuleScope } = require("../build/type-graph/type-graph"); const babelrc = { sourceType: "module", - plugins: ["flow", "bigInt", "classProperties"] + plugins: [["flow", { all: true }], "bigInt", "classProperties"] }; const definitionsRc = { diff --git a/packages/core/tests/type-inference.test.js b/packages/core/tests/type-inference.test.js index b7c87615..2eae483c 100644 --- a/packages/core/tests/type-inference.test.js +++ b/packages/core/tests/type-inference.test.js @@ -3220,4 +3220,36 @@ describe("Issues", () => { expect(errors.length).toBe(0); expect(age.type === Type.Number).toBe(true); }); + test("Issue #168: PromiseConsructor should conatain constructor", async () => { + const sourceAST = prepareAST(` + const p = new Promise<2>(resolve => { + resolve(2); + }); + `); + const [[module], errors] = await createTypeGraph( + [sourceAST], + getModuleAST, + false, + mixTypeDefinitions() + ); + const p = module.body.get("p"); + expect(errors.length).toBe(0); + expect(p.type === Type.find("Promise<2>")).toBe(true); + }); + test("Issue #168: PromiseConsructor should conatain constructor and right type inferene", async () => { + const sourceAST = prepareAST(` + const p = new Promise(resolve => { + resolve(2); + }); + `); + const [[module], errors] = await createTypeGraph( + [sourceAST], + getModuleAST, + false, + mixTypeDefinitions() + ); + const p = module.body.get("p"); + expect(errors.length).toBe(0); + expect(p.type === Type.find("Promise<2>")).toBe(true); + }); }); diff --git a/packages/typings/standard/index.d.ts b/packages/typings/standard/index.d.ts index a1e8b859..cb6e75da 100644 --- a/packages/typings/standard/index.d.ts +++ b/packages/typings/standard/index.d.ts @@ -1694,7 +1694,7 @@ interface PromiseConstructor { * a resolve callback used to resolve the promise with a value or the result of another promise, * and a reject callback used to reject the promise with a provided reason or error. */ - ( + new( executor: ( resolve: (value?: T | PromiseLike) => void, reject: (reason?: any) => void From 25b671a3f800182edc47e0234b07f8fc85591701 Mon Sep 17 00:00:00 2001 From: Artem Kobzar Date: Mon, 4 May 2020 16:55:50 +0300 Subject: [PATCH 4/7] fix($BottomType unpacking): unpack bottomed function. --- packages/core/src/inference/function-type.js | 4 +- packages/core/src/inference/refinement.js | 8 +-- .../core/src/type-graph/types/bottom-type.js | 11 ++-- .../src/type-graph/types/collection-type.js | 2 +- .../src/type-graph/types/immutable-type.js | 4 ++ .../core/src/type-graph/types/keys-type.js | 2 +- .../core/src/type-graph/types/partial-type.js | 2 +- .../src/type-graph/types/property-type.js | 4 +- packages/core/src/type-graph/types/type.js | 3 + .../core/src/type-graph/types/union-type.js | 60 ++++++++++++------- .../core/src/type-graph/types/values-type.js | 2 +- packages/core/tests/type-graph.test.js | 2 +- packages/core/tests/type-inference.test.js | 6 +- packages/typings/standard/index.d.ts | 21 ++----- 14 files changed, 70 insertions(+), 61 deletions(-) diff --git a/packages/core/src/inference/function-type.js b/packages/core/src/inference/function-type.js index 7a815664..0aea415a 100644 --- a/packages/core/src/inference/function-type.js +++ b/packages/core/src/inference/function-type.js @@ -515,7 +515,7 @@ export function implicitApplyGeneric( resultType === t && resultType.defaultType !== undefined ) { - return resultType.defaultType; + return rootFinder(resultType.defaultType) || Type.getTypeRoot(resultType.defaultType); } return resultType; }); @@ -601,7 +601,7 @@ export function getRawFunctionType( result = result.subordinateMagicType; } if (result instanceof GenericType) { - result = result.subordinateType; + result = result.subordinateType; } return result; } diff --git a/packages/core/src/inference/refinement.js b/packages/core/src/inference/refinement.js index d0b882d6..61a2a8de 100644 --- a/packages/core/src/inference/refinement.js +++ b/packages/core/src/inference/refinement.js @@ -198,7 +198,7 @@ function intersectionOfTypes( (a, b) => a.equalsTo(b) )[0]; return UnionType.term( - UnionType.getName(intersectedVariants), + null, {}, intersectedVariants ); @@ -219,7 +219,7 @@ function unionOfTypes(type1: Type, type2: Type, typeScope: TypeScope): Type { const unionVariants = union(type1.variants, type2.variants, (a, b) => a.equalsTo(b) ); - return UnionType.term(UnionType.getName(unionVariants), {}, unionVariants); + return UnionType.term(null, {}, unionVariants); } if (type1 instanceof UnionType || type2 instanceof UnionType) { const [unionType, notUnion]: [Type, Type] = @@ -230,7 +230,7 @@ function unionOfTypes(type1: Type, type2: Type, typeScope: TypeScope): Type { [notUnion], (a, b) => a.equalsTo(b) ); - return UnionType.term(UnionType.getName(newVariants), {}, newVariants); + return UnionType.term(null, {}, newVariants); } if (type1.isPrincipalTypeFor(type2)) { return type1; @@ -239,7 +239,7 @@ function unionOfTypes(type1: Type, type2: Type, typeScope: TypeScope): Type { return type2; } const variants = [type1, type2]; - return UnionType.term(UnionType.getName(variants), {}, variants); + return UnionType.term(null, {}, variants); } function getRefinementByBinaryExpression( diff --git a/packages/core/src/type-graph/types/bottom-type.js b/packages/core/src/type-graph/types/bottom-type.js index d6cbce65..7ffcad5e 100644 --- a/packages/core/src/type-graph/types/bottom-type.js +++ b/packages/core/src/type-graph/types/bottom-type.js @@ -1,6 +1,7 @@ import { Type } from "./type"; import { TypeVar } from "./type-var"; import { UnionType } from "./union-type"; +import { TypeScope } from "../type-scope"; import { FunctionType } from "./function-type"; export class $BottomType extends Type { @@ -106,12 +107,10 @@ export class $BottomType extends Type { } if (argument instanceof UnionType) { const newType = argument.changeAll(sourceTypes, targetTypes, typeScope); - const result = argument.variants - .map(mapper) - .filter(a => a !== undefined); - return result.length > 1 && newType.parent.priority <= 1 - ? newType - : result[0]; + if (newType.parent.priority > TypeScope. MODULE_SCOPE_PRIORITY) { + includedTypeVar = true; + } + return newType; } return argument; }; diff --git a/packages/core/src/type-graph/types/collection-type.js b/packages/core/src/type-graph/types/collection-type.js index 2e369b62..bf546df6 100644 --- a/packages/core/src/type-graph/types/collection-type.js +++ b/packages/core/src/type-graph/types/collection-type.js @@ -67,7 +67,7 @@ export class CollectionType extends Type { this.valueType.variants.some(a => a.equalsTo(Type.Undefined)) ? this.valueType : UnionType.term( - UnionType.getName([this.valueType, Type.Undefined]), + null, {}, [this.valueType, Type.Undefined] ); diff --git a/packages/core/src/type-graph/types/immutable-type.js b/packages/core/src/type-graph/types/immutable-type.js index d6c151c1..3434e630 100644 --- a/packages/core/src/type-graph/types/immutable-type.js +++ b/packages/core/src/type-graph/types/immutable-type.js @@ -80,6 +80,10 @@ export class $AppliedImmutable extends Type { weakContains(type) { return this.readonly.contains(type); } + + getDifference(type: Type, withReverseUnion?: boolean = false) { + return this.readonly.getDifference(type, withReverseUnion); + } changeAll(...args) { const changed = this.readonly.changeAll(...args); diff --git a/packages/core/src/type-graph/types/keys-type.js b/packages/core/src/type-graph/types/keys-type.js index 6cf5b26d..6438281a 100644 --- a/packages/core/src/type-graph/types/keys-type.js +++ b/packages/core/src/type-graph/types/keys-type.js @@ -69,6 +69,6 @@ export class $Keys extends GenericType { variants.push(Type.term(`'${property}'`, { isSubtypeOf: Type.String })); } } - return UnionType.term(UnionType.getName(variants), {}, variants); + return UnionType.term(null, {}, variants); } } diff --git a/packages/core/src/type-graph/types/partial-type.js b/packages/core/src/type-graph/types/partial-type.js index 7a6fb0f2..55ee4a0f 100644 --- a/packages/core/src/type-graph/types/partial-type.js +++ b/packages/core/src/type-graph/types/partial-type.js @@ -52,7 +52,7 @@ export class $Partial extends GenericType { ? property.type.variants : [property.type]) ]; - const newType = UnionType.term(UnionType.getName(variants), {}, variants); + const newType = UnionType.term(null, {}, variants); return [name, new VariableInfo(newType, property.parent, property.meta)]; }); return ObjectType.term( diff --git a/packages/core/src/type-graph/types/property-type.js b/packages/core/src/type-graph/types/property-type.js index 3aebfb52..81dd5585 100644 --- a/packages/core/src/type-graph/types/property-type.js +++ b/packages/core/src/type-graph/types/property-type.js @@ -158,7 +158,7 @@ export class $PropertyType extends GenericType { isCalledAsBottom ) ); - return UnionType.term(UnionType.getName(variants), {}, variants); + return UnionType.term(null, {}, variants); } catch { throw new HegelError( `Property "${propertyName}" does not exist in "${ @@ -178,7 +178,7 @@ export class $PropertyType extends GenericType { isCalledAsBottom ) ); - return UnionType.term(UnionType.getName(variants), {}, variants); + return UnionType.term(null, {}, variants); } catch { throw new HegelError( `Property "${propertyName}" does not exist in "${ diff --git a/packages/core/src/type-graph/types/type.js b/packages/core/src/type-graph/types/type.js index fc5c4fef..aeaef6b2 100644 --- a/packages/core/src/type-graph/types/type.js +++ b/packages/core/src/type-graph/types/type.js @@ -192,6 +192,9 @@ export class Type { if (this.referenceEqualsTo(type)) { return []; } + if ("readonly" in type) { + type = type.readonly; + } if ("variants" in type) { // $FlowIssue const variants = [...type.variants].sort( diff --git a/packages/core/src/type-graph/types/union-type.js b/packages/core/src/type-graph/types/union-type.js index 2a585fcc..b1d4c76b 100644 --- a/packages/core/src/type-graph/types/union-type.js +++ b/packages/core/src/type-graph/types/union-type.js @@ -1,9 +1,9 @@ // @flow import { Type } from "./type"; -import { unique } from "../../utils/common"; import { TypeVar } from "./type-var"; import type { TypeMeta } from "./type"; import type { TypeScope } from "../type-scope"; +import type { $BottomType } from "./bottom-type"; // $FlowIssue export class UnionType extends Type { @@ -18,9 +18,9 @@ export class UnionType extends Type { ...args: Array ) { variants = UnionType.flatten(variants); - const principalTypeInside = UnionType.getPrincipalTypeInside(variants); - if (principalTypeInside !== undefined) { - return principalTypeInside; + variants = UnionType.rollup(variants); + if (variants.length === 1) { + return variants[0]; } name = name == null ? UnionType.getName(variants) : name; let parent: TypeScope | void = meta.parent; @@ -38,18 +38,7 @@ export class UnionType extends Type { return super.term(name, newMeta, variants, ...args); } - static getPrincipalTypeInside(variants: any) { - return variants.length === 1 - ? variants[0] - : variants.find( - variant => - !(variant instanceof TypeVar) && - variants.every(subVariant => variant.equalsTo(subVariant)) - ); - } - static getName(params: Array) { - params = unique(params.map(a => Type.getTypeRoot(a)), a => String(a.name)); const isMultyLine = this.prettyMode && params.length >= 4; return `${params .sort((t1, t2) => String(t1.name).localeCompare(String(t2.name))) @@ -82,21 +71,50 @@ export class UnionType extends Type { variant => variant instanceof UnionType ? this.flatten(variant.variants) - : [variant] + : [Type.getTypeRoot(variant)] ); } + static shouldBeSkipped(variant: $BottomType | Type) { + return "subordinateMagicType" in variant || variant instanceof TypeVar || variant === Type.Unknown; + } + + static uniqueVariants(set: Array) { + const unique: Array = []; + for (let i = 0; i < set.length; i++) { + const currentType = set[i]; + if ( + this.shouldBeSkipped(currentType) || + !unique.some( + existed => + !this.shouldBeSkipped(existed) && + existed.isPrincipalTypeFor(currentType) + ) + ) { + unique.push(currentType); + } + } + return unique; + } + + static rollup(variants: any) { + return variants.length === 1 + ? [variants[0]] + : this.uniqueVariants(variants); + } + + variants: Array; constructor(name: ?string, meta?: TypeMeta = {}, variants: Array) { variants = UnionType.flatten(variants); + variants = UnionType.rollup(variants); + if (variants.length === 1) { + return variants[0]; + } name = name == null ? UnionType.getName(variants) : name; super(name, meta); - const principalTypeInside = UnionType.getPrincipalTypeInside(variants); - if (principalTypeInside) { - return principalTypeInside; - } - this.variants = unique(variants, a => String(a.name)).sort((t1, t2) => + this.variants = variants.sort((t1, t2) => String(t1.name).localeCompare(String(t2.name)) ); } diff --git a/packages/core/src/type-graph/types/values-type.js b/packages/core/src/type-graph/types/values-type.js index bfc5e0a2..efa61c24 100644 --- a/packages/core/src/type-graph/types/values-type.js +++ b/packages/core/src/type-graph/types/values-type.js @@ -54,6 +54,6 @@ export class $Values extends GenericType { } const values = [...realTarget.properties.values()]; const variants = values.map(value => value.type); - return UnionType.term(UnionType.getName(variants), {}, variants); + return UnionType.term(null, {}, variants); } } diff --git a/packages/core/tests/type-graph.test.js b/packages/core/tests/type-graph.test.js index 73520dd5..28d0bc98 100644 --- a/packages/core/tests/type-graph.test.js +++ b/packages/core/tests/type-graph.test.js @@ -1289,7 +1289,7 @@ describe("Classes", () => { expect(errors.length).toEqual(0); expect(b).not.toBe(undefined); expect(b.type).toBeInstanceOf(CollectionType); - expect(b.type === Type.find("Array")).toBe(true); + expect(b.type === Type.find("$Immutable>")).toBe(true); }); }); describe("Promises", () => { diff --git a/packages/core/tests/type-inference.test.js b/packages/core/tests/type-inference.test.js index 2eae483c..bee7a208 100644 --- a/packages/core/tests/type-inference.test.js +++ b/packages/core/tests/type-inference.test.js @@ -2795,11 +2795,7 @@ describe("Type refinement", () => { expect(a.type.variants.length).toBe(2); expect(a.type.variants[0] === Type.Null).toBe(true); expect(a.type.variants[1] === Type.Number).toBe(true); - expect(b.type).toBeInstanceOf(UnionType); - expect(b.type === Type.find("4 | number")).toBe(true); - expect(b.type.variants.length).toBe(2); - expect(b.type.variants[0] === Type.find(4)).toBe(true); - expect(b.type.variants[1] === Type.Number).toBe(true); + expect(b.type === Type.Number).toBe(true); }); test("Typeof refinement for property in nested member expression", async () => { const sourceAST = prepareAST(` diff --git a/packages/typings/standard/index.d.ts b/packages/typings/standard/index.d.ts index cb6e75da..c01be421 100644 --- a/packages/typings/standard/index.d.ts +++ b/packages/typings/standard/index.d.ts @@ -154,13 +154,8 @@ interface Array { // * Combines two or more arrays. // * @param items Additional items to add to the end of array1. // */ -// concat(...items: Array>): Array; - // /** - // * Combines two or more arrays. - // * @param items Additional items to add to the end of array1. - // */ -// concat(...items: Array): Array; - concat(...items: Array): T[]; + concat(...items: Array | Array>): Array; +// concat(...items: Array): T[]; // /** // * Adds all the elements of an array separated by the specified separator string. // * @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma. @@ -349,13 +344,7 @@ interface ReadonlyArray { // * Combines two or more arrays. // * @param items Additional items to add to the end of array1. // */ -// concat(...items: Array>): ReadonlyArray; - // /** - // * Combines two or more arrays. - // * @param items Additional items to add to the end of array1. - // */ -// concat(...items: Array): ReadonlyArray; - concat(...items: Array>): T[]; + concat(...items: Array | Array> | Array>): ReadonlyArray; // * Adds all the elements of an array separated by the specified separator string. // * @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma. // */ @@ -1651,7 +1640,7 @@ interface PromiseLike { // * @param onrejected The callback to execute when the Promise is rejected. // * @returns A Promise for the completion of which ever callback is executed. // */ - then( + then( onfulfilled?: (value: T) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike ): PromiseLike; @@ -1667,7 +1656,7 @@ interface Promise { // * @param onrejected The callback to execute when the Promise is rejected. // * @returns A Promise for the completion of which ever callback is executed. // */ - then( + then( onfulfilled?: (value: T) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike ): Promise; From 8e6f499b6d88d0cb491696967acae53d8f9ac486 Mon Sep 17 00:00:00 2001 From: Artem Kobzar Date: Mon, 4 May 2020 17:01:24 +0300 Subject: [PATCH 5/7] fix(Issue #101): add test for fixed bottomized function. --- packages/core/tests/type-graph.test.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/core/tests/type-graph.test.js b/packages/core/tests/type-graph.test.js index 28d0bc98..61d52051 100644 --- a/packages/core/tests/type-graph.test.js +++ b/packages/core/tests/type-graph.test.js @@ -1539,6 +1539,22 @@ describe("Issues", () => { expect(errors.length).toBe(0); }); + + test("Issue #101: WeakMap should normaly inferenced", async () => { + const sourceAST = prepareAST(` + const map = new WeakMap() + const result = map.has({}); + `); + const [[module], errors] = await createTypeGraph( + [sourceAST], + getModuleAST, + false, + mixTypeDefinitions() + ); + + expect(errors.length).toBe(0); + expect(module.body.get("result").type === Type.Boolean).toBe(true); + }); test("Issue #153: type interence for symbol without errors", async () => { const sourceAST = prepareAST(` From c5c061602c10e60b9c5eb5fdc66bd153daeb2eb5 Mon Sep 17 00:00:00 2001 From: Artem Kobzar Date: Mon, 4 May 2020 17:13:04 +0300 Subject: [PATCH 6/7] test(Issue #101): add test for function calculations. --- packages/core/tests/type-inference.test.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/core/tests/type-inference.test.js b/packages/core/tests/type-inference.test.js index bee7a208..636aacf0 100644 --- a/packages/core/tests/type-inference.test.js +++ b/packages/core/tests/type-inference.test.js @@ -3198,6 +3198,22 @@ describe("Issues", () => { } }); }); + test("Issue #101: function calculation should be inferenced right", async () => { + const sourceAST = prepareAST(` + const id = x => x + const fst = a => b => a + const snd = fst(id) + const num: 1 = fst(1)('1') + const str: '2' = snd(1)('2') + `); + const [[], errors] = await createTypeGraph( + [sourceAST], + getModuleAST, + false, + mixTypeDefinitions() + ); + expect(errors.length).toBe(0); + }); test("Issue #115: inference property type without error", async () => { const sourceAST = prepareAST(` function prop(a, b) { From 96e3b7d0e92132c487dfecd12c046df6261d6a83 Mon Sep 17 00:00:00 2001 From: Artem Kobzar Date: Mon, 4 May 2020 21:50:56 +0300 Subject: [PATCH 7/7] fix(Issue #162): change logic of scoping for loops. --- packages/core/src/utils/traverse.js | 27 ++++++++++++-------------- packages/core/tests/type-graph.test.js | 16 +++++++++++++++ 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/packages/core/src/utils/traverse.js b/packages/core/src/utils/traverse.js index 06f666ed..cb2734d7 100644 --- a/packages/core/src/utils/traverse.js +++ b/packages/core/src/utils/traverse.js @@ -168,28 +168,25 @@ function mixBlockToCaseStatement(currentNode: Node) { return currentNode; } -function mixDeclarationsInideForBlock(currentNode: Node) { +function mixDeclarationsInideForBlock(currentNode: Node, parentNode: Node) { if ( - currentNode.type !== NODE.FOR_IN_STATEMENT && + (currentNode.type !== NODE.FOR_IN_STATEMENT && currentNode.type !== NODE.FOR_OF_STATEMENT && - (currentNode.type !== NODE.FOR_STATEMENT || currentNode.init === null) + (currentNode.type !== NODE.FOR_STATEMENT || currentNode.init === null)) || + parentNode.isCustom ) { return currentNode; } - if (currentNode.body.type === NODE.EMPTY_STATEMENT) { - currentNode.body = { + const init = currentNode.init || { + ...currentNode.left, + init: getInitFor(currentNode) + }; + return { type: NODE.BLOCK_STATEMENT, - body: [], + body: [init, currentNode], + isCustom: true, loc: currentNode.init.loc - }; - } - currentNode.body.body.unshift( - currentNode.init || { - ...currentNode.left, - init: getInitFor(currentNode) - } - ); - return currentNode; + }; } function mixExportInfo(currentNode: Node) { diff --git a/packages/core/tests/type-graph.test.js b/packages/core/tests/type-graph.test.js index 61d52051..5511cf66 100644 --- a/packages/core/tests/type-graph.test.js +++ b/packages/core/tests/type-graph.test.js @@ -1589,6 +1589,22 @@ describe("Issues", () => { expect(errors.length).toBe(0); }); + + test("Issue #162: right scoping for 'for-loop'", async () => { + const sourceAST = prepareAST(` + for (let i = 10; i > 0; i--) {} + for (let i = 10; i > 0; i--) {} + for (let i = "10"; i != "1";i += "") {} + `); + const [, errors] = await createTypeGraph( + [sourceAST], + getModuleAST, + false, + mixTypeDefinitions() + ); + + expect(errors.length).toBe(0); + }); test("Issue #177: Union of the boolean literals should be a subtype of boolean", async () => { const sourceAST = prepareAST(`