Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
188b9bb
use bigint for type flags
devanshj Dec 19, 2022
5540ad5
self-type-checking types
devanshj Dec 19, 2022
34c8a80
add `NeverWithError` and `Print` type constructs
devanshj Dec 19, 2022
c4d98c3
fix bad comment
devanshj Dec 27, 2022
78d74a9
add new tests
devanshj Jan 3, 2023
f3dc6f5
make minor changes to some tests
devanshj Jan 3, 2023
ff00503
accept new baselines
devanshj Jan 3, 2023
a41f15b
fix lint
devanshj Jan 3, 2023
ea6d257
remove debug logging
devanshj Jan 3, 2023
69b7959
resolve conflicts
devanshj Jan 3, 2023
389833b
fix code to accomodate #51682
devanshj Jan 3, 2023
0e38395
allow intrinsic keyword in new intrinsic types
devanshj Jan 3, 2023
c10528b
add self as a global keyword in fourslash
devanshj Jan 3, 2023
e3cff6b
add "self" to more places in fourslash
devanshj Jan 3, 2023
9c076aa
remove accidently added `Map` global in fourslash
devanshj Jan 4, 2023
afdc60e
remove a possibly false positive debug assertion
devanshj Jan 4, 2023
a1fb821
remove a todo as it got fixed after resolving conflicts
devanshj Jan 4, 2023
2ee5f95
accept new baseline for new tests after resolving conflict
devanshj Jan 4, 2023
a805ae9
create a new type construct "Selfed"
devanshj Jan 6, 2023
3e9e52e
accept baseline
devanshj Jan 6, 2023
bf8b3ab
fix completions order
devanshj Jan 6, 2023
90c9032
accept completions and other chore baseline
devanshj Jan 6, 2023
bc980f1
fix lint
devanshj Jan 6, 2023
8ffb161
fix external .d.ts
devanshj Jan 7, 2023
d3e64a5
recognise "self" as a type at missing places
devanshj Jan 7, 2023
8b0e980
accept completions baseline
devanshj Jan 7, 2023
0eef6df
accept external .d.ts baseline
devanshj Jan 7, 2023
9ecf8a8
make self instantiation more resilient
devanshj Jan 7, 2023
9815389
create an emit flag to not escape string literals
devanshj Jan 7, 2023
ecfa9ed
fix lint
devanshj Jan 7, 2023
303ea00
accept new public api baseline
devanshj Jan 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
use bigint for type flags
  • Loading branch information
devanshj committed Dec 19, 2022
commit 188b9bb3e6b1fb01452e2cafb6b9ce44df6c0fd7
2 changes: 1 addition & 1 deletion Herebyfile.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ function createBundler(entrypoint, outfile, taskOptions = {}) {
bundle: true,
outfile,
platform: "node",
target: "es2018",
target: "es2020",
format: "cjs",
sourcemap: "linked",
sourcesContent: false,
Expand Down
30 changes: 15 additions & 15 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9474,7 +9474,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {

function formatUnionTypes(types: readonly Type[]): Type[] {
const result: Type[] = [];
let flags = 0 as TypeFlags;
let flags = 0n as TypeFlags;
for (let i = 0; i < types.length; i++) {
const t = types[i];
flags |= t.flags;
Expand Down Expand Up @@ -9883,7 +9883,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}

function isTypeAny(type: Type | undefined) {
return type && (type.flags & TypeFlags.Any) !== 0;
return type && (type.flags & TypeFlags.Any) !== 0n;
}

function isErrorType(type: Type) {
Expand Down Expand Up @@ -15777,7 +15777,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
function addTypeToUnion(typeSet: Type[], includes: TypeFlags, type: Type) {
const flags = type.flags;
if (flags & TypeFlags.Union) {
return addTypesToUnion(typeSet, includes | (isNamedUnionType(type) ? TypeFlags.Union : 0), (type as UnionType).types);
return addTypesToUnion(typeSet, includes | (isNamedUnionType(type) ? TypeFlags.Union : 0n), (type as UnionType).types);
}
// We ignore 'never' types in unions
if (!(flags & TypeFlags.Never)) {
Expand Down Expand Up @@ -15945,7 +15945,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return types[0];
}
let typeSet: Type[] | undefined = [];
const includes = addTypesToUnion(typeSet, 0 as TypeFlags, types);
const includes = addTypesToUnion(typeSet, 0n as TypeFlags, types);
if (unionReduction !== UnionReduction.None) {
if (includes & TypeFlags.AnyOrUnknown) {
return includes & TypeFlags.Any ?
Expand Down Expand Up @@ -16260,7 +16260,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// for intersections of types with signatures can be deterministic.
function getIntersectionType(types: readonly Type[], aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[], noSupertypeReduction?: boolean): Type {
const typeMembershipMap: Map<string, Type> = new Map();
const includes = addTypesToIntersection(typeMembershipMap, 0 as TypeFlags, types);
const includes = addTypesToIntersection(typeMembershipMap, 0n as TypeFlags, types);
const typeSet: Type[] = arrayFrom(typeMembershipMap.values());
// An intersection type is considered empty if it contains
// the type never, or
Expand Down Expand Up @@ -16562,7 +16562,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
type === wildcardType ? wildcardType :
type.flags & TypeFlags.Unknown ? neverType :
type.flags & (TypeFlags.Any | TypeFlags.Never) ? keyofConstraintType :
getLiteralTypeFromProperties(type, (noIndexSignatures ? TypeFlags.StringLiteral : TypeFlags.StringLike) | (stringsOnly ? 0 : TypeFlags.NumberLike | TypeFlags.ESSymbolLike),
getLiteralTypeFromProperties(type, (noIndexSignatures ? TypeFlags.StringLiteral : TypeFlags.StringLike) | (stringsOnly ? 0n : TypeFlags.NumberLike | TypeFlags.ESSymbolLike),
stringsOnly === keyofStringsOnly && !noIndexSignatures);
}

Expand Down Expand Up @@ -22514,7 +22514,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}

function getCombinedTypeFlags(types: Type[]): TypeFlags {
return reduceLeft(types, (flags, t) => flags | (t.flags & TypeFlags.Union ? getCombinedTypeFlags((t as UnionType).types) : t.flags), 0);
return reduceLeft(types, (flags, t) => flags | (t.flags & TypeFlags.Union ? getCombinedTypeFlags((t as UnionType).types) : t.flags), 0n);
}

function getCommonSupertype(types: Type[]): Type {
Expand Down Expand Up @@ -22779,7 +22779,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
*/
function getNullableType(type: Type, flags: TypeFlags): Type {
const missing = (flags & ~type.flags) & (TypeFlags.Undefined | TypeFlags.Null);
return missing === 0 ? type :
return missing === 0n ? type :
missing === TypeFlags.Undefined ? getUnionType([type, undefinedType]) :
missing === TypeFlags.Null ? getUnionType([type, nullType]) :
getUnionType([type, undefinedType, nullType]);
Expand Down Expand Up @@ -22855,8 +22855,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
* @param target
*/
function isCoercibleUnderDoubleEquals(source: Type, target: Type): boolean {
return ((source.flags & (TypeFlags.Number | TypeFlags.String | TypeFlags.BooleanLiteral)) !== 0)
&& ((target.flags & (TypeFlags.Number | TypeFlags.String | TypeFlags.Boolean)) !== 0);
return ((source.flags & (TypeFlags.Number | TypeFlags.String | TypeFlags.BooleanLiteral)) !== 0n)
&& ((target.flags & (TypeFlags.Number | TypeFlags.String | TypeFlags.Boolean)) !== 0n);
}

/**
Expand Down Expand Up @@ -24205,7 +24205,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const constraint = inferenceContext ? getBaseConstraintOfType(inferenceContext.typeParameter) : undefined;
if (constraint && !isTypeAny(constraint)) {
const constraintTypes = constraint.flags & TypeFlags.Union ? (constraint as UnionType).types : [constraint];
let allTypeFlags: TypeFlags = reduceLeft(constraintTypes, (flags, t) => flags | t.flags, 0 as TypeFlags);
let allTypeFlags: TypeFlags = reduceLeft(constraintTypes, (flags, t) => flags | t.flags, 0n as TypeFlags);

// If the constraint contains `string`, we don't need to look for a more preferred type
if (!(allTypeFlags & TypeFlags.String)) {
Expand Down Expand Up @@ -25375,7 +25375,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}

function extractTypesOfKind(type: Type, kind: TypeFlags) {
return filterType(type, t => (t.flags & kind) !== 0);
return filterType(type, t => (t.flags & kind) !== 0n);
}

// Return a new type in which occurrences of the string, number and bigint primitives and placeholder template
Expand Down Expand Up @@ -27291,7 +27291,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// the entire control flow graph from the variable's declaration (i.e. when the flow container and
// declaration container are the same).
const assumeInitialized = isParameter || isAlias || isOuterVariable || isSpreadDestructuringAssignmentTarget || isModuleExports || isSameScopedBindingElement(node, declaration) ||
type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Void)) !== 0 ||
type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Void)) !== 0n ||
isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) ||
node.parent.kind === SyntaxKind.NonNullExpression ||
declaration.kind === SyntaxKind.VariableDeclaration && (declaration as VariableDeclaration).exclamationToken ||
Expand Down Expand Up @@ -33982,7 +33982,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {

function getNonArrayRestType(signature: Signature) {
const restType = getEffectiveRestType(signature);
return restType && !isArrayType(restType) && !isTypeAny(restType) && (getReducedType(restType).flags & TypeFlags.Never) === 0 ? restType : undefined;
return restType && !isArrayType(restType) && !isTypeAny(restType) && (getReducedType(restType).flags & TypeFlags.Never) === 0n ? restType : undefined;
}

function getTypeOfFirstParameterOfSignature(signature: Signature) {
Expand Down Expand Up @@ -35273,7 +35273,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}

function isTypeEqualityComparableTo(source: Type, target: Type) {
return (target.flags & TypeFlags.Nullable) !== 0 || isTypeComparableTo(source, target);
return (target.flags & TypeFlags.Nullable) !== 0n || isTypeComparableTo(source, target);
}

function createCheckBinaryExpression() {
Expand Down
1 change: 1 addition & 0 deletions src/compiler/debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,7 @@ export namespace Debug {
}

export function formatTypeFlags(flags: TypeFlags | undefined): string {
// @ts-ignore TODO
return formatEnum(flags, (ts as any).TypeFlags, /*isFlags*/ true);
}

Expand Down
2 changes: 1 addition & 1 deletion src/compiler/tracing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ export namespace tracingEnabled {

// It's slow to compute the display text, so skip it unless it's really valuable (or cheap)
let display: string | undefined;
if ((objectFlags & ObjectFlags.Anonymous) | (type.flags & TypeFlags.Literal)) {
if ((objectFlags & ObjectFlags.Anonymous) || (type.flags & TypeFlags.Literal)) {
try {
display = type.checker?.typeToString(type);
}
Expand Down
159 changes: 80 additions & 79 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5682,96 +5682,97 @@ export interface NodeLinks {
serializedTypes?: Map<string, TypeNode & {truncating?: boolean, addedLength: number}>; // Collection of types serialized at this location
}

export const enum TypeFlags {
Any = 1 << 0,
Unknown = 1 << 1,
String = 1 << 2,
Number = 1 << 3,
Boolean = 1 << 4,
Enum = 1 << 5, // Numeric computed enum member value
BigInt = 1 << 6,
StringLiteral = 1 << 7,
NumberLiteral = 1 << 8,
BooleanLiteral = 1 << 9,
EnumLiteral = 1 << 10, // Always combined with StringLiteral, NumberLiteral, or Union
BigIntLiteral = 1 << 11,
ESSymbol = 1 << 12, // Type of symbol primitive introduced in ES6
UniqueESSymbol = 1 << 13, // unique symbol
Void = 1 << 14,
Undefined = 1 << 15,
Null = 1 << 16,
Never = 1 << 17, // Never type
TypeParameter = 1 << 18, // Type parameter
Object = 1 << 19, // Object type
Union = 1 << 20, // Union (T | U)
Intersection = 1 << 21, // Intersection (T & U)
Index = 1 << 22, // keyof T
IndexedAccess = 1 << 23, // T[K]
Conditional = 1 << 24, // T extends U ? X : Y
Substitution = 1 << 25, // Type parameter substitution
NonPrimitive = 1 << 26, // intrinsic object type
TemplateLiteral = 1 << 27, // Template literal type
StringMapping = 1 << 28, // Uppercase/Lowercase type

/** @internal */
AnyOrUnknown = Any | Unknown,
/** @internal */
Nullable = Undefined | Null,
Literal = StringLiteral | NumberLiteral | BigIntLiteral | BooleanLiteral,
Unit = Literal | UniqueESSymbol | Nullable,
StringOrNumberLiteral = StringLiteral | NumberLiteral,
/** @internal */
StringOrNumberLiteralOrUnique = StringLiteral | NumberLiteral | UniqueESSymbol,
/** @internal */
DefinitelyFalsy = StringLiteral | NumberLiteral | BigIntLiteral | BooleanLiteral | Void | Undefined | Null,
PossiblyFalsy = DefinitelyFalsy | String | Number | BigInt | Boolean,
/** @internal */
Intrinsic = Any | Unknown | String | Number | BigInt | Boolean | BooleanLiteral | ESSymbol | Void | Undefined | Null | Never | NonPrimitive,
/** @internal */
Primitive = String | Number | BigInt | Boolean | Enum | EnumLiteral | ESSymbol | Void | Undefined | Null | Literal | UniqueESSymbol,
StringLike = String | StringLiteral | TemplateLiteral | StringMapping,
NumberLike = Number | NumberLiteral | Enum,
BigIntLike = BigInt | BigIntLiteral,
BooleanLike = Boolean | BooleanLiteral,
EnumLike = Enum | EnumLiteral,
ESSymbolLike = ESSymbol | UniqueESSymbol,
VoidLike = Void | Undefined,
/** @internal */
DefinitelyNonNullable = StringLike | NumberLike | BigIntLike | BooleanLike | EnumLike | ESSymbolLike | Object | NonPrimitive,
/** @internal */
DisjointDomains = NonPrimitive | StringLike | NumberLike | BigIntLike | BooleanLike | ESSymbolLike | VoidLike | Null,
UnionOrIntersection = Union | Intersection,
StructuredType = Object | Union | Intersection,
TypeVariable = TypeParameter | IndexedAccess,
InstantiableNonPrimitive = TypeVariable | Conditional | Substitution,
InstantiablePrimitive = Index | TemplateLiteral | StringMapping,
Instantiable = InstantiableNonPrimitive | InstantiablePrimitive,
StructuredOrInstantiable = StructuredType | Instantiable,
/** @internal */
ObjectFlagsType = Any | Nullable | Never | Object | Union | Intersection,
/** @internal */
Simplifiable = IndexedAccess | Conditional,
/** @internal */
Singleton = Any | Unknown | String | Number | Boolean | BigInt | ESSymbol | Void | Undefined | Null | Never | NonPrimitive,
export type TypeFlags = (typeof TypeFlags)[keyof typeof TypeFlags]
export const TypeFlags = new class TypeFlags {
Any = 1n << 0n
Unknown = 1n << 1n
String = 1n << 2n
Number = 1n << 3n
Boolean = 1n << 4n
Enum = 1n << 5n // Numeric computed enum member value
BigInt = 1n << 6n
StringLiteral = 1n << 7n
NumberLiteral = 1n << 8n
BooleanLiteral = 1n << 9n
EnumLiteral = 1n << 10n // Always combined with StringLiteral, NumberLiteral, or Union
BigIntLiteral = 1n << 11n
ESSymbol = 1n << 12n // Type of symbol primitive introduced in ES6
UniqueESSymbol = 1n << 13n // unique symbol
Void = 1n << 14n
Undefined = 1n << 15n
Null = 1n << 16n
Never = 1n << 17n // Never type
TypeParameter = 1n << 18n // Type parameter
Object = 1n << 19n // Object type
Union = 1n << 20n // Union (T | U)
Intersection = 1n << 21n // Intersection (T & U)
Index = 1n << 22n // keyof T
IndexedAccess = 1n << 23n // T[K]
Conditional = 1n << 24n // T extends U ? X : Y
Substitution = 1n << 25n // Type parameter substitution
NonPrimitive = 1n << 26n // intrinsic object type
TemplateLiteral = 1n << 27n // Template literal type
StringMapping = 1n << 28n // Uppercase/Lowercase type

/** @internal */
AnyOrUnknown = this.Any | this.Unknown
/** @internal */
Nullable = this.Undefined | this.Null
Literal = this.StringLiteral | this.NumberLiteral | this.BigIntLiteral | this.BooleanLiteral
Unit = this.Literal | this.UniqueESSymbol | this.Nullable
StringOrNumberLiteral = this.StringLiteral | this.NumberLiteral
/** @internal */
StringOrNumberLiteralOrUnique = this.StringLiteral | this.NumberLiteral | this.UniqueESSymbol
/** @internal */
DefinitelyFalsy = this.StringLiteral | this.NumberLiteral | this.BigIntLiteral | this.BooleanLiteral | this.Void | this.Undefined | this.Null
PossiblyFalsy = this.DefinitelyFalsy | this.String | this.Number | this.BigInt | this.Boolean
/** @internal */
Intrinsic = this.Any | this.Unknown | this.String | this.Number | this.BigInt | this.Boolean | this.BooleanLiteral | this.ESSymbol | this.Void | this.Undefined | this.Null | this.Never | this.NonPrimitive
/** @internal */
Primitive = this.String | this.Number | this.BigInt | this.Boolean | this.Enum | this.EnumLiteral | this.ESSymbol | this.Void | this.Undefined | this.Null | this.Literal | this.UniqueESSymbol
StringLike = this.String | this.StringLiteral | this.TemplateLiteral | this.StringMapping | this.Print
NumberLike = this.Number | this.NumberLiteral | this.Enum
BigIntLike = this.BigInt | this.BigIntLiteral
BooleanLike = this.Boolean | this.BooleanLiteral
EnumLike = this.Enum | this.EnumLiteral
ESSymbolLike = this.ESSymbol | this.UniqueESSymbol
VoidLike = this.Void | this.Undefined
/** @internal */
DefinitelyNonNullable = this.StringLike | this.NumberLike | this.BigIntLike | this.BooleanLike | this.EnumLike | this.ESSymbolLike | this.Object | this.NonPrimitive
/** @internal */
DisjointDomains = this.NonPrimitive | this.StringLike | this.NumberLike | this.BigIntLike | this.BooleanLike | this.ESSymbolLike | this.VoidLike | this.Null
UnionOrIntersection = this.Union | this.Intersection
StructuredType = this.Object | this.Union | this.Intersection
TypeVariable = this.TypeParameter | this.IndexedAccess
InstantiableNonPrimitive = this.TypeVariable | this.Conditional | this.Substitution | this.NeverWithError
InstantiablePrimitive = this.Index | this.TemplateLiteral | this.StringMapping | this.Print
Instantiable = this.InstantiableNonPrimitive | this.InstantiablePrimitive
StructuredOrInstantiable = this.StructuredType | this.Instantiable
/** @internal */
ObjectFlagsType = this.Any | this.Nullable | this.Never | this.Object | this.Union | this.Intersection
/** @internal */
Simplifiable = this.IndexedAccess | this.Conditional
/** @internal */
Singleton = this.Any | this.Unknown | this.String | this.Number | this.Boolean | this.BigInt | this.ESSymbol | this.Void | this.Undefined | this.Null | this.Never | this.NonPrimitive
// 'Narrowable' types are types where narrowing actually narrows.
// This *should* be every type other than null, undefined, void, and never
Narrowable = Any | Unknown | StructuredOrInstantiable | StringLike | NumberLike | BigIntLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive,
Narrowable = this.Any | this.Unknown | this.StructuredOrInstantiable | this.StringLike | this.NumberLike | this.BigIntLike | this.BooleanLike | this.ESSymbol | this.UniqueESSymbol | this.NonPrimitive
// The following flags are aggregated during union and intersection type construction
/** @internal */
IncludesMask = Any | Unknown | Primitive | Never | Object | Union | Intersection | NonPrimitive | TemplateLiteral,
IncludesMask = this.Any | this.Unknown | this.Primitive | this.Never | this.Object | this.Union | this.Intersection | this.NonPrimitive | this.TemplateLiteral
// The following flags are used for different purposes during union and intersection type construction
/** @internal */
IncludesMissingType = TypeParameter,
IncludesMissingType = this.TypeParameter
/** @internal */
IncludesNonWideningType = Index,
IncludesNonWideningType = this.Index
/** @internal */
IncludesWildcard = IndexedAccess,
IncludesWildcard = this.IndexedAccess
/** @internal */
IncludesEmptyObject = Conditional,
IncludesEmptyObject = this.Conditional
/** @internal */
IncludesInstantiable = Substitution,
IncludesInstantiable = this.Substitution
/** @internal */
NotPrimitiveUnion = Any | Unknown | Enum | Void | Never | Object | Intersection | IncludesInstantiable,
NotPrimitiveUnion = this.Any | this.Unknown | this.Enum | this.Void | this.Never | this.Object | this.Intersection | this.IncludesInstantiable
}

export type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression;
Expand Down
4 changes: 2 additions & 2 deletions src/tsconfig-base.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"outDir": "../built/local",

"pretty": true,
"lib": ["es2018"],
"target": "es2018",
"lib": ["es2020"],
"target": "es2020",
"module": "CommonJS",
"moduleResolution": "node",

Expand Down