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.dart' show Builder, MixedAccessor; | 7 import 'builder.dart' show Builder, MixedAccessor; |
8 | 8 |
9 import '../errors.dart' show internalError; | 9 import '../errors.dart' show internalError; |
10 | 10 |
(...skipping 19 matching lines...) Expand all Loading... |
30 return new Scope(<String, Builder>{}, this, isModifiable: isModifiable); | 30 return new Scope(<String, Builder>{}, this, isModifiable: isModifiable); |
31 } | 31 } |
32 | 32 |
33 Builder lookup(String name, int charOffset, Uri fileUri) { | 33 Builder lookup(String name, int charOffset, Uri fileUri) { |
34 Builder builder = local[name]; | 34 Builder builder = local[name]; |
35 if (builder != null) { | 35 if (builder != null) { |
36 if (builder.next != null) { | 36 if (builder.next != null) { |
37 return lookupAmbiguous(name, builder, false, charOffset, fileUri); | 37 return lookupAmbiguous(name, builder, false, charOffset, fileUri); |
38 } | 38 } |
39 return builder.isSetter | 39 return builder.isSetter |
40 ? new AccessErrorBuilder(builder, charOffset, fileUri) | 40 ? new AccessErrorBuilder(name, builder, charOffset, fileUri) |
41 : builder; | 41 : builder; |
42 } else { | 42 } else { |
43 return parent?.lookup(name, charOffset, fileUri); | 43 return parent?.lookup(name, charOffset, fileUri); |
44 } | 44 } |
45 } | 45 } |
46 | 46 |
47 Builder lookupSetter(String name, int charOffset, Uri fileUri) { | 47 Builder lookupSetter(String name, int charOffset, Uri fileUri) { |
48 Builder builder = local[name]; | 48 Builder builder = local[name]; |
49 if (builder != null) { | 49 if (builder != null) { |
50 if (builder.next != null) { | 50 if (builder.next != null) { |
51 return lookupAmbiguous(name, builder, true, charOffset, fileUri); | 51 return lookupAmbiguous(name, builder, true, charOffset, fileUri); |
52 } | 52 } |
53 if (builder.isField) { | 53 if (builder.isField) { |
54 if (builder.isFinal) { | 54 if (builder.isFinal) { |
55 return new AccessErrorBuilder(builder, charOffset, fileUri); | 55 return new AccessErrorBuilder(name, builder, charOffset, fileUri); |
56 } else { | 56 } else { |
57 return builder; | 57 return builder; |
58 } | 58 } |
59 } else if (builder.isSetter) { | 59 } else if (builder.isSetter) { |
60 return builder; | 60 return builder; |
61 } else { | 61 } else { |
62 return new AccessErrorBuilder(builder, charOffset, fileUri); | 62 return new AccessErrorBuilder(name, builder, charOffset, fileUri); |
63 } | 63 } |
64 } else { | 64 } else { |
65 return parent?.lookupSetter(name, charOffset, fileUri); | 65 return parent?.lookupSetter(name, charOffset, fileUri); |
66 } | 66 } |
67 } | 67 } |
68 | 68 |
69 Builder lookupAmbiguous( | 69 Builder lookupAmbiguous( |
70 String name, Builder builder, bool setter, int charOffset, Uri fileUri) { | 70 String name, Builder builder, bool setter, int charOffset, Uri fileUri) { |
71 assert(builder.next != null); | 71 assert(builder.next != null); |
72 if (builder is MixedAccessor) { | 72 if (builder is MixedAccessor) { |
73 return setter ? builder.setter : builder.getter; | 73 return setter ? builder.setter : builder.getter; |
74 } | 74 } |
75 Builder setterBuilder; | 75 Builder setterBuilder; |
76 Builder getterBuilder; | 76 Builder getterBuilder; |
77 Builder current = builder; | 77 Builder current = builder; |
78 while (current != null) { | 78 while (current != null) { |
79 if (current.isGetter && getterBuilder == null) { | 79 if (current.isGetter && getterBuilder == null) { |
80 getterBuilder = current; | 80 getterBuilder = current; |
81 } else if (current.isSetter && setterBuilder == null) { | 81 } else if (current.isSetter && setterBuilder == null) { |
82 setterBuilder = current; | 82 setterBuilder = current; |
83 } else { | 83 } else { |
84 return new AmbiguousBuilder(builder, charOffset, fileUri); | 84 return new AmbiguousBuilder(name, builder, charOffset, fileUri); |
85 } | 85 } |
86 current = current.next; | 86 current = current.next; |
87 } | 87 } |
88 assert(getterBuilder != null); | 88 assert(getterBuilder != null); |
89 assert(setterBuilder != null); | 89 assert(setterBuilder != null); |
90 return setter ? setterBuilder : getterBuilder; | 90 return setter ? setterBuilder : getterBuilder; |
91 } | 91 } |
92 | 92 |
93 bool hasLocalLabel(String name) => labels != null && labels.containsKey(name); | 93 bool hasLocalLabel(String name) => labels != null && labels.containsKey(name); |
94 | 94 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 // TODO(ahe): Rename to extend or something. | 126 // TODO(ahe): Rename to extend or something. |
127 void operator []=(String name, Builder member) { | 127 void operator []=(String name, Builder member) { |
128 if (isModifiable) { | 128 if (isModifiable) { |
129 local[name] = member; | 129 local[name] = member; |
130 } else { | 130 } else { |
131 internalError("Can't extend an unmodifiable scope."); | 131 internalError("Can't extend an unmodifiable scope."); |
132 } | 132 } |
133 } | 133 } |
134 } | 134 } |
135 | 135 |
136 class AccessErrorBuilder extends Builder { | 136 abstract class ProblemBuilder extends Builder { |
| 137 final String name; |
| 138 |
137 final Builder builder; | 139 final Builder builder; |
138 | 140 |
139 AccessErrorBuilder(this.builder, int charOffset, Uri fileUri) | 141 ProblemBuilder(this.name, this.builder, int charOffset, Uri fileUri) |
140 : super(null, charOffset, fileUri); | 142 : super(null, charOffset, fileUri); |
141 | 143 |
| 144 get target => null; |
| 145 |
| 146 bool get hasProblem => true; |
| 147 |
| 148 String get message; |
| 149 |
| 150 @override |
| 151 String get fullNameForErrors => name; |
| 152 } |
| 153 |
| 154 /// Represents a [builder] that's being accessed incorrectly. For example, an |
| 155 /// attempt to write to a final field, or to read from a setter. |
| 156 class AccessErrorBuilder extends ProblemBuilder { |
| 157 AccessErrorBuilder(String name, Builder builder, int charOffset, Uri fileUri) |
| 158 : super(name, builder, charOffset, fileUri); |
| 159 |
142 Builder get parent => builder; | 160 Builder get parent => builder; |
143 | 161 |
144 get target => null; | |
145 | |
146 bool get isFinal => builder.isFinal; | 162 bool get isFinal => builder.isFinal; |
147 | 163 |
148 bool get isField => builder.isField; | 164 bool get isField => builder.isField; |
149 | 165 |
150 bool get isRegularMethod => builder.isRegularMethod; | 166 bool get isRegularMethod => builder.isRegularMethod; |
151 | 167 |
152 bool get isGetter => !builder.isGetter; | 168 bool get isGetter => !builder.isGetter; |
153 | 169 |
154 bool get isSetter => !builder.isSetter; | 170 bool get isSetter => !builder.isSetter; |
155 | 171 |
156 bool get isInstanceMember => builder.isInstanceMember; | 172 bool get isInstanceMember => builder.isInstanceMember; |
157 | 173 |
158 bool get isStatic => builder.isStatic; | 174 bool get isStatic => builder.isStatic; |
159 | 175 |
160 bool get isTopLevel => builder.isTopLevel; | 176 bool get isTopLevel => builder.isTopLevel; |
161 | 177 |
162 bool get isTypeDeclaration => builder.isTypeDeclaration; | 178 bool get isTypeDeclaration => builder.isTypeDeclaration; |
163 | 179 |
164 bool get isLocal => builder.isLocal; | 180 bool get isLocal => builder.isLocal; |
165 | 181 |
166 bool get hasProblem => true; | 182 String get message => "Access error: '$name'."; |
167 } | 183 } |
168 | 184 |
169 class AmbiguousBuilder extends Builder { | 185 class AmbiguousBuilder extends ProblemBuilder { |
170 final Builder builder; | 186 AmbiguousBuilder(String name, Builder builder, int charOffset, Uri fileUri) |
| 187 : super(name, builder, charOffset, fileUri); |
171 | 188 |
172 AmbiguousBuilder(this.builder, int charOffset, Uri fileUri) | 189 String get message => "Duplicated named: '$name'."; |
173 : super(null, charOffset, fileUri); | |
174 | |
175 get target => null; | |
176 | |
177 bool get hasProblem => true; | |
178 } | 190 } |
OLD | NEW |