{"id":18521808,"url":"https://github.com/simphotonics/generic_reader","last_synced_at":"2025-05-14T18:09:24.201Z","repository":{"id":56831081,"uuid":"263896310","full_name":"simphotonics/generic_reader","owner":"simphotonics","description":"Enables retrieving generic const values from a static analyzer representation. Streamlines reading constants of type Map, List, Set, and Dart enumerations.","archived":false,"fork":false,"pushed_at":"2024-12-29T12:57:48.000Z","size":264,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-17T05:25:25.141Z","etag":null,"topics":["annotation","compile-time","constants","data-type","generation","generators","generic","source-code"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/generic_reader","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/simphotonics.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-05-14T11:29:10.000Z","updated_at":"2024-12-29T12:57:51.000Z","dependencies_parsed_at":"2023-02-18T00:16:28.015Z","dependency_job_id":"80664bf0-2a2f-4b05-829b-4916e8d65dd2","html_url":"https://github.com/simphotonics/generic_reader","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simphotonics%2Fgeneric_reader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simphotonics%2Fgeneric_reader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simphotonics%2Fgeneric_reader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simphotonics%2Fgeneric_reader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/simphotonics","download_url":"https://codeload.github.com/simphotonics/generic_reader/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254198510,"owners_count":22030966,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["annotation","compile-time","constants","data-type","generation","generators","generic","source-code"],"created_at":"2024-11-06T17:27:42.682Z","updated_at":"2025-05-14T18:09:19.169Z","avatar_url":"https://github.com/simphotonics.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Generic Reader\n[![Dart](https://github.com/simphotonics/generic_reader/actions/workflows/dart.yml/badge.svg)](https://github.com/simphotonics/generic_reader/actions/workflows/dart.yml)\n\n## Introduction\n\nThe premise of *source code generation* is that we can specify\n(hopefully few) details and flesh out the rest of the classes, and methods during the build process.\nDart's static [`analyzer`][analyzer] provides access to libraries, classes,\nclass fields, class methods, functions, variables, etc in the form of [`Elements`][Elements].\n\nSource code generation relies heavily on *constants* known at compile time.\nCompile-time constant expressions are represented by a [`DartObject`][DartObject] and\ncan be accessed by using the method [`computeConstantValue()`][computeConstantValue()] (available for elements representing a variable).\n\nFor built-in types, [`DartObject`][DartObject] has methods that allow reading the underlying constant object.\nIt is a more laborious task to read constant values of user defined data-types.\n\nThe package [`generic_reader`][generic_reader] includes extentions on\n[`ConstantReader`][ConstantReader] that simplify reading constants of type `List`, `Set`, `Map`, `Enum`\n and provides a systematic way of reading arbitrary constants of *known* data-type.\n\n## Usage\n\nTo use the package [`generic_reader`][generic_reader] the following steps are required:\n1. Include [`generic_reader`][generic_reader] and [`source_gen`][source_gen] as dependencies in your pubspec.yaml file.\n\n2. Register a [Decoder][Decoder] function for each *user defined* data-type `T` that is going to be read.\nA decoder function has the signature `T Function(ConstantReader constantReader)`. It reads the constant expression\nrepresented by `constantReader` and returns a instance of `T`.\nNote: The built-in types `bool`, `double`, `int`, `String`, `Type`, `Symbol`, and Dart enums do **not** require a decoder function.\n\n\n3. Retrieve the compile-time constant values using the methods [`get\u003cT\u003e()`][get], [`getList\u003cT\u003e()`][getList],\n   [`getSet\u003cT\u003e()`][getSet], [`getMap\u003cT\u003e()`][getMap].\n\n4. Process the retrieved compile-time constants and generate the required source code.\n\n## Decoder Functions\n\nThe extension [`GenericReader`][GenericReader] provides a systematic method of retrieving constants of\narbitrary data-types by allowing users to register `Decoder` functions (for lack of a better a name).\nDecoder functions can make use of other registered decoder functions enabling the retrieval of\ncomplex generic data-structures.\n\nDecoders functions know how to **decode** a specific data-type and have the following signature:\n```Dart\ntypedef T Decoder\u003cT\u003e(ConstantReader constantReader);\n```\nThe input argument is of type [`ConstantReader`][ConstantReader], a wrapper around\n[`DartObject`][DartObject],\nand the function returns an object of type `T`.\nIt is required that the input argument `constantReader` represents an object of type `T`.\n\nUser defined types are often a composition of other types, as illustrated in the example below.\n\u003cdetails\u003e  \u003csummary\u003e Click to show source-code. \u003c/summary\u003e\n\n ```Dart\n enum Title{Mr, Mrs, Dr}\n\n class Age {\n   const Age(this.age);\n   final int age;\n   bool get isAdult =\u003e age \u003e 21;\n\n   @override\n   String toString() {\n     return 'age: $age';\n   }\n }\n\n class Name {\n   const Name({\n     required this.firstName,\n     required this.lastName,\n     this.middleName = '',\n   });\n   final String firstName;\n   final String lastName;\n   final String middleName;\n\n   @override\n   String toString() {\n     return '$firstName ${middleName == '' ? '' : middleName + ' ' }$lastName';\n   }\n }\n\n class User {\n   const User({\n     required this.name,\n     required this.id,\n     required this.age,\n     required this.title,\n   });\n   final Name name;\n   final Age age;\n   final int id;\n   final Title title;\n\n   @override\n   String toString() {\n     return 'user: $name\\n'\n         '  title: ${title}\\n'\n         '  id: $id\\n'\n         '  $age\\n';\n   }\n }\n\n ```\n\u003c/details\u003e\n\nIn order to retrieve a constant value of type `User` one has\nto retrieve the constructor parameters of type  `int`, `Name`, `Title`, and `Age` first.\n\nThe following shows how to define decoder functions for the types `Age`, `Name`, and `User`.\nNote that each decoder knows the constructor *parameter-names* and *parameter-types*\nof the class it handles. For example, the decoder for `User` knows that `age` has type `Age` and that the field-name is *age*.\n\n```Dart\nimport 'package:generic_reader/generic_reader.dart';\nimport 'package:source_gen/source_gen.dart' show ConstantReader;\n\nimport 'package:test_types/test_types.dart';\n\n/// Defining decoder functions.\nAge ageDecoder(ConstantReader constantReader) =\u003e Age(constantReader.read('age').intValue);\n\nName nameDecoder(ConstantReader constantReader) {\n  final firstName = constantReader.read('firstName').stringValue;\n  final lastName = constantReader.read('lastName').stringValue;\n  final middleName = constantReader.read('middleName').stringValue;\n  return Name(firstName: firstName, lastName: lastName, middleName: middleName);\n};\n\nUser userDecoder(ConstantReader constantReader){\n  final id = constantReader.read('id').intValue;\n  final age = constantReader.read('age').get\u003cAge\u003e();\n  final name = constantReader.read('name').get\u003cName\u003e();\n  final tile = constantReader.read('title').get\u003cTitle\u003e();\n  return User(name: name, age: age, id: id, title: title);\n};\n\n// Registering decoders.\nGenericReader.addDecoder\u003cAge\u003e(ageDecoder)\nGenericReader.addDecoder\u003cName\u003e(nameDecoder)\nGenericReader.addDecoder\u003cUser\u003e(userDecoder);\n\n// Reading the library where an object of type User is defined.\n// Retrieving the ConstantReader object representing an instance of User:\n// constantReaderOfUser.\n\n// Retrieving a constant value of type User:\nfinal User user = reader.get\u003cUser\u003e(constantReaderOfUser);\n```\nA short program demonstrating how to retrieve a constant of type `User`\nis located at [`examples/bin/user_example.dart`](https://github.com/simphotonics/generic_reader/tree/master/example/bin/user_example.dart).\n\n## Limitations\n\n1) Constants retrievable with [`GenericReader`][GenericReader] must have\n   a built-in Dart type, a type made available by depending on a package, or a type defined in the file being read.\n   The functions matching the static type of an analyzer element with the type\n   of a runtime object do **not** work with relative imports.\n\n   E.g. the demos in folder [`example/bin`](https://github.com/simphotonics/generic_reader/tree/master/example/bin) read types that are provided\n   by the package `test_types` located in the subfolder with the same name.\n\n2) Defining decoder functions for each data-type has its obvious limitiations when it comes to *generic types*. In practice, however, generic classes are often designed in such a manner that only few type parameters are valid or likely to be useful. Constants that need to be retrieved during the source-generation process are most likely *annotations* and *simple data-types* that convey information to source code generators. A demonstration on how to retrieve constant values with generic type is presented in [example].\n\n## Examples\n\nFor further information on how to use [GenericReader] to retrieve constants of\narbitrary type see [example].\n\n## Features and bugs\n\nPlease file feature requests and bugs at the [issue tracker].\n\n[issue tracker]: https://github.com/simphotonics/generic_reader/issues\n\n[analyzer]: https://pub.dev/packages/analyzer\n\n[Elements]: https://pub.dev/documentation/analyzer/latest/dart_element_element/dart_element_element-library.html\n\n[computeConstantValue()]: https://pub.dev/documentation/analyzer/latest/dart_element_element/VariableElement/computeConstantValue.html\n\n[ConstantReader]: https://pub.dev/documentation/source_gen/latest/source_gen/ConstantReader-class.html\n\n[Decoder]: https://github.com/simphotonics/generic_reader#decoder-functions\n\n[DartObject]: https://pub.dev/documentation/analyzer/latest/dart_constant_value/DartObject-class.html\n\n[example]: https://github.com/simphotonics/generic_reader/tree/master/example\n\n[GenericReader]: https://pub.dev/packages/generic_reader\n\n[generic_reader]: https://pub.dev/packages/generic_reader\n\n[get]: https://pub.dev/documentation/generic_reader/latest/generic_reader/GenericReader/get.html\n\n[getList]: https://pub.dev/documentation/generic_reader/latest/generic_reader/GenericReader/getList.html\n\n[getMap]: https://pub.dev/documentation/generic_reader/latest/generic_reader/GenericReader/getMap.html\n\n[getSet]: https://pub.dev/documentation/generic_reader/latest/generic_reader/GenericReader/getSet.html\n\n[peek]: https://pub.dev/documentation/source_gen/latest/source_gen/ConstantReader/peek.html\n\n[player_example.dart]: https://github.com/simphotonics/generic_reader/blob/master/example/bin/player_example.dart\n\n[source_gen]: https://pub.dev/packages/source_gen\n\n[source_gen_test]: https://pub.dev/packages/source_gen_test\n\n[TypeMethods]: https://pub.dev/documentation/generic_reader/latest/generic_reader/TypeMethods.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimphotonics%2Fgeneric_reader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimphotonics%2Fgeneric_reader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimphotonics%2Fgeneric_reader/lists"}