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

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

Issue 10831262: Revert "Revert "Allow patch files to add top-level declarations to the patched library."" (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixed bugs Created 8 years, 4 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 | « corelib/unified/math/random.dart ('k') | 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 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 patchDartLibrary(importedLibrary, path); 398 patchDartLibrary(importedLibrary, path);
399 }); 399 });
400 } 400 }
401 401
402 void applyContainerPatch(ContainerElement original, Link<Element> patches, 402 void applyContainerPatch(ContainerElement original, Link<Element> patches,
403 Element lookup(SourceString name)) { 403 Element lookup(SourceString name)) {
404 while (!patches.isEmpty()) { 404 while (!patches.isEmpty()) {
405 Element patchElement = patches.head; 405 Element patchElement = patches.head;
406 Element originalElement = lookup(patchElement.name); 406 Element originalElement = lookup(patchElement.name);
407 if (patchElement.isAccessor()) { 407 if (patchElement.isAccessor()) {
408 // Skip accessors. An accessor always has an abstract field, 408 // TODO(lrn): When we change to always add accessors to members, and
409 // representing the accessor in the lookup scope. We can thus skip the 409 // not add abstract fields, the logic here should be reversed.
410 // accessors and just handle the abstract field. 410 // For now, access getters through the abstract field and skip
411 // any accessors.
411 } else if (patchElement.kind === ElementKind.ABSTRACT_FIELD) { 412 } else if (patchElement.kind === ElementKind.ABSTRACT_FIELD) {
412 // Getters and setters are kept inside a synthetic field. 413 // Getters and setters are kept inside a synthetic field.
413 if (originalElement !== null && 414 if (originalElement !== null &&
414 originalElement.kind !== ElementKind.ABSTRACT_FIELD) { 415 originalElement.kind !== ElementKind.ABSTRACT_FIELD) {
415 internalError("Cannot patch non-getter/setter with getter/setter", 416 internalError("Cannot patch non-getter/setter with getter/setter",
416 element: originalElement); 417 element: originalElement);
417 } 418 }
418 AbstractFieldElement patchField = patchElement; 419 AbstractFieldElement patchField = patchElement;
419 AbstractFieldElement originalField = originalElement; 420 AbstractFieldElement originalField = originalElement;
420 if (patchField.getter !== null) { 421 if (patchField.getter !== null) {
421 if (originalField === null || originalField.getter === null) { 422 if (originalField === null || originalField.getter === null) {
422 original.addGetterOrSetter(clonePatch(patchField.getter), 423 original.addGetterOrSetter(clonePatch(patchField.getter, original),
423 originalField, 424 originalField,
424 this); 425 this);
425 if (originalField === null && patchField.setter !== null) { 426 if (originalField === null && patchField.setter !== null) {
426 // It exists now, so find it for the setter patching. 427 // It exists now, so find it for the setter patching.
427 originalField = lookup(patchElement.name); 428 originalField = lookup(patchElement.name);
428 } 429 }
429 } else { 430 } else {
430 patchMember(originalField.getter, patchField.getter); 431 patchMember(originalField.getter, patchField.getter);
431 } 432 }
432 } 433 }
433 if (patchField.setter !== null) { 434 if (patchField.setter !== null) {
434 if (originalField === null || originalField.setter === null) { 435 if (originalField === null || originalField.setter === null) {
435 original.addGetterOrSetter(clonePatch(patchField.setter), 436 original.addGetterOrSetter(clonePatch(patchField.setter, original),
436 originalField, 437 originalField,
437 this); 438 this);
438 } else { 439 } else {
439 patchMember(originalField.setter, patchField.setter); 440 patchMember(originalField.setter, patchField.setter);
440 } 441 }
441 } 442 }
442 } else if (originalElement === null) { 443 } else if (originalElement === null) {
443 if (isPatchElement(patchElement)) { 444 if (isPatchElement(patchElement)) {
444 internalError("Cannot patch non-existing member '" 445 internalError("Cannot patch non-existing member '"
445 "${patchElement.name.slowToString()}'."); 446 "${patchElement.name.slowToString()}'.");
446 } 447 }
447 original.addMember(clonePatch(patchElement), this); 448 original.addMember(clonePatch(patchElement, original), this);
448 } else { 449 } else {
449 patchMember(originalElement, patchElement); 450 patchMember(originalElement, patchElement);
450 } 451 }
451 patches = patches.tail; 452 patches = patches.tail;
452 } 453 }
453 } 454 }
454 455
455 bool isPatchElement(Element element) { 456 bool isPatchElement(Element element) {
456 // TODO(lrn): More checks needed if we introduce metadata for real. 457 // TODO(lrn): More checks needed if we introduce metadata for real.
457 // In that case, it must have the identifier "native" as metadata. 458 // In that case, it must have the identifier "native" as metadata.
458 return !element.metadata.isEmpty(); 459 return !element.metadata.isEmpty();
459 } 460 }
460 461
461 Element clonePatch(Element patchElement) { 462 Element clonePatch(Element patchElement, Element enclosing) {
462 // The original library does not have an element with the same name 463 // The original library does not have an element with the same name
463 // as the patch library element. 464 // as the patch library element.
464 // In this case, the patch library element must not be marked as "patch", 465 // In this case, the patch library element must not be marked as "patch",
465 // and its name must make it private. 466 // and its name must make it private.
466 if (!patchElement.name.isPrivate()) { 467 if (!patchElement.name.isPrivate()) {
467 internalError("Cannot add non-private member '" 468 internalError("Cannot add non-private member '"
468 "${patchElement.name.slowToString()}' from patch."); 469 "${patchElement.name.slowToString()}' from patch.");
469 } 470 }
470 // TODO(lrn): Create a copy of patchElement that isn't added to any 471 Element override =
471 // object/library yet, but which takes its source from patchElement. 472 new CompilationUnitOverrideElement(patchElement.getCompilationUnit(),
472 throw "Adding members from patch is unsupported"; 473 enclosing);
474 return patchElement.cloneTo(override, this);
473 } 475 }
474 476
475 void patchMember(Element originalElement, Element patchElement) { 477 void patchMember(Element originalElement, Element patchElement) {
476 // The original library has an element with the same name as the patch 478 // The original library has an element with the same name as the patch
477 // library element. 479 // library element.
478 // In this case, the patch library element must be a function marked as 480 // In this case, the patch library element must be a function marked as
479 // "patch" and it must have the same signature as the function it patches. 481 // "patch" and it must have the same signature as the function it patches.
480 if (!isPatchElement(patchElement)) { 482 if (!isPatchElement(patchElement)) {
481 internalError("Cannot overwrite existing '" 483 internalError("Cannot overwrite existing '"
482 "${originalElement.name.slowToString()}' with non-patch."); 484 "${originalElement.name.slowToString()}' with non-patch.");
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 final endOffset = end.charOffset + end.slowCharCount; 948 final endOffset = end.charOffset + end.slowCharCount;
947 949
948 // [begin] and [end] might be the same for the same empty token. This 950 // [begin] and [end] might be the same for the same empty token. This
949 // happens for instance when scanning '$$'. 951 // happens for instance when scanning '$$'.
950 assert(endOffset >= beginOffset); 952 assert(endOffset >= beginOffset);
951 return f(beginOffset, endOffset); 953 return f(beginOffset, endOffset);
952 } 954 }
953 955
954 String toString() => 'SourceSpan($uri, $begin, $end)'; 956 String toString() => 'SourceSpan($uri, $begin, $end)';
955 } 957 }
OLDNEW
« no previous file with comments | « corelib/unified/math/random.dart ('k') | lib/compiler/implementation/elements/elements.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698