@@ -5085,41 +5085,49 @@ class BodyBuilder extends StackListenerImpl
50855085 void enterNominalVariablesScope (
50865086 List <NominalParameterBuilder >? nominalVariableBuilders) {
50875087 debugEvent ("enterNominalVariableScope" );
5088- enterLocalScope (_localScope.createNestedScope (
5089- debugName: "function-type scope" , kind: ScopeKind .typeParameters));
5088+ Map <String , TypeParameterBuilder > typeParameters = {};
50905089 if (nominalVariableBuilders != null ) {
50915090 for (NominalParameterBuilder builder in nominalVariableBuilders) {
50925091 if (builder.isWildcard) continue ;
50935092 String name = builder.name;
5094- Builder ? existing = _localScope. lookupLocalVariable ( name) ;
5093+ TypeParameterBuilder ? existing = typeParameters[ name] ;
50955094 if (existing == null ) {
5096- _localScope. addLocalVariable ( name, builder) ;
5095+ typeParameters[ name] = builder;
50975096 } else {
50985097 // Coverage-ignore-block(suite): Not run.
50995098 reportDuplicatedDeclaration (existing, name, builder.fileOffset);
51005099 }
51015100 }
51025101 }
5102+ enterLocalScope (new LocalTypeParameterScope (
5103+ local: typeParameters,
5104+ parent: _localScope,
5105+ debugName: "local function type parameter scope" ,
5106+ kind: ScopeKind .typeParameters));
51035107 }
51045108
51055109 void enterStructuralVariablesScope (
51065110 List <StructuralParameterBuilder >? structuralVariableBuilders) {
51075111 debugEvent ("enterStructuralVariableScope" );
5108- enterLocalScope (_localScope.createNestedScope (
5109- debugName: "function-type scope" , kind: ScopeKind .typeParameters));
5112+ Map <String , TypeParameterBuilder > typeParameters = {};
51105113 if (structuralVariableBuilders != null ) {
51115114 for (StructuralParameterBuilder builder in structuralVariableBuilders) {
51125115 if (builder.isWildcard) continue ;
51135116 String name = builder.name;
5114- Builder ? existing = _localScope. lookupLocalVariable ( name) ;
5117+ TypeParameterBuilder ? existing = typeParameters[ name] ;
51155118 if (existing == null ) {
5116- _localScope. addLocalVariable ( name, builder) ;
5119+ typeParameters[ name] = builder;
51175120 } else {
51185121 // Coverage-ignore-block(suite): Not run.
51195122 reportDuplicatedDeclaration (existing, name, builder.fileOffset);
51205123 }
51215124 }
51225125 }
5126+ enterLocalScope (new LocalTypeParameterScope (
5127+ local: typeParameters,
5128+ parent: _localScope,
5129+ debugName: "function-type scope" ,
5130+ kind: ScopeKind .typeParameters));
51235131 }
51245132
51255133 @override
@@ -7273,7 +7281,8 @@ class BodyBuilder extends StackListenerImpl
72737281 void handleNamedRecordField (Token colon) => handleNamedArgument (colon);
72747282
72757283 @override
7276- void endFunctionName (Token beginToken, Token token) {
7284+ void endFunctionName (
7285+ Token beginToken, Token token, bool isFunctionExpression) {
72777286 debugEvent ("FunctionName" );
72787287 Identifier name = pop () as Identifier ;
72797288 Token nameToken = name.token;
@@ -7290,20 +7299,24 @@ class BodyBuilder extends StackListenerImpl
72907299 isLocalFunction: true ,
72917300 isWildcard: isWildcard)
72927301 ..fileOffset = name.nameOffset;
7293- // TODO(ahe): Why are we looking up in local scope, but declaring in parent
7294- // scope?
7295- Builder ? existing = _localScope.lookupLocalVariable (name.name);
7296- if (existing != null ) {
7297- // Coverage-ignore-block(suite): Not run.
7298- reportDuplicatedDeclaration (existing, name.name, name.nameOffset);
7299- }
73007302 push (new FunctionDeclarationImpl (
73017303 variable,
73027304 // The real function node is created later.
73037305 dummyFunctionNode)
73047306 ..fileOffset = beginToken.charOffset);
73057307 if (! (libraryFeatures.wildcardVariables.isEnabled && variable.isWildcard)) {
7306- declareVariable (variable, _localScopes.previous);
7308+ // The local scope stack contains a type parameter scope for the local
7309+ // function on top of the scope for the block in which the local function
7310+ // declaration occurs. So for a local function declaration, we add the
7311+ // declaration to the previous scope, i.e. the block scope.
7312+ //
7313+ // For a named function expression, a nested scope is created to hold the
7314+ // name, so that it doesn't pollute the block scope (the named function
7315+ // expression is erroneous and should introduce the name in the scope) and
7316+ // we therefore use the current scope in this case.
7317+ LocalScope scope =
7318+ isFunctionExpression ? _localScope : _localScopes.previous;
7319+ declareVariable (variable, scope);
73077320 }
73087321 }
73097322
0 commit comments