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

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

Issue 1318043005: Support user generated custom native JS classes. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: ptal Created 5 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
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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 import 'diagnostics/messages.dart' show 126 import 'diagnostics/messages.dart' show
127 MessageKind; 127 MessageKind;
128 import 'elements/elements.dart'; 128 import 'elements/elements.dart';
129 import 'elements/modelx.dart' show 129 import 'elements/modelx.dart' show
130 BaseFunctionElementX, 130 BaseFunctionElementX,
131 ClassElementX, 131 ClassElementX,
132 GetterElementX, 132 GetterElementX,
133 LibraryElementX, 133 LibraryElementX,
134 MetadataAnnotationX, 134 MetadataAnnotationX,
135 SetterElementX; 135 SetterElementX;
136 import 'js_backend/js_backend.dart' show
137 JavaScriptBackend;
136 import 'library_loader.dart' show 138 import 'library_loader.dart' show
137 LibraryLoader; 139 LibraryLoader;
138 import 'parser/listener.dart' show 140 import 'parser/listener.dart' show
139 Listener, 141 Listener,
140 ParserError; 142 ParserError;
141 import 'parser/element_listener.dart' show 143 import 'parser/element_listener.dart' show
142 ElementListener; 144 ElementListener;
143 import 'parser/member_listener.dart' show 145 import 'parser/member_listener.dart' show
144 MemberListener; 146 MemberListener;
145 import 'parser/partial_elements.dart' show 147 import 'parser/partial_elements.dart' show
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 } 298 }
297 299
298 void patchElement(Compiler compiler, 300 void patchElement(Compiler compiler,
299 Element origin, 301 Element origin,
300 Element patch) { 302 Element patch) {
301 if (origin == null) { 303 if (origin == null) {
302 compiler.reportErrorMessage( 304 compiler.reportErrorMessage(
303 patch, MessageKind.PATCH_NON_EXISTING, {'name': patch.name}); 305 patch, MessageKind.PATCH_NON_EXISTING, {'name': patch.name});
304 return; 306 return;
305 } 307 }
308
306 if (!(origin.isClass || 309 if (!(origin.isClass ||
307 origin.isConstructor || 310 origin.isConstructor ||
308 origin.isFunction || 311 origin.isFunction ||
309 origin.isAbstractField)) { 312 origin.isAbstractField)) {
310 // TODO(ahe): Remove this error when the parser rejects all bad modifiers. 313 // TODO(ahe): Remove this error when the parser rejects all bad modifiers.
311 compiler.reportErrorMessage(origin, MessageKind.PATCH_NONPATCHABLE); 314 compiler.reportErrorMessage(origin, MessageKind.PATCH_NONPATCHABLE);
312 return; 315 return;
313 } 316 }
314 if (patch.isClass) { 317 if (patch.isClass) {
315 tryPatchClass(compiler, origin, patch); 318 tryPatchClass(compiler, origin, patch);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 checkNativeAnnotation(compiler, patch); 361 checkNativeAnnotation(compiler, patch);
359 } 362 }
360 363
361 /// Check whether [cls] has a `@Native(...)` annotation, and if so, set its 364 /// Check whether [cls] has a `@Native(...)` annotation, and if so, set its
362 /// native name from the annotation. 365 /// native name from the annotation.
363 checkNativeAnnotation(Compiler compiler, ClassElement cls) { 366 checkNativeAnnotation(Compiler compiler, ClassElement cls) {
364 EagerAnnotationHandler.checkAnnotation(compiler, cls, 367 EagerAnnotationHandler.checkAnnotation(compiler, cls,
365 const NativeAnnotationHandler()); 368 const NativeAnnotationHandler());
366 } 369 }
367 370
371 checkJsInteropAnnotation(Compiler compiler, element) {
372 EagerAnnotationHandler.checkAnnotation(compiler, element,
373 const JsInteropAnnotationHandler());
374 }
375
376
368 /// Abstract interface for pre-resolution detection of metadata. 377 /// Abstract interface for pre-resolution detection of metadata.
369 /// 378 ///
370 /// The detection is handled in two steps: 379 /// The detection is handled in two steps:
371 /// - match the annotation syntactically and assume that the annotation is valid 380 /// - match the annotation syntactically and assume that the annotation is valid
372 /// if it looks correct, 381 /// if it looks correct,
373 /// - setup a deferred action to check that the annotation has a valid constant 382 /// - setup a deferred action to check that the annotation has a valid constant
374 /// value and report an internal error if not. 383 /// value and report an internal error if not.
375 abstract class EagerAnnotationHandler<T> { 384 abstract class EagerAnnotationHandler<T> {
376 /// Checks that [annotation] looks like a matching annotation and optionally 385 /// Checks that [annotation] looks like a matching annotation and optionally
377 /// applies actions on [element]. Returns a non-null annotation marker if the 386 /// applies actions on [element]. Returns a non-null annotation marker if the
(...skipping 12 matching lines...) Expand all
390 /// Checks [element] for metadata matching the [handler]. Return a non-null 399 /// Checks [element] for metadata matching the [handler]. Return a non-null
391 /// annotation marker matching metadata was found. 400 /// annotation marker matching metadata was found.
392 static checkAnnotation(Compiler compiler, 401 static checkAnnotation(Compiler compiler,
393 Element element, 402 Element element,
394 EagerAnnotationHandler handler) { 403 EagerAnnotationHandler handler) {
395 for (MetadataAnnotation annotation in element.implementation.metadata) { 404 for (MetadataAnnotation annotation in element.implementation.metadata) {
396 var result = handler.apply(compiler, element, annotation); 405 var result = handler.apply(compiler, element, annotation);
397 if (result != null) { 406 if (result != null) {
398 // TODO(johnniwinther): Perform this check in 407 // TODO(johnniwinther): Perform this check in
399 // [Compiler.onLibrariesLoaded]. 408 // [Compiler.onLibrariesLoaded].
400 compiler.enqueuer.resolution.addDeferredAction(element, () { 409 // TODO(jacobr): annotation resolution needs to be refactored.
410 actionCallback() {
401 annotation.ensureResolved(compiler.resolution); 411 annotation.ensureResolved(compiler.resolution);
402 handler.validate( 412 handler.validate(
403 compiler, element, annotation, 413 compiler, element, annotation,
404 compiler.constants.getConstantValue(annotation.constant)); 414 compiler.constants.getConstantValue(annotation.constant));
405 }); 415 }
416 if (compiler.enqueuer.resolution.queueIsClosed) {
417 actionCallback();
Siggi Cherem (dart-lang) 2015/10/06 22:38:02 I was hoping that now that you moved the logic to
Jacob 2015/10/13 01:19:24 me too.. reverted.
418 } else {
419 compiler.enqueuer.resolution.addDeferredAction(element,
420 actionCallback);
421 }
406 return result; 422 return result;
407 } 423 }
408 } 424 }
409 return null; 425 return null;
410 } 426 }
411 } 427 }
412 428
413 /// Annotation handler for pre-resolution detection of `@Native(...)` 429 /// Annotation handler for pre-resolution detection of `@Native(...)`
414 /// annotations. 430 /// annotations.
415 class NativeAnnotationHandler implements EagerAnnotationHandler<String> { 431 class NativeAnnotationHandler implements EagerAnnotationHandler<String> {
(...skipping 29 matching lines...) Expand all
445 Element element, 461 Element element,
446 MetadataAnnotation annotation, 462 MetadataAnnotation annotation,
447 ConstantValue constant) { 463 ConstantValue constant) {
448 if (constant.getType(compiler.coreTypes).element != 464 if (constant.getType(compiler.coreTypes).element !=
449 compiler.nativeAnnotationClass) { 465 compiler.nativeAnnotationClass) {
450 compiler.internalError(annotation, 'Invalid @Native(...) annotation.'); 466 compiler.internalError(annotation, 'Invalid @Native(...) annotation.');
451 } 467 }
452 } 468 }
453 } 469 }
454 470
471 /// Annotation handler for pre-resolution detection of `@Js(...)`
472 /// annotations.
473 class JsInteropAnnotationHandler implements EagerAnnotationHandler<bool> {
474 const JsInteropAnnotationHandler();
475
476 bool hasJsNameAnnotation(MetadataAnnotation annotation) =>
477 annotation.beginToken != null && annotation.beginToken.next.value == 'Js';
478
479 bool apply(Compiler compiler,
480 Element element,
481 MetadataAnnotation annotation) {
482 bool hasJsInterop = hasJsNameAnnotation(annotation);
483 if (hasJsInterop) {
484 element.setHasJsInterop();
485 }
486 return hasJsInterop == true ? true : null;
Siggi Cherem (dart-lang) 2015/10/06 22:38:02 might be worth a tiny comment on why not return fa
Jacob 2015/10/13 01:19:24 Done.
487 }
488
489 @override
490 void validate(Compiler compiler,
491 Element element,
492 MetadataAnnotation annotation,
493 ConstantValue constant) {
494 JavaScriptBackend backend = compiler.backend;
495 if (constant.getType(compiler.coreTypes).element !=
496 backend.jsAnnotationClass) {
497 compiler.internalError(annotation, 'Invalid @Js(...) annotation.');
498 }
499 }
500 }
501
455 /// Annotation handler for pre-resolution detection of `@patch` annotations. 502 /// Annotation handler for pre-resolution detection of `@patch` annotations.
456 class PatchAnnotationHandler implements EagerAnnotationHandler<PatchVersion> { 503 class PatchAnnotationHandler implements EagerAnnotationHandler<PatchVersion> {
457 const PatchAnnotationHandler(); 504 const PatchAnnotationHandler();
458 505
459 PatchVersion getPatchVersion(MetadataAnnotation annotation) { 506 PatchVersion getPatchVersion(MetadataAnnotation annotation) {
460 if (annotation.beginToken != null) { 507 if (annotation.beginToken != null) {
461 if (annotation.beginToken.next.value == 'patch') { 508 if (annotation.beginToken.next.value == 'patch') {
462 return const PatchVersion(null); 509 return const PatchVersion(null);
463 } else if (annotation.beginToken.next.value == 'patch_full') { 510 } else if (annotation.beginToken.next.value == 'patch_full') {
464 return const PatchVersion('full'); 511 return const PatchVersion('full');
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 678
632 class PatchVersion { 679 class PatchVersion {
633 final String tag; 680 final String tag;
634 681
635 const PatchVersion(this.tag); 682 const PatchVersion(this.tag);
636 683
637 bool isActive(String patchTag) => tag == null || tag == patchTag; 684 bool isActive(String patchTag) => tag == null || tag == patchTag;
638 685
639 String toString() => 'PatchVersion($tag)'; 686 String toString() => 'PatchVersion($tag)';
640 } 687 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698