| Index: pkg/compiler/lib/src/patch_parser.dart
 | 
| diff --git a/pkg/compiler/lib/src/patch_parser.dart b/pkg/compiler/lib/src/patch_parser.dart
 | 
| index 8d75b67cecd0f1a2c17f3fd855fc65821bfc8681..a0ad4d9ac86df1a1e776aeab7a5e686453652e5d 100644
 | 
| --- a/pkg/compiler/lib/src/patch_parser.dart
 | 
| +++ b/pkg/compiler/lib/src/patch_parser.dart
 | 
| @@ -133,6 +133,8 @@ import 'elements/modelx.dart' show
 | 
|      LibraryElementX,
 | 
|      MetadataAnnotationX,
 | 
|      SetterElementX;
 | 
| +import 'js_backend/js_backend.dart' show
 | 
| +    JavaScriptBackend;
 | 
|  import 'library_loader.dart' show
 | 
|      LibraryLoader;
 | 
|  import 'parser/listener.dart' show
 | 
| @@ -304,6 +306,7 @@ void patchElement(Compiler compiler,
 | 
|          patch, MessageKind.PATCH_NON_EXISTING, {'name': patch.name});
 | 
|      return;
 | 
|    }
 | 
| +
 | 
|    if (!(origin.isClass ||
 | 
|          origin.isConstructor ||
 | 
|          origin.isFunction ||
 | 
| @@ -368,6 +371,12 @@ checkNativeAnnotation(Compiler compiler, ClassElement cls) {
 | 
|        const NativeAnnotationHandler());
 | 
|  }
 | 
|  
 | 
| +checkJsInteropAnnotation(Compiler compiler, element) {
 | 
| +  EagerAnnotationHandler.checkAnnotation(compiler, element,
 | 
| +      const JsInteropAnnotationHandler());
 | 
| +}
 | 
| +
 | 
| +
 | 
|  /// Abstract interface for pre-resolution detection of metadata.
 | 
|  ///
 | 
|  /// The detection is handled in two steps:
 | 
| @@ -456,6 +465,39 @@ class NativeAnnotationHandler implements EagerAnnotationHandler<String> {
 | 
|    }
 | 
|  }
 | 
|  
 | 
| +/// Annotation handler for pre-resolution detection of `@Js(...)`
 | 
| +/// annotations.
 | 
| +class JsInteropAnnotationHandler implements EagerAnnotationHandler<bool> {
 | 
| +  const JsInteropAnnotationHandler();
 | 
| +
 | 
| +  bool hasJsNameAnnotation(MetadataAnnotation annotation) =>
 | 
| +      annotation.beginToken != null && annotation.beginToken.next.value == 'Js';
 | 
| +
 | 
| +  bool apply(Compiler compiler,
 | 
| +             Element element,
 | 
| +             MetadataAnnotation annotation) {
 | 
| +    bool hasJsInterop = hasJsNameAnnotation(annotation);
 | 
| +    if (hasJsInterop) {
 | 
| +      element.markAsJsInterop();
 | 
| +    }
 | 
| +    // Due to semantics of apply in the baseclass we have to return null to
 | 
| +    // indicate that no match was found.
 | 
| +    return hasJsInterop ? true : null;
 | 
| +  }
 | 
| +
 | 
| +  @override
 | 
| +  void validate(Compiler compiler,
 | 
| +                Element element,
 | 
| +                MetadataAnnotation annotation,
 | 
| +                ConstantValue constant) {
 | 
| +    JavaScriptBackend backend = compiler.backend;
 | 
| +    if (constant.getType(compiler.coreTypes).element !=
 | 
| +        backend.jsAnnotationClass) {
 | 
| +      compiler.reporter.internalError(annotation, 'Invalid @Js(...) annotation.');
 | 
| +    }
 | 
| +  }
 | 
| +}
 | 
| +
 | 
|  /// Annotation handler for pre-resolution detection of `@patch` annotations.
 | 
|  class PatchAnnotationHandler implements EagerAnnotationHandler<PatchVersion> {
 | 
|    const PatchAnnotationHandler();
 | 
| 
 |