Merge pull request #5706 from Microsoft/nameResolutionForParameters

restrict the scope of parameters\type parameters
This commit is contained in:
Vladimir Matveev
2015-11-17 17:09:53 -08:00
10 changed files with 224 additions and 7 deletions

View File

@@ -476,15 +476,41 @@ namespace ts {
// Locals of a source file are not in scope (because they get merged into the global symbol table)
if (location.locals && !isGlobalSourceFile(location)) {
if (result = getSymbol(location.locals, name, meaning)) {
// Type parameters of a function are in scope in the entire function declaration, including the parameter
// list and return type. However, local types are only in scope in the function body.
if (!(meaning & SymbolFlags.Type) ||
!(result.flags & (SymbolFlags.Type & ~SymbolFlags.TypeParameter)) ||
!isFunctionLike(location) ||
lastLocation === (<FunctionLikeDeclaration>location).body) {
let useResult = true;
if (isFunctionLike(location) && lastLocation && lastLocation !== (<FunctionLikeDeclaration>location).body) {
// symbol lookup restrictions for function-like declarations
// - Type parameters of a function are in scope in the entire function declaration, including the parameter
// list and return type. However, local types are only in scope in the function body.
// - parameters are only in the scope of function body
if (meaning & result.flags & SymbolFlags.Type) {
useResult = result.flags & SymbolFlags.TypeParameter
// type parameters are visible in parameter list, return type and type parameter list
? lastLocation === (<FunctionLikeDeclaration>location).type ||
lastLocation.kind === SyntaxKind.Parameter ||
lastLocation.kind === SyntaxKind.TypeParameter
// local types not visible outside the function body
: false;
}
if (meaning & SymbolFlags.Value && result.flags & SymbolFlags.FunctionScopedVariable) {
// parameters are visible only inside function body, parameter list and return type
// technically for parameter list case here we might mix parameters and variables declared in function,
// however it is detected separately when checking initializers of parameters
// to make sure that they reference no variables declared after them.
useResult =
lastLocation.kind === SyntaxKind.Parameter ||
(
lastLocation === (<FunctionLikeDeclaration>location).type &&
result.valueDeclaration.kind === SyntaxKind.Parameter
);
}
}
if (useResult) {
break loop;
}
result = undefined;
else {
result = undefined;
}
}
}
switch (location.kind) {