Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Unified Diff: pkg/analyzer/lib/src/summary/fasta/model.dart

Issue 2738273002: Add fasta-based summary generation code. (Closed)
Patch Set: Actually disable the test Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/analyzer/lib/src/summary/fasta/model.dart
diff --git a/pkg/analyzer/lib/src/summary/fasta/model.dart b/pkg/analyzer/lib/src/summary/fasta/model.dart
new file mode 100644
index 0000000000000000000000000000000000000000..373ad9825c401ae2540cf5d06bcab37d0e4006a5
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/fasta/model.dart
@@ -0,0 +1,189 @@
+// Copyright (c) 2017, 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.
+
+/// Additional data model classes used by the summary builder.
+///
+/// The summary builder uses 4 pieces of data:
+///
+/// * Unlinked**Builders: builder classes for each piece of output in the
+/// summary (see format.dart).
+///
+/// * A simplified expression syntax: model relevant pieces of initializers
+/// and constants before serializing them (see expressions.dart).
+///
+/// * Lazy references: a way to model references on the fly so we can build
+/// summaries in a single pass.
+///
+/// * Scopes: used to track the current context of the parser, used in great
+/// part to easily resolve lazy references at the end of the build process.
+library summary.src.scope;
+
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/idl.dart';
+
+export 'package:analyzer/src/summary/format.dart';
+export 'package:analyzer/src/summary/idl.dart';
+export 'package:analyzer/src/summary/api_signature.dart';
+export 'expressions.dart';
+export 'visitor.dart';
+
+/// A scope corresponding to a scope in the program like units, classes, or
+/// enums.
+///
+/// It is used to hold results that correspond to a given scope in the program
+/// and to lazily resolve name references.
+abstract class Scope {
+ Scope get parent;
+
+ TopScope get top {
+ var s = this;
+ while (s.parent != null) s = s.parent;
+ return s;
+ }
+
+ void computeReference(LazyEntityRef ref);
+}
+
+/// Top scope, where the top-level unit is built.
+class TopScope extends Scope {
+ get parent => null;
+ toString() => "<top-scope>";
+
+ /// Results of parsing the unit.
+ final UnlinkedUnitBuilder unit = new UnlinkedUnitBuilder(
+ classes: [],
+ enums: [],
+ executables: [],
+ exports: [],
+ imports: [],
+ parts: [],
+ references: [new UnlinkedReferenceBuilder()],
+ typedefs: [],
+ variables: []);
+
+ /// Stores publicly visible names exported from the unit.
+ final UnlinkedPublicNamespaceBuilder publicNamespace =
+ new UnlinkedPublicNamespaceBuilder(names: [], exports: [], parts: []);
+
+ /// Lazy references that need to be expanded after all scope information is
+ /// known.
+ List<LazyEntityRef> _toExpand = [];
+
+ void expandLazyReferences() {
+ _toExpand.forEach((r) => r.expand());
+ }
+
+ TopScope() {
+ unit.publicNamespace = publicNamespace;
+ }
+
+ final Map<int, Map<String, int>> nameToReference = <int, Map<String, int>>{};
+ int serializeReference(int prefixIndex, String name) => nameToReference
+ .putIfAbsent(prefixIndex, () => <String, int>{})
+ .putIfAbsent(name, () {
+ int index = unit.references.length;
+ unit.references.add(new UnlinkedReferenceBuilder(
+ prefixReference: prefixIndex, name: name));
+ return index;
+ });
+
+ void computeReference(LazyEntityRef ref) {
+ ref.reference = serializeReference(null, ref.name);
+ }
+}
+
+class TypeParameterScope extends Scope {
+ final Scope parent;
+ TypeParameterScope(this.parent);
+
+ List<String> typeParameters = [];
+
+ void computeReference(LazyEntityRef ref) {
+ var i = typeParameters.indexOf(ref.name);
+ if (i < 0) return parent.computeReference(ref);
+ // Note: there is no indexOffset here because we don't go into functions at
+ // all (so there is no nesting of type-parameter scopes).
+ ref.paramReference = typeParameters.length - i;
+ }
+}
+
+class ClassScope extends TypeParameterScope {
+ String className;
+ UnlinkedClassBuilder currentClass = new UnlinkedClassBuilder();
+ UnlinkedPublicNameBuilder publicName = new UnlinkedPublicNameBuilder();
+ Set<String> members = new Set<String>();
+ toString() => "<class-scope: $className>";
+
+ ClassScope(Scope parent) : super(parent);
+
+ void computeReference(LazyEntityRef ref) {
+ if (!members.contains(ref.name)) {
+ return super.computeReference(ref);
+ }
+ ref.reference = top.serializeReference(
+ top.serializeReference(null, className), ref.name);
+ }
+}
+
+class EnumScope extends Scope {
+ final Scope parent;
+ UnlinkedEnumBuilder currentEnum = new UnlinkedEnumBuilder();
+
+ EnumScope(this.parent);
+
+ void computeReference(LazyEntityRef ref) => throw "unexpected";
+}
+
+
+/// A lazily encoded reference.
+///
+/// References in summaries are encoded based on the scope where they appear.
+/// Most top-level references can be encoded eagerly, but references in the
+/// scope of a class need to check whether a name is a member of such class.
+/// Because we don't have such list of members available upfront, we create
+/// these lazy references and finalize them after we finish going through the
+/// program.
+class LazyEntityRef extends EntityRefBuilder {
+ Scope scope;
+ String name;
+ LazyEntityRef(this.name, this.scope) : super() {
+ scope.top._toExpand.add(this);
+ }
+
+
+ bool wasExpanded = false;
+ expand() {
+ if (!wasExpanded) {
+ scope.computeReference(this);
+ wasExpanded = true;
+ }
+ }
+
+ @override
+ int get reference {
+ expand();
+ return super.reference;
+ }
+
+ @override
+ int get paramReference {
+ expand();
+ return super.paramReference;
+ }
+}
+
+/// A nested lazy reference, modeling something like `a.b.c`.
+class NestedLazyEntityRef extends LazyEntityRef {
+ EntityRef prefix;
+ NestedLazyEntityRef(this.prefix, String name, Scope scope)
+ : super(name, scope.top);
+
+ @override
+ expand() {
+ if (!wasExpanded) {
+ super.reference = scope.top.serializeReference(prefix.reference, name);
+ wasExpanded = true;
+ }
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698