@@ -58,7 +58,7 @@ class _SpecBuilder implements Builder {
5858 if (ast == null ) continue ;
5959
6060 // Visit the AST to find function declarations
61- final visitor = _FirebaseFunctionsVisitor (resolver );
61+ final visitor = _FirebaseFunctionsVisitor ();
6262 ast.accept (visitor);
6363
6464 // Collect discovered functions and parameters
@@ -97,7 +97,7 @@ class _Namespace {
9797
9898/// AST visitor that discovers Firebase Functions declarations.
9999class _FirebaseFunctionsVisitor extends RecursiveAstVisitor <void > {
100- _FirebaseFunctionsVisitor (this .resolver ) {
100+ _FirebaseFunctionsVisitor () {
101101 namespaces = < _Namespace > [
102102 _Namespace (
103103 _extractHttpsFunction,
@@ -213,7 +213,7 @@ class _FirebaseFunctionsVisitor extends RecursiveAstVisitor<void> {
213213 ),
214214 ];
215215 }
216- final Resolver resolver;
216+
217217 final Map <String , ParamSpec > params = {};
218218 final Map <String , EndpointSpec > endpoints = {};
219219 late final List <_Namespace > namespaces;
@@ -224,6 +224,7 @@ class _FirebaseFunctionsVisitor extends RecursiveAstVisitor<void> {
224224
225225 @override
226226 void visitMethodInvocation (MethodInvocation node) {
227+ super .visitMethodInvocation (node);
227228 final target = node.target;
228229 final methodName = node.methodName.name;
229230 if (target != null ) {
@@ -1035,29 +1036,14 @@ class _FirebaseFunctionsVisitor extends RecursiveAstVisitor<void> {
10351036 String ? _extractStringField (
10361037 InstanceCreationExpression node,
10371038 String fieldName,
1038- ) => node.argumentList.arguments
1039- .whereType <NamedExpression >()
1040- .where ((e) => e.name.label.name == fieldName)
1041- .map ((e) => e.expression)
1042- .whereType <StringLiteral >()
1043- .map ((e) => e.stringValue! )
1044- .firstOrNull;
1039+ ) {
1040+ final arg = node.argumentList.arguments
1041+ .whereType <NamedExpression >()
1042+ .where ((e) => e.name.label.name == fieldName)
1043+ .map ((e) => e.expression)
1044+ .firstOrNull;
10451045
1046- /// Extracts a constant value from an expression.
1047- Object ? _extractConstValue (Expression expression) {
1048- return switch (expression) {
1049- StringLiteral () => expression.stringValue,
1050- IntegerLiteral () => expression.value,
1051- DoubleLiteral () => expression.value,
1052- BooleanLiteral () => expression.value,
1053- ListLiteral () =>
1054- expression.elements
1055- .whereType <Expression >()
1056- .map (_extractConstValue)
1057- .whereType <dynamic >()
1058- .toList (),
1059- _ => null ,
1060- };
1046+ return _extractStringLiteral (arg);
10611047 }
10621048}
10631049
@@ -1078,6 +1064,55 @@ extension on MethodInvocation {
10781064 }
10791065}
10801066
1081- /// Extracts a string literal value.
1082- String ? _extractStringLiteral (Expression ? expression) =>
1083- expression is StringLiteral ? expression.stringValue : null ;
1067+ /// Extracts a string literal or constant value.
1068+ String ? _extractStringLiteral (Expression ? expression) {
1069+ if (expression == null ) return null ;
1070+ final value = _extractConstValue (expression);
1071+ return value is String ? value : null ;
1072+ }
1073+
1074+ /// Extracts a constant value from an expression.
1075+ Object ? _extractConstValue (Expression expression) {
1076+ final literal = switch (expression) {
1077+ StringLiteral () => expression.stringValue,
1078+ IntegerLiteral () => expression.value,
1079+ DoubleLiteral () => expression.value,
1080+ BooleanLiteral () => expression.value,
1081+ ListLiteral () =>
1082+ expression.elements
1083+ .whereType <Expression >()
1084+ .map (_extractConstValue)
1085+ .whereType <Object >()
1086+ .toList (),
1087+ _ => null ,
1088+ };
1089+
1090+ if (literal != null ) return literal;
1091+
1092+ // Try to evaluate as constant if it's an identifier or property access
1093+ Element ? element;
1094+ if (expression is SimpleIdentifier ) {
1095+ element = expression.element;
1096+ } else if (expression is PrefixedIdentifier ) {
1097+ element = expression.element;
1098+ } else if (expression is PropertyAccess ) {
1099+ element = expression.propertyName.element;
1100+ }
1101+
1102+ if (element is PropertyAccessorElement ) {
1103+ element = element.variable;
1104+ }
1105+
1106+ if (element is VariableElement && element.isConst) {
1107+ final constant = element.computeConstantValue ();
1108+ if (constant != null ) {
1109+ final reader = ConstantReader (constant);
1110+ if (reader.isString) return reader.stringValue;
1111+ if (reader.isInt) return reader.intValue;
1112+ if (reader.isDouble) return reader.doubleValue;
1113+ if (reader.isBool) return reader.boolValue;
1114+ }
1115+ }
1116+
1117+ return null ;
1118+ }
0 commit comments