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

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

Issue 14079003: Implement Symbol correctly in dart2js. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 8 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 part of resolution; 5 part of resolution;
6 6
7 abstract class TreeElements { 7 abstract class TreeElements {
8 Element get currentElement; 8 Element get currentElement;
9 Set<Node> get superUses; 9 Set<Node> get superUses;
10 10
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 compiler.withCurrentElement(element, () => measure(() { 538 compiler.withCurrentElement(element, () => measure(() {
539 assert(element.resolutionState == STATE_NOT_STARTED); 539 assert(element.resolutionState == STATE_NOT_STARTED);
540 element.resolutionState = STATE_STARTED; 540 element.resolutionState = STATE_STARTED;
541 Node tree = element.parseNode(compiler); 541 Node tree = element.parseNode(compiler);
542 loadSupertypes(element, tree); 542 loadSupertypes(element, tree);
543 543
544 ClassResolverVisitor visitor = 544 ClassResolverVisitor visitor =
545 new ClassResolverVisitor(compiler, element); 545 new ClassResolverVisitor(compiler, element);
546 visitor.visit(tree); 546 visitor.visit(tree);
547 element.resolutionState = STATE_DONE; 547 element.resolutionState = STATE_DONE;
548 compiler.onClassResolved(element);
548 })); 549 }));
549 if (element.isPatched) { 550 if (element.isPatched) {
550 // Ensure handling patch after origin. 551 // Ensure handling patch after origin.
551 element.patch.ensureResolved(compiler); 552 element.patch.ensureResolved(compiler);
552 } 553 }
553 } else { // Handle patch classes: 554 } else { // Handle patch classes:
554 element.resolutionState = STATE_STARTED; 555 element.resolutionState = STATE_STARTED;
555 // Ensure handling origin before patch. 556 // Ensure handling origin before patch.
556 element.origin.ensureResolved(compiler); 557 element.origin.ensureResolved(compiler);
557 // Ensure that the type is computed. 558 // Ensure that the type is computed.
(...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after
1612 bool inCatchBlock; 1613 bool inCatchBlock;
1613 Scope scope; 1614 Scope scope;
1614 ClassElement currentClass; 1615 ClassElement currentClass;
1615 ExpressionStatement currentExpressionStatement; 1616 ExpressionStatement currentExpressionStatement;
1616 bool typeRequired = false; 1617 bool typeRequired = false;
1617 bool sendIsMemberAccess = false; 1618 bool sendIsMemberAccess = false;
1618 StatementScope statementScope; 1619 StatementScope statementScope;
1619 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION 1620 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION
1620 | ElementCategory.IMPLIES_TYPE; 1621 | ElementCategory.IMPLIES_TYPE;
1621 1622
1623 // TODO(ahe): Find a way to share this with runtime implementation.
1624 static final RegExp symbolValidationPattern =
1625 new RegExp(r'^(?:[a-zA-Z$][a-zA-Z$0-9_]*\.)*(?:[a-zA-Z$][a-zA-Z$0-9_]*=?|'
1626 r'-|'
1627 r'unary-|'
1628 r'\[\]=|'
1629 r'~|'
1630 r'==|'
1631 r'\[\]|'
1632 r'\*|'
1633 r'/|'
1634 r'%|'
1635 r'~/|'
1636 r'\+|'
1637 r'<<|'
1638 r'>>|'
1639 r'>=|'
1640 r'>|'
1641 r'<=|'
1642 r'<|'
1643 r'&|'
1644 r'\^|'
1645 r'\|'
1646 r')$');
1647
1622 ResolverVisitor(Compiler compiler, Element element, this.mapping) 1648 ResolverVisitor(Compiler compiler, Element element, this.mapping)
1623 : this.enclosingElement = element, 1649 : this.enclosingElement = element,
1624 // When the element is a field, we are actually resolving its 1650 // When the element is a field, we are actually resolving its
1625 // initial value, which should not have access to instance 1651 // initial value, which should not have access to instance
1626 // fields. 1652 // fields.
1627 inInstanceContext = (element.isInstanceMember() && !element.isField()) 1653 inInstanceContext = (element.isInstanceMember() && !element.isField())
1628 || element.isGenerativeConstructor(), 1654 || element.isGenerativeConstructor(),
1629 this.currentClass = element.isMember() ? element.getEnclosingClass() 1655 this.currentClass = element.isMember() ? element.getEnclosingClass()
1630 : null, 1656 : null,
1631 this.statementScope = new StatementScope(), 1657 this.statementScope = new StatementScope(),
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
2155 } 2181 }
2156 } 2182 }
2157 } 2183 }
2158 2184
2159 visitSend(Send node) { 2185 visitSend(Send node) {
2160 bool oldSendIsMemberAccess = sendIsMemberAccess; 2186 bool oldSendIsMemberAccess = sendIsMemberAccess;
2161 sendIsMemberAccess = node.isPropertyAccess || node.isCall; 2187 sendIsMemberAccess = node.isPropertyAccess || node.isCall;
2162 Element target = resolveSend(node); 2188 Element target = resolveSend(node);
2163 sendIsMemberAccess = oldSendIsMemberAccess; 2189 sendIsMemberAccess = oldSendIsMemberAccess;
2164 2190
2191 if (target != null && target == compiler.mirrorSystemGetNameFunction) {
2192 compiler.reportWarningCode(
2193 node.selector, MessageKind.GENERIC,
ahe 2013/04/18 11:34:44 Will provide real MessageKind before submitting.
2194 {'text': 'Warning: using '
2195 '"${compiler.mirrorSystemClass.name.slowToString()}.'
2196 '${compiler.mirrorSystemGetNameFunction.name.slowToString()}" '
2197 'will increase the size of compiled code.'});
2198 }
2199
2165 if (!Elements.isUnresolved(target)) { 2200 if (!Elements.isUnresolved(target)) {
2166 if (target.isAbstractField()) { 2201 if (target.isAbstractField()) {
2167 AbstractFieldElement field = target; 2202 AbstractFieldElement field = target;
2168 target = field.getter; 2203 target = field.getter;
2169 if (target == null && !inInstanceContext) { 2204 if (target == null && !inInstanceContext) {
2170 compiler.backend.registerThrowNoSuchMethod(mapping); 2205 compiler.backend.registerThrowNoSuchMethod(mapping);
2171 target = 2206 target =
2172 warnAndCreateErroneousElement(node.selector, field.name, 2207 warnAndCreateErroneousElement(node.selector, field.name,
2173 MessageKind.CANNOT_RESOLVE_GETTER); 2208 MessageKind.CANNOT_RESOLVE_GETTER);
2174 } 2209 }
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
2404 2439
2405 visitReturn(Return node) { 2440 visitReturn(Return node) {
2406 if (node.isRedirectingFactoryBody) { 2441 if (node.isRedirectingFactoryBody) {
2407 handleRedirectingFactoryBody(node); 2442 handleRedirectingFactoryBody(node);
2408 } else { 2443 } else {
2409 visit(node.expression); 2444 visit(node.expression);
2410 } 2445 }
2411 } 2446 }
2412 2447
2413 void handleRedirectingFactoryBody(Return node) { 2448 void handleRedirectingFactoryBody(Return node) {
2449 final isSymbolConstructor = enclosingElement == compiler.symbolConstructor;
2414 if (!enclosingElement.isFactoryConstructor()) { 2450 if (!enclosingElement.isFactoryConstructor()) {
2415 compiler.reportErrorCode( 2451 compiler.reportErrorCode(
2416 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); 2452 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY);
2417 compiler.reportErrorCode( 2453 compiler.reportErrorCode(
2418 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); 2454 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD);
2419 } 2455 }
2420 Element redirectionTarget = resolveRedirectingFactory(node); 2456 Element redirectionTarget = resolveRedirectingFactory(node);
2421 var type = mapping.getType(node.expression); 2457 var type = mapping.getType(node.expression);
2422 if (type is InterfaceType && !type.isRaw) { 2458 if (type is InterfaceType && !type.isRaw) {
2423 unimplemented(node.expression, 'type arguments on redirecting factory'); 2459 unimplemented(node.expression, 'type arguments on redirecting factory');
(...skipping 14 matching lines...) Expand all
2438 FunctionElement targetImplementation = redirectionTarget.implementation; 2474 FunctionElement targetImplementation = redirectionTarget.implementation;
2439 FunctionExpression function = targetImplementation.parseNode(compiler); 2475 FunctionExpression function = targetImplementation.parseNode(compiler);
2440 if (function.body != null && function.body.asReturn() != null 2476 if (function.body != null && function.body.asReturn() != null
2441 && function.body.asReturn().isRedirectingFactoryBody) { 2477 && function.body.asReturn().isRedirectingFactoryBody) {
2442 unimplemented(node.expression, 'redirecing to redirecting factory'); 2478 unimplemented(node.expression, 'redirecing to redirecting factory');
2443 } 2479 }
2444 } 2480 }
2445 world.registerStaticUse(redirectionTarget); 2481 world.registerStaticUse(redirectionTarget);
2446 world.registerInstantiatedClass( 2482 world.registerInstantiatedClass(
2447 redirectionTarget.enclosingElement.declaration, mapping); 2483 redirectionTarget.enclosingElement.declaration, mapping);
2484 if (isSymbolConstructor) {
2485 // Make sure that collection_dev.Symbol.validated is registered.
2486 // TODO(ahe): Don't simply use head.
ahe 2013/04/18 11:34:44 Will fix before submitting.
2487 world.registerStaticUse(
2488 redirectionTarget.enclosingElement.constructors.head);
2489 }
2448 } 2490 }
2449 2491
2450 visitThrow(Throw node) { 2492 visitThrow(Throw node) {
2451 if (!inCatchBlock && node.expression == null) { 2493 if (!inCatchBlock && node.expression == null) {
2452 error(node, MessageKind.THROW_WITHOUT_EXPRESSION); 2494 error(node, MessageKind.THROW_WITHOUT_EXPRESSION);
2453 } 2495 }
2454 // We don't know ahead of time whether we will need the throw in a statement 2496 // We don't know ahead of time whether we will need the throw in a statement
2455 // context or an expression context, so we register both here, even though 2497 // context or an expression context, so we register both here, even though
2456 // we may not need ThrowExpression. 2498 // we may not need ThrowExpression.
2457 compiler.backend.registerWrapException(mapping); 2499 compiler.backend.registerWrapException(mapping);
(...skipping 25 matching lines...) Expand all
2483 visitParenthesizedExpression(ParenthesizedExpression node) { 2525 visitParenthesizedExpression(ParenthesizedExpression node) {
2484 bool oldSendIsMemberAccess = sendIsMemberAccess; 2526 bool oldSendIsMemberAccess = sendIsMemberAccess;
2485 sendIsMemberAccess = false; 2527 sendIsMemberAccess = false;
2486 visit(node.expression); 2528 visit(node.expression);
2487 sendIsMemberAccess = oldSendIsMemberAccess; 2529 sendIsMemberAccess = oldSendIsMemberAccess;
2488 } 2530 }
2489 2531
2490 visitNewExpression(NewExpression node) { 2532 visitNewExpression(NewExpression node) {
2491 Node selector = node.send.selector; 2533 Node selector = node.send.selector;
2492 FunctionElement constructor = resolveConstructor(node); 2534 FunctionElement constructor = resolveConstructor(node);
2535 final bool isSymbolConstructor = constructor == compiler.symbolConstructor;
2536 if (!node.isConst() && isSymbolConstructor) {
2537 String name = compiler.symbolClass.name.slowToString();
2538 compiler.reportWarningCode(
2539 node.newToken, MessageKind.GENERIC,
ahe 2013/04/18 11:34:44 Will provide real MessageKind before submitting.
2540 {'text': 'Warning: using "new $name" will increase the size of '
2541 'compiled code. Use "const $name" if possible.'});
2542 }
2493 resolveSelector(node.send); 2543 resolveSelector(node.send);
2494 resolveArguments(node.send.argumentsNode); 2544 resolveArguments(node.send.argumentsNode);
2495 useElement(node.send, constructor); 2545 useElement(node.send, constructor);
2496 if (Elements.isUnresolved(constructor)) return constructor; 2546 if (Elements.isUnresolved(constructor)) return constructor;
2497 Selector callSelector = mapping.getSelector(node.send); 2547 Selector callSelector = mapping.getSelector(node.send);
2498 if (!callSelector.applies(constructor, compiler)) { 2548 if (!callSelector.applies(constructor, compiler)) {
2499 warnArgumentMismatch(node.send, constructor); 2549 warnArgumentMismatch(node.send, constructor);
2500 compiler.backend.registerThrowNoSuchMethod(mapping); 2550 compiler.backend.registerThrowNoSuchMethod(mapping);
2501 } 2551 }
2502 compiler.withCurrentElement(constructor, () { 2552 compiler.withCurrentElement(constructor, () {
(...skipping 22 matching lines...) Expand all
2525 compiler.backend.registerAbstractClassInstantiation(mapping); 2575 compiler.backend.registerAbstractClassInstantiation(mapping);
2526 } 2576 }
2527 // [cls] might be the declaration element and we want to include injected 2577 // [cls] might be the declaration element and we want to include injected
2528 // members. 2578 // members.
2529 cls.implementation.forEachInstanceField( 2579 cls.implementation.forEachInstanceField(
2530 (ClassElement enclosingClass, Element member) { 2580 (ClassElement enclosingClass, Element member) {
2531 world.addToWorkList(member); 2581 world.addToWorkList(member);
2532 }, 2582 },
2533 includeBackendMembers: false, 2583 includeBackendMembers: false,
2534 includeSuperMembers: true); 2584 includeSuperMembers: true);
2585
2586 if (node.isConst() && isSymbolConstructor) {
2587 Node argumentNode = node.send.arguments.head;
2588 Constant name = compiler.metadataHandler.compileNodeWithDefinitions(
2589 argumentNode, mapping, isConst: true);
2590 if (!name.isString()) {
2591 compiler.reportErrorCode(argumentNode, MessageKind.GENERIC,
ahe 2013/04/18 11:34:44 Will provide real MessageKind before submitting.
2592 {'text': 'Not a string'});
2593 } else {
2594 validateSymbol(argumentNode, name.toDartString().slowToString());
2595 }
2596 }
2597
2535 return null; 2598 return null;
2536 } 2599 }
2537 2600
2601 void validateSymbol(Node node, String name) {
2602 if (name.isEmpty) return;
2603 if (name.startsWith('_')) {
2604 compiler.reportErrorCode(node, MessageKind.GENERIC,
ahe 2013/04/18 11:34:44 Will provide real MessageKind before submitting.
2605 {'text': '"$name" is a private identifier.'});
2606 return;
2607 }
2608 if (!symbolValidationPattern.hasMatch(name)) {
2609 // TODO(ahe): Better error message.
2610 compiler.reportErrorCode(
2611 node, MessageKind.GENERIC,
ahe 2013/04/18 11:34:44 Will provide real MessageKind before submitting.
2612 {'text':
2613 '"$name" must be a library name, operator name, or identifier.'});
2614 }
2615 }
2616
2617
2538 /** 2618 /**
2539 * Try to resolve the constructor that is referred to by [node]. 2619 * Try to resolve the constructor that is referred to by [node].
2540 * Note: this function may return an ErroneousFunctionElement instead of 2620 * Note: this function may return an ErroneousFunctionElement instead of
2541 * [null], if there is no corresponding constructor, class or library. 2621 * [null], if there is no corresponding constructor, class or library.
2542 */ 2622 */
2543 FunctionElement resolveConstructor(NewExpression node) { 2623 FunctionElement resolveConstructor(NewExpression node) {
2544 return node.accept(new ConstructorResolver(compiler, this)); 2624 return node.accept(new ConstructorResolver(compiler, this));
2545 } 2625 }
2546 2626
2547 FunctionElement resolveRedirectingFactory(Return node) { 2627 FunctionElement resolveRedirectingFactory(Return node) {
(...skipping 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after
3877 return e; 3957 return e;
3878 } 3958 }
3879 3959
3880 /// Assumed to be called by [resolveRedirectingFactory]. 3960 /// Assumed to be called by [resolveRedirectingFactory].
3881 Element visitReturn(Return node) { 3961 Element visitReturn(Return node) {
3882 Node expression = node.expression; 3962 Node expression = node.expression;
3883 return finishConstructorReference(visit(expression), 3963 return finishConstructorReference(visit(expression),
3884 expression, expression); 3964 expression, expression);
3885 } 3965 }
3886 } 3966 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698