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

Side by Side Diff: pkg/analyzer/lib/src/task/dart.dart

Issue 1029953002: Task: BuildClassConstructorsTask. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 9 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
« no previous file with comments | « pkg/analyzer/lib/src/generated/element.dart ('k') | pkg/analyzer/test/src/task/dart_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 analyzer.src.task.dart; 5 library analyzer.src.task.dart;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 import 'dart:math' as math;
8 9
9 import 'package:analyzer/src/generated/ast.dart'; 10 import 'package:analyzer/src/generated/ast.dart';
10 import 'package:analyzer/src/generated/element.dart'; 11 import 'package:analyzer/src/generated/element.dart';
11 import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask; 12 import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
12 import 'package:analyzer/src/generated/error.dart'; 13 import 'package:analyzer/src/generated/error.dart';
13 import 'package:analyzer/src/generated/java_engine.dart'; 14 import 'package:analyzer/src/generated/java_engine.dart';
14 import 'package:analyzer/src/generated/parser.dart'; 15 import 'package:analyzer/src/generated/parser.dart';
15 import 'package:analyzer/src/generated/resolver.dart'; 16 import 'package:analyzer/src/generated/resolver.dart';
16 import 'package:analyzer/src/generated/scanner.dart'; 17 import 'package:analyzer/src/generated/scanner.dart';
17 import 'package:analyzer/src/generated/sdk.dart'; 18 import 'package:analyzer/src/generated/sdk.dart';
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 'BUILD_LIBRARY_ERRORS', AnalysisError.NO_ERRORS, 61 'BUILD_LIBRARY_ERRORS', AnalysisError.NO_ERRORS,
61 contributesTo: DART_ERRORS); 62 contributesTo: DART_ERRORS);
62 63
63 /** 64 /**
64 * The [ClassElement]s of a [LibraryUnitTarget]. 65 * The [ClassElement]s of a [LibraryUnitTarget].
65 */ 66 */
66 final ResultDescriptor<List<ClassElement>> CLASS_ELEMENTS = 67 final ResultDescriptor<List<ClassElement>> CLASS_ELEMENTS =
67 new ResultDescriptor<List<ClassElement>>('CLASS_ELEMENTS', null); 68 new ResultDescriptor<List<ClassElement>>('CLASS_ELEMENTS', null);
68 69
69 /** 70 /**
71 * The [ConstructorElement]s of a [ClassElement].
72 */
73 final ResultDescriptor<List<ConstructorElement>> CONSTRUCTORS =
74 new ResultDescriptor<List<ConstructorElement>>('CONSTRUCTORS', null);
75
76 /**
77 * The errors produced while building a [ClassElement] constructors.
78 *
79 * The list will be empty if there were no errors, but will not be `null`.
80 *
81 * The result is only available for targets representing a [ClassElement].
82 */
83 final ResultDescriptor<List<AnalysisError>> CONSTRUCTORS_ERRORS =
84 new ResultDescriptor<List<AnalysisError>>(
85 'CONSTRUCTORS_ERRORS', AnalysisError.NO_ERRORS);
86
87 /**
70 * The sources representing the export closure of a library. 88 * The sources representing the export closure of a library.
71 * 89 *
72 * The result is only available for targets representing a Dart library. 90 * The result is only available for targets representing a Dart library.
73 */ 91 */
74 final ResultDescriptor<List<Source>> EXPORT_SOURCE_CLOSURE = 92 final ResultDescriptor<List<Source>> EXPORT_SOURCE_CLOSURE =
75 new ResultDescriptor<List<Source>>('EXPORT_SOURCE_CLOSURE', null); 93 new ResultDescriptor<List<Source>>('EXPORT_SOURCE_CLOSURE', null);
76 94
77 /** 95 /**
78 * The partial [LibraryElement] associated with a library. 96 * The partial [LibraryElement] associated with a library.
79 * 97 *
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 final ResultDescriptor<CompilationUnit> RESOLVED_UNIT4 = 200 final ResultDescriptor<CompilationUnit> RESOLVED_UNIT4 =
183 new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT4', null); 201 new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT4', null);
184 202
185 /** 203 /**
186 * The [TypeProvider] of the context. 204 * The [TypeProvider] of the context.
187 */ 205 */
188 final ResultDescriptor<TypeProvider> TYPE_PROVIDER = 206 final ResultDescriptor<TypeProvider> TYPE_PROVIDER =
189 new ResultDescriptor<TypeProvider>('TYPE_PROVIDER', null); 207 new ResultDescriptor<TypeProvider>('TYPE_PROVIDER', null);
190 208
191 /** 209 /**
210 * A task that builds implicit constructors for a [ClassElement], or keeps
211 * the existing explicit constructors if the class has them.
212 */
213 class BuildClassConstructorsTask extends SourceBasedAnalysisTask {
214 /**
215 * The name of the [CONSTRUCTORS] input for the superclass.
216 */
217 static const String SUPER_CONSTRUCTORS = 'SUPER_CONSTRUCTORS';
218
219 /**
220 * The task descriptor describing this kind of task.
221 */
222 static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
223 'BuildConstructorsForClassTask', createTask, buildInputs,
224 <ResultDescriptor>[CONSTRUCTORS, CONSTRUCTORS_ERRORS]);
225
226 BuildClassConstructorsTask(
227 InternalAnalysisContext context, AnalysisTarget target)
228 : super(context, target);
229
230 @override
231 TaskDescriptor get descriptor => DESCRIPTOR;
232
233 @override
234 void internalPerform() {
235 List<AnalysisError> errors = <AnalysisError>[];
236 //
237 // Prepare inputs.
238 //
239 ClassElementImpl classElement = this.target;
240 List<ConstructorElement> superConstructors = inputs[SUPER_CONSTRUCTORS];
241 DartType superType = classElement.supertype;
242 ClassElement superElement = superType.element;
243 //
244 // Shortcut for ClassElement(s) without implicit constructors.
245 //
246 if (superConstructors == null) {
247 outputs[CONSTRUCTORS] = classElement.constructors;
248 outputs[CONSTRUCTORS_ERRORS] = AnalysisError.NO_ERRORS;
249 return;
250 }
251 //
252 // ClassTypeAlias
253 //
254 if (classElement.isTypedef) {
255 List<ConstructorElement> implicitConstructors =
256 new List<ConstructorElement>();
257 void callback(ConstructorElement explicitConstructor,
258 List<DartType> parameterTypes, List<DartType> argumentTypes) {
259 implicitConstructors.add(_createImplicitContructor(classElement.type,
260 explicitConstructor, parameterTypes, argumentTypes));
261 }
262 if (_findForwardedConstructors(classElement, superType, callback)) {
263 if (implicitConstructors.isEmpty) {
264 errors.add(new AnalysisError.con2(classElement.source,
265 classElement.nameOffset, classElement.name.length,
266 CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS,
267 [superElement.name]));
268 } else {
269 classElement.constructors = implicitConstructors;
270 }
271 }
272 outputs[CONSTRUCTORS] = classElement.constructors;
273 outputs[CONSTRUCTORS_ERRORS] = errors;
274 }
275 //
276 // ClassDeclaration
277 //
278 if (!classElement.isTypedef) {
279 bool constructorFound = false;
280 void callback(ConstructorElement explicitConstructor,
281 List<DartType> parameterTypes, List<DartType> argumentTypes) {
282 constructorFound = true;
283 }
284 if (_findForwardedConstructors(classElement, superType, callback) &&
285 !constructorFound) {
286 SourceRange withRange = classElement.withClauseRange;
287 errors.add(new AnalysisError.con2(classElement.source, withRange.offset,
288 withRange.length, CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS,
289 [superElement.name]));
290 classElement.mixinErrorsReported = true;
291 }
292 outputs[CONSTRUCTORS] = classElement.constructors;
293 outputs[CONSTRUCTORS_ERRORS] = errors;
294 }
295 }
296
297 /**
298 * Return a map from the names of the inputs of this kind of task to the task
299 * input descriptors describing those inputs for a task with the
300 * given [classElement].
301 */
302 static Map<String, TaskInput> buildInputs(ClassElement classElement) {
Paul Berry 2015/03/24 20:10:17 I think this is going to cause a problem in the lo
scheglov 2015/03/24 21:17:15 I will add TODO for now. We need to discuss it whe
303 DartType superType = classElement.supertype;
304 if (superType is InterfaceType) {
305 if (classElement.isTypedef || classElement.mixins.isNotEmpty) {
306 ClassElement superElement = superType.element;
307 return <String, TaskInput>{
308 SUPER_CONSTRUCTORS: CONSTRUCTORS.inputFor(superElement)
309 };
310 }
311 }
312 // No implicit constructors, no inputs required.
313 return <String, TaskInput>{};
314 }
315
316 /**
317 * Create a [BuildClassConstructorsTask] based on the given
318 * [target] in the given [context].
319 */
320 static BuildClassConstructorsTask createTask(
321 AnalysisContext context, AnalysisTarget target) {
322 return new BuildClassConstructorsTask(context, target);
323 }
324
325 /**
326 * Create an implicit constructor that is copied from the given
327 * [explicitConstructor], but that is in the given class.
328 *
329 * [classType] - the class in which the implicit constructor is defined.
330 * [explicitConstructor] - the constructor on which the implicit constructor
331 * is modeled.
332 * [parameterTypes] - the types to be replaced when creating parameters.
333 * [argumentTypes] - the types with which the parameters are to be replaced.
334 */
335 static ConstructorElement _createImplicitContructor(InterfaceType classType,
336 ConstructorElement explicitConstructor, List<DartType> parameterTypes,
337 List<DartType> argumentTypes) {
338 ConstructorElementImpl implicitConstructor =
339 new ConstructorElementImpl(explicitConstructor.name, -1);
340 implicitConstructor.synthetic = true;
341 implicitConstructor.redirectedConstructor = explicitConstructor;
342 implicitConstructor.const2 = explicitConstructor.isConst;
343 implicitConstructor.returnType = classType;
344 List<ParameterElement> explicitParameters = explicitConstructor.parameters;
345 int count = explicitParameters.length;
346 if (count > 0) {
347 List<ParameterElement> implicitParameters =
348 new List<ParameterElement>(count);
349 for (int i = 0; i < count; i++) {
350 ParameterElement explicitParameter = explicitParameters[i];
351 ParameterElementImpl implicitParameter =
352 new ParameterElementImpl(explicitParameter.name, -1);
353 implicitParameter.const3 = explicitParameter.isConst;
354 implicitParameter.final2 = explicitParameter.isFinal;
355 implicitParameter.parameterKind = explicitParameter.parameterKind;
356 implicitParameter.synthetic = true;
357 implicitParameter.type =
358 explicitParameter.type.substitute2(argumentTypes, parameterTypes);
359 implicitParameters[i] = implicitParameter;
360 }
361 implicitConstructor.parameters = implicitParameters;
362 }
363 FunctionTypeImpl type = new FunctionTypeImpl.con1(implicitConstructor);
364 type.typeArguments = classType.typeArguments;
365 implicitConstructor.type = type;
366 return implicitConstructor;
367 }
368
369 /**
370 * Find all the constructors that should be forwarded from the given
371 * [superType], to the class or mixin application [classElement],
372 * and pass information about them to [callback].
373 *
374 * Return true if some constructors were considered. (A false return value
375 * can only happen if the supeclass is a built-in type, in which case it
376 * can't be used as a mixin anyway).
377 */
378 static bool _findForwardedConstructors(ClassElementImpl classElement,
379 InterfaceType superType, void callback(
380 ConstructorElement explicitConstructor, List<DartType> parameterTypes,
381 List<DartType> argumentTypes)) {
382 ClassElement superclassElement = superType.element;
383 List<ConstructorElement> constructors = superclassElement.constructors;
384 int count = constructors.length;
385 if (count == 0) {
386 return false;
387 }
388 List<DartType> parameterTypes =
389 TypeParameterTypeImpl.getTypes(superType.typeParameters);
390 List<DartType> argumentTypes = _getArgumentTypes(superType, parameterTypes);
391 for (int i = 0; i < count; i++) {
392 ConstructorElement explicitConstructor = constructors[i];
393 if (!explicitConstructor.isFactory &&
394 classElement.isSuperConstructorAccessible(explicitConstructor)) {
395 callback(explicitConstructor, parameterTypes, argumentTypes);
396 }
397 }
398 return true;
399 }
400
401 /**
402 * Return a list of argument types that corresponds to the [parameterTypes]
403 * and that are derived from the type arguments of the given [superType].
404 */
405 static List<DartType> _getArgumentTypes(
406 InterfaceType superType, List<DartType> parameterTypes) {
407 DynamicTypeImpl dynamic = DynamicTypeImpl.instance;
408 int parameterCount = parameterTypes.length;
409 List<DartType> types = new List<DartType>(parameterCount);
410 if (superType == null) {
411 types = new List<DartType>.filled(parameterCount, dynamic);
412 } else {
413 List<DartType> typeArguments = superType.typeArguments;
414 int argumentCount = math.min(typeArguments.length, parameterCount);
415 for (int i = 0; i < argumentCount; i++) {
416 types[i] = typeArguments[i];
417 }
418 for (int i = argumentCount; i < parameterCount; i++) {
419 types[i] = dynamic;
420 }
421 }
422 return types;
423 }
424 }
425
426 /**
192 * A task that builds a compilation unit element for a single compilation unit. 427 * A task that builds a compilation unit element for a single compilation unit.
193 */ 428 */
194 class BuildCompilationUnitElementTask extends SourceBasedAnalysisTask { 429 class BuildCompilationUnitElementTask extends SourceBasedAnalysisTask {
195 /** 430 /**
196 * The name of the input whose value is the line information for the 431 * The name of the input whose value is the line information for the
197 * compilation unit. 432 * compilation unit.
198 */ 433 */
199 static const String LINE_INFO_INPUT_NAME = 'LINE_INFO_INPUT_NAME'; 434 static const String LINE_INFO_INPUT_NAME = 'LINE_INFO_INPUT_NAME';
200 435
201 /** 436 /**
(...skipping 1494 matching lines...) Expand 10 before | Expand all | Expand 10 after
1696 } 1931 }
1697 1932
1698 /** 1933 /**
1699 * Create a [ScanDartTask] based on the given [target] in the given [context]. 1934 * Create a [ScanDartTask] based on the given [target] in the given [context].
1700 */ 1935 */
1701 static ScanDartTask createTask( 1936 static ScanDartTask createTask(
1702 AnalysisContext context, AnalysisTarget target) { 1937 AnalysisContext context, AnalysisTarget target) {
1703 return new ScanDartTask(context, target); 1938 return new ScanDartTask(context, target);
1704 } 1939 }
1705 } 1940 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/generated/element.dart ('k') | pkg/analyzer/test/src/task/dart_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698