fix(language-service): remove incompletely used parameter from `createLanguageServiceFromTypescript()` (#13278)

Fixes #13277
This commit is contained in:
Chuck Jazdzewski 2016-12-06 16:19:39 -08:00 committed by Alex Rickabaugh
parent 2893c2c0a2
commit 25c2141991
8 changed files with 43 additions and 55 deletions

View File

@ -19,7 +19,6 @@ import {TypeScriptServiceHost} from './typescript_host';
* @experimental * @experimental
*/ */
export class LanguageServicePlugin { export class LanguageServicePlugin {
private ts: typeof ts;
private serviceHost: TypeScriptServiceHost; private serviceHost: TypeScriptServiceHost;
private service: LanguageService; private service: LanguageService;
private host: ts.LanguageServiceHost; private host: ts.LanguageServiceHost;
@ -27,12 +26,11 @@ export class LanguageServicePlugin {
static 'extension-kind' = 'language-service'; static 'extension-kind' = 'language-service';
constructor(config: { constructor(config: {
ts: typeof ts; host: ts.LanguageServiceHost; service: ts.LanguageService; host: ts.LanguageServiceHost; service: ts.LanguageService;
registry?: ts.DocumentRegistry, args?: any registry?: ts.DocumentRegistry, args?: any
}) { }) {
this.ts = config.ts;
this.host = config.host; this.host = config.host;
this.serviceHost = new TypeScriptServiceHost(this.ts, config.host, config.service); this.serviceHost = new TypeScriptServiceHost(config.host, config.service);
this.service = createLanguageService(this.serviceHost); this.service = createLanguageService(this.serviceHost);
this.serviceHost.setSite(this.service); this.serviceHost.setSite(this.service);
} }
@ -51,7 +49,7 @@ export class LanguageServicePlugin {
start: error.span.start, start: error.span.start,
length: error.span.end - error.span.start, length: error.span.end - error.span.start,
messageText: error.message, messageText: error.message,
category: this.ts.DiagnosticCategory.Error, category: ts.DiagnosticCategory.Error,
code: 0 code: 0
}); });
} }

View File

@ -34,9 +34,8 @@ import {BuiltinType, CompletionKind, Declaration, DeclarationError, Declarations
* Create a `LanguageServiceHost` * Create a `LanguageServiceHost`
*/ */
export function createLanguageServiceFromTypescript( export function createLanguageServiceFromTypescript(
typescript: typeof ts, host: ts.LanguageServiceHost, host: ts.LanguageServiceHost, service: ts.LanguageService): LanguageService {
service: ts.LanguageService): LanguageService { const ngHost = new TypeScriptServiceHost(host, service);
const ngHost = new TypeScriptServiceHost(typescript, host, service);
const ngServer = createLanguageService(ngHost); const ngServer = createLanguageService(ngHost);
ngHost.setSite(ngServer); ngHost.setSite(ngServer);
return ngServer; return ngServer;
@ -74,7 +73,6 @@ export class DummyResourceLoader extends ResourceLoader {
* @expermental * @expermental
*/ */
export class TypeScriptServiceHost implements LanguageServiceHost { export class TypeScriptServiceHost implements LanguageServiceHost {
private ts: typeof ts;
private _resolver: CompileMetadataResolver; private _resolver: CompileMetadataResolver;
private _staticSymbolCache = new StaticSymbolCache(); private _staticSymbolCache = new StaticSymbolCache();
private _reflector: StaticReflector; private _reflector: StaticReflector;
@ -90,11 +88,7 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
private templateReferences: string[]; private templateReferences: string[];
private collectedErrors: Map<string, any[]>; private collectedErrors: Map<string, any[]>;
constructor( constructor(private host: ts.LanguageServiceHost, private tsService: ts.LanguageService) {}
typescript: typeof ts, private host: ts.LanguageServiceHost,
private tsService: ts.LanguageService) {
this.ts = typescript;
}
setSite(service: LanguageService) { this.service = service; } setSite(service: LanguageService) { this.service = service; }
@ -190,14 +184,14 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
if (templateSource) { if (templateSource) {
result.push(templateSource); result.push(templateSource);
} else { } else {
this.ts.forEachChild(child, visit); ts.forEachChild(child, visit);
} }
}; };
let sourceFile = this.getSourceFile(fileName); let sourceFile = this.getSourceFile(fileName);
if (sourceFile) { if (sourceFile) {
this.context = sourceFile.path; this.context = sourceFile.path;
this.ts.forEachChild(sourceFile, visit); ts.forEachChild(sourceFile, visit);
} }
return result.length ? result : undefined; return result.length ? result : undefined;
} }
@ -304,7 +298,7 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
return new TypeWrapper(type, {node, program, checker}).members();}, return new TypeWrapper(type, {node, program, checker}).members();},
get query(): SymbolQuery{ get query(): SymbolQuery{
if (!queryCache) { if (!queryCache) {
queryCache = new TypeScriptSymbolQuery(t.ts, t.program, t.checker, sourceFile, () => { queryCache = new TypeScriptSymbolQuery(t.program, t.checker, sourceFile, () => {
const pipes = t.service.getPipesAt(fileName, node.getStart()); const pipes = t.service.getPipesAt(fileName, node.getStart());
const checker = t.checker; const checker = t.checker;
const program = t.program; const program = t.program;
@ -321,8 +315,8 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
let result: TemplateSource|undefined = undefined; let result: TemplateSource|undefined = undefined;
const t = this; const t = this;
switch (node.kind) { switch (node.kind) {
case this.ts.SyntaxKind.NoSubstitutionTemplateLiteral: case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
case this.ts.SyntaxKind.StringLiteral: case ts.SyntaxKind.StringLiteral:
let [declaration, decorator] = this.getTemplateClassDeclFromNode(node); let [declaration, decorator] = this.getTemplateClassDeclFromNode(node);
let queryCache: SymbolQuery|undefined = undefined; let queryCache: SymbolQuery|undefined = undefined;
if (declaration && declaration.name) { if (declaration && declaration.name) {
@ -403,7 +397,7 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
private getTemplateClassFromStaticSymbol(type: StaticSymbol): ts.ClassDeclaration|undefined { private getTemplateClassFromStaticSymbol(type: StaticSymbol): ts.ClassDeclaration|undefined {
const source = this.getSourceFile(type.filePath); const source = this.getSourceFile(type.filePath);
if (source) { if (source) {
const declarationNode = this.ts.forEachChild(source, child => { const declarationNode = ts.forEachChild(source, child => {
if (child.kind === ts.SyntaxKind.ClassDeclaration) { if (child.kind === ts.SyntaxKind.ClassDeclaration) {
const classDeclaration = child as ts.ClassDeclaration; const classDeclaration = child as ts.ClassDeclaration;
if (classDeclaration.name.text === type.name) { if (classDeclaration.name.text === type.name) {
@ -431,7 +425,7 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
if (!parentNode) { if (!parentNode) {
return TypeScriptServiceHost.missingTemplate; return TypeScriptServiceHost.missingTemplate;
} }
if (parentNode.kind !== this.ts.SyntaxKind.PropertyAssignment) { if (parentNode.kind !== ts.SyntaxKind.PropertyAssignment) {
return TypeScriptServiceHost.missingTemplate; return TypeScriptServiceHost.missingTemplate;
} else { } else {
// TODO: Is this different for a literal, i.e. a quoted property name like "template"? // TODO: Is this different for a literal, i.e. a quoted property name like "template"?
@ -440,23 +434,23 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
} }
} }
parentNode = parentNode.parent; // ObjectLiteralExpression parentNode = parentNode.parent; // ObjectLiteralExpression
if (!parentNode || parentNode.kind !== this.ts.SyntaxKind.ObjectLiteralExpression) { if (!parentNode || parentNode.kind !== ts.SyntaxKind.ObjectLiteralExpression) {
return TypeScriptServiceHost.missingTemplate; return TypeScriptServiceHost.missingTemplate;
} }
parentNode = parentNode.parent; // CallExpression parentNode = parentNode.parent; // CallExpression
if (!parentNode || parentNode.kind !== this.ts.SyntaxKind.CallExpression) { if (!parentNode || parentNode.kind !== ts.SyntaxKind.CallExpression) {
return TypeScriptServiceHost.missingTemplate; return TypeScriptServiceHost.missingTemplate;
} }
const callTarget = (<ts.CallExpression>parentNode).expression; const callTarget = (<ts.CallExpression>parentNode).expression;
let decorator = parentNode.parent; // Decorator let decorator = parentNode.parent; // Decorator
if (!decorator || decorator.kind !== this.ts.SyntaxKind.Decorator) { if (!decorator || decorator.kind !== ts.SyntaxKind.Decorator) {
return TypeScriptServiceHost.missingTemplate; return TypeScriptServiceHost.missingTemplate;
} }
let declaration = <ts.ClassDeclaration>decorator.parent; // ClassDeclaration let declaration = <ts.ClassDeclaration>decorator.parent; // ClassDeclaration
if (!declaration || declaration.kind !== this.ts.SyntaxKind.ClassDeclaration) { if (!declaration || declaration.kind !== ts.SyntaxKind.ClassDeclaration) {
return TypeScriptServiceHost.missingTemplate; return TypeScriptServiceHost.missingTemplate;
} }
return [declaration, callTarget]; return [declaration, callTarget];
@ -515,9 +509,9 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
private stringOf(node: ts.Node): string|undefined { private stringOf(node: ts.Node): string|undefined {
switch (node.kind) { switch (node.kind) {
case this.ts.SyntaxKind.NoSubstitutionTemplateLiteral: case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
return (<ts.LiteralExpression>node).text; return (<ts.LiteralExpression>node).text;
case this.ts.SyntaxKind.StringLiteral: case ts.SyntaxKind.StringLiteral:
return (<ts.StringLiteral>node).text; return (<ts.StringLiteral>node).text;
} }
} }
@ -527,7 +521,7 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
function find(node: ts.Node): ts.Node|undefined { function find(node: ts.Node): ts.Node|undefined {
if (position >= node.getStart() && position < node.getEnd()) { if (position >= node.getStart() && position < node.getEnd()) {
return _this.ts.forEachChild(node, find) || node; return ts.forEachChild(node, find) || node;
} }
} }
@ -540,26 +534,26 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
switch (kind) { switch (kind) {
case BuiltinType.Any: case BuiltinType.Any:
type = checker.getTypeAtLocation(<ts.Node><any>{ type = checker.getTypeAtLocation(<ts.Node><any>{
kind: this.ts.SyntaxKind.AsExpression, kind: ts.SyntaxKind.AsExpression,
expression: <ts.Node>{kind: this.ts.SyntaxKind.TrueKeyword}, expression: <ts.Node>{kind: ts.SyntaxKind.TrueKeyword},
type: <ts.Node>{kind: this.ts.SyntaxKind.AnyKeyword} type: <ts.Node>{kind: ts.SyntaxKind.AnyKeyword}
}); });
break; break;
case BuiltinType.Boolean: case BuiltinType.Boolean:
type = checker.getTypeAtLocation(<ts.Node>{kind: this.ts.SyntaxKind.TrueKeyword}); type = checker.getTypeAtLocation(<ts.Node>{kind: ts.SyntaxKind.TrueKeyword});
break; break;
case BuiltinType.Null: case BuiltinType.Null:
type = checker.getTypeAtLocation(<ts.Node>{kind: this.ts.SyntaxKind.NullKeyword}); type = checker.getTypeAtLocation(<ts.Node>{kind: ts.SyntaxKind.NullKeyword});
break; break;
case BuiltinType.Number: case BuiltinType.Number:
type = checker.getTypeAtLocation(<ts.Node>{kind: this.ts.SyntaxKind.NumericLiteral}); type = checker.getTypeAtLocation(<ts.Node>{kind: ts.SyntaxKind.NumericLiteral});
break; break;
case BuiltinType.String: case BuiltinType.String:
type = checker.getTypeAtLocation( type =
<ts.Node>{kind: this.ts.SyntaxKind.NoSubstitutionTemplateLiteral}); checker.getTypeAtLocation(<ts.Node>{kind: ts.SyntaxKind.NoSubstitutionTemplateLiteral});
break; break;
case BuiltinType.Undefined: case BuiltinType.Undefined:
type = checker.getTypeAtLocation(<ts.Node>{kind: this.ts.SyntaxKind.VoidExpression}); type = checker.getTypeAtLocation(<ts.Node>{kind: ts.SyntaxKind.VoidExpression});
break; break;
default: default:
throw new Error(`Internal error, unhandled literal kind ${kind}:${BuiltinType[kind]}`); throw new Error(`Internal error, unhandled literal kind ${kind}:${BuiltinType[kind]}`);
@ -569,30 +563,27 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
} }
class TypeScriptSymbolQuery implements SymbolQuery { class TypeScriptSymbolQuery implements SymbolQuery {
private ts: typeof ts;
private typeCache = new Map<BuiltinType, Symbol>(); private typeCache = new Map<BuiltinType, Symbol>();
private pipesCache: SymbolTable; private pipesCache: SymbolTable;
constructor( constructor(
typescript: typeof ts, private program: ts.Program, private checker: ts.TypeChecker, private program: ts.Program, private checker: ts.TypeChecker, private source: ts.SourceFile,
private source: ts.SourceFile, private fetchPipes: () => SymbolTable) { private fetchPipes: () => SymbolTable) {}
this.ts = typescript;
}
getTypeKind(symbol: Symbol): BuiltinType { getTypeKind(symbol: Symbol): BuiltinType {
const type = this.getTsTypeOf(symbol); const type = this.getTsTypeOf(symbol);
if (type) { if (type) {
if (type.flags & this.ts.TypeFlags.Any) { if (type.flags & ts.TypeFlags.Any) {
return BuiltinType.Any; return BuiltinType.Any;
} else if ( } else if (
type.flags & (this.ts.TypeFlags.String | this.ts.TypeFlags.StringLike | type.flags &
this.ts.TypeFlags.StringLiteral)) { (ts.TypeFlags.String | ts.TypeFlags.StringLike | ts.TypeFlags.StringLiteral)) {
return BuiltinType.String; return BuiltinType.String;
} else if (type.flags & (this.ts.TypeFlags.Number | this.ts.TypeFlags.NumberLike)) { } else if (type.flags & (ts.TypeFlags.Number | ts.TypeFlags.NumberLike)) {
return BuiltinType.Number; return BuiltinType.Number;
} else if (type.flags & (this.ts.TypeFlags.Undefined)) { } else if (type.flags & (ts.TypeFlags.Undefined)) {
return BuiltinType.Undefined; return BuiltinType.Undefined;
} else if (type.flags & (this.ts.TypeFlags.Null)) { } else if (type.flags & (ts.TypeFlags.Null)) {
return BuiltinType.Null; return BuiltinType.Null;
} }
} }

View File

@ -21,7 +21,7 @@ describe('completions', () => {
let mockHost = new MockTypescriptHost(['/app/main.ts', '/app/parsing-cases.ts'], toh); let mockHost = new MockTypescriptHost(['/app/main.ts', '/app/parsing-cases.ts'], toh);
let service = ts.createLanguageService(mockHost, documentRegistry); let service = ts.createLanguageService(mockHost, documentRegistry);
let program = service.getProgram(); let program = service.getProgram();
let ngHost = new TypeScriptServiceHost(ts, mockHost, service); let ngHost = new TypeScriptServiceHost(mockHost, service);
let ngService = createLanguageService(ngHost); let ngService = createLanguageService(ngHost);
ngHost.setSite(ngService); ngHost.setSite(ngService);

View File

@ -21,7 +21,7 @@ describe('definitions', () => {
let mockHost = new MockTypescriptHost(['/app/main.ts', '/app/parsing-cases.ts'], toh); let mockHost = new MockTypescriptHost(['/app/main.ts', '/app/parsing-cases.ts'], toh);
let service = ts.createLanguageService(mockHost, documentRegistry); let service = ts.createLanguageService(mockHost, documentRegistry);
let program = service.getProgram(); let program = service.getProgram();
let ngHost = new TypeScriptServiceHost(ts, mockHost, service); let ngHost = new TypeScriptServiceHost(mockHost, service);
let ngService = createLanguageService(ngHost); let ngService = createLanguageService(ngHost);
ngHost.setSite(ngService); ngHost.setSite(ngService);

View File

@ -20,7 +20,7 @@ describe('diagnostics', () => {
let mockHost = new MockTypescriptHost(['/app/main.ts', '/app/parsing-cases.ts'], toh); let mockHost = new MockTypescriptHost(['/app/main.ts', '/app/parsing-cases.ts'], toh);
let service = ts.createLanguageService(mockHost, documentRegistry); let service = ts.createLanguageService(mockHost, documentRegistry);
let program = service.getProgram(); let program = service.getProgram();
let ngHost = new TypeScriptServiceHost(ts, mockHost, service); let ngHost = new TypeScriptServiceHost(mockHost, service);
let ngService = createLanguageService(ngHost); let ngService = createLanguageService(ngHost);
ngHost.setSite(ngService); ngHost.setSite(ngService);

View File

@ -22,7 +22,7 @@ describe('hover', () => {
let mockHost = new MockTypescriptHost(['/app/main.ts', '/app/parsing-cases.ts'], toh); let mockHost = new MockTypescriptHost(['/app/main.ts', '/app/parsing-cases.ts'], toh);
let service = ts.createLanguageService(mockHost, documentRegistry); let service = ts.createLanguageService(mockHost, documentRegistry);
let program = service.getProgram(); let program = service.getProgram();
let ngHost = new TypeScriptServiceHost(ts, mockHost, service); let ngHost = new TypeScriptServiceHost(mockHost, service);
let ngService = createLanguageService(ngHost); let ngService = createLanguageService(ngHost);
ngHost.setSite(ngService); ngHost.setSite(ngService);

View File

@ -20,7 +20,7 @@ describe('references', () => {
let mockHost = new MockTypescriptHost(['/app/main.ts', '/app/parsing-cases.ts'], toh); let mockHost = new MockTypescriptHost(['/app/main.ts', '/app/parsing-cases.ts'], toh);
let service = ts.createLanguageService(mockHost, documentRegistry); let service = ts.createLanguageService(mockHost, documentRegistry);
let program = service.getProgram(); let program = service.getProgram();
let ngHost = new TypeScriptServiceHost(ts, mockHost, service); let ngHost = new TypeScriptServiceHost(mockHost, service);
let ngService = createLanguageService(ngHost); let ngService = createLanguageService(ngHost);
ngHost.setSite(ngService); ngHost.setSite(ngService);

View File

@ -29,8 +29,7 @@ describe('plugin', () => {
} }
}); });
let plugin = let plugin = new LanguageServicePlugin({host: mockHost, service, registry: documentRegistry});
new LanguageServicePlugin({ts: ts, host: mockHost, service, registry: documentRegistry});
it('should not report template errors on tour of heroes', () => { it('should not report template errors on tour of heroes', () => {
for (let source of program.getSourceFiles()) { for (let source of program.getSourceFiles()) {