545 * can have user defined getters 546 * @param obj the script object 547 * @return user defined getter function, or {@code null} if none exists 548 */ 549 public ScriptFunction getGetterFunction(final ScriptObject obj) { 550 return null; 551 } 552 553 /** 554 * Get the user defined setter function if one exists. Only {@link UserAccessorProperty} instances 555 * can have user defined getters 556 * @param obj the script object 557 * @return user defined getter function, or {@code null} if none exists 558 */ 559 public ScriptFunction getSetterFunction(final ScriptObject obj) { 560 return null; 561 } 562 563 @Override 564 public int hashCode() { 565 final Class<?> type = getLocalType(); 566 return Objects.hashCode(this.key) ^ flags ^ getSlot() ^ (type == null ? 0 : type.hashCode()); 567 } 568 569 @Override 570 public boolean equals(final Object other) { 571 if (this == other) { 572 return true; 573 } 574 575 if (other == null || this.getClass() != other.getClass()) { 576 return false; 577 } 578 579 final Property otherProperty = (Property)other; 580 581 return equalsWithoutType(otherProperty) && 582 getLocalType() == otherProperty.getLocalType(); 583 } 584 585 boolean equalsWithoutType(final Property otherProperty) { 586 return getFlags() == otherProperty.getFlags() && 587 getSlot() == otherProperty.getSlot() && 588 getKey().equals(otherProperty.getKey()); 589 } 590 591 private static final String type(final Class<?> type) { 592 if (type == null) { 593 return "undef"; 594 } else if (type == int.class) { 595 return "i"; 596 } else if (type == long.class) { 597 return "j"; 598 } else if (type == double.class) { 599 return "d"; 600 } else { 601 return "o"; 602 } 603 } 604 605 /** 606 * Short toString version 607 * @return short toString 608 */ 609 public final String toStringShort() { 610 final StringBuilder sb = new StringBuilder(); 611 final Class<?> type = getLocalType(); 612 sb.append(getKey()).append(" (").append(type(type)).append(')'); 613 return sb.toString(); 614 } 615 616 private static String indent(final String str, final int indent) { 617 final StringBuilder sb = new StringBuilder(); 618 sb.append(str); 619 for (int i = 0; i < indent - str.length(); i++) { 620 sb.append(' '); 621 } 622 return sb.toString(); 623 } 624 625 @Override 626 public String toString() { 627 final StringBuilder sb = new StringBuilder(); 628 final Class<?> type = getLocalType(); 629 630 sb.append(indent(getKey(), 20)). 631 append(" id="). 632 append(Debug.id(this)). 633 append(" (0x"). 634 append(indent(Integer.toHexString(flags), 4)). 635 append(") "). 636 append(getClass().getSimpleName()). 637 append(" {"). 638 append(indent(type(type), 5)). 639 append('}'); 640 641 if (slot != -1) { 642 sb.append(" ["). 643 append("slot="). 644 append(slot). 645 append(']'); 646 } 647 648 return sb.toString(); 649 } 650 651 /** 652 * Get the current type of this property. If you are running with object fields enabled, 653 * this will always be Object.class. See the value representation explanation in 654 * {@link Property#getSetter(Class, PropertyMap)} and {@link ObjectClassGenerator} 655 * for more information. 656 * 657 * <p>Note that for user accessor properties, this returns the type of the last observed 658 * value passed to or returned by a user accessor. Use {@link #getLocalType()} to always get | 545 * can have user defined getters 546 * @param obj the script object 547 * @return user defined getter function, or {@code null} if none exists 548 */ 549 public ScriptFunction getGetterFunction(final ScriptObject obj) { 550 return null; 551 } 552 553 /** 554 * Get the user defined setter function if one exists. Only {@link UserAccessorProperty} instances 555 * can have user defined getters 556 * @param obj the script object 557 * @return user defined getter function, or {@code null} if none exists 558 */ 559 public ScriptFunction getSetterFunction(final ScriptObject obj) { 560 return null; 561 } 562 563 @Override 564 public int hashCode() { 565 final Class<?> t = getLocalType(); 566 return Objects.hashCode(this.key) ^ flags ^ getSlot() ^ (t == null ? 0 : t.hashCode()); 567 } 568 569 @Override 570 public boolean equals(final Object other) { 571 if (this == other) { 572 return true; 573 } 574 575 if (other == null || this.getClass() != other.getClass()) { 576 return false; 577 } 578 579 final Property otherProperty = (Property)other; 580 581 return equalsWithoutType(otherProperty) && 582 getLocalType() == otherProperty.getLocalType(); 583 } 584 585 boolean equalsWithoutType(final Property otherProperty) { 586 return getFlags() == otherProperty.getFlags() && 587 getSlot() == otherProperty.getSlot() && 588 getKey().equals(otherProperty.getKey()); 589 } 590 591 private static String type(final Class<?> type) { 592 if (type == null) { 593 return "undef"; 594 } else if (type == int.class) { 595 return "i"; 596 } else if (type == long.class) { 597 return "j"; 598 } else if (type == double.class) { 599 return "d"; 600 } else { 601 return "o"; 602 } 603 } 604 605 /** 606 * Short toString version 607 * @return short toString 608 */ 609 public final String toStringShort() { 610 final StringBuilder sb = new StringBuilder(); 611 final Class<?> t = getLocalType(); 612 sb.append(getKey()).append(" (").append(type(t)).append(')'); 613 return sb.toString(); 614 } 615 616 private static String indent(final String str, final int indent) { 617 final StringBuilder sb = new StringBuilder(); 618 sb.append(str); 619 for (int i = 0; i < indent - str.length(); i++) { 620 sb.append(' '); 621 } 622 return sb.toString(); 623 } 624 625 @Override 626 public String toString() { 627 final StringBuilder sb = new StringBuilder(); 628 final Class<?> t = getLocalType(); 629 630 sb.append(indent(getKey(), 20)). 631 append(" id="). 632 append(Debug.id(this)). 633 append(" (0x"). 634 append(indent(Integer.toHexString(flags), 4)). 635 append(") "). 636 append(getClass().getSimpleName()). 637 append(" {"). 638 append(indent(type(t), 5)). 639 append('}'); 640 641 if (slot != -1) { 642 sb.append(" ["). 643 append("slot="). 644 append(slot). 645 append(']'); 646 } 647 648 return sb.toString(); 649 } 650 651 /** 652 * Get the current type of this property. If you are running with object fields enabled, 653 * this will always be Object.class. See the value representation explanation in 654 * {@link Property#getSetter(Class, PropertyMap)} and {@link ObjectClassGenerator} 655 * for more information. 656 * 657 * <p>Note that for user accessor properties, this returns the type of the last observed 658 * value passed to or returned by a user accessor. Use {@link #getLocalType()} to always get |