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

Unified Diff: pkg/front_end/lib/src/fasta/scope.dart

Issue 2788153002: Create separate scopes for constructors, setters, and other members. (Closed)
Patch Set: One more flaky standalone/io test. Created 3 years, 8 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/front_end/lib/src/fasta/scope.dart
diff --git a/pkg/front_end/lib/src/fasta/scope.dart b/pkg/front_end/lib/src/fasta/scope.dart
index c477ba95b303735a04e833cdc9f809eb24970cf6..2dd1656ef0bf633fb525fc4f7574981daa07c032 100644
--- a/pkg/front_end/lib/src/fasta/scope.dart
+++ b/pkg/front_end/lib/src/fasta/scope.dart
@@ -4,21 +4,25 @@
library fasta.scope;
-import 'builder/builder.dart' show Builder, MixedAccessor;
+import 'builder/builder.dart' show Builder, TypeVariableBuilder;
import 'errors.dart' show internalError;
-class Scope {
+class MutableScope {
/// Names declared in this scope.
- final Map<String, Builder> local;
+ Map<String, Builder> local;
/// Setters declared in this scope.
- final Map<String, Builder> setters;
+ Map<String, Builder> setters;
/// The scope that this scope is nested within, or `null` if this is the top
/// level scope.
- final Scope parent;
+ Scope parent;
+ MutableScope(this.local, this.setters, this.parent);
+}
+
+class Scope extends MutableScope {
/// Indicates whether an attempt to declare new names in this scope should
/// succeed.
final bool isModifiable;
@@ -27,9 +31,9 @@ class Scope {
Map<String, Builder> forwardDeclaredLabels;
- Scope(this.local, Map<String, Builder> setters, this.parent,
+ Scope(Map<String, Builder> local, Map<String, Builder> setters, Scope parent,
{this.isModifiable: true})
- : setters = setters ?? const <String, Builder>{};
+ : super(local, setters = setters ?? const <String, Builder>{}, parent);
Scope.top({bool isModifiable: false})
: this(<String, Builder>{}, <String, Builder>{}, null,
@@ -42,10 +46,38 @@ class Scope {
Scope.nested(Scope parent, {bool isModifiable: true})
: this(<String, Builder>{}, null, parent, isModifiable: isModifiable);
+ /// Don't use this. Use [becomePartOf] instead.
+ void set local(_) => internalError("Unsupported operation.");
+
+ /// Don't use this. Use [becomePartOf] instead.
+ void set setters(_) => internalError("Unsupported operation.");
+
+ /// Don't use this. Use [becomePartOf] instead.
+ void set parent(_) => internalError("Unsupported operation.");
+
+ /// This scope becomes equivalent to [scope]. This is used for parts to
+ /// become part of their library's scope.
+ void becomePartOf(Scope scope) {
+ assert(parent.parent == null);
+ assert(scope.parent.parent == null);
+ super.local = scope.local;
+ super.setters = scope.setters;
+ super.parent = scope.parent;
+ }
+
Scope createNestedScope({bool isModifiable: true}) {
return new Scope.nested(this, isModifiable: isModifiable);
}
+ Scope withTypeVariables(List<TypeVariableBuilder> typeVariables) {
+ if (typeVariables == null) return this;
+ Scope newScope = new Scope.nested(this, isModifiable: false);
+ for (TypeVariableBuilder t in typeVariables) {
+ newScope.local[t.name] = t;
+ }
+ return newScope;
+ }
+
/// Create a special scope for use by labeled staments. This scope doesn't
/// introduce a new scope for local variables, only for labels. This deals
/// with corner cases like this:
@@ -57,66 +89,49 @@ class Scope {
return new Scope(local, setters, parent, isModifiable: true);
}
- Builder lookup(String name, int charOffset, Uri fileUri,
- {bool isInstanceScope: true}) {
- Builder builder = local[name];
- if (builder != null) {
- if (builder.next != null) {
- return lookupAmbiguous(name, builder, false, charOffset, fileUri);
- }
- return builder.isSetter
- ? new AccessErrorBuilder(name, builder, charOffset, fileUri)
- : builder;
+ Builder lookupIn(String name, int charOffset, Uri fileUri,
+ Map<String, Builder> map, bool isInstanceScope) {
+ Builder builder = map[name];
+ if (builder == null) return null;
+ if (builder.next != null) {
+ return new AmbiguousBuilder(name, builder, charOffset, fileUri);
+ } else if (!isInstanceScope && builder.isInstanceMember) {
+ return null;
} else {
- return parent?.lookup(name, charOffset, fileUri);
+ return builder;
}
}
- Builder lookupSetter(String name, int charOffset, Uri fileUri,
+ Builder lookup(String name, int charOffset, Uri fileUri,
{bool isInstanceScope: true}) {
- Builder builder = local[name];
- if (builder != null) {
- if (builder.next != null) {
- return lookupAmbiguous(name, builder, true, charOffset, fileUri);
- }
- if (builder.isField) {
- if (builder.isFinal) {
- return new AccessErrorBuilder(name, builder, charOffset, fileUri);
- } else {
- return builder;
- }
- } else if (builder.isSetter) {
- return builder;
- } else {
- return new AccessErrorBuilder(name, builder, charOffset, fileUri);
- }
- } else {
- return parent?.lookupSetter(name, charOffset, fileUri);
+ Builder builder =
+ lookupIn(name, charOffset, fileUri, local, isInstanceScope);
+ if (builder != null) return builder;
+ builder = lookupIn(name, charOffset, fileUri, setters, isInstanceScope);
+ if (builder != null && !builder.hasProblem) {
+ return new AccessErrorBuilder(name, builder, charOffset, fileUri);
}
+ if (!isInstanceScope) {
+ // For static lookup, do not seach the parent scope.
+ return builder;
+ }
+ return builder ?? parent?.lookup(name, charOffset, fileUri);
}
- Builder lookupAmbiguous(
- String name, Builder builder, bool setter, int charOffset, Uri fileUri) {
- assert(builder.next != null);
- if (builder is MixedAccessor) {
- return setter ? builder.setter : builder.getter;
+ Builder lookupSetter(String name, int charOffset, Uri fileUri,
+ {bool isInstanceScope: true}) {
+ Builder builder =
+ lookupIn(name, charOffset, fileUri, setters, isInstanceScope);
+ if (builder != null) return builder;
+ builder = lookupIn(name, charOffset, fileUri, local, isInstanceScope);
+ if (builder != null && !builder.hasProblem) {
+ return new AccessErrorBuilder(name, builder, charOffset, fileUri);
}
- Builder setterBuilder;
- Builder getterBuilder;
- Builder current = builder;
- while (current != null) {
- if (current.isGetter && getterBuilder == null) {
- getterBuilder = current;
- } else if (current.isSetter && setterBuilder == null) {
- setterBuilder = current;
- } else {
- return new AmbiguousBuilder(name, builder, charOffset, fileUri);
- }
- current = current.next;
+ if (!isInstanceScope) {
+ // For static lookup, do not seach the parent scope.
+ return builder;
}
- assert(getterBuilder != null);
- assert(setterBuilder != null);
- return setter ? setterBuilder : getterBuilder;
+ return builder ?? parent?.lookupSetter(name, charOffset, fileUri);
}
bool hasLocalLabel(String name) => labels != null && labels.containsKey(name);
@@ -161,8 +176,28 @@ class Scope {
}
}
+ void merge(Scope scope,
+ buildAmbiguousBuilder(String name, Builder existing, Builder member)) {
+ Map<String, Builder> map = local;
+
+ void mergeMember(String name, Builder member) {
+ Builder existing = map[name];
+ if (existing != null) {
+ if (existing != member) {
+ member = buildAmbiguousBuilder(name, existing, member);
+ }
+ }
+ map[name] = member;
+ }
+
+ scope.local.forEach(mergeMember);
+ map = setters;
+ scope.setters.forEach(mergeMember);
+ }
+
void forEach(f(String name, Builder member)) {
local.forEach(f);
+ setters.forEach(f);
}
String get debugString {
@@ -188,6 +223,22 @@ class Scope {
}
}
+class ScopeBuilder {
+ final Scope scope;
+
+ ScopeBuilder(this.scope);
+
+ void addMember(String name, Builder builder) {
+ scope.local[name] = builder;
+ }
+
+ void addSetter(String name, Builder builder) {
+ scope.setters[name] = builder;
+ }
+
+ Builder operator [](String name) => scope.local[name];
+}
+
abstract class ProblemBuilder extends Builder {
final String name;
« no previous file with comments | « pkg/front_end/lib/src/fasta/kernel/kernel_target.dart ('k') | pkg/front_end/lib/src/fasta/source/diet_listener.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698