| 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 0e9943d481191eeeb7a5cc77eb2b7f33ce03a6fe..7c0f1055ab101a2ba053813542999bd49247dff8 100644
|
| --- a/pkg/compiler/lib/src/patch_parser.dart
|
| +++ b/pkg/compiler/lib/src/patch_parser.dart
|
| @@ -142,7 +142,50 @@ import 'parser/partial_parser.dart' show PartialParser;
|
| import 'parser/parser.dart' show Parser;
|
| import 'scanner/scanner.dart' show Scanner;
|
| import 'script.dart';
|
| -import 'tokens/token.dart' show StringToken, Token;
|
| +import 'tokens/token.dart' show SymbolToken, StringToken, Token;
|
| +
|
| +import 'tokens/token_constants.dart' show EOF_TOKEN;
|
| +
|
| +import 'tokens/precedence_constants.dart' show AT_INFO;
|
| +
|
| +class PartialPatchParser extends PartialParser {
|
| + PartialPatchParser(Listener listener, ParserOptions options)
|
| + : super(listener, options);
|
| +
|
| + Token parseMetadataStar(Token token, {bool forParameter: false}) {
|
| + listener.beginMetadataStar(token);
|
| + int count = 0;
|
| + while (token.kind != EOF_TOKEN) {
|
| + if (optional('@', token)) {
|
| + token = parseMetadata(token);
|
| + count++;
|
| + } else if (optional('patch', token)) {
|
| + token = parsePatchKeyword(token);
|
| + } else {
|
| + break;
|
| + }
|
| + }
|
| + listener.endMetadataStar(count, forParameter);
|
| + return token;
|
| + }
|
| +
|
| + Token parsePatchKeyword(Token token) {
|
| + listener.beginMetadata(token);
|
| + Token start = new SymbolToken(AT_INFO, token.charOffset)..next = token;
|
| + assert(optional('patch', token));
|
| + token = parseIdentifier(token);
|
| + token = parseQualifiedRestOpt(token);
|
| + token = parseTypeArgumentsOpt(token);
|
| + Token period = null;
|
| + if (optional('.', token)) {
|
| + period = token;
|
| + token = parseIdentifier(token.next);
|
| + }
|
| + token = parseArgumentsOpt(token);
|
| + listener.endMetadata(start, period, token);
|
| + return token;
|
| + }
|
| +}
|
|
|
| class PatchParserTask extends CompilerTask {
|
| final String name = "Patching Parser";
|
| @@ -167,7 +210,7 @@ class PatchParserTask extends CompilerTask {
|
| // Patch elements are stored on the patched functions or classes.
|
| scanLibraryElements(patchLibrary.entryCompilationUnit);
|
| });
|
| - return loader.processLibraryTags(patchLibrary);
|
| + return loader.processLibraryTags(patchLibrary, isPatchLibrary: true);
|
| });
|
| });
|
| }
|
| @@ -180,7 +223,7 @@ class PatchParserTask extends CompilerTask {
|
| Listener patchListener =
|
| new PatchElementListener(compiler, compilationUnit, compiler);
|
| try {
|
| - new PartialParser(patchListener, parserOptions).parseUnit(tokens);
|
| + new PartialPatchParser(patchListener, parserOptions).parseUnit(tokens);
|
| } on ParserError catch (e) {
|
| // No need to recover from a parser error in platform libraries, user
|
| // will never see this if the libraries are tested correctly.
|
| @@ -210,6 +253,11 @@ class PatchParserTask extends CompilerTask {
|
| assert(listener.nodes.isEmpty);
|
| }));
|
| }
|
| +
|
| + void scanUnit(CompilationUnitElement unit, {bool isPart: true}) {
|
| + // TODO(ahe): Implement this.
|
| + throw "not implemented";
|
| + }
|
| }
|
|
|
| class PatchMemberListener extends MemberListener {
|
| @@ -234,7 +282,10 @@ class PatchMemberListener extends MemberListener {
|
| // Skip this element.
|
| }
|
| } else {
|
| - if (Name.isPublicName(patch.name)) {
|
| + Element origin = enclosingClass.origin.localLookup(patch.name);
|
| + if (origin != null) {
|
| + patchElement(compiler, reporter, origin, patch);
|
| + } else if (Name.isPublicName(patch.name)) {
|
| reporter.reportErrorMessage(patch, MessageKind.INJECTED_PUBLIC_MEMBER);
|
| }
|
| enclosingClass.addMember(patch, reporter);
|
| @@ -281,7 +332,11 @@ class PatchElementListener extends ElementListener implements Listener {
|
| // Skip this element.
|
| }
|
| } else {
|
| - if (Name.isPublicName(patch.name)) {
|
| + LibraryElement originLibrary = compilationUnitElement.library;
|
| + Element origin = originLibrary.localLookup(patch.name);
|
| + if (origin != null) {
|
| + patchElement(compiler, reporter, origin, patch);
|
| + } else if (Name.isPublicName(patch.name)) {
|
| reporter.reportErrorMessage(patch, MessageKind.INJECTED_PUBLIC_MEMBER);
|
| }
|
| compilationUnitElement.addMember(patch, reporter);
|
|
|