From c7ba10e153cdebadee597054bd26d406d1fa0868 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Fri, 13 Dec 2024 16:34:47 -0800 Subject: [PATCH 01/11] add symbol baseline generation --- internal/compiler/checker.go | 94 ++--- internal/compiler/checker_test.go | 4 +- internal/compiler/flow.go | 6 +- internal/compiler/grammarchecks.go | 2 +- internal/compiler/printer.go | 4 +- internal/compiler/program.go | 13 +- internal/compiler/relater.go | 30 +- internal/compiler/utilities.go | 6 +- internal/testutil/baseline/error_baseline.go | 19 - internal/testutil/baseline/symbol_baseline.go | 335 ++++++++++++++++++ internal/testutil/baseline/util.go | 25 +- 11 files changed, 439 insertions(+), 99 deletions(-) create mode 100644 internal/testutil/baseline/symbol_baseline.go diff --git a/internal/compiler/checker.go b/internal/compiler/checker.go index 19b205dfe8..4d85608a8e 100644 --- a/internal/compiler/checker.go +++ b/internal/compiler/checker.go @@ -1432,7 +1432,7 @@ func (c *Checker) checkSourceElementWorker(node *ast.Node) { c.checkMissingDeclaration(node) default: // !!! Temporary - if isExpressionNode(node) && !(ast.IsIdentifier(node) && isRightSideOfQualifiedNameOrPropertyAccess(node)) { + if IsExpressionNode(node) && !(ast.IsIdentifier(node) && isRightSideOfQualifiedNameOrPropertyAccess(node)) { _ = c.checkExpression(node) } } @@ -2311,7 +2311,7 @@ func (c *Checker) checkVarDeclaredNamesNotShadowed(node *ast.Node) { // here we know that function scoped variable is "shadowed" by block scoped one // a var declatation can't hoist past a lexical declaration and it results in a SyntaxError at runtime if !namesShareScope { - name := c.symbolToString(localDeclarationSymbol) + name := c.SymbolToString(localDeclarationSymbol) c.error(node, diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name, name) } } @@ -5288,14 +5288,14 @@ func (c *Checker) checkIdentifier(node *ast.Node, checkMode CheckMode) *Type { default: assignmentError = diagnostics.Cannot_assign_to_0_because_it_is_not_a_variable } - c.error(node, assignmentError, c.symbolToString(symbol)) + c.error(node, assignmentError, c.SymbolToString(symbol)) return c.errorType } if c.isReadonlySymbol(localOrExportSymbol) { if localOrExportSymbol.Flags&ast.SymbolFlagsVariable != 0 { - c.error(node, diagnostics.Cannot_assign_to_0_because_it_is_a_constant, c.symbolToString(symbol)) + c.error(node, diagnostics.Cannot_assign_to_0_because_it_is_a_constant, c.SymbolToString(symbol)) } else { - c.error(node, diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, c.symbolToString(symbol)) + c.error(node, diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, c.SymbolToString(symbol)) } return c.errorType } @@ -5380,13 +5380,13 @@ func (c *Checker) checkIdentifier(node *ast.Node, checkMode CheckMode) *Type { if !c.isEvolvingArrayOperationTarget(node) && (t == c.autoType || t == c.autoArrayType) { if flowType == c.autoType || flowType == c.autoArrayType { if c.noImplicitAny { - c.error(ast.GetNameOfDeclaration(declaration), diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined, c.symbolToString(symbol), c.typeToString(flowType)) - c.error(node, diagnostics.Variable_0_implicitly_has_an_1_type, c.symbolToString(symbol), c.typeToString(flowType)) + c.error(ast.GetNameOfDeclaration(declaration), diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined, c.SymbolToString(symbol), c.typeToString(flowType)) + c.error(node, diagnostics.Variable_0_implicitly_has_an_1_type, c.SymbolToString(symbol), c.typeToString(flowType)) } return c.convertAutoToAny(flowType) } } else if !assumeInitialized && !c.containsUndefinedType(t) && c.containsUndefinedType(flowType) { - c.error(node, diagnostics.Variable_0_is_used_before_being_assigned, c.symbolToString(symbol)) + c.error(node, diagnostics.Variable_0_is_used_before_being_assigned, c.SymbolToString(symbol)) // Return the declared type to reduce follow-on errors return t } @@ -5620,7 +5620,7 @@ func (c *Checker) getFlowTypeOfAccessExpression(node *ast.Node, prop *ast.Symbol } flowType := c.getFlowTypeOfReferenceEx(node, propType, initialType, nil, nil) if assumeUninitialized && !c.containsUndefinedType(propType) && c.containsUndefinedType(flowType) { - c.error(errorNode, diagnostics.Property_0_is_used_before_being_assigned, c.symbolToString(prop)) + c.error(errorNode, diagnostics.Property_0_is_used_before_being_assigned, c.SymbolToString(prop)) // Return the declared type to reduce follow-on errors return propType } @@ -5897,7 +5897,7 @@ func (c *Checker) checkPropertyAccessibilityAtLocation(location *ast.Node, isSup // cannot simultaneously be private and abstract, so this will trigger an // additional error elsewhere. if errorNode != nil { - c.error(errorNode, diagnostics.Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression, c.symbolToString(prop), c.typeToString(c.getDeclaringClass(prop))) + c.error(errorNode, diagnostics.Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression, c.SymbolToString(prop), c.typeToString(c.getDeclaringClass(prop))) } return false } @@ -5905,7 +5905,7 @@ func (c *Checker) checkPropertyAccessibilityAtLocation(location *ast.Node, isSup // This is true for both [[Set]] (old) and [[Define]] (ES spec) semantics. if flags&ast.ModifierFlagsStatic == 0 && core.Some(prop.Declarations, isClassInstanceProperty) { if errorNode != nil { - c.error(errorNode, diagnostics.Class_field_0_defined_by_the_parent_class_is_not_accessible_in_the_child_class_via_super, c.symbolToString(prop)) + c.error(errorNode, diagnostics.Class_field_0_defined_by_the_parent_class_is_not_accessible_in_the_child_class_via_super, c.SymbolToString(prop)) } return false } @@ -5917,7 +5917,7 @@ func (c *Checker) checkPropertyAccessibilityAtLocation(location *ast.Node, isSup declaringClassDeclaration := getClassLikeDeclarationOfSymbol(c.getParentOfSymbol(prop)) if declaringClassDeclaration != nil && c.isNodeUsedDuringClassInitialization(location) { if errorNode != nil { - c.error(errorNode, diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, c.symbolToString(prop), declaringClassDeclaration.Name().Text()) + c.error(errorNode, diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, c.SymbolToString(prop), declaringClassDeclaration.Name().Text()) } return false } @@ -5932,7 +5932,7 @@ func (c *Checker) checkPropertyAccessibilityAtLocation(location *ast.Node, isSup declaringClassDeclaration := getClassLikeDeclarationOfSymbol(c.getParentOfSymbol(prop)) if !c.isNodeWithinClass(location, declaringClassDeclaration) { if errorNode != nil { - c.error(errorNode, diagnostics.Property_0_is_private_and_only_accessible_within_class_1, c.symbolToString(prop), c.typeToString(c.getDeclaringClass(prop))) + c.error(errorNode, diagnostics.Property_0_is_private_and_only_accessible_within_class_1, c.SymbolToString(prop), c.typeToString(c.getDeclaringClass(prop))) } return false } @@ -5969,7 +5969,7 @@ func (c *Checker) checkPropertyAccessibilityAtLocation(location *ast.Node, isSup if class == nil { class = containingType } - c.error(errorNode, diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses, c.symbolToString(prop), c.typeToString(class)) + c.error(errorNode, diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses, c.SymbolToString(prop), c.typeToString(class)) } return false } @@ -5988,7 +5988,7 @@ func (c *Checker) checkPropertyAccessibilityAtLocation(location *ast.Node, isSup } if containingType == nil || !c.hasBaseType(containingType, enclosingClass) { if errorNode != nil && containingType != nil { - c.error(errorNode, diagnostics.Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1_This_is_an_instance_of_class_2, c.symbolToString(prop), c.typeToString(enclosingClass), c.typeToString(containingType)) + c.error(errorNode, diagnostics.Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1_This_is_an_instance_of_class_2, c.SymbolToString(prop), c.typeToString(enclosingClass), c.typeToString(containingType)) } return false } @@ -6971,7 +6971,7 @@ func (c *Checker) checkObjectLiteral(node *ast.Node, checkMode CheckMode) *Type if impliedProp != nil { prop.Flags |= impliedProp.Flags & ast.SymbolFlagsOptional } else if c.getIndexInfoOfType(contextualType, c.stringType) == nil { - c.error(memberDecl.Name(), diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, c.symbolToString(member), c.typeToString(contextualType)) + c.error(memberDecl.Name(), diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, c.SymbolToString(member), c.typeToString(contextualType)) } } prop.Declarations = member.Declarations @@ -7398,7 +7398,7 @@ func (c *Checker) isInPropertyInitializerOrClassStaticBlock(node *ast.Node) bool } return ast.FindAncestorQuit default: - if isExpressionNode(node) { + if IsExpressionNode(node) { return ast.FindAncestorFalse } return ast.FindAncestorQuit @@ -7700,7 +7700,7 @@ func (c *Checker) mergeSymbol(target *ast.Symbol, source *ast.Symbol, unidirecti // as we will already report a "Declaration name conflicts..." error, and this error // won't make much sense. if target != c.globalThisSymbol { - c.error(ast.GetNameOfDeclaration(getFirstDeclaration(source)), diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, c.symbolToString(target)) + c.error(ast.GetNameOfDeclaration(getFirstDeclaration(source)), diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, c.SymbolToString(target)) } } else { c.reportMergeSymbolError(target, source) @@ -7722,7 +7722,7 @@ func (c *Checker) reportMergeSymbolError(target *ast.Symbol, source *ast.Symbol) } // sourceSymbolFile := ast.GetSourceFileOfNode(getFirstDeclaration(source)) // targetSymbolFile := ast.GetSourceFileOfNode(getFirstDeclaration(target)) - symbolName := c.symbolToString(source) + symbolName := c.SymbolToString(source) // !!! // Collect top-level duplicate identifier errors into one mapping, so we can then merge their diagnostics if there are a bunch // if sourceSymbolFile != nil && targetSymbolFile != nil && c.amalgamatedDuplicates && !isEitherEnum && sourceSymbolFile != targetSymbolFile { @@ -8381,7 +8381,7 @@ func (c *Checker) errorNoModuleMemberSymbol(moduleSymbol *ast.Symbol, targetSymb suggestion = c.getSuggestedSymbolForNonexistentModule(name, targetSymbol) } if suggestion != nil { - suggestionName := c.symbolToString(suggestion) + suggestionName := c.SymbolToString(suggestion) diagnostic := c.error(name, diagnostics.X_0_has_no_exported_member_named_1_Did_you_mean_2, moduleName, declarationName, suggestionName) if suggestion.ValueDeclaration != nil { diagnostic.AddRelatedInfo(createDiagnosticForNode(suggestion.ValueDeclaration, diagnostics.X_0_is_declared_here, suggestionName)) @@ -8414,7 +8414,7 @@ func (c *Checker) reportNonExportedMember(node *ast.Node, name *ast.Node, declar }) var diagnostic *ast.Diagnostic if exportedSymbol != nil { - diagnostic = c.error(name, diagnostics.Module_0_declares_1_locally_but_it_is_exported_as_2, moduleName, declarationName, c.symbolToString(exportedSymbol)) + diagnostic = c.error(name, diagnostics.Module_0_declares_1_locally_but_it_is_exported_as_2, moduleName, declarationName, c.SymbolToString(exportedSymbol)) } else { diagnostic = c.error(name, diagnostics.Module_0_declares_1_locally_but_it_is_not_exported, moduleName, declarationName) } @@ -8895,7 +8895,7 @@ func (c *Checker) resolveQualifiedName(name *ast.Node, left *ast.Node, right *as declarationName := scanner.DeclarationNameToString(right) suggestionForNonexistentModule := c.getSuggestedSymbolForNonexistentModule(right, namespace) if suggestionForNonexistentModule != nil { - c.error(right, diagnostics.X_0_has_no_exported_member_named_1_Did_you_mean_2, namespaceName, declarationName, c.symbolToString(suggestionForNonexistentModule)) + c.error(right, diagnostics.X_0_has_no_exported_member_named_1_Did_you_mean_2, namespaceName, declarationName, c.SymbolToString(suggestionForNonexistentModule)) return nil } var containingQualifiedName *ast.Node @@ -8912,7 +8912,7 @@ func (c *Checker) resolveQualifiedName(name *ast.Node, left *ast.Node, right *as exportedTypeSymbol := c.getMergedSymbol(c.getSymbol(c.getExportsOfSymbol(namespace), text, ast.SymbolFlagsType)) if exportedTypeSymbol != nil { qualified := name.Parent.AsQualifiedName() - c.error(qualified.Right, diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1, c.symbolToString(exportedTypeSymbol), qualified.Right.AsIdentifier().Text) + c.error(qualified.Right, diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1, c.SymbolToString(exportedTypeSymbol), qualified.Right.AsIdentifier().Text) return nil } } @@ -8947,9 +8947,9 @@ func (c *Checker) getSuggestedSymbolForNonexistentModule(name *ast.Node, targetM func (c *Checker) getFullyQualifiedName(symbol *ast.Symbol, containingLocation *ast.Node) string { if symbol.Parent != nil { - return c.getFullyQualifiedName(symbol.Parent, containingLocation) + "." + c.symbolToString(symbol) + return c.getFullyQualifiedName(symbol.Parent, containingLocation) + "." + c.SymbolToString(symbol) } - return c.symbolToString(symbol) // !!! + return c.SymbolToString(symbol) // !!! } func (c *Checker) getExportsOfSymbol(symbol *ast.Symbol) ast.SymbolTable { @@ -9274,7 +9274,7 @@ func (c *Checker) resolveAlias(symbol *ast.Symbol) *ast.Symbol { } links.aliasTarget = target } else { - c.error(node, diagnostics.Circular_definition_of_import_alias_0, c.symbolToString(symbol)) + c.error(node, diagnostics.Circular_definition_of_import_alias_0, c.SymbolToString(symbol)) } } else if links.aliasTarget == c.resolvingSymbol { links.aliasTarget = c.unknownSymbol @@ -9804,7 +9804,7 @@ func (c *Checker) getBaseConstructorTypeOfClass(t *Type) *Type { c.resolveStructuredTypeMembers(baseConstructorType) } if !c.popTypeResolution() { - c.error(t.symbol.ValueDeclaration, diagnostics.X_0_is_referenced_directly_or_indirectly_in_its_own_base_expression, c.symbolToString(t.symbol)) + c.error(t.symbol.ValueDeclaration, diagnostics.X_0_is_referenced_directly_or_indirectly_in_its_own_base_expression, c.SymbolToString(t.symbol)) if data.resolvedBaseConstructorType == nil { data.resolvedBaseConstructorType = c.errorType } @@ -9822,7 +9822,7 @@ func (c *Checker) getBaseConstructorTypeOfClass(t *Type) *Type { } } if baseConstructorType.symbol.Declarations != nil { - err.AddRelatedInfo(createDiagnosticForNode(baseConstructorType.symbol.Declarations[0], diagnostics.Did_you_mean_for_0_to_be_constrained_to_type_new_args_Colon_any_1, c.symbolToString(baseConstructorType.symbol), c.typeToString(ctorReturn))) + err.AddRelatedInfo(createDiagnosticForNode(baseConstructorType.symbol.Declarations[0], diagnostics.Did_you_mean_for_0_to_be_constrained_to_type_new_args_Colon_any_1, c.SymbolToString(baseConstructorType.symbol), c.typeToString(ctorReturn))) } } if data.resolvedBaseConstructorType == nil { @@ -10986,17 +10986,17 @@ func (c *Checker) reportCircularityError(symbol *ast.Symbol) *Type { // Check if variable has type annotation that circularly references the variable itself if declaration != nil { if declaration.Type() != nil { - c.error(symbol.ValueDeclaration, diagnostics.X_0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, c.symbolToString(symbol)) + c.error(symbol.ValueDeclaration, diagnostics.X_0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, c.SymbolToString(symbol)) return c.errorType } // Check if variable has initializer that circularly references the variable itself if c.noImplicitAny && (!ast.IsParameter(declaration) || declaration.Initializer() != nil) { - c.error(symbol.ValueDeclaration, diagnostics.X_0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer, c.symbolToString(symbol)) + c.error(symbol.ValueDeclaration, diagnostics.X_0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer, c.SymbolToString(symbol)) } } else if symbol.Flags&ast.SymbolFlagsAlias != 0 { node := c.getDeclarationOfAliasSymbol(symbol) if node != nil { - c.error(node, diagnostics.Circular_definition_of_import_alias_0, c.symbolToString(symbol)) + c.error(node, diagnostics.Circular_definition_of_import_alias_0, c.SymbolToString(symbol)) } } // Circularities could also result from parameters in function expressions that end up @@ -13460,11 +13460,11 @@ func (c *Checker) elaborateNeverIntersection(chain *ast.Diagnostic, node *ast.No if t.flags&TypeFlagsIntersection != 0 && t.objectFlags&ObjectFlagsIsNeverIntersection != 0 { neverProp := core.Find(c.getPropertiesOfUnionOrIntersectionType(t), c.isDiscriminantWithNeverType) if neverProp != nil { - return NewDiagnosticChainForNode(chain, node, diagnostics.The_intersection_0_was_reduced_to_never_because_property_1_has_conflicting_types_in_some_constituents, c.typeToStringEx(t, nil, TypeFormatFlagsNoTypeReduction), c.symbolToString(neverProp)) + return NewDiagnosticChainForNode(chain, node, diagnostics.The_intersection_0_was_reduced_to_never_because_property_1_has_conflicting_types_in_some_constituents, c.typeToStringEx(t, nil, TypeFormatFlagsNoTypeReduction), c.SymbolToString(neverProp)) } privateProp := core.Find(c.getPropertiesOfUnionOrIntersectionType(t), isConflictingPrivateProperty) if privateProp != nil { - return NewDiagnosticChainForNode(chain, node, diagnostics.The_intersection_0_was_reduced_to_never_because_property_1_exists_in_multiple_constituents_and_is_private_in_some, c.typeToStringEx(t, nil, TypeFormatFlagsNoTypeReduction), c.symbolToString(privateProp)) + return NewDiagnosticChainForNode(chain, node, diagnostics.The_intersection_0_was_reduced_to_never_because_property_1_exists_in_multiple_constituents_and_is_private_in_some, c.typeToStringEx(t, nil, TypeFormatFlagsNoTypeReduction), c.SymbolToString(privateProp)) } } return chain @@ -13565,7 +13565,7 @@ func (c *Checker) getTypeArguments(t *Type) []*Type { } errorNode := core.IfElse(node != nil, node, c.currentNode) if d.target.symbol != nil { - c.error(errorNode, diagnostics.Type_arguments_for_0_circularly_reference_themselves, c.symbolToString(d.target.symbol)) + c.error(errorNode, diagnostics.Type_arguments_for_0_circularly_reference_themselves, c.SymbolToString(d.target.symbol)) } else { c.error(errorNode, diagnostics.Tuple_type_arguments_circularly_reference_themselves) } @@ -14629,7 +14629,7 @@ func (c *Checker) getTypeArgumentsFromNode(node *ast.Node) []*Type { func (c *Checker) checkNoTypeArguments(node *ast.Node, symbol *ast.Symbol) bool { if len(node.TypeArguments()) != 0 { - c.error(node, diagnostics.Type_0_is_not_generic, c.symbolToString(symbol)) + c.error(node, diagnostics.Type_0_is_not_generic, c.SymbolToString(symbol)) return false } return true @@ -14998,7 +14998,7 @@ func (c *Checker) getTypeFromTypeAliasReference(node *ast.Node, symbol *ast.Symb message := core.IfElse(minTypeArgumentCount == len(typeParameters), diagnostics.Generic_type_0_requires_1_type_argument_s, diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments) - c.error(node, message, c.symbolToString(symbol), minTypeArgumentCount, len(typeParameters)) + c.error(node, message, c.SymbolToString(symbol), minTypeArgumentCount, len(typeParameters)) return c.errorType } // We refrain from associating a local type alias with an instantiation of a top-level type alias @@ -15262,7 +15262,7 @@ func (c *Checker) getDeclaredTypeOfTypeAlias(symbol *ast.Symbol) *Type { if errorNode == nil { errorNode = declaration } - c.error(errorNode, diagnostics.Type_alias_0_circularly_references_itself, c.symbolToString(symbol)) + c.error(errorNode, diagnostics.Type_alias_0_circularly_references_itself, c.SymbolToString(symbol)) t = c.errorType } if links.declaredType == nil { @@ -15474,7 +15474,7 @@ func (c *Checker) evaluateEntity(expr *ast.Node, location *ast.Node) EvaluatorRe func (c *Checker) evaluateEnumMember(expr *ast.Node, symbol *ast.Symbol, location *ast.Node) EvaluatorResult { declaration := symbol.ValueDeclaration if declaration == nil || declaration == location { - c.error(expr, diagnostics.Property_0_is_used_before_being_assigned, c.symbolToString(symbol)) + c.error(expr, diagnostics.Property_0_is_used_before_being_assigned, c.SymbolToString(symbol)) return evaluatorResult(nil, false, false, false) } if !c.isBlockScopedNameDeclaredBeforeUse(declaration, location) { @@ -18192,7 +18192,7 @@ func (c *Checker) getPropertyTypeForIndexType(originalObjectType *Type, objectTy if accessExpression != nil { c.markPropertyAsReferenced(prop, accessExpression, c.isSelfTypeAccess(accessExpression.Expression(), objectType.symbol)) if c.isAssignmentToReadonlyEntity(accessExpression, prop, getAssignmentTargetKind(accessExpression)) { - c.error(accessExpression.AsElementAccessExpression().ArgumentExpression, diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, c.symbolToString(prop)) + c.error(accessExpression.AsElementAccessExpression().ArgumentExpression, diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, c.SymbolToString(prop)) return nil } if accessFlags&AccessFlagsCacheSymbol != 0 { @@ -20959,7 +20959,7 @@ func (c *Checker) getActualTypeVariable(t *Type) *Type { return t } -func (c *Checker) getSymbolAtLocation(node *ast.Node, ignoreErrors bool) *ast.Symbol { +func (c *Checker) GetSymbolAtLocation(node *ast.Node, ignoreErrors bool) *ast.Symbol { if ast.IsSourceFile(node) { if ast.IsExternalModule(node.AsSourceFile()) { return c.getMergedSymbol(node.Symbol()) @@ -21074,7 +21074,7 @@ func (c *Checker) getSymbolAtLocation(node *ast.Node, ignoreErrors bool) *ast.Sy return c.getSymbolOfNode(node) case ast.KindImportType: if ast.IsLiteralImportTypeNode(node) { - return c.getSymbolAtLocation(node.AsImportTypeNode().Argument.AsLiteralTypeNode().Literal, ignoreErrors) + return c.GetSymbolAtLocation(node.AsImportTypeNode().Argument.AsLiteralTypeNode().Literal, ignoreErrors) } return nil case ast.KindExportKeyword: @@ -21186,7 +21186,7 @@ func (c *Checker) getSymbolOfNameOrPropertyAccessExpression(name *ast.Node) *ast } } - if isExpressionNode(name) { + if IsExpressionNode(name) { if ast.NodeIsMissing(name) { // Missing entity name. return nil @@ -21289,7 +21289,7 @@ func (c *Checker) getTypeOfNode(node *ast.Node) *Type { return typeFromTypeNode } - if isExpressionNode(node) { + if IsExpressionNode(node) { return c.getRegularTypeOfExpression(node) } @@ -21310,7 +21310,7 @@ func (c *Checker) getTypeOfNode(node *ast.Node) *Type { } if isTypeDeclarationName(node) { - symbol := c.getSymbolAtLocation(node, false /*ignoreErrors*/) + symbol := c.GetSymbolAtLocation(node, false /*ignoreErrors*/) if symbol != nil { return c.getDeclaredTypeOfSymbol(symbol) } @@ -21335,7 +21335,7 @@ func (c *Checker) getTypeOfNode(node *ast.Node) *Type { } if ast.IsDeclarationNameOrImportPropertyName(node) { - symbol := c.getSymbolAtLocation(node, false /*ignoreErrors*/) + symbol := c.GetSymbolAtLocation(node, false /*ignoreErrors*/) if symbol != nil { return c.getTypeOfSymbol(symbol) } @@ -21351,7 +21351,7 @@ func (c *Checker) getTypeOfNode(node *ast.Node) *Type { } if isInRightSideOfImportOrExportAssignment(node) { - symbol := c.getSymbolAtLocation(node, false /*ignoreErrors*/) + symbol := c.GetSymbolAtLocation(node, false /*ignoreErrors*/) if symbol != nil { declaredType := c.getDeclaredTypeOfSymbol(symbol) if !c.isErrorType(declaredType) { @@ -21439,7 +21439,7 @@ func (c *Checker) getApplicableIndexSymbol(t *Type, keyType *Type) *ast.Symbol { } else if t.symbol != nil { symbolCopy.Parent = t.symbol } else { - symbolCopy.Parent = c.getSymbolAtLocation(symbolCopy.Declarations[0].Parent, false /*ignoreErrors*/) + symbolCopy.Parent = c.GetSymbolAtLocation(symbolCopy.Declarations[0].Parent, false /*ignoreErrors*/) } indexSymbolLinks.filteredIndexSymbolCache[nodeListId] = symbolCopy return symbolCopy diff --git a/internal/compiler/checker_test.go b/internal/compiler/checker_test.go index 82a334057d..44efeb09f7 100644 --- a/internal/compiler/checker_test.go +++ b/internal/compiler/checker_test.go @@ -30,14 +30,14 @@ foo.bar;` } p := NewProgram(opts) p.bindSourceFiles() - c := p.getTypeChecker() + c := p.GetTypeChecker() file := p.SourceFiles()[0] interfaceId := file.Statements.Nodes[0].Name() varId := file.Statements.Nodes[1].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0].Name() propAccess := file.Statements.Nodes[2].AsExpressionStatement().Expression nodes := []*ast.Node{interfaceId, varId, propAccess} for _, node := range nodes { - symbol := c.getSymbolAtLocation(node, true /*ignoreErrors*/) + symbol := c.GetSymbolAtLocation(node, true /*ignoreErrors*/) if symbol == nil { t.Fatalf("Expected symbol to be non-nil") } diff --git a/internal/compiler/flow.go b/internal/compiler/flow.go index 83afaf84cb..20938c50d0 100644 --- a/internal/compiler/flow.go +++ b/internal/compiler/flow.go @@ -2111,7 +2111,7 @@ func (c *Checker) getExplicitTypeOfSymbol(symbol *ast.Symbol, diagnostic *ast.Di } } if diagnostic != nil { - diagnostic.AddRelatedInfo(createDiagnosticForNode(declaration, diagnostics.X_0_needs_an_explicit_type_annotation, c.symbolToString(symbol))) + diagnostic.AddRelatedInfo(createDiagnosticForNode(declaration, diagnostics.X_0_needs_an_explicit_type_annotation, c.SymbolToString(symbol))) } } } @@ -2382,7 +2382,7 @@ func (c *Checker) getFlowTypeInConstructor(symbol *ast.Symbol, constructor *ast. reference.FlowNodeData().FlowNode = constructor.AsConstructorDeclaration().ReturnFlowNode flowType := c.getFlowTypeOfProperty(reference, symbol) if c.noImplicitAny && (flowType == c.autoType || flowType == c.autoArrayType) { - c.error(symbol.ValueDeclaration, diagnostics.Member_0_implicitly_has_an_1_type, c.symbolToString(symbol), c.typeToString(flowType)) + c.error(symbol.ValueDeclaration, diagnostics.Member_0_implicitly_has_an_1_type, c.SymbolToString(symbol), c.typeToString(flowType)) } // We don't infer a type if assignments are only null or undefined. if everyType(flowType, c.isNullableType) { @@ -2405,7 +2405,7 @@ func (c *Checker) getFlowTypeInStaticBlocks(symbol *ast.Symbol, staticBlocks []* reference.FlowNodeData().FlowNode = staticBlock.AsClassStaticBlockDeclaration().ReturnFlowNode flowType := c.getFlowTypeOfProperty(reference, symbol) if c.noImplicitAny && (flowType == c.autoType || flowType == c.autoArrayType) { - c.error(symbol.ValueDeclaration, diagnostics.Member_0_implicitly_has_an_1_type, c.symbolToString(symbol), c.typeToString(flowType)) + c.error(symbol.ValueDeclaration, diagnostics.Member_0_implicitly_has_an_1_type, c.SymbolToString(symbol), c.typeToString(flowType)) } // We don't infer a type if assignments are only null or undefined. if everyType(flowType, c.isNullableType) { diff --git a/internal/compiler/grammarchecks.go b/internal/compiler/grammarchecks.go index cfeb450b11..82e5c1c3a4 100644 --- a/internal/compiler/grammarchecks.go +++ b/internal/compiler/grammarchecks.go @@ -97,7 +97,7 @@ func (c *Checker) checkGrammarPrivateIdentifierExpression(privId *ast.PrivateIde } if !ast.IsForInStatement(privId.Parent) { - if !isExpressionNode(privIdAsNode) { + if !IsExpressionNode(privIdAsNode) { return c.grammarErrorOnNode(privIdAsNode, diagnostics.Private_identifiers_are_only_allowed_in_class_bodies_and_may_only_be_used_as_part_of_a_class_member_declaration_property_access_or_on_the_left_hand_side_of_an_in_expression) } diff --git a/internal/compiler/printer.go b/internal/compiler/printer.go index 402129449c..13d91ad7f8 100644 --- a/internal/compiler/printer.go +++ b/internal/compiler/printer.go @@ -27,7 +27,7 @@ func (c *Checker) getTypePrecedence(t *Type) ast.TypePrecedence { return ast.TypePrecedenceNonArray } -func (c *Checker) symbolToString(s *ast.Symbol) string { +func (c *Checker) SymbolToString(s *ast.Symbol) string { if s.ValueDeclaration != nil { name := ast.GetNameOfDeclaration(s.ValueDeclaration) if name != nil { @@ -569,7 +569,7 @@ func (c *Checker) getTextAndTypeOfNode(node *ast.Node) (string, *Type, bool) { } } } - if isExpressionNode(node) && !isRightSideOfQualifiedNameOrPropertyAccess(node) { + if IsExpressionNode(node) && !isRightSideOfQualifiedNameOrPropertyAccess(node) { return scanner.GetTextOfNode(node), c.getTypeOfExpression(node), false } return "", nil, false diff --git a/internal/compiler/program.go b/internal/compiler/program.go index 057e901f70..addc141d84 100644 --- a/internal/compiler/program.go +++ b/internal/compiler/program.go @@ -282,7 +282,7 @@ func (p *Program) GetSemanticDiagnostics(sourceFile *ast.SourceFile) []*ast.Diag } func (p *Program) GetGlobalDiagnostics() []*ast.Diagnostic { - return sortAndDeduplicateDiagnostics(p.getTypeChecker().GetGlobalDiagnostics()) + return sortAndDeduplicateDiagnostics(p.GetTypeChecker().GetGlobalDiagnostics()) } func (p *Program) TypeCount() int { @@ -292,7 +292,7 @@ func (p *Program) TypeCount() int { return int(p.checker.typeCount) } -func (p *Program) getTypeChecker() *Checker { +func (p *Program) GetTypeChecker() *Checker { if p.checker == nil { p.checker = NewChecker(p) } @@ -308,7 +308,7 @@ func (p *Program) getBindDiagnosticsForFile(sourceFile *ast.SourceFile) []*ast.D } func (p *Program) getSemanticDiagnosticsForFile(sourceFile *ast.SourceFile) []*ast.Diagnostic { - return core.Concatenate(sourceFile.BindDiagnostics(), p.getTypeChecker().GetDiagnostics(sourceFile)) + return core.Concatenate(sourceFile.BindDiagnostics(), p.GetTypeChecker().GetDiagnostics(sourceFile)) } func (p *Program) getDiagnosticsHelper(sourceFile *ast.SourceFile, ensureBound bool, getDiagnostics func(*ast.SourceFile) []*ast.Diagnostic) []*ast.Diagnostic { @@ -336,7 +336,7 @@ type NodeCount struct { func (p *Program) PrintSourceFileWithTypes() { for _, file := range p.files { if tspath.GetBaseFileName(file.FileName()) == "main.ts" { - fmt.Print(p.getTypeChecker().sourceFileWithTypes(file)) + fmt.Print(p.GetTypeChecker().sourceFileWithTypes(file)) } } } @@ -707,3 +707,8 @@ func (p *Program) Emit(options *EmitOptions) *EmitResult { } return result } + +func (p *Program) GetSourceFile(filename string) *ast.SourceFile { + path := tspath.ToPath(filename, p.host.GetCurrentDirectory(), p.host.FS().UseCaseSensitiveFileNames()) + return p.filesByPath[path] +} diff --git a/internal/compiler/relater.go b/internal/compiler/relater.go index 3eb167baf4..a59bcdcd90 100644 --- a/internal/compiler/relater.go +++ b/internal/compiler/relater.go @@ -2360,9 +2360,9 @@ func (r *Relater) hasExcessProperties(source *Type, target *Type, reportErrors b } } if suggestion != "" { - r.reportError(diagnostics.Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2, r.c.symbolToString(prop), r.c.typeToString(errorTarget), suggestion) + r.reportError(diagnostics.Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2, r.c.SymbolToString(prop), r.c.typeToString(errorTarget), suggestion) } else { - r.reportError(diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, r.c.symbolToString(prop), r.c.typeToString(errorTarget)) + r.reportError(diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, r.c.SymbolToString(prop), r.c.typeToString(errorTarget)) } } } @@ -2370,7 +2370,7 @@ func (r *Relater) hasExcessProperties(source *Type, target *Type, reportErrors b } if checkTypes != nil && r.isRelatedTo(r.c.getTypeOfSymbol(prop), r.c.getTypeOfPropertyInTypes(checkTypes, prop.Name), RecursionFlagsBoth, reportErrors) == TernaryFalse { if reportErrors { - r.reportError(diagnostics.Types_of_property_0_are_incompatible, r.c.symbolToString(prop)) + r.reportError(diagnostics.Types_of_property_0_are_incompatible, r.c.SymbolToString(prop)) } return true } @@ -3811,7 +3811,7 @@ func (r *Relater) propertiesRelatedTo(source *Type, target *Type, reportErrors b sourceType := r.c.getTypeOfSymbol(sourceProp) if sourceType.flags&TypeFlagsUndefined == 0 { if reportErrors { - r.reportError(diagnostics.Property_0_does_not_exist_on_type_1, r.c.symbolToString(sourceProp), r.c.typeToString(target)) + r.reportError(diagnostics.Property_0_does_not_exist_on_type_1, r.c.SymbolToString(sourceProp), r.c.typeToString(target)) } return TernaryFalse } @@ -3846,9 +3846,9 @@ func (r *Relater) propertyRelatedTo(source *Type, target *Type, sourceProp *ast. if sourceProp.ValueDeclaration != targetProp.ValueDeclaration { if reportErrors { if sourcePropFlags&ast.ModifierFlagsPrivate != 0 && targetPropFlags&ast.ModifierFlagsPrivate != 0 { - r.reportError(diagnostics.Types_have_separate_declarations_of_a_private_property_0, r.c.symbolToString(targetProp)) + r.reportError(diagnostics.Types_have_separate_declarations_of_a_private_property_0, r.c.SymbolToString(targetProp)) } else { - r.reportError(diagnostics.Property_0_is_private_in_type_1_but_not_in_type_2, r.c.symbolToString(targetProp), r.c.typeToString(core.IfElse(sourcePropFlags&ast.ModifierFlagsPrivate != 0, source, target)), r.c.typeToString(core.IfElse(sourcePropFlags&ast.ModifierFlagsPrivate != 0, target, source))) + r.reportError(diagnostics.Property_0_is_private_in_type_1_but_not_in_type_2, r.c.SymbolToString(targetProp), r.c.typeToString(core.IfElse(sourcePropFlags&ast.ModifierFlagsPrivate != 0, source, target)), r.c.typeToString(core.IfElse(sourcePropFlags&ast.ModifierFlagsPrivate != 0, target, source))) } } return TernaryFalse @@ -3864,13 +3864,13 @@ func (r *Relater) propertyRelatedTo(source *Type, target *Type, sourceProp *ast. if targetType == nil { targetType = target } - r.reportError(diagnostics.Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2, r.c.symbolToString(targetProp), r.c.typeToString(sourceType), r.c.typeToString(targetType)) + r.reportError(diagnostics.Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2, r.c.SymbolToString(targetProp), r.c.typeToString(sourceType), r.c.typeToString(targetType)) } return TernaryFalse } case sourcePropFlags&ast.ModifierFlagsProtected != 0: if reportErrors { - r.reportError(diagnostics.Property_0_is_protected_in_type_1_but_public_in_type_2, r.c.symbolToString(targetProp), r.c.typeToString(source), r.c.typeToString(target)) + r.reportError(diagnostics.Property_0_is_protected_in_type_1_but_public_in_type_2, r.c.SymbolToString(targetProp), r.c.typeToString(source), r.c.typeToString(target)) } return TernaryFalse } @@ -3887,7 +3887,7 @@ func (r *Relater) propertyRelatedTo(source *Type, target *Type, sourceProp *ast. related := r.isPropertySymbolTypeRelated(sourceProp, targetProp, getTypeOfSourceProperty, reportErrors, intersectionState) if related == TernaryFalse { if reportErrors { - r.reportError(diagnostics.Types_of_property_0_are_incompatible, r.c.symbolToString(targetProp)) + r.reportError(diagnostics.Types_of_property_0_are_incompatible, r.c.SymbolToString(targetProp)) } return TernaryFalse } @@ -3901,7 +3901,7 @@ func (r *Relater) propertyRelatedTo(source *Type, target *Type, sourceProp *ast. // (M - property in T) // (N - property in S) if reportErrors { - r.reportError(diagnostics.Property_0_is_optional_in_type_1_but_required_in_type_2, r.c.symbolToString(targetProp), r.c.typeToString(source), r.c.typeToString(target)) + r.reportError(diagnostics.Property_0_is_optional_in_type_1_but_required_in_type_2, r.c.SymbolToString(targetProp), r.c.typeToString(source), r.c.typeToString(target)) } return TernaryFalse } @@ -3933,17 +3933,17 @@ func (r *Relater) reportUnmatchedProperty(source *Type, target *Type, unmatchedP } props := slices.Collect(r.c.getUnmatchedProperties(source, target, requireOptionalProperties, false /*matchDiscriminantProperties*/)) if len(props) == 1 { - propName := r.c.symbolToString(unmatchedProperty) + propName := r.c.SymbolToString(unmatchedProperty) r.reportError(diagnostics.Property_0_is_missing_in_type_1_but_required_in_type_2, unmatchedProperty.Name, r.c.typeToString(source), r.c.typeToString(target)) if len(unmatchedProperty.Declarations) != 0 { r.relatedInfo = append(r.relatedInfo, createDiagnosticForNode(unmatchedProperty.Declarations[0], diagnostics.X_0_is_declared_here, propName)) } } else if r.tryElaborateArrayLikeErrors(source, target, false /*reportErrors*/) { if len(props) > 5 { - propNames := strings.Join(core.Map(props[:4], r.c.symbolToString), ", ") + propNames := strings.Join(core.Map(props[:4], r.c.SymbolToString), ", ") r.reportError(diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more, r.c.typeToString(source), r.c.typeToString(target), propNames, len(props)-4) } else { - propNames := strings.Join(core.Map(props, r.c.symbolToString), ", ") + propNames := strings.Join(core.Map(props, r.c.SymbolToString), ", ") r.reportError(diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2, r.c.typeToString(source), r.c.typeToString(target), propNames) } } @@ -4225,7 +4225,7 @@ func (r *Relater) membersRelatedToIndexInfo(source *Type, targetInfo *IndexInfo, related := r.isRelatedToEx(t, targetInfo.valueType, RecursionFlagsBoth, reportErrors, nil /*headMessage*/, intersectionState) if related == TernaryFalse { if reportErrors { - r.reportError(diagnostics.Property_0_is_incompatible_with_index_signature, r.c.symbolToString(prop)) + r.reportError(diagnostics.Property_0_is_incompatible_with_index_signature, r.c.SymbolToString(prop)) } return TernaryFalse } @@ -4305,7 +4305,7 @@ func (r *Relater) reportErrorResults(originalSource *Type, originalTarget *Type, prop = core.Find(r.c.getPropertiesOfUnionOrIntersectionType(originalTarget), isConflictingPrivateProperty) } if prop != nil { - r.reportError(message, r.c.typeToStringEx(originalTarget, nil /*enclosingDeclaration*/, TypeFormatFlagsNoTypeReduction), r.c.symbolToString(prop)) + r.reportError(message, r.c.typeToStringEx(originalTarget, nil /*enclosingDeclaration*/, TypeFormatFlagsNoTypeReduction), r.c.SymbolToString(prop)) } } // !!! Logic having to do with canonical diagnostics for deduplication purposes diff --git a/internal/compiler/utilities.go b/internal/compiler/utilities.go index 6ed5b8ab72..297a5aa04c 100644 --- a/internal/compiler/utilities.go +++ b/internal/compiler/utilities.go @@ -992,7 +992,7 @@ func isValidTypeOnlyAliasUseSite(useSite *ast.Node) bool { ast.IsPartOfTypeQuery(useSite) || isIdentifierInNonEmittingHeritageClause(useSite) || isPartOfPossiblyValidTypeOrAbstractComputedPropertyName(useSite) || - !(isExpressionNode(useSite) || isShorthandPropertyNameUseSite(useSite)) + !(IsExpressionNode(useSite) || isShorthandPropertyNameUseSite(useSite)) } func isIdentifierInNonEmittingHeritageClause(node *ast.Node) bool { @@ -1061,7 +1061,7 @@ func nodeCanBeDecorated(useLegacyDecorators bool, node *ast.Node, parent *ast.No return false } -func isExpressionNode(node *ast.Node) bool { +func IsExpressionNode(node *ast.Node) bool { switch node.Kind { case ast.KindSuperKeyword, ast.KindNullKeyword, ast.KindTrueKeyword, ast.KindFalseKeyword, ast.KindRegularExpressionLiteral, ast.KindArrayLiteralExpression, ast.KindObjectLiteralExpression, ast.KindPropertyAccessExpression, ast.KindElementAccessExpression, @@ -1153,7 +1153,7 @@ func isInExpressionContext(node *ast.Node) bool { case ast.KindSatisfiesExpression: return parent.AsSatisfiesExpression().Expression == node default: - return isExpressionNode(parent) + return IsExpressionNode(parent) } } diff --git a/internal/testutil/baseline/error_baseline.go b/internal/testutil/baseline/error_baseline.go index 84b7fc27e5..99f47fd9e2 100644 --- a/internal/testutil/baseline/error_baseline.go +++ b/internal/testutil/baseline/error_baseline.go @@ -19,12 +19,6 @@ import ( // IO const harnessNewLine = "\r\n" -var ( - lineDelimiter = regexp.MustCompile("\r?\n") - nonWhitespace = regexp.MustCompile(`\S`) - tsExtension = regexp.MustCompile(`\.tsx?$`) -) - var formatOpts = &compiler.DiagnosticsFormattingOptions{ NewLine: harnessNewLine, } @@ -251,19 +245,6 @@ func iterateErrorBaseline(t testing.TB, inputFiles []*TestFile, inputDiagnostics return result } -func checkDuplicatedFileName(resultName string, dupeCase map[string]int) string { - resultName = sanitizeTestFilePath(resultName) - if _, ok := dupeCase[resultName]; ok { - // A different baseline filename should be manufactured if the names differ only in case, for windows compat - count := 1 + dupeCase[resultName] - dupeCase[resultName] = count - resultName = fmt.Sprintf("%s.dupe%d", resultName, count) - } else { - dupeCase[resultName] = 0 - } - return resultName -} - func flattenDiagnosticMessage(d *ast.Diagnostic, newLine string) string { var output strings.Builder compiler.WriteFlattenedDiagnosticMessage(&output, d, newLine) diff --git a/internal/testutil/baseline/symbol_baseline.go b/internal/testutil/baseline/symbol_baseline.go new file mode 100644 index 0000000000..d50421a0f4 --- /dev/null +++ b/internal/testutil/baseline/symbol_baseline.go @@ -0,0 +1,335 @@ +package baseline + +import ( + "fmt" + "regexp" + "slices" + "strconv" + "strings" + "testing" + + "github.com/microsoft/typescript-go/internal/ast" + "github.com/microsoft/typescript-go/internal/compiler" + "github.com/microsoft/typescript-go/internal/core" + "github.com/microsoft/typescript-go/internal/scanner" + "github.com/microsoft/typescript-go/internal/tspath" +) + +var ( + codeLinesRegexp = regexp.MustCompile(`[\r\\u2028\\u2029]|\r?\n`) + bracketLineRegex = regexp.MustCompile(`^\s*[{|}]\s*$`) + lineEndRegex = regexp.MustCompile(`\r?\n`) +) + +func DoTypeAndSymbolBaseline( + t testing.TB, + baselinePath string, + header string, + program *compiler.Program, + allFiles []*TestFile, + opts *Options, + skipTypeBaselines bool, + skipSymbolBaselines bool, + hasErrorBaseline bool) { + // The full walker simulates the types that you would get from doing a full + // compile. The pull walker simulates the types you get when you just do + // a type query for a random node (like how the LS would do it). Most of the + // time, these will be the same. However, occasionally, they can be different. + // Specifically, when the compiler internally depends on symbol IDs to order + // things, then we may see different results because symbols can be created in a + // different order with 'pull' operations, and thus can produce slightly differing + // output. + // + // For example, with a full type check, we may see a type displayed as: number | string + // But with a pull type check, we may see it as: string | number + // + // These types are equivalent, but depend on what order the compiler observed + // certain parts of the program. + + fullWalker := newTypeWriterWalker(program, hasErrorBaseline) + + // Produce baselines. The first gives the types for all expressions. + // The second gives symbols for all identifiers. + typesError := checkBaselines(t, baselinePath, allFiles, fullWalker, header, opts, false /*isSymbolBaseline*/, skipTypeBaselines) + symbolsError := checkBaselines(t, baselinePath, allFiles, fullWalker, header, opts, true /*isSymbolBaseline*/, skipSymbolBaselines) + + if typesError != nil && symbolsError != nil { + panic(fmt.Sprintf("Both types and symbols baselines failed. Type baseline failure: %v\nSymbol baseline failure: %v", typesError, symbolsError)) + } + + if typesError != nil { + panic(typesError) + } + + if symbolsError != nil { + panic(symbolsError) + } +} + +func checkBaselines( + t testing.TB, + baselinePath string, + allFiles []*TestFile, + fullWalker *typeWriterWalker, + header string, + opts *Options, + isSymbolBaseline bool, + skipBaseline bool, +) (err interface{}) { + defer func() { + if r := recover(); r != nil { + err = r + } + }() + fullExtension := core.IfElse(isSymbolBaseline, ".symbols", ".types") + outputFileName := tspath.RemoveFileExtension(baselinePath) + fullBaseline := generateBaseline(allFiles, fullWalker, header, isSymbolBaseline, skipBaseline) + Run(t, outputFileName+fullExtension, fullBaseline, *opts) + return nil +} + +func generateBaseline( + allFiles []*TestFile, + fullWalker *typeWriterWalker, + header string, + isSymbolBaseline bool, + skipBaseline bool, +) string { + var result strings.Builder + // !!! Perf baseline + var perfLines []string + // prePerformanceValues := getPerformanceBaselineValues() + baselines := iterateBaseline(allFiles, fullWalker, isSymbolBaseline, skipBaseline) + for _, value := range baselines { + result.WriteString(value.content) + } + // postPerformanceValues := getPerformanceBaselineValues() + + if !isSymbolBaseline { + // !!! Perf baselines + // const perfStats: [name: string, reportThreshold: number, beforeValue: number, afterValue: number][] = []; + // perfStats.push(["Strict subtype cache", 1000, prePerformanceValues.strictSubtype, postPerformanceValues.strictSubtype]); + // perfStats.push(["Subtype cache", 1000, prePerformanceValues.subtype, postPerformanceValues.subtype]); + // perfStats.push(["Identity cache", 1000, prePerformanceValues.identity, postPerformanceValues.identity]); + // perfStats.push(["Assignability cache", 1000, prePerformanceValues.assignability, postPerformanceValues.assignability]); + // perfStats.push(["Type Count", 1000, prePerformanceValues.typeCount, postPerformanceValues.typeCount]); + // perfStats.push(["Instantiation count", 1500, prePerformanceValues.instantiation, postPerformanceValues.instantiation]); + // perfStats.push(["Symbol count", 45000, prePerformanceValues.symbol, postPerformanceValues.symbol]); + + // if (perfStats.some(([, threshold, , postValue]) => postValue >= threshold)) { + // perfLines.push(`=== Performance Stats ===`); + // for (const [name, threshold, preValue, postValue] of perfStats) { + // if (postValue >= threshold) { + // const preString = valueToString(preValue); + // const postString = valueToString(postValue); + // if (preString === postString) { + // perfLines.push(`${name}: ${preString}`); + // } + // else { + // perfLines.push(`${name}: ${preString} -> ${postString}`); + // } + // } + // } + // perfLines.push(""); + // perfLines.push(""); + // } + } + + if result.Len() > 0 { + return fmt.Sprintf("//// [%s] ////\r\n\r\n%s%s", header, strings.Join(perfLines, "\n"), result.String()) + } + return result.String() +} + +type baselineResult struct { + name string + content string +} + +func iterateBaseline(allFiles []*TestFile, fullWalker *typeWriterWalker, isSymbolBaseline bool, skipBaseline bool) []*baselineResult { + if skipBaseline { + return nil + } + + var baselines []*baselineResult + dupeCase := make(map[string]int) + + for _, file := range allFiles { + unitName := file.unitName + var typeLines strings.Builder + typeLines.WriteString("=== " + unitName + " ===\r\n") + codeLines := codeLinesRegexp.Split(file.content, -1) + var results []*typeWriterResult + if isSymbolBaseline { + results = fullWalker.getSymbols(unitName) + } else { + results = fullWalker.getTypes(unitName) + } + lastIndexWritten := -1 + for _, result := range results { + if isSymbolBaseline && result.symbol == "" { + return baselines + } + if lastIndexWritten == -1 { + typeLines.WriteString(strings.Join(codeLines[:result.line+1], "\r\n")) + typeLines.WriteString("\r\n") + } else if lastIndexWritten != result.line { + if !(lastIndexWritten+1 < len(codeLines) && + (bracketLineRegex.MatchString(codeLines[lastIndexWritten+1]) || strings.TrimSpace(codeLines[lastIndexWritten+1]) == "")) { + typeLines.WriteString("\r\n") + } + typeLines.WriteString(strings.Join(codeLines[lastIndexWritten+1:result.line+1], "\r\n")) + typeLines.WriteString("\r\n") + } + lastIndexWritten = result.line + typeOrSymbolString := core.IfElse(isSymbolBaseline, result.symbol, result.typ) + lineText := lineDelimiter.ReplaceAllString(result.sourceText, "") + typeLines.WriteString(">") + fmt.Fprintf(&typeLines, "%s : %s", lineText, typeOrSymbolString) + typeLines.WriteString("\r\n") + if result.underline != "" { + typeLines.WriteString(">") + for range len(lineText) { + typeLines.WriteString(" ") + } + typeLines.WriteString(" : ") + typeLines.WriteString(result.underline) + typeLines.WriteString("\r\n") + } + } + + if lastIndexWritten+1 < len(codeLines) { + if !(lastIndexWritten+1 < len(codeLines) && + (bracketLineRegex.MatchString(codeLines[lastIndexWritten+1]) || strings.TrimSpace(codeLines[lastIndexWritten+1]) == "")) { + typeLines.WriteString("\r\n") + } + typeLines.WriteString(strings.Join(codeLines[lastIndexWritten+1:], "\r\n")) + } + typeLines.WriteString("\r\n") + + baselines = append( + baselines, + &baselineResult{ + content: removeTestPathPrefixes(typeLines.String(), false /*retainTrailingDirectorySeparator*/), + name: checkDuplicatedFileName(unitName, dupeCase), + }) + } + + return baselines +} + +type typeWriterWalker struct { + program *compiler.Program + checker *compiler.Checker + hadErrorBaseline bool + currentSourceFile *ast.SourceFile + declarationTextCache map[*ast.Node]string +} + +func newTypeWriterWalker(program *compiler.Program, hadErrorBaseline bool) *typeWriterWalker { + return &typeWriterWalker{ + checker: program.GetTypeChecker(), + program: program, + hadErrorBaseline: hadErrorBaseline, + declarationTextCache: make(map[*ast.Node]string), + } +} + +type typeWriterResult struct { + line int + sourceText string + symbol string + typ string + underline string // !!! +} + +func (walker *typeWriterWalker) getTypes(filename string) []*typeWriterResult { + sourceFile := walker.program.GetSourceFile(filename) + walker.currentSourceFile = sourceFile + return walker.visitNode(sourceFile.AsNode(), false /*isSymbolWalk*/) +} + +func (walker *typeWriterWalker) getSymbols(filename string) []*typeWriterResult { + sourceFile := walker.program.GetSourceFile(filename) + walker.currentSourceFile = sourceFile + return walker.visitNode(sourceFile.AsNode(), true /*isSymbolWalk*/) +} + +func (walker *typeWriterWalker) visitNode(node *ast.Node, isSymbolWalk bool) []*typeWriterResult { + nodes := forEachASTNode(node) + var results []*typeWriterResult + for _, n := range nodes { + if compiler.IsExpressionNode(n) || n.Kind == ast.KindIdentifier || ast.IsDeclarationName(n) { + result := walker.writeTypeOrSymbol(n, isSymbolWalk) + if result != nil { + results = append(results, result) + } + } + } + return results +} + +func forEachASTNode(node *ast.Node) []*ast.Node { + var result []*ast.Node + work := []*ast.Node{node} + for len(work) > 0 { + elem := work[len(work)-1] + work = work[:len(work)-1] + result = append(result, elem) + + var resChildren []*ast.Node + elem.ForEachChild(func(child *ast.Node) bool { + resChildren = append(resChildren, child) + return false + }) + slices.Reverse(resChildren) + work = append(work, resChildren...) + } + return result +} + +func (walker *typeWriterWalker) writeTypeOrSymbol(node *ast.Node, isSymbolWalk bool) *typeWriterResult { + actualPos := scanner.SkipTrivia(walker.currentSourceFile.Text, node.Pos()) + line, _ := scanner.GetLineAndCharacterOfPosition(walker.currentSourceFile, actualPos) + sourceText := scanner.GetSourceTextOfNodeFromSourceFile(walker.currentSourceFile, node, false /*includeTrivia*/) + + if !isSymbolWalk { + // !!! Types baseline + } + + symbol := walker.checker.GetSymbolAtLocation(node /*ignoreErrors*/, true) + if symbol == nil { + return nil + } + + var symbolString strings.Builder + symbolString.WriteString("Symbol(" + walker.checker.SymbolToString(symbol)) + count := 0 + for _, declaration := range symbol.Declarations { + if count >= 5 { + fmt.Fprintf(&symbolString, " ... and %d more", len(symbol.Declarations)-count) + break + } + count++ + symbolString.WriteString(", ") + if declText, ok := walker.declarationTextCache[declaration]; ok { + symbolString.WriteString(declText) + continue + } + + declSourceFile := ast.GetSourceFileOfNode(declaration) + declLine, declChar := scanner.GetLineAndCharacterOfPosition(declSourceFile, declaration.Pos()) + fileName := tspath.GetBaseFileName(declSourceFile.FileName()) + isLibFile := isDefaultLibraryFile(fileName) + lineStr := strconv.Itoa(declLine) + charStr := strconv.Itoa(declChar) + declText := fmt.Sprintf("Decl(%s, %s, %s)", fileName, core.IfElse(isLibFile, "--", lineStr), core.IfElse(isLibFile, "--", charStr)) + symbolString.WriteString(declText) + } + symbolString.WriteString(")") + return &typeWriterResult{ + line: line, + sourceText: sourceText, + symbol: symbolString.String(), + } +} diff --git a/internal/testutil/baseline/util.go b/internal/testutil/baseline/util.go index f0c9deeae8..46af39d106 100644 --- a/internal/testutil/baseline/util.go +++ b/internal/testutil/baseline/util.go @@ -1,15 +1,21 @@ package baseline import ( + "fmt" "regexp" "strings" "github.com/microsoft/typescript-go/internal/tspath" ) -var testPathPrefix = regexp.MustCompile(`(?:(file:\/{3})|\/)\.(?:ts|lib|src)\/`) -var testPathCharacters = regexp.MustCompile(`[\^<>:"|?*%]`) -var testPathDotDot = regexp.MustCompile(`\.\.\/`) +var ( + lineDelimiter = regexp.MustCompile("\r?\n") + nonWhitespace = regexp.MustCompile(`\S`) + tsExtension = regexp.MustCompile(`\.tsx?$`) + testPathPrefix = regexp.MustCompile(`(?:(file:\/{3})|\/)\.(?:ts|lib|src)\/`) + testPathCharacters = regexp.MustCompile(`[\^<>:"|?*%]`) + testPathDotDot = regexp.MustCompile(`\.\.\/`) +) var libFolder = "built/local/" var builtFolder = "/.ts" @@ -47,3 +53,16 @@ func sanitizeTestFilePath(name string) string { path = string(tspath.ToPath(path, "", false /*useCaseSensitiveFileNames*/)) return strings.TrimPrefix(path, "/") } + +func checkDuplicatedFileName(resultName string, dupeCase map[string]int) string { + resultName = sanitizeTestFilePath(resultName) + if _, ok := dupeCase[resultName]; ok { + // A different baseline filename should be manufactured if the names differ only in case, for windows compat + count := 1 + dupeCase[resultName] + dupeCase[resultName] = count + resultName = fmt.Sprintf("%s.dupe%d", resultName, count) + } else { + dupeCase[resultName] = 0 + } + return resultName +} From a31164b561e8d92b85fd0869299b2c3f45a86ae8 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Tue, 17 Dec 2024 10:32:20 -0800 Subject: [PATCH 02/11] fix compiler errors --- internal/compiler/checker.go | 4 ++-- internal/compiler/printer.go | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/compiler/checker.go b/internal/compiler/checker.go index 4d85608a8e..25f03b37ad 100644 --- a/internal/compiler/checker.go +++ b/internal/compiler/checker.go @@ -8102,7 +8102,7 @@ func (c *Checker) getTargetOfModuleDefault(moduleSymbol *ast.Symbol, node *ast.N // } // exportEqualsSymbol := moduleSymbol.exports.get(ast.InternalSymbolNameExportEquals) // exportAssignment := exportEqualsSymbol.valueDeclaration - // err := c.error(node.name, Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, c.symbolToString(moduleSymbol), compilerOptionName) + // err := c.error(node.name, Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, c.SymbolToString(moduleSymbol), compilerOptionName) // if exportAssignment { // addRelatedInfo(err, createDiagnosticForNode(exportAssignment, Diagnostics.This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag, compilerOptionName)) @@ -12642,7 +12642,7 @@ func (c *Checker) getTypeOfMappedSymbol(symbol *ast.Symbol) *Type { propType = c.removeMissingOrUndefinedType(propType) } if !c.popTypeResolution() { - c.error(c.currentNode, diagnostics.Type_of_property_0_circularly_references_itself_in_mapped_type_1, c.symbolToString(symbol), c.typeToString(mappedType)) + c.error(c.currentNode, diagnostics.Type_of_property_0_circularly_references_itself_in_mapped_type_1, c.SymbolToString(symbol), c.typeToString(mappedType)) propType = c.errorType } if links.resolvedType == nil { diff --git a/internal/compiler/printer.go b/internal/compiler/printer.go index 13d91ad7f8..24f3071f42 100644 --- a/internal/compiler/printer.go +++ b/internal/compiler/printer.go @@ -89,7 +89,7 @@ func (p *Printer) print(s string) { } func (p *Printer) printName(symbol *ast.Symbol) { - p.print(p.c.symbolToString(symbol)) + p.print(p.c.SymbolToString(symbol)) } func (p *Printer) printTypeEx(t *Type, precedence ast.TypePrecedence) { @@ -562,10 +562,10 @@ func (c *Checker) getTextAndTypeOfNode(node *ast.Node) (string, *Type, bool) { symbol := node.Symbol() if symbol != nil && !isReservedMemberName(symbol.Name) { if symbol.Flags&ast.SymbolFlagsValue != 0 { - return c.symbolToString(symbol), c.getTypeOfSymbol(symbol), true + return c.SymbolToString(symbol), c.getTypeOfSymbol(symbol), true } if symbol.Flags&ast.SymbolFlagsTypeAlias != 0 { - return c.symbolToString(symbol), c.getDeclaredTypeOfTypeAlias(symbol), true + return c.SymbolToString(symbol), c.getDeclaredTypeOfTypeAlias(symbol), true } } } From 68de1dc9c9668b751faba6c3e93abc9739313924 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Wed, 18 Dec 2024 14:12:39 -0800 Subject: [PATCH 03/11] remove unnecessary code --- internal/testutil/baseline/symbol_baseline.go | 38 +++---------------- 1 file changed, 6 insertions(+), 32 deletions(-) diff --git a/internal/testutil/baseline/symbol_baseline.go b/internal/testutil/baseline/symbol_baseline.go index d50421a0f4..552c657eac 100644 --- a/internal/testutil/baseline/symbol_baseline.go +++ b/internal/testutil/baseline/symbol_baseline.go @@ -48,22 +48,8 @@ func DoTypeAndSymbolBaseline( fullWalker := newTypeWriterWalker(program, hasErrorBaseline) - // Produce baselines. The first gives the types for all expressions. - // The second gives symbols for all identifiers. - typesError := checkBaselines(t, baselinePath, allFiles, fullWalker, header, opts, false /*isSymbolBaseline*/, skipTypeBaselines) - symbolsError := checkBaselines(t, baselinePath, allFiles, fullWalker, header, opts, true /*isSymbolBaseline*/, skipSymbolBaselines) - - if typesError != nil && symbolsError != nil { - panic(fmt.Sprintf("Both types and symbols baselines failed. Type baseline failure: %v\nSymbol baseline failure: %v", typesError, symbolsError)) - } - - if typesError != nil { - panic(typesError) - } - - if symbolsError != nil { - panic(symbolsError) - } + checkBaselines(t, baselinePath, allFiles, fullWalker, header, opts, false /*isSymbolBaseline*/) + checkBaselines(t, baselinePath, allFiles, fullWalker, header, opts, true /*isSymbolBaseline*/) } func checkBaselines( @@ -74,18 +60,11 @@ func checkBaselines( header string, opts *Options, isSymbolBaseline bool, - skipBaseline bool, -) (err interface{}) { - defer func() { - if r := recover(); r != nil { - err = r - } - }() +) { fullExtension := core.IfElse(isSymbolBaseline, ".symbols", ".types") outputFileName := tspath.RemoveFileExtension(baselinePath) - fullBaseline := generateBaseline(allFiles, fullWalker, header, isSymbolBaseline, skipBaseline) + fullBaseline := generateBaseline(allFiles, fullWalker, header, isSymbolBaseline) Run(t, outputFileName+fullExtension, fullBaseline, *opts) - return nil } func generateBaseline( @@ -93,13 +72,12 @@ func generateBaseline( fullWalker *typeWriterWalker, header string, isSymbolBaseline bool, - skipBaseline bool, ) string { var result strings.Builder // !!! Perf baseline var perfLines []string // prePerformanceValues := getPerformanceBaselineValues() - baselines := iterateBaseline(allFiles, fullWalker, isSymbolBaseline, skipBaseline) + baselines := iterateBaseline(allFiles, fullWalker, isSymbolBaseline) for _, value := range baselines { result.WriteString(value.content) } @@ -146,11 +124,7 @@ type baselineResult struct { content string } -func iterateBaseline(allFiles []*TestFile, fullWalker *typeWriterWalker, isSymbolBaseline bool, skipBaseline bool) []*baselineResult { - if skipBaseline { - return nil - } - +func iterateBaseline(allFiles []*TestFile, fullWalker *typeWriterWalker, isSymbolBaseline bool) []*baselineResult { var baselines []*baselineResult dupeCase := make(map[string]int) From e892a6849475f663ccce76d192787a2ec51f2c27 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Wed, 18 Dec 2024 14:15:03 -0800 Subject: [PATCH 04/11] pass down options instead of pointer --- internal/testutil/baseline/symbol_baseline.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/testutil/baseline/symbol_baseline.go b/internal/testutil/baseline/symbol_baseline.go index 552c657eac..b2b6edbd02 100644 --- a/internal/testutil/baseline/symbol_baseline.go +++ b/internal/testutil/baseline/symbol_baseline.go @@ -27,7 +27,7 @@ func DoTypeAndSymbolBaseline( header string, program *compiler.Program, allFiles []*TestFile, - opts *Options, + opts Options, skipTypeBaselines bool, skipSymbolBaselines bool, hasErrorBaseline bool) { @@ -58,13 +58,13 @@ func checkBaselines( allFiles []*TestFile, fullWalker *typeWriterWalker, header string, - opts *Options, + opts Options, isSymbolBaseline bool, ) { fullExtension := core.IfElse(isSymbolBaseline, ".symbols", ".types") outputFileName := tspath.RemoveFileExtension(baselinePath) fullBaseline := generateBaseline(allFiles, fullWalker, header, isSymbolBaseline) - Run(t, outputFileName+fullExtension, fullBaseline, *opts) + Run(t, outputFileName+fullExtension, fullBaseline, opts) } func generateBaseline( From 619db638e2e8beb3f06b25d7f6b64635dbfcd0d9 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Fri, 3 Jan 2025 11:14:07 -0800 Subject: [PATCH 05/11] use testing.T in baselines --- internal/testutil/baseline/baseline.go | 4 ++-- internal/testutil/baseline/error_baseline.go | 6 +++--- internal/testutil/baseline/symbol_baseline.go | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/testutil/baseline/baseline.go b/internal/testutil/baseline/baseline.go index 42eb483577..382dcb72eb 100644 --- a/internal/testutil/baseline/baseline.go +++ b/internal/testutil/baseline/baseline.go @@ -15,11 +15,11 @@ type Options struct { const NoContent = "" -func Run(t testing.TB, fileName string, actual string, opts Options) { +func Run(t *testing.T, fileName string, actual string, opts Options) { writeComparison(t, actual, fileName, opts) } -func writeComparison(t testing.TB, actual string, relativeFileName string, opts Options) { +func writeComparison(t *testing.T, actual string, relativeFileName string, opts Options) { if actual == "" { panic("The generated content was \"\". Return 'baseline.NoContent' if no baselining is required.") } diff --git a/internal/testutil/baseline/error_baseline.go b/internal/testutil/baseline/error_baseline.go index 99f47fd9e2..62d7ef3802 100644 --- a/internal/testutil/baseline/error_baseline.go +++ b/internal/testutil/baseline/error_baseline.go @@ -32,7 +32,7 @@ type TestFile struct { var diagnosticsLocationPrefix = regexp.MustCompile(`(?im)^(lib.*\.d\.ts)\(\d+,\d+\)`) var diagnosticsLocationPattern = regexp.MustCompile(`(?i)(lib.*\.d\.ts):\d+:\d+`) -func DoErrorBaseline(t testing.TB, baselinePath string, inputFiles []*TestFile, errors []*ast.Diagnostic, pretty bool) { +func DoErrorBaseline(t *testing.T, baselinePath string, inputFiles []*TestFile, errors []*ast.Diagnostic, pretty bool) { baselinePath = tsExtension.ReplaceAllString(baselinePath, ".errors.txt") var errorBaseline string if len(errors) > 0 { @@ -53,7 +53,7 @@ func minimalDiagnosticsToString(diagnostics []*ast.Diagnostic, pretty bool) stri return output.String() } -func getErrorBaseline(t testing.TB, inputFiles []*TestFile, diagnostics []*ast.Diagnostic, pretty bool) string { +func getErrorBaseline(t *testing.T, inputFiles []*TestFile, diagnostics []*ast.Diagnostic, pretty bool) string { t.Helper() outputLines := iterateErrorBaseline(t, inputFiles, diagnostics, pretty) @@ -69,7 +69,7 @@ func getErrorBaseline(t testing.TB, inputFiles []*TestFile, diagnostics []*ast.D return strings.Join(outputLines, "") } -func iterateErrorBaseline(t testing.TB, inputFiles []*TestFile, inputDiagnostics []*ast.Diagnostic, pretty bool) []string { +func iterateErrorBaseline(t *testing.T, inputFiles []*TestFile, inputDiagnostics []*ast.Diagnostic, pretty bool) []string { t.Helper() diagnostics := slices.Clone(inputDiagnostics) slices.SortFunc(diagnostics, compiler.CompareDiagnostics) diff --git a/internal/testutil/baseline/symbol_baseline.go b/internal/testutil/baseline/symbol_baseline.go index b2b6edbd02..6d5b7986f1 100644 --- a/internal/testutil/baseline/symbol_baseline.go +++ b/internal/testutil/baseline/symbol_baseline.go @@ -22,7 +22,7 @@ var ( ) func DoTypeAndSymbolBaseline( - t testing.TB, + t *testing.T, baselinePath string, header string, program *compiler.Program, @@ -53,7 +53,7 @@ func DoTypeAndSymbolBaseline( } func checkBaselines( - t testing.TB, + t *testing.T, baselinePath string, allFiles []*TestFile, fullWalker *typeWriterWalker, From 7bd349e557824f3da34975021aa2ab0fdfe915f5 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Fri, 3 Jan 2025 11:17:37 -0800 Subject: [PATCH 06/11] run type and symbol baselines as subtests --- internal/testutil/baseline/symbol_baseline.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/internal/testutil/baseline/symbol_baseline.go b/internal/testutil/baseline/symbol_baseline.go index 6d5b7986f1..daea0e8f51 100644 --- a/internal/testutil/baseline/symbol_baseline.go +++ b/internal/testutil/baseline/symbol_baseline.go @@ -48,8 +48,12 @@ func DoTypeAndSymbolBaseline( fullWalker := newTypeWriterWalker(program, hasErrorBaseline) - checkBaselines(t, baselinePath, allFiles, fullWalker, header, opts, false /*isSymbolBaseline*/) - checkBaselines(t, baselinePath, allFiles, fullWalker, header, opts, true /*isSymbolBaseline*/) + t.Run("type", func(t *testing.T) { + checkBaselines(t, baselinePath, allFiles, fullWalker, header, opts, false /*isSymbolBaseline*/) + }) + t.Run("symbol", func(t *testing.T) { + checkBaselines(t, baselinePath, allFiles, fullWalker, header, opts, true /*isSymbolBaseline*/) + }) } func checkBaselines( From 4f61e6d8ba7a994bf140b629111157f74cb655a9 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Fri, 3 Jan 2025 12:31:40 -0800 Subject: [PATCH 07/11] fix fmt and merge bug --- internal/compiler/checker_test.go | 2 +- internal/testutil/baseline/symbol_baseline.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/compiler/checker_test.go b/internal/compiler/checker_test.go index 945f7a59a8..b13548535a 100644 --- a/internal/compiler/checker_test.go +++ b/internal/compiler/checker_test.go @@ -33,7 +33,7 @@ foo.bar;` } p := NewProgram(opts) p.bindSourceFiles() - c := p.getTypeChecker() + c := p.GetTypeChecker() file := p.filesByPath["/foo.ts"] interfaceId := file.Statements.Nodes[0].Name() varId := file.Statements.Nodes[1].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0].Name() diff --git a/internal/testutil/baseline/symbol_baseline.go b/internal/testutil/baseline/symbol_baseline.go index daea0e8f51..b8010d55cd 100644 --- a/internal/testutil/baseline/symbol_baseline.go +++ b/internal/testutil/baseline/symbol_baseline.go @@ -30,7 +30,8 @@ func DoTypeAndSymbolBaseline( opts Options, skipTypeBaselines bool, skipSymbolBaselines bool, - hasErrorBaseline bool) { + hasErrorBaseline bool, +) { // The full walker simulates the types that you would get from doing a full // compile. The pull walker simulates the types you get when you just do // a type query for a random node (like how the LS would do it). Most of the From 4aaed8820e68016ce2d91da6ec00b19ce013b852 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Fri, 3 Jan 2025 15:56:40 -0800 Subject: [PATCH 08/11] fix regex and helper for symbol baselines --- internal/ast/utilities.go | 2 +- internal/testutil/baseline/symbol_baseline.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/ast/utilities.go b/internal/ast/utilities.go index 6c36d54efc..281bd540bd 100644 --- a/internal/ast/utilities.go +++ b/internal/ast/utilities.go @@ -1123,7 +1123,7 @@ func IsDeclaration(node *Node) bool { // True if `name` is the name of a declaration node func IsDeclarationName(name *Node) bool { - return !IsSourceFile(name) && !IsBindingPattern(name) && IsDeclaration(name.Parent) + return !IsSourceFile(name) && !IsBindingPattern(name) && IsDeclaration(name.Parent) && name.Parent.Name() == name } // Like 'isDeclarationName', but returns true for LHS of `import { x as y }` or `export { x as y }`. diff --git a/internal/testutil/baseline/symbol_baseline.go b/internal/testutil/baseline/symbol_baseline.go index b8010d55cd..66528cbbae 100644 --- a/internal/testutil/baseline/symbol_baseline.go +++ b/internal/testutil/baseline/symbol_baseline.go @@ -16,7 +16,7 @@ import ( ) var ( - codeLinesRegexp = regexp.MustCompile(`[\r\\u2028\\u2029]|\r?\n`) + codeLinesRegexp = regexp.MustCompile("[\r\u2028\u2029]|\r?\n") bracketLineRegex = regexp.MustCompile(`^\s*[{|}]\s*$`) lineEndRegex = regexp.MustCompile(`\r?\n`) ) From de513325f7a631b6cc406afa0a98b1f3617eb78c Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Mon, 6 Jan 2025 11:00:56 -0800 Subject: [PATCH 09/11] remove useless checkDuplicateName --- internal/testutil/baseline/error_baseline.go | 1 - internal/testutil/baseline/symbol_baseline.go | 18 +++++------------- internal/testutil/baseline/util.go | 14 -------------- 3 files changed, 5 insertions(+), 28 deletions(-) diff --git a/internal/testutil/baseline/error_baseline.go b/internal/testutil/baseline/error_baseline.go index 1796f6c0be..244bf9502a 100644 --- a/internal/testutil/baseline/error_baseline.go +++ b/internal/testutil/baseline/error_baseline.go @@ -219,7 +219,6 @@ func iterateErrorBaseline(t *testing.T, inputFiles []*TestFile, inputDiagnostics // Verify we didn't miss any errors in this file assert.Check(t, cmp.Equal(markedErrorCount, len(fileErrors)), "count of errors in "+inputFile.unitName) _, isDupe := dupeCase[sanitizeTestFilePath(inputFile.unitName)] - checkDuplicatedFileName(inputFile.unitName, dupeCase) result = append(result, outputLines.String()) if isDupe { // Case-duplicated files on a case-insensitive build will have errors reported in both the dupe and the original diff --git a/internal/testutil/baseline/symbol_baseline.go b/internal/testutil/baseline/symbol_baseline.go index 66528cbbae..588f520766 100644 --- a/internal/testutil/baseline/symbol_baseline.go +++ b/internal/testutil/baseline/symbol_baseline.go @@ -84,7 +84,7 @@ func generateBaseline( // prePerformanceValues := getPerformanceBaselineValues() baselines := iterateBaseline(allFiles, fullWalker, isSymbolBaseline) for _, value := range baselines { - result.WriteString(value.content) + result.WriteString(value) } // postPerformanceValues := getPerformanceBaselineValues() @@ -124,14 +124,8 @@ func generateBaseline( return result.String() } -type baselineResult struct { - name string - content string -} - -func iterateBaseline(allFiles []*TestFile, fullWalker *typeWriterWalker, isSymbolBaseline bool) []*baselineResult { - var baselines []*baselineResult - dupeCase := make(map[string]int) +func iterateBaseline(allFiles []*TestFile, fullWalker *typeWriterWalker, isSymbolBaseline bool) []string { + var baselines []string for _, file := range allFiles { unitName := file.unitName @@ -188,10 +182,8 @@ func iterateBaseline(allFiles []*TestFile, fullWalker *typeWriterWalker, isSymbo baselines = append( baselines, - &baselineResult{ - content: removeTestPathPrefixes(typeLines.String(), false /*retainTrailingDirectorySeparator*/), - name: checkDuplicatedFileName(unitName, dupeCase), - }) + removeTestPathPrefixes(typeLines.String(), false /*retainTrailingDirectorySeparator*/), + ) } return baselines diff --git a/internal/testutil/baseline/util.go b/internal/testutil/baseline/util.go index 61777046eb..2ba94a6654 100644 --- a/internal/testutil/baseline/util.go +++ b/internal/testutil/baseline/util.go @@ -1,7 +1,6 @@ package baseline import ( - "fmt" "regexp" "strings" @@ -55,16 +54,3 @@ func sanitizeTestFilePath(name string) string { path = string(tspath.ToPath(path, "", false /*useCaseSensitiveFileNames*/)) return strings.TrimPrefix(path, "/") } - -func checkDuplicatedFileName(resultName string, dupeCase map[string]int) string { - resultName = sanitizeTestFilePath(resultName) - if _, ok := dupeCase[resultName]; ok { - // A different baseline filename should be manufactured if the names differ only in case, for windows compat - count := 1 + dupeCase[resultName] - dupeCase[resultName] = count - resultName = fmt.Sprintf("%s.dupe%d", resultName, count) - } else { - dupeCase[resultName] = 0 - } - return resultName -} From 024e9b92889a5035dffd9291aa8b24f31ae954a5 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Tue, 7 Jan 2025 11:28:09 -0800 Subject: [PATCH 10/11] create public versions of getSymbolAtLocation and symbolToString --- internal/compiler/checker.go | 98 ++++++++++--------- internal/compiler/checker_test.go | 2 +- internal/compiler/flow.go | 6 +- internal/compiler/printer.go | 10 +- internal/compiler/relater.go | 30 +++--- internal/testutil/baseline/symbol_baseline.go | 2 +- 6 files changed, 80 insertions(+), 68 deletions(-) diff --git a/internal/compiler/checker.go b/internal/compiler/checker.go index 1e0f73134e..6f5d1e2d98 100644 --- a/internal/compiler/checker.go +++ b/internal/compiler/checker.go @@ -2366,7 +2366,7 @@ func (c *Checker) checkVarDeclaredNamesNotShadowed(node *ast.Node) { // here we know that function scoped variable is "shadowed" by block scoped one // a var declatation can't hoist past a lexical declaration and it results in a SyntaxError at runtime if !namesShareScope { - name := c.SymbolToString(localDeclarationSymbol) + name := c.symbolToString(localDeclarationSymbol) c.error(node, diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name, name) } } @@ -5593,14 +5593,14 @@ func (c *Checker) checkIdentifier(node *ast.Node, checkMode CheckMode) *Type { default: assignmentError = diagnostics.Cannot_assign_to_0_because_it_is_not_a_variable } - c.error(node, assignmentError, c.SymbolToString(symbol)) + c.error(node, assignmentError, c.symbolToString(symbol)) return c.errorType } if c.isReadonlySymbol(localOrExportSymbol) { if localOrExportSymbol.Flags&ast.SymbolFlagsVariable != 0 { - c.error(node, diagnostics.Cannot_assign_to_0_because_it_is_a_constant, c.SymbolToString(symbol)) + c.error(node, diagnostics.Cannot_assign_to_0_because_it_is_a_constant, c.symbolToString(symbol)) } else { - c.error(node, diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, c.SymbolToString(symbol)) + c.error(node, diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, c.symbolToString(symbol)) } return c.errorType } @@ -5685,13 +5685,13 @@ func (c *Checker) checkIdentifier(node *ast.Node, checkMode CheckMode) *Type { if !c.isEvolvingArrayOperationTarget(node) && (t == c.autoType || t == c.autoArrayType) { if flowType == c.autoType || flowType == c.autoArrayType { if c.noImplicitAny { - c.error(ast.GetNameOfDeclaration(declaration), diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined, c.SymbolToString(symbol), c.typeToString(flowType)) - c.error(node, diagnostics.Variable_0_implicitly_has_an_1_type, c.SymbolToString(symbol), c.typeToString(flowType)) + c.error(ast.GetNameOfDeclaration(declaration), diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined, c.symbolToString(symbol), c.typeToString(flowType)) + c.error(node, diagnostics.Variable_0_implicitly_has_an_1_type, c.symbolToString(symbol), c.typeToString(flowType)) } return c.convertAutoToAny(flowType) } } else if !assumeInitialized && !c.containsUndefinedType(t) && c.containsUndefinedType(flowType) { - c.error(node, diagnostics.Variable_0_is_used_before_being_assigned, c.SymbolToString(symbol)) + c.error(node, diagnostics.Variable_0_is_used_before_being_assigned, c.symbolToString(symbol)) // Return the declared type to reduce follow-on errors return t } @@ -5925,7 +5925,7 @@ func (c *Checker) getFlowTypeOfAccessExpression(node *ast.Node, prop *ast.Symbol } flowType := c.getFlowTypeOfReferenceEx(node, propType, initialType, nil, nil) if assumeUninitialized && !c.containsUndefinedType(propType) && c.containsUndefinedType(flowType) { - c.error(errorNode, diagnostics.Property_0_is_used_before_being_assigned, c.SymbolToString(prop)) + c.error(errorNode, diagnostics.Property_0_is_used_before_being_assigned, c.symbolToString(prop)) // Return the declared type to reduce follow-on errors return propType } @@ -6202,7 +6202,7 @@ func (c *Checker) checkPropertyAccessibilityAtLocation(location *ast.Node, isSup // cannot simultaneously be private and abstract, so this will trigger an // additional error elsewhere. if errorNode != nil { - c.error(errorNode, diagnostics.Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression, c.SymbolToString(prop), c.typeToString(c.getDeclaringClass(prop))) + c.error(errorNode, diagnostics.Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression, c.symbolToString(prop), c.typeToString(c.getDeclaringClass(prop))) } return false } @@ -6210,7 +6210,7 @@ func (c *Checker) checkPropertyAccessibilityAtLocation(location *ast.Node, isSup // This is true for both [[Set]] (old) and [[Define]] (ES spec) semantics. if flags&ast.ModifierFlagsStatic == 0 && core.Some(prop.Declarations, isClassInstanceProperty) { if errorNode != nil { - c.error(errorNode, diagnostics.Class_field_0_defined_by_the_parent_class_is_not_accessible_in_the_child_class_via_super, c.SymbolToString(prop)) + c.error(errorNode, diagnostics.Class_field_0_defined_by_the_parent_class_is_not_accessible_in_the_child_class_via_super, c.symbolToString(prop)) } return false } @@ -6222,7 +6222,7 @@ func (c *Checker) checkPropertyAccessibilityAtLocation(location *ast.Node, isSup declaringClassDeclaration := getClassLikeDeclarationOfSymbol(c.getParentOfSymbol(prop)) if declaringClassDeclaration != nil && c.isNodeUsedDuringClassInitialization(location) { if errorNode != nil { - c.error(errorNode, diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, c.SymbolToString(prop), declaringClassDeclaration.Name().Text()) + c.error(errorNode, diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, c.symbolToString(prop), declaringClassDeclaration.Name().Text()) } return false } @@ -6237,7 +6237,7 @@ func (c *Checker) checkPropertyAccessibilityAtLocation(location *ast.Node, isSup declaringClassDeclaration := getClassLikeDeclarationOfSymbol(c.getParentOfSymbol(prop)) if !c.isNodeWithinClass(location, declaringClassDeclaration) { if errorNode != nil { - c.error(errorNode, diagnostics.Property_0_is_private_and_only_accessible_within_class_1, c.SymbolToString(prop), c.typeToString(c.getDeclaringClass(prop))) + c.error(errorNode, diagnostics.Property_0_is_private_and_only_accessible_within_class_1, c.symbolToString(prop), c.typeToString(c.getDeclaringClass(prop))) } return false } @@ -6274,7 +6274,7 @@ func (c *Checker) checkPropertyAccessibilityAtLocation(location *ast.Node, isSup if class == nil { class = containingType } - c.error(errorNode, diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses, c.SymbolToString(prop), c.typeToString(class)) + c.error(errorNode, diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses, c.symbolToString(prop), c.typeToString(class)) } return false } @@ -6293,7 +6293,7 @@ func (c *Checker) checkPropertyAccessibilityAtLocation(location *ast.Node, isSup } if containingType == nil || !c.hasBaseType(containingType, enclosingClass) { if errorNode != nil && containingType != nil { - c.error(errorNode, diagnostics.Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1_This_is_an_instance_of_class_2, c.SymbolToString(prop), c.typeToString(enclosingClass), c.typeToString(containingType)) + c.error(errorNode, diagnostics.Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1_This_is_an_instance_of_class_2, c.symbolToString(prop), c.typeToString(enclosingClass), c.typeToString(containingType)) } return false } @@ -7318,7 +7318,7 @@ func (c *Checker) checkObjectLiteral(node *ast.Node, checkMode CheckMode) *Type if impliedProp != nil { prop.Flags |= impliedProp.Flags & ast.SymbolFlagsOptional } else if c.getIndexInfoOfType(contextualType, c.stringType) == nil { - c.error(memberDecl.Name(), diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, c.SymbolToString(member), c.typeToString(contextualType)) + c.error(memberDecl.Name(), diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, c.symbolToString(member), c.typeToString(contextualType)) } } prop.Declarations = member.Declarations @@ -8048,7 +8048,7 @@ func (c *Checker) mergeSymbol(target *ast.Symbol, source *ast.Symbol, unidirecti // as we will already report a "Declaration name conflicts..." error, and this error // won't make much sense. if target != c.globalThisSymbol { - c.error(ast.GetNameOfDeclaration(getFirstDeclaration(source)), diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, c.SymbolToString(target)) + c.error(ast.GetNameOfDeclaration(getFirstDeclaration(source)), diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, c.symbolToString(target)) } } else { c.reportMergeSymbolError(target, source) @@ -8070,7 +8070,7 @@ func (c *Checker) reportMergeSymbolError(target *ast.Symbol, source *ast.Symbol) } // sourceSymbolFile := ast.GetSourceFileOfNode(getFirstDeclaration(source)) // targetSymbolFile := ast.GetSourceFileOfNode(getFirstDeclaration(target)) - symbolName := c.SymbolToString(source) + symbolName := c.symbolToString(source) // !!! // Collect top-level duplicate identifier errors into one mapping, so we can then merge their diagnostics if there are a bunch // if sourceSymbolFile != nil && targetSymbolFile != nil && c.amalgamatedDuplicates && !isEitherEnum && sourceSymbolFile != targetSymbolFile { @@ -8729,7 +8729,7 @@ func (c *Checker) errorNoModuleMemberSymbol(moduleSymbol *ast.Symbol, targetSymb suggestion = c.getSuggestedSymbolForNonexistentModule(name, targetSymbol) } if suggestion != nil { - suggestionName := c.SymbolToString(suggestion) + suggestionName := c.symbolToString(suggestion) diagnostic := c.error(name, diagnostics.X_0_has_no_exported_member_named_1_Did_you_mean_2, moduleName, declarationName, suggestionName) if suggestion.ValueDeclaration != nil { diagnostic.AddRelatedInfo(createDiagnosticForNode(suggestion.ValueDeclaration, diagnostics.X_0_is_declared_here, suggestionName)) @@ -8762,7 +8762,7 @@ func (c *Checker) reportNonExportedMember(node *ast.Node, name *ast.Node, declar }) var diagnostic *ast.Diagnostic if exportedSymbol != nil { - diagnostic = c.error(name, diagnostics.Module_0_declares_1_locally_but_it_is_exported_as_2, moduleName, declarationName, c.SymbolToString(exportedSymbol)) + diagnostic = c.error(name, diagnostics.Module_0_declares_1_locally_but_it_is_exported_as_2, moduleName, declarationName, c.symbolToString(exportedSymbol)) } else { diagnostic = c.error(name, diagnostics.Module_0_declares_1_locally_but_it_is_not_exported, moduleName, declarationName) } @@ -9243,7 +9243,7 @@ func (c *Checker) resolveQualifiedName(name *ast.Node, left *ast.Node, right *as declarationName := scanner.DeclarationNameToString(right) suggestionForNonexistentModule := c.getSuggestedSymbolForNonexistentModule(right, namespace) if suggestionForNonexistentModule != nil { - c.error(right, diagnostics.X_0_has_no_exported_member_named_1_Did_you_mean_2, namespaceName, declarationName, c.SymbolToString(suggestionForNonexistentModule)) + c.error(right, diagnostics.X_0_has_no_exported_member_named_1_Did_you_mean_2, namespaceName, declarationName, c.symbolToString(suggestionForNonexistentModule)) return nil } var containingQualifiedName *ast.Node @@ -9260,7 +9260,7 @@ func (c *Checker) resolveQualifiedName(name *ast.Node, left *ast.Node, right *as exportedTypeSymbol := c.getMergedSymbol(c.getSymbol(c.getExportsOfSymbol(namespace), text, ast.SymbolFlagsType)) if exportedTypeSymbol != nil { qualified := name.Parent.AsQualifiedName() - c.error(qualified.Right, diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1, c.SymbolToString(exportedTypeSymbol), qualified.Right.AsIdentifier().Text) + c.error(qualified.Right, diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1, c.symbolToString(exportedTypeSymbol), qualified.Right.AsIdentifier().Text) return nil } } @@ -9295,9 +9295,9 @@ func (c *Checker) getSuggestedSymbolForNonexistentModule(name *ast.Node, targetM func (c *Checker) getFullyQualifiedName(symbol *ast.Symbol, containingLocation *ast.Node) string { if symbol.Parent != nil { - return c.getFullyQualifiedName(symbol.Parent, containingLocation) + "." + c.SymbolToString(symbol) + return c.getFullyQualifiedName(symbol.Parent, containingLocation) + "." + c.symbolToString(symbol) } - return c.SymbolToString(symbol) // !!! + return c.symbolToString(symbol) // !!! } func (c *Checker) getExportsOfSymbol(symbol *ast.Symbol) ast.SymbolTable { @@ -9622,7 +9622,7 @@ func (c *Checker) resolveAlias(symbol *ast.Symbol) *ast.Symbol { } links.aliasTarget = target } else { - c.error(node, diagnostics.Circular_definition_of_import_alias_0, c.SymbolToString(symbol)) + c.error(node, diagnostics.Circular_definition_of_import_alias_0, c.symbolToString(symbol)) } } else if links.aliasTarget == c.resolvingSymbol { links.aliasTarget = c.unknownSymbol @@ -10162,7 +10162,7 @@ func (c *Checker) getBaseConstructorTypeOfClass(t *Type) *Type { c.resolveStructuredTypeMembers(baseConstructorType) } if !c.popTypeResolution() { - c.error(t.symbol.ValueDeclaration, diagnostics.X_0_is_referenced_directly_or_indirectly_in_its_own_base_expression, c.SymbolToString(t.symbol)) + c.error(t.symbol.ValueDeclaration, diagnostics.X_0_is_referenced_directly_or_indirectly_in_its_own_base_expression, c.symbolToString(t.symbol)) if data.resolvedBaseConstructorType == nil { data.resolvedBaseConstructorType = c.errorType } @@ -10180,7 +10180,7 @@ func (c *Checker) getBaseConstructorTypeOfClass(t *Type) *Type { } } if baseConstructorType.symbol.Declarations != nil { - err.AddRelatedInfo(createDiagnosticForNode(baseConstructorType.symbol.Declarations[0], diagnostics.Did_you_mean_for_0_to_be_constrained_to_type_new_args_Colon_any_1, c.SymbolToString(baseConstructorType.symbol), c.typeToString(ctorReturn))) + err.AddRelatedInfo(createDiagnosticForNode(baseConstructorType.symbol.Declarations[0], diagnostics.Did_you_mean_for_0_to_be_constrained_to_type_new_args_Colon_any_1, c.symbolToString(baseConstructorType.symbol), c.typeToString(ctorReturn))) } } if data.resolvedBaseConstructorType == nil { @@ -11607,17 +11607,17 @@ func (c *Checker) reportCircularityError(symbol *ast.Symbol) *Type { // Check if variable has type annotation that circularly references the variable itself if declaration != nil { if declaration.Type() != nil { - c.error(symbol.ValueDeclaration, diagnostics.X_0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, c.SymbolToString(symbol)) + c.error(symbol.ValueDeclaration, diagnostics.X_0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, c.symbolToString(symbol)) return c.errorType } // Check if variable has initializer that circularly references the variable itself if c.noImplicitAny && (!ast.IsParameter(declaration) || declaration.Initializer() != nil) { - c.error(symbol.ValueDeclaration, diagnostics.X_0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer, c.SymbolToString(symbol)) + c.error(symbol.ValueDeclaration, diagnostics.X_0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer, c.symbolToString(symbol)) } } else if symbol.Flags&ast.SymbolFlagsAlias != 0 { node := c.getDeclarationOfAliasSymbol(symbol) if node != nil { - c.error(node, diagnostics.Circular_definition_of_import_alias_0, c.SymbolToString(symbol)) + c.error(node, diagnostics.Circular_definition_of_import_alias_0, c.symbolToString(symbol)) } } // Circularities could also result from parameters in function expressions that end up @@ -13202,7 +13202,7 @@ func (c *Checker) reportWideningErrorsInType(t *Type) bool { return valueDeclaration != nil && valueDeclaration.Parent == t.symbol.ValueDeclaration }) if valueDeclaration != nil { - c.error(valueDeclaration, diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, c.SymbolToString(p), c.typeToString(c.getWidenedType(s))) + c.error(valueDeclaration, diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, c.symbolToString(p), c.typeToString(c.getWidenedType(s))) errorReported = true } } @@ -13685,7 +13685,7 @@ func (c *Checker) getTypeOfMappedSymbol(symbol *ast.Symbol) *Type { propType = c.removeMissingOrUndefinedType(propType) } if !c.popTypeResolution() { - c.error(c.currentNode, diagnostics.Type_of_property_0_circularly_references_itself_in_mapped_type_1, c.SymbolToString(symbol), c.typeToString(mappedType)) + c.error(c.currentNode, diagnostics.Type_of_property_0_circularly_references_itself_in_mapped_type_1, c.symbolToString(symbol), c.typeToString(mappedType)) propType = c.errorType } if links.resolvedType == nil { @@ -14498,11 +14498,11 @@ func (c *Checker) elaborateNeverIntersection(chain *ast.Diagnostic, node *ast.No if t.flags&TypeFlagsIntersection != 0 && t.objectFlags&ObjectFlagsIsNeverIntersection != 0 { neverProp := core.Find(c.getPropertiesOfUnionOrIntersectionType(t), c.isDiscriminantWithNeverType) if neverProp != nil { - return NewDiagnosticChainForNode(chain, node, diagnostics.The_intersection_0_was_reduced_to_never_because_property_1_has_conflicting_types_in_some_constituents, c.typeToStringEx(t, nil, TypeFormatFlagsNoTypeReduction), c.SymbolToString(neverProp)) + return NewDiagnosticChainForNode(chain, node, diagnostics.The_intersection_0_was_reduced_to_never_because_property_1_has_conflicting_types_in_some_constituents, c.typeToStringEx(t, nil, TypeFormatFlagsNoTypeReduction), c.symbolToString(neverProp)) } privateProp := core.Find(c.getPropertiesOfUnionOrIntersectionType(t), isConflictingPrivateProperty) if privateProp != nil { - return NewDiagnosticChainForNode(chain, node, diagnostics.The_intersection_0_was_reduced_to_never_because_property_1_exists_in_multiple_constituents_and_is_private_in_some, c.typeToStringEx(t, nil, TypeFormatFlagsNoTypeReduction), c.SymbolToString(privateProp)) + return NewDiagnosticChainForNode(chain, node, diagnostics.The_intersection_0_was_reduced_to_never_because_property_1_exists_in_multiple_constituents_and_is_private_in_some, c.typeToStringEx(t, nil, TypeFormatFlagsNoTypeReduction), c.symbolToString(privateProp)) } } return chain @@ -14603,7 +14603,7 @@ func (c *Checker) getTypeArguments(t *Type) []*Type { } errorNode := core.IfElse(node != nil, node, c.currentNode) if d.target.symbol != nil { - c.error(errorNode, diagnostics.Type_arguments_for_0_circularly_reference_themselves, c.SymbolToString(d.target.symbol)) + c.error(errorNode, diagnostics.Type_arguments_for_0_circularly_reference_themselves, c.symbolToString(d.target.symbol)) } else { c.error(errorNode, diagnostics.Tuple_type_arguments_circularly_reference_themselves) } @@ -15668,7 +15668,7 @@ func (c *Checker) getTypeArgumentsFromNode(node *ast.Node) []*Type { func (c *Checker) checkNoTypeArguments(node *ast.Node, symbol *ast.Symbol) bool { if len(node.TypeArguments()) != 0 { - c.error(node, diagnostics.Type_0_is_not_generic, c.SymbolToString(symbol)) + c.error(node, diagnostics.Type_0_is_not_generic, c.symbolToString(symbol)) return false } return true @@ -16037,7 +16037,7 @@ func (c *Checker) getTypeFromTypeAliasReference(node *ast.Node, symbol *ast.Symb message := core.IfElse(minTypeArgumentCount == len(typeParameters), diagnostics.Generic_type_0_requires_1_type_argument_s, diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments) - c.error(node, message, c.SymbolToString(symbol), minTypeArgumentCount, len(typeParameters)) + c.error(node, message, c.symbolToString(symbol), minTypeArgumentCount, len(typeParameters)) return c.errorType } // We refrain from associating a local type alias with an instantiation of a top-level type alias @@ -16301,7 +16301,7 @@ func (c *Checker) getDeclaredTypeOfTypeAlias(symbol *ast.Symbol) *Type { if errorNode == nil { errorNode = declaration } - c.error(errorNode, diagnostics.Type_alias_0_circularly_references_itself, c.SymbolToString(symbol)) + c.error(errorNode, diagnostics.Type_alias_0_circularly_references_itself, c.symbolToString(symbol)) t = c.errorType } if links.declaredType == nil { @@ -16513,7 +16513,7 @@ func (c *Checker) evaluateEntity(expr *ast.Node, location *ast.Node) EvaluatorRe func (c *Checker) evaluateEnumMember(expr *ast.Node, symbol *ast.Symbol, location *ast.Node) EvaluatorResult { declaration := symbol.ValueDeclaration if declaration == nil || declaration == location { - c.error(expr, diagnostics.Property_0_is_used_before_being_assigned, c.SymbolToString(symbol)) + c.error(expr, diagnostics.Property_0_is_used_before_being_assigned, c.symbolToString(symbol)) return evaluatorResult(nil, false, false, false) } if !c.isBlockScopedNameDeclaredBeforeUse(declaration, location) { @@ -19388,7 +19388,7 @@ func (c *Checker) getPropertyTypeForIndexType(originalObjectType *Type, objectTy if accessExpression != nil { c.markPropertyAsReferenced(prop, accessExpression, c.isSelfTypeAccess(accessExpression.Expression(), objectType.symbol)) if c.isAssignmentToReadonlyEntity(accessExpression, prop, getAssignmentTargetKind(accessExpression)) { - c.error(accessExpression.AsElementAccessExpression().ArgumentExpression, diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, c.SymbolToString(prop)) + c.error(accessExpression.AsElementAccessExpression().ArgumentExpression, diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, c.symbolToString(prop)) return nil } if accessFlags&AccessFlagsCacheSymbol != 0 { @@ -22349,7 +22349,15 @@ func (c *Checker) getActualTypeVariable(t *Type) *Type { return t } -func (c *Checker) GetSymbolAtLocation(node *ast.Node, ignoreErrors bool) *ast.Symbol { +func (c *Checker) GetSymbolAtLocation(node *ast.Node) *ast.Symbol { + // !!! + // const node = getParseTreeNode(nodeIn); + + // set ignoreErrors: true because any lookups invoked by the API shouldn't cause any new errors + return c.getSymbolAtLocation(node, true /*ignoreErrors*/) +} + +func (c *Checker) getSymbolAtLocation(node *ast.Node, ignoreErrors bool) *ast.Symbol { if ast.IsSourceFile(node) { if ast.IsExternalModule(node.AsSourceFile()) { return c.getMergedSymbol(node.Symbol()) @@ -22464,7 +22472,7 @@ func (c *Checker) GetSymbolAtLocation(node *ast.Node, ignoreErrors bool) *ast.Sy return c.getSymbolOfNode(node) case ast.KindImportType: if ast.IsLiteralImportTypeNode(node) { - return c.GetSymbolAtLocation(node.AsImportTypeNode().Argument.AsLiteralTypeNode().Literal, ignoreErrors) + return c.getSymbolAtLocation(node.AsImportTypeNode().Argument.AsLiteralTypeNode().Literal, ignoreErrors) } return nil case ast.KindExportKeyword: @@ -22700,7 +22708,7 @@ func (c *Checker) getTypeOfNode(node *ast.Node) *Type { } if isTypeDeclarationName(node) { - symbol := c.GetSymbolAtLocation(node, false /*ignoreErrors*/) + symbol := c.getSymbolAtLocation(node, false /*ignoreErrors*/) if symbol != nil { return c.getDeclaredTypeOfSymbol(symbol) } @@ -22725,7 +22733,7 @@ func (c *Checker) getTypeOfNode(node *ast.Node) *Type { } if ast.IsDeclarationNameOrImportPropertyName(node) { - symbol := c.GetSymbolAtLocation(node, false /*ignoreErrors*/) + symbol := c.getSymbolAtLocation(node, false /*ignoreErrors*/) if symbol != nil { return c.getTypeOfSymbol(symbol) } @@ -22741,7 +22749,7 @@ func (c *Checker) getTypeOfNode(node *ast.Node) *Type { } if isInRightSideOfImportOrExportAssignment(node) { - symbol := c.GetSymbolAtLocation(node, false /*ignoreErrors*/) + symbol := c.getSymbolAtLocation(node, false /*ignoreErrors*/) if symbol != nil { declaredType := c.getDeclaredTypeOfSymbol(symbol) if !c.isErrorType(declaredType) { @@ -22829,7 +22837,7 @@ func (c *Checker) getApplicableIndexSymbol(t *Type, keyType *Type) *ast.Symbol { } else if t.symbol != nil { symbolCopy.Parent = t.symbol } else { - symbolCopy.Parent = c.GetSymbolAtLocation(symbolCopy.Declarations[0].Parent, false /*ignoreErrors*/) + symbolCopy.Parent = c.getSymbolAtLocation(symbolCopy.Declarations[0].Parent, false /*ignoreErrors*/) } indexSymbolLinks.filteredIndexSymbolCache[nodeListId] = symbolCopy return symbolCopy diff --git a/internal/compiler/checker_test.go b/internal/compiler/checker_test.go index b13548535a..35c77b98db 100644 --- a/internal/compiler/checker_test.go +++ b/internal/compiler/checker_test.go @@ -40,7 +40,7 @@ foo.bar;` propAccess := file.Statements.Nodes[2].AsExpressionStatement().Expression nodes := []*ast.Node{interfaceId, varId, propAccess} for _, node := range nodes { - symbol := c.GetSymbolAtLocation(node, true /*ignoreErrors*/) + symbol := c.GetSymbolAtLocation(node) if symbol == nil { t.Fatalf("Expected symbol to be non-nil") } diff --git a/internal/compiler/flow.go b/internal/compiler/flow.go index 28ab56a41f..73bdccd7d0 100644 --- a/internal/compiler/flow.go +++ b/internal/compiler/flow.go @@ -2111,7 +2111,7 @@ func (c *Checker) getExplicitTypeOfSymbol(symbol *ast.Symbol, diagnostic *ast.Di } } if diagnostic != nil { - diagnostic.AddRelatedInfo(createDiagnosticForNode(declaration, diagnostics.X_0_needs_an_explicit_type_annotation, c.SymbolToString(symbol))) + diagnostic.AddRelatedInfo(createDiagnosticForNode(declaration, diagnostics.X_0_needs_an_explicit_type_annotation, c.symbolToString(symbol))) } } } @@ -2382,7 +2382,7 @@ func (c *Checker) getFlowTypeInConstructor(symbol *ast.Symbol, constructor *ast. reference.FlowNodeData().FlowNode = constructor.AsConstructorDeclaration().ReturnFlowNode flowType := c.getFlowTypeOfProperty(reference, symbol) if c.noImplicitAny && (flowType == c.autoType || flowType == c.autoArrayType) { - c.error(symbol.ValueDeclaration, diagnostics.Member_0_implicitly_has_an_1_type, c.SymbolToString(symbol), c.typeToString(flowType)) + c.error(symbol.ValueDeclaration, diagnostics.Member_0_implicitly_has_an_1_type, c.symbolToString(symbol), c.typeToString(flowType)) } // We don't infer a type if assignments are only null or undefined. if everyType(flowType, c.isNullableType) { @@ -2405,7 +2405,7 @@ func (c *Checker) getFlowTypeInStaticBlocks(symbol *ast.Symbol, staticBlocks []* reference.FlowNodeData().FlowNode = staticBlock.AsClassStaticBlockDeclaration().ReturnFlowNode flowType := c.getFlowTypeOfProperty(reference, symbol) if c.noImplicitAny && (flowType == c.autoType || flowType == c.autoArrayType) { - c.error(symbol.ValueDeclaration, diagnostics.Member_0_implicitly_has_an_1_type, c.SymbolToString(symbol), c.typeToString(flowType)) + c.error(symbol.ValueDeclaration, diagnostics.Member_0_implicitly_has_an_1_type, c.symbolToString(symbol), c.typeToString(flowType)) } // We don't infer a type if assignments are only null or undefined. if everyType(flowType, c.isNullableType) { diff --git a/internal/compiler/printer.go b/internal/compiler/printer.go index 24f3071f42..3e9280e3cf 100644 --- a/internal/compiler/printer.go +++ b/internal/compiler/printer.go @@ -28,6 +28,10 @@ func (c *Checker) getTypePrecedence(t *Type) ast.TypePrecedence { } func (c *Checker) SymbolToString(s *ast.Symbol) string { + return c.symbolToString(s) +} + +func (c *Checker) symbolToString(s *ast.Symbol) string { if s.ValueDeclaration != nil { name := ast.GetNameOfDeclaration(s.ValueDeclaration) if name != nil { @@ -89,7 +93,7 @@ func (p *Printer) print(s string) { } func (p *Printer) printName(symbol *ast.Symbol) { - p.print(p.c.SymbolToString(symbol)) + p.print(p.c.symbolToString(symbol)) } func (p *Printer) printTypeEx(t *Type, precedence ast.TypePrecedence) { @@ -562,10 +566,10 @@ func (c *Checker) getTextAndTypeOfNode(node *ast.Node) (string, *Type, bool) { symbol := node.Symbol() if symbol != nil && !isReservedMemberName(symbol.Name) { if symbol.Flags&ast.SymbolFlagsValue != 0 { - return c.SymbolToString(symbol), c.getTypeOfSymbol(symbol), true + return c.symbolToString(symbol), c.getTypeOfSymbol(symbol), true } if symbol.Flags&ast.SymbolFlagsTypeAlias != 0 { - return c.SymbolToString(symbol), c.getDeclaredTypeOfTypeAlias(symbol), true + return c.symbolToString(symbol), c.getDeclaredTypeOfTypeAlias(symbol), true } } } diff --git a/internal/compiler/relater.go b/internal/compiler/relater.go index ea2a6e64d4..78cd681202 100644 --- a/internal/compiler/relater.go +++ b/internal/compiler/relater.go @@ -2360,9 +2360,9 @@ func (r *Relater) hasExcessProperties(source *Type, target *Type, reportErrors b } } if suggestion != "" { - r.reportError(diagnostics.Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2, r.c.SymbolToString(prop), r.c.typeToString(errorTarget), suggestion) + r.reportError(diagnostics.Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2, r.c.symbolToString(prop), r.c.typeToString(errorTarget), suggestion) } else { - r.reportError(diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, r.c.SymbolToString(prop), r.c.typeToString(errorTarget)) + r.reportError(diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, r.c.symbolToString(prop), r.c.typeToString(errorTarget)) } } } @@ -2370,7 +2370,7 @@ func (r *Relater) hasExcessProperties(source *Type, target *Type, reportErrors b } if checkTypes != nil && r.isRelatedTo(r.c.getTypeOfSymbol(prop), r.c.getTypeOfPropertyInTypes(checkTypes, prop.Name), RecursionFlagsBoth, reportErrors) == TernaryFalse { if reportErrors { - r.reportError(diagnostics.Types_of_property_0_are_incompatible, r.c.SymbolToString(prop)) + r.reportError(diagnostics.Types_of_property_0_are_incompatible, r.c.symbolToString(prop)) } return true } @@ -3811,7 +3811,7 @@ func (r *Relater) propertiesRelatedTo(source *Type, target *Type, reportErrors b sourceType := r.c.getTypeOfSymbol(sourceProp) if sourceType.flags&TypeFlagsUndefined == 0 { if reportErrors { - r.reportError(diagnostics.Property_0_does_not_exist_on_type_1, r.c.SymbolToString(sourceProp), r.c.typeToString(target)) + r.reportError(diagnostics.Property_0_does_not_exist_on_type_1, r.c.symbolToString(sourceProp), r.c.typeToString(target)) } return TernaryFalse } @@ -3846,9 +3846,9 @@ func (r *Relater) propertyRelatedTo(source *Type, target *Type, sourceProp *ast. if sourceProp.ValueDeclaration != targetProp.ValueDeclaration { if reportErrors { if sourcePropFlags&ast.ModifierFlagsPrivate != 0 && targetPropFlags&ast.ModifierFlagsPrivate != 0 { - r.reportError(diagnostics.Types_have_separate_declarations_of_a_private_property_0, r.c.SymbolToString(targetProp)) + r.reportError(diagnostics.Types_have_separate_declarations_of_a_private_property_0, r.c.symbolToString(targetProp)) } else { - r.reportError(diagnostics.Property_0_is_private_in_type_1_but_not_in_type_2, r.c.SymbolToString(targetProp), r.c.typeToString(core.IfElse(sourcePropFlags&ast.ModifierFlagsPrivate != 0, source, target)), r.c.typeToString(core.IfElse(sourcePropFlags&ast.ModifierFlagsPrivate != 0, target, source))) + r.reportError(diagnostics.Property_0_is_private_in_type_1_but_not_in_type_2, r.c.symbolToString(targetProp), r.c.typeToString(core.IfElse(sourcePropFlags&ast.ModifierFlagsPrivate != 0, source, target)), r.c.typeToString(core.IfElse(sourcePropFlags&ast.ModifierFlagsPrivate != 0, target, source))) } } return TernaryFalse @@ -3864,13 +3864,13 @@ func (r *Relater) propertyRelatedTo(source *Type, target *Type, sourceProp *ast. if targetType == nil { targetType = target } - r.reportError(diagnostics.Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2, r.c.SymbolToString(targetProp), r.c.typeToString(sourceType), r.c.typeToString(targetType)) + r.reportError(diagnostics.Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2, r.c.symbolToString(targetProp), r.c.typeToString(sourceType), r.c.typeToString(targetType)) } return TernaryFalse } case sourcePropFlags&ast.ModifierFlagsProtected != 0: if reportErrors { - r.reportError(diagnostics.Property_0_is_protected_in_type_1_but_public_in_type_2, r.c.SymbolToString(targetProp), r.c.typeToString(source), r.c.typeToString(target)) + r.reportError(diagnostics.Property_0_is_protected_in_type_1_but_public_in_type_2, r.c.symbolToString(targetProp), r.c.typeToString(source), r.c.typeToString(target)) } return TernaryFalse } @@ -3887,7 +3887,7 @@ func (r *Relater) propertyRelatedTo(source *Type, target *Type, sourceProp *ast. related := r.isPropertySymbolTypeRelated(sourceProp, targetProp, getTypeOfSourceProperty, reportErrors, intersectionState) if related == TernaryFalse { if reportErrors { - r.reportError(diagnostics.Types_of_property_0_are_incompatible, r.c.SymbolToString(targetProp)) + r.reportError(diagnostics.Types_of_property_0_are_incompatible, r.c.symbolToString(targetProp)) } return TernaryFalse } @@ -3901,7 +3901,7 @@ func (r *Relater) propertyRelatedTo(source *Type, target *Type, sourceProp *ast. // (M - property in T) // (N - property in S) if reportErrors { - r.reportError(diagnostics.Property_0_is_optional_in_type_1_but_required_in_type_2, r.c.SymbolToString(targetProp), r.c.typeToString(source), r.c.typeToString(target)) + r.reportError(diagnostics.Property_0_is_optional_in_type_1_but_required_in_type_2, r.c.symbolToString(targetProp), r.c.typeToString(source), r.c.typeToString(target)) } return TernaryFalse } @@ -3933,17 +3933,17 @@ func (r *Relater) reportUnmatchedProperty(source *Type, target *Type, unmatchedP } props := slices.Collect(r.c.getUnmatchedProperties(source, target, requireOptionalProperties, false /*matchDiscriminantProperties*/)) if len(props) == 1 { - propName := r.c.SymbolToString(unmatchedProperty) + propName := r.c.symbolToString(unmatchedProperty) r.reportError(diagnostics.Property_0_is_missing_in_type_1_but_required_in_type_2, unmatchedProperty.Name, r.c.typeToString(source), r.c.typeToString(target)) if len(unmatchedProperty.Declarations) != 0 { r.relatedInfo = append(r.relatedInfo, createDiagnosticForNode(unmatchedProperty.Declarations[0], diagnostics.X_0_is_declared_here, propName)) } } else if r.tryElaborateArrayLikeErrors(source, target, false /*reportErrors*/) { if len(props) > 5 { - propNames := strings.Join(core.Map(props[:4], r.c.SymbolToString), ", ") + propNames := strings.Join(core.Map(props[:4], r.c.symbolToString), ", ") r.reportError(diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more, r.c.typeToString(source), r.c.typeToString(target), propNames, len(props)-4) } else { - propNames := strings.Join(core.Map(props, r.c.SymbolToString), ", ") + propNames := strings.Join(core.Map(props, r.c.symbolToString), ", ") r.reportError(diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2, r.c.typeToString(source), r.c.typeToString(target), propNames) } } @@ -4225,7 +4225,7 @@ func (r *Relater) membersRelatedToIndexInfo(source *Type, targetInfo *IndexInfo, related := r.isRelatedToEx(t, targetInfo.valueType, RecursionFlagsBoth, reportErrors, nil /*headMessage*/, intersectionState) if related == TernaryFalse { if reportErrors { - r.reportError(diagnostics.Property_0_is_incompatible_with_index_signature, r.c.SymbolToString(prop)) + r.reportError(diagnostics.Property_0_is_incompatible_with_index_signature, r.c.symbolToString(prop)) } return TernaryFalse } @@ -4305,7 +4305,7 @@ func (r *Relater) reportErrorResults(originalSource *Type, originalTarget *Type, prop = core.Find(r.c.getPropertiesOfUnionOrIntersectionType(originalTarget), isConflictingPrivateProperty) } if prop != nil { - r.reportError(message, r.c.typeToStringEx(originalTarget, nil /*enclosingDeclaration*/, TypeFormatFlagsNoTypeReduction), r.c.SymbolToString(prop)) + r.reportError(message, r.c.typeToStringEx(originalTarget, nil /*enclosingDeclaration*/, TypeFormatFlagsNoTypeReduction), r.c.symbolToString(prop)) } } // !!! Logic having to do with canonical diagnostics for deduplication purposes diff --git a/internal/testutil/baseline/symbol_baseline.go b/internal/testutil/baseline/symbol_baseline.go index 588f520766..6df70bd7c6 100644 --- a/internal/testutil/baseline/symbol_baseline.go +++ b/internal/testutil/baseline/symbol_baseline.go @@ -268,7 +268,7 @@ func (walker *typeWriterWalker) writeTypeOrSymbol(node *ast.Node, isSymbolWalk b // !!! Types baseline } - symbol := walker.checker.GetSymbolAtLocation(node /*ignoreErrors*/, true) + symbol := walker.checker.GetSymbolAtLocation(node) if symbol == nil { return nil } From f73a494323f7fa316a00ce18e556f13612a4571f Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Tue, 7 Jan 2025 12:21:08 -0800 Subject: [PATCH 11/11] Update internal/compiler/checker.go Co-authored-by: Jake Bailey <5341706+jakebailey@users.noreply.github.com> --- internal/compiler/checker.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/compiler/checker.go b/internal/compiler/checker.go index 6f5d1e2d98..bb48427960 100644 --- a/internal/compiler/checker.go +++ b/internal/compiler/checker.go @@ -8450,7 +8450,7 @@ func (c *Checker) getTargetOfModuleDefault(moduleSymbol *ast.Symbol, node *ast.N // } // exportEqualsSymbol := moduleSymbol.exports.get(ast.InternalSymbolNameExportEquals) // exportAssignment := exportEqualsSymbol.valueDeclaration - // err := c.error(node.name, Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, c.SymbolToString(moduleSymbol), compilerOptionName) + // err := c.error(node.name, Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, c.symbolToString(moduleSymbol), compilerOptionName) // if exportAssignment { // addRelatedInfo(err, createDiagnosticForNode(exportAssignment, Diagnostics.This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag, compilerOptionName))