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

Side by Side Diff: pkg/compiler/lib/src/native/enqueue.dart

Issue 1383503002: Add Resolution and Parsing interfaces for computeType, ensureResolved and parseNode. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Add TODOs. Created 5 years, 2 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
« no previous file with comments | « pkg/compiler/lib/src/native/behavior.dart ('k') | pkg/compiler/lib/src/native/native.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) 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 part of native; 5 part of native;
6 6
7 /** 7 /**
8 * This could be an abstract class but we use it as a stub for the dart_backend. 8 * This could be an abstract class but we use it as a stub for the dart_backend.
9 */ 9 */
10 class NativeEnqueuer { 10 class NativeEnqueuer {
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 ClassElement _annotationCreatesClass; 124 ClassElement _annotationCreatesClass;
125 ClassElement _annotationReturnsClass; 125 ClassElement _annotationReturnsClass;
126 ClassElement _annotationJsNameClass; 126 ClassElement _annotationJsNameClass;
127 127
128 /// Subclasses of [NativeEnqueuerBase] are constructed by the backend. 128 /// Subclasses of [NativeEnqueuerBase] are constructed by the backend.
129 NativeEnqueuerBase(this.world, Compiler compiler, this.enableLiveTypeAnalysis) 129 NativeEnqueuerBase(this.world, Compiler compiler, this.enableLiveTypeAnalysis)
130 : this.compiler = compiler, 130 : this.compiler = compiler,
131 processedLibraries = compiler.cacheStrategy.newSet(); 131 processedLibraries = compiler.cacheStrategy.newSet();
132 132
133 JavaScriptBackend get backend => compiler.backend; 133 JavaScriptBackend get backend => compiler.backend;
134 Resolution get resolution => compiler.resolution;
134 135
135 void processNativeClasses(Iterable<LibraryElement> libraries) { 136 void processNativeClasses(Iterable<LibraryElement> libraries) {
136 if (compiler.hasIncrementalSupport) { 137 if (compiler.hasIncrementalSupport) {
137 // Since [Set.add] returns bool if an element was added, this restricts 138 // Since [Set.add] returns bool if an element was added, this restricts
138 // [libraries] to ones that haven't already been processed. This saves 139 // [libraries] to ones that haven't already been processed. This saves
139 // time during incremental compiles. 140 // time during incremental compiles.
140 libraries = libraries.where(processedLibraries.add); 141 libraries = libraries.where(processedLibraries.add);
141 } 142 }
142 libraries.forEach(processNativeClassesInLibrary); 143 libraries.forEach(processNativeClassesInLibrary);
143 if (backend.isolateHelperLibrary != null) { 144 if (backend.isolateHelperLibrary != null) {
(...skipping 12 matching lines...) Expand all
156 if (element.isClass && element.isNative) { 157 if (element.isClass && element.isNative) {
157 processNativeClass(element); 158 processNativeClass(element);
158 } 159 }
159 }); 160 });
160 } 161 }
161 162
162 void processNativeClass(ClassElement classElement) { 163 void processNativeClass(ClassElement classElement) {
163 nativeClasses.add(classElement); 164 nativeClasses.add(classElement);
164 unusedClasses.add(classElement); 165 unusedClasses.add(classElement);
165 // Resolve class to ensure the class has valid inheritance info. 166 // Resolve class to ensure the class has valid inheritance info.
166 classElement.ensureResolved(compiler); 167 classElement.ensureResolved(resolution);
167 } 168 }
168 169
169 void processSubclassesOfNativeClasses(Iterable<LibraryElement> libraries) { 170 void processSubclassesOfNativeClasses(Iterable<LibraryElement> libraries) {
170 // Collect potential subclasses, e.g. 171 // Collect potential subclasses, e.g.
171 // 172 //
172 // class B extends foo.A {} 173 // class B extends foo.A {}
173 // 174 //
174 // String "A" has a potential subclass B. 175 // String "A" has a potential subclass B.
175 176
176 var potentialExtends = new Map<String, Set<ClassElement>>(); 177 var potentialExtends = new Map<String, Set<ClassElement>>();
(...skipping 18 matching lines...) Expand all
195 // fact a subclass of a native class. 196 // fact a subclass of a native class.
196 197
197 ClassElement nativeSuperclassOf(ClassElement classElement) { 198 ClassElement nativeSuperclassOf(ClassElement classElement) {
198 if (classElement.isNative) return classElement; 199 if (classElement.isNative) return classElement;
199 if (classElement.superclass == null) return null; 200 if (classElement.superclass == null) return null;
200 return nativeSuperclassOf(classElement.superclass); 201 return nativeSuperclassOf(classElement.superclass);
201 } 202 }
202 203
203 void walkPotentialSubclasses(ClassElement element) { 204 void walkPotentialSubclasses(ClassElement element) {
204 if (nativeClassesAndSubclasses.contains(element)) return; 205 if (nativeClassesAndSubclasses.contains(element)) return;
205 element.ensureResolved(compiler); 206 element.ensureResolved(resolution);
206 ClassElement nativeSuperclass = nativeSuperclassOf(element); 207 ClassElement nativeSuperclass = nativeSuperclassOf(element);
207 if (nativeSuperclass != null) { 208 if (nativeSuperclass != null) {
208 nativeClassesAndSubclasses.add(element); 209 nativeClassesAndSubclasses.add(element);
209 if (!element.isNative) { 210 if (!element.isNative) {
210 nonNativeSubclasses.putIfAbsent(nativeSuperclass, 211 nonNativeSubclasses.putIfAbsent(nativeSuperclass,
211 () => new Set<ClassElement>()) 212 () => new Set<ClassElement>())
212 .add(element); 213 .add(element);
213 } 214 }
214 Set<ClassElement> potentialSubclasses = potentialExtends[element.name]; 215 Set<ClassElement> potentialSubclasses = potentialExtends[element.name];
215 if (potentialSubclasses != null) { 216 if (potentialSubclasses != null) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 _annotationReturnsClass = find('Returns'); 313 _annotationReturnsClass = find('Returns');
313 _annotationJsNameClass = find('JSName'); 314 _annotationJsNameClass = find('JSName');
314 } 315 }
315 316
316 /// Returns the JSName annotation string or `null` if no JSName annotation is 317 /// Returns the JSName annotation string or `null` if no JSName annotation is
317 /// present. 318 /// present.
318 String findJsNameFromAnnotation(Element element) { 319 String findJsNameFromAnnotation(Element element) {
319 String name = null; 320 String name = null;
320 ClassElement annotationClass = annotationJsNameClass; 321 ClassElement annotationClass = annotationJsNameClass;
321 for (MetadataAnnotation annotation in element.implementation.metadata) { 322 for (MetadataAnnotation annotation in element.implementation.metadata) {
322 annotation.ensureResolved(compiler); 323 annotation.ensureResolved(resolution);
323 ConstantValue value = 324 ConstantValue value =
324 compiler.constants.getConstantValue(annotation.constant); 325 compiler.constants.getConstantValue(annotation.constant);
325 if (!value.isConstructedObject) continue; 326 if (!value.isConstructedObject) continue;
326 ConstructedConstantValue constructedObject = value; 327 ConstructedConstantValue constructedObject = value;
327 if (constructedObject.type.element != annotationClass) continue; 328 if (constructedObject.type.element != annotationClass) continue;
328 329
329 Iterable<ConstantValue> fields = constructedObject.fields.values; 330 Iterable<ConstantValue> fields = constructedObject.fields.values;
330 // TODO(sra): Better validation of the constant. 331 // TODO(sra): Better validation of the constant.
331 if (fields.length != 1 || fields.single is! StringConstantValue) { 332 if (fields.length != 1 || fields.single is! StringConstantValue) {
332 PartialMetadataAnnotation partial = annotation;
333 compiler.internalError(annotation, 333 compiler.internalError(annotation,
334 'Annotations needs one string: ${partial.parseNode(compiler)}'); 334 'Annotations needs one string: ${annotation.node}');
335 } 335 }
336 StringConstantValue specStringConstant = fields.single; 336 StringConstantValue specStringConstant = fields.single;
337 String specString = specStringConstant.toDartString().slowToString(); 337 String specString = specStringConstant.toDartString().slowToString();
338 if (name == null) { 338 if (name == null) {
339 name = specString; 339 name = specString;
340 } else { 340 } else {
341 PartialMetadataAnnotation partial = annotation;
342 compiler.internalError(annotation, 341 compiler.internalError(annotation,
343 'Too many JSName annotations: ${partial.parseNode(compiler)}'); 342 'Too many JSName annotations: ${annotation.node}');
344 } 343 }
345 } 344 }
346 return name; 345 return name;
347 } 346 }
348 347
349 enqueueClass(ClassElement classElement, cause) { 348 enqueueClass(ClassElement classElement, cause) {
350 assert(unusedClasses.contains(classElement)); 349 assert(unusedClasses.contains(classElement));
351 unusedClasses.remove(classElement); 350 unusedClasses.remove(classElement);
352 pendingClasses.add(classElement); 351 pendingClasses.add(classElement);
353 queue.add(() { processClass(classElement, cause); }); 352 queue.add(() { processClass(classElement, cause); });
(...skipping 11 matching lines...) Expand all
365 processClass(BaseClassElementX classElement, cause) { 364 processClass(BaseClassElementX classElement, cause) {
366 // TODO(ahe): Fix this assertion to work in incremental compilation. 365 // TODO(ahe): Fix this assertion to work in incremental compilation.
367 assert(compiler.hasIncrementalSupport || 366 assert(compiler.hasIncrementalSupport ||
368 !registeredClasses.contains(classElement)); 367 !registeredClasses.contains(classElement));
369 368
370 bool firstTime = registeredClasses.isEmpty; 369 bool firstTime = registeredClasses.isEmpty;
371 pendingClasses.remove(classElement); 370 pendingClasses.remove(classElement);
372 registeredClasses.add(classElement); 371 registeredClasses.add(classElement);
373 372
374 // TODO(ahe): Is this really a global dependency? 373 // TODO(ahe): Is this really a global dependency?
375 classElement.ensureResolved(compiler); 374 classElement.ensureResolved(resolution);
376 compiler.backend.registerInstantiatedType( 375 compiler.backend.registerInstantiatedType(
377 classElement.rawType, world, compiler.globalDependencies); 376 classElement.rawType, world, compiler.globalDependencies);
378 377
379 // Also parse the node to know all its methods because otherwise it will
380 // only be parsed if there is a call to one of its constructors.
381 classElement.parseNode(compiler);
382
383 if (firstTime) { 378 if (firstTime) {
384 queue.add(onFirstNativeClass); 379 queue.add(onFirstNativeClass);
385 } 380 }
386 } 381 }
387 382
388 registerElement(Element element) { 383 registerElement(Element element) {
389 compiler.withCurrentElement(element, () { 384 compiler.withCurrentElement(element, () {
390 if (element.isFunction || element.isGetter || element.isSetter) { 385 if (element.isFunction || element.isGetter || element.isSetter) {
391 handleMethodAnnotations(element); 386 handleMethodAnnotations(element);
392 if (element.isNative) { 387 if (element.isNative) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 element.setNative(name); 450 element.setNative(name);
456 } 451 }
457 } 452 }
458 453
459 bool isIdentifier(String s) => _identifier.hasMatch(s); 454 bool isIdentifier(String s) => _identifier.hasMatch(s);
460 455
461 bool isNativeMethod(FunctionElementX element) { 456 bool isNativeMethod(FunctionElementX element) {
462 if (!element.library.canUseNative) return false; 457 if (!element.library.canUseNative) return false;
463 // Native method? 458 // Native method?
464 return compiler.withCurrentElement(element, () { 459 return compiler.withCurrentElement(element, () {
465 Node node = element.parseNode(compiler); 460 Node node = element.parseNode(resolution.parsing);
466 if (node is! FunctionExpression) return false; 461 if (node is! FunctionExpression) return false;
467 FunctionExpression functionExpression = node; 462 FunctionExpression functionExpression = node;
468 node = functionExpression.body; 463 node = functionExpression.body;
469 Token token = node.getBeginToken(); 464 Token token = node.getBeginToken();
470 if (identical(token.stringValue, 'native')) return true; 465 if (identical(token.stringValue, 'native')) return true;
471 return false; 466 return false;
472 }); 467 });
473 } 468 }
474 469
475 void registerNativeBehavior(NativeBehavior nativeBehavior, cause) { 470 void registerNativeBehavior(NativeBehavior nativeBehavior, cause) {
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 superclass, 678 superclass,
684 () => <ClassElement>[]); 679 () => <ClassElement>[]);
685 directSubtypes.add(cls); 680 directSubtypes.add(cls);
686 } 681 }
687 682
688 void logSummary(log(message)) { 683 void logSummary(log(message)) {
689 log('Compiled ${registeredClasses.length} native classes, ' 684 log('Compiled ${registeredClasses.length} native classes, '
690 '${unusedClasses.length} native classes omitted.'); 685 '${unusedClasses.length} native classes omitted.');
691 } 686 }
692 } 687 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/native/behavior.dart ('k') | pkg/compiler/lib/src/native/native.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698