Skip to content

Commit

Permalink
Version 3.4.0-149.0.dev
Browse files Browse the repository at this point in the history
Merge 276aa29 into dev
  • Loading branch information
Dart CI committed Feb 16, 2024
2 parents 947c8c4 + 276aa29 commit 660ee24
Show file tree
Hide file tree
Showing 32 changed files with 1,536 additions and 436 deletions.
2 changes: 1 addition & 1 deletion DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ vars = {
"usage_rev": "67ecd7d1328347ec15cbf8d8a46918df75a66af8",
"vector_math_rev": "cb976c731f5f9011f09311cd1c39d5778d4f8f2e",
"watcher_rev": "21858a41da1482922e03ee65cdf2169d01d59a67",
"web_rev": "3f1285e9460c2e4141f9a8c2fdca8a0e8af05fa0",
"web_rev": "a54a1f0447979f9a3ea220199eca849ffb214e91",
"web_socket_channel_rev": "5241175e7c66271850d6e75fb9ec90068f9dd3c4", # https://github.com/dart-lang/sdk/issues/54165
"webdev_rev": "629c63214466a77d0994e9b8003120f48af9ef1d",
"webdriver_rev": "2c1b6f8b9d684caf62d72bb327c24f738a4e7455",
Expand Down
92 changes: 63 additions & 29 deletions PRESUBMIT.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,34 +30,53 @@ def is_dart_file(path):
return path.endswith('.dart')


def _CheckFormat(input_api,
identification,
extension,
windows,
hasFormatErrors: Callable[[str, str], bool],
should_skip=lambda path: False):
def get_old_contents(input_api, path):
local_root = input_api.change.RepositoryRoot()
upstream = input_api.change._upstream
unformatted_files = []
return scm.GIT.Capture(['show', upstream + ':' + path],
cwd=local_root,
strip_out=False)


def files_to_check_for_format(input_api, extension, exclude_folders):
files = []
exclude_folders += [
"pkg/front_end/testcases/", "pkg/front_end/parser_testcases/"
]
for git_file in input_api.AffectedTextFiles():
if git_file.LocalPath().startswith("pkg/front_end/testcases/"):
local_path = git_file.LocalPath()
if not local_path.endswith(extension):
continue
if git_file.LocalPath().startswith("pkg/front_end/parser_testcases/"):
continue
if should_skip(git_file.LocalPath()):
if any([local_path.startswith(f) for f in exclude_folders]):
continue
files.append(git_file)
return files


def _CheckFormat(input_api, identification, extension, windows,
hasFormatErrors: Callable[[str, list, str],
bool], exclude_folders):
files = files_to_check_for_format(input_api, extension, exclude_folders)
if not files:
return []

# Check for formatting errors in bulk first. This is orders of magnitude
# faster than checking file-by-file on large changes with hundreds of files.
if not hasFormatErrors(filenames=[f.AbsoluteLocalPath() for f in files]):
return []

print("Formatting errors found, comparing against old versions.")
unformatted_files = []
for git_file in files:
filename = git_file.AbsoluteLocalPath()
if filename.endswith(extension) and hasFormatErrors(filename=filename):
if hasFormatErrors(filename=filename):
old_version_has_errors = False
try:
path = git_file.LocalPath()
if windows:
# Git expects a linux style path.
path = path.replace(os.sep, '/')
old_contents = scm.GIT.Capture(['show', upstream + ':' + path],
cwd=local_root,
strip_out=False)
if hasFormatErrors(contents=old_contents):
if hasFormatErrors(contents=get_old_contents(input_api, path)):
old_version_has_errors = True
except subprocess.CalledProcessError as e:
old_version_has_errors = False
Expand Down Expand Up @@ -102,15 +121,22 @@ def _CheckDartFormat(input_api, output_api):
'--fix-named-default-separator',
]

def HasFormatErrors(filename: str = None, contents: str = None):
def HasFormatErrors(filename: str = None,
filenames: list = None,
contents: str = None):
# Don't look for formatting errors in multitests. Since those are very
# sensitive to whitespace, many cannot be reformatted without breaking
# them.
if filename and filename.endswith('_test.dart'):
with open(filename) as f:
contents = f.read()
if '//#' in contents:
return False
def skip_file(path):
if path.endswith('_test.dart'):
with open(path) as f:
contents = f.read()
if '//#' in contents:
return True
return False

if filename and skip_file(filename):
return False

args = [
dart,
Expand Down Expand Up @@ -138,6 +164,9 @@ def HasFormatErrors(filename: str = None, contents: str = None):
os.unlink(f.name)
elif contents:
process = subprocess.run(args, input=contents, text=True)
elif filenames:
args += [f for f in filenames if not skip_file(f)]
process = subprocess.run(args)
else:
args.append(filename)
process = subprocess.run(args)
Expand All @@ -149,7 +178,7 @@ def HasFormatErrors(filename: str = None, contents: str = None):
return process.returncode == 1

unformatted_files = _CheckFormat(input_api, "dart format", ".dart", windows,
HasFormatErrors)
HasFormatErrors, [])

if unformatted_files:
lineSep = " \\\n"
Expand Down Expand Up @@ -185,17 +214,22 @@ def _CheckStatusFiles(input_api, output_api):
print('WARNING: Status file linter not found: %s' % lint)
return []

def HasFormatErrors(filename=None, contents=None):
def HasFormatErrors(filename=None, filenames=None, contents=None):
if filenames:
# The status file linter doesn't support checking files in bulk.
# Returning `True` causes `_CheckFormat` to fallback to check
# formatting file by file below.
return True
args = [dart, lint] + (['-t'] if contents else [filename])
process = subprocess.run(args, input=contents, text=True)
return process.returncode != 0

def should_skip(path):
return (path.startswith("pkg/status_file/test/data/") or
path.startswith("pkg/front_end/"))

exclude_folders = [
"pkg/status_file/test/data/",
"pkg/front_end/",
]
unformatted_files = _CheckFormat(input_api, "status file", ".status",
windows, HasFormatErrors, should_skip)
windows, HasFormatErrors, exclude_folders)

if unformatted_files:
normalize = os.path.join(local_root, 'pkg', 'status_file', 'bin',
Expand Down
71 changes: 41 additions & 30 deletions pkg/analyzer/lib/src/dart/analysis/file_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ class FileState {
///
/// This feature set is then restricted, with the [packageLanguageVersion],
/// or with a `@dart` language override token in the file header.
final FeatureSet _featureSet;
final FeatureSet featureSet;

/// The language version for the package that contains this file.
final Version packageLanguageVersion;
Expand Down Expand Up @@ -438,7 +438,7 @@ class FileState {
this.uri,
this.source,
this.workspacePackage,
this._featureSet,
this.featureSet,
this.packageLanguageVersion,
this.analysisOptions,
) : uriProperties = FileUriProperties(uri);
Expand Down Expand Up @@ -515,6 +515,41 @@ class FileState {
}
}

/// Parses given [code] with the same features as this file.
CompilationUnitImpl parseCode({
required String code,
required AnalysisErrorListener errorListener,
}) {
CharSequenceReader reader = CharSequenceReader(code);
Scanner scanner = Scanner(source, reader, errorListener)
..configureFeatures(
featureSetForOverriding: featureSet,
featureSet: featureSet.restrictToVersion(
packageLanguageVersion,
),
);
Token token = scanner.tokenize(reportScannerErrors: false);
LineInfo lineInfo = LineInfo(scanner.lineStarts);

Parser parser = Parser(
source,
errorListener,
featureSet: scanner.featureSet,
lineInfo: lineInfo,
);

var unit = parser.parseCompilationUnit(token);
unit.languageVersion = LibraryLanguageVersion(
package: packageLanguageVersion,
override: scanner.overrideVersion,
);

// Ensure the string canonicalization cache size is reasonable.
pruneStringCanonicalizationCache();

return unit;
}

/// Read the file content and ensure that all of the file properties are
/// consistent with the read content, including API signature.
///
Expand All @@ -540,7 +575,7 @@ class FileState {
{
var signature = ApiSignature();
signature.addUint32List(_fsState._saltForUnlinked);
signature.addFeatureSet(_featureSet);
signature.addFeatureSet(featureSet);
signature.addLanguageVersion(packageLanguageVersion);
signature.addString(contentHash);
signature.addBool(exists);
Expand Down Expand Up @@ -733,34 +768,10 @@ class FileState {
}

CompilationUnitImpl _parse(AnalysisErrorListener errorListener) {
CharSequenceReader reader = CharSequenceReader(content);
Scanner scanner = Scanner(source, reader, errorListener)
..configureFeatures(
featureSetForOverriding: _featureSet,
featureSet: _featureSet.restrictToVersion(
packageLanguageVersion,
),
);
Token token = scanner.tokenize(reportScannerErrors: false);
LineInfo lineInfo = LineInfo(scanner.lineStarts);

Parser parser = Parser(
source,
errorListener,
featureSet: scanner.featureSet,
lineInfo: lineInfo,
return parseCode(
code: content,
errorListener: errorListener,
);

var unit = parser.parseCompilationUnit(token);
unit.languageVersion = LibraryLanguageVersion(
package: packageLanguageVersion,
override: scanner.overrideVersion,
);

// Ensure the string canonicalization cache size is reasonable.
pruneStringCanonicalizationCache();

return unit;
}

// TODO(scheglov): write tests
Expand Down
57 changes: 54 additions & 3 deletions pkg/analyzer/lib/src/summary2/library_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
// BSD-style license that can be found in the LICENSE file.

import 'package:_fe_analyzer_shared/src/field_promotability.dart';
import 'package:_fe_analyzer_shared/src/macros/code_optimizer.dart' as macro;
import 'package:_fe_analyzer_shared/src/macros/executor.dart' as macro;
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart' as file_state;
import 'package:analyzer/src/dart/analysis/file_state.dart' hide DirectiveUri;
import 'package:analyzer/src/dart/analysis/info_declaration_store.dart';
Expand All @@ -16,13 +18,15 @@ import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/field_name_non_promotability_info.dart'
as element_model;
import 'package:analyzer/src/dart/resolver/scope.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/summary2/combinator.dart';
import 'package:analyzer/src/summary2/constructor_initializer_resolver.dart';
import 'package:analyzer/src/summary2/default_value_resolver.dart';
import 'package:analyzer/src/summary2/element_builder.dart';
import 'package:analyzer/src/summary2/export.dart';
import 'package:analyzer/src/summary2/informative_data.dart';
import 'package:analyzer/src/summary2/link.dart';
import 'package:analyzer/src/summary2/linked_element_factory.dart';
import 'package:analyzer/src/summary2/macro_application.dart';
import 'package:analyzer/src/summary2/macro_merge.dart';
import 'package:analyzer/src/summary2/metadata_resolver.dart';
Expand Down Expand Up @@ -459,13 +463,18 @@ class LibraryBuilder {
return;
}

final augmentationCode = macroApplier.buildAugmentationLibraryCode(
var augmentationCode = macroApplier.buildAugmentationLibraryCode(
_macroResults.flattenedToList2,
);
if (augmentationCode == null) {
return;
}

var mergedUnit = kind.file.parseCode(
code: augmentationCode,
errorListener: AnalysisErrorListener.NULL_LISTENER,
);

kind.disposeMacroAugmentations(disposeFiles: true);

// Remove import for partial macro augmentations.
Expand All @@ -477,8 +486,23 @@ class LibraryBuilder {
final partialUnits = units.sublist(units.length - _macroResults.length);
units.length -= _macroResults.length;

final importState = kind.addMacroAugmentation(
var optimizedCodeEdits = _CodeOptimizer(
elementFactory: linker.elementFactory,
).optimize(
augmentationCode,
libraryDeclarationNames: element.definingCompilationUnit.children
.map((e) => e.name)
.nonNulls
.toSet(),
scannerConfiguration: Scanner.buildConfig(kind.file.featureSet),
);
var optimizedCode = macro.Edit.applyList(
optimizedCodeEdits.reversed.toList(),
augmentationCode,
);

final importState = kind.addMacroAugmentation(
optimizedCode,
addLibraryAugmentDirective: true,
partialIndex: null,
);
Expand Down Expand Up @@ -521,7 +545,13 @@ class LibraryBuilder {
unitNode: unitNode,
unitElement: unitElement,
augmentation: augmentation,
).perform();
).perform(updateConstants: () {
MacroUpdateConstantsForOptimizedCode(
unitNode: mergedUnit,
codeEdits: optimizedCodeEdits,
unitElement: unitElement,
).perform();
});

// Set offsets the same way as when reading from summary.
InformativeDataApplier(
Expand Down Expand Up @@ -1216,6 +1246,27 @@ enum MacroDeclarationsPhaseStepResult {
topDeclaration,
}

class _CodeOptimizer extends macro.CodeOptimizer {
final LinkedElementFactory elementFactory;
final Map<Uri, Set<String>> exportedNames = {};

_CodeOptimizer({
required this.elementFactory,
});

@override
Set<String> getImportedNames(String uriStr) {
var uri = Uri.parse(uriStr);
var libraryElement = elementFactory.libraryOfUri(uri);
if (libraryElement != null) {
return exportedNames[uri] ??= libraryElement.exportedReferences
.map((exported) => exported.reference.name)
.toSet();
}
return const <String>{};
}
}

/// This class examines all the [InterfaceElement]s in a library and determines
/// which fields are promotable within that library.
class _FieldPromotability extends FieldPromotability<InterfaceElement,
Expand Down
Loading

0 comments on commit 660ee24

Please sign in to comment.