11/// <reference path="parser.ts"/>
22
33/* @internal */
4- module ts {
4+ namespace ts {
55 export let bindTime = 0 ;
66
77 export const enum ModuleInstanceState {
@@ -90,10 +90,12 @@ module ts {
9090 let lastContainer : Node ;
9191 let symbolCount = 0 ;
9292 let Symbol = objectAllocator . getSymbolConstructor ( ) ;
93+ let classifiableNames : Map < string > = { } ;
9394
9495 if ( ! file . locals ) {
9596 bind ( file ) ;
9697 file . symbolCount = symbolCount ;
98+ file . classifiableNames = classifiableNames ;
9799 }
98100
99101 return ;
@@ -194,6 +196,11 @@ module ts {
194196 symbol = hasProperty ( symbolTable , name )
195197 ? symbolTable [ name ]
196198 : ( symbolTable [ name ] = createSymbol ( SymbolFlags . None , name ) ) ;
199+
200+ if ( name && ( includes & SymbolFlags . Classifiable ) ) {
201+ classifiableNames [ name ] = name ;
202+ }
203+
197204 if ( symbol . flags & excludes ) {
198205 if ( node . name ) {
199206 node . name . parent = node ;
@@ -553,6 +560,23 @@ module ts {
553560 bindBlockScopedDeclaration ( node , SymbolFlags . BlockScopedVariable , SymbolFlags . BlockScopedVariableExcludes ) ;
554561 }
555562
563+ // The binder visits every node in the syntax tree so it is a convenient place to perform a single localized
564+ // check for reserved words used as identifiers in strict mode code.
565+ function checkStrictModeIdentifier ( node : Identifier ) {
566+ if ( node . parserContextFlags & ParserContextFlags . StrictMode &&
567+ node . originalKeywordKind >= SyntaxKind . FirstFutureReservedWord &&
568+ node . originalKeywordKind <= SyntaxKind . LastFutureReservedWord &&
569+ ! isIdentifierName ( node ) ) {
570+ // Report error only if there are no parse errors in file
571+ if ( ! file . parseDiagnostics . length ) {
572+ let message = getAncestor ( node , SyntaxKind . ClassDeclaration ) || getAncestor ( node , SyntaxKind . ClassExpression ) ?
573+ Diagnostics . Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode :
574+ Diagnostics . Identifier_expected_0_is_a_reserved_word_in_strict_mode ;
575+ file . bindDiagnostics . push ( createDiagnosticForNode ( node , message , declarationNameToString ( node ) ) ) ;
576+ }
577+ }
578+ }
579+
556580 function getDestructuringParameterName ( node : Declaration ) {
557581 return "__" + indexOf ( ( < SignatureDeclaration > node . parent ) . parameters , node ) ;
558582 }
@@ -581,6 +605,8 @@ module ts {
581605
582606 function bindWorker ( node : Node ) {
583607 switch ( node . kind ) {
608+ case SyntaxKind . Identifier :
609+ return checkStrictModeIdentifier ( < Identifier > node ) ;
584610 case SyntaxKind . TypeParameter :
585611 return declareSymbolAndAddToSymbolTable ( < Declaration > node , SymbolFlags . TypeParameter , SymbolFlags . TypeParameterExcludes ) ;
586612 case SyntaxKind . Parameter :
@@ -661,7 +687,11 @@ module ts {
661687 }
662688
663689 function bindExportAssignment ( node : ExportAssignment ) {
664- if ( node . expression . kind === SyntaxKind . Identifier ) {
690+ if ( ! container . symbol || ! container . symbol . exports ) {
691+ // Export assignment in some sort of block construct
692+ bindAnonymousDeclaration ( node , SymbolFlags . Alias , getDeclarationName ( node ) ) ;
693+ }
694+ else if ( node . expression . kind === SyntaxKind . Identifier ) {
665695 // An export default clause with an identifier exports all meanings of that identifier
666696 declareSymbol ( container . symbol . exports , container . symbol , node , SymbolFlags . Alias , SymbolFlags . PropertyExcludes | SymbolFlags . AliasExcludes ) ;
667697 }
@@ -672,7 +702,11 @@ module ts {
672702 }
673703
674704 function bindExportDeclaration ( node : ExportDeclaration ) {
675- if ( ! node . exportClause ) {
705+ if ( ! container . symbol || ! container . symbol . exports ) {
706+ // Export * in some sort of block construct
707+ bindAnonymousDeclaration ( node , SymbolFlags . ExportStar , getDeclarationName ( node ) ) ;
708+ }
709+ else if ( ! node . exportClause ) {
676710 // All export * declarations are collected in an __export symbol
677711 declareSymbol ( container . symbol . exports , container . symbol , node , SymbolFlags . ExportStar , SymbolFlags . None ) ;
678712 }
0 commit comments