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 |