demo/typescript.js
function resolveName(location, name, meaning, nameNotFoundMessage, nameArg) {
            var result;
            var lastLocation;
            var propertyWithInvalidInitializer;
            var errorLocation = location;
            var grandparent;
            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)) {
                        // 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.
                        if (!(meaning & 793056 /* Type */) ||
                            !(result.flags & (793056 /* Type */ & ~262144 /* TypeParameter */)) ||
                            !ts.isFunctionLike(location) ||
                            lastLocation === location.body) {
                            break loop;
                        }
                        result = undefined;
                    }
                }
                switch (location.kind) {
                    case 248 /* SourceFile */:
                        if (!ts.isExternalModule(location))
                            break;
                    case 218 /* ModuleDeclaration */:
                        var moduleExports = getSymbolOfNode(location).exports;
                        if (location.kind === 248 /* SourceFile */ ||
                            (location.kind === 218 /* ModuleDeclaration */ && location.name.kind === 9 /* StringLiteral */)) {
                            // It's an external module. 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 (ts.hasProperty(moduleExports, name) &&
                                moduleExports[name].flags === 8388608 /* Alias */ &&
                                ts.getDeclarationOfKind(moduleExports[name], 230 /* ExportSpecifier */)) {
                                break;
                            }
                            result = moduleExports["default"];
                            var localSymbol = ts.getLocalSymbolForExportDefault(result);
                            if (result && localSymbol && (result.flags & meaning) && localSymbol.name === name) {
                                break loop;
                            }
                            result = undefined;
                        }
                        if (result = getSymbol(moduleExports, name, meaning & 8914931 /* ModuleMember */)) {
                            break loop;
                        }
                        break;
                    case 217 /* EnumDeclaration */:
                        if (result = getSymbol(getSymbolOfNode(location).exports, name, meaning & 8 /* EnumMember */)) {
                            break loop;
                        }
                        break;
                    case 141 /* PropertyDeclaration */:
                    case 140 /* 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 & 128 /* 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 214 /* ClassDeclaration */:
                    case 186 /* ClassExpression */:
                    case 215 /* InterfaceDeclaration */:
                        if (result = getSymbol(getSymbolOfNode(location).members, name, meaning & 793056 /* Type */)) {
                            if (lastLocation && lastLocation.flags & 128 /* 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 === 186 /* 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 136 /* ComputedPropertyName */:
                        grandparent = location.parent.parent;
                        if (ts.isClassLike(grandparent) || grandparent.kind === 215 /* InterfaceDeclaration */) {
                            // A reference to this grandparent's type parameters would be an error
                            if (result = getSymbol(getSymbolOfNode(grandparent).members, name, meaning & 793056 /* Type */)) {
                                error(errorLocation, ts.Diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type);
                                return undefined;
                            }
                        }
                        break;
                    case 143 /* MethodDeclaration */:
                    case 142 /* MethodSignature */:
                    case 144 /* Constructor */:
                    case 145 /* GetAccessor */:
                    case 146 /* SetAccessor */:
                    case 213 /* FunctionDeclaration */:
                    case 174 /* ArrowFunction */:
                        if (meaning & 3 /* Variable */ && name === "arguments") {
                            result = argumentsSymbol;
                            break loop;
                        }
                        break;
                    case 173 /* 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 139 /* 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 === 138 /* 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) {
                result = getSymbol(globals, name, meaning);
            }
            if (!result) {
                if (nameNotFoundMessage) {
                    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 {}
                //          }
                //      let 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);
                    }
                }
            }
            return result;
        }
function resolveName(location, name, meaning, nameNotFoundMessage, nameArg) {
            var result;
            var lastLocation;
            var propertyWithInvalidInitializer;
            var errorLocation = location;
            var grandparent;
            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)) {
                        // 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.
                        if (!(meaning & 793056 /* Type */) ||
                            !(result.flags & (793056 /* Type */ & ~262144 /* TypeParameter */)) ||
                            !ts.isFunctionLike(location) ||
                            lastLocation === location.body) {
                            break loop;
                        }
                        result = undefined;
                    }
                }
                switch (location.kind) {
                    case 248 /* SourceFile */:
                        if (!ts.isExternalModule(location))
                            break;
                    case 218 /* ModuleDeclaration */:
                        var moduleExports = getSymbolOfNode(location).exports;
                        if (location.kind === 248 /* SourceFile */ ||
                            (location.kind === 218 /* ModuleDeclaration */ && location.name.kind === 9 /* StringLiteral */)) {
                            // It's an external module. 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 (ts.hasProperty(moduleExports, name) &&
                                moduleExports[name].flags === 8388608 /* Alias */ &&
                                ts.getDeclarationOfKind(moduleExports[name], 230 /* ExportSpecifier */)) {
                                break;
                            }
                            result = moduleExports["default"];
                            var localSymbol = ts.getLocalSymbolForExportDefault(result);
                            if (result && localSymbol && (result.flags & meaning) && localSymbol.name === name) {
                                break loop;
                            }
                            result = undefined;
                        }
                        if (result = getSymbol(moduleExports, name, meaning & 8914931 /* ModuleMember */)) {
                            break loop;
                        }
                        break;
                    case 217 /* EnumDeclaration */:
                        if (result = getSymbol(getSymbolOfNode(location).exports, name, meaning & 8 /* EnumMember */)) {
                            break loop;
                        }
                        break;
                    case 141 /* PropertyDeclaration */:
                    case 140 /* 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 & 128 /* 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 214 /* ClassDeclaration */:
                    case 186 /* ClassExpression */:
                    case 215 /* InterfaceDeclaration */:
                        if (result = getSymbol(getSymbolOfNode(location).members, name, meaning & 793056 /* Type */)) {
                            if (lastLocation && lastLocation.flags & 128 /* 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 === 186 /* 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 136 /* ComputedPropertyName */:
                        grandparent = location.parent.parent;
                        if (ts.isClassLike(grandparent) || grandparent.kind === 215 /* InterfaceDeclaration */) {
                            // A reference to this grandparent's type parameters would be an error
                            if (result = getSymbol(getSymbolOfNode(grandparent).members, name, meaning & 793056 /* Type */)) {
                                error(errorLocation, ts.Diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type);
                                return undefined;
                            }
                        }
                        break;
                    case 143 /* MethodDeclaration */:
                    case 142 /* MethodSignature */:
                    case 144 /* Constructor */:
                    case 145 /* GetAccessor */:
                    case 146 /* SetAccessor */:
                    case 213 /* FunctionDeclaration */:
                    case 174 /* ArrowFunction */:
                        if (meaning & 3 /* Variable */ && name === "arguments") {
                            result = argumentsSymbol;
                            break loop;
                        }
                        break;
                    case 173 /* 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 139 /* 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 === 138 /* 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) {
                result = getSymbol(globals, name, meaning);
            }
            if (!result) {
                if (nameNotFoundMessage) {
                    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 {}
                //          }
                //      let 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);
                    }
                }
            }
            return result;
        }
Resolve a given name for a given meaning at a given location. An error is reported if the name was not found and the nameNotFoundMessage argument is not undefined. Returns the resolved symbol, or undefined if no symbol with the given name can be found.