@@ -217,6 +217,7 @@ abstract class LinterContext {
217217 ///
218218 /// Note that this method can cause constant evaluation to occur, which can be
219219 /// computationally expensive.
220+ @Deprecated ('Use `expression.canBeConst`' )
220221 bool canBeConst (Expression expression);
221222
222223 /// Returns `true` if it would be valid for the given constructor declaration
@@ -227,6 +228,7 @@ abstract class LinterContext {
227228 ///
228229 /// Note that this method can cause constant evaluation to occur, which can be
229230 /// computationally expensive.
231+ @Deprecated ('Use `expression.canBeConstConstructor`' )
230232 bool canBeConstConstructor (ConstructorDeclaration node);
231233
232234 /// Returns `true` if the given [unit] is in a test directory.
@@ -304,35 +306,11 @@ class LinterContextImpl implements LinterContext {
304306 DeclaredVariables get declaredVariables => _declaredVariables;
305307
306308 @override
307- bool canBeConst (Expression expression) {
308- if (expression is InstanceCreationExpressionImpl ) {
309- return _canBeConstInstanceCreation (expression);
310- } else if (expression is TypedLiteralImpl ) {
311- return _canBeConstTypedLiteral (expression);
312- } else {
313- return false ;
314- }
315- }
309+ bool canBeConst (Expression expression) => expression.canBeConst;
316310
317311 @override
318- bool canBeConstConstructor (covariant ConstructorDeclarationImpl node) {
319- var element = node.declaredElement! ;
320-
321- var classElement = element.enclosingElement;
322- if (classElement is ClassElement && classElement.hasNonFinalField) {
323- return false ;
324- }
325-
326- var oldKeyword = node.constKeyword;
327- try {
328- temporaryConstConstructorElements[element] = true ;
329- node.constKeyword = KeywordToken (Keyword .CONST , node.offset);
330- return ! _hasConstantVerifierError (node);
331- } finally {
332- temporaryConstConstructorElements[element] = null ;
333- node.constKeyword = oldKeyword;
334- }
335- }
312+ bool canBeConstConstructor (covariant ConstructorDeclarationImpl node) =>
313+ node.canBeConst;
336314
337315 @override
338316 bool inTestDir (CompilationUnit unit) {
@@ -389,69 +367,6 @@ class LinterContextImpl implements LinterContext {
389367 return const LinterNameInScopeResolutionResult ._none ();
390368 }
391369
392- bool _canBeConstInstanceCreation (InstanceCreationExpressionImpl node) {
393- //
394- // Verify that the invoked constructor is a const constructor.
395- //
396- var element = node.constructorName.staticElement;
397- if (element == null || ! element.isConst) {
398- return false ;
399- }
400-
401- // Ensure that dependencies (e.g. default parameter values) are computed.
402- var implElement = element.declaration as ConstructorElementImpl ;
403- implElement.computeConstantDependencies ();
404-
405- //
406- // Verify that the evaluation of the constructor would not produce an
407- // exception.
408- //
409- var oldKeyword = node.keyword;
410- try {
411- node.keyword = KeywordToken (Keyword .CONST , node.offset);
412- return ! _hasConstantVerifierError (node);
413- } finally {
414- node.keyword = oldKeyword;
415- }
416- }
417-
418- bool _canBeConstTypedLiteral (TypedLiteralImpl node) {
419- var oldKeyword = node.constKeyword;
420- try {
421- node.constKeyword = KeywordToken (Keyword .CONST , node.offset);
422- return ! _hasConstantVerifierError (node);
423- } finally {
424- node.constKeyword = oldKeyword;
425- }
426- }
427-
428- /// Returns whether [ConstantVerifier] reports an error for the [node] .
429- bool _hasConstantVerifierError (AstNode node) {
430- var unitElement = currentUnit.unit.declaredElement! ;
431- var libraryElement = unitElement.library as LibraryElementImpl ;
432-
433- var dependenciesFinder = ConstantExpressionsDependenciesFinder ();
434- node.accept (dependenciesFinder);
435- computeConstants (
436- declaredVariables: _declaredVariables,
437- constants: dependenciesFinder.dependencies.toList (),
438- featureSet: libraryElement.featureSet,
439- configuration: ConstantEvaluationConfiguration (),
440- );
441-
442- var listener = _ConstantAnalysisErrorListener ();
443- var errorReporter = ErrorReporter (listener, unitElement.source);
444-
445- node.accept (
446- ConstantVerifier (
447- errorReporter,
448- libraryElement,
449- _declaredVariables,
450- ),
451- );
452- return listener.hasConstError;
453- }
454-
455370 static List <String > getTestDirectories (p.Context pathContext) {
456371 var separator = pathContext.separator;
457372 return [
@@ -873,7 +788,73 @@ enum _LinterNameInScopeResolutionResultState {
873788 differentName
874789}
875790
791+ extension on AstNode {
792+ /// Whether [ConstantVerifier] reports an error when computing the value of
793+ /// `this` as a constant.
794+ bool get hasConstantVerifierError {
795+ var unitElement = thisOrAncestorOfType <CompilationUnit >()? .declaredElement;
796+ if (unitElement == null ) return false ;
797+ var libraryElement = unitElement.library as LibraryElementImpl ;
798+
799+ var dependenciesFinder = ConstantExpressionsDependenciesFinder ();
800+ accept (dependenciesFinder);
801+ computeConstants (
802+ declaredVariables: unitElement.session.declaredVariables,
803+ constants: dependenciesFinder.dependencies.toList (),
804+ featureSet: libraryElement.featureSet,
805+ configuration: ConstantEvaluationConfiguration (),
806+ );
807+
808+ var listener = _ConstantAnalysisErrorListener ();
809+ var errorReporter = ErrorReporter (listener, unitElement.source);
810+
811+ accept (
812+ ConstantVerifier (
813+ errorReporter,
814+ libraryElement,
815+ unitElement.session.declaredVariables,
816+ ),
817+ );
818+ return listener.hasConstError;
819+ }
820+ }
821+
822+ extension ConstructorDeclarationExtension on ConstructorDeclaration {
823+ bool get canBeConst {
824+ var element = declaredElement! ;
825+
826+ var classElement = element.enclosingElement;
827+ if (classElement is ClassElement && classElement.hasNonFinalField) {
828+ return false ;
829+ }
830+
831+ var oldKeyword = constKeyword;
832+ var self = this as ConstructorDeclarationImpl ;
833+ try {
834+ temporaryConstConstructorElements[element] = true ;
835+ self.constKeyword = KeywordToken (Keyword .CONST , offset);
836+ return ! hasConstantVerifierError;
837+ } finally {
838+ temporaryConstConstructorElements[element] = null ;
839+ self.constKeyword = oldKeyword;
840+ }
841+ }
842+ }
843+
876844extension ExpressionExtension on Expression {
845+ /// Whether it would be valid for this expression to have a `const` keyword.
846+ ///
847+ /// Note that this method can cause constant evaluation to occur, which can be
848+ /// computationally expensive.
849+ bool get canBeConst {
850+ var self = this ;
851+ return switch (self) {
852+ InstanceCreationExpressionImpl () => _canBeConstInstanceCreation (self),
853+ TypedLiteralImpl () => _canBeConstTypedLiteral (self),
854+ _ => false ,
855+ };
856+ }
857+
877858 /// Computes the constant value of `this` , if it has one.
878859 ///
879860 /// Returns a [LinterConstantEvaluationResult] , containing both the computed
@@ -910,4 +891,33 @@ extension ExpressionExtension on Expression {
910891 var dartObject = constant is DartObjectImpl ? constant : null ;
911892 return LinterConstantEvaluationResult (dartObject, errorListener.errors);
912893 }
894+
895+ bool _canBeConstInstanceCreation (InstanceCreationExpressionImpl node) {
896+ var element = node.constructorName.staticElement;
897+ if (element == null || ! element.isConst) return false ;
898+
899+ // Ensure that dependencies (e.g. default parameter values) are computed.
900+ var implElement = element.declaration as ConstructorElementImpl ;
901+ implElement.computeConstantDependencies ();
902+
903+ // Verify that the evaluation of the constructor would not produce an
904+ // exception.
905+ var oldKeyword = node.keyword;
906+ try {
907+ node.keyword = KeywordToken (Keyword .CONST , offset);
908+ return ! hasConstantVerifierError;
909+ } finally {
910+ node.keyword = oldKeyword;
911+ }
912+ }
913+
914+ bool _canBeConstTypedLiteral (TypedLiteralImpl node) {
915+ var oldKeyword = node.constKeyword;
916+ try {
917+ node.constKeyword = KeywordToken (Keyword .CONST , offset);
918+ return ! hasConstantVerifierError;
919+ } finally {
920+ node.constKeyword = oldKeyword;
921+ }
922+ }
913923}
0 commit comments