diff --git a/scripts/buildProtocol.js b/scripts/buildProtocol.js new file mode 100644 index 00000000000..db080839309 --- /dev/null +++ b/scripts/buildProtocol.js @@ -0,0 +1,135 @@ +/// +"use strict"; +var ts = require("../lib/typescript"); +var path = require("path"); +function endsWith(s, suffix) { + return s.lastIndexOf(suffix, s.length - suffix.length) !== -1; +} +var DeclarationsWalker = (function () { + function DeclarationsWalker(typeChecker, protocolFile) { + this.typeChecker = typeChecker; + this.protocolFile = protocolFile; + this.visitedTypes = []; + this.text = ""; + } + DeclarationsWalker.getExtraDeclarations = function (typeChecker, protocolFile) { + var text = "declare namespace ts.server.protocol {\n"; + var walker = new DeclarationsWalker(typeChecker, protocolFile); + walker.visitTypeNodes(protocolFile); + return walker.text + ? "declare namespace ts.server.protocol {\n" + walker.text + "}" + : ""; + }; + DeclarationsWalker.prototype.processType = function (type) { + if (this.visitedTypes.indexOf(type) >= 0) { + return; + } + this.visitedTypes.push(type); + var s = type.aliasSymbol || type.getSymbol(); + if (!s) { + return; + } + if (s.name === "Array") { + // we should process type argument instead + return this.processType(type.typeArguments[0]); + } + else { + for (var _i = 0, _a = s.getDeclarations(); _i < _a.length; _i++) { + var decl = _a[_i]; + var sourceFile = decl.getSourceFile(); + if (sourceFile === this.protocolFile || path.basename(sourceFile.fileName) === "lib.d.ts") { + return; + } + // splice declaration in final d.ts file + var text = decl.getFullText(); + this.text += text + "\n"; + // recursively pull all dependencies into result dts file + this.visitTypeNodes(decl); + } + } + }; + DeclarationsWalker.prototype.visitTypeNodes = function (node) { + var _this = this; + if (node.parent) { + switch (node.parent.kind) { + case ts.SyntaxKind.VariableDeclaration: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertySignature: + case ts.SyntaxKind.Parameter: + case ts.SyntaxKind.IndexSignature: + if ((node.parent.type) === node) { + var type = this.typeChecker.getTypeAtLocation(node); + if (type && !(type.flags & ts.TypeFlags.TypeParameter)) { + this.processType(type); + } + } + break; + } + } + ts.forEachChild(node, function (n) { return _this.visitTypeNodes(n); }); + }; + return DeclarationsWalker; +}()); +function generateProtocolFile(protocolTs, typeScriptServicesDts) { + var options = { target: ts.ScriptTarget.ES5, declaration: true, noResolve: true, types: [], stripInternal: true }; + /** + * 1st pass - generate a program from protocol.ts and typescriptservices.d.ts and emit core version of protocol.d.ts with all internal members stripped + * @return text of protocol.d.t.s + */ + function getInitialDtsFileForProtocol() { + var program = ts.createProgram([protocolTs, typeScriptServicesDts], options); + var protocolDts; + program.emit(program.getSourceFile(protocolTs), function (file, content) { + if (endsWith(file, ".d.ts")) { + protocolDts = content; + } + }); + if (protocolDts === undefined) { + throw new Error("Declaration file for protocol.ts is not generated"); + } + return protocolDts; + } + var protocolFileName = "protocol.d.ts"; + /** + * Second pass - generate a program from protocol.d.ts and typescriptservices.d.ts, then augment core protocol.d.ts with extra types from typescriptservices.d.ts + */ + function getProgramWithProtocolText(protocolDts, includeTypeScriptServices) { + var host = ts.createCompilerHost(options); + var originalGetSourceFile = host.getSourceFile; + host.getSourceFile = function (fileName) { + if (fileName === protocolFileName) { + return ts.createSourceFile(fileName, protocolDts, options.target); + } + return originalGetSourceFile.apply(host, [fileName]); + }; + var rootFiles = includeTypeScriptServices ? [protocolFileName, typeScriptServicesDts] : [protocolFileName]; + return ts.createProgram(rootFiles, options, host); + } + var protocolDts = getInitialDtsFileForProtocol(); + var program = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ true); + var protocolFile = program.getSourceFile("protocol.d.ts"); + var extraDeclarations = DeclarationsWalker.getExtraDeclarations(program.getTypeChecker(), protocolFile); + if (extraDeclarations) { + protocolDts += extraDeclarations; + } + // do sanity check and try to compile generated text as standalone program + var sanityCheckProgram = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ false); + var diagnostics = program.getSyntacticDiagnostics().concat(program.getSemanticDiagnostics(), program.getGlobalDiagnostics()); + if (diagnostics.length) { + var flattenedDiagnostics = diagnostics.map(function (d) { return ts.flattenDiagnosticMessageText(d.messageText, "\n"); }).join("\n"); + throw new Error("Unexpected errors during sanity check: " + flattenedDiagnostics); + } + return protocolDts; +} +if (process.argv.length < 5) { + console.log("Expected 3 arguments: path to 'protocol.ts', path to 'typescriptservices.d.ts' and path to output file"); + process.exit(1); +} +var protocolTs = process.argv[2]; +var typeScriptServicesDts = process.argv[3]; +var outputFile = process.argv[4]; +var generatedProtocolDts = generateProtocolFile(protocolTs, typeScriptServicesDts); +ts.sys.writeFile(outputFile, generatedProtocolDts); +//# sourceMappingURL=file:///C:/repo/TypeScript/scripts/buildProtocol.js.map \ No newline at end of file diff --git a/src/services/codefixes/interfaceFixes.ts b/src/services/codefixes/interfaceFixes.ts index 49d69497333..dc507360db1 100644 --- a/src/services/codefixes/interfaceFixes.ts +++ b/src/services/codefixes/interfaceFixes.ts @@ -1,46 +1,5 @@ /* @internal */ namespace ts.codefix { - registerCodeFix({ - errorCodes: [Diagnostics.Type_0_is_not_assignable_to_type_1.code], - getCodeActions: (context: CodeFixContext) => { - const sourceFile = context.sourceFile; - const start = context.span.start; - const token = getTokenAtPosition(sourceFile, start); - const checker = context.program.getTypeChecker(); - let textChanges: TextChange[] = []; - - if (token.kind === SyntaxKind.Identifier && token.parent.kind === SyntaxKind.VariableDeclaration) { - const variableDeclaration = token.parent; - const membersAndStartPosObject = getMembersAndStartPosFromReference(variableDeclaration); - const variableMembers = membersAndStartPosObject.members; - const trackingAddedMembers: string[] = []; - const startPos: number = membersAndStartPosObject.startPos; - - if (variableDeclaration.type.kind === SyntaxKind.TypeReference) { - textChanges = textChanges.concat(getChanges(variableDeclaration.type, variableMembers, startPos, checker, /*reference*/ true, trackingAddedMembers, context.newLineCharacter)); - } - else if (variableDeclaration.type.kind === SyntaxKind.UnionType) { - const types = (variableDeclaration.type).types; - ts.forEach(types, t => { - textChanges = textChanges.concat(getChanges(t, variableMembers, startPos, checker, /*reference*/ true, trackingAddedMembers, context.newLineCharacter)); - }); - } - } - - if (textChanges.length > 0) { - return [{ - description: getLocaleSpecificMessage(Diagnostics.Implement_interface_on_reference), - changes: [{ - fileName: sourceFile.fileName, - textChanges: textChanges - }] - }]; - } - - return undefined; - } - }); - registerCodeFix({ errorCodes: [Diagnostics.Class_0_incorrectly_implements_interface_1.code], getCodeActions: (context: CodeFixContext) => { diff --git a/tests/cases/fourslash/unImplementedInterface14.ts b/tests/cases/fourslash/unImplementedInterface14.ts index ad55fef3cce..d5da3231b7b 100644 --- a/tests/cases/fourslash/unImplementedInterface14.ts +++ b/tests/cases/fourslash/unImplementedInterface14.ts @@ -10,7 +10,8 @@ //// |]f2() {} //// } -verify.codeFixAtPosition(`f1(){ - throw new Error('Method not Implemented'); -}, -`); +verify.not.codeFixAvailable(); +// verify.codeFixAtPosition(`f1(){ +// throw new Error('Method not Implemented'); +// }, +// `); \ No newline at end of file diff --git a/tests/cases/fourslash/unImplementedInterface15.ts b/tests/cases/fourslash/unImplementedInterface15.ts index e68f7171ee5..005ece4ea50 100644 --- a/tests/cases/fourslash/unImplementedInterface15.ts +++ b/tests/cases/fourslash/unImplementedInterface15.ts @@ -8,8 +8,9 @@ //// //// |]} -verify.codeFixAtPosition(` -f1(){ - throw new Error('Method not Implemented'); -} -`); +verify.not.codeFixAvailable(); +// verify.codeFixAtPosition(` +// f1(){ +// throw new Error('Method not Implemented'); +// } +// `); \ No newline at end of file diff --git a/tests/cases/fourslash/unImplementedInterface16.ts b/tests/cases/fourslash/unImplementedInterface16.ts index ca992b1eb1e..091174b47c4 100644 --- a/tests/cases/fourslash/unImplementedInterface16.ts +++ b/tests/cases/fourslash/unImplementedInterface16.ts @@ -8,5 +8,6 @@ //// var x: I1 ={[| //// |]} -verify.codeFixAtPosition(`x : "" -`); +verify.not.codeFixAvailable(); +// verify.codeFixAtPosition(`x : "" +// `); \ No newline at end of file diff --git a/tests/cases/fourslash/unImplementedInterface17.ts b/tests/cases/fourslash/unImplementedInterface17.ts index e909b60f588..7fa3cc61be3 100644 --- a/tests/cases/fourslash/unImplementedInterface17.ts +++ b/tests/cases/fourslash/unImplementedInterface17.ts @@ -7,5 +7,6 @@ //// var x: I1 ={[| //// |]} -verify.codeFixAtPosition(`x : 0 -`); +verify.not.codeFixAvailable(); +// verify.codeFixAtPosition(`x : 0 +// `); \ No newline at end of file diff --git a/tests/cases/fourslash/unImplementedInterface18.ts b/tests/cases/fourslash/unImplementedInterface18.ts index 9e0f9888bf3..0fa0eaefa56 100644 --- a/tests/cases/fourslash/unImplementedInterface18.ts +++ b/tests/cases/fourslash/unImplementedInterface18.ts @@ -8,5 +8,6 @@ //// //// |]} -verify.codeFixAtPosition(`x : false -`); +verify.not.codeFixAvailable(); +// verify.codeFixAtPosition(`x : false +// `); \ No newline at end of file diff --git a/tests/cases/fourslash/unImplementedInterface19.ts b/tests/cases/fourslash/unImplementedInterface19.ts index de484c282d8..d037a8611b3 100644 --- a/tests/cases/fourslash/unImplementedInterface19.ts +++ b/tests/cases/fourslash/unImplementedInterface19.ts @@ -9,5 +9,6 @@ //// |]f1(){} //// } -verify.codeFixAtPosition(`x : "", -`); +verify.not.codeFixAvailable(); +// verify.codeFixAtPosition(`x : "", +// `); \ No newline at end of file diff --git a/tests/cases/fourslash/unImplementedInterface20.ts b/tests/cases/fourslash/unImplementedInterface20.ts index 56a707d21ba..ffd3c8914b8 100644 --- a/tests/cases/fourslash/unImplementedInterface20.ts +++ b/tests/cases/fourslash/unImplementedInterface20.ts @@ -10,5 +10,6 @@ //// |]f1(){} //// } -verify.codeFixAtPosition(`x : 0, -`); +verify.not.codeFixAvailable(); +// verify.codeFixAtPosition(`x : 0, +// `); \ No newline at end of file diff --git a/tests/cases/fourslash/unImplementedInterface21.ts b/tests/cases/fourslash/unImplementedInterface21.ts index 867c697e595..39e9aaf0e96 100644 --- a/tests/cases/fourslash/unImplementedInterface21.ts +++ b/tests/cases/fourslash/unImplementedInterface21.ts @@ -10,5 +10,6 @@ //// |]f1(){} //// } -verify.codeFixAtPosition(`x : false, -`); +verify.not.codeFixAvailable(); +// verify.codeFixAtPosition(`x : false, +// `); \ No newline at end of file diff --git a/tests/cases/fourslash/unImplementedInterface22.ts b/tests/cases/fourslash/unImplementedInterface22.ts index 8a51577261f..8caeb26eb45 100644 --- a/tests/cases/fourslash/unImplementedInterface22.ts +++ b/tests/cases/fourslash/unImplementedInterface22.ts @@ -8,5 +8,6 @@ //// var x: I1 ={[| //// |]} -verify.codeFixAtPosition(`x : null -`); +verify.not.codeFixAvailable(); +// verify.codeFixAtPosition(`x : null +// `); \ No newline at end of file diff --git a/tests/cases/fourslash/unImplementedInterface23.ts b/tests/cases/fourslash/unImplementedInterface23.ts index 8d00689a446..70e3db4f57d 100644 --- a/tests/cases/fourslash/unImplementedInterface23.ts +++ b/tests/cases/fourslash/unImplementedInterface23.ts @@ -10,5 +10,6 @@ //// |]f1(){} //// } -verify.codeFixAtPosition(`x : null, -`); +verify.not.codeFixAvailable(); +// verify.codeFixAtPosition(`x : null, +// `); \ No newline at end of file diff --git a/tests/cases/fourslash/unImplementedInterface24.ts b/tests/cases/fourslash/unImplementedInterface24.ts index c206789b7f2..dead538d04d 100644 --- a/tests/cases/fourslash/unImplementedInterface24.ts +++ b/tests/cases/fourslash/unImplementedInterface24.ts @@ -8,5 +8,6 @@ //// var x: I1 ={[| //// |]} -verify.codeFixAtPosition(`x : null -`); +verify.not.codeFixAvailable(); +// verify.codeFixAtPosition(`x : null +// `); \ No newline at end of file diff --git a/tests/cases/fourslash/unImplementedInterface25.ts b/tests/cases/fourslash/unImplementedInterface25.ts index 6b2b809efaa..84a018edc16 100644 --- a/tests/cases/fourslash/unImplementedInterface25.ts +++ b/tests/cases/fourslash/unImplementedInterface25.ts @@ -10,5 +10,6 @@ //// |]f1(){} //// } -verify.codeFixAtPosition(`x : null, -`); +verify.not.codeFixAvailable(); +// verify.codeFixAtPosition(`x : null, +// `); \ No newline at end of file diff --git a/tests/cases/fourslash/unImplementedInterface26.ts b/tests/cases/fourslash/unImplementedInterface26.ts index a7136f0e70f..b75eac7184e 100644 --- a/tests/cases/fourslash/unImplementedInterface26.ts +++ b/tests/cases/fourslash/unImplementedInterface26.ts @@ -10,5 +10,6 @@ //// var x: I1 ={[| //// |]} -verify.codeFixAtPosition(`x : null -`); +verify.not.codeFixAvailable(); +// verify.codeFixAtPosition(`x : null +// `); \ No newline at end of file diff --git a/tests/cases/fourslash/unImplementedInterface27.ts b/tests/cases/fourslash/unImplementedInterface27.ts index fc12cb57377..10460158694 100644 --- a/tests/cases/fourslash/unImplementedInterface27.ts +++ b/tests/cases/fourslash/unImplementedInterface27.ts @@ -12,5 +12,6 @@ //// |]f1(){} //// } -verify.codeFixAtPosition(`x : null, -`); +verify.not.codeFixAvailable(); +// verify.codeFixAtPosition(`x : null, +// `); \ No newline at end of file diff --git a/tests/cases/fourslash/unImplementedInterface28.ts b/tests/cases/fourslash/unImplementedInterface28.ts index 16cbe47b26c..0e3aa3e95fb 100644 --- a/tests/cases/fourslash/unImplementedInterface28.ts +++ b/tests/cases/fourslash/unImplementedInterface28.ts @@ -12,10 +12,11 @@ //// //// |]} -verify.codeFixAtPosition(`f1(){ - throw new Error('Method not Implemented'); -} -f2(){ - throw new Error('Method not Implemented'); -} -`); +verify.not.codeFixAvailable(); +// verify.codeFixAtPosition(`f1(){ +// throw new Error('Method not Implemented'); +// } +// f2(){ +// throw new Error('Method not Implemented'); +// } +// `); \ No newline at end of file diff --git a/tests/cases/fourslash/unImplementedInterface38.ts b/tests/cases/fourslash/unImplementedInterface38.ts index c60b9922ef8..8d1e06c4c47 100644 --- a/tests/cases/fourslash/unImplementedInterface38.ts +++ b/tests/cases/fourslash/unImplementedInterface38.ts @@ -6,6 +6,7 @@ //// //// var x: C2 = {[| |]} -verify.codeFixAtPosition(`f1(){ - throw new Error('Method not Implemented'); -}`); +verify.not.codeFixAvailable(); +// verify.codeFixAtPosition(`f1(){ +// throw new Error('Method not Implemented'); +// }`); \ No newline at end of file