text: "use strict";
  /*---------------------------------------------------------------------------------------------
   *  Copyright (c) Microsoft Corporation. All rights reserved.
   *  Licensed under the MIT License. See License.txt in the project root for license information.
   *--------------------------------------------------------------------------------------------*/
  module.exports = function init(modules) {
      const ts = modules.typescript;
      function hasVersion(requiredMajor, requiredMinor) {
          const parts = ts.version.split('.');
          const majorVersion = Number(parts[0]);
          return requiredMajor < majorVersion || ((majorVersion === requiredMajor) && requiredMinor <= Number(parts[1]));
      }
      function decorate(languageService, logger) {
          var _a, _b;
          const intercept = Object.create(null);
          if (!hasVersion(3 /* major */, 7 /* minor */)) {
              (_a = logger) === null || _a === void 0 ? void 0 : _a.msg(`typescript-vscode-sh-plugin not active, version ${3 /* major */}.${7 /* minor */} required, is ${ts.version}`, ts.server.Msg.Info);
              return languageService;
          }
          (_b = logger) === null || _b === void 0 ? void 0 : _b.msg(`typescript-vscode-sh-plugin initialized. Intercepting getEncodedSemanticClassifications and getEncodedSyntacticClassifications.`, ts.server.Msg.Info);
          intercept.getEncodedSemanticClassifications = (filename, span) => {
              return {
                  spans: getSemanticTokens(languageService, filename, span),
                  endOfLineState: ts.EndOfLineState.None
              };
          };
          intercept.getEncodedSyntacticClassifications = (_filename, _span) => {
              return {
                  spans: [],
                  endOfLineState: ts.EndOfLineState.None
              };
          };
          return new Proxy(languageService, {
              get: (target, property) => {
                  return intercept[property] || target[property];
              },
          });
      }
      function getSemanticTokens(jsLanguageService, fileName, span) {
          let resultTokens = [];
          const collector = (node, typeIdx, modifierSet) => {
              resultTokens.push(node.getStart(), node.getWidth(), ((typeIdx + 1) << 8 /* typeOffset */) + modifierSet);
          };
          const program = jsLanguageService.getProgram();
          if (program) {
              const sourceFile = program.getSourceFile(fileName);
              if (sourceFile) {
                  collectTokens(program, sourceFile, span, collector);
              }
          }
          return resultTokens;
      }
      function collectTokens(program, sourceFile, span, collector) {
          const typeChecker = program.getTypeChecker();
          let inJSXElement = false;
          function visit(node) {
              if (!node || !ts.textSpanIntersectsWith(span, node.pos, node.getFullWidth()) || node.getFullWidth() === 0) {
                  return;
              }
              const prevInJSXElement = inJSXElement;
              if (ts.isJsxElement(node) || ts.isJsxSelfClosingElement(node)) {
                  inJSXElement = true;
              }
              if (ts.isJsxExpression(node)) {
                  inJSXElement = false;
              }
              if (ts.isIdentifier(node) && !inJSXElement && !inImportClause(node)) {
                  let symbol = typeChecker.getSymbolAtLocation(node);
                  if (symbol) {
                      if (symbol.flags & ts.SymbolFlags.Alias) {
                          symbol = typeChecker.getAliasedSymbol(symbol);
                      }
                      let typeIdx = classifySymbol(symbol, getMeaningFromLocation(node));
                      if (typeIdx !== undefined) {
                          let modifierSet = 0;
                          if (node.parent) {
                              const parentIsDeclaration = (ts.isBindingElement(node.parent) || tokenFromDeclarationMapping[node.parent.kind] === typeIdx);
                              if (parentIsDeclaration && node.parent.name === node) {
                                  modifierSet = 1 << 0 /* declaration */;
                              }
                          }
                          // property declaration in constructor
                          if (typeIdx === 6 /* parameter */ && isRightSideOfQualifiedNameOrPropertyAccess(node)) {
                              typeIdx = 9 /* property */;
                          }
                          typeIdx = reclassifyByType(typeChecker, node, typeIdx);
                          const decl = symbol.valueDeclaration;
                          if (decl) {
                              const modifiers = ts.getCombinedModifierFlags(decl);
                              const nodeFlags = ts.getCombinedNodeFlags(decl);
                              if (modifiers & ts.ModifierFlags.Static) {
                                  modifierSet |= 1 << 1 /* static */;
                              }
                              if (modifiers & ts.ModifierFlags.Async) {
                                  modifierSet |= 1 << 2 /* async */;
                              }
                              if (typeIdx !== 0 /* class */ && typeIdx !== 2 /* interface */) {
                                  if ((modifiers & ts.ModifierFlags.Readonly) || (nodeFlags & ts.NodeFlags.Const) || (symbol.getFlags() & ts.SymbolFlags.EnumMember)) {
                                      modifierSet |= 1 << 3 /* readonly */;
                                  }
                              }
                              if ((typeIdx === 7 /* variable */ || typeIdx === 10 /* function */) && isLocalDeclaration(decl, sourceFile)) {
                                  modifierSet |= 1 << 5 /* local */;
                              }
                              if (program.isSourceFileDefaultLibrary(decl.getSourceFile())) {
                                  modifierSet |= 1 << 4 /* defaultLibrary */;
                              }
                          }
                          else if (symbol.declarations && symbol.declarations.some(d => program.isSourceFileDefaultLibrary(d.getSourceFile()))) {
                              modifierSet |= 1 << 4 /* defaultLibrary */;
                          }
                          collector(node, typeIdx, modifierSet);
                      }
                  }
              }
              ts.forEachChild(node, visit);
              inJSXElement = prevInJSXElement;
          }
          visit(sourceFile);
      }
      function classifySymbol(symbol, meaning) {
          const flags = symbol.getFlags();
          if (flags & ts.SymbolFlags.Class) {
              return 0 /* class */;
          }
          else if (flags & ts.SymbolFlags.Enum) {
              return 1 /* enum */;
          }
          else if (flags & ts.SymbolFlags.TypeAlias) {
              return 5 /* type */;
          }
          else if (flags & ts.SymbolFlags.Interface) {
              if (meaning & 2 /* Type */) {
                  return 2 /* interface */;
              }
          }
          else if (flags & ts.SymbolFlags.TypeParameter) {
              return 4 /* typeParameter */;
          }
          let decl = symbol.valueDeclaration || symbol.declarations && symbol.declarations[0];
          if (decl && ts.isBindingElement(decl)) {
              decl = getDeclarationForBindingElement(decl);
          }
          return decl && tokenFromDeclarationMapping[decl.kind];
      }
      function reclassifyByType(typeChecker, node, typeIdx) {
          // type based classifications
          if (typeIdx === 7 /* variable */ || typeIdx === 9 /* property */ || typeIdx === 6 /* parameter */) {
              const type = typeChecker.getTypeAtLocation(node);
              if (type) {
                  const test = (condition) => {
                      return condition(type) || type.isUnion() && type.types.some(condition);
                  };
                  if (typeIdx !== 6 /* parameter */ && test(t => t.getConstructSignatures().length > 0)) {
                      return 0 /* class */;
                  }
                  if (test(t => t.getCallSignatures().length > 0) && !test(t => t.getProperties().length > 0) || isExpressionInCallExpression(node)) {
                      return typeIdx === 9 /* property */ ? 11 /* member */ : 10 /* function */;
                  }
              }
          }
          return typeIdx;
      }
      function isLocalDeclaration(decl, sourceFile) {
          if (ts.isBindingElement(decl)) {
              decl = getDeclarationForBindingElement(decl);
          }
          if (ts.isVariableDeclaration(decl)) {
              return (!ts.isSourceFile(decl.parent.parent.parent) || ts.isCatchClause(decl.parent)) && decl.getSourceFile() === sourceFile;
          }
          else if (ts.isFunctionDeclaration(decl)) {
              return !ts.isSourceFile(decl.parent) && decl.getSourceFile() === sourceFile;
          }
          return false;
      }
      function getDeclarationForBindingElement(element) {
          while (true) {
              if (ts.isBindingElement(element.parent.parent)) {
                  element = element.parent.parent;
              }
              else {
                  return element.parent.parent;
              }
          }
      }
      function inImportClause(node) {
          const parent = node.parent;
          return parent && (ts.isImportClause(parent) || ts.isImportSpecifier(parent) || ts.isNamespaceImport(parent));
      }
      function isExpressionInCallExpression(node) {
          while (isRightSideOfQualifiedNameOrPropertyAccess(node)) {
              node = node.parent;
          }
          return ts.isCallExpression(node.parent) && node.parent.expression === node;
      }
      function isRightSideOfQualifiedNameOrPropertyAccess(node) {
          return (ts.isQualifiedName(node.parent) && node.parent.right === node) || (ts.isPropertyAccessExpression(node.parent) && node.parent.name === node);
      }
      function getMeaningFromLocation(node) {
          const f = ts.getMeaningFromLocation;
          if (typeof f === 'function') {
              return f(node);
          }
          return 7 /* All */;
      }
      const tokenFromDeclarationMapping = {
          [ts.SyntaxKind.VariableDeclaration]: 7 /* variable */,
          [ts.SyntaxKind.Parameter]: 6 /* parameter */,
          [ts.SyntaxKind.PropertyDeclaration]: 9 /* property */,
          [ts.SyntaxKind.ModuleDeclaration]: 3 /* namespace */,
          [ts.SyntaxKind.EnumDeclaration]: 1 /* enum */,
          [ts.SyntaxKind.EnumMember]: 8 /* enumMember */,
          [ts.SyntaxKind.ClassDeclaration]: 0 /* class */,
          [ts.SyntaxKind.MethodDeclaration]: 11 /* member */,
          [ts.SyntaxKind.FunctionDeclaration]: 10 /* function */,
          [ts.SyntaxKind.FunctionExpression]: 10 /* function */,
          [ts.SyntaxKind.MethodSignature]: 11 /* member */,
          [ts.SyntaxKind.GetAccessor]: 9 /* property */,
          [ts.SyntaxKind.SetAccessor]: 9 /* property */,
          [ts.SyntaxKind.PropertySignature]: 9 /* property */,
          [ts.SyntaxKind.InterfaceDeclaration]: 2 /* interface */,
          [ts.SyntaxKind.TypeAliasDeclaration]: 5 /* type */,
          [ts.SyntaxKind.TypeParameter]: 4 /* typeParameter */,
          [ts.SyntaxKind.PropertyAssignment]: 9 /* property */,
          [ts.SyntaxKind.ShorthandPropertyAssignment]: 9 /* property */
      };
      return {
          create(info) {
              return decorate(info.languageService, info.project.projectService.logger);
          },
          onConfigurationChanged(_config) {
          },
          // added for testing
          decorate(languageService) {
              return decorate(languageService);
          }
      };
  };
  //# sourceMappingURL=index.js.map