Skip to content

Commit

Permalink
Version 3.8.0-71.0.dev
Browse files Browse the repository at this point in the history
Merge dacb2a7 into dev
  • Loading branch information
Dart CI committed Feb 4, 2025
2 parents 548dcc7 + dacb2a7 commit 1e8b9ea
Show file tree
Hide file tree
Showing 22 changed files with 229 additions and 333 deletions.
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@

### Tools

#### Analyzer

- Added the experimental [`unnecessary_ignore`][] lint rule.

[`unnecessary_ignore`]: http://dart.dev/lints/unnecessary_ignore

#### Dart Development Compiler (dartdevc)

In order to align with dart2js semantics, DDC will now throw a runtime error
Expand Down Expand Up @@ -94,7 +100,7 @@ main() {
- Code completion now suggests instance variables when completing inside the
initializer of a _late_ field.
- Assists and quick fixes that add a const keyword now consider the
`prefer_const_declarations` lint rule, prefering to add `const` to a variable
`prefer_const_declarations` lint rule, preferring to add `const` to a variable
declaration rather than the initial value.
- Add a fix to add a missing `on` keyword in an extension declaration.
- Add a fix to wrap an ambiguous property access or method call in an extension
Expand All @@ -109,6 +115,7 @@ main() {
- Add the [`unnecessary_underscores`][] lint rule.
- Add the experimental [`specify_nonobvious_property_types`][] lint rule.
- Add the experimental [`omit_obvious_property_types`][] lint rule.
- Add the experimental [`unnecessary_async`][] lint rule.
- Add the experimental [`unsafe_variance`][] lint rule.
- Remove the [`package_api_docs`][] lint rule.
- Remove the [`unsafe_html`][] lint rule.
Expand All @@ -117,6 +124,7 @@ main() {
[`unnecessary_underscores`]: https://dart.dev/lints/unnecessary_underscores
[`specify_nonobvious_property_types`]: https://dart.dev/tools/linter-rules/specify_nonobvious_property_types
[`omit_obvious_property_types`]: https://dart.dev/tools/linter-rules/omit_obvious_property_types
[`unnecessary_async`]: http://dart.dev/lints/unnecessary_async
[`unsafe_variance`]: https://dart.dev/tools/linter-rules/unsafe_variance
[`package_api_docs`]: https://dart.dev/tools/linter-rules/package_api_docs
[`unsafe_html`]: https://dart.dev/tools/linter-rules/unsafe_html
Expand Down
229 changes: 40 additions & 189 deletions pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,23 @@
// 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.

// ignore_for_file: analyzer_use_new_elements

/// Utilities for converting Dart entities into analysis server's protocol
/// entities.
library;

import 'package:analysis_server/src/protocol_server.dart';
import 'package:analyzer/dart/element/element.dart' as engine;
import 'package:analyzer/dart/element/element2.dart' as engine;
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/utilities/extensions/element.dart';
import 'package:path/path.dart' as path;

/// Return a protocol [Element] corresponding to the given [engine.Element].
Element convertElement(engine.Element element) {
Element convertElement(engine.Element2 element) {
var kind = convertElementToElementKind(element);
var name = getElementDisplayName(element);
var elementTypeParameters = _getTypeParametersString(element);
var aliasedType = getAliasedTypeString(element);
var elementParameters = getParametersString(element);
var elementReturnType = getReturnTypeString(element);
return Element(
kind,
name,
Element.makeFlags(
isPrivate: element.isPrivate,
isDeprecated: element.hasDeprecated,
isAbstract: _isAbstract(element),
isConst: _isConst(element),
isFinal: _isFinal(element),
isStatic: _isStatic(element),
),
location: newLocation_fromElement(element),
typeParameters: elementTypeParameters,
aliasedType: aliasedType,
parameters: elementParameters,
returnType: elementReturnType,
);
}

Element convertElement2(engine.Element2 element) {
var kind = convertElementToElementKind2(element);
var name = getElementDisplayName2(element);
var elementTypeParameters = _getTypeParametersString2(element);
var aliasedType = getAliasedTypeString2(element);
var elementParameters = getParametersString2(element);
var elementParameters = getParametersString(element);
var elementReturnType = getReturnTypeString2(element);
return Element(
kind,
Expand All @@ -57,10 +28,10 @@ Element convertElement2(engine.Element2 element) {
isDeprecated:
(element is engine.Annotatable) &&
(element as engine.Annotatable).metadata2.hasDeprecated,
isAbstract: _isAbstract2(element),
isConst: _isConst2(element),
isFinal: _isFinal2(element),
isStatic: _isStatic2(element),
isAbstract: _isAbstract(element),
isConst: _isConst(element),
isFinal: _isFinal(element),
isStatic: _isStatic(element),
),
location: newLocation_fromElement2(element),
typeParameters: elementTypeParameters,
Expand Down Expand Up @@ -149,21 +120,8 @@ ElementKind convertElementKind(engine.ElementKind kind) {
return ElementKind.UNKNOWN;
}

/// Return an [ElementKind] corresponding to the given [engine.Element].
ElementKind convertElementToElementKind(engine.Element element) {
if (element is engine.EnumElement) {
return ElementKind.ENUM;
} else if (element is engine.MixinElement) {
return ElementKind.MIXIN;
}
if (element is engine.FieldElement && element.isEnumConstant) {
return ElementKind.ENUM_CONSTANT;
}
return convertElementKind(element.kind);
}

/// Return an [ElementKind] corresponding to the given [engine.Element2].
ElementKind convertElementToElementKind2(engine.Element2 element) {
ElementKind convertElementToElementKind(engine.Element2 element) {
if (element is engine.EnumElement2) {
return ElementKind.ENUM;
} else if (element is engine.MixinElement2) {
Expand All @@ -175,72 +133,41 @@ ElementKind convertElementToElementKind2(engine.Element2 element) {
return convertElementKind(element.kind);
}

String getElementDisplayName(engine.Element element) {
if (element is engine.CompilationUnitElement) {
return path.basename(element.source.fullName);
} else {
return element.displayName;
}
Element convertLibraryFragment(CompilationUnitElementImpl fragment) {
var kind = convertElementToElementKind(fragment);
var name = getElementDisplayName(fragment);
var elementTypeParameters = _getTypeParametersString(fragment);
var aliasedType = getAliasedTypeString2(fragment);
var elementParameters = getParametersString(fragment);
var elementReturnType = getReturnTypeString2(fragment);
return Element(
kind,
name,
Element.makeFlags(
isPrivate: fragment.isPrivate,
isDeprecated: fragment.hasDeprecated,
isAbstract: _isAbstract(fragment),
isConst: _isConst(fragment),
isFinal: _isFinal(fragment),
isStatic: _isStatic(fragment),
),
location: newLocation_fromFragment(fragment),
typeParameters: elementTypeParameters,
aliasedType: aliasedType,
parameters: elementParameters,
returnType: elementReturnType,
);
}

String getElementDisplayName2(engine.Element2 element) {
String getElementDisplayName(engine.Element2 element) {
if (element is engine.LibraryFragment) {
return path.basename((element as engine.LibraryFragment).source.fullName);
} else {
return element.displayName;
}
}

String? getParametersString(engine.Element element) {
// TODO(scheglov): expose the corresponding feature from ExecutableElement
List<engine.ParameterElement> parameters;
if (element is engine.ExecutableElement) {
// valid getters don't have parameters
if (element.kind == engine.ElementKind.GETTER &&
element.parameters.isEmpty) {
return null;
}
parameters = element.parameters.toList();
} else if (element is engine.TypeAliasElement) {
var aliasedType = element.aliasedType;
if (aliasedType is FunctionType) {
parameters = aliasedType.parameters.toList();
} else {
return null;
}
} else {
return null;
}

parameters.sort(_preferRequiredParams);

var sb = StringBuffer();
var closeOptionalString = '';
for (var parameter in parameters) {
if (sb.isNotEmpty) {
sb.write(', ');
}
if (closeOptionalString.isEmpty) {
if (parameter.isNamed) {
sb.write('{');
closeOptionalString = '}';
} else if (parameter.isOptionalPositional) {
sb.write('[');
closeOptionalString = ']';
}
}
if (parameter.isRequiredNamed) {
sb.write('required ');
} else if (parameter.hasRequired) {
sb.write('@required ');
}
parameter.appendToWithoutDelimiters(sb);
}
sb.write(closeOptionalString);
return '($sb)';
}

String? getParametersString2(engine.Element2 element) {
String? getParametersString(engine.Element2 element) {
// TODO(scheglov): expose the corresponding feature from ExecutableElement
List<engine.FormalParameterElement> parameters;
if (element is engine.ExecutableElement2) {
Expand All @@ -261,7 +188,7 @@ String? getParametersString2(engine.Element2 element) {
return null;
}

parameters.sort(_preferRequiredParams2);
parameters.sort(_preferRequiredParams);

var sb = StringBuffer();
var closeOptionalString = '';
Expand Down Expand Up @@ -289,20 +216,7 @@ String? getParametersString2(engine.Element2 element) {
return '($sb)';
}

String? _getTypeParametersString(engine.Element element) {
List<engine.TypeParameterElement>? typeParameters;
if (element is engine.InterfaceElement) {
typeParameters = element.typeParameters;
} else if (element is engine.TypeAliasElement) {
typeParameters = element.typeParameters;
}
if (typeParameters == null || typeParameters.isEmpty) {
return null;
}
return '<${typeParameters.join(', ')}>';
}

String? _getTypeParametersString2(engine.Element2 element) {
String? _getTypeParametersString(engine.Element2 element) {
List<engine.TypeParameterElement2>? typeParameters;
if (element is engine.InterfaceElement2) {
typeParameters = element.typeParameters2;
Expand All @@ -315,23 +229,7 @@ String? _getTypeParametersString2(engine.Element2 element) {
return '<${typeParameters.join(', ')}>';
}

bool _isAbstract(engine.Element element) {
if (element is engine.ClassElement) {
return element.isAbstract;
}
if (element is engine.MethodElement) {
return element.isAbstract;
}
if (element is engine.MixinElement) {
return true;
}
if (element is engine.PropertyAccessorElement) {
return element.isAbstract;
}
return false;
}

bool _isAbstract2(engine.Element2 element) {
bool _isAbstract(engine.Element2 element) {
if (element is engine.ClassElement2) {
return element.isAbstract;
}
Expand All @@ -344,17 +242,7 @@ bool _isAbstract2(engine.Element2 element) {
return false;
}

bool _isConst(engine.Element element) {
if (element is engine.ConstructorElement) {
return element.isConst;
}
if (element is engine.VariableElement) {
return element.isConst;
}
return false;
}

bool _isConst2(engine.Element2 element) {
bool _isConst(engine.Element2 element) {
if (element is engine.ConstructorElement2) {
return element.isConst;
}
Expand All @@ -364,31 +252,14 @@ bool _isConst2(engine.Element2 element) {
return false;
}

bool _isFinal(engine.Element element) {
if (element is engine.VariableElement) {
return element.isFinal;
}
return false;
}

bool _isFinal2(engine.Element2 element) {
bool _isFinal(engine.Element2 element) {
if (element is engine.VariableElement2) {
return element.isFinal;
}
return false;
}

bool _isStatic(engine.Element element) {
if (element is engine.ExecutableElement) {
return element.isStatic;
}
if (element is engine.PropertyInducingElement) {
return element.isStatic;
}
return false;
}

bool _isStatic2(engine.Element2 element) {
bool _isStatic(engine.Element2 element) {
if (element is engine.ExecutableElement2) {
return element.isStatic;
}
Expand All @@ -400,26 +271,6 @@ bool _isStatic2(engine.Element2 element) {

/// Sort required named parameters before optional ones.
int _preferRequiredParams(
engine.ParameterElement e1,
engine.ParameterElement e2,
) {
var rank1 =
(e1.isRequiredNamed || e1.hasRequired)
? 0
: !e1.isNamed
? -1
: 1;
var rank2 =
(e2.isRequiredNamed || e2.hasRequired)
? 0
: !e2.isNamed
? -1
: 1;
return rank1 - rank2;
}

/// Sort required named parameters before optional ones.
int _preferRequiredParams2(
engine.FormalParameterElement e1,
engine.FormalParameterElement e2,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ void addDartOccurrences(OccurrencesCollector collector, CompilationUnit unit) {
// For legacy protocol, we only support occurrences with the same
// length, so we must filter the offset to only those that match the length
// from the element.
var serverElement = protocol.convertElement2(engineElement);
var serverElement = protocol.convertElement(engineElement);
// Prefer the length from the mapped element over the element directly,
// because 'name3' may contain 'new' for constructors which doesn't match
// what is in the source.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class SearchFindElementReferencesHandler extends LegacyHandler {
var result = protocol.SearchFindElementReferencesResult();
if (element != null) {
result.id = searchId;
result.element = protocol.convertElement(element);
result.element = protocol.convertElement(element.asElement2!);
}
sendResult(result);
// search elements
Expand Down
2 changes: 1 addition & 1 deletion pkg/analysis_server/lib/src/lsp/completion_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ CompletionDetail _getCompletionDetail(
}
String? parameters;
if (element != null) {
parameters = getParametersString2(element);
parameters = getParametersString(element);
// Prefer the element return type (because it may be more specific
// for overrides) and fall back to the parameter type or return type from
// the suggestion (handles records).
Expand Down
Loading

0 comments on commit 1e8b9ea

Please sign in to comment.