| // Copyright (c) 2023, 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 'dart:typed_data'; |
| |
| import 'package:analyzer/src/summary2/data_reader.dart'; |
| |
| abstract class InfoDeclarationStore { |
| String createKey(SummaryDataReader reader, int initialOffset); |
| E? get<E>(SummaryDataReader reader, String key, int initialOffset); |
| void put( |
| SummaryDataReader reader, String key, int initialOffset, Object value); |
| } |
| |
| class InfoDeclarationStoreImpl implements InfoDeclarationStore { |
| final Map<String, _InfoDeclarationStoreData> map = {}; |
| late final Finalizer _finalizer; |
| |
| InfoDeclarationStoreImpl() { |
| _finalizer = Finalizer((key) { |
| map.remove(key); |
| }); |
| } |
| |
| @override |
| String createKey(SummaryDataReader reader, int initialOffset) { |
| return "${identityHashCode(reader.bytes)}|$initialOffset"; |
| } |
| |
| @override |
| E? get<E>(SummaryDataReader reader, String key, int initialOffset) { |
| var lookup = map[key]; |
| if (lookup != null) { |
| if (identical(lookup.bytes.target, reader.bytes) && |
| lookup.offset == initialOffset) { |
| var result = lookup.result.target; |
| if (result is E) { |
| reader.offset = lookup.endOffset; |
| return result; |
| } |
| } else { |
| map.remove(key); |
| } |
| } |
| return null; |
| } |
| |
| @override |
| void put( |
| SummaryDataReader reader, String key, int initialOffset, Object value) { |
| // Assuming that the bytes will live longer than the result. |
| _finalizer.attach(value, key); |
| map[key] = _InfoDeclarationStoreData(WeakReference(reader.bytes), |
| initialOffset, reader.offset, WeakReference(value)); |
| } |
| } |
| |
| class NoOpInfoDeclarationStore implements InfoDeclarationStore { |
| const NoOpInfoDeclarationStore(); |
| |
| @override |
| String createKey(SummaryDataReader reader, int initialOffset) { |
| return ""; |
| } |
| |
| @override |
| E? get<E>(SummaryDataReader reader, String key, int initialOffset) { |
| return null; |
| } |
| |
| @override |
| void put( |
| SummaryDataReader reader, String key, int initialOffset, Object value) {} |
| } |
| |
| class _InfoDeclarationStoreData { |
| final WeakReference<Uint8List> bytes; |
| final int offset; |
| final int endOffset; |
| final WeakReference<Object> result; |
| |
| _InfoDeclarationStoreData( |
| this.bytes, this.offset, this.endOffset, this.result); |
| } |