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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/resolution/class_members.dart

Issue 141753002: Reapply "Implement new model for class members." and "Implement new model for interface members." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix dart2dart bug. Created 6 years, 11 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
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.
4
5 library resolution.compute_members;
6
7 import '../elements/elements.dart'
8 show Element,
9 Name,
10 PublicName,
11 Member,
12 MemberSignature,
13 LibraryElement,
14 ClassElement,
15 MixinApplicationElement;
16 import '../elements/modelx.dart'
17 show BaseClassElementX;
18 import '../dart_types.dart';
19 import '../dart2jslib.dart'
20 show Compiler,
21 MessageKind,
22 invariant;
23 import '../util/util.dart';
24
25 part 'member_impl.dart';
26
27 class MembersCreator {
28 final ClassElement cls;
29 final Compiler compiler;
30
31 Map<Name, Member> classMembers = new Map<Name, Member>();
32 Map<Name, MemberSignature> interfaceMembers =
33 new Map<Name, MemberSignature>();
34
35 MembersCreator(Compiler this.compiler, ClassElement this.cls);
36
37 void computeMembers() {
38 Map<Name, Set<Member>> inheritedInterfaceMembers =
39 _computeSuperMembers();
40 Map<Name, Member> declaredMembers = _computeClassMembers();
41 _computeInterfaceMembers(inheritedInterfaceMembers, declaredMembers);
42 }
43
44 Map<Name, Set<Member>> _computeSuperMembers() {
45 Map<Name, Set<Member>> inheritedInterfaceMembers =
46 new Map<Name, Set<Member>>();
47
48 void inheritInterfaceMembers(InterfaceType supertype) {
49 supertype.element.forEachInterfaceMember((MemberSignature member) {
50 Set<Member> members =
51 inheritedInterfaceMembers.putIfAbsent(
52 member.name, () => new Set<Member>());
53 for (DeclaredMember declaredMember in member.declarations) {
54 members.add(declaredMember.inheritFrom(supertype));
55 }
56 });
57 }
58
59 // Inherit class and interface members from superclass.
60 InterfaceType superclass = cls.supertype;
61 if (superclass != null) {
62 computeClassMembers(compiler, superclass.element);
63 superclass.element.forEachClassMember((DeclaredMember member) {
64 if (!member.isStatic) {
65 DeclaredMember inherited = member.inheritFrom(superclass);
66 classMembers[member.name] = inherited;
67 }
68 });
69 inheritInterfaceMembers(superclass);
70 }
71
72 // Inherit interface members from superinterfaces.
73 for (Link<DartType> link = cls.interfaces;
74 !link.isEmpty;
75 link = link.tail) {
76 InterfaceType superinterface = link.head;
77 computeClassMembers(compiler, superinterface.element);
78 inheritInterfaceMembers(superinterface);
79 }
80
81 return inheritedInterfaceMembers;
82 }
83
84 Map<Name, Member> _computeClassMembers() {
85 Map<Name, Member> declaredMembers = new Map<Name, Member>();
86
87 void overrideMember(DeclaredMember declared) {
88 classMembers[declared.name] = declared;
89 }
90
91 if (cls.isMixinApplication) {
92 MixinApplicationElement mixinApplication = cls;
93 if (mixinApplication.mixin != null) {
94 // Only mix in class members when the mixin type is not malformed.
95 computeClassMembers(compiler, mixinApplication.mixin);
96
97 mixinApplication.mixin.forEachClassMember((DeclaredMember member) {
98 if (!member.isStatic) {
99 // Abstract and static members are not mixed in.
100 DeclaredMember mixedInMember =
101 member.inheritFrom(mixinApplication.mixinType);
102 overrideMember(mixedInMember);
103 }
104 });
105 }
106 } else {
107 LibraryElement library = cls.getLibrary();
108 InterfaceType thisType = cls.thisType;
109
110 cls.forEachLocalMember((Element element) {
111 if (element.isConstructor()) return;
112
113 Name name = new Name(element.name, library);
114 if (element.isField()) {
115 DartType type = element.computeType(compiler);
116 declaredMembers[name] = new DeclaredMember(
117 name, element, thisType, type,
118 new FunctionType(compiler.functionClass, type));
119 if (!element.modifiers.isConst() &&
120 !element.modifiers.isFinal()) {
121 name = name.setter;
122 declaredMembers[name] = new DeclaredMember(
123 name, element, thisType, type,
124 new FunctionType(compiler.functionClass,
125 compiler.types.voidType,
126 const Link<DartType>().prepend(type)));
127 }
128 } else if (element.isGetter()) {
129 FunctionType functionType = element.computeType(compiler);
130 DartType type = functionType.returnType;
131 declaredMembers[name] =
132 new DeclaredMember(name, element, thisType, type, functionType);
133 } else if (element.isSetter()) {
134 FunctionType functionType = element.computeType(compiler);
135 DartType type;
136 if (!functionType.parameterTypes.isEmpty) {
137 type = functionType.parameterTypes.head;
138 } else {
139 type = compiler.types.dynamicType;
140 }
141 name = name.setter;
142 declaredMembers[name] = new DeclaredMember(
143 name, element, thisType, type, functionType);
144 } else {
145 assert(invariant(element, element.isFunction()));
146 FunctionType type = element.computeType(compiler);
147 declaredMembers[name] = new DeclaredMember(
148 name, element, thisType, type, type);
149 }
150 });
151 }
152
153 declaredMembers.values.forEach((Member member) {
154 if (!member.element.isAbstract) {
155 overrideMember(member);
156 }
157 });
158
159 return declaredMembers;
160 }
161
162 void _computeInterfaceMembers(
163 Map<Name, Set<Member>> inheritedInterfaceMembers,
164 Map<Name, Member> declaredMembers) {
165 InterfaceType thisType = cls.thisType;
166 // Compute the interface members by overriding the inherited members with
167 // a declared member or by computing a single, possibly synthesized,
168 // inherited member.
169 inheritedInterfaceMembers.forEach(
170 (Name name, Set<Member> inheritedMembers) {
171 Member declared = declaredMembers[name];
172 if (declared != null) {
173 if (!declared.isStatic) {
174 interfaceMembers[name] = declared;
175 }
176 } else {
177 bool someAreGetters = false;
178 bool allAreGetters = true;
179 Map<DartType, Set<Member>> subtypesOfAllInherited =
180 new Map<DartType, Set<Member>>();
181 outer: for (Member inherited in inheritedMembers) {
182 if (inherited.isGetter) {
183 someAreGetters = true;
184 if (!allAreGetters) break outer;
185 } else {
186 allAreGetters = false;
187 if (someAreGetters) break outer;
188 }
189 for (MemberSignature other in inheritedMembers) {
190 if (!compiler.types.isSubtype(inherited.functionType,
191 other.functionType)) {
192 continue outer;
193 }
194 }
195 subtypesOfAllInherited.putIfAbsent(inherited.functionType,
196 () => new Set<Member>()).add(inherited);
197 }
198 if (someAreGetters && !allAreGetters) {
199 interfaceMembers[name] = new ErroneousMember(inheritedMembers);
200 } else if (subtypesOfAllInherited.length == 1) {
201 // All signatures have the same type.
202 Set<Member> members = subtypesOfAllInherited.values.first;
203 MemberSignature inherited = members.first;
204 if (members.length != 1) {
205 // Multiple signatures with the same type => return a
206 // synthesized signature.
207 inherited = new SyntheticMember(
208 members, inherited.type, inherited.functionType);
209 }
210 interfaceMembers[name] = inherited;
211 } else {
212 _inheritedSynthesizedMember(name, inheritedMembers);
213 }
214 }
215 });
216
217 // Add the non-overriding instance methods to the interface members.
218 declaredMembers.forEach((Name name, Member member) {
219 if (!member.isStatic) {
220 interfaceMembers.putIfAbsent(name, () => member);
221 }
222 });
223 }
224
225 /// Create and inherit a synthesized member for [inheritedMembers].
226 void _inheritedSynthesizedMember(Name name,
227 Set<Member> inheritedMembers) {
228 // Multiple signatures with different types => create the synthesized
229 // version.
230 int minRequiredParameters;
231 int maxPositionalParameters;
232 Set<String> names = new Set<String>();
233 for (MemberSignature member in inheritedMembers) {
234 int requiredParameters = 0;
235 int optionalParameters = 0;
236 if (member.isSetter) {
237 requiredParameters = 1;
238 }
239 if (member.type.kind == TypeKind.FUNCTION) {
240 FunctionType type = member.type;
241 type.namedParameters.forEach(
242 (String name) => names.add(name));
243 requiredParameters = type.parameterTypes.slowLength();
244 optionalParameters = type.optionalParameterTypes.slowLength();
245 }
246 int positionalParameters = requiredParameters + optionalParameters;
247 if (minRequiredParameters == null ||
248 minRequiredParameters > requiredParameters) {
249 minRequiredParameters = requiredParameters;
250 }
251 if (maxPositionalParameters == null ||
252 maxPositionalParameters < positionalParameters) {
253 maxPositionalParameters = positionalParameters;
254 }
255 }
256 int optionalParameters =
257 maxPositionalParameters - minRequiredParameters;
258 // TODO(johnniwinther): Support function types with both optional
259 // and named parameters?
260 if (optionalParameters == 0 || names.isEmpty) {
261 Link<DartType> requiredParameterTypes = const Link<DartType>();
262 while (--minRequiredParameters >= 0) {
263 requiredParameterTypes =
264 requiredParameterTypes.prepend(compiler.types.dynamicType);
265 }
266 Link<DartType> optionalParameterTypes = const Link<DartType>();
267 while (--optionalParameters >= 0) {
268 optionalParameterTypes =
269 optionalParameterTypes.prepend(compiler.types.dynamicType);
270 }
271 Link<String> namedParameters = const Link<String>();
272 Link<DartType> namedParameterTypes = const Link<DartType>();
273 List<String> namesReversed =
274 names.toList()..sort((a, b) => -a.compareTo(b));
275 for (String name in namesReversed) {
276 namedParameters = namedParameters.prepend(name);
277 namedParameterTypes =
278 namedParameterTypes.prepend(compiler.types.dynamicType);
279 }
280 FunctionType memberType = new FunctionType(
281 compiler.functionClass,
282 compiler.types.dynamicType,
283 requiredParameterTypes,
284 optionalParameterTypes,
285 namedParameters, namedParameterTypes);
286 DartType type = memberType;
287 if (inheritedMembers.first.isGetter ||
288 inheritedMembers.first.isSetter) {
289 type = compiler.types.dynamicType;
290 }
291 interfaceMembers[name] = new SyntheticMember(
292 inheritedMembers, type, memberType);
293 }
294 }
295
296 static void computeClassMembers(Compiler compiler, BaseClassElementX cls) {
297 if (cls.classMembers != null) return;
298 MembersCreator creator = new MembersCreator(compiler, cls);
299 creator.computeMembers();
300 cls.classMembers = creator.classMembers;
301 cls.interfaceMembers = creator.interfaceMembers;
302 }
303 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698