docs: function getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, sourceFile, enclosingDeclaration, location, semanticMeaning) {
              if (semanticMeaning === void 0) { semanticMeaning = getMeaningFromLocation(location); }
              var typeChecker = program.getTypeChecker();
              var displayParts = [];
              var documentation;
              var symbolFlags = symbol.flags;
              var symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, symbolFlags, location);
              var hasAddedSymbolInfo;
              var isThisExpression = location.kind === 97 /* ThisKeyword */ && ts.isExpression(location);
              var type;
              // Class at constructor site need to be shown as constructor apart from property,method, vars
              if (symbolKind !== ScriptElementKind.unknown || symbolFlags & 32 /* Class */ || symbolFlags & 8388608 /* Alias */) {
                  // If it is accessor they are allowed only if location is at name of the accessor
                  if (symbolKind === ScriptElementKind.memberGetAccessorElement || symbolKind === ScriptElementKind.memberSetAccessorElement) {
                      symbolKind = ScriptElementKind.memberVariableElement;
                  }
                  var signature = void 0;
                  type = isThisExpression ? typeChecker.getTypeAtLocation(location) : typeChecker.getTypeOfSymbolAtLocation(symbol, location);
                  if (type) {
                      if (location.parent && location.parent.kind === 172 /* PropertyAccessExpression */) {
                          var right = location.parent.name;
                          // Either the location is on the right of a property access, or on the left and the right is missing
                          if (right === location || (right && right.getFullWidth() === 0)) {
                              location = location.parent;
                          }
                      }
                      // try get the call/construct signature from the type if it matches
                      var callExpression = void 0;
                      if (location.kind === 174 /* CallExpression */ || location.kind === 175 /* NewExpression */) {
                          callExpression = location;
                      }
                      else if (isCallExpressionTarget(location) || isNewExpressionTarget(location)) {
                          callExpression = location.parent;
                      }
                      if (callExpression) {
                          var candidateSignatures = [];
                          signature = typeChecker.getResolvedSignature(callExpression, candidateSignatures);
                          if (!signature && candidateSignatures.length) {
                              // Use the first candidate:
                              signature = candidateSignatures[0];
                          }
                          var useConstructSignatures = callExpression.kind === 175 /* NewExpression */ || callExpression.expression.kind === 95 /* SuperKeyword */;
                          var allSignatures = useConstructSignatures ? type.getConstructSignatures() : type.getCallSignatures();
                          if (!ts.contains(allSignatures, signature.target) && !ts.contains(allSignatures, signature)) {
                              // Get the first signature if there is one -- allSignatures may contain
                              // either the original signature or its target, so check for either
                              signature = allSignatures.length ? allSignatures[0] : undefined;
                          }
                          if (signature) {
                              if (useConstructSignatures && (symbolFlags & 32 /* Class */)) {
                                  // Constructor
                                  symbolKind = ScriptElementKind.constructorImplementationElement;
                                  addPrefixForAnyFunctionOrVar(type.symbol, symbolKind);
                              }
                              else if (symbolFlags & 8388608 /* Alias */) {
                                  symbolKind = ScriptElementKind.alias;
                                  pushTypePart(symbolKind);
                                  displayParts.push(ts.spacePart());
                                  if (useConstructSignatures) {
                                      displayParts.push(ts.keywordPart(92 /* NewKeyword */));
                                      displayParts.push(ts.spacePart());
                                  }
                                  addFullSymbolName(symbol);
                              }
                              else {
                                  addPrefixForAnyFunctionOrVar(symbol, symbolKind);
                              }
                              switch (symbolKind) {
                                  case ScriptElementKind.memberVariableElement:
                                  case ScriptElementKind.variableElement:
                                  case ScriptElementKind.constElement:
                                  case ScriptElementKind.letElement:
                                  case ScriptElementKind.parameterElement:
                                  case ScriptElementKind.localVariableElement:
                                      // If it is call or construct signature of lambda's write type name
                                      displayParts.push(ts.punctuationPart(54 /* ColonToken */));
                                      displayParts.push(ts.spacePart());
                                      if (useConstructSignatures) {
                                          displayParts.push(ts.keywordPart(92 /* NewKeyword */));
                                          displayParts.push(ts.spacePart());
                                      }
                                      if (!(type.flags & 2097152 /* Anonymous */) && type.symbol) {
                                          ts.addRange(displayParts, ts.symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, 1 /* WriteTypeParametersOrArguments */));
                                      }
                                      addSignatureDisplayParts(signature, allSignatures, 8 /* WriteArrowStyleSignature */);
                                      break;
                                  default:
                                      // Just signature
                                      addSignatureDisplayParts(signature, allSignatures);
                              }
                              hasAddedSymbolInfo = true;
                          }
                      }
                      else if ((isNameOfFunctionDeclaration(location) && !(symbol.flags & 98304 /* Accessor */)) ||
                          (location.kind === 121 /* ConstructorKeyword */ && location.parent.kind === 148 /* Constructor */)) {
                          // get the signature from the declaration and write it
                          var functionDeclaration = location.parent;
                          var allSignatures = functionDeclaration.kind === 148 /* Constructor */ ? type.getNonNullableType().getConstructSignatures() : type.getNonNullableType().getCallSignatures();
                          if (!typeChecker.isImplementationOfOverload(functionDeclaration)) {
                              signature = typeChecker.getSignatureFromDeclaration(functionDeclaration);
                          }
                          else {
                              signature = allSignatures[0];
                          }
                          if (functionDeclaration.kind === 148 /* Constructor */) {
                              // show (constructor) Type(...) signature
                              symbolKind = ScriptElementKind.constructorImplementationElement;
                              addPrefixForAnyFunctionOrVar(type.symbol, symbolKind);
                          }
                          else {
                              // (function/method) symbol(..signature)
                              addPrefixForAnyFunctionOrVar(functionDeclaration.kind === 151 /* CallSignature */ &&
                                  !(type.symbol.flags & 2048 /* TypeLiteral */ || type.symbol.flags & 4096 /* ObjectLiteral */) ? type.symbol : symbol, symbolKind);
                          }
                          addSignatureDisplayParts(signature, allSignatures);
                          hasAddedSymbolInfo = true;
                      }
                  }
              }
              if (symbolFlags & 32 /* Class */ && !hasAddedSymbolInfo && !isThisExpression) {
                  if (ts.getDeclarationOfKind(symbol, 192 /* ClassExpression */)) {
                      // Special case for class expressions because we would like to indicate that
                      // the class name is local to the class body (similar to function expression)
                      //      (local class) class <className>
                      pushTypePart(ScriptElementKind.localClassElement);
                  }
                  else {
                      // Class declaration has name which is not local.
                      displayParts.push(ts.keywordPart(73 /* ClassKeyword */));
                  }
                  displayParts.push(ts.spacePart());
                  addFullSymbolName(symbol);
                  writeTypeParametersOfSymbol(symbol, sourceFile);
              }
              if ((symbolFlags & 64 /* Interface */) && (semanticMeaning & 2 /* Type */)) {
                  addNewLineIfDisplayPartsExist();
                  displayParts.push(ts.keywordPart(107 /* InterfaceKeyword */));
                  displayParts.push(ts.spacePart());
                  addFullSymbolName(symbol);
                  writeTypeParametersOfSymbol(symbol, sourceFile);
              }
              if (symbolFlags & 524288 /* TypeAlias */) {
                  addNewLineIfDisplayPartsExist();
                  displayParts.push(ts.keywordPart(134 /* TypeKeyword */));
                  displayParts.push(ts.spacePart());
                  addFullSymbolName(symbol);
                  writeTypeParametersOfSymbol(symbol, sourceFile);
                  displayParts.push(ts.spacePart());
                  displayParts.push(ts.operatorPart(56 /* EqualsToken */));
                  displayParts.push(ts.spacePart());
                  ts.addRange(displayParts, ts.typeToDisplayParts(typeChecker, typeChecker.getDeclaredTypeOfSymbol(symbol), enclosingDeclaration, 512 /* InTypeAlias */));
              }
              if (symbolFlags & 384 /* Enum */) {
                  addNewLineIfDisplayPartsExist();
                  if (ts.forEach(symbol.declarations, ts.isConstEnumDeclaration)) {
                      displayParts.push(ts.keywordPart(74 /* ConstKeyword */));
                      displayParts.push(ts.spacePart());
                  }
                  displayParts.push(ts.keywordPart(81 /* EnumKeyword */));
                  displayParts.push(ts.spacePart());
                  addFullSymbolName(symbol);
              }
              if (symbolFlags & 1536 /* Module */) {
                  addNewLineIfDisplayPartsExist();
                  var declaration = ts.getDeclarationOfKind(symbol, 225 /* ModuleDeclaration */);
                  var isNamespace = declaration && declaration.name && declaration.name.kind === 69 /* Identifier */;
                  displayParts.push(ts.keywordPart(isNamespace ? 126 /* NamespaceKeyword */ : 125 /* ModuleKeyword */));
                  displayParts.push(ts.spacePart());
                  addFullSymbolName(symbol);
              }
              if ((symbolFlags & 262144 /* TypeParameter */) && (semanticMeaning & 2 /* Type */)) {
                  addNewLineIfDisplayPartsExist();
                  displayParts.push(ts.punctuationPart(17 /* OpenParenToken */));
                  displayParts.push(ts.textPart("type parameter"));
                  displayParts.push(ts.punctuationPart(18 /* CloseParenToken */));
                  displayParts.push(ts.spacePart());
                  addFullSymbolName(symbol);
                  displayParts.push(ts.spacePart());
                  displayParts.push(ts.keywordPart(90 /* InKeyword */));
                  displayParts.push(ts.spacePart());
                  if (symbol.parent) {
                      // Class/Interface type parameter
                      addFullSymbolName(symbol.parent, enclosingDeclaration);
                      writeTypeParametersOfSymbol(symbol.parent, enclosingDeclaration);
                  }
                  else {
                      // Method/function type parameter
                      var declaration = ts.getDeclarationOfKind(symbol, 141 /* TypeParameter */);
                      ts.Debug.assert(declaration !== undefined);
                      declaration = declaration.parent;
                      if (declaration) {
                          if (ts.isFunctionLikeKind(declaration.kind)) {
                              var signature = typeChecker.getSignatureFromDeclaration(declaration);
                              if (declaration.kind === 152 /* ConstructSignature */) {
                                  displayParts.push(ts.keywordPart(92 /* NewKeyword */));
                                  displayParts.push(ts.spacePart());
                              }
                              else if (declaration.kind !== 151 /* CallSignature */ && declaration.name) {
                                  addFullSymbolName(declaration.symbol);
                              }
                              ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, sourceFile, 32 /* WriteTypeArgumentsOfSignature */));
                          }
                          else {
                              // Type alias type parameter
                              // For example
                              //      type list<T> = T[];  // Both T will go through same code path
                              displayParts.push(ts.keywordPart(134 /* TypeKeyword */));
                              displayParts.push(ts.spacePart());
                              addFullSymbolName(declaration.symbol);
                              writeTypeParametersOfSymbol(declaration.symbol, sourceFile);
                          }
                      }
                  }
              }
              if (symbolFlags & 8 /* EnumMember */) {
                  addPrefixForAnyFunctionOrVar(symbol, "enum member");
                  var declaration = symbol.declarations[0];
                  if (declaration.kind === 255 /* EnumMember */) {
                      var constantValue = typeChecker.getConstantValue(declaration);
                      if (constantValue !== undefined) {
                          displayParts.push(ts.spacePart());
                          displayParts.push(ts.operatorPart(56 /* EqualsToken */));
                          displayParts.push(ts.spacePart());
                          displayParts.push(ts.displayPart(constantValue.toString(), SymbolDisplayPartKind.numericLiteral));
                      }
                  }
              }
              if (symbolFlags & 8388608 /* Alias */) {
                  addNewLineIfDisplayPartsExist();
                  if (symbol.declarations[0].kind === 228 /* NamespaceExportDeclaration */) {
                      displayParts.push(ts.keywordPart(82 /* ExportKeyword */));
                      displayParts.push(ts.spacePart());
                      displayParts.push(ts.keywordPart(126 /* NamespaceKeyword */));
                  }
                  else {
                      displayParts.push(ts.keywordPart(89 /* ImportKeyword */));
                  }
                  displayParts.push(ts.spacePart());
                  addFullSymbolName(symbol);
                  ts.forEach(symbol.declarations, function (declaration) {
                      if (declaration.kind === 229 /* ImportEqualsDeclaration */) {
                          var importEqualsDeclaration = declaration;
                          if (ts.isExternalModuleImportEqualsDeclaration(importEqualsDeclaration)) {
                              displayParts.push(ts.spacePart());
                              displayParts.push(ts.operatorPart(56 /* EqualsToken */));
                              displayParts.push(ts.spacePart());
                              displayParts.push(ts.keywordPart(129 /* RequireKeyword */));
                              displayParts.push(ts.punctuationPart(17 /* OpenParenToken */));
                              displayParts.push(ts.displayPart(ts.getTextOfNode(ts.getExternalModuleImportEqualsDeclarationExpression(importEqualsDeclaration)), SymbolDisplayPartKind.stringLiteral));
                              displayParts.push(ts.punctuationPart(18 /* CloseParenToken */));
                          }
                          else {
                              var internalAliasSymbol = typeChecker.getSymbolAtLocation(importEqualsDeclaration.moduleReference);
                              if (internalAliasSymbol) {
                                  displayParts.push(ts.spacePart());
                                  displayParts.push(ts.operatorPart(56 /* EqualsToken */));
                                  displayParts.push(ts.spacePart());
                                  addFullSymbolName(internalAliasSymbol, enclosingDeclaration);
                              }
                          }
                          return true;
                      }
                  });
              }
              if (!hasAddedSymbolInfo) {
                  if (symbolKind !== ScriptElementKind.unknown) {
                      if (type) {
                          if (isThisExpression) {
                              addNewLineIfDisplayPartsExist();
                              displayParts.push(ts.keywordPart(97 /* ThisKeyword */));
                          }
                          else {
                              addPrefixForAnyFunctionOrVar(symbol, symbolKind);
                          }
                          // For properties, variables and local vars: show the type
                          if (symbolKind === ScriptElementKind.memberVariableElement ||
                              symbolFlags & 3 /* Variable */ ||
                              symbolKind === ScriptElementKind.localVariableElement ||
                              isThisExpression) {
                              displayParts.push(ts.punctuationPart(54 /* ColonToken */));
                              displayParts.push(ts.spacePart());
                              // If the type is type parameter, format it specially
                              if (type.symbol && type.symbol.flags & 262144 /* TypeParameter */) {
                                  var typeParameterParts = ts.mapToDisplayParts(function (writer) {
                                      typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplay(type, writer, enclosingDeclaration);
                                  });
                                  ts.addRange(displayParts, typeParameterParts);
                              }
                              else {
                                  ts.addRange(displayParts, ts.typeToDisplayParts(typeChecker, type, enclosingDeclaration));
                              }
                          }
                          else if (symbolFlags & 16 /* Function */ ||
                              symbolFlags & 8192 /* Method */ ||
                              symbolFlags & 16384 /* Constructor */ ||
                              symbolFlags & 131072 /* Signature */ ||
                              symbolFlags & 98304 /* Accessor */ ||
                              symbolKind === ScriptElementKind.memberFunctionElement) {
                              var allSignatures = type.getNonNullableType().getCallSignatures();
                              addSignatureDisplayParts(allSignatures[0], allSignatures);
                          }
                      }
                  }
                  else {
                      symbolKind = getSymbolKind(symbol, location);
                  }
              }
              if (!documentation) {
                  documentation = symbol.getDocumentationComment();
                  if (documentation.length === 0 && symbol.flags & 4 /* Property */) {
                      // For some special property access expressions like `experts.foo = foo` or `module.exports.foo = foo`
                      // there documentation comments might be attached to the right hand side symbol of their declarations.
                      // The pattern of such special property access is that the parent symbol is the symbol of the file.
                      if (symbol.parent && ts.forEach(symbol.parent.declarations, function (declaration) { return declaration.kind === 256 /* SourceFile */; })) {
                          for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                              var declaration = _a[_i];
                              if (!declaration.parent || declaration.parent.kind !== 187 /* BinaryExpression */) {
                                  continue;
                              }
                              var rhsSymbol = program.getTypeChecker().getSymbolAtLocation(declaration.parent.right);
                              if (!rhsSymbol) {
                                  continue;
                              }
                              documentation = rhsSymbol.getDocumentationComment();
                              if (documentation.length > 0) {
                                  break;
                              }
                          }
                      }
                  }
              }
              return { displayParts: displayParts, documentation: documentation, symbolKind: symbolKind };
              function addNewLineIfDisplayPartsExist() {
                  if (displayParts.length) {
                      displayParts.push(ts.lineBreakPart());
                  }
              }
              function addFullSymbolName(symbol, enclosingDeclaration) {
                  var fullSymbolDisplayParts = ts.symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration || sourceFile, /*meaning*/ undefined, 1 /* WriteTypeParametersOrArguments */ | 2 /* UseOnlyExternalAliasing */);
                  ts.addRange(displayParts, fullSymbolDisplayParts);
              }
              function addPrefixForAnyFunctionOrVar(symbol, symbolKind) {
                  addNewLineIfDisplayPartsExist();
                  if (symbolKind) {
                      pushTypePart(symbolKind);
                      displayParts.push(ts.spacePart());
                      addFullSymbolName(symbol);
                  }
              }
              function pushTypePart(symbolKind) {
                  switch (symbolKind) {
                      case ScriptElementKind.variableElement:
                      case ScriptElementKind.functionElement:
                      case ScriptElementKind.letElement:
                      case ScriptElementKind.constElement:
                      case ScriptElementKind.constructorImplementationElement:
                          displayParts.push(ts.textOrKeywordPart(symbolKind));
                          return;
                      default:
                          displayParts.push(ts.punctuationPart(17 /* OpenParenToken */));
                          displayParts.push(ts.textOrKeywordPart(symbolKind));
                          displayParts.push(ts.punctuationPart(18 /* CloseParenToken */));
                          return;
                  }
              }
              function addSignatureDisplayParts(signature, allSignatures, flags) {
                  ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, enclosingDeclaration, flags | 32 /* WriteTypeArgumentsOfSignature */));
                  if (allSignatures.length > 1) {
                      displayParts.push(ts.spacePart());
                      displayParts.push(ts.punctuationPart(17 /* OpenParenToken */));
                      displayParts.push(ts.operatorPart(35 /* PlusToken */));
                      displayParts.push(ts.displayPart((allSignatures.length - 1).toString(), SymbolDisplayPartKind.numericLiteral));
                      displayParts.push(ts.spacePart());
                      displayParts.push(ts.textPart(allSignatures.length === 2 ? "overload" : "overloads"));
                      displayParts.push(ts.punctuationPart(18 /* CloseParenToken */));
                  }
                  documentation = signature.getDocumentationComment();
              }
              function writeTypeParametersOfSymbol(symbol, enclosingDeclaration) {
                  var typeParameterParts = ts.mapToDisplayParts(function (writer) {
                      typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaration);
                  });
                  ts.addRange(displayParts, typeParameterParts);
              }
          }