66 * found in the LICENSE file at https://angular.io/license
77 */
88
9- import { AotSummaryResolver , CompileDirectiveMetadata , CompileMetadataResolver , CompilerConfig , DEFAULT_INTERPOLATION_CONFIG , DirectiveNormalizer , DirectiveResolver , DomElementSchemaRegistry , HtmlParser , InterpolationConfig , NgAnalyzedModules , NgModuleResolver , ParseTreeResult , Parser , PipeResolver , ResourceLoader , StaticAndDynamicReflectionCapabilities , StaticReflector , StaticSymbol , StaticSymbolCache , StaticSymbolResolver , SummaryResolver , UrlResolver , analyzeNgModules , componentModuleUrl , createOfflineCompileUrlResolver , extractProgramSymbols } from '@angular/compiler' ;
9+ import { AotSummaryResolver , CompileMetadataResolver , CompilerConfig , DEFAULT_INTERPOLATION_CONFIG , DirectiveNormalizer , DirectiveResolver , DomElementSchemaRegistry , HtmlParser , InterpolationConfig , NgAnalyzedModules , NgModuleResolver , ParseTreeResult , PipeResolver , ResourceLoader , StaticAndDynamicReflectionCapabilities , StaticReflector , StaticSymbol , StaticSymbolCache , StaticSymbolResolver , SummaryResolver , analyzeNgModules , componentModuleUrl , createOfflineCompileUrlResolver , extractProgramSymbols } from '@angular/compiler' ;
1010import { AngularCompilerOptions } from '@angular/compiler-cli' ;
11- import { Type , ViewEncapsulation , ɵConsole as Console } from '@angular/core' ;
11+ import { ViewEncapsulation , ɵConsole as Console } from '@angular/core' ;
1212import * as fs from 'fs' ;
1313import * as path from 'path' ;
1414import * as ts from 'typescript' ;
1515
1616import { createLanguageService } from './language_service' ;
1717import { ReflectorHost } from './reflector_host' ;
1818import { BuiltinType , CompletionKind , Declaration , DeclarationError , Declarations , Definition , LanguageService , LanguageServiceHost , PipeInfo , Pipes , Signature , Span , Symbol , SymbolDeclaration , SymbolQuery , SymbolTable , TemplateSource , TemplateSources } from './types' ;
19+ import { isTypescriptVersion } from './utils' ;
1920
2021
2122
@@ -25,6 +26,7 @@ const isPrivate = (ts as any).ModifierFlags ?
2526 ( ( node : ts . Node ) =>
2627 ! ! ( ( ts as any ) . getCombinedModifierFlags ( node ) & ( ts as any ) . ModifierFlags . Private ) ) :
2728 ( ( node : ts . Node ) => ! ! ( node . flags & ( ts as any ) . NodeFlags . Private ) ) ;
29+
2830const isReferenceType = ( ts as any ) . ObjectFlags ?
2931 ( ( type : ts . Type ) =>
3032 ! ! ( type . flags & ( ts as any ) . TypeFlags . Object &&
@@ -46,11 +48,9 @@ export function createLanguageServiceFromTypescript(
4648 * The language service never needs the normalized versions of the metadata. To avoid parsing
4749 * the content and resolving references, return an empty file. This also allows normalizing
4850 * template that are syntatically incorrect which is required to provide completions in
49- * syntatically incorrect templates.
51+ * syntactically incorrect templates.
5052 */
5153export class DummyHtmlParser extends HtmlParser {
52- constructor ( ) { super ( ) ; }
53-
5454 parse (
5555 source : string , url : string , parseExpansionForms : boolean = false ,
5656 interpolationConfig : InterpolationConfig = DEFAULT_INTERPOLATION_CONFIG ) : ParseTreeResult {
@@ -71,7 +71,7 @@ export class DummyResourceLoader extends ResourceLoader {
7171 * The `TypeScriptServiceHost` implements the Angular `LanguageServiceHost` using
7272 * the TypeScript language services.
7373 *
74- * @expermental
74+ * @experimental
7575 */
7676export class TypeScriptServiceHost implements LanguageServiceHost {
7777 private _resolver : CompileMetadataResolver ;
@@ -342,7 +342,6 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
342342 case ts . SyntaxKind . NoSubstitutionTemplateLiteral :
343343 case ts . SyntaxKind . StringLiteral :
344344 let [ declaration , decorator ] = this . getTemplateClassDeclFromNode ( node ) ;
345- let queryCache : SymbolQuery | undefined = undefined ;
346345 if ( declaration && declaration . name ) {
347346 const sourceFile = this . getSourceFile ( fileName ) ;
348347 return this . getSourceFromDeclaration (
@@ -564,8 +563,6 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
564563 }
565564
566565 private findNode ( sourceFile : ts . SourceFile , position : number ) : ts . Node | undefined {
567- let _this = this ;
568-
569566 function find ( node : ts . Node ) : ts . Node | undefined {
570567 if ( position >= node . getStart ( ) && position < node . getEnd ( ) ) {
571568 return ts . forEachChild ( node , find ) || node ;
@@ -634,8 +631,6 @@ class TypeScriptSymbolQuery implements SymbolQuery {
634631
635632 getTypeUnion ( ...types : Symbol [ ] ) : Symbol {
636633 // TODO: Replace with typeChecker API when available
637- const checker = this . checker ;
638-
639634 // No API exists so the cheat is to just return the last type any if no types are given.
640635 return types . length ? types [ types . length - 1 ] : this . getBuiltinType ( BuiltinType . Any ) ;
641636 }
@@ -708,7 +703,9 @@ class TypeScriptSymbolQuery implements SymbolQuery {
708703
709704 private getTemplateRefContextType ( typeSymbol : ts . Symbol ) : ts . Symbol | undefined {
710705 const type = this . checker . getTypeOfSymbolAtLocation ( typeSymbol , this . source ) ;
711- const constructor = type . symbol && type . symbol . members && type . symbol . members [ '__constructor' ] ;
706+ const constructor = type . symbol && type . symbol . members &&
707+ getFromSymbolTable ( type . symbol . members ! , '__constructor' ) ;
708+
712709 if ( constructor ) {
713710 const constructorDeclaration = constructor . declarations ! [ 0 ] as ts . ConstructorTypeNode ;
714711 for ( const parameter of constructorDeclaration . parameters ) {
@@ -719,7 +716,7 @@ class TypeScriptSymbolQuery implements SymbolQuery {
719716 return typeReference . typeArguments [ 0 ] . symbol ;
720717 }
721718 }
722- } ;
719+ }
723720 }
724721 }
725722
@@ -761,29 +758,6 @@ function selectSignature(type: ts.Type, context: TypeContext, types: Symbol[]):
761758 return signatures . length ? new SignatureWrapper ( signatures [ 0 ] , context ) : undefined ;
762759}
763760
764- function toSymbolTable ( symbols : ts . Symbol [ ] ) : ts . SymbolTable {
765- const result : ts . SymbolTable = < any > { } ;
766- for ( const symbol of symbols ) {
767- result [ symbol . name ] = symbol ;
768- }
769- return result ;
770- }
771-
772- function toSymbols (
773- symbolTable : ts . SymbolTable | undefined , filter ?: ( symbol : ts . Symbol ) => boolean ) {
774- const result : ts . Symbol [ ] = [ ] ;
775- if ( ! symbolTable ) return result ;
776- const own = typeof symbolTable . hasOwnProperty === 'function' ?
777- ( name : string ) => symbolTable . hasOwnProperty ( name ) :
778- ( name : string ) => ! ! symbolTable [ name ] ;
779- for ( const name in symbolTable ) {
780- if ( own ( name ) && ( ! filter || filter ( symbolTable [ name ] ) ) ) {
781- result . push ( symbolTable [ name ] ) ;
782- }
783- }
784- return result ;
785- }
786-
787761class TypeWrapper implements Symbol {
788762 constructor ( public tsType : ts . Type , public context : TypeContext ) {
789763 if ( ! tsType ) {
@@ -932,31 +906,72 @@ class SignatureResultOverride implements Signature {
932906 get result ( ) : Symbol { return this . resultType ; }
933907}
934908
909+ function toSymbolTable ( symbols : ts . Symbol [ ] ) : ts . SymbolTable {
910+ if ( isTypescriptVersion ( '2.2' ) ) {
911+ const result = new Map < string , ts . Symbol > ( ) ;
912+ for ( const symbol of symbols ) {
913+ result . set ( symbol . name , symbol ) ;
914+ }
915+ return < ts . SymbolTable > ( result as any ) ;
916+ }
917+
918+ const result = < any > { } ;
919+ for ( const symbol of symbols ) {
920+ result [ symbol . name ] = symbol ;
921+ }
922+ return result as ts . SymbolTable ;
923+ }
924+
925+ function toSymbols ( symbolTable : ts . SymbolTable | undefined ) : ts . Symbol [ ] {
926+ if ( ! symbolTable ) return [ ] ;
927+
928+ const table = symbolTable as any ;
929+
930+ if ( typeof table . values === 'function' ) {
931+ return Array . from ( table . values ( ) ) as ts . Symbol [ ] ;
932+ }
933+
934+ const result : ts . Symbol [ ] = [ ] ;
935+
936+ const own = typeof table . hasOwnProperty === 'function' ?
937+ ( name : string ) => table . hasOwnProperty ( name ) :
938+ ( name : string ) => ! ! table [ name ] ;
939+
940+ for ( const name in table ) {
941+ if ( own ( name ) ) {
942+ result . push ( table [ name ] ) ;
943+ }
944+ }
945+ return result ;
946+ }
947+
935948class SymbolTableWrapper implements SymbolTable {
936949 private symbols : ts . Symbol [ ] ;
937950 private symbolTable : ts . SymbolTable ;
938951
939- constructor (
940- symbols : ts . SymbolTable | ts . Symbol [ ] | undefined , private context : TypeContext ,
941- filter ?: ( symbol : ts . Symbol ) => boolean ) {
952+ constructor ( symbols : ts . SymbolTable | ts . Symbol [ ] | undefined , private context : TypeContext ) {
942953 symbols = symbols || [ ] ;
954+
943955 if ( Array . isArray ( symbols ) ) {
944- this . symbols = filter ? symbols . filter ( filter ) : symbols ;
956+ this . symbols = symbols ;
945957 this . symbolTable = toSymbolTable ( symbols ) ;
946958 } else {
947- this . symbols = toSymbols ( symbols , filter ) ;
948- this . symbolTable = filter ? toSymbolTable ( this . symbols ) : symbols ;
959+ this . symbols = toSymbols ( symbols ) ;
960+ this . symbolTable = symbols ;
949961 }
950962 }
951963
952964 get size ( ) : number { return this . symbols . length ; }
953965
954966 get ( key : string ) : Symbol | undefined {
955- const symbol = this . symbolTable [ key ] ;
967+ const symbol = getFromSymbolTable ( this . symbolTable , key ) ;
956968 return symbol ? new SymbolWrapper ( symbol , this . context ) : undefined ;
957969 }
958970
959- has ( key : string ) : boolean { return this . symbolTable [ key ] != null ; }
971+ has ( key : string ) : boolean {
972+ const table : any = this . symbolTable ;
973+ return ( typeof table . has === 'function' ) ? table . has ( key ) : table [ key ] != null ;
974+ }
960975
961976 values ( ) : Symbol [ ] { return this . symbols . map ( s => new SymbolWrapper ( s , this . context ) ) ; }
962977}
@@ -1320,3 +1335,19 @@ function typeKindOf(type: ts.Type): BuiltinType {
13201335 }
13211336 return BuiltinType . Other ;
13221337}
1338+
1339+
1340+ function getFromSymbolTable ( symbolTable : ts . SymbolTable , key : string ) : ts . Symbol | undefined {
1341+ const table = symbolTable as any ;
1342+ let symbol : ts . Symbol | undefined ;
1343+
1344+ if ( typeof table . get === 'function' ) {
1345+ // TS 2.2 uses a Map
1346+ symbol = table . get ( key ) ;
1347+ } else {
1348+ // TS pre-2.2 uses an object
1349+ symbol = table [ key ] ;
1350+ }
1351+
1352+ return symbol ;
1353+ }
0 commit comments