Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix custom builders with import prefixes. #703

Merged
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
2 changes: 1 addition & 1 deletion built_value_generator/lib/src/value_source_class.dart
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ abstract class ValueSourceClass
if (hasBuilder) {
for (var field in fields) {
final type = field.typeInCompilationUnit(compilationUnit);
final typeInBuilder = field.typeInBuilder(compilationUnit);
final typeInBuilder = field.builderElementTypeWithPrefix;
final name = field.name;

if (field.isNestedBuilder) {
Expand Down
33 changes: 31 additions & 2 deletions built_value_generator/lib/src/value_source_field.dart
Original file line number Diff line number Diff line change
Expand Up @@ -124,15 +124,44 @@ abstract class ValueSourceField
// Try to get a resolved type first, it's faster.
var result = builderElement.getter?.returnType?.displayName;
if (result != null && result != 'dynamic') return result;
// Go via AST to allow use of unresolvable types not yet generated.
return parsedLibrary
// Go via AST to allow use of unresolvable types not yet generated;
// this includes generated Builder types.
result = parsedLibrary
.getElementDeclaration(builderElement)
?.node
?.parent
?.childEntities
?.first
.toString() ??
'dynamic';
// If we went via the AST there may be an import prefix, but we don't
// want one here. Strip it off.
if (result.contains('.')) {
result = result.substring(result.indexOf('.') + 1);
}
return result;
}

/// The [builderElementType] plus any import prefix.
@memoized
String get builderElementTypeWithPrefix {
// If it's a real field, it's a [VariableDeclaration] which is guaranteed
// to have parent node [VariableDeclarationList] giving the type.
var fieldDeclaration = parsedLibrary.getElementDeclaration(builderElement);
if (fieldDeclaration != null) {
return (((fieldDeclaration.node as VariableDeclaration).parent)
as VariableDeclarationList)
?.type
?.toSource() ??
'dynamic';
} else {
// Otherwise it's an explicit getter/setter pair; get the type from the getter.
return (parsedLibrary.getElementDeclaration(builderElement.getter).node
as MethodDeclaration)
?.returnType
?.toSource() ??
'dynamic';
}
}

/// Gets the type name for the builder. Specify the compilation unit to
Expand Down
5 changes: 5 additions & 0 deletions built_value_generator/lib/src/value_source_field.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 51 additions & 0 deletions end_to_end_test/lib/imported_values.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,54 @@ abstract class ImportedValue
_$ImportedValue;
ImportedValue._();
}

// With a custom builder.
abstract class ImportedCustomValue
implements Built<ImportedCustomValue, ImportedCustomValueBuilder> {
static Serializer<ImportedCustomValue> get serializer =>
_$importedCustomValueSerializer;

prefix.SimpleValue get simpleValue;
BuiltList<prefix.SimpleValue> get simpleValues;

factory ImportedCustomValue(
[void Function(ImportedCustomValueBuilder) updates]) =
_$ImportedCustomValue;
ImportedCustomValue._();
}

abstract class ImportedCustomValueBuilder
implements Builder<ImportedCustomValue, ImportedCustomValueBuilder> {
prefix.SimpleValue simpleValue;
BuiltList<prefix.SimpleValue> simpleValues;

ImportedCustomValueBuilder._();
factory ImportedCustomValueBuilder() = _$ImportedCustomValueBuilder;
}

// With a custom builder using nested buliders.
abstract class ImportedCustomNestedValue
implements
Built<ImportedCustomNestedValue, ImportedCustomNestedValueBuilder> {
static Serializer<ImportedCustomNestedValue> get serializer =>
_$importedCustomNestedValueSerializer;

prefix.SimpleValue get simpleValue;
BuiltList<prefix.SimpleValue> get simpleValues;

factory ImportedCustomNestedValue(
[void Function(ImportedCustomNestedValueBuilder) updates]) =
_$ImportedCustomNestedValue;
ImportedCustomNestedValue._();
}

abstract class ImportedCustomNestedValueBuilder
implements
Builder<ImportedCustomNestedValue, ImportedCustomNestedValueBuilder> {
prefix.SimpleValueBuilder simpleValue;
ListBuilder<prefix.SimpleValue> simpleValues;

ImportedCustomNestedValueBuilder._();
factory ImportedCustomNestedValueBuilder() =
_$ImportedCustomNestedValueBuilder;
}
Loading