Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
version: 2
updates:
- package-ecosystem: "pub"
directory: "package/inject_compile"
schedule:
interval: "daily"
- package-ecosystem: "pub"
directory: "package/inject_compile_generator"
schedule:
interval: "daily"
- package-ecosystem: "pub"
directory: "example/train"
schedule:
interval: "daily"
- package-ecosystem: "pub"
directory: "example/clean_architecture"
schedule:
interval: "daily"
- package-ecosystem: "pub"
directory: "example/coffee"
schedule:
interval: "daily"
32 changes: 32 additions & 0 deletions .github/workflows/dart.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Dart

on:
pull_request:
branches: [main]
push:
branches: [main]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dart-lang/setup-dart@v1

- name: Install dependencies
run: dart pub get

- name: Run code generation
run: dart run build_runner build --workspace

# Verify the use of 'dart format' on each commit.
- name: Verify formatting
run: dart format --output=none --set-exit-if-changed .

# Ensure the analyzer passes without issues
- name: Analyze project source
run: dart analyze --fatal-infos

# Ensure the test suite works
- name: Run tests
run: dart test -p vm package/inject_compile/test package/inject_compile_generator/test example/coffee/test example/train/test example/clean_architecture/test
14 changes: 14 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Publish to pub.dev

on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+*'

jobs:
publish:
permissions:
id-token: write # Required for authentication using OIDC
uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1
with:
environment: 'pub.dev'
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:meta/meta.dart';
import 'lookup_key.dart';

part 'injected_type.g.dart';

/// A type that is being injected, with metadata about how it is being injected.
@immutable
@JsonSerializable()
class InjectedType {
/// The type the user is trying to inject.
final LookupKey lookupKey;
Expand All @@ -16,10 +12,15 @@ class InjectedType {

const InjectedType({required this.lookupKey, this.isProvider = false});

factory InjectedType.fromJson(Map<String, dynamic> json) =>
_$InjectedTypeFromJson(json);
factory InjectedType.fromJson(Map<String, dynamic> json) => InjectedType(
lookupKey: LookupKey.fromJson(json['lookupKey'] as Map<String, dynamic>),
isProvider: json['isProvider'] as bool? ?? false,
);

Map<String, dynamic> toJson() => _$InjectedTypeToJson(this);
Map<String, dynamic> toJson() => {
'lookupKey': lookupKey.toJson(),
'isProvider': isProvider,
};

@override
bool operator ==(Object other) =>
Expand Down
19 changes: 11 additions & 8 deletions package/inject_compile_generator/lib/src/models/lookup_key.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:meta/meta.dart';
import 'symbol_path.dart';

part 'lookup_key.g.dart';

/// A representation of a key in the dependency injection graph.
@immutable
@JsonSerializable()
class LookupKey {
/// The [SymbolPath] of the root type.
final SymbolPath root;
Expand All @@ -16,10 +12,17 @@ class LookupKey {

const LookupKey({required this.root, this.qualifier});

factory LookupKey.fromJson(Map<String, dynamic> json) =>
_$LookupKeyFromJson(json);

Map<String, dynamic> toJson() => _$LookupKeyToJson(this);
factory LookupKey.fromJson(Map<String, dynamic> json) => LookupKey(
root: SymbolPath.fromJson(json['root'] as Map<String, dynamic>),
qualifier: json['qualifier'] == null
? null
: SymbolPath.fromJson(json['qualifier'] as Map<String, dynamic>),
);

Map<String, dynamic> toJson() => {
'root': root.toJson(),
if (qualifier != null) 'qualifier': qualifier!.toJson(),
};

/// A human-readable string representation of this key.
String toPrettyString() {
Expand Down
110 changes: 85 additions & 25 deletions package/inject_compile_generator/lib/src/models/summary.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:meta/meta.dart';
import 'injected_type.dart';
import 'symbol_path.dart';

part 'summary.g.dart';

/// The kind of provider.
enum ProviderKind {
/// A method annotated with `@provide` in a module.
Expand All @@ -19,7 +16,6 @@ enum ProviderKind {

/// Metadata for a provider (method or constructor).
@immutable
@JsonSerializable()
class ProviderSummary {
/// The name of the method or constructor.
final String name;
Expand Down Expand Up @@ -49,14 +45,33 @@ class ProviderSummary {
});

factory ProviderSummary.fromJson(Map<String, dynamic> json) =>
_$ProviderSummaryFromJson(json);

Map<String, dynamic> toJson() => _$ProviderSummaryToJson(this);
ProviderSummary(
name: json['name'] as String,
resultType: InjectedType.fromJson(
json['resultType'] as Map<String, dynamic>,
),
kind: ProviderKind.values.byName(json['kind'] as String),
isSingleton: json['isSingleton'] as bool? ?? false,
isAsynchronous: json['isAsynchronous'] as bool? ?? false,
dependencies:
(json['dependencies'] as List<dynamic>?)
?.map((e) => InjectedType.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
);

Map<String, dynamic> toJson() => {
'name': name,
'resultType': resultType.toJson(),
'kind': kind.name,
'isSingleton': isSingleton,
'isAsynchronous': isAsynchronous,
'dependencies': dependencies.map((e) => e.toJson()).toList(),
};
}

/// Metadata for a module class.
@immutable
@JsonSerializable()
class ModuleSummary {
/// The class that defines the module.
final SymbolPath clazz;
Expand All @@ -66,15 +81,21 @@ class ModuleSummary {

const ModuleSummary({required this.clazz, required this.providers});

factory ModuleSummary.fromJson(Map<String, dynamic> json) =>
_$ModuleSummaryFromJson(json);

Map<String, dynamic> toJson() => _$ModuleSummaryToJson(this);
factory ModuleSummary.fromJson(Map<String, dynamic> json) => ModuleSummary(
clazz: SymbolPath.fromJson(json['clazz'] as Map<String, dynamic>),
providers: (json['providers'] as List<dynamic>)
.map((e) => ProviderSummary.fromJson(e as Map<String, dynamic>))
.toList(),
);

Map<String, dynamic> toJson() => {
'clazz': clazz.toJson(),
'providers': providers.map((e) => e.toJson()).toList(),
};
}

/// Metadata for an injector class.
@immutable
@JsonSerializable()
class InjectorSummary {
/// The abstract class that defines the injector.
final SymbolPath clazz;
Expand All @@ -92,14 +113,25 @@ class InjectorSummary {
});

factory InjectorSummary.fromJson(Map<String, dynamic> json) =>
_$InjectorSummaryFromJson(json);

Map<String, dynamic> toJson() => _$InjectorSummaryToJson(this);
InjectorSummary(
clazz: SymbolPath.fromJson(json['clazz'] as Map<String, dynamic>),
modules: (json['modules'] as List<dynamic>)
.map((e) => SymbolPath.fromJson(e as Map<String, dynamic>))
.toList(),
providers: (json['providers'] as List<dynamic>)
.map((e) => ProviderSummary.fromJson(e as Map<String, dynamic>))
.toList(),
);

Map<String, dynamic> toJson() => {
'clazz': clazz.toJson(),
'modules': modules.map((e) => e.toJson()).toList(),
'providers': providers.map((e) => e.toJson()).toList(),
};
}

/// Metadata for a class that can be injected (e.g. annotated with `@provide` on constructor).
@immutable
@JsonSerializable()
class InjectableSummary {
/// The class that is injectable.
final SymbolPath clazz;
Expand All @@ -110,14 +142,21 @@ class InjectableSummary {
const InjectableSummary({required this.clazz, required this.constructor});

factory InjectableSummary.fromJson(Map<String, dynamic> json) =>
_$InjectableSummaryFromJson(json);

Map<String, dynamic> toJson() => _$InjectableSummaryToJson(this);
InjectableSummary(
clazz: SymbolPath.fromJson(json['clazz'] as Map<String, dynamic>),
constructor: ProviderSummary.fromJson(
json['constructor'] as Map<String, dynamic>,
),
);

Map<String, dynamic> toJson() => {
'clazz': clazz.toJson(),
'constructor': constructor.toJson(),
};
}

/// The top-level summary for a Dart library.
@immutable
@JsonSerializable()
class LibrarySummary {
/// The URI of the library (asset scheme).
final String assetUri;
Expand All @@ -138,8 +177,29 @@ class LibrarySummary {
this.injectables = const [],
});

factory LibrarySummary.fromJson(Map<String, dynamic> json) =>
_$LibrarySummaryFromJson(json);

Map<String, dynamic> toJson() => _$LibrarySummaryToJson(this);
factory LibrarySummary.fromJson(Map<String, dynamic> json) => LibrarySummary(
assetUri: json['assetUri'] as String,
modules:
(json['modules'] as List<dynamic>?)
?.map((e) => ModuleSummary.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
injectors:
(json['injectors'] as List<dynamic>?)
?.map((e) => InjectorSummary.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
injectables:
(json['injectables'] as List<dynamic>?)
?.map((e) => InjectableSummary.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
);

Map<String, dynamic> toJson() => {
'assetUri': assetUri,
'modules': modules.map((e) => e.toJson()).toList(),
'injectors': injectors.map((e) => e.toJson()).toList(),
'injectables': injectables.map((e) => e.toJson()).toList(),
};
}
24 changes: 17 additions & 7 deletions package/inject_compile_generator/lib/src/models/symbol_path.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:meta/meta.dart';

part 'symbol_path.g.dart';

/// The absolute canonical location of a symbol within Dart.
@immutable
@JsonSerializable()
class SymbolPath {
/// The name of the package containing the Dart source code.
///
Expand Down Expand Up @@ -47,10 +43,24 @@ class SymbolPath {
: package = null,
path = null;

factory SymbolPath.fromJson(Map<String, dynamic> json) =>
_$SymbolPathFromJson(json);
factory SymbolPath.fromJson(Map<String, dynamic> json) => SymbolPath(
package: json['package'] as String?,
path: json['path'] as String?,
symbol: json['symbol'] as String,
typeArguments:
(json['typeArguments'] as List<dynamic>?)
?.map((e) => SymbolPath.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
);

Map<String, dynamic> toJson() => _$SymbolPathToJson(this);
Map<String, dynamic> toJson() => {
if (package != null) 'package': package,
if (path != null) 'path': path,
'symbol': symbol,
if (typeArguments.isNotEmpty)
'typeArguments': typeArguments.map((e) => e.toJson()).toList(),
};

/// Whether the [path] points within the Dart SDK, not a pub package.
bool get isDartSdk => package == 'dart';
Expand Down
2 changes: 0 additions & 2 deletions package/inject_compile_generator/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ dependencies:
build: ^4.0.6
code_builder: ^4.11.0
collection: ^1.19.1
json_annotation: ^4.12.0
logging: ^1.3.0
meta: ^1.18.0
path: ^1.9.0
Expand All @@ -26,6 +25,5 @@ dev_dependencies:
build_runner: ^2.15.0
build_test: ^3.5.15
inject_compile: ^0.9.0
json_serializable: ^6.14.0
lints: ^6.0.0
test: ^1.31.0
Loading