Skip to content

Commit 8239985

Browse files
authored
Fix getDeclarationModifierFlagsFromSymbolEx for synthetic properties (#63932)
1 parent 1824be0 commit 8239985

9 files changed

Lines changed: 1001 additions & 73 deletions

File tree

packages/typescript/src/enums/checkFlags.enum.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,22 @@ export enum CheckFlags {
1313
ContainsPublic = 1 << 8,
1414
ContainsProtected = 1 << 9,
1515
ContainsPrivate = 1 << 10,
16-
ContainsStatic = 1 << 11,
17-
Late = 1 << 12,
18-
ReverseMapped = 1 << 13,
19-
OptionalParameter = 1 << 14,
20-
RestParameter = 1 << 15,
21-
DeferredType = 1 << 16,
22-
HasNeverType = 1 << 17,
23-
Mapped = 1 << 18,
24-
StripOptional = 1 << 19,
25-
Unresolved = 1 << 20,
26-
IsDiscriminantComputed = 1 << 21,
27-
IsDiscriminant = 1 << 22,
28-
IndexSymbol = 1 << 23,
16+
ContainsWritePublic = 1 << 11,
17+
ContainsWriteProtected = 1 << 12,
18+
ContainsWritePrivate = 1 << 13,
19+
ContainsStatic = 1 << 14,
20+
Late = 1 << 15,
21+
ReverseMapped = 1 << 16,
22+
OptionalParameter = 1 << 17,
23+
RestParameter = 1 << 18,
24+
DeferredType = 1 << 19,
25+
HasNeverType = 1 << 20,
26+
Mapped = 1 << 21,
27+
StripOptional = 1 << 22,
28+
Unresolved = 1 << 23,
29+
IsDiscriminantComputed = 1 << 24,
30+
IsDiscriminant = 1 << 25,
31+
IndexSymbol = 1 << 26,
2932
Synthetic = SyntheticProperty | SyntheticMethod,
3033
NonUniformAndLiteral = HasNonUniformType | HasLiteralType,
3134
Partial = ReadPartial | WritePartial,

packages/typescript/src/enums/checkFlags.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,22 @@ export var CheckFlags: any;
1313
CheckFlags[CheckFlags["ContainsPublic"] = 256] = "ContainsPublic";
1414
CheckFlags[CheckFlags["ContainsProtected"] = 512] = "ContainsProtected";
1515
CheckFlags[CheckFlags["ContainsPrivate"] = 1024] = "ContainsPrivate";
16-
CheckFlags[CheckFlags["ContainsStatic"] = 2048] = "ContainsStatic";
17-
CheckFlags[CheckFlags["Late"] = 4096] = "Late";
18-
CheckFlags[CheckFlags["ReverseMapped"] = 8192] = "ReverseMapped";
19-
CheckFlags[CheckFlags["OptionalParameter"] = 16384] = "OptionalParameter";
20-
CheckFlags[CheckFlags["RestParameter"] = 32768] = "RestParameter";
21-
CheckFlags[CheckFlags["DeferredType"] = 65536] = "DeferredType";
22-
CheckFlags[CheckFlags["HasNeverType"] = 131072] = "HasNeverType";
23-
CheckFlags[CheckFlags["Mapped"] = 262144] = "Mapped";
24-
CheckFlags[CheckFlags["StripOptional"] = 524288] = "StripOptional";
25-
CheckFlags[CheckFlags["Unresolved"] = 1048576] = "Unresolved";
26-
CheckFlags[CheckFlags["IsDiscriminantComputed"] = 2097152] = "IsDiscriminantComputed";
27-
CheckFlags[CheckFlags["IsDiscriminant"] = 4194304] = "IsDiscriminant";
28-
CheckFlags[CheckFlags["IndexSymbol"] = 8388608] = "IndexSymbol";
16+
CheckFlags[CheckFlags["ContainsWritePublic"] = 2048] = "ContainsWritePublic";
17+
CheckFlags[CheckFlags["ContainsWriteProtected"] = 4096] = "ContainsWriteProtected";
18+
CheckFlags[CheckFlags["ContainsWritePrivate"] = 8192] = "ContainsWritePrivate";
19+
CheckFlags[CheckFlags["ContainsStatic"] = 16384] = "ContainsStatic";
20+
CheckFlags[CheckFlags["Late"] = 32768] = "Late";
21+
CheckFlags[CheckFlags["ReverseMapped"] = 65536] = "ReverseMapped";
22+
CheckFlags[CheckFlags["OptionalParameter"] = 131072] = "OptionalParameter";
23+
CheckFlags[CheckFlags["RestParameter"] = 262144] = "RestParameter";
24+
CheckFlags[CheckFlags["DeferredType"] = 524288] = "DeferredType";
25+
CheckFlags[CheckFlags["HasNeverType"] = 1048576] = "HasNeverType";
26+
CheckFlags[CheckFlags["Mapped"] = 2097152] = "Mapped";
27+
CheckFlags[CheckFlags["StripOptional"] = 4194304] = "StripOptional";
28+
CheckFlags[CheckFlags["Unresolved"] = 8388608] = "Unresolved";
29+
CheckFlags[CheckFlags["IsDiscriminantComputed"] = 16777216] = "IsDiscriminantComputed";
30+
CheckFlags[CheckFlags["IsDiscriminant"] = 33554432] = "IsDiscriminant";
31+
CheckFlags[CheckFlags["IndexSymbol"] = 67108864] = "IndexSymbol";
2932
CheckFlags[CheckFlags["Synthetic"] = 6] = "Synthetic";
3033
CheckFlags[CheckFlags["NonUniformAndLiteral"] = 192] = "NonUniformAndLiteral";
3134
CheckFlags[CheckFlags["Partial"] = 48] = "Partial";

tsc/internal/ast/checkflags.go

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,22 @@ const (
1717
CheckFlagsContainsPublic CheckFlags = 1 << 8 // Synthetic property with public constituent(s)
1818
CheckFlagsContainsProtected CheckFlags = 1 << 9 // Synthetic property with protected constituent(s)
1919
CheckFlagsContainsPrivate CheckFlags = 1 << 10 // Synthetic property with private constituent(s)
20-
CheckFlagsContainsStatic CheckFlags = 1 << 11 // Synthetic property with static constituent(s)
21-
CheckFlagsLate CheckFlags = 1 << 12 // Late-bound symbol for a computed property with a dynamic name
22-
CheckFlagsReverseMapped CheckFlags = 1 << 13 // Property of reverse-inferred homomorphic mapped type
23-
CheckFlagsOptionalParameter CheckFlags = 1 << 14 // Optional parameter
24-
CheckFlagsRestParameter CheckFlags = 1 << 15 // Rest parameter
25-
CheckFlagsDeferredType CheckFlags = 1 << 16 // Calculation of the type of this symbol is deferred due to processing costs, should be fetched with `getTypeOfSymbolWithDeferredType`
26-
CheckFlagsHasNeverType CheckFlags = 1 << 17 // Synthetic property with at least one never type in constituents
27-
CheckFlagsMapped CheckFlags = 1 << 18 // Property of mapped type
28-
CheckFlagsStripOptional CheckFlags = 1 << 19 // Strip optionality in mapped property
29-
CheckFlagsUnresolved CheckFlags = 1 << 20 // Unresolved type alias symbol
30-
CheckFlagsIsDiscriminantComputed CheckFlags = 1 << 21 // IsDiscriminant flags has been computed
31-
CheckFlagsIsDiscriminant CheckFlags = 1 << 22 // Discriminant property
32-
CheckFlagsIndexSymbol CheckFlags = 1 << 23 // Synthetic property created from index signature
20+
CheckFlagsContainsWritePublic CheckFlags = 1 << 11 // Synthetic property with public set accessors(s)
21+
CheckFlagsContainsWriteProtected CheckFlags = 1 << 12 // Synthetic property with protected set accessors(s)
22+
CheckFlagsContainsWritePrivate CheckFlags = 1 << 13 // Synthetic property with private set accessors(s)
23+
CheckFlagsContainsStatic CheckFlags = 1 << 14 // Synthetic property with static constituent(s)
24+
CheckFlagsLate CheckFlags = 1 << 15 // Late-bound symbol for a computed property with a dynamic name
25+
CheckFlagsReverseMapped CheckFlags = 1 << 16 // Property of reverse-inferred homomorphic mapped type
26+
CheckFlagsOptionalParameter CheckFlags = 1 << 17 // Optional parameter
27+
CheckFlagsRestParameter CheckFlags = 1 << 18 // Rest parameter
28+
CheckFlagsDeferredType CheckFlags = 1 << 19 // Calculation of the type of this symbol is deferred due to processing costs, should be fetched with `getTypeOfSymbolWithDeferredType`
29+
CheckFlagsHasNeverType CheckFlags = 1 << 20 // Synthetic property with at least one never type in constituents
30+
CheckFlagsMapped CheckFlags = 1 << 21 // Property of mapped type
31+
CheckFlagsStripOptional CheckFlags = 1 << 22 // Strip optionality in mapped property
32+
CheckFlagsUnresolved CheckFlags = 1 << 23 // Unresolved type alias symbol
33+
CheckFlagsIsDiscriminantComputed CheckFlags = 1 << 24 // IsDiscriminant flags has been computed
34+
CheckFlagsIsDiscriminant CheckFlags = 1 << 25 // Discriminant property
35+
CheckFlagsIndexSymbol CheckFlags = 1 << 26 // Synthetic property created from index signature
3336
CheckFlagsSynthetic = CheckFlagsSyntheticProperty | CheckFlagsSyntheticMethod
3437
CheckFlagsNonUniformAndLiteral = CheckFlagsHasNonUniformType | CheckFlagsHasLiteralType
3538
CheckFlagsPartial = CheckFlagsReadPartial | CheckFlagsWritePartial

tsc/internal/checker/checker.go

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11922,10 +11922,14 @@ func (c *Checker) checkPropertyAccessibilityAtLocation(location *ast.Node, isSup
1192211922
// Property is known to be private or protected at this point
1192311923
// Private property is accessible if the property is within the declaring class
1192411924
if flags&ast.ModifierFlagsPrivate != 0 {
11925-
declaringClassDeclaration := ast.GetClassLikeDeclarationOfSymbol(c.getParentOfSymbol(prop))
11926-
if !c.isNodeWithinClass(location, declaringClassDeclaration) {
11925+
var declaringClassDeclaration *ast.Node
11926+
if parent := c.getParentOfSymbol(prop); parent != nil {
11927+
declaringClassDeclaration = ast.GetClassLikeDeclarationOfSymbol(parent)
11928+
}
11929+
if declaringClassDeclaration == nil || !c.isNodeWithinClass(location, declaringClassDeclaration) {
1192711930
if errorNode != nil {
11928-
c.error(errorNode, diagnostics.Property_0_is_private_and_only_accessible_within_class_1, c.symbolToString(prop), c.TypeToString(c.getDeclaringClass(prop)))
11931+
class := core.OrElse(c.getDeclaringClass(prop), containingType)
11932+
c.error(errorNode, diagnostics.Property_0_is_private_and_only_accessible_within_class_1, c.symbolToString(prop), c.TypeToString(class))
1192911933
}
1193011934
return false
1193111935
}
@@ -11958,10 +11962,7 @@ func (c *Checker) checkPropertyAccessibilityAtLocation(location *ast.Node, isSup
1195811962
}
1195911963
if flags&ast.ModifierFlagsStatic != 0 || enclosingClass == nil {
1196011964
if errorNode != nil {
11961-
class := c.getDeclaringClass(prop)
11962-
if class == nil {
11963-
class = containingType
11964-
}
11965+
class := core.OrElse(c.getDeclaringClass(prop), containingType)
1196511966
c.error(errorNode, diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses, c.symbolToString(prop), c.TypeToString(class))
1196611967
}
1196711968
return false
@@ -21585,6 +21586,7 @@ func (c *Checker) createUnionOrIntersectionProperty(containingType *Type, name s
2158521586
var modifiers ast.ModifierFlags
2158621587
if prop != nil {
2158721588
modifiers = getDeclarationModifierFlagsFromSymbol(prop)
21589+
writeModifiers := getDeclarationModifierFlagsFromSymbolEx(prop, true /*isWrite*/)
2158821590
if prop.Flags&ast.SymbolFlagsClassMember != 0 {
2158921591
if isUnion {
2159021592
optionalFlag |= prop.Flags & ast.SymbolFlagsOptional
@@ -21624,14 +21626,19 @@ func (c *Checker) createUnionOrIntersectionProperty(containingType *Type, name s
2162421626
} else if !isUnion && !c.isReadonlySymbol(prop) {
2162521627
checkFlags &^= ast.CheckFlagsReadonly
2162621628
}
21627-
if modifiers&ast.ModifierFlagsNonPublicAccessibilityModifier == 0 {
21628-
checkFlags |= ast.CheckFlagsContainsPublic
21629-
}
21630-
if modifiers&ast.ModifierFlagsProtected != 0 {
21629+
if modifiers&ast.ModifierFlagsProtected != 0 && modifiers&ast.ModifierFlagsPublic == 0 {
2163121630
checkFlags |= ast.CheckFlagsContainsProtected
21632-
}
21633-
if modifiers&ast.ModifierFlagsPrivate != 0 {
21631+
} else if modifiers&ast.ModifierFlagsPrivate != 0 && modifiers&ast.ModifierFlagsPublic == 0 {
2163421632
checkFlags |= ast.CheckFlagsContainsPrivate
21633+
} else {
21634+
checkFlags |= ast.CheckFlagsContainsPublic
21635+
}
21636+
if writeModifiers&ast.ModifierFlagsProtected != 0 && writeModifiers&ast.ModifierFlagsPublic == 0 {
21637+
checkFlags |= ast.CheckFlagsContainsWriteProtected
21638+
} else if writeModifiers&ast.ModifierFlagsPrivate != 0 && writeModifiers&ast.ModifierFlagsPublic == 0 {
21639+
checkFlags |= ast.CheckFlagsContainsWritePrivate
21640+
} else {
21641+
checkFlags |= ast.CheckFlagsContainsWritePublic
2163521642
}
2163621643
if modifiers&ast.ModifierFlagsStatic != 0 {
2163721644
checkFlags |= ast.CheckFlagsContainsStatic
@@ -21665,13 +21672,27 @@ func (c *Checker) createUnionOrIntersectionProperty(containingType *Type, name s
2166521672
}
2166621673
}
2166721674
}
21668-
if singleProp == nil || isUnion &&
21675+
if singleProp == nil {
21676+
// No property was found
21677+
return nil
21678+
}
21679+
if isUnion &&
2166921680
(propSet.Size() != 0 || checkFlags&ast.CheckFlagsPartial != 0) &&
21670-
checkFlags&(ast.CheckFlagsContainsPrivate|ast.CheckFlagsContainsProtected) != 0 &&
21681+
checkFlags&(ast.CheckFlagsContainsPrivate|ast.CheckFlagsContainsProtected|ast.CheckFlagsContainsWritePrivate|ast.CheckFlagsContainsWriteProtected) != 0 &&
2167121682
!(propSet.Size() != 0 && c.hasCommonDeclaration(&propSet)) {
21672-
// No property was found, or, in a union, a property has a private or protected declaration in one
21673-
// constituent, but is missing or has a different declaration in another constituent.
21674-
return nil
21683+
// A property in a union has a private or protected declaration in one constituent, but is missing
21684+
// or has a different declaration in another constituent. If the private or protected declaration is
21685+
// for reading, we don't create a property.
21686+
if checkFlags&(ast.CheckFlagsContainsPrivate|ast.CheckFlagsContainsProtected) != 0 {
21687+
return nil
21688+
}
21689+
// Otherwise, if the private or protected declaration is for writing, reduce accessibility to that of
21690+
// the most restricted constituent.
21691+
if checkFlags&ast.CheckFlagsContainsWritePrivate != 0 {
21692+
checkFlags &^= ast.CheckFlagsContainsWritePublic | ast.CheckFlagsContainsWriteProtected
21693+
} else if checkFlags&ast.CheckFlagsContainsWriteProtected != 0 {
21694+
checkFlags &^= ast.CheckFlagsContainsWritePublic
21695+
}
2167521696
}
2167621697
if propSet.Size() == 0 && checkFlags&ast.CheckFlagsReadPartial == 0 && len(indexTypes) == 0 {
2167721698
if !mergedInstantiations {

tsc/internal/checker/utilities.go

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,21 @@ func getDeclarationModifierFlagsFromSymbol(s *ast.Symbol) ast.ModifierFlags {
715715
}
716716

717717
func getDeclarationModifierFlagsFromSymbolEx(s *ast.Symbol, isWrite bool) ast.ModifierFlags {
718+
if s.CheckFlags&ast.CheckFlagsSynthetic != 0 {
719+
var accessModifier ast.ModifierFlags
720+
switch {
721+
case !isWrite && s.CheckFlags&ast.CheckFlagsContainsPublic != 0 || isWrite && s.CheckFlags&ast.CheckFlagsContainsWritePublic != 0:
722+
accessModifier = ast.ModifierFlagsPublic
723+
case !isWrite && s.CheckFlags&ast.CheckFlagsContainsProtected != 0 || isWrite && s.CheckFlags&ast.CheckFlagsContainsWriteProtected != 0:
724+
accessModifier = ast.ModifierFlagsProtected
725+
case !isWrite && s.CheckFlags&ast.CheckFlagsContainsPrivate != 0 || isWrite && s.CheckFlags&ast.CheckFlagsContainsWritePrivate != 0:
726+
accessModifier = ast.ModifierFlagsPrivate
727+
}
728+
if s.CheckFlags&ast.CheckFlagsContainsStatic != 0 {
729+
return accessModifier | ast.ModifierFlagsStatic
730+
}
731+
return accessModifier
732+
}
718733
if s.ValueDeclaration != nil {
719734
var declaration *ast.Node
720735
if isWrite {
@@ -732,22 +747,6 @@ func getDeclarationModifierFlagsFromSymbolEx(s *ast.Symbol, isWrite bool) ast.Mo
732747
}
733748
return flags & ^ast.ModifierFlagsAccessibilityModifier
734749
}
735-
if s.CheckFlags&ast.CheckFlagsSynthetic != 0 {
736-
var accessModifier ast.ModifierFlags
737-
switch {
738-
case s.CheckFlags&ast.CheckFlagsContainsPrivate != 0:
739-
accessModifier = ast.ModifierFlagsPrivate
740-
case s.CheckFlags&ast.CheckFlagsContainsPublic != 0:
741-
accessModifier = ast.ModifierFlagsPublic
742-
default:
743-
accessModifier = ast.ModifierFlagsProtected
744-
}
745-
var staticModifier ast.ModifierFlags
746-
if s.CheckFlags&ast.CheckFlagsContainsStatic != 0 {
747-
staticModifier = ast.ModifierFlagsStatic
748-
}
749-
return accessModifier | staticModifier
750-
}
751750
if s.Flags&ast.SymbolFlagsPrototype != 0 {
752751
return ast.ModifierFlagsPublic | ast.ModifierFlagsStatic
753752
}

0 commit comments

Comments
 (0)