* Declares a Symbol for the node and adds it to symbols. Reports errors for conflicting identifier names. * @param symbolTable - The symbol table which node will be added to. * @param parent - node's parent declaration. * @param node - The declaration to be added to the sy
(symbolTable, parent, node, includes, excludes, isReplaceableByMethod, isComputedName)
| 44901 | * @param excludes - The flags which node cannot be declared alongside in a symbol table. Used to report forbidden declarations. |
| 44902 | */ |
| 44903 | function declareSymbol(symbolTable, parent, node, includes, excludes, isReplaceableByMethod, isComputedName) { |
| 44904 | ts.Debug.assert(isComputedName || !ts.hasDynamicName(node)); |
| 44905 | var isDefaultExport = ts.hasSyntacticModifier(node, 512 /* ModifierFlags.Default */) || ts.isExportSpecifier(node) && node.name.escapedText === "default"; |
| 44906 | // The exported symbol for an export default function/class node is always named "default" |
| 44907 | var name = isComputedName ? "__computed" /* InternalSymbolName.Computed */ |
| 44908 | : isDefaultExport && parent ? "default" /* InternalSymbolName.Default */ |
| 44909 | : getDeclarationName(node); |
| 44910 | var symbol; |
| 44911 | if (name === undefined) { |
| 44912 | symbol = createSymbol(0 /* SymbolFlags.None */, "__missing" /* InternalSymbolName.Missing */); |
| 44913 | } |
| 44914 | else { |
| 44915 | // Check and see if the symbol table already has a symbol with this name. If not, |
| 44916 | // create a new symbol with this name and add it to the table. Note that we don't |
| 44917 | // give the new symbol any flags *yet*. This ensures that it will not conflict |
| 44918 | // with the 'excludes' flags we pass in. |
| 44919 | // |
| 44920 | // If we do get an existing symbol, see if it conflicts with the new symbol we're |
| 44921 | // creating. For example, a 'var' symbol and a 'class' symbol will conflict within |
| 44922 | // the same symbol table. If we have a conflict, report the issue on each |
| 44923 | // declaration we have for this symbol, and then create a new symbol for this |
| 44924 | // declaration. |
| 44925 | // |
| 44926 | // Note that when properties declared in Javascript constructors |
| 44927 | // (marked by isReplaceableByMethod) conflict with another symbol, the property loses. |
| 44928 | // Always. This allows the common Javascript pattern of overwriting a prototype method |
| 44929 | // with an bound instance method of the same type: `this.method = this.method.bind(this)` |
| 44930 | // |
| 44931 | // If we created a new symbol, either because we didn't have a symbol with this name |
| 44932 | // in the symbol table, or we conflicted with an existing symbol, then just add this |
| 44933 | // node as the sole declaration of the new symbol. |
| 44934 | // |
| 44935 | // Otherwise, we'll be merging into a compatible existing symbol (for example when |
| 44936 | // you have multiple 'vars' with the same name in the same container). In this case |
| 44937 | // just add this node into the declarations list of the symbol. |
| 44938 | symbol = symbolTable.get(name); |
| 44939 | if (includes & 2885600 /* SymbolFlags.Classifiable */) { |
| 44940 | classifiableNames.add(name); |
| 44941 | } |
| 44942 | if (!symbol) { |
| 44943 | symbolTable.set(name, symbol = createSymbol(0 /* SymbolFlags.None */, name)); |
| 44944 | if (isReplaceableByMethod) |
| 44945 | symbol.isReplaceableByMethod = true; |
| 44946 | } |
| 44947 | else if (isReplaceableByMethod && !symbol.isReplaceableByMethod) { |
| 44948 | // A symbol already exists, so don't add this as a declaration. |
| 44949 | return symbol; |
| 44950 | } |
| 44951 | else if (symbol.flags & excludes) { |
| 44952 | if (symbol.isReplaceableByMethod) { |
| 44953 | // Javascript constructor-declared symbols can be discarded in favor of |
| 44954 | // prototype symbols like methods. |
| 44955 | symbolTable.set(name, symbol = createSymbol(0 /* SymbolFlags.None */, name)); |
| 44956 | } |
| 44957 | else if (!(includes & 3 /* SymbolFlags.Variable */ && symbol.flags & 67108864 /* SymbolFlags.Assignment */)) { |
| 44958 | // Assignment declarations are allowed to merge with variables, no matter what other flags they have. |
| 44959 | if (ts.isNamedDeclaration(node)) { |
| 44960 | ts.setParent(node.name, node); |
no test coverage detected