(Identifier id)
| 824 | |
| 825 | // Resolves a non-binding identifier to an existing binding, or null. |
| 826 | @Nullable |
| 827 | private Binding use(Identifier id) { |
| 828 | String name = id.getName(); |
| 829 | |
| 830 | // Locally defined in this function, comprehension, |
| 831 | // or file block, or an enclosing one? |
| 832 | Binding bind = lookupLexical(name, locals); |
| 833 | if (bind != null) { |
| 834 | return bind; |
| 835 | } |
| 836 | |
| 837 | // Defined at toplevel (global, predeclared, universal)? |
| 838 | bind = toplevel.get(name); |
| 839 | if (bind != null) { |
| 840 | return bind; |
| 841 | } |
| 842 | Scope scope; |
| 843 | try { |
| 844 | scope = module.resolve(name); |
| 845 | } catch (Resolver.Module.Undefined ex) { |
| 846 | if (!Identifier.isValid(name)) { |
| 847 | // If Identifier was created by Parser.makeErrorExpression, it |
| 848 | // contains misparsed text. Ignore ex and report an appropriate error. |
| 849 | errorf(id, "contains syntax errors"); |
| 850 | } else if (ex.candidates != null) { |
| 851 | // Exception provided toplevel candidates. |
| 852 | // Show spelling suggestions of all symbols in scope, |
| 853 | String suggestion = SpellChecker.didYouMean(name, getAllSymbols(ex.candidates)); |
| 854 | errorf(id, "%s%s", ex.getMessage(), suggestion); |
| 855 | } else { |
| 856 | errorf(id, "%s", ex.getMessage()); |
| 857 | } |
| 858 | return null; |
| 859 | } |
| 860 | switch (scope) { |
| 861 | case GLOBAL: |
| 862 | bind = new Binding(scope, globals.size(), /* isSyntactic= */ false, id); |
| 863 | // Accumulate globals in module. |
| 864 | globals.add(name); |
| 865 | break; |
| 866 | case PREDECLARED: |
| 867 | case UNIVERSAL: |
| 868 | bind = new Binding(scope, 0, /* isSyntactic= */ false, id); // index not used |
| 869 | break; |
| 870 | default: |
| 871 | throw new IllegalStateException("bad scope: " + scope); |
| 872 | } |
| 873 | toplevel.put(name, bind); |
| 874 | return bind; |
| 875 | } |
| 876 | |
| 877 | // lookupLexical finds a lexically enclosing local binding of the name, |
| 878 | // plumbing it through enclosing functions as needed. |
no test coverage detected