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

Side by Side Diff: lib/compiler/implementation/compiler.dart

Issue 10697084: Recognize "patch" identifier in .dartp files. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | lib/compiler/implementation/elements/elements.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 /** 6 /**
7 * If true, print a warning for each method that was resolved, but not 7 * If true, print a warning for each method that was resolved, but not
8 * compiled. 8 * compiled.
9 */ 9 */
10 final bool REPORT_EXCESS_RESOLUTION = false; 10 final bool REPORT_EXCESS_RESOLUTION = false;
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 throw; 277 throw;
278 } finally { 278 } finally {
279 _currentElement = old; 279 _currentElement = old;
280 } 280 }
281 } 281 }
282 282
283 List<CompilerTask> tasks; 283 List<CompilerTask> tasks;
284 ScannerTask scanner; 284 ScannerTask scanner;
285 DietParserTask dietParser; 285 DietParserTask dietParser;
286 ParserTask parser; 286 ParserTask parser;
287 PatchParserTask patchParser;
287 TreeValidatorTask validator; 288 TreeValidatorTask validator;
288 ResolverTask resolver; 289 ResolverTask resolver;
289 TypeCheckerTask checker; 290 TypeCheckerTask checker;
290 Backend backend; 291 Backend backend;
291 ConstantHandler constantHandler; 292 ConstantHandler constantHandler;
292 EnqueueTask enqueuer; 293 EnqueueTask enqueuer;
293 294
294 static final SourceString MAIN = const SourceString('main'); 295 static final SourceString MAIN = const SourceString('main');
295 static final SourceString NO_SUCH_METHOD = const SourceString('noSuchMethod'); 296 static final SourceString NO_SUCH_METHOD = const SourceString('noSuchMethod');
296 static final SourceString NO_SUCH_METHOD_EXCEPTION = 297 static final SourceString NO_SUCH_METHOD_EXCEPTION =
(...skipping 19 matching lines...) Expand all
316 validateUnparse = false, 317 validateUnparse = false,
317 generateSourceMap = true]) 318 generateSourceMap = true])
318 : libraries = new Map<String, LibraryElement>(), 319 : libraries = new Map<String, LibraryElement>(),
319 world = new World(), 320 world = new World(),
320 progress = new Stopwatch.start() { 321 progress = new Stopwatch.start() {
321 namer = new Namer(this); 322 namer = new Namer(this);
322 constantHandler = new ConstantHandler(this); 323 constantHandler = new ConstantHandler(this);
323 scanner = new ScannerTask(this); 324 scanner = new ScannerTask(this);
324 dietParser = new DietParserTask(this); 325 dietParser = new DietParserTask(this);
325 parser = new ParserTask(this); 326 parser = new ParserTask(this);
327 patchParser = new PatchParserTask(this);
326 validator = new TreeValidatorTask(this); 328 validator = new TreeValidatorTask(this);
327 resolver = new ResolverTask(this); 329 resolver = new ResolverTask(this);
328 checker = new TypeCheckerTask(this); 330 checker = new TypeCheckerTask(this);
329 backend = emitJavascript ? 331 backend = emitJavascript ?
330 new JavaScriptBackend(this, generateSourceMap) : 332 new JavaScriptBackend(this, generateSourceMap) :
331 new dart_backend.DartBackend(this, validateUnparse); 333 new dart_backend.DartBackend(this, validateUnparse);
332 enqueuer = new EnqueueTask(this); 334 enqueuer = new EnqueueTask(this);
333 tasks = [scanner, dietParser, parser, resolver, checker, 335 tasks = [scanner, dietParser, parser, resolver, checker,
334 constantHandler, enqueuer]; 336 constantHandler, enqueuer];
335 tasks.addAll(backend.tasks); 337 tasks.addAll(backend.tasks);
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 initializeSpecialClasses(); 515 initializeSpecialClasses();
514 516
515 patchDartLibrary(coreLibrary, 'core'); 517 patchDartLibrary(coreLibrary, 'core');
516 patchDartLibrary(coreImplLibrary, 'coreimpl'); 518 patchDartLibrary(coreImplLibrary, 'coreimpl');
517 } 519 }
518 520
519 void patchDartLibrary(LibraryElement library, String dartLibraryPath) { 521 void patchDartLibrary(LibraryElement library, String dartLibraryPath) {
520 if (library.isPatched) return; 522 if (library.isPatched) return;
521 Uri patchUri = resolvePatchUri(dartLibraryPath); 523 Uri patchUri = resolvePatchUri(dartLibraryPath);
522 if (patchUri !== null) { 524 if (patchUri !== null) {
523 // TODO(lrn): Use a different parser to allow for "patch" annotations. 525 LibraryElement patchLibrary =
524 // For now just assume everything in the patch library is a patch 526 patchParser.loadPatchLibrary(patchUri);
525 // function. 527 // We allow foreign functions in patched libraries.
526 LibraryElement patchLibrary = scanner.loadLibrary(patchUri, null); 528 addForeignFunctions(library); // Is safe even if already added.
527 applyLibraryPatch(library, patchLibrary); 529 applyLibraryPatch(library, patchLibrary);
528 } 530 }
529 } 531 }
530 532
531 void applyLibraryPatch(LibraryElement library, LibraryElement patch) { 533 void applyLibraryPatch(LibraryElement original, LibraryElement patch) {
532 // We allow foreign functions in patched libraries. 534 Link<Element> patches = patch.topLevelElements;
533 addForeignFunctions(library); // Is safe even if already added.
534 535
535 // Copy/patch top-level elements. 536 // Copy/patch top-level elements.
536 Link<Element> patches = patch.topLevelElements;
537 while (!patches.isEmpty()) { 537 while (!patches.isEmpty()) {
538 Element patchElement = patches.head; 538 Element patchElement = patches.head;
539 Element originalElement = library.elements[patchElement.name]; 539 Element originalElement = original.elements[patchElement.name];
540 if (originalElement !== null) { 540 // Getters and setters are kept inside a synthetic field.
541 // Assume that we are patching if the original exists. 541 if (patchElement.kind === ElementKind.ABSTRACT_FIELD) {
542 if (originalElement is! FunctionElement) { 542 if (originalElement !== null &&
543 // TODO(lrn): Handle class declarations too. 543 originalElement.kind !== ElementKind.ABSTRACT_FIELD) {
544 internalError("Can only patch functions", element: originalElement); 544 internalError("Cannot patch non-getter/setter with getter/setter",
545 }
546 // TODO(lrn): Abort if the original isn't marked external, when
547 // that is added to the language.
548 if (patchElement is! FunctionElement ||
549 !patchSignatureMatches(originalElement, patchElement)) {
550 internalError("Can only patch functions with matching signatures",
551 element: originalElement); 545 element: originalElement);
552 } 546 }
553 applyFunctionPatch(originalElement, patchElement); 547 AbstractFieldElement patchField = patchElement;
548 AbstractFieldElement originalField = originalElement;
549 if (patchField.getter !== null) {
550 if (originalField === null || originalField.getter === null) {
551 original.addGetterOrSetter(clonePatch(patchField.getter));
552 } else {
553 patchMember(originalField.getter, patchField.getter);
554 }
555 }
556 if (patchField.setter !== null) {
557 if (originalField === null || originalField.setter === null) {
558 original.addGetterOrSetter(clonePatch(patchField.setter));
559 } else {
560 patchMember(originalField.setter, patchField.setter);
561 }
562 }
563 } else if (originalElement === null) {
564 original.addMember(clonePatch(patchElement));
554 } else { 565 } else {
555 // TODO(lrn): Allow adding private elements to the original library. 566 patchMember(originalElement, patchElement);
556 } 567 }
557 patches = patches.tail; 568 patches = patches.tail;
558 } 569 }
559 570
560 // Copy imports. 571 // Copy imports.
561 Map<String, LibraryElement> delayedPatches = <LibraryElement>{}; 572 Map<String, LibraryElement> delayedPatches = <LibraryElement>{};
562 Uri base = patch.script.uri; 573 Uri patchBase = patch.script.uri;
563 for (ScriptTag tag in patch.tags.reverse()) { 574 for (ScriptTag tag in patch.tags.reverse()) {
564 if (tag.isImport()) { 575 if (tag.isImport()) {
565 StringNode argument = tag.argument; 576 StringNode argument = tag.argument;
566 Uri resolved = base.resolve(argument.dartString.slowToString()); 577 Uri resolved = patchBase.resolve(argument.dartString.slowToString());
567 LibraryElement importedLibrary = 578 LibraryElement importedLibrary =
568 scanner.loadLibrary(resolved, argument); 579 scanner.loadLibrary(resolved, argument);
569 scanner.importLibrary(library, importedLibrary, tag, patch); 580 scanner.importLibrary(original, importedLibrary, tag, patch);
570 if (resolved.scheme == "dart") { 581 if (resolved.scheme == "dart") {
571 delayedPatches[resolved.path] = importedLibrary; 582 delayedPatches[resolved.path] = importedLibrary;
572 } 583 }
573 } 584 }
574 } 585 }
586
575 // Mark library as already patched. 587 // Mark library as already patched.
576 library.patch = patch; 588 original.patch = patch;
577 // We patch imported libraries after marking the current library as patched, 589
578 // to avoid problems with cyclic dependencies. 590 // We patch imported libraries after marking the current library as
591 // patched, to avoid problems with cyclic dependencies.
579 delayedPatches.forEach((String path, LibraryElement importedLibrary) { 592 delayedPatches.forEach((String path, LibraryElement importedLibrary) {
580 patchDartLibrary(importedLibrary, path); 593 patchDartLibrary(importedLibrary, path);
581 }); 594 });
582 } 595 }
583 596
597 Element clonePatch(Element patchElement) {
598 bool isPatch(Element element) {
599 // TODO(lrn): More checks needed if we introduce matadata for real.
Johnni Winther 2012/07/06 07:57:39 matadata -> metadata
Lasse Reichstein Nielsen 2012/07/06 10:26:23 Done.
600 return !element.metadata.isEmpty();
601 }
602 if (isPatch(patchElement)) {
603 internalError("Cannot patch non-existing member '"
604 "${patchElement.name.slowToString()}'.");
Johnni Winther 2012/07/06 07:57:39 I can't see the relation between 1) the element ha
Lasse Reichstein Nielsen 2012/07/06 10:26:23 This function is for copying a declaration from th
605
606 }
607 if (!patchElement.name.isPrivate()) {
608 internalError("Cannot add non-private member '"
609 "${patchElement.name.slowToString()}' from patch.");
610 }
611 // TODO(lrn): Create a copy of patchElement that isn't added to anything,
612 // but which takes its source from patchElement.
613 throw "Adding members from patch is unsupported";
614 }
615
616 void patchMember(Element originalElement,
617 Element patchElement) {
618 // originalElement isn't null.
619 bool isPatch(Element element) {
Johnni Winther 2012/07/06 07:57:39 Make a separate isPatch check to be used both in c
Lasse Reichstein Nielsen 2012/07/06 10:26:23 Done. I consider moving everything to patch-parser
620 // TODO(lrn): More checks needed if we introduce matadata for real.
621 return !element.metadata.isEmpty();
622 }
623 if (!isPatch(patchElement)) {
624 internalError("Cannot overwrite existing '"
625 "${originalElement.name.slowToString()}' with non-patch.");
626 }
627 if (originalElement is! FunctionElement) {
628 // TODO(lrn): Handle class declarations too.
629 internalError("Can only patch functions", element: originalElement);
630 }
631 // TODO(lrn): Abort if the original isn't marked external, when
632 // that is added to the language.
633 if (patchElement is! FunctionElement ||
634 !patchSignatureMatches(originalElement, patchElement)) {
635 internalError("Can only patch functions with matching signatures",
636 element: originalElement);
637 }
638 applyFunctionPatch(originalElement, patchElement);
639 }
640
584 bool patchSignatureMatches(FunctionElement original, FunctionElement patch) { 641 bool patchSignatureMatches(FunctionElement original, FunctionElement patch) {
585 // TODO(lrn): Check that patches actually match the signature of 642 // TODO(lrn): Check that patches actually match the signature of
586 // the function it's patching. 643 // the function it's patching.
587 return true; 644 return true;
588 } 645 }
589 646
590 void applyFunctionPatch(FunctionElement element, 647 void applyFunctionPatch(FunctionElement element,
591 FunctionElement patchElement) { 648 FunctionElement patchElement) {
592 // Don't just assign the patch field. This also updates the cachedNode. 649 // Don't just assign the patch field. This also updates the cachedNode.
593 if (element.isPatched) { 650 if (element.isPatched) {
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
992 f(int beginOffset, int endOffset)) { 1049 f(int beginOffset, int endOffset)) {
993 final beginOffset = begin.charOffset; 1050 final beginOffset = begin.charOffset;
994 final endOffset = end.charOffset + end.slowCharCount; 1051 final endOffset = end.charOffset + end.slowCharCount;
995 1052
996 // [begin] and [end] might be the same for the same empty token. This 1053 // [begin] and [end] might be the same for the same empty token. This
997 // happens for instance when scanning '$$'. 1054 // happens for instance when scanning '$$'.
998 assert(endOffset >= beginOffset); 1055 assert(endOffset >= beginOffset);
999 return f(beginOffset, endOffset); 1056 return f(beginOffset, endOffset);
1000 } 1057 }
1001 } 1058 }
OLDNEW
« no previous file with comments | « no previous file | lib/compiler/implementation/elements/elements.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698