Skip to content

Wolvereness/OverMapped

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

35 Commits
 
 
 
 
 
 
 
 

Repository files navigation

OverMapped - Allows a project to map methods, fields, or classes to new names.

  Inspired by Java's inability to have two methods with same name but unique
  return types at compile-time.

A list of parameters follows in the format of 'pom parameter' - 'property'. A
property is used as a command parameter, like `-Dmapping.maps=./maps.yml',
while the parameter name is used in the pom's plugin-configuration.

  maps - mapping.maps
    This is yaml file containing mapping changes. The top-level structure
    should be a list of relational arrays, or a single relational array. Each
    relational array can have four processed keys, `members', `classes',
    `flags', and `regex'. Relational arrays are processed in order of
    appearance. In each relational array, sections are processed in the order
    of `classes', then `members', then `flags', then `regex'. Each
    consecutive entry (as the set of previously described keys) is processed
    as if every entry is being applied on top of any previous entry.

    MEMBERS (Fields / Methods)

    A member entry requires a fully qualified name (delimited by slashes or
    `/' ), the previous name, and a descriptor. Methods will use parenthesis
    around the parameter list, with a trailing return type, to define their
    description. Fields simply use their type as a descriptor. This
    information is interpreted from the structure of the yaml. Member entries
    are contained in a relational array. Each member entry may be a variety
    of styles.

    To map a method similarly-defined in multiple
    classes, where some class may implement / extend said classes, but the
    classes do not extend or implement each other, a multi-class mapping
    needs to be used. The mappings should have a relational key of some
    sequence. Each mapping should have a relational value of the new string-
    name of the member. The relational key can be a relational pair of
    strings, or a single-string with a (single) space-delimitation.

    An example mapping both Runnable.run() and Thread.run()
    * Note, in a real application, mapping Runnable.run() would automatically
      map Thread.run() as well, because Thread implements/extends Runnable.
      This would not work if the only definition was Thread.run(), as maps are
      only applied to classes that extend or implement the method's class.

    members:
      [ java/lang/Runnable, java/lang/Thread ]:
        "run ()V": go

    The above example is equally valid to using a relational pair in this
    example:

    members:
      [ java/lang/Runnable, java/lang/Thread ]:
        { "run": "()V" }: go

    In a real application, it would be appropriate to only define the mapping
    from Runnable, so only providing a single class-name as the relational
    key to the maps is also correct, like in these two examples:

    members:
      java/lang/Runnable:
        "run ()V": go

    members:
      java/lang/Runnable:
        { "run": "()V" }: go

    Similarly, the same styles will also work for fields (only when a
    single-class is provided). These examples demonstrate renaming
    ByteArrayInputStream.buf to buffer:

    members:
      java/io/ByteArrayInputStream:
        "buf [B": buffer

    members:
      java/io/ByteArrayInputStream:
        { buf: "[B" }: buffer

    Specifically for fields, the description may be ommitted if there is only
    a single field with the same name in the class:

    members:
      java/io/ByteArrayInputStream:
        buf: buffer

    members:
      java/io/ByteArrayInputStream:
        { buf: }: buffer

    For situations that multiple fields in a particular style need to be
    renamed, the relational key can be a relational pair of sequence to
    starting name, where the relational value is a sequence of values to map
    each respective entry, starting from the defined value. This style
    follows the same behavior from omitting descriptions, such that all the
    specified names need to be unique.

    This example shows the general syntax:

    members:
      java/package/Class:
        { [ FIELD_1, FIELD_2, FIELD_3, FIELD_4 ]: FIELD_2 }:
        - OTHER_FIELD_2
        - OTHER_FIELD_3

    Assuming the appropriate Class existed, this would map the fields of
    FIELD_2 and FIELD_3 to OTHER_FIELD_2 and OTHER_FIELD_3 respectively. If
    FIELD_1 or FIELD_4 existed, they would not be affected. For repetitive
    uses of these lists, anchors and aliases can be helpful.

    CLASS NAMES

    Classes are mapped simply by making the previous name a relational key
    with the new name the relational value. An example mapping Runnable to
    GoTime:

    classes:
      "java/lang/Runnable": "java/lang/GoTime"

    MEMBER FLAGS

    Flags are changed by using the fully qualified description (see above) as
    the relational key, with an integer as the relational value. These must be
    exact matches to the members. An example flagging Thread.run() as
    synthetic (this doesn't affect sub-classes!):

    flags:
      "java/lang/Thread run ()V": 1001

    REGEX (Class names)

    Regex replacements are applied to class names. For every class name, the
    given name has all matching sequences replaced with the specified
    replacement string. Backslash ( \ ) and dollar-sign ( $ ) carry unique
    meaning for escaping and matching groups respectively. Standard java
    convention is used. An example that renames all classes in java.lang to
    start with an underscore:

    regex:
      "^java/lang/([^/]+)$": "java/lang/_$1"

    Required

  input - mapping.input
    This is the jar (or zip) file to read from.

    Required

  output - mapping.output
    This is the jar file to write to.

    Default - the input file

  original - mapping.original
    The file to copy the original input to, intended for usage when
    overwriting the input file.

    Default - does not copy the original

  cores - mapping.cores
    The number of cores to use. This must be at least 1 (intended to start no
    extra threads). Extra threads are used to process classes and perform some
    file-IO.

    Default - 2

  missing - mapping.missing
    This value dictates behavior when a class or member specified in the maps
    is not found. Valid options include:

    IGNORE - takes no action.
    WARN - outputs a message in the log.
    FAIL - throws an exception, causing the goal to enter a 'failed' state.
    VERBOSE - outputs detailed information when reading in classes and state
      information when a value is not found. This information is helpful for
      users to debug their maps.

    Default - WARN

  findParents - mapping.findParents
    This value indicates should attempt to detect when a mapped methods loses
    inheritance to a parent's (implemented interface or extended class)
    method. If a parent class has a method with the same signature, OverMapped
    will print a message indicating the method that is no longer overridden.

    Default - false

  correctEnums - mapping.correctEnums
    This value indicates that when the field-name of an Enum is changed, it
    should also change the internal "String" used to identify the Enum. No
    specific configuration is used, as all internal names will mirror that of
    the field used to store the enum.

    This value changes the behavior of the static method in Enum,
    Enum.valueOf(Class<T> enumType, String name), and in turn affects
    serialization of the enum values (which is performed by internal-names).

    Default - true

About

OverMapped - inclusive Java remapping tool

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages