Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ jobs:
DART_VERSION="${{ steps.setup-dart.outputs.dart-version }}"
if [[ "$DART_VERSION" =~ ^3 ]]; then
./tool/delete_dart_2_only_files.sh
./tool/update_tests_for_dart_3.sh
# Stage these changes so they don't show up in the generated file `git diff` check below
git add .
fi
Expand Down Expand Up @@ -111,17 +110,17 @@ jobs:
strategy:
fail-fast: false
matrix:
sdk: [ 2.19.6, stable ]
sdk: [ stable ]
analyzer:
- ^5.13.0 # This should match the lower bound
- ^6.0.0
- ^7.0.0
exclude:
# Analyzer 6+ only resolves in Dart 3
- sdk: 2.19.6
analyzer: ^6.0.0
- ^8.0.0
- ^9.0.0
- ^10.0.0
# Analyzer 6+ does not resolve in Dart 2.
include:
- sdk: 2.19.6
analyzer: ^7.0.0
analyzer: ^5.13.0 # This should match the lower bound

steps:
- uses: actions/checkout@v4
Expand All @@ -146,7 +145,6 @@ jobs:
DART_VERSION="${{ steps.setup-dart.outputs.dart-version }}"
if [[ "$DART_VERSION" =~ ^3 ]]; then
./tool/delete_dart_2_only_files.sh
./tool/update_tests_for_dart_3.sh
fi

- name: Analyze package source
Expand Down Expand Up @@ -196,7 +194,7 @@ jobs:
run: |
DART_VERSION="${{ steps.setup-dart.outputs.dart-version }}"
if [[ "$DART_VERSION" =~ ^3 ]]; then
(cd ../.. && ./tool/delete_dart_2_only_files.sh && ./tool/update_tests_for_dart_3.sh)
(cd ../.. && ./tool/delete_dart_2_only_files.sh)
fi

- name: Validate dependencies
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# OverReact Changelog

## Unreleased
- Allow analyzer 8.x, 9.x, 10.x

## 5.5.0
- [#989] Optimize generated code to decrease dart2js compile size, saving ~577 bytes per component (when using `-03 --csp --minify`)
- [#992] Fix compilation errors for legacy boilerplate defined in libraries with a Dart language version of >=3.0
Expand Down
17 changes: 14 additions & 3 deletions lib/src/builder/parsing/ast_util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,27 @@ extension TypeAnnotationNameHelper on TypeAnnotation {
/// Extension built on [NameHelper] to allow for easy access to the `name`
/// field of [Identifier]s.
extension TypeNameHelper on NamedType {
// Backwards compatibility for various analyzer versions that remove name/name2.
dynamic get name => this.name2; // Use `this.` to point to real impl if it exists, not extension.
dynamic get name2 => this.name; // Use `this.` to point to real impl if it exists, not extension.
dynamic get _name => name;
String get nameLexeme {
final name = this._name;
if (name is Identifier) return name.name;
if (name is Token) return name.lexeme;
if (name is String) return name;
throw UnimplementedError('Unexpected type for name: ${name.runtimeType}');
}

/// The type name without any namespace prefixes.
String get nameWithoutPrefix => name2.lexeme;
String get nameWithoutPrefix => nameLexeme;

/// The type name including the namespace prefix.
String get nameWithPrefix {
final prefix = importPrefix?.name.lexeme;
final name = name2.lexeme;
return [
if (prefix != null) prefix,
name,
nameLexeme,
].join('.');
}
}
Expand Down
32 changes: 13 additions & 19 deletions lib/src/builder/vendor/transformer_utils/src/analyzer_helpers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ String copyClassMember(ClassMember? member, String body) {
if (member.isSetter) return _copySetterDeclaration(member, body);
return _copyMethodDeclaration(member, body);
}
throw UnsupportedError(
'Unsupported class member type: ${member.runtimeType}. '
throw UnsupportedError('Unsupported class member type: ${member.runtimeType}. '
'Only FieldDeclaration and MethodDeclaration are supported.');
}

Expand All @@ -45,8 +44,7 @@ String copyClassMember(ClassMember? member, String body) {
/// If this is being leveraged within a transformer, you can associate the
/// returned [DeclarationWithMeta] instance with the asset in which it is
/// located by passing in an [assetId].
Iterable<CompilationUnitMember> getDeclarationsAnnotatedBy(
CompilationUnit unit, Type annotation) {
Iterable<CompilationUnitMember> getDeclarationsAnnotatedBy(CompilationUnit unit, Type annotation) {
var annotationName = _getReflectedName(annotation);
return unit.declarations.where((member) {
return member.metadata.any((meta) => meta.name.name == annotationName);
Expand Down Expand Up @@ -91,8 +89,8 @@ dynamic getValue(Expression expression,
/// or null if no matching annotations are found.
Annotation? getMatchingAnnotation(AnnotatedNode member, Type annotationType) {
// Be sure to use `originalDeclaration` so that generic parameters work.
final classMirror = mirrors.reflectClass(annotationType).originalDeclaration
as mirrors.ClassMirror;
final classMirror =
mirrors.reflectClass(annotationType).originalDeclaration as mirrors.ClassMirror;
String className = mirrors.MirrorSystem.getName(classMirror.simpleName);

// Find the annotation that matches [type]'s name.
Expand Down Expand Up @@ -128,19 +126,16 @@ dynamic instantiateAnnotation(AnnotatedNode member, Type annotationType,
List positionalParameters = [];

matchingAnnotationArgs.arguments.forEach((argument) {
var onUnsupportedExpression = onUnsupportedArgument == null
? null
: (_) => onUnsupportedArgument(argument);
var onUnsupportedExpression =
onUnsupportedArgument == null ? null : (_) => onUnsupportedArgument(argument);

if (argument is NamedExpression) {
var name = argument.name.label.name;
var value = getValue(argument.expression,
onUnsupportedExpression: onUnsupportedExpression);
var value = getValue(argument.expression, onUnsupportedExpression: onUnsupportedExpression);

namedParameters[Symbol(name)] = value;
} else {
var value =
getValue(argument, onUnsupportedExpression: onUnsupportedExpression);
var value = getValue(argument, onUnsupportedExpression: onUnsupportedExpression);

positionalParameters.add(value);
}
Expand All @@ -150,12 +145,12 @@ dynamic instantiateAnnotation(AnnotatedNode member, Type annotationType,
String constructorName = _getConstructorName(matchingAnnotation) ?? '';

// Be sure to use `originalDeclaration` so that generic parameters work.
final classMirror = mirrors.reflectClass(annotationType).originalDeclaration
as mirrors.ClassMirror;
final classMirror =
mirrors.reflectClass(annotationType).originalDeclaration as mirrors.ClassMirror;

try {
var instanceMirror = classMirror.newInstance(
Symbol(constructorName), positionalParameters, namedParameters);
var instanceMirror =
classMirror.newInstance(Symbol(constructorName), positionalParameters, namedParameters);
return instanceMirror.reflectee;
} catch (e, stacktrace) {
throw Exception('Unable to instantiate annotation: $matchingAnnotation. This is '
Expand Down Expand Up @@ -232,8 +227,7 @@ String _copyMethodDeclaration(MethodDeclaration decl, String body) {
///
/// Workaround for a Dart analyzer issue where the constructor name is included
/// in [annotation.name].
String _getClassName(Annotation annotation) =>
annotation.name.name.split('.').first;
String _getClassName(Annotation annotation) => annotation.name.name.split('.').first;

/// Returns the name of the constructor being instantiated for [annotation], or
/// null if the annotation is not the invocation of a named constructor.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ import 'package:source_span/source_span.dart';
/// `lib/`.
Uri assetIdToPackageUri(AssetId id) {
if (!id.path.startsWith('lib/')) return Uri(path: id.path);
return Uri(
scheme: 'package',
path: path.url.join(id.package, id.path.replaceFirst('lib/', '')));
return Uri(scheme: 'package', path: path.url.join(id.package, id.path.replaceFirst('lib/', '')));
}

/// Returns a [SourceSpan] spanning from the beginning to the end of the given
Expand All @@ -38,8 +36,7 @@ Uri assetIdToPackageUri(AssetId id) {
SourceSpan getSpanForNode(SourceFile sourceFile, AstNode node,
{bool skipCommentAndMetadata = true}) {
if (skipCommentAndMetadata && node is AnnotatedNode) {
return sourceFile.span(
node.firstTokenAfterCommentAndMetadata.offset, node.end);
return sourceFile.span(node.firstTokenAfterCommentAndMetadata.offset, node.end);
}

return sourceFile.span(node.offset, node.end);
Expand Down
10 changes: 4 additions & 6 deletions lib/src/builder/vendor/transformer_utils/src/node_with_meta.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,9 @@ class NodeWithMeta<TNode extends AnnotatedNode, TMeta> {
/// Construct a [NodeWithMeta] instance from an [AnnotatedNode].
/// The original node will be available via [node].
/// The instantiated annotation of type `TMeta` will be available via [meta].
NodeWithMeta(this.node, {this.assetId})
: this.metaNode = getMatchingAnnotation(node, TMeta) {
this._meta = instantiateAnnotation(node, TMeta,
onUnsupportedArgument: unsupportedArguments.add) as TMeta?;
NodeWithMeta(this.node, {this.assetId}) : this.metaNode = getMatchingAnnotation(node, TMeta) {
this._meta = instantiateAnnotation(node, TMeta, onUnsupportedArgument: unsupportedArguments.add)
as TMeta?;
}

/// Whether this node's metadata has arguments that could not be initialized using [getValue]
Expand All @@ -58,8 +57,7 @@ class NodeWithMeta<TNode extends AnnotatedNode, TMeta> {
/// Throws a [StateError] if this node's metadata is incomplete.
TMeta? get meta {
if (isIncomplete) {
throw StateError(
'Metadata is incomplete; unsupported arguments $unsupportedArguments. '
throw StateError('Metadata is incomplete; unsupported arguments $unsupportedArguments. '
'Use `potentiallyIncompleteMeta` instead.');
}
return _meta;
Expand Down
7 changes: 2 additions & 5 deletions lib/src/builder/vendor/transformer_utils/src/text_util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ library;
///
/// If [content] is null, a string version of the the `null` literal will be
/// returned instead.
String stringLiteral(String? content,
{bool quote = true, bool useSingleQuote = true}) {
String stringLiteral(String? content, {bool quote = true, bool useSingleQuote = true}) {
// Adapted from dart.convert library's JSON encoder:
// https://github.com/dart-lang/sdk/blob/1.12.0/sdk/lib/convert/json.dart#L565
//
Expand Down Expand Up @@ -129,9 +128,7 @@ String stringLiteral(String? content,
writeCharCode(hexDigit(charCode & 0xf));
break;
}
} else if (charCode == quoteChar ||
charCode == BACKSLASH ||
charCode == DOLLAR_SIGN) {
} else if (charCode == quoteChar || charCode == BACKSLASH || charCode == DOLLAR_SIGN) {
if (i > offset) writeStringSlice(content, offset, i);
offset = i + 1;
writeCharCode(BACKSLASH);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ class TransformedSourceFile {
throw Exception('Overlapping replacement $replacement in replacements $_replacements.');
}

var unmodifiedText =
sourceFile.getText(lastEdge, replacement.span.start.offset);
var unmodifiedText = sourceFile.getText(lastEdge, replacement.span.start.offset);
var removalText = replacement.span.text;
var additionText = replacement.newText;

Expand All @@ -102,9 +101,7 @@ class TransformedSourceFile {
String getTransformedText() {
StringBuffer transformedSource = StringBuffer();

iterateReplacements(
onUnmodified: transformedSource.write,
onAddition: transformedSource.write);
iterateReplacements(onUnmodified: transformedSource.write, onAddition: transformedSource.write);

return transformedSource.toString();
}
Expand Down Expand Up @@ -156,11 +153,9 @@ class TransformedSourceFile {
}
}

SourceSpan getSpan(SourceFile sourceFile, AstNode node,
{bool skipCommentAndMetadata = true}) {
SourceSpan getSpan(SourceFile sourceFile, AstNode node, {bool skipCommentAndMetadata = true}) {
if (skipCommentAndMetadata && node is AnnotatedNode) {
return sourceFile.span(
node.firstTokenAfterCommentAndMetadata.offset, node.end);
return sourceFile.span(node.firstTokenAfterCommentAndMetadata.offset, node.end);
}

return sourceFile.span(node.offset, node.end);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ library;

export './src/analyzer_helpers.dart'
show copyClassMember, getDeclarationsAnnotatedBy, instantiateAnnotation;
export './src/barback_utils.dart'
show assetIdToPackageUri, getSpanForNode;
export './src/barback_utils.dart' show assetIdToPackageUri, getSpanForNode;
export './src/node_with_meta.dart' show NodeWithMeta;
export './src/text_util.dart' show stringLiteral;
export './src/transformed_source_file.dart'
show TransformedSourceFile, getSpan;
export './src/transformed_source_file.dart' show TransformedSourceFile, getSpan;
13 changes: 9 additions & 4 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ environment:

dependencies:
collection: ^1.15.0
analyzer: '>=5.13.0 <8.0.0'
build: ^2.0.0
analyzer: '>=5.13.0 <11.0.0'
build: '>=2.0.0 <5.0.0'
dart_style: '>=2.0.0 <4.0.0'
js: ^0.6.1+1
logging: ^1.0.0
Expand All @@ -27,12 +27,11 @@ dependencies:

dev_dependencies:
benchmark_harness: ^2.2.1
build_resolvers: ^2.0.0
build_runner: ^2.0.0
build_test: '>=2.0.0 <4.0.0'
build_web_compilers: '>=3.2.6 <5.0.0'
dart_dev: ^4.0.1
dependency_validator: ^3.0.0
dependency_validator: '>=3.0.0 <6.0.0'
glob: ^2.0.1
io: ^1.0.0
react_testing_library: ^3.1.1
Expand All @@ -46,3 +45,9 @@ workiva:
core_checks:
version: 1
react_boilerplate: disabled
Comment thread
greglittlefield-wf marked this conversation as resolved.
Outdated

dependency_overrides:
dart_dev:
git:
url: https://github.com/Workiva/dart_dev.git
ref: raise-analyzer
Loading