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

Side by Side Diff: pkg/compiler/lib/src/patch_parser.dart

Issue 1859343004: dartfmt pkg/compiler (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 /** 5 /**
6 * This library contains the infrastructure to parse and integrate patch files. 6 * This library contains the infrastructure to parse and integrate patch files.
7 * 7 *
8 * Three types of elements can be patched: [LibraryElement], [ClassElement], 8 * Three types of elements can be patched: [LibraryElement], [ClassElement],
9 * [FunctionElement]. Patches are introduced in patch libraries which are loaded 9 * [FunctionElement]. Patches are introduced in patch libraries which are loaded
10 * together with the corresponding origin library. Which libraries that are 10 * together with the corresponding origin library. Which libraries that are
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 * - Builders shift between declaration and implementation depending on usages. 109 * - Builders shift between declaration and implementation depending on usages.
110 * - Compile-time constants use constructor implementation exclusively. 110 * - Compile-time constants use constructor implementation exclusively.
111 * - Work on function parameters is performed on the declaration of the function 111 * - Work on function parameters is performed on the declaration of the function
112 * element. 112 * element.
113 */ 113 */
114 114
115 library dart2js.patchparser; 115 library dart2js.patchparser;
116 116
117 import 'dart:async'; 117 import 'dart:async';
118 118
119 import 'constants/values.dart' show 119 import 'constants/values.dart' show ConstantValue;
120 ConstantValue;
121 import 'common.dart'; 120 import 'common.dart';
122 import 'compiler.dart' show 121 import 'compiler.dart' show Compiler;
123 Compiler; 122 import 'common/tasks.dart' show CompilerTask;
124 import 'common/tasks.dart' show 123 import 'dart_types.dart' show DartType;
125 CompilerTask;
126 import 'dart_types.dart' show
127 DartType;
128 import 'elements/elements.dart'; 124 import 'elements/elements.dart';
129 import 'elements/modelx.dart' show 125 import 'elements/modelx.dart'
130 BaseFunctionElementX, 126 show
131 ClassElementX, 127 BaseFunctionElementX,
132 GetterElementX, 128 ClassElementX,
133 LibraryElementX, 129 GetterElementX,
134 MetadataAnnotationX, 130 LibraryElementX,
135 SetterElementX; 131 MetadataAnnotationX,
136 import 'js_backend/js_backend.dart' show 132 SetterElementX;
137 JavaScriptBackend; 133 import 'js_backend/js_backend.dart' show JavaScriptBackend;
138 import 'library_loader.dart' show 134 import 'library_loader.dart' show LibraryLoader;
139 LibraryLoader; 135 import 'options.dart' show ParserOptions;
140 import 'options.dart' show 136 import 'parser/listener.dart' show Listener, ParserError;
141 ParserOptions; 137 import 'parser/element_listener.dart' show ElementListener;
142 import 'parser/listener.dart' show 138 import 'parser/member_listener.dart' show MemberListener;
143 Listener, 139 import 'parser/partial_elements.dart' show PartialClassElement;
144 ParserError; 140 import 'parser/partial_parser.dart' show PartialParser;
145 import 'parser/element_listener.dart' show 141 import 'parser/parser.dart' show Parser;
146 ElementListener; 142 import 'scanner/scanner.dart' show Scanner;
147 import 'parser/member_listener.dart' show
148 MemberListener;
149 import 'parser/partial_elements.dart' show
150 PartialClassElement;
151 import 'parser/partial_parser.dart' show
152 PartialParser;
153 import 'parser/parser.dart' show
154 Parser;
155 import 'scanner/scanner.dart' show
156 Scanner;
157 import 'script.dart'; 143 import 'script.dart';
158 import 'tokens/token.dart' show 144 import 'tokens/token.dart' show StringToken, Token;
159 StringToken,
160 Token;
161 145
162 class PatchParserTask extends CompilerTask { 146 class PatchParserTask extends CompilerTask {
163 final String name = "Patching Parser"; 147 final String name = "Patching Parser";
164 final ParserOptions parserOptions; 148 final ParserOptions parserOptions;
165 149
166 PatchParserTask(Compiler compiler, this.parserOptions) : super(compiler); 150 PatchParserTask(Compiler compiler, this.parserOptions) : super(compiler);
167 151
168 /** 152 /**
169 * Scans a library patch file, applies the method patches and 153 * Scans a library patch file, applies the method patches and
170 * injections to the library, and returns a list of class 154 * injections to the library, and returns a list of class
171 * patches. 155 * patches.
172 */ 156 */
173 Future patchLibrary(LibraryLoader loader, 157 Future patchLibrary(
174 Uri patchUri, LibraryElement originLibrary) { 158 LibraryLoader loader, Uri patchUri, LibraryElement originLibrary) {
175 return compiler.readScript(patchUri, originLibrary) 159 return compiler.readScript(patchUri, originLibrary).then((Script script) {
176 .then((Script script) {
177 var patchLibrary = new LibraryElementX(script, null, originLibrary); 160 var patchLibrary = new LibraryElementX(script, null, originLibrary);
178 return reporter.withCurrentElement(patchLibrary, () { 161 return reporter.withCurrentElement(patchLibrary, () {
179 loader.registerNewLibrary(patchLibrary); 162 loader.registerNewLibrary(patchLibrary);
180 reporter.withCurrentElement(patchLibrary.entryCompilationUnit, () { 163 reporter.withCurrentElement(patchLibrary.entryCompilationUnit, () {
181 // This patches the elements of the patch library into [library]. 164 // This patches the elements of the patch library into [library].
182 // Injected elements are added directly under the compilation unit. 165 // Injected elements are added directly under the compilation unit.
183 // Patch elements are stored on the patched functions or classes. 166 // Patch elements are stored on the patched functions or classes.
184 scanLibraryElements(patchLibrary.entryCompilationUnit); 167 scanLibraryElements(patchLibrary.entryCompilationUnit);
185 }); 168 });
186 return loader.processLibraryTags(patchLibrary); 169 return loader.processLibraryTags(patchLibrary);
187 }); 170 });
188 }); 171 });
189 } 172 }
190 173
191 void scanLibraryElements(CompilationUnitElement compilationUnit) { 174 void scanLibraryElements(CompilationUnitElement compilationUnit) {
192 measure(() { 175 measure(() {
193 // TODO(johnniwinther): Test that parts and exports are handled correctly. 176 // TODO(johnniwinther): Test that parts and exports are handled correctly.
194 Script script = compilationUnit.script; 177 Script script = compilationUnit.script;
195 Token tokens = new Scanner(script.file).tokenize(); 178 Token tokens = new Scanner(script.file).tokenize();
196 Function idGenerator = compiler.getNextFreeClassId; 179 Function idGenerator = compiler.getNextFreeClassId;
197 Listener patchListener = new PatchElementListener(compiler, 180 Listener patchListener =
198 compilationUnit, 181 new PatchElementListener(compiler, compilationUnit, idGenerator);
199 idGenerator);
200 try { 182 try {
201 new PartialParser(patchListener, parserOptions).parseUnit(tokens); 183 new PartialParser(patchListener, parserOptions).parseUnit(tokens);
202 } on ParserError catch (e) { 184 } on ParserError catch (e) {
203 // No need to recover from a parser error in platform libraries, user 185 // No need to recover from a parser error in platform libraries, user
204 // will never see this if the libraries are tested correctly. 186 // will never see this if the libraries are tested correctly.
205 reporter.internalError( 187 reporter.internalError(
206 compilationUnit, "Parser error in patch file: $e"); 188 compilationUnit, "Parser error in patch file: $e");
207 } 189 }
208 }); 190 });
209 } 191 }
210 192
211 void parsePatchClassNode(PartialClassElement cls) { 193 void parsePatchClassNode(PartialClassElement cls) {
212 // Parse [PartialClassElement] using a "patch"-aware parser instead 194 // Parse [PartialClassElement] using a "patch"-aware parser instead
213 // of calling its [parseNode] method. 195 // of calling its [parseNode] method.
214 if (cls.cachedNode != null) return; 196 if (cls.cachedNode != null) return;
215 197
216 measure(() => reporter.withCurrentElement(cls, () { 198 measure(() => reporter.withCurrentElement(cls, () {
217 MemberListener listener = new PatchMemberListener(compiler, cls); 199 MemberListener listener = new PatchMemberListener(compiler, cls);
218 Parser parser = new PatchClassElementParser(listener, parserOptions); 200 Parser parser = new PatchClassElementParser(listener, parserOptions);
219 try { 201 try {
220 Token token = parser.parseTopLevelDeclaration(cls.beginToken); 202 Token token = parser.parseTopLevelDeclaration(cls.beginToken);
221 assert(identical(token, cls.endToken.next)); 203 assert(identical(token, cls.endToken.next));
222 } on ParserError catch (e) { 204 } on ParserError catch (e) {
223 // No need to recover from a parser error in platform libraries, user 205 // No need to recover from a parser error in platform libraries, use r
224 // will never see this if the libraries are tested correctly. 206 // will never see this if the libraries are tested correctly.
225 reporter.internalError( 207 reporter.internalError(cls, "Parser error in patch file: $e");
226 cls, "Parser error in patch file: $e"); 208 }
227 } 209 cls.cachedNode = listener.popNode();
228 cls.cachedNode = listener.popNode(); 210 assert(listener.nodes.isEmpty);
229 assert(listener.nodes.isEmpty); 211 }));
230 }));
231 } 212 }
232 } 213 }
233 214
234 class PatchMemberListener extends MemberListener { 215 class PatchMemberListener extends MemberListener {
235 final Compiler compiler; 216 final Compiler compiler;
236 217
237 PatchMemberListener(Compiler compiler, ClassElement enclosingClass) 218 PatchMemberListener(Compiler compiler, ClassElement enclosingClass)
238 : this.compiler = compiler, 219 : this.compiler = compiler,
239 super(compiler.parsing.getScannerOptionsFor(enclosingClass), 220 super(compiler.parsing.getScannerOptionsFor(enclosingClass),
240 compiler.reporter, 221 compiler.reporter, enclosingClass);
241 enclosingClass);
242 222
243 @override 223 @override
244 void addMember(Element patch) { 224 void addMember(Element patch) {
245 addMetadata(patch); 225 addMetadata(patch);
246 226
247 PatchVersion patchVersion = getPatchVersion(compiler, patch); 227 PatchVersion patchVersion = getPatchVersion(compiler, patch);
248 if (patchVersion != null) { 228 if (patchVersion != null) {
249 if (patchVersion.isActive(compiler.patchVersion)) { 229 if (patchVersion.isActive(compiler.patchVersion)) {
250 Element origin = enclosingClass.origin.localLookup(patch.name); 230 Element origin = enclosingClass.origin.localLookup(patch.name);
251 patchElement(compiler, reporter, origin, patch); 231 patchElement(compiler, reporter, origin, patch);
(...skipping 20 matching lines...) Expand all
272 252
273 Token parseClassBody(Token token) => fullParseClassBody(token); 253 Token parseClassBody(Token token) => fullParseClassBody(token);
274 } 254 }
275 255
276 /** 256 /**
277 * Extension of [ElementListener] for parsing patch files. 257 * Extension of [ElementListener] for parsing patch files.
278 */ 258 */
279 class PatchElementListener extends ElementListener implements Listener { 259 class PatchElementListener extends ElementListener implements Listener {
280 final Compiler compiler; 260 final Compiler compiler;
281 261
282 PatchElementListener(Compiler compiler, 262 PatchElementListener(
283 CompilationUnitElement patchElement, 263 Compiler compiler, CompilationUnitElement patchElement, int idGenerator())
284 int idGenerator()) 264 : this.compiler = compiler,
285 : this.compiler = compiler, 265 super(compiler.parsing.getScannerOptionsFor(patchElement),
286 super(compiler.parsing.getScannerOptionsFor(patchElement),
287 compiler.reporter, patchElement, idGenerator); 266 compiler.reporter, patchElement, idGenerator);
288 267
289 @override 268 @override
290 void pushElement(Element patch) { 269 void pushElement(Element patch) {
291 popMetadata(patch); 270 popMetadata(patch);
292 271
293 PatchVersion patchVersion = getPatchVersion(compiler, patch); 272 PatchVersion patchVersion = getPatchVersion(compiler, patch);
294 if (patchVersion != null) { 273 if (patchVersion != null) {
295 if (patchVersion.isActive(compiler.patchVersion)) { 274 if (patchVersion.isActive(compiler.patchVersion)) {
296 LibraryElement originLibrary = compilationUnitElement.library; 275 LibraryElement originLibrary = compilationUnitElement.library;
297 assert(originLibrary.isPatched); 276 assert(originLibrary.isPatched);
298 Element origin = originLibrary.localLookup(patch.name); 277 Element origin = originLibrary.localLookup(patch.name);
299 patchElement(compiler, reporter, origin, patch); 278 patchElement(compiler, reporter, origin, patch);
300 compilationUnitElement.addMember(patch, reporter); 279 compilationUnitElement.addMember(patch, reporter);
301 } else { 280 } else {
302 // Skip this element. 281 // Skip this element.
303 } 282 }
304 } else { 283 } else {
305 if (Name.isPublicName(patch.name)) { 284 if (Name.isPublicName(patch.name)) {
306 reporter.reportErrorMessage(patch, MessageKind.INJECTED_PUBLIC_MEMBER); 285 reporter.reportErrorMessage(patch, MessageKind.INJECTED_PUBLIC_MEMBER);
307 } 286 }
308 compilationUnitElement.addMember(patch, reporter); 287 compilationUnitElement.addMember(patch, reporter);
309 } 288 }
310 } 289 }
311 } 290 }
312 291
313 void patchElement(Compiler compiler, 292 void patchElement(Compiler compiler, DiagnosticReporter reporter,
314 DiagnosticReporter reporter, 293 Element origin, Element patch) {
315 Element origin,
316 Element patch) {
317 if (origin == null) { 294 if (origin == null) {
318 reporter.reportErrorMessage( 295 reporter.reportErrorMessage(
319 patch, MessageKind.PATCH_NON_EXISTING, {'name': patch.name}); 296 patch, MessageKind.PATCH_NON_EXISTING, {'name': patch.name});
320 return; 297 return;
321 } 298 }
322 299
323 if (!(origin.isClass || 300 if (!(origin.isClass ||
324 origin.isConstructor || 301 origin.isConstructor ||
325 origin.isFunction || 302 origin.isFunction ||
326 origin.isAbstractField)) { 303 origin.isAbstractField)) {
327 // TODO(ahe): Remove this error when the parser rejects all bad modifiers. 304 // TODO(ahe): Remove this error when the parser rejects all bad modifiers.
328 reporter.reportErrorMessage(origin, MessageKind.PATCH_NONPATCHABLE); 305 reporter.reportErrorMessage(origin, MessageKind.PATCH_NONPATCHABLE);
329 return; 306 return;
330 } 307 }
331 if (patch.isClass) { 308 if (patch.isClass) {
332 tryPatchClass(compiler, reporter, origin, patch); 309 tryPatchClass(compiler, reporter, origin, patch);
333 } else if (patch.isGetter) { 310 } else if (patch.isGetter) {
334 tryPatchGetter(reporter, origin, patch); 311 tryPatchGetter(reporter, origin, patch);
335 } else if (patch.isSetter) { 312 } else if (patch.isSetter) {
336 tryPatchSetter(reporter, origin, patch); 313 tryPatchSetter(reporter, origin, patch);
337 } else if (patch.isConstructor) { 314 } else if (patch.isConstructor) {
338 tryPatchConstructor(reporter, origin, patch); 315 tryPatchConstructor(reporter, origin, patch);
339 } else if(patch.isFunction) { 316 } else if (patch.isFunction) {
340 tryPatchFunction(reporter, origin, patch); 317 tryPatchFunction(reporter, origin, patch);
341 } else { 318 } else {
342 // TODO(ahe): Remove this error when the parser rejects all bad modifiers. 319 // TODO(ahe): Remove this error when the parser rejects all bad modifiers.
343 reporter.reportErrorMessage(patch, MessageKind.PATCH_NONPATCHABLE); 320 reporter.reportErrorMessage(patch, MessageKind.PATCH_NONPATCHABLE);
344 } 321 }
345 } 322 }
346 323
347 void tryPatchClass(Compiler compiler, 324 void tryPatchClass(Compiler compiler, DiagnosticReporter reporter,
348 DiagnosticReporter reporter, 325 Element origin, ClassElement patch) {
349 Element origin,
350 ClassElement patch) {
351 if (!origin.isClass) { 326 if (!origin.isClass) {
352 reporter.reportError( 327 reporter.reportError(
353 reporter.createMessage( 328 reporter.createMessage(
354 origin, 329 origin, MessageKind.PATCH_NON_CLASS, {'className': patch.name}),
355 MessageKind.PATCH_NON_CLASS,
356 {'className': patch.name}),
357 <DiagnosticMessage>[ 330 <DiagnosticMessage>[
358 reporter.createMessage( 331 reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_CLASS,
359 patch, 332 {'className': patch.name}),
360 MessageKind.PATCH_POINT_TO_CLASS,
361 {'className': patch.name}),
362 ]); 333 ]);
363 return; 334 return;
364 } 335 }
365 patchClass(compiler, reporter, origin, patch); 336 patchClass(compiler, reporter, origin, patch);
366 } 337 }
367 338
368 void patchClass(Compiler compiler, 339 void patchClass(Compiler compiler, DiagnosticReporter reporter,
369 DiagnosticReporter reporter, 340 ClassElementX origin, ClassElementX patch) {
370 ClassElementX origin,
371 ClassElementX patch) {
372 if (origin.isPatched) { 341 if (origin.isPatched) {
373 reporter.internalError(origin, 342 reporter.internalError(origin, "Patching the same class more than once.");
374 "Patching the same class more than once.");
375 } 343 }
376 origin.applyPatch(patch); 344 origin.applyPatch(patch);
377 checkNativeAnnotation(compiler, patch); 345 checkNativeAnnotation(compiler, patch);
378 } 346 }
379 347
380 /// Check whether [cls] has a `@Native(...)` annotation, and if so, set its 348 /// Check whether [cls] has a `@Native(...)` annotation, and if so, set its
381 /// native name from the annotation. 349 /// native name from the annotation.
382 checkNativeAnnotation(Compiler compiler, ClassElement cls) { 350 checkNativeAnnotation(Compiler compiler, ClassElement cls) {
383 EagerAnnotationHandler.checkAnnotation(compiler, cls, 351 EagerAnnotationHandler.checkAnnotation(
384 const NativeAnnotationHandler()); 352 compiler, cls, const NativeAnnotationHandler());
385 } 353 }
386 354
387 checkJsInteropAnnotation(Compiler compiler, element) { 355 checkJsInteropAnnotation(Compiler compiler, element) {
388 EagerAnnotationHandler.checkAnnotation(compiler, element, 356 EagerAnnotationHandler.checkAnnotation(
389 const JsInteropAnnotationHandler()); 357 compiler, element, const JsInteropAnnotationHandler());
390 } 358 }
391 359
392
393 /// Abstract interface for pre-resolution detection of metadata. 360 /// Abstract interface for pre-resolution detection of metadata.
394 /// 361 ///
395 /// The detection is handled in two steps: 362 /// The detection is handled in two steps:
396 /// - match the annotation syntactically and assume that the annotation is valid 363 /// - match the annotation syntactically and assume that the annotation is valid
397 /// if it looks correct, 364 /// if it looks correct,
398 /// - setup a deferred action to check that the annotation has a valid constant 365 /// - setup a deferred action to check that the annotation has a valid constant
399 /// value and report an internal error if not. 366 /// value and report an internal error if not.
400 abstract class EagerAnnotationHandler<T> { 367 abstract class EagerAnnotationHandler<T> {
401 /// Checks that [annotation] looks like a matching annotation and optionally 368 /// Checks that [annotation] looks like a matching annotation and optionally
402 /// applies actions on [element]. Returns a non-null annotation marker if the 369 /// applies actions on [element]. Returns a non-null annotation marker if the
403 /// annotation matched and should be validated. 370 /// annotation matched and should be validated.
404 T apply(Compiler compiler, 371 T apply(Compiler compiler, Element element, MetadataAnnotation annotation);
405 Element element,
406 MetadataAnnotation annotation);
407 372
408 /// Checks that the annotation value is valid. 373 /// Checks that the annotation value is valid.
409 void validate(Compiler compiler, 374 void validate(Compiler compiler, Element element,
410 Element element, 375 MetadataAnnotation annotation, ConstantValue constant);
411 MetadataAnnotation annotation,
412 ConstantValue constant);
413
414 376
415 /// Checks [element] for metadata matching the [handler]. Return a non-null 377 /// Checks [element] for metadata matching the [handler]. Return a non-null
416 /// annotation marker matching metadata was found. 378 /// annotation marker matching metadata was found.
417 static checkAnnotation(Compiler compiler, 379 static checkAnnotation(
418 Element element, 380 Compiler compiler, Element element, EagerAnnotationHandler handler) {
419 EagerAnnotationHandler handler) {
420 for (MetadataAnnotation annotation in element.implementation.metadata) { 381 for (MetadataAnnotation annotation in element.implementation.metadata) {
421 var result = handler.apply(compiler, element, annotation); 382 var result = handler.apply(compiler, element, annotation);
422 if (result != null) { 383 if (result != null) {
423 // TODO(johnniwinther): Perform this check in 384 // TODO(johnniwinther): Perform this check in
424 // [Compiler.onLibrariesLoaded]. 385 // [Compiler.onLibrariesLoaded].
425 compiler.enqueuer.resolution.addDeferredAction(element, () { 386 compiler.enqueuer.resolution.addDeferredAction(element, () {
426 annotation.ensureResolved(compiler.resolution); 387 annotation.ensureResolved(compiler.resolution);
427 handler.validate( 388 handler.validate(compiler, element, annotation,
428 compiler, element, annotation,
429 compiler.constants.getConstantValue(annotation.constant)); 389 compiler.constants.getConstantValue(annotation.constant));
430 }); 390 });
431 return result; 391 return result;
432 } 392 }
433 } 393 }
434 return null; 394 return null;
435 } 395 }
436 } 396 }
437 397
438 /// Annotation handler for pre-resolution detection of `@Native(...)` 398 /// Annotation handler for pre-resolution detection of `@Native(...)`
439 /// annotations. 399 /// annotations.
440 class NativeAnnotationHandler implements EagerAnnotationHandler<String> { 400 class NativeAnnotationHandler implements EagerAnnotationHandler<String> {
441 const NativeAnnotationHandler(); 401 const NativeAnnotationHandler();
442 402
443 String getNativeAnnotation(MetadataAnnotation annotation) { 403 String getNativeAnnotation(MetadataAnnotation annotation) {
444 if (annotation.beginToken != null && 404 if (annotation.beginToken != null &&
445 annotation.beginToken.next.value == 'Native') { 405 annotation.beginToken.next.value == 'Native') {
446 // Skipping '@', 'Native', and '('. 406 // Skipping '@', 'Native', and '('.
447 Token argument = annotation.beginToken.next.next.next; 407 Token argument = annotation.beginToken.next.next.next;
448 if (argument is StringToken) { 408 if (argument is StringToken) {
449 return argument.value; 409 return argument.value;
450 } 410 }
451 } 411 }
452 return null; 412 return null;
453 } 413 }
454 414
455 String apply(Compiler compiler, 415 String apply(
456 Element element, 416 Compiler compiler, Element element, MetadataAnnotation annotation) {
457 MetadataAnnotation annotation) {
458 if (element.isClass) { 417 if (element.isClass) {
459 String native = getNativeAnnotation(annotation); 418 String native = getNativeAnnotation(annotation);
460 if (native != null) { 419 if (native != null) {
461 JavaScriptBackend backend = compiler.backend; 420 JavaScriptBackend backend = compiler.backend;
462 backend.nativeData.setNativeClassTagInfo(element, native); 421 backend.nativeData.setNativeClassTagInfo(element, native);
463 return native; 422 return native;
464 } 423 }
465 } 424 }
466 return null; 425 return null;
467 } 426 }
468 427
469 void validate(Compiler compiler, 428 void validate(Compiler compiler, Element element,
470 Element element, 429 MetadataAnnotation annotation, ConstantValue constant) {
471 MetadataAnnotation annotation,
472 ConstantValue constant) {
473 DartType annotationType = constant.getType(compiler.coreTypes); 430 DartType annotationType = constant.getType(compiler.coreTypes);
474 if (annotationType.element != compiler.nativeAnnotationClass) { 431 if (annotationType.element != compiler.nativeAnnotationClass) {
475 DiagnosticReporter reporter = compiler.reporter; 432 DiagnosticReporter reporter = compiler.reporter;
476 reporter.internalError(annotation, 'Invalid @Native(...) annotation.'); 433 reporter.internalError(annotation, 'Invalid @Native(...) annotation.');
477 } 434 }
478 } 435 }
479 } 436 }
480 437
481 /// Annotation handler for pre-resolution detection of `@JS(...)` 438 /// Annotation handler for pre-resolution detection of `@JS(...)`
482 /// annotations. 439 /// annotations.
483 class JsInteropAnnotationHandler implements EagerAnnotationHandler<bool> { 440 class JsInteropAnnotationHandler implements EagerAnnotationHandler<bool> {
484 const JsInteropAnnotationHandler(); 441 const JsInteropAnnotationHandler();
485 442
486 bool hasJsNameAnnotation(MetadataAnnotation annotation) => 443 bool hasJsNameAnnotation(MetadataAnnotation annotation) =>
487 annotation.beginToken != null && annotation.beginToken.next.value == 'JS'; 444 annotation.beginToken != null && annotation.beginToken.next.value == 'JS';
488 445
489 bool apply(Compiler compiler, 446 bool apply(
490 Element element, 447 Compiler compiler, Element element, MetadataAnnotation annotation) {
491 MetadataAnnotation annotation) {
492 bool hasJsInterop = hasJsNameAnnotation(annotation); 448 bool hasJsInterop = hasJsNameAnnotation(annotation);
493 if (hasJsInterop) { 449 if (hasJsInterop) {
494 JavaScriptBackend backend = compiler.backend; 450 JavaScriptBackend backend = compiler.backend;
495 backend.nativeData.markAsJsInterop(element); 451 backend.nativeData.markAsJsInterop(element);
496 } 452 }
497 // Due to semantics of apply in the baseclass we have to return null to 453 // Due to semantics of apply in the baseclass we have to return null to
498 // indicate that no match was found. 454 // indicate that no match was found.
499 return hasJsInterop ? true : null; 455 return hasJsInterop ? true : null;
500 } 456 }
501 457
502 @override 458 @override
503 void validate(Compiler compiler, 459 void validate(Compiler compiler, Element element,
504 Element element, 460 MetadataAnnotation annotation, ConstantValue constant) {
505 MetadataAnnotation annotation,
506 ConstantValue constant) {
507 JavaScriptBackend backend = compiler.backend; 461 JavaScriptBackend backend = compiler.backend;
508 if (constant.getType(compiler.coreTypes).element != 462 if (constant.getType(compiler.coreTypes).element !=
509 backend.helpers.jsAnnotationClass) { 463 backend.helpers.jsAnnotationClass) {
510 compiler.reporter.internalError(annotation, 'Invalid @JS(...) annotation.' ); 464 compiler.reporter
465 .internalError(annotation, 'Invalid @JS(...) annotation.');
511 } 466 }
512 } 467 }
513 } 468 }
514 469
515 /// Annotation handler for pre-resolution detection of `@patch` annotations. 470 /// Annotation handler for pre-resolution detection of `@patch` annotations.
516 class PatchAnnotationHandler implements EagerAnnotationHandler<PatchVersion> { 471 class PatchAnnotationHandler implements EagerAnnotationHandler<PatchVersion> {
517 const PatchAnnotationHandler(); 472 const PatchAnnotationHandler();
518 473
519 PatchVersion getPatchVersion(MetadataAnnotation annotation) { 474 PatchVersion getPatchVersion(MetadataAnnotation annotation) {
520 if (annotation.beginToken != null) { 475 if (annotation.beginToken != null) {
521 if (annotation.beginToken.next.value == 'patch') { 476 if (annotation.beginToken.next.value == 'patch') {
522 return const PatchVersion(null); 477 return const PatchVersion(null);
523 } else if (annotation.beginToken.next.value == 'patch_full') { 478 } else if (annotation.beginToken.next.value == 'patch_full') {
524 return const PatchVersion('full'); 479 return const PatchVersion('full');
525 } else if (annotation.beginToken.next.value == 'patch_lazy') { 480 } else if (annotation.beginToken.next.value == 'patch_lazy') {
526 return const PatchVersion('lazy'); 481 return const PatchVersion('lazy');
527 } else if (annotation.beginToken.next.value == 'patch_startup') { 482 } else if (annotation.beginToken.next.value == 'patch_startup') {
528 return const PatchVersion('startup'); 483 return const PatchVersion('startup');
529 } 484 }
530 } 485 }
531 return null; 486 return null;
532 } 487 }
533 488
534 @override 489 @override
535 PatchVersion apply(Compiler compiler, 490 PatchVersion apply(
536 Element element, 491 Compiler compiler, Element element, MetadataAnnotation annotation) {
537 MetadataAnnotation annotation) {
538 return getPatchVersion(annotation); 492 return getPatchVersion(annotation);
539 } 493 }
540 494
541 @override 495 @override
542 void validate(Compiler compiler, 496 void validate(Compiler compiler, Element element,
543 Element element, 497 MetadataAnnotation annotation, ConstantValue constant) {
544 MetadataAnnotation annotation,
545 ConstantValue constant) {
546 DartType annotationType = constant.getType(compiler.coreTypes); 498 DartType annotationType = constant.getType(compiler.coreTypes);
547 if (annotationType.element != compiler.patchAnnotationClass) { 499 if (annotationType.element != compiler.patchAnnotationClass) {
548 DiagnosticReporter reporter = compiler.reporter; 500 DiagnosticReporter reporter = compiler.reporter;
549 reporter.internalError(annotation, 'Invalid patch annotation.'); 501 reporter.internalError(annotation, 'Invalid patch annotation.');
550 } 502 }
551 } 503 }
552 } 504 }
553 505
554 506 void tryPatchGetter(
555 void tryPatchGetter(DiagnosticReporter reporter, 507 DiagnosticReporter reporter, Element origin, FunctionElement patch) {
556 Element origin,
557 FunctionElement patch) {
558 if (!origin.isAbstractField) { 508 if (!origin.isAbstractField) {
559 reporter.reportError( 509 reporter.reportError(
560 reporter.createMessage( 510 reporter.createMessage(
561 origin, 511 origin, MessageKind.PATCH_NON_GETTER, {'name': origin.name}),
562 MessageKind.PATCH_NON_GETTER,
563 {'name': origin.name}),
564 <DiagnosticMessage>[ 512 <DiagnosticMessage>[
565 reporter.createMessage( 513 reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_GETTER,
566 patch, 514 {'getterName': patch.name}),
567 MessageKind.PATCH_POINT_TO_GETTER,
568 {'getterName': patch.name}),
569 ]); 515 ]);
570 return; 516 return;
571 } 517 }
572 AbstractFieldElement originField = origin; 518 AbstractFieldElement originField = origin;
573 if (originField.getter == null) { 519 if (originField.getter == null) {
574 reporter.reportError( 520 reporter.reportError(
575 reporter.createMessage( 521 reporter.createMessage(
576 origin, 522 origin, MessageKind.PATCH_NO_GETTER, {'getterName': patch.name}),
577 MessageKind.PATCH_NO_GETTER,
578 {'getterName': patch.name}),
579 <DiagnosticMessage>[ 523 <DiagnosticMessage>[
580 reporter.createMessage( 524 reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_GETTER,
581 patch, 525 {'getterName': patch.name}),
582 MessageKind.PATCH_POINT_TO_GETTER,
583 {'getterName': patch.name}),
584 ]); 526 ]);
585 return; 527 return;
586 } 528 }
587 GetterElementX getter = originField.getter; 529 GetterElementX getter = originField.getter;
588 patchFunction(reporter, getter, patch); 530 patchFunction(reporter, getter, patch);
589 } 531 }
590 532
591 void tryPatchSetter(DiagnosticReporter reporter, 533 void tryPatchSetter(
592 Element origin, 534 DiagnosticReporter reporter, Element origin, FunctionElement patch) {
593 FunctionElement patch) {
594 if (!origin.isAbstractField) { 535 if (!origin.isAbstractField) {
595 reporter.reportError( 536 reporter.reportError(
596 reporter.createMessage( 537 reporter.createMessage(
597 origin, 538 origin, MessageKind.PATCH_NON_SETTER, {'name': origin.name}),
598 MessageKind.PATCH_NON_SETTER,
599 {'name': origin.name}),
600 <DiagnosticMessage>[ 539 <DiagnosticMessage>[
601 reporter.createMessage( 540 reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_SETTER,
602 patch, 541 {'setterName': patch.name}),
603 MessageKind.PATCH_POINT_TO_SETTER,
604 {'setterName': patch.name}),
605 ]); 542 ]);
606 return; 543 return;
607 } 544 }
608 AbstractFieldElement originField = origin; 545 AbstractFieldElement originField = origin;
609 if (originField.setter == null) { 546 if (originField.setter == null) {
610 reporter.reportError( 547 reporter.reportError(
611 reporter.createMessage( 548 reporter.createMessage(
612 origin, 549 origin, MessageKind.PATCH_NO_SETTER, {'setterName': patch.name}),
613 MessageKind.PATCH_NO_SETTER,
614 {'setterName': patch.name}),
615 <DiagnosticMessage>[ 550 <DiagnosticMessage>[
616 reporter.createMessage( 551 reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_SETTER,
617 patch, 552 {'setterName': patch.name}),
618 MessageKind.PATCH_POINT_TO_SETTER,
619 {'setterName': patch.name}),
620 ]); 553 ]);
621 return; 554 return;
622 } 555 }
623 SetterElementX setter = originField.setter; 556 SetterElementX setter = originField.setter;
624 patchFunction(reporter, setter, patch); 557 patchFunction(reporter, setter, patch);
625 } 558 }
626 559
627 void tryPatchConstructor(DiagnosticReporter reporter, 560 void tryPatchConstructor(
628 Element origin, 561 DiagnosticReporter reporter, Element origin, FunctionElement patch) {
629 FunctionElement patch) {
630 if (!origin.isConstructor) { 562 if (!origin.isConstructor) {
631 reporter.reportError( 563 reporter.reportError(
632 reporter.createMessage( 564 reporter.createMessage(origin, MessageKind.PATCH_NON_CONSTRUCTOR,
633 origin,
634 MessageKind.PATCH_NON_CONSTRUCTOR,
635 {'constructorName': patch.name}), 565 {'constructorName': patch.name}),
636 <DiagnosticMessage>[ 566 <DiagnosticMessage>[
637 reporter.createMessage( 567 reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_CONSTRUCTOR,
638 patch, 568 {'constructorName': patch.name}),
639 MessageKind.PATCH_POINT_TO_CONSTRUCTOR,
640 {'constructorName': patch.name}),
641 ]); 569 ]);
642 return; 570 return;
643 } 571 }
644 patchFunction(reporter, origin, patch); 572 patchFunction(reporter, origin, patch);
645 } 573 }
646 574
647 void tryPatchFunction(DiagnosticReporter reporter, 575 void tryPatchFunction(
648 Element origin, 576 DiagnosticReporter reporter, Element origin, FunctionElement patch) {
649 FunctionElement patch) {
650 if (!origin.isFunction) { 577 if (!origin.isFunction) {
651 reporter.reportError( 578 reporter.reportError(
652 reporter.createMessage( 579 reporter.createMessage(origin, MessageKind.PATCH_NON_FUNCTION,
653 origin,
654 MessageKind.PATCH_NON_FUNCTION,
655 {'functionName': patch.name}), 580 {'functionName': patch.name}),
656 <DiagnosticMessage>[ 581 <DiagnosticMessage>[
657 reporter.createMessage( 582 reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_FUNCTION,
658 patch, 583 {'functionName': patch.name}),
659 MessageKind.PATCH_POINT_TO_FUNCTION,
660 {'functionName': patch.name}),
661 ]); 584 ]);
662 return; 585 return;
663 } 586 }
664 patchFunction(reporter, origin, patch); 587 patchFunction(reporter, origin, patch);
665 } 588 }
666 589
667 void patchFunction(DiagnosticReporter reporter, 590 void patchFunction(DiagnosticReporter reporter, BaseFunctionElementX origin,
668 BaseFunctionElementX origin, 591 BaseFunctionElementX patch) {
669 BaseFunctionElementX patch) {
670 if (!origin.modifiers.isExternal) { 592 if (!origin.modifiers.isExternal) {
671 reporter.reportError( 593 reporter.reportError(
672 reporter.createMessage(origin, MessageKind.PATCH_NON_EXTERNAL), 594 reporter.createMessage(origin, MessageKind.PATCH_NON_EXTERNAL),
673 <DiagnosticMessage>[ 595 <DiagnosticMessage>[
674 reporter.createMessage( 596 reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_FUNCTION,
675 patch, 597 {'functionName': patch.name}),
676 MessageKind.PATCH_POINT_TO_FUNCTION,
677 {'functionName': patch.name}),
678 ]); 598 ]);
679 return; 599 return;
680 } 600 }
681 if (origin.isPatched) { 601 if (origin.isPatched) {
682 reporter.internalError(origin, 602 reporter.internalError(
683 "Trying to patch a function more than once."); 603 origin, "Trying to patch a function more than once.");
684 } 604 }
685 origin.applyPatch(patch); 605 origin.applyPatch(patch);
686 } 606 }
687 607
688 PatchVersion getPatchVersion(Compiler compiler, Element element) { 608 PatchVersion getPatchVersion(Compiler compiler, Element element) {
689 return EagerAnnotationHandler.checkAnnotation(compiler, element, 609 return EagerAnnotationHandler.checkAnnotation(
690 const PatchAnnotationHandler()); 610 compiler, element, const PatchAnnotationHandler());
691 } 611 }
692 612
693 class PatchVersion { 613 class PatchVersion {
694 final String tag; 614 final String tag;
695 615
696 const PatchVersion(this.tag); 616 const PatchVersion(this.tag);
697 617
698 bool isActive(String patchTag) => tag == null || tag == patchTag; 618 bool isActive(String patchTag) => tag == null || tag == patchTag;
699 619
700 String toString() => 'PatchVersion($tag)'; 620 String toString() => 'PatchVersion($tag)';
701 } 621 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/parser/partial_parser.dart ('k') | pkg/compiler/lib/src/platform_configuration.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698