// Copyright (c) 2019, 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 "ast.dart" show Class, Constructor, Extension, Field, Library, Member, Name, Procedure, ProcedureKind, Reference, Typedef; class ReferenceFromIndex { Map _indexedLibraries = new Map.identity(); /// Add an entry mapping from *new* [library] to an index of the old library. void addIndexedLibrary(Library library, IndexedLibrary indexedLibrary) { assert(!_indexedLibraries.containsKey(library)); _indexedLibraries[library] = indexedLibrary; } /// Lookup the new library and get an index of the old library. IndexedLibrary? lookupLibrary(Library library) => _indexedLibraries[library]; } abstract class IndexedContainer { final Map _getterReferences = new Map(); final Map _setterReferences = new Map(); Reference? lookupGetterReference(Name name) => _getterReferences[name]; Reference? lookupSetterReference(Name name) => _setterReferences[name]; Library get library; void _addProcedures(List procedures) { for (int i = 0; i < procedures.length; i++) { _addProcedure(procedures[i]); } } void _addProcedure(Procedure procedure) { Name name = procedure.name!; if (procedure.isSetter) { assert(_setterReferences[name] == null); _setterReferences[name] = procedure.reference; } else { assert(_getterReferences[name] == null); assert(procedure.kind == ProcedureKind.Method || procedure.kind == ProcedureKind.Getter || procedure.kind == ProcedureKind.Operator); _getterReferences[name] = procedure.reference; } } void _addFields(List fields) { for (int i = 0; i < fields.length; i++) { Field field = fields[i]; Name name = field.name!; assert(_getterReferences[name] == null); _getterReferences[name] = field.getterReference; if (field.hasSetter) { assert(_setterReferences[name] == null); _setterReferences[name] = field.setterReference!; } } } } class IndexedLibrary extends IndexedContainer { final Map _typedefs = new Map(); final Map _classes = new Map(); final Map _indexedClasses = new Map(); final Map _extensions = new Map(); final Library library; IndexedLibrary(this.library) { for (int i = 0; i < library.typedefs.length; i++) { Typedef typedef = library.typedefs[i]; assert(_typedefs[typedef.name] == null); _typedefs[typedef.name] = typedef; } for (int i = 0; i < library.classes.length; i++) { Class c = library.classes[i]; assert(_classes[c.name] == null); _classes[c.name] = c; assert(_indexedClasses[c.name] == null); _indexedClasses[c.name] = new IndexedClass._(c, library); } for (int i = 0; i < library.extensions.length; i++) { Extension extension = library.extensions[i]; assert(_extensions[extension.name] == null); _extensions[extension.name] = extension; } _addProcedures(library.procedures); _addFields(library.fields); } Typedef? lookupTypedef(String name) => _typedefs[name]; Class? lookupClass(String name) => _classes[name]; IndexedClass? lookupIndexedClass(String name) => _indexedClasses[name]; Extension? lookupExtension(String name) => _extensions[name]; } class IndexedClass extends IndexedContainer { final Map _constructors = new Map(); final Library library; IndexedClass._(Class c, this.library) { for (int i = 0; i < c.constructors.length; i++) { Constructor constructor = c.constructors[i]; _constructors[constructor.name!] = constructor; } for (int i = 0; i < c.procedures.length; i++) { Procedure procedure = c.procedures[i]; if (procedure.isFactory) { _constructors[procedure.name!] = procedure; } else { _addProcedure(procedure); } } _addFields(c.fields); } Member? lookupConstructor(Name name) => _constructors[name]; }