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

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: Address review comments 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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 690
690 // If the name could not be deconstructed, this is is from a 691 // If the name could not be deconstructed, this is is from a
691 // factory method from a deprecated interface implementation. 692 // factory method from a deprecated interface implementation.
692 if (name == null) return; 693 if (name == null) return;
693 694
694 Element otherMember = holder.lookupLocalMember(name); 695 Element otherMember = holder.lookupLocalMember(name);
695 if (otherMember != null) { 696 if (otherMember != null) {
696 if (compiler.onDeprecatedFeature(member, 'conflicting constructor')) { 697 if (compiler.onDeprecatedFeature(member, 'conflicting constructor')) {
697 compiler.reportMessage( 698 compiler.reportMessage(
698 compiler.spanFromElement(otherMember), 699 compiler.spanFromElement(otherMember),
700 // Using GENERIC as this message is temporary.
699 MessageKind.GENERIC.error({'text': 'This member conflicts with a' 701 MessageKind.GENERIC.error({'text': 'This member conflicts with a'
700 ' constructor.'}), 702 ' constructor.'}),
701 Diagnostic.INFO); 703 Diagnostic.INFO);
702 } 704 }
703 } 705 }
704 } 706 }
705 707
706 void checkAbstractField(Element member) { 708 void checkAbstractField(Element member) {
707 // Only check for getters. The test can only fail if there is both a setter 709 // Only check for getters. The test can only fail if there is both a setter
708 // and a getter with the same name, and we only need to check each abstract 710 // and a getter with the same name, and we only need to check each abstract
(...skipping 903 matching lines...) Expand 10 before | Expand all | Expand 10 after
1612 bool inCatchBlock; 1614 bool inCatchBlock;
1613 Scope scope; 1615 Scope scope;
1614 ClassElement currentClass; 1616 ClassElement currentClass;
1615 ExpressionStatement currentExpressionStatement; 1617 ExpressionStatement currentExpressionStatement;
1616 bool typeRequired = false; 1618 bool typeRequired = false;
1617 bool sendIsMemberAccess = false; 1619 bool sendIsMemberAccess = false;
1618 StatementScope statementScope; 1620 StatementScope statementScope;
1619 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION 1621 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION
1620 | ElementCategory.IMPLIES_TYPE; 1622 | ElementCategory.IMPLIES_TYPE;
1621 1623
1624 // TODO(ahe): Find a way to share this with runtime implementation.
1625 static final RegExp symbolValidationPattern =
1626 new RegExp(r'^(?:[a-zA-Z$][a-zA-Z$0-9_]*\.)*(?:[a-zA-Z$][a-zA-Z$0-9_]*=?|'
1627 r'-|'
1628 r'unary-|'
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 r')$');
1648
1622 ResolverVisitor(Compiler compiler, Element element, this.mapping) 1649 ResolverVisitor(Compiler compiler, Element element, this.mapping)
1623 : this.enclosingElement = element, 1650 : this.enclosingElement = element,
1624 // When the element is a field, we are actually resolving its 1651 // When the element is a field, we are actually resolving its
1625 // initial value, which should not have access to instance 1652 // initial value, which should not have access to instance
1626 // fields. 1653 // fields.
1627 inInstanceContext = (element.isInstanceMember() && !element.isField()) 1654 inInstanceContext = (element.isInstanceMember() && !element.isField())
1628 || element.isGenerativeConstructor(), 1655 || element.isGenerativeConstructor(),
1629 this.currentClass = element.isMember() ? element.getEnclosingClass() 1656 this.currentClass = element.isMember() ? element.getEnclosingClass()
1630 : null, 1657 : null,
1631 this.statementScope = new StatementScope(), 1658 this.statementScope = new StatementScope(),
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
1975 } 2002 }
1976 2003
1977 var oldCategory = allowedCategory; 2004 var oldCategory = allowedCategory;
1978 allowedCategory |= ElementCategory.PREFIX | ElementCategory.SUPER; 2005 allowedCategory |= ElementCategory.PREFIX | ElementCategory.SUPER;
1979 Element resolvedReceiver = visit(node.receiver); 2006 Element resolvedReceiver = visit(node.receiver);
1980 allowedCategory = oldCategory; 2007 allowedCategory = oldCategory;
1981 2008
1982 Element target; 2009 Element target;
1983 SourceString name = node.selector.asIdentifier().source; 2010 SourceString name = node.selector.asIdentifier().source;
1984 if (identical(name.stringValue, 'this')) { 2011 if (identical(name.stringValue, 'this')) {
2012 // TODO(ahe): Why is this using GENERIC?
1985 error(node.selector, MessageKind.GENERIC, 2013 error(node.selector, MessageKind.GENERIC,
1986 {'text': "expected an identifier"}); 2014 {'text': "expected an identifier"});
1987 } else if (node.isSuperCall) { 2015 } else if (node.isSuperCall) {
1988 if (node.isOperator) { 2016 if (node.isOperator) {
1989 if (isUserDefinableOperator(name.stringValue)) { 2017 if (isUserDefinableOperator(name.stringValue)) {
1990 name = selector.name; 2018 name = selector.name;
1991 } else { 2019 } else {
1992 error(node.selector, MessageKind.ILLEGAL_SUPER_SEND, {'name': name}); 2020 error(node.selector, MessageKind.ILLEGAL_SUPER_SEND, {'name': name});
1993 } 2021 }
1994 } 2022 }
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
2155 } 2183 }
2156 } 2184 }
2157 } 2185 }
2158 2186
2159 visitSend(Send node) { 2187 visitSend(Send node) {
2160 bool oldSendIsMemberAccess = sendIsMemberAccess; 2188 bool oldSendIsMemberAccess = sendIsMemberAccess;
2161 sendIsMemberAccess = node.isPropertyAccess || node.isCall; 2189 sendIsMemberAccess = node.isPropertyAccess || node.isCall;
2162 Element target = resolveSend(node); 2190 Element target = resolveSend(node);
2163 sendIsMemberAccess = oldSendIsMemberAccess; 2191 sendIsMemberAccess = oldSendIsMemberAccess;
2164 2192
2193 if (target != null && target == compiler.mirrorSystemGetNameFunction) {
2194 compiler.reportWarningCode(
2195 node.selector, MessageKind.STATIC_FUNCTION_BLOAT,
2196 {'class': compiler.mirrorSystemClass.name,
2197 'name': compiler.mirrorSystemGetNameFunction.name});
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 assert(invariant(node, compiler.symbolValidatedConstructor != null));
2487 world.registerStaticUse(compiler.symbolValidatedConstructor);
2488 }
2448 } 2489 }
2449 2490
2450 visitThrow(Throw node) { 2491 visitThrow(Throw node) {
2451 if (!inCatchBlock && node.expression == null) { 2492 if (!inCatchBlock && node.expression == null) {
2452 error(node, MessageKind.THROW_WITHOUT_EXPRESSION); 2493 error(node, MessageKind.THROW_WITHOUT_EXPRESSION);
2453 } 2494 }
2454 // We don't know ahead of time whether we will need the throw in a statement 2495 // 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 2496 // context or an expression context, so we register both here, even though
2456 // we may not need ThrowExpression. 2497 // we may not need ThrowExpression.
2457 compiler.backend.registerWrapException(mapping); 2498 compiler.backend.registerWrapException(mapping);
(...skipping 25 matching lines...) Expand all
2483 visitParenthesizedExpression(ParenthesizedExpression node) { 2524 visitParenthesizedExpression(ParenthesizedExpression node) {
2484 bool oldSendIsMemberAccess = sendIsMemberAccess; 2525 bool oldSendIsMemberAccess = sendIsMemberAccess;
2485 sendIsMemberAccess = false; 2526 sendIsMemberAccess = false;
2486 visit(node.expression); 2527 visit(node.expression);
2487 sendIsMemberAccess = oldSendIsMemberAccess; 2528 sendIsMemberAccess = oldSendIsMemberAccess;
2488 } 2529 }
2489 2530
2490 visitNewExpression(NewExpression node) { 2531 visitNewExpression(NewExpression node) {
2491 Node selector = node.send.selector; 2532 Node selector = node.send.selector;
2492 FunctionElement constructor = resolveConstructor(node); 2533 FunctionElement constructor = resolveConstructor(node);
2534 final bool isSymbolConstructor = constructor == compiler.symbolConstructor;
2535 if (!node.isConst() && isSymbolConstructor) {
2536 compiler.reportWarningCode(
2537 node.newToken, MessageKind.NON_CONST_BLOAT,
2538 {'name': compiler.symbolClass.name});
2539 }
2493 resolveSelector(node.send); 2540 resolveSelector(node.send);
2494 resolveArguments(node.send.argumentsNode); 2541 resolveArguments(node.send.argumentsNode);
2495 useElement(node.send, constructor); 2542 useElement(node.send, constructor);
2496 if (Elements.isUnresolved(constructor)) return constructor; 2543 if (Elements.isUnresolved(constructor)) return constructor;
2497 Selector callSelector = mapping.getSelector(node.send); 2544 Selector callSelector = mapping.getSelector(node.send);
2498 if (!callSelector.applies(constructor, compiler)) { 2545 if (!callSelector.applies(constructor, compiler)) {
2499 warnArgumentMismatch(node.send, constructor); 2546 warnArgumentMismatch(node.send, constructor);
2500 compiler.backend.registerThrowNoSuchMethod(mapping); 2547 compiler.backend.registerThrowNoSuchMethod(mapping);
2501 } 2548 }
2502 compiler.withCurrentElement(constructor, () { 2549 compiler.withCurrentElement(constructor, () {
(...skipping 22 matching lines...) Expand all
2525 compiler.backend.registerAbstractClassInstantiation(mapping); 2572 compiler.backend.registerAbstractClassInstantiation(mapping);
2526 } 2573 }
2527 // [cls] might be the declaration element and we want to include injected 2574 // [cls] might be the declaration element and we want to include injected
2528 // members. 2575 // members.
2529 cls.implementation.forEachInstanceField( 2576 cls.implementation.forEachInstanceField(
2530 (ClassElement enclosingClass, Element member) { 2577 (ClassElement enclosingClass, Element member) {
2531 world.addToWorkList(member); 2578 world.addToWorkList(member);
2532 }, 2579 },
2533 includeBackendMembers: false, 2580 includeBackendMembers: false,
2534 includeSuperMembers: true); 2581 includeSuperMembers: true);
2582
2583 if (node.isConst() && isSymbolConstructor) {
2584 Node argumentNode = node.send.arguments.head;
2585 Constant name = compiler.metadataHandler.compileNodeWithDefinitions(
2586 argumentNode, mapping, isConst: true);
2587 if (!name.isString()) {
2588 DartType type = name.computeType(compiler);
2589 compiler.reportErrorCode(argumentNode, MessageKind.STRING_EXPECTED,
2590 {'type': type});
2591 } else {
2592 validateSymbol(argumentNode, name.toDartString().slowToString());
2593 }
2594 }
2595
2535 return null; 2596 return null;
2536 } 2597 }
2537 2598
2599 void validateSymbol(Node node, String name) {
2600 if (name.isEmpty) return;
2601 if (name.startsWith('_')) {
2602 compiler.reportErrorCode(node, MessageKind.PRIVATE_IDENTIFIER,
2603 {'value': name});
2604 return;
2605 }
2606 if (!symbolValidationPattern.hasMatch(name)) {
2607 compiler.reportErrorCode(node, MessageKind.INVALID_SYMBOL,
2608 {'value': name});
2609 }
2610 }
2611
2612
2538 /** 2613 /**
2539 * Try to resolve the constructor that is referred to by [node]. 2614 * Try to resolve the constructor that is referred to by [node].
2540 * Note: this function may return an ErroneousFunctionElement instead of 2615 * Note: this function may return an ErroneousFunctionElement instead of
2541 * [null], if there is no corresponding constructor, class or library. 2616 * [null], if there is no corresponding constructor, class or library.
2542 */ 2617 */
2543 FunctionElement resolveConstructor(NewExpression node) { 2618 FunctionElement resolveConstructor(NewExpression node) {
2544 return node.accept(new ConstructorResolver(compiler, this)); 2619 return node.accept(new ConstructorResolver(compiler, this));
2545 } 2620 }
2546 2621
2547 FunctionElement resolveRedirectingFactory(Return node) { 2622 FunctionElement resolveRedirectingFactory(Return node) {
(...skipping 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after
3877 return e; 3952 return e;
3878 } 3953 }
3879 3954
3880 /// Assumed to be called by [resolveRedirectingFactory]. 3955 /// Assumed to be called by [resolveRedirectingFactory].
3881 Element visitReturn(Return node) { 3956 Element visitReturn(Return node) {
3882 Node expression = node.expression; 3957 Node expression = node.expression;
3883 return finishConstructorReference(visit(expression), 3958 return finishConstructorReference(visit(expression),
3884 expression, expression); 3959 expression, expression);
3885 } 3960 }
3886 } 3961 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698