definitionWorker.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // > This worker will analyze the syntaxtree and return an array of deprecated functions (but the goal is to do more in the future!)
  2. // We need to do this because:
  3. // - checking extended properties during completion is time consuming, so we need to prefilter potential candidates
  4. // - we don't want to maintain a static list of deprecated members or to instrument this work on the CI
  5. // - we have more plans involving syntaxtree analysis
  6. // > This worker was carefully crafted to work even if the processing is super fast or super long.
  7. // In both cases the deprecation filter will start working after the worker is done.
  8. // We will also need this worker in the future to compute Intellicode scores for completion using dedicated attributes.
  9. // see monacoCreator.js/setupDefinitionWorker
  10. // monaco is using 'define' for module dependencies and service lookup.
  11. // hopefully typescript is self-contained
  12. var ts = null;
  13. var define = (id, dependencies, callback) => ts = callback();
  14. importScripts("../node_modules/monaco-editor/dev/vs/language/typescript/lib/typescriptServices.js");
  15. // store deprecated names
  16. var deprecatedCandidates = [];
  17. // optimize syntaxtree visitor, we don't care about non documented nodes
  18. function canHaveJsDoc(node) {
  19. const kind = node.kind;
  20. switch (kind) {
  21. case ts.SyntaxKind.Parameter:
  22. case ts.SyntaxKind.CallSignature:
  23. case ts.SyntaxKind.ConstructSignature:
  24. case ts.SyntaxKind.MethodSignature:
  25. case ts.SyntaxKind.PropertySignature:
  26. case ts.SyntaxKind.ArrowFunction:
  27. case ts.SyntaxKind.ParenthesizedExpression:
  28. case ts.SyntaxKind.SpreadAssignment:
  29. case ts.SyntaxKind.ShorthandPropertyAssignment:
  30. case ts.SyntaxKind.PropertyAssignment:
  31. case ts.SyntaxKind.FunctionExpression:
  32. case ts.SyntaxKind.FunctionDeclaration:
  33. case ts.SyntaxKind.LabeledStatement:
  34. case ts.SyntaxKind.ExpressionStatement:
  35. case ts.SyntaxKind.VariableStatement:
  36. case ts.SyntaxKind.Constructor:
  37. case ts.SyntaxKind.MethodDeclaration:
  38. case ts.SyntaxKind.PropertyDeclaration:
  39. case ts.SyntaxKind.GetAccessor:
  40. case ts.SyntaxKind.SetAccessor:
  41. case ts.SyntaxKind.ClassDeclaration:
  42. case ts.SyntaxKind.ClassExpression:
  43. case ts.SyntaxKind.InterfaceDeclaration:
  44. case ts.SyntaxKind.TypeAliasDeclaration:
  45. case ts.SyntaxKind.EnumMember:
  46. case ts.SyntaxKind.EnumDeclaration:
  47. case ts.SyntaxKind.ModuleDeclaration:
  48. case ts.SyntaxKind.ImportEqualsDeclaration:
  49. case ts.SyntaxKind.IndexSignature:
  50. case ts.SyntaxKind.FunctionType:
  51. case ts.SyntaxKind.ConstructorType:
  52. case ts.SyntaxKind.JSDocFunctionType:
  53. case ts.SyntaxKind.EndOfFileToken:
  54. case ts.SyntaxKind.ExportDeclaration:
  55. return true;
  56. default:
  57. return false;
  58. }
  59. }
  60. function onFindDeprecatedCandidate(node) {
  61. const name = relatedName(node);
  62. if (name)
  63. deprecatedCandidates.push(name);
  64. }
  65. function relatedName(node) {
  66. if (canHaveJsDoc(node) && node.name)
  67. return node.name.escapedText;
  68. if (node.parent)
  69. return relatedName(parent);
  70. return undefined;
  71. }
  72. function visit(node) {
  73. if (node.jsDoc) {
  74. for (const jsDocEntry of node.jsDoc) {
  75. if (jsDocEntry.tags) {
  76. for (const tag of jsDocEntry.tags) {
  77. if (tag.tagName && tag.tagName.escapedText == 'deprecated')
  78. onFindDeprecatedCandidate(node);
  79. }
  80. }
  81. }
  82. }
  83. ts.forEachChild(node, visit);
  84. }
  85. function processDefinition(code) {
  86. if (deprecatedCandidates.length == 0) {
  87. const sourceFile = ts.createSourceFile('babylon.js', code, ts.ScriptTarget.ESNext, true);
  88. ts.forEachChild(sourceFile, visit);
  89. }
  90. self.postMessage({ result: deprecatedCandidates });
  91. }
  92. self.addEventListener('message', event => {
  93. const { code } = event.data;
  94. processDefinition(code);
  95. });