Remove SymbolLinks.typeChecked

This commit is contained in:
Jason Freeman
2014-07-16 13:34:27 -07:00
parent e668756ac2
commit 17563f3c5d
6 changed files with 69 additions and 26 deletions
+35 -24
View File
@@ -415,8 +415,13 @@ module ts {
}
function getExportAssignmentSymbol(symbol: Symbol): Symbol {
if (!symbol.exportAssignSymbol) {
var exportInformation = collectExportInformationForSourceFileOrModule(symbol);
checkTypeOfExportAssignmentSymbol(symbol);
return symbol.exportAssignSymbol === unknownSymbol ? undefined : symbol.exportAssignSymbol;
}
function checkTypeOfExportAssignmentSymbol(containerSymbol: Symbol): void {
if (!containerSymbol.exportAssignSymbol) {
var exportInformation = collectExportInformationForSourceFileOrModule(containerSymbol);
if (exportInformation.exportAssignments.length) {
if (exportInformation.exportAssignments.length > 1) {
// TypeScript 1.0 spec (April 2014): 11.2.4
@@ -436,9 +441,8 @@ module ts {
var exportSymbol = resolveName(node, node.exportName.text, meaning, Diagnostics.Cannot_find_name_0, identifierToString(node.exportName));
}
}
symbol.exportAssignSymbol = exportSymbol || unknownSymbol;
containerSymbol.exportAssignSymbol = exportSymbol || unknownSymbol;
}
return symbol.exportAssignSymbol === unknownSymbol ? undefined : symbol.exportAssignSymbol;
}
function collectExportInformationForSourceFileOrModule(symbol: Symbol) {
@@ -504,8 +508,12 @@ module ts {
var declarations = symbol.declarations;
for (var i = 0; i < declarations.length; i++) {
var declaration = declarations[i];
if (declaration.kind === kind) return declaration;
if (declaration.kind === kind) {
return declaration;
}
}
return undefined;
}
function findConstructorDeclaration(node: ClassDeclaration): ConstructorDeclaration {
@@ -970,6 +978,12 @@ module ts {
function getTypeOfAccessors(symbol: Symbol): Type {
var links = getSymbolLinks(symbol);
checkAndStoreTypeOfAccessors(symbol, links);
return links.type;
}
function checkAndStoreTypeOfAccessors(symbol: Symbol, links?: SymbolLinks) {
links = links || getSymbolLinks(symbol);
if (!links.type) {
links.type = resolvingType;
var getter = <AccessorDeclaration>getDeclarationOfKind(symbol, SyntaxKind.GetAccessor);
@@ -1003,7 +1017,6 @@ module ts {
}
}
}
if (links.type === resolvingType) {
links.type = type;
@@ -1012,7 +1025,6 @@ module ts {
else if (links.type === resolvingType) {
links.type = anyType;
}
return links.type;
}
function getTypeOfFuncClassEnumModule(symbol: Symbol): Type {
@@ -4260,11 +4272,10 @@ module ts {
checkSourceElement(node.body);
var symbol = getSymbolOfNode(node);
var symbolLinks = getSymbolLinks(symbol);
var type = getTypeOfSymbol(symbol.parent);
if (!(symbolLinks.typeChecked)) {
var firstDeclaration = getDeclarationOfKind(symbol, node.kind);
// Only type check the symbol once
if (node === firstDeclaration) {
checkFunctionOrConstructorSymbol(symbol);
symbolLinks.typeChecked = true;
}
// exit early in the case of signature - super checks are not relevant to them
@@ -4383,6 +4394,7 @@ module ts {
}
checkFunctionDeclaration(node);
checkAndStoreTypeOfAccessors(getSymbolOfNode(node));
}
function checkTypeReference(node: TypeReferenceNode) {
@@ -4598,12 +4610,12 @@ module ts {
function checkFunctionDeclaration(node: FunctionDeclaration) {
checkDeclarationModifiers(node);
checkSignatureDeclaration(node);
var symbol = getSymbolOfNode(node);
var symbolLinks = getSymbolLinks(symbol);
var type = getTypeOfSymbol(symbol);
if (!(symbolLinks.typeChecked)) {
var firstDeclaration = getDeclarationOfKind(symbol, node.kind);
// Only type check the symbol once
if (node === firstDeclaration) {
checkFunctionOrConstructorSymbol(symbol);
symbolLinks.typeChecked = true;
}
checkSourceElement(node.body);
@@ -5204,15 +5216,15 @@ module ts {
checkNameIsReserved(node.name, Diagnostics.Interface_name_cannot_be_0);
checkTypeParameters(node.typeParameters);
var symbol = getSymbolOfNode(node);
var firstInterfaceDecl = <InterfaceDeclaration>getDeclarationOfKind(symbol, SyntaxKind.InterfaceDeclaration);
if (symbol.declarations.length > 1) {
var firstInterfaceDecl = <InterfaceDeclaration>getDeclarationOfKind(symbol, SyntaxKind.InterfaceDeclaration);
if (node !== firstInterfaceDecl && !areTypeParametersIdentical(firstInterfaceDecl.typeParameters, node.typeParameters)) {
error(node.name, Diagnostics.All_declarations_of_an_interface_must_have_identical_type_parameters);
}
}
var links = getSymbolLinks(symbol);
if (!links.typeChecked) {
// Only check this symbol once
if (node === firstInterfaceDecl) {
var type = <InterfaceType>getDeclaredTypeOfSymbol(symbol);
// run subsequent checks only if first set succeeded
if (checkInheritedPropertiesAreIdentical(type, node.name)) {
@@ -5221,7 +5233,6 @@ module ts {
});
checkIndexConstraints(type);
}
links.typeChecked = true;
}
forEach(node.baseTypes, checkTypeReference);
forEach(node.members, checkSourceElement);
@@ -5285,11 +5296,6 @@ module ts {
error(node, Diagnostics.Ambient_external_module_declaration_cannot_specify_relative_module_name);
}
var symbol = getSymbolOfNode(node);
var links = getSymbolLinks(symbol);
if (!links.typeChecked) {
getExportAssignmentSymbol(symbol);
links.typeChecked = true;
}
}
checkSourceElement(node.body);
}
@@ -5358,6 +5364,11 @@ module ts {
if (container.kind === SyntaxKind.SourceFile) {
checkModulesEnabled(node);
}
else {
// In a module, the immediate parent will be a block, so climb up one more parent
container = container.parent;
}
checkTypeOfExportAssignmentSymbol(getSymbolOfNode(container));
}
function checkSourceElement(node: Node): void {
-1
View File
@@ -715,7 +715,6 @@ module ts {
type?: Type; // Type of value symbol
declaredType?: Type; // Type of class, interface, enum, or type parameter
mapper?: TypeMapper; // Type mapper for instantiation alias
typeChecked?: boolean; // True if symbol has been type checked
referenced?: boolean; // True if alias symbol has been referenced as a value
}
@@ -0,0 +1,12 @@
==== tests/cases/compiler/functionAndInterfaceWithSeparateErrors.ts (2 errors) ====
function Foo(s: string);
~~~~~~~~~~~~~~~~~~~~~~~~
!!! Overload signature is not compatible with function implementation.
function Foo(n: number) { }
interface Foo {
[s: string]: string;
prop: number;
~~~~~~~~~~~~~
!!! Property 'prop' of type 'number' is not assignable to string index type 'string'.
}
@@ -0,0 +1,12 @@
//// [functionAndInterfaceWithSeparateErrors.ts]
function Foo(s: string);
function Foo(n: number) { }
interface Foo {
[s: string]: string;
prop: number;
}
//// [functionAndInterfaceWithSeparateErrors.js]
function Foo(n) {
}
@@ -1,6 +1,8 @@
==== tests/cases/conformance/parser/ecmascript5/ExportAssignments/parserExportAssignment5.ts (1 errors) ====
==== tests/cases/conformance/parser/ecmascript5/ExportAssignments/parserExportAssignment5.ts (2 errors) ====
module M {
export = A;
~~~~~~~~~~~
!!! An export assignment cannot be used in an internal module.
~~~~~~~~~~~
!!! Cannot find name 'A'.
}
@@ -0,0 +1,7 @@
function Foo(s: string);
function Foo(n: number) { }
interface Foo {
[s: string]: string;
prop: number;
}