-
Notifications
You must be signed in to change notification settings - Fork 13k
Turn 2 type flags into properties #11212
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
Conversation
1. Instantiated (only modifies anonymous types) 2. ObjectLiteralWithComputedProperties (only modifies [resolved] object types) 3. ThisType (only modifies type parameters) This is needed for object spread and rest, which will each need a type flag. There are 4-5 other likely targets for removal, and I may remove those later.
@ahejlsberg and @mhegazy can you take a look at this? |
@@ -2382,19 +2382,16 @@ namespace ts { | |||
Union = 1 << 19, // Union (T | U) | |||
Intersection = 1 << 20, // Intersection (T & U) | |||
Anonymous = 1 << 21, // Anonymous | |||
Instantiated = 1 << 22, // Instantiated anonymous type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would preserve this flag unless you really need to free it up. In generic code we create lots of instantiated anonymous types and it would be nice not to incur the overhead of another property.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only need one flag right now (Spread), but I'll need another for Rest and Ryan will need one for Subset. Maybe ObjectLiteral is a better target?
FreshLiteral seems pretty easy to excise as well, but there are a lot of literals in any given program.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instantiated is back in. I'm looking at ObjectLiteral instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd leave ObjectLiteral alone. Just free up the other two for now and then we can do more if and when it is needed. I'd prefer not incurring overhead unless we have to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
if (hasComputedProperties) { | ||
result.flags |= TypeFlags.ObjectLiteralPatternWithComputedProperties; | ||
} | ||
result.inObjectLiteralPatternWithComputedProperties = hasComputedProperties; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only create this property if hasComputedProperties
is true.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, turns out I was wrong when I thought that x.prop = undefined
is a no-op. Fixed.
@@ -4414,7 +4413,7 @@ namespace ts { | |||
* boolean, and symbol primitive types, return the corresponding object types. Otherwise return the | |||
* type itself. Note that the apparent type of a union type is the union type itself. | |||
*/ | |||
function getApparentType(type: Type): Type { | |||
function getApparentType(type: Type): ObjectType { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this change? This function isn't guaranteed to return an ObjectType
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the branches do return ObjectType
, but I forgot about the else branch. Reverted.
@@ -6646,7 +6647,7 @@ namespace ts { | |||
} | |||
|
|||
function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean { | |||
if (!(target.flags & TypeFlags.ObjectLiteralPatternWithComputedProperties) && maybeTypeOfKind(target, TypeFlags.ObjectType)) { | |||
if (maybeTypeOfKind(target, TypeFlags.ObjectType) && !(target as ObjectType).inObjectLiteralPatternWithComputedProperties) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The maybeTypeOfKind
function could return true when target
is a union or intersection containing an object type, so the second check needs to first ensure target
is actually an object type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was relying on unions and intersections not having inObjectLiteralPatternWithComputedProperties
and having the check come back with undefined. Adding the check is the right thing, though.
@@ -9937,7 +9938,7 @@ namespace ts { | |||
|
|||
// Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily | |||
// be "pushed" onto a node using the contextualType property. | |||
function getApparentTypeOfContextualType(node: Expression): Type { | |||
function getApparentTypeOfContextualType(node: Expression): ObjectType { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The returned type could be something other than an ObjectType
so this change isn't correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
@@ -10371,7 +10372,8 @@ namespace ts { | |||
const numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node, propertiesArray, IndexKind.Number) : undefined; | |||
const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo); | |||
const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : TypeFlags.FreshLiteral; | |||
result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag | (typeFlags & TypeFlags.PropagatingFlags) | (patternWithComputedProperties ? TypeFlags.ObjectLiteralPatternWithComputedProperties : 0); | |||
result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag | (typeFlags & TypeFlags.PropagatingFlags); | |||
result.inObjectLiteralPatternWithComputedProperties = patternWithComputedProperties; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only set the property if patternWithComputedProperties
is true.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
I put |
Oops, I didn't see your new comments, @ahejlsberg. I put |
Why didn't you just introduce a new |
@@ -3178,7 +3178,7 @@ namespace ts { | |||
result.pattern = pattern; | |||
} | |||
if (hasComputedProperties) { | |||
result.flags |= TypeFlags.ObjectLiteralPatternWithComputedProperties; | |||
result.inObjectLiteralPatternWithComputedProperties = hasComputedProperties; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just say = true;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, shouldn't it be isObjectBlaBlaBla...
? In other words, "is" instead of "in".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -10271,7 +10274,7 @@ namespace ts { | |||
const contextualTypeHasPattern = contextualType && contextualType.pattern && | |||
(contextualType.pattern.kind === SyntaxKind.ObjectBindingPattern || contextualType.pattern.kind === SyntaxKind.ObjectLiteralExpression); | |||
let typeFlags: TypeFlags = 0; | |||
let patternWithComputedProperties = false; | |||
let patternWithComputedProperties: boolean | undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
const members = createMap<Symbol>(); | ||
let hasComputedProperties = false; | ||
let hasComputedProperties: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -3156,7 +3156,7 @@ namespace ts { | |||
} | |||
|
|||
// Return the type implied by an object binding pattern | |||
function getTypeFromObjectBindingPattern(pattern: ObjectBindingPattern, includePatternInType: boolean, reportErrors: boolean): Type { | |||
function getTypeFromObjectBindingPattern(pattern: ObjectBindingPattern, includePatternInType: boolean, reportErrors: boolean): ResolvedType { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more change that isn't necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reverted to Type
This is needed for object spread and rest, which will each need a type
flag.
There are 4-5 other likely targets for removal, and I may remove those
later.