Skip to content

Commit d1079e4

Browse files
committed
Merge branch 'master' into overloadResolution
2 parents 962cde9 + 20392de commit d1079e4

1 file changed

Lines changed: 70 additions & 64 deletions

File tree

src/compiler/checker.ts

Lines changed: 70 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -307,80 +307,49 @@ module ts {
307307
// return undefined if we can't find a symbol.
308308
}
309309

310-
function resolveName(location: Node, name: string, meaning: SymbolFlags, nameNotFoundMessage: DiagnosticMessage, nameArg: string): Symbol {
311-
var errorLocation = location;
310+
// Resolve a given name for a given meaning at a given location. An error is reported if the name was not found and
311+
// the nameNotFoundMessage argument is not undefined. Returns the resolved symbol, or undefined if no symbol with
312+
// the given name can be found.
313+
function resolveName(location: Node, name: string, meaning: SymbolFlags, nameNotFoundMessage: DiagnosticMessage, nameArg: string | Identifier): Symbol {
314+
312315
var result: Symbol;
313316
var lastLocation: Node;
317+
var propertyWithInvalidInitializer: Node;
318+
var errorLocation = location;
314319

315-
var memberWithInitializerThatReferencesIdentifierFromConstructor: Node;
316-
317-
function returnResolvedSymbol(s: Symbol) {
318-
// we've seen member with initializer that references identifier defined in constructor during the search.
319-
// if this was the only result with given name then just report default 'nameNotFound' message.
320-
// however if we met something else that was 'shadowed' by the identifier in constructor - report more specific error
321-
if (s && memberWithInitializerThatReferencesIdentifierFromConstructor) {
322-
var propertyName = (<PropertyDeclaration>memberWithInitializerThatReferencesIdentifierFromConstructor).name;
323-
error(errorLocation, Diagnostics.Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor, identifierToString(propertyName), nameArg);
324-
return undefined;
325-
}
326-
if (!s && nameNotFoundMessage) {
327-
error(errorLocation, nameNotFoundMessage, nameArg);
328-
}
329-
330-
if (s && s.flags & SymbolFlags.BlockScopedVariable) {
331-
// Block-scoped variables can not be used before their definition
332-
var declaration = forEach(s.declarations, d => d.flags & NodeFlags.BlockScoped ? d : undefined);
333-
Debug.assert(declaration, "Block-scoped variable declaration is undefined");
334-
var declarationSourceFile = getSourceFileOfNode(declaration);
335-
var referenceSourceFile = getSourceFileOfNode(errorLocation);
336-
if (declarationSourceFile === referenceSourceFile) {
337-
if (declaration.pos > errorLocation.pos) {
338-
error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, identifierToString(declaration.name));
339-
}
340-
}
341-
else if (compilerOptions.out) {
342-
var sourceFiles = program.getSourceFiles();
343-
if (sourceFiles.indexOf(referenceSourceFile) < sourceFiles.indexOf(declarationSourceFile)) {
344-
error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, identifierToString(declaration.name));
345-
}
346-
}
347-
}
348-
return s;
349-
}
350-
351-
while (location) {
320+
loop: while (location) {
352321
// Locals of a source file are not in scope (because they get merged into the global symbol table)
353322
if (location.locals && !isGlobalSourceFile(location)) {
354323
if (result = getSymbol(location.locals, name, meaning)) {
355-
return returnResolvedSymbol(result);
324+
break loop;
356325
}
357326
}
358327
switch (location.kind) {
359328
case SyntaxKind.SourceFile:
360329
if (!isExternalModule(<SourceFile>location)) break;
361330
case SyntaxKind.ModuleDeclaration:
362331
if (result = getSymbol(getSymbolOfNode(location).exports, name, meaning & SymbolFlags.ModuleMember)) {
363-
return returnResolvedSymbol(result);
332+
break loop;
364333
}
365334
break;
366335
case SyntaxKind.EnumDeclaration:
367336
if (result = getSymbol(getSymbolOfNode(location).exports, name, meaning & SymbolFlags.EnumMember)) {
368-
return returnResolvedSymbol(result);
337+
break loop;
369338
}
370339
break;
371340
case SyntaxKind.Property:
372341
// TypeScript 1.0 spec (April 2014): 8.4.1
373342
// Initializer expressions for instance member variables are evaluated in the scope
374343
// of the class constructor body but are not permitted to reference parameters or
375-
// local variables of the constructor.This effectively means that entities from outer scopes
344+
// local variables of the constructor. This effectively means that entities from outer scopes
376345
// by the same name as a constructor parameter or local variable are inaccessible
377346
// in initializer expressions for instance member variables.
378347
if (location.parent.kind === SyntaxKind.ClassDeclaration && !(location.flags & NodeFlags.Static)) {
379348
var ctor = findConstructorDeclaration(<ClassDeclaration>location.parent);
380349
if (ctor && ctor.locals) {
381350
if (getSymbol(ctor.locals, name, meaning & SymbolFlags.Value)) {
382-
// save the property node - later it will be used by 'returnResolvedSymbol' to report appropriate error
383-
memberWithInitializerThatReferencesIdentifierFromConstructor = location;
351+
// Remember the property node, it will be used later to report appropriate error
352+
propertyWithInvalidInitializer = location;
384353
}
385354
}
386355
}
@@ -390,14 +359,12 @@ module ts {
390359
if (result = getSymbol(getSymbolOfNode(location).members, name, meaning & SymbolFlags.Type)) {
391360
if (lastLocation && lastLocation.flags & NodeFlags.Static) {
392361
// TypeScript 1.0 spec (April 2014): 3.4.1
393-
// The scope of a type parameter extends over the entire declaration
394-
// with which the type parameter list is associated, with the exception of static member declarations in classes.
362+
// The scope of a type parameter extends over the entire declaration with which the type
363+
// parameter list is associated, with the exception of static member declarations in classes.
395364
error(errorLocation, Diagnostics.Static_members_cannot_reference_class_type_parameters);
396365
return undefined;
397366
}
398-
else {
399-
return returnResolvedSymbol(result);
400-
}
367+
break loop;
401368
}
402369
break;
403370
case SyntaxKind.Method:
@@ -407,33 +374,74 @@ module ts {
407374
case SyntaxKind.FunctionDeclaration:
408375
case SyntaxKind.ArrowFunction:
409376
if (name === "arguments") {
410-
return returnResolvedSymbol(argumentsSymbol);
377+
result = argumentsSymbol;
378+
break loop;
411379
}
412380
break;
413381
case SyntaxKind.FunctionExpression:
414382
if (name === "arguments") {
415-
return returnResolvedSymbol(argumentsSymbol);
383+
result = argumentsSymbol;
384+
break loop;
416385
}
417386
var id = (<FunctionExpression>location).name;
418387
if (id && name === id.text) {
419-
return returnResolvedSymbol(location.symbol);
388+
result = location.symbol;
389+
break loop;
420390
}
421391
break;
422392
case SyntaxKind.CatchBlock:
423393
var id = (<CatchBlock>location).variable;
424394
if (name === id.text) {
425-
return returnResolvedSymbol(location.symbol);
395+
result = location.symbol;
396+
break loop;
426397
}
427398
break;
428399
}
429400
lastLocation = location;
430401
location = location.parent;
431402
}
432-
if (result = getSymbol(globals, name, meaning)) {
433-
return returnResolvedSymbol(result);
403+
404+
if (!result) {
405+
result = getSymbol(globals, name, meaning);
406+
}
407+
408+
if (!result) {
409+
if (nameNotFoundMessage) {
410+
error(errorLocation, nameNotFoundMessage, typeof nameArg === "string" ? nameArg : identifierToString(nameArg));
411+
}
412+
return undefined;
434413
}
435414

436-
return returnResolvedSymbol(undefined);
415+
// Perform extra checks only if error reporting was requested
416+
if (nameNotFoundMessage) {
417+
if (propertyWithInvalidInitializer) {
418+
// We have a match, but the reference occurred within a property initializer and the identifier also binds
419+
// to a local variable in the constructor where the code will be emitted.
420+
var propertyName = (<PropertyDeclaration>propertyWithInvalidInitializer).name;
421+
error(errorLocation, Diagnostics.Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor,
422+
identifierToString(propertyName), typeof nameArg === "string" ? nameArg : identifierToString(nameArg));
423+
return undefined;
424+
}
425+
if (result.flags & SymbolFlags.BlockScopedVariable) {
426+
// Block-scoped variables cannot be used before their definition
427+
var declaration = forEach(result.declarations, d => d.flags & NodeFlags.BlockScoped ? d : undefined);
428+
Debug.assert(declaration, "Block-scoped variable declaration is undefined");
429+
var declarationSourceFile = getSourceFileOfNode(declaration);
430+
var referenceSourceFile = getSourceFileOfNode(errorLocation);
431+
if (declarationSourceFile === referenceSourceFile) {
432+
if (declaration.pos > errorLocation.pos) {
433+
error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, identifierToString(declaration.name));
434+
}
435+
}
436+
else if (compilerOptions.out) {
437+
var sourceFiles = program.getSourceFiles();
438+
if (sourceFiles.indexOf(referenceSourceFile) < sourceFiles.indexOf(declarationSourceFile)) {
439+
error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, identifierToString(declaration.name));
440+
}
441+
}
442+
}
443+
}
444+
return result;
437445
}
438446

439447
function resolveImport(symbol: Symbol): Symbol {
@@ -492,8 +500,7 @@ module ts {
492500
// Resolves a qualified name and any involved import aliases
493501
function resolveEntityName(location: Node, name: EntityName, meaning: SymbolFlags): Symbol {
494502
if (name.kind === SyntaxKind.Identifier) {
495-
// TODO: Investigate error recovery for symbols not found
496-
var symbol = resolveName(location, (<Identifier>name).text, meaning, Diagnostics.Cannot_find_name_0, identifierToString(<Identifier>name));
503+
var symbol = resolveName(location, (<Identifier>name).text, meaning, Diagnostics.Cannot_find_name_0, <Identifier>name);
497504
if (!symbol) {
498505
return;
499506
}
@@ -590,7 +597,7 @@ module ts {
590597
}
591598
if (node.exportName.text) {
592599
var meaning = SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace;
593-
var exportSymbol = resolveName(node, node.exportName.text, meaning, Diagnostics.Cannot_find_name_0, identifierToString(node.exportName));
600+
var exportSymbol = resolveName(node, node.exportName.text, meaning, Diagnostics.Cannot_find_name_0, node.exportName);
594601
}
595602
}
596603
symbolLinks.exportAssignSymbol = exportSymbol || unknownSymbol;
@@ -961,13 +968,12 @@ module ts {
961968

962969
function isImportDeclarationEntityNameReferenceDeclarationVisibile(entityName: EntityName): SymbolAccessiblityResult {
963970
var firstIdentifier = getFirstIdentifier(entityName);
964-
var firstIdentifierName = identifierToString(<Identifier>firstIdentifier);
965-
var symbolOfNameSpace = resolveName(entityName.parent, (<Identifier>firstIdentifier).text, SymbolFlags.Namespace, Diagnostics.Cannot_find_name_0, firstIdentifierName);
971+
var symbolOfNameSpace = resolveName(entityName.parent, (<Identifier>firstIdentifier).text, SymbolFlags.Namespace, Diagnostics.Cannot_find_name_0, firstIdentifier);
966972
// Verify if the symbol is accessible
967973
var hasNamespaceDeclarationsVisibile = hasVisibleDeclarations(symbolOfNameSpace);
968974
return hasNamespaceDeclarationsVisibile ?
969975
{ accessibility: SymbolAccessibility.Accessible, aliasesToMakeVisible: hasNamespaceDeclarationsVisibile.aliasesToMakeVisible } :
970-
{ accessibility: SymbolAccessibility.NotAccessible, errorSymbolName: firstIdentifierName };
976+
{ accessibility: SymbolAccessibility.NotAccessible, errorSymbolName: identifierToString(<Identifier>firstIdentifier) };
971977
}
972978

973979
function releaseStringWriter(writer: StringSymbolWriter) {
@@ -4114,7 +4120,7 @@ module ts {
41144120
function getResolvedSymbol(node: Identifier): Symbol {
41154121
var links = getNodeLinks(node);
41164122
if (!links.resolvedSymbol) {
4117-
links.resolvedSymbol = resolveName(node, node.text, SymbolFlags.Value | SymbolFlags.ExportValue, Diagnostics.Cannot_find_name_0, identifierToString(node)) || unknownSymbol;
4123+
links.resolvedSymbol = resolveName(node, node.text, SymbolFlags.Value | SymbolFlags.ExportValue, Diagnostics.Cannot_find_name_0, node) || unknownSymbol;
41184124
}
41194125
return links.resolvedSymbol;
41204126
}

0 commit comments

Comments
 (0)