| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 dart2js; | 5 part of dart2js; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * If true, print a warning for each method that was resolved, but not | 8 * If true, print a warning for each method that was resolved, but not |
| 9 * compiled. | 9 * compiled. |
| 10 */ | 10 */ |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 ClassElement get boolImplementation => compiler.boolClass; | 254 ClassElement get boolImplementation => compiler.boolClass; |
| 255 ClassElement get nullImplementation => compiler.nullClass; | 255 ClassElement get nullImplementation => compiler.nullClass; |
| 256 ClassElement get uint32Implementation => compiler.intClass; | 256 ClassElement get uint32Implementation => compiler.intClass; |
| 257 ClassElement get uint31Implementation => compiler.intClass; | 257 ClassElement get uint31Implementation => compiler.intClass; |
| 258 ClassElement get positiveIntImplementation => compiler.intClass; | 258 ClassElement get positiveIntImplementation => compiler.intClass; |
| 259 | 259 |
| 260 ClassElement defaultSuperclass(ClassElement element) => compiler.objectClass; | 260 ClassElement defaultSuperclass(ClassElement element) => compiler.objectClass; |
| 261 | 261 |
| 262 bool isDefaultNoSuchMethodImplementation(Element element) { | 262 bool isDefaultNoSuchMethodImplementation(Element element) { |
| 263 assert(element.name == Compiler.NO_SUCH_METHOD); | 263 assert(element.name == Compiler.NO_SUCH_METHOD); |
| 264 ClassElement classElement = element.getEnclosingClass(); | 264 ClassElement classElement = element.enclosingClass; |
| 265 return classElement == compiler.objectClass; | 265 return classElement == compiler.objectClass; |
| 266 } | 266 } |
| 267 | 267 |
| 268 bool isInterceptorClass(ClassElement element) => false; | 268 bool isInterceptorClass(ClassElement element) => false; |
| 269 | 269 |
| 270 void registerStaticUse(Element element, Enqueuer enqueuer) {} | 270 void registerStaticUse(Element element, Enqueuer enqueuer) {} |
| 271 | 271 |
| 272 Future onLibraryLoaded(LibraryElement library, Uri uri) { | 272 Future onLibraryLoaded(LibraryElement library, Uri uri) { |
| 273 return new Future.value(); | 273 return new Future.value(); |
| 274 } | 274 } |
| (...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 765 return node; | 765 return node; |
| 766 } else if (node is Node) { | 766 } else if (node is Node) { |
| 767 return spanFromNode(node); | 767 return spanFromNode(node); |
| 768 } else if (node is Token) { | 768 } else if (node is Token) { |
| 769 return spanFromTokens(node, node); | 769 return spanFromTokens(node, node); |
| 770 } else if (node is HInstruction) { | 770 } else if (node is HInstruction) { |
| 771 return spanFromHInstruction(node); | 771 return spanFromHInstruction(node); |
| 772 } else if (node is Element) { | 772 } else if (node is Element) { |
| 773 return spanFromElement(node); | 773 return spanFromElement(node); |
| 774 } else if (node is MetadataAnnotation) { | 774 } else if (node is MetadataAnnotation) { |
| 775 Uri uri = node.annotatedElement.getCompilationUnit().script.readableUri; | 775 Uri uri = node.annotatedElement.compilationUnit.script.readableUri; |
| 776 return spanFromTokens(node.beginToken, node.endToken, uri); | 776 return spanFromTokens(node.beginToken, node.endToken, uri); |
| 777 } else { | 777 } else { |
| 778 throw 'No error location.'; | 778 throw 'No error location.'; |
| 779 } | 779 } |
| 780 } | 780 } |
| 781 | 781 |
| 782 /// Finds the approximate [Element] for [node]. [currentElement] is used as | 782 /// Finds the approximate [Element] for [node]. [currentElement] is used as |
| 783 /// the default value. | 783 /// the default value. |
| 784 Element elementFromSpannable(Spannable node) { | 784 Element elementFromSpannable(Spannable node) { |
| 785 Element element; | 785 Element element; |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 965 dynamicClass.ensureResolved(this); | 965 dynamicClass.ensureResolved(this); |
| 966 | 966 |
| 967 proxyConstant = | 967 proxyConstant = |
| 968 resolver.constantCompiler.compileConstant(coreLibrary.find('proxy')); | 968 resolver.constantCompiler.compileConstant(coreLibrary.find('proxy')); |
| 969 } | 969 } |
| 970 | 970 |
| 971 Element _unnamedListConstructor; | 971 Element _unnamedListConstructor; |
| 972 Element get unnamedListConstructor { | 972 Element get unnamedListConstructor { |
| 973 if (_unnamedListConstructor != null) return _unnamedListConstructor; | 973 if (_unnamedListConstructor != null) return _unnamedListConstructor; |
| 974 Selector callConstructor = new Selector.callConstructor( | 974 Selector callConstructor = new Selector.callConstructor( |
| 975 "", listClass.getLibrary()); | 975 "", listClass.library); |
| 976 return _unnamedListConstructor = | 976 return _unnamedListConstructor = |
| 977 listClass.lookupConstructor(callConstructor); | 977 listClass.lookupConstructor(callConstructor); |
| 978 } | 978 } |
| 979 | 979 |
| 980 Element _filledListConstructor; | 980 Element _filledListConstructor; |
| 981 Element get filledListConstructor { | 981 Element get filledListConstructor { |
| 982 if (_filledListConstructor != null) return _filledListConstructor; | 982 if (_filledListConstructor != null) return _filledListConstructor; |
| 983 Selector callConstructor = new Selector.callConstructor( | 983 Selector callConstructor = new Selector.callConstructor( |
| 984 "filled", listClass.getLibrary()); | 984 "filled", listClass.library); |
| 985 return _filledListConstructor = | 985 return _filledListConstructor = |
| 986 listClass.lookupConstructor(callConstructor); | 986 listClass.lookupConstructor(callConstructor); |
| 987 } | 987 } |
| 988 | 988 |
| 989 Future scanBuiltinLibraries() { | 989 Future scanBuiltinLibraries() { |
| 990 return scanBuiltinLibrary('_js_helper').then((LibraryElement library) { | 990 return scanBuiltinLibrary('_js_helper').then((LibraryElement library) { |
| 991 jsHelperLibrary = library; | 991 jsHelperLibrary = library; |
| 992 return scanBuiltinLibrary('_interceptors'); | 992 return scanBuiltinLibrary('_interceptors'); |
| 993 }).then((LibraryElement library) { | 993 }).then((LibraryElement library) { |
| 994 interceptorsLibrary = library; | 994 interceptorsLibrary = library; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1073 MessageKind.GENERIC, | 1073 MessageKind.GENERIC, |
| 1074 {'text': "Could not find '$MAIN'."}); | 1074 {'text': "Could not find '$MAIN'."}); |
| 1075 } else if (!analyzeAll) { | 1075 } else if (!analyzeAll) { |
| 1076 reportFatalError(mainApp, MessageKind.GENERIC, | 1076 reportFatalError(mainApp, MessageKind.GENERIC, |
| 1077 {'text': "Could not find '$MAIN'. " | 1077 {'text': "Could not find '$MAIN'. " |
| 1078 "No source will be analyzed. " | 1078 "No source will be analyzed. " |
| 1079 "Use '--analyze-all' to analyze all code in the " | 1079 "Use '--analyze-all' to analyze all code in the " |
| 1080 "library."}); | 1080 "library."}); |
| 1081 } | 1081 } |
| 1082 } else { | 1082 } else { |
| 1083 if (main.isErroneous()) { | 1083 if (main.isErroneous) { |
| 1084 reportFatalError(main, MessageKind.GENERIC, | 1084 reportFatalError(main, MessageKind.GENERIC, |
| 1085 {'text': "Cannot determine which '$MAIN' to use."}); | 1085 {'text': "Cannot determine which '$MAIN' to use."}); |
| 1086 } else if (!main.isFunction()) { | 1086 } else if (!main.isFunction) { |
| 1087 reportFatalError(main, MessageKind.GENERIC, | 1087 reportFatalError(main, MessageKind.GENERIC, |
| 1088 {'text': "'$MAIN' is not a function."}); | 1088 {'text': "'$MAIN' is not a function."}); |
| 1089 } | 1089 } |
| 1090 mainFunction = main; | 1090 mainFunction = main; |
| 1091 FunctionSignature parameters = mainFunction.computeSignature(this); | 1091 FunctionSignature parameters = mainFunction.computeSignature(this); |
| 1092 if (parameters.parameterCount > 2) { | 1092 if (parameters.parameterCount > 2) { |
| 1093 int index = 0; | 1093 int index = 0; |
| 1094 parameters.forEachParameter((Element parameter) { | 1094 parameters.forEachParameter((Element parameter) { |
| 1095 if (index++ < 2) return; | 1095 if (index++ < 2) return; |
| 1096 reportError(parameter, MessageKind.GENERIC, | 1096 reportError(parameter, MessageKind.GENERIC, |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1202 } | 1202 } |
| 1203 | 1203 |
| 1204 void fullyEnqueueLibrary(LibraryElement library, Enqueuer world) { | 1204 void fullyEnqueueLibrary(LibraryElement library, Enqueuer world) { |
| 1205 void enqueueAll(Element element) { | 1205 void enqueueAll(Element element) { |
| 1206 fullyEnqueueTopLevelElement(element, world); | 1206 fullyEnqueueTopLevelElement(element, world); |
| 1207 } | 1207 } |
| 1208 library.implementation.forEachLocalMember(enqueueAll); | 1208 library.implementation.forEachLocalMember(enqueueAll); |
| 1209 } | 1209 } |
| 1210 | 1210 |
| 1211 void fullyEnqueueTopLevelElement(Element element, Enqueuer world) { | 1211 void fullyEnqueueTopLevelElement(Element element, Enqueuer world) { |
| 1212 if (element.isClass()) { | 1212 if (element.isClass) { |
| 1213 ClassElement cls = element; | 1213 ClassElement cls = element; |
| 1214 cls.ensureResolved(this); | 1214 cls.ensureResolved(this); |
| 1215 cls.forEachLocalMember(enqueuer.resolution.addToWorkList); | 1215 cls.forEachLocalMember(enqueuer.resolution.addToWorkList); |
| 1216 world.registerInstantiatedClass(element, globalDependencies); | 1216 world.registerInstantiatedClass(element, globalDependencies); |
| 1217 } else { | 1217 } else { |
| 1218 world.addToWorkList(element); | 1218 world.addToWorkList(element); |
| 1219 } | 1219 } |
| 1220 } | 1220 } |
| 1221 | 1221 |
| 1222 // Resolves metadata on library elements. This is necessary in order to | 1222 // Resolves metadata on library elements. This is necessary in order to |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1233 } | 1233 } |
| 1234 | 1234 |
| 1235 void processQueue(Enqueuer world, Element main) { | 1235 void processQueue(Enqueuer world, Element main) { |
| 1236 world.nativeEnqueuer.processNativeClasses(libraries.values); | 1236 world.nativeEnqueuer.processNativeClasses(libraries.values); |
| 1237 if (main != null) { | 1237 if (main != null) { |
| 1238 FunctionElement mainMethod = main; | 1238 FunctionElement mainMethod = main; |
| 1239 if (mainMethod.computeSignature(this).parameterCount != 0) { | 1239 if (mainMethod.computeSignature(this).parameterCount != 0) { |
| 1240 // TODO(ngeoffray, floitsch): we should also ensure that the | 1240 // TODO(ngeoffray, floitsch): we should also ensure that the |
| 1241 // class IsolateMessage is instantiated. Currently, just enabling | 1241 // class IsolateMessage is instantiated. Currently, just enabling |
| 1242 // isolate support works. | 1242 // isolate support works. |
| 1243 world.enableIsolateSupport(main.getLibrary()); | 1243 world.enableIsolateSupport(main.library); |
| 1244 world.registerInstantiatedClass(listClass, globalDependencies); | 1244 world.registerInstantiatedClass(listClass, globalDependencies); |
| 1245 world.registerInstantiatedClass(stringClass, globalDependencies); | 1245 world.registerInstantiatedClass(stringClass, globalDependencies); |
| 1246 } | 1246 } |
| 1247 world.addToWorkList(main); | 1247 world.addToWorkList(main); |
| 1248 } | 1248 } |
| 1249 progress.reset(); | 1249 progress.reset(); |
| 1250 world.forEach((WorkItem work) { | 1250 world.forEach((WorkItem work) { |
| 1251 withCurrentElement(work.element, () => work.run(this, world)); | 1251 withCurrentElement(work.element, () => work.run(this, world)); |
| 1252 }); | 1252 }); |
| 1253 world.queueIsClosed = true; | 1253 world.queueIsClosed = true; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1266 world.forEach((WorkItem work) { | 1266 world.forEach((WorkItem work) { |
| 1267 internalError(work.element, "Work list is not empty."); | 1267 internalError(work.element, "Work list is not empty."); |
| 1268 }); | 1268 }); |
| 1269 } | 1269 } |
| 1270 if (!REPORT_EXCESS_RESOLUTION) return; | 1270 if (!REPORT_EXCESS_RESOLUTION) return; |
| 1271 var resolved = new Set.from(enqueuer.resolution.resolvedElements.keys); | 1271 var resolved = new Set.from(enqueuer.resolution.resolvedElements.keys); |
| 1272 for (Element e in enqueuer.codegen.generatedCode.keys) { | 1272 for (Element e in enqueuer.codegen.generatedCode.keys) { |
| 1273 resolved.remove(e); | 1273 resolved.remove(e); |
| 1274 } | 1274 } |
| 1275 for (Element e in new Set.from(resolved)) { | 1275 for (Element e in new Set.from(resolved)) { |
| 1276 if (e.isClass() || | 1276 if (e.isClass || |
| 1277 e.isField() || | 1277 e.isField || |
| 1278 e.isTypeVariable() || | 1278 e.isTypeVariable || |
| 1279 e.isTypedef() || | 1279 e.isTypedef || |
| 1280 identical(e.kind, ElementKind.ABSTRACT_FIELD)) { | 1280 identical(e.kind, ElementKind.ABSTRACT_FIELD)) { |
| 1281 resolved.remove(e); | 1281 resolved.remove(e); |
| 1282 } | 1282 } |
| 1283 if (identical(e.kind, ElementKind.GENERATIVE_CONSTRUCTOR)) { | 1283 if (identical(e.kind, ElementKind.GENERATIVE_CONSTRUCTOR)) { |
| 1284 ClassElement enclosingClass = e.getEnclosingClass(); | 1284 ClassElement enclosingClass = e.enclosingClass; |
| 1285 resolved.remove(e); | 1285 resolved.remove(e); |
| 1286 | 1286 |
| 1287 } | 1287 } |
| 1288 if (identical(e.getLibrary(), jsHelperLibrary)) { | 1288 if (identical(e.library, jsHelperLibrary)) { |
| 1289 resolved.remove(e); | 1289 resolved.remove(e); |
| 1290 } | 1290 } |
| 1291 if (identical(e.getLibrary(), interceptorsLibrary)) { | 1291 if (identical(e.library, interceptorsLibrary)) { |
| 1292 resolved.remove(e); | 1292 resolved.remove(e); |
| 1293 } | 1293 } |
| 1294 } | 1294 } |
| 1295 log('Excess resolution work: ${resolved.length}.'); | 1295 log('Excess resolution work: ${resolved.length}.'); |
| 1296 for (Element e in resolved) { | 1296 for (Element e in resolved) { |
| 1297 reportWarning(e, | 1297 reportWarning(e, |
| 1298 MessageKind.GENERIC, | 1298 MessageKind.GENERIC, |
| 1299 {'text': 'Warning: $e resolved but not compiled.'}); | 1299 {'text': 'Warning: $e resolved but not compiled.'}); |
| 1300 } | 1300 } |
| 1301 } | 1301 } |
| 1302 | 1302 |
| 1303 TreeElements analyzeElement(Element element) { | 1303 TreeElements analyzeElement(Element element) { |
| 1304 assert(invariant(element, | 1304 assert(invariant(element, |
| 1305 element.impliesType() || | 1305 element.impliesType || |
| 1306 element.isField() || | 1306 element.isField || |
| 1307 element.isFunction() || | 1307 element.isFunction || |
| 1308 element.isGenerativeConstructor() || | 1308 element.isGenerativeConstructor || |
| 1309 element.isGetter() || | 1309 element.isGetter || |
| 1310 element.isSetter(), | 1310 element.isSetter, |
| 1311 message: 'Unexpected element kind: ${element.kind}')); | 1311 message: 'Unexpected element kind: ${element.kind}')); |
| 1312 assert(invariant(element, element is AnalyzableElement, | 1312 assert(invariant(element, element is AnalyzableElement, |
| 1313 message: 'Element $element is not analyzable.')); | 1313 message: 'Element $element is not analyzable.')); |
| 1314 assert(invariant(element, element.isDeclaration)); | 1314 assert(invariant(element, element.isDeclaration)); |
| 1315 ResolutionEnqueuer world = enqueuer.resolution; | 1315 ResolutionEnqueuer world = enqueuer.resolution; |
| 1316 TreeElements elements = world.getCachedElements(element); | 1316 TreeElements elements = world.getCachedElements(element); |
| 1317 if (elements != null) return elements; | 1317 if (elements != null) return elements; |
| 1318 assert(parser != null); | 1318 assert(parser != null); |
| 1319 Node tree = parser.parse(element); | 1319 Node tree = parser.parse(element); |
| 1320 assert(invariant(element, !element.isSynthesized || tree == null)); | 1320 assert(invariant(element, !element.isSynthesized || tree == null)); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1453 } | 1453 } |
| 1454 | 1454 |
| 1455 SourceSpan spanFromTokens(Token begin, Token end, [Uri uri]) { | 1455 SourceSpan spanFromTokens(Token begin, Token end, [Uri uri]) { |
| 1456 if (begin == null || end == null) { | 1456 if (begin == null || end == null) { |
| 1457 // TODO(ahe): We can almost always do better. Often it is only | 1457 // TODO(ahe): We can almost always do better. Often it is only |
| 1458 // end that is null. Otherwise, we probably know the current | 1458 // end that is null. Otherwise, we probably know the current |
| 1459 // URI. | 1459 // URI. |
| 1460 throw 'Cannot find tokens to produce error message.'; | 1460 throw 'Cannot find tokens to produce error message.'; |
| 1461 } | 1461 } |
| 1462 if (uri == null && currentElement != null) { | 1462 if (uri == null && currentElement != null) { |
| 1463 uri = currentElement.getCompilationUnit().script.readableUri; | 1463 uri = currentElement.compilationUnit.script.readableUri; |
| 1464 } | 1464 } |
| 1465 return SourceSpan.withCharacterOffsets(begin, end, | 1465 return SourceSpan.withCharacterOffsets(begin, end, |
| 1466 (beginOffset, endOffset) => new SourceSpan(uri, beginOffset, endOffset)); | 1466 (beginOffset, endOffset) => new SourceSpan(uri, beginOffset, endOffset)); |
| 1467 } | 1467 } |
| 1468 | 1468 |
| 1469 SourceSpan spanFromNode(Node node) { | 1469 SourceSpan spanFromNode(Node node) { |
| 1470 return spanFromTokens(node.getBeginToken(), node.getEndToken()); | 1470 return spanFromTokens(node.getBeginToken(), node.getEndToken()); |
| 1471 } | 1471 } |
| 1472 | 1472 |
| 1473 SourceSpan spanFromElement(Element element) { | 1473 SourceSpan spanFromElement(Element element) { |
| 1474 if (Elements.isErroneousElement(element)) { | 1474 if (Elements.isErroneousElement(element)) { |
| 1475 element = element.enclosingElement; | 1475 element = element.enclosingElement; |
| 1476 } | 1476 } |
| 1477 if (element.position() == null && | 1477 if (element.position == null && |
| 1478 !element.isLibrary() && | 1478 !element.isLibrary && |
| 1479 !element.isCompilationUnit()) { | 1479 !element.isCompilationUnit) { |
| 1480 // Sometimes, the backend fakes up elements that have no | 1480 // Sometimes, the backend fakes up elements that have no |
| 1481 // position. So we use the enclosing element instead. It is | 1481 // position. So we use the enclosing element instead. It is |
| 1482 // not a good error location, but cancel really is "internal | 1482 // not a good error location, but cancel really is "internal |
| 1483 // error" or "not implemented yet", so the vicinity is good | 1483 // error" or "not implemented yet", so the vicinity is good |
| 1484 // enough for now. | 1484 // enough for now. |
| 1485 element = element.enclosingElement; | 1485 element = element.enclosingElement; |
| 1486 // TODO(ahe): I plan to overhaul this infrastructure anyways. | 1486 // TODO(ahe): I plan to overhaul this infrastructure anyways. |
| 1487 } | 1487 } |
| 1488 if (element == null) { | 1488 if (element == null) { |
| 1489 element = currentElement; | 1489 element = currentElement; |
| 1490 } | 1490 } |
| 1491 Token position = element.position(); | 1491 Token position = element.position; |
| 1492 Uri uri = element.getCompilationUnit().script.readableUri; | 1492 Uri uri = element.compilationUnit.script.readableUri; |
| 1493 return (position == null) | 1493 return (position == null) |
| 1494 ? new SourceSpan(uri, 0, 0) | 1494 ? new SourceSpan(uri, 0, 0) |
| 1495 : spanFromTokens(position, position, uri); | 1495 : spanFromTokens(position, position, uri); |
| 1496 } | 1496 } |
| 1497 | 1497 |
| 1498 SourceSpan spanFromHInstruction(HInstruction instruction) { | 1498 SourceSpan spanFromHInstruction(HInstruction instruction) { |
| 1499 Element element = instruction.sourceElement; | 1499 Element element = instruction.sourceElement; |
| 1500 if (element == null) element = currentElement; | 1500 if (element == null) element = currentElement; |
| 1501 var position = instruction.sourcePosition; | 1501 var position = instruction.sourcePosition; |
| 1502 if (position == null) return spanFromElement(element); | 1502 if (position == null) return spanFromElement(element); |
| 1503 Token token = position.token; | 1503 Token token = position.token; |
| 1504 if (token == null) return spanFromElement(element); | 1504 if (token == null) return spanFromElement(element); |
| 1505 Uri uri = element.getCompilationUnit().script.readableUri; | 1505 Uri uri = element.compilationUnit.script.readableUri; |
| 1506 return spanFromTokens(token, token, uri); | 1506 return spanFromTokens(token, token, uri); |
| 1507 } | 1507 } |
| 1508 | 1508 |
| 1509 /** | 1509 /** |
| 1510 * Translates the [resolvedUri] into a readable URI. | 1510 * Translates the [resolvedUri] into a readable URI. |
| 1511 * | 1511 * |
| 1512 * The [importingLibrary] holds the library importing [resolvedUri] or | 1512 * The [importingLibrary] holds the library importing [resolvedUri] or |
| 1513 * [:null:] if [resolvedUri] is loaded as the main library. The | 1513 * [:null:] if [resolvedUri] is loaded as the main library. The |
| 1514 * [importingLibrary] is used to grant access to internal libraries from | 1514 * [importingLibrary] is used to grant access to internal libraries from |
| 1515 * platform libraries and patch libraries. | 1515 * platform libraries and patch libraries. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1569 } | 1569 } |
| 1570 } | 1570 } |
| 1571 prevToken = currentToken; | 1571 prevToken = currentToken; |
| 1572 currentToken = currentToken.next; | 1572 currentToken = currentToken.next; |
| 1573 } | 1573 } |
| 1574 return firstToken; | 1574 return firstToken; |
| 1575 } | 1575 } |
| 1576 | 1576 |
| 1577 void reportUnusedCode() { | 1577 void reportUnusedCode() { |
| 1578 void checkLive(member) { | 1578 void checkLive(member) { |
| 1579 if (member.isFunction()) { | 1579 if (member.isFunction) { |
| 1580 if (!enqueuer.resolution.isLive(member)) { | 1580 if (!enqueuer.resolution.isLive(member)) { |
| 1581 reportHint(member, MessageKind.UNUSED_METHOD, | 1581 reportHint(member, MessageKind.UNUSED_METHOD, |
| 1582 {'name': member.name}); | 1582 {'name': member.name}); |
| 1583 } | 1583 } |
| 1584 } else if (member.isClass()) { | 1584 } else if (member.isClass) { |
| 1585 if (!member.isResolved) { | 1585 if (!member.isResolved) { |
| 1586 reportHint(member, MessageKind.UNUSED_CLASS, | 1586 reportHint(member, MessageKind.UNUSED_CLASS, |
| 1587 {'name': member.name}); | 1587 {'name': member.name}); |
| 1588 } else { | 1588 } else { |
| 1589 member.forEachLocalMember(checkLive); | 1589 member.forEachLocalMember(checkLive); |
| 1590 } | 1590 } |
| 1591 } else if (member.isTypedef()) { | 1591 } else if (member.isTypedef) { |
| 1592 if (!member.isResolved) { | 1592 if (!member.isResolved) { |
| 1593 reportHint(member, MessageKind.UNUSED_TYPEDEF, | 1593 reportHint(member, MessageKind.UNUSED_TYPEDEF, |
| 1594 {'name': member.name}); | 1594 {'name': member.name}); |
| 1595 } | 1595 } |
| 1596 } | 1596 } |
| 1597 } | 1597 } |
| 1598 libraries.forEach((_, library) { | 1598 libraries.forEach((_, library) { |
| 1599 // TODO(ahe): Implement better heuristics to discover entry points of | 1599 // TODO(ahe): Implement better heuristics to discover entry points of |
| 1600 // packages and use that to discover unused implementation details in | 1600 // packages and use that to discover unused implementation details in |
| 1601 // packages. | 1601 // packages. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1637 entrypoints.add(mainApp.canonicalUri); | 1637 entrypoints.add(mainApp.canonicalUri); |
| 1638 } | 1638 } |
| 1639 if (librariesToAnalyzeWhenRun != null) { | 1639 if (librariesToAnalyzeWhenRun != null) { |
| 1640 entrypoints.addAll(librariesToAnalyzeWhenRun); | 1640 entrypoints.addAll(librariesToAnalyzeWhenRun); |
| 1641 } | 1641 } |
| 1642 if (entrypoints.isEmpty && assumeInUserCode) { | 1642 if (entrypoints.isEmpty && assumeInUserCode) { |
| 1643 // Assume in user code since [mainApp] has not been set yet. | 1643 // Assume in user code since [mainApp] has not been set yet. |
| 1644 return true; | 1644 return true; |
| 1645 } | 1645 } |
| 1646 if (element == null) return false; | 1646 if (element == null) return false; |
| 1647 Uri libraryUri = element.getLibrary().canonicalUri; | 1647 Uri libraryUri = element.library.canonicalUri; |
| 1648 if (libraryUri.scheme == 'package') { | 1648 if (libraryUri.scheme == 'package') { |
| 1649 for (Uri uri in entrypoints) { | 1649 for (Uri uri in entrypoints) { |
| 1650 if (uri.scheme != 'package') continue; | 1650 if (uri.scheme != 'package') continue; |
| 1651 int slashPos = libraryUri.path.indexOf('/'); | 1651 int slashPos = libraryUri.path.indexOf('/'); |
| 1652 if (slashPos != -1) { | 1652 if (slashPos != -1) { |
| 1653 String packageName = libraryUri.path.substring(0, slashPos + 1); | 1653 String packageName = libraryUri.path.substring(0, slashPos + 1); |
| 1654 if (uri.path.startsWith(packageName)) { | 1654 if (uri.path.startsWith(packageName)) { |
| 1655 return true; | 1655 return true; |
| 1656 } | 1656 } |
| 1657 } else { | 1657 } else { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1668 return false; | 1668 return false; |
| 1669 } | 1669 } |
| 1670 | 1670 |
| 1671 /// Return a canonical URI for the source of [element]. | 1671 /// Return a canonical URI for the source of [element]. |
| 1672 /// | 1672 /// |
| 1673 /// For a package library with canonical URI 'package:foo/bar/baz.dart' the | 1673 /// For a package library with canonical URI 'package:foo/bar/baz.dart' the |
| 1674 /// return URI is 'package:foo'. For non-package libraries the returned URI is | 1674 /// return URI is 'package:foo'. For non-package libraries the returned URI is |
| 1675 /// the canonical URI of the library itself. | 1675 /// the canonical URI of the library itself. |
| 1676 Uri getCanonicalUri(Element element) { | 1676 Uri getCanonicalUri(Element element) { |
| 1677 if (element == null) return null; | 1677 if (element == null) return null; |
| 1678 Uri libraryUri = element.getLibrary().canonicalUri; | 1678 Uri libraryUri = element.library.canonicalUri; |
| 1679 if (libraryUri.scheme == 'package') { | 1679 if (libraryUri.scheme == 'package') { |
| 1680 int slashPos = libraryUri.path.indexOf('/'); | 1680 int slashPos = libraryUri.path.indexOf('/'); |
| 1681 if (slashPos != -1) { | 1681 if (slashPos != -1) { |
| 1682 String packageName = libraryUri.path.substring(0, slashPos); | 1682 String packageName = libraryUri.path.substring(0, slashPos); |
| 1683 return new Uri(scheme: 'package', path: packageName); | 1683 return new Uri(scheme: 'package', path: packageName); |
| 1684 } | 1684 } |
| 1685 } | 1685 } |
| 1686 return libraryUri; | 1686 return libraryUri; |
| 1687 } | 1687 } |
| 1688 | 1688 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1806 static NullSink outputProvider(String name, String extension) { | 1806 static NullSink outputProvider(String name, String extension) { |
| 1807 return new NullSink('$name.$extension'); | 1807 return new NullSink('$name.$extension'); |
| 1808 } | 1808 } |
| 1809 } | 1809 } |
| 1810 | 1810 |
| 1811 /// Information about suppressed warnings and hints for a given library. | 1811 /// Information about suppressed warnings and hints for a given library. |
| 1812 class SuppressionInfo { | 1812 class SuppressionInfo { |
| 1813 int warnings = 0; | 1813 int warnings = 0; |
| 1814 int hints = 0; | 1814 int hints = 0; |
| 1815 } | 1815 } |
| OLD | NEW |