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

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: Created 5 years, 3 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 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 343
344 void patchClass(Compiler compiler, 344 void patchClass(Compiler compiler,
345 ClassElementX origin, 345 ClassElementX origin,
346 ClassElementX patch) { 346 ClassElementX patch) {
347 if (origin.isPatched) { 347 if (origin.isPatched) {
348 compiler.internalError(origin, 348 compiler.internalError(origin,
349 "Patching the same class more than once."); 349 "Patching the same class more than once.");
350 } 350 }
351 origin.applyPatch(patch); 351 origin.applyPatch(patch);
352 checkNativeAnnotation(compiler, patch); 352 checkNativeAnnotation(compiler, patch);
353 checkJsInteropAnnotation(compiler, patch);
353 } 354 }
354 355
355 /// Check whether [cls] has a `@Native(...)` annotation, and if so, set its 356 /// Check whether [cls] has a `@Native(...)` annotation, and if so, set its
356 /// native name from the annotation. 357 /// native name from the annotation.
357 checkNativeAnnotation(Compiler compiler, ClassElement cls) { 358 checkNativeAnnotation(Compiler compiler, ClassElement cls) {
358 EagerAnnotationHandler.checkAnnotation(compiler, cls, 359 EagerAnnotationHandler.checkAnnotation(compiler, cls,
359 const NativeAnnotationHandler()); 360 const NativeAnnotationHandler());
360 } 361 }
361 362
363 checkJsInteropAnnotation(Compiler compiler, ClassElement cls) {
364 EagerAnnotationHandler.checkAnnotation(compiler, cls,
365 const JsInteropAnnotationHandler());
366 }
367
368
362 /// Abstract interface for pre-resolution detection of metadata. 369 /// Abstract interface for pre-resolution detection of metadata.
363 /// 370 ///
364 /// The detection is handled in two steps: 371 /// The detection is handled in two steps:
365 /// - match the annotation syntactically and assume that the annotation is valid 372 /// - match the annotation syntactically and assume that the annotation is valid
366 /// if it looks correct, 373 /// if it looks correct,
367 /// - setup a deferred action to check that the annotation has a valid constant 374 /// - setup a deferred action to check that the annotation has a valid constant
368 /// value and report an internal error if not. 375 /// value and report an internal error if not.
369 abstract class EagerAnnotationHandler<T> { 376 abstract class EagerAnnotationHandler<T> {
370 /// Checks that [annotation] looks like a matching annotation and optionally 377 /// Checks that [annotation] looks like a matching annotation and optionally
371 /// applies actions on [element]. Returns a non-null annotation marker if the 378 /// applies actions on [element]. Returns a non-null annotation marker if the
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 Element element, 449 Element element,
443 MetadataAnnotation annotation, 450 MetadataAnnotation annotation,
444 ConstantValue constant) { 451 ConstantValue constant) {
445 if (constant.getType(compiler.coreTypes).element != 452 if (constant.getType(compiler.coreTypes).element !=
446 compiler.nativeAnnotationClass) { 453 compiler.nativeAnnotationClass) {
447 compiler.internalError(annotation, 'Invalid @Native(...) annotation.'); 454 compiler.internalError(annotation, 'Invalid @Native(...) annotation.');
448 } 455 }
449 } 456 }
450 } 457 }
451 458
459 /// Annotation handler for pre-resolution detection of `@JsName(...)`
460 /// annotations.
461 class JsInteropAnnotationHandler implements EagerAnnotationHandler<String> {
462 const JsInteropAnnotationHandler();
463
464 String getJsNameAnnotation(MetadataAnnotation annotation) {
465 if (annotation.beginToken != null &&
466 annotation.beginToken.next.value == 'JsName') {
467 // Skipping '@', 'JsName', and '('.
468 Token argument = annotation.beginToken.next.next.next;
469 return (argument is StringToken) ? argument.value : '';
470 }
471
472 return null;
473 }
474
475 String apply(Compiler compiler,
476 Element element,
477 MetadataAnnotation annotation) {
478 if (element.isClass) {
479 String jsName = getJsNameAnnotation(annotation);
480 if (jsName != null) {
481 ClassElementX declaration = element.declaration;
482 // We do not track the class names for JsName annotations as we are not
483 // concerned about checked mode errors these classes.
484 declaration.isJsInterop = true;
485 return jsName;
486 }
487 }
488 return null;
489 }
490
491 @override
492 void validate(Compiler compiler,
493 Element element,
494 MetadataAnnotation annotation,
495 ConstantValue constant) {
496 }
497 }
498
452 /// Annotation handler for pre-resolution detection of `@patch` annotations. 499 /// Annotation handler for pre-resolution detection of `@patch` annotations.
453 class PatchAnnotationHandler implements EagerAnnotationHandler<PatchVersion> { 500 class PatchAnnotationHandler implements EagerAnnotationHandler<PatchVersion> {
454 const PatchAnnotationHandler(); 501 const PatchAnnotationHandler();
455 502
456 PatchVersion getPatchVersion(MetadataAnnotation annotation) { 503 PatchVersion getPatchVersion(MetadataAnnotation annotation) {
457 if (annotation.beginToken != null) { 504 if (annotation.beginToken != null) {
458 if (annotation.beginToken.next.value == 'patch') { 505 if (annotation.beginToken.next.value == 'patch') {
459 return const PatchVersion(null); 506 return const PatchVersion(null);
460 } else if (annotation.beginToken.next.value == 'patch_full') { 507 } else if (annotation.beginToken.next.value == 'patch_full') {
461 return const PatchVersion('full'); 508 return const PatchVersion('full');
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 638
592 class PatchVersion { 639 class PatchVersion {
593 final String tag; 640 final String tag;
594 641
595 const PatchVersion(this.tag); 642 const PatchVersion(this.tag);
596 643
597 bool isActive(String patchTag) => tag == null || tag == patchTag; 644 bool isActive(String patchTag) => tag == null || tag == patchTag;
598 645
599 String toString() => 'PatchVersion($tag)'; 646 String toString() => 'PatchVersion($tag)';
600 } 647 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698