mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 20:25:23 -06:00
Issue an error when class is used before class declaration
This commit is contained in:
parent
65da012527
commit
ed7a3d00b9
@ -1056,9 +1056,9 @@ namespace ts {
|
||||
// block-scoped variable and namespace module. However, only when we
|
||||
// try to resolve name in /*1*/ which is used in variable position,
|
||||
// we want to check for block-scoped
|
||||
if (meaning & SymbolFlags.BlockScopedVariable) {
|
||||
if (meaning & SymbolFlags.BlockScopedVariable || (meaning & SymbolFlags.Class && (meaning & SymbolFlags.Value) === SymbolFlags.Value)) {
|
||||
const exportOrLocalSymbol = getExportSymbolOfValueSymbolIfExported(result);
|
||||
if (exportOrLocalSymbol.flags & SymbolFlags.BlockScopedVariable) {
|
||||
if (exportOrLocalSymbol.flags & SymbolFlags.BlockScopedVariable || exportOrLocalSymbol.flags & SymbolFlags.Class) {
|
||||
checkResolvedBlockScopedVariable(exportOrLocalSymbol, errorLocation);
|
||||
}
|
||||
}
|
||||
@ -1171,14 +1171,19 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkResolvedBlockScopedVariable(result: Symbol, errorLocation: Node): void {
|
||||
Debug.assert((result.flags & SymbolFlags.BlockScopedVariable) !== 0);
|
||||
Debug.assert(!!(result.flags & SymbolFlags.BlockScopedVariable || result.flags & SymbolFlags.Class));
|
||||
// Block-scoped variables cannot be used before their definition
|
||||
const declaration = forEach(result.declarations, d => isBlockOrCatchScoped(d) ? d : undefined);
|
||||
const declaration = forEach(result.declarations, d => isBlockOrCatchScoped(d) || isClassLike(d) ? d : undefined);
|
||||
|
||||
Debug.assert(declaration !== undefined, "Block-scoped variable declaration is undefined");
|
||||
|
||||
if (!isInAmbientContext(declaration) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) {
|
||||
error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationNameToString(declaration.name));
|
||||
if (result.flags & SymbolFlags.BlockScopedVariable) {
|
||||
error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationNameToString(declaration.name));
|
||||
}
|
||||
else {
|
||||
error(errorLocation, Diagnostics.Class_0_used_before_its_declaration, declarationNameToString(declaration.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13171,10 +13176,17 @@ namespace ts {
|
||||
}
|
||||
return unknownType;
|
||||
}
|
||||
if (prop.valueDeclaration &&
|
||||
isInPropertyInitializer(node) &&
|
||||
!isBlockScopedNameDeclaredBeforeUse(prop.valueDeclaration, right)) {
|
||||
error(right, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, right.text);
|
||||
if (prop.valueDeclaration) {
|
||||
if (isInPropertyInitializer(node) &&
|
||||
!isBlockScopedNameDeclaredBeforeUse(prop.valueDeclaration, right)) {
|
||||
error(right, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, right.text);
|
||||
}
|
||||
if (prop.valueDeclaration.kind === SyntaxKind.ClassDeclaration &&
|
||||
node.parent && node.parent.kind !== SyntaxKind.TypeReference &&
|
||||
!isInAmbientContext(prop.valueDeclaration) &&
|
||||
!isBlockScopedNameDeclaredBeforeUse(prop.valueDeclaration, right)) {
|
||||
error(right, Diagnostics.Class_0_used_before_its_declaration, right.text);
|
||||
}
|
||||
}
|
||||
|
||||
markPropertyAsReferenced(prop);
|
||||
@ -19421,14 +19433,6 @@ namespace ts {
|
||||
error(node.name || node, Diagnostics.A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any);
|
||||
}
|
||||
|
||||
if (baseType.symbol && baseType.symbol.valueDeclaration &&
|
||||
!isInAmbientContext(baseType.symbol.valueDeclaration) &&
|
||||
baseType.symbol.valueDeclaration.kind === SyntaxKind.ClassDeclaration) {
|
||||
if (!isBlockScopedNameDeclaredBeforeUse(baseType.symbol.valueDeclaration, node)) {
|
||||
error(baseTypeNode, Diagnostics.A_class_must_be_declared_after_its_base_class);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(staticBaseType.symbol && staticBaseType.symbol.flags & SymbolFlags.Class) && !(baseConstructorType.flags & TypeFlags.TypeVariable)) {
|
||||
// When the static base type is a "class-like" constructor function (but not actually a class), we verify
|
||||
// that all instantiated base constructor signatures return the same type. We can simply compare the type
|
||||
|
||||
@ -1435,6 +1435,10 @@
|
||||
"category": "Error",
|
||||
"code": 2448
|
||||
},
|
||||
"Class '{0}' used before its declaration.": {
|
||||
"category": "Error",
|
||||
"code": 2449
|
||||
},
|
||||
"Cannot redeclare block-scoped variable '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2451
|
||||
@ -2019,10 +2023,6 @@
|
||||
"category": "Error",
|
||||
"code": 2689
|
||||
},
|
||||
"A class must be declared after its base class.": {
|
||||
"category": "Error",
|
||||
"code": 2690
|
||||
},
|
||||
"An import path cannot end with a '{0}' extension. Consider importing '{1}' instead.": {
|
||||
"category": "Error",
|
||||
"code": 2691
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user