From a0c47d452ef3d7612100a0fda4072bee20f9d333 Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Tue, 12 Sep 2017 00:57:56 +0000 Subject: [PATCH 1/7] chore(package): update @types/sinon to version 2.3.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d0c223908..9b526d959 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "@types/node": "7.0.32", "@types/rimraf": "2.0.2", "@types/object-hash": "0.5.29", - "@types/sinon": "2.3.3", + "@types/sinon": "2.3.4", "@types/temp": "0.8.29", "commitizen": "^2.9.6", "cz-conventional-changelog": "^2.0.0", From 6087974050c313488b2497c1c7aee10a3d8b3a15 Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Tue, 19 Sep 2017 18:18:11 +0000 Subject: [PATCH 2/7] chore(package): update @types/sinon to version 2.3.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9b526d959..c77757592 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "@types/node": "7.0.32", "@types/rimraf": "2.0.2", "@types/object-hash": "0.5.29", - "@types/sinon": "2.3.4", + "@types/sinon": "2.3.5", "@types/temp": "0.8.29", "commitizen": "^2.9.6", "cz-conventional-changelog": "^2.0.0", From 122329df15a50434e49719032ef8420cd7645e0b Mon Sep 17 00:00:00 2001 From: Tom van Ommeren Date: Wed, 27 Sep 2017 04:10:28 +0200 Subject: [PATCH 3/7] chore(package): upgrade to typescript 2.4.2 (#356) --- package.json | 2 +- src/ast.ts | 806 +------------------------ src/connection.ts | 4 +- src/diagnostics.ts | 13 +- src/fs.ts | 4 +- src/packages.ts | 4 +- src/project-manager.ts | 16 +- src/test/typescript-service-helpers.ts | 8 +- src/typescript-service.ts | 2 +- 9 files changed, 33 insertions(+), 826 deletions(-) diff --git a/package.json b/package.json index c77757592..2ff39be4e 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "opentracing": "^0.14.0", "semaphore-async-await": "^1.5.1", "string-similarity": "^1.1.0", - "typescript": "2.3.4", + "typescript": "2.4.2", "vscode-jsonrpc": "^3.3.1", "vscode-languageserver": "^3.1.0", "vscode-languageserver-types": "^3.0.3" diff --git a/src/ast.ts b/src/ast.ts index ae70f8b55..f17555e84 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -8,814 +8,10 @@ import * as ts from 'typescript'; */ export function *walkMostAST(node: ts.Node): IterableIterator { yield node; - // TODO don't maintain an array - const children: ts.Node[] = []; - switch (node.kind) { - case ts.SyntaxKind.QualifiedName: { - const n = node as ts.QualifiedName; - children.push(n.left, n.right); - break; - } - case ts.SyntaxKind.ComputedPropertyName: { - const n = node as ts.ComputedPropertyName; - children.push(n.expression); - break; - } - case ts.SyntaxKind.TypeParameter: { - const n = node as ts.TypeParameterDeclaration; - pushall(children, n.name, n.constraint, n.expression); - break; - } - case ts.SyntaxKind.Parameter: { - const n = node as ts.ParameterDeclaration; - pushall(children, n.name, n.type, n.initializer); - break; - } - case ts.SyntaxKind.Decorator: { - const n = node as ts.Decorator; - children.push(n.expression); - break; - } - case ts.SyntaxKind.PropertySignature: { - const n = node as ts.PropertySignature; - pushall(children, n.name, n.type, n.initializer); - break; - } - case ts.SyntaxKind.PropertyDeclaration: { - const n = node as ts.PropertyDeclaration; - pushall(children, n.name, n.type, n.initializer); - break; - } - case ts.SyntaxKind.MethodSignature: { - const n = node as ts.MethodSignature; - pushall(children, n.name, n.type); - if (n.typeParameters) { - children.push(...n.typeParameters); - } - if (n.parameters) { - children.push(...n.parameters); - } - break; - } - case ts.SyntaxKind.MethodDeclaration: { - const n = node as ts.MethodDeclaration; - pushall(children, n.name, n.body); - break; - } - case ts.SyntaxKind.Constructor: { - const n = node as ts.ConstructorDeclaration; - pushall(children, n.name, n.body); - break; - } - case ts.SyntaxKind.GetAccessor: { - const n = node as ts.GetAccessorDeclaration; - children.push(n.name, n.body); - break; - } - case ts.SyntaxKind.SetAccessor: { - const n = node as ts.SetAccessorDeclaration; - children.push(n.name, n.body); - break; - } - case ts.SyntaxKind.CallSignature: { - const n = node as ts.CallSignatureDeclaration; - pushall(children, n.name, n.type); - if (n.typeParameters) { - children.push(...n.typeParameters); - } - if (n.parameters) { - children.push(...n.parameters); - } - break; - } - case ts.SyntaxKind.ConstructSignature: { - const n = node as ts.ConstructSignatureDeclaration; - pushall(children, n.name, n.type); - if (n.typeParameters) { - children.push(...n.typeParameters); - } - if (n.parameters) { - children.push(...n.parameters); - } - break; - } - case ts.SyntaxKind.IndexSignature: { - const n = node as ts.IndexSignatureDeclaration; - pushall(children, n.name, n.type); - if (n.typeParameters) { - children.push(...n.typeParameters); - } - if (n.parameters) { - children.push(...n.parameters); - } - break; - } - case ts.SyntaxKind.TypePredicate: { - const n = node as ts.TypePredicateNode; - children.push(n.parameterName, n.type); - break; - } - case ts.SyntaxKind.TypeReference: { - const n = node as ts.TypeReferenceNode; - children.push(n.typeName); - if (n.typeArguments) { - children.push(...n.typeArguments); - } - break; - } - case ts.SyntaxKind.ConstructorType: - case ts.SyntaxKind.FunctionType: { - const n = node as ts.FunctionOrConstructorTypeNode; - pushall(children, n.name, n.type); - pushall(children, n.name, n.type); - if (n.typeParameters) { - children.push(...n.typeParameters); - } - if (n.parameters) { - children.push(...n.parameters); - } - break; - } - case ts.SyntaxKind.TypeQuery: { - const n = node as ts.TypeQueryNode; - children.push(n.exprName); - break; - } - case ts.SyntaxKind.TypeLiteral: { - const n = node as ts.TypeLiteralNode; - pushall(children, n.name); - children.push(...n.members); - break; - } - case ts.SyntaxKind.ArrayType: { - const n = node as ts.ArrayTypeNode; - children.push(n.elementType); - break; - } - case ts.SyntaxKind.TupleType: { - const n = node as ts.TupleTypeNode; - children.push(...n.elementTypes); - break; - } - case ts.SyntaxKind.IntersectionType: - case ts.SyntaxKind.UnionType: { - const n = node as ts.UnionTypeNode; - children.push(...n.types); - break; - } - case ts.SyntaxKind.ParenthesizedType: { - const n = node as ts.ParenthesizedTypeNode; - children.push(n.type); - break; - } - case ts.SyntaxKind.LiteralType: { - const n = node as ts.LiteralTypeNode; - children.push(n.literal); - break; - } - case ts.SyntaxKind.ObjectBindingPattern: - case ts.SyntaxKind.ArrayBindingPattern: { - const n = node as ts.ObjectBindingPattern; - children.push(...n.elements); - break; - } - case ts.SyntaxKind.BindingElement: { - const n = node as ts.BindingElement; - pushall(children, n.propertyName, n.name, n.initializer); - break; - } - case ts.SyntaxKind.ArrayLiteralExpression: { - const n = node as ts.ArrayLiteralExpression; - children.push(...n.elements); - break; - } - case ts.SyntaxKind.ObjectLiteralExpression: { - const n = node as ts.ObjectLiteralExpression; - children.push(...n.properties); - break; - } - case ts.SyntaxKind.PropertyAccessExpression: { - const n = node as ts.PropertyAccessExpression; - children.push(n.expression, n.name); - break; - } - case ts.SyntaxKind.ElementAccessExpression: { - const n = node as ts.ElementAccessExpression; - pushall(children, n.expression, n.argumentExpression); - break; - } - case ts.SyntaxKind.CallExpression: { - const n = node as ts.CallExpression; - pushall(children, n.name, n.expression, ...n.arguments); - if (n.typeArguments) { - children.push(...n.typeArguments); - } - break; - } - case ts.SyntaxKind.NewExpression: { - const n = node as ts.NewExpression; - if (n.name) { - yield* walkMostAST(n.name); - } - yield* walkMostAST(n.expression); - if (n.arguments) { - for (const argument of n.arguments) { - yield* walkMostAST(argument); - } - } - if (n.typeArguments) { - for (const typeArgument of n.typeArguments) { - yield* walkMostAST(typeArgument); - } - } - break; - } - case ts.SyntaxKind.TaggedTemplateExpression: { - const n = node as ts.TaggedTemplateExpression; - children.push(n.tag, n.template); - break; - } - case ts.SyntaxKind.TypeAssertionExpression: { - const n = node as ts.TypeAssertion; - children.push(n.type, n.expression); - break; - } - case ts.SyntaxKind.ParenthesizedExpression: { - const n = node as ts.ParenthesizedExpression; - children.push(n.expression); - break; - } - case ts.SyntaxKind.FunctionExpression: { - const n = node as ts.FunctionExpression; - pushall(children, n.name, n.body); - break; - } - case ts.SyntaxKind.ArrowFunction: { - const n = node as ts.ArrowFunction; - children.push(n.body); - break; - } - case ts.SyntaxKind.DeleteExpression: { - const n = node as ts.DeleteExpression; - children.push(n.expression); - break; - } - case ts.SyntaxKind.TypeOfExpression: { - const n = node as ts.TypeOfExpression; - children.push(n.expression); - break; - } - case ts.SyntaxKind.VoidExpression: { - const n = node as ts.VoidExpression; - children.push(n.expression); - break; - } - case ts.SyntaxKind.AwaitExpression: { - const n = node as ts.AwaitExpression; - children.push(n.expression); - break; - } - case ts.SyntaxKind.PrefixUnaryExpression: { - const n = node as ts.PrefixUnaryExpression; - children.push(n.operand); - break; - } - case ts.SyntaxKind.PostfixUnaryExpression: { - const n = node as ts.PostfixUnaryExpression; - children.push(n.operand); - break; - } - case ts.SyntaxKind.BinaryExpression: { - const n = node as ts.BinaryExpression; - children.push(n.left, n.right); - break; - } - case ts.SyntaxKind.ConditionalExpression: { - const n = node as ts.ConditionalExpression; - children.push(n.condition, n.whenTrue, n.whenFalse); - break; - } - case ts.SyntaxKind.TemplateExpression: { - const n = node as ts.TemplateExpression; - children.push(n.head, ...n.templateSpans); - break; - } - case ts.SyntaxKind.YieldExpression: { - const n = node as ts.YieldExpression; - pushall(children, n.expression); - break; - } - case ts.SyntaxKind.SpreadElement: { - const n = node as ts.SpreadElement; - children.push(n.expression); - break; - } - case ts.SyntaxKind.ClassExpression: { - const n = node as ts.ClassExpression; - pushall(children, n.name, ...n.members); - if (n.typeParameters) { - children.push(...n.typeParameters); - } - if (n.heritageClauses) { - children.push(...n.heritageClauses); - } - break; - } - case ts.SyntaxKind.ExpressionWithTypeArguments: { - const n = node as ts.ExpressionWithTypeArguments; - children.push(n.expression); - if (n.typeArguments) { - children.push(...n.typeArguments); - } - break; - } - case ts.SyntaxKind.AsExpression: { - const n = node as ts.AsExpression; - children.push(n.expression, n.type); - break; - } - case ts.SyntaxKind.NonNullExpression: { - const n = node as ts.NonNullExpression; - children.push(n.expression); - break; - } - case ts.SyntaxKind.TemplateSpan: { - const n = node as ts.TemplateSpan; - children.push(n.expression, n.literal); - break; - } - case ts.SyntaxKind.SemicolonClassElement: { - const n = node as ts.SemicolonClassElement; - if (n.name) { - children.push(n.name); - } - break; - } - case ts.SyntaxKind.Block: { - const n = node as ts.Block; - children.push(...n.statements); - break; - } - case ts.SyntaxKind.VariableStatement: { - const n = node as ts.VariableStatement; - children.push(n.declarationList); - break; - } - case ts.SyntaxKind.ExpressionStatement: { - const n = node as ts.ExpressionStatement; - children.push(n.expression); - break; - } - case ts.SyntaxKind.IfStatement: { - const n = node as ts.IfStatement; - pushall(children, n.expression, n.thenStatement, n.elseStatement); - break; - } - case ts.SyntaxKind.DoStatement: { - const n = node as ts.DoStatement; - children.push(n.expression, n.statement); - break; - } - case ts.SyntaxKind.WhileStatement: { - const n = node as ts.WhileStatement; - children.push(n.expression, n.statement); - break; - } - case ts.SyntaxKind.ForStatement: { - const n = node as ts.ForStatement; - pushall(children, n.initializer, n.condition, n.incrementor, n.statement); - break; - } - case ts.SyntaxKind.ForInStatement: { - const n = node as ts.ForInStatement; - children.push(n.initializer, n.expression, n.statement); - break; - } - case ts.SyntaxKind.ForOfStatement: { - const n = node as ts.ForOfStatement; - children.push(n.initializer, n.expression, n.statement); - break; - } - case ts.SyntaxKind.ContinueStatement: { - const n = node as ts.ContinueStatement; - if (n.label) { - children.push(n.label); - } - break; - } - case ts.SyntaxKind.BreakStatement: { - const n = node as ts.BreakStatement; - if (n.label) { - children.push(n.label); - } - break; - } - case ts.SyntaxKind.ReturnStatement: { - const n = node as ts.ReturnStatement; - if (n.expression) { - children.push(n.expression); - } - break; - } - case ts.SyntaxKind.WithStatement: { - const n = node as ts.WithStatement; - children.push(n.expression, n.statement); - break; - } - case ts.SyntaxKind.SwitchStatement: { - const n = node as ts.SwitchStatement; - children.push(n.expression, n.caseBlock); - break; - } - case ts.SyntaxKind.LabeledStatement: { - const n = node as ts.LabeledStatement; - children.push(n.label, n.statement); - break; - } - case ts.SyntaxKind.ThrowStatement: { - const n = node as ts.ThrowStatement; - children.push(n.expression); - break; - } - case ts.SyntaxKind.TryStatement: { - const n = node as ts.TryStatement; - pushall(children, n.tryBlock, n.catchClause, n.finallyBlock); - break; - } - case ts.SyntaxKind.VariableDeclaration: { - const n = node as ts.VariableDeclaration; - pushall(children, n.name, n.type, n.initializer); - break; - } - case ts.SyntaxKind.VariableDeclarationList: { - const n = node as ts.VariableDeclarationList; - children.push(...n.declarations); - break; - } - case ts.SyntaxKind.FunctionDeclaration: { - const n = node as ts.FunctionDeclaration; - pushall(children, n.name, n.body, n.type, ...n.parameters); - if (n.typeParameters) { - children.push(...n.typeParameters); - } - break; - } - case ts.SyntaxKind.ClassDeclaration: { - const n = node as ts.ClassDeclaration; - pushall(children, n.name, ...n.members); - if (n.typeParameters) { - children.push(...n.typeParameters); - } - if (n.heritageClauses) { - children.push(...n.heritageClauses); - } - break; - } - case ts.SyntaxKind.InterfaceDeclaration: { - const n = node as ts.InterfaceDeclaration; - children.push(n.name, ...n.members); - if (n.typeParameters) { - children.push(...n.typeParameters); - } - if (n.heritageClauses) { - children.push(...n.heritageClauses); - } - break; - } - case ts.SyntaxKind.TypeAliasDeclaration: { - const n = node as ts.TypeAliasDeclaration; - children.push(n.name, n.type); - if (n.typeParameters) { - children.push(...n.typeParameters); - } - break; - } - case ts.SyntaxKind.EnumDeclaration: { - const n = node as ts.EnumDeclaration; - children.push(n.name, ...n.members); - break; - } - case ts.SyntaxKind.ModuleDeclaration: { - const n = node as ts.ModuleDeclaration; - pushall(children, n.name, n.body); - break; - } - case ts.SyntaxKind.ModuleBlock: { - const n = node as ts.ModuleBlock; - children.push(...n.statements); - break; - } - case ts.SyntaxKind.CaseBlock: { - const n = node as ts.CaseBlock; - children.push(...n.clauses); - break; - } - case ts.SyntaxKind.NamespaceExportDeclaration: { - const n = node as ts.NamespaceExportDeclaration; - yield* walkMostAST(n.name); - break; - } - case ts.SyntaxKind.ImportEqualsDeclaration: { - const n = node as ts.ImportEqualsDeclaration; - children.push(n.name, n.moduleReference); - break; - } - case ts.SyntaxKind.ImportDeclaration: { - const n = node as ts.ImportDeclaration; - pushall(children, n.importClause, n.moduleSpecifier); - break; - } - case ts.SyntaxKind.ImportClause: { - const n = node as ts.ImportClause; - pushall(children, n.name, n.namedBindings); - break; - } - case ts.SyntaxKind.NamespaceImport: { - const n = node as ts.NamespaceImport; - children.push(n.name); - break; - } - case ts.SyntaxKind.NamedImports: { - const n = node as ts.NamedImports; - children.push(...n.elements); - break; - } - case ts.SyntaxKind.ImportSpecifier: { - const n = node as ts.ImportSpecifier; - pushall(children, n.propertyName, n.name); - break; - } - case ts.SyntaxKind.ExportAssignment: { - const n = node as ts.ExportAssignment; - pushall(children, n.name, n.expression); - break; - } - case ts.SyntaxKind.ExportDeclaration: { - const n = node as ts.ExportDeclaration; - pushall(children, n.exportClause, n.moduleSpecifier, n.name); - break; - } - case ts.SyntaxKind.NamedExports: { - const n = node as ts.NamedExports; - children.push(...n.elements); - break; - } - case ts.SyntaxKind.ExportSpecifier: { - const n = node as ts.ExportSpecifier; - pushall(children, n.propertyName, n.name); - break; - } - case ts.SyntaxKind.MissingDeclaration: { - const n = node as ts.MissingDeclaration; - if (n.name) { - children.push(n.name); - } - break; - } - case ts.SyntaxKind.ExternalModuleReference: { - const n = node as ts.ExternalModuleReference; - pushall(children, n.expression); - break; - } - case ts.SyntaxKind.JsxElement: { - const n = node as ts.JsxElement; - children.push(n.openingElement, n.closingElement, ...n.children); - break; - } - case ts.SyntaxKind.JsxSelfClosingElement: { - const n = node as ts.JsxSelfClosingElement; - yield* walkMostAST(n.tagName); - for (const property of n.attributes.properties) { - yield* walkMostAST(property); - } - break; - } - case ts.SyntaxKind.JsxOpeningElement: { - const n = node as ts.JsxOpeningElement; - yield* walkMostAST(n.tagName); - yield* walkMostAST(n.attributes); - break; - } - case ts.SyntaxKind.JsxClosingElement: { - const n = node as ts.JsxClosingElement; - children.push(n.tagName); - break; - } - case ts.SyntaxKind.JsxAttribute: { - const n = node as ts.JsxAttribute; - pushall(children, n.name, n.initializer); - break; - } - case ts.SyntaxKind.JsxSpreadAttribute: { - const n = node as ts.JsxSpreadAttribute; - children.push(n.expression); - break; - } - case ts.SyntaxKind.JsxExpression: { - const n = node as ts.JsxExpression; - if (n.expression) { - children.push(n.expression); - } - break; - } - case ts.SyntaxKind.CaseClause: { - const n = node as ts.CaseClause; - children.push(n.expression, ...n.statements); - break; - } - case ts.SyntaxKind.DefaultClause: { - const n = node as ts.DefaultClause; - children.push(...n.statements); - break; - } - case ts.SyntaxKind.HeritageClause: { - const n = node as ts.HeritageClause; - if (n.types) { - children.push(...n.types); - } - break; - } - case ts.SyntaxKind.CatchClause: { - const n = node as ts.CatchClause; - children.push(n.variableDeclaration, n.block); - break; - } - case ts.SyntaxKind.PropertyAssignment: { - const n = node as ts.PropertyAssignment; - children.push(n.name, n.initializer); - break; - } - case ts.SyntaxKind.ShorthandPropertyAssignment: { - const n = node as ts.ShorthandPropertyAssignment; - pushall(children, n.name, n.objectAssignmentInitializer); - break; - } - case ts.SyntaxKind.EnumMember: { - const n = node as ts.EnumMember; - pushall(children, n.name, n.initializer); - break; - } - case ts.SyntaxKind.SourceFile: { - const n = node as ts.SourceFile; - children.push(...n.statements); - break; - } - case ts.SyntaxKind.JSDocTypeExpression: { - const n = node as ts.JSDocTypeExpression; - children.push(n.type); - break; - } - case ts.SyntaxKind.JSDocArrayType: { - const n = node as ts.JSDocArrayType; - children.push(n.elementType); - break; - } - case ts.SyntaxKind.JSDocUnionType: { - const n = node as ts.JSDocUnionType; - children.push(...n.types); - break; - } - case ts.SyntaxKind.JSDocTupleType: { - const n = node as ts.JSDocTupleType; - children.push(...n.types); - break; - } - case ts.SyntaxKind.JSDocNullableType: { - const n = node as ts.JSDocNullableType; - children.push(n.type); - break; - } - case ts.SyntaxKind.JSDocNonNullableType: { - const n = node as ts.JSDocNonNullableType; - children.push(n.type); - break; - } - case ts.SyntaxKind.JSDocRecordType: { - const n = node as ts.JSDocRecordType; - children.push(n.literal); - break; - } - case ts.SyntaxKind.JSDocRecordMember: { - const n = node as ts.JSDocRecordMember; - pushall(children, n.name, n.type, n.initializer); - break; - } - case ts.SyntaxKind.JSDocTypeReference: { - const n = node as ts.JSDocTypeReference; - children.push(n.name, ...n.typeArguments); - break; - } - case ts.SyntaxKind.JSDocOptionalType: { - const n = node as ts.JSDocOptionalType; - children.push(n.type); - break; - } - case ts.SyntaxKind.JSDocFunctionType: { - const n = node as ts.JSDocFunctionType; - pushall(children, n.name, n.type, ...n.parameters); - if (n.typeParameters) { - children.push(...n.typeParameters); - } - break; - } - case ts.SyntaxKind.JSDocVariadicType: { - const n = node as ts.JSDocVariadicType; - children.push(n.type); - break; - } - case ts.SyntaxKind.JSDocConstructorType: { - const n = node as ts.JSDocConstructorType; - children.push(n.type); - break; - } - case ts.SyntaxKind.JSDocThisType: { - const n = node as ts.JSDocThisType; - children.push(n.type); - break; - } - case ts.SyntaxKind.JSDocComment: { - const n = node as ts.JSDoc; - if (n.tags) { - children.push(...n.tags); - } - break; - } - case ts.SyntaxKind.JSDocTag: { - const n = node as ts.JSDocTag; - children.push(n.tagName); - break; - } - case ts.SyntaxKind.JSDocParameterTag: { - const n = node as ts.JSDocParameterTag; - pushall(children, n.typeExpression, n.postParameterName, n.parameterName); - if (n.preParameterName) { - children.push(n.preParameterName); - } - break; - } - case ts.SyntaxKind.JSDocReturnTag: { - const n = node as ts.JSDocReturnTag; - children.push(n.typeExpression); - break; - } - case ts.SyntaxKind.JSDocTypeTag: { - const n = node as ts.JSDocTypeTag; - children.push(n.typeExpression); - break; - } - case ts.SyntaxKind.JSDocTemplateTag: { - const n = node as ts.JSDocTemplateTag; - children.push(...n.typeParameters); - break; - } - case ts.SyntaxKind.JSDocTypedefTag: { - const n = node as ts.JSDocTypedefTag; - pushall(children, n.fullName, n.typeExpression, n.jsDocTypeLiteral); - if (n.name) { - children.push(n.name); - } - break; - } - case ts.SyntaxKind.JSDocPropertyTag: { - const n = node as ts.JSDocPropertyTag; - children.push(n.name, n.typeExpression); - break; - } - case ts.SyntaxKind.JSDocTypeLiteral: { - const n = node as ts.JSDocTypeLiteral; - if (n.jsDocPropertyTags) { - children.push(...n.jsDocPropertyTags); - } - if (n.jsDocTypeTag) { - children.push(n.jsDocTypeTag); - } - break; - } - case ts.SyntaxKind.JSDocLiteralType: { - const n = node as ts.JSDocLiteralType; - children.push(n.literal); - break; - } - case ts.SyntaxKind.SyntaxList: { - const n = node as ts.SyntaxList; - children.push(...n._children); - break; - } - default: - break; - } + const children = node.getChildren(); for (const child of children) { if (child) { yield* walkMostAST(child); } } } - -function pushall(arr: T[], ...elems: (T | null | undefined)[]): number { - for (const e of elems) { - if (e) { - arr.push(e); - } - } - return arr.length; -} diff --git a/src/connection.ts b/src/connection.ts index 5218cfacb..dcfd67cba 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -82,7 +82,7 @@ export class MessageEmitter extends EventEmitter { /** Emitted when the underlying input stream was closed */ on(event: 'close', listener: () => void): this; /* istanbul ignore next */ - on(event: string, listener: () => void): this { + on(event: string, listener: (arg?: any) => void): this { return super.on(event, listener); } @@ -93,7 +93,7 @@ export class MessageEmitter extends EventEmitter { /** Emitted when the underlying input stream was closed */ once(event: 'close', listener: () => void): this; /* istanbul ignore next */ - once(event: string, listener: () => void): this { + once(event: string, listener: (arg?: any) => void): this { return super.on(event, listener); } } diff --git a/src/diagnostics.ts b/src/diagnostics.ts index ed33f54fc..ca239d370 100644 --- a/src/diagnostics.ts +++ b/src/diagnostics.ts @@ -1,17 +1,20 @@ - import * as ts from 'typescript'; -import { Diagnostic, DiagnosticSeverity } from 'vscode-languageserver'; +import { Diagnostic, DiagnosticSeverity, Range } from 'vscode-languageserver'; /** * Converts a TypeScript Diagnostic to an LSP Diagnostic */ export function convertTsDiagnostic(diagnostic: ts.Diagnostic): Diagnostic { const text = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); - return { - range: { + let range: Range = { start: {character: 0, line: 0}, end: {character: 0, line: 0} }; + if (diagnostic.file && diagnostic.start && diagnostic.length) { + range = { start: diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start), end: diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start + diagnostic.length) - }, + }; + } + return { + range, message: text, severity: convertDiagnosticCategory(diagnostic.category), code: diagnostic.code, diff --git a/src/fs.ts b/src/fs.ts index ba901bf25..e2bddfe13 100644 --- a/src/fs.ts +++ b/src/fs.ts @@ -139,7 +139,7 @@ export class FileSystemUpdater { }) .ignoreElements() .publishReplay() - .refCount(); + .refCount() as Observable; this.fetches.set(uri, observable); return observable; } @@ -174,7 +174,7 @@ export class FileSystemUpdater { }) .ignoreElements() .publishReplay() - .refCount() + .refCount() as Observable ); this.structureFetch = observable; return observable; diff --git a/src/packages.ts b/src/packages.ts index 2f1631a26..ac11bc812 100644 --- a/src/packages.ts +++ b/src/packages.ts @@ -132,7 +132,7 @@ export class PackageManager extends EventEmitter implements Disposable { /** Emitted when a new package.json was found and parsed */ on(event: 'parsed', listener: (uri: string, packageJson: PackageJson) => void): this; - on(event: string, listener: () => void): this { + on(event: string, listener: (...args: any[]) => void): this { return super.on(event, listener); } @@ -193,7 +193,7 @@ export class PackageManager extends EventEmitter implements Disposable { * @return The found package.json or undefined if none found */ getClosestPackageJsonUri(uri: string): string | undefined { - const parts = url.parse(uri); + const parts: url.UrlObject = url.parse(uri); while (true) { if (!parts.pathname) { return undefined; diff --git a/src/project-manager.ts b/src/project-manager.ts index a5ef62198..ea29f9e9c 100644 --- a/src/project-manager.ts +++ b/src/project-manager.ts @@ -1,4 +1,5 @@ import { Observable, Subscription } from '@reactivex/rxjs'; +import { SelectorMethodSignature } from '@reactivex/rxjs/dist/cjs/observable/FromEventObservable'; import iterate from 'iterare'; import { noop } from 'lodash'; import { Span } from 'opentracing'; @@ -146,7 +147,7 @@ export class ProjectManager implements Disposable { // Whenever a file with content is added to the InMemoryFileSystem, check if it's a tsconfig.json and add a new ProjectConfiguration this.subscriptions.add( - Observable.fromEvent<[string, string]>(inMemoryFileSystem, 'add', Array.of) + Observable.fromEvent(inMemoryFileSystem, 'add', Array.of as SelectorMethodSignature<[string, string]>) .filter(([uri, content]) => !!content && /\/[tj]sconfig\.json/.test(uri) && !uri.includes('/node_modules/')) .subscribe(([uri, content]) => { const filePath = uri2path(uri); @@ -241,7 +242,7 @@ export class ProjectManager implements Disposable { this.invalidateReferencedFiles(); }) .publishReplay() - .refCount(); + .refCount() as Observable; } return this.ensuredModuleStructure; }); @@ -272,7 +273,7 @@ export class ProjectManager implements Disposable { this.ensuredOwnFiles = undefined; }) .publishReplay() - .refCount(); + .refCount() as Observable; } return this.ensuredOwnFiles; }); @@ -293,7 +294,7 @@ export class ProjectManager implements Disposable { this.ensuredAllFiles = undefined; }) .publishReplay() - .refCount(); + .refCount() as Observable; } return this.ensuredAllFiles; }); @@ -673,6 +674,13 @@ export class InMemoryLanguageServiceHost implements ts.LanguageServiceHost { this.logger.error(message); } + readFile(path: string, encoding?: string): string { + return this.fs.readFile(path); + } + + fileExists(path: string): boolean { + return this.fs.fileExists(path); + } } /** diff --git a/src/test/typescript-service-helpers.ts b/src/test/typescript-service-helpers.ts index d4da745a5..1c293b19d 100644 --- a/src/test/typescript-service-helpers.ts +++ b/src/test/typescript-service-helpers.ts @@ -1829,11 +1829,11 @@ export function describeTypeScriptService(createService: TypeScriptServiceFactor uri: 'git://github.com/Microsoft/TypeScript?v' + ts.version + '#lib/lib.dom.d.ts', range: { start: { - line: 8258, + line: 8259, character: 10 }, end: { - line: 8258, + line: 8259, character: 14 } } @@ -1841,11 +1841,11 @@ export function describeTypeScriptService(createService: TypeScriptServiceFactor uri: 'git://github.com/Microsoft/TypeScript?v' + ts.version + '#lib/lib.dom.d.ts', range: { start: { - line: 8310, + line: 8311, character: 12 }, end: { - line: 8310, + line: 8311, character: 16 } } diff --git a/src/typescript-service.ts b/src/typescript-service.ts index a889a5198..fb1030452 100644 --- a/src/typescript-service.ts +++ b/src/typescript-service.ts @@ -453,7 +453,7 @@ export class TypeScriptService { // The symbol is part of a dependency in node_modules // Build URI to package.json of the Dependency const encodedPackageName = packageName.split('/').map(encodeURIComponent).join('/'); - const parts = url.parse(uri); + const parts: url.UrlObject = url.parse(uri); const packageJsonUri = url.format({ ...parts, pathname: parts.pathname!.slice(0, parts.pathname!.lastIndexOf('/node_modules/' + encodedPackageName)) + `/node_modules/${encodedPackageName}/package.json` }); // Fetch the package.json of the dependency return this.updater.ensure(packageJsonUri, span) From 0d0a1087c95427e69637c72f16187a1bf70055f8 Mon Sep 17 00:00:00 2001 From: Felix Becker Date: Tue, 26 Sep 2017 19:12:57 -0700 Subject: [PATCH 4/7] chore(package): disable package-lock --- .gitignore | 1 + .npmrc | 1 + 2 files changed, 2 insertions(+) create mode 100644 .npmrc diff --git a/.gitignore b/.gitignore index d15c715bf..2873c1052 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ coverage/ *.iml npm-debug.log yarn.lock +package-lock.json diff --git a/.npmrc b/.npmrc new file mode 100644 index 000000000..43c97e719 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +package-lock=false From a44530e126840164c5027681f1bf9ca53d9d4676 Mon Sep 17 00:00:00 2001 From: Felix Becker Date: Tue, 26 Sep 2017 19:16:32 -0700 Subject: [PATCH 5/7] chore(tasks): update tasks.json --- .vscode/tasks.json | 50 ++++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index cf7fd3f8d..ef2035e3c 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,39 +1,33 @@ { - "version": "0.1.0", - "isShellCommand": true, - "command": "npm", - "args": ["--silent", "run"], - "options": { - "cwd": "${workspaceRoot}" - }, + "version": "2.0.0", "tasks": [ { - "taskName": "build", - "isBuildCommand": true, - "problemMatcher": "$tsc" + "type": "npm", + "script": "build", + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [ + "$tsc" + ] }, { - "taskName": "watch", + "type": "npm", + "script": "watch", + "group": "build", "isBackground": true, - "problemMatcher": "$tsc-watch" + "problemMatcher": [ + "$tsc-watch" + ] }, { - "taskName": "clean" - }, - { - "taskName": "lint", - "problemMatcher": { - "pattern": { - "regexp": "^(.+)\\((\\d+),(\\d+)\\): (\\w+) (.+)$", - "file": 1, - "line": 2, - "column": 3, - "severity": 4, - "message": 5 - }, - "owner": "tslint", - "fileLocation": ["relative", "${workspaceRoot}"] - } + "type": "npm", + "script": "lint", + "group": "test", + "problemMatcher": [ + "$tslint5" + ] } ] } From 425220783dc97705f7845012923979652fd0b899 Mon Sep 17 00:00:00 2001 From: Felix Becker Date: Tue, 26 Sep 2017 19:18:00 -0700 Subject: [PATCH 6/7] chore(package): use caret dependency for @types packages --- package.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 2ff39be4e..8730273e6 100644 --- a/package.json +++ b/package.json @@ -56,18 +56,18 @@ "vscode-languageserver-types": "^3.0.3" }, "devDependencies": { - "@types/chai": "4.0.0", - "@types/chai-as-promised": "7.1.0", - "@types/chalk": "0.4.31", - "@types/glob": "5.0.30", - "@types/lodash": "4.14.74", - "@types/mocha": "2.2.41", - "@types/mz": "0.0.31", - "@types/node": "7.0.32", - "@types/rimraf": "2.0.2", - "@types/object-hash": "0.5.29", - "@types/sinon": "2.3.5", - "@types/temp": "0.8.29", + "@types/chai": "^4.0.0", + "@types/chai-as-promised": "^7.1.0", + "@types/chalk": "^0.4.31", + "@types/glob": "^5.0.30", + "@types/lodash": "^4.14.74", + "@types/mocha": "^2.2.41", + "@types/mz": "^0.0.31", + "@types/node": "^7.0.32", + "@types/rimraf": "^2.0.2", + "@types/object-hash": "^0.5.29", + "@types/sinon": "^2.3.5", + "@types/temp": "^0.8.29", "commitizen": "^2.9.6", "cz-conventional-changelog": "^2.0.0", "husky": "^0.14.0", From 25e0108b7d7e311d47511fdc4fefd53ebc4f6857 Mon Sep 17 00:00:00 2001 From: Tom van Ommeren Date: Wed, 27 Sep 2017 04:21:35 +0200 Subject: [PATCH 7/7] feat(tsconfig): add support for typeRoots setting (#343) --- src/project-manager.ts | 63 +++++++++++++++++++++++++++++++- src/test/project-manager.test.ts | 20 ++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/src/project-manager.ts b/src/project-manager.ts index ea29f9e9c..96831cc41 100644 --- a/src/project-manager.ts +++ b/src/project-manager.ts @@ -75,6 +75,11 @@ export class ProjectManager implements Disposable { */ private ensuredModuleStructure?: Observable; + /** + * Observable that completes when extra dependencies pointed to by tsconfig.json have been loaded. + */ + private ensuredConfigDependencies?: Observable; + /** * Observable that completes when `ensureAllFiles` completed */ @@ -253,6 +258,7 @@ export class ProjectManager implements Disposable { */ invalidateModuleStructure(): void { this.ensuredModuleStructure = undefined; + this.ensuredConfigDependencies = undefined; this.ensuredAllFiles = undefined; this.ensuredOwnFiles = undefined; } @@ -322,6 +328,7 @@ export class ProjectManager implements Disposable { span.addTags({ uri, maxDepth }); ignore.add(uri); return this.ensureModuleStructure(span) + .concat(Observable.defer(() => this.ensureConfigDependencies())) // If max depth was reached, don't go any further .concat(Observable.defer(() => maxDepth === 0 ? Observable.empty() : this.resolveReferencedFiles(uri))) // Prevent cycles @@ -338,6 +345,39 @@ export class ProjectManager implements Disposable { }); } + /** + * Determines if a tsconfig/jsconfig needs additional declaration files loaded. + * @param filePath + */ + isConfigDependency(filePath: string): boolean { + for (const config of this.configurations()) { + config.ensureConfigFile(); + if (config.isExpectedDeclarationFile(filePath)) { + return true; + } + } + return false; + } + + /** + * Loads files determined by tsconfig to be needed into the file system + */ + ensureConfigDependencies(childOf = new Span()): Observable { + return traceObservable('Ensure config dependencies', childOf, span => { + if (!this.ensuredConfigDependencies) { + this.ensuredConfigDependencies = observableFromIterable(this.inMemoryFs.uris()) + .filter(uri => this.isConfigDependency(uri2path(uri))) + .mergeMap(uri => this.updater.ensure(uri)) + .do(noop, err => { + this.ensuredConfigDependencies = undefined; + }) + .publishReplay() + .refCount() as Observable; + } + return this.ensuredConfigDependencies; + }); + } + /** * Invalidates a cache entry for `resolveReferencedFiles` (e.g. because the file changed) * @@ -742,6 +782,11 @@ export class ProjectConfiguration { */ private expectedFilePaths = new Set(); + /** + * List of resolved extra root directories to allow global type declaration files to be loaded from. + */ + private typeRoots: string[]; + /** * @param fs file system to use * @param documentRegistry Shared DocumentRegistry that manages SourceFile objects @@ -846,6 +891,11 @@ export class ProjectConfiguration { this.expectedFilePaths = new Set(configParseResult.fileNames); const options = configParseResult.options; + const pathResolver = /^[a-z]:\//i.test(base) ? path.win32 : path.posix; + this.typeRoots = options.typeRoots ? + options.typeRoots.map((r: string) => pathResolver.resolve(this.rootFilePath, r)) : + []; + if (/(^|\/)jsconfig\.json$/.test(this.configFilePath)) { options.allowJs = true; } @@ -872,6 +922,16 @@ export class ProjectConfiguration { private ensuredBasicFiles = false; + /** + * Determines if a fileName is a declaration file within expected files or type roots + * @param fileName + */ + public isExpectedDeclarationFile(fileName: string) { + return isDeclarationFile(fileName) && + (this.expectedFilePaths.has(toUnixPath(fileName)) || + this.typeRoots.some(root => fileName.startsWith(root))); + } + /** * Ensures we added basic files (global TS files, dependencies, declarations) */ @@ -890,7 +950,8 @@ export class ProjectConfiguration { // Add all global declaration files from the workspace and all declarations from the project for (const uri of this.fs.uris()) { const fileName = uri2path(uri); - if (isGlobalTSFile(fileName) || (isDeclarationFile(fileName) && this.expectedFilePaths.has(toUnixPath(fileName)))) { + if (isGlobalTSFile(fileName) || + this.isExpectedDeclarationFile(fileName)) { const sourceFile = program.getSourceFile(fileName); if (!sourceFile) { this.getHost().addFile(fileName); diff --git a/src/test/project-manager.test.ts b/src/test/project-manager.test.ts index ee40fabfe..aa8e8392b 100644 --- a/src/test/project-manager.test.ts +++ b/src/test/project-manager.test.ts @@ -24,6 +24,26 @@ describe('ProjectManager', () => { assert.isDefined(configs.find(config => config.configFilePath === '/foo/tsconfig.json')); }); + describe('ensureBasicFiles', () => { + beforeEach(async () => { + memfs = new InMemoryFileSystem('/'); + const localfs = new MapFileSystem(new Map([ + ['file:///project/package.json', '{"name": "package-name-1"}'], + ['file:///project/tsconfig.json', '{ "compilerOptions": { "typeRoots": ["../types"]} }'], + ['file:///project/file.ts', 'console.log(GLOBALCONSTANT);'], + ['file:///types/types.d.ts', 'declare var GLOBALCONSTANT=1;'] + + ])); + const updater = new FileSystemUpdater(localfs, memfs); + projectManager = new ProjectManager('/', memfs, updater, true); + }); + it('loads files from typeRoots', async () => { + await projectManager.ensureReferencedFiles('file:///project/file.ts').toPromise(); + memfs.getContent('file:///project/file.ts'); + memfs.getContent('file:///types/types.d.ts'); + }); + }); + describe('getPackageName()', () => { beforeEach(async () => { memfs = new InMemoryFileSystem('/');