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'; |
11 import 'package:analyzer/src/dart/scanner/reader.dart'; | 11 import 'package:analyzer/src/dart/scanner/reader.dart'; |
12 import 'package:analyzer/src/dart/scanner/scanner.dart'; | 12 import 'package:analyzer/src/dart/scanner/scanner.dart'; |
13 import 'package:analyzer/src/dart/sdk/sdk.dart'; | 13 import 'package:analyzer/src/dart/sdk/sdk.dart'; |
14 import 'package:analyzer/src/generated/parser.dart'; | 14 import 'package:analyzer/src/generated/parser.dart'; |
15 import 'package:analyzer/src/generated/sdk.dart'; | 15 import 'package:analyzer/src/generated/sdk.dart'; |
16 import 'package:analyzer/src/generated/source.dart'; | 16 import 'package:analyzer/src/generated/source.dart'; |
17 import 'package:meta/meta.dart'; | 17 import 'package:meta/meta.dart'; |
18 import 'package:path/src/context.dart'; | 18 import 'package:path/src/context.dart'; |
19 | 19 |
20 /** | 20 /** |
21 * [SdkPatcher] applies patches to SDK [CompilationUnit]. | 21 * [SdkPatcher] applies patches to SDK [CompilationUnit]. |
22 */ | 22 */ |
23 class SdkPatcher { | 23 class SdkPatcher { |
| 24 bool _allowNewPublicNames; |
24 String _baseDesc; | 25 String _baseDesc; |
25 String _patchDesc; | 26 String _patchDesc; |
26 CompilationUnit _patchUnit; | 27 CompilationUnit _patchUnit; |
27 | 28 |
28 /** | 29 /** |
29 * Patch the given [unit] of a SDK [source] with the patches defined in | 30 * Patch the given [unit] of a SDK [source] with the patches defined in |
30 * the [sdk] for the given [platform]. Throw [ArgumentError] if a patch | 31 * the [sdk] for the given [platform]. Throw [ArgumentError] if a patch |
31 * file cannot be read, or the contents violates rules for patch files. | 32 * file cannot be read, or the contents violates rules for patch files. |
32 */ | 33 */ |
33 void patch( | 34 void patch( |
34 FolderBasedDartSdk sdk, | 35 FolderBasedDartSdk sdk, |
35 int platform, | 36 int platform, |
36 AnalysisErrorListener errorListener, | 37 AnalysisErrorListener errorListener, |
37 Source source, | 38 Source source, |
38 CompilationUnit unit) { | 39 CompilationUnit unit) { |
39 // Process URI. | 40 // Process URI. |
40 String libraryUriStr; | 41 String libraryUriStr; |
41 bool isLibraryDefiningUnit; | 42 bool isLibraryDefiningUnit; |
42 { | 43 { |
43 Uri uri = source.uri; | 44 Uri uri = source.uri; |
44 if (uri.scheme != 'dart') { | 45 if (uri.scheme != 'dart') { |
45 throw new ArgumentError( | 46 throw new ArgumentError( |
46 'The URI of the unit to patch must have the "dart" scheme: $uri'); | 47 'The URI of the unit to patch must have the "dart" scheme: $uri'); |
47 } | 48 } |
48 List<String> uriSegments = uri.pathSegments; | 49 List<String> uriSegments = uri.pathSegments; |
49 libraryUriStr = 'dart:${uriSegments.first}'; | 50 String libraryName = uriSegments.first; |
| 51 libraryUriStr = 'dart:$libraryName'; |
50 isLibraryDefiningUnit = uriSegments.length == 1; | 52 isLibraryDefiningUnit = uriSegments.length == 1; |
| 53 _allowNewPublicNames = libraryName == '_internal'; |
51 } | 54 } |
52 // Prepare the patch files to apply. | 55 // Prepare the patch files to apply. |
53 List<String> patchPaths; | 56 List<String> patchPaths; |
54 { | 57 { |
55 SdkLibrary sdkLibrary = sdk.getSdkLibrary(libraryUriStr); | 58 SdkLibrary sdkLibrary = sdk.getSdkLibrary(libraryUriStr); |
56 if (sdkLibrary == null) { | 59 if (sdkLibrary == null) { |
57 throw new ArgumentError( | 60 throw new ArgumentError( |
58 'The library $libraryUriStr is not defined in the SDK.'); | 61 'The library $libraryUriStr is not defined in the SDK.'); |
59 } | 62 } |
60 patchPaths = sdkLibrary.getPatches(platform); | 63 patchPaths = sdkLibrary.getPatches(platform); |
(...skipping 22 matching lines...) Expand all Loading... |
83 _patchTopLevelDeclarations(unit, patchUnit, isLibraryDefiningUnit); | 86 _patchTopLevelDeclarations(unit, patchUnit, isLibraryDefiningUnit); |
84 } | 87 } |
85 } | 88 } |
86 | 89 |
87 void _failExternalKeyword(String name, int offset) { | 90 void _failExternalKeyword(String name, int offset) { |
88 throw new ArgumentError( | 91 throw new ArgumentError( |
89 'The keyword "external" was expected for "$name" in $_baseDesc @ $offset
.'); | 92 'The keyword "external" was expected for "$name" in $_baseDesc @ $offset
.'); |
90 } | 93 } |
91 | 94 |
92 void _failIfPublicName(AstNode node, String name) { | 95 void _failIfPublicName(AstNode node, String name) { |
| 96 if (_allowNewPublicNames) { |
| 97 return; |
| 98 } |
93 if (!Identifier.isPrivateName(name)) { | 99 if (!Identifier.isPrivateName(name)) { |
94 _failInPatch('contains a public declaration "$name"', node.offset); | 100 _failInPatch('contains a public declaration "$name"', node.offset); |
95 } | 101 } |
96 } | 102 } |
97 | 103 |
98 void _failInPatch(String message, int offset) { | 104 void _failInPatch(String message, int offset) { |
99 String loc = _getLocationDesc3(_patchUnit, offset); | 105 String loc = _getLocationDesc3(_patchUnit, offset); |
100 throw new ArgumentError( | 106 throw new ArgumentError( |
101 'The patch file $_patchDesc for $_baseDesc $message at $loc.'); | 107 'The patch file $_patchDesc for $_baseDesc $message at $loc.'); |
102 } | 108 } |
(...skipping 11 matching lines...) Expand all Loading... |
114 if (patchMember is FieldDeclaration) { | 120 if (patchMember is FieldDeclaration) { |
115 if (_hasPatchAnnotation(patchMember.metadata)) { | 121 if (_hasPatchAnnotation(patchMember.metadata)) { |
116 _failInPatch('attempts to patch a field', patchMember.offset); | 122 _failInPatch('attempts to patch a field', patchMember.offset); |
117 } | 123 } |
118 List<VariableDeclaration> fields = patchMember.fields.variables; | 124 List<VariableDeclaration> fields = patchMember.fields.variables; |
119 if (fields.length != 1) { | 125 if (fields.length != 1) { |
120 _failInPatch('contains a field declaration with more than one field', | 126 _failInPatch('contains a field declaration with more than one field', |
121 patchMember.offset); | 127 patchMember.offset); |
122 } | 128 } |
123 String name = fields[0].name.name; | 129 String name = fields[0].name.name; |
124 if (!Identifier.isPrivateName(className) && | 130 if (!_allowNewPublicNames && |
| 131 !Identifier.isPrivateName(className) && |
125 !Identifier.isPrivateName(name)) { | 132 !Identifier.isPrivateName(name)) { |
126 // TODO(scheglov) allow adding public fields into dart:_internal | |
127 _failInPatch('contains a public field', patchMember.offset); | 133 _failInPatch('contains a public field', patchMember.offset); |
128 } | 134 } |
129 membersToAppend.add(patchMember); | 135 membersToAppend.add(patchMember); |
130 } else if (patchMember is MethodDeclaration) { | 136 } else if (patchMember is MethodDeclaration) { |
131 String name = patchMember.name.name; | 137 String name = patchMember.name.name; |
132 if (_hasPatchAnnotation(patchMember.metadata)) { | 138 if (_hasPatchAnnotation(patchMember.metadata)) { |
133 for (ClassMember baseMember in baseClass.members) { | 139 for (ClassMember baseMember in baseClass.members) { |
134 if (baseMember is MethodDeclaration && | 140 if (baseMember is MethodDeclaration && |
135 baseMember.name.name == name) { | 141 baseMember.name.name == name) { |
136 // Remove the "external" keyword. | 142 // Remove the "external" keyword. |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 patchBody.endToken.setNext(baseBody.endToken.next); | 205 patchBody.endToken.setNext(baseBody.endToken.next); |
200 } else { | 206 } else { |
201 _replaceNodeTokens(baseBody, patchBody); | 207 _replaceNodeTokens(baseBody, patchBody); |
202 } | 208 } |
203 // Replace the body. | 209 // Replace the body. |
204 baseMember.body = patchBody; | 210 baseMember.body = patchBody; |
205 } | 211 } |
206 } | 212 } |
207 } else { | 213 } else { |
208 if (name == null) { | 214 if (name == null) { |
209 if (!Identifier.isPrivateName(className)) { | 215 if (!_allowNewPublicNames && !Identifier.isPrivateName(className)) { |
210 _failInPatch( | 216 _failInPatch( |
211 'contains an unnamed public constructor', patchMember.offset); | 217 'contains an unnamed public constructor', patchMember.offset); |
212 } | 218 } |
213 } else { | 219 } else { |
214 _failIfPublicName(patchMember, name); | 220 _failIfPublicName(patchMember, name); |
215 } | 221 } |
216 membersToAppend.add(patchMember); | 222 membersToAppend.add(patchMember); |
217 } | 223 } |
218 } else { | 224 } else { |
219 String className = patchClass.name.name; | 225 String className = patchClass.name.name; |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 } | 362 } |
357 | 363 |
358 /** | 364 /** |
359 * Replace tokens of the [oldNode] with tokens of the [newNode]. | 365 * Replace tokens of the [oldNode] with tokens of the [newNode]. |
360 */ | 366 */ |
361 static void _replaceNodeTokens(AstNode oldNode, AstNode newNode) { | 367 static void _replaceNodeTokens(AstNode oldNode, AstNode newNode) { |
362 oldNode.beginToken.previous.setNext(newNode.beginToken); | 368 oldNode.beginToken.previous.setNext(newNode.beginToken); |
363 newNode.endToken.setNext(oldNode.endToken.next); | 369 newNode.endToken.setNext(oldNode.endToken.next); |
364 } | 370 } |
365 } | 371 } |
OLD | NEW |