Macro. Add more details for performance.

Bug: https://github.com/dart-lang/sdk/issues/55784
Change-Id: I2e633eae9f28a6ed053eca762068e8fac7e56c6d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/372121
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Konstantin Shcheglov 2024-06-18 18:19:22 +00:00 committed by Commit Queue
parent 88e62a23cf
commit ddce8d50c4
5 changed files with 274 additions and 107 deletions

View file

@ -1151,7 +1151,10 @@ class AnalysisDriver {
FileState file = _fsState.getFileForPath(path); FileState file = _fsState.getFileForPath(path);
RecordingErrorListener listener = RecordingErrorListener(); RecordingErrorListener listener = RecordingErrorListener();
CompilationUnit unit = file.parse(listener); CompilationUnit unit = file.parse(
errorListener: listener,
performance: OperationPerformanceImpl('<root>'),
);
return ParsedUnitResultImpl( return ParsedUnitResultImpl(
session: currentSession, session: currentSession,
fileState: file, fileState: file,
@ -1848,25 +1851,35 @@ class AnalysisDriver {
} }
Future<void> _getUnitElement(String path) async { Future<void> _getUnitElement(String path) async {
FileState file = _fsState.getFileForPath(path); await scheduler.accumulatedPerformance.runAsync(
'getUnitElement',
(performance) async {
FileState file = _fsState.getFileForPath(path);
// Prepare the library - the file itself, or the known library. // Prepare the library - the file itself, or the known library.
var kind = file.kind; var kind = file.kind;
var library = kind.library ?? kind.asLibrary; var library = kind.library ?? kind.asLibrary;
await libraryContext.load( await performance.runAsync(
targetLibrary: library, 'libraryContext',
performance: OperationPerformanceImpl('<root>'), (performance) async {
await libraryContext.load(
targetLibrary: library,
performance: performance,
);
},
);
var element = libraryContext.computeUnitElement(library, file);
var result = UnitElementResultImpl(
session: currentSession,
fileState: file,
element: element,
);
_unitElementRequestedFiles.completeAll(path, result);
},
); );
var element = libraryContext.computeUnitElement(library, file);
var result = UnitElementResultImpl(
session: currentSession,
fileState: file,
element: element,
);
_unitElementRequestedFiles.completeAll(path, result);
} }
bool _hasLibraryByUri(String uriStr) { bool _hasLibraryByUri(String uriStr) {

View file

@ -37,6 +37,7 @@ import 'package:analyzer/src/summary/api_signature.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart'; import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/summary2/informative_data.dart'; import 'package:analyzer/src/summary2/informative_data.dart';
import 'package:analyzer/src/util/file_paths.dart' as file_paths; import 'package:analyzer/src/util/file_paths.dart' as file_paths;
import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:analyzer/src/util/uri.dart'; import 'package:analyzer/src/util/uri.dart';
import 'package:analyzer/src/utilities/extensions/collection.dart'; import 'package:analyzer/src/utilities/extensions/collection.dart';
import 'package:analyzer/src/utilities/uri_cache.dart'; import 'package:analyzer/src/utilities/uri_cache.dart';
@ -495,10 +496,16 @@ class FileState {
} }
/// Return a new parsed unresolved [CompilationUnit]. /// Return a new parsed unresolved [CompilationUnit].
CompilationUnitImpl parse([AnalysisErrorListener? errorListener]) { CompilationUnitImpl parse({
AnalysisErrorListener? errorListener,
required OperationPerformanceImpl performance,
}) {
errorListener ??= AnalysisErrorListener.NULL_LISTENER; errorListener ??= AnalysisErrorListener.NULL_LISTENER;
try { try {
return _parse(errorListener); return _parse(
errorListener,
performance: performance,
);
} catch (exception, stackTrace) { } catch (exception, stackTrace) {
throw CaughtExceptionWithFiles( throw CaughtExceptionWithFiles(
exception, exception,
@ -512,42 +519,50 @@ class FileState {
CompilationUnitImpl parseCode({ CompilationUnitImpl parseCode({
required String code, required String code,
required AnalysisErrorListener errorListener, required AnalysisErrorListener errorListener,
required OperationPerformanceImpl performance,
}) { }) {
CharSequenceReader reader = CharSequenceReader(code); return performance.run('parseCode', (performance) {
Scanner scanner = Scanner(source, reader, errorListener) performance.getDataInt('length').add(code.length);
..configureFeatures(
featureSetForOverriding: featureSet, CharSequenceReader reader = CharSequenceReader(code);
featureSet: featureSet.restrictToVersion( Scanner scanner = Scanner(source, reader, errorListener)
packageLanguageVersion, ..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,
); );
Token token = scanner.tokenize(reportScannerErrors: false);
LineInfo lineInfo = LineInfo(scanner.lineStarts);
Parser parser = Parser( var unit = parser.parseCompilationUnit(token);
source, unit.languageVersion = LibraryLanguageVersion(
errorListener, package: packageLanguageVersion,
featureSet: scanner.featureSet, override: scanner.overrideVersion,
lineInfo: lineInfo, );
);
var unit = parser.parseCompilationUnit(token); // Ensure the string canonicalization cache size is reasonable.
unit.languageVersion = LibraryLanguageVersion( pruneStringCanonicalizationCache();
package: packageLanguageVersion,
override: scanner.overrideVersion,
);
// Ensure the string canonicalization cache size is reasonable. return unit;
pruneStringCanonicalizationCache(); });
return unit;
} }
/// Read the file content and ensure that all of the file properties are /// Read the file content and ensure that all of the file properties are
/// consistent with the read content, including API signature. /// consistent with the read content, including API signature.
/// ///
/// Return how the file changed since the last refresh. /// Return how the file changed since the last refresh.
FileStateRefreshResult refresh() { FileStateRefreshResult refresh({
OperationPerformanceImpl? performance,
}) {
performance ??= OperationPerformanceImpl('<root>');
_invalidateCurrentUnresolvedData(); _invalidateCurrentUnresolvedData();
FileContent rawFileState; FileContent rawFileState;
@ -578,7 +593,12 @@ class FileState {
} }
// Prepare the unlinked unit. // Prepare the unlinked unit.
_driverUnlinkedUnit = _getUnlinkedUnit(previousUnlinkedKey); performance.run('getUnlinkedUnit', (performance) {
_driverUnlinkedUnit = _getUnlinkedUnit(
previousUnlinkedKey,
performance: performance,
);
});
_unlinked2 = _driverUnlinkedUnit!.unit; _unlinked2 = _driverUnlinkedUnit!.unit;
_lineInfo = LineInfo(_unlinked2!.lineStarts); _lineInfo = LineInfo(_unlinked2!.lineStarts);
@ -699,7 +719,10 @@ class FileState {
/// Return the unlinked unit, freshly deserialized from bytes, /// Return the unlinked unit, freshly deserialized from bytes,
/// previously deserialized from bytes, or new. /// previously deserialized from bytes, or new.
AnalysisDriverUnlinkedUnit _getUnlinkedUnit(String? previousUnlinkedKey) { AnalysisDriverUnlinkedUnit _getUnlinkedUnit(
String? previousUnlinkedKey, {
required OperationPerformanceImpl performance,
}) {
if (previousUnlinkedKey != null) { if (previousUnlinkedKey != null) {
if (previousUnlinkedKey != _unlinkedKey) { if (previousUnlinkedKey != _unlinkedKey) {
_fsState.unlinkedUnitStore.release(previousUnlinkedKey); _fsState.unlinkedUnitStore.release(previousUnlinkedKey);
@ -723,7 +746,10 @@ class FileState {
return result; return result;
} }
var unit = parse(); var unit = parse(
performance: performance,
);
return _fsState._logger.run('Create unlinked for $path', () { return _fsState._logger.run('Create unlinked for $path', () {
var unlinkedUnit = serializeAstUnlinked2( var unlinkedUnit = serializeAstUnlinked2(
unit, unit,
@ -759,10 +785,14 @@ class FileState {
} }
} }
CompilationUnitImpl _parse(AnalysisErrorListener errorListener) { CompilationUnitImpl _parse(
AnalysisErrorListener errorListener, {
required OperationPerformanceImpl performance,
}) {
return parseCode( return parseCode(
code: content, code: content,
errorListener: errorListener, errorListener: errorListener,
performance: performance,
); );
} }
@ -1316,7 +1346,10 @@ class FileSystemState {
/// to a file, for example because it is invalid (e.g. a `package:` URI /// to a file, for example because it is invalid (e.g. a `package:` URI
/// without a package name), or we don't know this package. The returned /// without a package name), or we don't know this package. The returned
/// file has the last known state since if was last refreshed. /// file has the last known state since if was last refreshed.
UriResolution? getFileForUri(Uri uri) { UriResolution? getFileForUri(
Uri uri, {
OperationPerformanceImpl? performance,
}) {
var uriSource = _sourceFactory.forUri2(uri); var uriSource = _sourceFactory.forUri2(uri);
// If the external store has this URI, create a stub file for it. // If the external store has this URI, create a stub file for it.
@ -1349,7 +1382,12 @@ class FileSystemState {
return null; return null;
} }
file = _newFile(resource, path, rewrittenUri); file = _newFile(
resource,
path,
rewrittenUri,
performance: performance,
);
} }
return UriResolutionFile(file); return UriResolutionFile(file);
} }
@ -1494,7 +1532,12 @@ class FileSystemState {
nonPackageLanguageVersion: analysisOptions.nonPackageLanguageVersion); nonPackageLanguageVersion: analysisOptions.nonPackageLanguageVersion);
} }
FileState _newFile(File resource, String path, Uri uri) { FileState _newFile(
File resource,
String path,
Uri uri, {
OperationPerformanceImpl? performance,
}) {
FileSource uriSource = FileSource(resource, uri); FileSource uriSource = FileSource(resource, uri);
WorkspacePackage? workspacePackage = _workspace?.findPackageFor(path); WorkspacePackage? workspacePackage = _workspace?.findPackageFor(path);
AnalysisOptionsImpl analysisOptions = _getAnalysisOptions(resource); AnalysisOptionsImpl analysisOptions = _getAnalysisOptions(resource);
@ -1509,7 +1552,14 @@ class FileSystemState {
knownFilePaths.add(path); knownFilePaths.add(path);
knownFiles.add(file); knownFiles.add(file);
fileStamp++; fileStamp++;
file.refresh();
performance ??= OperationPerformanceImpl('<root>');
performance.run('fileState.refresh', (performance) {
file.refresh(
performance: performance,
);
});
onNewFile(file); onNewFile(file);
return file; return file;
} }
@ -1843,6 +1893,7 @@ class LibraryFileKind extends LibraryOrAugmentationFileKind {
AugmentationImportWithFile addMacroAugmentation( AugmentationImportWithFile addMacroAugmentation(
String code, { String code, {
required int? partialIndex, required int? partialIndex,
required OperationPerformanceImpl performance,
}) { }) {
var pathContext = file._fsState.pathContext; var pathContext = file._fsState.pathContext;
var libraryFileName = pathContext.basename(file.path); var libraryFileName = pathContext.basename(file.path);
@ -1869,7 +1920,15 @@ class LibraryFileKind extends LibraryOrAugmentationFileKind {
// Or this happens during the explicit `refresh()`, more below. // Or this happens during the explicit `refresh()`, more below.
file._fsState._macroFileContent = fileContent; file._fsState._macroFileContent = fileContent;
var macroFileResolution = file._fsState.getFileForUri(macroUri); var macroFileResolution = performance.run(
'getFileForUri',
(performance) {
return file._fsState.getFileForUri(
macroUri,
performance: performance,
);
},
);
macroFileResolution as UriResolutionFile; macroFileResolution as UriResolutionFile;
var macroFile = macroFileResolution.file; var macroFile = macroFileResolution.file;

View file

@ -575,7 +575,10 @@ class LibraryAnalyzer {
/// Return a new parsed unresolved [CompilationUnit]. /// Return a new parsed unresolved [CompilationUnit].
UnitAnalysis _parse(FileState file) { UnitAnalysis _parse(FileState file) {
var errorListener = RecordingErrorListener(); var errorListener = RecordingErrorListener();
var unit = file.parse(errorListener); var unit = file.parse(
errorListener: errorListener,
performance: OperationPerformanceImpl('<root>'),
);
// TODO(scheglov): Store [IgnoreInfo] as unlinked data. // TODO(scheglov): Store [IgnoreInfo] as unlinked data.

View file

@ -347,6 +347,7 @@ class LibraryContext {
libraryKind.addMacroAugmentation( libraryKind.addMacroAugmentation(
macroGeneratedCode, macroGeneratedCode,
partialIndex: null, partialIndex: null,
performance: OperationPerformanceImpl('<root>'),
); );
} }
} }

View file

@ -351,10 +351,15 @@ class LibraryBuilder with MacroApplicationsContainer {
return MacroDeclarationsPhaseStepResult.nothing; return MacroDeclarationsPhaseStepResult.nothing;
} }
var applicationResult = await macroApplier.executeDeclarationsPhase( var applicationResult = await performance.runAsync(
libraryBuilder: this, 'macroApplier.executeDeclarationsPhase',
targetElement: targetElement, (performance) async {
performance: performance, return await macroApplier.executeDeclarationsPhase(
libraryBuilder: this,
targetElement: targetElement,
performance: performance,
);
},
); );
// No more applications to execute. // No more applications to execute.
@ -362,10 +367,16 @@ class LibraryBuilder with MacroApplicationsContainer {
return MacroDeclarationsPhaseStepResult.nothing; return MacroDeclarationsPhaseStepResult.nothing;
} }
await _addMacroResults( await performance.runAsync(
macroApplier, 'addMacroResults',
applicationResult, (performance) async {
phase: macro.Phase.declarations, await _addMacroResults(
macroApplier,
applicationResult,
phase: macro.Phase.declarations,
performance: performance,
);
},
); );
// Check if a new top-level declaration was added. // Check if a new top-level declaration was added.
@ -394,7 +405,7 @@ class LibraryBuilder with MacroApplicationsContainer {
while (true) { while (true) {
var applicationResult = await performance.runAsync( var applicationResult = await performance.runAsync(
'executeDefinitionsPhase', 'macroApplier.executeDefinitionsPhase',
(performance) async { (performance) async {
return await macroApplier.executeDefinitionsPhase( return await macroApplier.executeDefinitionsPhase(
libraryBuilder: this, libraryBuilder: this,
@ -415,6 +426,7 @@ class LibraryBuilder with MacroApplicationsContainer {
macroApplier, macroApplier,
applicationResult, applicationResult,
phase: macro.Phase.definitions, phase: macro.Phase.definitions,
performance: performance,
); );
}, },
); );
@ -434,8 +446,13 @@ class LibraryBuilder with MacroApplicationsContainer {
} }
while (true) { while (true) {
var applicationResult = await macroApplier.executeTypesPhase( var applicationResult = await performance.runAsync(
libraryBuilder: this, 'macroApplier.executeTypesPhase',
(performance) async {
return await macroApplier.executeTypesPhase(
libraryBuilder: this,
);
},
); );
// No more applications to execute. // No more applications to execute.
@ -443,10 +460,16 @@ class LibraryBuilder with MacroApplicationsContainer {
break; break;
} }
await _addMacroResults( await performance.runAsync(
macroApplier, 'addMacroResults',
applicationResult, (performance) async {
phase: macro.Phase.types, await _addMacroResults(
macroApplier,
applicationResult,
phase: macro.Phase.types,
performance: performance,
);
},
); );
} }
} }
@ -497,17 +520,29 @@ class LibraryBuilder with MacroApplicationsContainer {
return; return;
} }
var augmentationCode = macroApplier.buildAugmentationLibraryCode( var augmentationCode = performance.run(
uri, 'buildAugmentationLibraryCode',
_macroResults.flattenedToList2, (performance) {
return macroApplier.buildAugmentationLibraryCode(
uri,
_macroResults.flattenedToList2,
);
},
); );
if (augmentationCode == null) { if (augmentationCode == null) {
return; return;
} }
var mergedUnit = kind.file.parseCode( var mergedUnit = performance.run(
code: augmentationCode, 'mergedUnit',
errorListener: AnalysisErrorListener.NULL_LISTENER, (performance) {
performance.getDataInt('length').add(augmentationCode.length);
return kind.file.parseCode(
code: augmentationCode,
errorListener: AnalysisErrorListener.NULL_LISTENER,
performance: performance,
);
},
); );
kind.disposeMacroAugmentations(disposeFiles: true); kind.disposeMacroAugmentations(disposeFiles: true);
@ -543,14 +578,28 @@ class LibraryBuilder with MacroApplicationsContainer {
optimizedCode = augmentationCode; optimizedCode = augmentationCode;
} }
var importState = kind.addMacroAugmentation( var importState = performance.run(
optimizedCode, 'kind.addMacroAugmentation',
partialIndex: null, (performance) {
return kind.addMacroAugmentation(
optimizedCode,
partialIndex: null,
performance: performance,
);
},
); );
var importedAugmentation = importState.importedAugmentation!; var importedAugmentation = importState.importedAugmentation!;
var importedFile = importedAugmentation.file; var importedFile = importedAugmentation.file;
var unitNode = importedFile.parse(); var unitNode = performance.run(
'importedFile.parse()',
(performance) {
performance.getDataInt('length').add(importedFile.content.length);
return importedFile.parse(
performance: performance,
);
},
);
var unitElement = CompilationUnitElementImpl( var unitElement = CompilationUnitElementImpl(
source: importedFile.source, source: importedFile.source,
librarySource: importedFile.source, librarySource: importedFile.source,
@ -779,9 +828,14 @@ class LibraryBuilder with MacroApplicationsContainer {
} }
LibraryAugmentationElementImpl _addMacroAugmentation( LibraryAugmentationElementImpl _addMacroAugmentation(
AugmentationImportWithFile state, AugmentationImportWithFile state, {
) { required OperationPerformanceImpl performance,
var import = _buildAugmentationImport(element, state); }) {
var import = _buildAugmentationImport(
element,
state,
performance: performance,
);
import.isSynthetic = true; import.isSynthetic = true;
element.augmentationImports = [ element.augmentationImports = [
...element.augmentationImports, ...element.augmentationImports,
@ -802,6 +856,7 @@ class LibraryBuilder with MacroApplicationsContainer {
LibraryMacroApplier macroApplier, LibraryMacroApplier macroApplier,
ApplicationResult applicationResult, { ApplicationResult applicationResult, {
required macro.Phase phase, required macro.Phase phase,
required OperationPerformanceImpl performance,
}) async { }) async {
// No results from the application. // No results from the application.
var results = applicationResult.results; var results = applicationResult.results;
@ -809,20 +864,40 @@ class LibraryBuilder with MacroApplicationsContainer {
return; return;
} }
var augmentationCode = macroApplier.buildAugmentationLibraryCode( var augmentationCode = performance.run(
uri, 'buildAugmentationLibraryCode',
results, (performance) {
return macroApplier.buildAugmentationLibraryCode(
uri,
results,
);
},
); );
if (augmentationCode == null) { if (augmentationCode == null) {
return; return;
} }
var importState = kind.addMacroAugmentation( var importState = performance.run(
augmentationCode, 'kind.addMacroAugmentation',
partialIndex: _macroResults.length, (performance) {
performance.getDataInt('length').add(augmentationCode.length);
return kind.addMacroAugmentation(
augmentationCode,
partialIndex: _macroResults.length,
performance: performance,
);
},
); );
var augmentation = _addMacroAugmentation(importState); var augmentation = performance.run(
'_addMacroAugmentation',
(performance) {
return _addMacroAugmentation(
importState,
performance: performance,
);
},
);
var macroLinkingUnit = units.last; var macroLinkingUnit = units.last;
// If the generated code contains declarations that are not allowed at // If the generated code contains declarations that are not allowed at
@ -850,19 +925,22 @@ class LibraryBuilder with MacroApplicationsContainer {
return; return;
} }
ElementBuilder( performance.run('elements + types', (performance) {
libraryBuilder: this, ElementBuilder(
container: macroLinkingUnit.container, libraryBuilder: this,
unitReference: macroLinkingUnit.reference, container: macroLinkingUnit.container,
unitElement: macroLinkingUnit.element, unitReference: macroLinkingUnit.reference,
).buildDeclarationElements(macroLinkingUnit.node); unitElement: macroLinkingUnit.element,
).buildDeclarationElements(macroLinkingUnit.node);
if (phase != macro.Phase.types) { if (phase != macro.Phase.types) {
var nodesToBuildType = NodesToBuildType(); var nodesToBuildType = NodesToBuildType();
var resolver = ReferenceResolver(linker, nodesToBuildType, augmentation); var resolver =
macroLinkingUnit.node.accept(resolver); ReferenceResolver(linker, nodesToBuildType, augmentation);
TypesBuilder(linker).build(nodesToBuildType); macroLinkingUnit.node.accept(resolver);
} TypesBuilder(linker).build(nodesToBuildType);
}
});
_macroResults.add(results); _macroResults.add(results);
@ -876,15 +954,19 @@ class LibraryBuilder with MacroApplicationsContainer {
AugmentationImportElementImpl _buildAugmentationImport( AugmentationImportElementImpl _buildAugmentationImport(
LibraryOrAugmentationElementImpl augmentationTarget, LibraryOrAugmentationElementImpl augmentationTarget,
AugmentationImportState state, AugmentationImportState state, {
) { required OperationPerformanceImpl performance,
}) {
DirectiveUri uri; DirectiveUri uri;
if (state is AugmentationImportWithFile) { if (state is AugmentationImportWithFile) {
var importedAugmentation = state.importedAugmentation; var importedAugmentation = state.importedAugmentation;
if (importedAugmentation != null) { if (importedAugmentation != null) {
var importedFile = importedAugmentation.file; var importedFile = importedAugmentation.file;
var unitNode = importedFile.parse(); var unitNode = importedFile.parse(
performance: performance,
);
var unitElement = CompilationUnitElementImpl( var unitElement = CompilationUnitElementImpl(
source: importedFile.source, source: importedFile.source,
// TODO(scheglov): Remove this parameter. // TODO(scheglov): Remove this parameter.
@ -990,7 +1072,11 @@ class LibraryBuilder with MacroApplicationsContainer {
}).toFixedList(); }).toFixedList();
container.augmentationImports = kind.augmentationImports.map((state) { container.augmentationImports = kind.augmentationImports.map((state) {
return _buildAugmentationImport(container, state); return _buildAugmentationImport(
container,
state,
performance: OperationPerformanceImpl('<root>'),
);
}).toFixedList(); }).toFixedList();
} }
@ -1198,7 +1284,9 @@ class LibraryBuilder with MacroApplicationsContainer {
var libraryUriStr = libraryFile.uriStr; var libraryUriStr = libraryFile.uriStr;
var libraryReference = rootReference.getChild(libraryUriStr); var libraryReference = rootReference.getChild(libraryUriStr);
var libraryUnitNode = libraryFile.parse(); var libraryUnitNode = libraryFile.parse(
performance: OperationPerformanceImpl('<root>'),
);
var name = ''; var name = '';
var nameOffset = -1; var nameOffset = -1;
@ -1263,7 +1351,9 @@ class LibraryBuilder with MacroApplicationsContainer {
var includedPart = partState.includedPart; var includedPart = partState.includedPart;
if (includedPart != null) { if (includedPart != null) {
var partFile = includedPart.file; var partFile = includedPart.file;
var partUnitNode = partFile.parse(); var partUnitNode = partFile.parse(
performance: OperationPerformanceImpl('<root>'),
);
var unitElement = CompilationUnitElementImpl( var unitElement = CompilationUnitElementImpl(
source: partFile.source, source: partFile.source,
librarySource: libraryFile.source, librarySource: libraryFile.source,
@ -1336,6 +1426,7 @@ class LibraryBuilder with MacroApplicationsContainer {
var import = inputLibrary.addMacroAugmentation( var import = inputLibrary.addMacroAugmentation(
inputMacroResult.code, inputMacroResult.code,
partialIndex: null, partialIndex: null,
performance: OperationPerformanceImpl('<root>'),
); );
builder.inputMacroAugmentationImport = import; builder.inputMacroAugmentationImport = import;
} }