Skip to content

Commit

Permalink
fix: Fatal SERVERPOD error in 'serverpod generate'. (serverpod#2975)
Browse files Browse the repository at this point in the history
  • Loading branch information
klkucaj authored Nov 26, 2024
1 parent b9bc89d commit 04e6ae0
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 979 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import 'package:serverpod_cli/src/analyzer/dart/endpoint_analyzers/endpoint_para
import 'package:serverpod_cli/src/analyzer/dart/definitions.dart';
import 'package:serverpod_cli/src/analyzer/dart/element_extensions.dart';
import 'package:serverpod_cli/src/generator/types.dart';
import 'package:serverpod_cli/src/analyzer/dart/endpoint_analyzers/keywords.dart';
import 'extension/endpoint_parameters_extension.dart';

const _excludedMethodNameSet = {
'streamOpened',
Expand All @@ -32,8 +32,7 @@ abstract class EndpointMethodAnalyzer {
name: method.name,
documentationComment: method.documentationComment,
annotations: _parseAnnotations(dartElement: method),
// TODO: Move removal of session parameter to Parameter analyzer
parameters: parameters.required.sublist(1), // Skip session parameter,
parameters: parameters.required,
parametersNamed: parameters.named,
parametersPositional: parameters.positional,
returnType: TypeDefinition.fromDartType(method.returnType),
Expand All @@ -44,8 +43,7 @@ abstract class EndpointMethodAnalyzer {
name: method.name,
documentationComment: method.documentationComment,
annotations: _parseAnnotations(dartElement: method),
// TODO: Move removal of session parameter to Parameter analyzer
parameters: parameters.required.sublist(1), // Skip session parameter,
parameters: parameters.required,
parametersNamed: parameters.named,
parametersPositional: parameters.positional,
returnType: TypeDefinition.fromDartType(method.returnType),
Expand All @@ -72,9 +70,7 @@ abstract class EndpointMethodAnalyzer {

if (_excludedMethodNameSet.contains(method.name)) return false;

if (_missingSessionParameter(method.parameters)) return false;

return true;
return method.parameters.isFirstRequiredParameterSession;
}

/// Validates the [MethodElement] and returns a list of
Expand All @@ -91,17 +87,6 @@ abstract class EndpointMethodAnalyzer {
return errors.whereType<SourceSpanSeverityException>().toList();
}

static bool _missingSessionParameter(List<ParameterElement> parameters) {
if (parameters.isEmpty) return true;

bool firstParameterIsNotSession =
parameters.first.type.element?.displayName != Keyword.sessionClassName;

return firstParameterIsNotSession ||
parameters.first.isNamed ||
parameters.first.isOptional;
}

static SourceSpanSeverityException? _validateReturnType({
required DartType dartType,
required Element dartElement,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import 'package:analyzer/dart/element/type.dart';
import 'package:serverpod_cli/src/analyzer/code_analysis_collector.dart';
import 'package:serverpod_cli/src/analyzer/dart/definitions.dart';
import 'package:serverpod_cli/src/analyzer/dart/element_extensions.dart';
import 'package:serverpod_cli/src/analyzer/dart/endpoint_analyzers/keywords.dart';
import 'package:serverpod_cli/src/analyzer/dart/endpoint_analyzers/extension/endpoint_parameters_extension.dart';

import 'package:serverpod_cli/src/generator/types.dart';

abstract class EndpointParameterAnalyzer {
Expand All @@ -17,7 +18,8 @@ abstract class EndpointParameterAnalyzer {
var positionalParameters = <ParameterDefinition>[];
var namedParameters = <ParameterDefinition>[];

for (var parameter in parameters) {
var filteredParameters = parameters.withoutSessionParameter;
for (var parameter in filteredParameters) {
var definition = ParameterDefinition(
name: parameter.name,
required: _isRequired(parameter),
Expand Down Expand Up @@ -46,18 +48,25 @@ abstract class EndpointParameterAnalyzer {
) {
List<SourceSpanSeverityException> exceptions = [];

bool firstParameterIsSession = parameters.isNotEmpty &&
parameters.first.type.element?.displayName == Keyword.sessionClassName;

if (firstParameterIsSession) {
bool sessionIsNullable =
parameters.first.type.nullabilitySuffix != NullabilitySuffix.none;
if (sessionIsNullable) {
exceptions.add(SourceSpanSeverityException(
'The "Session" argument in an endpoint method does not have to be nullable, consider making it non-nullable.',
parameters.first.span,
severity: SourceSpanSeverity.hint));
}
if (!parameters.isFirstRequiredParameterSession) {
exceptions.add(
SourceSpanSeverityException(
'The first parameter of an endpoint method must be a required positional parameter of type "Session".',
parameters.first.span,
severity: SourceSpanSeverity.error,
),
);
return exceptions;
}

if (parameters.isSessionParameterNullable) {
exceptions.add(
SourceSpanSeverityException(
'The "Session" argument in an endpoint method does not have to be nullable, consider making it non-nullable.',
parameters.first.span,
severity: SourceSpanSeverity.hint,
),
);
}

exceptions.addAll(parameters.map((parameter) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:serverpod_cli/src/analyzer/dart/endpoint_analyzers/keywords.dart';

/// Extension for [List<ParameterElement>] to analyze endpoint parameters.
extension EndpointParametersExtension on List<ParameterElement> {
/// Returns true if the first required parameter is a session parameter.
bool get isFirstRequiredParameterSession {
if (isEmpty) return false;

var parameter = first;

return parameter.type.element?.displayName == Keyword.sessionClassName &&
parameter.isRequiredPositional;
}

bool get isSessionParameterNullable {
return first.type.nullabilitySuffix != NullabilitySuffix.none;
}

/// Returns a list of parameters without the session parameter.
List<ParameterElement> get withoutSessionParameter {
return where((parameter) =>
parameter.type.element?.displayName != Keyword.sessionClassName)
.toList();
}
}
Loading

0 comments on commit 04e6ae0

Please sign in to comment.