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

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: Address comments and rebase. 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
« no previous file with comments | « no previous file | lib/compiler/implementation/resolver.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 isErroneous() => false;
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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 bool _isNative = false; 280 bool _isNative = false;
278 void setNative() { _isNative = true; } 281 void setNative() { _isNative = true; }
279 bool isNative() => _isNative; 282 bool isNative() => _isNative;
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
290
291 static bool isInvalid(Element e) => e == null || e.isErroneous();
292 }
293
294 /**
295 * Represents an unresolvable element.
ahe 2012/08/21 12:55:25 I imagine this could also be used for duplicated e
karlklose 2012/08/21 13:05:59 Done.
296 *
297 * [ErroneousElement]s are used instead of [null] to provide additional
ahe 2012/08/21 12:55:25 Perhaps more elegant: An [ErroneousElement] is us
karlklose 2012/08/21 13:05:59 Done.
298 * information about the error that caused the element to be unresolvable.
299 *
300 * Accessing any field or calling any method defined on [Element] except
301 * [isValid] will currently throw an exception. (This might change when we
302 * actually want more information on the erroneous element, e.g., the name
303 * of the element we were trying to resolve.)
304 *
305 * Code that does not handle [ErroneousElement]s should use
ahe 2012/08/21 12:55:25 Perhaps more elegant: Code that cannot handle an
karlklose 2012/08/21 13:05:59 Done.
306 * [: Element.isInvalid(element) :]
307 * to check for unresolvable elements instead of
308 * [: element == null :].
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 isErroneous() => true;
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();
287 } 343 }
288 344
289 class ContainerElement extends Element { 345 class ContainerElement extends Element {
290 Link<Element> localMembers = const EmptyLink<Element>(); 346 Link<Element> localMembers = const EmptyLink<Element>();
291 347
292 ContainerElement(name, kind, enclosingElement) 348 ContainerElement(name, kind, enclosingElement)
293 : super(name, kind, enclosingElement); 349 : super(name, kind, enclosingElement);
294 350
295 void addMember(Element element, DiagnosticListener listener) { 351 void addMember(Element element, DiagnosticListener listener) {
296 localMembers = localMembers.prepend(element); 352 localMembers = localMembers.prepend(element);
(...skipping 1013 matching lines...) Expand 10 before | Expand all | Expand 10 after
1310 listener.internalErrorOnElement(this, 'unsupported operation'); 1366 listener.internalErrorOnElement(this, 'unsupported operation');
1311 } 1367 }
1312 1368
1313 Link<Type> get allSupertypesAndSelf() { 1369 Link<Type> get allSupertypesAndSelf() {
1314 return allSupertypes.prepend(new InterfaceType(this)); 1370 return allSupertypes.prepend(new InterfaceType(this));
1315 } 1371 }
1316 } 1372 }
1317 1373
1318 class Elements { 1374 class Elements {
1319 static bool isLocal(Element element) { 1375 static bool isLocal(Element element) {
1320 return ((element !== null) 1376 return !Element.isInvalid(element)
1321 && !element.isInstanceMember() 1377 && !element.isInstanceMember()
1322 && !isStaticOrTopLevelField(element) 1378 && !isStaticOrTopLevelField(element)
1323 && !isStaticOrTopLevelFunction(element) 1379 && !isStaticOrTopLevelFunction(element)
1324 && (element.kind === ElementKind.VARIABLE || 1380 && (element.kind === ElementKind.VARIABLE ||
1325 element.kind === ElementKind.PARAMETER || 1381 element.kind === ElementKind.PARAMETER ||
1326 element.kind === ElementKind.FUNCTION)); 1382 element.kind === ElementKind.FUNCTION);
1327 } 1383 }
1328 1384
1329 static bool isInstanceField(Element element) { 1385 static bool isInstanceField(Element element) {
1330 return (element !== null) 1386 return !Element.isInvalid(element)
1331 && element.isInstanceMember() 1387 && element.isInstanceMember()
1332 && (element.kind === ElementKind.FIELD 1388 && (element.kind === ElementKind.FIELD
1333 || element.kind === ElementKind.GETTER 1389 || element.kind === ElementKind.GETTER
1334 || element.kind === ElementKind.SETTER); 1390 || element.kind === ElementKind.SETTER);
1335 } 1391 }
1336 1392
1337 static bool isStaticOrTopLevel(Element element) { 1393 static bool isStaticOrTopLevel(Element element) {
1338 // TODO(ager): This should not be necessary when patch support has 1394 // TODO(ager): This should not be necessary when patch support has
1339 // been reworked. 1395 // been reworked.
1340 if (element != null 1396 if (!Element.isInvalid(element)
1341 && element.modifiers != null 1397 && element.modifiers != null
1342 && element.modifiers.isStatic()) { 1398 && element.modifiers.isStatic()) {
1343 return true; 1399 return true;
1344 } 1400 }
1345 return (element != null) 1401 return !Element.isInvalid(element)
1346 && !element.isInstanceMember() 1402 && !element.isInstanceMember()
1347 && !element.isPrefix() 1403 && !element.isPrefix()
1348 && element.enclosingElement !== null 1404 && element.enclosingElement !== null
1349 && (element.enclosingElement.kind == ElementKind.CLASS || 1405 && (element.enclosingElement.kind == ElementKind.CLASS ||
1350 element.enclosingElement.kind == ElementKind.COMPILATION_UNIT || 1406 element.enclosingElement.kind == ElementKind.COMPILATION_UNIT ||
1351 element.enclosingElement.kind == ElementKind.LIBRARY); 1407 element.enclosingElement.kind == ElementKind.LIBRARY);
1352 } 1408 }
1353 1409
1354 static bool isStaticOrTopLevelField(Element element) { 1410 static bool isStaticOrTopLevelField(Element element) {
1355 return isStaticOrTopLevel(element) 1411 return isStaticOrTopLevel(element)
1356 && (element.kind === ElementKind.FIELD 1412 && (element.kind === ElementKind.FIELD
1357 || element.kind === ElementKind.GETTER 1413 || element.kind === ElementKind.GETTER
1358 || element.kind === ElementKind.SETTER); 1414 || element.kind === ElementKind.SETTER);
1359 } 1415 }
1360 1416
1361 static bool isStaticOrTopLevelFunction(Element element) { 1417 static bool isStaticOrTopLevelFunction(Element element) {
1362 return isStaticOrTopLevel(element) 1418 return isStaticOrTopLevel(element)
1363 && (element.kind === ElementKind.FUNCTION); 1419 && (element.kind === ElementKind.FUNCTION);
1364 } 1420 }
1365 1421
1366 static bool isInstanceMethod(Element element) { 1422 static bool isInstanceMethod(Element element) {
1367 return (element != null) 1423 return !Element.isInvalid(element)
1368 && element.isInstanceMember() 1424 && element.isInstanceMember()
1369 && (element.kind === ElementKind.FUNCTION); 1425 && (element.kind === ElementKind.FUNCTION);
1370 } 1426 }
1371 1427
1372 static bool isInstanceSend(Send send, TreeElements elements) { 1428 static bool isInstanceSend(Send send, TreeElements elements) {
1373 Element element = elements[send]; 1429 Element element = elements[send];
1374 if (element === null) return !isClosureSend(send, element); 1430 if (element === null) return !isClosureSend(send, element);
1375 return isInstanceMethod(element) || isInstanceField(element); 1431 return isInstanceMethod(element) || isInstanceField(element);
1376 } 1432 }
1377 1433
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 Node parseNode(compiler) => cachedNode; 1566 Node parseNode(compiler) => cachedNode;
1511 1567
1512 String toString() => "${enclosingElement.toString()}.${name.slowToString()}"; 1568 String toString() => "${enclosingElement.toString()}.${name.slowToString()}";
1513 1569
1514 TypeVariableElement cloneTo(Element enclosing, DiagnosticListener listener) { 1570 TypeVariableElement cloneTo(Element enclosing, DiagnosticListener listener) {
1515 TypeVariableElement result = 1571 TypeVariableElement result =
1516 new TypeVariableElement(name, enclosing, cachedNode, type, bound); 1572 new TypeVariableElement(name, enclosing, cachedNode, type, bound);
1517 return result; 1573 return result;
1518 } 1574 }
1519 } 1575 }
OLDNEW
« no previous file with comments | « no previous file | lib/compiler/implementation/resolver.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698