| 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 dart2js.js_backend.patch_resolver; | 5 library dart2js.js_backend.patch_resolver; |
| 6 | 6 |
| 7 import '../common/resolution.dart' show | 7 import '../common/resolution.dart' show |
| 8 Resolution; | 8 Resolution; |
| 9 import '../common/tasks.dart' show | 9 import '../common/tasks.dart' show |
| 10 CompilerTask; | 10 CompilerTask; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 class PatchResolverTask extends CompilerTask { | 24 class PatchResolverTask extends CompilerTask { |
| 25 PatchResolverTask(Compiler compiler) : super(compiler); | 25 PatchResolverTask(Compiler compiler) : super(compiler); |
| 26 | 26 |
| 27 Resolution get resolution => compiler.resolution; | 27 Resolution get resolution => compiler.resolution; |
| 28 | 28 |
| 29 String get name => 'JavaScript patch resolver'; | 29 String get name => 'JavaScript patch resolver'; |
| 30 | 30 |
| 31 FunctionElement resolveExternalFunction(FunctionElementX element) { | 31 FunctionElement resolveExternalFunction(FunctionElementX element) { |
| 32 if (element.isPatched) { | 32 if (element.isPatched) { |
| 33 FunctionElementX patch = element.patch; | 33 FunctionElementX patch = element.patch; |
| 34 compiler.withCurrentElement(patch, () { | 34 reporter.withCurrentElement(patch, () { |
| 35 patch.computeType(resolution); | 35 patch.computeType(resolution); |
| 36 }); | 36 }); |
| 37 checkMatchingPatchSignatures(element, patch); | 37 checkMatchingPatchSignatures(element, patch); |
| 38 element = patch; | 38 element = patch; |
| 39 } else { | 39 } else { |
| 40 compiler.reportErrorMessage( | 40 reporter.reportErrorMessage( |
| 41 element, MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION); | 41 element, MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION); |
| 42 } | 42 } |
| 43 return element; | 43 return element; |
| 44 } | 44 } |
| 45 | 45 |
| 46 void checkMatchingPatchParameters(FunctionElement origin, | 46 void checkMatchingPatchParameters(FunctionElement origin, |
| 47 List<Element> originParameters, | 47 List<Element> originParameters, |
| 48 List<Element> patchParameters) { | 48 List<Element> patchParameters) { |
| 49 | 49 |
| 50 assert(originParameters.length == patchParameters.length); | 50 assert(originParameters.length == patchParameters.length); |
| 51 for (int index = 0; index < originParameters.length; index++) { | 51 for (int index = 0; index < originParameters.length; index++) { |
| 52 ParameterElementX originParameter = originParameters[index]; | 52 ParameterElementX originParameter = originParameters[index]; |
| 53 ParameterElementX patchParameter = patchParameters[index]; | 53 ParameterElementX patchParameter = patchParameters[index]; |
| 54 // TODO(johnniwinther): Remove the conditional patching when we never | 54 // TODO(johnniwinther): Remove the conditional patching when we never |
| 55 // resolve the same method twice. | 55 // resolve the same method twice. |
| 56 if (!originParameter.isPatched) { | 56 if (!originParameter.isPatched) { |
| 57 originParameter.applyPatch(patchParameter); | 57 originParameter.applyPatch(patchParameter); |
| 58 } else { | 58 } else { |
| 59 assert(invariant(origin, originParameter.patch == patchParameter, | 59 assert(invariant(origin, originParameter.patch == patchParameter, |
| 60 message: "Inconsistent repatch of $originParameter.")); | 60 message: "Inconsistent repatch of $originParameter.")); |
| 61 } | 61 } |
| 62 DartType originParameterType = originParameter.computeType(resolution); | 62 DartType originParameterType = originParameter.computeType(resolution); |
| 63 DartType patchParameterType = patchParameter.computeType(resolution); | 63 DartType patchParameterType = patchParameter.computeType(resolution); |
| 64 if (originParameterType != patchParameterType) { | 64 if (originParameterType != patchParameterType) { |
| 65 compiler.reportError( | 65 reporter.reportError( |
| 66 compiler.createMessage( | 66 reporter.createMessage( |
| 67 originParameter, | 67 originParameter, |
| 68 MessageKind.PATCH_PARAMETER_TYPE_MISMATCH, | 68 MessageKind.PATCH_PARAMETER_TYPE_MISMATCH, |
| 69 {'methodName': origin.name, | 69 {'methodName': origin.name, |
| 70 'parameterName': originParameter.name, | 70 'parameterName': originParameter.name, |
| 71 'originParameterType': originParameterType, | 71 'originParameterType': originParameterType, |
| 72 'patchParameterType': patchParameterType}), | 72 'patchParameterType': patchParameterType}), |
| 73 <DiagnosticMessage>[ | 73 <DiagnosticMessage>[ |
| 74 compiler.createMessage( | 74 reporter.createMessage( |
| 75 patchParameter, | 75 patchParameter, |
| 76 MessageKind.PATCH_POINT_TO_PARAMETER, | 76 MessageKind.PATCH_POINT_TO_PARAMETER, |
| 77 {'parameterName': patchParameter.name}), | 77 {'parameterName': patchParameter.name}), |
| 78 ]); | 78 ]); |
| 79 } else { | 79 } else { |
| 80 // Hack: Use unparser to test parameter equality. This only works | 80 // Hack: Use unparser to test parameter equality. This only works |
| 81 // because we are restricting patch uses and the approach cannot be used | 81 // because we are restricting patch uses and the approach cannot be used |
| 82 // elsewhere. | 82 // elsewhere. |
| 83 | 83 |
| 84 // The node contains the type, so there is a potential overlap. | 84 // The node contains the type, so there is a potential overlap. |
| 85 // Therefore we only check the text if the types are identical. | 85 // Therefore we only check the text if the types are identical. |
| 86 String originParameterText = originParameter.node.toString(); | 86 String originParameterText = originParameter.node.toString(); |
| 87 String patchParameterText = patchParameter.node.toString(); | 87 String patchParameterText = patchParameter.node.toString(); |
| 88 if (originParameterText != patchParameterText | 88 if (originParameterText != patchParameterText |
| 89 // We special case the list constructor because of the | 89 // We special case the list constructor because of the |
| 90 // optional parameter. | 90 // optional parameter. |
| 91 && origin != compiler.unnamedListConstructor) { | 91 && origin != compiler.unnamedListConstructor) { |
| 92 compiler.reportError( | 92 reporter.reportError( |
| 93 compiler.createMessage( | 93 reporter.createMessage( |
| 94 originParameter, | 94 originParameter, |
| 95 MessageKind.PATCH_PARAMETER_MISMATCH, | 95 MessageKind.PATCH_PARAMETER_MISMATCH, |
| 96 {'methodName': origin.name, | 96 {'methodName': origin.name, |
| 97 'originParameter': originParameterText, | 97 'originParameter': originParameterText, |
| 98 'patchParameter': patchParameterText}), | 98 'patchParameter': patchParameterText}), |
| 99 <DiagnosticMessage>[ | 99 <DiagnosticMessage>[ |
| 100 compiler.createMessage( | 100 reporter.createMessage( |
| 101 patchParameter, | 101 patchParameter, |
| 102 MessageKind.PATCH_POINT_TO_PARAMETER, | 102 MessageKind.PATCH_POINT_TO_PARAMETER, |
| 103 {'parameterName': patchParameter.name}), | 103 {'parameterName': patchParameter.name}), |
| 104 ]); | 104 ]); |
| 105 | 105 |
| 106 } | 106 } |
| 107 } | 107 } |
| 108 } | 108 } |
| 109 } | 109 } |
| 110 | 110 |
| 111 void checkMatchingPatchSignatures(FunctionElement origin, | 111 void checkMatchingPatchSignatures(FunctionElement origin, |
| 112 FunctionElement patch) { | 112 FunctionElement patch) { |
| 113 // TODO(johnniwinther): Show both origin and patch locations on errors. | 113 // TODO(johnniwinther): Show both origin and patch locations on errors. |
| 114 FunctionSignature originSignature = origin.functionSignature; | 114 FunctionSignature originSignature = origin.functionSignature; |
| 115 FunctionExpression patchTree = patch.node; | 115 FunctionExpression patchTree = patch.node; |
| 116 FunctionSignature patchSignature = patch.functionSignature; | 116 FunctionSignature patchSignature = patch.functionSignature; |
| 117 | 117 |
| 118 if (originSignature.type.returnType != patchSignature.type.returnType) { | 118 if (originSignature.type.returnType != patchSignature.type.returnType) { |
| 119 compiler.withCurrentElement(patch, () { | 119 reporter.withCurrentElement(patch, () { |
| 120 Node errorNode = | 120 Node errorNode = |
| 121 patchTree.returnType != null ? patchTree.returnType : patchTree; | 121 patchTree.returnType != null ? patchTree.returnType : patchTree; |
| 122 compiler.reportErrorMessage( | 122 reporter.reportErrorMessage( |
| 123 errorNode, MessageKind.PATCH_RETURN_TYPE_MISMATCH, | 123 errorNode, MessageKind.PATCH_RETURN_TYPE_MISMATCH, |
| 124 {'methodName': origin.name, | 124 {'methodName': origin.name, |
| 125 'originReturnType': originSignature.type.returnType, | 125 'originReturnType': originSignature.type.returnType, |
| 126 'patchReturnType': patchSignature.type.returnType}); | 126 'patchReturnType': patchSignature.type.returnType}); |
| 127 }); | 127 }); |
| 128 } | 128 } |
| 129 if (originSignature.requiredParameterCount != | 129 if (originSignature.requiredParameterCount != |
| 130 patchSignature.requiredParameterCount) { | 130 patchSignature.requiredParameterCount) { |
| 131 compiler.withCurrentElement(patch, () { | 131 reporter.withCurrentElement(patch, () { |
| 132 compiler.reportErrorMessage( | 132 reporter.reportErrorMessage( |
| 133 patchTree, | 133 patchTree, |
| 134 MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH, | 134 MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH, |
| 135 {'methodName': origin.name, | 135 {'methodName': origin.name, |
| 136 'originParameterCount': originSignature.requiredParameterCount, | 136 'originParameterCount': originSignature.requiredParameterCount, |
| 137 'patchParameterCount': patchSignature.requiredParameterCount}); | 137 'patchParameterCount': patchSignature.requiredParameterCount}); |
| 138 }); | 138 }); |
| 139 } else { | 139 } else { |
| 140 checkMatchingPatchParameters(origin, | 140 checkMatchingPatchParameters(origin, |
| 141 originSignature.requiredParameters, | 141 originSignature.requiredParameters, |
| 142 patchSignature.requiredParameters); | 142 patchSignature.requiredParameters); |
| 143 } | 143 } |
| 144 if (originSignature.optionalParameterCount != 0 && | 144 if (originSignature.optionalParameterCount != 0 && |
| 145 patchSignature.optionalParameterCount != 0) { | 145 patchSignature.optionalParameterCount != 0) { |
| 146 if (originSignature.optionalParametersAreNamed != | 146 if (originSignature.optionalParametersAreNamed != |
| 147 patchSignature.optionalParametersAreNamed) { | 147 patchSignature.optionalParametersAreNamed) { |
| 148 compiler.withCurrentElement(patch, () { | 148 reporter.withCurrentElement(patch, () { |
| 149 compiler.reportErrorMessage( | 149 reporter.reportErrorMessage( |
| 150 patchTree, | 150 patchTree, |
| 151 MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH, | 151 MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH, |
| 152 {'methodName': origin.name}); | 152 {'methodName': origin.name}); |
| 153 }); | 153 }); |
| 154 } | 154 } |
| 155 } | 155 } |
| 156 if (originSignature.optionalParameterCount != | 156 if (originSignature.optionalParameterCount != |
| 157 patchSignature.optionalParameterCount) { | 157 patchSignature.optionalParameterCount) { |
| 158 compiler.withCurrentElement(patch, () { | 158 reporter.withCurrentElement(patch, () { |
| 159 compiler.reportErrorMessage( | 159 reporter.reportErrorMessage( |
| 160 patchTree, | 160 patchTree, |
| 161 MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH, | 161 MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH, |
| 162 {'methodName': origin.name, | 162 {'methodName': origin.name, |
| 163 'originParameterCount': originSignature.optionalParameterCount, | 163 'originParameterCount': originSignature.optionalParameterCount, |
| 164 'patchParameterCount': patchSignature.optionalParameterCount}); | 164 'patchParameterCount': patchSignature.optionalParameterCount}); |
| 165 }); | 165 }); |
| 166 } else { | 166 } else { |
| 167 checkMatchingPatchParameters(origin, | 167 checkMatchingPatchParameters(origin, |
| 168 originSignature.optionalParameters, | 168 originSignature.optionalParameters, |
| 169 patchSignature.optionalParameters); | 169 patchSignature.optionalParameters); |
| 170 } | 170 } |
| 171 } | 171 } |
| 172 | 172 |
| 173 } | 173 } |
| OLD | NEW |