Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(222)

Side by Side Diff: lib/analyzer/ast_from_analyzer.dart

Issue 2431623002: Revert "Add null initializers to fields that have no initializer." (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 library kernel.analyzer.ast_from_analyzer; 4 library kernel.analyzer.ast_from_analyzer;
5 5
6 import '../ast.dart' as ast; 6 import '../ast.dart' as ast;
7 import '../frontend/accessors.dart'; 7 import '../frontend/accessors.dart';
8 import '../frontend/super_initializers.dart'; 8 import '../frontend/super_initializers.dart';
9 import '../log.dart'; 9 import '../log.dart';
10 import '../type_algebra.dart'; 10 import '../type_algebra.dart';
(...skipping 2322 matching lines...) Expand 10 before | Expand all | Expand 10 after
2333 assert(defaultConstructor.enclosingElement == node.element); 2333 assert(defaultConstructor.enclosingElement == node.element);
2334 if (!defaultConstructor.isSynthetic) { 2334 if (!defaultConstructor.isSynthetic) {
2335 throw 'Non-synthetic default constructor not in list of members. ' 2335 throw 'Non-synthetic default constructor not in list of members. '
2336 '${node} $element $defaultConstructor'; 2336 '${node} $element $defaultConstructor';
2337 } 2337 }
2338 var memberNode = scope.getMemberReference(defaultConstructor); 2338 var memberNode = scope.getMemberReference(defaultConstructor);
2339 classNode.addMember(memberNode); 2339 classNode.addMember(memberNode);
2340 buildDefaultConstructor(memberNode, defaultConstructor); 2340 buildDefaultConstructor(memberNode, defaultConstructor);
2341 } 2341 }
2342 } 2342 }
2343
2344 addDefaultFieldInitializers(classNode);
2345 } 2343 }
2346 2344
2347 void buildDefaultConstructor( 2345 void buildDefaultConstructor(
2348 ast.Constructor constructor, ConstructorElement element) { 2346 ast.Constructor constructor, ConstructorElement element) {
2349 var function = constructor.function; 2347 var function = constructor.function;
2350 function.body = new ast.EmptyStatement()..parent = function; 2348 function.body = new ast.EmptyStatement()..parent = function;
2351 var class_ = element.enclosingElement; 2349 var class_ = element.enclosingElement;
2352 if (class_.supertype != null) { 2350 if (class_.supertype != null) {
2353 // DESIGN TODO: If the super class is a mixin application, we will link to 2351 // DESIGN TODO: If the super class is a mixin application, we will link to
2354 // a constructor not in the immediate super class. This is a problem due 2352 // a constructor not in the immediate super class. This is a problem due
2355 // to the fact that mixed-in fields come with initializers which need to 2353 // to the fact that mixed-in fields come with initializers which need to
2356 // be executed by a constructor. The mixin transformer takes care of 2354 // be executed by a constructor. The mixin transformer takes care of
2357 // this by making forwarding constructors and the super initializers will 2355 // this by making forwarding constructors and the super initializers will
2358 // be rewritten to use them (see `transformations/mixin_full_resolution`). 2356 // be rewritten to use them (see `transformations/mixin_full_resolution`).
2359 var superConstructor = 2357 var superConstructor =
2360 scope.findDefaultConstructor(class_.supertype.element); 2358 scope.findDefaultConstructor(class_.supertype.element);
2361 var target = scope.resolveConstructor(superConstructor); 2359 var target = scope.resolveConstructor(superConstructor);
2362 if (target == null) { 2360 if (target == null) {
2363 constructor.initializers 2361 constructor.initializers
2364 .add(new ast.InvalidInitializer()..parent = constructor); 2362 .add(new ast.InvalidInitializer()..parent = constructor);
2365 } else { 2363 } else {
2366 var arguments = new ast.Arguments.empty(); 2364 var arguments = new ast.Arguments.empty();
2367 constructor.initializers.add( 2365 constructor.initializers.add(
2368 new ast.SuperInitializer(target, arguments)..parent = constructor); 2366 new ast.SuperInitializer(target, arguments)..parent = constructor);
2369 } 2367 }
2370 } 2368 }
2371 } 2369 }
2372 2370
2373 /// Adds initializers to fields that are have no initializer and are not
2374 /// initialized by all constructors in the class.
2375 void addDefaultFieldInitializers(ast.Class node) {
2376 List<ast.Field> uninitializedFields = new List<ast.Field>();
2377 for (var field in node.fields) {
2378 if (field.initializer != null || field.isExternal) continue;
2379 if (field.isStatic) {
2380 field.initializer = new ast.NullLiteral()..parent = field;
2381 } else {
2382 uninitializedFields.add(field);
2383 }
2384 }
2385 if (uninitializedFields.isEmpty) return;
2386 constructorLoop:
2387 for (var constructor in node.constructors) {
2388 var remainingFields = uninitializedFields.toSet();
2389 for (var initializer in constructor.initializers) {
2390 if (initializer is ast.FieldInitializer) {
2391 remainingFields.remove(initializer.field);
2392 } else if (initializer is ast.RedirectingInitializer) {
2393 // The target constructor will be checked in another iteration.
2394 continue constructorLoop;
2395 }
2396 }
2397 for (var field in remainingFields) {
2398 if (field.initializer == null) {
2399 field.initializer = new ast.NullLiteral()..parent = field;
2400 }
2401 }
2402 }
2403 }
2404
2405 /// True for the `values` field of an `enum` class. 2371 /// True for the `values` field of an `enum` class.
2406 static bool _isValuesField(FieldElement field) => field.name == 'values'; 2372 static bool _isValuesField(FieldElement field) => field.name == 'values';
2407 2373
2408 /// True for the `index` field of an `enum` class. 2374 /// True for the `index` field of an `enum` class.
2409 static bool _isIndexField(FieldElement field) => field.name == 'index'; 2375 static bool _isIndexField(FieldElement field) => field.name == 'index';
2410 2376
2411 visitEnumDeclaration(EnumDeclaration node) { 2377 visitEnumDeclaration(EnumDeclaration node) {
2412 addAnnotations(node.metadata); 2378 addAnnotations(node.metadata);
2413 ast.Class classNode = currentClass; 2379 ast.Class classNode = currentClass;
2414 var intType = 2380 var intType =
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
2756 if (element is FieldElement) return element.getter; 2722 if (element is FieldElement) return element.getter;
2757 return element; 2723 return element;
2758 } 2724 }
2759 2725
2760 Element desynthesizeSetter(Element element) { 2726 Element desynthesizeSetter(Element element) {
2761 if (element == null || !element.isSynthetic) return element; 2727 if (element == null || !element.isSynthetic) return element;
2762 if (element is PropertyAccessorElement) return element.variable; 2728 if (element is PropertyAccessorElement) return element.variable;
2763 if (element is FieldElement) return element.setter; 2729 if (element is FieldElement) return element.setter;
2764 return element; 2730 return element;
2765 } 2731 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698