diff --git a/pkgs/ffigen/lib/src/code_generator/scope.dart b/pkgs/ffigen/lib/src/code_generator/scope.dart index d3266771d..ae44fb79f 100644 --- a/pkgs/ffigen/lib/src/code_generator/scope.dart +++ b/pkgs/ffigen/lib/src/code_generator/scope.dart @@ -40,15 +40,26 @@ class Scope { /// Add a [Symbol] to this [Scope]. /// - /// It's fine to add the [Symbol] to this [Scope] multiple times. It's - /// also fine to add the [Symbol] to multiple [Scope]s, as long as one of - /// the [Scope]s is an ancestor of all the others (this is checked during - /// [fillNames]). + /// [Symbol]s can only be in one [Scope], so this call does nothing if the + /// symbol is already in a scope, unless this scope is an ancestor of the + /// symbol's existing scope. /// /// [fillNames] must not have been called yet. void add(Symbol? symbol) { assert(!_filled); - if (symbol != null) _symbols.add(symbol); + if (symbol == null) return; + final existingScope = symbol._scope; + if (existingScope == null || _isAncestor(existingScope)) { + _symbols.add(symbol); + symbol._scope = this; + } + } + + bool _isAncestor(Scope other) { + for (Scope? s = other; s != null; s = s._parent) { + if (s == this) return true; + } + return false; } /// Add an ad-hoc name to the [Scope]. @@ -161,6 +172,7 @@ class Namer { class Symbol extends AstNode { final String oldName; final SymbolKind kind; + Scope? _scope; String? _name; /// Only valid if [Scope.fillNames] has been called already.