| 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 engine.resolver; | 5 library engine.resolver; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import '../task/strong/info.dart' show InferredType, StaticInfo; | 9 import '../task/strong/info.dart' show InferredType, StaticInfo; |
| 10 import '../task/strong/rules.dart' show TypeRules; | 10 import '../task/strong/rules.dart' show TypeRules; |
| 11 import 'ast.dart'; | 11 import 'ast.dart'; |
| 12 import 'constant.dart'; | 12 import 'constant.dart'; |
| 13 import 'element.dart'; | 13 import 'element.dart'; |
| 14 import 'element_resolver.dart'; | 14 import 'element_resolver.dart'; |
| 15 import 'engine.dart'; | 15 import 'engine.dart'; |
| 16 import 'error.dart'; | 16 import 'error.dart'; |
| 17 import 'error_verifier.dart'; | 17 import 'error_verifier.dart'; |
| 18 import 'html.dart' as ht; | |
| 19 import 'java_core.dart'; | 18 import 'java_core.dart'; |
| 20 import 'java_engine.dart'; | 19 import 'java_engine.dart'; |
| 21 import 'scanner.dart'; | 20 import 'scanner.dart'; |
| 22 import 'scanner.dart' as sc; | 21 import 'scanner.dart' as sc; |
| 23 import 'sdk.dart' show DartSdk, SdkLibrary; | |
| 24 import 'source.dart'; | 22 import 'source.dart'; |
| 25 import 'static_type_analyzer.dart'; | 23 import 'static_type_analyzer.dart'; |
| 26 import 'type_system.dart'; | 24 import 'type_system.dart'; |
| 27 import 'utilities_dart.dart'; | 25 import 'utilities_dart.dart'; |
| 28 | 26 |
| 29 export 'type_system.dart'; | 27 export 'type_system.dart'; |
| 30 | 28 |
| 31 /** | 29 /** |
| 32 * Callback signature used by ImplicitConstructorBuilder to register | 30 * Callback signature used by ImplicitConstructorBuilder to register |
| 33 * computations to be performed, and their dependencies. A call to this | 31 * computations to be performed, and their dependencies. A call to this |
| 34 * callback indicates that [computation] may be used to compute implicit | 32 * callback indicates that [computation] may be used to compute implicit |
| 35 * constructors for [classElement], but that the computation may not be invoked | 33 * constructors for [classElement], but that the computation may not be invoked |
| 36 * until after implicit constructors have been built for [superclassElement]. | 34 * until after implicit constructors have been built for [superclassElement]. |
| 37 */ | 35 */ |
| 38 typedef void ImplicitConstructorBuilderCallback(ClassElement classElement, | 36 typedef void ImplicitConstructorBuilderCallback(ClassElement classElement, |
| 39 ClassElement superclassElement, void computation()); | 37 ClassElement superclassElement, void computation()); |
| 40 | 38 |
| 41 typedef LibraryResolver LibraryResolverFactory(AnalysisContext context); | |
| 42 | |
| 43 typedef ResolverVisitor ResolverVisitorFactory( | 39 typedef ResolverVisitor ResolverVisitorFactory( |
| 44 Library library, Source source, TypeProvider typeProvider); | 40 Library library, Source source, TypeProvider typeProvider); |
| 45 | 41 |
| 46 typedef StaticTypeAnalyzer StaticTypeAnalyzerFactory(ResolverVisitor visitor); | 42 typedef StaticTypeAnalyzer StaticTypeAnalyzerFactory(ResolverVisitor visitor); |
| 47 | 43 |
| 48 typedef TypeResolverVisitor TypeResolverVisitorFactory( | 44 typedef TypeResolverVisitor TypeResolverVisitorFactory( |
| 49 Library library, Source source, TypeProvider typeProvider); | 45 Library library, Source source, TypeProvider typeProvider); |
| 50 | 46 |
| 51 typedef void VoidFunction(); | 47 typedef void VoidFunction(); |
| 52 | 48 |
| (...skipping 4946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4999 // Find to-do comments | 4995 // Find to-do comments |
| 5000 new ToDoFinder(errorReporter).findIn(unit); | 4996 new ToDoFinder(errorReporter).findIn(unit); |
| 5001 // pub analysis | 4997 // pub analysis |
| 5002 // TODO(danrubel/jwren) Commented out until bugs in the pub verifier are | 4998 // TODO(danrubel/jwren) Commented out until bugs in the pub verifier are |
| 5003 // fixed | 4999 // fixed |
| 5004 // unit.accept(new PubVerifier(context, errorReporter)); | 5000 // unit.accept(new PubVerifier(context, errorReporter)); |
| 5005 } | 5001 } |
| 5006 } | 5002 } |
| 5007 | 5003 |
| 5008 /** | 5004 /** |
| 5009 * Instances of the class {@code HtmlTagInfo} record information about the tags
used in an HTML | |
| 5010 * file. | |
| 5011 */ | |
| 5012 class HtmlTagInfo { | |
| 5013 /** | |
| 5014 * An array containing all of the tags used in the HTML file. | |
| 5015 */ | |
| 5016 List<String> allTags; | |
| 5017 | |
| 5018 /** | |
| 5019 * A table mapping the id's defined in the HTML file to an array containing th
e names of tags with | |
| 5020 * that identifier. | |
| 5021 */ | |
| 5022 HashMap<String, String> idToTagMap; | |
| 5023 | |
| 5024 /** | |
| 5025 * A table mapping the classes defined in the HTML file to an array containing
the names of tags | |
| 5026 * with that class. | |
| 5027 */ | |
| 5028 HashMap<String, List<String>> classToTagsMap; | |
| 5029 | |
| 5030 /** | |
| 5031 * Initialize a newly created information holder to hold the given information
about the tags in | |
| 5032 * an HTML file. | |
| 5033 * | |
| 5034 * @param allTags an array containing all of the tags used in the HTML file | |
| 5035 * @param idToTagMap a table mapping the id's defined in the HTML file to an a
rray containing the | |
| 5036 * names of tags with that identifier | |
| 5037 * @param classToTagsMap a table mapping the classes defined in the HTML file
to an array | |
| 5038 * containing the names of tags with that class | |
| 5039 */ | |
| 5040 HtmlTagInfo(this.allTags, this.idToTagMap, this.classToTagsMap); | |
| 5041 | |
| 5042 /** | |
| 5043 * Return an array containing the tags that have the given class, or {@code nu
ll} if there are no | |
| 5044 * such tags. | |
| 5045 * | |
| 5046 * @return an array containing the tags that have the given class | |
| 5047 */ | |
| 5048 List<String> getTagsWithClass(String identifier) { | |
| 5049 return classToTagsMap[identifier]; | |
| 5050 } | |
| 5051 | |
| 5052 /** | |
| 5053 * Return the tag that has the given identifier, or {@code null} if there is n
o such tag (the | |
| 5054 * identifier is not defined). | |
| 5055 * | |
| 5056 * @return the tag that has the given identifier | |
| 5057 */ | |
| 5058 String getTagWithId(String identifier) { | |
| 5059 return idToTagMap[identifier]; | |
| 5060 } | |
| 5061 } | |
| 5062 | |
| 5063 /** | |
| 5064 * Instances of the class {@code HtmlTagInfoBuilder} gather information about th
e tags used in one | |
| 5065 * or more HTML structures. | |
| 5066 */ | |
| 5067 class HtmlTagInfoBuilder implements ht.XmlVisitor { | |
| 5068 /** | |
| 5069 * The name of the 'id' attribute. | |
| 5070 */ | |
| 5071 static final String ID_ATTRIBUTE = "id"; | |
| 5072 | |
| 5073 /** | |
| 5074 * The name of the 'class' attribute. | |
| 5075 */ | |
| 5076 static final String ID_CLASS = "class"; | |
| 5077 | |
| 5078 /** | |
| 5079 * A set containing all of the tag names used in the HTML. | |
| 5080 */ | |
| 5081 HashSet<String> tagSet = new HashSet<String>(); | |
| 5082 | |
| 5083 /** | |
| 5084 * A table mapping the id's that are defined to the tag name with that id. | |
| 5085 */ | |
| 5086 HashMap<String, String> idMap = new HashMap<String, String>(); | |
| 5087 | |
| 5088 /** | |
| 5089 * A table mapping the classes that are defined to a set of the tag names with
that class. | |
| 5090 */ | |
| 5091 HashMap<String, HashSet<String>> classMap = | |
| 5092 new HashMap<String, HashSet<String>>(); | |
| 5093 | |
| 5094 /** | |
| 5095 * Initialize a newly created HTML tag info builder. | |
| 5096 */ | |
| 5097 HtmlTagInfoBuilder(); | |
| 5098 | |
| 5099 /** | |
| 5100 * Create a tag information holder holding all of the information gathered abo
ut the tags in the | |
| 5101 * HTML structures that were visited. | |
| 5102 * | |
| 5103 * @return the information gathered about the tags in the visited HTML structu
res | |
| 5104 */ | |
| 5105 HtmlTagInfo getTagInfo() { | |
| 5106 List<String> allTags = tagSet.toList(); | |
| 5107 HashMap<String, List<String>> classToTagsMap = | |
| 5108 new HashMap<String, List<String>>(); | |
| 5109 classMap.forEach((String key, Set<String> tags) { | |
| 5110 classToTagsMap[key] = tags.toList(); | |
| 5111 }); | |
| 5112 return new HtmlTagInfo(allTags, idMap, classToTagsMap); | |
| 5113 } | |
| 5114 | |
| 5115 @override | |
| 5116 visitHtmlScriptTagNode(ht.HtmlScriptTagNode node) { | |
| 5117 visitXmlTagNode(node); | |
| 5118 } | |
| 5119 | |
| 5120 @override | |
| 5121 visitHtmlUnit(ht.HtmlUnit node) { | |
| 5122 node.visitChildren(this); | |
| 5123 } | |
| 5124 | |
| 5125 @override | |
| 5126 visitXmlAttributeNode(ht.XmlAttributeNode node) {} | |
| 5127 | |
| 5128 @override | |
| 5129 visitXmlTagNode(ht.XmlTagNode node) { | |
| 5130 node.visitChildren(this); | |
| 5131 String tagName = node.tag; | |
| 5132 tagSet.add(tagName); | |
| 5133 for (ht.XmlAttributeNode attribute in node.attributes) { | |
| 5134 String attributeName = attribute.name; | |
| 5135 if (attributeName == ID_ATTRIBUTE) { | |
| 5136 String attributeValue = attribute.text; | |
| 5137 if (attributeValue != null) { | |
| 5138 String tag = idMap[attributeValue]; | |
| 5139 if (tag == null) { | |
| 5140 idMap[attributeValue] = tagName; | |
| 5141 } else { | |
| 5142 // reportError(HtmlWarningCode.MULTIPLY_DEFINED_ID, valueToken); | |
| 5143 } | |
| 5144 } | |
| 5145 } else if (attributeName == ID_CLASS) { | |
| 5146 String attributeValue = attribute.text; | |
| 5147 if (attributeValue != null) { | |
| 5148 HashSet<String> tagList = classMap[attributeValue]; | |
| 5149 if (tagList == null) { | |
| 5150 tagList = new HashSet<String>(); | |
| 5151 classMap[attributeValue] = tagList; | |
| 5152 } else { | |
| 5153 // reportError(HtmlWarningCode.MULTIPLY_DEFINED_ID, valueToken); | |
| 5154 } | |
| 5155 tagList.add(tagName); | |
| 5156 } | |
| 5157 } | |
| 5158 } | |
| 5159 } | |
| 5160 | |
| 5161 // /** | |
| 5162 // * Report an error with the given error code at the given location. Use the
given arguments to | |
| 5163 // * compose the error message. | |
| 5164 // * | |
| 5165 // * @param errorCode the error code of the error to be reported | |
| 5166 // * @param offset the offset of the first character to be highlighted | |
| 5167 // * @param length the number of characters to be highlighted | |
| 5168 // * @param arguments the arguments used to compose the error message | |
| 5169 // */ | |
| 5170 // private void reportError(ErrorCode errorCode, Token token, Object... argumen
ts) { | |
| 5171 // errorListener.onError(new AnalysisError( | |
| 5172 // htmlElement.getSource(), | |
| 5173 // token.getOffset(), | |
| 5174 // token.getLength(), | |
| 5175 // errorCode, | |
| 5176 // arguments)); | |
| 5177 // } | |
| 5178 // | |
| 5179 // /** | |
| 5180 // * Report an error with the given error code at the given location. Use the
given arguments to | |
| 5181 // * compose the error message. | |
| 5182 // * | |
| 5183 // * @param errorCode the error code of the error to be reported | |
| 5184 // * @param offset the offset of the first character to be highlighted | |
| 5185 // * @param length the number of characters to be highlighted | |
| 5186 // * @param arguments the arguments used to compose the error message | |
| 5187 // */ | |
| 5188 // private void reportError(ErrorCode errorCode, int offset, int length, Object
... arguments) { | |
| 5189 // errorListener.onError(new AnalysisError( | |
| 5190 // htmlElement.getSource(), | |
| 5191 // offset, | |
| 5192 // length, | |
| 5193 // errorCode, | |
| 5194 // arguments)); | |
| 5195 // } | |
| 5196 } | |
| 5197 | |
| 5198 /** | |
| 5199 * Instances of the class `HtmlUnitBuilder` build an element model for a single
HTML unit. | |
| 5200 */ | |
| 5201 class HtmlUnitBuilder implements ht.XmlVisitor<Object> { | |
| 5202 static String _SRC = "src"; | |
| 5203 | |
| 5204 /** | |
| 5205 * The analysis context in which the element model will be built. | |
| 5206 */ | |
| 5207 final InternalAnalysisContext _context; | |
| 5208 | |
| 5209 /** | |
| 5210 * The error listener to which errors will be reported. | |
| 5211 */ | |
| 5212 RecordingErrorListener _errorListener; | |
| 5213 | |
| 5214 /** | |
| 5215 * The HTML element being built. | |
| 5216 */ | |
| 5217 HtmlElementImpl _htmlElement; | |
| 5218 | |
| 5219 /** | |
| 5220 * The elements in the path from the HTML unit to the current tag node. | |
| 5221 */ | |
| 5222 List<ht.XmlTagNode> _parentNodes; | |
| 5223 | |
| 5224 /** | |
| 5225 * The script elements being built. | |
| 5226 */ | |
| 5227 List<HtmlScriptElement> _scripts; | |
| 5228 | |
| 5229 /** | |
| 5230 * A set of the libraries that were resolved while resolving the HTML unit. | |
| 5231 */ | |
| 5232 Set<Library> _resolvedLibraries = new HashSet<Library>(); | |
| 5233 | |
| 5234 /** | |
| 5235 * Initialize a newly created HTML unit builder. | |
| 5236 * | |
| 5237 * @param context the analysis context in which the element model will be buil
t | |
| 5238 */ | |
| 5239 HtmlUnitBuilder(this._context) { | |
| 5240 this._errorListener = new RecordingErrorListener(); | |
| 5241 } | |
| 5242 | |
| 5243 /** | |
| 5244 * Return the listener to which analysis errors will be reported. | |
| 5245 * | |
| 5246 * @return the listener to which analysis errors will be reported | |
| 5247 */ | |
| 5248 RecordingErrorListener get errorListener => _errorListener; | |
| 5249 | |
| 5250 /** | |
| 5251 * Return an array containing information about all of the libraries that were
resolved. | |
| 5252 * | |
| 5253 * @return an array containing the libraries that were resolved | |
| 5254 */ | |
| 5255 Set<Library> get resolvedLibraries => _resolvedLibraries; | |
| 5256 | |
| 5257 /** | |
| 5258 * Build the HTML element for the given source. | |
| 5259 * | |
| 5260 * @param source the source describing the compilation unit | |
| 5261 * @param unit the AST structure representing the HTML | |
| 5262 * @throws AnalysisException if the analysis could not be performed | |
| 5263 */ | |
| 5264 HtmlElementImpl buildHtmlElement(Source source, ht.HtmlUnit unit) { | |
| 5265 HtmlElementImpl result = new HtmlElementImpl(_context, source.shortName); | |
| 5266 result.source = source; | |
| 5267 _htmlElement = result; | |
| 5268 unit.accept(this); | |
| 5269 _htmlElement = null; | |
| 5270 unit.element = result; | |
| 5271 return result; | |
| 5272 } | |
| 5273 | |
| 5274 @override | |
| 5275 Object visitHtmlScriptTagNode(ht.HtmlScriptTagNode node) { | |
| 5276 if (_parentNodes.contains(node)) { | |
| 5277 return _reportCircularity(node); | |
| 5278 } | |
| 5279 _parentNodes.add(node); | |
| 5280 try { | |
| 5281 Source htmlSource = _htmlElement.source; | |
| 5282 ht.XmlAttributeNode scriptAttribute = _getScriptSourcePath(node); | |
| 5283 String scriptSourcePath = | |
| 5284 scriptAttribute == null ? null : scriptAttribute.text; | |
| 5285 if (node.attributeEnd.type == ht.TokenType.GT && | |
| 5286 scriptSourcePath == null) { | |
| 5287 EmbeddedHtmlScriptElementImpl script = | |
| 5288 new EmbeddedHtmlScriptElementImpl(node); | |
| 5289 try { | |
| 5290 LibraryResolver resolver = new LibraryResolver(_context); | |
| 5291 LibraryElementImpl library = | |
| 5292 resolver.resolveEmbeddedLibrary(htmlSource, node.script, true); | |
| 5293 script.scriptLibrary = library; | |
| 5294 _resolvedLibraries.addAll(resolver.resolvedLibraries); | |
| 5295 _errorListener.addAll(resolver.errorListener); | |
| 5296 } on AnalysisException catch (exception, stackTrace) { | |
| 5297 //TODO (danrubel): Handle or forward the exception | |
| 5298 AnalysisEngine.instance.logger.logError( | |
| 5299 "Could not resolve script tag", | |
| 5300 new CaughtException(exception, stackTrace)); | |
| 5301 } | |
| 5302 node.scriptElement = script; | |
| 5303 _scripts.add(script); | |
| 5304 } else { | |
| 5305 ExternalHtmlScriptElementImpl script = | |
| 5306 new ExternalHtmlScriptElementImpl(node); | |
| 5307 if (scriptSourcePath != null) { | |
| 5308 try { | |
| 5309 scriptSourcePath = Uri.encodeFull(scriptSourcePath); | |
| 5310 // Force an exception to be thrown if the URI is invalid so that we | |
| 5311 // can report the problem. | |
| 5312 parseUriWithException(scriptSourcePath); | |
| 5313 Source scriptSource = | |
| 5314 _context.sourceFactory.resolveUri(htmlSource, scriptSourcePath); | |
| 5315 script.scriptSource = scriptSource; | |
| 5316 if (!_context.exists(scriptSource)) { | |
| 5317 _reportValueError(HtmlWarningCode.URI_DOES_NOT_EXIST, | |
| 5318 scriptAttribute, [scriptSourcePath]); | |
| 5319 } | |
| 5320 } on URISyntaxException { | |
| 5321 _reportValueError(HtmlWarningCode.INVALID_URI, scriptAttribute, | |
| 5322 [scriptSourcePath]); | |
| 5323 } | |
| 5324 } | |
| 5325 node.scriptElement = script; | |
| 5326 _scripts.add(script); | |
| 5327 } | |
| 5328 } finally { | |
| 5329 _parentNodes.remove(node); | |
| 5330 } | |
| 5331 return null; | |
| 5332 } | |
| 5333 | |
| 5334 @override | |
| 5335 Object visitHtmlUnit(ht.HtmlUnit node) { | |
| 5336 _parentNodes = new List<ht.XmlTagNode>(); | |
| 5337 _scripts = new List<HtmlScriptElement>(); | |
| 5338 try { | |
| 5339 node.visitChildren(this); | |
| 5340 _htmlElement.scripts = new List.from(_scripts); | |
| 5341 } finally { | |
| 5342 _scripts = null; | |
| 5343 _parentNodes = null; | |
| 5344 } | |
| 5345 return null; | |
| 5346 } | |
| 5347 | |
| 5348 @override | |
| 5349 Object visitXmlAttributeNode(ht.XmlAttributeNode node) => null; | |
| 5350 | |
| 5351 @override | |
| 5352 Object visitXmlTagNode(ht.XmlTagNode node) { | |
| 5353 if (_parentNodes.contains(node)) { | |
| 5354 return _reportCircularity(node); | |
| 5355 } | |
| 5356 _parentNodes.add(node); | |
| 5357 try { | |
| 5358 node.visitChildren(this); | |
| 5359 } finally { | |
| 5360 _parentNodes.remove(node); | |
| 5361 } | |
| 5362 return null; | |
| 5363 } | |
| 5364 | |
| 5365 /** | |
| 5366 * Return the first source attribute for the given tag node, or `null` if it d
oes not exist. | |
| 5367 * | |
| 5368 * @param node the node containing attributes | |
| 5369 * @return the source attribute contained in the given tag | |
| 5370 */ | |
| 5371 ht.XmlAttributeNode _getScriptSourcePath(ht.XmlTagNode node) { | |
| 5372 for (ht.XmlAttributeNode attribute in node.attributes) { | |
| 5373 if (attribute.name == _SRC) { | |
| 5374 return attribute; | |
| 5375 } | |
| 5376 } | |
| 5377 return null; | |
| 5378 } | |
| 5379 | |
| 5380 Object _reportCircularity(ht.XmlTagNode node) { | |
| 5381 // | |
| 5382 // This should not be possible, but we have an error report that suggests | |
| 5383 // that it happened at least once. This code will guard against infinite | |
| 5384 // recursion and might help us identify the cause of the issue. | |
| 5385 // | |
| 5386 StringBuffer buffer = new StringBuffer(); | |
| 5387 buffer.write("Found circularity in XML nodes: "); | |
| 5388 bool first = true; | |
| 5389 for (ht.XmlTagNode pathNode in _parentNodes) { | |
| 5390 if (first) { | |
| 5391 first = false; | |
| 5392 } else { | |
| 5393 buffer.write(", "); | |
| 5394 } | |
| 5395 String tagName = pathNode.tag; | |
| 5396 if (identical(pathNode, node)) { | |
| 5397 buffer.write("*"); | |
| 5398 buffer.write(tagName); | |
| 5399 buffer.write("*"); | |
| 5400 } else { | |
| 5401 buffer.write(tagName); | |
| 5402 } | |
| 5403 } | |
| 5404 AnalysisEngine.instance.logger.logError(buffer.toString()); | |
| 5405 return null; | |
| 5406 } | |
| 5407 | |
| 5408 /** | |
| 5409 * Report an error with the given error code at the given location. Use the gi
ven arguments to | |
| 5410 * compose the error message. | |
| 5411 * | |
| 5412 * @param errorCode the error code of the error to be reported | |
| 5413 * @param offset the offset of the first character to be highlighted | |
| 5414 * @param length the number of characters to be highlighted | |
| 5415 * @param arguments the arguments used to compose the error message | |
| 5416 */ | |
| 5417 void _reportErrorForOffset( | |
| 5418 ErrorCode errorCode, int offset, int length, List<Object> arguments) { | |
| 5419 _errorListener.onError(new AnalysisError( | |
| 5420 _htmlElement.source, offset, length, errorCode, arguments)); | |
| 5421 } | |
| 5422 | |
| 5423 /** | |
| 5424 * Report an error with the given error code at the location of the value of t
he given attribute. | |
| 5425 * Use the given arguments to compose the error message. | |
| 5426 * | |
| 5427 * @param errorCode the error code of the error to be reported | |
| 5428 * @param offset the offset of the first character to be highlighted | |
| 5429 * @param length the number of characters to be highlighted | |
| 5430 * @param arguments the arguments used to compose the error message | |
| 5431 */ | |
| 5432 void _reportValueError(ErrorCode errorCode, ht.XmlAttributeNode attribute, | |
| 5433 List<Object> arguments) { | |
| 5434 int offset = attribute.valueToken.offset + 1; | |
| 5435 int length = attribute.valueToken.length - 2; | |
| 5436 _reportErrorForOffset(errorCode, offset, length, arguments); | |
| 5437 } | |
| 5438 } | |
| 5439 | |
| 5440 /** | |
| 5441 * Instances of the class `ImplicitLabelScope` represent the scope statements | 5005 * Instances of the class `ImplicitLabelScope` represent the scope statements |
| 5442 * that can be the target of unlabeled break and continue statements. | 5006 * that can be the target of unlabeled break and continue statements. |
| 5443 */ | 5007 */ |
| 5444 class ImplicitLabelScope { | 5008 class ImplicitLabelScope { |
| 5445 /** | 5009 /** |
| 5446 * The implicit label scope associated with the top level of a function. | 5010 * The implicit label scope associated with the top level of a function. |
| 5447 */ | 5011 */ |
| 5448 static const ImplicitLabelScope ROOT = const ImplicitLabelScope._(null, null); | 5012 static const ImplicitLabelScope ROOT = const ImplicitLabelScope._(null, null); |
| 5449 | 5013 |
| 5450 /** | 5014 /** |
| (...skipping 1928 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7379 */ | 6943 */ |
| 7380 void setDefiningCompilationUnit(CompilationUnit unit) { | 6944 void setDefiningCompilationUnit(CompilationUnit unit) { |
| 7381 _astMap[librarySource] = unit; | 6945 _astMap[librarySource] = unit; |
| 7382 } | 6946 } |
| 7383 | 6947 |
| 7384 @override | 6948 @override |
| 7385 String toString() => librarySource.shortName; | 6949 String toString() => librarySource.shortName; |
| 7386 } | 6950 } |
| 7387 | 6951 |
| 7388 /** | 6952 /** |
| 7389 * Instances of the class `LibraryElementBuilder` build an element model for a s
ingle library. | |
| 7390 */ | |
| 7391 class LibraryElementBuilder { | |
| 7392 /** | |
| 7393 * The analysis context in which the element model will be built. | |
| 7394 */ | |
| 7395 final InternalAnalysisContext _analysisContext; | |
| 7396 | |
| 7397 /** | |
| 7398 * The listener to which errors will be reported. | |
| 7399 */ | |
| 7400 final AnalysisErrorListener _errorListener; | |
| 7401 | |
| 7402 /** | |
| 7403 * Initialize a newly created library element builder. | |
| 7404 * | |
| 7405 * @param analysisContext the analysis context in which the element model will
be built | |
| 7406 * @param errorListener the listener to which errors will be reported | |
| 7407 */ | |
| 7408 LibraryElementBuilder(this._analysisContext, this._errorListener); | |
| 7409 | |
| 7410 /** | |
| 7411 * Build the library element for the given library. | |
| 7412 * | |
| 7413 * @param library the library for which an element model is to be built | |
| 7414 * @return the library element that was built | |
| 7415 * @throws AnalysisException if the analysis could not be performed | |
| 7416 */ | |
| 7417 LibraryElementImpl buildLibrary(Library library) { | |
| 7418 CompilationUnitBuilder builder = new CompilationUnitBuilder(); | |
| 7419 Source librarySource = library.librarySource; | |
| 7420 CompilationUnit definingCompilationUnit = library.definingCompilationUnit; | |
| 7421 CompilationUnitElementImpl definingCompilationUnitElement = builder | |
| 7422 .buildCompilationUnit( | |
| 7423 librarySource, definingCompilationUnit, librarySource); | |
| 7424 NodeList<Directive> directives = definingCompilationUnit.directives; | |
| 7425 LibraryDirective libraryDirective = null; | |
| 7426 LibraryIdentifier libraryNameNode = null; | |
| 7427 bool hasPartDirective = false; | |
| 7428 FunctionElement entryPoint = | |
| 7429 _findEntryPoint(definingCompilationUnitElement); | |
| 7430 List<Directive> directivesToResolve = new List<Directive>(); | |
| 7431 List<CompilationUnitElementImpl> sourcedCompilationUnits = | |
| 7432 new List<CompilationUnitElementImpl>(); | |
| 7433 for (Directive directive in directives) { | |
| 7434 // | |
| 7435 // We do not build the elements representing the import and export | |
| 7436 // directives at this point. That is not done until we get to | |
| 7437 // LibraryResolver.buildDirectiveModels() because we need the | |
| 7438 // LibraryElements for the referenced libraries, which might not exist at | |
| 7439 // this point (due to the possibility of circular references). | |
| 7440 // | |
| 7441 if (directive is LibraryDirective) { | |
| 7442 if (libraryNameNode == null) { | |
| 7443 libraryDirective = directive; | |
| 7444 libraryNameNode = directive.name; | |
| 7445 directivesToResolve.add(directive); | |
| 7446 } | |
| 7447 } else if (directive is PartDirective) { | |
| 7448 PartDirective partDirective = directive; | |
| 7449 StringLiteral partUri = partDirective.uri; | |
| 7450 Source partSource = partDirective.source; | |
| 7451 if (_analysisContext.exists(partSource)) { | |
| 7452 hasPartDirective = true; | |
| 7453 CompilationUnit partUnit = library.getAST(partSource); | |
| 7454 CompilationUnitElementImpl part = | |
| 7455 builder.buildCompilationUnit(partSource, partUnit, librarySource); | |
| 7456 part.uriOffset = partUri.offset; | |
| 7457 part.uriEnd = partUri.end; | |
| 7458 part.uri = partDirective.uriContent; | |
| 7459 // | |
| 7460 // Validate that the part contains a part-of directive with the same | |
| 7461 // name as the library. | |
| 7462 // | |
| 7463 String partLibraryName = | |
| 7464 _getPartLibraryName(partSource, partUnit, directivesToResolve); | |
| 7465 if (partLibraryName == null) { | |
| 7466 _errorListener.onError(new AnalysisError( | |
| 7467 librarySource, | |
| 7468 partUri.offset, | |
| 7469 partUri.length, | |
| 7470 CompileTimeErrorCode.PART_OF_NON_PART, | |
| 7471 [partUri.toSource()])); | |
| 7472 } else if (libraryNameNode == null) { | |
| 7473 // TODO(brianwilkerson) Collect the names declared by the part. | |
| 7474 // If they are all the same then we can use that name as the | |
| 7475 // inferred name of the library and present it in a quick-fix. | |
| 7476 // partLibraryNames.add(partLibraryName); | |
| 7477 } else if (libraryNameNode.name != partLibraryName) { | |
| 7478 _errorListener.onError(new AnalysisError( | |
| 7479 librarySource, | |
| 7480 partUri.offset, | |
| 7481 partUri.length, | |
| 7482 StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, | |
| 7483 [libraryNameNode.name, partLibraryName])); | |
| 7484 } | |
| 7485 if (entryPoint == null) { | |
| 7486 entryPoint = _findEntryPoint(part); | |
| 7487 } | |
| 7488 directive.element = part; | |
| 7489 sourcedCompilationUnits.add(part); | |
| 7490 } | |
| 7491 } | |
| 7492 } | |
| 7493 if (hasPartDirective && libraryNameNode == null) { | |
| 7494 _errorListener.onError(new AnalysisError(librarySource, 0, 0, | |
| 7495 ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART)); | |
| 7496 } | |
| 7497 // | |
| 7498 // Create and populate the library element. | |
| 7499 // | |
| 7500 LibraryElementImpl libraryElement = new LibraryElementImpl.forNode( | |
| 7501 _analysisContext.getContextFor(librarySource), libraryNameNode); | |
| 7502 _setDocRange(libraryElement, libraryDirective); | |
| 7503 libraryElement.definingCompilationUnit = definingCompilationUnitElement; | |
| 7504 if (entryPoint != null) { | |
| 7505 libraryElement.entryPoint = entryPoint; | |
| 7506 } | |
| 7507 int sourcedUnitCount = sourcedCompilationUnits.length; | |
| 7508 libraryElement.parts = sourcedCompilationUnits; | |
| 7509 for (Directive directive in directivesToResolve) { | |
| 7510 directive.element = libraryElement; | |
| 7511 } | |
| 7512 library.libraryElement = libraryElement; | |
| 7513 if (sourcedUnitCount > 0) { | |
| 7514 _patchTopLevelAccessors(libraryElement); | |
| 7515 } | |
| 7516 return libraryElement; | |
| 7517 } | |
| 7518 | |
| 7519 /** | |
| 7520 * Build the library element for the given library. The resulting element is | |
| 7521 * stored in the [ResolvableLibrary] structure. | |
| 7522 * | |
| 7523 * @param library the library for which an element model is to be built | |
| 7524 * @throws AnalysisException if the analysis could not be performed | |
| 7525 */ | |
| 7526 void buildLibrary2(ResolvableLibrary library) { | |
| 7527 CompilationUnitBuilder builder = new CompilationUnitBuilder(); | |
| 7528 Source librarySource = library.librarySource; | |
| 7529 CompilationUnit definingCompilationUnit = library.definingCompilationUnit; | |
| 7530 CompilationUnitElementImpl definingCompilationUnitElement = builder | |
| 7531 .buildCompilationUnit( | |
| 7532 librarySource, definingCompilationUnit, librarySource); | |
| 7533 NodeList<Directive> directives = definingCompilationUnit.directives; | |
| 7534 LibraryDirective libraryDirective = null; | |
| 7535 LibraryIdentifier libraryNameNode = null; | |
| 7536 bool hasPartDirective = false; | |
| 7537 FunctionElement entryPoint = | |
| 7538 _findEntryPoint(definingCompilationUnitElement); | |
| 7539 List<Directive> directivesToResolve = new List<Directive>(); | |
| 7540 List<CompilationUnitElementImpl> sourcedCompilationUnits = | |
| 7541 new List<CompilationUnitElementImpl>(); | |
| 7542 for (Directive directive in directives) { | |
| 7543 // | |
| 7544 // We do not build the elements representing the import and export | |
| 7545 // directives at this point. That is not done until we get to | |
| 7546 // LibraryResolver.buildDirectiveModels() because we need the | |
| 7547 // LibraryElements for the referenced libraries, which might not exist at | |
| 7548 // this point (due to the possibility of circular references). | |
| 7549 // | |
| 7550 if (directive is LibraryDirective) { | |
| 7551 if (libraryNameNode == null) { | |
| 7552 libraryDirective = directive; | |
| 7553 libraryNameNode = directive.name; | |
| 7554 directivesToResolve.add(directive); | |
| 7555 } | |
| 7556 } else if (directive is PartDirective) { | |
| 7557 PartDirective partDirective = directive; | |
| 7558 StringLiteral partUri = partDirective.uri; | |
| 7559 Source partSource = partDirective.source; | |
| 7560 if (_analysisContext.exists(partSource)) { | |
| 7561 hasPartDirective = true; | |
| 7562 CompilationUnit partUnit = library.getAST(partSource); | |
| 7563 if (partUnit != null) { | |
| 7564 CompilationUnitElementImpl part = builder.buildCompilationUnit( | |
| 7565 partSource, partUnit, librarySource); | |
| 7566 part.uriOffset = partUri.offset; | |
| 7567 part.uriEnd = partUri.end; | |
| 7568 part.uri = partDirective.uriContent; | |
| 7569 // | |
| 7570 // Validate that the part contains a part-of directive with the same | |
| 7571 // name as the library. | |
| 7572 // | |
| 7573 String partLibraryName = | |
| 7574 _getPartLibraryName(partSource, partUnit, directivesToResolve); | |
| 7575 if (partLibraryName == null) { | |
| 7576 _errorListener.onError(new AnalysisError( | |
| 7577 librarySource, | |
| 7578 partUri.offset, | |
| 7579 partUri.length, | |
| 7580 CompileTimeErrorCode.PART_OF_NON_PART, | |
| 7581 [partUri.toSource()])); | |
| 7582 } else if (libraryNameNode == null) { | |
| 7583 // TODO(brianwilkerson) Collect the names declared by the part. | |
| 7584 // If they are all the same then we can use that name as the | |
| 7585 // inferred name of the library and present it in a quick-fix. | |
| 7586 // partLibraryNames.add(partLibraryName); | |
| 7587 } else if (libraryNameNode.name != partLibraryName) { | |
| 7588 _errorListener.onError(new AnalysisError( | |
| 7589 librarySource, | |
| 7590 partUri.offset, | |
| 7591 partUri.length, | |
| 7592 StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, | |
| 7593 [libraryNameNode.name, partLibraryName])); | |
| 7594 } | |
| 7595 if (entryPoint == null) { | |
| 7596 entryPoint = _findEntryPoint(part); | |
| 7597 } | |
| 7598 directive.element = part; | |
| 7599 sourcedCompilationUnits.add(part); | |
| 7600 } | |
| 7601 } | |
| 7602 } | |
| 7603 } | |
| 7604 if (hasPartDirective && libraryNameNode == null) { | |
| 7605 _errorListener.onError(new AnalysisError(librarySource, 0, 0, | |
| 7606 ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART)); | |
| 7607 } | |
| 7608 // | |
| 7609 // Create and populate the library element. | |
| 7610 // | |
| 7611 LibraryElementImpl libraryElement = new LibraryElementImpl.forNode( | |
| 7612 _analysisContext.getContextFor(librarySource), libraryNameNode); | |
| 7613 _setDocRange(libraryElement, libraryDirective); | |
| 7614 libraryElement.definingCompilationUnit = definingCompilationUnitElement; | |
| 7615 if (entryPoint != null) { | |
| 7616 libraryElement.entryPoint = entryPoint; | |
| 7617 } | |
| 7618 int sourcedUnitCount = sourcedCompilationUnits.length; | |
| 7619 libraryElement.parts = sourcedCompilationUnits; | |
| 7620 for (Directive directive in directivesToResolve) { | |
| 7621 directive.element = libraryElement; | |
| 7622 } | |
| 7623 library.libraryElement = libraryElement; | |
| 7624 if (sourcedUnitCount > 0) { | |
| 7625 _patchTopLevelAccessors(libraryElement); | |
| 7626 } | |
| 7627 } | |
| 7628 | |
| 7629 /** | |
| 7630 * Add all of the non-synthetic getters and setters defined in the given compi
lation unit that | |
| 7631 * have no corresponding accessor to one of the given collections. | |
| 7632 * | |
| 7633 * @param getters the map to which getters are to be added | |
| 7634 * @param setters the list to which setters are to be added | |
| 7635 * @param unit the compilation unit defining the accessors that are potentiall
y being added | |
| 7636 */ | |
| 7637 void _collectAccessors(HashMap<String, PropertyAccessorElement> getters, | |
| 7638 List<PropertyAccessorElement> setters, CompilationUnitElement unit) { | |
| 7639 for (PropertyAccessorElement accessor in unit.accessors) { | |
| 7640 if (accessor.isGetter) { | |
| 7641 if (!accessor.isSynthetic && accessor.correspondingSetter == null) { | |
| 7642 getters[accessor.displayName] = accessor; | |
| 7643 } | |
| 7644 } else { | |
| 7645 if (!accessor.isSynthetic && accessor.correspondingGetter == null) { | |
| 7646 setters.add(accessor); | |
| 7647 } | |
| 7648 } | |
| 7649 } | |
| 7650 } | |
| 7651 | |
| 7652 /** | |
| 7653 * Search the top-level functions defined in the given compilation unit for th
e entry point. | |
| 7654 * | |
| 7655 * @param element the compilation unit to be searched | |
| 7656 * @return the entry point that was found, or `null` if the compilation unit d
oes not define | |
| 7657 * an entry point | |
| 7658 */ | |
| 7659 FunctionElement _findEntryPoint(CompilationUnitElementImpl element) { | |
| 7660 for (FunctionElement function in element.functions) { | |
| 7661 if (function.isEntryPoint) { | |
| 7662 return function; | |
| 7663 } | |
| 7664 } | |
| 7665 return null; | |
| 7666 } | |
| 7667 | |
| 7668 /** | |
| 7669 * Return the name of the library that the given part is declared to be a part
of, or `null` | |
| 7670 * if the part does not contain a part-of directive. | |
| 7671 * | |
| 7672 * @param partSource the source representing the part | |
| 7673 * @param partUnit the AST structure of the part | |
| 7674 * @param directivesToResolve a list of directives that should be resolved to
the library being | |
| 7675 * built | |
| 7676 * @return the name of the library that the given part is declared to be a par
t of | |
| 7677 */ | |
| 7678 String _getPartLibraryName(Source partSource, CompilationUnit partUnit, | |
| 7679 List<Directive> directivesToResolve) { | |
| 7680 for (Directive directive in partUnit.directives) { | |
| 7681 if (directive is PartOfDirective) { | |
| 7682 directivesToResolve.add(directive); | |
| 7683 LibraryIdentifier libraryName = directive.libraryName; | |
| 7684 if (libraryName != null) { | |
| 7685 return libraryName.name; | |
| 7686 } | |
| 7687 } | |
| 7688 } | |
| 7689 return null; | |
| 7690 } | |
| 7691 | |
| 7692 /** | |
| 7693 * Look through all of the compilation units defined for the given library, lo
oking for getters | |
| 7694 * and setters that are defined in different compilation units but that have t
he same names. If | |
| 7695 * any are found, make sure that they have the same variable element. | |
| 7696 * | |
| 7697 * @param libraryElement the library defining the compilation units to be proc
essed | |
| 7698 */ | |
| 7699 void _patchTopLevelAccessors(LibraryElementImpl libraryElement) { | |
| 7700 HashMap<String, PropertyAccessorElement> getters = | |
| 7701 new HashMap<String, PropertyAccessorElement>(); | |
| 7702 List<PropertyAccessorElement> setters = new List<PropertyAccessorElement>(); | |
| 7703 _collectAccessors(getters, setters, libraryElement.definingCompilationUnit); | |
| 7704 for (CompilationUnitElement unit in libraryElement.parts) { | |
| 7705 _collectAccessors(getters, setters, unit); | |
| 7706 } | |
| 7707 for (PropertyAccessorElement setter in setters) { | |
| 7708 PropertyAccessorElement getter = getters[setter.displayName]; | |
| 7709 if (getter != null) { | |
| 7710 PropertyInducingElementImpl variable = | |
| 7711 getter.variable as PropertyInducingElementImpl; | |
| 7712 variable.setter = setter; | |
| 7713 (setter as PropertyAccessorElementImpl).variable = variable; | |
| 7714 } | |
| 7715 } | |
| 7716 } | |
| 7717 | |
| 7718 /** | |
| 7719 * If the given [node] has a documentation comment, remember its range | |
| 7720 * into the given [element]. | |
| 7721 */ | |
| 7722 void _setDocRange(ElementImpl element, LibraryDirective node) { | |
| 7723 if (node != null) { | |
| 7724 Comment comment = node.documentationComment; | |
| 7725 if (comment != null && comment.isDocumentation) { | |
| 7726 element.setDocRange(comment.offset, comment.length); | |
| 7727 } | |
| 7728 } | |
| 7729 } | |
| 7730 } | |
| 7731 | |
| 7732 /** | |
| 7733 * Instances of the class `LibraryImportScope` represent the scope containing al
l of the names | 6953 * Instances of the class `LibraryImportScope` represent the scope containing al
l of the names |
| 7734 * available from imported libraries. | 6954 * available from imported libraries. |
| 7735 */ | 6955 */ |
| 7736 class LibraryImportScope extends Scope { | 6956 class LibraryImportScope extends Scope { |
| 7737 /** | 6957 /** |
| 7738 * The element representing the library in which this scope is enclosed. | 6958 * The element representing the library in which this scope is enclosed. |
| 7739 */ | 6959 */ |
| 7740 final LibraryElement _definingLibrary; | 6960 final LibraryElement _definingLibrary; |
| 7741 | 6961 |
| 7742 /** | 6962 /** |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7934 } | 7154 } |
| 7935 return new MultiplyDefinedElementImpl( | 7155 return new MultiplyDefinedElementImpl( |
| 7936 _definingLibrary.context, nonSdkElements); | 7156 _definingLibrary.context, nonSdkElements); |
| 7937 } | 7157 } |
| 7938 } | 7158 } |
| 7939 | 7159 |
| 7940 /** | 7160 /** |
| 7941 * Instances of the class `LibraryResolver` are used to resolve one or more mutu
ally dependent | 7161 * Instances of the class `LibraryResolver` are used to resolve one or more mutu
ally dependent |
| 7942 * libraries within a single context. | 7162 * libraries within a single context. |
| 7943 */ | 7163 */ |
| 7944 class LibraryResolver { | |
| 7945 /** | |
| 7946 * The analysis context in which the libraries are being analyzed. | |
| 7947 */ | |
| 7948 final InternalAnalysisContext analysisContext; | |
| 7949 | |
| 7950 /** | |
| 7951 * The listener to which analysis errors will be reported, this error listener
is either | |
| 7952 * references [recordingErrorListener], or it unions the passed | |
| 7953 * [AnalysisErrorListener] with the [recordingErrorListener]. | |
| 7954 */ | |
| 7955 RecordingErrorListener _errorListener; | |
| 7956 | |
| 7957 /** | |
| 7958 * A source object representing the core library (dart:core). | |
| 7959 */ | |
| 7960 Source _coreLibrarySource; | |
| 7961 | |
| 7962 /** | |
| 7963 * A Source object representing the async library (dart:async). | |
| 7964 */ | |
| 7965 Source _asyncLibrarySource; | |
| 7966 | |
| 7967 /** | |
| 7968 * The object representing the core library. | |
| 7969 */ | |
| 7970 Library _coreLibrary; | |
| 7971 | |
| 7972 /** | |
| 7973 * The object representing the async library. | |
| 7974 */ | |
| 7975 Library _asyncLibrary; | |
| 7976 | |
| 7977 /** | |
| 7978 * The object used to access the types from the core library. | |
| 7979 */ | |
| 7980 TypeProvider _typeProvider; | |
| 7981 | |
| 7982 /** | |
| 7983 * The type system in use for the library | |
| 7984 */ | |
| 7985 TypeSystem _typeSystem; | |
| 7986 | |
| 7987 /** | |
| 7988 * A table mapping library sources to the information being maintained for tho
se libraries. | |
| 7989 */ | |
| 7990 HashMap<Source, Library> _libraryMap = new HashMap<Source, Library>(); | |
| 7991 | |
| 7992 /** | |
| 7993 * A collection containing the libraries that are being resolved together. | |
| 7994 */ | |
| 7995 Set<Library> _librariesInCycles; | |
| 7996 | |
| 7997 /** | |
| 7998 * Initialize a newly created library resolver to resolve libraries within the
given context. | |
| 7999 * | |
| 8000 * @param analysisContext the analysis context in which the library is being a
nalyzed | |
| 8001 */ | |
| 8002 LibraryResolver(this.analysisContext) { | |
| 8003 this._errorListener = new RecordingErrorListener(); | |
| 8004 _coreLibrarySource = | |
| 8005 analysisContext.sourceFactory.forUri(DartSdk.DART_CORE); | |
| 8006 _asyncLibrarySource = | |
| 8007 analysisContext.sourceFactory.forUri(DartSdk.DART_ASYNC); | |
| 8008 } | |
| 8009 | |
| 8010 /** | |
| 8011 * Return the listener to which analysis errors will be reported. | |
| 8012 * | |
| 8013 * @return the listener to which analysis errors will be reported | |
| 8014 */ | |
| 8015 RecordingErrorListener get errorListener => _errorListener; | |
| 8016 | |
| 8017 /** | |
| 8018 * Return an array containing information about all of the libraries that were
resolved. | |
| 8019 * | |
| 8020 * @return an array containing the libraries that were resolved | |
| 8021 */ | |
| 8022 Set<Library> get resolvedLibraries => _librariesInCycles; | |
| 8023 | |
| 8024 /** | |
| 8025 * The object used to access the types from the core library. | |
| 8026 */ | |
| 8027 TypeProvider get typeProvider => _typeProvider; | |
| 8028 | |
| 8029 /** | |
| 8030 * The type system in use. | |
| 8031 */ | |
| 8032 TypeSystem get typeSystem => _typeSystem; | |
| 8033 | |
| 8034 /** | |
| 8035 * Create an object to represent the information about the library defined by
the compilation unit | |
| 8036 * with the given source. | |
| 8037 * | |
| 8038 * @param librarySource the source of the library's defining compilation unit | |
| 8039 * @return the library object that was created | |
| 8040 * @throws AnalysisException if the library source is not valid | |
| 8041 */ | |
| 8042 Library createLibrary(Source librarySource) { | |
| 8043 Library library = | |
| 8044 new Library(analysisContext, _errorListener, librarySource); | |
| 8045 _libraryMap[librarySource] = library; | |
| 8046 return library; | |
| 8047 } | |
| 8048 | |
| 8049 /** | |
| 8050 * Resolve the library specified by the given source in the given context. The
library is assumed | |
| 8051 * to be embedded in the given source. | |
| 8052 * | |
| 8053 * @param librarySource the source specifying the defining compilation unit of
the library to be | |
| 8054 * resolved | |
| 8055 * @param unit the compilation unit representing the embedded library | |
| 8056 * @param fullAnalysis `true` if a full analysis should be performed | |
| 8057 * @return the element representing the resolved library | |
| 8058 * @throws AnalysisException if the library could not be resolved for some rea
son | |
| 8059 */ | |
| 8060 LibraryElement resolveEmbeddedLibrary( | |
| 8061 Source librarySource, CompilationUnit unit, bool fullAnalysis) { | |
| 8062 // | |
| 8063 // Create the objects representing the library being resolved and the core | |
| 8064 // library. | |
| 8065 // | |
| 8066 Library targetLibrary = _createLibraryWithUnit(librarySource, unit); | |
| 8067 _coreLibrary = _libraryMap[_coreLibrarySource]; | |
| 8068 if (_coreLibrary == null) { | |
| 8069 // This will only happen if the library being analyzed is the core | |
| 8070 // library. | |
| 8071 _coreLibrary = createLibrary(_coreLibrarySource); | |
| 8072 if (_coreLibrary == null) { | |
| 8073 LibraryResolver2.missingCoreLibrary( | |
| 8074 analysisContext, _coreLibrarySource); | |
| 8075 } | |
| 8076 } | |
| 8077 _asyncLibrary = _libraryMap[_asyncLibrarySource]; | |
| 8078 if (_asyncLibrary == null) { | |
| 8079 // This will only happen if the library being analyzed is the async | |
| 8080 // library. | |
| 8081 _asyncLibrary = createLibrary(_asyncLibrarySource); | |
| 8082 if (_asyncLibrary == null) { | |
| 8083 LibraryResolver2.missingAsyncLibrary( | |
| 8084 analysisContext, _asyncLibrarySource); | |
| 8085 } | |
| 8086 } | |
| 8087 // | |
| 8088 // Compute the set of libraries that need to be resolved together. | |
| 8089 // | |
| 8090 _computeEmbeddedLibraryDependencies(targetLibrary, unit); | |
| 8091 _librariesInCycles = _computeLibrariesInCycles(targetLibrary); | |
| 8092 // | |
| 8093 // Build the element models representing the libraries being resolved. | |
| 8094 // This is done in three steps: | |
| 8095 // | |
| 8096 // 1. Build the basic element models without making any connections | |
| 8097 // between elements other than the basic parent/child relationships. | |
| 8098 // This includes building the elements representing the libraries. | |
| 8099 // 2. Build the elements for the import and export directives. This | |
| 8100 // requires that we have the elements built for the referenced | |
| 8101 // libraries, but because of the possibility of circular references | |
| 8102 // needs to happen after all of the library elements have been created. | |
| 8103 // 3. Build the rest of the type model by connecting superclasses, mixins, | |
| 8104 // and interfaces. This requires that we be able to compute the names | |
| 8105 // visible in the libraries being resolved, which in turn requires that | |
| 8106 // we have resolved the import directives. | |
| 8107 // | |
| 8108 _buildElementModels(); | |
| 8109 LibraryElement coreElement = _coreLibrary.libraryElement; | |
| 8110 if (coreElement == null) { | |
| 8111 throw new AnalysisException("Could not resolve dart:core"); | |
| 8112 } | |
| 8113 LibraryElement asyncElement = _asyncLibrary.libraryElement; | |
| 8114 if (asyncElement == null) { | |
| 8115 throw new AnalysisException("Could not resolve dart:async"); | |
| 8116 } | |
| 8117 _buildDirectiveModels(); | |
| 8118 _typeProvider = new TypeProviderImpl(coreElement, asyncElement); | |
| 8119 _typeSystem = TypeSystem.create(analysisContext); | |
| 8120 _buildTypeHierarchies(); | |
| 8121 // | |
| 8122 // Perform resolution and type analysis. | |
| 8123 // | |
| 8124 // TODO(brianwilkerson) Decide whether we want to resolve all of the | |
| 8125 // libraries or whether we want to only resolve the target library. | |
| 8126 // The advantage to resolving everything is that we have already done part | |
| 8127 // of the work so we'll avoid duplicated effort. The disadvantage of | |
| 8128 // resolving everything is that we might do extra work that we don't | |
| 8129 // really care about. Another possibility is to add a parameter to this | |
| 8130 // method and punt the decision to the clients. | |
| 8131 // | |
| 8132 //if (analyzeAll) { | |
| 8133 resolveReferencesAndTypes(); | |
| 8134 //} else { | |
| 8135 // resolveReferencesAndTypes(targetLibrary); | |
| 8136 //} | |
| 8137 _performConstantEvaluation(); | |
| 8138 return targetLibrary.libraryElement; | |
| 8139 } | |
| 8140 | |
| 8141 /** | |
| 8142 * Resolve the library specified by the given source in the given context. | |
| 8143 * | |
| 8144 * Note that because Dart allows circular imports between libraries, it is pos
sible that more than | |
| 8145 * one library will need to be resolved. In such cases the error listener can
receive errors from | |
| 8146 * multiple libraries. | |
| 8147 * | |
| 8148 * @param librarySource the source specifying the defining compilation unit of
the library to be | |
| 8149 * resolved | |
| 8150 * @param fullAnalysis `true` if a full analysis should be performed | |
| 8151 * @return the element representing the resolved library | |
| 8152 * @throws AnalysisException if the library could not be resolved for some rea
son | |
| 8153 */ | |
| 8154 LibraryElement resolveLibrary(Source librarySource, bool fullAnalysis) { | |
| 8155 // | |
| 8156 // Create the object representing the library being resolved and compute | |
| 8157 // the dependency relationship. Note that all libraries depend implicitly | |
| 8158 // on core, and we inject an ersatz dependency on async, so once this is | |
| 8159 // done the core and async library elements will have been created. | |
| 8160 // | |
| 8161 Library targetLibrary = createLibrary(librarySource); | |
| 8162 _computeLibraryDependencies(targetLibrary); | |
| 8163 _coreLibrary = _libraryMap[_coreLibrarySource]; | |
| 8164 _asyncLibrary = _libraryMap[_asyncLibrarySource]; | |
| 8165 // | |
| 8166 // Compute the set of libraries that need to be resolved together. | |
| 8167 // | |
| 8168 _librariesInCycles = _computeLibrariesInCycles(targetLibrary); | |
| 8169 // | |
| 8170 // Build the element models representing the libraries being resolved. | |
| 8171 // This is done in three steps: | |
| 8172 // | |
| 8173 // 1. Build the basic element models without making any connections | |
| 8174 // between elements other than the basic parent/child relationships. | |
| 8175 // This includes building the elements representing the libraries, but | |
| 8176 // excludes members defined in enums. | |
| 8177 // 2. Build the elements for the import and export directives. This | |
| 8178 // requires that we have the elements built for the referenced | |
| 8179 // libraries, but because of the possibility of circular references | |
| 8180 // needs to happen after all of the library elements have been created. | |
| 8181 // 3. Build the members in enum declarations. | |
| 8182 // 4. Build the rest of the type model by connecting superclasses, mixins, | |
| 8183 // and interfaces. This requires that we be able to compute the names | |
| 8184 // visible in the libraries being resolved, which in turn requires that | |
| 8185 // we have resolved the import directives. | |
| 8186 // | |
| 8187 _buildElementModels(); | |
| 8188 LibraryElement coreElement = _coreLibrary.libraryElement; | |
| 8189 if (coreElement == null) { | |
| 8190 throw new AnalysisException("Could not resolve dart:core"); | |
| 8191 } | |
| 8192 LibraryElement asyncElement = _asyncLibrary.libraryElement; | |
| 8193 if (asyncElement == null) { | |
| 8194 throw new AnalysisException("Could not resolve dart:async"); | |
| 8195 } | |
| 8196 _buildDirectiveModels(); | |
| 8197 _typeProvider = new TypeProviderImpl(coreElement, asyncElement); | |
| 8198 _typeSystem = TypeSystem.create(analysisContext); | |
| 8199 _buildEnumMembers(); | |
| 8200 _buildTypeHierarchies(); | |
| 8201 // | |
| 8202 // Perform resolution and type analysis. | |
| 8203 // | |
| 8204 // TODO(brianwilkerson) Decide whether we want to resolve all of the | |
| 8205 // libraries or whether we want to only resolve the target library. The | |
| 8206 // advantage to resolving everything is that we have already done part of | |
| 8207 // the work so we'll avoid duplicated effort. The disadvantage of | |
| 8208 // resolving everything is that we might do extra work that we don't | |
| 8209 // really care about. Another possibility is to add a parameter to this | |
| 8210 // method and punt the decision to the clients. | |
| 8211 // | |
| 8212 //if (analyzeAll) { | |
| 8213 resolveReferencesAndTypes(); | |
| 8214 //} else { | |
| 8215 // resolveReferencesAndTypes(targetLibrary); | |
| 8216 //} | |
| 8217 _performConstantEvaluation(); | |
| 8218 return targetLibrary.libraryElement; | |
| 8219 } | |
| 8220 | |
| 8221 /** | |
| 8222 * Resolve the identifiers and perform type analysis in the libraries in the c
urrent cycle. | |
| 8223 * | |
| 8224 * @throws AnalysisException if any of the identifiers could not be resolved o
r if any of the | |
| 8225 * libraries could not have their types analyzed | |
| 8226 */ | |
| 8227 void resolveReferencesAndTypes() { | |
| 8228 for (Library library in _librariesInCycles) { | |
| 8229 _resolveReferencesAndTypesInLibrary(library); | |
| 8230 } | |
| 8231 } | |
| 8232 | |
| 8233 /** | |
| 8234 * Add a dependency to the given map from the referencing library to the refer
enced library. | |
| 8235 * | |
| 8236 * @param dependencyMap the map to which the dependency is to be added | |
| 8237 * @param referencingLibrary the library that references the referenced librar
y | |
| 8238 * @param referencedLibrary the library referenced by the referencing library | |
| 8239 */ | |
| 8240 void _addDependencyToMap(HashMap<Library, List<Library>> dependencyMap, | |
| 8241 Library referencingLibrary, Library referencedLibrary) { | |
| 8242 List<Library> dependentLibraries = dependencyMap[referencedLibrary]; | |
| 8243 if (dependentLibraries == null) { | |
| 8244 dependentLibraries = new List<Library>(); | |
| 8245 dependencyMap[referencedLibrary] = dependentLibraries; | |
| 8246 } | |
| 8247 dependentLibraries.add(referencingLibrary); | |
| 8248 } | |
| 8249 | |
| 8250 /** | |
| 8251 * Given a library that is part of a cycle that includes the root library, add
to the given set of | |
| 8252 * libraries all of the libraries reachable from the root library that are als
o included in the | |
| 8253 * cycle. | |
| 8254 * | |
| 8255 * @param library the library to be added to the collection of libraries in cy
cles | |
| 8256 * @param librariesInCycle a collection of the libraries that are in the cycle | |
| 8257 * @param dependencyMap a table mapping libraries to the collection of librari
es from which those | |
| 8258 * libraries are referenced | |
| 8259 */ | |
| 8260 void _addLibrariesInCycle(Library library, Set<Library> librariesInCycle, | |
| 8261 HashMap<Library, List<Library>> dependencyMap) { | |
| 8262 if (librariesInCycle.add(library)) { | |
| 8263 List<Library> dependentLibraries = dependencyMap[library]; | |
| 8264 if (dependentLibraries != null) { | |
| 8265 for (Library dependentLibrary in dependentLibraries) { | |
| 8266 _addLibrariesInCycle( | |
| 8267 dependentLibrary, librariesInCycle, dependencyMap); | |
| 8268 } | |
| 8269 } | |
| 8270 } | |
| 8271 } | |
| 8272 | |
| 8273 /** | |
| 8274 * Add the given library, and all libraries reachable from it that have not al
ready been visited, | |
| 8275 * to the given dependency map. | |
| 8276 * | |
| 8277 * @param library the library currently being added to the dependency map | |
| 8278 * @param dependencyMap the dependency map being computed | |
| 8279 * @param visitedLibraries the libraries that have already been visited, used
to prevent infinite | |
| 8280 * recursion | |
| 8281 */ | |
| 8282 void _addToDependencyMap( | |
| 8283 Library library, | |
| 8284 HashMap<Library, List<Library>> dependencyMap, | |
| 8285 Set<Library> visitedLibraries) { | |
| 8286 if (visitedLibraries.add(library)) { | |
| 8287 bool asyncFound = false; | |
| 8288 for (Library referencedLibrary in library.importsAndExports) { | |
| 8289 _addDependencyToMap(dependencyMap, library, referencedLibrary); | |
| 8290 _addToDependencyMap(referencedLibrary, dependencyMap, visitedLibraries); | |
| 8291 if (identical(referencedLibrary, _asyncLibrary)) { | |
| 8292 asyncFound = true; | |
| 8293 } | |
| 8294 } | |
| 8295 if (!library.explicitlyImportsCore && !identical(library, _coreLibrary)) { | |
| 8296 _addDependencyToMap(dependencyMap, library, _coreLibrary); | |
| 8297 } | |
| 8298 if (!asyncFound && !identical(library, _asyncLibrary)) { | |
| 8299 _addDependencyToMap(dependencyMap, library, _asyncLibrary); | |
| 8300 _addToDependencyMap(_asyncLibrary, dependencyMap, visitedLibraries); | |
| 8301 } | |
| 8302 } | |
| 8303 } | |
| 8304 | |
| 8305 /** | |
| 8306 * Build the element model representing the combinators declared by the given
directive. | |
| 8307 * | |
| 8308 * @param directive the directive that declares the combinators | |
| 8309 * @return an array containing the import combinators that were built | |
| 8310 */ | |
| 8311 List<NamespaceCombinator> _buildCombinators(NamespaceDirective directive) { | |
| 8312 List<NamespaceCombinator> combinators = new List<NamespaceCombinator>(); | |
| 8313 for (Combinator combinator in directive.combinators) { | |
| 8314 if (combinator is HideCombinator) { | |
| 8315 HideElementCombinatorImpl hide = new HideElementCombinatorImpl(); | |
| 8316 hide.hiddenNames = _getIdentifiers(combinator.hiddenNames); | |
| 8317 combinators.add(hide); | |
| 8318 } else { | |
| 8319 ShowElementCombinatorImpl show = new ShowElementCombinatorImpl(); | |
| 8320 show.offset = combinator.offset; | |
| 8321 show.end = combinator.end; | |
| 8322 show.shownNames = | |
| 8323 _getIdentifiers((combinator as ShowCombinator).shownNames); | |
| 8324 combinators.add(show); | |
| 8325 } | |
| 8326 } | |
| 8327 return combinators; | |
| 8328 } | |
| 8329 | |
| 8330 /** | |
| 8331 * Every library now has a corresponding [LibraryElement], so it is now possib
le to resolve | |
| 8332 * the import and export directives. | |
| 8333 * | |
| 8334 * @throws AnalysisException if the defining compilation unit for any of the l
ibraries could not | |
| 8335 * be accessed | |
| 8336 */ | |
| 8337 void _buildDirectiveModels() { | |
| 8338 for (Library library in _librariesInCycles) { | |
| 8339 HashMap<String, PrefixElementImpl> nameToPrefixMap = | |
| 8340 new HashMap<String, PrefixElementImpl>(); | |
| 8341 List<ImportElement> imports = new List<ImportElement>(); | |
| 8342 List<ExportElement> exports = new List<ExportElement>(); | |
| 8343 for (Directive directive in library.definingCompilationUnit.directives) { | |
| 8344 if (directive is ImportDirective) { | |
| 8345 ImportDirective importDirective = directive; | |
| 8346 String uriContent = importDirective.uriContent; | |
| 8347 if (DartUriResolver.isDartExtUri(uriContent)) { | |
| 8348 library.libraryElement.hasExtUri = true; | |
| 8349 } | |
| 8350 Source importedSource = importDirective.source; | |
| 8351 if (importedSource != null) { | |
| 8352 // The imported source will be null if the URI in the import | |
| 8353 // directive was invalid. | |
| 8354 Library importedLibrary = _libraryMap[importedSource]; | |
| 8355 if (importedLibrary != null) { | |
| 8356 ImportElementImpl importElement = | |
| 8357 new ImportElementImpl(directive.offset); | |
| 8358 StringLiteral uriLiteral = importDirective.uri; | |
| 8359 importElement.uriOffset = uriLiteral.offset; | |
| 8360 importElement.uriEnd = uriLiteral.end; | |
| 8361 importElement.uri = uriContent; | |
| 8362 importElement.deferred = importDirective.deferredKeyword != null; | |
| 8363 importElement.combinators = _buildCombinators(importDirective); | |
| 8364 LibraryElement importedLibraryElement = | |
| 8365 importedLibrary.libraryElement; | |
| 8366 if (importedLibraryElement != null) { | |
| 8367 importElement.importedLibrary = importedLibraryElement; | |
| 8368 } | |
| 8369 SimpleIdentifier prefixNode = directive.prefix; | |
| 8370 if (prefixNode != null) { | |
| 8371 importElement.prefixOffset = prefixNode.offset; | |
| 8372 String prefixName = prefixNode.name; | |
| 8373 PrefixElementImpl prefix = nameToPrefixMap[prefixName]; | |
| 8374 if (prefix == null) { | |
| 8375 prefix = new PrefixElementImpl.forNode(prefixNode); | |
| 8376 nameToPrefixMap[prefixName] = prefix; | |
| 8377 } | |
| 8378 importElement.prefix = prefix; | |
| 8379 prefixNode.staticElement = prefix; | |
| 8380 } | |
| 8381 directive.element = importElement; | |
| 8382 imports.add(importElement); | |
| 8383 if (analysisContext.computeKindOf(importedSource) != | |
| 8384 SourceKind.LIBRARY) { | |
| 8385 ErrorCode errorCode = (importElement.isDeferred | |
| 8386 ? StaticWarningCode.IMPORT_OF_NON_LIBRARY | |
| 8387 : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY); | |
| 8388 _errorListener.onError(new AnalysisError( | |
| 8389 library.librarySource, | |
| 8390 uriLiteral.offset, | |
| 8391 uriLiteral.length, | |
| 8392 errorCode, | |
| 8393 [uriLiteral.toSource()])); | |
| 8394 } | |
| 8395 } | |
| 8396 } | |
| 8397 } else if (directive is ExportDirective) { | |
| 8398 ExportDirective exportDirective = directive; | |
| 8399 Source exportedSource = exportDirective.source; | |
| 8400 if (exportedSource != null) { | |
| 8401 // The exported source will be null if the URI in the export | |
| 8402 // directive was invalid. | |
| 8403 Library exportedLibrary = _libraryMap[exportedSource]; | |
| 8404 if (exportedLibrary != null) { | |
| 8405 ExportElementImpl exportElement = | |
| 8406 new ExportElementImpl(directive.offset); | |
| 8407 StringLiteral uriLiteral = exportDirective.uri; | |
| 8408 exportElement.uriOffset = uriLiteral.offset; | |
| 8409 exportElement.uriEnd = uriLiteral.end; | |
| 8410 exportElement.uri = exportDirective.uriContent; | |
| 8411 exportElement.combinators = _buildCombinators(exportDirective); | |
| 8412 LibraryElement exportedLibraryElement = | |
| 8413 exportedLibrary.libraryElement; | |
| 8414 if (exportedLibraryElement != null) { | |
| 8415 exportElement.exportedLibrary = exportedLibraryElement; | |
| 8416 } | |
| 8417 directive.element = exportElement; | |
| 8418 exports.add(exportElement); | |
| 8419 if (analysisContext.computeKindOf(exportedSource) != | |
| 8420 SourceKind.LIBRARY) { | |
| 8421 _errorListener.onError(new AnalysisError( | |
| 8422 library.librarySource, | |
| 8423 uriLiteral.offset, | |
| 8424 uriLiteral.length, | |
| 8425 CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY, | |
| 8426 [uriLiteral.toSource()])); | |
| 8427 } | |
| 8428 } | |
| 8429 } | |
| 8430 } | |
| 8431 } | |
| 8432 Source librarySource = library.librarySource; | |
| 8433 if (!library.explicitlyImportsCore && | |
| 8434 _coreLibrarySource != librarySource) { | |
| 8435 ImportElementImpl importElement = new ImportElementImpl(-1); | |
| 8436 importElement.importedLibrary = _coreLibrary.libraryElement; | |
| 8437 importElement.synthetic = true; | |
| 8438 imports.add(importElement); | |
| 8439 } | |
| 8440 LibraryElementImpl libraryElement = library.libraryElement; | |
| 8441 libraryElement.imports = imports; | |
| 8442 libraryElement.exports = exports; | |
| 8443 if (libraryElement.entryPoint == null) { | |
| 8444 Namespace namespace = new NamespaceBuilder() | |
| 8445 .createExportNamespaceForLibrary(libraryElement); | |
| 8446 Element element = namespace.get(FunctionElement.MAIN_FUNCTION_NAME); | |
| 8447 if (element is FunctionElement) { | |
| 8448 libraryElement.entryPoint = element; | |
| 8449 } | |
| 8450 } | |
| 8451 } | |
| 8452 } | |
| 8453 | |
| 8454 /** | |
| 8455 * Build element models for all of the libraries in the current cycle. | |
| 8456 * | |
| 8457 * @throws AnalysisException if any of the element models cannot be built | |
| 8458 */ | |
| 8459 void _buildElementModels() { | |
| 8460 for (Library library in _librariesInCycles) { | |
| 8461 LibraryElementBuilder builder = | |
| 8462 new LibraryElementBuilder(analysisContext, errorListener); | |
| 8463 LibraryElementImpl libraryElement = builder.buildLibrary(library); | |
| 8464 library.libraryElement = libraryElement; | |
| 8465 } | |
| 8466 } | |
| 8467 | |
| 8468 /** | |
| 8469 * Build the members in enum declarations. This cannot be done while building
the rest of the | |
| 8470 * element model because it depends on being able to access core types, which
cannot happen until | |
| 8471 * the rest of the element model has been built (when resolving the core libra
ry). | |
| 8472 * | |
| 8473 * @throws AnalysisException if any of the enum members could not be built | |
| 8474 */ | |
| 8475 void _buildEnumMembers() { | |
| 8476 PerformanceStatistics.resolve.makeCurrentWhile(() { | |
| 8477 for (Library library in _librariesInCycles) { | |
| 8478 for (Source source in library.compilationUnitSources) { | |
| 8479 EnumMemberBuilder builder = new EnumMemberBuilder(_typeProvider); | |
| 8480 library.getAST(source).accept(builder); | |
| 8481 } | |
| 8482 } | |
| 8483 }); | |
| 8484 } | |
| 8485 | |
| 8486 /** | |
| 8487 * Resolve the type hierarchy across all of the types declared in the librarie
s in the current | |
| 8488 * cycle. | |
| 8489 * | |
| 8490 * @throws AnalysisException if any of the type hierarchies could not be resol
ved | |
| 8491 */ | |
| 8492 void _buildTypeHierarchies() { | |
| 8493 PerformanceStatistics.resolve.makeCurrentWhile(() { | |
| 8494 for (Library library in _librariesInCycles) { | |
| 8495 for (Source source in library.compilationUnitSources) { | |
| 8496 TypeResolverVisitorFactory typeResolverVisitorFactory = | |
| 8497 analysisContext.typeResolverVisitorFactory; | |
| 8498 TypeResolverVisitor visitor = (typeResolverVisitorFactory == null) | |
| 8499 ? new TypeResolverVisitor(library.libraryElement, source, | |
| 8500 _typeProvider, library.errorListener, | |
| 8501 nameScope: library.libraryScope) | |
| 8502 : typeResolverVisitorFactory(library, source, _typeProvider); | |
| 8503 library.getAST(source).accept(visitor); | |
| 8504 } | |
| 8505 library.libraryElement.createLoadLibraryFunction(_typeProvider); | |
| 8506 } | |
| 8507 }); | |
| 8508 } | |
| 8509 | |
| 8510 /** | |
| 8511 * Compute a dependency map of libraries reachable from the given library. A d
ependency map is a | |
| 8512 * table that maps individual libraries to a list of the libraries that either
import or export | |
| 8513 * those libraries. | |
| 8514 * | |
| 8515 * This map is used to compute all of the libraries involved in a cycle that i
nclude the root | |
| 8516 * library. Given that we only add libraries that are reachable from the root
library, when we | |
| 8517 * work backward we are guaranteed to only get libraries in the cycle. | |
| 8518 * | |
| 8519 * @param library the library currently being added to the dependency map | |
| 8520 */ | |
| 8521 HashMap<Library, List<Library>> _computeDependencyMap(Library library) { | |
| 8522 HashMap<Library, List<Library>> dependencyMap = | |
| 8523 new HashMap<Library, List<Library>>(); | |
| 8524 _addToDependencyMap(library, dependencyMap, new HashSet<Library>()); | |
| 8525 return dependencyMap; | |
| 8526 } | |
| 8527 | |
| 8528 /** | |
| 8529 * Recursively traverse the libraries reachable from the given library, creati
ng instances of the | |
| 8530 * class [Library] to represent them, and record the references in the library
objects. | |
| 8531 * | |
| 8532 * @param library the library to be processed to find libraries that have not
yet been traversed | |
| 8533 * @throws AnalysisException if some portion of the library graph could not be
traversed | |
| 8534 */ | |
| 8535 void _computeEmbeddedLibraryDependencies( | |
| 8536 Library library, CompilationUnit unit) { | |
| 8537 Source librarySource = library.librarySource; | |
| 8538 HashSet<Source> exportedSources = new HashSet<Source>(); | |
| 8539 HashSet<Source> importedSources = new HashSet<Source>(); | |
| 8540 for (Directive directive in unit.directives) { | |
| 8541 if (directive is ExportDirective) { | |
| 8542 Source exportSource = _resolveSource(librarySource, directive); | |
| 8543 if (exportSource != null) { | |
| 8544 exportedSources.add(exportSource); | |
| 8545 } | |
| 8546 } else if (directive is ImportDirective) { | |
| 8547 Source importSource = _resolveSource(librarySource, directive); | |
| 8548 if (importSource != null) { | |
| 8549 importedSources.add(importSource); | |
| 8550 } | |
| 8551 } | |
| 8552 } | |
| 8553 _computeLibraryDependenciesFromDirectives(library, | |
| 8554 new List.from(importedSources), new List.from(exportedSources)); | |
| 8555 } | |
| 8556 | |
| 8557 /** | |
| 8558 * Return a collection containing all of the libraries reachable from the give
n library that are | |
| 8559 * contained in a cycle that includes the given library. | |
| 8560 * | |
| 8561 * @param library the library that must be included in any cycles whose member
s are to be returned | |
| 8562 * @return all of the libraries referenced by the given library that have a ci
rcular reference | |
| 8563 * back to the given library | |
| 8564 */ | |
| 8565 Set<Library> _computeLibrariesInCycles(Library library) { | |
| 8566 HashMap<Library, List<Library>> dependencyMap = | |
| 8567 _computeDependencyMap(library); | |
| 8568 Set<Library> librariesInCycle = new HashSet<Library>(); | |
| 8569 _addLibrariesInCycle(library, librariesInCycle, dependencyMap); | |
| 8570 return librariesInCycle; | |
| 8571 } | |
| 8572 | |
| 8573 /** | |
| 8574 * Recursively traverse the libraries reachable from the given library, creati
ng instances of the | |
| 8575 * class [Library] to represent them, and record the references in the library
objects. | |
| 8576 * | |
| 8577 * @param library the library to be processed to find libraries that have not
yet been traversed | |
| 8578 * @throws AnalysisException if some portion of the library graph could not be
traversed | |
| 8579 */ | |
| 8580 void _computeLibraryDependencies(Library library) { | |
| 8581 Source librarySource = library.librarySource; | |
| 8582 _computeLibraryDependenciesFromDirectives( | |
| 8583 library, | |
| 8584 analysisContext.computeImportedLibraries(librarySource), | |
| 8585 analysisContext.computeExportedLibraries(librarySource)); | |
| 8586 } | |
| 8587 | |
| 8588 /** | |
| 8589 * Recursively traverse the libraries reachable from the given library, creati
ng instances of the | |
| 8590 * class [Library] to represent them, and record the references in the library
objects. | |
| 8591 * | |
| 8592 * @param library the library to be processed to find libraries that have not
yet been traversed | |
| 8593 * @param importedSources an array containing the sources that are imported in
to the given library | |
| 8594 * @param exportedSources an array containing the sources that are exported fr
om the given library | |
| 8595 * @throws AnalysisException if some portion of the library graph could not be
traversed | |
| 8596 */ | |
| 8597 void _computeLibraryDependenciesFromDirectives(Library library, | |
| 8598 List<Source> importedSources, List<Source> exportedSources) { | |
| 8599 List<Library> importedLibraries = new List<Library>(); | |
| 8600 bool explicitlyImportsCore = false; | |
| 8601 bool importsAsync = false; | |
| 8602 for (Source importedSource in importedSources) { | |
| 8603 if (importedSource == _coreLibrarySource) { | |
| 8604 explicitlyImportsCore = true; | |
| 8605 } | |
| 8606 if (importedSource == _asyncLibrarySource) { | |
| 8607 importsAsync = true; | |
| 8608 } | |
| 8609 Library importedLibrary = _libraryMap[importedSource]; | |
| 8610 if (importedLibrary == null) { | |
| 8611 importedLibrary = _createLibraryOrNull(importedSource); | |
| 8612 if (importedLibrary != null) { | |
| 8613 _computeLibraryDependencies(importedLibrary); | |
| 8614 } | |
| 8615 } | |
| 8616 if (importedLibrary != null) { | |
| 8617 importedLibraries.add(importedLibrary); | |
| 8618 } | |
| 8619 } | |
| 8620 library.importedLibraries = importedLibraries; | |
| 8621 List<Library> exportedLibraries = new List<Library>(); | |
| 8622 for (Source exportedSource in exportedSources) { | |
| 8623 Library exportedLibrary = _libraryMap[exportedSource]; | |
| 8624 if (exportedLibrary == null) { | |
| 8625 exportedLibrary = _createLibraryOrNull(exportedSource); | |
| 8626 if (exportedLibrary != null) { | |
| 8627 _computeLibraryDependencies(exportedLibrary); | |
| 8628 } | |
| 8629 } | |
| 8630 if (exportedLibrary != null) { | |
| 8631 exportedLibraries.add(exportedLibrary); | |
| 8632 } | |
| 8633 } | |
| 8634 library.exportedLibraries = exportedLibraries; | |
| 8635 library.explicitlyImportsCore = explicitlyImportsCore; | |
| 8636 if (!explicitlyImportsCore && _coreLibrarySource != library.librarySource) { | |
| 8637 Library importedLibrary = _libraryMap[_coreLibrarySource]; | |
| 8638 if (importedLibrary == null) { | |
| 8639 importedLibrary = _createLibraryOrNull(_coreLibrarySource); | |
| 8640 if (importedLibrary != null) { | |
| 8641 _computeLibraryDependencies(importedLibrary); | |
| 8642 } | |
| 8643 } | |
| 8644 } | |
| 8645 if (!importsAsync && _asyncLibrarySource != library.librarySource) { | |
| 8646 Library importedLibrary = _libraryMap[_asyncLibrarySource]; | |
| 8647 if (importedLibrary == null) { | |
| 8648 importedLibrary = _createLibraryOrNull(_asyncLibrarySource); | |
| 8649 if (importedLibrary != null) { | |
| 8650 _computeLibraryDependencies(importedLibrary); | |
| 8651 } | |
| 8652 } | |
| 8653 } | |
| 8654 } | |
| 8655 | |
| 8656 /** | |
| 8657 * Create an object to represent the information about the library defined by
the compilation unit | |
| 8658 * with the given source. Return the library object that was created, or `null
` if the | |
| 8659 * source is not valid. | |
| 8660 * | |
| 8661 * @param librarySource the source of the library's defining compilation unit | |
| 8662 * @return the library object that was created | |
| 8663 */ | |
| 8664 Library _createLibraryOrNull(Source librarySource) { | |
| 8665 if (!analysisContext.exists(librarySource)) { | |
| 8666 return null; | |
| 8667 } | |
| 8668 Library library = | |
| 8669 new Library(analysisContext, _errorListener, librarySource); | |
| 8670 _libraryMap[librarySource] = library; | |
| 8671 return library; | |
| 8672 } | |
| 8673 | |
| 8674 /** | |
| 8675 * Create an object to represent the information about the library defined by
the compilation unit | |
| 8676 * with the given source. | |
| 8677 * | |
| 8678 * @param librarySource the source of the library's defining compilation unit | |
| 8679 * @param unit the compilation unit that defines the library | |
| 8680 * @return the library object that was created | |
| 8681 * @throws AnalysisException if the library source is not valid | |
| 8682 */ | |
| 8683 Library _createLibraryWithUnit(Source librarySource, CompilationUnit unit) { | |
| 8684 Library library = | |
| 8685 new Library(analysisContext, _errorListener, librarySource); | |
| 8686 library.setDefiningCompilationUnit(unit); | |
| 8687 _libraryMap[librarySource] = library; | |
| 8688 return library; | |
| 8689 } | |
| 8690 | |
| 8691 /** | |
| 8692 * Return an array containing the lexical identifiers associated with the node
s in the given list. | |
| 8693 * | |
| 8694 * @param names the AST nodes representing the identifiers | |
| 8695 * @return the lexical identifiers associated with the nodes in the list | |
| 8696 */ | |
| 8697 List<String> _getIdentifiers(NodeList<SimpleIdentifier> names) { | |
| 8698 int count = names.length; | |
| 8699 List<String> identifiers = new List<String>(count); | |
| 8700 for (int i = 0; i < count; i++) { | |
| 8701 identifiers[i] = names[i].name; | |
| 8702 } | |
| 8703 return identifiers; | |
| 8704 } | |
| 8705 | |
| 8706 /** | |
| 8707 * Compute a value for all of the constants in the libraries being analyzed. | |
| 8708 */ | |
| 8709 void _performConstantEvaluation() { | |
| 8710 PerformanceStatistics.resolve.makeCurrentWhile(() { | |
| 8711 ConstantValueComputer computer = new ConstantValueComputer( | |
| 8712 analysisContext, | |
| 8713 _typeProvider, | |
| 8714 analysisContext.declaredVariables, | |
| 8715 null, | |
| 8716 _typeSystem); | |
| 8717 for (Library library in _librariesInCycles) { | |
| 8718 for (Source source in library.compilationUnitSources) { | |
| 8719 try { | |
| 8720 CompilationUnit unit = library.getAST(source); | |
| 8721 if (unit != null) { | |
| 8722 computer.add(unit, source, library.librarySource); | |
| 8723 } | |
| 8724 } on AnalysisException catch (exception, stackTrace) { | |
| 8725 AnalysisEngine.instance.logger.logError( | |
| 8726 "Internal Error: Could not access AST for ${source.fullName} dur
ing constant evaluation", | |
| 8727 new CaughtException(exception, stackTrace)); | |
| 8728 } | |
| 8729 } | |
| 8730 } | |
| 8731 computer.computeValues(); | |
| 8732 // As a temporary workaround for issue 21572, run ConstantVerifier now. | |
| 8733 // TODO(paulberry): remove this workaround once issue 21572 is fixed. | |
| 8734 for (Library library in _librariesInCycles) { | |
| 8735 for (Source source in library.compilationUnitSources) { | |
| 8736 try { | |
| 8737 CompilationUnit unit = library.getAST(source); | |
| 8738 ErrorReporter errorReporter = | |
| 8739 new ErrorReporter(_errorListener, source); | |
| 8740 ConstantVerifier constantVerifier = new ConstantVerifier( | |
| 8741 errorReporter, | |
| 8742 library.libraryElement, | |
| 8743 _typeProvider, | |
| 8744 analysisContext.declaredVariables); | |
| 8745 unit.accept(constantVerifier); | |
| 8746 } on AnalysisException catch (exception, stackTrace) { | |
| 8747 AnalysisEngine.instance.logger.logError( | |
| 8748 "Internal Error: Could not access AST for ${source.fullName} " | |
| 8749 "during constant verification", | |
| 8750 new CaughtException(exception, stackTrace)); | |
| 8751 } | |
| 8752 } | |
| 8753 } | |
| 8754 }); | |
| 8755 } | |
| 8756 | |
| 8757 /** | |
| 8758 * Resolve the identifiers and perform type analysis in the given library. | |
| 8759 * | |
| 8760 * @param library the library to be resolved | |
| 8761 * @throws AnalysisException if any of the identifiers could not be resolved o
r if the types in | |
| 8762 * the library cannot be analyzed | |
| 8763 */ | |
| 8764 void _resolveReferencesAndTypesInLibrary(Library library) { | |
| 8765 PerformanceStatistics.resolve.makeCurrentWhile(() { | |
| 8766 for (Source source in library.compilationUnitSources) { | |
| 8767 CompilationUnit ast = library.getAST(source); | |
| 8768 ast.accept(new VariableResolverVisitor(library.libraryElement, source, | |
| 8769 _typeProvider, library.errorListener, | |
| 8770 nameScope: library.libraryScope)); | |
| 8771 ResolverVisitorFactory visitorFactory = | |
| 8772 analysisContext.resolverVisitorFactory; | |
| 8773 ResolverVisitor visitor = visitorFactory != null | |
| 8774 ? visitorFactory(library, source, _typeProvider) | |
| 8775 : new ResolverVisitor(library.libraryElement, source, _typeProvider, | |
| 8776 library.errorListener, | |
| 8777 nameScope: library.libraryScope, | |
| 8778 inheritanceManager: library.inheritanceManager); | |
| 8779 ast.accept(visitor); | |
| 8780 } | |
| 8781 }); | |
| 8782 } | |
| 8783 | |
| 8784 /** | |
| 8785 * Return the result of resolving the URI of the given URI-based directive aga
inst the URI of the | |
| 8786 * given library, or `null` if the URI is not valid. | |
| 8787 * | |
| 8788 * @param librarySource the source representing the library containing the dir
ective | |
| 8789 * @param directive the directive which URI should be resolved | |
| 8790 * @return the result of resolving the URI against the URI of the library | |
| 8791 */ | |
| 8792 Source _resolveSource(Source librarySource, UriBasedDirective directive) { | |
| 8793 StringLiteral uriLiteral = directive.uri; | |
| 8794 if (uriLiteral is StringInterpolation) { | |
| 8795 return null; | |
| 8796 } | |
| 8797 String uriContent = uriLiteral.stringValue.trim(); | |
| 8798 if (uriContent == null || uriContent.isEmpty) { | |
| 8799 return null; | |
| 8800 } | |
| 8801 uriContent = Uri.encodeFull(uriContent); | |
| 8802 return analysisContext.sourceFactory.resolveUri(librarySource, uriContent); | |
| 8803 } | |
| 8804 } | |
| 8805 | 7164 |
| 8806 /** | 7165 /** |
| 8807 * Instances of the class `LibraryResolver` are used to resolve one or more mutu
ally dependent | 7166 * Instances of the class `LibraryResolver` are used to resolve one or more mutu
ally dependent |
| 8808 * libraries within a single context. | 7167 * libraries within a single context. |
| 8809 */ | 7168 */ |
| 8810 class LibraryResolver2 { | |
| 8811 /** | |
| 8812 * The analysis context in which the libraries are being analyzed. | |
| 8813 */ | |
| 8814 final InternalAnalysisContext analysisContext; | |
| 8815 | |
| 8816 /** | |
| 8817 * The listener to which analysis errors will be reported, this error listener
is either | |
| 8818 * references [recordingErrorListener], or it unions the passed | |
| 8819 * [AnalysisErrorListener] with the [recordingErrorListener]. | |
| 8820 */ | |
| 8821 RecordingErrorListener _errorListener; | |
| 8822 | |
| 8823 /** | |
| 8824 * A source object representing the core library (dart:core). | |
| 8825 */ | |
| 8826 Source _coreLibrarySource; | |
| 8827 | |
| 8828 /** | |
| 8829 * A source object representing the async library (dart:async). | |
| 8830 */ | |
| 8831 Source _asyncLibrarySource; | |
| 8832 | |
| 8833 /** | |
| 8834 * The object representing the core library. | |
| 8835 */ | |
| 8836 ResolvableLibrary _coreLibrary; | |
| 8837 | |
| 8838 /** | |
| 8839 * The object representing the async library. | |
| 8840 */ | |
| 8841 ResolvableLibrary _asyncLibrary; | |
| 8842 | |
| 8843 /** | |
| 8844 * The object used to access the types from the core library. | |
| 8845 */ | |
| 8846 TypeProvider _typeProvider; | |
| 8847 | |
| 8848 /** | |
| 8849 * The type system in use for the library | |
| 8850 */ | |
| 8851 TypeSystem _typeSystem; | |
| 8852 | |
| 8853 /** | |
| 8854 * A table mapping library sources to the information being maintained for tho
se libraries. | |
| 8855 */ | |
| 8856 HashMap<Source, ResolvableLibrary> _libraryMap = | |
| 8857 new HashMap<Source, ResolvableLibrary>(); | |
| 8858 | |
| 8859 /** | |
| 8860 * A collection containing the libraries that are being resolved together. | |
| 8861 */ | |
| 8862 List<ResolvableLibrary> _librariesInCycle; | |
| 8863 | |
| 8864 /** | |
| 8865 * Initialize a newly created library resolver to resolve libraries within the
given context. | |
| 8866 * | |
| 8867 * @param analysisContext the analysis context in which the library is being a
nalyzed | |
| 8868 */ | |
| 8869 LibraryResolver2(this.analysisContext) { | |
| 8870 this._errorListener = new RecordingErrorListener(); | |
| 8871 _coreLibrarySource = | |
| 8872 analysisContext.sourceFactory.forUri(DartSdk.DART_CORE); | |
| 8873 _asyncLibrarySource = | |
| 8874 analysisContext.sourceFactory.forUri(DartSdk.DART_ASYNC); | |
| 8875 } | |
| 8876 | |
| 8877 /** | |
| 8878 * Return the listener to which analysis errors will be reported. | |
| 8879 * | |
| 8880 * @return the listener to which analysis errors will be reported | |
| 8881 */ | |
| 8882 RecordingErrorListener get errorListener => _errorListener; | |
| 8883 | |
| 8884 /** | |
| 8885 * Return an array containing information about all of the libraries that were
resolved. | |
| 8886 * | |
| 8887 * @return an array containing the libraries that were resolved | |
| 8888 */ | |
| 8889 List<ResolvableLibrary> get resolvedLibraries => _librariesInCycle; | |
| 8890 | |
| 8891 /** | |
| 8892 * Resolve the library specified by the given source in the given context. | |
| 8893 * | |
| 8894 * Note that because Dart allows circular imports between libraries, it is pos
sible that more than | |
| 8895 * one library will need to be resolved. In such cases the error listener can
receive errors from | |
| 8896 * multiple libraries. | |
| 8897 * | |
| 8898 * @param librarySource the source specifying the defining compilation unit of
the library to be | |
| 8899 * resolved | |
| 8900 * @param fullAnalysis `true` if a full analysis should be performed | |
| 8901 * @return the element representing the resolved library | |
| 8902 * @throws AnalysisException if the library could not be resolved for some rea
son | |
| 8903 */ | |
| 8904 LibraryElement resolveLibrary( | |
| 8905 Source librarySource, List<ResolvableLibrary> librariesInCycle) { | |
| 8906 // | |
| 8907 // Build the map of libraries that are known. | |
| 8908 // | |
| 8909 this._librariesInCycle = librariesInCycle; | |
| 8910 _libraryMap = _buildLibraryMap(); | |
| 8911 ResolvableLibrary targetLibrary = _libraryMap[librarySource]; | |
| 8912 _coreLibrary = _libraryMap[_coreLibrarySource]; | |
| 8913 _asyncLibrary = _libraryMap[_asyncLibrarySource]; | |
| 8914 // | |
| 8915 // Build the element models representing the libraries being resolved. | |
| 8916 // This is done in three steps: | |
| 8917 // | |
| 8918 // 1. Build the basic element models without making any connections | |
| 8919 // between elements other than the basic parent/child relationships. | |
| 8920 // This includes building the elements representing the libraries, but | |
| 8921 // excludes members defined in enums. | |
| 8922 // 2. Build the elements for the import and export directives. This | |
| 8923 // requires that we have the elements built for the referenced | |
| 8924 // libraries, but because of the possibility of circular references | |
| 8925 // needs to happen after all of the library elements have been created. | |
| 8926 // 3. Build the members in enum declarations. | |
| 8927 // 4. Build the rest of the type model by connecting superclasses, mixins, | |
| 8928 // and interfaces. This requires that we be able to compute the names | |
| 8929 // visible in the libraries being resolved, which in turn requires that | |
| 8930 // we have resolved the import directives. | |
| 8931 // | |
| 8932 _buildElementModels(); | |
| 8933 LibraryElement coreElement = _coreLibrary.libraryElement; | |
| 8934 if (coreElement == null) { | |
| 8935 missingCoreLibrary(analysisContext, _coreLibrarySource); | |
| 8936 } | |
| 8937 LibraryElement asyncElement = _asyncLibrary.libraryElement; | |
| 8938 if (asyncElement == null) { | |
| 8939 missingAsyncLibrary(analysisContext, _asyncLibrarySource); | |
| 8940 } | |
| 8941 _buildDirectiveModels(); | |
| 8942 _typeProvider = new TypeProviderImpl(coreElement, asyncElement); | |
| 8943 _typeSystem = TypeSystem.create(analysisContext); | |
| 8944 _buildEnumMembers(); | |
| 8945 _buildTypeHierarchies(); | |
| 8946 // | |
| 8947 // Perform resolution and type analysis. | |
| 8948 // | |
| 8949 // TODO(brianwilkerson) Decide whether we want to resolve all of the | |
| 8950 // libraries or whether we want to only resolve the target library. The | |
| 8951 // advantage to resolving everything is that we have already done part of | |
| 8952 // the work so we'll avoid duplicated effort. The disadvantage of | |
| 8953 // resolving everything is that we might do extra work that we don't | |
| 8954 // really care about. Another possibility is to add a parameter to this | |
| 8955 // method and punt the decision to the clients. | |
| 8956 // | |
| 8957 //if (analyzeAll) { | |
| 8958 _resolveReferencesAndTypes(); | |
| 8959 //} else { | |
| 8960 // resolveReferencesAndTypes(targetLibrary); | |
| 8961 //} | |
| 8962 _performConstantEvaluation(); | |
| 8963 return targetLibrary.libraryElement; | |
| 8964 } | |
| 8965 | |
| 8966 /** | |
| 8967 * Build the element model representing the combinators declared by the given
directive. | |
| 8968 * | |
| 8969 * @param directive the directive that declares the combinators | |
| 8970 * @return an array containing the import combinators that were built | |
| 8971 */ | |
| 8972 List<NamespaceCombinator> _buildCombinators(NamespaceDirective directive) { | |
| 8973 List<NamespaceCombinator> combinators = new List<NamespaceCombinator>(); | |
| 8974 for (Combinator combinator in directive.combinators) { | |
| 8975 if (combinator is HideCombinator) { | |
| 8976 HideElementCombinatorImpl hide = new HideElementCombinatorImpl(); | |
| 8977 hide.hiddenNames = _getIdentifiers(combinator.hiddenNames); | |
| 8978 combinators.add(hide); | |
| 8979 } else { | |
| 8980 ShowElementCombinatorImpl show = new ShowElementCombinatorImpl(); | |
| 8981 show.offset = combinator.offset; | |
| 8982 show.end = combinator.end; | |
| 8983 show.shownNames = | |
| 8984 _getIdentifiers((combinator as ShowCombinator).shownNames); | |
| 8985 combinators.add(show); | |
| 8986 } | |
| 8987 } | |
| 8988 return combinators; | |
| 8989 } | |
| 8990 | |
| 8991 /** | |
| 8992 * Every library now has a corresponding [LibraryElement], so it is now possib
le to resolve | |
| 8993 * the import and export directives. | |
| 8994 * | |
| 8995 * @throws AnalysisException if the defining compilation unit for any of the l
ibraries could not | |
| 8996 * be accessed | |
| 8997 */ | |
| 8998 void _buildDirectiveModels() { | |
| 8999 for (ResolvableLibrary library in _librariesInCycle) { | |
| 9000 HashMap<String, PrefixElementImpl> nameToPrefixMap = | |
| 9001 new HashMap<String, PrefixElementImpl>(); | |
| 9002 List<ImportElement> imports = new List<ImportElement>(); | |
| 9003 List<ExportElement> exports = new List<ExportElement>(); | |
| 9004 for (Directive directive in library.definingCompilationUnit.directives) { | |
| 9005 if (directive is ImportDirective) { | |
| 9006 ImportDirective importDirective = directive; | |
| 9007 String uriContent = importDirective.uriContent; | |
| 9008 if (DartUriResolver.isDartExtUri(uriContent)) { | |
| 9009 library.libraryElement.hasExtUri = true; | |
| 9010 } | |
| 9011 Source importedSource = importDirective.source; | |
| 9012 if (importedSource != null && | |
| 9013 analysisContext.exists(importedSource)) { | |
| 9014 // The imported source will be null if the URI in the import | |
| 9015 // directive was invalid. | |
| 9016 ResolvableLibrary importedLibrary = _libraryMap[importedSource]; | |
| 9017 if (importedLibrary != null) { | |
| 9018 ImportElementImpl importElement = | |
| 9019 new ImportElementImpl(directive.offset); | |
| 9020 StringLiteral uriLiteral = importDirective.uri; | |
| 9021 if (uriLiteral != null) { | |
| 9022 importElement.uriOffset = uriLiteral.offset; | |
| 9023 importElement.uriEnd = uriLiteral.end; | |
| 9024 } | |
| 9025 importElement.uri = uriContent; | |
| 9026 importElement.deferred = importDirective.deferredKeyword != null; | |
| 9027 importElement.combinators = _buildCombinators(importDirective); | |
| 9028 LibraryElement importedLibraryElement = | |
| 9029 importedLibrary.libraryElement; | |
| 9030 if (importedLibraryElement != null) { | |
| 9031 importElement.importedLibrary = importedLibraryElement; | |
| 9032 } | |
| 9033 SimpleIdentifier prefixNode = directive.prefix; | |
| 9034 if (prefixNode != null) { | |
| 9035 importElement.prefixOffset = prefixNode.offset; | |
| 9036 String prefixName = prefixNode.name; | |
| 9037 PrefixElementImpl prefix = nameToPrefixMap[prefixName]; | |
| 9038 if (prefix == null) { | |
| 9039 prefix = new PrefixElementImpl.forNode(prefixNode); | |
| 9040 nameToPrefixMap[prefixName] = prefix; | |
| 9041 } | |
| 9042 importElement.prefix = prefix; | |
| 9043 prefixNode.staticElement = prefix; | |
| 9044 } | |
| 9045 directive.element = importElement; | |
| 9046 imports.add(importElement); | |
| 9047 if (analysisContext.computeKindOf(importedSource) != | |
| 9048 SourceKind.LIBRARY) { | |
| 9049 ErrorCode errorCode = (importElement.isDeferred | |
| 9050 ? StaticWarningCode.IMPORT_OF_NON_LIBRARY | |
| 9051 : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY); | |
| 9052 _errorListener.onError(new AnalysisError( | |
| 9053 library.librarySource, | |
| 9054 uriLiteral.offset, | |
| 9055 uriLiteral.length, | |
| 9056 errorCode, | |
| 9057 [uriLiteral.toSource()])); | |
| 9058 } | |
| 9059 } | |
| 9060 } | |
| 9061 } else if (directive is ExportDirective) { | |
| 9062 ExportDirective exportDirective = directive; | |
| 9063 Source exportedSource = exportDirective.source; | |
| 9064 if (exportedSource != null && | |
| 9065 analysisContext.exists(exportedSource)) { | |
| 9066 // The exported source will be null if the URI in the export | |
| 9067 // directive was invalid. | |
| 9068 ResolvableLibrary exportedLibrary = _libraryMap[exportedSource]; | |
| 9069 if (exportedLibrary != null) { | |
| 9070 ExportElementImpl exportElement = | |
| 9071 new ExportElementImpl(directive.offset); | |
| 9072 StringLiteral uriLiteral = exportDirective.uri; | |
| 9073 if (uriLiteral != null) { | |
| 9074 exportElement.uriOffset = uriLiteral.offset; | |
| 9075 exportElement.uriEnd = uriLiteral.end; | |
| 9076 } | |
| 9077 exportElement.uri = exportDirective.uriContent; | |
| 9078 exportElement.combinators = _buildCombinators(exportDirective); | |
| 9079 LibraryElement exportedLibraryElement = | |
| 9080 exportedLibrary.libraryElement; | |
| 9081 if (exportedLibraryElement != null) { | |
| 9082 exportElement.exportedLibrary = exportedLibraryElement; | |
| 9083 } | |
| 9084 directive.element = exportElement; | |
| 9085 exports.add(exportElement); | |
| 9086 if (analysisContext.computeKindOf(exportedSource) != | |
| 9087 SourceKind.LIBRARY) { | |
| 9088 _errorListener.onError(new AnalysisError( | |
| 9089 library.librarySource, | |
| 9090 uriLiteral.offset, | |
| 9091 uriLiteral.length, | |
| 9092 CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY, | |
| 9093 [uriLiteral.toSource()])); | |
| 9094 } | |
| 9095 } | |
| 9096 } | |
| 9097 } | |
| 9098 } | |
| 9099 Source librarySource = library.librarySource; | |
| 9100 if (!library.explicitlyImportsCore && | |
| 9101 _coreLibrarySource != librarySource) { | |
| 9102 ImportElementImpl importElement = new ImportElementImpl(-1); | |
| 9103 importElement.importedLibrary = _coreLibrary.libraryElement; | |
| 9104 importElement.synthetic = true; | |
| 9105 imports.add(importElement); | |
| 9106 } | |
| 9107 LibraryElementImpl libraryElement = library.libraryElement; | |
| 9108 libraryElement.imports = imports; | |
| 9109 libraryElement.exports = exports; | |
| 9110 if (libraryElement.entryPoint == null) { | |
| 9111 Namespace namespace = new NamespaceBuilder() | |
| 9112 .createExportNamespaceForLibrary(libraryElement); | |
| 9113 Element element = namespace.get(FunctionElement.MAIN_FUNCTION_NAME); | |
| 9114 if (element is FunctionElement) { | |
| 9115 libraryElement.entryPoint = element; | |
| 9116 } | |
| 9117 } | |
| 9118 } | |
| 9119 } | |
| 9120 | |
| 9121 /** | |
| 9122 * Build element models for all of the libraries in the current cycle. | |
| 9123 * | |
| 9124 * @throws AnalysisException if any of the element models cannot be built | |
| 9125 */ | |
| 9126 void _buildElementModels() { | |
| 9127 for (ResolvableLibrary library in _librariesInCycle) { | |
| 9128 LibraryElementBuilder builder = | |
| 9129 new LibraryElementBuilder(analysisContext, errorListener); | |
| 9130 builder.buildLibrary2(library); | |
| 9131 } | |
| 9132 } | |
| 9133 | |
| 9134 /** | |
| 9135 * Build the members in enum declarations. This cannot be done while building
the rest of the | |
| 9136 * element model because it depends on being able to access core types, which
cannot happen until | |
| 9137 * the rest of the element model has been built (when resolving the core libra
ry). | |
| 9138 * | |
| 9139 * @throws AnalysisException if any of the enum members could not be built | |
| 9140 */ | |
| 9141 void _buildEnumMembers() { | |
| 9142 PerformanceStatistics.resolve.makeCurrentWhile(() { | |
| 9143 for (ResolvableLibrary library in _librariesInCycle) { | |
| 9144 for (Source source in library.compilationUnitSources) { | |
| 9145 EnumMemberBuilder builder = new EnumMemberBuilder(_typeProvider); | |
| 9146 library.getAST(source).accept(builder); | |
| 9147 } | |
| 9148 } | |
| 9149 }); | |
| 9150 } | |
| 9151 | |
| 9152 HashMap<Source, ResolvableLibrary> _buildLibraryMap() { | |
| 9153 HashMap<Source, ResolvableLibrary> libraryMap = | |
| 9154 new HashMap<Source, ResolvableLibrary>(); | |
| 9155 int libraryCount = _librariesInCycle.length; | |
| 9156 for (int i = 0; i < libraryCount; i++) { | |
| 9157 ResolvableLibrary library = _librariesInCycle[i]; | |
| 9158 library.errorListener = _errorListener; | |
| 9159 libraryMap[library.librarySource] = library; | |
| 9160 List<ResolvableLibrary> dependencies = library.importsAndExports; | |
| 9161 int dependencyCount = dependencies.length; | |
| 9162 for (int j = 0; j < dependencyCount; j++) { | |
| 9163 ResolvableLibrary dependency = dependencies[j]; | |
| 9164 //dependency.setErrorListener(errorListener); | |
| 9165 libraryMap[dependency.librarySource] = dependency; | |
| 9166 } | |
| 9167 } | |
| 9168 return libraryMap; | |
| 9169 } | |
| 9170 | |
| 9171 /** | |
| 9172 * Resolve the type hierarchy across all of the types declared in the librarie
s in the current | |
| 9173 * cycle. | |
| 9174 * | |
| 9175 * @throws AnalysisException if any of the type hierarchies could not be resol
ved | |
| 9176 */ | |
| 9177 void _buildTypeHierarchies() { | |
| 9178 PerformanceStatistics.resolve.makeCurrentWhile(() { | |
| 9179 for (ResolvableLibrary library in _librariesInCycle) { | |
| 9180 for (ResolvableCompilationUnit unit | |
| 9181 in library.resolvableCompilationUnits) { | |
| 9182 Source source = unit.source; | |
| 9183 CompilationUnit ast = unit.compilationUnit; | |
| 9184 TypeResolverVisitor visitor = new TypeResolverVisitor( | |
| 9185 library.libraryElement, | |
| 9186 source, | |
| 9187 _typeProvider, | |
| 9188 library.libraryScope.errorListener, | |
| 9189 nameScope: library.libraryScope); | |
| 9190 ast.accept(visitor); | |
| 9191 } | |
| 9192 library.libraryElement.createLoadLibraryFunction(_typeProvider); | |
| 9193 } | |
| 9194 }); | |
| 9195 } | |
| 9196 | |
| 9197 /** | |
| 9198 * Return an array containing the lexical identifiers associated with the node
s in the given list. | |
| 9199 * | |
| 9200 * @param names the AST nodes representing the identifiers | |
| 9201 * @return the lexical identifiers associated with the nodes in the list | |
| 9202 */ | |
| 9203 List<String> _getIdentifiers(NodeList<SimpleIdentifier> names) { | |
| 9204 int count = names.length; | |
| 9205 List<String> identifiers = new List<String>(count); | |
| 9206 for (int i = 0; i < count; i++) { | |
| 9207 identifiers[i] = names[i].name; | |
| 9208 } | |
| 9209 return identifiers; | |
| 9210 } | |
| 9211 | |
| 9212 /** | |
| 9213 * Compute a value for all of the constants in the libraries being analyzed. | |
| 9214 */ | |
| 9215 void _performConstantEvaluation() { | |
| 9216 PerformanceStatistics.resolve.makeCurrentWhile(() { | |
| 9217 ConstantValueComputer computer = new ConstantValueComputer( | |
| 9218 analysisContext, | |
| 9219 _typeProvider, | |
| 9220 analysisContext.declaredVariables, | |
| 9221 null, | |
| 9222 _typeSystem); | |
| 9223 for (ResolvableLibrary library in _librariesInCycle) { | |
| 9224 for (ResolvableCompilationUnit unit | |
| 9225 in library.resolvableCompilationUnits) { | |
| 9226 CompilationUnit ast = unit.compilationUnit; | |
| 9227 if (ast != null) { | |
| 9228 computer.add(ast, unit.source, library.librarySource); | |
| 9229 } | |
| 9230 } | |
| 9231 } | |
| 9232 computer.computeValues(); | |
| 9233 // As a temporary workaround for issue 21572, run ConstantVerifier now. | |
| 9234 // TODO(paulberry): remove this workaround once issue 21572 is fixed. | |
| 9235 for (ResolvableLibrary library in _librariesInCycle) { | |
| 9236 for (ResolvableCompilationUnit unit | |
| 9237 in library.resolvableCompilationUnits) { | |
| 9238 CompilationUnit ast = unit.compilationUnit; | |
| 9239 ErrorReporter errorReporter = | |
| 9240 new ErrorReporter(_errorListener, unit.source); | |
| 9241 ConstantVerifier constantVerifier = new ConstantVerifier( | |
| 9242 errorReporter, | |
| 9243 library.libraryElement, | |
| 9244 _typeProvider, | |
| 9245 analysisContext.declaredVariables); | |
| 9246 ast.accept(constantVerifier); | |
| 9247 } | |
| 9248 } | |
| 9249 }); | |
| 9250 } | |
| 9251 | |
| 9252 /** | |
| 9253 * Resolve the identifiers and perform type analysis in the libraries in the c
urrent cycle. | |
| 9254 * | |
| 9255 * @throws AnalysisException if any of the identifiers could not be resolved o
r if any of the | |
| 9256 * libraries could not have their types analyzed | |
| 9257 */ | |
| 9258 void _resolveReferencesAndTypes() { | |
| 9259 for (ResolvableLibrary library in _librariesInCycle) { | |
| 9260 _resolveReferencesAndTypesInLibrary(library); | |
| 9261 } | |
| 9262 } | |
| 9263 | |
| 9264 /** | |
| 9265 * Resolve the identifiers and perform type analysis in the given library. | |
| 9266 * | |
| 9267 * @param library the library to be resolved | |
| 9268 * @throws AnalysisException if any of the identifiers could not be resolved o
r if the types in | |
| 9269 * the library cannot be analyzed | |
| 9270 */ | |
| 9271 void _resolveReferencesAndTypesInLibrary(ResolvableLibrary library) { | |
| 9272 PerformanceStatistics.resolve.makeCurrentWhile(() { | |
| 9273 for (ResolvableCompilationUnit unit | |
| 9274 in library.resolvableCompilationUnits) { | |
| 9275 Source source = unit.source; | |
| 9276 CompilationUnit ast = unit.compilationUnit; | |
| 9277 ast.accept(new VariableResolverVisitor(library.libraryElement, source, | |
| 9278 _typeProvider, library.libraryScope.errorListener, | |
| 9279 nameScope: library.libraryScope)); | |
| 9280 ResolverVisitor visitor = new ResolverVisitor(library.libraryElement, | |
| 9281 source, _typeProvider, library._libraryScope.errorListener, | |
| 9282 nameScope: library._libraryScope, | |
| 9283 inheritanceManager: library.inheritanceManager); | |
| 9284 ast.accept(visitor); | |
| 9285 } | |
| 9286 }); | |
| 9287 } | |
| 9288 | |
| 9289 /** | |
| 9290 * Report that the async library could not be resolved in the given | |
| 9291 * [analysisContext] and throw an exception. [asyncLibrarySource] is the sour
ce | |
| 9292 * representing the async library. | |
| 9293 */ | |
| 9294 static void missingAsyncLibrary( | |
| 9295 AnalysisContext analysisContext, Source asyncLibrarySource) { | |
| 9296 throw new AnalysisException("Could not resolve dart:async"); | |
| 9297 } | |
| 9298 | |
| 9299 /** | |
| 9300 * Report that the core library could not be resolved in the given analysis co
ntext and throw an | |
| 9301 * exception. | |
| 9302 * | |
| 9303 * @param analysisContext the analysis context in which the failure occurred | |
| 9304 * @param coreLibrarySource the source representing the core library | |
| 9305 * @throws AnalysisException always | |
| 9306 */ | |
| 9307 static void missingCoreLibrary( | |
| 9308 AnalysisContext analysisContext, Source coreLibrarySource) { | |
| 9309 throw new AnalysisException("Could not resolve dart:core"); | |
| 9310 } | |
| 9311 } | |
| 9312 | 7169 |
| 9313 /** | 7170 /** |
| 9314 * Instances of the class `LibraryScope` implement a scope containing all of the
names defined | 7171 * Instances of the class `LibraryScope` implement a scope containing all of the
names defined |
| 9315 * in a given library. | 7172 * in a given library. |
| 9316 */ | 7173 */ |
| 9317 class LibraryScope extends EnclosedScope { | 7174 class LibraryScope extends EnclosedScope { |
| 9318 /** | 7175 /** |
| 9319 * Initialize a newly created scope representing the names defined in the give
n library. | 7176 * Initialize a newly created scope representing the names defined in the give
n library. |
| 9320 * | 7177 * |
| 9321 * @param definingLibrary the element representing the library represented by
this scope | 7178 * @param definingLibrary the element representing the library represented by
this scope |
| (...skipping 956 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10278 static const RedirectingConstructorKind NORMAL = | 8135 static const RedirectingConstructorKind NORMAL = |
| 10279 const RedirectingConstructorKind('NORMAL', 1); | 8136 const RedirectingConstructorKind('NORMAL', 1); |
| 10280 | 8137 |
| 10281 static const List<RedirectingConstructorKind> values = const [CONST, NORMAL]; | 8138 static const List<RedirectingConstructorKind> values = const [CONST, NORMAL]; |
| 10282 | 8139 |
| 10283 const RedirectingConstructorKind(String name, int ordinal) | 8140 const RedirectingConstructorKind(String name, int ordinal) |
| 10284 : super(name, ordinal); | 8141 : super(name, ordinal); |
| 10285 } | 8142 } |
| 10286 | 8143 |
| 10287 /** | 8144 /** |
| 10288 * A `ResolvableLibrary` represents a single library during the resolution of | |
| 10289 * some (possibly different) library. They are not intended to be used except | |
| 10290 * during the resolution process. | |
| 10291 */ | |
| 10292 class ResolvableLibrary { | |
| 10293 /** | |
| 10294 * An empty array that can be used to initialize lists of libraries. | |
| 10295 */ | |
| 10296 static List<ResolvableLibrary> _EMPTY_ARRAY = new List<ResolvableLibrary>(0); | |
| 10297 | |
| 10298 /** | |
| 10299 * The next artificial hash code. | |
| 10300 */ | |
| 10301 static int _NEXT_HASH_CODE = 0; | |
| 10302 | |
| 10303 /** | |
| 10304 * The artifitial hash code for this object. | |
| 10305 */ | |
| 10306 final int _hashCode = _nextHashCode(); | |
| 10307 | |
| 10308 /** | |
| 10309 * The source specifying the defining compilation unit of this library. | |
| 10310 */ | |
| 10311 final Source librarySource; | |
| 10312 | |
| 10313 /** | |
| 10314 * A list containing all of the libraries that are imported into this library. | |
| 10315 */ | |
| 10316 List<ResolvableLibrary> _importedLibraries = _EMPTY_ARRAY; | |
| 10317 | |
| 10318 /** | |
| 10319 * A flag indicating whether this library explicitly imports core. | |
| 10320 */ | |
| 10321 bool explicitlyImportsCore = false; | |
| 10322 | |
| 10323 /** | |
| 10324 * An array containing all of the libraries that are exported from this librar
y. | |
| 10325 */ | |
| 10326 List<ResolvableLibrary> _exportedLibraries = _EMPTY_ARRAY; | |
| 10327 | |
| 10328 /** | |
| 10329 * An array containing the compilation units that comprise this library. The | |
| 10330 * defining compilation unit is always first. | |
| 10331 */ | |
| 10332 List<ResolvableCompilationUnit> _compilationUnits; | |
| 10333 | |
| 10334 /** | |
| 10335 * The library element representing this library. | |
| 10336 */ | |
| 10337 LibraryElementImpl _libraryElement; | |
| 10338 | |
| 10339 /** | |
| 10340 * The listener to which analysis errors will be reported. | |
| 10341 */ | |
| 10342 AnalysisErrorListener _errorListener; | |
| 10343 | |
| 10344 /** | |
| 10345 * The inheritance manager which is used for member lookups in this library. | |
| 10346 */ | |
| 10347 InheritanceManager _inheritanceManager; | |
| 10348 | |
| 10349 /** | |
| 10350 * The library scope used when resolving elements within this library's compil
ation units. | |
| 10351 */ | |
| 10352 LibraryScope _libraryScope; | |
| 10353 | |
| 10354 /** | |
| 10355 * Initialize a newly created data holder that can maintain the data associate
d with a library. | |
| 10356 * | |
| 10357 * @param librarySource the source specifying the defining compilation unit of
this library | |
| 10358 * @param errorListener the listener to which analysis errors will be reported | |
| 10359 */ | |
| 10360 ResolvableLibrary(this.librarySource); | |
| 10361 | |
| 10362 /** | |
| 10363 * Return an array of the [CompilationUnit]s that make up the library. The fir
st unit is | |
| 10364 * always the defining unit. | |
| 10365 * | |
| 10366 * @return an array of the [CompilationUnit]s that make up the library. The fi
rst unit is | |
| 10367 * always the defining unit | |
| 10368 */ | |
| 10369 List<CompilationUnit> get compilationUnits { | |
| 10370 int count = _compilationUnits.length; | |
| 10371 List<CompilationUnit> units = new List<CompilationUnit>(count); | |
| 10372 for (int i = 0; i < count; i++) { | |
| 10373 units[i] = _compilationUnits[i].compilationUnit; | |
| 10374 } | |
| 10375 return units; | |
| 10376 } | |
| 10377 | |
| 10378 /** | |
| 10379 * Return an array containing the sources for the compilation units in this li
brary, including the | |
| 10380 * defining compilation unit. | |
| 10381 * | |
| 10382 * @return the sources for the compilation units in this library | |
| 10383 */ | |
| 10384 List<Source> get compilationUnitSources { | |
| 10385 int count = _compilationUnits.length; | |
| 10386 List<Source> sources = new List<Source>(count); | |
| 10387 for (int i = 0; i < count; i++) { | |
| 10388 sources[i] = _compilationUnits[i].source; | |
| 10389 } | |
| 10390 return sources; | |
| 10391 } | |
| 10392 | |
| 10393 /** | |
| 10394 * Return the AST structure associated with the defining compilation unit for
this library. | |
| 10395 * | |
| 10396 * @return the AST structure associated with the defining compilation unit for
this library | |
| 10397 * @throws AnalysisException if an AST structure could not be created for the
defining compilation | |
| 10398 * unit | |
| 10399 */ | |
| 10400 CompilationUnit get definingCompilationUnit => | |
| 10401 _compilationUnits[0].compilationUnit; | |
| 10402 | |
| 10403 /** | |
| 10404 * Set the listener to which analysis errors will be reported to be the given
listener. | |
| 10405 * | |
| 10406 * @param errorListener the listener to which analysis errors will be reported | |
| 10407 */ | |
| 10408 void set errorListener(AnalysisErrorListener errorListener) { | |
| 10409 this._errorListener = errorListener; | |
| 10410 } | |
| 10411 | |
| 10412 /** | |
| 10413 * Set the libraries that are exported by this library to be those in the give
n array. | |
| 10414 * | |
| 10415 * @param exportedLibraries the libraries that are exported by this library | |
| 10416 */ | |
| 10417 void set exportedLibraries(List<ResolvableLibrary> exportedLibraries) { | |
| 10418 this._exportedLibraries = exportedLibraries; | |
| 10419 } | |
| 10420 | |
| 10421 /** | |
| 10422 * Return an array containing the libraries that are exported from this librar
y. | |
| 10423 * | |
| 10424 * @return an array containing the libraries that are exported from this libra
ry | |
| 10425 */ | |
| 10426 List<ResolvableLibrary> get exports => _exportedLibraries; | |
| 10427 | |
| 10428 @override | |
| 10429 int get hashCode => _hashCode; | |
| 10430 | |
| 10431 /** | |
| 10432 * Set the libraries that are imported into this library to be those in the gi
ven array. | |
| 10433 * | |
| 10434 * @param importedLibraries the libraries that are imported into this library | |
| 10435 */ | |
| 10436 void set importedLibraries(List<ResolvableLibrary> importedLibraries) { | |
| 10437 this._importedLibraries = importedLibraries; | |
| 10438 } | |
| 10439 | |
| 10440 /** | |
| 10441 * Return an array containing the libraries that are imported into this librar
y. | |
| 10442 * | |
| 10443 * @return an array containing the libraries that are imported into this libra
ry | |
| 10444 */ | |
| 10445 List<ResolvableLibrary> get imports => _importedLibraries; | |
| 10446 | |
| 10447 /** | |
| 10448 * Return an array containing the libraries that are either imported or export
ed from this | |
| 10449 * library. | |
| 10450 * | |
| 10451 * @return the libraries that are either imported or exported from this librar
y | |
| 10452 */ | |
| 10453 List<ResolvableLibrary> get importsAndExports { | |
| 10454 HashSet<ResolvableLibrary> libraries = new HashSet<ResolvableLibrary>(); | |
| 10455 for (ResolvableLibrary library in _importedLibraries) { | |
| 10456 libraries.add(library); | |
| 10457 } | |
| 10458 for (ResolvableLibrary library in _exportedLibraries) { | |
| 10459 libraries.add(library); | |
| 10460 } | |
| 10461 return new List.from(libraries); | |
| 10462 } | |
| 10463 | |
| 10464 /** | |
| 10465 * Return the inheritance manager for this library. | |
| 10466 * | |
| 10467 * @return the inheritance manager for this library | |
| 10468 */ | |
| 10469 InheritanceManager get inheritanceManager { | |
| 10470 if (_inheritanceManager == null) { | |
| 10471 return _inheritanceManager = new InheritanceManager(_libraryElement); | |
| 10472 } | |
| 10473 return _inheritanceManager; | |
| 10474 } | |
| 10475 | |
| 10476 /** | |
| 10477 * Return the library element representing this library, creating it if necess
ary. | |
| 10478 * | |
| 10479 * @return the library element representing this library | |
| 10480 */ | |
| 10481 LibraryElementImpl get libraryElement => _libraryElement; | |
| 10482 | |
| 10483 /** | |
| 10484 * Set the library element representing this library to the given library elem
ent. | |
| 10485 * | |
| 10486 * @param libraryElement the library element representing this library | |
| 10487 */ | |
| 10488 void set libraryElement(LibraryElementImpl libraryElement) { | |
| 10489 this._libraryElement = libraryElement; | |
| 10490 if (_inheritanceManager != null) { | |
| 10491 _inheritanceManager.libraryElement = libraryElement; | |
| 10492 } | |
| 10493 } | |
| 10494 | |
| 10495 /** | |
| 10496 * Return the library scope used when resolving elements within this library's
compilation units. | |
| 10497 * | |
| 10498 * @return the library scope used when resolving elements within this library'
s compilation units | |
| 10499 */ | |
| 10500 LibraryScope get libraryScope { | |
| 10501 if (_libraryScope == null) { | |
| 10502 _libraryScope = new LibraryScope(_libraryElement, _errorListener); | |
| 10503 } | |
| 10504 return _libraryScope; | |
| 10505 } | |
| 10506 | |
| 10507 /** | |
| 10508 * Return an array containing the compilation units that comprise this library
. The defining | |
| 10509 * compilation unit is always first. | |
| 10510 * | |
| 10511 * @return the compilation units that comprise this library | |
| 10512 */ | |
| 10513 List<ResolvableCompilationUnit> get resolvableCompilationUnits => | |
| 10514 _compilationUnits; | |
| 10515 | |
| 10516 /** | |
| 10517 * Set the compilation unit in this library to the given compilation units. Th
e defining | |
| 10518 * compilation unit must be the first element of the array. | |
| 10519 * | |
| 10520 * @param units the compilation units in this library | |
| 10521 */ | |
| 10522 void set resolvableCompilationUnits(List<ResolvableCompilationUnit> units) { | |
| 10523 _compilationUnits = units; | |
| 10524 } | |
| 10525 | |
| 10526 /** | |
| 10527 * Return the AST structure associated with the given source, or `null` if the
source does | |
| 10528 * not represent a compilation unit that is included in this library. | |
| 10529 * | |
| 10530 * @param source the source representing the compilation unit whose AST is to
be returned | |
| 10531 * @return the AST structure associated with the given source | |
| 10532 * @throws AnalysisException if an AST structure could not be created for the
compilation unit | |
| 10533 */ | |
| 10534 CompilationUnit getAST(Source source) { | |
| 10535 int count = _compilationUnits.length; | |
| 10536 for (int i = 0; i < count; i++) { | |
| 10537 if (_compilationUnits[i].source == source) { | |
| 10538 return _compilationUnits[i].compilationUnit; | |
| 10539 } | |
| 10540 } | |
| 10541 return null; | |
| 10542 } | |
| 10543 | |
| 10544 @override | |
| 10545 String toString() => librarySource.shortName; | |
| 10546 | |
| 10547 static int _nextHashCode() { | |
| 10548 int next = (_NEXT_HASH_CODE + 1) & 0xFFFFFF; | |
| 10549 _NEXT_HASH_CODE = next; | |
| 10550 return next; | |
| 10551 } | |
| 10552 } | |
| 10553 | |
| 10554 /** | |
| 10555 * The enumeration `ResolverErrorCode` defines the error codes used for errors | 8145 * The enumeration `ResolverErrorCode` defines the error codes used for errors |
| 10556 * detected by the resolver. The convention for this class is for the name of | 8146 * detected by the resolver. The convention for this class is for the name of |
| 10557 * the error code to indicate the problem that caused the error to be generated | 8147 * the error code to indicate the problem that caused the error to be generated |
| 10558 * and for the error message to explain what is wrong and, when appropriate, how | 8148 * and for the error message to explain what is wrong and, when appropriate, how |
| 10559 * the problem can be corrected. | 8149 * the problem can be corrected. |
| 10560 */ | 8150 */ |
| 10561 class ResolverErrorCode extends ErrorCode { | 8151 class ResolverErrorCode extends ErrorCode { |
| 10562 static const ResolverErrorCode BREAK_LABEL_ON_SWITCH_MEMBER = | 8152 static const ResolverErrorCode BREAK_LABEL_ON_SWITCH_MEMBER = |
| 10563 const ResolverErrorCode('BREAK_LABEL_ON_SWITCH_MEMBER', | 8153 const ResolverErrorCode('BREAK_LABEL_ON_SWITCH_MEMBER', |
| 10564 "Break label resolves to case or default statement"); | 8154 "Break label resolves to case or default statement"); |
| (...skipping 5494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16059 nonFields.add(node); | 13649 nonFields.add(node); |
| 16060 return null; | 13650 return null; |
| 16061 } | 13651 } |
| 16062 | 13652 |
| 16063 @override | 13653 @override |
| 16064 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); | 13654 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); |
| 16065 | 13655 |
| 16066 @override | 13656 @override |
| 16067 Object visitWithClause(WithClause node) => null; | 13657 Object visitWithClause(WithClause node) => null; |
| 16068 } | 13658 } |
| OLD | NEW |