@@ -63,7 +63,8 @@ module ts {
6363 /* @internal */ scriptSnapshot : IScriptSnapshot ;
6464 /* @internal */ nameTable : Map < string > ;
6565
66- getNamedDeclarations ( ) : Declaration [ ] ;
66+ /* @internal */ getNamedDeclarations ( ) : Map < Declaration [ ] > ;
67+
6768 getLineAndCharacterOfPosition ( pos : number ) : LineAndCharacter ;
6869 getLineStarts ( ) : number [ ] ;
6970 getPositionOfLineAndCharacter ( line : number , character : number ) : number ;
@@ -749,7 +750,7 @@ module ts {
749750 public identifiers : Map < string > ;
750751 public nameTable : Map < string > ;
751752
752- private namedDeclarations : Declaration [ ] ;
753+ private namedDeclarations : Map < Declaration [ ] > ;
753754
754755 public update ( newText : string , textChangeRange : TextChangeRange ) : SourceFile {
755756 return updateSourceFile ( this , newText , textChangeRange ) ;
@@ -767,43 +768,88 @@ module ts {
767768 return ts . getPositionOfLineAndCharacter ( this , line , character ) ;
768769 }
769770
770- public getNamedDeclarations ( ) {
771+ public getNamedDeclarations ( ) : Map < Declaration [ ] > {
771772 if ( ! this . namedDeclarations ) {
772773 this . namedDeclarations = this . computeNamedDeclarations ( ) ;
773774 }
774775
775776 return this . namedDeclarations ;
776777 }
777778
778- private computeNamedDeclarations ( ) {
779- let namedDeclarations : Declaration [ ] = [ ] ;
779+ private computeNamedDeclarations ( ) : Map < Declaration [ ] > {
780+ let result : Map < Declaration [ ] > = { } ;
780781
781782 forEachChild ( this , visit ) ;
782783
783- return namedDeclarations ;
784+ return result ;
785+
786+ function addDeclaration ( declaration : Declaration ) {
787+ let name = getDeclarationName ( declaration ) ;
788+ if ( name ) {
789+ let declarations = getDeclarations ( name ) ;
790+ declarations . push ( declaration ) ;
791+ }
792+ }
793+
794+ function getDeclarations ( name : string ) {
795+ return getProperty ( result , name ) || ( result [ name ] = [ ] ) ;
796+ }
797+
798+ function getDeclarationName ( declaration : Declaration ) {
799+ if ( declaration . name ) {
800+ let result = getTextOfIdentifierOrLiteral ( declaration . name ) ;
801+ if ( result !== undefined ) {
802+ return result ;
803+ }
804+
805+ if ( declaration . name . kind === SyntaxKind . ComputedPropertyName ) {
806+ let expr = ( < ComputedPropertyName > declaration . name ) . expression ;
807+ if ( expr . kind === SyntaxKind . PropertyAccessExpression ) {
808+ return ( < PropertyAccessExpression > expr ) . name . text ;
809+ }
810+
811+ return getTextOfIdentifierOrLiteral ( expr ) ;
812+ }
813+ }
814+
815+ return undefined ;
816+ }
817+
818+ function getTextOfIdentifierOrLiteral ( node : Node ) {
819+ if ( node ) {
820+ if ( node . kind === SyntaxKind . Identifier ||
821+ node . kind === SyntaxKind . StringLiteral ||
822+ node . kind === SyntaxKind . NumericLiteral ) {
823+
824+ return ( < Identifier | LiteralExpression > node ) . text ;
825+ }
826+ }
827+
828+ return undefined ;
829+ }
784830
785831 function visit ( node : Node ) : void {
786832 switch ( node . kind ) {
787833 case SyntaxKind . FunctionDeclaration :
788834 case SyntaxKind . MethodDeclaration :
789835 case SyntaxKind . MethodSignature :
790836 let functionDeclaration = < FunctionLikeDeclaration > node ;
837+ let declarationName = getDeclarationName ( functionDeclaration ) ;
791838
792- if ( functionDeclaration . name && functionDeclaration . name . getFullWidth ( ) > 0 ) {
793- let lastDeclaration = namedDeclarations . length > 0 ?
794- namedDeclarations [ namedDeclarations . length - 1 ] :
795- undefined ;
839+ if ( declarationName ) {
840+ let declarations = getDeclarations ( declarationName ) ;
841+ let lastDeclaration = lastOrUndefined ( declarations ) ;
796842
797843 // Check whether this declaration belongs to an "overload group".
798- if ( lastDeclaration && functionDeclaration . symbol === lastDeclaration . symbol ) {
844+ if ( lastDeclaration && functionDeclaration . parent === lastDeclaration . parent && functionDeclaration . symbol === lastDeclaration . symbol ) {
799845 // Overwrite the last declaration if it was an overload
800846 // and this one is an implementation.
801847 if ( functionDeclaration . body && ! ( < FunctionLikeDeclaration > lastDeclaration ) . body ) {
802- namedDeclarations [ namedDeclarations . length - 1 ] = functionDeclaration ;
848+ declarations [ declarations . length - 1 ] = functionDeclaration ;
803849 }
804850 }
805851 else {
806- namedDeclarations . push ( functionDeclaration ) ;
852+ declarations . push ( functionDeclaration ) ;
807853 }
808854
809855 forEachChild ( node , visit ) ;
@@ -824,10 +870,8 @@ module ts {
824870 case SyntaxKind . GetAccessor :
825871 case SyntaxKind . SetAccessor :
826872 case SyntaxKind . TypeLiteral :
827- if ( ( < Declaration > node ) . name ) {
828- namedDeclarations . push ( < Declaration > node ) ;
829- }
830- // fall through
873+ addDeclaration ( < Declaration > node ) ;
874+ // fall through
831875 case SyntaxKind . Constructor :
832876 case SyntaxKind . VariableStatement :
833877 case SyntaxKind . VariableDeclarationList :
@@ -858,7 +902,7 @@ module ts {
858902 case SyntaxKind . EnumMember :
859903 case SyntaxKind . PropertyDeclaration :
860904 case SyntaxKind . PropertySignature :
861- namedDeclarations . push ( < Declaration > node ) ;
905+ addDeclaration ( < Declaration > node ) ;
862906 break ;
863907
864908 case SyntaxKind . ExportDeclaration :
@@ -875,15 +919,15 @@ module ts {
875919 // Handle default import case e.g.:
876920 // import d from "mod";
877921 if ( importClause . name ) {
878- namedDeclarations . push ( importClause ) ;
922+ addDeclaration ( importClause ) ;
879923 }
880924
881925 // Handle named bindings in imports e.g.:
882926 // import * as NS from "mod";
883927 // import {a, b as B} from "mod";
884928 if ( importClause . namedBindings ) {
885929 if ( importClause . namedBindings . kind === SyntaxKind . NamespaceImport ) {
886- namedDeclarations . push ( < NamespaceImport > importClause . namedBindings ) ;
930+ addDeclaration ( < NamespaceImport > importClause . namedBindings ) ;
887931 }
888932 else {
889933 forEach ( ( < NamedImports > importClause . namedBindings ) . elements , visit ) ;
0 commit comments