Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Numeric literals assignable to enum literals only when values match #51561

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Nov 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
33 changes: 18 additions & 15 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ export const enum CheckMode {

/** @internal */
export const enum SignatureCheckMode {
None = 0,
BivariantCallback = 1 << 0,
StrictCallback = 1 << 1,
IgnoreReturnTypes = 1 << 2,
Expand Down Expand Up @@ -476,7 +477,7 @@ function SymbolLinks(this: SymbolLinks) {
}

function NodeLinks(this: NodeLinks) {
this.flags = 0;
this.flags = NodeCheckFlags.None;
}

/** @internal */
Expand Down Expand Up @@ -1473,7 +1474,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
function createSymbol(flags: SymbolFlags, name: __String, checkFlags?: CheckFlags) {
symbolCount++;
const symbol = (new Symbol(flags | SymbolFlags.Transient, name) as TransientSymbol);
symbol.checkFlags = checkFlags || 0;
symbol.checkFlags = checkFlags || CheckFlags.None;
return symbol;
}

Expand Down Expand Up @@ -4543,7 +4544,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return new Type(checker, flags);
}

function createIntrinsicType(kind: TypeFlags, intrinsicName: string, objectFlags: ObjectFlags = 0): IntrinsicType {
function createIntrinsicType(kind: TypeFlags, intrinsicName: string, objectFlags = ObjectFlags.None): IntrinsicType {
const type = createType(kind) as IntrinsicType;
type.intrinsicName = intrinsicName;
type.objectFlags = objectFlags;
Expand Down Expand Up @@ -8659,7 +8660,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {

function formatUnionTypes(types: readonly Type[]): Type[] {
const result: Type[] = [];
let flags: TypeFlags = 0;
let flags = 0 as TypeFlags;
Copy link
Member

@RyanCavanaugh RyanCavanaugh Nov 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding TypeFlags.Uninitialized = 0 ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be an alternative. But I prefer 0 as TypeFlags as an indicator this isn't actually a permitted value.

for (let i = 0; i < types.length; i++) {
const t = types[i];
flags |= t.flags;
Expand Down Expand Up @@ -14750,7 +14751,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const minLength = countWhere(elementFlags, f => !!(f & (ElementFlags.Required | ElementFlags.Variadic)));
let typeParameters: TypeParameter[] | undefined;
const properties: Symbol[] = [];
let combinedFlags: ElementFlags = 0;
let combinedFlags = 0 as ElementFlags;
if (arity) {
typeParameters = new Array(arity);
for (let i = 0; i < arity; i++) {
Expand Down Expand Up @@ -15114,7 +15115,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return types[0];
}
let typeSet: Type[] | undefined = [];
const includes = addTypesToUnion(typeSet, 0, types);
const includes = addTypesToUnion(typeSet, 0 as TypeFlags, types);
if (unionReduction !== UnionReduction.None) {
if (includes & TypeFlags.AnyOrUnknown) {
return includes & TypeFlags.Any ?
Expand Down Expand Up @@ -15429,7 +15430,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, types);
const includes = addTypesToIntersection(typeMembershipMap, 0 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 @@ -18441,7 +18442,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
function isSignatureAssignableTo(source: Signature,
target: Signature,
ignoreReturnTypes: boolean): boolean {
return compareSignaturesRelated(source, target, ignoreReturnTypes ? SignatureCheckMode.IgnoreReturnTypes : 0, /*reportErrors*/ false,
return compareSignaturesRelated(source, target, ignoreReturnTypes ? SignatureCheckMode.IgnoreReturnTypes : SignatureCheckMode.None, /*reportErrors*/ false,
/*errorReporter*/ undefined, /*errorReporter*/ undefined, compareTypesAssignable, /*reportUnreliableMarkers*/ undefined) !== Ternary.False;
}

Expand Down Expand Up @@ -18757,11 +18758,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (s & TypeFlags.Object && t & TypeFlags.NonPrimitive && !(relation === strictSubtypeRelation && isEmptyAnonymousObjectType(source) && !(getObjectFlags(source) & ObjectFlags.FreshLiteral))) return true;
if (relation === assignableRelation || relation === comparableRelation) {
if (s & TypeFlags.Any) return true;
// Type number or any numeric literal type is assignable to any numeric enum type or any
// numeric enum literal type. This rule exists for backwards compatibility reasons because
// bit-flag enum types sometimes look like literal enum types with numeric literal values.
if (s & (TypeFlags.Number | TypeFlags.NumberLiteral) && !(s & TypeFlags.EnumLiteral) && (
t & TypeFlags.Enum || relation === assignableRelation && t & TypeFlags.NumberLiteral && t & TypeFlags.EnumLiteral)) return true;
// Type number is assignable to any computed numeric enum type or any numeric enum literal type, and
// a numeric literal type is assignable any computed numeric enum type or any numeric enum literal type
// with a matching value. These rules exist such that enums can be used for bit-flag purposes.
if (s & TypeFlags.Number && (t & TypeFlags.Enum || t & TypeFlags.NumberLiteral && t & TypeFlags.EnumLiteral)) return true;
if (s & TypeFlags.NumberLiteral && !(s & TypeFlags.EnumLiteral) && (t & TypeFlags.Enum ||
t & TypeFlags.NumberLiteral && t & TypeFlags.EnumLiteral &&
(source as NumberLiteralType).value === (target as NumberLiteralType).value)) return true;
// Anything is assignable to a union containing undefined, null, and {}
if (isUnknownLikeUnionType(target)) return true;
}
Expand Down Expand Up @@ -19745,7 +19748,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (!(expandingFlags & ExpandingFlags.Target) && isDeeplyNestedType(target, targetStack, targetDepth)) expandingFlags |= ExpandingFlags.Target;
}
let originalHandler: typeof outofbandVarianceMarkerHandler;
let propagatingVarianceFlags: RelationComparisonResult = 0;
let propagatingVarianceFlags = 0 as RelationComparisonResult;
if (outofbandVarianceMarkerHandler) {
originalHandler = outofbandVarianceMarkerHandler;
outofbandVarianceMarkerHandler = onlyUnreliable => {
Expand Down Expand Up @@ -22863,7 +22866,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}

function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0, contravariant = false) {
function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority = InferencePriority.None, contravariant = false) {
let bivariant = false;
let propagationType: Type;
let inferencePriority: number = InferencePriority.MaxValue;
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/transformers/es2015.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ interface LoopOutParameter {
}

const enum LoopOutParameterFlags {
None = 0,
Body = 1 << 0, // Modified in the body of the iteration statement
Initializer = 1 << 1, // Set in the initializer of a ForStatement
}
Expand Down Expand Up @@ -3488,7 +3489,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
const checkFlags = resolver.getNodeCheckFlags(decl);
if (checkFlags & NodeCheckFlags.NeedsLoopOutParameter || hasCapturedBindingsInForHead) {
const outParamName = factory.createUniqueName("out_" + idText(name));
let flags: LoopOutParameterFlags = 0;
let flags = LoopOutParameterFlags.None;
if (checkFlags & NodeCheckFlags.NeedsLoopOutParameter) {
flags |= LoopOutParameterFlags.Body;
}
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/transformers/es2017.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const enum ES2017SubstitutionFlags {
}

const enum ContextFlags {
None = 0,
NonTopLevel = 1 << 0,
HasLexicalThis = 1 << 1
}
Expand Down Expand Up @@ -66,7 +67,7 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
/** A set of node IDs for generated super accessors (variable statements). */
const substitutedSuperAccessors: boolean[] = [];

let contextFlags: ContextFlags = 0;
let contextFlags = ContextFlags.None;

// Save the previous transformation hooks.
const previousOnEmitNode = context.onEmitNode;
Expand Down
54 changes: 29 additions & 25 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5514,6 +5514,7 @@ export const enum EnumKind {

/** @internal */
export const enum CheckFlags {
None = 0,
Instantiated = 1 << 0, // Instantiated symbol
SyntheticProperty = 1 << 1, // Property in union or intersection type
SyntheticMethod = 1 << 2, // Method in union or intersection type
Expand Down Expand Up @@ -5611,31 +5612,32 @@ export interface PatternAmbientModule {

/** @internal */
export const enum NodeCheckFlags {
TypeChecked = 0x00000001, // Node has been type checked
LexicalThis = 0x00000002, // Lexical 'this' reference
CaptureThis = 0x00000004, // Lexical 'this' used in body
CaptureNewTarget = 0x00000008, // Lexical 'new.target' used in body
SuperInstance = 0x00000100, // Instance 'super' reference
SuperStatic = 0x00000200, // Static 'super' reference
ContextChecked = 0x00000400, // Contextual types have been assigned
MethodWithSuperPropertyAccessInAsync = 0x00000800, // A method that contains a SuperProperty access in an async context.
MethodWithSuperPropertyAssignmentInAsync = 0x00001000, // A method that contains a SuperProperty assignment in an async context.
CaptureArguments = 0x00002000, // Lexical 'arguments' used in body
EnumValuesComputed = 0x00004000, // Values for enum members have been computed, and any errors have been reported for them.
LexicalModuleMergesWithClass = 0x00008000, // Instantiated lexical module declaration is merged with a previous class declaration.
LoopWithCapturedBlockScopedBinding = 0x00010000, // Loop that contains block scoped variable captured in closure
ContainsCapturedBlockScopeBinding = 0x00020000, // Part of a loop that contains block scoped variable captured in closure
CapturedBlockScopedBinding = 0x00040000, // Block-scoped binding that is captured in some function
BlockScopedBindingInLoop = 0x00080000, // Block-scoped binding with declaration nested inside iteration statement
ClassWithBodyScopedClassBinding = 0x00100000, // Decorated class that contains a binding to itself inside of the class body.
BodyScopedClassBinding = 0x00200000, // Binding to a decorated class inside of the class's body.
NeedsLoopOutParameter = 0x00400000, // Block scoped binding whose value should be explicitly copied outside of the converted loop
AssignmentsMarked = 0x00800000, // Parameter assignments have been marked
ClassWithConstructorReference = 0x01000000, // Class that contains a binding to its constructor inside of the class body.
ConstructorReferenceInClass = 0x02000000, // Binding to a class constructor inside of the class's body.
ContainsClassWithPrivateIdentifiers = 0x04000000, // Marked on all block-scoped containers containing a class with private identifiers.
ContainsSuperPropertyInStaticInitializer = 0x08000000, // Marked on all block-scoped containers containing a static initializer with 'super.x' or 'super[x]'.
InCheckIdentifier = 0x10000000,
None = 0,
TypeChecked = 1 << 0, // Node has been type checked
LexicalThis = 1 << 1, // Lexical 'this' reference
CaptureThis = 1 << 2, // Lexical 'this' used in body
CaptureNewTarget = 1 << 3, // Lexical 'new.target' used in body
SuperInstance = 1 << 4, // Instance 'super' reference
SuperStatic = 1 << 5, // Static 'super' reference
ContextChecked = 1 << 6, // Contextual types have been assigned
MethodWithSuperPropertyAccessInAsync = 1 << 7, // A method that contains a SuperProperty access in an async context.
MethodWithSuperPropertyAssignmentInAsync = 1 << 8, // A method that contains a SuperProperty assignment in an async context.
CaptureArguments = 1 << 9, // Lexical 'arguments' used in body
EnumValuesComputed = 1 << 10, // Values for enum members have been computed, and any errors have been reported for them.
LexicalModuleMergesWithClass = 1 << 11, // Instantiated lexical module declaration is merged with a previous class declaration.
LoopWithCapturedBlockScopedBinding = 1 << 12, // Loop that contains block scoped variable captured in closure
ContainsCapturedBlockScopeBinding = 1 << 13, // Part of a loop that contains block scoped variable captured in closure
CapturedBlockScopedBinding = 1 << 14, // Block-scoped binding that is captured in some function
BlockScopedBindingInLoop = 1 << 15, // Block-scoped binding with declaration nested inside iteration statement
ClassWithBodyScopedClassBinding = 1 << 16, // Decorated class that contains a binding to itself inside of the class body.
BodyScopedClassBinding = 1 << 17, // Binding to a decorated class inside of the class's body.
NeedsLoopOutParameter = 1 << 18, // Block scoped binding whose value should be explicitly copied outside of the converted loop
AssignmentsMarked = 1 << 19, // Parameter assignments have been marked
ClassWithConstructorReference = 1 << 20, // Class that contains a binding to its constructor inside of the class body.
ConstructorReferenceInClass = 1 << 21, // Binding to a class constructor inside of the class's body.
ContainsClassWithPrivateIdentifiers = 1 << 22, // Marked on all block-scoped containers containing a class with private identifiers.
ContainsSuperPropertyInStaticInitializer = 1 << 23, // Marked on all block-scoped containers containing a static initializer with 'super.x' or 'super[x]'.
InCheckIdentifier = 1 << 24,
}

/** @internal */
Expand Down Expand Up @@ -5842,6 +5844,7 @@ export interface EnumType extends Type {
// are specific to certain types and reuse the same bit position. Those ObjectFlags require a check
// for a certain TypeFlags value to determine their meaning.
export const enum ObjectFlags {
None = 0,
Class = 1 << 0, // Class
Interface = 1 << 1, // Interface
Reference = 1 << 2, // Generic type reference
Expand Down Expand Up @@ -6384,6 +6387,7 @@ export type TypeMapper =
| { kind: TypeMapKind.Composite | TypeMapKind.Merged, mapper1: TypeMapper, mapper2: TypeMapper };

export const enum InferencePriority {
None = 0,
NakedTypeVariable = 1 << 0, // Naked type variable in union or intersection type
SpeculativeTuple = 1 << 1, // Speculative tuple inference
SubstituteSource = 1 << 2, // Source of inference originated within a substitution type's substitute
Expand Down
1 change: 1 addition & 0 deletions src/services/formatting/rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const anyContext: readonly ContextPredicate[] = emptyArray;

/** @internal */
export const enum RuleAction {
None = 0,
StopProcessingSpaceActions = 1 << 0,
StopProcessingTokenActions = 1 << 1,
InsertSpace = 1 << 2,
Expand Down
2 changes: 1 addition & 1 deletion src/services/formatting/rulesMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function getRulesMap(): RulesMap {
* cannot be applied at the same position.
*/
function getRuleActionExclusion(ruleAction: RuleAction): RuleAction {
let mask: RuleAction = 0;
let mask = RuleAction.None;
if (ruleAction & RuleAction.StopProcessingSpaceActions) {
mask |= RuleAction.ModifySpaceAction;
}
Expand Down
3 changes: 2 additions & 1 deletion src/testRunner/unittests/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as ts from "../_namespaces/ts";

const enum ChangedPart {
none = 0,
references = 1 << 0,
importsAndExports = 1 << 1,
program = 1 << 2
Expand Down Expand Up @@ -32,7 +33,7 @@ export class SourceText implements ts.IScriptSnapshot {
constructor(private references: string,
private importsAndExports: string,
private program: string,
private changedPart: ChangedPart = 0,
private changedPart = ChangedPart.none,
private version = 0) {
}

Expand Down
2 changes: 2 additions & 0 deletions tests/baselines/reference/api/tsserverlibrary.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6719,6 +6719,7 @@ declare namespace ts {
interface EnumType extends Type {
}
enum ObjectFlags {
None = 0,
Class = 1,
Interface = 2,
Reference = 4,
Expand Down Expand Up @@ -6889,6 +6890,7 @@ declare namespace ts {
declaration?: IndexSignatureDeclaration;
}
enum InferencePriority {
None = 0,
NakedTypeVariable = 1,
SpeculativeTuple = 2,
SubstituteSource = 4,
Expand Down
2 changes: 2 additions & 0 deletions tests/baselines/reference/api/typescript.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2783,6 +2783,7 @@ declare namespace ts {
interface EnumType extends Type {
}
enum ObjectFlags {
None = 0,
Class = 1,
Interface = 2,
Reference = 4,
Expand Down Expand Up @@ -2953,6 +2954,7 @@ declare namespace ts {
declaration?: IndexSignatureDeclaration;
}
enum InferencePriority {
None = 0,
NakedTypeVariable = 1,
SpeculativeTuple = 2,
SubstituteSource = 4,
Expand Down
Loading