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

Side by Side Diff: pkg/analyzer/lib/src/dart/sdk/patch.dart

Issue 2417933002: Add support for patching constructors. (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 | pkg/analyzer/test/src/dart/sdk/patch_test.dart » ('j') | 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 4
5 library analyzer.src.dart.sdk.patch; 5 library analyzer.src.dart.sdk.patch;
6 6
7 import 'package:analyzer/dart/ast/ast.dart'; 7 import 'package:analyzer/dart/ast/ast.dart';
8 import 'package:analyzer/dart/ast/token.dart'; 8 import 'package:analyzer/dart/ast/token.dart';
9 import 'package:analyzer/error/listener.dart'; 9 import 'package:analyzer/error/listener.dart';
10 import 'package:analyzer/file_system/file_system.dart'; 10 import 'package:analyzer/file_system/file_system.dart';
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 FunctionBody oldBody = baseMember.body; 120 FunctionBody oldBody = baseMember.body;
121 FunctionBody newBody = patchMember.body; 121 FunctionBody newBody = patchMember.body;
122 _replaceNodeTokens(oldBody, newBody); 122 _replaceNodeTokens(oldBody, newBody);
123 baseMember.body = newBody; 123 baseMember.body = newBody;
124 } 124 }
125 } 125 }
126 } else { 126 } else {
127 _failIfPublicName(patchMember, name); 127 _failIfPublicName(patchMember, name);
128 membersToAppend.add(patchMember); 128 membersToAppend.add(patchMember);
129 } 129 }
130 } else if (patchMember is ConstructorDeclaration) {
131 String name = patchMember.name?.name;
132 if (_hasPatchAnnotation(patchMember.metadata)) {
133 for (ClassMember baseMember in baseClass.members) {
134 if (baseMember is ConstructorDeclaration &&
135 baseMember.name?.name == name) {
136 // Remove the "external" keyword.
137 Token externalKeyword = baseMember.externalKeyword;
138 if (externalKeyword != null) {
139 baseMember.externalKeyword = null;
140 _removeToken(externalKeyword);
141 } else {
142 _failExternalKeyword(name, baseMember.offset);
143 }
144 // Factory vs. generative.
145 if (baseMember.factoryKeyword == null &&
146 patchMember.factoryKeyword != null) {
147 _failInPatch(
148 'attempts to replace generative constructor with a factory o ne',
149 patchMember.offset);
150 } else if (baseMember.factoryKeyword != null &&
151 patchMember.factoryKeyword == null) {
152 _failInPatch(
153 'attempts to replace factory constructor with a generative o ne',
154 patchMember.offset);
155 }
156 // The base constructor should not have initializers.
157 if (baseMember.initializers.isNotEmpty) {
158 throw new ArgumentError(
159 'Cannot patch external constructors with initializers '
160 'in $_baseDesc.');
161 }
162 // Prepare nodes.
163 FunctionBody baseBody = baseMember.body;
164 FunctionBody patchBody = patchMember.body;
165 NodeList<ConstructorInitializer> baseInitializers =
166 baseMember.initializers;
167 NodeList<ConstructorInitializer> patchInitializers =
168 patchMember.initializers;
169 // Replace initializers and link tokens.
170 if (patchInitializers.isNotEmpty) {
171 baseMember.parameters.endToken
172 .setNext(patchInitializers.beginToken.previous);
173 baseInitializers.addAll(patchInitializers);
174 patchBody.endToken.setNext(baseBody.endToken.next);
175 } else {
176 _replaceNodeTokens(baseBody, patchBody);
177 }
178 // Replace the body.
179 baseMember.body = patchBody;
180 }
181 }
182 } else {
183 if (name == null) {
184 if (!Identifier.isPrivateName(baseClass.name.name)) {
185 _failInPatch(
186 'contains an unnamed public constructor', patchMember.offset);
187 }
188 } else {
189 _failIfPublicName(patchMember, name);
190 }
191 membersToAppend.add(patchMember);
192 }
130 } else { 193 } else {
131 // TODO(scheglov) support field 194 // TODO(scheglov) support field
132 // TODO(scheglov) support constructors
133 String className = patchClass.name.name; 195 String className = patchClass.name.name;
134 _failInPatch('contains an unsupported class member in $className', 196 _failInPatch('contains an unsupported class member in $className',
135 patchMember.offset); 197 patchMember.offset);
136 } 198 }
137 } 199 }
138 // Append new top-level declarations. 200 // Append new top-level declarations.
139 Token lastToken = baseClass.endToken.previous; 201 Token lastToken = baseClass.endToken.previous;
140 for (ClassMember newMember in membersToAppend) { 202 for (ClassMember newMember in membersToAppend) {
141 newMember.endToken.setNext(lastToken.next); 203 newMember.endToken.setNext(lastToken.next);
142 lastToken.setNext(newMember.beginToken); 204 lastToken.setNext(newMember.beginToken);
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 } 329 }
268 330
269 /** 331 /**
270 * Replace tokens of the [oldNode] with tokens of the [newNode]. 332 * Replace tokens of the [oldNode] with tokens of the [newNode].
271 */ 333 */
272 static void _replaceNodeTokens(AstNode oldNode, AstNode newNode) { 334 static void _replaceNodeTokens(AstNode oldNode, AstNode newNode) {
273 oldNode.beginToken.previous.setNext(newNode.beginToken); 335 oldNode.beginToken.previous.setNext(newNode.beginToken);
274 newNode.endToken.setNext(oldNode.endToken.next); 336 newNode.endToken.setNext(oldNode.endToken.next);
275 } 337 }
276 } 338 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/src/dart/sdk/patch_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698