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

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: about to land 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 'dart_types.dart' show 126 import 'dart_types.dart' show
127 DartType; 127 DartType;
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 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 299
298 void patchElement(Compiler compiler, 300 void patchElement(Compiler compiler,
299 DiagnosticReporter reporter, 301 DiagnosticReporter reporter,
300 Element origin, 302 Element origin,
301 Element patch) { 303 Element patch) {
302 if (origin == null) { 304 if (origin == null) {
303 reporter.reportErrorMessage( 305 reporter.reportErrorMessage(
304 patch, MessageKind.PATCH_NON_EXISTING, {'name': patch.name}); 306 patch, MessageKind.PATCH_NON_EXISTING, {'name': patch.name});
305 return; 307 return;
306 } 308 }
309
307 if (!(origin.isClass || 310 if (!(origin.isClass ||
308 origin.isConstructor || 311 origin.isConstructor ||
309 origin.isFunction || 312 origin.isFunction ||
310 origin.isAbstractField)) { 313 origin.isAbstractField)) {
311 // TODO(ahe): Remove this error when the parser rejects all bad modifiers. 314 // TODO(ahe): Remove this error when the parser rejects all bad modifiers.
312 reporter.reportErrorMessage(origin, MessageKind.PATCH_NONPATCHABLE); 315 reporter.reportErrorMessage(origin, MessageKind.PATCH_NONPATCHABLE);
313 return; 316 return;
314 } 317 }
315 if (patch.isClass) { 318 if (patch.isClass) {
316 tryPatchClass(compiler, reporter, origin, patch); 319 tryPatchClass(compiler, reporter, origin, patch);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 checkNativeAnnotation(compiler, patch); 364 checkNativeAnnotation(compiler, patch);
362 } 365 }
363 366
364 /// Check whether [cls] has a `@Native(...)` annotation, and if so, set its 367 /// Check whether [cls] has a `@Native(...)` annotation, and if so, set its
365 /// native name from the annotation. 368 /// native name from the annotation.
366 checkNativeAnnotation(Compiler compiler, ClassElement cls) { 369 checkNativeAnnotation(Compiler compiler, ClassElement cls) {
367 EagerAnnotationHandler.checkAnnotation(compiler, cls, 370 EagerAnnotationHandler.checkAnnotation(compiler, cls,
368 const NativeAnnotationHandler()); 371 const NativeAnnotationHandler());
369 } 372 }
370 373
374 checkJsInteropAnnotation(Compiler compiler, element) {
375 EagerAnnotationHandler.checkAnnotation(compiler, element,
376 const JsInteropAnnotationHandler());
377 }
378
379
371 /// Abstract interface for pre-resolution detection of metadata. 380 /// Abstract interface for pre-resolution detection of metadata.
372 /// 381 ///
373 /// The detection is handled in two steps: 382 /// The detection is handled in two steps:
374 /// - match the annotation syntactically and assume that the annotation is valid 383 /// - match the annotation syntactically and assume that the annotation is valid
375 /// if it looks correct, 384 /// if it looks correct,
376 /// - setup a deferred action to check that the annotation has a valid constant 385 /// - setup a deferred action to check that the annotation has a valid constant
377 /// value and report an internal error if not. 386 /// value and report an internal error if not.
378 abstract class EagerAnnotationHandler<T> { 387 abstract class EagerAnnotationHandler<T> {
379 /// Checks that [annotation] looks like a matching annotation and optionally 388 /// Checks that [annotation] looks like a matching annotation and optionally
380 /// applies actions on [element]. Returns a non-null annotation marker if the 389 /// applies actions on [element]. Returns a non-null annotation marker if the
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 MetadataAnnotation annotation, 458 MetadataAnnotation annotation,
450 ConstantValue constant) { 459 ConstantValue constant) {
451 DartType annotationType = constant.getType(compiler.coreTypes); 460 DartType annotationType = constant.getType(compiler.coreTypes);
452 if (annotationType.element != compiler.nativeAnnotationClass) { 461 if (annotationType.element != compiler.nativeAnnotationClass) {
453 DiagnosticReporter reporter = compiler.reporter; 462 DiagnosticReporter reporter = compiler.reporter;
454 reporter.internalError(annotation, 'Invalid @Native(...) annotation.'); 463 reporter.internalError(annotation, 'Invalid @Native(...) annotation.');
455 } 464 }
456 } 465 }
457 } 466 }
458 467
468 /// Annotation handler for pre-resolution detection of `@Js(...)`
469 /// annotations.
470 class JsInteropAnnotationHandler implements EagerAnnotationHandler<bool> {
471 const JsInteropAnnotationHandler();
472
473 bool hasJsNameAnnotation(MetadataAnnotation annotation) =>
474 annotation.beginToken != null && annotation.beginToken.next.value == 'Js';
475
476 bool apply(Compiler compiler,
477 Element element,
478 MetadataAnnotation annotation) {
479 bool hasJsInterop = hasJsNameAnnotation(annotation);
480 if (hasJsInterop) {
481 element.markAsJsInterop();
482 }
483 // Due to semantics of apply in the baseclass we have to return null to
484 // indicate that no match was found.
485 return hasJsInterop ? true : null;
486 }
487
488 @override
489 void validate(Compiler compiler,
490 Element element,
491 MetadataAnnotation annotation,
492 ConstantValue constant) {
493 JavaScriptBackend backend = compiler.backend;
494 if (constant.getType(compiler.coreTypes).element !=
495 backend.jsAnnotationClass) {
496 compiler.reporter.internalError(annotation, 'Invalid @Js(...) annotation.' );
497 }
498 }
499 }
500
459 /// Annotation handler for pre-resolution detection of `@patch` annotations. 501 /// Annotation handler for pre-resolution detection of `@patch` annotations.
460 class PatchAnnotationHandler implements EagerAnnotationHandler<PatchVersion> { 502 class PatchAnnotationHandler implements EagerAnnotationHandler<PatchVersion> {
461 const PatchAnnotationHandler(); 503 const PatchAnnotationHandler();
462 504
463 PatchVersion getPatchVersion(MetadataAnnotation annotation) { 505 PatchVersion getPatchVersion(MetadataAnnotation annotation) {
464 if (annotation.beginToken != null) { 506 if (annotation.beginToken != null) {
465 if (annotation.beginToken.next.value == 'patch') { 507 if (annotation.beginToken.next.value == 'patch') {
466 return const PatchVersion(null); 508 return const PatchVersion(null);
467 } else if (annotation.beginToken.next.value == 'patch_full') { 509 } else if (annotation.beginToken.next.value == 'patch_full') {
468 return const PatchVersion('full'); 510 return const PatchVersion('full');
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 678
637 class PatchVersion { 679 class PatchVersion {
638 final String tag; 680 final String tag;
639 681
640 const PatchVersion(this.tag); 682 const PatchVersion(this.tag);
641 683
642 bool isActive(String patchTag) => tag == null || tag == patchTag; 684 bool isActive(String patchTag) => tag == null || tag == patchTag;
643 685
644 String toString() => 'PatchVersion($tag)'; 686 String toString() => 'PatchVersion($tag)';
645 } 687 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/native/enqueue.dart ('k') | pkg/compiler/lib/src/serialization/modelz.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698