Skip to content

Commit 7631247

Browse files
committed
WIP: fix comments
1 parent 2546be8 commit 7631247

File tree

2 files changed

+98
-98
lines changed

2 files changed

+98
-98
lines changed

src/compiler/checker.ts

Lines changed: 97 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -263,30 +263,6 @@ namespace ts {
263263
Uncapitalize: IntrinsicTypeKind.Uncapitalize
264264
}));
265265

266-
enum TypeChecks {
267-
Ok,
268-
HasDiagnostic
269-
}
270-
271-
interface CheckerResultOk {
272-
result: TypeChecks.Ok
273-
}
274-
275-
interface CheckerResultHasDiagnostic {
276-
result: TypeChecks.HasDiagnostic,
277-
message: DiagnosticMessage;
278-
args:
279-
| never[]
280-
| [string | number]
281-
| [string | number, string | number]
282-
| [string | number, string | number, string | number]
283-
| [string | number, string | number, string | number, string | number];
284-
}
285-
286-
type CheckerResult =
287-
| CheckerResultOk
288-
| CheckerResultHasDiagnostic;
289-
290266
function SymbolLinks(this: SymbolLinks) {
291267
}
292268

@@ -736,9 +712,7 @@ namespace ts {
736712

737713
getLocalTypeParametersOfClassOrInterfaceOrTypeAlias,
738714
isDeclarationVisible,
739-
isPropertyAccessible: (node, isSuper, writing, type, prop) => {
740-
return checkPropertyAccessibilityAtNode(node, isSuper, writing, type, prop).result === TypeChecks.Ok;
741-
}
715+
isPropertyAccessible,
742716
};
743717

744718
function getResolvedSignatureWorker(nodeIn: CallLikeExpression, candidatesOutArray: Signature[] | undefined, argumentCount: number | undefined, checkMode: CheckMode): Signature | undefined {
@@ -27293,35 +27267,28 @@ namespace ts {
2729327267
node: PropertyAccessExpression | QualifiedName | PropertyAccessExpression | VariableDeclaration | ParameterDeclaration | ImportTypeNode | PropertyAssignment | ShorthandPropertyAssignment | BindingElement,
2729427268
isSuper: boolean, writing: boolean, type: Type, prop: Symbol, reportError = true): boolean {
2729527269

27296-
const errorNode = node.kind === SyntaxKind.QualifiedName ? node.right :
27270+
const errorNode = !reportError ? undefined : node.kind === SyntaxKind.QualifiedName ? node.right :
2729727271
node.kind === SyntaxKind.ImportType ? node :
2729827272
node.kind === SyntaxKind.BindingElement && node.propertyName ? node.propertyName : node.name;
2729927273

27300-
const typeChecks = checkPropertyAccessibilityAtNode(node, isSuper, writing, type, prop);
27301-
switch (typeChecks.result) {
27302-
case (TypeChecks.Ok):
27303-
return true;
27304-
case (TypeChecks.HasDiagnostic):
27305-
if (reportError) {
27306-
error(errorNode, typeChecks.message, ...typeChecks.args);
27307-
}
27308-
return false;
27309-
}
27274+
return checkPropertyAccessibilityAtLocation(node, isSuper, writing, type, prop, errorNode);
2731027275
}
2731127276

27312-
// Possible concerns:
27313-
// (1) I'm not sure if this function has the right behavior if `node` is allowed to be any node,
27314-
// although we only use `node` for its location in the parse tree.
27315-
// (2) Does it even make sense to check for property accessibility at a certain arbitrary node?
27316-
// Maybe this function should be called "checkPropertyVisibilityAtNode" or something else.
27317-
function checkPropertyAccessibilityAtNode(node: Node,
27277+
/**
27278+
* Check whether the requested property can be accessed at the requested location.
27279+
* Returns true if node is a valid property access, and false otherwise.
27280+
* @param location The location node where we want to check if the property is accessible.
27281+
* @param isSuper True if the access is from `super.`.
27282+
* @param writing True if this is a write property access, false if it is a read property access.
27283+
* @param type The type of the object whose property is being accessed. (Not the type of the property.)
27284+
* @param prop The symbol for the property being accessed.
27285+
* @param errorNode The node where we should report an invalid property access error, or undefined if we should not report errors.
27286+
*/
27287+
function checkPropertyAccessibilityAtLocation(location: Node,
2731827288
isSuper: boolean, writing: boolean,
27319-
type: Type, prop: Symbol): CheckerResult {
27320-
const flags = getDeclarationModifierFlagsFromSymbol(prop, writing);
27289+
type: Type, prop: Symbol, errorNode?: Node): boolean {
2732127290

27322-
const checkerOk: CheckerResultOk = {
27323-
result: TypeChecks.Ok
27324-
};
27291+
const flags = getDeclarationModifierFlagsFromSymbol(prop, writing);
2732527292

2732627293
if (isSuper) {
2732727294
// TS 1.0 spec (April 2014): 4.8.2
@@ -27333,69 +27300,74 @@ namespace ts {
2733327300
// a super property access is permitted and must specify a public static member function of the base class.
2733427301
if (languageVersion < ScriptTarget.ES2015) {
2733527302
if (symbolHasNonMethodDeclaration(prop)) {
27336-
return {
27337-
result: TypeChecks.HasDiagnostic,
27338-
message: Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword,
27339-
args: emptyArray
27340-
};
27303+
if (errorNode) {
27304+
error(errorNode, Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword);
27305+
}
27306+
return false;
2734127307
}
2734227308
}
2734327309
if (flags & ModifierFlags.Abstract) {
2734427310
// A method cannot be accessed in a super property access if the method is abstract.
2734527311
// This error could mask a private property access error. But, a member
2734627312
// cannot simultaneously be private and abstract, so this will trigger an
2734727313
// additional error elsewhere.
27348-
return {
27349-
result: TypeChecks.HasDiagnostic,
27350-
message: Diagnostics.Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression,
27351-
args: [symbolToString(prop), typeToString(getDeclaringClass(prop)!)]
27352-
};
27314+
if (errorNode) {
27315+
error(errorNode,
27316+
Diagnostics.Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression,
27317+
symbolToString(prop),
27318+
typeToString(getDeclaringClass(prop)!));
27319+
}
27320+
return false;
2735327321
}
2735427322
}
2735527323

2735627324
// Referencing abstract properties within their own constructors is not allowed
2735727325
if ((flags & ModifierFlags.Abstract) && symbolHasNonMethodDeclaration(prop) &&
27358-
(isThisProperty(node) || isThisInitializedObjectBindingExpression(node) || isObjectBindingPattern(node.parent) && isThisInitializedDeclaration(node.parent.parent))) {
27326+
(isThisProperty(location) || isThisInitializedObjectBindingExpression(location) || isObjectBindingPattern(location.parent) && isThisInitializedDeclaration(location.parent.parent))) {
2735927327
const declaringClassDeclaration = getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)!);
27360-
if (declaringClassDeclaration && isNodeUsedDuringClassInitialization(node)) {
27361-
return {
27362-
result: TypeChecks.HasDiagnostic,
27363-
message: Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor,
27364-
args: [symbolToString(prop), getTextOfIdentifierOrLiteral(declaringClassDeclaration.name!)]
27365-
};
27328+
if (declaringClassDeclaration && isNodeUsedDuringClassInitialization(location)) {
27329+
if (errorNode) {
27330+
error(errorNode,
27331+
Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor,
27332+
symbolToString(prop),
27333+
getTextOfIdentifierOrLiteral(declaringClassDeclaration.name!));
27334+
}
27335+
return false;
2736627336
}
2736727337
}
2736827338

2736927339
// Public properties are otherwise accessible.
2737027340
if (!(flags & ModifierFlags.NonPublicAccessibilityModifier)) {
27371-
return checkerOk;
27341+
return true;
2737227342
}
2737327343

2737427344
// Property is known to be private or protected at this point
2737527345

2737627346
// Private property is accessible if the property is within the declaring class
2737727347
if (flags & ModifierFlags.Private) {
2737827348
const declaringClassDeclaration = getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)!)!;
27379-
if (!isNodeWithinClass(node, declaringClassDeclaration)) {
27380-
return {
27381-
result: TypeChecks.HasDiagnostic,
27382-
message: Diagnostics.Property_0_is_private_and_only_accessible_within_class_1,
27383-
args: [symbolToString(prop), typeToString(getDeclaringClass(prop)!)]
27384-
};
27349+
if (!isNodeWithinClass(location, declaringClassDeclaration)) {
27350+
if (errorNode) {
27351+
error(errorNode,
27352+
Diagnostics.Property_0_is_private_and_only_accessible_within_class_1,
27353+
symbolToString(prop),
27354+
typeToString(getDeclaringClass(prop)!));
27355+
}
27356+
return false;
2738527357
}
27386-
return checkerOk;
27358+
return true;
2738727359
}
2738827360

2738927361
// Property is known to be protected at this point
2739027362

2739127363
// All protected properties of a supertype are accessible in a super access
2739227364
if (isSuper) {
27393-
return checkerOk;
27365+
return true;
2739427366
}
2739527367

2739627368
// Find the first enclosing class that has the declaring classes of the protected constituents
2739727369
// of the property as base classes
27398-
let enclosingClass = forEachEnclosingClass(node, enclosingDeclaration => {
27370+
let enclosingClass = forEachEnclosingClass(location, enclosingDeclaration => {
2739927371
const enclosingClass = getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingDeclaration)!) as InterfaceType;
2740027372
return isClassDerivedFromDeclaringClasses(enclosingClass, prop, writing) ? enclosingClass : undefined;
2740127373
});
@@ -27404,33 +27376,36 @@ namespace ts {
2740427376
// allow PropertyAccessibility if context is in function with this parameter
2740527377
// static member access is disallow
2740627378
let thisParameter: ParameterDeclaration | undefined;
27407-
if (flags & ModifierFlags.Static || !(thisParameter = getThisParameterFromNodeContext(node)) || !thisParameter.type) {
27408-
return {
27409-
result: TypeChecks.HasDiagnostic,
27410-
message: Diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses,
27411-
args: [symbolToString(prop), typeToString(getDeclaringClass(prop) || type)]
27412-
};
27379+
if (flags & ModifierFlags.Static || !(thisParameter = getThisParameterFromNodeContext(location)) || !thisParameter.type) {
27380+
if (errorNode) {
27381+
error(errorNode,
27382+
Diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses,
27383+
symbolToString(prop),
27384+
typeToString(getDeclaringClass(prop) || type));
27385+
}
27386+
return false;
2741327387
}
2741427388

2741527389
const thisType = getTypeFromTypeNode(thisParameter.type);
2741627390
enclosingClass = (((thisType.flags & TypeFlags.TypeParameter) ? getConstraintOfTypeParameter(thisType as TypeParameter) : thisType) as TypeReference).target;
2741727391
}
2741827392
// No further restrictions for static properties
2741927393
if (flags & ModifierFlags.Static) {
27420-
return checkerOk;
27394+
return true;
2742127395
}
2742227396
if (type.flags & TypeFlags.TypeParameter) {
2742327397
// get the original type -- represented as the type constraint of the 'this' type
2742427398
type = (type as TypeParameter).isThisType ? getConstraintOfTypeParameter(type as TypeParameter)! : getBaseConstraintOfType(type as TypeParameter)!; // TODO: GH#18217 Use a different variable that's allowed to be undefined
2742527399
}
2742627400
if (!type || !hasBaseType(type, enclosingClass)) {
27427-
return {
27428-
result: TypeChecks.HasDiagnostic,
27429-
message: Diagnostics.Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1_This_is_an_instance_of_class_2,
27430-
args: [symbolToString(prop), typeToString(enclosingClass), typeToString(type)]
27431-
};
27401+
if (errorNode) {
27402+
error(errorNode,
27403+
Diagnostics.Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1_This_is_an_instance_of_class_2,
27404+
symbolToString(prop), typeToString(enclosingClass), typeToString(type));
27405+
}
27406+
return false;
2743227407
}
27433-
return checkerOk;
27408+
return true;
2743427409
}
2743527410

2743627411
function getThisParameterFromNodeContext(node: Node) {
@@ -27726,7 +27701,7 @@ namespace ts {
2772627701
checkPropertyNotUsedBeforeDeclaration(prop, node, right);
2772727702
markPropertyAsReferenced(prop, node, isSelfTypeAccess(left, parentSymbol));
2772827703
getNodeLinks(node).resolvedSymbol = prop;
27729-
const writing = isWriteAccess(node);
27704+
const writing = isWriteAccess(node); // Look here for `isSuper`, `writing`
2773027705
checkPropertyAccessibility(node, left.kind === SyntaxKind.SuperKeyword, writing, apparentType, prop);
2773127706
if (isAssignmentToReadonlyEntity(node as Expression, prop, assignmentKind)) {
2773227707
error(right, Diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, idText(right));
@@ -28151,7 +28126,12 @@ namespace ts {
2815128126
}
2815228127

2815328128
function isValidPropertyAccessForCompletions(node: PropertyAccessExpression | ImportTypeNode | QualifiedName, type: Type, property: Symbol): boolean {
28154-
return isValidPropertyAccessWithType(node, node.kind === SyntaxKind.PropertyAccessExpression && node.expression.kind === SyntaxKind.SuperKeyword, property.escapedName, type);
28129+
// return isValidPropertyAccessWithType(node, node.kind === SyntaxKind.PropertyAccessExpression && node.expression.kind === SyntaxKind.SuperKeyword, property, type);
28130+
return isPropertyAccessible(node,
28131+
node.kind === SyntaxKind.PropertyAccessExpression && node.expression.kind === SyntaxKind.SuperKeyword,
28132+
/* isWriteAccess */ false,
28133+
type,
28134+
property);
2815528135
// Previously we validated the 'this' type of methods but this adversely affected performance. See #31377 for more context.
2815628136
}
2815728137

@@ -28161,21 +28141,41 @@ namespace ts {
2816128141
propertyName: __String,
2816228142
type: Type): boolean {
2816328143

28144+
// Short-circuiting for improved performance
2816428145
if (type === errorType || isTypeAny(type)) {
2816528146
return true;
2816628147
}
28148+
2816728149
const prop = getPropertyOfType(type, propertyName);
28168-
if (prop) {
28169-
if (prop.valueDeclaration && isPrivateIdentifierClassElementDeclaration(prop.valueDeclaration)) {
28170-
const declClass = getContainingClass(prop.valueDeclaration);
28171-
return !isOptionalChain(node) && !!findAncestor(node, parent => parent === declClass);
28172-
}
28173-
return checkPropertyAccessibility(node, isSuper, /*writing*/ false, type, prop, /* reportError */ false);
28150+
if (prop) { // TODO: move to `isPropertyAccessible`
28151+
return isPropertyAccessible(node, isSuper, /* isWriteAccess */ false, type, prop);
2817428152
}
28153+
2817528154
// In js files properties of unions are allowed in completion
2817628155
return isInJSFile(node) && (type.flags & TypeFlags.Union) !== 0 && (type as UnionType).types.some(elementType => isValidPropertyAccessWithType(node, isSuper, propertyName, elementType));
2817728156
}
2817828157

28158+
function isPropertyAccessible(node: Node, isSuper: boolean, isWriteAccess: boolean, type: Type, prop: Symbol): boolean {
28159+
/* TODO: compute isSuper? */
28160+
// Probably don't want to compute `isSuper`,
28161+
// since we'd like this function to be usable both for already existing property accesses
28162+
// and for possible, yet to exist property accesses (e.g. in a completions scenario).
28163+
28164+
// Short-circuiting for improved performance.
28165+
if (type === errorType || isTypeAny(type)) {
28166+
return true;
28167+
}
28168+
28169+
// A #private property access in an optional chain is an error dealt with by the parser.
28170+
// The checker does not check for it, so we need to do our own check here.
28171+
if (prop.valueDeclaration && isPrivateIdentifierClassElementDeclaration(prop.valueDeclaration)) {
28172+
const declClass = getContainingClass(prop.valueDeclaration);
28173+
return !isOptionalChain(node) && !!findAncestor(node, parent => parent === declClass);
28174+
}
28175+
28176+
return checkPropertyAccessibilityAtLocation(node, isSuper, isWriteAccess, type, prop);
28177+
}
28178+
2817928179
/**
2818028180
* Return the symbol of the for-in variable declared or referenced by the given for-in statement.
2818128181
*/

src/compiler/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4216,7 +4216,7 @@ namespace ts {
42164216

42174217
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): string | number | undefined;
42184218
isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName | ImportTypeNode, propertyName: string): boolean;
4219-
/** Exclude accesses to private properties or methods with a `this` parameter that `type` doesn't satisfy. */
4219+
/** Exclude accesses to private properties. */
42204220
/* @internal */ isValidPropertyAccessForCompletions(node: PropertyAccessExpression | ImportTypeNode | QualifiedName, type: Type, property: Symbol): boolean;
42214221
/** Follow all aliases to get the original symbol. */
42224222
getAliasedSymbol(symbol: Symbol): Symbol;

0 commit comments

Comments
 (0)