MCPcopy Create free account
hub / github.com/microsoft/typescript-go / declareSymbolEx

Method declareSymbolEx

internal/binder/binder.go:154–302  ·  view source on GitHub ↗
(symbolTable ast.SymbolTable, parent *ast.Symbol, node *ast.Node, includes ast.SymbolFlags, excludes ast.SymbolFlags, isReplaceableByMethod bool, isComputedName bool)

Source from the content-addressed store, hash-verified

152}
153
154func (b *Binder) declareSymbolEx(symbolTable ast.SymbolTable, parent *ast.Symbol, node *ast.Node, includes ast.SymbolFlags, excludes ast.SymbolFlags, isReplaceableByMethod bool, isComputedName bool) *ast.Symbol {
155 debug.Assert(isComputedName || !ast.HasDynamicName(node))
156 isDefaultExport := ast.HasSyntacticModifier(node, ast.ModifierFlagsDefault) || ast.IsExportSpecifier(node) && ast.ModuleExportNameIsDefault(node.AsExportSpecifier().Name())
157 // The exported symbol for an export default function/class node is always named "default"
158 var name string
159 switch {
160 case isComputedName:
161 name = ast.InternalSymbolNameComputed
162 case isDefaultExport && parent != nil:
163 name = ast.InternalSymbolNameDefault
164 default:
165 name = b.getDeclarationName(node)
166 }
167 var symbol *ast.Symbol
168 if name == ast.InternalSymbolNameMissing {
169 symbol = b.newSymbol(ast.SymbolFlagsNone, ast.InternalSymbolNameMissing)
170 } else {
171 // Check and see if the symbol table already has a symbol with this name. If not,
172 // create a new symbol with this name and add it to the table. Note that we don't
173 // give the new symbol any flags *yet*. This ensures that it will not conflict
174 // with the 'excludes' flags we pass in.
175 //
176 // If we do get an existing symbol, see if it conflicts with the new symbol we're
177 // creating. For example, a 'var' symbol and a 'class' symbol will conflict within
178 // the same symbol table. If we have a conflict, report the issue on each
179 // declaration we have for this symbol, and then create a new symbol for this
180 // declaration.
181 //
182 // Note that when properties declared in Javascript constructors
183 // (marked by isReplaceableByMethod) conflict with another symbol, the property loses.
184 // Always. This allows the common Javascript pattern of overwriting a prototype method
185 // with an bound instance method of the same type: `this.method = this.method.bind(this)`
186 //
187 // If we created a new symbol, either because we didn't have a symbol with this name
188 // in the symbol table, or we conflicted with an existing symbol, then just add this
189 // node as the sole declaration of the new symbol.
190 //
191 // Otherwise, we'll be merging into a compatible existing symbol (for example when
192 // you have multiple 'vars' with the same name in the same container). In this case
193 // just add this node into the declarations list of the symbol.
194 symbol = symbolTable[name]
195 if includes&ast.SymbolFlagsClassifiable != 0 {
196 b.classifiableNames.Add(name)
197 }
198 if symbol == nil {
199 symbol = b.newSymbol(ast.SymbolFlagsNone, name)
200 symbolTable[name] = symbol
201 if isReplaceableByMethod {
202 symbol.Flags |= ast.SymbolFlagsReplaceableByMethod
203 }
204 } else if isReplaceableByMethod && symbol.Flags&ast.SymbolFlagsReplaceableByMethod == 0 {
205 // A symbol already exists, so don't add this as a declaration.
206 return symbol
207 } else if symbol.Flags&excludes != 0 {
208 if symbol.Flags&ast.SymbolFlagsReplaceableByMethod != 0 {
209 // Javascript constructor-declared symbols can be discarded in favor of
210 // prototype symbols like methods.
211 symbol = b.newSymbol(ast.SymbolFlagsNone, name)

Callers 2

declareSymbolMethod · 0.95

Calls 15

getDeclarationNameMethod · 0.95
newSymbolMethod · 0.95
getDisplayNameMethod · 0.95
AddRelatedInfoMethod · 0.95
addDiagnosticMethod · 0.95
AssertFunction · 0.92
HasDynamicNameFunction · 0.92
HasSyntacticModifierFunction · 0.92
IsExportSpecifierFunction · 0.92

Tested by

no test coverage detected