* Performs late-binding of a dynamic member. This performs the same function for * late-bound members that `declareSymbol` in binder.ts performs for early-bound * members. * * If a symbol is a dynamic name from a computed property, we perform an additional "late"
(parent, earlySymbols, lateSymbols, decl)
| 57772 | * @param decl The member to bind. |
| 57773 | */ |
| 57774 | function lateBindMember(parent, earlySymbols, lateSymbols, decl) { |
| 57775 | ts.Debug.assert(!!decl.symbol, "The member is expected to have a symbol."); |
| 57776 | var links = getNodeLinks(decl); |
| 57777 | if (!links.resolvedSymbol) { |
| 57778 | // In the event we attempt to resolve the late-bound name of this member recursively, |
| 57779 | // fall back to the early-bound name of this member. |
| 57780 | links.resolvedSymbol = decl.symbol; |
| 57781 | var declName = ts.isBinaryExpression(decl) ? decl.left : decl.name; |
| 57782 | var type = ts.isElementAccessExpression(declName) ? checkExpressionCached(declName.argumentExpression) : checkComputedPropertyName(declName); |
| 57783 | if (isTypeUsableAsPropertyName(type)) { |
| 57784 | var memberName = getPropertyNameFromType(type); |
| 57785 | var symbolFlags = decl.symbol.flags; |
| 57786 | // Get or add a late-bound symbol for the member. This allows us to merge late-bound accessor declarations. |
| 57787 | var lateSymbol = lateSymbols.get(memberName); |
| 57788 | if (!lateSymbol) |
| 57789 | lateSymbols.set(memberName, lateSymbol = createSymbol(0 /* SymbolFlags.None */, memberName, 4096 /* CheckFlags.Late */)); |
| 57790 | // Report an error if a late-bound member has the same name as an early-bound member, |
| 57791 | // or if we have another early-bound symbol declaration with the same name and |
| 57792 | // conflicting flags. |
| 57793 | var earlySymbol = earlySymbols && earlySymbols.get(memberName); |
| 57794 | if (lateSymbol.flags & getExcludedSymbolFlags(symbolFlags) || earlySymbol) { |
| 57795 | // If we have an existing early-bound member, combine its declarations so that we can |
| 57796 | // report an error at each declaration. |
| 57797 | var declarations = earlySymbol ? ts.concatenate(earlySymbol.declarations, lateSymbol.declarations) : lateSymbol.declarations; |
| 57798 | var name_5 = !(type.flags & 8192 /* TypeFlags.UniqueESSymbol */) && ts.unescapeLeadingUnderscores(memberName) || ts.declarationNameToString(declName); |
| 57799 | ts.forEach(declarations, function (declaration) { return error(ts.getNameOfDeclaration(declaration) || declaration, ts.Diagnostics.Property_0_was_also_declared_here, name_5); }); |
| 57800 | error(declName || decl, ts.Diagnostics.Duplicate_property_0, name_5); |
| 57801 | lateSymbol = createSymbol(0 /* SymbolFlags.None */, memberName, 4096 /* CheckFlags.Late */); |
| 57802 | } |
| 57803 | lateSymbol.nameType = type; |
| 57804 | addDeclarationToLateBoundSymbol(lateSymbol, decl, symbolFlags); |
| 57805 | if (lateSymbol.parent) { |
| 57806 | ts.Debug.assert(lateSymbol.parent === parent, "Existing symbol parent should match new one"); |
| 57807 | } |
| 57808 | else { |
| 57809 | lateSymbol.parent = parent; |
| 57810 | } |
| 57811 | return links.resolvedSymbol = lateSymbol; |
| 57812 | } |
| 57813 | } |
| 57814 | return links.resolvedSymbol; |
| 57815 | } |
| 57816 | function getResolvedMembersOrExportsOfSymbol(symbol, resolutionKind) { |
| 57817 | var links = getSymbolLinks(symbol); |
| 57818 | if (!links[resolutionKind]) { |
no test coverage detected
searching dependent graphs…