Skip to content

Commit

Permalink
Adding support for top level variables
Browse files Browse the repository at this point in the history
  • Loading branch information
martinale14 committed Aug 29, 2023
1 parent c7b67a6 commit 1cd0691
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 13 deletions.
2 changes: 2 additions & 0 deletions chopper/lib/src/annotations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import 'package:meta/meta.dart';
@immutable
final class ChopperApi {
/// A part of a URL that every request defined inside a class annotated with [ChopperApi] will be prefixed with.
///
/// The `baseUrl` can be a top level constant string variable.
final String baseUrl;

const ChopperApi({
Expand Down
75 changes: 62 additions & 13 deletions chopper_generator/lib/src/generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,21 @@ final class ChopperGenerator

final String friendlyName = element.name;
final String name = '_\$$friendlyName';
final String baseUrl =
annotation.peek(Vars.baseUrl.toString())?.stringValue ?? '';

final ConstantReader? baseUrlReader =
annotation.peek(Vars.baseUrl.toString());

TopLevelVariableElement? baseUrlVariableElement;

final VariableElement? posibleBaseUrl = baseUrlReader?.objectValue.variable;

if (posibleBaseUrl is TopLevelVariableElement &&
posibleBaseUrl.type.isDartCoreString &&
posibleBaseUrl.isConst) {
baseUrlVariableElement = posibleBaseUrl;
}

final String baseUrl = baseUrlReader?.stringValue ?? '';

final Class classBuilder = Class((builder) {
builder
Expand All @@ -73,7 +86,11 @@ final class ChopperGenerator
..extend = refer(friendlyName)
..fields.add(_buildDefinitionTypeMethod(friendlyName))
..constructors.add(_generateConstructor())
..methods.addAll(_parseMethods(element, baseUrl));
..methods.addAll(_parseMethods(
element,
baseUrl,
baseUrlVariableElement,
));
});

const String ignore = '// ignore_for_file: '
Expand Down Expand Up @@ -102,17 +119,31 @@ final class ChopperGenerator
},
);

static Iterable<Method> _parseMethods(ClassElement element, String baseUrl) =>
static Iterable<Method> _parseMethods(
ClassElement element,
String baseUrl,
TopLevelVariableElement? baseUrlVariableElement,
) =>
element.methods
.where(
(MethodElement method) =>
_getMethodAnnotation(method) != null &&
method.isAbstract &&
method.returnType.isDartAsyncFuture,
)
.map((MethodElement m) => _generateMethod(m, baseUrl));
.map(
(MethodElement m) => _generateMethod(
m,
baseUrl,
baseUrlVariableElement,
),
);

static Method _generateMethod(MethodElement m, String baseUrl) {
static Method _generateMethod(
MethodElement m,
String baseUrl,
TopLevelVariableElement? baseUrlVariableElement,
) {
final ConstantReader? method = _getMethodAnnotation(m);
final bool multipart = _hasAnnotation(m, chopper.Multipart);
final ConstantReader? factoryConverter = _getFactoryConverterAnnotation(m);
Expand All @@ -138,7 +169,12 @@ final class ChopperGenerator
_getAnnotation(m, chopper.PartFileMap);

final Code? headers = _generateHeaders(m, method!);
final Expression url = _generateUrl(method, paths, baseUrl);
final Expression url = _generateUrl(
method,
paths,
baseUrl,
baseUrlVariableElement,
);
final DartType? responseType = _getResponseType(m.returnType);
final DartType? responseInnerType =
_getResponseInnerType(m.returnType) ?? responseType;
Expand Down Expand Up @@ -481,6 +517,7 @@ final class ChopperGenerator
ConstantReader method,
Map<ParameterElement, ConstantReader> paths,
String baseUrl,
TopLevelVariableElement? baseUrlVariableElement,
) {
String path = Utils.getMethodPath(method);
paths.forEach((p, ConstantReader r) {
Expand All @@ -498,14 +535,26 @@ final class ChopperGenerator
return _generateUri('');
}

if (path.isNotEmpty &&
baseUrl.isNotEmpty &&
!baseUrl.endsWith('/') &&
!path.startsWith('/')) {
return _generateUri('$baseUrl/$path');
String finalBaseUrl = baseUrl;

if (baseUrlVariableElement != null) {
finalBaseUrl = '\${${baseUrlVariableElement.displayName}}';
}

if (path.isNotEmpty && baseUrl.isNotEmpty) {
bool pathHasSlash = path.startsWith('/');
bool baseUrlHasSlash = baseUrl.endsWith('/');

if ((!baseUrlHasSlash && !pathHasSlash)) {
return _generateUri('$finalBaseUrl/$path');
}

if (baseUrlHasSlash && pathHasSlash) {
return _generateUri('$finalBaseUrl${path.replaceFirst('/', '')}');
}
}

return _generateUri('$baseUrl$path');
return _generateUri('$finalBaseUrl$path'.replaceAll('//', '/'));
}

static Expression _generateUri(String url) =>
Expand Down

0 comments on commit 1cd0691

Please sign in to comment.