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:
committed by
Commit Queue
parent
684f8639d1
commit
cda4f034ed
@@ -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));
|
||||
|
||||
+4
-4
@@ -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';
|
||||
|
||||
+3
-3
@@ -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;
|
||||
}
|
||||
|
||||
+4
-6
@@ -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
-4
@@ -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;
|
||||
}
|
||||
|
||||
+2
-2
@@ -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
-10
@@ -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;
|
||||
}
|
||||
|
||||
+6
-8
@@ -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);
|
||||
|
||||
+5
-7
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user