| 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 |