OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library fasta.scope; | 5 library fasta.scope; |
6 | 6 |
7 import 'builder/builder.dart' show Builder, TypeVariableBuilder; | 7 import 'builder/builder.dart' show Builder, TypeVariableBuilder; |
8 | 8 |
9 import 'fasta_codes.dart' | 9 import 'fasta_codes.dart' |
10 show | 10 show |
(...skipping 10 matching lines...) Expand all Loading... |
21 /// Names declared in this scope. | 21 /// Names declared in this scope. |
22 Map<String, Builder> local; | 22 Map<String, Builder> local; |
23 | 23 |
24 /// Setters declared in this scope. | 24 /// Setters declared in this scope. |
25 Map<String, Builder> setters; | 25 Map<String, Builder> setters; |
26 | 26 |
27 /// The scope that this scope is nested within, or `null` if this is the top | 27 /// The scope that this scope is nested within, or `null` if this is the top |
28 /// level scope. | 28 /// level scope. |
29 Scope parent; | 29 Scope parent; |
30 | 30 |
31 MutableScope(this.local, this.setters, this.parent); | 31 final String debugName; |
| 32 |
| 33 MutableScope(this.local, this.setters, this.parent, this.debugName) { |
| 34 assert(debugName != null); |
| 35 } |
| 36 |
| 37 String toString() => "Scope($debugName, ${local.keys})"; |
32 } | 38 } |
33 | 39 |
34 class Scope extends MutableScope { | 40 class Scope extends MutableScope { |
35 /// Indicates whether an attempt to declare new names in this scope should | 41 /// Indicates whether an attempt to declare new names in this scope should |
36 /// succeed. | 42 /// succeed. |
37 final bool isModifiable; | 43 final bool isModifiable; |
38 | 44 |
39 Map<String, Builder> labels; | 45 Map<String, Builder> labels; |
40 | 46 |
41 Map<String, Builder> forwardDeclaredLabels; | 47 Map<String, Builder> forwardDeclaredLabels; |
42 | 48 |
43 Map<String, int> usedNames; | 49 Map<String, int> usedNames; |
44 | 50 |
45 Scope(Map<String, Builder> local, Map<String, Builder> setters, Scope parent, | 51 Scope(Map<String, Builder> local, Map<String, Builder> setters, Scope parent, |
46 {this.isModifiable: true}) | 52 String debugName, {this.isModifiable: true}) |
47 : super(local, setters = setters ?? const <String, Builder>{}, parent); | 53 : super(local, setters = setters ?? const <String, Builder>{}, parent, |
| 54 debugName); |
48 | 55 |
49 Scope.top({bool isModifiable: false}) | 56 Scope.top({bool isModifiable: false}) |
50 : this(<String, Builder>{}, <String, Builder>{}, null, | 57 : this(<String, Builder>{}, <String, Builder>{}, null, "top", |
51 isModifiable: isModifiable); | 58 isModifiable: isModifiable); |
52 | 59 |
53 Scope.immutable() | 60 Scope.immutable() |
54 : this(const <String, Builder>{}, const <String, Builder>{}, null, | 61 : this(const <String, Builder>{}, const <String, Builder>{}, null, |
| 62 "immutable", |
55 isModifiable: false); | 63 isModifiable: false); |
56 | 64 |
57 Scope.nested(Scope parent, {bool isModifiable: true}) | 65 Scope.nested(Scope parent, String debugName, {bool isModifiable: true}) |
58 : this(<String, Builder>{}, null, parent, isModifiable: isModifiable); | 66 : this(<String, Builder>{}, null, parent, debugName, |
| 67 isModifiable: isModifiable); |
59 | 68 |
60 /// Don't use this. Use [becomePartOf] instead. | 69 /// Don't use this. Use [becomePartOf] instead. |
61 void set local(_) => unsupported("local=", -1, null); | 70 void set local(_) => unsupported("local=", -1, null); |
62 | 71 |
63 /// Don't use this. Use [becomePartOf] instead. | 72 /// Don't use this. Use [becomePartOf] instead. |
64 void set setters(_) => unsupported("setters=", -1, null); | 73 void set setters(_) => unsupported("setters=", -1, null); |
65 | 74 |
66 /// Don't use this. Use [becomePartOf] instead. | 75 /// Don't use this. Use [becomePartOf] instead. |
67 void set parent(_) => unsupported("parent=", -1, null); | 76 void set parent(_) => unsupported("parent=", -1, null); |
68 | 77 |
69 /// This scope becomes equivalent to [scope]. This is used for parts to | 78 /// This scope becomes equivalent to [scope]. This is used for parts to |
70 /// become part of their library's scope. | 79 /// become part of their library's scope. |
71 void becomePartOf(Scope scope) { | 80 void becomePartOf(Scope scope) { |
72 assert(parent.parent == null); | 81 assert(parent.parent == null); |
73 assert(scope.parent.parent == null); | 82 assert(scope.parent.parent == null); |
74 super.local = scope.local; | 83 super.local = scope.local; |
75 super.setters = scope.setters; | 84 super.setters = scope.setters; |
76 super.parent = scope.parent; | 85 super.parent = scope.parent; |
77 } | 86 } |
78 | 87 |
79 Scope createNestedScope({bool isModifiable: true}) { | 88 Scope createNestedScope(String debugName, {bool isModifiable: true}) { |
80 return new Scope.nested(this, isModifiable: isModifiable); | 89 return new Scope.nested(this, debugName, isModifiable: isModifiable); |
81 } | 90 } |
82 | 91 |
83 Scope withTypeVariables(List<TypeVariableBuilder> typeVariables) { | 92 Scope withTypeVariables(List<TypeVariableBuilder> typeVariables) { |
84 if (typeVariables == null) return this; | 93 if (typeVariables == null) return this; |
85 Scope newScope = new Scope.nested(this, isModifiable: false); | 94 Scope newScope = |
| 95 new Scope.nested(this, "type variables", isModifiable: false); |
86 for (TypeVariableBuilder t in typeVariables) { | 96 for (TypeVariableBuilder t in typeVariables) { |
87 newScope.local[t.name] = t; | 97 newScope.local[t.name] = t; |
88 } | 98 } |
89 return newScope; | 99 return newScope; |
90 } | 100 } |
91 | 101 |
92 /// Create a special scope for use by labeled staments. This scope doesn't | 102 /// Create a special scope for use by labeled staments. This scope doesn't |
93 /// introduce a new scope for local variables, only for labels. This deals | 103 /// introduce a new scope for local variables, only for labels. This deals |
94 /// with corner cases like this: | 104 /// with corner cases like this: |
95 /// | 105 /// |
96 /// L: var x; | 106 /// L: var x; |
97 /// x = 42; | 107 /// x = 42; |
98 /// print("The answer is $x."); | 108 /// print("The answer is $x."); |
99 Scope createNestedLabelScope() { | 109 Scope createNestedLabelScope() { |
100 return new Scope(local, setters, parent, isModifiable: true); | 110 return new Scope(local, setters, parent, "label", isModifiable: true); |
101 } | 111 } |
102 | 112 |
103 void recordUse(String name, int charOffset, Uri fileUri) { | 113 void recordUse(String name, int charOffset, Uri fileUri) { |
104 if (isModifiable) { | 114 if (isModifiable) { |
105 usedNames ??= <String, int>{}; | 115 usedNames ??= <String, int>{}; |
106 usedNames.putIfAbsent(name, () => charOffset); | 116 usedNames.putIfAbsent(name, () => charOffset); |
107 } | 117 } |
108 } | 118 } |
109 | 119 |
110 Builder lookupIn(String name, int charOffset, Uri fileUri, | 120 Builder lookupIn(String name, int charOffset, Uri fileUri, |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 | 331 |
322 Message get message => templateAccessError.withArguments(name); | 332 Message get message => templateAccessError.withArguments(name); |
323 } | 333 } |
324 | 334 |
325 class AmbiguousBuilder extends ProblemBuilder { | 335 class AmbiguousBuilder extends ProblemBuilder { |
326 AmbiguousBuilder(String name, Builder builder, int charOffset, Uri fileUri) | 336 AmbiguousBuilder(String name, Builder builder, int charOffset, Uri fileUri) |
327 : super(name, builder, charOffset, fileUri); | 337 : super(name, builder, charOffset, fileUri); |
328 | 338 |
329 Message get message => templateDuplicatedName.withArguments(name); | 339 Message get message => templateDuplicatedName.withArguments(name); |
330 } | 340 } |
OLD | NEW |