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

Side by Side Diff: lib/compiler/implementation/elements/elements.dart

Issue 10829379: Add erroneous elements for function types and use them to allow unresolvable constructors to be han… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 4 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
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 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 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('elements'); 5 #library('elements');
6 6
7 #import('dart:uri'); 7 #import('dart:uri');
8 8
9 #import('../tree/tree.dart'); 9 #import('../tree/tree.dart');
10 #import('../scanner/scannerlib.dart'); 10 #import('../scanner/scannerlib.dart');
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 bool isTypeVariable() => kind === ElementKind.TYPE_VARIABLE; 153 bool isTypeVariable() => kind === ElementKind.TYPE_VARIABLE;
154 bool isField() => kind === ElementKind.FIELD; 154 bool isField() => kind === ElementKind.FIELD;
155 bool isGetter() => kind === ElementKind.GETTER; 155 bool isGetter() => kind === ElementKind.GETTER;
156 bool isSetter() => kind === ElementKind.SETTER; 156 bool isSetter() => kind === ElementKind.SETTER;
157 bool isAccessor() => isGetter() || isSetter(); 157 bool isAccessor() => isGetter() || isSetter();
158 bool isForeign() => kind === ElementKind.FOREIGN; 158 bool isForeign() => kind === ElementKind.FOREIGN;
159 bool isLibrary() => kind === ElementKind.LIBRARY; 159 bool isLibrary() => kind === ElementKind.LIBRARY;
160 bool impliesType() => (kind.category & ElementCategory.IMPLIES_TYPE) != 0; 160 bool impliesType() => (kind.category & ElementCategory.IMPLIES_TYPE) != 0;
161 bool isExtendable() => (kind.category & ElementCategory.IS_EXTENDABLE) != 0; 161 bool isExtendable() => (kind.category & ElementCategory.IS_EXTENDABLE) != 0;
162 162
163 /** See [ErroneousElement] for documentation. */
164 bool isValid() => true;
ahe 2012/08/20 15:06:47 How about isErroneous instead (and reversed).
karlklose 2012/08/21 11:44:10 Done.
165
163 // TODO(johnniwinther): This breaks for libraries (for which enclosing 166 // TODO(johnniwinther): This breaks for libraries (for which enclosing
164 // elements are null) and is invalid for top level variable declarations for 167 // elements are null) and is invalid for top level variable declarations for
165 // which the enclosing element is a VariableDeclarations and not a compilation 168 // which the enclosing element is a VariableDeclarations and not a compilation
166 // unit. 169 // unit.
167 bool isTopLevel() { 170 bool isTopLevel() {
168 return enclosingElement !== null && enclosingElement.isCompilationUnit(); 171 return enclosingElement !== null && enclosingElement.isCompilationUnit();
169 } 172 }
170 173
171 bool isAssignable() { 174 bool isAssignable() {
172 if (modifiers != null && modifiers.isFinal()) return false; 175 if (modifiers != null && modifiers.isFinal()) return false;
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 283
281 FunctionElement asFunctionElement() => null; 284 FunctionElement asFunctionElement() => null;
282 285
283 Element cloneTo(Element enclosing, DiagnosticListener listener) { 286 Element cloneTo(Element enclosing, DiagnosticListener listener) {
284 listener.cancel("Unimplemented cloneTo", element: this); 287 listener.cancel("Unimplemented cloneTo", element: this);
285 } 288 }
286 289
287 Link<Type> get allSupertypesAndSelf() { 290 Link<Type> get allSupertypesAndSelf() {
288 return allSupertypes.prepend(new InterfaceType(this)); 291 return allSupertypes.prepend(new InterfaceType(this));
289 } 292 }
293
294 static bool isInvalid(Element e) => e == null || !e.isValid();
295 }
296
297 /**
298 * [ErroneousElement]s are used to mark something as unresolvable, but in
ahe 2012/08/20 15:06:47 Try to keep the first line a summary of the class
karlklose 2012/08/21 11:44:10 Done.
299 * contrast to using [null], there is additional information about the error
300 * that caused the element to be unresolvable.
301 *
302 * Accessing any field or calling any method defined on [Element] except
303 * [isValid] will throw an exception.
ahe 2012/08/20 15:06:47 I don't think that is a good idea.
karlklose 2012/08/21 11:44:10 On 2012/08/20 15:06:47, ahe wrote: I added a comme
304 *
305 * Code that does not handle [ErroneousElement]s should use
306 * [Element.isInvalid(element)]
ahe 2012/08/20 15:06:47 [: Element.isInvalid(element) :]
karlklose 2012/08/21 11:44:10 Done.
307 * to check for unresolvable elements instead of
308 * [element == null].
ahe 2012/08/20 15:06:47 [: element == null :]
karlklose 2012/08/21 11:44:10 Done.
309 */
310 class ErroneousElement extends Element {
311 final Message errorMessage;
312
313 ErroneousElement(this.errorMessage, Element enclosing)
314 : super(const SourceString('erroneous element'), null, enclosing);
315
316 isValid() => false;
317
318 unsupported() {
319 throw 'unsupported operation on erroneous element';
320 }
321
322 SourceString get name() => unsupported();
323 ElementKind get kind() => unsupported();
324 Link<Node> get metadata() => unsupported();
325 }
326
327 class ErroneousFunctionElement extends ErroneousElement
328 implements FunctionElement {
329 ErroneousFunctionElement(errorMessage, Element enclosing)
330 : super(errorMessage, enclosing);
331
332 get type() => unsupported();
333 get cachedNode() => unsupported();
334 get functionSignature() => unsupported();
335 get patch() => unsupported();
336 get defaultImplementation() => unsupported();
337 bool get isPatched() => unsupported();
338 setPatch(patch) => unsupported();
339 computeSignature(compiler) => unsupported();
340 requiredParameterCount(compiler) => unsupported();
341 optionalParameterCount(compiler) => unsupported();
342 parameterCount(copmiler) => unsupported();
290 } 343 }
291 344
292 class ContainerElement extends Element { 345 class ContainerElement extends Element {
293 Link<Element> localMembers = const EmptyLink<Element>(); 346 Link<Element> localMembers = const EmptyLink<Element>();
294 347
295 ContainerElement(name, kind, enclosingElement) 348 ContainerElement(name, kind, enclosingElement)
296 : super(name, kind, enclosingElement); 349 : super(name, kind, enclosingElement);
297 350
298 void addMember(Element element, DiagnosticListener listener) { 351 void addMember(Element element, DiagnosticListener listener) {
299 localMembers = localMembers.prepend(element); 352 localMembers = localMembers.prepend(element);
(...skipping 986 matching lines...) Expand 10 before | Expand all | Expand 10 after
1286 Scope buildScope() => 1339 Scope buildScope() =>
1287 new ClassScope(enclosingElement.buildScope(), this); 1340 new ClassScope(enclosingElement.buildScope(), this);
1288 1341
1289 ClassElement cloneTo(Element enclosing, DiagnosticListener listener) { 1342 ClassElement cloneTo(Element enclosing, DiagnosticListener listener) {
1290 listener.internalErrorOnElement(this, 'unsupported operation'); 1343 listener.internalErrorOnElement(this, 'unsupported operation');
1291 } 1344 }
1292 } 1345 }
1293 1346
1294 class Elements { 1347 class Elements {
1295 static bool isLocal(Element element) { 1348 static bool isLocal(Element element) {
1296 return ((element !== null) 1349 return !Element.isInvalid(element)
1297 && !element.isInstanceMember() 1350 && !element.isInstanceMember()
1298 && !isStaticOrTopLevelField(element) 1351 && !isStaticOrTopLevelField(element)
1299 && !isStaticOrTopLevelFunction(element) 1352 && !isStaticOrTopLevelFunction(element)
1300 && (element.kind === ElementKind.VARIABLE || 1353 && (element.kind === ElementKind.VARIABLE ||
1301 element.kind === ElementKind.PARAMETER || 1354 element.kind === ElementKind.PARAMETER ||
1302 element.kind === ElementKind.FUNCTION)); 1355 element.kind === ElementKind.FUNCTION);
1303 } 1356 }
1304 1357
1305 static bool isInstanceField(Element element) { 1358 static bool isInstanceField(Element element) {
1306 return (element !== null) 1359 return !Element.isInvalid(element)
1307 && element.isInstanceMember() 1360 && element.isInstanceMember()
1308 && (element.kind === ElementKind.FIELD 1361 && (element.kind === ElementKind.FIELD
1309 || element.kind === ElementKind.GETTER 1362 || element.kind === ElementKind.GETTER
1310 || element.kind === ElementKind.SETTER); 1363 || element.kind === ElementKind.SETTER);
1311 } 1364 }
1312 1365
1313 static bool isStaticOrTopLevel(Element element) { 1366 static bool isStaticOrTopLevel(Element element) {
1314 return (element != null) 1367 return !Element.isInvalid(element)
1315 && !element.isInstanceMember() 1368 && !element.isInstanceMember()
1316 && !element.isPrefix() 1369 && !element.isPrefix()
1317 && element.enclosingElement !== null 1370 && element.enclosingElement !== null
1318 && (element.enclosingElement.kind == ElementKind.CLASS || 1371 && (element.enclosingElement.kind == ElementKind.CLASS ||
1319 element.enclosingElement.kind == ElementKind.COMPILATION_UNIT || 1372 element.enclosingElement.kind == ElementKind.COMPILATION_UNIT ||
1320 element.enclosingElement.kind == ElementKind.LIBRARY); 1373 element.enclosingElement.kind == ElementKind.LIBRARY);
1321 } 1374 }
1322 1375
1323 static bool isStaticOrTopLevelField(Element element) { 1376 static bool isStaticOrTopLevelField(Element element) {
1324 return isStaticOrTopLevel(element) 1377 return isStaticOrTopLevel(element)
1325 && (element.kind === ElementKind.FIELD 1378 && (element.kind === ElementKind.FIELD
1326 || element.kind === ElementKind.GETTER 1379 || element.kind === ElementKind.GETTER
1327 || element.kind === ElementKind.SETTER); 1380 || element.kind === ElementKind.SETTER);
1328 } 1381 }
1329 1382
1330 static bool isStaticOrTopLevelFunction(Element element) { 1383 static bool isStaticOrTopLevelFunction(Element element) {
1331 return isStaticOrTopLevel(element) 1384 return isStaticOrTopLevel(element)
1332 && (element.kind === ElementKind.FUNCTION); 1385 && (element.kind === ElementKind.FUNCTION);
1333 } 1386 }
1334 1387
1335 static bool isInstanceMethod(Element element) { 1388 static bool isInstanceMethod(Element element) {
1336 return (element != null) 1389 return !Element.isInvalid(element)
1337 && element.isInstanceMember() 1390 && element.isInstanceMember()
1338 && (element.kind === ElementKind.FUNCTION); 1391 && (element.kind === ElementKind.FUNCTION);
1339 } 1392 }
1340 1393
1341 static bool isInstanceSend(Send send, TreeElements elements) { 1394 static bool isInstanceSend(Send send, TreeElements elements) {
1342 Element element = elements[send]; 1395 Element element = elements[send];
1343 if (element === null) return !isClosureSend(send, element); 1396 if (element === null) return !isClosureSend(send, element);
1344 return isInstanceMethod(element) || isInstanceField(element); 1397 return isInstanceMethod(element) || isInstanceField(element);
1345 } 1398 }
1346 1399
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1479 Node parseNode(compiler) => cachedNode; 1532 Node parseNode(compiler) => cachedNode;
1480 1533
1481 String toString() => "${enclosingElement.toString()}.${name.slowToString()}"; 1534 String toString() => "${enclosingElement.toString()}.${name.slowToString()}";
1482 1535
1483 TypeVariableElement cloneTo(Element enclosing, DiagnosticListener listener) { 1536 TypeVariableElement cloneTo(Element enclosing, DiagnosticListener listener) {
1484 TypeVariableElement result = 1537 TypeVariableElement result =
1485 new TypeVariableElement(name, enclosing, node, type, bound); 1538 new TypeVariableElement(name, enclosing, node, type, bound);
1486 return result; 1539 return result;
1487 } 1540 }
1488 } 1541 }
OLDNEW
« no previous file with comments | « no previous file | lib/compiler/implementation/resolver.dart » ('j') | lib/compiler/implementation/resolver.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698