DAS: Extract static code from static class Flutter.

Most methods are refactored as extension methods. Some unused ones are deleted.
Some are inlined into their call sites.

Change-Id: I47826fd3241db86526efa2ee410990a0fc7be702
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/362300
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
This commit is contained in:
Sam Rawlins
2024-04-12 19:28:54 +00:00
committed by Commit Queue
parent 684f8639d1
commit cda4f034ed
42 changed files with 778 additions and 845 deletions
@@ -9,7 +9,7 @@ import 'package:analysis_server/src/services/refactoring/legacy/naming_conventio
import 'package:analysis_server/src/services/refactoring/legacy/refactoring.dart';
import 'package:analysis_server/src/services/search/hierarchy.dart';
import 'package:analysis_server/src/utilities/change_builder.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/source/line_info.dart';
@@ -81,9 +81,9 @@ class CanRenameResponse {
}
FlutterWidgetState? _findFlutterStateClass(Element element, String newName) {
if (Flutter.isStatefulWidgetDeclaration(element)) {
if (element is ClassElement && element.isStatefulWidgetDeclaration) {
var oldStateName = '${element.displayName}State';
var library = element.library!;
var library = element.library;
var state =
library.getClass(oldStateName) ?? library.getClass('_$oldStateName');
if (state != null) {
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
@@ -55,7 +55,7 @@ class ColorComputer {
String? memberName,
int? index,
}) {
if (!Flutter.isColor(expression.staticType)) return false;
if (!expression.staticType.isColor) return false;
target ??= expression;
@@ -80,7 +80,7 @@ class ColorComputer {
/// because they are not const) but are simple well-known dart:ui/Flutter
/// color constructors that we can manually parse.
bool tryAddKnownColorConstructor(InstanceCreationExpression expression) {
if (!Flutter.isColor(expression.staticType)) return false;
if (!expression.staticType.isColor) return false;
final constructor = expression.constructorName;
final staticElement = constructor.staticElement;
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/collections.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
@@ -482,14 +482,14 @@ class _FunctionBodyOutlinesVisitor extends RecursiveAstVisitor<void> {
@override
void visitInstanceCreationExpression(InstanceCreationExpression node) {
if (outlineComputer.withBasicFlutter && Flutter.isWidgetCreation(node)) {
if (outlineComputer.withBasicFlutter && node.isWidgetCreation) {
var children = <Outline>[];
node.argumentList
.accept(_FunctionBodyOutlinesVisitor(outlineComputer, children));
// The method `getWidgetPresentationText` should not return `null` when
// `isWidgetCreation` returns `true`.
var text = Flutter.getWidgetPresentationText(node) ?? '<unknown>';
var text = node.widgetPresentationText ?? '<unknown>';
var element = Element(ElementKind.CONSTRUCTOR_INVOCATION, text, 0,
location: outlineComputer._getLocationOffsetLength(node.offset, 0));
@@ -4,7 +4,7 @@
import 'package:analysis_server/src/computer/computer_outline.dart';
import 'package:analysis_server/src/protocol_server.dart' as protocol;
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
@@ -129,7 +129,7 @@ class FlutterOutlineComputer {
/// a widget reference outline item.
protocol.FlutterOutline? _createOutline(Expression node, bool withGeneric) {
var type = node.staticType;
if (type is! InterfaceType || !Flutter.isWidgetType(type)) {
if (type is! InterfaceType || !type.isWidgetType) {
return null;
}
var className = type.element.displayName;
@@ -138,11 +138,6 @@ class FlutterOutlineComputer {
var attributes = <protocol.FlutterOutlineAttribute>[];
var children = <protocol.FlutterOutline>[];
for (var argument in node.argumentList.arguments) {
var argumentType = argument.staticType;
var isWidgetArgument = Flutter.isWidgetType(argumentType);
var isWidgetListArgument =
argumentType != null && Flutter.isListOfWidgetsType(argumentType);
String? parentAssociationLabel;
Expression childrenExpression;
@@ -174,6 +169,11 @@ class FlutterOutlineComputer {
}
}
var argumentType = argument.staticType;
var isWidgetArgument = argumentType.isWidgetType;
var isWidgetListArgument =
argumentType != null && argumentType.isListOfWidgetsType;
if (isWidgetArgument && childrenExpression is ConditionalExpression) {
addChildrenFrom(childrenExpression.thenExpression);
addChildrenFrom(childrenExpression.elseExpression);
@@ -6,7 +6,6 @@ import 'package:analysis_server/lsp_protocol/protocol.dart';
import 'package:analysis_server/src/lsp/error_or.dart';
import 'package:analysis_server/src/lsp/handlers/handlers.dart';
import 'package:analysis_server/src/lsp/mapping.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -135,8 +134,7 @@ class DocumentColorPresentationHandler extends SharedMessageHandler<
final editRange = SourceRange(editStart, editEnd - editStart);
final sessionHelper = AnalysisSessionHelper(unit.session);
final colorType =
await sessionHelper.getClass(Flutter.widgetsUri, 'Color');
final colorType = await sessionHelper.getFlutterClass('Color');
if (colorType == null) {
// If we can't find the class (perhaps because this isn't a Flutter
// project) we will not include any results. In theory the client should
@@ -29,7 +29,7 @@ import 'package:analysis_server/src/server/diagnostic_server.dart';
import 'package:analysis_server/src/server/error_notifier.dart';
import 'package:analysis_server/src/server/performance.dart';
import 'package:analysis_server/src/services/user_prompts/dart_fix_prompt_manager.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analysis_server/src/utilities/process.dart';
import 'package:analyzer/dart/analysis/context_locator.dart';
import 'package:analyzer/dart/analysis/results.dart';
@@ -1016,13 +1016,13 @@ class LspAnalysisServer extends AnalysisServer {
);
}
/// Checks whether [file] is in a project that can resolve 'package:flutter'
/// libraries.
/// Returns whether [filePath] is in a project that can resolve
/// 'package:flutter' libraries.
bool _isInFlutterProject(String filePath) =>
getAnalysisDriver(filePath)
?.currentSession
.uriConverter
.uriToPath(Uri.parse(Flutter.widgetsUri)) !=
.uriToPath(Uri.parse(widgetsUri)) !=
null;
void _notifyPluginsOverlayChanged(
@@ -14,8 +14,8 @@ import 'package:analysis_server/src/services/completion/dart/uri_helper.dart';
import 'package:analysis_server/src/services/completion/dart/visibility_tracker.dart';
import 'package:analysis_server/src/utilities/extensions/ast.dart';
import 'package:analysis_server/src/utilities/extensions/completion_request.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/object.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/syntactic_entity.dart';
@@ -345,7 +345,7 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
appendComma = true;
}
} else if (parent is InstanceCreationExpression &&
Flutter.isWidgetCreation(parent)) {
parent.isWidgetCreation) {
appendComma = true;
}
int? replacementLength;
@@ -16,7 +16,7 @@ import 'package:analysis_server/src/services/completion/dart/feature_computer.da
import 'package:analysis_server/src/services/completion/dart/utilities.dart';
import 'package:analysis_server/src/utilities/extensions/ast.dart';
import 'package:analysis_server/src/utilities/extensions/element.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
@@ -776,7 +776,7 @@ class SuggestionBuilder {
var enclosingElement = method.enclosingElement;
if (method.name == 'setState' &&
enclosingElement is ClassElement &&
Flutter.isExactState(enclosingElement)) {
enclosingElement.isExactState) {
// TODO(brianwilkerson): Make this more efficient by creating the correct
// suggestion in the first place.
// Find the line indentation.
@@ -844,11 +844,11 @@ class SuggestionBuilder {
var selectionOffset = completion.length;
// Optionally add Flutter child widget details.
// TODO(pq): revisit this special casing; likely it can be generalized away
// TODO(pq): revisit this special casing; likely it can be generalized away.
var element = parameter.enclosingElement;
// If appendColon is false, default values should never be appended.
// If `appendColon` is false, default values should never be appended.
if (element is ConstructorElement && appendColon) {
if (Flutter.isWidget(element.enclosingElement.augmented.declaration)) {
if (element.enclosingElement.augmented.declaration.isWidget) {
var analysisOptions = request.analysisSession.analysisContext
.getAnalysisOptionsForFile(
request.resourceProvider.getFile(request.path));
@@ -5,7 +5,7 @@
import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
@@ -45,7 +45,7 @@ class AddDiagnosticPropertyReference extends ResolvedCorrectionProducer {
final classDeclaration = node.thisOrAncestorOfType<ClassDeclaration>();
if (classDeclaration == null ||
!Flutter.isDiagnosticable(classDeclaration.declaredElement!.thisType)) {
!classDeclaration.declaredElement!.thisType.isDiagnosticable) {
return;
}
@@ -74,9 +74,9 @@ class AddDiagnosticPropertyReference extends ResolvedCorrectionProducer {
} else if (_isIterable(type)) {
constructorId = 'IterableProperty';
typeArgs = (type as InterfaceType).typeArguments;
} else if (Flutter.isColor(type)) {
} else if (type.isColor) {
constructorId = 'ColorProperty';
} else if (Flutter.isMatrix4(type)) {
} else if (type.isMatrix4) {
constructorId = 'TransformProperty';
} else {
constructorId = 'DiagnosticsProperty';
@@ -4,7 +4,7 @@
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/generated/error_verifier.dart';
@@ -39,8 +39,8 @@ class AddFieldFormalParameters extends ResolvedCorrectionProducer {
fields.sort((a, b) => a.nameOffset - b.nameOffset);
// Specialize for Flutter widgets.
if (Flutter.isExactlyStatelessWidgetType(superType) ||
Flutter.isExactlyStatefulWidgetType(superType)) {
if (superType.isExactlyStatelessWidgetType ||
superType.isExactlyStatefulWidgetType) {
if (parameters.isNotEmpty && parameters.last.isNamed) {
String parameterForField(FieldElement field) {
var prefix = '';
@@ -4,7 +4,6 @@
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
@@ -161,7 +160,7 @@ class AddKeyToConstructors extends ResolvedCorrectionProducer {
/// Return the type for the class `Key`.
Future<DartType?> _getKeyType() async {
var keyClass = await sessionHelper.getClass(Flutter.widgetsUri, 'Key');
var keyClass = await sessionHelper.getFlutterClass('Key');
if (keyClass == null) {
return null;
}
@@ -6,7 +6,7 @@ import 'package:_fe_analyzer_shared/src/scanner/token.dart';
import 'package:analysis_server/src/services/completion/dart/utilities.dart';
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
@@ -85,10 +85,8 @@ class AddMissingRequiredArgument extends ResolvedCorrectionProducer {
offset = lastArgument.end;
hasTrailingComma = lastArgument.endToken.next!.type == TokenType.COMMA;
if (lastArgument is NamedExpression &&
Flutter.isWidgetExpression(creation)) {
if (Flutter.isChildArgument(lastArgument) ||
Flutter.isChildrenArgument(lastArgument)) {
if (lastArgument is NamedExpression && creation.isWidgetExpression) {
if (lastArgument.isChildArgument || lastArgument.isChildrenArgument) {
offset = lastArgument.offset;
hasTrailingComma = true;
insertBetweenParams = true;
@@ -123,7 +121,7 @@ class AddMissingRequiredArgument extends ResolvedCorrectionProducer {
builder.addSimpleLinkedEdit('VALUE', 'null');
}
if (Flutter.isWidgetExpression(creation)) {
if (creation.isWidgetExpression) {
// Insert a trailing comma after Flutter instance creation params.
if (!hasTrailingComma) {
builder.write(',');
@@ -4,8 +4,9 @@
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/source/source_range.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';
@@ -16,33 +17,55 @@ class ConvertFlutterChild extends ResolvedCorrectionProducer {
@override
Future<void> compute(ChangeBuilder builder) async {
var named = Flutter.findNamedExpression(node, 'child');
var named = node.findArgumentNamed('child');
if (named == null) {
return;
}
// child: widget
var expression = named.expression;
if (Flutter.isWidgetExpression(expression)) {
if (expression.isWidgetExpression) {
await builder.addDartFileEdit(file, (builder) {
Flutter.convertChildToChildren2(
builder,
expression,
named,
eol,
utils.getNodeText,
utils.getLinePrefix,
utils.oneIndent,
utils.getText,
utils.replaceSourceIndent,
range.node);
var childLoc = named.offset + 'child'.length;
builder.addSimpleInsertion(childLoc, 'ren');
var listLoc = expression.offset;
var childArgSrc = utils.getNodeText(expression);
if (!childArgSrc.contains(eol)) {
builder.addSimpleInsertion(listLoc, '[');
builder.addSimpleInsertion(listLoc + expression.length, ']');
} else {
var newlineLoc = childArgSrc.lastIndexOf(eol);
if (newlineLoc == childArgSrc.length) {
newlineLoc -= 1;
}
var indentOld =
utils.getLinePrefix(expression.offset + eol.length + newlineLoc);
var indentNew = '$indentOld${utils.oneIndent}';
// The separator includes 'child:' but that has no newlines.
var separator =
utils.getText(named.offset, expression.offset - named.offset);
var prefix = separator.contains(eol) ? '' : '$eol$indentNew';
if (prefix.isEmpty) {
builder.addSimpleInsertion(named.offset + 'child:'.length, ' [');
builder.addDeletion(SourceRange(expression.offset - 2, 2));
} else {
builder.addSimpleInsertion(listLoc, '[');
}
var newChildArgSrc = utils.replaceSourceIndent(
childArgSrc,
indentOld,
indentNew,
);
newChildArgSrc = '$prefix$newChildArgSrc,$eol$indentOld]';
builder.addSimpleReplacement(range.node(expression), newChildArgSrc);
}
});
return;
}
// child: [widget1, widget2]
if (expression is ListLiteral &&
expression.elements.every(Flutter.isWidgetExpression)) {
expression.elements.every((e) => e.isWidgetExpression)) {
await builder.addDartFileEdit(file, (builder) {
builder.addSimpleReplacement(range.node(named.name), 'children:');
});
@@ -4,7 +4,7 @@
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
@@ -23,7 +23,7 @@ class ConvertFlutterChildren extends ResolvedCorrectionProducer {
var expression = namedExpression.expression;
if (expression is ListLiteral && expression.elements.length == 1) {
var widget = expression.elements[0];
if (Flutter.isWidgetExpression(widget)) {
if (widget.isWidgetExpression) {
var widgetText = utils.getNodeText(widget);
var indentOld = utils.getLinePrefix(widget.offset);
var indentNew = utils.getLinePrefix(namedExpression.offset);
@@ -4,8 +4,8 @@
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/object.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -77,8 +77,8 @@ class CreateConstructorForFinalFields extends ResolvedCorrectionProducer {
return;
}
if (Flutter.isExactlyStatelessWidgetType(superType) ||
Flutter.isExactlyStatefulWidgetType(superType)) {
if (superType.isExactlyStatelessWidgetType ||
superType.isExactlyStatefulWidgetType) {
await _forFlutterWidget(
fixContext: fixContext, classDeclaration: container);
} else {
@@ -142,7 +142,7 @@ class CreateConstructorForFinalFields extends ResolvedCorrectionProducer {
required _FixContext fixContext,
required NamedCompilationUnitMember classDeclaration,
}) async {
final keyClass = await sessionHelper.getClass(Flutter.widgetsUri, 'Key');
final keyClass = await sessionHelper.getFlutterClass('Key');
if (keyClass == null) {
return;
}
@@ -4,7 +4,7 @@
import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer_plugin/utilities/assist/assist.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
@@ -27,7 +27,7 @@ class FlutterConvertToChildren extends ResolvedCorrectionProducer {
parent2 is NamedExpression &&
node.name == 'child' &&
node.staticElement != null &&
Flutter.isWidgetExpression(parent2.expression)) {
parent2.expression.isWidgetExpression) {
namedExp = parent2;
} else {
return;
@@ -5,7 +5,7 @@
import 'package:_fe_analyzer_shared/src/scanner/token.dart';
import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -38,7 +38,7 @@ class FlutterConvertToStatefulWidget extends ResolvedCorrectionProducer {
// Must be a StatelessWidget subclass.
var widgetClassElement = widgetClass.declaredElement!;
var superType = widgetClassElement.supertype;
if (superType == null || !Flutter.isExactlyStatelessWidgetType(superType)) {
if (superType == null || !superType.isExactlyStatelessWidgetType) {
return;
}
@@ -104,14 +104,9 @@ class FlutterConvertToStatefulWidget extends ResolvedCorrectionProducer {
return SourceEdit.applySequence(text, visitor.edits.reversed);
}
var statefulWidgetClass = await sessionHelper.getClass(
Flutter.widgetsUri,
'StatefulWidget',
);
var stateClass = await sessionHelper.getClass(
Flutter.widgetsUri,
'State',
);
var statefulWidgetClass =
await sessionHelper.getFlutterClass('StatefulWidget');
var stateClass = await sessionHelper.getFlutterClass('State');
if (statefulWidgetClass == null || stateClass == null) {
return;
}
@@ -5,7 +5,7 @@
import 'package:_fe_analyzer_shared/src/scanner/token.dart';
import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -37,7 +37,7 @@ class FlutterConvertToStatelessWidget extends ResolvedCorrectionProducer {
// Must be a StatefulWidget subclass.
var widgetClassElement = widgetClass.declaredElement!;
var superType = widgetClassElement.supertype;
if (superType == null || !Flutter.isExactlyStatefulWidgetType(superType)) {
if (superType == null || !superType.isExactlyStatefulWidgetType) {
return;
}
@@ -124,10 +124,8 @@ class FlutterConvertToStatelessWidget extends ResolvedCorrectionProducer {
return SourceEdit.applySequence(text, visitor.edits.reversed);
}
var statelessWidgetClass = await sessionHelper.getClass(
Flutter.widgetsUri,
'StatelessWidget',
);
var statelessWidgetClass =
await sessionHelper.getFlutterClass('StatelessWidget');
if (statelessWidgetClass == null) {
return;
}
@@ -259,7 +257,7 @@ class FlutterConvertToStatelessWidget extends ResolvedCorrectionProducer {
}
var classElement = type.element;
return classElement is ClassElement && Flutter.isExactState(classElement);
return classElement is ClassElement && classElement.isExactState;
}
}
@@ -367,7 +365,7 @@ class _StatelessVerifier extends RecursiveAstVisitor<void> {
if (methodElement is ClassMemberElement) {
var classElement = methodElement.enclosingElement;
if (classElement is ClassElement &&
Flutter.isExactState(classElement) &&
classElement.isExactState &&
!FlutterConvertToStatelessWidget._isDefaultOverride(
node.thisOrAncestorOfType<MethodDeclaration>())) {
canBeStateless = false;
@@ -4,7 +4,7 @@
import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/utilities/assist/assist.dart';
@@ -17,7 +17,7 @@ class FlutterMoveDown extends ResolvedCorrectionProducer {
@override
Future<void> compute(ChangeBuilder builder) async {
var widget = Flutter.identifyWidgetExpression(node);
var widget = node.findWidgetExpression;
if (widget == null) {
return;
}
@@ -4,7 +4,7 @@
import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/utilities/assist/assist.dart';
@@ -17,7 +17,7 @@ class FlutterMoveUp extends ResolvedCorrectionProducer {
@override
Future<void> compute(ChangeBuilder builder) async {
var widget = Flutter.identifyWidgetExpression(node);
var widget = node.findWidgetExpression;
if (widget == null) {
return;
}
@@ -5,7 +5,7 @@
import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -34,13 +34,13 @@ class FlutterRemoveWidget extends ResolvedCorrectionProducer {
@override
Future<void> compute(ChangeBuilder builder) async {
var widgetCreation = Flutter.identifyNewExpression(node);
var widgetCreation = node.findInstanceCreationExpression;
if (widgetCreation == null) {
return;
}
// Prepare the list of our children.
var childrenArgument = Flutter.findChildrenArgument(widgetCreation);
var childrenArgument = widgetCreation.childrenArgument;
if (childrenArgument != null) {
var childrenExpression = childrenArgument.expression;
if (childrenExpression is ListLiteral &&
@@ -49,11 +49,11 @@ class FlutterRemoveWidget extends ResolvedCorrectionProducer {
builder, widgetCreation, childrenExpression.elements);
}
} else {
var childArgument = Flutter.findChildArgument(widgetCreation);
var childArgument = widgetCreation.childArgument;
if (childArgument != null) {
await _removeSingle(builder, widgetCreation, childArgument.expression);
} else {
var builderArgument = Flutter.findBuilderArgument(widgetCreation);
var builderArgument = widgetCreation.builderArgument;
if (builderArgument != null) {
await _removeBuilder(builder, widgetCreation, builderArgument);
}
@@ -4,7 +4,7 @@
import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer_plugin/utilities/assist/assist.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
@@ -16,7 +16,7 @@ abstract class FlutterParentAndChild extends ResolvedCorrectionProducer {
InstanceCreationExpression parent,
InstanceCreationExpression child) async {
// The child must have its own child.
var stableChild = Flutter.findChildArgument(child);
var stableChild = child.childArgument;
if (stableChild == null) {
return;
}
@@ -63,7 +63,7 @@ abstract class FlutterParentAndChild extends ResolvedCorrectionProducer {
// Write all arguments of the parent.
// Don't write its child.
for (var argument in parentArgs.arguments) {
if (!Flutter.isChildArgument(argument)) {
if (!argument.isChildArgument) {
var text = utils.getNodeText(argument);
text = utils.replaceSourceIndent(
text,
@@ -104,15 +104,14 @@ class FlutterSwapWithChild extends FlutterParentAndChild {
@override
Future<void> compute(ChangeBuilder builder) async {
var parent = Flutter.identifyNewExpression(node);
if (parent == null || !Flutter.isWidgetCreation(parent)) {
var parent = node.findInstanceCreationExpression;
if (parent == null || !parent.isWidgetCreation) {
return;
}
var childArgument = Flutter.findChildArgument(parent);
var childArgument = parent.childArgument;
var child = childArgument?.expression;
if (child is! InstanceCreationExpression ||
!Flutter.isWidgetCreation(child)) {
if (child is! InstanceCreationExpression || !child.isWidgetCreation) {
return;
}
@@ -4,7 +4,7 @@
import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/correction/dart/flutter_swap_with_child.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer_plugin/utilities/assist/assist.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
@@ -15,8 +15,8 @@ class FlutterSwapWithParent extends FlutterParentAndChild {
@override
Future<void> compute(ChangeBuilder builder) async {
var child = Flutter.identifyNewExpression(node);
if (child == null || !Flutter.isWidgetCreation(child)) {
var child = node.findInstanceCreationExpression;
if (child == null || !child.isWidgetCreation) {
return;
}
@@ -5,7 +5,7 @@
import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/selection_analyzer.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/source/source_range.dart';
@@ -18,20 +18,20 @@ class FlutterWrap extends MultiCorrectionProducer {
@override
Future<List<ResolvedCorrectionProducer>> get producers async {
var producers = <ResolvedCorrectionProducer>[];
var widgetExpr = Flutter.identifyWidgetExpression(node);
var widgetExpr = node.findWidgetExpression;
if (widgetExpr != null) {
var widgetType = widgetExpr.typeOrThrow;
producers.add(_FlutterWrapGeneric(widgetExpr));
if (!Flutter.isExactWidgetTypeCenter(widgetType)) {
if (!widgetType.isExactWidgetTypeCenter) {
producers.add(_FlutterWrapCenter(widgetExpr));
}
if (!Flutter.isExactWidgetTypeContainer(widgetType)) {
if (!widgetType.isExactWidgetTypeContainer) {
producers.add(_FlutterWrapContainer(widgetExpr));
}
if (!Flutter.isExactWidgetTypePadding(widgetType)) {
if (!widgetType.isExactWidgetTypePadding) {
producers.add(_FlutterWrapPadding(widgetExpr));
}
if (!Flutter.isExactWidgetTypeSizedBox(widgetType)) {
if (!widgetType.isExactWidgetTypeSizedBox) {
producers.add(_FlutterWrapSizedBox(widgetExpr));
}
}
@@ -58,8 +58,7 @@ class FlutterWrap extends MultiCorrectionProducer {
parent is InstanceCreationExpression) {
selectedNode = parent;
}
if (selectedNode is! Expression ||
!Flutter.isWidgetExpression(selectedNode)) {
if (selectedNode is! Expression || !selectedNode.isWidgetExpression) {
return;
}
widgetExpressions.add(selectedNode);
@@ -77,7 +76,7 @@ class FlutterWrap extends MultiCorrectionProducer {
coveringNode = coveringNode.parent;
}
var widget = Flutter.identifyWidgetExpression(coveringNode);
var widget = coveringNode.findWidgetExpression;
if (widget != null) {
widgetExpressions.add(widget);
}
@@ -105,7 +104,7 @@ class _FlutterWrapCenter extends _WrapSingleWidget {
String get _parentClassName => 'Center';
@override
String get _parentLibraryUri => Flutter.widgetsUri;
String get _parentLibraryUri => widgetsUri;
}
/// A correction processor that can make one of the possible changes computed by
@@ -132,7 +131,7 @@ class _FlutterWrapContainer extends _WrapSingleWidget {
String get _parentClassName => 'Container';
@override
String get _parentLibraryUri => Flutter.widgetsUri;
String get _parentLibraryUri => widgetsUri;
}
/// A correction processor that can make one of the possible changes computed by
@@ -162,7 +161,7 @@ class _FlutterWrapPadding extends _WrapSingleWidget {
String get _parentClassName => 'Padding';
@override
String get _parentLibraryUri => Flutter.widgetsUri;
String get _parentLibraryUri => widgetsUri;
}
/// A correction processor that can make one of the possible changes computed by
@@ -189,7 +188,7 @@ class _FlutterWrapSizedBox extends _WrapSingleWidget {
String get _parentClassName => 'SizedBox';
@override
String get _parentLibraryUri => Flutter.widgetsUri;
String get _parentLibraryUri => widgetsUri;
}
/// A correction processor that can make one of the possible changes computed by
@@ -203,7 +202,7 @@ abstract class _WrapMultipleWidgets extends ResolvedCorrectionProducer {
String get _parentClassName;
String get _parentLibraryUri => Flutter.widgetsUri;
String get _parentLibraryUri => widgetsUri;
@override
Future<void> compute(ChangeBuilder builder) async {
@@ -211,8 +210,7 @@ abstract class _WrapMultipleWidgets extends ResolvedCorrectionProducer {
var src = utils.getRangeText(selectedRange);
var parentClassElement =
await sessionHelper.getClass(_parentLibraryUri, _parentClassName);
var widgetClassElement =
await sessionHelper.getClass(Flutter.widgetsUri, 'Widget');
var widgetClassElement = await sessionHelper.getFlutterClass('Widget');
if (parentClassElement == null || widgetClassElement == null) {
return;
}
@@ -4,7 +4,7 @@
import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/src/dart/ast/extensions.dart';
import 'package:analyzer_plugin/utilities/assist/assist.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
@@ -16,19 +16,16 @@ class FlutterWrapBuilder extends ResolvedCorrectionProducer {
@override
Future<void> compute(ChangeBuilder builder) async {
var widgetExpr = Flutter.identifyWidgetExpression(node);
var widgetExpr = node.findWidgetExpression;
if (widgetExpr == null) {
return;
}
if (Flutter.isExactWidgetTypeBuilder(widgetExpr.typeOrThrow)) {
if (widgetExpr.typeOrThrow.isExactWidgetTypeBuilder) {
return;
}
var widgetSrc = utils.getNodeText(widgetExpr);
var builderElement = await sessionHelper.getClass(
Flutter.widgetsUri,
'Builder',
);
var builderElement = await sessionHelper.getFlutterClass('Builder');
if (builderElement == null) {
return;
}
@@ -4,7 +4,7 @@
import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer_plugin/utilities/assist/assist.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
@@ -19,9 +19,8 @@ class FlutterWrapGeneric extends ResolvedCorrectionProducer {
if (node is! ListLiteral) {
return;
}
if ((node as ListLiteral).elements.any((CollectionElement exp) =>
!(exp is InstanceCreationExpression &&
Flutter.isWidgetCreation(exp)))) {
if ((node as ListLiteral).elements.any((CollectionElement element) =>
!(element is InstanceCreationExpression && element.isWidgetCreation))) {
return;
}
var literalSrc = utils.getNodeText(node);
@@ -4,7 +4,7 @@
import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/src/dart/ast/extensions.dart';
import 'package:analyzer_plugin/utilities/assist/assist.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
@@ -16,19 +16,17 @@ class FlutterWrapStreamBuilder extends ResolvedCorrectionProducer {
@override
Future<void> compute(ChangeBuilder builder) async {
var widgetExpr = Flutter.identifyWidgetExpression(node);
var widgetExpr = node.findWidgetExpression;
if (widgetExpr == null) {
return;
}
if (Flutter.isExactWidgetTypeStreamBuilder(widgetExpr.typeOrThrow)) {
if (widgetExpr.typeOrThrow.isExactWidgetTypeStreamBuilder) {
return;
}
var widgetSrc = utils.getNodeText(widgetExpr);
var streamBuilderElement = await sessionHelper.getClass(
Flutter.widgetsUri,
'StreamBuilder',
);
var streamBuilderElement =
await sessionHelper.getFlutterClass('StreamBuilder');
if (streamBuilderElement == null) {
return;
}
@@ -5,7 +5,7 @@
import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
@@ -39,7 +39,7 @@ class SortChildPropertyLast extends ResolvedCorrectionProducer {
var creationExpression = childProp.parent?.parent;
if (creationExpression is! InstanceCreationExpression ||
!Flutter.isWidgetCreation(creationExpression)) {
!creationExpression.isWidgetCreation) {
return;
}
@@ -96,7 +96,7 @@ class SortChildPropertyLast extends ResolvedCorrectionProducer {
return node;
}
}
return Flutter.findNamedExpression(node, 'child') ??
Flutter.findNamedExpression(node, 'children');
return node.findArgumentNamed('child') ??
node.findArgumentNamed('children');
}
}
@@ -5,7 +5,7 @@
import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/statement_analyzer.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/source/source_range.dart';
import 'package:analyzer_plugin/utilities/assist/assist.dart';
@@ -238,10 +238,9 @@ class _SurroundWithSetState extends _SurroundWith {
@override
Future<void> compute(ChangeBuilder builder) async {
var classDeclaration =
node.parent?.thisOrAncestorOfType<ClassDeclaration>();
if (classDeclaration != null &&
Flutter.isState(classDeclaration.declaredElement)) {
var classElement =
node.parent?.thisOrAncestorOfType<ClassDeclaration>()?.declaredElement;
if (classElement != null && classElement.isState) {
await builder.addDartFileEdit(file, (builder) {
builder.addReplacement(statementsRange, (builder) {
builder.write(indentOld);
@@ -4,7 +4,7 @@
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/ast/extensions.dart';
@@ -25,7 +25,7 @@ class WrapInText extends ResolvedCorrectionProducer {
if (context == null) {
return;
}
if (!Flutter.isWidgetType(context.parameterElement.type)) {
if (!context.parameterElement.type.isWidgetType) {
return;
}
@@ -5,7 +5,7 @@
import 'package:analysis_server/src/protocol_server.dart' as protocol;
import 'package:analysis_server/src/services/flutter/class_description.dart';
import 'package:analysis_server/src/services/flutter/property.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -147,7 +147,7 @@ class _WidgetDescriptionComputer {
if (node == null) {
return null;
}
var instanceCreation = Flutter.identifyNewExpression(node);
var instanceCreation = node.findInstanceCreationExpression;
if (instanceCreation == null) {
return null;
}
@@ -173,7 +173,7 @@ class _WidgetDescriptionComputer {
List<PropertyDescription> properties,
InstanceCreationExpression widgetCreation,
) {
if (!Flutter.isWidgetCreation(widgetCreation)) {
if (!widgetCreation.isWidgetCreation) {
return;
}
@@ -190,7 +190,7 @@ class _WidgetDescriptionComputer {
}
PropertyDescription containerProperty;
if (Flutter.isExactlyContainerCreation(parentCreation)) {
if (parentCreation?.isExactlyContainerCreation ?? false) {
containerProperty = PropertyDescription(
resolvedUnit: resolvedUnit,
instanceCreation: parentCreation,
@@ -241,7 +241,7 @@ class _WidgetDescriptionComputer {
);
if (parentCreation != null &&
Flutter.isExactlyAlignCreation(parentCreation) &&
parentCreation.isExactlyAlignCreation &&
parentCreation.argumentList.byName('widthFactor') == null &&
parentCreation.argumentList.byName('heightFactor') == null) {
_replaceNestedContainerProperty(
@@ -251,8 +251,7 @@ class _WidgetDescriptionComputer {
);
}
if (parentCreation != null &&
Flutter.isExactlyPaddingCreation(parentCreation)) {
if (parentCreation != null && parentCreation.isExactlyPaddingCreation) {
_replaceNestedContainerProperty(
containerProperty,
parentCreation,
@@ -373,7 +372,7 @@ class _WidgetDescriptionComputer {
var classEdgeInsets = _classEdgeInsets;
if (classEdgeInsets != null &&
Flutter.isExactEdgeInsetsGeometryType(parameter.type)) {
parameter.type.isExactEdgeInsetsGeometryType) {
propertyDescription.addEdgeInsetsNestedProperties(classEdgeInsets);
} else if (valueExpression is InstanceCreationExpression) {
var type = valueExpression.staticType;
@@ -420,22 +419,11 @@ class _WidgetDescriptionComputer {
Future<void> _fetchClassElements() async {
var sessionHelper = AnalysisSessionHelper(resolvedUnit.session);
_classAlignment = await sessionHelper.getClass(
Flutter.widgetsUri,
'Alignment',
);
_classAlignmentDirectional = await sessionHelper.getClass(
Flutter.widgetsUri,
'AlignmentDirectional',
);
_classContainer = await sessionHelper.getClass(
Flutter.widgetsUri,
'Container',
);
_classEdgeInsets = await sessionHelper.getClass(
Flutter.widgetsUri,
'EdgeInsets',
);
_classAlignment = await sessionHelper.getFlutterClass('Alignment');
_classAlignmentDirectional =
await sessionHelper.getFlutterClass('AlignmentDirectional');
_classContainer = await sessionHelper.getFlutterClass('Container');
_classEdgeInsets = await sessionHelper.getFlutterClass('EdgeInsets');
}
protocol.FlutterWidgetPropertyEditor? _getEditor(DartType type) {
@@ -467,7 +455,7 @@ class _WidgetDescriptionComputer {
enumItems: _enumItemsForEnum(classElement),
);
}
if (Flutter.isExactAlignmentGeometry(classElement)) {
if (classElement.isExactAlignmentGeometry) {
var items = <protocol.FlutterWidgetPropertyValueEnumItem>[];
var classAlignment = _classAlignment;
if (classAlignment != null) {
@@ -546,8 +534,8 @@ class _WidgetDescriptionComputer {
if (field is FieldElement && field.isStatic) {
var enclosingClass = field.enclosingElement as InterfaceElement;
if (field.isEnumConstant ||
Flutter.isExactAlignment(enclosingClass) ||
Flutter.isExactAlignmentDirectional(enclosingClass)) {
enclosingClass.isExactAlignment ||
enclosingClass.isExactAlignmentDirectional) {
return protocol.FlutterWidgetPropertyValue(
enumValue: _toEnumItem(field),
);
@@ -10,7 +10,7 @@ import 'package:analysis_server/src/services/refactoring/legacy/refactoring.dart
import 'package:analysis_server/src/services/refactoring/legacy/refactoring_internal.dart';
import 'package:analysis_server/src/services/search/element_visitors.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
@@ -183,9 +183,9 @@ class ExtractWidgetRefactoringImpl extends RefactoringImpl
_enclosingClassNode = node?.thisOrAncestorOfType<ClassDeclaration>();
_enclosingClassElement = _enclosingClassNode?.declaredElement;
// new MyWidget(...)
var newExpression = Flutter.identifyNewExpression(node);
if (Flutter.isWidgetCreation(newExpression)) {
// `new MyWidget(...)`
var newExpression = node.findInstanceCreationExpression;
if (newExpression?.isWidgetCreation ?? false) {
_expression = newExpression;
return RefactoringStatus();
}
@@ -203,7 +203,7 @@ class ExtractWidgetRefactoringImpl extends RefactoringImpl
if (statements.isNotEmpty) {
var lastStatement = statements.last;
if (lastStatement is ReturnStatement &&
Flutter.isWidgetExpression(lastStatement.expression)) {
lastStatement.expression.isWidgetExpression) {
_statements = statements;
_statementsRange = range.startEnd(statements.first, statements.last);
return RefactoringStatus();
@@ -221,7 +221,7 @@ class ExtractWidgetRefactoringImpl extends RefactoringImpl
}
if (node is MethodDeclaration) {
var returnType = node.returnType?.type;
if (Flutter.isWidgetType(returnType)) {
if (returnType.isWidgetType) {
_method = node;
return RefactoringStatus();
}
@@ -238,11 +238,9 @@ class ExtractWidgetRefactoringImpl extends RefactoringImpl
var result = RefactoringStatus();
Future<ClassElement?> getClass(String name) async {
var element = await sessionHelper.getClass(Flutter.widgetsUri, name);
var element = await sessionHelper.getFlutterClass(name);
if (element == null) {
result.addFatalError(
"Unable to find '$name' in ${Flutter.widgetsUri}",
);
result.addFatalError("Unable to find '$name' in $widgetsUri");
}
return element;
}
@@ -11,7 +11,7 @@ import 'package:analysis_server/src/services/refactoring/legacy/refactoring.dart
import 'package:analysis_server/src/services/refactoring/legacy/rename.dart';
import 'package:analysis_server/src/services/search/element_visitors.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart' show Identifier;
import 'package:analyzer/dart/element/element.dart';
@@ -152,9 +152,10 @@ class RenameUnitMemberRefactoringImpl extends RenameRefactoringImpl {
}
void _findFlutterStateClass() {
if (Flutter.isStatefulWidgetDeclaration(element)) {
final element = this.element;
if (element is ClassElement && element.isStatefulWidgetDeclaration) {
var oldStateName = '${oldName}State';
var library = element.library!;
var library = element.library;
_flutterWidgetState =
library.getClass(oldStateName) ?? library.getClass('_$oldStateName');
}
@@ -5,7 +5,7 @@
import 'package:analysis_server/src/services/correction/util.dart';
import 'package:analysis_server/src/services/snippets/dart_snippet_request.dart';
import 'package:analysis_server/src/services/snippets/snippet.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/analysis/code_style_options.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -72,7 +72,7 @@ abstract class FlutterSnippetProducer extends DartSnippetProducer {
FlutterSnippetProducer(super.request, {required super.elementImportCache});
Future<ClassElement?> getClass(String name) async {
final class_ = await sessionHelper.getClass(Flutter.widgetsUri, name);
final class_ = await sessionHelper.getFlutterClass(name);
if (class_ != null) {
requiredElementImports.add(class_);
}
@@ -80,7 +80,7 @@ abstract class FlutterSnippetProducer extends DartSnippetProducer {
}
Future<MixinElement?> getMixin(String name) async {
final mixin = await sessionHelper.getMixin(Flutter.widgetsUri, name);
final mixin = await sessionHelper.getMixin(widgetsUri, name);
if (mixin != null) {
requiredElementImports.add(mixin);
}
@@ -0,0 +1,437 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/utilities/strings.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:collection/collection.dart';
const String widgetsUri = 'package:flutter/widgets.dart';
const _nameAlign = 'Align';
const _nameBuilder = 'Builder';
const _nameCenter = 'Center';
const _nameContainer = 'Container';
const _namePadding = 'Padding';
const _nameSizedBox = 'SizedBox';
const _nameState = 'State';
const _nameStatefulWidget = 'StatefulWidget';
const _nameStatelessWidget = 'StatelessWidget';
const _nameStreamBuilder = 'StreamBuilder';
const _nameWidget = 'Widget';
final Uri _uriAlignment = Uri.parse(
'package:flutter/src/painting/alignment.dart',
);
final Uri _uriAsync = Uri.parse(
'package:flutter/src/widgets/async.dart',
);
final Uri _uriBasic = Uri.parse(
'package:flutter/src/widgets/basic.dart',
);
final Uri _uriContainer = Uri.parse(
'package:flutter/src/widgets/container.dart',
);
final Uri _uriDiagnostics = Uri.parse(
'package:flutter/src/foundation/diagnostics.dart',
);
final Uri _uriEdgeInsets = Uri.parse(
'package:flutter/src/painting/edge_insets.dart',
);
final Uri _uriFramework = Uri.parse(
'package:flutter/src/widgets/framework.dart',
);
final Uri _uriWidgetsIcon = Uri.parse(
'package:flutter/src/widgets/icon.dart',
);
final Uri _uriWidgetsText = Uri.parse(
'package:flutter/src/widgets/text.dart',
);
extension AstNodeExtension on AstNode? {
/// Returns the instance creation expression that surrounds this node, if any,
/// and otherwise `null`.
///
/// This node may be the instance creation expression itself or an (optionally
/// prefixed) identifier that names the constructor.
InstanceCreationExpression? get findInstanceCreationExpression {
var node = this;
if (node is ImportPrefixReference) {
node = node.parent;
}
if (node is SimpleIdentifier) {
node = node.parent;
}
if (node is PrefixedIdentifier) {
node = node.parent;
}
if (node is NamedType) {
node = node.parent;
}
if (node is ConstructorName) {
node = node.parent;
}
if (node is InstanceCreationExpression) {
return node;
}
return null;
}
/// Attempts to find and return the closest expression that encloses this
/// and is an independent Flutter `Widget`.
///
/// Returns `null` if nothing is found.
Expression? get findWidgetExpression {
for (var node = this; node != null; node = node.parent) {
if (!node.isWidgetExpression) {
if (node is ArgumentList || node is Statement || node is FunctionBody) {
return null;
}
continue;
}
if (node is AssignmentExpression) {
return null;
}
var parent = node.parent;
if (parent is AssignmentExpression) {
if (parent.rightHandSide == node) {
return node as Expression;
}
return null;
}
if (parent is ArgumentList ||
parent is ConditionalExpression && parent.thenExpression == node ||
parent is ConditionalExpression && parent.elseExpression == node ||
parent is ExpressionFunctionBody && parent.expression == node ||
parent is ForElement && parent.body == node ||
parent is IfElement && parent.thenElement == node ||
parent is IfElement && parent.elseElement == node ||
parent is ListLiteral ||
parent is NamedExpression && parent.expression == node ||
parent is Statement ||
parent is SwitchExpressionCase && parent.expression == node ||
parent is VariableDeclaration) {
return node as Expression;
}
}
return null;
}
/// Whether the given [node] is the Flutter class `Widget`, or its subtype.
bool get isWidgetExpression {
return switch (this) {
null => false,
AstNode(parent: NamedType()) ||
AstNode(parent: AstNode(parent: NamedType())) =>
false,
AstNode(parent: ConstructorName()) => false,
NamedExpression() => false,
Expression(:var staticType) => staticType.isWidgetType,
_ => false,
};
}
/// Finds the named expression whose name is the given [name] that is an
/// argument to a Flutter instance creation expression.
///
/// Returns `null` if this is not a [SimpleIdentifier], or if any other
/// condition cannot be satisfied.
NamedExpression? findArgumentNamed(String name) {
var self = this;
if (self is! SimpleIdentifier) {
return null;
}
var parent = self.parent;
var grandParent = parent?.parent;
if (parent is Label && grandParent is NamedExpression) {
if (self.name != name) {
return null;
}
} else {
return null;
}
var invocation = grandParent.parent?.parent;
if (invocation is! InstanceCreationExpression ||
!invocation.isWidgetCreation) {
return null;
}
return grandParent;
}
}
extension ClassElementExtension on ClassElement {
/// Whether this is the Flutter class `State`.
bool get isExactState => _isExactly(_nameState, _uriFramework);
/// Whether this has the Flutter class `State` as a superclass.
bool get isState => _hasSupertype(_uriFramework, _nameState);
/// Whether this is a [ClassElement] that extends the Flutter class
/// `StatefulWidget`.
bool get isStatefulWidgetDeclaration => supertype.isExactlyStatefulWidgetType;
}
extension DartTypeExtension on DartType? {
/// Whether this is the 'dart.ui' class `Color`, or a subtype.
bool get isColor {
var self = this;
if (self is! InterfaceType) {
return false;
}
return [self, ...self.element.allSupertypes].any((t) =>
t.element.name == 'Color' && t.element.library.name == 'dart.ui');
}
/// Whether this is the Flutter mixin `Diagnosticable` or a subtype.
bool get isDiagnosticable {
var self = this;
if (self is! InterfaceType) {
return false;
}
return [self, ...self.element.allSupertypes].any((t) =>
t.element.name == 'Diagnosticable' &&
t.element.source.uri == _uriDiagnostics);
}
/// Whether this is the Flutter type `EdgeInsetsGeometry`.
bool get isExactEdgeInsetsGeometryType {
var self = this;
return self is InterfaceType &&
self.element._isExactly('EdgeInsetsGeometry', _uriEdgeInsets);
}
/// Whether this is the Flutter class `StatefulWidget`.
bool get isExactlyStatefulWidgetType {
var self = this;
return self is InterfaceType &&
self.element._isExactly(_nameStatefulWidget, _uriFramework);
}
/// Whether this is the Flutter class `StatelessWidget`.
bool get isExactlyStatelessWidgetType {
var self = this;
return self is InterfaceType &&
self.element._isExactly(_nameStatelessWidget, _uriFramework);
}
/// Whether this is the Flutter class `Align`.
bool get isExactWidgetTypeAlign {
var self = this;
return self is InterfaceType &&
self.element._isExactly(_nameAlign, _uriBasic);
}
/// Whether this is the Flutter class `StreamBuilder`.
bool get isExactWidgetTypeBuilder {
var self = this;
return self is InterfaceType &&
self.element._isExactly(_nameBuilder, _uriBasic);
}
/// Whether this is the Flutter class `Center`.
bool get isExactWidgetTypeCenter {
var self = this;
return self is InterfaceType &&
self.element._isExactly(_nameCenter, _uriBasic);
}
/// Whether this is the Flutter class `Container`.
bool get isExactWidgetTypeContainer {
var self = this;
return self is InterfaceType &&
self.element._isExactly(_nameContainer, _uriContainer);
}
/// Whether this is the Flutter class `Padding`.
bool get isExactWidgetTypePadding {
var self = this;
return self is InterfaceType &&
self.element._isExactly(_namePadding, _uriBasic);
}
/// Whether this is the Flutter class `SizedBox`.
bool get isExactWidgetTypeSizedBox {
var self = this;
return self is InterfaceType &&
self.element._isExactly(_nameSizedBox, _uriBasic);
}
/// Whether this is the Flutter class `StreamBuilder`.
bool get isExactWidgetTypeStreamBuilder {
var self = this;
return self is InterfaceType &&
self.element._isExactly(_nameStreamBuilder, _uriAsync);
}
/// Whether this is the Flutter class `Widget`, or its subtype.
bool get isListOfWidgetsType {
var self = this;
return self is InterfaceType &&
self.isDartCoreList &&
self.typeArguments[0].isWidgetType;
}
/// Whether this is the vector_math_64 class `Matrix4`, or its
/// subtype.
bool get isMatrix4 {
var self = this;
if (self is! InterfaceType) {
return false;
}
return [self, ...self.element.allSupertypes].any((t) =>
t.element.name == 'Matrix4' &&
t.element.library.name == 'vector_math_64');
}
/// Whether this is the Flutter class `Widget`, or its subtype.
bool get isWidgetType {
var self = this;
return self is InterfaceType && self.element.isWidget;
}
}
extension ExpressionExtension on Expression {
/// Whether this is the `builder` argument.
bool get isBuilderArgument {
var self = this;
return self is NamedExpression && self.name.label.name == 'builder';
}
/// Whether this is the `child` argument.
bool get isChildArgument {
var self = this;
return self is NamedExpression && self.name.label.name == 'child';
}
/// Whether this is the `children` argument.
bool get isChildrenArgument {
var self = this;
return self is NamedExpression && self.name.label.name == 'children';
}
}
extension InstanceCreationExpressionExtension on InstanceCreationExpression {
/// The named expression representing the `builder` argument, or `null` if
/// there is none.
NamedExpression? get builderArgument => argumentList.arguments
.whereType<NamedExpression>()
.firstWhereOrNull((argument) => argument.isBuilderArgument);
/// The named expression representing the `child` argument, or `null` if there
/// is none.
NamedExpression? get childArgument => argumentList.arguments
.whereType<NamedExpression>()
.firstWhereOrNull((argument) => argument.isChildArgument);
/// The named expression representing the `children` argument, or `null` if
/// there is none.
NamedExpression? get childrenArgument => argumentList.arguments
.whereType<NamedExpression>()
.firstWhereOrNull((argument) => argument.isChildrenArgument);
bool get isExactlyAlignCreation => staticType.isExactWidgetTypeAlign;
bool get isExactlyContainerCreation => staticType.isExactWidgetTypeContainer;
bool get isExactlyPaddingCreation => staticType.isExactWidgetTypePadding;
/// Whether this is a constructor invocation for a class that has the Flutter
/// class `Widget` as a superclass.
bool get isWidgetCreation {
var element =
constructorName.staticElement?.enclosingElement.augmented.declaration;
return element.isWidget;
}
/// The presentation for this node.
String? get widgetPresentationText {
var element =
constructorName.staticElement?.enclosingElement.augmented.declaration;
if (!element.isWidget) {
return null;
}
var arguments = argumentList.arguments;
if (element._isExactly('Icon', _uriWidgetsIcon)) {
if (arguments.isNotEmpty) {
var text = arguments[0].toString();
var arg = shorten(text, 32);
return 'Icon($arg)';
} else {
return 'Icon';
}
}
if (element._isExactly('Text', _uriWidgetsText)) {
if (arguments.isNotEmpty) {
var text = arguments[0].toString();
var arg = shorten(text, 32);
return 'Text($arg)';
} else {
return 'Text';
}
}
return element?.name;
}
}
extension InterfaceElementExtension on InterfaceElement? {
/// Whether this is the Flutter class `Alignment`.
bool get isExactAlignment {
return _isExactly('Alignment', _uriAlignment);
}
/// Whether this is the Flutter class `AlignmentDirectional`.
bool get isExactAlignmentDirectional {
return _isExactly('AlignmentDirectional', _uriAlignment);
}
/// Whether this is the Flutter class `AlignmentGeometry`.
bool get isExactAlignmentGeometry {
return _isExactly('AlignmentGeometry', _uriAlignment);
}
/// Whether this is the Flutter class `Widget`, or a subtype.
bool get isWidget {
var self = this;
if (self is! ClassElement) {
return false;
}
if (_isExactly(_nameWidget, _uriFramework)) {
return true;
}
return self.allSupertypes
.any((type) => type.element._isExactly(_nameWidget, _uriFramework));
}
/// Whether this has a supertype with the [requiredName] defined in the file
/// with the [requiredUri].
bool _hasSupertype(Uri requiredUri, String requiredName) {
var self = this;
if (self == null) {
return false;
}
for (var type in self.allSupertypes) {
if (type.element.name == requiredName) {
var uri = type.element.source.uri;
if (uri == requiredUri) {
return true;
}
}
}
return false;
}
/// Whether this is the exact [type] defined in the file with the given [uri].
bool _isExactly(String type, Uri uri) {
var self = this;
return self is ClassElement && self.name == type && self.source.uri == uri;
}
}
@@ -1,488 +0,0 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/utilities/strings.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/source/source_range.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
import 'package:collection/collection.dart';
abstract final class Flutter {
static const _nameAlign = 'Align';
static const _nameBuilder = 'Builder';
static const _nameCenter = 'Center';
static const _nameContainer = 'Container';
static const _namePadding = 'Padding';
static const _nameSizedBox = 'SizedBox';
static const _nameState = 'State';
static const _nameStatefulWidget = 'StatefulWidget';
static const _nameStatelessWidget = 'StatelessWidget';
static const _nameStreamBuilder = 'StreamBuilder';
static const _nameWidget = 'Widget';
static final String widgetsUri = 'package:flutter/widgets.dart';
static final Uri _uriAlignment = Uri.parse(
'package:flutter/src/painting/alignment.dart',
);
static final Uri _uriAsync = Uri.parse(
'package:flutter/src/widgets/async.dart',
);
static final Uri _uriBasic = Uri.parse(
'package:flutter/src/widgets/basic.dart',
);
static final Uri _uriContainer = Uri.parse(
'package:flutter/src/widgets/container.dart',
);
static final Uri _uriDiagnostics = Uri.parse(
'package:flutter/src/foundation/diagnostics.dart',
);
static final Uri _uriEdgeInsets = Uri.parse(
'package:flutter/src/painting/edge_insets.dart',
);
static final Uri _uriFramework = Uri.parse(
'package:flutter/src/widgets/framework.dart',
);
static final Uri _uriWidgetsIcon = Uri.parse(
'package:flutter/src/widgets/icon.dart',
);
static final Uri _uriWidgetsText = Uri.parse(
'package:flutter/src/widgets/text.dart',
);
static void convertChildToChildren2(
DartFileEditBuilder builder,
Expression childArg,
NamedExpression namedExp,
String eol,
String Function(Expression) getNodeText,
String Function(int) getLinePrefix,
String oneIndent,
String Function(int, int) getText,
String Function(String, String, String,
{bool includeLeading, bool ensureTrailingNewline})
replaceSourceIndent,
SourceRange Function(Expression) rangeNode) {
var childLoc = namedExp.offset + 'child'.length;
builder.addSimpleInsertion(childLoc, 'ren');
var listLoc = childArg.offset;
var childArgSrc = getNodeText(childArg);
if (!childArgSrc.contains(eol)) {
builder.addSimpleInsertion(listLoc, '[');
builder.addSimpleInsertion(listLoc + childArg.length, ']');
} else {
var newlineLoc = childArgSrc.lastIndexOf(eol);
if (newlineLoc == childArgSrc.length) {
newlineLoc -= 1;
}
var indentOld = getLinePrefix(childArg.offset + eol.length + newlineLoc);
var indentNew = '$indentOld$oneIndent';
// The separator includes 'child:' but that has no newlines.
var separator =
getText(namedExp.offset, childArg.offset - namedExp.offset);
var prefix = separator.contains(eol) ? '' : '$eol$indentNew';
if (prefix.isEmpty) {
builder.addSimpleInsertion(namedExp.offset + 'child:'.length, ' [');
builder.addDeletion(SourceRange(childArg.offset - 2, 2));
} else {
builder.addSimpleInsertion(listLoc, '[');
}
var newChildArgSrc = replaceSourceIndent(
childArgSrc,
indentOld,
indentNew,
);
newChildArgSrc = '$prefix$newChildArgSrc,$eol$indentOld]';
builder.addSimpleReplacement(rangeNode(childArg), newChildArgSrc);
}
}
/// Returns the named expression representing the `builder` argument of the
/// given [newExpr], or `null` if none.
static NamedExpression? findBuilderArgument(
InstanceCreationExpression newExpr) =>
newExpr.argumentList.arguments
.whereType<NamedExpression>()
.firstWhereOrNull((argument) => isBuilderArgument(argument));
/// Returns the named expression representing the `child` argument of the
/// given [newExpr], or `null` if none.
static NamedExpression? findChildArgument(
InstanceCreationExpression newExpr) =>
newExpr.argumentList.arguments
.whereType<NamedExpression>()
.firstWhereOrNull((argument) => isChildArgument(argument));
/// Returns the named expression representing the `children` argument of the
/// given [newExpr], or `null` if none.
static NamedExpression? findChildrenArgument(
InstanceCreationExpression newExpr) =>
newExpr.argumentList.arguments
.whereType<NamedExpression>()
.firstWhereOrNull((argument) => isChildrenArgument(argument));
/// Returns the Flutter instance creation expression that is the value of the
/// 'child' argument of the given [newExpr], or `null` if none.
static InstanceCreationExpression? findChildWidget(
InstanceCreationExpression newExpr) {
var child = findChildArgument(newExpr);
var widget = getChildWidget(child);
if (widget is InstanceCreationExpression) {
return widget;
}
return null;
}
/// If the given [node] is a simple identifier, finds the named expression
/// whose name is the given [name] that is an argument to a Flutter instance
/// creation expression.
///
/// Returns `null` if any condition cannot be satisfied.
static NamedExpression? findNamedExpression(AstNode node, String name) {
if (node is! SimpleIdentifier) {
return null;
}
var parent = node.parent;
var grandParent = parent?.parent;
if (parent is Label && grandParent is NamedExpression) {
if (node.name != name) {
return null;
}
} else {
return null;
}
var invocation = grandParent.parent?.parent;
if (invocation is! InstanceCreationExpression ||
!isWidgetCreation(invocation)) {
return null;
}
return grandParent;
}
/// Returns the expression that is a Flutter Widget that is the value of the
/// given [child], or `null` if none.
static Expression? getChildWidget(NamedExpression? child) {
var expression = child?.expression;
if (isWidgetExpression(expression)) {
return expression;
}
return null;
}
/// Returns the presentation for the given Flutter `Widget` creation [node].
static String? getWidgetPresentationText(InstanceCreationExpression node) {
var element = node
.constructorName.staticElement?.enclosingElement.augmented.declaration;
if (!isWidget(element)) {
return null;
}
var arguments = node.argumentList.arguments;
if (_isExactWidget(element, 'Icon', _uriWidgetsIcon)) {
if (arguments.isNotEmpty) {
var text = arguments[0].toString();
var arg = shorten(text, 32);
return 'Icon($arg)';
} else {
return 'Icon';
}
}
if (_isExactWidget(element, 'Text', _uriWidgetsText)) {
if (arguments.isNotEmpty) {
var text = arguments[0].toString();
var arg = shorten(text, 32);
return 'Text($arg)';
} else {
return 'Text';
}
}
return element?.name;
}
/// Returns the instance creation expression that surrounds the given
/// [node], if any, else null.
///
/// The [node] may be the instance creation expression itself or an
/// (optionally prefixed) identifier that names the constructor.
static InstanceCreationExpression? identifyNewExpression(AstNode? node) {
InstanceCreationExpression? newExpr;
if (node is ImportPrefixReference) {
node = node.parent;
}
if (node is SimpleIdentifier) {
node = node.parent;
}
if (node is PrefixedIdentifier) {
node = node.parent;
}
if (node is NamedType) {
node = node.parent;
}
if (node is ConstructorName) {
node = node.parent;
}
if (node is InstanceCreationExpression) {
newExpr = node;
}
return newExpr;
}
/// Attempts to find and return the closest expression that encloses the [node]
/// and is an independent Flutter `Widget`.
///
/// Returns `null` if nothing is found.
static Expression? identifyWidgetExpression(AstNode? node) {
for (; node != null; node = node.parent) {
if (isWidgetExpression(node)) {
var parent = node.parent;
if (node is AssignmentExpression) {
return null;
}
if (parent is AssignmentExpression) {
if (parent.rightHandSide == node) {
return node as Expression;
}
return null;
}
if (parent is ArgumentList ||
parent is ConditionalExpression && parent.thenExpression == node ||
parent is ConditionalExpression && parent.elseExpression == node ||
parent is ExpressionFunctionBody && parent.expression == node ||
parent is ForElement && parent.body == node ||
parent is IfElement && parent.thenElement == node ||
parent is IfElement && parent.elseElement == node ||
parent is ListLiteral ||
parent is NamedExpression && parent.expression == node ||
parent is Statement ||
parent is SwitchExpressionCase && parent.expression == node ||
parent is VariableDeclaration) {
return node as Expression;
}
}
if (node is ArgumentList || node is Statement || node is FunctionBody) {
return null;
}
}
return null;
}
/// Whether the given [argument] is the `builder` argument.
static bool isBuilderArgument(Expression argument) =>
argument is NamedExpression && argument.name.label.name == 'builder';
/// Whether the given [argument] is the `child` argument.
static bool isChildArgument(Expression argument) =>
argument is NamedExpression && argument.name.label.name == 'child';
/// Whether the given [argument] is the `child` argument.
static bool isChildrenArgument(Expression argument) =>
argument is NamedExpression && argument.name.label.name == 'children';
/// Whether the given [type] is the 'dart.ui' class `Color`, or its subtype.
static bool isColor(DartType? type) {
if (type is! InterfaceType) {
return false;
}
return [type, ...type.element.allSupertypes].any((t) =>
t.element.name == 'Color' && t.element.library.name == 'dart.ui');
}
/// Whether the given [type] is the flutter mixin `Diagnosticable` or its
/// subtype.
static bool isDiagnosticable(DartType? type) {
if (type is! InterfaceType) {
return false;
}
return [type, ...type.element.allSupertypes].any((t) =>
t.element.name == 'Diagnosticable' &&
t.element.source.uri == _uriDiagnostics);
}
/// Whether the [element] is the Flutter class `Alignment`.
static bool isExactAlignment(InterfaceElement element) {
return _isExactWidget(element, 'Alignment', _uriAlignment);
}
/// Whether if the [element] is the Flutter class
/// `AlignmentDirectional`.
static bool isExactAlignmentDirectional(InterfaceElement element) {
return _isExactWidget(element, 'AlignmentDirectional', _uriAlignment);
}
/// Whether if the [element] is the Flutter class `AlignmentGeometry`.
static bool isExactAlignmentGeometry(InterfaceElement element) {
return _isExactWidget(element, 'AlignmentGeometry', _uriAlignment);
}
/// Whether the [type] is the Flutter type `EdgeInsetsGeometry`.
static bool isExactEdgeInsetsGeometryType(DartType type) {
return type is InterfaceType &&
_isExactWidget(type.element, 'EdgeInsetsGeometry', _uriEdgeInsets);
}
/// Whether the [node] is creation of `Align`.
static bool isExactlyAlignCreation(InstanceCreationExpression node) =>
isExactWidgetTypeAlign(node.staticType);
/// Whether the [node] is creation of `Container`.
static bool isExactlyContainerCreation(InstanceCreationExpression? node) =>
isExactWidgetTypeContainer(node?.staticType);
/// Whether the [node] is creation of `Padding`.
static bool isExactlyPaddingCreation(InstanceCreationExpression node) =>
isExactWidgetTypePadding(node.staticType);
/// Whether the given [type] is the Flutter class `StatefulWidget`.
static bool isExactlyStatefulWidgetType(DartType? type) =>
type is InterfaceType &&
_isExactWidget(type.element, _nameStatefulWidget, _uriFramework);
/// Whether the given [type] is the Flutter class `StatelessWidget`.
static bool isExactlyStatelessWidgetType(DartType type) =>
type is InterfaceType &&
_isExactWidget(type.element, _nameStatelessWidget, _uriFramework);
/// Whether the given [element] is the Flutter class `State`.
static bool isExactState(ClassElement element) =>
_isExactWidget(element, _nameState, _uriFramework);
/// Whether the given [type] is the Flutter class `Align`.
static bool isExactWidgetTypeAlign(DartType? type) =>
type is InterfaceType &&
_isExactWidget(type.element, _nameAlign, _uriBasic);
/// Whether the given [type] is the Flutter class `StreamBuilder`.
static bool isExactWidgetTypeBuilder(DartType type) =>
type is InterfaceType &&
_isExactWidget(type.element, _nameBuilder, _uriBasic);
/// Whether the given [type] is the Flutter class `Center`.
static bool isExactWidgetTypeCenter(DartType type) =>
type is InterfaceType &&
_isExactWidget(type.element, _nameCenter, _uriBasic);
/// Whether the given [type] is the Flutter class `Container`.
static bool isExactWidgetTypeContainer(DartType? type) =>
type is InterfaceType &&
_isExactWidget(type.element, _nameContainer, _uriContainer);
/// Whether the given [type] is the Flutter class `Padding`.
static bool isExactWidgetTypePadding(DartType? type) =>
type is InterfaceType &&
_isExactWidget(type.element, _namePadding, _uriBasic);
/// Whether the given [type] is the Flutter class `SizedBox`.
static bool isExactWidgetTypeSizedBox(DartType type) =>
type is InterfaceType &&
_isExactWidget(type.element, _nameSizedBox, _uriBasic);
/// Whether the given [type] is the Flutter class `StreamBuilder`.
static bool isExactWidgetTypeStreamBuilder(DartType type) =>
type is InterfaceType &&
_isExactWidget(type.element, _nameStreamBuilder, _uriAsync);
/// Whether the given [type] is the Flutter class `Widget`, or its subtype.
static bool isListOfWidgetsType(DartType type) =>
type is InterfaceType &&
type.isDartCoreList &&
isWidgetType(type.typeArguments[0]);
/// Whether the given [type] is the vector_math_64 class `Matrix4`, or its
/// subtype.
static bool isMatrix4(DartType type) {
if (type is! InterfaceType) {
return false;
}
return [type, ...type.element.allSupertypes].any((t) =>
t.element.name == 'Matrix4' &&
t.element.library.name == 'vector_math_64');
}
/// Whether the given [element] has the Flutter class `State` as
/// a superclass.
static bool isState(ClassElement? element) =>
_hasSupertype(element, _uriFramework, _nameState);
/// Whether the given [element] is a [ClassElement] that extends the Flutter
/// class `StatefulWidget`.
static bool isStatefulWidgetDeclaration(Element element) =>
element is ClassElement && isExactlyStatefulWidgetType(element.supertype);
/// Whether the given [element] is the Flutter class `Widget`, or its
/// subtype.
static bool isWidget(InterfaceElement? element) {
if (element is! ClassElement) {
return false;
}
if (_isExactWidget(element, _nameWidget, _uriFramework)) {
return true;
}
return element.allSupertypes.any(
(type) => _isExactWidget(type.element, _nameWidget, _uriFramework));
}
/// Whether the given [expr] is a constructor invocation for a class that has
/// the Flutter class `Widget` as a superclass.
static bool isWidgetCreation(InstanceCreationExpression? expr) {
var element = expr
?.constructorName.staticElement?.enclosingElement.augmented.declaration;
return isWidget(element);
}
/// Whether the given [node] is the Flutter class `Widget`, or its subtype.
static bool isWidgetExpression(AstNode? node) {
if (node == null) {
return false;
}
if (node.parent is NamedType || node.parent?.parent is NamedType) {
return false;
}
if (node.parent is ConstructorName) {
return false;
}
if (node is NamedExpression) {
return false;
}
if (node is Expression) {
return isWidgetType(node.staticType);
}
return false;
}
/// Whether the given [type] is the Flutter class `Widget`, or its subtype.
static bool isWidgetType(DartType? type) =>
type is InterfaceType && isWidget(type.element);
/// Whether the given [element] has a supertype with the [requiredName]
/// defined in the file with the [requiredUri].
static bool _hasSupertype(
InterfaceElement? element, Uri requiredUri, String requiredName) {
if (element == null) {
return false;
}
for (var type in element.allSupertypes) {
if (type.element.name == requiredName) {
var uri = type.element.source.uri;
if (uri == requiredUri) {
return true;
}
}
}
return false;
}
/// Whether the given [element] is the exact [type] defined in the file with
/// the given [uri].
static bool _isExactWidget(InterfaceElement? element, String type, Uri uri) =>
element is ClassElement &&
element.name == type &&
element.source.uri == uri;
}
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/lsp_protocol/protocol.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/src/test_utilities/test_code_format.dart';
import 'package:test/test.dart';
@@ -95,8 +95,8 @@ Widget build(BuildContext context) => Icon(Icons.alarm);
// Find the path to our mock 'package:flutter/widgets.dart'.
var driver = server.getAnalysisDriver(mainFilePath)!;
var widgetsFilePath = driver.currentSession.uriConverter
.uriToPath(Uri.parse(Flutter.widgetsUri))!;
var widgetsFilePath =
driver.currentSession.uriConverter.uriToPath(Uri.parse(widgetsUri))!;
var widgetsFileUri = Uri.file(widgetsFilePath);
// We have to provide content to open a file so just read it.
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -25,76 +25,7 @@ class FlutterTest extends AbstractSingleUnitTest {
);
}
Future<void> test_getWidgetPresentationText_icon() async {
await resolveTestCode('''
import 'package:flutter/material.dart';
var w = const Icon(Icons.book);
''');
var w = _getTopVariableCreation('w');
expect(Flutter.getWidgetPresentationText(w), 'Icon(Icons.book)');
}
Future<void> test_getWidgetPresentationText_icon_withoutArguments() async {
verifyNoTestUnitErrors = false;
await resolveTestCode('''
import 'package:flutter/material.dart';
var w = const Icon();
''');
var w = _getTopVariableCreation('w');
expect(Flutter.getWidgetPresentationText(w), 'Icon');
}
Future<void> test_getWidgetPresentationText_notWidget() async {
await resolveTestCode('''
import 'package:flutter/material.dart';
var w = Object();
''');
var w = _getTopVariableCreation('w');
expect(Flutter.getWidgetPresentationText(w), isNull);
}
Future<void> test_getWidgetPresentationText_text() async {
await resolveTestCode('''
import 'package:flutter/material.dart';
var w = const Text('foo');
''');
var w = _getTopVariableCreation('w');
expect(Flutter.getWidgetPresentationText(w), "Text('foo')");
}
Future<void> test_getWidgetPresentationText_text_longText() async {
await resolveTestCode('''
import 'package:flutter/material.dart';
var w = const Text('${'abc' * 100}');
''');
var w = _getTopVariableCreation('w');
expect(
Flutter.getWidgetPresentationText(w),
"Text('abcabcabcabcab...cabcabcabcabc')",
);
}
Future<void> test_getWidgetPresentationText_text_withoutArguments() async {
verifyNoTestUnitErrors = false;
await resolveTestCode('''
import 'package:flutter/material.dart';
var w = const Text();
''');
var w = _getTopVariableCreation('w');
expect(Flutter.getWidgetPresentationText(w), 'Text');
}
Future<void> test_getWidgetPresentationText_unresolved() async {
verifyNoTestUnitErrors = false;
await resolveTestCode('''
import 'package:flutter/material.dart';
var w = new Foo();
''');
var w = _getTopVariableCreation('w');
expect(Flutter.getWidgetPresentationText(w), isNull);
}
Future<void> test_identifyWidgetExpression_node_instanceCreation() async {
Future<void> test_enclosingWidgetExpression_node_instanceCreation() async {
await resolveTestCode('''
import 'package:flutter/widgets.dart';
@@ -120,14 +51,11 @@ class MyWidget extends StatelessWidget {
var constructorName = creation.constructorName;
var namedType = constructorName.type;
var argumentList = creation.argumentList;
expect(Flutter.identifyWidgetExpression(creation), creation);
expect(Flutter.identifyWidgetExpression(constructorName), creation);
expect(Flutter.identifyWidgetExpression(namedType), creation);
expect(Flutter.identifyWidgetExpression(argumentList), isNull);
expect(
Flutter.identifyWidgetExpression(argumentList.arguments[0]),
isNull,
);
expect(creation.findWidgetExpression, creation);
expect(constructorName.findWidgetExpression, creation);
expect(namedType.findWidgetExpression, creation);
expect(argumentList.findWidgetExpression, isNull);
expect(argumentList.arguments[0].findWidgetExpression, isNull);
}
// MyWidget.named(5678);
@@ -137,19 +65,16 @@ class MyWidget extends StatelessWidget {
var constructorName = creation.constructorName;
var namedType = constructorName.type;
var argumentList = creation.argumentList;
expect(Flutter.identifyWidgetExpression(creation), creation);
expect(Flutter.identifyWidgetExpression(constructorName), creation);
expect(Flutter.identifyWidgetExpression(namedType), creation);
expect(Flutter.identifyWidgetExpression(constructorName.name), creation);
expect(Flutter.identifyWidgetExpression(argumentList), isNull);
expect(
Flutter.identifyWidgetExpression(argumentList.arguments[0]),
isNull,
);
expect(creation.findWidgetExpression, creation);
expect(constructorName.findWidgetExpression, creation);
expect(namedType.findWidgetExpression, creation);
expect(constructorName.name.findWidgetExpression, creation);
expect(argumentList.findWidgetExpression, isNull);
expect(argumentList.arguments[0].findWidgetExpression, isNull);
}
}
Future<void> test_identifyWidgetExpression_node_invocation() async {
Future<void> test_enclosingWidgetExpression_node_invocation() async {
await resolveTestCode('''
import 'package:flutter/widgets.dart';
@@ -163,24 +88,21 @@ Text createText(String txt) => Text(txt);
''');
{
var invocation = findNode.methodInvocation('createEmptyText();');
expect(Flutter.identifyWidgetExpression(invocation), invocation);
expect(invocation.findWidgetExpression, invocation);
var argumentList = invocation.argumentList;
expect(Flutter.identifyWidgetExpression(argumentList), isNull);
expect(argumentList.findWidgetExpression, isNull);
}
{
var invocation = findNode.methodInvocation("createText('xyz');");
expect(Flutter.identifyWidgetExpression(invocation), invocation);
expect(invocation.findWidgetExpression, invocation);
var argumentList = invocation.argumentList;
expect(Flutter.identifyWidgetExpression(argumentList), isNull);
expect(
Flutter.identifyWidgetExpression(argumentList.arguments[0]),
isNull,
);
expect(argumentList.findWidgetExpression, isNull);
expect(argumentList.arguments[0].findWidgetExpression, isNull);
}
}
Future<void> test_identifyWidgetExpression_node_namedExpression() async {
Future<void> test_enclosingWidgetExpression_node_namedExpression() async {
await resolveTestCode('''
import 'package:flutter/widgets.dart';
@@ -191,11 +113,11 @@ void f() {
Text createEmptyText() => Text('');
''');
var childExpression = findNode.namedExpression('child: ');
expect(Flutter.identifyWidgetExpression(childExpression), isNull);
expect(childExpression.findWidgetExpression, isNull);
}
Future<void>
test_identifyWidgetExpression_node_prefixedIdentifier_identifier() async {
test_enclosingWidgetExpression_node_prefixedIdentifier_identifier() async {
await resolveTestCode('''
import 'package:flutter/widgets.dart';
@@ -210,11 +132,11 @@ void f(Foo foo) {
}
''');
var bar = findNode.simple('bar; // ref');
expect(Flutter.identifyWidgetExpression(bar), bar.parent);
expect(bar.findWidgetExpression, bar.parent);
}
Future<void>
test_identifyWidgetExpression_node_prefixedIdentifier_prefix() async {
test_enclosingWidgetExpression_node_prefixedIdentifier_prefix() async {
await resolveTestCode('''
import 'package:flutter/widgets.dart';
@@ -229,10 +151,10 @@ void f(Foo foo) {
}
''');
var foo = findNode.simple('foo.bar');
expect(Flutter.identifyWidgetExpression(foo), foo.parent);
expect(foo.findWidgetExpression, foo.parent);
}
Future<void> test_identifyWidgetExpression_node_simpleIdentifier() async {
Future<void> test_enclosingWidgetExpression_node_simpleIdentifier() async {
await resolveTestCode('''
import 'package:flutter/widgets.dart';
@@ -241,10 +163,10 @@ void f(Widget widget) {
}
''');
var expression = findNode.simple('widget; // ref');
expect(Flutter.identifyWidgetExpression(expression), expression);
expect(expression.findWidgetExpression, expression);
}
Future<void> test_identifyWidgetExpression_node_switchExpression() async {
Future<void> test_enclosingWidgetExpression_node_switchExpression() async {
await resolveTestCode('''
import 'package:flutter/widgets.dart';
@@ -253,10 +175,10 @@ Widget f() => switch (1) {
};
''');
var expression = findNode.instanceCreation('Container');
expect(Flutter.identifyWidgetExpression(expression), expression);
expect(expression.findWidgetExpression, expression);
}
Future<void> test_identifyWidgetExpression_null() async {
Future<void> test_enclosingWidgetExpression_null() async {
await resolveTestCode('''
import 'package:flutter/widgets.dart';
@@ -267,19 +189,19 @@ void f() {
Text createEmptyText() => Text('');
''');
expect(Flutter.identifyWidgetExpression(null), isNull);
expect(null.findWidgetExpression, isNull);
{
var expression = findNode.integerLiteral('42;');
expect(Flutter.identifyWidgetExpression(expression), isNull);
expect(expression.findWidgetExpression, isNull);
}
{
var expression = findNode.simple('intVariable;');
expect(Flutter.identifyWidgetExpression(expression), isNull);
expect(expression.findWidgetExpression, isNull);
}
}
Future<void> test_identifyWidgetExpression_parent_argumentList() async {
Future<void> test_enclosingWidgetExpression_parent_argumentList() async {
await resolveTestCode('''
import 'package:flutter/widgets.dart';
@@ -291,11 +213,11 @@ void f() {
void useWidget(Widget w) {}
''');
var expression = findNode.simple('text); // ref');
expect(Flutter.identifyWidgetExpression(expression), expression);
expect(expression.findWidgetExpression, expression);
}
Future<void>
test_identifyWidgetExpression_parent_assignmentExpression() async {
test_enclosingWidgetExpression_parent_assignmentExpression() async {
await resolveTestCode('''
import 'package:flutter/widgets.dart';
@@ -309,24 +231,24 @@ void useWidget(Widget w) {}
// Assignment itself.
{
var expression = findNode.simple('text =');
expect(Flutter.identifyWidgetExpression(expression), isNull);
expect(expression.findWidgetExpression, isNull);
}
// Left hand side.
{
var expression = findNode.assignment('text =');
expect(Flutter.identifyWidgetExpression(expression), isNull);
expect(expression.findWidgetExpression, isNull);
}
// Right hand side.
{
var expression = findNode.instanceCreation('Text(');
expect(Flutter.identifyWidgetExpression(expression), expression);
expect(expression.findWidgetExpression, expression);
}
}
Future<void>
test_identifyWidgetExpression_parent_conditionalExpression() async {
test_enclosingWidgetExpression_parent_conditionalExpression() async {
await resolveTestCode('''
import 'package:flutter/widgets.dart';
@@ -335,25 +257,25 @@ void f(bool condition, Widget w1, Widget w2) {
}
''');
var thenWidget = findNode.simple('w1 :');
expect(Flutter.identifyWidgetExpression(thenWidget), thenWidget);
expect(thenWidget.findWidgetExpression, thenWidget);
var elseWidget = findNode.simple('w2;');
expect(Flutter.identifyWidgetExpression(elseWidget), elseWidget);
expect(elseWidget.findWidgetExpression, elseWidget);
}
Future<void>
test_identifyWidgetExpression_parent_expressionFunctionBody() async {
test_enclosingWidgetExpression_parent_expressionFunctionBody() async {
await resolveTestCode('''
import 'package:flutter/widgets.dart';
void f(Widget widget) => widget; // ref
''');
var expression = findNode.simple('widget; // ref');
expect(Flutter.identifyWidgetExpression(expression), expression);
expect(expression.findWidgetExpression, expression);
}
Future<void>
test_identifyWidgetExpression_parent_expressionStatement() async {
test_enclosingWidgetExpression_parent_expressionStatement() async {
await resolveTestCode('''
import 'package:flutter/widgets.dart';
@@ -362,10 +284,10 @@ void f(Widget widget) {
}
''');
var expression = findNode.simple('widget; // ref');
expect(Flutter.identifyWidgetExpression(expression), expression);
expect(expression.findWidgetExpression, expression);
}
Future<void> test_identifyWidgetExpression_parent_forElement() async {
Future<void> test_enclosingWidgetExpression_parent_forElement() async {
await resolveTestCode('''
import 'package:flutter/widgets.dart';
@@ -378,10 +300,10 @@ void f(bool b) {
void useWidget(Widget w) {}
''');
var expression = findNode.instanceCreation('Container()');
expect(Flutter.identifyWidgetExpression(expression), expression);
expect(expression.findWidgetExpression, expression);
}
Future<void> test_identifyWidgetExpression_parent_ifElement() async {
Future<void> test_enclosingWidgetExpression_parent_ifElement() async {
await resolveTestCode('''
import 'package:flutter/widgets.dart';
@@ -397,13 +319,13 @@ void f(bool b) {
void useWidget(Widget w) {}
''');
var thenExpression = findNode.instanceCreation("Text('then')");
expect(Flutter.identifyWidgetExpression(thenExpression), thenExpression);
expect(thenExpression.findWidgetExpression, thenExpression);
var elseExpression = findNode.instanceCreation("Text('else')");
expect(Flutter.identifyWidgetExpression(elseExpression), elseExpression);
expect(elseExpression.findWidgetExpression, elseExpression);
}
Future<void> test_identifyWidgetExpression_parent_listLiteral() async {
Future<void> test_enclosingWidgetExpression_parent_listLiteral() async {
await resolveTestCode('''
import 'package:flutter/widgets.dart';
@@ -412,10 +334,10 @@ List<Widget> f(Widget widget) {
}
''');
var expression = findNode.simple('widget]; // ref');
expect(Flutter.identifyWidgetExpression(expression), expression);
expect(expression.findWidgetExpression, expression);
}
Future<void> test_identifyWidgetExpression_parent_namedExpression() async {
Future<void> test_enclosingWidgetExpression_parent_namedExpression() async {
await resolveTestCode('''
import 'package:flutter/widgets.dart';
@@ -427,10 +349,10 @@ void f() {
void useWidget({required Widget child}) {}
''');
var expression = findNode.simple('text); // ref');
expect(Flutter.identifyWidgetExpression(expression), expression);
expect(expression.findWidgetExpression, expression);
}
Future<void> test_identifyWidgetExpression_parent_returnStatement() async {
Future<void> test_enclosingWidgetExpression_parent_returnStatement() async {
await resolveTestCode('''
import 'package:flutter/widgets.dart';
@@ -439,7 +361,76 @@ Widget f(Widget widget) {
}
''');
var expression = findNode.simple('widget; // ref');
expect(Flutter.identifyWidgetExpression(expression), expression);
expect(expression.findWidgetExpression, expression);
}
Future<void> test_getWidgetPresentationText_icon() async {
await resolveTestCode('''
import 'package:flutter/material.dart';
var w = const Icon(Icons.book);
''');
var widget = _getTopVariableCreation('w');
expect(widget.widgetPresentationText, 'Icon(Icons.book)');
}
Future<void> test_getWidgetPresentationText_icon_withoutArguments() async {
verifyNoTestUnitErrors = false;
await resolveTestCode('''
import 'package:flutter/material.dart';
var w = const Icon();
''');
var widget = _getTopVariableCreation('w');
expect(widget.widgetPresentationText, 'Icon');
}
Future<void> test_getWidgetPresentationText_notWidget() async {
await resolveTestCode('''
import 'package:flutter/material.dart';
var w = Object();
''');
var widget = _getTopVariableCreation('w');
expect(widget.widgetPresentationText, isNull);
}
Future<void> test_getWidgetPresentationText_text() async {
await resolveTestCode('''
import 'package:flutter/material.dart';
var w = const Text('foo');
''');
var widget = _getTopVariableCreation('w');
expect(widget.widgetPresentationText, "Text('foo')");
}
Future<void> test_getWidgetPresentationText_text_longText() async {
await resolveTestCode('''
import 'package:flutter/material.dart';
var w = const Text('${'abc' * 100}');
''');
var widget = _getTopVariableCreation('w');
expect(
widget.widgetPresentationText,
"Text('abcabcabcabcab...cabcabcabcabc')",
);
}
Future<void> test_getWidgetPresentationText_text_withoutArguments() async {
verifyNoTestUnitErrors = false;
await resolveTestCode('''
import 'package:flutter/material.dart';
var w = const Text();
''');
var widget = _getTopVariableCreation('w');
expect(widget.widgetPresentationText, 'Text');
}
Future<void> test_getWidgetPresentationText_unresolved() async {
verifyNoTestUnitErrors = false;
await resolveTestCode('''
import 'package:flutter/material.dart';
var w = new Foo();
''');
var widget = _getTopVariableCreation('w');
expect(widget.widgetPresentationText, isNull);
}
Future<void> test_isWidget() async {
@@ -453,19 +444,19 @@ class NotFlutter {}
class NotWidget extends State {}
''');
var myStatelessWidget = testUnitElement.getClass('MyStatelessWidget');
expect(Flutter.isWidget(myStatelessWidget), isTrue);
expect(myStatelessWidget.isWidget, isTrue);
var myStatefulWidget = testUnitElement.getClass('MyStatefulWidget');
expect(Flutter.isWidget(myStatefulWidget), isTrue);
expect(myStatefulWidget.isWidget, isTrue);
var myContainer = testUnitElement.getClass('MyContainer');
expect(Flutter.isWidget(myContainer), isTrue);
expect(myContainer.isWidget, isTrue);
var notFlutter = testUnitElement.getClass('NotFlutter');
expect(Flutter.isWidget(notFlutter), isFalse);
expect(notFlutter.isWidget, isFalse);
var notWidget = testUnitElement.getClass('NotWidget');
expect(Flutter.isWidget(notWidget), isFalse);
expect(notWidget.isWidget, isFalse);
}
Future<void> test_isWidgetCreation() async {
@@ -475,13 +466,12 @@ import 'package:flutter/widgets.dart';
var a = Object();
var b = Text('bbb');
''');
expect(Flutter.isWidgetCreation(null), isFalse);
var a = _getTopVariableCreation('a');
expect(Flutter.isWidgetCreation(a), isFalse);
expect(a.isWidgetCreation, isFalse);
var b = _getTopVariableCreation('b');
expect(Flutter.isWidgetCreation(b), isTrue);
expect(b.isWidgetCreation, isTrue);
}
Future<void> test_isWidgetExpression() async {
@@ -506,44 +496,44 @@ Text createEmptyText() => new Text('');
''');
{
var expression = findNode.simple('named(); // use');
expect(Flutter.isWidgetExpression(expression), isFalse);
expect(expression.isWidgetExpression, isFalse);
var creation = expression.parent?.parent as InstanceCreationExpression;
expect(Flutter.isWidgetExpression(creation), isTrue);
expect(creation.isWidgetExpression, isTrue);
}
{
var expression = findNode.instanceCreation("Text('abc')");
expect(Flutter.isWidgetExpression(expression), isTrue);
expect(expression.isWidgetExpression, isTrue);
}
{
var expression = findNode.simple('text;');
expect(Flutter.isWidgetExpression(expression), isTrue);
expect(expression.isWidgetExpression, isTrue);
}
{
var expression = findNode.methodInvocation('createEmptyText();');
expect(Flutter.isWidgetExpression(expression), isTrue);
expect(expression.isWidgetExpression, isTrue);
}
{
var expression = findNode.namedType('Container(');
expect(Flutter.isWidgetExpression(expression), isFalse);
expect(expression.isWidgetExpression, isFalse);
}
{
var expression = findNode.namedExpression('child: ');
expect(Flutter.isWidgetExpression(expression), isFalse);
expect(expression.isWidgetExpression, isFalse);
}
{
var expression = findNode.integerLiteral('42;');
expect(Flutter.isWidgetExpression(expression), isFalse);
expect(expression.isWidgetExpression, isFalse);
}
{
var expression = findNode.simple('intVariable;');
expect(Flutter.isWidgetExpression(expression), isFalse);
expect(expression.isWidgetExpression, isFalse);
}
}
@@ -4,7 +4,7 @@
import 'dart:io' as io;
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/dart/analysis/context_root.dart';
import 'package:analyzer/dart/analysis/results.dart';
@@ -135,7 +135,7 @@ class FlutterDataCollector extends RecursiveAstVisitor<void> {
@override
void visitInstanceCreationExpression(InstanceCreationExpression node) {
var previousParentWidget = parentWidget;
if (Flutter.isWidgetCreation(node)) {
if (node.isWidgetCreation) {
var element = node.constructorName.staticElement;
if (element == null) {
throw StateError(
@@ -9,7 +9,7 @@ import 'package:_fe_analyzer_shared/src/base/syntactic_entity.dart';
import 'package:analysis_server/src/protocol_server.dart'
show convertElementToElementKind, ElementKind;
import 'package:analysis_server/src/services/completion/dart/feature_computer.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/dart/analysis/context_root.dart';
import 'package:analyzer/dart/analysis/results.dart';
@@ -303,8 +303,8 @@ class RelevanceDataCollector extends RecursiveAstVisitor<void> {
void visitArgumentList(ArgumentList node) {
var context = _argumentListContext(node);
var parent = node.parent;
var inWidgetConstructor = parent is InstanceCreationExpression &&
Flutter.isWidgetType(parent.staticType);
var inWidgetConstructor =
parent is InstanceCreationExpression && parent.staticType.isWidgetType;
for (var argument in node.arguments) {
var realArgument = argument;
var argumentKind = 'unnamed';
@@ -8,7 +8,7 @@ import 'dart:io' as io;
import 'package:_fe_analyzer_shared/src/base/syntactic_entity.dart';
import 'package:analysis_server/src/protocol_server.dart' show ElementKind;
import 'package:analysis_server/src/services/completion/dart/feature_computer.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/dart/analysis/context_root.dart';
import 'package:analyzer/dart/analysis/results.dart';
@@ -1276,7 +1276,7 @@ class RelevanceDataCollector extends RecursiveAstVisitor<void> {
} else if (parent is FunctionExpressionInvocation) {
return 'function';
} else if (parent is InstanceCreationExpression) {
if (Flutter.isWidgetType(parent.staticType)) {
if (parent.staticType.isWidgetType) {
return 'widgetConstructor';
}
return 'constructor';
@@ -18,7 +18,7 @@ class AnalysisSessionHelper {
AnalysisSessionHelper(this.session);
/// Return the [ClassElement] with the given [className] that is exported
/// Returns the [ClassElement] with the given [className] that is exported
/// from the library with the given [libraryUri], or `null` if the library
/// does not export a class with such name.
Future<ClassElement?> getClass(String libraryUri, String className) async {
@@ -55,6 +55,12 @@ class AnalysisSessionHelper {
return null;
}
/// Returns the [ClassElement] with the given [className] that is exported
/// from the Flutter widgets library, or `null` if the library does not export
/// a class with such name.
Future<ClassElement?> getFlutterClass(String className) =>
getClass('package:flutter/widgets.dart', className);
/// Return the [MixinElement] with the given [name] that is exported
/// from the library with the given [libraryUri], or `null` if the library
/// does not export a class with such name.