OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 engine.resolver; | 5 library engine.resolver; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import 'ast.dart'; | 9 import 'ast.dart'; |
10 import 'constant.dart'; | 10 import 'constant.dart'; |
(...skipping 2413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2424 return null; | 2424 return null; |
2425 } | 2425 } |
2426 | 2426 |
2427 @override | 2427 @override |
2428 Object visitCatchClause(CatchClause node) { | 2428 Object visitCatchClause(CatchClause node) { |
2429 SimpleIdentifier exceptionParameter = node.exceptionParameter; | 2429 SimpleIdentifier exceptionParameter = node.exceptionParameter; |
2430 if (exceptionParameter != null) { | 2430 if (exceptionParameter != null) { |
2431 // exception | 2431 // exception |
2432 LocalVariableElementImpl exception = | 2432 LocalVariableElementImpl exception = |
2433 new LocalVariableElementImpl.forNode(exceptionParameter); | 2433 new LocalVariableElementImpl.forNode(exceptionParameter); |
| 2434 if (node.exceptionType == null) { |
| 2435 exception.hasImplicitType = true; |
| 2436 } |
2434 _currentHolder.addLocalVariable(exception); | 2437 _currentHolder.addLocalVariable(exception); |
2435 exceptionParameter.staticElement = exception; | 2438 exceptionParameter.staticElement = exception; |
2436 // stack trace | 2439 // stack trace |
2437 SimpleIdentifier stackTraceParameter = node.stackTraceParameter; | 2440 SimpleIdentifier stackTraceParameter = node.stackTraceParameter; |
2438 if (stackTraceParameter != null) { | 2441 if (stackTraceParameter != null) { |
2439 LocalVariableElementImpl stackTrace = | 2442 LocalVariableElementImpl stackTrace = |
2440 new LocalVariableElementImpl.forNode(stackTraceParameter); | 2443 new LocalVariableElementImpl.forNode(stackTraceParameter); |
2441 _currentHolder.addLocalVariable(stackTrace); | 2444 _currentHolder.addLocalVariable(stackTrace); |
2442 stackTraceParameter.staticElement = stackTrace; | 2445 stackTraceParameter.staticElement = stackTrace; |
2443 } | 2446 } |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2593 Object visitDeclaredIdentifier(DeclaredIdentifier node) { | 2596 Object visitDeclaredIdentifier(DeclaredIdentifier node) { |
2594 SimpleIdentifier variableName = node.identifier; | 2597 SimpleIdentifier variableName = node.identifier; |
2595 LocalVariableElementImpl element = | 2598 LocalVariableElementImpl element = |
2596 new LocalVariableElementImpl.forNode(variableName); | 2599 new LocalVariableElementImpl.forNode(variableName); |
2597 ForEachStatement statement = node.parent as ForEachStatement; | 2600 ForEachStatement statement = node.parent as ForEachStatement; |
2598 int declarationEnd = node.offset + node.length; | 2601 int declarationEnd = node.offset + node.length; |
2599 int statementEnd = statement.offset + statement.length; | 2602 int statementEnd = statement.offset + statement.length; |
2600 element.setVisibleRange(declarationEnd, statementEnd - declarationEnd - 1); | 2603 element.setVisibleRange(declarationEnd, statementEnd - declarationEnd - 1); |
2601 element.const3 = node.isConst; | 2604 element.const3 = node.isConst; |
2602 element.final2 = node.isFinal; | 2605 element.final2 = node.isFinal; |
| 2606 if (node.type == null) { |
| 2607 element.hasImplicitType = true; |
| 2608 } |
2603 _currentHolder.addLocalVariable(element); | 2609 _currentHolder.addLocalVariable(element); |
2604 variableName.staticElement = element; | 2610 variableName.staticElement = element; |
2605 return super.visitDeclaredIdentifier(node); | 2611 return super.visitDeclaredIdentifier(node); |
2606 } | 2612 } |
2607 | 2613 |
2608 @override | 2614 @override |
2609 Object visitDefaultFormalParameter(DefaultFormalParameter node) { | 2615 Object visitDefaultFormalParameter(DefaultFormalParameter node) { |
2610 ElementHolder holder = new ElementHolder(); | 2616 ElementHolder holder = new ElementHolder(); |
2611 NormalFormalParameter normalParameter = node.parameter; | 2617 NormalFormalParameter normalParameter = node.parameter; |
2612 SimpleIdentifier parameterName = normalParameter.identifier; | 2618 SimpleIdentifier parameterName = normalParameter.identifier; |
(...skipping 20 matching lines...) Expand all Loading... |
2633 initializer.functions = holder.functions; | 2639 initializer.functions = holder.functions; |
2634 initializer.labels = holder.labels; | 2640 initializer.labels = holder.labels; |
2635 initializer.localVariables = holder.localVariables; | 2641 initializer.localVariables = holder.localVariables; |
2636 initializer.parameters = holder.parameters; | 2642 initializer.parameters = holder.parameters; |
2637 initializer.synthetic = true; | 2643 initializer.synthetic = true; |
2638 parameter.initializer = initializer; | 2644 parameter.initializer = initializer; |
2639 parameter.defaultValueCode = defaultValue.toSource(); | 2645 parameter.defaultValueCode = defaultValue.toSource(); |
2640 } | 2646 } |
2641 // visible range | 2647 // visible range |
2642 _setParameterVisibleRange(node, parameter); | 2648 _setParameterVisibleRange(node, parameter); |
| 2649 if (normalParameter is SimpleFormalParameter && |
| 2650 normalParameter.type == null) { |
| 2651 parameter.hasImplicitType = true; |
| 2652 } |
2643 _currentHolder.addParameter(parameter); | 2653 _currentHolder.addParameter(parameter); |
2644 parameterName.staticElement = parameter; | 2654 parameterName.staticElement = parameter; |
2645 normalParameter.accept(this); | 2655 normalParameter.accept(this); |
2646 holder.validate(); | 2656 holder.validate(); |
2647 return null; | 2657 return null; |
2648 } | 2658 } |
2649 | 2659 |
2650 @override | 2660 @override |
2651 Object visitEnumDeclaration(EnumDeclaration node) { | 2661 Object visitEnumDeclaration(EnumDeclaration node) { |
2652 SimpleIdentifier enumName = node.name; | 2662 SimpleIdentifier enumName = node.name; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2739 element.generator = true; | 2749 element.generator = true; |
2740 } | 2750 } |
2741 if (_inFunction) { | 2751 if (_inFunction) { |
2742 Block enclosingBlock = node.getAncestor((node) => node is Block); | 2752 Block enclosingBlock = node.getAncestor((node) => node is Block); |
2743 if (enclosingBlock != null) { | 2753 if (enclosingBlock != null) { |
2744 int functionEnd = node.offset + node.length; | 2754 int functionEnd = node.offset + node.length; |
2745 int blockEnd = enclosingBlock.offset + enclosingBlock.length; | 2755 int blockEnd = enclosingBlock.offset + enclosingBlock.length; |
2746 element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1); | 2756 element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1); |
2747 } | 2757 } |
2748 } | 2758 } |
| 2759 if (node.returnType == null) { |
| 2760 element.hasImplicitReturnType = true; |
| 2761 } |
2749 _currentHolder.addFunction(element); | 2762 _currentHolder.addFunction(element); |
2750 expression.element = element; | 2763 expression.element = element; |
2751 functionName.staticElement = element; | 2764 functionName.staticElement = element; |
2752 } else { | 2765 } else { |
2753 SimpleIdentifier propertyNameNode = node.name; | 2766 SimpleIdentifier propertyNameNode = node.name; |
2754 if (propertyNameNode == null) { | 2767 if (propertyNameNode == null) { |
2755 // TODO(brianwilkerson) Report this internal error. | 2768 // TODO(brianwilkerson) Report this internal error. |
2756 return null; | 2769 return null; |
2757 } | 2770 } |
2758 String propertyName = propertyNameNode.name; | 2771 String propertyName = propertyNameNode.name; |
(...skipping 17 matching lines...) Expand all Loading... |
2776 if (body.isAsynchronous) { | 2789 if (body.isAsynchronous) { |
2777 getter.asynchronous = true; | 2790 getter.asynchronous = true; |
2778 } | 2791 } |
2779 if (body.isGenerator) { | 2792 if (body.isGenerator) { |
2780 getter.generator = true; | 2793 getter.generator = true; |
2781 } | 2794 } |
2782 getter.variable = variable; | 2795 getter.variable = variable; |
2783 getter.getter = true; | 2796 getter.getter = true; |
2784 getter.static = true; | 2797 getter.static = true; |
2785 variable.getter = getter; | 2798 variable.getter = getter; |
| 2799 if (node.returnType == null) { |
| 2800 getter.hasImplicitReturnType = true; |
| 2801 } |
2786 _currentHolder.addAccessor(getter); | 2802 _currentHolder.addAccessor(getter); |
2787 expression.element = getter; | 2803 expression.element = getter; |
2788 propertyNameNode.staticElement = getter; | 2804 propertyNameNode.staticElement = getter; |
2789 } else { | 2805 } else { |
2790 PropertyAccessorElementImpl setter = | 2806 PropertyAccessorElementImpl setter = |
2791 new PropertyAccessorElementImpl.forNode(propertyNameNode); | 2807 new PropertyAccessorElementImpl.forNode(propertyNameNode); |
2792 if (node.externalKeyword != null) { | 2808 if (node.externalKeyword != null) { |
2793 setter.external = true; | 2809 setter.external = true; |
2794 } | 2810 } |
2795 setter.functions = holder.functions; | 2811 setter.functions = holder.functions; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2852 int functionEnd = node.offset + node.length; | 2868 int functionEnd = node.offset + node.length; |
2853 int blockEnd = enclosingBlock.offset + enclosingBlock.length; | 2869 int blockEnd = enclosingBlock.offset + enclosingBlock.length; |
2854 element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1); | 2870 element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1); |
2855 } | 2871 } |
2856 } | 2872 } |
2857 FunctionTypeImpl type = new FunctionTypeImpl(element); | 2873 FunctionTypeImpl type = new FunctionTypeImpl(element); |
2858 if (_functionTypesToFix != null) { | 2874 if (_functionTypesToFix != null) { |
2859 _functionTypesToFix.add(type); | 2875 _functionTypesToFix.add(type); |
2860 } | 2876 } |
2861 element.type = type; | 2877 element.type = type; |
| 2878 element.hasImplicitReturnType = true; |
2862 _currentHolder.addFunction(element); | 2879 _currentHolder.addFunction(element); |
2863 node.element = element; | 2880 node.element = element; |
2864 holder.validate(); | 2881 holder.validate(); |
2865 return null; | 2882 return null; |
2866 } | 2883 } |
2867 | 2884 |
2868 @override | 2885 @override |
2869 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | 2886 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
2870 ElementHolder holder = new ElementHolder(); | 2887 ElementHolder holder = new ElementHolder(); |
2871 _visitChildren(holder, node); | 2888 _visitChildren(holder, node); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2954 element.localVariables = holder.localVariables; | 2971 element.localVariables = holder.localVariables; |
2955 element.parameters = holder.parameters; | 2972 element.parameters = holder.parameters; |
2956 element.static = isStatic; | 2973 element.static = isStatic; |
2957 element.typeParameters = holder.typeParameters; | 2974 element.typeParameters = holder.typeParameters; |
2958 if (body.isAsynchronous) { | 2975 if (body.isAsynchronous) { |
2959 element.asynchronous = true; | 2976 element.asynchronous = true; |
2960 } | 2977 } |
2961 if (body.isGenerator) { | 2978 if (body.isGenerator) { |
2962 element.generator = true; | 2979 element.generator = true; |
2963 } | 2980 } |
| 2981 if (node.returnType == null) { |
| 2982 element.hasImplicitReturnType = true; |
| 2983 } |
2964 _currentHolder.addMethod(element); | 2984 _currentHolder.addMethod(element); |
2965 methodName.staticElement = element; | 2985 methodName.staticElement = element; |
2966 } else { | 2986 } else { |
2967 SimpleIdentifier propertyNameNode = node.name; | 2987 SimpleIdentifier propertyNameNode = node.name; |
2968 String propertyName = propertyNameNode.name; | 2988 String propertyName = propertyNameNode.name; |
2969 FieldElementImpl field = | 2989 FieldElementImpl field = |
2970 _currentHolder.getField(propertyName) as FieldElementImpl; | 2990 _currentHolder.getField(propertyName) as FieldElementImpl; |
2971 if (field == null) { | 2991 if (field == null) { |
2972 field = new FieldElementImpl(node.name.name, -1); | 2992 field = new FieldElementImpl(node.name.name, -1); |
2973 field.final2 = true; | 2993 field.final2 = true; |
(...skipping 14 matching lines...) Expand all Loading... |
2988 getter.asynchronous = true; | 3008 getter.asynchronous = true; |
2989 } | 3009 } |
2990 if (body.isGenerator) { | 3010 if (body.isGenerator) { |
2991 getter.generator = true; | 3011 getter.generator = true; |
2992 } | 3012 } |
2993 getter.variable = field; | 3013 getter.variable = field; |
2994 getter.abstract = node.isAbstract; | 3014 getter.abstract = node.isAbstract; |
2995 getter.getter = true; | 3015 getter.getter = true; |
2996 getter.static = isStatic; | 3016 getter.static = isStatic; |
2997 field.getter = getter; | 3017 field.getter = getter; |
| 3018 if (node.returnType == null) { |
| 3019 getter.hasImplicitReturnType = true; |
| 3020 } |
2998 _currentHolder.addAccessor(getter); | 3021 _currentHolder.addAccessor(getter); |
2999 propertyNameNode.staticElement = getter; | 3022 propertyNameNode.staticElement = getter; |
3000 } else { | 3023 } else { |
3001 PropertyAccessorElementImpl setter = | 3024 PropertyAccessorElementImpl setter = |
3002 new PropertyAccessorElementImpl.forNode(propertyNameNode); | 3025 new PropertyAccessorElementImpl.forNode(propertyNameNode); |
3003 if (node.externalKeyword != null) { | 3026 if (node.externalKeyword != null) { |
3004 setter.external = true; | 3027 setter.external = true; |
3005 } | 3028 } |
3006 setter.functions = holder.functions; | 3029 setter.functions = holder.functions; |
3007 setter.labels = holder.labels; | 3030 setter.labels = holder.labels; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3064 @override | 3087 @override |
3065 Object visitSimpleFormalParameter(SimpleFormalParameter node) { | 3088 Object visitSimpleFormalParameter(SimpleFormalParameter node) { |
3066 if (node.parent is! DefaultFormalParameter) { | 3089 if (node.parent is! DefaultFormalParameter) { |
3067 SimpleIdentifier parameterName = node.identifier; | 3090 SimpleIdentifier parameterName = node.identifier; |
3068 ParameterElementImpl parameter = | 3091 ParameterElementImpl parameter = |
3069 new ParameterElementImpl.forNode(parameterName); | 3092 new ParameterElementImpl.forNode(parameterName); |
3070 parameter.const3 = node.isConst; | 3093 parameter.const3 = node.isConst; |
3071 parameter.final2 = node.isFinal; | 3094 parameter.final2 = node.isFinal; |
3072 parameter.parameterKind = node.kind; | 3095 parameter.parameterKind = node.kind; |
3073 _setParameterVisibleRange(node, parameter); | 3096 _setParameterVisibleRange(node, parameter); |
| 3097 if (node.type == null) { |
| 3098 parameter.hasImplicitType = true; |
| 3099 } |
3074 _currentHolder.addParameter(parameter); | 3100 _currentHolder.addParameter(parameter); |
3075 parameterName.staticElement = parameter; | 3101 parameterName.staticElement = parameter; |
3076 } | 3102 } |
3077 return super.visitSimpleFormalParameter(node); | 3103 return super.visitSimpleFormalParameter(node); |
3078 } | 3104 } |
3079 | 3105 |
3080 @override | 3106 @override |
3081 Object visitSuperExpression(SuperExpression node) { | 3107 Object visitSuperExpression(SuperExpression node) { |
3082 _isValidMixin = false; | 3108 _isValidMixin = false; |
3083 return super.visitSuperExpression(node); | 3109 return super.visitSuperExpression(node); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3126 VariableElementImpl element; | 3152 VariableElementImpl element; |
3127 if (_inFieldContext) { | 3153 if (_inFieldContext) { |
3128 SimpleIdentifier fieldName = node.name; | 3154 SimpleIdentifier fieldName = node.name; |
3129 FieldElementImpl field; | 3155 FieldElementImpl field; |
3130 if ((isConst || isFinal) && hasInitializer) { | 3156 if ((isConst || isFinal) && hasInitializer) { |
3131 field = new ConstFieldElementImpl.forNode(fieldName); | 3157 field = new ConstFieldElementImpl.forNode(fieldName); |
3132 } else { | 3158 } else { |
3133 field = new FieldElementImpl.forNode(fieldName); | 3159 field = new FieldElementImpl.forNode(fieldName); |
3134 } | 3160 } |
3135 element = field; | 3161 element = field; |
| 3162 if ((node.parent as VariableDeclarationList).type == null) { |
| 3163 field.hasImplicitType = true; |
| 3164 } |
3136 _currentHolder.addField(field); | 3165 _currentHolder.addField(field); |
3137 fieldName.staticElement = field; | 3166 fieldName.staticElement = field; |
3138 } else if (_inFunction) { | 3167 } else if (_inFunction) { |
3139 SimpleIdentifier variableName = node.name; | 3168 SimpleIdentifier variableName = node.name; |
3140 LocalVariableElementImpl variable; | 3169 LocalVariableElementImpl variable; |
3141 if (isConst && hasInitializer) { | 3170 if (isConst && hasInitializer) { |
3142 variable = new ConstLocalVariableElementImpl.forNode(variableName); | 3171 variable = new ConstLocalVariableElementImpl.forNode(variableName); |
3143 } else { | 3172 } else { |
3144 variable = new LocalVariableElementImpl.forNode(variableName); | 3173 variable = new LocalVariableElementImpl.forNode(variableName); |
3145 } | 3174 } |
3146 element = variable; | 3175 element = variable; |
3147 Block enclosingBlock = node.getAncestor((node) => node is Block); | 3176 Block enclosingBlock = node.getAncestor((node) => node is Block); |
3148 // TODO(brianwilkerson) This isn't right for variables declared in a for | 3177 // TODO(brianwilkerson) This isn't right for variables declared in a for |
3149 // loop. | 3178 // loop. |
3150 variable.setVisibleRange(enclosingBlock.offset, enclosingBlock.length); | 3179 variable.setVisibleRange(enclosingBlock.offset, enclosingBlock.length); |
| 3180 if ((node.parent as VariableDeclarationList).type == null) { |
| 3181 variable.hasImplicitType = true; |
| 3182 } |
3151 _currentHolder.addLocalVariable(variable); | 3183 _currentHolder.addLocalVariable(variable); |
3152 variableName.staticElement = element; | 3184 variableName.staticElement = element; |
3153 } else { | 3185 } else { |
3154 SimpleIdentifier variableName = node.name; | 3186 SimpleIdentifier variableName = node.name; |
3155 TopLevelVariableElementImpl variable; | 3187 TopLevelVariableElementImpl variable; |
3156 if (isConst && hasInitializer) { | 3188 if (isConst && hasInitializer) { |
3157 variable = new ConstTopLevelVariableElementImpl(variableName); | 3189 variable = new ConstTopLevelVariableElementImpl(variableName); |
3158 } else { | 3190 } else { |
3159 variable = new TopLevelVariableElementImpl.forNode(variableName); | 3191 variable = new TopLevelVariableElementImpl.forNode(variableName); |
3160 } | 3192 } |
3161 element = variable; | 3193 element = variable; |
| 3194 if ((node.parent as VariableDeclarationList).type == null) { |
| 3195 variable.hasImplicitType = true; |
| 3196 } |
3162 _currentHolder.addTopLevelVariable(variable); | 3197 _currentHolder.addTopLevelVariable(variable); |
3163 variableName.staticElement = element; | 3198 variableName.staticElement = element; |
3164 } | 3199 } |
3165 element.const3 = isConst; | 3200 element.const3 = isConst; |
3166 element.final2 = isFinal; | 3201 element.final2 = isFinal; |
3167 if (hasInitializer) { | 3202 if (hasInitializer) { |
3168 ElementHolder holder = new ElementHolder(); | 3203 ElementHolder holder = new ElementHolder(); |
3169 bool wasInFieldContext = _inFieldContext; | 3204 bool wasInFieldContext = _inFieldContext; |
3170 _inFieldContext = false; | 3205 _inFieldContext = false; |
3171 try { | 3206 try { |
(...skipping 11 matching lines...) Expand all Loading... |
3183 holder.validate(); | 3218 holder.validate(); |
3184 } | 3219 } |
3185 if (element is PropertyInducingElementImpl) { | 3220 if (element is PropertyInducingElementImpl) { |
3186 if (_inFieldContext) { | 3221 if (_inFieldContext) { |
3187 (element as FieldElementImpl).static = | 3222 (element as FieldElementImpl).static = |
3188 (node.parent.parent as FieldDeclaration).isStatic; | 3223 (node.parent.parent as FieldDeclaration).isStatic; |
3189 } | 3224 } |
3190 PropertyAccessorElementImpl getter = | 3225 PropertyAccessorElementImpl getter = |
3191 new PropertyAccessorElementImpl.forVariable(element); | 3226 new PropertyAccessorElementImpl.forVariable(element); |
3192 getter.getter = true; | 3227 getter.getter = true; |
| 3228 if (element.hasImplicitType) { |
| 3229 getter.hasImplicitReturnType = true; |
| 3230 } |
3193 _currentHolder.addAccessor(getter); | 3231 _currentHolder.addAccessor(getter); |
3194 element.getter = getter; | 3232 element.getter = getter; |
3195 if (!isConst && !isFinal) { | 3233 if (!isConst && !isFinal) { |
3196 PropertyAccessorElementImpl setter = | 3234 PropertyAccessorElementImpl setter = |
3197 new PropertyAccessorElementImpl.forVariable(element); | 3235 new PropertyAccessorElementImpl.forVariable(element); |
3198 setter.setter = true; | 3236 setter.setter = true; |
3199 ParameterElementImpl parameter = | 3237 ParameterElementImpl parameter = |
3200 new ParameterElementImpl("_${element.name}", element.nameOffset); | 3238 new ParameterElementImpl("_${element.name}", element.nameOffset); |
3201 parameter.synthetic = true; | 3239 parameter.synthetic = true; |
3202 parameter.parameterKind = ParameterKind.REQUIRED; | 3240 parameter.parameterKind = ParameterKind.REQUIRED; |
(...skipping 12082 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15285 nonFields.add(node); | 15323 nonFields.add(node); |
15286 return null; | 15324 return null; |
15287 } | 15325 } |
15288 | 15326 |
15289 @override | 15327 @override |
15290 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); | 15328 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); |
15291 | 15329 |
15292 @override | 15330 @override |
15293 Object visitWithClause(WithClause node) => null; | 15331 Object visitWithClause(WithClause node) => null; |
15294 } | 15332 } |
OLD | NEW |