docs: function resolveName(location, name, meaning, nameNotFoundMessage, nameArg) {
              var result;
              var lastLocation;
              var propertyWithInvalidInitializer;
              var errorLocation = location;
              var grandparent;
              var isInExternalModule = false;
              loop: while (location) {
                  // Locals of a source file are not in scope (because they get merged into the global symbol table)
                  if (location.locals && !isGlobalSourceFile(location)) {
                      if (result = getSymbol(location.locals, name, meaning)) {
                          var useResult = true;
                          if (ts.isFunctionLike(location) && lastLocation && lastLocation !== location.body) {
                              // symbol lookup restrictions for function-like declarations
                              // - Type parameters of a function are in scope in the entire function declaration, including the parameter
                              //   list and return type. However, local types are only in scope in the function body.
                              // - parameters are only in the scope of function body
                              // This restriction does not apply to JSDoc comment types because they are parented
                              // at a higher level than type parameters would normally be
                              if (meaning & result.flags & 793064 /* Type */ && lastLocation.kind !== 273 /* JSDocComment */) {
                                  useResult = result.flags & 262144 /* TypeParameter */
                                      ? lastLocation === location.type ||
                                          lastLocation.kind === 142 /* Parameter */ ||
                                          lastLocation.kind === 141 /* TypeParameter */
                                      : false;
                              }
                              if (meaning & 107455 /* Value */ && result.flags & 1 /* FunctionScopedVariable */) {
                                  // parameters are visible only inside function body, parameter list and return type
                                  // technically for parameter list case here we might mix parameters and variables declared in function,
                                  // however it is detected separately when checking initializers of parameters
                                  // to make sure that they reference no variables declared after them.
                                  useResult =
                                      lastLocation.kind === 142 /* Parameter */ ||
                                          (lastLocation === location.type &&
                                              result.valueDeclaration.kind === 142 /* Parameter */);
                              }
                          }
                          if (useResult) {
                              break loop;
                          }
                          else {
                              result = undefined;
                          }
                      }
                  }
                  switch (location.kind) {
                      case 256 /* SourceFile */:
                          if (!ts.isExternalOrCommonJsModule(location))
                              break;
                          isInExternalModule = true;
                      case 225 /* ModuleDeclaration */:
                          var moduleExports = getSymbolOfNode(location).exports;
                          if (location.kind === 256 /* SourceFile */ || ts.isAmbientModule(location)) {
                              // It's an external module. First see if the module has an export default and if the local
                              // name of that export default matches.
                              if (result = moduleExports["default"]) {
                                  var localSymbol = ts.getLocalSymbolForExportDefault(result);
                                  if (localSymbol && (result.flags & meaning) && localSymbol.name === name) {
                                      break loop;
                                  }
                                  result = undefined;
                              }
                              // Because of module/namespace merging, a module's exports are in scope,
                              // yet we never want to treat an export specifier as putting a member in scope.
                              // Therefore, if the name we find is purely an export specifier, it is not actually considered in scope.
                              // Two things to note about this:
                              //     1. We have to check this without calling getSymbol. The problem with calling getSymbol
                              //        on an export specifier is that it might find the export specifier itself, and try to
                              //        resolve it as an alias. This will cause the checker to consider the export specifier
                              //        a circular alias reference when it might not be.
                              //     2. We check === SymbolFlags.Alias in order to check that the symbol is *purely*
                              //        an alias. If we used &, we'd be throwing out symbols that have non alias aspects,
                              //        which is not the desired behavior.
                              if (moduleExports[name] &&
                                  moduleExports[name].flags === 8388608 /* Alias */ &&
                                  ts.getDeclarationOfKind(moduleExports[name], 238 /* ExportSpecifier */)) {
                                  break;
                              }
                          }
                          if (result = getSymbol(moduleExports, name, meaning & 8914931 /* ModuleMember */)) {
                              break loop;
                          }
                          break;
                      case 224 /* EnumDeclaration */:
                          if (result = getSymbol(getSymbolOfNode(location).exports, name, meaning & 8 /* EnumMember */)) {
                              break loop;
                          }
                          break;
                      case 145 /* PropertyDeclaration */:
                      case 144 /* PropertySignature */:
                          // TypeScript 1.0 spec (April 2014): 8.4.1
                          // Initializer expressions for instance member variables are evaluated in the scope
                          // of the class constructor body but are not permitted to reference parameters or
                          // local variables of the constructor. This effectively means that entities from outer scopes
                          // by the same name as a constructor parameter or local variable are inaccessible
                          // in initializer expressions for instance member variables.
                          if (ts.isClassLike(location.parent) && !(location.flags & 32 /* Static */)) {
                              var ctor = findConstructorDeclaration(location.parent);
                              if (ctor && ctor.locals) {
                                  if (getSymbol(ctor.locals, name, meaning & 107455 /* Value */)) {
                                      // Remember the property node, it will be used later to report appropriate error
                                      propertyWithInvalidInitializer = location;
                                  }
                              }
                          }
                          break;
                      case 221 /* ClassDeclaration */:
                      case 192 /* ClassExpression */:
                      case 222 /* InterfaceDeclaration */:
                          if (result = getSymbol(getSymbolOfNode(location).members, name, meaning & 793064 /* Type */)) {
                              if (lastLocation && lastLocation.flags & 32 /* Static */) {
                                  // TypeScript 1.0 spec (April 2014): 3.4.1
                                  // The scope of a type parameter extends over the entire declaration with which the type
                                  // parameter list is associated, with the exception of static member declarations in classes.
                                  error(errorLocation, ts.Diagnostics.Static_members_cannot_reference_class_type_parameters);
                                  return undefined;
                              }
                              break loop;
                          }
                          if (location.kind === 192 /* ClassExpression */ && meaning & 32 /* Class */) {
                              var className = location.name;
                              if (className && name === className.text) {
                                  result = location.symbol;
                                  break loop;
                              }
                          }
                          break;
                      // It is not legal to reference a class's own type parameters from a computed property name that
                      // belongs to the class. For example:
                      //
                      //   function foo<T>() { return '' }
                      //   class C<T> { // <-- Class's own type parameter T
                      //       [foo<T>()]() { } // <-- Reference to T from class's own computed property
                      //   }
                      //
                      case 140 /* ComputedPropertyName */:
                          grandparent = location.parent.parent;
                          if (ts.isClassLike(grandparent) || grandparent.kind === 222 /* InterfaceDeclaration */) {
                              // A reference to this grandparent's type parameters would be an error
                              if (result = getSymbol(getSymbolOfNode(grandparent).members, name, meaning & 793064 /* Type */)) {
                                  error(errorLocation, ts.Diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type);
                                  return undefined;
                              }
                          }
                          break;
                      case 147 /* MethodDeclaration */:
                      case 146 /* MethodSignature */:
                      case 148 /* Constructor */:
                      case 149 /* GetAccessor */:
                      case 150 /* SetAccessor */:
                      case 220 /* FunctionDeclaration */:
                      case 180 /* ArrowFunction */:
                          if (meaning & 3 /* Variable */ && name === "arguments") {
                              result = argumentsSymbol;
                              break loop;
                          }
                          break;
                      case 179 /* FunctionExpression */:
                          if (meaning & 3 /* Variable */ && name === "arguments") {
                              result = argumentsSymbol;
                              break loop;
                          }
                          if (meaning & 16 /* Function */) {
                              var functionName = location.name;
                              if (functionName && name === functionName.text) {
                                  result = location.symbol;
                                  break loop;
                              }
                          }
                          break;
                      case 143 /* Decorator */:
                          // Decorators are resolved at the class declaration. Resolving at the parameter
                          // or member would result in looking up locals in the method.
                          //
                          //   function y() {}
                          //   class C {
                          //       method(@y x, y) {} // <-- decorator y should be resolved at the class declaration, not the parameter.
                          //   }
                          //
                          if (location.parent && location.parent.kind === 142 /* Parameter */) {
                              location = location.parent;
                          }
                          //
                          //   function y() {}
                          //   class C {
                          //       @y method(x, y) {} // <-- decorator y should be resolved at the class declaration, not the method.
                          //   }
                          //
                          if (location.parent && ts.isClassElement(location.parent)) {
                              location = location.parent;
                          }
                          break;
                  }
                  lastLocation = location;
                  location = location.parent;
              }
              if (result && nameNotFoundMessage && noUnusedIdentifiers) {
                  result.isReferenced = true;
              }
              if (!result) {
                  result = getSymbol(globals, name, meaning);
              }
              if (!result) {
                  if (nameNotFoundMessage) {
                      if (!errorLocation ||
                          !checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) &&
                              !checkAndReportErrorForExtendingInterface(errorLocation)) {
                          error(errorLocation, nameNotFoundMessage, typeof nameArg === "string" ? nameArg : ts.declarationNameToString(nameArg));
                      }
                  }
                  return undefined;
              }
              // Perform extra checks only if error reporting was requested
              if (nameNotFoundMessage) {
                  if (propertyWithInvalidInitializer) {
                      // We have a match, but the reference occurred within a property initializer and the identifier also binds
                      // to a local variable in the constructor where the code will be emitted.
                      var propertyName = propertyWithInvalidInitializer.name;
                      error(errorLocation, ts.Diagnostics.Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor, ts.declarationNameToString(propertyName), typeof nameArg === "string" ? nameArg : ts.declarationNameToString(nameArg));
                      return undefined;
                  }
                  // Only check for block-scoped variable if we are looking for the
                  // name with variable meaning
                  //      For example,
                  //          declare module foo {
                  //              interface bar {}
                  //          }
                  //      const foo/*1*/: foo/*2*/.bar;
                  // The foo at /*1*/ and /*2*/ will share same symbol with two meaning
                  // block - scope variable and namespace module. However, only when we
                  // try to resolve name in /*1*/ which is used in variable position,
                  // we want to check for block- scoped
                  if (meaning & 2 /* BlockScopedVariable */) {
                      var exportOrLocalSymbol = getExportSymbolOfValueSymbolIfExported(result);
                      if (exportOrLocalSymbol.flags & 2 /* BlockScopedVariable */) {
                          checkResolvedBlockScopedVariable(exportOrLocalSymbol, errorLocation);
                      }
                  }
                  // If we're in an external module, we can't reference value symbols created from UMD export declarations
                  if (result && isInExternalModule && (meaning & 107455 /* Value */) === 107455 /* Value */) {
                      var decls = result.declarations;
                      if (decls && decls.length === 1 && decls[0].kind === 228 /* NamespaceExportDeclaration */) {
                          error(errorLocation, ts.Diagnostics.Identifier_0_must_be_imported_from_a_module, name);
                      }
                  }
              }
              return result;
          }