OLD | NEW |
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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 'The patch file $_patchDesc for $_baseDesc $message at $loc.'); | 93 'The patch file $_patchDesc for $_baseDesc $message at $loc.'); |
94 } | 94 } |
95 | 95 |
96 String _getLocationDesc3(CompilationUnit unit, int offset) { | 96 String _getLocationDesc3(CompilationUnit unit, int offset) { |
97 LineInfo_Location location = unit.lineInfo.getLocation(offset); | 97 LineInfo_Location location = unit.lineInfo.getLocation(offset); |
98 return 'the line ${location.lineNumber}'; | 98 return 'the line ${location.lineNumber}'; |
99 } | 99 } |
100 | 100 |
101 void _patchClassMembers( | 101 void _patchClassMembers( |
102 ClassDeclaration baseClass, ClassDeclaration patchClass) { | 102 ClassDeclaration baseClass, ClassDeclaration patchClass) { |
| 103 String className = baseClass.name.name; |
103 List<ClassMember> membersToAppend = []; | 104 List<ClassMember> membersToAppend = []; |
104 for (ClassMember patchMember in patchClass.members) { | 105 for (ClassMember patchMember in patchClass.members) { |
105 if (patchMember is MethodDeclaration) { | 106 if (patchMember is FieldDeclaration) { |
| 107 if (_hasPatchAnnotation(patchMember.metadata)) { |
| 108 _failInPatch('attempts to patch a field', patchMember.offset); |
| 109 } |
| 110 List<VariableDeclaration> fields = patchMember.fields.variables; |
| 111 if (fields.length != 1) { |
| 112 _failInPatch('contains a field declaration with more than one field', |
| 113 patchMember.offset); |
| 114 } |
| 115 String name = fields[0].name.name; |
| 116 if (!Identifier.isPrivateName(className) && |
| 117 !Identifier.isPrivateName(name)) { |
| 118 // TODO(scheglov) allow adding public fields into dart:_internal |
| 119 _failInPatch('contains a public field', patchMember.offset); |
| 120 } |
| 121 membersToAppend.add(patchMember); |
| 122 } else if (patchMember is MethodDeclaration) { |
106 String name = patchMember.name.name; | 123 String name = patchMember.name.name; |
107 if (_hasPatchAnnotation(patchMember.metadata)) { | 124 if (_hasPatchAnnotation(patchMember.metadata)) { |
108 for (ClassMember baseMember in baseClass.members) { | 125 for (ClassMember baseMember in baseClass.members) { |
109 if (baseMember is MethodDeclaration && | 126 if (baseMember is MethodDeclaration && |
110 baseMember.name.name == name) { | 127 baseMember.name.name == name) { |
111 // Remove the "external" keyword. | 128 // Remove the "external" keyword. |
112 Token externalKeyword = baseMember.externalKeyword; | 129 Token externalKeyword = baseMember.externalKeyword; |
113 if (externalKeyword != null) { | 130 if (externalKeyword != null) { |
114 baseMember.externalKeyword = null; | 131 baseMember.externalKeyword = null; |
115 _removeToken(externalKeyword); | 132 _removeToken(externalKeyword); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 patchBody.endToken.setNext(baseBody.endToken.next); | 191 patchBody.endToken.setNext(baseBody.endToken.next); |
175 } else { | 192 } else { |
176 _replaceNodeTokens(baseBody, patchBody); | 193 _replaceNodeTokens(baseBody, patchBody); |
177 } | 194 } |
178 // Replace the body. | 195 // Replace the body. |
179 baseMember.body = patchBody; | 196 baseMember.body = patchBody; |
180 } | 197 } |
181 } | 198 } |
182 } else { | 199 } else { |
183 if (name == null) { | 200 if (name == null) { |
184 if (!Identifier.isPrivateName(baseClass.name.name)) { | 201 if (!Identifier.isPrivateName(className)) { |
185 _failInPatch( | 202 _failInPatch( |
186 'contains an unnamed public constructor', patchMember.offset); | 203 'contains an unnamed public constructor', patchMember.offset); |
187 } | 204 } |
188 } else { | 205 } else { |
189 _failIfPublicName(patchMember, name); | 206 _failIfPublicName(patchMember, name); |
190 } | 207 } |
191 membersToAppend.add(patchMember); | 208 membersToAppend.add(patchMember); |
192 } | 209 } |
193 } else { | 210 } else { |
194 // TODO(scheglov) support field | |
195 String className = patchClass.name.name; | 211 String className = patchClass.name.name; |
196 _failInPatch('contains an unsupported class member in $className', | 212 _failInPatch('contains an unsupported class member in $className', |
197 patchMember.offset); | 213 patchMember.offset); |
198 } | 214 } |
199 } | 215 } |
200 // Append new class members. | 216 // Append new class members. |
201 _appendToNodeList( | 217 _appendToNodeList( |
202 baseClass.members, membersToAppend, baseClass.leftBracket); | 218 baseClass.members, membersToAppend, baseClass.leftBracket); |
203 } | 219 } |
204 | 220 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 } | 350 } |
335 | 351 |
336 /** | 352 /** |
337 * Replace tokens of the [oldNode] with tokens of the [newNode]. | 353 * Replace tokens of the [oldNode] with tokens of the [newNode]. |
338 */ | 354 */ |
339 static void _replaceNodeTokens(AstNode oldNode, AstNode newNode) { | 355 static void _replaceNodeTokens(AstNode oldNode, AstNode newNode) { |
340 oldNode.beginToken.previous.setNext(newNode.beginToken); | 356 oldNode.beginToken.previous.setNext(newNode.beginToken); |
341 newNode.endToken.setNext(oldNode.endToken.next); | 357 newNode.endToken.setNext(oldNode.endToken.next); |
342 } | 358 } |
343 } | 359 } |
OLD | NEW |