| 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_test; | 5 library analyzer.test.generated.resolver_test; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/src/context/context.dart' as newContext; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/src/generated/ast.dart'; | 10 import 'package:analyzer/dart/ast/token.dart'; |
| 11 import 'package:analyzer/src/generated/element.dart'; | 11 import 'package:analyzer/dart/ast/visitor.dart'; |
| 12 import 'package:analyzer/src/generated/element_resolver.dart'; | 12 import 'package:analyzer/dart/element/element.dart'; |
| 13 import 'package:analyzer/dart/element/type.dart'; |
| 14 import 'package:analyzer/file_system/memory_file_system.dart'; |
| 15 import 'package:analyzer/src/dart/element/element.dart'; |
| 16 import 'package:analyzer/src/dart/element/type.dart'; |
| 17 import 'package:analyzer/src/error/codes.dart'; |
| 13 import 'package:analyzer/src/generated/engine.dart'; | 18 import 'package:analyzer/src/generated/engine.dart'; |
| 14 import 'package:analyzer/src/generated/error.dart'; | |
| 15 import 'package:analyzer/src/generated/java_core.dart'; | |
| 16 import 'package:analyzer/src/generated/java_engine.dart'; | |
| 17 import 'package:analyzer/src/generated/java_engine_io.dart'; | |
| 18 import 'package:analyzer/src/generated/java_io.dart'; | |
| 19 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode; | 19 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode; |
| 20 import 'package:analyzer/src/generated/resolver.dart'; | 20 import 'package:analyzer/src/generated/resolver.dart'; |
| 21 import 'package:analyzer/src/generated/scanner.dart'; | |
| 22 import 'package:analyzer/src/generated/sdk.dart'; | |
| 23 import 'package:analyzer/src/generated/sdk_io.dart' show DirectoryBasedDartSdk; | |
| 24 import 'package:analyzer/src/generated/source_io.dart'; | 21 import 'package:analyzer/src/generated/source_io.dart'; |
| 25 import 'package:analyzer/src/generated/static_type_analyzer.dart'; | |
| 26 import 'package:analyzer/src/generated/testing/ast_factory.dart'; | 22 import 'package:analyzer/src/generated/testing/ast_factory.dart'; |
| 27 import 'package:analyzer/src/generated/testing/element_factory.dart'; | 23 import 'package:analyzer/src/generated/testing/element_factory.dart'; |
| 28 import 'package:analyzer/src/generated/testing/test_type_provider.dart'; | 24 import 'package:analyzer/src/generated/testing/test_type_provider.dart'; |
| 29 import 'package:analyzer/src/generated/testing/token_factory.dart'; | |
| 30 import 'package:analyzer/src/generated/utilities_dart.dart'; | 25 import 'package:analyzer/src/generated/utilities_dart.dart'; |
| 26 import 'package:analyzer/src/source/source_resource.dart'; |
| 27 import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| 31 import 'package:unittest/unittest.dart'; | 28 import 'package:unittest/unittest.dart'; |
| 32 | 29 |
| 33 import '../reflective_tests.dart'; | |
| 34 import '../utils.dart'; | 30 import '../utils.dart'; |
| 31 import 'analysis_context_factory.dart'; |
| 32 import 'resolver_test_case.dart'; |
| 35 import 'test_support.dart'; | 33 import 'test_support.dart'; |
| 36 | 34 |
| 37 main() { | 35 main() { |
| 38 initializeTestEnvironment(); | 36 initializeTestEnvironment(); |
| 39 runReflectiveTests(AnalysisDeltaTest); | 37 defineReflectiveTests(AnalysisDeltaTest); |
| 40 runReflectiveTests(ChangeSetTest); | 38 defineReflectiveTests(ChangeSetTest); |
| 41 runReflectiveTests(EnclosedScopeTest); | 39 defineReflectiveTests(EnclosedScopeTest); |
| 42 runReflectiveTests(LibraryImportScopeTest); | 40 defineReflectiveTests(ErrorResolverTest); |
| 43 runReflectiveTests(LibraryScopeTest); | 41 defineReflectiveTests(LibraryImportScopeTest); |
| 44 runReflectiveTests(ScopeTest); | 42 defineReflectiveTests(LibraryScopeTest); |
| 45 runReflectiveTests(ElementResolverTest); | 43 defineReflectiveTests(PrefixedNamespaceTest); |
| 46 runReflectiveTests(InheritanceManagerTest); | 44 defineReflectiveTests(ScopeTest); |
| 47 if (!AnalysisEngine.instance.useTaskModel) { | 45 defineReflectiveTests(StrictModeTest); |
| 48 runReflectiveTests(LibraryElementBuilderTest); | 46 defineReflectiveTests(SubtypeManagerTest); |
| 49 } | 47 defineReflectiveTests(TypeOverrideManagerTest); |
| 50 if (!AnalysisEngine.instance.useTaskModel) { | 48 defineReflectiveTests(TypePropagationTest); |
| 51 runReflectiveTests(LibraryResolver2Test); | 49 defineReflectiveTests(TypeProviderImplTest); |
| 52 } | 50 defineReflectiveTests(TypeResolverVisitorTest); |
| 53 if (!AnalysisEngine.instance.useTaskModel) { | |
| 54 runReflectiveTests(LibraryResolverTest); | |
| 55 } | |
| 56 runReflectiveTests(LibraryTest); | |
| 57 runReflectiveTests(StaticTypeAnalyzerTest); | |
| 58 runReflectiveTests(StaticTypeAnalyzer2Test); | |
| 59 runReflectiveTests(SubtypeManagerTest); | |
| 60 runReflectiveTests(TypeOverrideManagerTest); | |
| 61 runReflectiveTests(TypeProviderImplTest); | |
| 62 runReflectiveTests(TypeResolverVisitorTest); | |
| 63 runReflectiveTests(CheckedModeCompileTimeErrorCodeTest); | |
| 64 runReflectiveTests(ErrorResolverTest); | |
| 65 runReflectiveTests(HintCodeTest); | |
| 66 runReflectiveTests(MemberMapTest); | |
| 67 runReflectiveTests(NonHintCodeTest); | |
| 68 runReflectiveTests(SimpleResolverTest); | |
| 69 runReflectiveTests(StrictModeTest); | |
| 70 runReflectiveTests(TypePropagationTest); | |
| 71 runReflectiveTests(StrongModeStaticTypeAnalyzer2Test); | |
| 72 runReflectiveTests(StrongModeTypePropagationTest); | |
| 73 } | |
| 74 | |
| 75 /** | |
| 76 * The class `AnalysisContextFactory` defines utility methods used to create ana
lysis contexts | |
| 77 * for testing purposes. | |
| 78 */ | |
| 79 class AnalysisContextFactory { | |
| 80 static String _DART_MATH = "dart:math"; | |
| 81 | |
| 82 static String _DART_INTERCEPTORS = "dart:_interceptors"; | |
| 83 | |
| 84 static String _DART_JS_HELPER = "dart:_js_helper"; | |
| 85 | |
| 86 /** | |
| 87 * Create an analysis context that has a fake core library already resolved. | |
| 88 * Return the context that was created. | |
| 89 */ | |
| 90 static InternalAnalysisContext contextWithCore() { | |
| 91 if (AnalysisEngine.instance.useTaskModel) { | |
| 92 NewAnalysisContextForTests context = new NewAnalysisContextForTests(); | |
| 93 return initContextWithCore(context); | |
| 94 } | |
| 95 AnalysisContextForTests context = new AnalysisContextForTests(); | |
| 96 return initContextWithCore(context); | |
| 97 } | |
| 98 | |
| 99 /** | |
| 100 * Create an analysis context that uses the given [options] and has a fake | |
| 101 * core library already resolved. Return the context that was created. | |
| 102 */ | |
| 103 static InternalAnalysisContext contextWithCoreAndOptions( | |
| 104 AnalysisOptions options) { | |
| 105 if (AnalysisEngine.instance.useTaskModel) { | |
| 106 NewAnalysisContextForTests context = new NewAnalysisContextForTests(); | |
| 107 context._internalSetAnalysisOptions(options); | |
| 108 return initContextWithCore(context); | |
| 109 } | |
| 110 AnalysisContextForTests context = new AnalysisContextForTests(); | |
| 111 context._internalSetAnalysisOptions(options); | |
| 112 return initContextWithCore(context); | |
| 113 } | |
| 114 | |
| 115 /** | |
| 116 * Initialize the given analysis context with a fake core library already reso
lved. | |
| 117 * | |
| 118 * @param context the context to be initialized (not `null`) | |
| 119 * @return the analysis context that was created | |
| 120 */ | |
| 121 static InternalAnalysisContext initContextWithCore( | |
| 122 InternalAnalysisContext context) { | |
| 123 DirectoryBasedDartSdk sdk = new _AnalysisContextFactory_initContextWithCore( | |
| 124 new JavaFile("/fake/sdk")); | |
| 125 SourceFactory sourceFactory = | |
| 126 new SourceFactory([new DartUriResolver(sdk), new FileUriResolver()]); | |
| 127 context.sourceFactory = sourceFactory; | |
| 128 AnalysisContext coreContext = sdk.context; | |
| 129 // | |
| 130 // dart:core | |
| 131 // | |
| 132 TestTypeProvider provider = new TestTypeProvider(); | |
| 133 CompilationUnitElementImpl coreUnit = | |
| 134 new CompilationUnitElementImpl("core.dart"); | |
| 135 Source coreSource = sourceFactory.forUri(DartSdk.DART_CORE); | |
| 136 coreContext.setContents(coreSource, ""); | |
| 137 coreUnit.librarySource = coreUnit.source = coreSource; | |
| 138 ClassElementImpl proxyClassElement = ElementFactory.classElement2("_Proxy"); | |
| 139 ClassElement objectClassElement = provider.objectType.element; | |
| 140 coreUnit.types = <ClassElement>[ | |
| 141 provider.boolType.element, | |
| 142 provider.deprecatedType.element, | |
| 143 provider.doubleType.element, | |
| 144 provider.functionType.element, | |
| 145 provider.intType.element, | |
| 146 provider.iterableType.element, | |
| 147 provider.iteratorType.element, | |
| 148 provider.listType.element, | |
| 149 provider.mapType.element, | |
| 150 provider.nullType.element, | |
| 151 provider.numType.element, | |
| 152 objectClassElement, | |
| 153 proxyClassElement, | |
| 154 provider.stackTraceType.element, | |
| 155 provider.stringType.element, | |
| 156 provider.symbolType.element, | |
| 157 provider.typeType.element | |
| 158 ]; | |
| 159 coreUnit.functions = <FunctionElement>[ | |
| 160 ElementFactory.functionElement3("identical", provider.boolType.element, | |
| 161 <ClassElement>[objectClassElement, objectClassElement], null), | |
| 162 ElementFactory.functionElement3("print", VoidTypeImpl.instance.element, | |
| 163 <ClassElement>[objectClassElement], null) | |
| 164 ]; | |
| 165 TopLevelVariableElement proxyTopLevelVariableElt = ElementFactory | |
| 166 .topLevelVariableElement3("proxy", true, false, proxyClassElement.type); | |
| 167 ConstTopLevelVariableElementImpl deprecatedTopLevelVariableElt = | |
| 168 ElementFactory.topLevelVariableElement3( | |
| 169 "deprecated", true, false, provider.deprecatedType); | |
| 170 deprecatedTopLevelVariableElt.constantInitializer = AstFactory | |
| 171 .instanceCreationExpression2( | |
| 172 Keyword.CONST, | |
| 173 AstFactory.typeName(provider.deprecatedType.element), | |
| 174 [AstFactory.string2('next release')]); | |
| 175 coreUnit.accessors = <PropertyAccessorElement>[ | |
| 176 proxyTopLevelVariableElt.getter, | |
| 177 deprecatedTopLevelVariableElt.getter | |
| 178 ]; | |
| 179 coreUnit.topLevelVariables = <TopLevelVariableElement>[ | |
| 180 proxyTopLevelVariableElt, | |
| 181 deprecatedTopLevelVariableElt | |
| 182 ]; | |
| 183 LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode( | |
| 184 coreContext, AstFactory.libraryIdentifier2(["dart", "core"])); | |
| 185 coreLibrary.definingCompilationUnit = coreUnit; | |
| 186 // | |
| 187 // dart:async | |
| 188 // | |
| 189 CompilationUnitElementImpl asyncUnit = | |
| 190 new CompilationUnitElementImpl("async.dart"); | |
| 191 Source asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC); | |
| 192 coreContext.setContents(asyncSource, ""); | |
| 193 asyncUnit.librarySource = asyncUnit.source = asyncSource; | |
| 194 // Future | |
| 195 ClassElementImpl futureElement = | |
| 196 ElementFactory.classElement2("Future", ["T"]); | |
| 197 // factory Future.value([value]) | |
| 198 ConstructorElementImpl futureConstructor = | |
| 199 ElementFactory.constructorElement2(futureElement, "value"); | |
| 200 futureConstructor.parameters = <ParameterElement>[ | |
| 201 ElementFactory.positionalParameter2("value", provider.dynamicType) | |
| 202 ]; | |
| 203 futureConstructor.factory = true; | |
| 204 (futureConstructor.type as FunctionTypeImpl).typeArguments = | |
| 205 futureElement.type.typeArguments; | |
| 206 futureElement.constructors = <ConstructorElement>[futureConstructor]; | |
| 207 // Future then(onValue(T value), { Function onError }); | |
| 208 List<ParameterElement> parameters = <ParameterElement>[ | |
| 209 ElementFactory.requiredParameter2( | |
| 210 "value", futureElement.typeParameters[0].type) | |
| 211 ]; | |
| 212 FunctionTypeAliasElementImpl aliasElement = | |
| 213 new FunctionTypeAliasElementImpl.forNode(null); | |
| 214 aliasElement.synthetic = true; | |
| 215 aliasElement.parameters = parameters; | |
| 216 aliasElement.returnType = provider.dynamicType; | |
| 217 aliasElement.enclosingElement = asyncUnit; | |
| 218 FunctionTypeImpl aliasType = new FunctionTypeImpl.forTypedef(aliasElement); | |
| 219 aliasElement.shareTypeParameters(futureElement.typeParameters); | |
| 220 aliasType.typeArguments = futureElement.type.typeArguments; | |
| 221 DartType futureDynamicType = | |
| 222 futureElement.type.substitute4([provider.dynamicType]); | |
| 223 MethodElement thenMethod = ElementFactory.methodElementWithParameters( | |
| 224 "then", futureElement.type.typeArguments, futureDynamicType, [ | |
| 225 ElementFactory.requiredParameter2("onValue", aliasType), | |
| 226 ElementFactory.namedParameter2("onError", provider.functionType) | |
| 227 ]); | |
| 228 futureElement.methods = <MethodElement>[thenMethod]; | |
| 229 // Completer | |
| 230 ClassElementImpl completerElement = | |
| 231 ElementFactory.classElement2("Completer", ["T"]); | |
| 232 ConstructorElementImpl completerConstructor = | |
| 233 ElementFactory.constructorElement2(completerElement, null); | |
| 234 (completerConstructor.type as FunctionTypeImpl).typeArguments = | |
| 235 completerElement.type.typeArguments; | |
| 236 completerElement.constructors = <ConstructorElement>[completerConstructor]; | |
| 237 // StreamSubscription | |
| 238 ClassElementImpl streamSubscriptionElement = | |
| 239 ElementFactory.classElement2("StreamSubscription", ["T"]); | |
| 240 // Stream | |
| 241 ClassElementImpl streamElement = | |
| 242 ElementFactory.classElement2("Stream", ["T"]); | |
| 243 streamElement.constructors = <ConstructorElement>[ | |
| 244 ElementFactory.constructorElement2(streamElement, null) | |
| 245 ]; | |
| 246 DartType returnType = streamSubscriptionElement.type | |
| 247 .substitute4(streamElement.type.typeArguments); | |
| 248 List<DartType> parameterTypes = <DartType>[ | |
| 249 ElementFactory | |
| 250 .functionElement3('onData', VoidTypeImpl.instance.element, | |
| 251 <TypeDefiningElement>[streamElement.typeParameters[0]], null) | |
| 252 .type, | |
| 253 ]; | |
| 254 // TODO(brianwilkerson) This is missing the optional parameters. | |
| 255 MethodElementImpl listenMethod = | |
| 256 ElementFactory.methodElement('listen', returnType, parameterTypes); | |
| 257 streamElement.methods = <MethodElement>[listenMethod]; | |
| 258 | |
| 259 asyncUnit.types = <ClassElement>[ | |
| 260 completerElement, | |
| 261 futureElement, | |
| 262 streamElement | |
| 263 ]; | |
| 264 LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode( | |
| 265 coreContext, AstFactory.libraryIdentifier2(["dart", "async"])); | |
| 266 asyncLibrary.definingCompilationUnit = asyncUnit; | |
| 267 // | |
| 268 // dart:html | |
| 269 // | |
| 270 CompilationUnitElementImpl htmlUnit = | |
| 271 new CompilationUnitElementImpl("html_dartium.dart"); | |
| 272 Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML); | |
| 273 coreContext.setContents(htmlSource, ""); | |
| 274 htmlUnit.librarySource = htmlUnit.source = htmlSource; | |
| 275 ClassElementImpl elementElement = ElementFactory.classElement2("Element"); | |
| 276 InterfaceType elementType = elementElement.type; | |
| 277 ClassElementImpl canvasElement = | |
| 278 ElementFactory.classElement("CanvasElement", elementType); | |
| 279 ClassElementImpl contextElement = | |
| 280 ElementFactory.classElement2("CanvasRenderingContext"); | |
| 281 InterfaceType contextElementType = contextElement.type; | |
| 282 ClassElementImpl context2dElement = ElementFactory.classElement( | |
| 283 "CanvasRenderingContext2D", contextElementType); | |
| 284 canvasElement.methods = <MethodElement>[ | |
| 285 ElementFactory.methodElement( | |
| 286 "getContext", contextElementType, [provider.stringType]) | |
| 287 ]; | |
| 288 canvasElement.accessors = <PropertyAccessorElement>[ | |
| 289 ElementFactory.getterElement("context2D", false, context2dElement.type) | |
| 290 ]; | |
| 291 canvasElement.fields = canvasElement.accessors | |
| 292 .map((PropertyAccessorElement accessor) => accessor.variable) | |
| 293 .toList(); | |
| 294 ClassElementImpl documentElement = | |
| 295 ElementFactory.classElement("Document", elementType); | |
| 296 ClassElementImpl htmlDocumentElement = | |
| 297 ElementFactory.classElement("HtmlDocument", documentElement.type); | |
| 298 htmlDocumentElement.methods = <MethodElement>[ | |
| 299 ElementFactory.methodElement( | |
| 300 "query", elementType, <DartType>[provider.stringType]) | |
| 301 ]; | |
| 302 htmlUnit.types = <ClassElement>[ | |
| 303 ElementFactory.classElement("AnchorElement", elementType), | |
| 304 ElementFactory.classElement("BodyElement", elementType), | |
| 305 ElementFactory.classElement("ButtonElement", elementType), | |
| 306 canvasElement, | |
| 307 contextElement, | |
| 308 context2dElement, | |
| 309 ElementFactory.classElement("DivElement", elementType), | |
| 310 documentElement, | |
| 311 elementElement, | |
| 312 htmlDocumentElement, | |
| 313 ElementFactory.classElement("InputElement", elementType), | |
| 314 ElementFactory.classElement("SelectElement", elementType) | |
| 315 ]; | |
| 316 htmlUnit.functions = <FunctionElement>[ | |
| 317 ElementFactory.functionElement3("query", elementElement, | |
| 318 <ClassElement>[provider.stringType.element], ClassElement.EMPTY_LIST) | |
| 319 ]; | |
| 320 TopLevelVariableElementImpl document = ElementFactory | |
| 321 .topLevelVariableElement3( | |
| 322 "document", false, true, htmlDocumentElement.type); | |
| 323 htmlUnit.topLevelVariables = <TopLevelVariableElement>[document]; | |
| 324 htmlUnit.accessors = <PropertyAccessorElement>[document.getter]; | |
| 325 LibraryElementImpl htmlLibrary = new LibraryElementImpl.forNode( | |
| 326 coreContext, AstFactory.libraryIdentifier2(["dart", "dom", "html"])); | |
| 327 htmlLibrary.definingCompilationUnit = htmlUnit; | |
| 328 // | |
| 329 // dart:math | |
| 330 // | |
| 331 CompilationUnitElementImpl mathUnit = | |
| 332 new CompilationUnitElementImpl("math.dart"); | |
| 333 Source mathSource = sourceFactory.forUri(_DART_MATH); | |
| 334 coreContext.setContents(mathSource, ""); | |
| 335 mathUnit.librarySource = mathUnit.source = mathSource; | |
| 336 FunctionElement cosElement = ElementFactory.functionElement3( | |
| 337 "cos", | |
| 338 provider.doubleType.element, | |
| 339 <ClassElement>[provider.numType.element], | |
| 340 ClassElement.EMPTY_LIST); | |
| 341 TopLevelVariableElement ln10Element = ElementFactory | |
| 342 .topLevelVariableElement3("LN10", true, false, provider.doubleType); | |
| 343 FunctionElement maxElement = ElementFactory.functionElement3( | |
| 344 "max", | |
| 345 provider.numType.element, | |
| 346 <ClassElement>[provider.numType.element, provider.numType.element], | |
| 347 ClassElement.EMPTY_LIST); | |
| 348 TopLevelVariableElement piElement = ElementFactory.topLevelVariableElement3( | |
| 349 "PI", true, false, provider.doubleType); | |
| 350 ClassElementImpl randomElement = ElementFactory.classElement2("Random"); | |
| 351 randomElement.abstract = true; | |
| 352 ConstructorElementImpl randomConstructor = | |
| 353 ElementFactory.constructorElement2(randomElement, null); | |
| 354 randomConstructor.factory = true; | |
| 355 ParameterElementImpl seedParam = new ParameterElementImpl("seed", 0); | |
| 356 seedParam.parameterKind = ParameterKind.POSITIONAL; | |
| 357 seedParam.type = provider.intType; | |
| 358 randomConstructor.parameters = <ParameterElement>[seedParam]; | |
| 359 randomElement.constructors = <ConstructorElement>[randomConstructor]; | |
| 360 FunctionElement sinElement = ElementFactory.functionElement3( | |
| 361 "sin", | |
| 362 provider.doubleType.element, | |
| 363 <ClassElement>[provider.numType.element], | |
| 364 ClassElement.EMPTY_LIST); | |
| 365 FunctionElement sqrtElement = ElementFactory.functionElement3( | |
| 366 "sqrt", | |
| 367 provider.doubleType.element, | |
| 368 <ClassElement>[provider.numType.element], | |
| 369 ClassElement.EMPTY_LIST); | |
| 370 mathUnit.accessors = <PropertyAccessorElement>[ | |
| 371 ln10Element.getter, | |
| 372 piElement.getter | |
| 373 ]; | |
| 374 mathUnit.functions = <FunctionElement>[ | |
| 375 cosElement, | |
| 376 maxElement, | |
| 377 sinElement, | |
| 378 sqrtElement | |
| 379 ]; | |
| 380 mathUnit.topLevelVariables = <TopLevelVariableElement>[ | |
| 381 ln10Element, | |
| 382 piElement | |
| 383 ]; | |
| 384 mathUnit.types = <ClassElement>[randomElement]; | |
| 385 LibraryElementImpl mathLibrary = new LibraryElementImpl.forNode( | |
| 386 coreContext, AstFactory.libraryIdentifier2(["dart", "math"])); | |
| 387 mathLibrary.definingCompilationUnit = mathUnit; | |
| 388 // | |
| 389 // Set empty sources for the rest of the libraries. | |
| 390 // | |
| 391 Source source = sourceFactory.forUri(_DART_INTERCEPTORS); | |
| 392 coreContext.setContents(source, ""); | |
| 393 source = sourceFactory.forUri(_DART_JS_HELPER); | |
| 394 coreContext.setContents(source, ""); | |
| 395 // | |
| 396 // Record the elements. | |
| 397 // | |
| 398 HashMap<Source, LibraryElement> elementMap = | |
| 399 new HashMap<Source, LibraryElement>(); | |
| 400 elementMap[coreSource] = coreLibrary; | |
| 401 elementMap[asyncSource] = asyncLibrary; | |
| 402 elementMap[htmlSource] = htmlLibrary; | |
| 403 elementMap[mathSource] = mathLibrary; | |
| 404 context.recordLibraryElements(elementMap); | |
| 405 return context; | |
| 406 } | |
| 407 | |
| 408 /** | |
| 409 * Create an analysis context that has a fake core library already resolved. | |
| 410 * Return the context that was created. | |
| 411 */ | |
| 412 static AnalysisContextImpl oldContextWithCore() { | |
| 413 AnalysisContextForTests context = new AnalysisContextForTests(); | |
| 414 return initContextWithCore(context); | |
| 415 } | |
| 416 | |
| 417 /** | |
| 418 * Create an analysis context that uses the given [options] and has a fake | |
| 419 * core library already resolved. Return the context that was created. | |
| 420 */ | |
| 421 static AnalysisContextImpl oldContextWithCoreAndOptions( | |
| 422 AnalysisOptions options) { | |
| 423 AnalysisContextForTests context = new AnalysisContextForTests(); | |
| 424 context._internalSetAnalysisOptions(options); | |
| 425 return initContextWithCore(context); | |
| 426 } | |
| 427 } | |
| 428 | |
| 429 /** | |
| 430 * Instances of the class `AnalysisContextForTests` implement an analysis contex
t that has a | |
| 431 * fake SDK that is much smaller and faster for testing purposes. | |
| 432 */ | |
| 433 class AnalysisContextForTests extends AnalysisContextImpl { | |
| 434 @override | |
| 435 void set analysisOptions(AnalysisOptions options) { | |
| 436 AnalysisOptions currentOptions = analysisOptions; | |
| 437 bool needsRecompute = currentOptions.analyzeFunctionBodiesPredicate != | |
| 438 options.analyzeFunctionBodiesPredicate || | |
| 439 currentOptions.generateImplicitErrors != | |
| 440 options.generateImplicitErrors || | |
| 441 currentOptions.generateSdkErrors != options.generateSdkErrors || | |
| 442 currentOptions.dart2jsHint != options.dart2jsHint || | |
| 443 (currentOptions.hint && !options.hint) || | |
| 444 currentOptions.preserveComments != options.preserveComments || | |
| 445 currentOptions.enableStrictCallChecks != options.enableStrictCallChecks; | |
| 446 if (needsRecompute) { | |
| 447 fail( | |
| 448 "Cannot set options that cause the sources to be reanalyzed in a test
context"); | |
| 449 } | |
| 450 super.analysisOptions = options; | |
| 451 } | |
| 452 | |
| 453 @override | |
| 454 bool exists(Source source) => | |
| 455 super.exists(source) || sourceFactory.dartSdk.context.exists(source); | |
| 456 | |
| 457 @override | |
| 458 TimestampedData<String> getContents(Source source) { | |
| 459 if (source.isInSystemLibrary) { | |
| 460 return sourceFactory.dartSdk.context.getContents(source); | |
| 461 } | |
| 462 return super.getContents(source); | |
| 463 } | |
| 464 | |
| 465 @override | |
| 466 int getModificationStamp(Source source) { | |
| 467 if (source.isInSystemLibrary) { | |
| 468 return sourceFactory.dartSdk.context.getModificationStamp(source); | |
| 469 } | |
| 470 return super.getModificationStamp(source); | |
| 471 } | |
| 472 | |
| 473 /** | |
| 474 * Set the analysis options, even if they would force re-analysis. This method
should only be | |
| 475 * invoked before the fake SDK is initialized. | |
| 476 * | |
| 477 * @param options the analysis options to be set | |
| 478 */ | |
| 479 void _internalSetAnalysisOptions(AnalysisOptions options) { | |
| 480 super.analysisOptions = options; | |
| 481 } | |
| 482 } | |
| 483 | |
| 484 /** | |
| 485 * Helper for creating and managing single [AnalysisContext]. | |
| 486 */ | |
| 487 class AnalysisContextHelper { | |
| 488 AnalysisContext context; | |
| 489 | |
| 490 /** | |
| 491 * Creates new [AnalysisContext] using [AnalysisContextFactory]. | |
| 492 */ | |
| 493 AnalysisContextHelper([AnalysisOptionsImpl options]) { | |
| 494 if (options == null) { | |
| 495 options = new AnalysisOptionsImpl(); | |
| 496 } | |
| 497 options.cacheSize = 256; | |
| 498 context = AnalysisContextFactory.contextWithCoreAndOptions(options); | |
| 499 } | |
| 500 | |
| 501 Source addSource(String path, String code) { | |
| 502 Source source = new FileBasedSource(FileUtilities2.createFile(path)); | |
| 503 if (path.endsWith(".dart") || path.endsWith(".html")) { | |
| 504 ChangeSet changeSet = new ChangeSet(); | |
| 505 changeSet.addedSource(source); | |
| 506 context.applyChanges(changeSet); | |
| 507 } | |
| 508 context.setContents(source, code); | |
| 509 return source; | |
| 510 } | |
| 511 | |
| 512 CompilationUnitElement getDefiningUnitElement(Source source) => | |
| 513 context.getCompilationUnitElement(source, source); | |
| 514 | |
| 515 CompilationUnit resolveDefiningUnit(Source source) { | |
| 516 LibraryElement libraryElement = context.computeLibraryElement(source); | |
| 517 return context.resolveCompilationUnit(source, libraryElement); | |
| 518 } | |
| 519 | |
| 520 void runTasks() { | |
| 521 AnalysisResult result = context.performAnalysisTask(); | |
| 522 while (result.changeNotices != null) { | |
| 523 result = context.performAnalysisTask(); | |
| 524 } | |
| 525 } | |
| 526 } | 51 } |
| 527 | 52 |
| 528 @reflectiveTest | 53 @reflectiveTest |
| 529 class AnalysisDeltaTest extends EngineTestCase { | 54 class AnalysisDeltaTest extends EngineTestCase { |
| 530 TestSource source1 = new TestSource('/1.dart'); | 55 TestSource source1 = new TestSource('/1.dart'); |
| 531 TestSource source2 = new TestSource('/2.dart'); | 56 TestSource source2 = new TestSource('/2.dart'); |
| 532 TestSource source3 = new TestSource('/3.dart'); | 57 TestSource source3 = new TestSource('/3.dart'); |
| 533 | 58 |
| 534 void test_getAddedSources() { | 59 void test_getAddedSources() { |
| 535 AnalysisDelta delta = new AnalysisDelta(); | 60 AnalysisDelta delta = new AnalysisDelta(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 571 TestSource source = new TestSource(); | 96 TestSource source = new TestSource(); |
| 572 String content = ""; | 97 String content = ""; |
| 573 ChangeSet changeSet = new ChangeSet(); | 98 ChangeSet changeSet = new ChangeSet(); |
| 574 changeSet.changedContent(source, content); | 99 changeSet.changedContent(source, content); |
| 575 expect(changeSet.addedSources, hasLength(0)); | 100 expect(changeSet.addedSources, hasLength(0)); |
| 576 expect(changeSet.changedSources, hasLength(0)); | 101 expect(changeSet.changedSources, hasLength(0)); |
| 577 Map<Source, String> map = changeSet.changedContents; | 102 Map<Source, String> map = changeSet.changedContents; |
| 578 expect(map, hasLength(1)); | 103 expect(map, hasLength(1)); |
| 579 expect(map[source], same(content)); | 104 expect(map[source], same(content)); |
| 580 expect(changeSet.changedRanges, hasLength(0)); | 105 expect(changeSet.changedRanges, hasLength(0)); |
| 581 expect(changeSet.deletedSources, hasLength(0)); | |
| 582 expect(changeSet.removedSources, hasLength(0)); | 106 expect(changeSet.removedSources, hasLength(0)); |
| 583 expect(changeSet.removedContainers, hasLength(0)); | 107 expect(changeSet.removedContainers, hasLength(0)); |
| 584 } | 108 } |
| 585 | 109 |
| 586 void test_changedRange() { | 110 void test_changedRange() { |
| 587 TestSource source = new TestSource(); | 111 TestSource source = new TestSource(); |
| 588 String content = ""; | 112 String content = ""; |
| 589 ChangeSet changeSet = new ChangeSet(); | 113 ChangeSet changeSet = new ChangeSet(); |
| 590 changeSet.changedRange(source, content, 1, 2, 3); | 114 changeSet.changedRange(source, content, 1, 2, 3); |
| 591 expect(changeSet.addedSources, hasLength(0)); | 115 expect(changeSet.addedSources, hasLength(0)); |
| 592 expect(changeSet.changedSources, hasLength(0)); | 116 expect(changeSet.changedSources, hasLength(0)); |
| 593 expect(changeSet.changedContents, hasLength(0)); | 117 expect(changeSet.changedContents, hasLength(0)); |
| 594 Map<Source, ChangeSet_ContentChange> map = changeSet.changedRanges; | 118 Map<Source, ChangeSet_ContentChange> map = changeSet.changedRanges; |
| 595 expect(map, hasLength(1)); | 119 expect(map, hasLength(1)); |
| 596 ChangeSet_ContentChange change = map[source]; | 120 ChangeSet_ContentChange change = map[source]; |
| 597 expect(change, isNotNull); | 121 expect(change, isNotNull); |
| 598 expect(change.contents, content); | 122 expect(change.contents, content); |
| 599 expect(change.offset, 1); | 123 expect(change.offset, 1); |
| 600 expect(change.oldLength, 2); | 124 expect(change.oldLength, 2); |
| 601 expect(change.newLength, 3); | 125 expect(change.newLength, 3); |
| 602 expect(changeSet.deletedSources, hasLength(0)); | |
| 603 expect(changeSet.removedSources, hasLength(0)); | 126 expect(changeSet.removedSources, hasLength(0)); |
| 604 expect(changeSet.removedContainers, hasLength(0)); | 127 expect(changeSet.removedContainers, hasLength(0)); |
| 605 } | 128 } |
| 606 | 129 |
| 607 void test_toString() { | 130 void test_toString() { |
| 608 ChangeSet changeSet = new ChangeSet(); | 131 ChangeSet changeSet = new ChangeSet(); |
| 609 changeSet.addedSource(new TestSource()); | 132 changeSet.addedSource(new TestSource()); |
| 610 changeSet.changedSource(new TestSource()); | 133 changeSet.changedSource(new TestSource()); |
| 611 changeSet.changedContent(new TestSource(), ""); | 134 changeSet.changedContent(new TestSource(), ""); |
| 612 changeSet.changedRange(new TestSource(), "", 0, 0, 0); | 135 changeSet.changedRange(new TestSource(), "", 0, 0, 0); |
| 613 changeSet.deletedSource(new TestSource()); | |
| 614 changeSet.removedSource(new TestSource()); | 136 changeSet.removedSource(new TestSource()); |
| 615 changeSet | 137 changeSet |
| 616 .removedContainer(new SourceContainer_ChangeSetTest_test_toString()); | 138 .removedContainer(new SourceContainer_ChangeSetTest_test_toString()); |
| 617 expect(changeSet.toString(), isNotNull); | 139 expect(changeSet.toString(), isNotNull); |
| 618 } | 140 } |
| 619 } | 141 } |
| 620 | 142 |
| 621 @reflectiveTest | 143 @reflectiveTest |
| 622 class CheckedModeCompileTimeErrorCodeTest extends ResolverTestCase { | |
| 623 void test_fieldFormalParameterAssignableToField_extends() { | |
| 624 // According to checked-mode type checking rules, a value of type B is | |
| 625 // assignable to a field of type A, because B extends A (and hence is a | |
| 626 // subtype of A). | |
| 627 Source source = addSource(r''' | |
| 628 class A { | |
| 629 const A(); | |
| 630 } | |
| 631 class B extends A { | |
| 632 const B(); | |
| 633 } | |
| 634 class C { | |
| 635 final A a; | |
| 636 const C(this.a); | |
| 637 } | |
| 638 var v = const C(const B());'''); | |
| 639 computeLibrarySourceErrors(source); | |
| 640 assertNoErrors(source); | |
| 641 verify([source]); | |
| 642 } | |
| 643 | |
| 644 void test_fieldFormalParameterAssignableToField_fieldType_unresolved_null() { | |
| 645 // Null always passes runtime type checks, even when the type is | |
| 646 // unresolved. | |
| 647 Source source = addSource(r''' | |
| 648 class A { | |
| 649 final Unresolved x; | |
| 650 const A(String this.x); | |
| 651 } | |
| 652 var v = const A(null);'''); | |
| 653 computeLibrarySourceErrors(source); | |
| 654 assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]); | |
| 655 verify([source]); | |
| 656 } | |
| 657 | |
| 658 void test_fieldFormalParameterAssignableToField_implements() { | |
| 659 // According to checked-mode type checking rules, a value of type B is | |
| 660 // assignable to a field of type A, because B implements A (and hence is a | |
| 661 // subtype of A). | |
| 662 Source source = addSource(r''' | |
| 663 class A {} | |
| 664 class B implements A { | |
| 665 const B(); | |
| 666 } | |
| 667 class C { | |
| 668 final A a; | |
| 669 const C(this.a); | |
| 670 } | |
| 671 var v = const C(const B());'''); | |
| 672 computeLibrarySourceErrors(source); | |
| 673 assertNoErrors(source); | |
| 674 verify([source]); | |
| 675 } | |
| 676 | |
| 677 void test_fieldFormalParameterAssignableToField_list_dynamic() { | |
| 678 // [1, 2, 3] has type List<dynamic>, which is a subtype of List<int>. | |
| 679 Source source = addSource(r''' | |
| 680 class A { | |
| 681 const A(List<int> x); | |
| 682 } | |
| 683 var x = const A(const [1, 2, 3]);'''); | |
| 684 computeLibrarySourceErrors(source); | |
| 685 assertNoErrors(source); | |
| 686 verify([source]); | |
| 687 } | |
| 688 | |
| 689 void test_fieldFormalParameterAssignableToField_list_nonDynamic() { | |
| 690 // <int>[1, 2, 3] has type List<int>, which is a subtype of List<num>. | |
| 691 Source source = addSource(r''' | |
| 692 class A { | |
| 693 const A(List<num> x); | |
| 694 } | |
| 695 var x = const A(const <int>[1, 2, 3]);'''); | |
| 696 computeLibrarySourceErrors(source); | |
| 697 assertNoErrors(source); | |
| 698 verify([source]); | |
| 699 } | |
| 700 | |
| 701 void test_fieldFormalParameterAssignableToField_map_dynamic() { | |
| 702 // {1: 2} has type Map<dynamic, dynamic>, which is a subtype of | |
| 703 // Map<int, int>. | |
| 704 Source source = addSource(r''' | |
| 705 class A { | |
| 706 const A(Map<int, int> x); | |
| 707 } | |
| 708 var x = const A(const {1: 2});'''); | |
| 709 computeLibrarySourceErrors(source); | |
| 710 assertNoErrors(source); | |
| 711 verify([source]); | |
| 712 } | |
| 713 | |
| 714 void test_fieldFormalParameterAssignableToField_map_keyDifferent() { | |
| 715 // <int, int>{1: 2} has type Map<int, int>, which is a subtype of | |
| 716 // Map<num, int>. | |
| 717 Source source = addSource(r''' | |
| 718 class A { | |
| 719 const A(Map<num, int> x); | |
| 720 } | |
| 721 var x = const A(const <int, int>{1: 2});'''); | |
| 722 computeLibrarySourceErrors(source); | |
| 723 assertNoErrors(source); | |
| 724 verify([source]); | |
| 725 } | |
| 726 | |
| 727 void test_fieldFormalParameterAssignableToField_map_valueDifferent() { | |
| 728 // <int, int>{1: 2} has type Map<int, int>, which is a subtype of | |
| 729 // Map<int, num>. | |
| 730 Source source = addSource(r''' | |
| 731 class A { | |
| 732 const A(Map<int, num> x); | |
| 733 } | |
| 734 var x = const A(const <int, int>{1: 2});'''); | |
| 735 computeLibrarySourceErrors(source); | |
| 736 assertNoErrors(source); | |
| 737 verify([source]); | |
| 738 } | |
| 739 | |
| 740 void test_fieldFormalParameterAssignableToField_notype() { | |
| 741 // If a field is declared without a type, then any value may be assigned to | |
| 742 // it. | |
| 743 Source source = addSource(r''' | |
| 744 class A { | |
| 745 final x; | |
| 746 const A(this.x); | |
| 747 } | |
| 748 var v = const A(5);'''); | |
| 749 computeLibrarySourceErrors(source); | |
| 750 assertNoErrors(source); | |
| 751 verify([source]); | |
| 752 } | |
| 753 | |
| 754 void test_fieldFormalParameterAssignableToField_null() { | |
| 755 // Null is assignable to anything. | |
| 756 Source source = addSource(r''' | |
| 757 class A { | |
| 758 final int x; | |
| 759 const A(this.x); | |
| 760 } | |
| 761 var v = const A(null);'''); | |
| 762 computeLibrarySourceErrors(source); | |
| 763 assertNoErrors(source); | |
| 764 verify([source]); | |
| 765 } | |
| 766 | |
| 767 void test_fieldFormalParameterAssignableToField_typedef() { | |
| 768 // foo has the runtime type dynamic -> dynamic, so it should be assignable | |
| 769 // to A.f. | |
| 770 Source source = addSource(r''' | |
| 771 typedef String Int2String(int x); | |
| 772 class A { | |
| 773 final Int2String f; | |
| 774 const A(this.f); | |
| 775 } | |
| 776 foo(x) => 1; | |
| 777 var v = const A(foo);'''); | |
| 778 computeLibrarySourceErrors(source); | |
| 779 assertNoErrors(source); | |
| 780 verify([source]); | |
| 781 } | |
| 782 | |
| 783 void test_fieldFormalParameterAssignableToField_typeSubstitution() { | |
| 784 // foo has the runtime type dynamic -> dynamic, so it should be assignable | |
| 785 // to A.f. | |
| 786 Source source = addSource(r''' | |
| 787 class A<T> { | |
| 788 final T x; | |
| 789 const A(this.x); | |
| 790 } | |
| 791 var v = const A<int>(3);'''); | |
| 792 computeLibrarySourceErrors(source); | |
| 793 assertNoErrors(source); | |
| 794 verify([source]); | |
| 795 } | |
| 796 | |
| 797 void test_fieldFormalParameterNotAssignableToField() { | |
| 798 Source source = addSource(r''' | |
| 799 class A { | |
| 800 final int x; | |
| 801 const A(this.x); | |
| 802 } | |
| 803 var v = const A('foo');'''); | |
| 804 computeLibrarySourceErrors(source); | |
| 805 assertErrors(source, [ | |
| 806 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, | |
| 807 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE | |
| 808 ]); | |
| 809 verify([source]); | |
| 810 } | |
| 811 | |
| 812 void test_fieldFormalParameterNotAssignableToField_extends() { | |
| 813 // According to checked-mode type checking rules, a value of type A is not | |
| 814 // assignable to a field of type B, because B extends A (the subtyping | |
| 815 // relationship is in the wrong direction). | |
| 816 Source source = addSource(r''' | |
| 817 class A { | |
| 818 const A(); | |
| 819 } | |
| 820 class B extends A { | |
| 821 const B(); | |
| 822 } | |
| 823 class C { | |
| 824 final B b; | |
| 825 const C(this.b); | |
| 826 } | |
| 827 var v = const C(const A());'''); | |
| 828 computeLibrarySourceErrors(source); | |
| 829 assertErrors(source, [ | |
| 830 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH | |
| 831 ]); | |
| 832 verify([source]); | |
| 833 } | |
| 834 | |
| 835 void test_fieldFormalParameterNotAssignableToField_fieldType() { | |
| 836 Source source = addSource(r''' | |
| 837 class A { | |
| 838 final int x; | |
| 839 const A(String this.x); | |
| 840 } | |
| 841 var v = const A('foo');'''); | |
| 842 computeLibrarySourceErrors(source); | |
| 843 assertErrors(source, [ | |
| 844 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, | |
| 845 StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE | |
| 846 ]); | |
| 847 verify([source]); | |
| 848 } | |
| 849 | |
| 850 void test_fieldFormalParameterNotAssignableToField_fieldType_unresolved() { | |
| 851 Source source = addSource(r''' | |
| 852 class A { | |
| 853 final Unresolved x; | |
| 854 const A(String this.x); | |
| 855 } | |
| 856 var v = const A('foo');'''); | |
| 857 computeLibrarySourceErrors(source); | |
| 858 assertErrors(source, [ | |
| 859 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, | |
| 860 StaticWarningCode.UNDEFINED_CLASS | |
| 861 ]); | |
| 862 verify([source]); | |
| 863 } | |
| 864 | |
| 865 void test_fieldFormalParameterNotAssignableToField_implements() { | |
| 866 // According to checked-mode type checking rules, a value of type A is not | |
| 867 // assignable to a field of type B, because B implements A (the subtyping | |
| 868 // relationship is in the wrong direction). | |
| 869 Source source = addSource(r''' | |
| 870 class A { | |
| 871 const A(); | |
| 872 } | |
| 873 class B implements A {} | |
| 874 class C { | |
| 875 final B b; | |
| 876 const C(this.b); | |
| 877 } | |
| 878 var v = const C(const A());'''); | |
| 879 computeLibrarySourceErrors(source); | |
| 880 assertErrors(source, [ | |
| 881 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH | |
| 882 ]); | |
| 883 verify([source]); | |
| 884 } | |
| 885 | |
| 886 void test_fieldFormalParameterNotAssignableToField_list() { | |
| 887 // <num>[1, 2, 3] has type List<num>, which is not a subtype of List<int>. | |
| 888 Source source = addSource(r''' | |
| 889 class A { | |
| 890 const A(List<int> x); | |
| 891 } | |
| 892 var x = const A(const <num>[1, 2, 3]);'''); | |
| 893 computeLibrarySourceErrors(source); | |
| 894 assertErrors(source, [ | |
| 895 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH | |
| 896 ]); | |
| 897 verify([source]); | |
| 898 } | |
| 899 | |
| 900 void test_fieldFormalParameterNotAssignableToField_map_keyMismatch() { | |
| 901 // <num, int>{1: 2} has type Map<num, int>, which is not a subtype of | |
| 902 // Map<int, int>. | |
| 903 Source source = addSource(r''' | |
| 904 class A { | |
| 905 const A(Map<int, int> x); | |
| 906 } | |
| 907 var x = const A(const <num, int>{1: 2});'''); | |
| 908 computeLibrarySourceErrors(source); | |
| 909 assertErrors(source, [ | |
| 910 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH | |
| 911 ]); | |
| 912 verify([source]); | |
| 913 } | |
| 914 | |
| 915 void test_fieldFormalParameterNotAssignableToField_map_valueMismatch() { | |
| 916 // <int, num>{1: 2} has type Map<int, num>, which is not a subtype of | |
| 917 // Map<int, int>. | |
| 918 Source source = addSource(r''' | |
| 919 class A { | |
| 920 const A(Map<int, int> x); | |
| 921 } | |
| 922 var x = const A(const <int, num>{1: 2});'''); | |
| 923 computeLibrarySourceErrors(source); | |
| 924 assertErrors(source, [ | |
| 925 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH | |
| 926 ]); | |
| 927 verify([source]); | |
| 928 } | |
| 929 | |
| 930 void test_fieldFormalParameterNotAssignableToField_optional() { | |
| 931 Source source = addSource(r''' | |
| 932 class A { | |
| 933 final int x; | |
| 934 const A([this.x = 'foo']); | |
| 935 } | |
| 936 var v = const A();'''); | |
| 937 computeLibrarySourceErrors(source); | |
| 938 assertErrors(source, [ | |
| 939 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, | |
| 940 StaticTypeWarningCode.INVALID_ASSIGNMENT | |
| 941 ]); | |
| 942 verify([source]); | |
| 943 } | |
| 944 | |
| 945 void test_fieldFormalParameterNotAssignableToField_typedef() { | |
| 946 // foo has the runtime type String -> int, so it should not be assignable | |
| 947 // to A.f (A.f requires it to be int -> String). | |
| 948 Source source = addSource(r''' | |
| 949 typedef String Int2String(int x); | |
| 950 class A { | |
| 951 final Int2String f; | |
| 952 const A(this.f); | |
| 953 } | |
| 954 int foo(String x) => 1; | |
| 955 var v = const A(foo);'''); | |
| 956 computeLibrarySourceErrors(source); | |
| 957 assertErrors(source, [ | |
| 958 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, | |
| 959 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE | |
| 960 ]); | |
| 961 verify([source]); | |
| 962 } | |
| 963 | |
| 964 void test_fieldInitializerNotAssignable() { | |
| 965 Source source = addSource(r''' | |
| 966 class A { | |
| 967 final int x; | |
| 968 const A() : x = ''; | |
| 969 }'''); | |
| 970 computeLibrarySourceErrors(source); | |
| 971 assertErrors(source, [ | |
| 972 CheckedModeCompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE, | |
| 973 StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE | |
| 974 ]); | |
| 975 verify([source]); | |
| 976 } | |
| 977 | |
| 978 void test_fieldTypeMismatch() { | |
| 979 Source source = addSource(r''' | |
| 980 class A { | |
| 981 const A(x) : y = x; | |
| 982 final int y; | |
| 983 } | |
| 984 var v = const A('foo');'''); | |
| 985 computeLibrarySourceErrors(source); | |
| 986 assertErrors(source, [ | |
| 987 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH | |
| 988 ]); | |
| 989 verify([source]); | |
| 990 } | |
| 991 | |
| 992 void test_fieldTypeMismatch_generic() { | |
| 993 Source source = addSource(r''' | |
| 994 class C<T> { | |
| 995 final T x = y; | |
| 996 const C(); | |
| 997 } | |
| 998 const int y = 1; | |
| 999 var v = const C<String>(); | |
| 1000 '''); | |
| 1001 computeLibrarySourceErrors(source); | |
| 1002 assertErrors(source, [ | |
| 1003 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH, | |
| 1004 StaticTypeWarningCode.INVALID_ASSIGNMENT | |
| 1005 ]); | |
| 1006 verify([source]); | |
| 1007 } | |
| 1008 | |
| 1009 void test_fieldTypeMismatch_unresolved() { | |
| 1010 Source source = addSource(r''' | |
| 1011 class A { | |
| 1012 const A(x) : y = x; | |
| 1013 final Unresolved y; | |
| 1014 } | |
| 1015 var v = const A('foo');'''); | |
| 1016 computeLibrarySourceErrors(source); | |
| 1017 assertErrors(source, [ | |
| 1018 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH, | |
| 1019 StaticWarningCode.UNDEFINED_CLASS | |
| 1020 ]); | |
| 1021 verify([source]); | |
| 1022 } | |
| 1023 | |
| 1024 void test_fieldTypeOk_generic() { | |
| 1025 Source source = addSource(r''' | |
| 1026 class C<T> { | |
| 1027 final T x = y; | |
| 1028 const C(); | |
| 1029 } | |
| 1030 const int y = 1; | |
| 1031 var v = const C<int>(); | |
| 1032 '''); | |
| 1033 computeLibrarySourceErrors(source); | |
| 1034 assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]); | |
| 1035 verify([source]); | |
| 1036 } | |
| 1037 | |
| 1038 void test_fieldTypeOk_null() { | |
| 1039 Source source = addSource(r''' | |
| 1040 class A { | |
| 1041 const A(x) : y = x; | |
| 1042 final int y; | |
| 1043 } | |
| 1044 var v = const A(null);'''); | |
| 1045 computeLibrarySourceErrors(source); | |
| 1046 assertNoErrors(source); | |
| 1047 verify([source]); | |
| 1048 } | |
| 1049 | |
| 1050 void test_fieldTypeOk_unresolved_null() { | |
| 1051 // Null always passes runtime type checks, even when the type is | |
| 1052 // unresolved. | |
| 1053 Source source = addSource(r''' | |
| 1054 class A { | |
| 1055 const A(x) : y = x; | |
| 1056 final Unresolved y; | |
| 1057 } | |
| 1058 var v = const A(null);'''); | |
| 1059 computeLibrarySourceErrors(source); | |
| 1060 assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]); | |
| 1061 verify([source]); | |
| 1062 } | |
| 1063 | |
| 1064 void test_listElementTypeNotAssignable() { | |
| 1065 Source source = addSource("var v = const <String> [42];"); | |
| 1066 computeLibrarySourceErrors(source); | |
| 1067 assertErrors(source, [ | |
| 1068 CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE, | |
| 1069 StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE | |
| 1070 ]); | |
| 1071 verify([source]); | |
| 1072 } | |
| 1073 | |
| 1074 void test_mapKeyTypeNotAssignable() { | |
| 1075 Source source = addSource("var v = const <String, int > {1 : 2};"); | |
| 1076 computeLibrarySourceErrors(source); | |
| 1077 assertErrors(source, [ | |
| 1078 CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE, | |
| 1079 StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE | |
| 1080 ]); | |
| 1081 verify([source]); | |
| 1082 } | |
| 1083 | |
| 1084 void test_mapValueTypeNotAssignable() { | |
| 1085 Source source = addSource("var v = const <String, String> {'a' : 2};"); | |
| 1086 computeLibrarySourceErrors(source); | |
| 1087 assertErrors(source, [ | |
| 1088 CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE, | |
| 1089 StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE | |
| 1090 ]); | |
| 1091 verify([source]); | |
| 1092 } | |
| 1093 | |
| 1094 void test_parameterAssignable_null() { | |
| 1095 // Null is assignable to anything. | |
| 1096 Source source = addSource(r''' | |
| 1097 class A { | |
| 1098 const A(int x); | |
| 1099 } | |
| 1100 var v = const A(null);'''); | |
| 1101 computeLibrarySourceErrors(source); | |
| 1102 assertNoErrors(source); | |
| 1103 verify([source]); | |
| 1104 } | |
| 1105 | |
| 1106 void test_parameterAssignable_typeSubstitution() { | |
| 1107 Source source = addSource(r''' | |
| 1108 class A<T> { | |
| 1109 const A(T x); | |
| 1110 } | |
| 1111 var v = const A<int>(3);'''); | |
| 1112 computeLibrarySourceErrors(source); | |
| 1113 assertNoErrors(source); | |
| 1114 verify([source]); | |
| 1115 } | |
| 1116 | |
| 1117 void test_parameterAssignable_undefined_null() { | |
| 1118 // Null always passes runtime type checks, even when the type is | |
| 1119 // unresolved. | |
| 1120 Source source = addSource(r''' | |
| 1121 class A { | |
| 1122 const A(Unresolved x); | |
| 1123 } | |
| 1124 var v = const A(null);'''); | |
| 1125 computeLibrarySourceErrors(source); | |
| 1126 assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]); | |
| 1127 verify([source]); | |
| 1128 } | |
| 1129 | |
| 1130 void test_parameterNotAssignable() { | |
| 1131 Source source = addSource(r''' | |
| 1132 class A { | |
| 1133 const A(int x); | |
| 1134 } | |
| 1135 var v = const A('foo');'''); | |
| 1136 computeLibrarySourceErrors(source); | |
| 1137 assertErrors(source, [ | |
| 1138 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, | |
| 1139 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE | |
| 1140 ]); | |
| 1141 verify([source]); | |
| 1142 } | |
| 1143 | |
| 1144 void test_parameterNotAssignable_typeSubstitution() { | |
| 1145 Source source = addSource(r''' | |
| 1146 class A<T> { | |
| 1147 const A(T x); | |
| 1148 } | |
| 1149 var v = const A<int>('foo');'''); | |
| 1150 computeLibrarySourceErrors(source); | |
| 1151 assertErrors(source, [ | |
| 1152 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, | |
| 1153 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE | |
| 1154 ]); | |
| 1155 verify([source]); | |
| 1156 } | |
| 1157 | |
| 1158 void test_parameterNotAssignable_undefined() { | |
| 1159 Source source = addSource(r''' | |
| 1160 class A { | |
| 1161 const A(Unresolved x); | |
| 1162 } | |
| 1163 var v = const A('foo');'''); | |
| 1164 computeLibrarySourceErrors(source); | |
| 1165 assertErrors(source, [ | |
| 1166 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, | |
| 1167 StaticWarningCode.UNDEFINED_CLASS | |
| 1168 ]); | |
| 1169 verify([source]); | |
| 1170 } | |
| 1171 | |
| 1172 void test_redirectingConstructor_paramTypeMismatch() { | |
| 1173 Source source = addSource(r''' | |
| 1174 class A { | |
| 1175 const A.a1(x) : this.a2(x); | |
| 1176 const A.a2(String x); | |
| 1177 } | |
| 1178 var v = const A.a1(0);'''); | |
| 1179 computeLibrarySourceErrors(source); | |
| 1180 assertErrors(source, [ | |
| 1181 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH | |
| 1182 ]); | |
| 1183 verify([source]); | |
| 1184 } | |
| 1185 | |
| 1186 void test_topLevelVarAssignable_null() { | |
| 1187 Source source = addSource("const int x = null;"); | |
| 1188 computeLibrarySourceErrors(source); | |
| 1189 assertNoErrors(source); | |
| 1190 verify([source]); | |
| 1191 } | |
| 1192 | |
| 1193 void test_topLevelVarAssignable_undefined_null() { | |
| 1194 // Null always passes runtime type checks, even when the type is | |
| 1195 // unresolved. | |
| 1196 Source source = addSource("const Unresolved x = null;"); | |
| 1197 computeLibrarySourceErrors(source); | |
| 1198 assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]); | |
| 1199 verify([source]); | |
| 1200 } | |
| 1201 | |
| 1202 void test_topLevelVarNotAssignable() { | |
| 1203 Source source = addSource("const int x = 'foo';"); | |
| 1204 computeLibrarySourceErrors(source); | |
| 1205 assertErrors(source, [ | |
| 1206 CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, | |
| 1207 StaticTypeWarningCode.INVALID_ASSIGNMENT | |
| 1208 ]); | |
| 1209 verify([source]); | |
| 1210 } | |
| 1211 | |
| 1212 void test_topLevelVarNotAssignable_undefined() { | |
| 1213 Source source = addSource("const Unresolved x = 'foo';"); | |
| 1214 computeLibrarySourceErrors(source); | |
| 1215 assertErrors(source, [ | |
| 1216 CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, | |
| 1217 StaticWarningCode.UNDEFINED_CLASS | |
| 1218 ]); | |
| 1219 verify([source]); | |
| 1220 } | |
| 1221 } | |
| 1222 | |
| 1223 @reflectiveTest | |
| 1224 class ElementResolverTest extends EngineTestCase { | |
| 1225 /** | |
| 1226 * The error listener to which errors will be reported. | |
| 1227 */ | |
| 1228 GatheringErrorListener _listener; | |
| 1229 | |
| 1230 /** | |
| 1231 * The type provider used to access the types. | |
| 1232 */ | |
| 1233 TestTypeProvider _typeProvider; | |
| 1234 | |
| 1235 /** | |
| 1236 * The library containing the code being resolved. | |
| 1237 */ | |
| 1238 LibraryElementImpl _definingLibrary; | |
| 1239 | |
| 1240 /** | |
| 1241 * The resolver visitor that maintains the state for the resolver. | |
| 1242 */ | |
| 1243 ResolverVisitor _visitor; | |
| 1244 | |
| 1245 /** | |
| 1246 * The resolver being used to resolve the test cases. | |
| 1247 */ | |
| 1248 ElementResolver _resolver; | |
| 1249 | |
| 1250 void fail_visitExportDirective_combinators() { | |
| 1251 fail("Not yet tested"); | |
| 1252 // Need to set up the exported library so that the identifier can be | |
| 1253 // resolved. | |
| 1254 ExportDirective directive = AstFactory.exportDirective2(null, [ | |
| 1255 AstFactory.hideCombinator2(["A"]) | |
| 1256 ]); | |
| 1257 _resolveNode(directive); | |
| 1258 _listener.assertNoErrors(); | |
| 1259 } | |
| 1260 | |
| 1261 void fail_visitFunctionExpressionInvocation() { | |
| 1262 fail("Not yet tested"); | |
| 1263 _listener.assertNoErrors(); | |
| 1264 } | |
| 1265 | |
| 1266 void fail_visitImportDirective_combinators_noPrefix() { | |
| 1267 fail("Not yet tested"); | |
| 1268 // Need to set up the imported library so that the identifier can be | |
| 1269 // resolved. | |
| 1270 ImportDirective directive = AstFactory.importDirective3(null, null, [ | |
| 1271 AstFactory.showCombinator2(["A"]) | |
| 1272 ]); | |
| 1273 _resolveNode(directive); | |
| 1274 _listener.assertNoErrors(); | |
| 1275 } | |
| 1276 | |
| 1277 void fail_visitImportDirective_combinators_prefix() { | |
| 1278 fail("Not yet tested"); | |
| 1279 // Need to set up the imported library so that the identifiers can be | |
| 1280 // resolved. | |
| 1281 String prefixName = "p"; | |
| 1282 _definingLibrary.imports = <ImportElement>[ | |
| 1283 ElementFactory.importFor(null, ElementFactory.prefix(prefixName)) | |
| 1284 ]; | |
| 1285 ImportDirective directive = AstFactory.importDirective3(null, prefixName, [ | |
| 1286 AstFactory.showCombinator2(["A"]), | |
| 1287 AstFactory.hideCombinator2(["B"]) | |
| 1288 ]); | |
| 1289 _resolveNode(directive); | |
| 1290 _listener.assertNoErrors(); | |
| 1291 } | |
| 1292 | |
| 1293 void fail_visitRedirectingConstructorInvocation() { | |
| 1294 fail("Not yet tested"); | |
| 1295 _listener.assertNoErrors(); | |
| 1296 } | |
| 1297 | |
| 1298 @override | |
| 1299 void setUp() { | |
| 1300 _listener = new GatheringErrorListener(); | |
| 1301 _typeProvider = new TestTypeProvider(); | |
| 1302 _resolver = _createResolver(); | |
| 1303 } | |
| 1304 | |
| 1305 void test_lookUpMethodInInterfaces() { | |
| 1306 InterfaceType intType = _typeProvider.intType; | |
| 1307 // | |
| 1308 // abstract class A { int operator[](int index); } | |
| 1309 // | |
| 1310 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1311 MethodElement operator = | |
| 1312 ElementFactory.methodElement("[]", intType, [intType]); | |
| 1313 classA.methods = <MethodElement>[operator]; | |
| 1314 // | |
| 1315 // class B implements A {} | |
| 1316 // | |
| 1317 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 1318 classB.interfaces = <InterfaceType>[classA.type]; | |
| 1319 // | |
| 1320 // class C extends Object with B {} | |
| 1321 // | |
| 1322 ClassElementImpl classC = ElementFactory.classElement2("C"); | |
| 1323 classC.mixins = <InterfaceType>[classB.type]; | |
| 1324 // | |
| 1325 // class D extends C {} | |
| 1326 // | |
| 1327 ClassElementImpl classD = ElementFactory.classElement("D", classC.type); | |
| 1328 // | |
| 1329 // D a; | |
| 1330 // a[i]; | |
| 1331 // | |
| 1332 SimpleIdentifier array = AstFactory.identifier3("a"); | |
| 1333 array.staticType = classD.type; | |
| 1334 IndexExpression expression = | |
| 1335 AstFactory.indexExpression(array, AstFactory.identifier3("i")); | |
| 1336 expect(_resolveIndexExpression(expression), same(operator)); | |
| 1337 _listener.assertNoErrors(); | |
| 1338 } | |
| 1339 | |
| 1340 void test_visitAssignmentExpression_compound() { | |
| 1341 InterfaceType intType = _typeProvider.intType; | |
| 1342 SimpleIdentifier leftHandSide = AstFactory.identifier3("a"); | |
| 1343 leftHandSide.staticType = intType; | |
| 1344 AssignmentExpression assignment = AstFactory.assignmentExpression( | |
| 1345 leftHandSide, TokenType.PLUS_EQ, AstFactory.integer(1)); | |
| 1346 _resolveNode(assignment); | |
| 1347 expect( | |
| 1348 assignment.staticElement, same(getMethod(_typeProvider.numType, "+"))); | |
| 1349 _listener.assertNoErrors(); | |
| 1350 } | |
| 1351 | |
| 1352 void test_visitAssignmentExpression_simple() { | |
| 1353 AssignmentExpression expression = AstFactory.assignmentExpression( | |
| 1354 AstFactory.identifier3("x"), TokenType.EQ, AstFactory.integer(0)); | |
| 1355 _resolveNode(expression); | |
| 1356 expect(expression.staticElement, isNull); | |
| 1357 _listener.assertNoErrors(); | |
| 1358 } | |
| 1359 | |
| 1360 void test_visitBinaryExpression_bangEq() { | |
| 1361 // String i; | |
| 1362 // var j; | |
| 1363 // i == j | |
| 1364 InterfaceType stringType = _typeProvider.stringType; | |
| 1365 SimpleIdentifier left = AstFactory.identifier3("i"); | |
| 1366 left.staticType = stringType; | |
| 1367 BinaryExpression expression = AstFactory.binaryExpression( | |
| 1368 left, TokenType.BANG_EQ, AstFactory.identifier3("j")); | |
| 1369 _resolveNode(expression); | |
| 1370 var stringElement = stringType.element; | |
| 1371 expect(expression.staticElement, isNotNull); | |
| 1372 expect( | |
| 1373 expression.staticElement, | |
| 1374 stringElement.lookUpMethod( | |
| 1375 TokenType.EQ_EQ.lexeme, stringElement.library)); | |
| 1376 expect(expression.propagatedElement, isNull); | |
| 1377 _listener.assertNoErrors(); | |
| 1378 } | |
| 1379 | |
| 1380 void test_visitBinaryExpression_eq() { | |
| 1381 // String i; | |
| 1382 // var j; | |
| 1383 // i == j | |
| 1384 InterfaceType stringType = _typeProvider.stringType; | |
| 1385 SimpleIdentifier left = AstFactory.identifier3("i"); | |
| 1386 left.staticType = stringType; | |
| 1387 BinaryExpression expression = AstFactory.binaryExpression( | |
| 1388 left, TokenType.EQ_EQ, AstFactory.identifier3("j")); | |
| 1389 _resolveNode(expression); | |
| 1390 var stringElement = stringType.element; | |
| 1391 expect( | |
| 1392 expression.staticElement, | |
| 1393 stringElement.lookUpMethod( | |
| 1394 TokenType.EQ_EQ.lexeme, stringElement.library)); | |
| 1395 expect(expression.propagatedElement, isNull); | |
| 1396 _listener.assertNoErrors(); | |
| 1397 } | |
| 1398 | |
| 1399 void test_visitBinaryExpression_plus() { | |
| 1400 // num i; | |
| 1401 // var j; | |
| 1402 // i + j | |
| 1403 InterfaceType numType = _typeProvider.numType; | |
| 1404 SimpleIdentifier left = AstFactory.identifier3("i"); | |
| 1405 left.staticType = numType; | |
| 1406 BinaryExpression expression = AstFactory.binaryExpression( | |
| 1407 left, TokenType.PLUS, AstFactory.identifier3("j")); | |
| 1408 _resolveNode(expression); | |
| 1409 expect(expression.staticElement, getMethod(numType, "+")); | |
| 1410 expect(expression.propagatedElement, isNull); | |
| 1411 _listener.assertNoErrors(); | |
| 1412 } | |
| 1413 | |
| 1414 void test_visitBinaryExpression_plus_propagatedElement() { | |
| 1415 // var i = 1; | |
| 1416 // var j; | |
| 1417 // i + j | |
| 1418 InterfaceType numType = _typeProvider.numType; | |
| 1419 SimpleIdentifier left = AstFactory.identifier3("i"); | |
| 1420 left.propagatedType = numType; | |
| 1421 BinaryExpression expression = AstFactory.binaryExpression( | |
| 1422 left, TokenType.PLUS, AstFactory.identifier3("j")); | |
| 1423 _resolveNode(expression); | |
| 1424 expect(expression.staticElement, isNull); | |
| 1425 expect(expression.propagatedElement, getMethod(numType, "+")); | |
| 1426 _listener.assertNoErrors(); | |
| 1427 } | |
| 1428 | |
| 1429 void test_visitBreakStatement_withLabel() { | |
| 1430 // loop: while (true) { | |
| 1431 // break loop; | |
| 1432 // } | |
| 1433 String label = "loop"; | |
| 1434 LabelElementImpl labelElement = | |
| 1435 new LabelElementImpl(AstFactory.identifier3(label), false, false); | |
| 1436 BreakStatement breakStatement = AstFactory.breakStatement2(label); | |
| 1437 Expression condition = AstFactory.booleanLiteral(true); | |
| 1438 WhileStatement whileStatement = | |
| 1439 AstFactory.whileStatement(condition, breakStatement); | |
| 1440 expect(_resolveBreak(breakStatement, labelElement, whileStatement), | |
| 1441 same(labelElement)); | |
| 1442 expect(breakStatement.target, same(whileStatement)); | |
| 1443 _listener.assertNoErrors(); | |
| 1444 } | |
| 1445 | |
| 1446 void test_visitBreakStatement_withoutLabel() { | |
| 1447 BreakStatement statement = AstFactory.breakStatement(); | |
| 1448 _resolveStatement(statement, null, null); | |
| 1449 _listener.assertNoErrors(); | |
| 1450 } | |
| 1451 | |
| 1452 void test_visitConstructorName_named() { | |
| 1453 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1454 String constructorName = "a"; | |
| 1455 ConstructorElement constructor = | |
| 1456 ElementFactory.constructorElement2(classA, constructorName); | |
| 1457 classA.constructors = <ConstructorElement>[constructor]; | |
| 1458 ConstructorName name = AstFactory.constructorName( | |
| 1459 AstFactory.typeName(classA), constructorName); | |
| 1460 _resolveNode(name); | |
| 1461 expect(name.staticElement, same(constructor)); | |
| 1462 _listener.assertNoErrors(); | |
| 1463 } | |
| 1464 | |
| 1465 void test_visitConstructorName_unnamed() { | |
| 1466 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1467 String constructorName = null; | |
| 1468 ConstructorElement constructor = | |
| 1469 ElementFactory.constructorElement2(classA, constructorName); | |
| 1470 classA.constructors = <ConstructorElement>[constructor]; | |
| 1471 ConstructorName name = AstFactory.constructorName( | |
| 1472 AstFactory.typeName(classA), constructorName); | |
| 1473 _resolveNode(name); | |
| 1474 expect(name.staticElement, same(constructor)); | |
| 1475 _listener.assertNoErrors(); | |
| 1476 } | |
| 1477 | |
| 1478 void test_visitContinueStatement_withLabel() { | |
| 1479 // loop: while (true) { | |
| 1480 // continue loop; | |
| 1481 // } | |
| 1482 String label = "loop"; | |
| 1483 LabelElementImpl labelElement = | |
| 1484 new LabelElementImpl(AstFactory.identifier3(label), false, false); | |
| 1485 ContinueStatement continueStatement = AstFactory.continueStatement(label); | |
| 1486 Expression condition = AstFactory.booleanLiteral(true); | |
| 1487 WhileStatement whileStatement = | |
| 1488 AstFactory.whileStatement(condition, continueStatement); | |
| 1489 expect(_resolveContinue(continueStatement, labelElement, whileStatement), | |
| 1490 same(labelElement)); | |
| 1491 expect(continueStatement.target, same(whileStatement)); | |
| 1492 _listener.assertNoErrors(); | |
| 1493 } | |
| 1494 | |
| 1495 void test_visitContinueStatement_withoutLabel() { | |
| 1496 ContinueStatement statement = AstFactory.continueStatement(); | |
| 1497 _resolveStatement(statement, null, null); | |
| 1498 _listener.assertNoErrors(); | |
| 1499 } | |
| 1500 | |
| 1501 void test_visitEnumDeclaration() { | |
| 1502 ClassElementImpl enumElement = | |
| 1503 ElementFactory.enumElement(_typeProvider, ('E')); | |
| 1504 EnumDeclaration enumNode = AstFactory.enumDeclaration2('E', []); | |
| 1505 Annotation annotationNode = | |
| 1506 AstFactory.annotation(AstFactory.identifier3('a')); | |
| 1507 annotationNode.element = ElementFactory.classElement2('A'); | |
| 1508 enumNode.metadata.add(annotationNode); | |
| 1509 enumNode.name.staticElement = enumElement; | |
| 1510 _resolveNode(enumNode); | |
| 1511 List<ElementAnnotation> metadata = enumElement.metadata; | |
| 1512 expect(metadata, hasLength(1)); | |
| 1513 } | |
| 1514 | |
| 1515 void test_visitExportDirective_noCombinators() { | |
| 1516 ExportDirective directive = AstFactory.exportDirective2(null); | |
| 1517 directive.element = ElementFactory | |
| 1518 .exportFor(ElementFactory.library(_definingLibrary.context, "lib")); | |
| 1519 _resolveNode(directive); | |
| 1520 _listener.assertNoErrors(); | |
| 1521 } | |
| 1522 | |
| 1523 void test_visitFieldFormalParameter() { | |
| 1524 String fieldName = "f"; | |
| 1525 InterfaceType intType = _typeProvider.intType; | |
| 1526 FieldElementImpl fieldElement = | |
| 1527 ElementFactory.fieldElement(fieldName, false, false, false, intType); | |
| 1528 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1529 classA.fields = <FieldElement>[fieldElement]; | |
| 1530 FieldFormalParameter parameter = | |
| 1531 AstFactory.fieldFormalParameter2(fieldName); | |
| 1532 FieldFormalParameterElementImpl parameterElement = | |
| 1533 ElementFactory.fieldFormalParameter(parameter.identifier); | |
| 1534 parameterElement.field = fieldElement; | |
| 1535 parameterElement.type = intType; | |
| 1536 parameter.identifier.staticElement = parameterElement; | |
| 1537 _resolveInClass(parameter, classA); | |
| 1538 expect(parameter.element.type, same(intType)); | |
| 1539 } | |
| 1540 | |
| 1541 void test_visitImportDirective_noCombinators_noPrefix() { | |
| 1542 ImportDirective directive = AstFactory.importDirective3(null, null); | |
| 1543 directive.element = ElementFactory.importFor( | |
| 1544 ElementFactory.library(_definingLibrary.context, "lib"), null); | |
| 1545 _resolveNode(directive); | |
| 1546 _listener.assertNoErrors(); | |
| 1547 } | |
| 1548 | |
| 1549 void test_visitImportDirective_noCombinators_prefix() { | |
| 1550 String prefixName = "p"; | |
| 1551 ImportElement importElement = ElementFactory.importFor( | |
| 1552 ElementFactory.library(_definingLibrary.context, "lib"), | |
| 1553 ElementFactory.prefix(prefixName)); | |
| 1554 _definingLibrary.imports = <ImportElement>[importElement]; | |
| 1555 ImportDirective directive = AstFactory.importDirective3(null, prefixName); | |
| 1556 directive.element = importElement; | |
| 1557 _resolveNode(directive); | |
| 1558 _listener.assertNoErrors(); | |
| 1559 } | |
| 1560 | |
| 1561 void test_visitImportDirective_withCombinators() { | |
| 1562 ShowCombinator combinator = AstFactory.showCombinator2(["A", "B", "C"]); | |
| 1563 ImportDirective directive = | |
| 1564 AstFactory.importDirective3(null, null, [combinator]); | |
| 1565 LibraryElementImpl library = | |
| 1566 ElementFactory.library(_definingLibrary.context, "lib"); | |
| 1567 TopLevelVariableElementImpl varA = | |
| 1568 ElementFactory.topLevelVariableElement2("A"); | |
| 1569 TopLevelVariableElementImpl varB = | |
| 1570 ElementFactory.topLevelVariableElement2("B"); | |
| 1571 TopLevelVariableElementImpl varC = | |
| 1572 ElementFactory.topLevelVariableElement2("C"); | |
| 1573 CompilationUnitElementImpl unit = | |
| 1574 library.definingCompilationUnit as CompilationUnitElementImpl; | |
| 1575 unit.accessors = <PropertyAccessorElement>[ | |
| 1576 varA.getter, | |
| 1577 varA.setter, | |
| 1578 varB.getter, | |
| 1579 varC.setter | |
| 1580 ]; | |
| 1581 unit.topLevelVariables = <TopLevelVariableElement>[varA, varB, varC]; | |
| 1582 directive.element = ElementFactory.importFor(library, null); | |
| 1583 _resolveNode(directive); | |
| 1584 expect(combinator.shownNames[0].staticElement, same(varA)); | |
| 1585 expect(combinator.shownNames[1].staticElement, same(varB)); | |
| 1586 expect(combinator.shownNames[2].staticElement, same(varC)); | |
| 1587 _listener.assertNoErrors(); | |
| 1588 } | |
| 1589 | |
| 1590 void test_visitIndexExpression_get() { | |
| 1591 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1592 InterfaceType intType = _typeProvider.intType; | |
| 1593 MethodElement getter = | |
| 1594 ElementFactory.methodElement("[]", intType, [intType]); | |
| 1595 classA.methods = <MethodElement>[getter]; | |
| 1596 SimpleIdentifier array = AstFactory.identifier3("a"); | |
| 1597 array.staticType = classA.type; | |
| 1598 IndexExpression expression = | |
| 1599 AstFactory.indexExpression(array, AstFactory.identifier3("i")); | |
| 1600 expect(_resolveIndexExpression(expression), same(getter)); | |
| 1601 _listener.assertNoErrors(); | |
| 1602 } | |
| 1603 | |
| 1604 void test_visitIndexExpression_set() { | |
| 1605 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1606 InterfaceType intType = _typeProvider.intType; | |
| 1607 MethodElement setter = | |
| 1608 ElementFactory.methodElement("[]=", intType, [intType]); | |
| 1609 classA.methods = <MethodElement>[setter]; | |
| 1610 SimpleIdentifier array = AstFactory.identifier3("a"); | |
| 1611 array.staticType = classA.type; | |
| 1612 IndexExpression expression = | |
| 1613 AstFactory.indexExpression(array, AstFactory.identifier3("i")); | |
| 1614 AstFactory.assignmentExpression( | |
| 1615 expression, TokenType.EQ, AstFactory.integer(0)); | |
| 1616 expect(_resolveIndexExpression(expression), same(setter)); | |
| 1617 _listener.assertNoErrors(); | |
| 1618 } | |
| 1619 | |
| 1620 void test_visitInstanceCreationExpression_named() { | |
| 1621 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1622 String constructorName = "a"; | |
| 1623 ConstructorElement constructor = | |
| 1624 ElementFactory.constructorElement2(classA, constructorName); | |
| 1625 classA.constructors = <ConstructorElement>[constructor]; | |
| 1626 ConstructorName name = AstFactory.constructorName( | |
| 1627 AstFactory.typeName(classA), constructorName); | |
| 1628 name.staticElement = constructor; | |
| 1629 InstanceCreationExpression creation = | |
| 1630 AstFactory.instanceCreationExpression(Keyword.NEW, name); | |
| 1631 _resolveNode(creation); | |
| 1632 expect(creation.staticElement, same(constructor)); | |
| 1633 _listener.assertNoErrors(); | |
| 1634 } | |
| 1635 | |
| 1636 void test_visitInstanceCreationExpression_unnamed() { | |
| 1637 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1638 String constructorName = null; | |
| 1639 ConstructorElement constructor = | |
| 1640 ElementFactory.constructorElement2(classA, constructorName); | |
| 1641 classA.constructors = <ConstructorElement>[constructor]; | |
| 1642 ConstructorName name = AstFactory.constructorName( | |
| 1643 AstFactory.typeName(classA), constructorName); | |
| 1644 name.staticElement = constructor; | |
| 1645 InstanceCreationExpression creation = | |
| 1646 AstFactory.instanceCreationExpression(Keyword.NEW, name); | |
| 1647 _resolveNode(creation); | |
| 1648 expect(creation.staticElement, same(constructor)); | |
| 1649 _listener.assertNoErrors(); | |
| 1650 } | |
| 1651 | |
| 1652 void test_visitInstanceCreationExpression_unnamed_namedParameter() { | |
| 1653 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1654 String constructorName = null; | |
| 1655 ConstructorElementImpl constructor = | |
| 1656 ElementFactory.constructorElement2(classA, constructorName); | |
| 1657 String parameterName = "a"; | |
| 1658 ParameterElement parameter = ElementFactory.namedParameter(parameterName); | |
| 1659 constructor.parameters = <ParameterElement>[parameter]; | |
| 1660 classA.constructors = <ConstructorElement>[constructor]; | |
| 1661 ConstructorName name = AstFactory.constructorName( | |
| 1662 AstFactory.typeName(classA), constructorName); | |
| 1663 name.staticElement = constructor; | |
| 1664 InstanceCreationExpression creation = AstFactory.instanceCreationExpression( | |
| 1665 Keyword.NEW, | |
| 1666 name, | |
| 1667 [AstFactory.namedExpression2(parameterName, AstFactory.integer(0))]); | |
| 1668 _resolveNode(creation); | |
| 1669 expect(creation.staticElement, same(constructor)); | |
| 1670 expect( | |
| 1671 (creation.argumentList.arguments[0] as NamedExpression) | |
| 1672 .name | |
| 1673 .label | |
| 1674 .staticElement, | |
| 1675 same(parameter)); | |
| 1676 _listener.assertNoErrors(); | |
| 1677 } | |
| 1678 | |
| 1679 void test_visitMethodInvocation() { | |
| 1680 InterfaceType numType = _typeProvider.numType; | |
| 1681 SimpleIdentifier left = AstFactory.identifier3("i"); | |
| 1682 left.staticType = numType; | |
| 1683 String methodName = "abs"; | |
| 1684 MethodInvocation invocation = AstFactory.methodInvocation(left, methodName); | |
| 1685 _resolveNode(invocation); | |
| 1686 expect(invocation.methodName.staticElement, | |
| 1687 same(getMethod(numType, methodName))); | |
| 1688 _listener.assertNoErrors(); | |
| 1689 } | |
| 1690 | |
| 1691 void test_visitMethodInvocation_namedParameter() { | |
| 1692 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1693 String methodName = "m"; | |
| 1694 String parameterName = "p"; | |
| 1695 MethodElementImpl method = ElementFactory.methodElement(methodName, null); | |
| 1696 ParameterElement parameter = ElementFactory.namedParameter(parameterName); | |
| 1697 method.parameters = <ParameterElement>[parameter]; | |
| 1698 classA.methods = <MethodElement>[method]; | |
| 1699 SimpleIdentifier left = AstFactory.identifier3("i"); | |
| 1700 left.staticType = classA.type; | |
| 1701 MethodInvocation invocation = AstFactory.methodInvocation(left, methodName, | |
| 1702 [AstFactory.namedExpression2(parameterName, AstFactory.integer(0))]); | |
| 1703 _resolveNode(invocation); | |
| 1704 expect(invocation.methodName.staticElement, same(method)); | |
| 1705 expect( | |
| 1706 (invocation.argumentList.arguments[0] as NamedExpression) | |
| 1707 .name | |
| 1708 .label | |
| 1709 .staticElement, | |
| 1710 same(parameter)); | |
| 1711 _listener.assertNoErrors(); | |
| 1712 } | |
| 1713 | |
| 1714 void test_visitPostfixExpression() { | |
| 1715 InterfaceType numType = _typeProvider.numType; | |
| 1716 SimpleIdentifier operand = AstFactory.identifier3("i"); | |
| 1717 operand.staticType = numType; | |
| 1718 PostfixExpression expression = | |
| 1719 AstFactory.postfixExpression(operand, TokenType.PLUS_PLUS); | |
| 1720 _resolveNode(expression); | |
| 1721 expect(expression.staticElement, getMethod(numType, "+")); | |
| 1722 _listener.assertNoErrors(); | |
| 1723 } | |
| 1724 | |
| 1725 void test_visitPrefixedIdentifier_dynamic() { | |
| 1726 DartType dynamicType = _typeProvider.dynamicType; | |
| 1727 SimpleIdentifier target = AstFactory.identifier3("a"); | |
| 1728 VariableElementImpl variable = ElementFactory.localVariableElement(target); | |
| 1729 variable.type = dynamicType; | |
| 1730 target.staticElement = variable; | |
| 1731 target.staticType = dynamicType; | |
| 1732 PrefixedIdentifier identifier = | |
| 1733 AstFactory.identifier(target, AstFactory.identifier3("b")); | |
| 1734 _resolveNode(identifier); | |
| 1735 expect(identifier.staticElement, isNull); | |
| 1736 expect(identifier.identifier.staticElement, isNull); | |
| 1737 _listener.assertNoErrors(); | |
| 1738 } | |
| 1739 | |
| 1740 void test_visitPrefixedIdentifier_nonDynamic() { | |
| 1741 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1742 String getterName = "b"; | |
| 1743 PropertyAccessorElement getter = | |
| 1744 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 1745 classA.accessors = <PropertyAccessorElement>[getter]; | |
| 1746 SimpleIdentifier target = AstFactory.identifier3("a"); | |
| 1747 VariableElementImpl variable = ElementFactory.localVariableElement(target); | |
| 1748 variable.type = classA.type; | |
| 1749 target.staticElement = variable; | |
| 1750 target.staticType = classA.type; | |
| 1751 PrefixedIdentifier identifier = | |
| 1752 AstFactory.identifier(target, AstFactory.identifier3(getterName)); | |
| 1753 _resolveNode(identifier); | |
| 1754 expect(identifier.staticElement, same(getter)); | |
| 1755 expect(identifier.identifier.staticElement, same(getter)); | |
| 1756 _listener.assertNoErrors(); | |
| 1757 } | |
| 1758 | |
| 1759 void test_visitPrefixedIdentifier_staticClassMember_getter() { | |
| 1760 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1761 // set accessors | |
| 1762 String propName = "b"; | |
| 1763 PropertyAccessorElement getter = | |
| 1764 ElementFactory.getterElement(propName, false, _typeProvider.intType); | |
| 1765 PropertyAccessorElement setter = | |
| 1766 ElementFactory.setterElement(propName, false, _typeProvider.intType); | |
| 1767 classA.accessors = <PropertyAccessorElement>[getter, setter]; | |
| 1768 // prepare "A.m" | |
| 1769 SimpleIdentifier target = AstFactory.identifier3("A"); | |
| 1770 target.staticElement = classA; | |
| 1771 target.staticType = classA.type; | |
| 1772 PrefixedIdentifier identifier = | |
| 1773 AstFactory.identifier(target, AstFactory.identifier3(propName)); | |
| 1774 // resolve | |
| 1775 _resolveNode(identifier); | |
| 1776 expect(identifier.staticElement, same(getter)); | |
| 1777 expect(identifier.identifier.staticElement, same(getter)); | |
| 1778 _listener.assertNoErrors(); | |
| 1779 } | |
| 1780 | |
| 1781 void test_visitPrefixedIdentifier_staticClassMember_method() { | |
| 1782 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1783 // set methods | |
| 1784 String propName = "m"; | |
| 1785 MethodElement method = | |
| 1786 ElementFactory.methodElement("m", _typeProvider.intType); | |
| 1787 classA.methods = <MethodElement>[method]; | |
| 1788 // prepare "A.m" | |
| 1789 SimpleIdentifier target = AstFactory.identifier3("A"); | |
| 1790 target.staticElement = classA; | |
| 1791 target.staticType = classA.type; | |
| 1792 PrefixedIdentifier identifier = | |
| 1793 AstFactory.identifier(target, AstFactory.identifier3(propName)); | |
| 1794 AstFactory.assignmentExpression( | |
| 1795 identifier, TokenType.EQ, AstFactory.nullLiteral()); | |
| 1796 // resolve | |
| 1797 _resolveNode(identifier); | |
| 1798 expect(identifier.staticElement, same(method)); | |
| 1799 expect(identifier.identifier.staticElement, same(method)); | |
| 1800 _listener.assertNoErrors(); | |
| 1801 } | |
| 1802 | |
| 1803 void test_visitPrefixedIdentifier_staticClassMember_setter() { | |
| 1804 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1805 // set accessors | |
| 1806 String propName = "b"; | |
| 1807 PropertyAccessorElement getter = | |
| 1808 ElementFactory.getterElement(propName, false, _typeProvider.intType); | |
| 1809 PropertyAccessorElement setter = | |
| 1810 ElementFactory.setterElement(propName, false, _typeProvider.intType); | |
| 1811 classA.accessors = <PropertyAccessorElement>[getter, setter]; | |
| 1812 // prepare "A.b = null" | |
| 1813 SimpleIdentifier target = AstFactory.identifier3("A"); | |
| 1814 target.staticElement = classA; | |
| 1815 target.staticType = classA.type; | |
| 1816 PrefixedIdentifier identifier = | |
| 1817 AstFactory.identifier(target, AstFactory.identifier3(propName)); | |
| 1818 AstFactory.assignmentExpression( | |
| 1819 identifier, TokenType.EQ, AstFactory.nullLiteral()); | |
| 1820 // resolve | |
| 1821 _resolveNode(identifier); | |
| 1822 expect(identifier.staticElement, same(setter)); | |
| 1823 expect(identifier.identifier.staticElement, same(setter)); | |
| 1824 _listener.assertNoErrors(); | |
| 1825 } | |
| 1826 | |
| 1827 void test_visitPrefixExpression() { | |
| 1828 InterfaceType numType = _typeProvider.numType; | |
| 1829 SimpleIdentifier operand = AstFactory.identifier3("i"); | |
| 1830 operand.staticType = numType; | |
| 1831 PrefixExpression expression = | |
| 1832 AstFactory.prefixExpression(TokenType.PLUS_PLUS, operand); | |
| 1833 _resolveNode(expression); | |
| 1834 expect(expression.staticElement, getMethod(numType, "+")); | |
| 1835 _listener.assertNoErrors(); | |
| 1836 } | |
| 1837 | |
| 1838 void test_visitPropertyAccess_getter_identifier() { | |
| 1839 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1840 String getterName = "b"; | |
| 1841 PropertyAccessorElement getter = | |
| 1842 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 1843 classA.accessors = <PropertyAccessorElement>[getter]; | |
| 1844 SimpleIdentifier target = AstFactory.identifier3("a"); | |
| 1845 target.staticType = classA.type; | |
| 1846 PropertyAccess access = AstFactory.propertyAccess2(target, getterName); | |
| 1847 _resolveNode(access); | |
| 1848 expect(access.propertyName.staticElement, same(getter)); | |
| 1849 _listener.assertNoErrors(); | |
| 1850 } | |
| 1851 | |
| 1852 void test_visitPropertyAccess_getter_super() { | |
| 1853 // | |
| 1854 // class A { | |
| 1855 // int get b; | |
| 1856 // } | |
| 1857 // class B { | |
| 1858 // ... super.m ... | |
| 1859 // } | |
| 1860 // | |
| 1861 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1862 String getterName = "b"; | |
| 1863 PropertyAccessorElement getter = | |
| 1864 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 1865 classA.accessors = <PropertyAccessorElement>[getter]; | |
| 1866 SuperExpression target = AstFactory.superExpression(); | |
| 1867 target.staticType = ElementFactory.classElement("B", classA.type).type; | |
| 1868 PropertyAccess access = AstFactory.propertyAccess2(target, getterName); | |
| 1869 AstFactory.methodDeclaration2( | |
| 1870 null, | |
| 1871 null, | |
| 1872 null, | |
| 1873 null, | |
| 1874 AstFactory.identifier3("m"), | |
| 1875 AstFactory.formalParameterList(), | |
| 1876 AstFactory.expressionFunctionBody(access)); | |
| 1877 _resolveNode(access); | |
| 1878 expect(access.propertyName.staticElement, same(getter)); | |
| 1879 _listener.assertNoErrors(); | |
| 1880 } | |
| 1881 | |
| 1882 void test_visitPropertyAccess_setter_this() { | |
| 1883 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1884 String setterName = "b"; | |
| 1885 PropertyAccessorElement setter = | |
| 1886 ElementFactory.setterElement(setterName, false, _typeProvider.intType); | |
| 1887 classA.accessors = <PropertyAccessorElement>[setter]; | |
| 1888 ThisExpression target = AstFactory.thisExpression(); | |
| 1889 target.staticType = classA.type; | |
| 1890 PropertyAccess access = AstFactory.propertyAccess2(target, setterName); | |
| 1891 AstFactory.assignmentExpression( | |
| 1892 access, TokenType.EQ, AstFactory.integer(0)); | |
| 1893 _resolveNode(access); | |
| 1894 expect(access.propertyName.staticElement, same(setter)); | |
| 1895 _listener.assertNoErrors(); | |
| 1896 } | |
| 1897 | |
| 1898 void test_visitSimpleIdentifier_classScope() { | |
| 1899 InterfaceType doubleType = _typeProvider.doubleType; | |
| 1900 String fieldName = "NAN"; | |
| 1901 SimpleIdentifier node = AstFactory.identifier3(fieldName); | |
| 1902 _resolveInClass(node, doubleType.element); | |
| 1903 expect(node.staticElement, getGetter(doubleType, fieldName)); | |
| 1904 _listener.assertNoErrors(); | |
| 1905 } | |
| 1906 | |
| 1907 void test_visitSimpleIdentifier_dynamic() { | |
| 1908 SimpleIdentifier node = AstFactory.identifier3("dynamic"); | |
| 1909 _resolveIdentifier(node); | |
| 1910 expect(node.staticElement, same(_typeProvider.dynamicType.element)); | |
| 1911 expect(node.staticType, same(_typeProvider.typeType)); | |
| 1912 _listener.assertNoErrors(); | |
| 1913 } | |
| 1914 | |
| 1915 void test_visitSimpleIdentifier_lexicalScope() { | |
| 1916 SimpleIdentifier node = AstFactory.identifier3("i"); | |
| 1917 VariableElementImpl element = ElementFactory.localVariableElement(node); | |
| 1918 expect(_resolveIdentifier(node, [element]), same(element)); | |
| 1919 _listener.assertNoErrors(); | |
| 1920 } | |
| 1921 | |
| 1922 void test_visitSimpleIdentifier_lexicalScope_field_setter() { | |
| 1923 InterfaceType intType = _typeProvider.intType; | |
| 1924 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1925 String fieldName = "a"; | |
| 1926 FieldElement field = | |
| 1927 ElementFactory.fieldElement(fieldName, false, false, false, intType); | |
| 1928 classA.fields = <FieldElement>[field]; | |
| 1929 classA.accessors = <PropertyAccessorElement>[field.getter, field.setter]; | |
| 1930 SimpleIdentifier node = AstFactory.identifier3(fieldName); | |
| 1931 AstFactory.assignmentExpression(node, TokenType.EQ, AstFactory.integer(0)); | |
| 1932 _resolveInClass(node, classA); | |
| 1933 Element element = node.staticElement; | |
| 1934 EngineTestCase.assertInstanceOf((obj) => obj is PropertyAccessorElement, | |
| 1935 PropertyAccessorElement, element); | |
| 1936 expect((element as PropertyAccessorElement).isSetter, isTrue); | |
| 1937 _listener.assertNoErrors(); | |
| 1938 } | |
| 1939 | |
| 1940 void test_visitSuperConstructorInvocation() { | |
| 1941 ClassElementImpl superclass = ElementFactory.classElement2("A"); | |
| 1942 ConstructorElementImpl superConstructor = | |
| 1943 ElementFactory.constructorElement2(superclass, null); | |
| 1944 superclass.constructors = <ConstructorElement>[superConstructor]; | |
| 1945 ClassElementImpl subclass = | |
| 1946 ElementFactory.classElement("B", superclass.type); | |
| 1947 ConstructorElementImpl subConstructor = | |
| 1948 ElementFactory.constructorElement2(subclass, null); | |
| 1949 subclass.constructors = <ConstructorElement>[subConstructor]; | |
| 1950 SuperConstructorInvocation invocation = | |
| 1951 AstFactory.superConstructorInvocation(); | |
| 1952 _resolveInClass(invocation, subclass); | |
| 1953 expect(invocation.staticElement, superConstructor); | |
| 1954 _listener.assertNoErrors(); | |
| 1955 } | |
| 1956 | |
| 1957 void test_visitSuperConstructorInvocation_namedParameter() { | |
| 1958 ClassElementImpl superclass = ElementFactory.classElement2("A"); | |
| 1959 ConstructorElementImpl superConstructor = | |
| 1960 ElementFactory.constructorElement2(superclass, null); | |
| 1961 String parameterName = "p"; | |
| 1962 ParameterElement parameter = ElementFactory.namedParameter(parameterName); | |
| 1963 superConstructor.parameters = <ParameterElement>[parameter]; | |
| 1964 superclass.constructors = <ConstructorElement>[superConstructor]; | |
| 1965 ClassElementImpl subclass = | |
| 1966 ElementFactory.classElement("B", superclass.type); | |
| 1967 ConstructorElementImpl subConstructor = | |
| 1968 ElementFactory.constructorElement2(subclass, null); | |
| 1969 subclass.constructors = <ConstructorElement>[subConstructor]; | |
| 1970 SuperConstructorInvocation invocation = AstFactory | |
| 1971 .superConstructorInvocation([ | |
| 1972 AstFactory.namedExpression2(parameterName, AstFactory.integer(0)) | |
| 1973 ]); | |
| 1974 _resolveInClass(invocation, subclass); | |
| 1975 expect(invocation.staticElement, superConstructor); | |
| 1976 expect( | |
| 1977 (invocation.argumentList.arguments[0] as NamedExpression) | |
| 1978 .name | |
| 1979 .label | |
| 1980 .staticElement, | |
| 1981 same(parameter)); | |
| 1982 _listener.assertNoErrors(); | |
| 1983 } | |
| 1984 | |
| 1985 /** | |
| 1986 * Create the resolver used by the tests. | |
| 1987 * | |
| 1988 * @return the resolver that was created | |
| 1989 */ | |
| 1990 ElementResolver _createResolver() { | |
| 1991 InternalAnalysisContext context = AnalysisContextFactory.contextWithCore(); | |
| 1992 FileBasedSource source = | |
| 1993 new FileBasedSource(FileUtilities2.createFile("/test.dart")); | |
| 1994 CompilationUnitElementImpl definingCompilationUnit = | |
| 1995 new CompilationUnitElementImpl("test.dart"); | |
| 1996 definingCompilationUnit.librarySource = | |
| 1997 definingCompilationUnit.source = source; | |
| 1998 _definingLibrary = ElementFactory.library(context, "test"); | |
| 1999 _definingLibrary.definingCompilationUnit = definingCompilationUnit; | |
| 2000 Library library = new Library(context, _listener, source); | |
| 2001 library.libraryElement = _definingLibrary; | |
| 2002 _visitor = new ResolverVisitor( | |
| 2003 library.libraryElement, source, _typeProvider, library.errorListener, | |
| 2004 nameScope: library.libraryScope, | |
| 2005 inheritanceManager: library.inheritanceManager); | |
| 2006 try { | |
| 2007 return _visitor.elementResolver; | |
| 2008 } catch (exception) { | |
| 2009 throw new IllegalArgumentException( | |
| 2010 "Could not create resolver", exception); | |
| 2011 } | |
| 2012 } | |
| 2013 | |
| 2014 /** | |
| 2015 * Return the element associated with the label of [statement] after the | |
| 2016 * resolver has resolved it. [labelElement] is the label element to be | |
| 2017 * defined in the statement's label scope, and [labelTarget] is the statement | |
| 2018 * the label resolves to. | |
| 2019 */ | |
| 2020 Element _resolveBreak(BreakStatement statement, LabelElementImpl labelElement, | |
| 2021 Statement labelTarget) { | |
| 2022 _resolveStatement(statement, labelElement, labelTarget); | |
| 2023 return statement.label.staticElement; | |
| 2024 } | |
| 2025 | |
| 2026 /** | |
| 2027 * Return the element associated with the label [statement] after the | |
| 2028 * resolver has resolved it. [labelElement] is the label element to be | |
| 2029 * defined in the statement's label scope, and [labelTarget] is the AST node | |
| 2030 * the label resolves to. | |
| 2031 * | |
| 2032 * @param statement the statement to be resolved | |
| 2033 * @param labelElement the label element to be defined in the statement's labe
l scope | |
| 2034 * @return the element to which the statement's label was resolved | |
| 2035 */ | |
| 2036 Element _resolveContinue(ContinueStatement statement, | |
| 2037 LabelElementImpl labelElement, AstNode labelTarget) { | |
| 2038 _resolveStatement(statement, labelElement, labelTarget); | |
| 2039 return statement.label.staticElement; | |
| 2040 } | |
| 2041 | |
| 2042 /** | |
| 2043 * Return the element associated with the given identifier after the resolver
has resolved the | |
| 2044 * identifier. | |
| 2045 * | |
| 2046 * @param node the expression to be resolved | |
| 2047 * @param definedElements the elements that are to be defined in the scope in
which the element is | |
| 2048 * being resolved | |
| 2049 * @return the element to which the expression was resolved | |
| 2050 */ | |
| 2051 Element _resolveIdentifier(Identifier node, [List<Element> definedElements]) { | |
| 2052 _resolveNode(node, definedElements); | |
| 2053 return node.staticElement; | |
| 2054 } | |
| 2055 | |
| 2056 /** | |
| 2057 * Return the element associated with the given identifier after the resolver
has resolved the | |
| 2058 * identifier. | |
| 2059 * | |
| 2060 * @param node the expression to be resolved | |
| 2061 * @param enclosingClass the element representing the class enclosing the iden
tifier | |
| 2062 * @return the element to which the expression was resolved | |
| 2063 */ | |
| 2064 void _resolveInClass(AstNode node, ClassElement enclosingClass) { | |
| 2065 try { | |
| 2066 Scope outerScope = _visitor.nameScope; | |
| 2067 try { | |
| 2068 _visitor.enclosingClass = enclosingClass; | |
| 2069 EnclosedScope innerScope = new ClassScope( | |
| 2070 new TypeParameterScope(outerScope, enclosingClass), enclosingClass); | |
| 2071 _visitor.nameScope = innerScope; | |
| 2072 node.accept(_resolver); | |
| 2073 } finally { | |
| 2074 _visitor.enclosingClass = null; | |
| 2075 _visitor.nameScope = outerScope; | |
| 2076 } | |
| 2077 } catch (exception) { | |
| 2078 throw new IllegalArgumentException("Could not resolve node", exception); | |
| 2079 } | |
| 2080 } | |
| 2081 | |
| 2082 /** | |
| 2083 * Return the element associated with the given expression after the resolver
has resolved the | |
| 2084 * expression. | |
| 2085 * | |
| 2086 * @param node the expression to be resolved | |
| 2087 * @param definedElements the elements that are to be defined in the scope in
which the element is | |
| 2088 * being resolved | |
| 2089 * @return the element to which the expression was resolved | |
| 2090 */ | |
| 2091 Element _resolveIndexExpression(IndexExpression node, | |
| 2092 [List<Element> definedElements]) { | |
| 2093 _resolveNode(node, definedElements); | |
| 2094 return node.staticElement; | |
| 2095 } | |
| 2096 | |
| 2097 /** | |
| 2098 * Return the element associated with the given identifier after the resolver
has resolved the | |
| 2099 * identifier. | |
| 2100 * | |
| 2101 * @param node the expression to be resolved | |
| 2102 * @param definedElements the elements that are to be defined in the scope in
which the element is | |
| 2103 * being resolved | |
| 2104 * @return the element to which the expression was resolved | |
| 2105 */ | |
| 2106 void _resolveNode(AstNode node, [List<Element> definedElements]) { | |
| 2107 try { | |
| 2108 Scope outerScope = _visitor.nameScope; | |
| 2109 try { | |
| 2110 EnclosedScope innerScope = new EnclosedScope(outerScope); | |
| 2111 if (definedElements != null) { | |
| 2112 for (Element element in definedElements) { | |
| 2113 innerScope.define(element); | |
| 2114 } | |
| 2115 } | |
| 2116 _visitor.nameScope = innerScope; | |
| 2117 node.accept(_resolver); | |
| 2118 } finally { | |
| 2119 _visitor.nameScope = outerScope; | |
| 2120 } | |
| 2121 } catch (exception) { | |
| 2122 throw new IllegalArgumentException("Could not resolve node", exception); | |
| 2123 } | |
| 2124 } | |
| 2125 | |
| 2126 /** | |
| 2127 * Return the element associated with the label of the given statement after t
he resolver has | |
| 2128 * resolved the statement. | |
| 2129 * | |
| 2130 * @param statement the statement to be resolved | |
| 2131 * @param labelElement the label element to be defined in the statement's labe
l scope | |
| 2132 * @return the element to which the statement's label was resolved | |
| 2133 */ | |
| 2134 void _resolveStatement( | |
| 2135 Statement statement, LabelElementImpl labelElement, AstNode labelTarget) { | |
| 2136 try { | |
| 2137 LabelScope outerScope = _visitor.labelScope; | |
| 2138 try { | |
| 2139 LabelScope innerScope; | |
| 2140 if (labelElement == null) { | |
| 2141 innerScope = outerScope; | |
| 2142 } else { | |
| 2143 innerScope = new LabelScope( | |
| 2144 outerScope, labelElement.name, labelTarget, labelElement); | |
| 2145 } | |
| 2146 _visitor.labelScope = innerScope; | |
| 2147 statement.accept(_resolver); | |
| 2148 } finally { | |
| 2149 _visitor.labelScope = outerScope; | |
| 2150 } | |
| 2151 } catch (exception) { | |
| 2152 throw new IllegalArgumentException("Could not resolve node", exception); | |
| 2153 } | |
| 2154 } | |
| 2155 } | |
| 2156 | |
| 2157 @reflectiveTest | |
| 2158 class EnclosedScopeTest extends ResolverTestCase { | 144 class EnclosedScopeTest extends ResolverTestCase { |
| 2159 void test_define_duplicate() { | 145 void test_define_duplicate() { |
| 2160 GatheringErrorListener listener = new GatheringErrorListener(); | 146 Scope rootScope = new _RootScope(); |
| 2161 Scope rootScope = | |
| 2162 new Scope_EnclosedScopeTest_test_define_duplicate(listener); | |
| 2163 EnclosedScope scope = new EnclosedScope(rootScope); | 147 EnclosedScope scope = new EnclosedScope(rootScope); |
| 2164 VariableElement element1 = | 148 SimpleIdentifier identifier = AstFactory.identifier3('v'); |
| 2165 ElementFactory.localVariableElement(AstFactory.identifier3("v1")); | 149 VariableElement element1 = ElementFactory.localVariableElement(identifier); |
| 2166 VariableElement element2 = | 150 VariableElement element2 = ElementFactory.localVariableElement(identifier); |
| 2167 ElementFactory.localVariableElement(AstFactory.identifier3("v1")); | |
| 2168 scope.define(element1); | 151 scope.define(element1); |
| 2169 scope.define(element2); | 152 scope.define(element2); |
| 2170 listener.assertErrorsWithSeverities([ErrorSeverity.ERROR]); | 153 expect(scope.lookup(identifier, null), same(element1)); |
| 2171 } | |
| 2172 | |
| 2173 void test_define_normal() { | |
| 2174 GatheringErrorListener listener = new GatheringErrorListener(); | |
| 2175 Scope rootScope = new Scope_EnclosedScopeTest_test_define_normal(listener); | |
| 2176 EnclosedScope outerScope = new EnclosedScope(rootScope); | |
| 2177 EnclosedScope innerScope = new EnclosedScope(outerScope); | |
| 2178 VariableElement element1 = | |
| 2179 ElementFactory.localVariableElement(AstFactory.identifier3("v1")); | |
| 2180 VariableElement element2 = | |
| 2181 ElementFactory.localVariableElement(AstFactory.identifier3("v2")); | |
| 2182 outerScope.define(element1); | |
| 2183 innerScope.define(element2); | |
| 2184 listener.assertNoErrors(); | |
| 2185 } | 154 } |
| 2186 } | 155 } |
| 2187 | 156 |
| 2188 @reflectiveTest | 157 @reflectiveTest |
| 2189 class ErrorResolverTest extends ResolverTestCase { | 158 class ErrorResolverTest extends ResolverTestCase { |
| 2190 void test_breakLabelOnSwitchMember() { | 159 void test_breakLabelOnSwitchMember() { |
| 2191 Source source = addSource(r''' | 160 Source source = addSource(r''' |
| 2192 class A { | 161 class A { |
| 2193 void m(int i) { | 162 void m(int i) { |
| 2194 switch (i) { | 163 switch (i) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2241 ConstructorElement constructor = constructors[0]; | 210 ConstructorElement constructor = constructors[0]; |
| 2242 expect(constructor, isNotNull); | 211 expect(constructor, isNotNull); |
| 2243 List<FunctionElement> functions = constructor.functions; | 212 List<FunctionElement> functions = constructor.functions; |
| 2244 expect(functions, isNotNull); | 213 expect(functions, isNotNull); |
| 2245 expect(functions, hasLength(1)); | 214 expect(functions, hasLength(1)); |
| 2246 expect(functions[0].enclosingElement, constructor); | 215 expect(functions[0].enclosingElement, constructor); |
| 2247 assertErrors(source, [ParserErrorCode.GETTER_IN_FUNCTION]); | 216 assertErrors(source, [ParserErrorCode.GETTER_IN_FUNCTION]); |
| 2248 } | 217 } |
| 2249 } | 218 } |
| 2250 | 219 |
| 2251 @reflectiveTest | 220 /** |
| 2252 class HintCodeTest extends ResolverTestCase { | 221 * Tests for generic method and function resolution that do not use strong mode. |
| 2253 void fail_deadCode_statementAfterRehrow() { | 222 */ |
| 2254 Source source = addSource(r''' | 223 @reflectiveTest |
| 2255 f() { | 224 class GenericMethodResolverTest extends StaticTypeAnalyzer2TestShared { |
| 2256 try { | 225 void setUp() { |
| 2257 var one = 1; | 226 super.setUp(); |
| 2258 } catch (e) { | |
| 2259 rethrow; | |
| 2260 var two = 2; | |
| 2261 } | |
| 2262 }'''); | |
| 2263 computeLibrarySourceErrors(source); | |
| 2264 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2265 verify([source]); | |
| 2266 } | |
| 2267 | |
| 2268 void fail_deadCode_statementAfterThrow() { | |
| 2269 Source source = addSource(r''' | |
| 2270 f() { | |
| 2271 var one = 1; | |
| 2272 throw 'Stop here'; | |
| 2273 var two = 2; | |
| 2274 }'''); | |
| 2275 computeLibrarySourceErrors(source); | |
| 2276 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2277 verify([source]); | |
| 2278 } | |
| 2279 | |
| 2280 void fail_isInt() { | |
| 2281 Source source = addSource("var v = 1 is int;"); | |
| 2282 computeLibrarySourceErrors(source); | |
| 2283 assertErrors(source, [HintCode.IS_INT]); | |
| 2284 verify([source]); | |
| 2285 } | |
| 2286 | |
| 2287 void fail_isNotInt() { | |
| 2288 Source source = addSource("var v = 1 is! int;"); | |
| 2289 computeLibrarySourceErrors(source); | |
| 2290 assertErrors(source, [HintCode.IS_NOT_INT]); | |
| 2291 verify([source]); | |
| 2292 } | |
| 2293 | |
| 2294 void fail_overrideEqualsButNotHashCode() { | |
| 2295 Source source = addSource(r''' | |
| 2296 class A { | |
| 2297 bool operator ==(x) {} | |
| 2298 }'''); | |
| 2299 computeLibrarySourceErrors(source); | |
| 2300 assertErrors(source, [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE]); | |
| 2301 verify([source]); | |
| 2302 } | |
| 2303 | |
| 2304 void fail_unusedImport_as_equalPrefixes() { | |
| 2305 // See todo at ImportsVerifier.prefixElementMap. | |
| 2306 Source source = addSource(r''' | |
| 2307 library L; | |
| 2308 import 'lib1.dart' as one; | |
| 2309 import 'lib2.dart' as one; | |
| 2310 one.A a;'''); | |
| 2311 Source source2 = addNamedSource( | |
| 2312 "/lib1.dart", | |
| 2313 r''' | |
| 2314 library lib1; | |
| 2315 class A {}'''); | |
| 2316 Source source3 = addNamedSource( | |
| 2317 "/lib2.dart", | |
| 2318 r''' | |
| 2319 library lib2; | |
| 2320 class B {}'''); | |
| 2321 computeLibrarySourceErrors(source); | |
| 2322 assertErrors(source, [HintCode.UNUSED_IMPORT]); | |
| 2323 assertNoErrors(source2); | |
| 2324 assertNoErrors(source3); | |
| 2325 verify([source, source2, source3]); | |
| 2326 } | |
| 2327 | |
| 2328 void test_argumentTypeNotAssignable_functionType() { | |
| 2329 Source source = addSource(r''' | |
| 2330 m() { | |
| 2331 var a = new A(); | |
| 2332 a.n(() => 0); | |
| 2333 } | |
| 2334 class A { | |
| 2335 n(void f(int i)) {} | |
| 2336 }'''); | |
| 2337 computeLibrarySourceErrors(source); | |
| 2338 assertErrors(source, [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]); | |
| 2339 verify([source]); | |
| 2340 } | |
| 2341 | |
| 2342 void test_argumentTypeNotAssignable_message() { | |
| 2343 // The implementation of HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE assumes that | |
| 2344 // StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE has the same message. | |
| 2345 expect(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE.message, | |
| 2346 HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE.message); | |
| 2347 } | |
| 2348 | |
| 2349 void test_argumentTypeNotAssignable_type() { | |
| 2350 Source source = addSource(r''' | |
| 2351 m() { | |
| 2352 var i = ''; | |
| 2353 n(i); | |
| 2354 } | |
| 2355 n(int i) {}'''); | |
| 2356 computeLibrarySourceErrors(source); | |
| 2357 assertErrors(source, [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]); | |
| 2358 verify([source]); | |
| 2359 } | |
| 2360 | |
| 2361 void test_deadCode_deadBlock_conditionalElse() { | |
| 2362 Source source = addSource(r''' | |
| 2363 f() { | |
| 2364 true ? 1 : 2; | |
| 2365 }'''); | |
| 2366 computeLibrarySourceErrors(source); | |
| 2367 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2368 verify([source]); | |
| 2369 } | |
| 2370 | |
| 2371 void test_deadCode_deadBlock_conditionalElse_nested() { | |
| 2372 // test that a dead else-statement can't generate additional violations | |
| 2373 Source source = addSource(r''' | |
| 2374 f() { | |
| 2375 true ? true : false && false; | |
| 2376 }'''); | |
| 2377 computeLibrarySourceErrors(source); | |
| 2378 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2379 verify([source]); | |
| 2380 } | |
| 2381 | |
| 2382 void test_deadCode_deadBlock_conditionalIf() { | |
| 2383 Source source = addSource(r''' | |
| 2384 f() { | |
| 2385 false ? 1 : 2; | |
| 2386 }'''); | |
| 2387 computeLibrarySourceErrors(source); | |
| 2388 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2389 verify([source]); | |
| 2390 } | |
| 2391 | |
| 2392 void test_deadCode_deadBlock_conditionalIf_nested() { | |
| 2393 // test that a dead then-statement can't generate additional violations | |
| 2394 Source source = addSource(r''' | |
| 2395 f() { | |
| 2396 false ? false && false : true; | |
| 2397 }'''); | |
| 2398 computeLibrarySourceErrors(source); | |
| 2399 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2400 verify([source]); | |
| 2401 } | |
| 2402 | |
| 2403 void test_deadCode_deadBlock_else() { | |
| 2404 Source source = addSource(r''' | |
| 2405 f() { | |
| 2406 if(true) {} else {} | |
| 2407 }'''); | |
| 2408 computeLibrarySourceErrors(source); | |
| 2409 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2410 verify([source]); | |
| 2411 } | |
| 2412 | |
| 2413 void test_deadCode_deadBlock_else_nested() { | |
| 2414 // test that a dead else-statement can't generate additional violations | |
| 2415 Source source = addSource(r''' | |
| 2416 f() { | |
| 2417 if(true) {} else {if (false) {}} | |
| 2418 }'''); | |
| 2419 computeLibrarySourceErrors(source); | |
| 2420 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2421 verify([source]); | |
| 2422 } | |
| 2423 | |
| 2424 void test_deadCode_deadBlock_if() { | |
| 2425 Source source = addSource(r''' | |
| 2426 f() { | |
| 2427 if(false) {} | |
| 2428 }'''); | |
| 2429 computeLibrarySourceErrors(source); | |
| 2430 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2431 verify([source]); | |
| 2432 } | |
| 2433 | |
| 2434 void test_deadCode_deadBlock_if_nested() { | |
| 2435 // test that a dead then-statement can't generate additional violations | |
| 2436 Source source = addSource(r''' | |
| 2437 f() { | |
| 2438 if(false) {if(false) {}} | |
| 2439 }'''); | |
| 2440 computeLibrarySourceErrors(source); | |
| 2441 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2442 verify([source]); | |
| 2443 } | |
| 2444 | |
| 2445 void test_deadCode_deadBlock_while() { | |
| 2446 Source source = addSource(r''' | |
| 2447 f() { | |
| 2448 while(false) {} | |
| 2449 }'''); | |
| 2450 computeLibrarySourceErrors(source); | |
| 2451 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2452 verify([source]); | |
| 2453 } | |
| 2454 | |
| 2455 void test_deadCode_deadBlock_while_nested() { | |
| 2456 // test that a dead while body can't generate additional violations | |
| 2457 Source source = addSource(r''' | |
| 2458 f() { | |
| 2459 while(false) {if(false) {}} | |
| 2460 }'''); | |
| 2461 computeLibrarySourceErrors(source); | |
| 2462 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2463 verify([source]); | |
| 2464 } | |
| 2465 | |
| 2466 void test_deadCode_deadCatch_catchFollowingCatch() { | |
| 2467 Source source = addSource(r''' | |
| 2468 class A {} | |
| 2469 f() { | |
| 2470 try {} catch (e) {} catch (e) {} | |
| 2471 }'''); | |
| 2472 computeLibrarySourceErrors(source); | |
| 2473 assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]); | |
| 2474 verify([source]); | |
| 2475 } | |
| 2476 | |
| 2477 void test_deadCode_deadCatch_catchFollowingCatch_nested() { | |
| 2478 // test that a dead catch clause can't generate additional violations | |
| 2479 Source source = addSource(r''' | |
| 2480 class A {} | |
| 2481 f() { | |
| 2482 try {} catch (e) {} catch (e) {if(false) {}} | |
| 2483 }'''); | |
| 2484 computeLibrarySourceErrors(source); | |
| 2485 assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]); | |
| 2486 verify([source]); | |
| 2487 } | |
| 2488 | |
| 2489 void test_deadCode_deadCatch_catchFollowingCatch_object() { | |
| 2490 Source source = addSource(r''' | |
| 2491 f() { | |
| 2492 try {} on Object catch (e) {} catch (e) {} | |
| 2493 }'''); | |
| 2494 computeLibrarySourceErrors(source); | |
| 2495 assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]); | |
| 2496 verify([source]); | |
| 2497 } | |
| 2498 | |
| 2499 void test_deadCode_deadCatch_catchFollowingCatch_object_nested() { | |
| 2500 // test that a dead catch clause can't generate additional violations | |
| 2501 Source source = addSource(r''' | |
| 2502 f() { | |
| 2503 try {} on Object catch (e) {} catch (e) {if(false) {}} | |
| 2504 }'''); | |
| 2505 computeLibrarySourceErrors(source); | |
| 2506 assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]); | |
| 2507 verify([source]); | |
| 2508 } | |
| 2509 | |
| 2510 void test_deadCode_deadCatch_onCatchSubtype() { | |
| 2511 Source source = addSource(r''' | |
| 2512 class A {} | |
| 2513 class B extends A {} | |
| 2514 f() { | |
| 2515 try {} on A catch (e) {} on B catch (e) {} | |
| 2516 }'''); | |
| 2517 computeLibrarySourceErrors(source); | |
| 2518 assertErrors(source, [HintCode.DEAD_CODE_ON_CATCH_SUBTYPE]); | |
| 2519 verify([source]); | |
| 2520 } | |
| 2521 | |
| 2522 void test_deadCode_deadCatch_onCatchSubtype_nested() { | |
| 2523 // test that a dead catch clause can't generate additional violations | |
| 2524 Source source = addSource(r''' | |
| 2525 class A {} | |
| 2526 class B extends A {} | |
| 2527 f() { | |
| 2528 try {} on A catch (e) {} on B catch (e) {if(false) {}} | |
| 2529 }'''); | |
| 2530 computeLibrarySourceErrors(source); | |
| 2531 assertErrors(source, [HintCode.DEAD_CODE_ON_CATCH_SUBTYPE]); | |
| 2532 verify([source]); | |
| 2533 } | |
| 2534 | |
| 2535 void test_deadCode_deadOperandLHS_and() { | |
| 2536 Source source = addSource(r''' | |
| 2537 f() { | |
| 2538 bool b = false && false; | |
| 2539 }'''); | |
| 2540 computeLibrarySourceErrors(source); | |
| 2541 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2542 verify([source]); | |
| 2543 } | |
| 2544 | |
| 2545 void test_deadCode_deadOperandLHS_and_nested() { | |
| 2546 Source source = addSource(r''' | |
| 2547 f() { | |
| 2548 bool b = false && (false && false); | |
| 2549 }'''); | |
| 2550 computeLibrarySourceErrors(source); | |
| 2551 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2552 verify([source]); | |
| 2553 } | |
| 2554 | |
| 2555 void test_deadCode_deadOperandLHS_or() { | |
| 2556 Source source = addSource(r''' | |
| 2557 f() { | |
| 2558 bool b = true || true; | |
| 2559 }'''); | |
| 2560 computeLibrarySourceErrors(source); | |
| 2561 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2562 verify([source]); | |
| 2563 } | |
| 2564 | |
| 2565 void test_deadCode_deadOperandLHS_or_nested() { | |
| 2566 Source source = addSource(r''' | |
| 2567 f() { | |
| 2568 bool b = true || (false && false); | |
| 2569 }'''); | |
| 2570 computeLibrarySourceErrors(source); | |
| 2571 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2572 verify([source]); | |
| 2573 } | |
| 2574 | |
| 2575 void test_deadCode_statementAfterBreak_inDefaultCase() { | |
| 2576 Source source = addSource(r''' | |
| 2577 f(v) { | |
| 2578 switch(v) { | |
| 2579 case 1: | |
| 2580 default: | |
| 2581 break; | |
| 2582 var a; | |
| 2583 } | |
| 2584 }'''); | |
| 2585 computeLibrarySourceErrors(source); | |
| 2586 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2587 verify([source]); | |
| 2588 } | |
| 2589 | |
| 2590 void test_deadCode_statementAfterBreak_inForEachStatement() { | |
| 2591 Source source = addSource(r''' | |
| 2592 f() { | |
| 2593 var list; | |
| 2594 for(var l in list) { | |
| 2595 break; | |
| 2596 var a; | |
| 2597 } | |
| 2598 }'''); | |
| 2599 computeLibrarySourceErrors(source); | |
| 2600 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2601 verify([source]); | |
| 2602 } | |
| 2603 | |
| 2604 void test_deadCode_statementAfterBreak_inForStatement() { | |
| 2605 Source source = addSource(r''' | |
| 2606 f() { | |
| 2607 for(;;) { | |
| 2608 break; | |
| 2609 var a; | |
| 2610 } | |
| 2611 }'''); | |
| 2612 computeLibrarySourceErrors(source); | |
| 2613 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2614 verify([source]); | |
| 2615 } | |
| 2616 | |
| 2617 void test_deadCode_statementAfterBreak_inSwitchCase() { | |
| 2618 Source source = addSource(r''' | |
| 2619 f(v) { | |
| 2620 switch(v) { | |
| 2621 case 1: | |
| 2622 break; | |
| 2623 var a; | |
| 2624 } | |
| 2625 }'''); | |
| 2626 computeLibrarySourceErrors(source); | |
| 2627 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2628 verify([source]); | |
| 2629 } | |
| 2630 | |
| 2631 void test_deadCode_statementAfterBreak_inWhileStatement() { | |
| 2632 Source source = addSource(r''' | |
| 2633 f(v) { | |
| 2634 while(v) { | |
| 2635 break; | |
| 2636 var a; | |
| 2637 } | |
| 2638 }'''); | |
| 2639 computeLibrarySourceErrors(source); | |
| 2640 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2641 verify([source]); | |
| 2642 } | |
| 2643 | |
| 2644 void test_deadCode_statementAfterContinue_inForEachStatement() { | |
| 2645 Source source = addSource(r''' | |
| 2646 f() { | |
| 2647 var list; | |
| 2648 for(var l in list) { | |
| 2649 continue; | |
| 2650 var a; | |
| 2651 } | |
| 2652 }'''); | |
| 2653 computeLibrarySourceErrors(source); | |
| 2654 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2655 verify([source]); | |
| 2656 } | |
| 2657 | |
| 2658 void test_deadCode_statementAfterContinue_inForStatement() { | |
| 2659 Source source = addSource(r''' | |
| 2660 f() { | |
| 2661 for(;;) { | |
| 2662 continue; | |
| 2663 var a; | |
| 2664 } | |
| 2665 }'''); | |
| 2666 computeLibrarySourceErrors(source); | |
| 2667 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2668 verify([source]); | |
| 2669 } | |
| 2670 | |
| 2671 void test_deadCode_statementAfterContinue_inWhileStatement() { | |
| 2672 Source source = addSource(r''' | |
| 2673 f(v) { | |
| 2674 while(v) { | |
| 2675 continue; | |
| 2676 var a; | |
| 2677 } | |
| 2678 }'''); | |
| 2679 computeLibrarySourceErrors(source); | |
| 2680 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2681 verify([source]); | |
| 2682 } | |
| 2683 | |
| 2684 void test_deadCode_statementAfterReturn_function() { | |
| 2685 Source source = addSource(r''' | |
| 2686 f() { | |
| 2687 var one = 1; | |
| 2688 return; | |
| 2689 var two = 2; | |
| 2690 }'''); | |
| 2691 computeLibrarySourceErrors(source); | |
| 2692 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2693 verify([source]); | |
| 2694 } | |
| 2695 | |
| 2696 void test_deadCode_statementAfterReturn_ifStatement() { | |
| 2697 Source source = addSource(r''' | |
| 2698 f(bool b) { | |
| 2699 if(b) { | |
| 2700 var one = 1; | |
| 2701 return; | |
| 2702 var two = 2; | |
| 2703 } | |
| 2704 }'''); | |
| 2705 computeLibrarySourceErrors(source); | |
| 2706 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2707 verify([source]); | |
| 2708 } | |
| 2709 | |
| 2710 void test_deadCode_statementAfterReturn_method() { | |
| 2711 Source source = addSource(r''' | |
| 2712 class A { | |
| 2713 m() { | |
| 2714 var one = 1; | |
| 2715 return; | |
| 2716 var two = 2; | |
| 2717 } | |
| 2718 }'''); | |
| 2719 computeLibrarySourceErrors(source); | |
| 2720 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2721 verify([source]); | |
| 2722 } | |
| 2723 | |
| 2724 void test_deadCode_statementAfterReturn_nested() { | |
| 2725 Source source = addSource(r''' | |
| 2726 f() { | |
| 2727 var one = 1; | |
| 2728 return; | |
| 2729 if(false) {} | |
| 2730 }'''); | |
| 2731 computeLibrarySourceErrors(source); | |
| 2732 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2733 verify([source]); | |
| 2734 } | |
| 2735 | |
| 2736 void test_deadCode_statementAfterReturn_twoReturns() { | |
| 2737 Source source = addSource(r''' | |
| 2738 f() { | |
| 2739 var one = 1; | |
| 2740 return; | |
| 2741 var two = 2; | |
| 2742 return; | |
| 2743 var three = 3; | |
| 2744 }'''); | |
| 2745 computeLibrarySourceErrors(source); | |
| 2746 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2747 verify([source]); | |
| 2748 } | |
| 2749 | |
| 2750 void test_deprecatedAnnotationUse_assignment() { | |
| 2751 Source source = addSource(r''' | |
| 2752 class A { | |
| 2753 @deprecated | |
| 2754 A operator+(A a) { return a; } | |
| 2755 } | |
| 2756 f(A a) { | |
| 2757 A b; | |
| 2758 a += b; | |
| 2759 }'''); | |
| 2760 computeLibrarySourceErrors(source); | |
| 2761 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 2762 verify([source]); | |
| 2763 } | |
| 2764 | |
| 2765 void test_deprecatedAnnotationUse_Deprecated() { | |
| 2766 Source source = addSource(r''' | |
| 2767 class A { | |
| 2768 @Deprecated('0.9') | |
| 2769 m() {} | |
| 2770 n() {m();} | |
| 2771 }'''); | |
| 2772 computeLibrarySourceErrors(source); | |
| 2773 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 2774 verify([source]); | |
| 2775 } | |
| 2776 | |
| 2777 void test_deprecatedAnnotationUse_deprecated() { | |
| 2778 Source source = addSource(r''' | |
| 2779 class A { | |
| 2780 @deprecated | |
| 2781 m() {} | |
| 2782 n() {m();} | |
| 2783 }'''); | |
| 2784 computeLibrarySourceErrors(source); | |
| 2785 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 2786 verify([source]); | |
| 2787 } | |
| 2788 | |
| 2789 void test_deprecatedAnnotationUse_export() { | |
| 2790 Source source = addSource("export 'deprecated_library.dart';"); | |
| 2791 addNamedSource( | |
| 2792 "/deprecated_library.dart", | |
| 2793 r''' | |
| 2794 @deprecated | |
| 2795 library deprecated_library; | |
| 2796 class A {}'''); | |
| 2797 computeLibrarySourceErrors(source); | |
| 2798 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 2799 verify([source]); | |
| 2800 } | |
| 2801 | |
| 2802 void test_deprecatedAnnotationUse_getter() { | |
| 2803 Source source = addSource(r''' | |
| 2804 class A { | |
| 2805 @deprecated | |
| 2806 get m => 1; | |
| 2807 } | |
| 2808 f(A a) { | |
| 2809 return a.m; | |
| 2810 }'''); | |
| 2811 computeLibrarySourceErrors(source); | |
| 2812 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 2813 verify([source]); | |
| 2814 } | |
| 2815 | |
| 2816 void test_deprecatedAnnotationUse_import() { | |
| 2817 Source source = addSource(r''' | |
| 2818 import 'deprecated_library.dart'; | |
| 2819 f(A a) {}'''); | |
| 2820 addNamedSource( | |
| 2821 "/deprecated_library.dart", | |
| 2822 r''' | |
| 2823 @deprecated | |
| 2824 library deprecated_library; | |
| 2825 class A {}'''); | |
| 2826 computeLibrarySourceErrors(source); | |
| 2827 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 2828 verify([source]); | |
| 2829 } | |
| 2830 | |
| 2831 void test_deprecatedAnnotationUse_indexExpression() { | |
| 2832 Source source = addSource(r''' | |
| 2833 class A { | |
| 2834 @deprecated | |
| 2835 operator[](int i) {} | |
| 2836 } | |
| 2837 f(A a) { | |
| 2838 return a[1]; | |
| 2839 }'''); | |
| 2840 computeLibrarySourceErrors(source); | |
| 2841 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 2842 verify([source]); | |
| 2843 } | |
| 2844 | |
| 2845 void test_deprecatedAnnotationUse_instanceCreation() { | |
| 2846 Source source = addSource(r''' | |
| 2847 class A { | |
| 2848 @deprecated | |
| 2849 A(int i) {} | |
| 2850 } | |
| 2851 f() { | |
| 2852 A a = new A(1); | |
| 2853 }'''); | |
| 2854 computeLibrarySourceErrors(source); | |
| 2855 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 2856 verify([source]); | |
| 2857 } | |
| 2858 | |
| 2859 void test_deprecatedAnnotationUse_instanceCreation_namedConstructor() { | |
| 2860 Source source = addSource(r''' | |
| 2861 class A { | |
| 2862 @deprecated | |
| 2863 A.named(int i) {} | |
| 2864 } | |
| 2865 f() { | |
| 2866 A a = new A.named(1); | |
| 2867 }'''); | |
| 2868 computeLibrarySourceErrors(source); | |
| 2869 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 2870 verify([source]); | |
| 2871 } | |
| 2872 | |
| 2873 void test_deprecatedAnnotationUse_operator() { | |
| 2874 Source source = addSource(r''' | |
| 2875 class A { | |
| 2876 @deprecated | |
| 2877 operator+(A a) {} | |
| 2878 } | |
| 2879 f(A a) { | |
| 2880 A b; | |
| 2881 return a + b; | |
| 2882 }'''); | |
| 2883 computeLibrarySourceErrors(source); | |
| 2884 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 2885 verify([source]); | |
| 2886 } | |
| 2887 | |
| 2888 void test_deprecatedAnnotationUse_setter() { | |
| 2889 Source source = addSource(r''' | |
| 2890 class A { | |
| 2891 @deprecated | |
| 2892 set s(v) {} | |
| 2893 } | |
| 2894 f(A a) { | |
| 2895 return a.s = 1; | |
| 2896 }'''); | |
| 2897 computeLibrarySourceErrors(source); | |
| 2898 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 2899 verify([source]); | |
| 2900 } | |
| 2901 | |
| 2902 void test_deprecatedAnnotationUse_superConstructor() { | |
| 2903 Source source = addSource(r''' | |
| 2904 class A { | |
| 2905 @deprecated | |
| 2906 A() {} | |
| 2907 } | |
| 2908 class B extends A { | |
| 2909 B() : super() {} | |
| 2910 }'''); | |
| 2911 computeLibrarySourceErrors(source); | |
| 2912 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 2913 verify([source]); | |
| 2914 } | |
| 2915 | |
| 2916 void test_deprecatedAnnotationUse_superConstructor_namedConstructor() { | |
| 2917 Source source = addSource(r''' | |
| 2918 class A { | |
| 2919 @deprecated | |
| 2920 A.named() {} | |
| 2921 } | |
| 2922 class B extends A { | |
| 2923 B() : super.named() {} | |
| 2924 }'''); | |
| 2925 computeLibrarySourceErrors(source); | |
| 2926 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 2927 verify([source]); | |
| 2928 } | |
| 2929 | |
| 2930 void test_divisionOptimization_double() { | |
| 2931 Source source = addSource(r''' | |
| 2932 f(double x, double y) { | |
| 2933 var v = (x / y).toInt(); | |
| 2934 }'''); | |
| 2935 computeLibrarySourceErrors(source); | |
| 2936 assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]); | |
| 2937 verify([source]); | |
| 2938 } | |
| 2939 | |
| 2940 void test_divisionOptimization_int() { | |
| 2941 Source source = addSource(r''' | |
| 2942 f(int x, int y) { | |
| 2943 var v = (x / y).toInt(); | |
| 2944 }'''); | |
| 2945 computeLibrarySourceErrors(source); | |
| 2946 assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]); | |
| 2947 verify([source]); | |
| 2948 } | |
| 2949 | |
| 2950 void test_divisionOptimization_propagatedType() { | |
| 2951 // Tests the propagated type information of the '/' method | |
| 2952 Source source = addSource(r''' | |
| 2953 f(x, y) { | |
| 2954 x = 1; | |
| 2955 y = 1; | |
| 2956 var v = (x / y).toInt(); | |
| 2957 }'''); | |
| 2958 computeLibrarySourceErrors(source); | |
| 2959 assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]); | |
| 2960 verify([source]); | |
| 2961 } | |
| 2962 | |
| 2963 void test_divisionOptimization_wrappedBinaryExpression() { | |
| 2964 Source source = addSource(r''' | |
| 2965 f(int x, int y) { | |
| 2966 var v = (((x / y))).toInt(); | |
| 2967 }'''); | |
| 2968 computeLibrarySourceErrors(source); | |
| 2969 assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]); | |
| 2970 verify([source]); | |
| 2971 } | |
| 2972 | |
| 2973 void test_duplicateImport() { | |
| 2974 Source source = addSource(r''' | |
| 2975 library L; | |
| 2976 import 'lib1.dart'; | |
| 2977 import 'lib1.dart'; | |
| 2978 A a;'''); | |
| 2979 addNamedSource( | |
| 2980 "/lib1.dart", | |
| 2981 r''' | |
| 2982 library lib1; | |
| 2983 class A {}'''); | |
| 2984 computeLibrarySourceErrors(source); | |
| 2985 assertErrors(source, [HintCode.DUPLICATE_IMPORT]); | |
| 2986 verify([source]); | |
| 2987 } | |
| 2988 | |
| 2989 void test_duplicateImport2() { | |
| 2990 Source source = addSource(r''' | |
| 2991 library L; | |
| 2992 import 'lib1.dart'; | |
| 2993 import 'lib1.dart'; | |
| 2994 import 'lib1.dart'; | |
| 2995 A a;'''); | |
| 2996 addNamedSource( | |
| 2997 "/lib1.dart", | |
| 2998 r''' | |
| 2999 library lib1; | |
| 3000 class A {}'''); | |
| 3001 computeLibrarySourceErrors(source); | |
| 3002 assertErrors( | |
| 3003 source, [HintCode.DUPLICATE_IMPORT, HintCode.DUPLICATE_IMPORT]); | |
| 3004 verify([source]); | |
| 3005 } | |
| 3006 | |
| 3007 void test_duplicateImport3() { | |
| 3008 Source source = addSource(r''' | |
| 3009 library L; | |
| 3010 import 'lib1.dart' as M show A hide B; | |
| 3011 import 'lib1.dart' as M show A hide B; | |
| 3012 M.A a;'''); | |
| 3013 addNamedSource( | |
| 3014 "/lib1.dart", | |
| 3015 r''' | |
| 3016 library lib1; | |
| 3017 class A {} | |
| 3018 class B {}'''); | |
| 3019 computeLibrarySourceErrors(source); | |
| 3020 assertErrors(source, [HintCode.DUPLICATE_IMPORT]); | |
| 3021 verify([source]); | |
| 3022 } | |
| 3023 | |
| 3024 void test_importDeferredLibraryWithLoadFunction() { | |
| 3025 resolveWithErrors(<String>[ | |
| 3026 r''' | |
| 3027 library lib1; | |
| 3028 loadLibrary() {} | |
| 3029 f() {}''', | |
| 3030 r''' | |
| 3031 library root; | |
| 3032 import 'lib1.dart' deferred as lib1; | |
| 3033 main() { lib1.f(); }''' | |
| 3034 ], <ErrorCode>[ | |
| 3035 HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION | |
| 3036 ]); | |
| 3037 } | |
| 3038 | |
| 3039 void test_invalidAssignment_instanceVariable() { | |
| 3040 Source source = addSource(r''' | |
| 3041 class A { | |
| 3042 int x; | |
| 3043 } | |
| 3044 f(var y) { | |
| 3045 A a; | |
| 3046 if(y is String) { | |
| 3047 a.x = y; | |
| 3048 } | |
| 3049 }'''); | |
| 3050 computeLibrarySourceErrors(source); | |
| 3051 assertErrors(source, [HintCode.INVALID_ASSIGNMENT]); | |
| 3052 verify([source]); | |
| 3053 } | |
| 3054 | |
| 3055 void test_invalidAssignment_localVariable() { | |
| 3056 Source source = addSource(r''' | |
| 3057 f(var y) { | |
| 3058 if(y is String) { | |
| 3059 int x = y; | |
| 3060 } | |
| 3061 }'''); | |
| 3062 computeLibrarySourceErrors(source); | |
| 3063 assertErrors(source, [HintCode.INVALID_ASSIGNMENT]); | |
| 3064 verify([source]); | |
| 3065 } | |
| 3066 | |
| 3067 void test_invalidAssignment_message() { | |
| 3068 // The implementation of HintCode.INVALID_ASSIGNMENT assumes that | |
| 3069 // StaticTypeWarningCode.INVALID_ASSIGNMENT has the same message. | |
| 3070 expect(StaticTypeWarningCode.INVALID_ASSIGNMENT.message, | |
| 3071 HintCode.INVALID_ASSIGNMENT.message); | |
| 3072 } | |
| 3073 | |
| 3074 void test_invalidAssignment_staticVariable() { | |
| 3075 Source source = addSource(r''' | |
| 3076 class A { | |
| 3077 static int x; | |
| 3078 } | |
| 3079 f(var y) { | |
| 3080 if(y is String) { | |
| 3081 A.x = y; | |
| 3082 } | |
| 3083 }'''); | |
| 3084 computeLibrarySourceErrors(source); | |
| 3085 assertErrors(source, [HintCode.INVALID_ASSIGNMENT]); | |
| 3086 verify([source]); | |
| 3087 } | |
| 3088 | |
| 3089 void test_invalidAssignment_variableDeclaration() { | |
| 3090 // 17971 | |
| 3091 Source source = addSource(r''' | |
| 3092 class Point { | |
| 3093 final num x, y; | |
| 3094 Point(this.x, this.y); | |
| 3095 Point operator +(Point other) { | |
| 3096 return new Point(x+other.x, y+other.y); | |
| 3097 } | |
| 3098 } | |
| 3099 main() { | |
| 3100 var p1 = new Point(0, 0); | |
| 3101 var p2 = new Point(10, 10); | |
| 3102 int n = p1 + p2; | |
| 3103 }'''); | |
| 3104 computeLibrarySourceErrors(source); | |
| 3105 assertErrors(source, [HintCode.INVALID_ASSIGNMENT]); | |
| 3106 verify([source]); | |
| 3107 } | |
| 3108 | |
| 3109 void test_isDouble() { | |
| 3110 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); | 227 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); |
| 3111 options.dart2jsHint = true; | 228 options.enableGenericMethods = true; |
| 3112 resetWithOptions(options); | 229 resetWithOptions(options); |
| 3113 Source source = addSource("var v = 1 is double;"); | 230 } |
| 3114 computeLibrarySourceErrors(source); | 231 |
| 3115 assertErrors(source, [HintCode.IS_DOUBLE]); | 232 void test_genericMethod_propagatedType_promotion() { |
| 3116 verify([source]); | 233 // Regression test for: |
| 3117 } | 234 // https://github.com/dart-lang/sdk/issues/25340 |
| 3118 | 235 // |
| 3119 void test_isNotDouble() { | 236 // Note, after https://github.com/dart-lang/sdk/issues/25486 the original |
| 3120 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); | 237 // strong mode example won't work, as we now compute a static type and |
| 3121 options.dart2jsHint = true; | 238 // therefore discard the propagated type. |
| 3122 resetWithOptions(options); | 239 // |
| 3123 Source source = addSource("var v = 1 is! double;"); | 240 // So this test does not use strong mode. |
| 3124 computeLibrarySourceErrors(source); | 241 resolveTestUnit(r''' |
| 3125 assertErrors(source, [HintCode.IS_NOT_DOUBLE]); | 242 abstract class Iter { |
| 3126 verify([source]); | 243 List<S> map<S>(S f(x)); |
| 3127 } | 244 } |
| 3128 | 245 class C {} |
| 3129 void test_missingReturn_async() { | 246 C toSpan(dynamic element) { |
| 3130 Source source = addSource(''' | 247 if (element is Iter) { |
| 3131 import 'dart:async'; | 248 var y = element.map(toSpan); |
| 3132 Future<int> f() async {} | 249 } |
| 3133 '''); | 250 return null; |
| 3134 computeLibrarySourceErrors(source); | 251 }'''); |
| 3135 assertErrors(source, [HintCode.MISSING_RETURN]); | 252 expectIdentifierType('y = ', 'dynamic', 'List<dynamic>'); |
| 3136 verify([source]); | |
| 3137 } | |
| 3138 | |
| 3139 void test_missingReturn_function() { | |
| 3140 Source source = addSource("int f() {}"); | |
| 3141 computeLibrarySourceErrors(source); | |
| 3142 assertErrors(source, [HintCode.MISSING_RETURN]); | |
| 3143 verify([source]); | |
| 3144 } | |
| 3145 | |
| 3146 void test_missingReturn_method() { | |
| 3147 Source source = addSource(r''' | |
| 3148 class A { | |
| 3149 int m() {} | |
| 3150 }'''); | |
| 3151 computeLibrarySourceErrors(source); | |
| 3152 assertErrors(source, [HintCode.MISSING_RETURN]); | |
| 3153 verify([source]); | |
| 3154 } | |
| 3155 | |
| 3156 void test_overrideOnNonOverridingGetter_invalid() { | |
| 3157 Source source = addSource(r''' | |
| 3158 library dart.core; | |
| 3159 const override = null; | |
| 3160 class A { | |
| 3161 } | |
| 3162 class B extends A { | |
| 3163 @override | |
| 3164 int get m => 1; | |
| 3165 }'''); | |
| 3166 computeLibrarySourceErrors(source); | |
| 3167 assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER]); | |
| 3168 verify([source]); | |
| 3169 } | |
| 3170 | |
| 3171 void test_overrideOnNonOverridingMethod_invalid() { | |
| 3172 Source source = addSource(r''' | |
| 3173 library dart.core; | |
| 3174 const override = null; | |
| 3175 class A { | |
| 3176 } | |
| 3177 class B extends A { | |
| 3178 @override | |
| 3179 int m() => 1; | |
| 3180 }'''); | |
| 3181 computeLibrarySourceErrors(source); | |
| 3182 assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD]); | |
| 3183 verify([source]); | |
| 3184 } | |
| 3185 | |
| 3186 void test_overrideOnNonOverridingSetter_invalid() { | |
| 3187 Source source = addSource(r''' | |
| 3188 library dart.core; | |
| 3189 const override = null; | |
| 3190 class A { | |
| 3191 } | |
| 3192 class B extends A { | |
| 3193 @override | |
| 3194 set m(int x) {} | |
| 3195 }'''); | |
| 3196 computeLibrarySourceErrors(source); | |
| 3197 assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER]); | |
| 3198 verify([source]); | |
| 3199 } | |
| 3200 | |
| 3201 void test_typeCheck_type_is_Null() { | |
| 3202 Source source = addSource(r''' | |
| 3203 m(i) { | |
| 3204 bool b = i is Null; | |
| 3205 }'''); | |
| 3206 computeLibrarySourceErrors(source); | |
| 3207 assertErrors(source, [HintCode.TYPE_CHECK_IS_NULL]); | |
| 3208 verify([source]); | |
| 3209 } | |
| 3210 | |
| 3211 void test_typeCheck_type_not_Null() { | |
| 3212 Source source = addSource(r''' | |
| 3213 m(i) { | |
| 3214 bool b = i is! Null; | |
| 3215 }'''); | |
| 3216 computeLibrarySourceErrors(source); | |
| 3217 assertErrors(source, [HintCode.TYPE_CHECK_IS_NOT_NULL]); | |
| 3218 verify([source]); | |
| 3219 } | |
| 3220 | |
| 3221 void test_undefinedGetter() { | |
| 3222 Source source = addSource(r''' | |
| 3223 class A {} | |
| 3224 f(var a) { | |
| 3225 if(a is A) { | |
| 3226 return a.m; | |
| 3227 } | |
| 3228 }'''); | |
| 3229 computeLibrarySourceErrors(source); | |
| 3230 assertErrors(source, [HintCode.UNDEFINED_GETTER]); | |
| 3231 } | |
| 3232 | |
| 3233 void test_undefinedGetter_message() { | |
| 3234 // The implementation of HintCode.UNDEFINED_SETTER assumes that | |
| 3235 // UNDEFINED_SETTER in StaticTypeWarningCode and StaticWarningCode are the | |
| 3236 // same, this verifies that assumption. | |
| 3237 expect(StaticWarningCode.UNDEFINED_GETTER.message, | |
| 3238 StaticTypeWarningCode.UNDEFINED_GETTER.message); | |
| 3239 } | |
| 3240 | |
| 3241 void test_undefinedMethod() { | |
| 3242 Source source = addSource(r''' | |
| 3243 f() { | |
| 3244 var a = 'str'; | |
| 3245 a.notAMethodOnString(); | |
| 3246 }'''); | |
| 3247 computeLibrarySourceErrors(source); | |
| 3248 assertErrors(source, [HintCode.UNDEFINED_METHOD]); | |
| 3249 } | |
| 3250 | |
| 3251 void test_undefinedMethod_assignmentExpression() { | |
| 3252 Source source = addSource(r''' | |
| 3253 class A {} | |
| 3254 class B { | |
| 3255 f(var a, var a2) { | |
| 3256 a = new A(); | |
| 3257 a2 = new A(); | |
| 3258 a += a2; | |
| 3259 } | |
| 3260 }'''); | |
| 3261 computeLibrarySourceErrors(source); | |
| 3262 assertErrors(source, [HintCode.UNDEFINED_METHOD]); | |
| 3263 } | |
| 3264 | |
| 3265 void test_undefinedOperator_binaryExpression() { | |
| 3266 Source source = addSource(r''' | |
| 3267 class A {} | |
| 3268 f(var a) { | |
| 3269 if(a is A) { | |
| 3270 a + 1; | |
| 3271 } | |
| 3272 }'''); | |
| 3273 computeLibrarySourceErrors(source); | |
| 3274 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]); | |
| 3275 } | |
| 3276 | |
| 3277 void test_undefinedOperator_indexBoth() { | |
| 3278 Source source = addSource(r''' | |
| 3279 class A {} | |
| 3280 f(var a) { | |
| 3281 if(a is A) { | |
| 3282 a[0]++; | |
| 3283 } | |
| 3284 }'''); | |
| 3285 computeLibrarySourceErrors(source); | |
| 3286 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]); | |
| 3287 } | |
| 3288 | |
| 3289 void test_undefinedOperator_indexGetter() { | |
| 3290 Source source = addSource(r''' | |
| 3291 class A {} | |
| 3292 f(var a) { | |
| 3293 if(a is A) { | |
| 3294 a[0]; | |
| 3295 } | |
| 3296 }'''); | |
| 3297 computeLibrarySourceErrors(source); | |
| 3298 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]); | |
| 3299 } | |
| 3300 | |
| 3301 void test_undefinedOperator_indexSetter() { | |
| 3302 Source source = addSource(r''' | |
| 3303 class A {} | |
| 3304 f(var a) { | |
| 3305 if(a is A) { | |
| 3306 a[0] = 1; | |
| 3307 } | |
| 3308 }'''); | |
| 3309 computeLibrarySourceErrors(source); | |
| 3310 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]); | |
| 3311 } | |
| 3312 | |
| 3313 void test_undefinedOperator_postfixExpression() { | |
| 3314 Source source = addSource(r''' | |
| 3315 class A {} | |
| 3316 f(var a) { | |
| 3317 if(a is A) { | |
| 3318 a++; | |
| 3319 } | |
| 3320 }'''); | |
| 3321 computeLibrarySourceErrors(source); | |
| 3322 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]); | |
| 3323 } | |
| 3324 | |
| 3325 void test_undefinedOperator_prefixExpression() { | |
| 3326 Source source = addSource(r''' | |
| 3327 class A {} | |
| 3328 f(var a) { | |
| 3329 if(a is A) { | |
| 3330 ++a; | |
| 3331 } | |
| 3332 }'''); | |
| 3333 computeLibrarySourceErrors(source); | |
| 3334 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]); | |
| 3335 } | |
| 3336 | |
| 3337 void test_undefinedSetter() { | |
| 3338 Source source = addSource(r''' | |
| 3339 class A {} | |
| 3340 f(var a) { | |
| 3341 if(a is A) { | |
| 3342 a.m = 0; | |
| 3343 } | |
| 3344 }'''); | |
| 3345 computeLibrarySourceErrors(source); | |
| 3346 assertErrors(source, [HintCode.UNDEFINED_SETTER]); | |
| 3347 } | |
| 3348 | |
| 3349 void test_undefinedSetter_message() { | |
| 3350 // The implementation of HintCode.UNDEFINED_SETTER assumes that | |
| 3351 // UNDEFINED_SETTER in StaticTypeWarningCode and StaticWarningCode are the | |
| 3352 // same, this verifies that assumption. | |
| 3353 expect(StaticWarningCode.UNDEFINED_SETTER.message, | |
| 3354 StaticTypeWarningCode.UNDEFINED_SETTER.message); | |
| 3355 } | |
| 3356 | |
| 3357 void test_unnecessaryCast_type_supertype() { | |
| 3358 Source source = addSource(r''' | |
| 3359 m(int i) { | |
| 3360 var b = i as Object; | |
| 3361 }'''); | |
| 3362 computeLibrarySourceErrors(source); | |
| 3363 assertErrors(source, [HintCode.UNNECESSARY_CAST]); | |
| 3364 verify([source]); | |
| 3365 } | |
| 3366 | |
| 3367 void test_unnecessaryCast_type_type() { | |
| 3368 Source source = addSource(r''' | |
| 3369 m(num i) { | |
| 3370 var b = i as num; | |
| 3371 }'''); | |
| 3372 computeLibrarySourceErrors(source); | |
| 3373 assertErrors(source, [HintCode.UNNECESSARY_CAST]); | |
| 3374 verify([source]); | |
| 3375 } | |
| 3376 | |
| 3377 void test_unnecessaryTypeCheck_null_is_Null() { | |
| 3378 Source source = addSource("bool b = null is Null;"); | |
| 3379 computeLibrarySourceErrors(source); | |
| 3380 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]); | |
| 3381 verify([source]); | |
| 3382 } | |
| 3383 | |
| 3384 void test_unnecessaryTypeCheck_null_not_Null() { | |
| 3385 Source source = addSource("bool b = null is! Null;"); | |
| 3386 computeLibrarySourceErrors(source); | |
| 3387 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]); | |
| 3388 verify([source]); | |
| 3389 } | |
| 3390 | |
| 3391 void test_unnecessaryTypeCheck_type_is_dynamic() { | |
| 3392 Source source = addSource(r''' | |
| 3393 m(i) { | |
| 3394 bool b = i is dynamic; | |
| 3395 }'''); | |
| 3396 computeLibrarySourceErrors(source); | |
| 3397 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]); | |
| 3398 verify([source]); | |
| 3399 } | |
| 3400 | |
| 3401 void test_unnecessaryTypeCheck_type_is_object() { | |
| 3402 Source source = addSource(r''' | |
| 3403 m(i) { | |
| 3404 bool b = i is Object; | |
| 3405 }'''); | |
| 3406 computeLibrarySourceErrors(source); | |
| 3407 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]); | |
| 3408 verify([source]); | |
| 3409 } | |
| 3410 | |
| 3411 void test_unnecessaryTypeCheck_type_not_dynamic() { | |
| 3412 Source source = addSource(r''' | |
| 3413 m(i) { | |
| 3414 bool b = i is! dynamic; | |
| 3415 }'''); | |
| 3416 computeLibrarySourceErrors(source); | |
| 3417 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]); | |
| 3418 verify([source]); | |
| 3419 } | |
| 3420 | |
| 3421 void test_unnecessaryTypeCheck_type_not_object() { | |
| 3422 Source source = addSource(r''' | |
| 3423 m(i) { | |
| 3424 bool b = i is! Object; | |
| 3425 }'''); | |
| 3426 computeLibrarySourceErrors(source); | |
| 3427 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]); | |
| 3428 verify([source]); | |
| 3429 } | |
| 3430 | |
| 3431 void test_unusedElement_class_isUsed_extends() { | |
| 3432 enableUnusedElement = true; | |
| 3433 Source source = addSource(r''' | |
| 3434 class _A {} | |
| 3435 class B extends _A {} | |
| 3436 '''); | |
| 3437 computeLibrarySourceErrors(source); | |
| 3438 assertNoErrors(source); | |
| 3439 verify([source]); | |
| 3440 } | |
| 3441 | |
| 3442 void test_unusedElement_class_isUsed_implements() { | |
| 3443 enableUnusedElement = true; | |
| 3444 Source source = addSource(r''' | |
| 3445 class _A {} | |
| 3446 class B implements _A {} | |
| 3447 '''); | |
| 3448 computeLibrarySourceErrors(source); | |
| 3449 assertNoErrors(source); | |
| 3450 verify([source]); | |
| 3451 } | |
| 3452 | |
| 3453 void test_unusedElement_class_isUsed_instanceCreation() { | |
| 3454 enableUnusedElement = true; | |
| 3455 Source source = addSource(r''' | |
| 3456 class _A {} | |
| 3457 main() { | |
| 3458 new _A(); | |
| 3459 }'''); | |
| 3460 computeLibrarySourceErrors(source); | |
| 3461 assertNoErrors(source); | |
| 3462 verify([source]); | |
| 3463 } | |
| 3464 | |
| 3465 void test_unusedElement_class_isUsed_staticFieldAccess() { | |
| 3466 enableUnusedElement = true; | |
| 3467 Source source = addSource(r''' | |
| 3468 class _A { | |
| 3469 static const F = 42; | |
| 3470 } | |
| 3471 main() { | |
| 3472 _A.F; | |
| 3473 }'''); | |
| 3474 computeLibrarySourceErrors(source); | |
| 3475 assertNoErrors(source); | |
| 3476 verify([source]); | |
| 3477 } | |
| 3478 | |
| 3479 void test_unusedElement_class_isUsed_staticMethodInvocation() { | |
| 3480 enableUnusedElement = true; | |
| 3481 Source source = addSource(r''' | |
| 3482 class _A { | |
| 3483 static m() {} | |
| 3484 } | |
| 3485 main() { | |
| 3486 _A.m(); | |
| 3487 }'''); | |
| 3488 computeLibrarySourceErrors(source); | |
| 3489 assertNoErrors(source); | |
| 3490 verify([source]); | |
| 3491 } | |
| 3492 | |
| 3493 void test_unusedElement_class_isUsed_typeArgument() { | |
| 3494 enableUnusedElement = true; | |
| 3495 Source source = addSource(r''' | |
| 3496 class _A {} | |
| 3497 main() { | |
| 3498 var v = new List<_A>(); | |
| 3499 print(v); | |
| 3500 }'''); | |
| 3501 computeLibrarySourceErrors(source); | |
| 3502 assertNoErrors(source); | |
| 3503 verify([source]); | |
| 3504 } | |
| 3505 | |
| 3506 void test_unusedElement_class_notUsed_inClassMember() { | |
| 3507 enableUnusedElement = true; | |
| 3508 Source source = addSource(r''' | |
| 3509 class _A { | |
| 3510 static staticMethod() { | |
| 3511 new _A(); | |
| 3512 } | |
| 3513 instanceMethod() { | |
| 3514 new _A(); | |
| 3515 } | |
| 3516 } | |
| 3517 '''); | |
| 3518 computeLibrarySourceErrors(source); | |
| 3519 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 3520 verify([source]); | |
| 3521 } | |
| 3522 | |
| 3523 void test_unusedElement_class_notUsed_inConstructorName() { | |
| 3524 enableUnusedElement = true; | |
| 3525 Source source = addSource(r''' | |
| 3526 class _A { | |
| 3527 _A() {} | |
| 3528 _A.named() {} | |
| 3529 } | |
| 3530 '''); | |
| 3531 computeLibrarySourceErrors(source); | |
| 3532 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 3533 verify([source]); | |
| 3534 } | |
| 3535 | |
| 3536 void test_unusedElement_class_notUsed_isExpression() { | |
| 3537 enableUnusedElement = true; | |
| 3538 Source source = addSource(r''' | |
| 3539 class _A {} | |
| 3540 main(p) { | |
| 3541 if (p is _A) { | |
| 3542 } | |
| 3543 } | |
| 3544 '''); | |
| 3545 computeLibrarySourceErrors(source); | |
| 3546 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 3547 verify([source]); | |
| 3548 } | |
| 3549 | |
| 3550 void test_unusedElement_class_notUsed_noReference() { | |
| 3551 enableUnusedElement = true; | |
| 3552 Source source = addSource(r''' | |
| 3553 class _A {} | |
| 3554 main() { | |
| 3555 }'''); | |
| 3556 computeLibrarySourceErrors(source); | |
| 3557 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 3558 verify([source]); | |
| 3559 } | |
| 3560 | |
| 3561 void test_unusedElement_class_notUsed_variableDeclaration() { | |
| 3562 enableUnusedElement = true; | |
| 3563 Source source = addSource(r''' | |
| 3564 class _A {} | |
| 3565 main() { | |
| 3566 _A v; | |
| 3567 print(v); | |
| 3568 } | |
| 3569 print(x) {} | |
| 3570 '''); | |
| 3571 computeLibrarySourceErrors(source); | |
| 3572 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 3573 verify([source]); | |
| 3574 } | |
| 3575 | |
| 3576 void test_unusedElement_enum_isUsed_fieldReference() { | |
| 3577 enableUnusedElement = true; | |
| 3578 Source source = addSource(r''' | |
| 3579 enum _MyEnum {A, B, C} | |
| 3580 main() { | |
| 3581 print(_MyEnum.B); | |
| 3582 }'''); | |
| 3583 computeLibrarySourceErrors(source); | |
| 3584 assertNoErrors(source); | |
| 3585 verify([source]); | |
| 3586 } | |
| 3587 | |
| 3588 void test_unusedElement_enum_notUsed_noReference() { | |
| 3589 enableUnusedElement = true; | |
| 3590 Source source = addSource(r''' | |
| 3591 enum _MyEnum {A, B, C} | |
| 3592 main() { | |
| 3593 }'''); | |
| 3594 computeLibrarySourceErrors(source); | |
| 3595 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 3596 verify([source]); | |
| 3597 } | |
| 3598 | |
| 3599 void test_unusedElement_functionLocal_isUsed_closure() { | |
| 3600 enableUnusedElement = true; | |
| 3601 Source source = addSource(r''' | |
| 3602 main() { | |
| 3603 print(() {}); | |
| 3604 } | |
| 3605 print(x) {} | |
| 3606 '''); | |
| 3607 computeLibrarySourceErrors(source); | |
| 3608 assertNoErrors(source); | |
| 3609 verify([source]); | |
| 3610 } | |
| 3611 | |
| 3612 void test_unusedElement_functionLocal_isUsed_invocation() { | |
| 3613 enableUnusedElement = true; | |
| 3614 Source source = addSource(r''' | |
| 3615 main() { | |
| 3616 f() {} | |
| 3617 f(); | |
| 3618 }'''); | |
| 3619 computeLibrarySourceErrors(source); | |
| 3620 assertNoErrors(source); | |
| 3621 verify([source]); | |
| 3622 } | |
| 3623 | |
| 3624 void test_unusedElement_functionLocal_isUsed_reference() { | |
| 3625 enableUnusedElement = true; | |
| 3626 Source source = addSource(r''' | |
| 3627 main() { | |
| 3628 f() {} | |
| 3629 print(f); | |
| 3630 } | |
| 3631 print(x) {} | |
| 3632 '''); | |
| 3633 computeLibrarySourceErrors(source); | |
| 3634 assertNoErrors(source); | |
| 3635 verify([source]); | |
| 3636 } | |
| 3637 | |
| 3638 void test_unusedElement_functionLocal_notUsed_noReference() { | |
| 3639 enableUnusedElement = true; | |
| 3640 Source source = addSource(r''' | |
| 3641 main() { | |
| 3642 f() {} | |
| 3643 }'''); | |
| 3644 computeLibrarySourceErrors(source); | |
| 3645 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 3646 verify([source]); | |
| 3647 } | |
| 3648 | |
| 3649 void test_unusedElement_functionLocal_notUsed_referenceFromItself() { | |
| 3650 enableUnusedElement = true; | |
| 3651 Source source = addSource(r''' | |
| 3652 main() { | |
| 3653 _f(int p) { | |
| 3654 _f(p - 1); | |
| 3655 } | |
| 3656 }'''); | |
| 3657 computeLibrarySourceErrors(source); | |
| 3658 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 3659 verify([source]); | |
| 3660 } | |
| 3661 | |
| 3662 void test_unusedElement_functionTop_isUsed_invocation() { | |
| 3663 enableUnusedElement = true; | |
| 3664 Source source = addSource(r''' | |
| 3665 _f() {} | |
| 3666 main() { | |
| 3667 _f(); | |
| 3668 }'''); | |
| 3669 computeLibrarySourceErrors(source); | |
| 3670 assertNoErrors(source); | |
| 3671 verify([source]); | |
| 3672 } | |
| 3673 | |
| 3674 void test_unusedElement_functionTop_isUsed_reference() { | |
| 3675 enableUnusedElement = true; | |
| 3676 Source source = addSource(r''' | |
| 3677 _f() {} | |
| 3678 main() { | |
| 3679 print(_f); | |
| 3680 } | |
| 3681 print(x) {} | |
| 3682 '''); | |
| 3683 computeLibrarySourceErrors(source); | |
| 3684 assertNoErrors(source); | |
| 3685 verify([source]); | |
| 3686 } | |
| 3687 | |
| 3688 void test_unusedElement_functionTop_notUsed_noReference() { | |
| 3689 enableUnusedElement = true; | |
| 3690 Source source = addSource(r''' | |
| 3691 _f() {} | |
| 3692 main() { | |
| 3693 }'''); | |
| 3694 computeLibrarySourceErrors(source); | |
| 3695 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 3696 verify([source]); | |
| 3697 } | |
| 3698 | |
| 3699 void test_unusedElement_functionTop_notUsed_referenceFromItself() { | |
| 3700 enableUnusedElement = true; | |
| 3701 Source source = addSource(r''' | |
| 3702 _f(int p) { | |
| 3703 _f(p - 1); | |
| 3704 } | |
| 3705 main() { | |
| 3706 }'''); | |
| 3707 computeLibrarySourceErrors(source); | |
| 3708 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 3709 verify([source]); | |
| 3710 } | |
| 3711 | |
| 3712 void test_unusedElement_functionTypeAlias_isUsed_isExpression() { | |
| 3713 enableUnusedElement = true; | |
| 3714 Source source = addSource(r''' | |
| 3715 typedef _F(a, b); | |
| 3716 main(f) { | |
| 3717 if (f is _F) { | |
| 3718 print('F'); | |
| 3719 } | |
| 3720 }'''); | |
| 3721 computeLibrarySourceErrors(source); | |
| 3722 assertNoErrors(source); | |
| 3723 verify([source]); | |
| 3724 } | |
| 3725 | |
| 3726 void test_unusedElement_functionTypeAlias_isUsed_reference() { | |
| 3727 enableUnusedElement = true; | |
| 3728 Source source = addSource(r''' | |
| 3729 typedef _F(a, b); | |
| 3730 main(_F f) { | |
| 3731 }'''); | |
| 3732 computeLibrarySourceErrors(source); | |
| 3733 assertNoErrors(source); | |
| 3734 verify([source]); | |
| 3735 } | |
| 3736 | |
| 3737 void test_unusedElement_functionTypeAlias_isUsed_typeArgument() { | |
| 3738 enableUnusedElement = true; | |
| 3739 Source source = addSource(r''' | |
| 3740 typedef _F(a, b); | |
| 3741 main() { | |
| 3742 var v = new List<_F>(); | |
| 3743 print(v); | |
| 3744 }'''); | |
| 3745 computeLibrarySourceErrors(source); | |
| 3746 assertNoErrors(source); | |
| 3747 verify([source]); | |
| 3748 } | |
| 3749 | |
| 3750 void test_unusedElement_functionTypeAlias_isUsed_variableDeclaration() { | |
| 3751 enableUnusedElement = true; | |
| 3752 Source source = addSource(r''' | |
| 3753 typedef _F(a, b); | |
| 3754 class A { | |
| 3755 _F f; | |
| 3756 }'''); | |
| 3757 computeLibrarySourceErrors(source); | |
| 3758 assertNoErrors(source); | |
| 3759 verify([source]); | |
| 3760 } | |
| 3761 | |
| 3762 void test_unusedElement_functionTypeAlias_notUsed_noReference() { | |
| 3763 enableUnusedElement = true; | |
| 3764 Source source = addSource(r''' | |
| 3765 typedef _F(a, b); | |
| 3766 main() { | |
| 3767 }'''); | |
| 3768 computeLibrarySourceErrors(source); | |
| 3769 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 3770 verify([source]); | |
| 3771 } | |
| 3772 | |
| 3773 void test_unusedElement_getter_isUsed_invocation_implicitThis() { | |
| 3774 enableUnusedElement = true; | |
| 3775 Source source = addSource(r''' | |
| 3776 class A { | |
| 3777 get _g => null; | |
| 3778 useGetter() { | |
| 3779 var v = _g; | |
| 3780 } | |
| 3781 }'''); | |
| 3782 computeLibrarySourceErrors(source); | |
| 3783 assertNoErrors(source); | |
| 3784 verify([source]); | |
| 3785 } | |
| 3786 | |
| 3787 void test_unusedElement_getter_isUsed_invocation_PrefixedIdentifier() { | |
| 3788 enableUnusedElement = true; | |
| 3789 Source source = addSource(r''' | |
| 3790 class A { | |
| 3791 get _g => null; | |
| 3792 } | |
| 3793 main(A a) { | |
| 3794 var v = a._g; | |
| 3795 } | |
| 3796 '''); | |
| 3797 computeLibrarySourceErrors(source); | |
| 3798 assertNoErrors(source); | |
| 3799 verify([source]); | |
| 3800 } | |
| 3801 | |
| 3802 void test_unusedElement_getter_isUsed_invocation_PropertyAccess() { | |
| 3803 enableUnusedElement = true; | |
| 3804 Source source = addSource(r''' | |
| 3805 class A { | |
| 3806 get _g => null; | |
| 3807 } | |
| 3808 main() { | |
| 3809 var v = new A()._g; | |
| 3810 } | |
| 3811 '''); | |
| 3812 computeLibrarySourceErrors(source); | |
| 3813 assertNoErrors(source); | |
| 3814 verify([source]); | |
| 3815 } | |
| 3816 | |
| 3817 void test_unusedElement_getter_notUsed_noReference() { | |
| 3818 enableUnusedElement = true; | |
| 3819 Source source = addSource(r''' | |
| 3820 class A { | |
| 3821 get _g => null; | |
| 3822 }'''); | |
| 3823 computeLibrarySourceErrors(source); | |
| 3824 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 3825 verify([source]); | |
| 3826 } | |
| 3827 | |
| 3828 void test_unusedElement_getter_notUsed_referenceFromItself() { | |
| 3829 enableUnusedElement = true; | |
| 3830 Source source = addSource(r''' | |
| 3831 class A { | |
| 3832 get _g { | |
| 3833 return _g; | |
| 3834 } | |
| 3835 }'''); | |
| 3836 computeLibrarySourceErrors(source); | |
| 3837 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 3838 verify([source]); | |
| 3839 } | |
| 3840 | |
| 3841 void test_unusedElement_method_isUsed_hasReference_implicitThis() { | |
| 3842 enableUnusedElement = true; | |
| 3843 Source source = addSource(r''' | |
| 3844 class A { | |
| 3845 _m() {} | |
| 3846 useMethod() { | |
| 3847 print(_m); | |
| 3848 } | |
| 3849 } | |
| 3850 print(x) {} | |
| 3851 '''); | |
| 3852 computeLibrarySourceErrors(source); | |
| 3853 assertNoErrors(source); | |
| 3854 verify([source]); | |
| 3855 } | |
| 3856 | |
| 3857 void test_unusedElement_method_isUsed_hasReference_implicitThis_subclass() { | |
| 3858 enableUnusedElement = true; | |
| 3859 Source source = addSource(r''' | |
| 3860 class A { | |
| 3861 _m() {} | |
| 3862 useMethod() { | |
| 3863 print(_m); | |
| 3864 } | |
| 3865 } | |
| 3866 class B extends A { | |
| 3867 _m() {} | |
| 3868 } | |
| 3869 print(x) {} | |
| 3870 '''); | |
| 3871 computeLibrarySourceErrors(source); | |
| 3872 assertNoErrors(source); | |
| 3873 verify([source]); | |
| 3874 } | |
| 3875 | |
| 3876 void test_unusedElement_method_isUsed_hasReference_PrefixedIdentifier() { | |
| 3877 enableUnusedElement = true; | |
| 3878 Source source = addSource(r''' | |
| 3879 class A { | |
| 3880 _m() {} | |
| 3881 } | |
| 3882 main(A a) { | |
| 3883 a._m; | |
| 3884 }'''); | |
| 3885 computeLibrarySourceErrors(source); | |
| 3886 assertNoErrors(source); | |
| 3887 verify([source]); | |
| 3888 } | |
| 3889 | |
| 3890 void test_unusedElement_method_isUsed_hasReference_PropertyAccess() { | |
| 3891 enableUnusedElement = true; | |
| 3892 Source source = addSource(r''' | |
| 3893 class A { | |
| 3894 _m() {} | |
| 3895 } | |
| 3896 main() { | |
| 3897 new A()._m; | |
| 3898 }'''); | |
| 3899 computeLibrarySourceErrors(source); | |
| 3900 assertNoErrors(source); | |
| 3901 verify([source]); | |
| 3902 } | |
| 3903 | |
| 3904 void test_unusedElement_method_isUsed_invocation_implicitThis() { | |
| 3905 enableUnusedElement = true; | |
| 3906 Source source = addSource(r''' | |
| 3907 class A { | |
| 3908 _m() {} | |
| 3909 useMethod() { | |
| 3910 _m(); | |
| 3911 } | |
| 3912 }'''); | |
| 3913 computeLibrarySourceErrors(source); | |
| 3914 assertNoErrors(source); | |
| 3915 verify([source]); | |
| 3916 } | |
| 3917 | |
| 3918 void test_unusedElement_method_isUsed_invocation_implicitThis_subclass() { | |
| 3919 enableUnusedElement = true; | |
| 3920 Source source = addSource(r''' | |
| 3921 class A { | |
| 3922 _m() {} | |
| 3923 useMethod() { | |
| 3924 _m(); | |
| 3925 } | |
| 3926 } | |
| 3927 class B extends A { | |
| 3928 _m() {} | |
| 3929 }'''); | |
| 3930 computeLibrarySourceErrors(source); | |
| 3931 assertNoErrors(source); | |
| 3932 verify([source]); | |
| 3933 } | |
| 3934 | |
| 3935 void test_unusedElement_method_isUsed_invocation_MemberElement() { | |
| 3936 enableUnusedElement = true; | |
| 3937 Source source = addSource(r''' | |
| 3938 class A<T> { | |
| 3939 _m(T t) {} | |
| 3940 } | |
| 3941 main(A<int> a) { | |
| 3942 a._m(0); | |
| 3943 }'''); | |
| 3944 computeLibrarySourceErrors(source); | |
| 3945 assertNoErrors(source); | |
| 3946 verify([source]); | |
| 3947 } | |
| 3948 | |
| 3949 void test_unusedElement_method_isUsed_invocation_propagated() { | |
| 3950 enableUnusedElement = true; | |
| 3951 Source source = addSource(r''' | |
| 3952 class A { | |
| 3953 _m() {} | |
| 3954 } | |
| 3955 main() { | |
| 3956 var a = new A(); | |
| 3957 a._m(); | |
| 3958 }'''); | |
| 3959 computeLibrarySourceErrors(source); | |
| 3960 assertNoErrors(source); | |
| 3961 verify([source]); | |
| 3962 } | |
| 3963 | |
| 3964 void test_unusedElement_method_isUsed_invocation_static() { | |
| 3965 enableUnusedElement = true; | |
| 3966 Source source = addSource(r''' | |
| 3967 class A { | |
| 3968 _m() {} | |
| 3969 } | |
| 3970 main() { | |
| 3971 A a = new A(); | |
| 3972 a._m(); | |
| 3973 }'''); | |
| 3974 computeLibrarySourceErrors(source); | |
| 3975 assertNoErrors(source); | |
| 3976 verify([source]); | |
| 3977 } | |
| 3978 | |
| 3979 void test_unusedElement_method_isUsed_invocation_subclass() { | |
| 3980 enableUnusedElement = true; | |
| 3981 Source source = addSource(r''' | |
| 3982 class A { | |
| 3983 _m() {} | |
| 3984 } | |
| 3985 class B extends A { | |
| 3986 _m() {} | |
| 3987 } | |
| 3988 main(A a) { | |
| 3989 a._m(); | |
| 3990 }'''); | |
| 3991 computeLibrarySourceErrors(source); | |
| 3992 assertNoErrors(source); | |
| 3993 verify([source]); | |
| 3994 } | |
| 3995 | |
| 3996 void test_unusedElement_method_isUsed_notPrivate() { | |
| 3997 enableUnusedElement = true; | |
| 3998 Source source = addSource(r''' | |
| 3999 class A { | |
| 4000 m() {} | |
| 4001 } | |
| 4002 main() { | |
| 4003 }'''); | |
| 4004 computeLibrarySourceErrors(source); | |
| 4005 assertNoErrors(source); | |
| 4006 verify([source]); | |
| 4007 } | |
| 4008 | |
| 4009 void test_unusedElement_method_isUsed_staticInvocation() { | |
| 4010 enableUnusedElement = true; | |
| 4011 Source source = addSource(r''' | |
| 4012 class A { | |
| 4013 static _m() {} | |
| 4014 } | |
| 4015 main() { | |
| 4016 A._m(); | |
| 4017 }'''); | |
| 4018 computeLibrarySourceErrors(source); | |
| 4019 assertNoErrors(source); | |
| 4020 verify([source]); | |
| 4021 } | |
| 4022 | |
| 4023 void test_unusedElement_method_notUsed_noReference() { | |
| 4024 enableUnusedElement = true; | |
| 4025 Source source = addSource(r''' | |
| 4026 class A { | |
| 4027 static _m() {} | |
| 4028 }'''); | |
| 4029 computeLibrarySourceErrors(source); | |
| 4030 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 4031 verify([source]); | |
| 4032 } | |
| 4033 | |
| 4034 void test_unusedElement_method_notUsed_referenceFromItself() { | |
| 4035 enableUnusedElement = true; | |
| 4036 Source source = addSource(r''' | |
| 4037 class A { | |
| 4038 static _m(int p) { | |
| 4039 _m(p - 1); | |
| 4040 } | |
| 4041 }'''); | |
| 4042 computeLibrarySourceErrors(source); | |
| 4043 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 4044 verify([source]); | |
| 4045 } | |
| 4046 | |
| 4047 void test_unusedElement_setter_isUsed_invocation_implicitThis() { | |
| 4048 enableUnusedElement = true; | |
| 4049 Source source = addSource(r''' | |
| 4050 class A { | |
| 4051 set _s(x) {} | |
| 4052 useSetter() { | |
| 4053 _s = 42; | |
| 4054 } | |
| 4055 }'''); | |
| 4056 computeLibrarySourceErrors(source); | |
| 4057 assertNoErrors(source); | |
| 4058 verify([source]); | |
| 4059 } | |
| 4060 | |
| 4061 void test_unusedElement_setter_isUsed_invocation_PrefixedIdentifier() { | |
| 4062 enableUnusedElement = true; | |
| 4063 Source source = addSource(r''' | |
| 4064 class A { | |
| 4065 set _s(x) {} | |
| 4066 } | |
| 4067 main(A a) { | |
| 4068 a._s = 42; | |
| 4069 } | |
| 4070 '''); | |
| 4071 computeLibrarySourceErrors(source); | |
| 4072 assertNoErrors(source); | |
| 4073 verify([source]); | |
| 4074 } | |
| 4075 | |
| 4076 void test_unusedElement_setter_isUsed_invocation_PropertyAccess() { | |
| 4077 enableUnusedElement = true; | |
| 4078 Source source = addSource(r''' | |
| 4079 class A { | |
| 4080 set _s(x) {} | |
| 4081 } | |
| 4082 main() { | |
| 4083 new A()._s = 42; | |
| 4084 } | |
| 4085 '''); | |
| 4086 computeLibrarySourceErrors(source); | |
| 4087 assertNoErrors(source); | |
| 4088 verify([source]); | |
| 4089 } | |
| 4090 | |
| 4091 void test_unusedElement_setter_notUsed_noReference() { | |
| 4092 enableUnusedElement = true; | |
| 4093 Source source = addSource(r''' | |
| 4094 class A { | |
| 4095 set _s(x) {} | |
| 4096 }'''); | |
| 4097 computeLibrarySourceErrors(source); | |
| 4098 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 4099 verify([source]); | |
| 4100 } | |
| 4101 | |
| 4102 void test_unusedElement_setter_notUsed_referenceFromItself() { | |
| 4103 enableUnusedElement = true; | |
| 4104 Source source = addSource(r''' | |
| 4105 class A { | |
| 4106 set _s(int x) { | |
| 4107 if (x > 5) { | |
| 4108 _s = x - 1; | |
| 4109 } | |
| 4110 } | |
| 4111 }'''); | |
| 4112 computeLibrarySourceErrors(source); | |
| 4113 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 4114 verify([source]); | |
| 4115 } | |
| 4116 | |
| 4117 void test_unusedField_isUsed_argument() { | |
| 4118 enableUnusedElement = true; | |
| 4119 Source source = addSource(r''' | |
| 4120 class A { | |
| 4121 int _f = 0; | |
| 4122 main() { | |
| 4123 print(++_f); | |
| 4124 } | |
| 4125 } | |
| 4126 print(x) {}'''); | |
| 4127 computeLibrarySourceErrors(source); | |
| 4128 assertErrors(source); | |
| 4129 verify([source]); | |
| 4130 } | |
| 4131 | |
| 4132 void test_unusedField_isUsed_reference_implicitThis() { | |
| 4133 enableUnusedElement = true; | |
| 4134 Source source = addSource(r''' | |
| 4135 class A { | |
| 4136 int _f; | |
| 4137 main() { | |
| 4138 print(_f); | |
| 4139 } | |
| 4140 } | |
| 4141 print(x) {}'''); | |
| 4142 computeLibrarySourceErrors(source); | |
| 4143 assertErrors(source); | |
| 4144 verify([source]); | |
| 4145 } | |
| 4146 | |
| 4147 void test_unusedField_isUsed_reference_implicitThis_expressionFunctionBody() { | |
| 4148 enableUnusedElement = true; | |
| 4149 Source source = addSource(r''' | |
| 4150 class A { | |
| 4151 int _f; | |
| 4152 m() => _f; | |
| 4153 }'''); | |
| 4154 computeLibrarySourceErrors(source); | |
| 4155 assertErrors(source); | |
| 4156 verify([source]); | |
| 4157 } | |
| 4158 | |
| 4159 void test_unusedField_isUsed_reference_implicitThis_subclass() { | |
| 4160 enableUnusedElement = true; | |
| 4161 Source source = addSource(r''' | |
| 4162 class A { | |
| 4163 int _f; | |
| 4164 main() { | |
| 4165 print(_f); | |
| 4166 } | |
| 4167 } | |
| 4168 class B extends A { | |
| 4169 int _f; | |
| 4170 } | |
| 4171 print(x) {}'''); | |
| 4172 computeLibrarySourceErrors(source); | |
| 4173 assertErrors(source); | |
| 4174 verify([source]); | |
| 4175 } | |
| 4176 | |
| 4177 void test_unusedField_isUsed_reference_qualified_propagatedElement() { | |
| 4178 enableUnusedElement = true; | |
| 4179 Source source = addSource(r''' | |
| 4180 class A { | |
| 4181 int _f; | |
| 4182 } | |
| 4183 main() { | |
| 4184 var a = new A(); | |
| 4185 print(a._f); | |
| 4186 } | |
| 4187 print(x) {}'''); | |
| 4188 computeLibrarySourceErrors(source); | |
| 4189 assertErrors(source); | |
| 4190 verify([source]); | |
| 4191 } | |
| 4192 | |
| 4193 void test_unusedField_isUsed_reference_qualified_staticElement() { | |
| 4194 enableUnusedElement = true; | |
| 4195 Source source = addSource(r''' | |
| 4196 class A { | |
| 4197 int _f; | |
| 4198 } | |
| 4199 main() { | |
| 4200 A a = new A(); | |
| 4201 print(a._f); | |
| 4202 } | |
| 4203 print(x) {}'''); | |
| 4204 computeLibrarySourceErrors(source); | |
| 4205 assertErrors(source); | |
| 4206 verify([source]); | |
| 4207 } | |
| 4208 | |
| 4209 void test_unusedField_isUsed_reference_qualified_unresolved() { | |
| 4210 enableUnusedElement = true; | |
| 4211 Source source = addSource(r''' | |
| 4212 class A { | |
| 4213 int _f; | |
| 4214 } | |
| 4215 main(a) { | |
| 4216 print(a._f); | |
| 4217 } | |
| 4218 print(x) {}'''); | |
| 4219 computeLibrarySourceErrors(source); | |
| 4220 assertErrors(source); | |
| 4221 verify([source]); | |
| 4222 } | |
| 4223 | |
| 4224 void test_unusedField_notUsed_compoundAssign() { | |
| 4225 enableUnusedElement = true; | |
| 4226 Source source = addSource(r''' | |
| 4227 class A { | |
| 4228 int _f; | |
| 4229 main() { | |
| 4230 _f += 2; | |
| 4231 } | |
| 4232 }'''); | |
| 4233 computeLibrarySourceErrors(source); | |
| 4234 assertErrors(source, [HintCode.UNUSED_FIELD]); | |
| 4235 verify([source]); | |
| 4236 } | |
| 4237 | |
| 4238 void test_unusedField_notUsed_noReference() { | |
| 4239 enableUnusedElement = true; | |
| 4240 Source source = addSource(r''' | |
| 4241 class A { | |
| 4242 int _f; | |
| 4243 } | |
| 4244 '''); | |
| 4245 computeLibrarySourceErrors(source); | |
| 4246 assertErrors(source, [HintCode.UNUSED_FIELD]); | |
| 4247 verify([source]); | |
| 4248 } | |
| 4249 | |
| 4250 void test_unusedField_notUsed_postfixExpr() { | |
| 4251 enableUnusedElement = true; | |
| 4252 Source source = addSource(r''' | |
| 4253 class A { | |
| 4254 int _f = 0; | |
| 4255 main() { | |
| 4256 _f++; | |
| 4257 } | |
| 4258 }'''); | |
| 4259 computeLibrarySourceErrors(source); | |
| 4260 assertErrors(source, [HintCode.UNUSED_FIELD]); | |
| 4261 verify([source]); | |
| 4262 } | |
| 4263 | |
| 4264 void test_unusedField_notUsed_prefixExpr() { | |
| 4265 enableUnusedElement = true; | |
| 4266 Source source = addSource(r''' | |
| 4267 class A { | |
| 4268 int _f = 0; | |
| 4269 main() { | |
| 4270 ++_f; | |
| 4271 } | |
| 4272 }'''); | |
| 4273 computeLibrarySourceErrors(source); | |
| 4274 assertErrors(source, [HintCode.UNUSED_FIELD]); | |
| 4275 verify([source]); | |
| 4276 } | |
| 4277 | |
| 4278 void test_unusedField_notUsed_simpleAssignment() { | |
| 4279 enableUnusedElement = true; | |
| 4280 Source source = addSource(r''' | |
| 4281 class A { | |
| 4282 int _f; | |
| 4283 m() { | |
| 4284 _f = 1; | |
| 4285 } | |
| 4286 } | |
| 4287 main(A a) { | |
| 4288 a._f = 2; | |
| 4289 } | |
| 4290 '''); | |
| 4291 computeLibrarySourceErrors(source); | |
| 4292 assertErrors(source, [HintCode.UNUSED_FIELD]); | |
| 4293 verify([source]); | |
| 4294 } | |
| 4295 | |
| 4296 void test_unusedImport() { | |
| 4297 Source source = addSource(r''' | |
| 4298 library L; | |
| 4299 import 'lib1.dart';'''); | |
| 4300 Source source2 = addNamedSource("/lib1.dart", "library lib1;"); | |
| 4301 computeLibrarySourceErrors(source); | |
| 4302 assertErrors(source, [HintCode.UNUSED_IMPORT]); | |
| 4303 assertNoErrors(source2); | |
| 4304 verify([source, source2]); | |
| 4305 } | |
| 4306 | |
| 4307 void test_unusedImport_as() { | |
| 4308 Source source = addSource(r''' | |
| 4309 library L; | |
| 4310 import 'lib1.dart'; | |
| 4311 import 'lib1.dart' as one; | |
| 4312 one.A a;'''); | |
| 4313 Source source2 = addNamedSource( | |
| 4314 "/lib1.dart", | |
| 4315 r''' | |
| 4316 library lib1; | |
| 4317 class A {}'''); | |
| 4318 computeLibrarySourceErrors(source); | |
| 4319 assertErrors(source, [HintCode.UNUSED_IMPORT]); | |
| 4320 assertNoErrors(source2); | |
| 4321 verify([source, source2]); | |
| 4322 } | |
| 4323 | |
| 4324 void test_unusedImport_hide() { | |
| 4325 Source source = addSource(r''' | |
| 4326 library L; | |
| 4327 import 'lib1.dart'; | |
| 4328 import 'lib1.dart' hide A; | |
| 4329 A a;'''); | |
| 4330 Source source2 = addNamedSource( | |
| 4331 "/lib1.dart", | |
| 4332 r''' | |
| 4333 library lib1; | |
| 4334 class A {}'''); | |
| 4335 computeLibrarySourceErrors(source); | |
| 4336 assertErrors(source, [HintCode.UNUSED_IMPORT]); | |
| 4337 assertNoErrors(source2); | |
| 4338 verify([source, source2]); | |
| 4339 } | |
| 4340 | |
| 4341 void test_unusedImport_show() { | |
| 4342 Source source = addSource(r''' | |
| 4343 library L; | |
| 4344 import 'lib1.dart' show A; | |
| 4345 import 'lib1.dart' show B; | |
| 4346 A a;'''); | |
| 4347 Source source2 = addNamedSource( | |
| 4348 "/lib1.dart", | |
| 4349 r''' | |
| 4350 library lib1; | |
| 4351 class A {} | |
| 4352 class B {}'''); | |
| 4353 computeLibrarySourceErrors(source); | |
| 4354 assertErrors(source, [HintCode.UNUSED_IMPORT]); | |
| 4355 assertNoErrors(source2); | |
| 4356 verify([source, source2]); | |
| 4357 } | |
| 4358 | |
| 4359 void test_unusedLocalVariable_inCatch_exception() { | |
| 4360 enableUnusedLocalVariable = true; | |
| 4361 Source source = addSource(r''' | |
| 4362 main() { | |
| 4363 try { | |
| 4364 } on String catch (exception) { | |
| 4365 } | |
| 4366 }'''); | |
| 4367 computeLibrarySourceErrors(source); | |
| 4368 assertErrors(source, [HintCode.UNUSED_CATCH_CLAUSE]); | |
| 4369 verify([source]); | |
| 4370 } | |
| 4371 | |
| 4372 void test_unusedLocalVariable_inCatch_exception_hasStack() { | |
| 4373 enableUnusedLocalVariable = true; | |
| 4374 Source source = addSource(r''' | |
| 4375 main() { | |
| 4376 try { | |
| 4377 } catch (exception, stack) { | |
| 4378 print(stack); | |
| 4379 } | |
| 4380 }'''); | |
| 4381 computeLibrarySourceErrors(source); | |
| 4382 assertNoErrors(source); | |
| 4383 verify([source]); | |
| 4384 } | |
| 4385 | |
| 4386 void test_unusedLocalVariable_inCatch_exception_noOnClause() { | |
| 4387 enableUnusedLocalVariable = true; | |
| 4388 Source source = addSource(r''' | |
| 4389 main() { | |
| 4390 try { | |
| 4391 } catch (exception) { | |
| 4392 } | |
| 4393 }'''); | |
| 4394 computeLibrarySourceErrors(source); | |
| 4395 assertNoErrors(source); | |
| 4396 verify([source]); | |
| 4397 } | |
| 4398 | |
| 4399 void test_unusedLocalVariable_inCatch_stackTrace() { | |
| 4400 enableUnusedLocalVariable = true; | |
| 4401 Source source = addSource(r''' | |
| 4402 main() { | |
| 4403 try { | |
| 4404 } catch (exception, stackTrace) { | |
| 4405 } | |
| 4406 }'''); | |
| 4407 computeLibrarySourceErrors(source); | |
| 4408 assertErrors(source, [HintCode.UNUSED_CATCH_STACK]); | |
| 4409 verify([source]); | |
| 4410 } | |
| 4411 | |
| 4412 void test_unusedLocalVariable_inCatch_stackTrace_used() { | |
| 4413 enableUnusedLocalVariable = true; | |
| 4414 Source source = addSource(r''' | |
| 4415 main() { | |
| 4416 try { | |
| 4417 } catch (exception, stackTrace) { | |
| 4418 print('exception at $stackTrace'); | |
| 4419 } | |
| 4420 } | |
| 4421 print(x) {}'''); | |
| 4422 computeLibrarySourceErrors(source); | |
| 4423 assertErrors(source); | |
| 4424 verify([source]); | |
| 4425 } | |
| 4426 | |
| 4427 void test_unusedLocalVariable_inFor_underscore_ignored() { | |
| 4428 enableUnusedLocalVariable = true; | |
| 4429 Source source = addSource(r''' | |
| 4430 main() { | |
| 4431 for (var _ in [1,2,3]) { | |
| 4432 for (var __ in [4,5,6]) { | |
| 4433 // do something | |
| 4434 } | |
| 4435 } | |
| 4436 }'''); | |
| 4437 computeLibrarySourceErrors(source); | |
| 4438 assertErrors(source); | |
| 4439 verify([source]); | |
| 4440 } | |
| 4441 | |
| 4442 void test_unusedLocalVariable_inFunction() { | |
| 4443 enableUnusedLocalVariable = true; | |
| 4444 Source source = addSource(r''' | |
| 4445 main() { | |
| 4446 var v = 1; | |
| 4447 v = 2; | |
| 4448 }'''); | |
| 4449 computeLibrarySourceErrors(source); | |
| 4450 assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]); | |
| 4451 verify([source]); | |
| 4452 } | |
| 4453 | |
| 4454 void test_unusedLocalVariable_inMethod() { | |
| 4455 enableUnusedLocalVariable = true; | |
| 4456 Source source = addSource(r''' | |
| 4457 class A { | |
| 4458 foo() { | |
| 4459 var v = 1; | |
| 4460 v = 2; | |
| 4461 } | |
| 4462 }'''); | |
| 4463 computeLibrarySourceErrors(source); | |
| 4464 assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]); | |
| 4465 verify([source]); | |
| 4466 } | |
| 4467 | |
| 4468 void test_unusedLocalVariable_isInvoked() { | |
| 4469 enableUnusedLocalVariable = true; | |
| 4470 Source source = addSource(r''' | |
| 4471 typedef Foo(); | |
| 4472 main() { | |
| 4473 Foo foo; | |
| 4474 foo(); | |
| 4475 }'''); | |
| 4476 computeLibrarySourceErrors(source); | |
| 4477 assertErrors(source); | |
| 4478 verify([source]); | |
| 4479 } | |
| 4480 | |
| 4481 void test_unusedLocalVariable_isRead_notUsed_compoundAssign() { | |
| 4482 enableUnusedLocalVariable = true; | |
| 4483 Source source = addSource(r''' | |
| 4484 main() { | |
| 4485 var v = 1; | |
| 4486 v += 2; | |
| 4487 }'''); | |
| 4488 computeLibrarySourceErrors(source); | |
| 4489 assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]); | |
| 4490 verify([source]); | |
| 4491 } | |
| 4492 | |
| 4493 void test_unusedLocalVariable_isRead_notUsed_postfixExpr() { | |
| 4494 enableUnusedLocalVariable = true; | |
| 4495 Source source = addSource(r''' | |
| 4496 main() { | |
| 4497 var v = 1; | |
| 4498 v++; | |
| 4499 }'''); | |
| 4500 computeLibrarySourceErrors(source); | |
| 4501 assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]); | |
| 4502 verify([source]); | |
| 4503 } | |
| 4504 | |
| 4505 void test_unusedLocalVariable_isRead_notUsed_prefixExpr() { | |
| 4506 enableUnusedLocalVariable = true; | |
| 4507 Source source = addSource(r''' | |
| 4508 main() { | |
| 4509 var v = 1; | |
| 4510 ++v; | |
| 4511 }'''); | |
| 4512 computeLibrarySourceErrors(source); | |
| 4513 assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]); | |
| 4514 verify([source]); | |
| 4515 } | |
| 4516 | |
| 4517 void test_unusedLocalVariable_isRead_usedArgument() { | |
| 4518 enableUnusedLocalVariable = true; | |
| 4519 Source source = addSource(r''' | |
| 4520 main() { | |
| 4521 var v = 1; | |
| 4522 print(++v); | |
| 4523 } | |
| 4524 print(x) {}'''); | |
| 4525 computeLibrarySourceErrors(source); | |
| 4526 assertErrors(source); | |
| 4527 verify([source]); | |
| 4528 } | |
| 4529 | |
| 4530 void test_unusedLocalVariable_isRead_usedInvocationTarget() { | |
| 4531 enableUnusedLocalVariable = true; | |
| 4532 Source source = addSource(r''' | |
| 4533 class A { | |
| 4534 foo() {} | |
| 4535 } | |
| 4536 main() { | |
| 4537 var a = new A(); | |
| 4538 a.foo(); | |
| 4539 } | |
| 4540 '''); | |
| 4541 computeLibrarySourceErrors(source); | |
| 4542 assertErrors(source); | |
| 4543 verify([source]); | |
| 4544 } | |
| 4545 | |
| 4546 void test_useOfVoidResult_assignmentExpression_function() { | |
| 4547 Source source = addSource(r''' | |
| 4548 void f() {} | |
| 4549 class A { | |
| 4550 n() { | |
| 4551 var a; | |
| 4552 a = f(); | |
| 4553 } | |
| 4554 }'''); | |
| 4555 computeLibrarySourceErrors(source); | |
| 4556 assertErrors(source, [HintCode.USE_OF_VOID_RESULT]); | |
| 4557 verify([source]); | |
| 4558 } | |
| 4559 | |
| 4560 void test_useOfVoidResult_assignmentExpression_method() { | |
| 4561 Source source = addSource(r''' | |
| 4562 class A { | |
| 4563 void m() {} | |
| 4564 n() { | |
| 4565 var a; | |
| 4566 a = m(); | |
| 4567 } | |
| 4568 }'''); | |
| 4569 computeLibrarySourceErrors(source); | |
| 4570 assertErrors(source, [HintCode.USE_OF_VOID_RESULT]); | |
| 4571 verify([source]); | |
| 4572 } | |
| 4573 | |
| 4574 void test_useOfVoidResult_inForLoop() { | |
| 4575 Source source = addSource(r''' | |
| 4576 class A { | |
| 4577 void m() {} | |
| 4578 n() { | |
| 4579 for(var a = m();;) {} | |
| 4580 } | |
| 4581 }'''); | |
| 4582 computeLibrarySourceErrors(source); | |
| 4583 assertErrors(source, [HintCode.USE_OF_VOID_RESULT]); | |
| 4584 verify([source]); | |
| 4585 } | |
| 4586 | |
| 4587 void test_useOfVoidResult_variableDeclaration_function() { | |
| 4588 Source source = addSource(r''' | |
| 4589 void f() {} | |
| 4590 class A { | |
| 4591 n() { | |
| 4592 var a = f(); | |
| 4593 } | |
| 4594 }'''); | |
| 4595 computeLibrarySourceErrors(source); | |
| 4596 assertErrors(source, [HintCode.USE_OF_VOID_RESULT]); | |
| 4597 verify([source]); | |
| 4598 } | |
| 4599 | |
| 4600 void test_useOfVoidResult_variableDeclaration_method() { | |
| 4601 Source source = addSource(r''' | |
| 4602 class A { | |
| 4603 void m() {} | |
| 4604 n() { | |
| 4605 var a = m(); | |
| 4606 } | |
| 4607 }'''); | |
| 4608 computeLibrarySourceErrors(source); | |
| 4609 assertErrors(source, [HintCode.USE_OF_VOID_RESULT]); | |
| 4610 verify([source]); | |
| 4611 } | |
| 4612 | |
| 4613 void test_useOfVoidResult_variableDeclaration_method2() { | |
| 4614 Source source = addSource(r''' | |
| 4615 class A { | |
| 4616 void m() {} | |
| 4617 n() { | |
| 4618 var a = m(), b = m(); | |
| 4619 } | |
| 4620 }'''); | |
| 4621 computeLibrarySourceErrors(source); | |
| 4622 assertErrors( | |
| 4623 source, [HintCode.USE_OF_VOID_RESULT, HintCode.USE_OF_VOID_RESULT]); | |
| 4624 verify([source]); | |
| 4625 } | |
| 4626 } | |
| 4627 | |
| 4628 @reflectiveTest | |
| 4629 class InheritanceManagerTest extends EngineTestCase { | |
| 4630 /** | |
| 4631 * The type provider used to access the types. | |
| 4632 */ | |
| 4633 TestTypeProvider _typeProvider; | |
| 4634 | |
| 4635 /** | |
| 4636 * The library containing the code being resolved. | |
| 4637 */ | |
| 4638 LibraryElementImpl _definingLibrary; | |
| 4639 | |
| 4640 /** | |
| 4641 * The inheritance manager being tested. | |
| 4642 */ | |
| 4643 InheritanceManager _inheritanceManager; | |
| 4644 | |
| 4645 /** | |
| 4646 * The number of members that Object implements (as determined by [TestTypePro
vider]). | |
| 4647 */ | |
| 4648 int _numOfMembersInObject = 0; | |
| 4649 | |
| 4650 @override | |
| 4651 void setUp() { | |
| 4652 _typeProvider = new TestTypeProvider(); | |
| 4653 _inheritanceManager = _createInheritanceManager(); | |
| 4654 InterfaceType objectType = _typeProvider.objectType; | |
| 4655 _numOfMembersInObject = | |
| 4656 objectType.methods.length + objectType.accessors.length; | |
| 4657 } | |
| 4658 | |
| 4659 void test_getMapOfMembersInheritedFromClasses_accessor_extends() { | |
| 4660 // class A { int get g; } | |
| 4661 // class B extends A {} | |
| 4662 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 4663 String getterName = "g"; | |
| 4664 PropertyAccessorElement getterG = | |
| 4665 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 4666 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 4667 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 4668 MemberMap mapB = | |
| 4669 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB); | |
| 4670 MemberMap mapA = | |
| 4671 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA); | |
| 4672 expect(mapA.size, _numOfMembersInObject); | |
| 4673 expect(mapB.size, _numOfMembersInObject + 1); | |
| 4674 expect(mapB.get(getterName), same(getterG)); | |
| 4675 _assertNoErrors(classA); | |
| 4676 _assertNoErrors(classB); | |
| 4677 } | |
| 4678 | |
| 4679 void test_getMapOfMembersInheritedFromClasses_accessor_implements() { | |
| 4680 // class A { int get g; } | |
| 4681 // class B implements A {} | |
| 4682 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 4683 String getterName = "g"; | |
| 4684 PropertyAccessorElement getterG = | |
| 4685 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 4686 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 4687 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 4688 classB.interfaces = <InterfaceType>[classA.type]; | |
| 4689 MemberMap mapB = | |
| 4690 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB); | |
| 4691 MemberMap mapA = | |
| 4692 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA); | |
| 4693 expect(mapA.size, _numOfMembersInObject); | |
| 4694 expect(mapB.size, _numOfMembersInObject); | |
| 4695 expect(mapB.get(getterName), isNull); | |
| 4696 _assertNoErrors(classA); | |
| 4697 _assertNoErrors(classB); | |
| 4698 } | |
| 4699 | |
| 4700 void test_getMapOfMembersInheritedFromClasses_accessor_with() { | |
| 4701 // class A { int get g; } | |
| 4702 // class B extends Object with A {} | |
| 4703 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 4704 String getterName = "g"; | |
| 4705 PropertyAccessorElement getterG = | |
| 4706 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 4707 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 4708 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 4709 classB.mixins = <InterfaceType>[classA.type]; | |
| 4710 MemberMap mapB = | |
| 4711 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB); | |
| 4712 MemberMap mapA = | |
| 4713 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA); | |
| 4714 expect(mapA.size, _numOfMembersInObject); | |
| 4715 expect(mapB.size, _numOfMembersInObject + 1); | |
| 4716 expect(mapB.get(getterName), same(getterG)); | |
| 4717 _assertNoErrors(classA); | |
| 4718 _assertNoErrors(classB); | |
| 4719 } | |
| 4720 | |
| 4721 void test_getMapOfMembersInheritedFromClasses_implicitExtends() { | |
| 4722 // class A {} | |
| 4723 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 4724 MemberMap mapA = | |
| 4725 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA); | |
| 4726 expect(mapA.size, _numOfMembersInObject); | |
| 4727 _assertNoErrors(classA); | |
| 4728 } | |
| 4729 | |
| 4730 void test_getMapOfMembersInheritedFromClasses_method_extends() { | |
| 4731 // class A { int g(); } | |
| 4732 // class B extends A {} | |
| 4733 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 4734 String methodName = "m"; | |
| 4735 MethodElement methodM = | |
| 4736 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 4737 classA.methods = <MethodElement>[methodM]; | |
| 4738 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 4739 classB.supertype = classA.type; | |
| 4740 MemberMap mapB = | |
| 4741 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB); | |
| 4742 MemberMap mapA = | |
| 4743 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA); | |
| 4744 expect(mapA.size, _numOfMembersInObject); | |
| 4745 expect(mapB.size, _numOfMembersInObject + 1); | |
| 4746 expect(mapB.get(methodName), same(methodM)); | |
| 4747 _assertNoErrors(classA); | |
| 4748 _assertNoErrors(classB); | |
| 4749 } | |
| 4750 | |
| 4751 void test_getMapOfMembersInheritedFromClasses_method_implements() { | |
| 4752 // class A { int g(); } | |
| 4753 // class B implements A {} | |
| 4754 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 4755 String methodName = "m"; | |
| 4756 MethodElement methodM = | |
| 4757 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 4758 classA.methods = <MethodElement>[methodM]; | |
| 4759 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 4760 classB.interfaces = <InterfaceType>[classA.type]; | |
| 4761 MemberMap mapB = | |
| 4762 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB); | |
| 4763 MemberMap mapA = | |
| 4764 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA); | |
| 4765 expect(mapA.size, _numOfMembersInObject); | |
| 4766 expect(mapB.size, _numOfMembersInObject); | |
| 4767 expect(mapB.get(methodName), isNull); | |
| 4768 _assertNoErrors(classA); | |
| 4769 _assertNoErrors(classB); | |
| 4770 } | |
| 4771 | |
| 4772 void test_getMapOfMembersInheritedFromClasses_method_with() { | |
| 4773 // class A { int g(); } | |
| 4774 // class B extends Object with A {} | |
| 4775 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 4776 String methodName = "m"; | |
| 4777 MethodElement methodM = | |
| 4778 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 4779 classA.methods = <MethodElement>[methodM]; | |
| 4780 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 4781 classB.mixins = <InterfaceType>[classA.type]; | |
| 4782 MemberMap mapB = | |
| 4783 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB); | |
| 4784 MemberMap mapA = | |
| 4785 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA); | |
| 4786 expect(mapA.size, _numOfMembersInObject); | |
| 4787 expect(mapB.size, _numOfMembersInObject + 1); | |
| 4788 expect(mapB.get(methodName), same(methodM)); | |
| 4789 _assertNoErrors(classA); | |
| 4790 _assertNoErrors(classB); | |
| 4791 } | |
| 4792 | |
| 4793 void test_getMapOfMembersInheritedFromClasses_method_with_two_mixins() { | |
| 4794 // class A1 { int m(); } | |
| 4795 // class A2 { int m(); } | |
| 4796 // class B extends Object with A1, A2 {} | |
| 4797 ClassElementImpl classA1 = ElementFactory.classElement2("A1"); | |
| 4798 String methodName = "m"; | |
| 4799 MethodElement methodA1M = | |
| 4800 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 4801 classA1.methods = <MethodElement>[methodA1M]; | |
| 4802 ClassElementImpl classA2 = ElementFactory.classElement2("A2"); | |
| 4803 MethodElement methodA2M = | |
| 4804 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 4805 classA2.methods = <MethodElement>[methodA2M]; | |
| 4806 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 4807 classB.mixins = <InterfaceType>[classA1.type, classA2.type]; | |
| 4808 MemberMap mapB = | |
| 4809 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB); | |
| 4810 expect(mapB.get(methodName), same(methodA2M)); | |
| 4811 _assertNoErrors(classA1); | |
| 4812 _assertNoErrors(classA2); | |
| 4813 _assertNoErrors(classB); | |
| 4814 } | |
| 4815 | |
| 4816 void test_getMapOfMembersInheritedFromInterfaces_accessor_extends() { | |
| 4817 // class A { int get g; } | |
| 4818 // class B extends A {} | |
| 4819 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 4820 String getterName = "g"; | |
| 4821 PropertyAccessorElement getterG = | |
| 4822 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 4823 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 4824 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 4825 MemberMap mapB = | |
| 4826 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB); | |
| 4827 MemberMap mapA = | |
| 4828 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 4829 expect(mapA.size, _numOfMembersInObject); | |
| 4830 expect(mapB.size, _numOfMembersInObject + 1); | |
| 4831 expect(mapB.get(getterName), same(getterG)); | |
| 4832 _assertNoErrors(classA); | |
| 4833 _assertNoErrors(classB); | |
| 4834 } | |
| 4835 | |
| 4836 void test_getMapOfMembersInheritedFromInterfaces_accessor_implements() { | |
| 4837 // class A { int get g; } | |
| 4838 // class B implements A {} | |
| 4839 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 4840 String getterName = "g"; | |
| 4841 PropertyAccessorElement getterG = | |
| 4842 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 4843 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 4844 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 4845 classB.interfaces = <InterfaceType>[classA.type]; | |
| 4846 MemberMap mapB = | |
| 4847 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB); | |
| 4848 MemberMap mapA = | |
| 4849 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 4850 expect(mapA.size, _numOfMembersInObject); | |
| 4851 expect(mapB.size, _numOfMembersInObject + 1); | |
| 4852 expect(mapB.get(getterName), same(getterG)); | |
| 4853 _assertNoErrors(classA); | |
| 4854 _assertNoErrors(classB); | |
| 4855 } | |
| 4856 | |
| 4857 void test_getMapOfMembersInheritedFromInterfaces_accessor_with() { | |
| 4858 // class A { int get g; } | |
| 4859 // class B extends Object with A {} | |
| 4860 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 4861 String getterName = "g"; | |
| 4862 PropertyAccessorElement getterG = | |
| 4863 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 4864 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 4865 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 4866 classB.mixins = <InterfaceType>[classA.type]; | |
| 4867 MemberMap mapB = | |
| 4868 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB); | |
| 4869 MemberMap mapA = | |
| 4870 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 4871 expect(mapA.size, _numOfMembersInObject); | |
| 4872 expect(mapB.size, _numOfMembersInObject + 1); | |
| 4873 expect(mapB.get(getterName), same(getterG)); | |
| 4874 _assertNoErrors(classA); | |
| 4875 _assertNoErrors(classB); | |
| 4876 } | |
| 4877 | |
| 4878 void test_getMapOfMembersInheritedFromInterfaces_implicitExtends() { | |
| 4879 // class A {} | |
| 4880 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 4881 MemberMap mapA = | |
| 4882 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 4883 expect(mapA.size, _numOfMembersInObject); | |
| 4884 _assertNoErrors(classA); | |
| 4885 } | |
| 4886 | |
| 4887 void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance
_getter_method() { | |
| 4888 // class I1 { int m(); } | |
| 4889 // class I2 { int get m; } | |
| 4890 // class A implements I2, I1 {} | |
| 4891 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 4892 String methodName = "m"; | |
| 4893 MethodElement methodM = | |
| 4894 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 4895 classI1.methods = <MethodElement>[methodM]; | |
| 4896 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 4897 PropertyAccessorElement getter = | |
| 4898 ElementFactory.getterElement(methodName, false, _typeProvider.intType); | |
| 4899 classI2.accessors = <PropertyAccessorElement>[getter]; | |
| 4900 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 4901 classA.interfaces = <InterfaceType>[classI2.type, classI1.type]; | |
| 4902 MemberMap mapA = | |
| 4903 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 4904 expect(mapA.size, _numOfMembersInObject); | |
| 4905 expect(mapA.get(methodName), isNull); | |
| 4906 _assertErrors(classA, | |
| 4907 [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]); | |
| 4908 } | |
| 4909 | |
| 4910 void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance
_int_str() { | |
| 4911 // class I1 { int m(); } | |
| 4912 // class I2 { String m(); } | |
| 4913 // class A implements I1, I2 {} | |
| 4914 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 4915 String methodName = "m"; | |
| 4916 MethodElement methodM1 = | |
| 4917 ElementFactory.methodElement(methodName, null, [_typeProvider.intType]); | |
| 4918 classI1.methods = <MethodElement>[methodM1]; | |
| 4919 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 4920 MethodElement methodM2 = ElementFactory.methodElement( | |
| 4921 methodName, null, [_typeProvider.stringType]); | |
| 4922 classI2.methods = <MethodElement>[methodM2]; | |
| 4923 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 4924 classA.interfaces = <InterfaceType>[classI1.type, classI2.type]; | |
| 4925 MemberMap mapA = | |
| 4926 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 4927 expect(mapA.size, _numOfMembersInObject); | |
| 4928 expect(mapA.get(methodName), isNull); | |
| 4929 _assertErrors( | |
| 4930 classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]); | |
| 4931 } | |
| 4932 | |
| 4933 void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance
_method_getter() { | |
| 4934 // class I1 { int m(); } | |
| 4935 // class I2 { int get m; } | |
| 4936 // class A implements I1, I2 {} | |
| 4937 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 4938 String methodName = "m"; | |
| 4939 MethodElement methodM = | |
| 4940 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 4941 classI1.methods = <MethodElement>[methodM]; | |
| 4942 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 4943 PropertyAccessorElement getter = | |
| 4944 ElementFactory.getterElement(methodName, false, _typeProvider.intType); | |
| 4945 classI2.accessors = <PropertyAccessorElement>[getter]; | |
| 4946 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 4947 classA.interfaces = <InterfaceType>[classI1.type, classI2.type]; | |
| 4948 MemberMap mapA = | |
| 4949 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 4950 expect(mapA.size, _numOfMembersInObject); | |
| 4951 expect(mapA.get(methodName), isNull); | |
| 4952 _assertErrors(classA, | |
| 4953 [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]); | |
| 4954 } | |
| 4955 | |
| 4956 void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance
_numOfRequiredParams() { | |
| 4957 // class I1 { dynamic m(int, [int]); } | |
| 4958 // class I2 { dynamic m(int, int, int); } | |
| 4959 // class A implements I1, I2 {} | |
| 4960 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 4961 String methodName = "m"; | |
| 4962 MethodElementImpl methodM1 = | |
| 4963 ElementFactory.methodElement(methodName, _typeProvider.dynamicType); | |
| 4964 ParameterElementImpl parameter1 = | |
| 4965 new ParameterElementImpl.forNode(AstFactory.identifier3("a1")); | |
| 4966 parameter1.type = _typeProvider.intType; | |
| 4967 parameter1.parameterKind = ParameterKind.REQUIRED; | |
| 4968 ParameterElementImpl parameter2 = | |
| 4969 new ParameterElementImpl.forNode(AstFactory.identifier3("a2")); | |
| 4970 parameter2.type = _typeProvider.intType; | |
| 4971 parameter2.parameterKind = ParameterKind.POSITIONAL; | |
| 4972 methodM1.parameters = <ParameterElement>[parameter1, parameter2]; | |
| 4973 classI1.methods = <MethodElement>[methodM1]; | |
| 4974 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 4975 MethodElementImpl methodM2 = | |
| 4976 ElementFactory.methodElement(methodName, _typeProvider.dynamicType); | |
| 4977 ParameterElementImpl parameter3 = | |
| 4978 new ParameterElementImpl.forNode(AstFactory.identifier3("a3")); | |
| 4979 parameter3.type = _typeProvider.intType; | |
| 4980 parameter3.parameterKind = ParameterKind.REQUIRED; | |
| 4981 ParameterElementImpl parameter4 = | |
| 4982 new ParameterElementImpl.forNode(AstFactory.identifier3("a4")); | |
| 4983 parameter4.type = _typeProvider.intType; | |
| 4984 parameter4.parameterKind = ParameterKind.REQUIRED; | |
| 4985 ParameterElementImpl parameter5 = | |
| 4986 new ParameterElementImpl.forNode(AstFactory.identifier3("a5")); | |
| 4987 parameter5.type = _typeProvider.intType; | |
| 4988 parameter5.parameterKind = ParameterKind.REQUIRED; | |
| 4989 methodM2.parameters = <ParameterElement>[ | |
| 4990 parameter3, | |
| 4991 parameter4, | |
| 4992 parameter5 | |
| 4993 ]; | |
| 4994 classI2.methods = <MethodElement>[methodM2]; | |
| 4995 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 4996 classA.interfaces = <InterfaceType>[classI1.type, classI2.type]; | |
| 4997 MemberMap mapA = | |
| 4998 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 4999 expect(mapA.size, _numOfMembersInObject); | |
| 5000 expect(mapA.get(methodName), isNull); | |
| 5001 _assertErrors( | |
| 5002 classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]); | |
| 5003 } | |
| 5004 | |
| 5005 void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance
_str_int() { | |
| 5006 // class I1 { int m(); } | |
| 5007 // class I2 { String m(); } | |
| 5008 // class A implements I2, I1 {} | |
| 5009 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5010 String methodName = "m"; | |
| 5011 MethodElement methodM1 = ElementFactory.methodElement( | |
| 5012 methodName, null, [_typeProvider.stringType]); | |
| 5013 classI1.methods = <MethodElement>[methodM1]; | |
| 5014 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5015 MethodElement methodM2 = | |
| 5016 ElementFactory.methodElement(methodName, null, [_typeProvider.intType]); | |
| 5017 classI2.methods = <MethodElement>[methodM2]; | |
| 5018 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5019 classA.interfaces = <InterfaceType>[classI2.type, classI1.type]; | |
| 5020 MemberMap mapA = | |
| 5021 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5022 expect(mapA.size, _numOfMembersInObject); | |
| 5023 expect(mapA.get(methodName), isNull); | |
| 5024 _assertErrors( | |
| 5025 classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]); | |
| 5026 } | |
| 5027 | |
| 5028 void test_getMapOfMembersInheritedFromInterfaces_method_extends() { | |
| 5029 // class A { int g(); } | |
| 5030 // class B extends A {} | |
| 5031 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5032 String methodName = "m"; | |
| 5033 MethodElement methodM = | |
| 5034 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5035 classA.methods = <MethodElement>[methodM]; | |
| 5036 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 5037 MemberMap mapB = | |
| 5038 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB); | |
| 5039 MemberMap mapA = | |
| 5040 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5041 expect(mapA.size, _numOfMembersInObject); | |
| 5042 expect(mapB.size, _numOfMembersInObject + 1); | |
| 5043 expect(mapB.get(methodName), same(methodM)); | |
| 5044 _assertNoErrors(classA); | |
| 5045 _assertNoErrors(classB); | |
| 5046 } | |
| 5047 | |
| 5048 void test_getMapOfMembersInheritedFromInterfaces_method_implements() { | |
| 5049 // class A { int g(); } | |
| 5050 // class B implements A {} | |
| 5051 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5052 String methodName = "m"; | |
| 5053 MethodElement methodM = | |
| 5054 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5055 classA.methods = <MethodElement>[methodM]; | |
| 5056 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5057 classB.interfaces = <InterfaceType>[classA.type]; | |
| 5058 MemberMap mapB = | |
| 5059 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB); | |
| 5060 MemberMap mapA = | |
| 5061 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5062 expect(mapA.size, _numOfMembersInObject); | |
| 5063 expect(mapB.size, _numOfMembersInObject + 1); | |
| 5064 expect(mapB.get(methodName), same(methodM)); | |
| 5065 _assertNoErrors(classA); | |
| 5066 _assertNoErrors(classB); | |
| 5067 } | |
| 5068 | |
| 5069 void test_getMapOfMembersInheritedFromInterfaces_method_with() { | |
| 5070 // class A { int g(); } | |
| 5071 // class B extends Object with A {} | |
| 5072 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5073 String methodName = "m"; | |
| 5074 MethodElement methodM = | |
| 5075 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5076 classA.methods = <MethodElement>[methodM]; | |
| 5077 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5078 classB.mixins = <InterfaceType>[classA.type]; | |
| 5079 MemberMap mapB = | |
| 5080 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB); | |
| 5081 MemberMap mapA = | |
| 5082 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5083 expect(mapA.size, _numOfMembersInObject); | |
| 5084 expect(mapB.size, _numOfMembersInObject + 1); | |
| 5085 expect(mapB.get(methodName), same(methodM)); | |
| 5086 _assertNoErrors(classA); | |
| 5087 _assertNoErrors(classB); | |
| 5088 } | |
| 5089 | |
| 5090 void test_getMapOfMembersInheritedFromInterfaces_union_differentNames() { | |
| 5091 // class I1 { int m1(); } | |
| 5092 // class I2 { int m2(); } | |
| 5093 // class A implements I1, I2 {} | |
| 5094 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5095 String methodName1 = "m1"; | |
| 5096 MethodElement methodM1 = | |
| 5097 ElementFactory.methodElement(methodName1, _typeProvider.intType); | |
| 5098 classI1.methods = <MethodElement>[methodM1]; | |
| 5099 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5100 String methodName2 = "m2"; | |
| 5101 MethodElement methodM2 = | |
| 5102 ElementFactory.methodElement(methodName2, _typeProvider.intType); | |
| 5103 classI2.methods = <MethodElement>[methodM2]; | |
| 5104 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5105 classA.interfaces = <InterfaceType>[classI1.type, classI2.type]; | |
| 5106 MemberMap mapA = | |
| 5107 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5108 expect(mapA.size, _numOfMembersInObject + 2); | |
| 5109 expect(mapA.get(methodName1), same(methodM1)); | |
| 5110 expect(mapA.get(methodName2), same(methodM2)); | |
| 5111 _assertNoErrors(classA); | |
| 5112 } | |
| 5113 | |
| 5114 void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_gett
ers() { | |
| 5115 // class I1 { int get g; } | |
| 5116 // class I2 { num get g; } | |
| 5117 // class A implements I1, I2 {} | |
| 5118 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5119 String accessorName = "g"; | |
| 5120 PropertyAccessorElement getter1 = ElementFactory.getterElement( | |
| 5121 accessorName, false, _typeProvider.intType); | |
| 5122 classI1.accessors = <PropertyAccessorElement>[getter1]; | |
| 5123 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5124 PropertyAccessorElement getter2 = ElementFactory.getterElement( | |
| 5125 accessorName, false, _typeProvider.numType); | |
| 5126 classI2.accessors = <PropertyAccessorElement>[getter2]; | |
| 5127 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5128 classA.interfaces = <InterfaceType>[classI1.type, classI2.type]; | |
| 5129 MemberMap mapA = | |
| 5130 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5131 expect(mapA.size, _numOfMembersInObject + 1); | |
| 5132 PropertyAccessorElement syntheticAccessor = ElementFactory.getterElement( | |
| 5133 accessorName, false, _typeProvider.dynamicType); | |
| 5134 expect(mapA.get(accessorName).type, syntheticAccessor.type); | |
| 5135 _assertNoErrors(classA); | |
| 5136 } | |
| 5137 | |
| 5138 void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_meth
ods() { | |
| 5139 // class I1 { dynamic m(int); } | |
| 5140 // class I2 { dynamic m(num); } | |
| 5141 // class A implements I1, I2 {} | |
| 5142 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5143 String methodName = "m"; | |
| 5144 MethodElementImpl methodM1 = | |
| 5145 ElementFactory.methodElement(methodName, _typeProvider.dynamicType); | |
| 5146 ParameterElementImpl parameter1 = | |
| 5147 new ParameterElementImpl.forNode(AstFactory.identifier3("a0")); | |
| 5148 parameter1.type = _typeProvider.intType; | |
| 5149 parameter1.parameterKind = ParameterKind.REQUIRED; | |
| 5150 methodM1.parameters = <ParameterElement>[parameter1]; | |
| 5151 classI1.methods = <MethodElement>[methodM1]; | |
| 5152 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5153 MethodElementImpl methodM2 = | |
| 5154 ElementFactory.methodElement(methodName, _typeProvider.dynamicType); | |
| 5155 ParameterElementImpl parameter2 = | |
| 5156 new ParameterElementImpl.forNode(AstFactory.identifier3("a0")); | |
| 5157 parameter2.type = _typeProvider.numType; | |
| 5158 parameter2.parameterKind = ParameterKind.REQUIRED; | |
| 5159 methodM2.parameters = <ParameterElement>[parameter2]; | |
| 5160 classI2.methods = <MethodElement>[methodM2]; | |
| 5161 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5162 classA.interfaces = <InterfaceType>[classI1.type, classI2.type]; | |
| 5163 MemberMap mapA = | |
| 5164 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5165 expect(mapA.size, _numOfMembersInObject + 1); | |
| 5166 MethodElement syntheticMethod = ElementFactory.methodElement( | |
| 5167 methodName, _typeProvider.dynamicType, [_typeProvider.dynamicType]); | |
| 5168 expect(mapA.get(methodName).type, syntheticMethod.type); | |
| 5169 _assertNoErrors(classA); | |
| 5170 } | |
| 5171 | |
| 5172 void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_sett
ers() { | |
| 5173 // class I1 { set s(int); } | |
| 5174 // class I2 { set s(num); } | |
| 5175 // class A implements I1, I2 {} | |
| 5176 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5177 String accessorName = "s"; | |
| 5178 PropertyAccessorElement setter1 = ElementFactory.setterElement( | |
| 5179 accessorName, false, _typeProvider.intType); | |
| 5180 classI1.accessors = <PropertyAccessorElement>[setter1]; | |
| 5181 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5182 PropertyAccessorElement setter2 = ElementFactory.setterElement( | |
| 5183 accessorName, false, _typeProvider.numType); | |
| 5184 classI2.accessors = <PropertyAccessorElement>[setter2]; | |
| 5185 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5186 classA.interfaces = <InterfaceType>[classI1.type, classI2.type]; | |
| 5187 MemberMap mapA = | |
| 5188 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5189 expect(mapA.size, _numOfMembersInObject + 1); | |
| 5190 PropertyAccessorElementImpl syntheticAccessor = ElementFactory | |
| 5191 .setterElement(accessorName, false, _typeProvider.dynamicType); | |
| 5192 syntheticAccessor.returnType = _typeProvider.dynamicType; | |
| 5193 expect(mapA.get("$accessorName=").type, syntheticAccessor.type); | |
| 5194 _assertNoErrors(classA); | |
| 5195 } | |
| 5196 | |
| 5197 void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_gett
ers() { | |
| 5198 // class A {} | |
| 5199 // class B extends A {} | |
| 5200 // class C extends B {} | |
| 5201 // class I1 { A get g; } | |
| 5202 // class I2 { B get g; } | |
| 5203 // class I3 { C get g; } | |
| 5204 // class D implements I1, I2, I3 {} | |
| 5205 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5206 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 5207 ClassElementImpl classC = ElementFactory.classElement("C", classB.type); | |
| 5208 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5209 String accessorName = "g"; | |
| 5210 PropertyAccessorElement getter1 = | |
| 5211 ElementFactory.getterElement(accessorName, false, classA.type); | |
| 5212 classI1.accessors = <PropertyAccessorElement>[getter1]; | |
| 5213 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5214 PropertyAccessorElement getter2 = | |
| 5215 ElementFactory.getterElement(accessorName, false, classB.type); | |
| 5216 classI2.accessors = <PropertyAccessorElement>[getter2]; | |
| 5217 ClassElementImpl classI3 = ElementFactory.classElement2("I3"); | |
| 5218 PropertyAccessorElement getter3 = | |
| 5219 ElementFactory.getterElement(accessorName, false, classC.type); | |
| 5220 classI3.accessors = <PropertyAccessorElement>[getter3]; | |
| 5221 ClassElementImpl classD = ElementFactory.classElement2("D"); | |
| 5222 classD.interfaces = <InterfaceType>[ | |
| 5223 classI1.type, | |
| 5224 classI2.type, | |
| 5225 classI3.type | |
| 5226 ]; | |
| 5227 MemberMap mapD = | |
| 5228 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD); | |
| 5229 expect(mapD.size, _numOfMembersInObject + 1); | |
| 5230 PropertyAccessorElement syntheticAccessor = ElementFactory.getterElement( | |
| 5231 accessorName, false, _typeProvider.dynamicType); | |
| 5232 expect(mapD.get(accessorName).type, syntheticAccessor.type); | |
| 5233 _assertNoErrors(classD); | |
| 5234 } | |
| 5235 | |
| 5236 void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_meth
ods() { | |
| 5237 // class A {} | |
| 5238 // class B extends A {} | |
| 5239 // class C extends B {} | |
| 5240 // class I1 { dynamic m(A a); } | |
| 5241 // class I2 { dynamic m(B b); } | |
| 5242 // class I3 { dynamic m(C c); } | |
| 5243 // class D implements I1, I2, I3 {} | |
| 5244 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5245 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 5246 ClassElementImpl classC = ElementFactory.classElement("C", classB.type); | |
| 5247 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5248 String methodName = "m"; | |
| 5249 MethodElementImpl methodM1 = | |
| 5250 ElementFactory.methodElement(methodName, _typeProvider.dynamicType); | |
| 5251 ParameterElementImpl parameter1 = | |
| 5252 new ParameterElementImpl.forNode(AstFactory.identifier3("a0")); | |
| 5253 parameter1.type = classA.type; | |
| 5254 parameter1.parameterKind = ParameterKind.REQUIRED; | |
| 5255 methodM1.parameters = <ParameterElement>[parameter1]; | |
| 5256 classI1.methods = <MethodElement>[methodM1]; | |
| 5257 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5258 MethodElementImpl methodM2 = | |
| 5259 ElementFactory.methodElement(methodName, _typeProvider.dynamicType); | |
| 5260 ParameterElementImpl parameter2 = | |
| 5261 new ParameterElementImpl.forNode(AstFactory.identifier3("a0")); | |
| 5262 parameter2.type = classB.type; | |
| 5263 parameter2.parameterKind = ParameterKind.REQUIRED; | |
| 5264 methodM2.parameters = <ParameterElement>[parameter2]; | |
| 5265 classI2.methods = <MethodElement>[methodM2]; | |
| 5266 ClassElementImpl classI3 = ElementFactory.classElement2("I3"); | |
| 5267 MethodElementImpl methodM3 = | |
| 5268 ElementFactory.methodElement(methodName, _typeProvider.dynamicType); | |
| 5269 ParameterElementImpl parameter3 = | |
| 5270 new ParameterElementImpl.forNode(AstFactory.identifier3("a0")); | |
| 5271 parameter3.type = classC.type; | |
| 5272 parameter3.parameterKind = ParameterKind.REQUIRED; | |
| 5273 methodM3.parameters = <ParameterElement>[parameter3]; | |
| 5274 classI3.methods = <MethodElement>[methodM3]; | |
| 5275 ClassElementImpl classD = ElementFactory.classElement2("D"); | |
| 5276 classD.interfaces = <InterfaceType>[ | |
| 5277 classI1.type, | |
| 5278 classI2.type, | |
| 5279 classI3.type | |
| 5280 ]; | |
| 5281 MemberMap mapD = | |
| 5282 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD); | |
| 5283 expect(mapD.size, _numOfMembersInObject + 1); | |
| 5284 MethodElement syntheticMethod = ElementFactory.methodElement( | |
| 5285 methodName, _typeProvider.dynamicType, [_typeProvider.dynamicType]); | |
| 5286 expect(mapD.get(methodName).type, syntheticMethod.type); | |
| 5287 _assertNoErrors(classD); | |
| 5288 } | |
| 5289 | |
| 5290 void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_sett
ers() { | |
| 5291 // class A {} | |
| 5292 // class B extends A {} | |
| 5293 // class C extends B {} | |
| 5294 // class I1 { set s(A); } | |
| 5295 // class I2 { set s(B); } | |
| 5296 // class I3 { set s(C); } | |
| 5297 // class D implements I1, I2, I3 {} | |
| 5298 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5299 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 5300 ClassElementImpl classC = ElementFactory.classElement("C", classB.type); | |
| 5301 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5302 String accessorName = "s"; | |
| 5303 PropertyAccessorElement setter1 = | |
| 5304 ElementFactory.setterElement(accessorName, false, classA.type); | |
| 5305 classI1.accessors = <PropertyAccessorElement>[setter1]; | |
| 5306 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5307 PropertyAccessorElement setter2 = | |
| 5308 ElementFactory.setterElement(accessorName, false, classB.type); | |
| 5309 classI2.accessors = <PropertyAccessorElement>[setter2]; | |
| 5310 ClassElementImpl classI3 = ElementFactory.classElement2("I3"); | |
| 5311 PropertyAccessorElement setter3 = | |
| 5312 ElementFactory.setterElement(accessorName, false, classC.type); | |
| 5313 classI3.accessors = <PropertyAccessorElement>[setter3]; | |
| 5314 ClassElementImpl classD = ElementFactory.classElement2("D"); | |
| 5315 classD.interfaces = <InterfaceType>[ | |
| 5316 classI1.type, | |
| 5317 classI2.type, | |
| 5318 classI3.type | |
| 5319 ]; | |
| 5320 MemberMap mapD = | |
| 5321 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD); | |
| 5322 expect(mapD.size, _numOfMembersInObject + 1); | |
| 5323 PropertyAccessorElementImpl syntheticAccessor = ElementFactory | |
| 5324 .setterElement(accessorName, false, _typeProvider.dynamicType); | |
| 5325 syntheticAccessor.returnType = _typeProvider.dynamicType; | |
| 5326 expect(mapD.get("$accessorName=").type, syntheticAccessor.type); | |
| 5327 _assertNoErrors(classD); | |
| 5328 } | |
| 5329 | |
| 5330 void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_2_methods()
{ | |
| 5331 // class I1 { int m(); } | |
| 5332 // class I2 { int m([int]); } | |
| 5333 // class A implements I1, I2 {} | |
| 5334 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5335 String methodName = "m"; | |
| 5336 MethodElement methodM1 = | |
| 5337 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5338 classI1.methods = <MethodElement>[methodM1]; | |
| 5339 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5340 MethodElementImpl methodM2 = | |
| 5341 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5342 ParameterElementImpl parameter1 = | |
| 5343 new ParameterElementImpl.forNode(AstFactory.identifier3("a1")); | |
| 5344 parameter1.type = _typeProvider.intType; | |
| 5345 parameter1.parameterKind = ParameterKind.POSITIONAL; | |
| 5346 methodM2.parameters = <ParameterElement>[parameter1]; | |
| 5347 classI2.methods = <MethodElement>[methodM2]; | |
| 5348 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5349 classA.interfaces = <InterfaceType>[classI1.type, classI2.type]; | |
| 5350 MemberMap mapA = | |
| 5351 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5352 expect(mapA.size, _numOfMembersInObject + 1); | |
| 5353 expect(mapA.get(methodName), same(methodM2)); | |
| 5354 _assertNoErrors(classA); | |
| 5355 } | |
| 5356 | |
| 5357 void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_3_methods()
{ | |
| 5358 // class I1 { int m(); } | |
| 5359 // class I2 { int m([int]); } | |
| 5360 // class I3 { int m([int, int]); } | |
| 5361 // class A implements I1, I2, I3 {} | |
| 5362 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5363 String methodName = "m"; | |
| 5364 MethodElementImpl methodM1 = | |
| 5365 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5366 classI1.methods = <MethodElement>[methodM1]; | |
| 5367 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5368 MethodElementImpl methodM2 = | |
| 5369 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5370 ParameterElementImpl parameter1 = | |
| 5371 new ParameterElementImpl.forNode(AstFactory.identifier3("a1")); | |
| 5372 parameter1.type = _typeProvider.intType; | |
| 5373 parameter1.parameterKind = ParameterKind.POSITIONAL; | |
| 5374 methodM1.parameters = <ParameterElement>[parameter1]; | |
| 5375 classI2.methods = <MethodElement>[methodM2]; | |
| 5376 ClassElementImpl classI3 = ElementFactory.classElement2("I3"); | |
| 5377 MethodElementImpl methodM3 = | |
| 5378 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5379 ParameterElementImpl parameter2 = | |
| 5380 new ParameterElementImpl.forNode(AstFactory.identifier3("a2")); | |
| 5381 parameter2.type = _typeProvider.intType; | |
| 5382 parameter2.parameterKind = ParameterKind.POSITIONAL; | |
| 5383 ParameterElementImpl parameter3 = | |
| 5384 new ParameterElementImpl.forNode(AstFactory.identifier3("a3")); | |
| 5385 parameter3.type = _typeProvider.intType; | |
| 5386 parameter3.parameterKind = ParameterKind.POSITIONAL; | |
| 5387 methodM3.parameters = <ParameterElement>[parameter2, parameter3]; | |
| 5388 classI3.methods = <MethodElement>[methodM3]; | |
| 5389 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5390 classA.interfaces = <InterfaceType>[ | |
| 5391 classI1.type, | |
| 5392 classI2.type, | |
| 5393 classI3.type | |
| 5394 ]; | |
| 5395 MemberMap mapA = | |
| 5396 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5397 expect(mapA.size, _numOfMembersInObject + 1); | |
| 5398 expect(mapA.get(methodName), same(methodM3)); | |
| 5399 _assertNoErrors(classA); | |
| 5400 } | |
| 5401 | |
| 5402 void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_4_methods()
{ | |
| 5403 // class I1 { int m(); } | |
| 5404 // class I2 { int m(); } | |
| 5405 // class I3 { int m([int]); } | |
| 5406 // class I4 { int m([int, int]); } | |
| 5407 // class A implements I1, I2, I3, I4 {} | |
| 5408 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5409 String methodName = "m"; | |
| 5410 MethodElement methodM1 = | |
| 5411 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5412 classI1.methods = <MethodElement>[methodM1]; | |
| 5413 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5414 MethodElement methodM2 = | |
| 5415 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5416 classI2.methods = <MethodElement>[methodM2]; | |
| 5417 ClassElementImpl classI3 = ElementFactory.classElement2("I3"); | |
| 5418 MethodElementImpl methodM3 = | |
| 5419 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5420 ParameterElementImpl parameter1 = | |
| 5421 new ParameterElementImpl.forNode(AstFactory.identifier3("a1")); | |
| 5422 parameter1.type = _typeProvider.intType; | |
| 5423 parameter1.parameterKind = ParameterKind.POSITIONAL; | |
| 5424 methodM3.parameters = <ParameterElement>[parameter1]; | |
| 5425 classI3.methods = <MethodElement>[methodM3]; | |
| 5426 ClassElementImpl classI4 = ElementFactory.classElement2("I4"); | |
| 5427 MethodElementImpl methodM4 = | |
| 5428 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5429 ParameterElementImpl parameter2 = | |
| 5430 new ParameterElementImpl.forNode(AstFactory.identifier3("a2")); | |
| 5431 parameter2.type = _typeProvider.intType; | |
| 5432 parameter2.parameterKind = ParameterKind.POSITIONAL; | |
| 5433 ParameterElementImpl parameter3 = | |
| 5434 new ParameterElementImpl.forNode(AstFactory.identifier3("a3")); | |
| 5435 parameter3.type = _typeProvider.intType; | |
| 5436 parameter3.parameterKind = ParameterKind.POSITIONAL; | |
| 5437 methodM4.parameters = <ParameterElement>[parameter2, parameter3]; | |
| 5438 classI4.methods = <MethodElement>[methodM4]; | |
| 5439 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5440 classA.interfaces = <InterfaceType>[ | |
| 5441 classI1.type, | |
| 5442 classI2.type, | |
| 5443 classI3.type, | |
| 5444 classI4.type | |
| 5445 ]; | |
| 5446 MemberMap mapA = | |
| 5447 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5448 expect(mapA.size, _numOfMembersInObject + 1); | |
| 5449 expect(mapA.get(methodName), same(methodM4)); | |
| 5450 _assertNoErrors(classA); | |
| 5451 } | |
| 5452 | |
| 5453 void test_lookupInheritance_interface_getter() { | |
| 5454 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5455 String getterName = "g"; | |
| 5456 PropertyAccessorElement getterG = | |
| 5457 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 5458 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 5459 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5460 classB.interfaces = <InterfaceType>[classA.type]; | |
| 5461 expect(_inheritanceManager.lookupInheritance(classB, getterName), | |
| 5462 same(getterG)); | |
| 5463 _assertNoErrors(classA); | |
| 5464 _assertNoErrors(classB); | |
| 5465 } | |
| 5466 | |
| 5467 void test_lookupInheritance_interface_method() { | |
| 5468 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5469 String methodName = "m"; | |
| 5470 MethodElement methodM = | |
| 5471 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5472 classA.methods = <MethodElement>[methodM]; | |
| 5473 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5474 classB.interfaces = <InterfaceType>[classA.type]; | |
| 5475 expect(_inheritanceManager.lookupInheritance(classB, methodName), | |
| 5476 same(methodM)); | |
| 5477 _assertNoErrors(classA); | |
| 5478 _assertNoErrors(classB); | |
| 5479 } | |
| 5480 | |
| 5481 void test_lookupInheritance_interface_setter() { | |
| 5482 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5483 String setterName = "s"; | |
| 5484 PropertyAccessorElement setterS = | |
| 5485 ElementFactory.setterElement(setterName, false, _typeProvider.intType); | |
| 5486 classA.accessors = <PropertyAccessorElement>[setterS]; | |
| 5487 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5488 classB.interfaces = <InterfaceType>[classA.type]; | |
| 5489 expect(_inheritanceManager.lookupInheritance(classB, "$setterName="), | |
| 5490 same(setterS)); | |
| 5491 _assertNoErrors(classA); | |
| 5492 _assertNoErrors(classB); | |
| 5493 } | |
| 5494 | |
| 5495 void test_lookupInheritance_interface_staticMember() { | |
| 5496 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5497 String methodName = "m"; | |
| 5498 MethodElement methodM = | |
| 5499 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5500 (methodM as MethodElementImpl).static = true; | |
| 5501 classA.methods = <MethodElement>[methodM]; | |
| 5502 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5503 classB.interfaces = <InterfaceType>[classA.type]; | |
| 5504 expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull); | |
| 5505 _assertNoErrors(classA); | |
| 5506 _assertNoErrors(classB); | |
| 5507 } | |
| 5508 | |
| 5509 void test_lookupInheritance_interfaces_infiniteLoop() { | |
| 5510 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5511 classA.interfaces = <InterfaceType>[classA.type]; | |
| 5512 expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull); | |
| 5513 _assertNoErrors(classA); | |
| 5514 } | |
| 5515 | |
| 5516 void test_lookupInheritance_interfaces_infiniteLoop2() { | |
| 5517 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5518 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5519 classA.interfaces = <InterfaceType>[classB.type]; | |
| 5520 classB.interfaces = <InterfaceType>[classA.type]; | |
| 5521 expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull); | |
| 5522 _assertNoErrors(classA); | |
| 5523 _assertNoErrors(classB); | |
| 5524 } | |
| 5525 | |
| 5526 void test_lookupInheritance_interfaces_union2() { | |
| 5527 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5528 String methodName1 = "m1"; | |
| 5529 MethodElement methodM1 = | |
| 5530 ElementFactory.methodElement(methodName1, _typeProvider.intType); | |
| 5531 classI1.methods = <MethodElement>[methodM1]; | |
| 5532 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5533 String methodName2 = "m2"; | |
| 5534 MethodElement methodM2 = | |
| 5535 ElementFactory.methodElement(methodName2, _typeProvider.intType); | |
| 5536 classI2.methods = <MethodElement>[methodM2]; | |
| 5537 classI2.interfaces = <InterfaceType>[classI1.type]; | |
| 5538 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5539 classA.interfaces = <InterfaceType>[classI2.type]; | |
| 5540 expect(_inheritanceManager.lookupInheritance(classA, methodName1), | |
| 5541 same(methodM1)); | |
| 5542 expect(_inheritanceManager.lookupInheritance(classA, methodName2), | |
| 5543 same(methodM2)); | |
| 5544 _assertNoErrors(classI1); | |
| 5545 _assertNoErrors(classI2); | |
| 5546 _assertNoErrors(classA); | |
| 5547 } | |
| 5548 | |
| 5549 void test_lookupInheritance_mixin_getter() { | |
| 5550 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5551 String getterName = "g"; | |
| 5552 PropertyAccessorElement getterG = | |
| 5553 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 5554 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 5555 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5556 classB.mixins = <InterfaceType>[classA.type]; | |
| 5557 expect(_inheritanceManager.lookupInheritance(classB, getterName), | |
| 5558 same(getterG)); | |
| 5559 _assertNoErrors(classA); | |
| 5560 _assertNoErrors(classB); | |
| 5561 } | |
| 5562 | |
| 5563 void test_lookupInheritance_mixin_method() { | |
| 5564 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5565 String methodName = "m"; | |
| 5566 MethodElement methodM = | |
| 5567 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5568 classA.methods = <MethodElement>[methodM]; | |
| 5569 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5570 classB.mixins = <InterfaceType>[classA.type]; | |
| 5571 expect(_inheritanceManager.lookupInheritance(classB, methodName), | |
| 5572 same(methodM)); | |
| 5573 _assertNoErrors(classA); | |
| 5574 _assertNoErrors(classB); | |
| 5575 } | |
| 5576 | |
| 5577 void test_lookupInheritance_mixin_setter() { | |
| 5578 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5579 String setterName = "s"; | |
| 5580 PropertyAccessorElement setterS = | |
| 5581 ElementFactory.setterElement(setterName, false, _typeProvider.intType); | |
| 5582 classA.accessors = <PropertyAccessorElement>[setterS]; | |
| 5583 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5584 classB.mixins = <InterfaceType>[classA.type]; | |
| 5585 expect(_inheritanceManager.lookupInheritance(classB, "$setterName="), | |
| 5586 same(setterS)); | |
| 5587 _assertNoErrors(classA); | |
| 5588 _assertNoErrors(classB); | |
| 5589 } | |
| 5590 | |
| 5591 void test_lookupInheritance_mixin_staticMember() { | |
| 5592 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5593 String methodName = "m"; | |
| 5594 MethodElement methodM = | |
| 5595 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5596 (methodM as MethodElementImpl).static = true; | |
| 5597 classA.methods = <MethodElement>[methodM]; | |
| 5598 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5599 classB.mixins = <InterfaceType>[classA.type]; | |
| 5600 expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull); | |
| 5601 _assertNoErrors(classA); | |
| 5602 _assertNoErrors(classB); | |
| 5603 } | |
| 5604 | |
| 5605 void test_lookupInheritance_noMember() { | |
| 5606 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5607 expect(_inheritanceManager.lookupInheritance(classA, "a"), isNull); | |
| 5608 _assertNoErrors(classA); | |
| 5609 } | |
| 5610 | |
| 5611 void test_lookupInheritance_superclass_getter() { | |
| 5612 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5613 String getterName = "g"; | |
| 5614 PropertyAccessorElement getterG = | |
| 5615 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 5616 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 5617 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 5618 expect(_inheritanceManager.lookupInheritance(classB, getterName), | |
| 5619 same(getterG)); | |
| 5620 _assertNoErrors(classA); | |
| 5621 _assertNoErrors(classB); | |
| 5622 } | |
| 5623 | |
| 5624 void test_lookupInheritance_superclass_infiniteLoop() { | |
| 5625 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5626 classA.supertype = classA.type; | |
| 5627 expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull); | |
| 5628 _assertNoErrors(classA); | |
| 5629 } | |
| 5630 | |
| 5631 void test_lookupInheritance_superclass_infiniteLoop2() { | |
| 5632 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5633 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5634 classA.supertype = classB.type; | |
| 5635 classB.supertype = classA.type; | |
| 5636 expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull); | |
| 5637 _assertNoErrors(classA); | |
| 5638 _assertNoErrors(classB); | |
| 5639 } | |
| 5640 | |
| 5641 void test_lookupInheritance_superclass_method() { | |
| 5642 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5643 String methodName = "m"; | |
| 5644 MethodElement methodM = | |
| 5645 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5646 classA.methods = <MethodElement>[methodM]; | |
| 5647 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 5648 expect(_inheritanceManager.lookupInheritance(classB, methodName), | |
| 5649 same(methodM)); | |
| 5650 _assertNoErrors(classA); | |
| 5651 _assertNoErrors(classB); | |
| 5652 } | |
| 5653 | |
| 5654 void test_lookupInheritance_superclass_setter() { | |
| 5655 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5656 String setterName = "s"; | |
| 5657 PropertyAccessorElement setterS = | |
| 5658 ElementFactory.setterElement(setterName, false, _typeProvider.intType); | |
| 5659 classA.accessors = <PropertyAccessorElement>[setterS]; | |
| 5660 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 5661 expect(_inheritanceManager.lookupInheritance(classB, "$setterName="), | |
| 5662 same(setterS)); | |
| 5663 _assertNoErrors(classA); | |
| 5664 _assertNoErrors(classB); | |
| 5665 } | |
| 5666 | |
| 5667 void test_lookupInheritance_superclass_staticMember() { | |
| 5668 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5669 String methodName = "m"; | |
| 5670 MethodElement methodM = | |
| 5671 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5672 (methodM as MethodElementImpl).static = true; | |
| 5673 classA.methods = <MethodElement>[methodM]; | |
| 5674 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 5675 expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull); | |
| 5676 _assertNoErrors(classA); | |
| 5677 _assertNoErrors(classB); | |
| 5678 } | |
| 5679 | |
| 5680 void test_lookupMember_getter() { | |
| 5681 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5682 String getterName = "g"; | |
| 5683 PropertyAccessorElement getterG = | |
| 5684 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 5685 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 5686 expect(_inheritanceManager.lookupMember(classA, getterName), same(getterG)); | |
| 5687 _assertNoErrors(classA); | |
| 5688 } | |
| 5689 | |
| 5690 void test_lookupMember_getter_static() { | |
| 5691 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5692 String getterName = "g"; | |
| 5693 PropertyAccessorElement getterG = | |
| 5694 ElementFactory.getterElement(getterName, true, _typeProvider.intType); | |
| 5695 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 5696 expect(_inheritanceManager.lookupMember(classA, getterName), isNull); | |
| 5697 _assertNoErrors(classA); | |
| 5698 } | |
| 5699 | |
| 5700 void test_lookupMember_method() { | |
| 5701 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5702 String methodName = "m"; | |
| 5703 MethodElement methodM = | |
| 5704 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5705 classA.methods = <MethodElement>[methodM]; | |
| 5706 expect(_inheritanceManager.lookupMember(classA, methodName), same(methodM)); | |
| 5707 _assertNoErrors(classA); | |
| 5708 } | |
| 5709 | |
| 5710 void test_lookupMember_method_static() { | |
| 5711 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5712 String methodName = "m"; | |
| 5713 MethodElement methodM = | |
| 5714 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5715 (methodM as MethodElementImpl).static = true; | |
| 5716 classA.methods = <MethodElement>[methodM]; | |
| 5717 expect(_inheritanceManager.lookupMember(classA, methodName), isNull); | |
| 5718 _assertNoErrors(classA); | |
| 5719 } | |
| 5720 | |
| 5721 void test_lookupMember_noMember() { | |
| 5722 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5723 expect(_inheritanceManager.lookupMember(classA, "a"), isNull); | |
| 5724 _assertNoErrors(classA); | |
| 5725 } | |
| 5726 | |
| 5727 void test_lookupMember_setter() { | |
| 5728 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5729 String setterName = "s"; | |
| 5730 PropertyAccessorElement setterS = | |
| 5731 ElementFactory.setterElement(setterName, false, _typeProvider.intType); | |
| 5732 classA.accessors = <PropertyAccessorElement>[setterS]; | |
| 5733 expect(_inheritanceManager.lookupMember(classA, "$setterName="), | |
| 5734 same(setterS)); | |
| 5735 _assertNoErrors(classA); | |
| 5736 } | |
| 5737 | |
| 5738 void test_lookupMember_setter_static() { | |
| 5739 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5740 String setterName = "s"; | |
| 5741 PropertyAccessorElement setterS = | |
| 5742 ElementFactory.setterElement(setterName, true, _typeProvider.intType); | |
| 5743 classA.accessors = <PropertyAccessorElement>[setterS]; | |
| 5744 expect(_inheritanceManager.lookupMember(classA, setterName), isNull); | |
| 5745 _assertNoErrors(classA); | |
| 5746 } | |
| 5747 | |
| 5748 void test_lookupOverrides_noParentClasses() { | |
| 5749 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5750 String methodName = "m"; | |
| 5751 MethodElementImpl methodM = | |
| 5752 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5753 classA.methods = <MethodElement>[methodM]; | |
| 5754 expect( | |
| 5755 _inheritanceManager.lookupOverrides(classA, methodName), hasLength(0)); | |
| 5756 _assertNoErrors(classA); | |
| 5757 } | |
| 5758 | |
| 5759 void test_lookupOverrides_overrideBaseClass() { | |
| 5760 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5761 String methodName = "m"; | |
| 5762 MethodElementImpl methodMinA = | |
| 5763 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5764 classA.methods = <MethodElement>[methodMinA]; | |
| 5765 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 5766 MethodElementImpl methodMinB = | |
| 5767 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5768 classB.methods = <MethodElement>[methodMinB]; | |
| 5769 List<ExecutableElement> overrides = | |
| 5770 _inheritanceManager.lookupOverrides(classB, methodName); | |
| 5771 expect(overrides, unorderedEquals([methodMinA])); | |
| 5772 _assertNoErrors(classA); | |
| 5773 _assertNoErrors(classB); | |
| 5774 } | |
| 5775 | |
| 5776 void test_lookupOverrides_overrideInterface() { | |
| 5777 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5778 String methodName = "m"; | |
| 5779 MethodElementImpl methodMinA = | |
| 5780 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5781 classA.methods = <MethodElement>[methodMinA]; | |
| 5782 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5783 classB.interfaces = <InterfaceType>[classA.type]; | |
| 5784 MethodElementImpl methodMinB = | |
| 5785 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5786 classB.methods = <MethodElement>[methodMinB]; | |
| 5787 List<ExecutableElement> overrides = | |
| 5788 _inheritanceManager.lookupOverrides(classB, methodName); | |
| 5789 expect(overrides, unorderedEquals([methodMinA])); | |
| 5790 _assertNoErrors(classA); | |
| 5791 _assertNoErrors(classB); | |
| 5792 } | |
| 5793 | |
| 5794 void test_lookupOverrides_overrideTwoInterfaces() { | |
| 5795 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5796 String methodName = "m"; | |
| 5797 MethodElementImpl methodMinA = | |
| 5798 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5799 classA.methods = <MethodElement>[methodMinA]; | |
| 5800 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5801 MethodElementImpl methodMinB = | |
| 5802 ElementFactory.methodElement(methodName, _typeProvider.doubleType); | |
| 5803 classB.methods = <MethodElement>[methodMinB]; | |
| 5804 ClassElementImpl classC = ElementFactory.classElement2("C"); | |
| 5805 classC.interfaces = <InterfaceType>[classA.type, classB.type]; | |
| 5806 MethodElementImpl methodMinC = | |
| 5807 ElementFactory.methodElement(methodName, _typeProvider.numType); | |
| 5808 classC.methods = <MethodElement>[methodMinC]; | |
| 5809 List<ExecutableElement> overrides = | |
| 5810 _inheritanceManager.lookupOverrides(classC, methodName); | |
| 5811 expect(overrides, unorderedEquals([methodMinA, methodMinB])); | |
| 5812 _assertNoErrors(classA); | |
| 5813 _assertNoErrors(classB); | |
| 5814 _assertNoErrors(classC); | |
| 5815 } | |
| 5816 | |
| 5817 void _assertErrors(ClassElement classElt, | |
| 5818 [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) { | |
| 5819 GatheringErrorListener errorListener = new GatheringErrorListener(); | |
| 5820 HashSet<AnalysisError> actualErrors = | |
| 5821 _inheritanceManager.getErrors(classElt); | |
| 5822 if (actualErrors != null) { | |
| 5823 for (AnalysisError error in actualErrors) { | |
| 5824 errorListener.onError(error); | |
| 5825 } | |
| 5826 } | |
| 5827 errorListener.assertErrorsWithCodes(expectedErrorCodes); | |
| 5828 } | |
| 5829 | |
| 5830 void _assertNoErrors(ClassElement classElt) { | |
| 5831 _assertErrors(classElt); | |
| 5832 } | |
| 5833 | |
| 5834 /** | |
| 5835 * Create the inheritance manager used by the tests. | |
| 5836 * | |
| 5837 * @return the inheritance manager that was created | |
| 5838 */ | |
| 5839 InheritanceManager _createInheritanceManager() { | |
| 5840 AnalysisContext context = AnalysisContextFactory.contextWithCore(); | |
| 5841 FileBasedSource source = | |
| 5842 new FileBasedSource(FileUtilities2.createFile("/test.dart")); | |
| 5843 CompilationUnitElementImpl definingCompilationUnit = | |
| 5844 new CompilationUnitElementImpl("test.dart"); | |
| 5845 definingCompilationUnit.librarySource = | |
| 5846 definingCompilationUnit.source = source; | |
| 5847 _definingLibrary = ElementFactory.library(context, "test"); | |
| 5848 _definingLibrary.definingCompilationUnit = definingCompilationUnit; | |
| 5849 return new InheritanceManager(_definingLibrary); | |
| 5850 } | |
| 5851 } | |
| 5852 | |
| 5853 @reflectiveTest | |
| 5854 class LibraryElementBuilderTest extends EngineTestCase { | |
| 5855 /** | |
| 5856 * The analysis context used to analyze sources. | |
| 5857 */ | |
| 5858 InternalAnalysisContext _context; | |
| 5859 | |
| 5860 /** | |
| 5861 * Add a source file to the content provider. The file path should be absolute
. | |
| 5862 * | |
| 5863 * @param filePath the path of the file being added | |
| 5864 * @param contents the contents to be returned by the content provider for the
specified file | |
| 5865 * @return the source object representing the added file | |
| 5866 */ | |
| 5867 Source addSource(String filePath, String contents) { | |
| 5868 Source source = new FileBasedSource(FileUtilities2.createFile(filePath)); | |
| 5869 _context.setContents(source, contents); | |
| 5870 return source; | |
| 5871 } | |
| 5872 | |
| 5873 @override | |
| 5874 void setUp() { | |
| 5875 _context = AnalysisContextFactory.contextWithCore(); | |
| 5876 } | |
| 5877 | |
| 5878 @override | |
| 5879 void tearDown() { | |
| 5880 _context = null; | |
| 5881 super.tearDown(); | |
| 5882 } | |
| 5883 | |
| 5884 void test_accessorsAcrossFiles() { | |
| 5885 Source librarySource = addSource( | |
| 5886 "/lib.dart", | |
| 5887 r''' | |
| 5888 library lib; | |
| 5889 part 'first.dart'; | |
| 5890 part 'second.dart';'''); | |
| 5891 addSource( | |
| 5892 "/first.dart", | |
| 5893 r''' | |
| 5894 part of lib; | |
| 5895 int get V => 0;'''); | |
| 5896 addSource( | |
| 5897 "/second.dart", | |
| 5898 r''' | |
| 5899 part of lib; | |
| 5900 void set V(int v) {}'''); | |
| 5901 LibraryElement element = _buildLibrary(librarySource); | |
| 5902 expect(element, isNotNull); | |
| 5903 List<CompilationUnitElement> sourcedUnits = element.parts; | |
| 5904 expect(sourcedUnits, hasLength(2)); | |
| 5905 List<PropertyAccessorElement> firstAccessors = sourcedUnits[0].accessors; | |
| 5906 expect(firstAccessors, hasLength(1)); | |
| 5907 List<PropertyAccessorElement> secondAccessors = sourcedUnits[1].accessors; | |
| 5908 expect(secondAccessors, hasLength(1)); | |
| 5909 expect(secondAccessors[0].variable, same(firstAccessors[0].variable)); | |
| 5910 } | |
| 5911 | |
| 5912 void test_empty() { | |
| 5913 Source librarySource = addSource("/lib.dart", "library lib;"); | |
| 5914 LibraryElement element = _buildLibrary(librarySource); | |
| 5915 expect(element, isNotNull); | |
| 5916 expect(element.name, "lib"); | |
| 5917 expect(element.entryPoint, isNull); | |
| 5918 expect(element.importedLibraries, hasLength(0)); | |
| 5919 expect(element.imports, hasLength(0)); | |
| 5920 expect(element.library, same(element)); | |
| 5921 expect(element.prefixes, hasLength(0)); | |
| 5922 expect(element.parts, hasLength(0)); | |
| 5923 CompilationUnitElement unit = element.definingCompilationUnit; | |
| 5924 expect(unit, isNotNull); | |
| 5925 expect(unit.name, "lib.dart"); | |
| 5926 expect(unit.library, element); | |
| 5927 expect(unit.accessors, hasLength(0)); | |
| 5928 expect(unit.functions, hasLength(0)); | |
| 5929 expect(unit.functionTypeAliases, hasLength(0)); | |
| 5930 expect(unit.types, hasLength(0)); | |
| 5931 expect(unit.topLevelVariables, hasLength(0)); | |
| 5932 } | |
| 5933 | |
| 5934 void test_libraryElement_docRange() { | |
| 5935 String code = r''' | |
| 5936 /// My dart doc. | |
| 5937 library lib; | |
| 5938 | |
| 5939 class A {}'''; | |
| 5940 Source librarySource = addSource("/lib.dart", code); | |
| 5941 LibraryElement element = _buildLibrary(librarySource); | |
| 5942 expect(element, isNotNull); | |
| 5943 SourceRange docRange = element.docRange; | |
| 5944 expect(docRange, isNotNull); | |
| 5945 expect(docRange.offset, code.indexOf('/// My dart doc.')); | |
| 5946 expect(docRange.length, '/// My dart doc.'.length); | |
| 5947 } | |
| 5948 | |
| 5949 void test_missingLibraryDirectiveWithPart() { | |
| 5950 addSource("/a.dart", "part of lib;"); | |
| 5951 Source librarySource = addSource("/lib.dart", "part 'a.dart';"); | |
| 5952 LibraryElement element = _buildLibrary( | |
| 5953 librarySource, [ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART]); | |
| 5954 expect(element, isNotNull); | |
| 5955 } | |
| 5956 | |
| 5957 void test_missingPartOfDirective() { | |
| 5958 addSource("/a.dart", "class A {}"); | |
| 5959 Source librarySource = addSource( | |
| 5960 "/lib.dart", | |
| 5961 r''' | |
| 5962 library lib; | |
| 5963 | |
| 5964 part 'a.dart';'''); | |
| 5965 LibraryElement element = | |
| 5966 _buildLibrary(librarySource, [CompileTimeErrorCode.PART_OF_NON_PART]); | |
| 5967 expect(element, isNotNull); | |
| 5968 } | |
| 5969 | |
| 5970 void test_multipleFiles() { | |
| 5971 Source librarySource = addSource( | |
| 5972 "/lib.dart", | |
| 5973 r''' | |
| 5974 library lib; | |
| 5975 part 'first.dart'; | |
| 5976 part 'second.dart'; | |
| 5977 | |
| 5978 class A {}'''); | |
| 5979 addSource( | |
| 5980 "/first.dart", | |
| 5981 r''' | |
| 5982 part of lib; | |
| 5983 class B {}'''); | |
| 5984 addSource( | |
| 5985 "/second.dart", | |
| 5986 r''' | |
| 5987 part of lib; | |
| 5988 class C {}'''); | |
| 5989 LibraryElement element = _buildLibrary(librarySource); | |
| 5990 expect(element, isNotNull); | |
| 5991 List<CompilationUnitElement> sourcedUnits = element.parts; | |
| 5992 expect(sourcedUnits, hasLength(2)); | |
| 5993 _assertTypes(element.definingCompilationUnit, ["A"]); | |
| 5994 if (sourcedUnits[0].name == "first.dart") { | |
| 5995 _assertTypes(sourcedUnits[0], ["B"]); | |
| 5996 _assertTypes(sourcedUnits[1], ["C"]); | |
| 5997 } else { | |
| 5998 _assertTypes(sourcedUnits[0], ["C"]); | |
| 5999 _assertTypes(sourcedUnits[1], ["B"]); | |
| 6000 } | |
| 6001 } | |
| 6002 | |
| 6003 void test_singleFile() { | |
| 6004 Source librarySource = addSource( | |
| 6005 "/lib.dart", | |
| 6006 r''' | |
| 6007 /// My dart doc. | |
| 6008 library lib; | |
| 6009 | |
| 6010 class A {}'''); | |
| 6011 LibraryElement element = _buildLibrary(librarySource); | |
| 6012 expect(element, isNotNull); | |
| 6013 _assertTypes(element.definingCompilationUnit, ["A"]); | |
| 6014 } | |
| 6015 | |
| 6016 /** | |
| 6017 * Ensure that there are elements representing all of the types in the given a
rray of type names. | |
| 6018 * | |
| 6019 * @param unit the compilation unit containing the types | |
| 6020 * @param typeNames the names of the types that should be found | |
| 6021 */ | |
| 6022 void _assertTypes(CompilationUnitElement unit, List<String> typeNames) { | |
| 6023 expect(unit, isNotNull); | |
| 6024 List<ClassElement> types = unit.types; | |
| 6025 expect(types, hasLength(typeNames.length)); | |
| 6026 for (ClassElement type in types) { | |
| 6027 expect(type, isNotNull); | |
| 6028 String actualTypeName = type.displayName; | |
| 6029 bool wasExpected = false; | |
| 6030 for (String expectedTypeName in typeNames) { | |
| 6031 if (expectedTypeName == actualTypeName) { | |
| 6032 wasExpected = true; | |
| 6033 } | |
| 6034 } | |
| 6035 if (!wasExpected) { | |
| 6036 fail("Found unexpected type $actualTypeName"); | |
| 6037 } | |
| 6038 } | |
| 6039 } | |
| 6040 | |
| 6041 /** | |
| 6042 * Build the element model for the library whose defining compilation unit has
the given source. | |
| 6043 * | |
| 6044 * @param librarySource the source of the defining compilation unit for the li
brary | |
| 6045 * @param expectedErrorCodes the errors that are expected to be found while bu
ilding the element | |
| 6046 * model | |
| 6047 * @return the element model that was built for the library | |
| 6048 * @throws Exception if the element model could not be built | |
| 6049 */ | |
| 6050 LibraryElement _buildLibrary(Source librarySource, | |
| 6051 [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) { | |
| 6052 LibraryResolver resolver = new LibraryResolver(_context); | |
| 6053 LibraryElementBuilder builder = new LibraryElementBuilder( | |
| 6054 resolver.analysisContext, resolver.errorListener); | |
| 6055 Library library = resolver.createLibrary(librarySource); | |
| 6056 LibraryElement element = builder.buildLibrary(library); | |
| 6057 GatheringErrorListener listener = new GatheringErrorListener(); | |
| 6058 listener.addAll2(resolver.errorListener); | |
| 6059 listener.assertErrorsWithCodes(expectedErrorCodes); | |
| 6060 return element; | |
| 6061 } | 253 } |
| 6062 } | 254 } |
| 6063 | 255 |
| 6064 @reflectiveTest | 256 @reflectiveTest |
| 6065 class LibraryImportScopeTest extends ResolverTestCase { | 257 class LibraryImportScopeTest extends ResolverTestCase { |
| 6066 void test_conflictingImports() { | |
| 6067 AnalysisContext context = AnalysisContextFactory.contextWithCore(); | |
| 6068 String typeNameA = "A"; | |
| 6069 String typeNameB = "B"; | |
| 6070 String typeNameC = "C"; | |
| 6071 ClassElement typeA = ElementFactory.classElement2(typeNameA); | |
| 6072 ClassElement typeB1 = ElementFactory.classElement2(typeNameB); | |
| 6073 ClassElement typeB2 = ElementFactory.classElement2(typeNameB); | |
| 6074 ClassElement typeC = ElementFactory.classElement2(typeNameC); | |
| 6075 LibraryElement importedLibrary1 = createTestLibrary(context, "imported1"); | |
| 6076 (importedLibrary1.definingCompilationUnit as CompilationUnitElementImpl) | |
| 6077 .types = <ClassElement>[typeA, typeB1]; | |
| 6078 ImportElementImpl import1 = | |
| 6079 ElementFactory.importFor(importedLibrary1, null); | |
| 6080 LibraryElement importedLibrary2 = createTestLibrary(context, "imported2"); | |
| 6081 (importedLibrary2.definingCompilationUnit as CompilationUnitElementImpl) | |
| 6082 .types = <ClassElement>[typeB2, typeC]; | |
| 6083 ImportElementImpl import2 = | |
| 6084 ElementFactory.importFor(importedLibrary2, null); | |
| 6085 LibraryElementImpl importingLibrary = | |
| 6086 createTestLibrary(context, "importing"); | |
| 6087 importingLibrary.imports = <ImportElement>[import1, import2]; | |
| 6088 { | |
| 6089 GatheringErrorListener errorListener = new GatheringErrorListener(); | |
| 6090 Scope scope = new LibraryImportScope(importingLibrary, errorListener); | |
| 6091 expect(scope.lookup(AstFactory.identifier3(typeNameA), importingLibrary), | |
| 6092 typeA); | |
| 6093 errorListener.assertNoErrors(); | |
| 6094 expect(scope.lookup(AstFactory.identifier3(typeNameC), importingLibrary), | |
| 6095 typeC); | |
| 6096 errorListener.assertNoErrors(); | |
| 6097 Element element = | |
| 6098 scope.lookup(AstFactory.identifier3(typeNameB), importingLibrary); | |
| 6099 errorListener.assertErrorsWithCodes([StaticWarningCode.AMBIGUOUS_IMPORT]); | |
| 6100 EngineTestCase.assertInstanceOf((obj) => obj is MultiplyDefinedElement, | |
| 6101 MultiplyDefinedElement, element); | |
| 6102 List<Element> conflictingElements = | |
| 6103 (element as MultiplyDefinedElement).conflictingElements; | |
| 6104 expect(conflictingElements, hasLength(2)); | |
| 6105 if (identical(conflictingElements[0], typeB1)) { | |
| 6106 expect(conflictingElements[1], same(typeB2)); | |
| 6107 } else if (identical(conflictingElements[0], typeB2)) { | |
| 6108 expect(conflictingElements[1], same(typeB1)); | |
| 6109 } else { | |
| 6110 expect(conflictingElements[0], same(typeB1)); | |
| 6111 } | |
| 6112 } | |
| 6113 { | |
| 6114 GatheringErrorListener errorListener = new GatheringErrorListener(); | |
| 6115 Scope scope = new LibraryImportScope(importingLibrary, errorListener); | |
| 6116 Identifier identifier = AstFactory.identifier3(typeNameB); | |
| 6117 AstFactory.methodDeclaration(null, AstFactory.typeName3(identifier), null, | |
| 6118 null, AstFactory.identifier3("foo"), null); | |
| 6119 Element element = scope.lookup(identifier, importingLibrary); | |
| 6120 errorListener.assertErrorsWithCodes([StaticWarningCode.AMBIGUOUS_IMPORT]); | |
| 6121 EngineTestCase.assertInstanceOf((obj) => obj is MultiplyDefinedElement, | |
| 6122 MultiplyDefinedElement, element); | |
| 6123 } | |
| 6124 } | |
| 6125 | |
| 6126 void test_creation_empty() { | 258 void test_creation_empty() { |
| 6127 LibraryElement definingLibrary = createDefaultTestLibrary(); | 259 new LibraryImportScope(createDefaultTestLibrary()); |
| 6128 GatheringErrorListener errorListener = new GatheringErrorListener(); | |
| 6129 new LibraryImportScope(definingLibrary, errorListener); | |
| 6130 } | 260 } |
| 6131 | 261 |
| 6132 void test_creation_nonEmpty() { | 262 void test_creation_nonEmpty() { |
| 6133 AnalysisContext context = AnalysisContextFactory.contextWithCore(); | 263 AnalysisContext context = AnalysisContextFactory.contextWithCore(); |
| 6134 String importedTypeName = "A"; | 264 String importedTypeName = "A"; |
| 6135 ClassElement importedType = | 265 ClassElement importedType = |
| 6136 new ClassElementImpl.forNode(AstFactory.identifier3(importedTypeName)); | 266 new ClassElementImpl.forNode(AstFactory.identifier3(importedTypeName)); |
| 6137 LibraryElement importedLibrary = createTestLibrary(context, "imported"); | 267 LibraryElement importedLibrary = createTestLibrary(context, "imported"); |
| 6138 (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl) | 268 (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl) |
| 6139 .types = <ClassElement>[importedType]; | 269 .types = <ClassElement>[importedType]; |
| 6140 LibraryElementImpl definingLibrary = | 270 LibraryElementImpl definingLibrary = |
| 6141 createTestLibrary(context, "importing"); | 271 createTestLibrary(context, "importing"); |
| 6142 ImportElementImpl importElement = new ImportElementImpl(0); | 272 ImportElementImpl importElement = new ImportElementImpl(0); |
| 6143 importElement.importedLibrary = importedLibrary; | 273 importElement.importedLibrary = importedLibrary; |
| 6144 definingLibrary.imports = <ImportElement>[importElement]; | 274 definingLibrary.imports = <ImportElement>[importElement]; |
| 6145 GatheringErrorListener errorListener = new GatheringErrorListener(); | 275 Scope scope = new LibraryImportScope(definingLibrary); |
| 6146 Scope scope = new LibraryImportScope(definingLibrary, errorListener); | |
| 6147 expect( | 276 expect( |
| 6148 scope.lookup(AstFactory.identifier3(importedTypeName), definingLibrary), | 277 scope.lookup(AstFactory.identifier3(importedTypeName), definingLibrary), |
| 6149 importedType); | 278 importedType); |
| 6150 } | 279 } |
| 6151 | 280 |
| 6152 void test_getErrorListener() { | |
| 6153 LibraryElement definingLibrary = createDefaultTestLibrary(); | |
| 6154 GatheringErrorListener errorListener = new GatheringErrorListener(); | |
| 6155 LibraryImportScope scope = | |
| 6156 new LibraryImportScope(definingLibrary, errorListener); | |
| 6157 expect(scope.errorListener, errorListener); | |
| 6158 } | |
| 6159 | |
| 6160 void test_nonConflictingImports_fromSdk() { | |
| 6161 AnalysisContext context = AnalysisContextFactory.contextWithCore(); | |
| 6162 String typeName = "List"; | |
| 6163 ClassElement type = ElementFactory.classElement2(typeName); | |
| 6164 LibraryElement importedLibrary = createTestLibrary(context, "lib"); | |
| 6165 (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl) | |
| 6166 .types = <ClassElement>[type]; | |
| 6167 ImportElementImpl importCore = ElementFactory.importFor( | |
| 6168 context.getLibraryElement(context.sourceFactory.forUri("dart:core")), | |
| 6169 null); | |
| 6170 ImportElementImpl importLib = | |
| 6171 ElementFactory.importFor(importedLibrary, null); | |
| 6172 LibraryElementImpl importingLibrary = | |
| 6173 createTestLibrary(context, "importing"); | |
| 6174 importingLibrary.imports = <ImportElement>[importCore, importLib]; | |
| 6175 GatheringErrorListener errorListener = new GatheringErrorListener(); | |
| 6176 Scope scope = new LibraryImportScope(importingLibrary, errorListener); | |
| 6177 expect( | |
| 6178 scope.lookup(AstFactory.identifier3(typeName), importingLibrary), type); | |
| 6179 errorListener | |
| 6180 .assertErrorsWithCodes([StaticWarningCode.CONFLICTING_DART_IMPORT]); | |
| 6181 } | |
| 6182 | |
| 6183 void test_nonConflictingImports_sameElement() { | |
| 6184 AnalysisContext context = AnalysisContextFactory.contextWithCore(); | |
| 6185 String typeNameA = "A"; | |
| 6186 String typeNameB = "B"; | |
| 6187 ClassElement typeA = ElementFactory.classElement2(typeNameA); | |
| 6188 ClassElement typeB = ElementFactory.classElement2(typeNameB); | |
| 6189 LibraryElement importedLibrary = createTestLibrary(context, "imported"); | |
| 6190 (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl) | |
| 6191 .types = <ClassElement>[typeA, typeB]; | |
| 6192 ImportElementImpl import1 = ElementFactory.importFor(importedLibrary, null); | |
| 6193 ImportElementImpl import2 = ElementFactory.importFor(importedLibrary, null); | |
| 6194 LibraryElementImpl importingLibrary = | |
| 6195 createTestLibrary(context, "importing"); | |
| 6196 importingLibrary.imports = <ImportElement>[import1, import2]; | |
| 6197 GatheringErrorListener errorListener = new GatheringErrorListener(); | |
| 6198 Scope scope = new LibraryImportScope(importingLibrary, errorListener); | |
| 6199 expect(scope.lookup(AstFactory.identifier3(typeNameA), importingLibrary), | |
| 6200 typeA); | |
| 6201 errorListener.assertNoErrors(); | |
| 6202 expect(scope.lookup(AstFactory.identifier3(typeNameB), importingLibrary), | |
| 6203 typeB); | |
| 6204 errorListener.assertNoErrors(); | |
| 6205 } | |
| 6206 | |
| 6207 void test_prefixedAndNonPrefixed() { | 281 void test_prefixedAndNonPrefixed() { |
| 6208 AnalysisContext context = AnalysisContextFactory.contextWithCore(); | 282 AnalysisContext context = AnalysisContextFactory.contextWithCore(); |
| 6209 String typeName = "C"; | 283 String typeName = "C"; |
| 6210 String prefixName = "p"; | 284 String prefixName = "p"; |
| 6211 ClassElement prefixedType = ElementFactory.classElement2(typeName); | 285 ClassElement prefixedType = ElementFactory.classElement2(typeName); |
| 6212 ClassElement nonPrefixedType = ElementFactory.classElement2(typeName); | 286 ClassElement nonPrefixedType = ElementFactory.classElement2(typeName); |
| 6213 LibraryElement prefixedLibrary = | 287 LibraryElement prefixedLibrary = |
| 6214 createTestLibrary(context, "import.prefixed"); | 288 createTestLibrary(context, "import.prefixed"); |
| 6215 (prefixedLibrary.definingCompilationUnit as CompilationUnitElementImpl) | 289 (prefixedLibrary.definingCompilationUnit as CompilationUnitElementImpl) |
| 6216 .types = <ClassElement>[prefixedType]; | 290 .types = <ClassElement>[prefixedType]; |
| 6217 ImportElementImpl prefixedImport = ElementFactory.importFor( | 291 ImportElementImpl prefixedImport = ElementFactory.importFor( |
| 6218 prefixedLibrary, ElementFactory.prefix(prefixName)); | 292 prefixedLibrary, ElementFactory.prefix(prefixName)); |
| 6219 LibraryElement nonPrefixedLibrary = | 293 LibraryElement nonPrefixedLibrary = |
| 6220 createTestLibrary(context, "import.nonPrefixed"); | 294 createTestLibrary(context, "import.nonPrefixed"); |
| 6221 (nonPrefixedLibrary.definingCompilationUnit as CompilationUnitElementImpl) | 295 (nonPrefixedLibrary.definingCompilationUnit as CompilationUnitElementImpl) |
| 6222 .types = <ClassElement>[nonPrefixedType]; | 296 .types = <ClassElement>[nonPrefixedType]; |
| 6223 ImportElementImpl nonPrefixedImport = | 297 ImportElementImpl nonPrefixedImport = |
| 6224 ElementFactory.importFor(nonPrefixedLibrary, null); | 298 ElementFactory.importFor(nonPrefixedLibrary, null); |
| 6225 LibraryElementImpl importingLibrary = | 299 LibraryElementImpl importingLibrary = |
| 6226 createTestLibrary(context, "importing"); | 300 createTestLibrary(context, "importing"); |
| 6227 importingLibrary.imports = <ImportElement>[ | 301 importingLibrary.imports = <ImportElement>[ |
| 6228 prefixedImport, | 302 prefixedImport, |
| 6229 nonPrefixedImport | 303 nonPrefixedImport |
| 6230 ]; | 304 ]; |
| 6231 GatheringErrorListener errorListener = new GatheringErrorListener(); | 305 Scope scope = new LibraryImportScope(importingLibrary); |
| 6232 Scope scope = new LibraryImportScope(importingLibrary, errorListener); | |
| 6233 Element prefixedElement = scope.lookup( | 306 Element prefixedElement = scope.lookup( |
| 6234 AstFactory.identifier5(prefixName, typeName), importingLibrary); | 307 AstFactory.identifier5(prefixName, typeName), importingLibrary); |
| 6235 errorListener.assertNoErrors(); | |
| 6236 expect(prefixedElement, same(prefixedType)); | 308 expect(prefixedElement, same(prefixedType)); |
| 6237 Element nonPrefixedElement = | 309 Element nonPrefixedElement = |
| 6238 scope.lookup(AstFactory.identifier3(typeName), importingLibrary); | 310 scope.lookup(AstFactory.identifier3(typeName), importingLibrary); |
| 6239 errorListener.assertNoErrors(); | |
| 6240 expect(nonPrefixedElement, same(nonPrefixedType)); | 311 expect(nonPrefixedElement, same(nonPrefixedType)); |
| 6241 } | 312 } |
| 6242 } | 313 } |
| 6243 | 314 |
| 6244 @reflectiveTest | 315 @reflectiveTest |
| 6245 class LibraryResolver2Test extends ResolverTestCase { | |
| 6246 LibraryResolver2 _resolver; | |
| 6247 | |
| 6248 Source _coreLibrarySource; | |
| 6249 | |
| 6250 Source _asyncLibrarySource; | |
| 6251 | |
| 6252 @override | |
| 6253 void setUp() { | |
| 6254 super.setUp(); | |
| 6255 _resolver = new LibraryResolver2(analysisContext2); | |
| 6256 _coreLibrarySource = | |
| 6257 analysisContext2.sourceFactory.forUri(DartSdk.DART_CORE); | |
| 6258 _asyncLibrarySource = | |
| 6259 analysisContext2.sourceFactory.forUri(DartSdk.DART_ASYNC); | |
| 6260 } | |
| 6261 | |
| 6262 void test_imports_relative() { | |
| 6263 Source sourceA = addSource(r''' | |
| 6264 library libA; | |
| 6265 import 'libB.dart'; | |
| 6266 class A {}'''); | |
| 6267 Source sourceB = addNamedSource( | |
| 6268 "/libB.dart", | |
| 6269 r''' | |
| 6270 library libB; | |
| 6271 import 'test.dart | |
| 6272 class B {}'''); | |
| 6273 List<ResolvableLibrary> cycle = new List<ResolvableLibrary>(); | |
| 6274 ResolvableLibrary coreLib = _createResolvableLibrary(_coreLibrarySource); | |
| 6275 coreLib.libraryElement = analysisContext2 | |
| 6276 .computeLibraryElement(_coreLibrarySource) as LibraryElementImpl; | |
| 6277 ResolvableLibrary asyncLib = _createResolvableLibrary(_asyncLibrarySource); | |
| 6278 asyncLib.libraryElement = analysisContext2 | |
| 6279 .computeLibraryElement(_asyncLibrarySource) as LibraryElementImpl; | |
| 6280 ResolvableLibrary libA = _createResolvableLibrary(sourceA); | |
| 6281 ResolvableLibrary libB = _createResolvableLibrary(sourceB); | |
| 6282 libA.importedLibraries = <ResolvableLibrary>[coreLib, asyncLib, libB]; | |
| 6283 libB.importedLibraries = <ResolvableLibrary>[coreLib, asyncLib, libA]; | |
| 6284 cycle.add(libA); | |
| 6285 cycle.add(libB); | |
| 6286 LibraryElement library = _resolver.resolveLibrary(sourceA, cycle); | |
| 6287 List<LibraryElement> importedLibraries = library.importedLibraries; | |
| 6288 assertNamedElements(importedLibraries, ["dart.core", "libB"]); | |
| 6289 } | |
| 6290 | |
| 6291 ResolvableLibrary _createResolvableLibrary(Source source) { | |
| 6292 CompilationUnit unit = analysisContext2.parseCompilationUnit(source); | |
| 6293 ResolvableLibrary resolvableLibrary = new ResolvableLibrary(source); | |
| 6294 resolvableLibrary.resolvableCompilationUnits = <ResolvableCompilationUnit>[ | |
| 6295 new ResolvableCompilationUnit(source, unit) | |
| 6296 ]; | |
| 6297 return resolvableLibrary; | |
| 6298 } | |
| 6299 } | |
| 6300 | |
| 6301 @reflectiveTest | |
| 6302 class LibraryResolverTest extends ResolverTestCase { | |
| 6303 LibraryResolver _resolver; | |
| 6304 | |
| 6305 @override | |
| 6306 void setUp() { | |
| 6307 super.setUp(); | |
| 6308 _resolver = new LibraryResolver(analysisContext2); | |
| 6309 } | |
| 6310 | |
| 6311 void test_imports_dart_html() { | |
| 6312 Source source = addSource(r''' | |
| 6313 library libA; | |
| 6314 import 'dart:html'; | |
| 6315 class A {}'''); | |
| 6316 LibraryElement library = _resolver.resolveLibrary(source, true); | |
| 6317 List<LibraryElement> importedLibraries = library.importedLibraries; | |
| 6318 assertNamedElements(importedLibraries, ["dart.core", "dart.dom.html"]); | |
| 6319 } | |
| 6320 | |
| 6321 void test_imports_none() { | |
| 6322 Source source = addSource(r''' | |
| 6323 library libA; | |
| 6324 class A {}'''); | |
| 6325 LibraryElement library = _resolver.resolveLibrary(source, true); | |
| 6326 List<LibraryElement> importedLibraries = library.importedLibraries; | |
| 6327 assertNamedElements(importedLibraries, ["dart.core"]); | |
| 6328 } | |
| 6329 | |
| 6330 void test_imports_relative() { | |
| 6331 addNamedSource("/libB.dart", "library libB;"); | |
| 6332 Source source = addSource(r''' | |
| 6333 library libA; | |
| 6334 import 'libB.dart'; | |
| 6335 class A {}'''); | |
| 6336 LibraryElement library = _resolver.resolveLibrary(source, true); | |
| 6337 List<LibraryElement> importedLibraries = library.importedLibraries; | |
| 6338 assertNamedElements(importedLibraries, ["dart.core", "libB"]); | |
| 6339 } | |
| 6340 } | |
| 6341 | |
| 6342 @reflectiveTest | |
| 6343 class LibraryScopeTest extends ResolverTestCase { | 316 class LibraryScopeTest extends ResolverTestCase { |
| 6344 void test_creation_empty() { | 317 void test_creation_empty() { |
| 6345 LibraryElement definingLibrary = createDefaultTestLibrary(); | 318 new LibraryScope(createDefaultTestLibrary()); |
| 6346 GatheringErrorListener errorListener = new GatheringErrorListener(); | |
| 6347 new LibraryScope(definingLibrary, errorListener); | |
| 6348 } | 319 } |
| 6349 | 320 |
| 6350 void test_creation_nonEmpty() { | 321 void test_creation_nonEmpty() { |
| 6351 AnalysisContext context = AnalysisContextFactory.contextWithCore(); | 322 AnalysisContext context = AnalysisContextFactory.contextWithCore(); |
| 6352 String importedTypeName = "A"; | 323 String importedTypeName = "A"; |
| 6353 ClassElement importedType = | 324 ClassElement importedType = |
| 6354 new ClassElementImpl.forNode(AstFactory.identifier3(importedTypeName)); | 325 new ClassElementImpl.forNode(AstFactory.identifier3(importedTypeName)); |
| 6355 LibraryElement importedLibrary = createTestLibrary(context, "imported"); | 326 LibraryElement importedLibrary = createTestLibrary(context, "imported"); |
| 6356 (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl) | 327 (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl) |
| 6357 .types = <ClassElement>[importedType]; | 328 .types = <ClassElement>[importedType]; |
| 6358 LibraryElementImpl definingLibrary = | 329 LibraryElementImpl definingLibrary = |
| 6359 createTestLibrary(context, "importing"); | 330 createTestLibrary(context, "importing"); |
| 6360 ImportElementImpl importElement = new ImportElementImpl(0); | 331 ImportElementImpl importElement = new ImportElementImpl(0); |
| 6361 importElement.importedLibrary = importedLibrary; | 332 importElement.importedLibrary = importedLibrary; |
| 6362 definingLibrary.imports = <ImportElement>[importElement]; | 333 definingLibrary.imports = <ImportElement>[importElement]; |
| 6363 GatheringErrorListener errorListener = new GatheringErrorListener(); | 334 Scope scope = new LibraryScope(definingLibrary); |
| 6364 Scope scope = new LibraryScope(definingLibrary, errorListener); | |
| 6365 expect( | 335 expect( |
| 6366 scope.lookup(AstFactory.identifier3(importedTypeName), definingLibrary), | 336 scope.lookup(AstFactory.identifier3(importedTypeName), definingLibrary), |
| 6367 importedType); | 337 importedType); |
| 6368 } | 338 } |
| 6369 | 339 } |
| 6370 void test_getErrorListener() { | 340 |
| 6371 LibraryElement definingLibrary = createDefaultTestLibrary(); | 341 @reflectiveTest |
| 6372 GatheringErrorListener errorListener = new GatheringErrorListener(); | 342 class PrefixedNamespaceTest extends ResolverTestCase { |
| 6373 LibraryScope scope = new LibraryScope(definingLibrary, errorListener); | 343 void test_lookup_missing() { |
| 6374 expect(scope.errorListener, errorListener); | 344 ClassElement element = ElementFactory.classElement2('A'); |
| 6375 } | 345 PrefixedNamespace namespace = new PrefixedNamespace('p', _toMap([element])); |
| 6376 } | 346 expect(namespace.get('p.B'), isNull); |
| 6377 | 347 } |
| 6378 @reflectiveTest | 348 |
| 6379 class LibraryTest extends EngineTestCase { | 349 void test_lookup_missing_matchesPrefix() { |
| 6380 /** | 350 ClassElement element = ElementFactory.classElement2('A'); |
| 6381 * The error listener to which all errors will be reported. | 351 PrefixedNamespace namespace = new PrefixedNamespace('p', _toMap([element])); |
| 6382 */ | 352 expect(namespace.get('p'), isNull); |
| 6383 GatheringErrorListener _errorListener; | 353 } |
| 6384 | 354 |
| 6385 /** | 355 void test_lookup_valid() { |
| 6386 * The analysis context to pass in to all libraries created by the tests. | 356 ClassElement element = ElementFactory.classElement2('A'); |
| 6387 */ | 357 PrefixedNamespace namespace = new PrefixedNamespace('p', _toMap([element])); |
| 6388 InternalAnalysisContext _analysisContext; | 358 expect(namespace.get('p.A'), same(element)); |
| 6389 | 359 } |
| 6390 /** | 360 |
| 6391 * The library used by the tests. | 361 HashMap<String, Element> _toMap(List<Element> elements) { |
| 6392 */ | 362 HashMap<String, Element> map = new HashMap<String, Element>(); |
| 6393 Library _library; | 363 for (Element element in elements) { |
| 6394 | 364 map[element.name] = element; |
| 6395 @override | |
| 6396 void setUp() { | |
| 6397 _analysisContext = AnalysisContextFactory.contextWithCore(); | |
| 6398 _errorListener = new GatheringErrorListener(); | |
| 6399 _library = _createLibrary("/lib.dart"); | |
| 6400 } | |
| 6401 | |
| 6402 @override | |
| 6403 void tearDown() { | |
| 6404 _errorListener = null; | |
| 6405 _analysisContext = null; | |
| 6406 _library = null; | |
| 6407 super.tearDown(); | |
| 6408 } | |
| 6409 | |
| 6410 void test_getExplicitlyImportsCore() { | |
| 6411 expect(_library.explicitlyImportsCore, isFalse); | |
| 6412 _errorListener.assertNoErrors(); | |
| 6413 } | |
| 6414 | |
| 6415 void test_getExports() { | |
| 6416 expect(_library.exports, hasLength(0)); | |
| 6417 _errorListener.assertNoErrors(); | |
| 6418 } | |
| 6419 | |
| 6420 void test_getImports() { | |
| 6421 expect(_library.imports, hasLength(0)); | |
| 6422 _errorListener.assertNoErrors(); | |
| 6423 } | |
| 6424 | |
| 6425 void test_getImportsAndExports() { | |
| 6426 _library.importedLibraries = <Library>[_createLibrary("/imported.dart")]; | |
| 6427 _library.exportedLibraries = <Library>[_createLibrary("/exported.dart")]; | |
| 6428 expect(_library.importsAndExports, hasLength(2)); | |
| 6429 _errorListener.assertNoErrors(); | |
| 6430 } | |
| 6431 | |
| 6432 void test_getLibraryScope() { | |
| 6433 LibraryElementImpl element = new LibraryElementImpl.forNode( | |
| 6434 _analysisContext, AstFactory.libraryIdentifier2(["lib"])); | |
| 6435 element.definingCompilationUnit = | |
| 6436 new CompilationUnitElementImpl("lib.dart"); | |
| 6437 _library.libraryElement = element; | |
| 6438 expect(_library.libraryScope, isNotNull); | |
| 6439 _errorListener.assertNoErrors(); | |
| 6440 } | |
| 6441 | |
| 6442 void test_getLibrarySource() { | |
| 6443 expect(_library.librarySource, isNotNull); | |
| 6444 } | |
| 6445 | |
| 6446 void test_setExplicitlyImportsCore() { | |
| 6447 _library.explicitlyImportsCore = true; | |
| 6448 expect(_library.explicitlyImportsCore, isTrue); | |
| 6449 _errorListener.assertNoErrors(); | |
| 6450 } | |
| 6451 | |
| 6452 void test_setExportedLibraries() { | |
| 6453 Library exportLibrary = _createLibrary("/exported.dart"); | |
| 6454 _library.exportedLibraries = <Library>[exportLibrary]; | |
| 6455 List<Library> exports = _library.exports; | |
| 6456 expect(exports, hasLength(1)); | |
| 6457 expect(exports[0], same(exportLibrary)); | |
| 6458 _errorListener.assertNoErrors(); | |
| 6459 } | |
| 6460 | |
| 6461 void test_setImportedLibraries() { | |
| 6462 Library importLibrary = _createLibrary("/imported.dart"); | |
| 6463 _library.importedLibraries = <Library>[importLibrary]; | |
| 6464 List<Library> imports = _library.imports; | |
| 6465 expect(imports, hasLength(1)); | |
| 6466 expect(imports[0], same(importLibrary)); | |
| 6467 _errorListener.assertNoErrors(); | |
| 6468 } | |
| 6469 | |
| 6470 void test_setLibraryElement() { | |
| 6471 LibraryElementImpl element = new LibraryElementImpl.forNode( | |
| 6472 _analysisContext, AstFactory.libraryIdentifier2(["lib"])); | |
| 6473 _library.libraryElement = element; | |
| 6474 expect(_library.libraryElement, same(element)); | |
| 6475 } | |
| 6476 | |
| 6477 Library _createLibrary(String definingCompilationUnitPath) => new Library( | |
| 6478 _analysisContext, | |
| 6479 _errorListener, | |
| 6480 new FileBasedSource( | |
| 6481 FileUtilities2.createFile(definingCompilationUnitPath))); | |
| 6482 } | |
| 6483 | |
| 6484 @reflectiveTest | |
| 6485 class MemberMapTest { | |
| 6486 /** | |
| 6487 * The null type. | |
| 6488 */ | |
| 6489 InterfaceType _nullType; | |
| 6490 | |
| 6491 void setUp() { | |
| 6492 _nullType = new TestTypeProvider().nullType; | |
| 6493 } | |
| 6494 | |
| 6495 void test_MemberMap_copyConstructor() { | |
| 6496 MethodElement m1 = ElementFactory.methodElement("m1", _nullType); | |
| 6497 MethodElement m2 = ElementFactory.methodElement("m2", _nullType); | |
| 6498 MethodElement m3 = ElementFactory.methodElement("m3", _nullType); | |
| 6499 MemberMap map = new MemberMap(); | |
| 6500 map.put(m1.name, m1); | |
| 6501 map.put(m2.name, m2); | |
| 6502 map.put(m3.name, m3); | |
| 6503 MemberMap copy = new MemberMap.from(map); | |
| 6504 expect(copy.size, map.size); | |
| 6505 expect(copy.get(m1.name), m1); | |
| 6506 expect(copy.get(m2.name), m2); | |
| 6507 expect(copy.get(m3.name), m3); | |
| 6508 } | |
| 6509 | |
| 6510 void test_MemberMap_override() { | |
| 6511 MethodElement m1 = ElementFactory.methodElement("m", _nullType); | |
| 6512 MethodElement m2 = ElementFactory.methodElement("m", _nullType); | |
| 6513 MemberMap map = new MemberMap(); | |
| 6514 map.put(m1.name, m1); | |
| 6515 map.put(m2.name, m2); | |
| 6516 expect(map.size, 1); | |
| 6517 expect(map.get("m"), m2); | |
| 6518 } | |
| 6519 | |
| 6520 void test_MemberMap_put() { | |
| 6521 MethodElement m1 = ElementFactory.methodElement("m1", _nullType); | |
| 6522 MemberMap map = new MemberMap(); | |
| 6523 expect(map.size, 0); | |
| 6524 map.put(m1.name, m1); | |
| 6525 expect(map.size, 1); | |
| 6526 expect(map.get("m1"), m1); | |
| 6527 } | |
| 6528 } | |
| 6529 | |
| 6530 /** | |
| 6531 * An analysis context that has a fake SDK that is much smaller and faster for | |
| 6532 * testing purposes. | |
| 6533 */ | |
| 6534 class NewAnalysisContextForTests extends newContext.AnalysisContextImpl { | |
| 6535 @override | |
| 6536 void set analysisOptions(AnalysisOptions options) { | |
| 6537 AnalysisOptions currentOptions = analysisOptions; | |
| 6538 bool needsRecompute = currentOptions.analyzeFunctionBodiesPredicate != | |
| 6539 options.analyzeFunctionBodiesPredicate || | |
| 6540 currentOptions.generateImplicitErrors != | |
| 6541 options.generateImplicitErrors || | |
| 6542 currentOptions.generateSdkErrors != options.generateSdkErrors || | |
| 6543 currentOptions.dart2jsHint != options.dart2jsHint || | |
| 6544 (currentOptions.hint && !options.hint) || | |
| 6545 currentOptions.preserveComments != options.preserveComments || | |
| 6546 currentOptions.enableStrictCallChecks != options.enableStrictCallChecks; | |
| 6547 if (needsRecompute) { | |
| 6548 fail( | |
| 6549 "Cannot set options that cause the sources to be reanalyzed in a test
context"); | |
| 6550 } | 365 } |
| 6551 super.analysisOptions = options; | 366 return map; |
| 6552 } | 367 } |
| 6553 | |
| 6554 @override | |
| 6555 bool exists(Source source) => | |
| 6556 super.exists(source) || sourceFactory.dartSdk.context.exists(source); | |
| 6557 | |
| 6558 @override | |
| 6559 TimestampedData<String> getContents(Source source) { | |
| 6560 if (source.isInSystemLibrary) { | |
| 6561 return sourceFactory.dartSdk.context.getContents(source); | |
| 6562 } | |
| 6563 return super.getContents(source); | |
| 6564 } | |
| 6565 | |
| 6566 @override | |
| 6567 int getModificationStamp(Source source) { | |
| 6568 if (source.isInSystemLibrary) { | |
| 6569 return sourceFactory.dartSdk.context.getModificationStamp(source); | |
| 6570 } | |
| 6571 return super.getModificationStamp(source); | |
| 6572 } | |
| 6573 | |
| 6574 /** | |
| 6575 * Set the analysis options, even if they would force re-analysis. This method
should only be | |
| 6576 * invoked before the fake SDK is initialized. | |
| 6577 * | |
| 6578 * @param options the analysis options to be set | |
| 6579 */ | |
| 6580 void _internalSetAnalysisOptions(AnalysisOptions options) { | |
| 6581 super.analysisOptions = options; | |
| 6582 } | |
| 6583 } | |
| 6584 | |
| 6585 @reflectiveTest | |
| 6586 class NonHintCodeTest extends ResolverTestCase { | |
| 6587 void test_deadCode_deadBlock_conditionalElse_debugConst() { | |
| 6588 Source source = addSource(r''' | |
| 6589 const bool DEBUG = true; | |
| 6590 f() { | |
| 6591 DEBUG ? 1 : 2; | |
| 6592 }'''); | |
| 6593 computeLibrarySourceErrors(source); | |
| 6594 assertNoErrors(source); | |
| 6595 verify([source]); | |
| 6596 } | |
| 6597 | |
| 6598 void test_deadCode_deadBlock_conditionalIf_debugConst() { | |
| 6599 Source source = addSource(r''' | |
| 6600 const bool DEBUG = false; | |
| 6601 f() { | |
| 6602 DEBUG ? 1 : 2; | |
| 6603 }'''); | |
| 6604 computeLibrarySourceErrors(source); | |
| 6605 assertNoErrors(source); | |
| 6606 verify([source]); | |
| 6607 } | |
| 6608 | |
| 6609 void test_deadCode_deadBlock_else() { | |
| 6610 Source source = addSource(r''' | |
| 6611 const bool DEBUG = true; | |
| 6612 f() { | |
| 6613 if(DEBUG) {} else {} | |
| 6614 }'''); | |
| 6615 computeLibrarySourceErrors(source); | |
| 6616 assertNoErrors(source); | |
| 6617 verify([source]); | |
| 6618 } | |
| 6619 | |
| 6620 void test_deadCode_deadBlock_if_debugConst_prefixedIdentifier() { | |
| 6621 Source source = addSource(r''' | |
| 6622 class A { | |
| 6623 static const bool DEBUG = false; | |
| 6624 } | |
| 6625 f() { | |
| 6626 if(A.DEBUG) {} | |
| 6627 }'''); | |
| 6628 computeLibrarySourceErrors(source); | |
| 6629 assertNoErrors(source); | |
| 6630 verify([source]); | |
| 6631 } | |
| 6632 | |
| 6633 void test_deadCode_deadBlock_if_debugConst_prefixedIdentifier2() { | |
| 6634 Source source = addSource(r''' | |
| 6635 library L; | |
| 6636 import 'lib2.dart'; | |
| 6637 f() { | |
| 6638 if(A.DEBUG) {} | |
| 6639 }'''); | |
| 6640 addNamedSource( | |
| 6641 "/lib2.dart", | |
| 6642 r''' | |
| 6643 library lib2; | |
| 6644 class A { | |
| 6645 static const bool DEBUG = false; | |
| 6646 }'''); | |
| 6647 computeLibrarySourceErrors(source); | |
| 6648 assertNoErrors(source); | |
| 6649 verify([source]); | |
| 6650 } | |
| 6651 | |
| 6652 void test_deadCode_deadBlock_if_debugConst_propertyAccessor() { | |
| 6653 Source source = addSource(r''' | |
| 6654 library L; | |
| 6655 import 'lib2.dart' as LIB; | |
| 6656 f() { | |
| 6657 if(LIB.A.DEBUG) {} | |
| 6658 }'''); | |
| 6659 addNamedSource( | |
| 6660 "/lib2.dart", | |
| 6661 r''' | |
| 6662 library lib2; | |
| 6663 class A { | |
| 6664 static const bool DEBUG = false; | |
| 6665 }'''); | |
| 6666 computeLibrarySourceErrors(source); | |
| 6667 assertNoErrors(source); | |
| 6668 verify([source]); | |
| 6669 } | |
| 6670 | |
| 6671 void test_deadCode_deadBlock_if_debugConst_simpleIdentifier() { | |
| 6672 Source source = addSource(r''' | |
| 6673 const bool DEBUG = false; | |
| 6674 f() { | |
| 6675 if(DEBUG) {} | |
| 6676 }'''); | |
| 6677 computeLibrarySourceErrors(source); | |
| 6678 assertNoErrors(source); | |
| 6679 verify([source]); | |
| 6680 } | |
| 6681 | |
| 6682 void test_deadCode_deadBlock_while_debugConst() { | |
| 6683 Source source = addSource(r''' | |
| 6684 const bool DEBUG = false; | |
| 6685 f() { | |
| 6686 while(DEBUG) {} | |
| 6687 }'''); | |
| 6688 computeLibrarySourceErrors(source); | |
| 6689 assertNoErrors(source); | |
| 6690 verify([source]); | |
| 6691 } | |
| 6692 | |
| 6693 void test_deadCode_deadCatch_onCatchSubtype() { | |
| 6694 Source source = addSource(r''' | |
| 6695 class A {} | |
| 6696 class B extends A {} | |
| 6697 f() { | |
| 6698 try {} on B catch (e) {} on A catch (e) {} catch (e) {} | |
| 6699 }'''); | |
| 6700 computeLibrarySourceErrors(source); | |
| 6701 assertNoErrors(source); | |
| 6702 verify([source]); | |
| 6703 } | |
| 6704 | |
| 6705 void test_deadCode_deadOperandLHS_and_debugConst() { | |
| 6706 Source source = addSource(r''' | |
| 6707 const bool DEBUG = false; | |
| 6708 f() { | |
| 6709 bool b = DEBUG && false; | |
| 6710 }'''); | |
| 6711 computeLibrarySourceErrors(source); | |
| 6712 assertNoErrors(source); | |
| 6713 verify([source]); | |
| 6714 } | |
| 6715 | |
| 6716 void test_deadCode_deadOperandLHS_or_debugConst() { | |
| 6717 Source source = addSource(r''' | |
| 6718 const bool DEBUG = true; | |
| 6719 f() { | |
| 6720 bool b = DEBUG || true; | |
| 6721 }'''); | |
| 6722 computeLibrarySourceErrors(source); | |
| 6723 assertNoErrors(source); | |
| 6724 verify([source]); | |
| 6725 } | |
| 6726 | |
| 6727 void test_divisionOptimization() { | |
| 6728 Source source = addSource(r''' | |
| 6729 f(int x, int y) { | |
| 6730 var v = x / y.toInt(); | |
| 6731 }'''); | |
| 6732 computeLibrarySourceErrors(source); | |
| 6733 assertNoErrors(source); | |
| 6734 verify([source]); | |
| 6735 } | |
| 6736 | |
| 6737 void test_divisionOptimization_supressIfDivisionNotDefinedInCore() { | |
| 6738 Source source = addSource(r''' | |
| 6739 f(x, y) { | |
| 6740 var v = (x / y).toInt(); | |
| 6741 }'''); | |
| 6742 computeLibrarySourceErrors(source); | |
| 6743 assertNoErrors(source); | |
| 6744 verify([source]); | |
| 6745 } | |
| 6746 | |
| 6747 void test_divisionOptimization_supressIfDivisionOverridden() { | |
| 6748 Source source = addSource(r''' | |
| 6749 class A { | |
| 6750 num operator /(x) { return x; } | |
| 6751 } | |
| 6752 f(A x, A y) { | |
| 6753 var v = (x / y).toInt(); | |
| 6754 }'''); | |
| 6755 computeLibrarySourceErrors(source); | |
| 6756 assertNoErrors(source); | |
| 6757 verify([source]); | |
| 6758 } | |
| 6759 | |
| 6760 void test_duplicateImport_as() { | |
| 6761 Source source = addSource(r''' | |
| 6762 library L; | |
| 6763 import 'lib1.dart'; | |
| 6764 import 'lib1.dart' as one; | |
| 6765 A a; | |
| 6766 one.A a2;'''); | |
| 6767 addNamedSource( | |
| 6768 "/lib1.dart", | |
| 6769 r''' | |
| 6770 library lib1; | |
| 6771 class A {}'''); | |
| 6772 computeLibrarySourceErrors(source); | |
| 6773 assertNoErrors(source); | |
| 6774 verify([source]); | |
| 6775 } | |
| 6776 | |
| 6777 void test_duplicateImport_hide() { | |
| 6778 Source source = addSource(r''' | |
| 6779 library L; | |
| 6780 import 'lib1.dart'; | |
| 6781 import 'lib1.dart' hide A; | |
| 6782 A a; | |
| 6783 B b;'''); | |
| 6784 addNamedSource( | |
| 6785 "/lib1.dart", | |
| 6786 r''' | |
| 6787 library lib1; | |
| 6788 class A {} | |
| 6789 class B {}'''); | |
| 6790 computeLibrarySourceErrors(source); | |
| 6791 assertNoErrors(source); | |
| 6792 verify([source]); | |
| 6793 } | |
| 6794 | |
| 6795 void test_duplicateImport_show() { | |
| 6796 Source source = addSource(r''' | |
| 6797 library L; | |
| 6798 import 'lib1.dart'; | |
| 6799 import 'lib1.dart' show A; | |
| 6800 A a; | |
| 6801 B b;'''); | |
| 6802 addNamedSource( | |
| 6803 "/lib1.dart", | |
| 6804 r''' | |
| 6805 library lib1; | |
| 6806 class A {} | |
| 6807 class B {}'''); | |
| 6808 computeLibrarySourceErrors(source); | |
| 6809 assertNoErrors(source); | |
| 6810 verify([source]); | |
| 6811 } | |
| 6812 | |
| 6813 void test_importDeferredLibraryWithLoadFunction() { | |
| 6814 resolveWithErrors(<String>[ | |
| 6815 r''' | |
| 6816 library lib1; | |
| 6817 f() {}''', | |
| 6818 r''' | |
| 6819 library root; | |
| 6820 import 'lib1.dart' deferred as lib1; | |
| 6821 main() { lib1.f(); }''' | |
| 6822 ], ErrorCode.EMPTY_LIST); | |
| 6823 } | |
| 6824 | |
| 6825 void test_issue20904BuggyTypePromotionAtIfJoin_1() { | |
| 6826 // https://code.google.com/p/dart/issues/detail?id=20904 | |
| 6827 Source source = addSource(r''' | |
| 6828 f(var message, var dynamic_) { | |
| 6829 if (message is Function) { | |
| 6830 message = dynamic_; | |
| 6831 } | |
| 6832 int s = message; | |
| 6833 }'''); | |
| 6834 computeLibrarySourceErrors(source); | |
| 6835 assertNoErrors(source); | |
| 6836 verify([source]); | |
| 6837 } | |
| 6838 | |
| 6839 void test_issue20904BuggyTypePromotionAtIfJoin_3() { | |
| 6840 // https://code.google.com/p/dart/issues/detail?id=20904 | |
| 6841 Source source = addSource(r''' | |
| 6842 f(var message) { | |
| 6843 var dynamic_; | |
| 6844 if (message is Function) { | |
| 6845 message = dynamic_; | |
| 6846 } else { | |
| 6847 return; | |
| 6848 } | |
| 6849 int s = message; | |
| 6850 }'''); | |
| 6851 computeLibrarySourceErrors(source); | |
| 6852 assertNoErrors(source); | |
| 6853 verify([source]); | |
| 6854 } | |
| 6855 | |
| 6856 void test_issue20904BuggyTypePromotionAtIfJoin_4() { | |
| 6857 // https://code.google.com/p/dart/issues/detail?id=20904 | |
| 6858 Source source = addSource(r''' | |
| 6859 f(var message) { | |
| 6860 if (message is Function) { | |
| 6861 message = ''; | |
| 6862 } else { | |
| 6863 return; | |
| 6864 } | |
| 6865 String s = message; | |
| 6866 }'''); | |
| 6867 computeLibrarySourceErrors(source); | |
| 6868 assertNoErrors(source); | |
| 6869 verify([source]); | |
| 6870 } | |
| 6871 | |
| 6872 void test_missingReturn_emptyFunctionBody() { | |
| 6873 Source source = addSource(r''' | |
| 6874 abstract class A { | |
| 6875 int m(); | |
| 6876 }'''); | |
| 6877 computeLibrarySourceErrors(source); | |
| 6878 assertNoErrors(source); | |
| 6879 verify([source]); | |
| 6880 } | |
| 6881 | |
| 6882 void test_missingReturn_expressionFunctionBody() { | |
| 6883 Source source = addSource("int f() => 0;"); | |
| 6884 computeLibrarySourceErrors(source); | |
| 6885 assertNoErrors(source); | |
| 6886 verify([source]); | |
| 6887 } | |
| 6888 | |
| 6889 void test_missingReturn_noReturnType() { | |
| 6890 Source source = addSource("f() {}"); | |
| 6891 computeLibrarySourceErrors(source); | |
| 6892 assertNoErrors(source); | |
| 6893 verify([source]); | |
| 6894 } | |
| 6895 | |
| 6896 void test_missingReturn_voidReturnType() { | |
| 6897 Source source = addSource("void f() {}"); | |
| 6898 computeLibrarySourceErrors(source); | |
| 6899 assertNoErrors(source); | |
| 6900 verify([source]); | |
| 6901 } | |
| 6902 | |
| 6903 void test_overrideEqualsButNotHashCode() { | |
| 6904 Source source = addSource(r''' | |
| 6905 class A { | |
| 6906 bool operator ==(x) { return x; } | |
| 6907 get hashCode => 0; | |
| 6908 }'''); | |
| 6909 computeLibrarySourceErrors(source); | |
| 6910 assertNoErrors(source); | |
| 6911 verify([source]); | |
| 6912 } | |
| 6913 | |
| 6914 void test_overrideOnNonOverridingGetter_inInterface() { | |
| 6915 Source source = addSource(r''' | |
| 6916 library dart.core; | |
| 6917 const override = null; | |
| 6918 class A { | |
| 6919 int get m => 0; | |
| 6920 } | |
| 6921 class B implements A { | |
| 6922 @override | |
| 6923 int get m => 1; | |
| 6924 }'''); | |
| 6925 computeLibrarySourceErrors(source); | |
| 6926 assertNoErrors(source); | |
| 6927 verify([source]); | |
| 6928 } | |
| 6929 | |
| 6930 void test_overrideOnNonOverridingGetter_inSuperclass() { | |
| 6931 Source source = addSource(r''' | |
| 6932 library dart.core; | |
| 6933 const override = null; | |
| 6934 class A { | |
| 6935 int get m => 0; | |
| 6936 } | |
| 6937 class B extends A { | |
| 6938 @override | |
| 6939 int get m => 1; | |
| 6940 }'''); | |
| 6941 computeLibrarySourceErrors(source); | |
| 6942 assertNoErrors(source); | |
| 6943 verify([source]); | |
| 6944 } | |
| 6945 | |
| 6946 void test_overrideOnNonOverridingMethod_inInterface() { | |
| 6947 Source source = addSource(r''' | |
| 6948 library dart.core; | |
| 6949 const override = null; | |
| 6950 class A { | |
| 6951 int m() => 0; | |
| 6952 } | |
| 6953 class B implements A { | |
| 6954 @override | |
| 6955 int m() => 1; | |
| 6956 }'''); | |
| 6957 computeLibrarySourceErrors(source); | |
| 6958 assertNoErrors(source); | |
| 6959 verify([source]); | |
| 6960 } | |
| 6961 | |
| 6962 void test_overrideOnNonOverridingMethod_inSuperclass() { | |
| 6963 Source source = addSource(r''' | |
| 6964 library dart.core; | |
| 6965 const override = null; | |
| 6966 class A { | |
| 6967 int m() => 0; | |
| 6968 } | |
| 6969 class B extends A { | |
| 6970 @override | |
| 6971 int m() => 1; | |
| 6972 }'''); | |
| 6973 computeLibrarySourceErrors(source); | |
| 6974 assertNoErrors(source); | |
| 6975 verify([source]); | |
| 6976 } | |
| 6977 | |
| 6978 void test_overrideOnNonOverridingSetter_inInterface() { | |
| 6979 Source source = addSource(r''' | |
| 6980 library dart.core; | |
| 6981 const override = null; | |
| 6982 class A { | |
| 6983 set m(int x) {} | |
| 6984 } | |
| 6985 class B implements A { | |
| 6986 @override | |
| 6987 set m(int x) {} | |
| 6988 }'''); | |
| 6989 computeLibrarySourceErrors(source); | |
| 6990 assertNoErrors(source); | |
| 6991 verify([source]); | |
| 6992 } | |
| 6993 | |
| 6994 void test_overrideOnNonOverridingSetter_inSuperclass() { | |
| 6995 Source source = addSource(r''' | |
| 6996 library dart.core; | |
| 6997 const override = null; | |
| 6998 class A { | |
| 6999 set m(int x) {} | |
| 7000 } | |
| 7001 class B extends A { | |
| 7002 @override | |
| 7003 set m(int x) {} | |
| 7004 }'''); | |
| 7005 computeLibrarySourceErrors(source); | |
| 7006 assertNoErrors(source); | |
| 7007 verify([source]); | |
| 7008 } | |
| 7009 | |
| 7010 void test_propagatedFieldType() { | |
| 7011 Source source = addSource(r''' | |
| 7012 class A { } | |
| 7013 class X<T> { | |
| 7014 final x = new List<T>(); | |
| 7015 } | |
| 7016 class Z { | |
| 7017 final X<A> y = new X<A>(); | |
| 7018 foo() { | |
| 7019 y.x.add(new A()); | |
| 7020 } | |
| 7021 }'''); | |
| 7022 computeLibrarySourceErrors(source); | |
| 7023 assertNoErrors(source); | |
| 7024 verify([source]); | |
| 7025 } | |
| 7026 | |
| 7027 void test_proxy_annotation_prefixed() { | |
| 7028 Source source = addSource(r''' | |
| 7029 library L; | |
| 7030 @proxy | |
| 7031 class A {} | |
| 7032 f(var a) { | |
| 7033 a = new A(); | |
| 7034 a.m(); | |
| 7035 var x = a.g; | |
| 7036 a.s = 1; | |
| 7037 var y = a + a; | |
| 7038 a++; | |
| 7039 ++a; | |
| 7040 }'''); | |
| 7041 computeLibrarySourceErrors(source); | |
| 7042 assertNoErrors(source); | |
| 7043 } | |
| 7044 | |
| 7045 void test_proxy_annotation_prefixed2() { | |
| 7046 Source source = addSource(r''' | |
| 7047 library L; | |
| 7048 @proxy | |
| 7049 class A {} | |
| 7050 class B { | |
| 7051 f(var a) { | |
| 7052 a = new A(); | |
| 7053 a.m(); | |
| 7054 var x = a.g; | |
| 7055 a.s = 1; | |
| 7056 var y = a + a; | |
| 7057 a++; | |
| 7058 ++a; | |
| 7059 } | |
| 7060 }'''); | |
| 7061 computeLibrarySourceErrors(source); | |
| 7062 assertNoErrors(source); | |
| 7063 } | |
| 7064 | |
| 7065 void test_proxy_annotation_prefixed3() { | |
| 7066 Source source = addSource(r''' | |
| 7067 library L; | |
| 7068 class B { | |
| 7069 f(var a) { | |
| 7070 a = new A(); | |
| 7071 a.m(); | |
| 7072 var x = a.g; | |
| 7073 a.s = 1; | |
| 7074 var y = a + a; | |
| 7075 a++; | |
| 7076 ++a; | |
| 7077 } | |
| 7078 } | |
| 7079 @proxy | |
| 7080 class A {}'''); | |
| 7081 computeLibrarySourceErrors(source); | |
| 7082 assertNoErrors(source); | |
| 7083 } | |
| 7084 | |
| 7085 void test_undefinedGetter_inSubtype() { | |
| 7086 Source source = addSource(r''' | |
| 7087 class A {} | |
| 7088 class B extends A { | |
| 7089 get b => 0; | |
| 7090 } | |
| 7091 f(var a) { | |
| 7092 if(a is A) { | |
| 7093 return a.b; | |
| 7094 } | |
| 7095 }'''); | |
| 7096 computeLibrarySourceErrors(source); | |
| 7097 assertNoErrors(source); | |
| 7098 } | |
| 7099 | |
| 7100 void test_undefinedMethod_assignmentExpression_inSubtype() { | |
| 7101 Source source = addSource(r''' | |
| 7102 class A {} | |
| 7103 class B extends A { | |
| 7104 operator +(B b) {return new B();} | |
| 7105 } | |
| 7106 f(var a, var a2) { | |
| 7107 a = new A(); | |
| 7108 a2 = new A(); | |
| 7109 a += a2; | |
| 7110 }'''); | |
| 7111 computeLibrarySourceErrors(source); | |
| 7112 assertNoErrors(source); | |
| 7113 } | |
| 7114 | |
| 7115 void test_undefinedMethod_dynamic() { | |
| 7116 Source source = addSource(r''' | |
| 7117 class D<T extends dynamic> { | |
| 7118 fieldAccess(T t) => t.abc; | |
| 7119 methodAccess(T t) => t.xyz(1, 2, 'three'); | |
| 7120 }'''); | |
| 7121 computeLibrarySourceErrors(source); | |
| 7122 assertNoErrors(source); | |
| 7123 } | |
| 7124 | |
| 7125 void test_undefinedMethod_inSubtype() { | |
| 7126 Source source = addSource(r''' | |
| 7127 class A {} | |
| 7128 class B extends A { | |
| 7129 b() {} | |
| 7130 } | |
| 7131 f() { | |
| 7132 var a = new A(); | |
| 7133 a.b(); | |
| 7134 }'''); | |
| 7135 computeLibrarySourceErrors(source); | |
| 7136 assertNoErrors(source); | |
| 7137 } | |
| 7138 | |
| 7139 void test_undefinedMethod_unionType_all() { | |
| 7140 Source source = addSource(r''' | |
| 7141 class A { | |
| 7142 int m(int x) => 0; | |
| 7143 } | |
| 7144 class B { | |
| 7145 String m() => '0'; | |
| 7146 } | |
| 7147 f(A a, B b) { | |
| 7148 var ab; | |
| 7149 if (0 < 1) { | |
| 7150 ab = a; | |
| 7151 } else { | |
| 7152 ab = b; | |
| 7153 } | |
| 7154 ab.m(); | |
| 7155 }'''); | |
| 7156 computeLibrarySourceErrors(source); | |
| 7157 assertNoErrors(source); | |
| 7158 } | |
| 7159 | |
| 7160 void test_undefinedMethod_unionType_some() { | |
| 7161 Source source = addSource(r''' | |
| 7162 class A { | |
| 7163 int m(int x) => 0; | |
| 7164 } | |
| 7165 class B {} | |
| 7166 f(A a, B b) { | |
| 7167 var ab; | |
| 7168 if (0 < 1) { | |
| 7169 ab = a; | |
| 7170 } else { | |
| 7171 ab = b; | |
| 7172 } | |
| 7173 ab.m(0); | |
| 7174 }'''); | |
| 7175 computeLibrarySourceErrors(source); | |
| 7176 assertNoErrors(source); | |
| 7177 } | |
| 7178 | |
| 7179 void test_undefinedOperator_binaryExpression_inSubtype() { | |
| 7180 Source source = addSource(r''' | |
| 7181 class A {} | |
| 7182 class B extends A { | |
| 7183 operator +(B b) {} | |
| 7184 } | |
| 7185 f(var a) { | |
| 7186 if(a is A) { | |
| 7187 a + 1; | |
| 7188 } | |
| 7189 }'''); | |
| 7190 computeLibrarySourceErrors(source); | |
| 7191 assertNoErrors(source); | |
| 7192 } | |
| 7193 | |
| 7194 void test_undefinedOperator_indexBoth_inSubtype() { | |
| 7195 Source source = addSource(r''' | |
| 7196 class A {} | |
| 7197 class B extends A { | |
| 7198 operator [](int index) {} | |
| 7199 } | |
| 7200 f(var a) { | |
| 7201 if(a is A) { | |
| 7202 a[0]++; | |
| 7203 } | |
| 7204 }'''); | |
| 7205 computeLibrarySourceErrors(source); | |
| 7206 assertNoErrors(source); | |
| 7207 } | |
| 7208 | |
| 7209 void test_undefinedOperator_indexGetter_inSubtype() { | |
| 7210 Source source = addSource(r''' | |
| 7211 class A {} | |
| 7212 class B extends A { | |
| 7213 operator [](int index) {} | |
| 7214 } | |
| 7215 f(var a) { | |
| 7216 if(a is A) { | |
| 7217 a[0]; | |
| 7218 } | |
| 7219 }'''); | |
| 7220 computeLibrarySourceErrors(source); | |
| 7221 assertNoErrors(source); | |
| 7222 } | |
| 7223 | |
| 7224 void test_undefinedOperator_indexSetter_inSubtype() { | |
| 7225 Source source = addSource(r''' | |
| 7226 class A {} | |
| 7227 class B extends A { | |
| 7228 operator []=(i, v) {} | |
| 7229 } | |
| 7230 f(var a) { | |
| 7231 if(a is A) { | |
| 7232 a[0] = 1; | |
| 7233 } | |
| 7234 }'''); | |
| 7235 computeLibrarySourceErrors(source); | |
| 7236 assertNoErrors(source); | |
| 7237 } | |
| 7238 | |
| 7239 void test_undefinedOperator_postfixExpression() { | |
| 7240 Source source = addSource(r''' | |
| 7241 class A {} | |
| 7242 class B extends A { | |
| 7243 operator +(B b) {return new B();} | |
| 7244 } | |
| 7245 f(var a) { | |
| 7246 if(a is A) { | |
| 7247 a++; | |
| 7248 } | |
| 7249 }'''); | |
| 7250 computeLibrarySourceErrors(source); | |
| 7251 assertNoErrors(source); | |
| 7252 } | |
| 7253 | |
| 7254 void test_undefinedOperator_prefixExpression() { | |
| 7255 Source source = addSource(r''' | |
| 7256 class A {} | |
| 7257 class B extends A { | |
| 7258 operator +(B b) {return new B();} | |
| 7259 } | |
| 7260 f(var a) { | |
| 7261 if(a is A) { | |
| 7262 ++a; | |
| 7263 } | |
| 7264 }'''); | |
| 7265 computeLibrarySourceErrors(source); | |
| 7266 assertNoErrors(source); | |
| 7267 } | |
| 7268 | |
| 7269 void test_undefinedSetter_inSubtype() { | |
| 7270 Source source = addSource(r''' | |
| 7271 class A {} | |
| 7272 class B extends A { | |
| 7273 set b(x) {} | |
| 7274 } | |
| 7275 f(var a) { | |
| 7276 if(a is A) { | |
| 7277 a.b = 0; | |
| 7278 } | |
| 7279 }'''); | |
| 7280 computeLibrarySourceErrors(source); | |
| 7281 assertNoErrors(source); | |
| 7282 } | |
| 7283 | |
| 7284 void test_unnecessaryCast_13855_parameter_A() { | |
| 7285 // dartbug.com/13855, dartbug.com/13732 | |
| 7286 Source source = addSource(r''' | |
| 7287 class A{ | |
| 7288 a() {} | |
| 7289 } | |
| 7290 class B<E> { | |
| 7291 E e; | |
| 7292 m() { | |
| 7293 (e as A).a(); | |
| 7294 } | |
| 7295 }'''); | |
| 7296 computeLibrarySourceErrors(source); | |
| 7297 assertNoErrors(source); | |
| 7298 verify([source]); | |
| 7299 } | |
| 7300 | |
| 7301 void test_unnecessaryCast_conditionalExpression() { | |
| 7302 Source source = addSource(r''' | |
| 7303 abstract class I {} | |
| 7304 class A implements I {} | |
| 7305 class B implements I {} | |
| 7306 I m(A a, B b) { | |
| 7307 return a == null ? b as I : a as I; | |
| 7308 }'''); | |
| 7309 computeLibrarySourceErrors(source); | |
| 7310 assertNoErrors(source); | |
| 7311 verify([source]); | |
| 7312 } | |
| 7313 | |
| 7314 void test_unnecessaryCast_dynamic_type() { | |
| 7315 Source source = addSource(r''' | |
| 7316 m(v) { | |
| 7317 var b = v as Object; | |
| 7318 }'''); | |
| 7319 computeLibrarySourceErrors(source); | |
| 7320 assertNoErrors(source); | |
| 7321 verify([source]); | |
| 7322 } | |
| 7323 | |
| 7324 void test_unnecessaryCast_generics() { | |
| 7325 // dartbug.com/18953 | |
| 7326 Source source = addSource(r''' | |
| 7327 import 'dart:async'; | |
| 7328 Future<int> f() => new Future.value(0); | |
| 7329 void g(bool c) { | |
| 7330 (c ? f(): new Future.value(0) as Future<int>).then((int value) {}); | |
| 7331 }'''); | |
| 7332 computeLibrarySourceErrors(source); | |
| 7333 assertNoErrors(source); | |
| 7334 verify([source]); | |
| 7335 } | |
| 7336 | |
| 7337 void test_unnecessaryCast_type_dynamic() { | |
| 7338 Source source = addSource(r''' | |
| 7339 m(v) { | |
| 7340 var b = Object as dynamic; | |
| 7341 }'''); | |
| 7342 computeLibrarySourceErrors(source); | |
| 7343 assertNoErrors(source); | |
| 7344 verify([source]); | |
| 7345 } | |
| 7346 | |
| 7347 void test_unusedImport_annotationOnDirective() { | |
| 7348 Source source = addSource(r''' | |
| 7349 library L; | |
| 7350 @A() | |
| 7351 import 'lib1.dart';'''); | |
| 7352 Source source2 = addNamedSource( | |
| 7353 "/lib1.dart", | |
| 7354 r''' | |
| 7355 library lib1; | |
| 7356 class A { | |
| 7357 const A() {} | |
| 7358 }'''); | |
| 7359 computeLibrarySourceErrors(source); | |
| 7360 assertErrors(source); | |
| 7361 verify([source, source2]); | |
| 7362 } | |
| 7363 | |
| 7364 void test_unusedImport_as_equalPrefixes() { | |
| 7365 // 18818 | |
| 7366 Source source = addSource(r''' | |
| 7367 library L; | |
| 7368 import 'lib1.dart' as one; | |
| 7369 import 'lib2.dart' as one; | |
| 7370 one.A a; | |
| 7371 one.B b;'''); | |
| 7372 Source source2 = addNamedSource( | |
| 7373 "/lib1.dart", | |
| 7374 r''' | |
| 7375 library lib1; | |
| 7376 class A {}'''); | |
| 7377 Source source3 = addNamedSource( | |
| 7378 "/lib2.dart", | |
| 7379 r''' | |
| 7380 library lib2; | |
| 7381 class B {}'''); | |
| 7382 computeLibrarySourceErrors(source); | |
| 7383 assertErrors(source); | |
| 7384 assertNoErrors(source2); | |
| 7385 assertNoErrors(source3); | |
| 7386 verify([source, source2, source3]); | |
| 7387 } | |
| 7388 | |
| 7389 void test_unusedImport_core_library() { | |
| 7390 Source source = addSource(r''' | |
| 7391 library L; | |
| 7392 import 'dart:core';'''); | |
| 7393 computeLibrarySourceErrors(source); | |
| 7394 assertNoErrors(source); | |
| 7395 verify([source]); | |
| 7396 } | |
| 7397 | |
| 7398 void test_unusedImport_export() { | |
| 7399 Source source = addSource(r''' | |
| 7400 library L; | |
| 7401 import 'lib1.dart'; | |
| 7402 Two two;'''); | |
| 7403 addNamedSource( | |
| 7404 "/lib1.dart", | |
| 7405 r''' | |
| 7406 library lib1; | |
| 7407 export 'lib2.dart'; | |
| 7408 class One {}'''); | |
| 7409 addNamedSource( | |
| 7410 "/lib2.dart", | |
| 7411 r''' | |
| 7412 library lib2; | |
| 7413 class Two {}'''); | |
| 7414 computeLibrarySourceErrors(source); | |
| 7415 assertNoErrors(source); | |
| 7416 verify([source]); | |
| 7417 } | |
| 7418 | |
| 7419 void test_unusedImport_export2() { | |
| 7420 Source source = addSource(r''' | |
| 7421 library L; | |
| 7422 import 'lib1.dart'; | |
| 7423 Three three;'''); | |
| 7424 addNamedSource( | |
| 7425 "/lib1.dart", | |
| 7426 r''' | |
| 7427 library lib1; | |
| 7428 export 'lib2.dart'; | |
| 7429 class One {}'''); | |
| 7430 addNamedSource( | |
| 7431 "/lib2.dart", | |
| 7432 r''' | |
| 7433 library lib2; | |
| 7434 export 'lib3.dart'; | |
| 7435 class Two {}'''); | |
| 7436 addNamedSource( | |
| 7437 "/lib3.dart", | |
| 7438 r''' | |
| 7439 library lib3; | |
| 7440 class Three {}'''); | |
| 7441 computeLibrarySourceErrors(source); | |
| 7442 assertNoErrors(source); | |
| 7443 verify([source]); | |
| 7444 } | |
| 7445 | |
| 7446 void test_unusedImport_export_infiniteLoop() { | |
| 7447 Source source = addSource(r''' | |
| 7448 library L; | |
| 7449 import 'lib1.dart'; | |
| 7450 Two two;'''); | |
| 7451 addNamedSource( | |
| 7452 "/lib1.dart", | |
| 7453 r''' | |
| 7454 library lib1; | |
| 7455 export 'lib2.dart'; | |
| 7456 class One {}'''); | |
| 7457 addNamedSource( | |
| 7458 "/lib2.dart", | |
| 7459 r''' | |
| 7460 library lib2; | |
| 7461 export 'lib3.dart'; | |
| 7462 class Two {}'''); | |
| 7463 addNamedSource( | |
| 7464 "/lib3.dart", | |
| 7465 r''' | |
| 7466 library lib3; | |
| 7467 export 'lib2.dart'; | |
| 7468 class Three {}'''); | |
| 7469 computeLibrarySourceErrors(source); | |
| 7470 assertNoErrors(source); | |
| 7471 verify([source]); | |
| 7472 } | |
| 7473 | |
| 7474 void test_unusedImport_metadata() { | |
| 7475 Source source = addSource(r''' | |
| 7476 library L; | |
| 7477 @A(x) | |
| 7478 import 'lib1.dart'; | |
| 7479 class A { | |
| 7480 final int value; | |
| 7481 const A(this.value); | |
| 7482 }'''); | |
| 7483 addNamedSource( | |
| 7484 "/lib1.dart", | |
| 7485 r''' | |
| 7486 library lib1; | |
| 7487 const x = 0;'''); | |
| 7488 computeLibrarySourceErrors(source); | |
| 7489 assertNoErrors(source); | |
| 7490 verify([source]); | |
| 7491 } | |
| 7492 | |
| 7493 void test_unusedImport_prefix_topLevelFunction() { | |
| 7494 Source source = addSource(r''' | |
| 7495 library L; | |
| 7496 import 'lib1.dart' hide topLevelFunction; | |
| 7497 import 'lib1.dart' as one show topLevelFunction; | |
| 7498 class A { | |
| 7499 static void x() { | |
| 7500 One o; | |
| 7501 one.topLevelFunction(); | |
| 7502 } | |
| 7503 }'''); | |
| 7504 addNamedSource( | |
| 7505 "/lib1.dart", | |
| 7506 r''' | |
| 7507 library lib1; | |
| 7508 class One {} | |
| 7509 topLevelFunction() {}'''); | |
| 7510 computeLibrarySourceErrors(source); | |
| 7511 assertNoErrors(source); | |
| 7512 verify([source]); | |
| 7513 } | |
| 7514 | |
| 7515 void test_useOfVoidResult_implicitReturnValue() { | |
| 7516 Source source = addSource(r''' | |
| 7517 f() {} | |
| 7518 class A { | |
| 7519 n() { | |
| 7520 var a = f(); | |
| 7521 } | |
| 7522 }'''); | |
| 7523 computeLibrarySourceErrors(source); | |
| 7524 assertNoErrors(source); | |
| 7525 verify([source]); | |
| 7526 } | |
| 7527 | |
| 7528 void test_useOfVoidResult_nonVoidReturnValue() { | |
| 7529 Source source = addSource(r''' | |
| 7530 int f() => 1; | |
| 7531 g() { | |
| 7532 var a = f(); | |
| 7533 }'''); | |
| 7534 computeLibrarySourceErrors(source); | |
| 7535 assertNoErrors(source); | |
| 7536 verify([source]); | |
| 7537 } | |
| 7538 } | |
| 7539 | |
| 7540 class PubSuggestionCodeTest extends ResolverTestCase { | |
| 7541 void test_import_package() { | |
| 7542 Source source = addSource("import 'package:somepackage/other.dart';"); | |
| 7543 computeLibrarySourceErrors(source); | |
| 7544 assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]); | |
| 7545 } | |
| 7546 | |
| 7547 void test_import_packageWithDotDot() { | |
| 7548 Source source = addSource("import 'package:somepackage/../other.dart';"); | |
| 7549 computeLibrarySourceErrors(source); | |
| 7550 assertErrors(source, [ | |
| 7551 CompileTimeErrorCode.URI_DOES_NOT_EXIST, | |
| 7552 HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT | |
| 7553 ]); | |
| 7554 } | |
| 7555 | |
| 7556 void test_import_packageWithLeadingDotDot() { | |
| 7557 Source source = addSource("import 'package:../other.dart';"); | |
| 7558 computeLibrarySourceErrors(source); | |
| 7559 assertErrors(source, [ | |
| 7560 CompileTimeErrorCode.URI_DOES_NOT_EXIST, | |
| 7561 HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT | |
| 7562 ]); | |
| 7563 } | |
| 7564 | |
| 7565 void test_import_referenceIntoLibDirectory() { | |
| 7566 cacheSource("/myproj/pubspec.yaml", ""); | |
| 7567 cacheSource("/myproj/lib/other.dart", ""); | |
| 7568 Source source = | |
| 7569 addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';"); | |
| 7570 computeLibrarySourceErrors(source); | |
| 7571 assertErrors( | |
| 7572 source, [HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE]); | |
| 7573 } | |
| 7574 | |
| 7575 void test_import_referenceIntoLibDirectory_no_pubspec() { | |
| 7576 cacheSource("/myproj/lib/other.dart", ""); | |
| 7577 Source source = | |
| 7578 addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';"); | |
| 7579 computeLibrarySourceErrors(source); | |
| 7580 assertNoErrors(source); | |
| 7581 } | |
| 7582 | |
| 7583 void test_import_referenceOutOfLibDirectory() { | |
| 7584 cacheSource("/myproj/pubspec.yaml", ""); | |
| 7585 cacheSource("/myproj/web/other.dart", ""); | |
| 7586 Source source = | |
| 7587 addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';"); | |
| 7588 computeLibrarySourceErrors(source); | |
| 7589 assertErrors( | |
| 7590 source, [HintCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE]); | |
| 7591 } | |
| 7592 | |
| 7593 void test_import_referenceOutOfLibDirectory_no_pubspec() { | |
| 7594 cacheSource("/myproj/web/other.dart", ""); | |
| 7595 Source source = | |
| 7596 addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';"); | |
| 7597 computeLibrarySourceErrors(source); | |
| 7598 assertNoErrors(source); | |
| 7599 } | |
| 7600 | |
| 7601 void test_import_valid_inside_lib1() { | |
| 7602 cacheSource("/myproj/pubspec.yaml", ""); | |
| 7603 cacheSource("/myproj/lib/other.dart", ""); | |
| 7604 Source source = | |
| 7605 addNamedSource("/myproj/lib/test.dart", "import 'other.dart';"); | |
| 7606 computeLibrarySourceErrors(source); | |
| 7607 assertNoErrors(source); | |
| 7608 } | |
| 7609 | |
| 7610 void test_import_valid_inside_lib2() { | |
| 7611 cacheSource("/myproj/pubspec.yaml", ""); | |
| 7612 cacheSource("/myproj/lib/bar/other.dart", ""); | |
| 7613 Source source = addNamedSource( | |
| 7614 "/myproj/lib/foo/test.dart", "import '../bar/other.dart';"); | |
| 7615 computeLibrarySourceErrors(source); | |
| 7616 assertNoErrors(source); | |
| 7617 } | |
| 7618 | |
| 7619 void test_import_valid_outside_lib() { | |
| 7620 cacheSource("/myproj/pubspec.yaml", ""); | |
| 7621 cacheSource("/myproj/web/other.dart", ""); | |
| 7622 Source source = | |
| 7623 addNamedSource("/myproj/lib2/test.dart", "import '../web/other.dart';"); | |
| 7624 computeLibrarySourceErrors(source); | |
| 7625 assertNoErrors(source); | |
| 7626 } | |
| 7627 } | |
| 7628 | |
| 7629 /** | |
| 7630 * An AST visitor used to verify that all of the nodes in an AST structure that | |
| 7631 * should have been resolved were resolved. | |
| 7632 */ | |
| 7633 class ResolutionVerifier extends RecursiveAstVisitor<Object> { | |
| 7634 /** | |
| 7635 * A set containing nodes that are known to not be resolvable and should | |
| 7636 * therefore not cause the test to fail. | |
| 7637 */ | |
| 7638 final Set<AstNode> _knownExceptions; | |
| 7639 | |
| 7640 /** | |
| 7641 * A list containing all of the AST nodes that were not resolved. | |
| 7642 */ | |
| 7643 List<AstNode> _unresolvedNodes = new List<AstNode>(); | |
| 7644 | |
| 7645 /** | |
| 7646 * A list containing all of the AST nodes that were resolved to an element of | |
| 7647 * the wrong type. | |
| 7648 */ | |
| 7649 List<AstNode> _wrongTypedNodes = new List<AstNode>(); | |
| 7650 | |
| 7651 /** | |
| 7652 * Initialize a newly created verifier to verify that all of the identifiers | |
| 7653 * in the visited AST structures that are expected to have been resolved have | |
| 7654 * an element associated with them. Nodes in the set of [_knownExceptions] are | |
| 7655 * not expected to have been resolved, even if they normally would have been | |
| 7656 * expected to have been resolved. | |
| 7657 */ | |
| 7658 ResolutionVerifier([this._knownExceptions]); | |
| 7659 | |
| 7660 /** | |
| 7661 * Assert that all of the visited identifiers were resolved. | |
| 7662 */ | |
| 7663 void assertResolved() { | |
| 7664 if (!_unresolvedNodes.isEmpty || !_wrongTypedNodes.isEmpty) { | |
| 7665 StringBuffer buffer = new StringBuffer(); | |
| 7666 if (!_unresolvedNodes.isEmpty) { | |
| 7667 buffer.write("Failed to resolve "); | |
| 7668 buffer.write(_unresolvedNodes.length); | |
| 7669 buffer.writeln(" nodes:"); | |
| 7670 _printNodes(buffer, _unresolvedNodes); | |
| 7671 } | |
| 7672 if (!_wrongTypedNodes.isEmpty) { | |
| 7673 buffer.write("Resolved "); | |
| 7674 buffer.write(_wrongTypedNodes.length); | |
| 7675 buffer.writeln(" to the wrong type of element:"); | |
| 7676 _printNodes(buffer, _wrongTypedNodes); | |
| 7677 } | |
| 7678 fail(buffer.toString()); | |
| 7679 } | |
| 7680 } | |
| 7681 | |
| 7682 @override | |
| 7683 Object visitAnnotation(Annotation node) { | |
| 7684 node.visitChildren(this); | |
| 7685 ElementAnnotation elementAnnotation = node.elementAnnotation; | |
| 7686 if (elementAnnotation == null) { | |
| 7687 if (_knownExceptions == null || !_knownExceptions.contains(node)) { | |
| 7688 _unresolvedNodes.add(node); | |
| 7689 } | |
| 7690 } else if (elementAnnotation is! ElementAnnotation) { | |
| 7691 _wrongTypedNodes.add(node); | |
| 7692 } | |
| 7693 return null; | |
| 7694 } | |
| 7695 | |
| 7696 @override | |
| 7697 Object visitBinaryExpression(BinaryExpression node) { | |
| 7698 node.visitChildren(this); | |
| 7699 if (!node.operator.isUserDefinableOperator) { | |
| 7700 return null; | |
| 7701 } | |
| 7702 DartType operandType = node.leftOperand.staticType; | |
| 7703 if (operandType == null || operandType.isDynamic) { | |
| 7704 return null; | |
| 7705 } | |
| 7706 return _checkResolved( | |
| 7707 node, node.staticElement, (node) => node is MethodElement); | |
| 7708 } | |
| 7709 | |
| 7710 @override | |
| 7711 Object visitCommentReference(CommentReference node) => null; | |
| 7712 | |
| 7713 @override | |
| 7714 Object visitCompilationUnit(CompilationUnit node) { | |
| 7715 node.visitChildren(this); | |
| 7716 return _checkResolved( | |
| 7717 node, node.element, (node) => node is CompilationUnitElement); | |
| 7718 } | |
| 7719 | |
| 7720 @override | |
| 7721 Object visitExportDirective(ExportDirective node) => | |
| 7722 _checkResolved(node, node.element, (node) => node is ExportElement); | |
| 7723 | |
| 7724 @override | |
| 7725 Object visitFunctionDeclaration(FunctionDeclaration node) { | |
| 7726 node.visitChildren(this); | |
| 7727 if (node.element is LibraryElement) { | |
| 7728 _wrongTypedNodes.add(node); | |
| 7729 } | |
| 7730 return null; | |
| 7731 } | |
| 7732 | |
| 7733 @override | |
| 7734 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { | |
| 7735 node.visitChildren(this); | |
| 7736 // TODO(brianwilkerson) If we start resolving function expressions, then | |
| 7737 // conditionally check to see whether the node was resolved correctly. | |
| 7738 return null; | |
| 7739 //checkResolved(node, node.getElement(), FunctionElement.class); | |
| 7740 } | |
| 7741 | |
| 7742 @override | |
| 7743 Object visitImportDirective(ImportDirective node) { | |
| 7744 // Not sure how to test the combinators given that it isn't an error if the | |
| 7745 // names are not defined. | |
| 7746 _checkResolved(node, node.element, (node) => node is ImportElement); | |
| 7747 SimpleIdentifier prefix = node.prefix; | |
| 7748 if (prefix == null) { | |
| 7749 return null; | |
| 7750 } | |
| 7751 return _checkResolved( | |
| 7752 prefix, prefix.staticElement, (node) => node is PrefixElement); | |
| 7753 } | |
| 7754 | |
| 7755 @override | |
| 7756 Object visitIndexExpression(IndexExpression node) { | |
| 7757 node.visitChildren(this); | |
| 7758 DartType targetType = node.realTarget.staticType; | |
| 7759 if (targetType == null || targetType.isDynamic) { | |
| 7760 return null; | |
| 7761 } | |
| 7762 return _checkResolved( | |
| 7763 node, node.staticElement, (node) => node is MethodElement); | |
| 7764 } | |
| 7765 | |
| 7766 @override | |
| 7767 Object visitLibraryDirective(LibraryDirective node) => | |
| 7768 _checkResolved(node, node.element, (node) => node is LibraryElement); | |
| 7769 | |
| 7770 @override | |
| 7771 Object visitNamedExpression(NamedExpression node) => | |
| 7772 node.expression.accept(this); | |
| 7773 | |
| 7774 @override | |
| 7775 Object visitPartDirective(PartDirective node) => _checkResolved( | |
| 7776 node, node.element, (node) => node is CompilationUnitElement); | |
| 7777 | |
| 7778 @override | |
| 7779 Object visitPartOfDirective(PartOfDirective node) => | |
| 7780 _checkResolved(node, node.element, (node) => node is LibraryElement); | |
| 7781 | |
| 7782 @override | |
| 7783 Object visitPostfixExpression(PostfixExpression node) { | |
| 7784 node.visitChildren(this); | |
| 7785 if (!node.operator.isUserDefinableOperator) { | |
| 7786 return null; | |
| 7787 } | |
| 7788 DartType operandType = node.operand.staticType; | |
| 7789 if (operandType == null || operandType.isDynamic) { | |
| 7790 return null; | |
| 7791 } | |
| 7792 return _checkResolved( | |
| 7793 node, node.staticElement, (node) => node is MethodElement); | |
| 7794 } | |
| 7795 | |
| 7796 @override | |
| 7797 Object visitPrefixedIdentifier(PrefixedIdentifier node) { | |
| 7798 SimpleIdentifier prefix = node.prefix; | |
| 7799 prefix.accept(this); | |
| 7800 DartType prefixType = prefix.staticType; | |
| 7801 if (prefixType == null || prefixType.isDynamic) { | |
| 7802 return null; | |
| 7803 } | |
| 7804 return _checkResolved(node, node.staticElement, null); | |
| 7805 } | |
| 7806 | |
| 7807 @override | |
| 7808 Object visitPrefixExpression(PrefixExpression node) { | |
| 7809 node.visitChildren(this); | |
| 7810 if (!node.operator.isUserDefinableOperator) { | |
| 7811 return null; | |
| 7812 } | |
| 7813 DartType operandType = node.operand.staticType; | |
| 7814 if (operandType == null || operandType.isDynamic) { | |
| 7815 return null; | |
| 7816 } | |
| 7817 return _checkResolved( | |
| 7818 node, node.staticElement, (node) => node is MethodElement); | |
| 7819 } | |
| 7820 | |
| 7821 @override | |
| 7822 Object visitPropertyAccess(PropertyAccess node) { | |
| 7823 Expression target = node.realTarget; | |
| 7824 target.accept(this); | |
| 7825 DartType targetType = target.staticType; | |
| 7826 if (targetType == null || targetType.isDynamic) { | |
| 7827 return null; | |
| 7828 } | |
| 7829 return node.propertyName.accept(this); | |
| 7830 } | |
| 7831 | |
| 7832 @override | |
| 7833 Object visitSimpleIdentifier(SimpleIdentifier node) { | |
| 7834 if (node.name == "void") { | |
| 7835 return null; | |
| 7836 } | |
| 7837 AstNode parent = node.parent; | |
| 7838 if (parent is MethodInvocation) { | |
| 7839 MethodInvocation invocation = parent; | |
| 7840 if (identical(invocation.methodName, node)) { | |
| 7841 Expression target = invocation.realTarget; | |
| 7842 DartType targetType = target == null ? null : target.staticType; | |
| 7843 if (targetType == null || targetType.isDynamic) { | |
| 7844 return null; | |
| 7845 } | |
| 7846 } | |
| 7847 } | |
| 7848 return _checkResolved(node, node.staticElement, null); | |
| 7849 } | |
| 7850 | |
| 7851 Object _checkResolved( | |
| 7852 AstNode node, Element element, Predicate<Element> predicate) { | |
| 7853 if (element == null) { | |
| 7854 if (_knownExceptions == null || !_knownExceptions.contains(node)) { | |
| 7855 _unresolvedNodes.add(node); | |
| 7856 } | |
| 7857 } else if (predicate != null) { | |
| 7858 if (!predicate(element)) { | |
| 7859 _wrongTypedNodes.add(node); | |
| 7860 } | |
| 7861 } | |
| 7862 return null; | |
| 7863 } | |
| 7864 | |
| 7865 String _getFileName(AstNode node) { | |
| 7866 // TODO (jwren) there are two copies of this method, one here and one in | |
| 7867 // StaticTypeVerifier, they should be resolved into a single method | |
| 7868 if (node != null) { | |
| 7869 AstNode root = node.root; | |
| 7870 if (root is CompilationUnit) { | |
| 7871 CompilationUnit rootCU = root; | |
| 7872 if (rootCU.element != null) { | |
| 7873 return rootCU.element.source.fullName; | |
| 7874 } else { | |
| 7875 return "<unknown file- CompilationUnit.getElement() returned null>"; | |
| 7876 } | |
| 7877 } else { | |
| 7878 return "<unknown file- CompilationUnit.getRoot() is not a CompilationUni
t>"; | |
| 7879 } | |
| 7880 } | |
| 7881 return "<unknown file- ASTNode is null>"; | |
| 7882 } | |
| 7883 | |
| 7884 void _printNodes(StringBuffer buffer, List<AstNode> nodes) { | |
| 7885 for (AstNode identifier in nodes) { | |
| 7886 buffer.write(" "); | |
| 7887 buffer.write(identifier.toString()); | |
| 7888 buffer.write(" ("); | |
| 7889 buffer.write(_getFileName(identifier)); | |
| 7890 buffer.write(" : "); | |
| 7891 buffer.write(identifier.offset); | |
| 7892 buffer.writeln(")"); | |
| 7893 } | |
| 7894 } | |
| 7895 } | |
| 7896 | |
| 7897 class ResolverTestCase extends EngineTestCase { | |
| 7898 /** | |
| 7899 * The analysis context used to parse the compilation units being resolved. | |
| 7900 */ | |
| 7901 InternalAnalysisContext analysisContext2; | |
| 7902 | |
| 7903 /** | |
| 7904 * Specifies if [assertErrors] should check for [HintCode.UNUSED_ELEMENT] and | |
| 7905 * [HintCode.UNUSED_FIELD]. | |
| 7906 */ | |
| 7907 bool enableUnusedElement = false; | |
| 7908 | |
| 7909 /** | |
| 7910 * Specifies if [assertErrors] should check for [HintCode.UNUSED_LOCAL_VARIABL
E]. | |
| 7911 */ | |
| 7912 bool enableUnusedLocalVariable = false; | |
| 7913 | |
| 7914 AnalysisContext get analysisContext => analysisContext2; | |
| 7915 | |
| 7916 /** | |
| 7917 * Return a type provider that can be used to test the results of resolution. | |
| 7918 * | |
| 7919 * @return a type provider | |
| 7920 * @throws AnalysisException if dart:core cannot be resolved | |
| 7921 */ | |
| 7922 TypeProvider get typeProvider => analysisContext2.typeProvider; | |
| 7923 | |
| 7924 /** | |
| 7925 * Return a type system that can be used to test the results of resolution. | |
| 7926 * | |
| 7927 * @return a type system | |
| 7928 */ | |
| 7929 TypeSystem get typeSystem => analysisContext2.typeSystem; | |
| 7930 | |
| 7931 /** | |
| 7932 * Add a source file to the content provider. The file path should be absolute
. | |
| 7933 * | |
| 7934 * @param filePath the path of the file being added | |
| 7935 * @param contents the contents to be returned by the content provider for the
specified file | |
| 7936 * @return the source object representing the added file | |
| 7937 */ | |
| 7938 Source addNamedSource(String filePath, String contents) { | |
| 7939 Source source = cacheSource(filePath, contents); | |
| 7940 ChangeSet changeSet = new ChangeSet(); | |
| 7941 changeSet.addedSource(source); | |
| 7942 analysisContext2.applyChanges(changeSet); | |
| 7943 return source; | |
| 7944 } | |
| 7945 | |
| 7946 /** | |
| 7947 * Add a source file to the content provider. | |
| 7948 * | |
| 7949 * @param contents the contents to be returned by the content provider for the
specified file | |
| 7950 * @return the source object representing the added file | |
| 7951 */ | |
| 7952 Source addSource(String contents) => addNamedSource("/test.dart", contents); | |
| 7953 | |
| 7954 /** | |
| 7955 * Assert that the number of errors reported against the given source matches
the number of errors | |
| 7956 * that are given and that they have the expected error codes. The order in wh
ich the errors were | |
| 7957 * gathered is ignored. | |
| 7958 * | |
| 7959 * @param source the source against which the errors should have been reported | |
| 7960 * @param expectedErrorCodes the error codes of the errors that should have be
en reported | |
| 7961 * @throws AnalysisException if the reported errors could not be computed | |
| 7962 * @throws AssertionFailedError if a different number of errors have been repo
rted than were | |
| 7963 * expected | |
| 7964 */ | |
| 7965 void assertErrors(Source source, | |
| 7966 [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) { | |
| 7967 GatheringErrorListener errorListener = new GatheringErrorListener(); | |
| 7968 for (AnalysisError error in analysisContext2.computeErrors(source)) { | |
| 7969 ErrorCode errorCode = error.errorCode; | |
| 7970 if (!enableUnusedElement && | |
| 7971 (errorCode == HintCode.UNUSED_ELEMENT || | |
| 7972 errorCode == HintCode.UNUSED_FIELD)) { | |
| 7973 continue; | |
| 7974 } | |
| 7975 if (!enableUnusedLocalVariable && | |
| 7976 (errorCode == HintCode.UNUSED_CATCH_CLAUSE || | |
| 7977 errorCode == HintCode.UNUSED_CATCH_STACK || | |
| 7978 errorCode == HintCode.UNUSED_LOCAL_VARIABLE)) { | |
| 7979 continue; | |
| 7980 } | |
| 7981 errorListener.onError(error); | |
| 7982 } | |
| 7983 errorListener.assertErrorsWithCodes(expectedErrorCodes); | |
| 7984 } | |
| 7985 | |
| 7986 /** | |
| 7987 * Assert that no errors have been reported against the given source. | |
| 7988 * | |
| 7989 * @param source the source against which no errors should have been reported | |
| 7990 * @throws AnalysisException if the reported errors could not be computed | |
| 7991 * @throws AssertionFailedError if any errors have been reported | |
| 7992 */ | |
| 7993 void assertNoErrors(Source source) { | |
| 7994 assertErrors(source); | |
| 7995 } | |
| 7996 | |
| 7997 /** | |
| 7998 * Cache the source file content in the source factory but don't add the sourc
e to the analysis | |
| 7999 * context. The file path should be absolute. | |
| 8000 * | |
| 8001 * @param filePath the path of the file being cached | |
| 8002 * @param contents the contents to be returned by the content provider for the
specified file | |
| 8003 * @return the source object representing the cached file | |
| 8004 */ | |
| 8005 Source cacheSource(String filePath, String contents) { | |
| 8006 Source source = new FileBasedSource(FileUtilities2.createFile(filePath)); | |
| 8007 analysisContext2.setContents(source, contents); | |
| 8008 return source; | |
| 8009 } | |
| 8010 | |
| 8011 /** | |
| 8012 * Change the contents of the given [source] to the given [contents]. | |
| 8013 */ | |
| 8014 void changeSource(Source source, String contents) { | |
| 8015 analysisContext2.setContents(source, contents); | |
| 8016 ChangeSet changeSet = new ChangeSet(); | |
| 8017 changeSet.changedSource(source); | |
| 8018 analysisContext2.applyChanges(changeSet); | |
| 8019 } | |
| 8020 | |
| 8021 /** | |
| 8022 * Computes errors for the given [librarySource]. | |
| 8023 * This assumes that the given [librarySource] and its parts have already | |
| 8024 * been added to the content provider using the method [addNamedSource]. | |
| 8025 */ | |
| 8026 void computeLibrarySourceErrors(Source librarySource) { | |
| 8027 analysisContext.computeErrors(librarySource); | |
| 8028 } | |
| 8029 | |
| 8030 /** | |
| 8031 * Create a library element that represents a library named `"test"` containin
g a single | |
| 8032 * empty compilation unit. | |
| 8033 * | |
| 8034 * @return the library element that was created | |
| 8035 */ | |
| 8036 LibraryElementImpl createDefaultTestLibrary() => | |
| 8037 createTestLibrary(AnalysisContextFactory.contextWithCore(), "test"); | |
| 8038 | |
| 8039 /** | |
| 8040 * Create a library element that represents a library with the given name cont
aining a single | |
| 8041 * empty compilation unit. | |
| 8042 * | |
| 8043 * @param libraryName the name of the library to be created | |
| 8044 * @return the library element that was created | |
| 8045 */ | |
| 8046 LibraryElementImpl createTestLibrary( | |
| 8047 AnalysisContext context, String libraryName, | |
| 8048 [List<String> typeNames]) { | |
| 8049 String fileName = "$libraryName.dart"; | |
| 8050 FileBasedSource definingCompilationUnitSource = | |
| 8051 _createNamedSource(fileName); | |
| 8052 List<CompilationUnitElement> sourcedCompilationUnits; | |
| 8053 if (typeNames == null) { | |
| 8054 sourcedCompilationUnits = CompilationUnitElement.EMPTY_LIST; | |
| 8055 } else { | |
| 8056 int count = typeNames.length; | |
| 8057 sourcedCompilationUnits = new List<CompilationUnitElement>(count); | |
| 8058 for (int i = 0; i < count; i++) { | |
| 8059 String typeName = typeNames[i]; | |
| 8060 ClassElementImpl type = | |
| 8061 new ClassElementImpl.forNode(AstFactory.identifier3(typeName)); | |
| 8062 String fileName = "$typeName.dart"; | |
| 8063 CompilationUnitElementImpl compilationUnit = | |
| 8064 new CompilationUnitElementImpl(fileName); | |
| 8065 compilationUnit.source = _createNamedSource(fileName); | |
| 8066 compilationUnit.librarySource = definingCompilationUnitSource; | |
| 8067 compilationUnit.types = <ClassElement>[type]; | |
| 8068 sourcedCompilationUnits[i] = compilationUnit; | |
| 8069 } | |
| 8070 } | |
| 8071 CompilationUnitElementImpl compilationUnit = | |
| 8072 new CompilationUnitElementImpl(fileName); | |
| 8073 compilationUnit.librarySource = | |
| 8074 compilationUnit.source = definingCompilationUnitSource; | |
| 8075 LibraryElementImpl library = new LibraryElementImpl.forNode( | |
| 8076 context, AstFactory.libraryIdentifier2([libraryName])); | |
| 8077 library.definingCompilationUnit = compilationUnit; | |
| 8078 library.parts = sourcedCompilationUnits; | |
| 8079 return library; | |
| 8080 } | |
| 8081 | |
| 8082 Expression findTopLevelConstantExpression( | |
| 8083 CompilationUnit compilationUnit, String name) => | |
| 8084 findTopLevelDeclaration(compilationUnit, name).initializer; | |
| 8085 | |
| 8086 VariableDeclaration findTopLevelDeclaration( | |
| 8087 CompilationUnit compilationUnit, String name) { | |
| 8088 for (CompilationUnitMember member in compilationUnit.declarations) { | |
| 8089 if (member is TopLevelVariableDeclaration) { | |
| 8090 for (VariableDeclaration variable in member.variables.variables) { | |
| 8091 if (variable.name.name == name) { | |
| 8092 return variable; | |
| 8093 } | |
| 8094 } | |
| 8095 } | |
| 8096 } | |
| 8097 return null; | |
| 8098 // Not found | |
| 8099 } | |
| 8100 | |
| 8101 /** | |
| 8102 * In the rare cases we want to group several tests into single "test_" method
, so need a way to | |
| 8103 * reset test instance to reuse it. | |
| 8104 */ | |
| 8105 void reset() { | |
| 8106 analysisContext2 = AnalysisContextFactory.contextWithCore(); | |
| 8107 } | |
| 8108 | |
| 8109 /** | |
| 8110 * Reset the analysis context to have the given options applied. | |
| 8111 * | |
| 8112 * @param options the analysis options to be applied to the context | |
| 8113 */ | |
| 8114 void resetWithOptions(AnalysisOptions options) { | |
| 8115 analysisContext2 = | |
| 8116 AnalysisContextFactory.contextWithCoreAndOptions(options); | |
| 8117 } | |
| 8118 | |
| 8119 /** | |
| 8120 * Given a library and all of its parts, resolve the contents of the library a
nd the contents of | |
| 8121 * the parts. This assumes that the sources for the library and its parts have
already been added | |
| 8122 * to the content provider using the method [addNamedSource]. | |
| 8123 * | |
| 8124 * @param librarySource the source for the compilation unit that defines the l
ibrary | |
| 8125 * @return the element representing the resolved library | |
| 8126 * @throws AnalysisException if the analysis could not be performed | |
| 8127 */ | |
| 8128 LibraryElement resolve2(Source librarySource) => | |
| 8129 analysisContext2.computeLibraryElement(librarySource); | |
| 8130 | |
| 8131 /** | |
| 8132 * Return the resolved compilation unit corresponding to the given source in t
he given library. | |
| 8133 * | |
| 8134 * @param source the source of the compilation unit to be returned | |
| 8135 * @param library the library in which the compilation unit is to be resolved | |
| 8136 * @return the resolved compilation unit | |
| 8137 * @throws Exception if the compilation unit could not be resolved | |
| 8138 */ | |
| 8139 CompilationUnit resolveCompilationUnit( | |
| 8140 Source source, LibraryElement library) => | |
| 8141 analysisContext2.resolveCompilationUnit(source, library); | |
| 8142 | |
| 8143 CompilationUnit resolveSource(String sourceText) => | |
| 8144 resolveSource2("/test.dart", sourceText); | |
| 8145 | |
| 8146 CompilationUnit resolveSource2(String fileName, String sourceText) { | |
| 8147 Source source = addNamedSource(fileName, sourceText); | |
| 8148 LibraryElement library = analysisContext.computeLibraryElement(source); | |
| 8149 return analysisContext.resolveCompilationUnit(source, library); | |
| 8150 } | |
| 8151 | |
| 8152 Source resolveSources(List<String> sourceTexts) { | |
| 8153 for (int i = 0; i < sourceTexts.length; i++) { | |
| 8154 CompilationUnit unit = | |
| 8155 resolveSource2("/lib${i + 1}.dart", sourceTexts[i]); | |
| 8156 // reference the source if this is the last source | |
| 8157 if (i + 1 == sourceTexts.length) { | |
| 8158 return unit.element.source; | |
| 8159 } | |
| 8160 } | |
| 8161 return null; | |
| 8162 } | |
| 8163 | |
| 8164 void resolveWithAndWithoutExperimental( | |
| 8165 List<String> strSources, | |
| 8166 List<ErrorCode> codesWithoutExperimental, | |
| 8167 List<ErrorCode> codesWithExperimental) { | |
| 8168 // Setup analysis context as non-experimental | |
| 8169 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); | |
| 8170 // options.enableDeferredLoading = false; | |
| 8171 resetWithOptions(options); | |
| 8172 // Analysis and assertions | |
| 8173 Source source = resolveSources(strSources); | |
| 8174 assertErrors(source, codesWithoutExperimental); | |
| 8175 verify([source]); | |
| 8176 // Setup analysis context as experimental | |
| 8177 reset(); | |
| 8178 // Analysis and assertions | |
| 8179 source = resolveSources(strSources); | |
| 8180 assertErrors(source, codesWithExperimental); | |
| 8181 verify([source]); | |
| 8182 } | |
| 8183 | |
| 8184 void resolveWithErrors(List<String> strSources, List<ErrorCode> codes) { | |
| 8185 // Analysis and assertions | |
| 8186 Source source = resolveSources(strSources); | |
| 8187 assertErrors(source, codes); | |
| 8188 verify([source]); | |
| 8189 } | |
| 8190 | |
| 8191 @override | |
| 8192 void setUp() { | |
| 8193 reset(); | |
| 8194 } | |
| 8195 | |
| 8196 @override | |
| 8197 void tearDown() { | |
| 8198 analysisContext2 = null; | |
| 8199 super.tearDown(); | |
| 8200 } | |
| 8201 | |
| 8202 /** | |
| 8203 * Verify that all of the identifiers in the compilation units associated with | |
| 8204 * the given [sources] have been resolved. | |
| 8205 */ | |
| 8206 void verify(List<Source> sources) { | |
| 8207 ResolutionVerifier verifier = new ResolutionVerifier(); | |
| 8208 for (Source source in sources) { | |
| 8209 List<Source> libraries = analysisContext2.getLibrariesContaining(source); | |
| 8210 for (Source library in libraries) { | |
| 8211 analysisContext2 | |
| 8212 .resolveCompilationUnit2(source, library) | |
| 8213 .accept(verifier); | |
| 8214 } | |
| 8215 } | |
| 8216 verifier.assertResolved(); | |
| 8217 } | |
| 8218 | |
| 8219 /** | |
| 8220 * @param code the code that assigns the value to the variable "v", no matter
how. We check that | |
| 8221 * "v" has expected static and propagated type. | |
| 8222 */ | |
| 8223 void _assertPropagatedAssignedType(String code, DartType expectedStaticType, | |
| 8224 DartType expectedPropagatedType) { | |
| 8225 SimpleIdentifier identifier = _findMarkedIdentifier(code, "v = "); | |
| 8226 expect(identifier.staticType, same(expectedStaticType)); | |
| 8227 expect(identifier.propagatedType, same(expectedPropagatedType)); | |
| 8228 } | |
| 8229 | |
| 8230 /** | |
| 8231 * @param code the code that iterates using variable "v". We check that | |
| 8232 * "v" has expected static and propagated type. | |
| 8233 */ | |
| 8234 void _assertPropagatedIterationType(String code, DartType expectedStaticType, | |
| 8235 DartType expectedPropagatedType) { | |
| 8236 SimpleIdentifier identifier = _findMarkedIdentifier(code, "v in "); | |
| 8237 expect(identifier.staticType, same(expectedStaticType)); | |
| 8238 expect(identifier.propagatedType, same(expectedPropagatedType)); | |
| 8239 } | |
| 8240 | |
| 8241 /** | |
| 8242 * Check the static and propagated types of the expression marked with "; // m
arker" comment. | |
| 8243 * | |
| 8244 * @param code source code to analyze, with the expression to check marked wit
h "// marker". | |
| 8245 * @param expectedStaticType if non-null, check actual static type is equal to
this. | |
| 8246 * @param expectedPropagatedType if non-null, check actual static type is equa
l to this. | |
| 8247 * @throws Exception | |
| 8248 */ | |
| 8249 void _assertTypeOfMarkedExpression(String code, DartType expectedStaticType, | |
| 8250 DartType expectedPropagatedType) { | |
| 8251 SimpleIdentifier identifier = _findMarkedIdentifier(code, "; // marker"); | |
| 8252 if (expectedStaticType != null) { | |
| 8253 expect(identifier.staticType, expectedStaticType); | |
| 8254 } | |
| 8255 expect(identifier.propagatedType, expectedPropagatedType); | |
| 8256 } | |
| 8257 | |
| 8258 /** | |
| 8259 * Create a source object representing a file with the given [fileName] and | |
| 8260 * give it an empty content. Return the source that was created. | |
| 8261 */ | |
| 8262 FileBasedSource _createNamedSource(String fileName) { | |
| 8263 FileBasedSource source = | |
| 8264 new FileBasedSource(FileUtilities2.createFile(fileName)); | |
| 8265 analysisContext2.setContents(source, ""); | |
| 8266 return source; | |
| 8267 } | |
| 8268 | |
| 8269 /** | |
| 8270 * Return the `SimpleIdentifier` marked by `marker`. The source code must have
no | |
| 8271 * errors and be verifiable. | |
| 8272 * | |
| 8273 * @param code source code to analyze. | |
| 8274 * @param marker marker identifying sought after expression in source code. | |
| 8275 * @return expression marked by the marker. | |
| 8276 * @throws Exception | |
| 8277 */ | |
| 8278 SimpleIdentifier _findMarkedIdentifier(String code, String marker) { | |
| 8279 try { | |
| 8280 Source source = addSource(code); | |
| 8281 LibraryElement library = resolve2(source); | |
| 8282 assertNoErrors(source); | |
| 8283 verify([source]); | |
| 8284 CompilationUnit unit = resolveCompilationUnit(source, library); | |
| 8285 // Could generalize this further by making [SimpleIdentifier.class] a | |
| 8286 // parameter. | |
| 8287 return EngineTestCase.findNode( | |
| 8288 unit, code, marker, (node) => node is SimpleIdentifier); | |
| 8289 } catch (exception) { | |
| 8290 // Is there a better exception to throw here? The point is that an | |
| 8291 // assertion failure here should be a failure, in both "test_*" and | |
| 8292 // "fail_*" tests. However, an assertion failure is success for the | |
| 8293 // purpose of "fail_*" tests, so without catching them here "fail_*" tests | |
| 8294 // can succeed by failing for the wrong reason. | |
| 8295 throw new JavaException("Unexexpected assertion failure: $exception"); | |
| 8296 } | |
| 8297 } | |
| 8298 } | |
| 8299 | |
| 8300 class Scope_EnclosedScopeTest_test_define_duplicate extends Scope { | |
| 8301 GatheringErrorListener listener; | |
| 8302 | |
| 8303 Scope_EnclosedScopeTest_test_define_duplicate(this.listener) : super(); | |
| 8304 | |
| 8305 @override | |
| 8306 AnalysisErrorListener get errorListener => listener; | |
| 8307 | |
| 8308 @override | |
| 8309 Element internalLookup(Identifier identifier, String name, | |
| 8310 LibraryElement referencingLibrary) => | |
| 8311 null; | |
| 8312 } | |
| 8313 | |
| 8314 class Scope_EnclosedScopeTest_test_define_normal extends Scope { | |
| 8315 GatheringErrorListener listener; | |
| 8316 | |
| 8317 Scope_EnclosedScopeTest_test_define_normal(this.listener) : super(); | |
| 8318 | |
| 8319 @override | |
| 8320 AnalysisErrorListener get errorListener => listener; | |
| 8321 | |
| 8322 @override | |
| 8323 Element internalLookup(Identifier identifier, String name, | |
| 8324 LibraryElement referencingLibrary) => | |
| 8325 null; | |
| 8326 } | 368 } |
| 8327 | 369 |
| 8328 @reflectiveTest | 370 @reflectiveTest |
| 8329 class ScopeTest extends ResolverTestCase { | 371 class ScopeTest extends ResolverTestCase { |
| 8330 void test_define_duplicate() { | 372 void test_define_duplicate() { |
| 8331 GatheringErrorListener errorListener = new GatheringErrorListener(); | 373 Scope scope = new _RootScope(); |
| 8332 ScopeTest_TestScope scope = new ScopeTest_TestScope(errorListener); | 374 SimpleIdentifier identifier = AstFactory.identifier3('v'); |
| 8333 VariableElement element1 = | 375 VariableElement element1 = ElementFactory.localVariableElement(identifier); |
| 8334 ElementFactory.localVariableElement(AstFactory.identifier3("v1")); | 376 VariableElement element2 = ElementFactory.localVariableElement(identifier); |
| 8335 VariableElement element2 = | |
| 8336 ElementFactory.localVariableElement(AstFactory.identifier3("v1")); | |
| 8337 scope.define(element1); | 377 scope.define(element1); |
| 8338 scope.define(element2); | 378 scope.define(element2); |
| 8339 errorListener.assertErrorsWithSeverities([ErrorSeverity.ERROR]); | 379 expect(scope.localLookup('v', null), same(element1)); |
| 8340 } | |
| 8341 | |
| 8342 void test_define_normal() { | |
| 8343 GatheringErrorListener errorListener = new GatheringErrorListener(); | |
| 8344 ScopeTest_TestScope scope = new ScopeTest_TestScope(errorListener); | |
| 8345 VariableElement element1 = | |
| 8346 ElementFactory.localVariableElement(AstFactory.identifier3("v1")); | |
| 8347 VariableElement element2 = | |
| 8348 ElementFactory.localVariableElement(AstFactory.identifier3("v2")); | |
| 8349 scope.define(element1); | |
| 8350 scope.define(element2); | |
| 8351 errorListener.assertNoErrors(); | |
| 8352 } | |
| 8353 | |
| 8354 void test_getErrorListener() { | |
| 8355 GatheringErrorListener errorListener = new GatheringErrorListener(); | |
| 8356 ScopeTest_TestScope scope = new ScopeTest_TestScope(errorListener); | |
| 8357 expect(scope.errorListener, errorListener); | |
| 8358 } | 380 } |
| 8359 | 381 |
| 8360 void test_isPrivateName_nonPrivate() { | 382 void test_isPrivateName_nonPrivate() { |
| 8361 expect(Scope.isPrivateName("Public"), isFalse); | 383 expect(Scope.isPrivateName("Public"), isFalse); |
| 8362 } | 384 } |
| 8363 | 385 |
| 8364 void test_isPrivateName_private() { | 386 void test_isPrivateName_private() { |
| 8365 expect(Scope.isPrivateName("_Private"), isTrue); | 387 expect(Scope.isPrivateName("_Private"), isTrue); |
| 8366 } | 388 } |
| 8367 } | 389 } |
| 8368 | 390 |
| 8369 /** | |
| 8370 * A non-abstract subclass that can be used for testing purposes. | |
| 8371 */ | |
| 8372 class ScopeTest_TestScope extends Scope { | |
| 8373 /** | |
| 8374 * The listener that is to be informed when an error is encountered. | |
| 8375 */ | |
| 8376 final AnalysisErrorListener errorListener; | |
| 8377 | |
| 8378 ScopeTest_TestScope(this.errorListener); | |
| 8379 | |
| 8380 @override | |
| 8381 Element internalLookup(Identifier identifier, String name, | |
| 8382 LibraryElement referencingLibrary) => | |
| 8383 localLookup(name, referencingLibrary); | |
| 8384 } | |
| 8385 | |
| 8386 @reflectiveTest | |
| 8387 class SimpleResolverTest extends ResolverTestCase { | |
| 8388 void fail_getter_and_setter_fromMixins_property_access() { | |
| 8389 // TODO(paulberry): it appears that auxiliaryElements isn't properly set on | |
| 8390 // a SimpleIdentifier that's inside a property access. This bug should be | |
| 8391 // fixed. | |
| 8392 Source source = addSource(''' | |
| 8393 class B {} | |
| 8394 class M1 { | |
| 8395 get x => null; | |
| 8396 set x(value) {} | |
| 8397 } | |
| 8398 class M2 { | |
| 8399 get x => null; | |
| 8400 set x(value) {} | |
| 8401 } | |
| 8402 class C extends B with M1, M2 {} | |
| 8403 void main() { | |
| 8404 new C().x += 1; | |
| 8405 } | |
| 8406 '''); | |
| 8407 LibraryElement library = resolve2(source); | |
| 8408 assertNoErrors(source); | |
| 8409 verify([source]); | |
| 8410 // Verify that both the getter and setter for "x" in "new C().x" refer to | |
| 8411 // the accessors defined in M2. | |
| 8412 FunctionDeclaration main = | |
| 8413 library.definingCompilationUnit.functions[0].computeNode(); | |
| 8414 BlockFunctionBody body = main.functionExpression.body; | |
| 8415 ExpressionStatement stmt = body.block.statements[0]; | |
| 8416 AssignmentExpression assignment = stmt.expression; | |
| 8417 PropertyAccess propertyAccess = assignment.leftHandSide; | |
| 8418 expect( | |
| 8419 propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2'); | |
| 8420 expect( | |
| 8421 propertyAccess | |
| 8422 .propertyName.auxiliaryElements.staticElement.enclosingElement.name, | |
| 8423 'M2'); | |
| 8424 } | |
| 8425 | |
| 8426 void fail_staticInvocation() { | |
| 8427 Source source = addSource(r''' | |
| 8428 class A { | |
| 8429 static int get g => (a,b) => 0; | |
| 8430 } | |
| 8431 class B { | |
| 8432 f() { | |
| 8433 A.g(1,0); | |
| 8434 } | |
| 8435 }'''); | |
| 8436 computeLibrarySourceErrors(source); | |
| 8437 assertNoErrors(source); | |
| 8438 verify([source]); | |
| 8439 } | |
| 8440 | |
| 8441 void test_argumentResolution_required_matching() { | |
| 8442 Source source = addSource(r''' | |
| 8443 class A { | |
| 8444 void f() { | |
| 8445 g(1, 2, 3); | |
| 8446 } | |
| 8447 void g(a, b, c) {} | |
| 8448 }'''); | |
| 8449 _validateArgumentResolution(source, [0, 1, 2]); | |
| 8450 } | |
| 8451 | |
| 8452 void test_argumentResolution_required_tooFew() { | |
| 8453 Source source = addSource(r''' | |
| 8454 class A { | |
| 8455 void f() { | |
| 8456 g(1, 2); | |
| 8457 } | |
| 8458 void g(a, b, c) {} | |
| 8459 }'''); | |
| 8460 _validateArgumentResolution(source, [0, 1]); | |
| 8461 } | |
| 8462 | |
| 8463 void test_argumentResolution_required_tooMany() { | |
| 8464 Source source = addSource(r''' | |
| 8465 class A { | |
| 8466 void f() { | |
| 8467 g(1, 2, 3); | |
| 8468 } | |
| 8469 void g(a, b) {} | |
| 8470 }'''); | |
| 8471 _validateArgumentResolution(source, [0, 1, -1]); | |
| 8472 } | |
| 8473 | |
| 8474 void test_argumentResolution_requiredAndNamed_extra() { | |
| 8475 Source source = addSource(r''' | |
| 8476 class A { | |
| 8477 void f() { | |
| 8478 g(1, 2, c: 3, d: 4); | |
| 8479 } | |
| 8480 void g(a, b, {c}) {} | |
| 8481 }'''); | |
| 8482 _validateArgumentResolution(source, [0, 1, 2, -1]); | |
| 8483 } | |
| 8484 | |
| 8485 void test_argumentResolution_requiredAndNamed_matching() { | |
| 8486 Source source = addSource(r''' | |
| 8487 class A { | |
| 8488 void f() { | |
| 8489 g(1, 2, c: 3); | |
| 8490 } | |
| 8491 void g(a, b, {c}) {} | |
| 8492 }'''); | |
| 8493 _validateArgumentResolution(source, [0, 1, 2]); | |
| 8494 } | |
| 8495 | |
| 8496 void test_argumentResolution_requiredAndNamed_missing() { | |
| 8497 Source source = addSource(r''' | |
| 8498 class A { | |
| 8499 void f() { | |
| 8500 g(1, 2, d: 3); | |
| 8501 } | |
| 8502 void g(a, b, {c, d}) {} | |
| 8503 }'''); | |
| 8504 _validateArgumentResolution(source, [0, 1, 3]); | |
| 8505 } | |
| 8506 | |
| 8507 void test_argumentResolution_requiredAndPositional_fewer() { | |
| 8508 Source source = addSource(r''' | |
| 8509 class A { | |
| 8510 void f() { | |
| 8511 g(1, 2, 3); | |
| 8512 } | |
| 8513 void g(a, b, [c, d]) {} | |
| 8514 }'''); | |
| 8515 _validateArgumentResolution(source, [0, 1, 2]); | |
| 8516 } | |
| 8517 | |
| 8518 void test_argumentResolution_requiredAndPositional_matching() { | |
| 8519 Source source = addSource(r''' | |
| 8520 class A { | |
| 8521 void f() { | |
| 8522 g(1, 2, 3, 4); | |
| 8523 } | |
| 8524 void g(a, b, [c, d]) {} | |
| 8525 }'''); | |
| 8526 _validateArgumentResolution(source, [0, 1, 2, 3]); | |
| 8527 } | |
| 8528 | |
| 8529 void test_argumentResolution_requiredAndPositional_more() { | |
| 8530 Source source = addSource(r''' | |
| 8531 class A { | |
| 8532 void f() { | |
| 8533 g(1, 2, 3, 4); | |
| 8534 } | |
| 8535 void g(a, b, [c]) {} | |
| 8536 }'''); | |
| 8537 _validateArgumentResolution(source, [0, 1, 2, -1]); | |
| 8538 } | |
| 8539 | |
| 8540 void test_argumentResolution_setter_propagated() { | |
| 8541 Source source = addSource(r''' | |
| 8542 main() { | |
| 8543 var a = new A(); | |
| 8544 a.sss = 0; | |
| 8545 } | |
| 8546 class A { | |
| 8547 set sss(x) {} | |
| 8548 }'''); | |
| 8549 LibraryElement library = resolve2(source); | |
| 8550 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 8551 // find "a.sss = 0" | |
| 8552 AssignmentExpression assignment; | |
| 8553 { | |
| 8554 FunctionElement mainElement = unit.functions[0]; | |
| 8555 FunctionBody mainBody = mainElement.computeNode().functionExpression.body; | |
| 8556 Statement statement = (mainBody as BlockFunctionBody).block.statements[1]; | |
| 8557 ExpressionStatement expressionStatement = | |
| 8558 statement as ExpressionStatement; | |
| 8559 assignment = expressionStatement.expression as AssignmentExpression; | |
| 8560 } | |
| 8561 // get parameter | |
| 8562 Expression rhs = assignment.rightHandSide; | |
| 8563 expect(rhs.staticParameterElement, isNull); | |
| 8564 ParameterElement parameter = rhs.propagatedParameterElement; | |
| 8565 expect(parameter, isNotNull); | |
| 8566 expect(parameter.displayName, "x"); | |
| 8567 // validate | |
| 8568 ClassElement classA = unit.types[0]; | |
| 8569 PropertyAccessorElement setter = classA.accessors[0]; | |
| 8570 expect(setter.parameters[0], same(parameter)); | |
| 8571 } | |
| 8572 | |
| 8573 void test_argumentResolution_setter_propagated_propertyAccess() { | |
| 8574 Source source = addSource(r''' | |
| 8575 main() { | |
| 8576 var a = new A(); | |
| 8577 a.b.sss = 0; | |
| 8578 } | |
| 8579 class A { | |
| 8580 B b = new B(); | |
| 8581 } | |
| 8582 class B { | |
| 8583 set sss(x) {} | |
| 8584 }'''); | |
| 8585 LibraryElement library = resolve2(source); | |
| 8586 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 8587 // find "a.b.sss = 0" | |
| 8588 AssignmentExpression assignment; | |
| 8589 { | |
| 8590 FunctionElement mainElement = unit.functions[0]; | |
| 8591 FunctionBody mainBody = mainElement.computeNode().functionExpression.body; | |
| 8592 Statement statement = (mainBody as BlockFunctionBody).block.statements[1]; | |
| 8593 ExpressionStatement expressionStatement = | |
| 8594 statement as ExpressionStatement; | |
| 8595 assignment = expressionStatement.expression as AssignmentExpression; | |
| 8596 } | |
| 8597 // get parameter | |
| 8598 Expression rhs = assignment.rightHandSide; | |
| 8599 expect(rhs.staticParameterElement, isNull); | |
| 8600 ParameterElement parameter = rhs.propagatedParameterElement; | |
| 8601 expect(parameter, isNotNull); | |
| 8602 expect(parameter.displayName, "x"); | |
| 8603 // validate | |
| 8604 ClassElement classB = unit.types[1]; | |
| 8605 PropertyAccessorElement setter = classB.accessors[0]; | |
| 8606 expect(setter.parameters[0], same(parameter)); | |
| 8607 } | |
| 8608 | |
| 8609 void test_argumentResolution_setter_static() { | |
| 8610 Source source = addSource(r''' | |
| 8611 main() { | |
| 8612 A a = new A(); | |
| 8613 a.sss = 0; | |
| 8614 } | |
| 8615 class A { | |
| 8616 set sss(x) {} | |
| 8617 }'''); | |
| 8618 LibraryElement library = resolve2(source); | |
| 8619 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 8620 // find "a.sss = 0" | |
| 8621 AssignmentExpression assignment; | |
| 8622 { | |
| 8623 FunctionElement mainElement = unit.functions[0]; | |
| 8624 FunctionBody mainBody = mainElement.computeNode().functionExpression.body; | |
| 8625 Statement statement = (mainBody as BlockFunctionBody).block.statements[1]; | |
| 8626 ExpressionStatement expressionStatement = | |
| 8627 statement as ExpressionStatement; | |
| 8628 assignment = expressionStatement.expression as AssignmentExpression; | |
| 8629 } | |
| 8630 // get parameter | |
| 8631 Expression rhs = assignment.rightHandSide; | |
| 8632 ParameterElement parameter = rhs.staticParameterElement; | |
| 8633 expect(parameter, isNotNull); | |
| 8634 expect(parameter.displayName, "x"); | |
| 8635 // validate | |
| 8636 ClassElement classA = unit.types[0]; | |
| 8637 PropertyAccessorElement setter = classA.accessors[0]; | |
| 8638 expect(setter.parameters[0], same(parameter)); | |
| 8639 } | |
| 8640 | |
| 8641 void test_argumentResolution_setter_static_propertyAccess() { | |
| 8642 Source source = addSource(r''' | |
| 8643 main() { | |
| 8644 A a = new A(); | |
| 8645 a.b.sss = 0; | |
| 8646 } | |
| 8647 class A { | |
| 8648 B b = new B(); | |
| 8649 } | |
| 8650 class B { | |
| 8651 set sss(x) {} | |
| 8652 }'''); | |
| 8653 LibraryElement library = resolve2(source); | |
| 8654 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 8655 // find "a.b.sss = 0" | |
| 8656 AssignmentExpression assignment; | |
| 8657 { | |
| 8658 FunctionElement mainElement = unit.functions[0]; | |
| 8659 FunctionBody mainBody = mainElement.computeNode().functionExpression.body; | |
| 8660 Statement statement = (mainBody as BlockFunctionBody).block.statements[1]; | |
| 8661 ExpressionStatement expressionStatement = | |
| 8662 statement as ExpressionStatement; | |
| 8663 assignment = expressionStatement.expression as AssignmentExpression; | |
| 8664 } | |
| 8665 // get parameter | |
| 8666 Expression rhs = assignment.rightHandSide; | |
| 8667 ParameterElement parameter = rhs.staticParameterElement; | |
| 8668 expect(parameter, isNotNull); | |
| 8669 expect(parameter.displayName, "x"); | |
| 8670 // validate | |
| 8671 ClassElement classB = unit.types[1]; | |
| 8672 PropertyAccessorElement setter = classB.accessors[0]; | |
| 8673 expect(setter.parameters[0], same(parameter)); | |
| 8674 } | |
| 8675 | |
| 8676 void test_breakTarget_labeled() { | |
| 8677 // Verify that the target of the label is correctly found and is recorded | |
| 8678 // as the unlabeled portion of the statement. | |
| 8679 String text = r''' | |
| 8680 void f() { | |
| 8681 loop1: while (true) { | |
| 8682 loop2: for (int i = 0; i < 10; i++) { | |
| 8683 break loop1; | |
| 8684 break loop2; | |
| 8685 } | |
| 8686 } | |
| 8687 } | |
| 8688 '''; | |
| 8689 CompilationUnit unit = resolveSource(text); | |
| 8690 WhileStatement whileStatement = EngineTestCase.findNode( | |
| 8691 unit, text, 'while (true)', (n) => n is WhileStatement); | |
| 8692 ForStatement forStatement = | |
| 8693 EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement); | |
| 8694 BreakStatement break1 = EngineTestCase.findNode( | |
| 8695 unit, text, 'break loop1', (n) => n is BreakStatement); | |
| 8696 BreakStatement break2 = EngineTestCase.findNode( | |
| 8697 unit, text, 'break loop2', (n) => n is BreakStatement); | |
| 8698 expect(break1.target, same(whileStatement)); | |
| 8699 expect(break2.target, same(forStatement)); | |
| 8700 } | |
| 8701 | |
| 8702 void test_breakTarget_unlabeledBreakFromDo() { | |
| 8703 String text = r''' | |
| 8704 void f() { | |
| 8705 do { | |
| 8706 break; | |
| 8707 } while (true); | |
| 8708 } | |
| 8709 '''; | |
| 8710 CompilationUnit unit = resolveSource(text); | |
| 8711 DoStatement doStatement = | |
| 8712 EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement); | |
| 8713 BreakStatement breakStatement = EngineTestCase.findNode( | |
| 8714 unit, text, 'break', (n) => n is BreakStatement); | |
| 8715 expect(breakStatement.target, same(doStatement)); | |
| 8716 } | |
| 8717 | |
| 8718 void test_breakTarget_unlabeledBreakFromFor() { | |
| 8719 String text = r''' | |
| 8720 void f() { | |
| 8721 for (int i = 0; i < 10; i++) { | |
| 8722 break; | |
| 8723 } | |
| 8724 } | |
| 8725 '''; | |
| 8726 CompilationUnit unit = resolveSource(text); | |
| 8727 ForStatement forStatement = | |
| 8728 EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement); | |
| 8729 BreakStatement breakStatement = EngineTestCase.findNode( | |
| 8730 unit, text, 'break', (n) => n is BreakStatement); | |
| 8731 expect(breakStatement.target, same(forStatement)); | |
| 8732 } | |
| 8733 | |
| 8734 void test_breakTarget_unlabeledBreakFromForEach() { | |
| 8735 String text = r''' | |
| 8736 void f() { | |
| 8737 for (x in []) { | |
| 8738 break; | |
| 8739 } | |
| 8740 } | |
| 8741 '''; | |
| 8742 CompilationUnit unit = resolveSource(text); | |
| 8743 ForEachStatement forStatement = EngineTestCase.findNode( | |
| 8744 unit, text, 'for', (n) => n is ForEachStatement); | |
| 8745 BreakStatement breakStatement = EngineTestCase.findNode( | |
| 8746 unit, text, 'break', (n) => n is BreakStatement); | |
| 8747 expect(breakStatement.target, same(forStatement)); | |
| 8748 } | |
| 8749 | |
| 8750 void test_breakTarget_unlabeledBreakFromSwitch() { | |
| 8751 String text = r''' | |
| 8752 void f() { | |
| 8753 while (true) { | |
| 8754 switch (0) { | |
| 8755 case 0: | |
| 8756 break; | |
| 8757 } | |
| 8758 } | |
| 8759 } | |
| 8760 '''; | |
| 8761 CompilationUnit unit = resolveSource(text); | |
| 8762 SwitchStatement switchStatement = EngineTestCase.findNode( | |
| 8763 unit, text, 'switch', (n) => n is SwitchStatement); | |
| 8764 BreakStatement breakStatement = EngineTestCase.findNode( | |
| 8765 unit, text, 'break', (n) => n is BreakStatement); | |
| 8766 expect(breakStatement.target, same(switchStatement)); | |
| 8767 } | |
| 8768 | |
| 8769 void test_breakTarget_unlabeledBreakFromWhile() { | |
| 8770 String text = r''' | |
| 8771 void f() { | |
| 8772 while (true) { | |
| 8773 break; | |
| 8774 } | |
| 8775 } | |
| 8776 '''; | |
| 8777 CompilationUnit unit = resolveSource(text); | |
| 8778 WhileStatement whileStatement = EngineTestCase.findNode( | |
| 8779 unit, text, 'while', (n) => n is WhileStatement); | |
| 8780 BreakStatement breakStatement = EngineTestCase.findNode( | |
| 8781 unit, text, 'break', (n) => n is BreakStatement); | |
| 8782 expect(breakStatement.target, same(whileStatement)); | |
| 8783 } | |
| 8784 | |
| 8785 void test_breakTarget_unlabeledBreakToOuterFunction() { | |
| 8786 // Verify that unlabeled break statements can't resolve to loops in an | |
| 8787 // outer function. | |
| 8788 String text = r''' | |
| 8789 void f() { | |
| 8790 while (true) { | |
| 8791 void g() { | |
| 8792 break; | |
| 8793 } | |
| 8794 } | |
| 8795 } | |
| 8796 '''; | |
| 8797 CompilationUnit unit = resolveSource(text); | |
| 8798 BreakStatement breakStatement = EngineTestCase.findNode( | |
| 8799 unit, text, 'break', (n) => n is BreakStatement); | |
| 8800 expect(breakStatement.target, isNull); | |
| 8801 } | |
| 8802 | |
| 8803 void test_class_definesCall() { | |
| 8804 Source source = addSource(r''' | |
| 8805 class A { | |
| 8806 int call(int x) { return x; } | |
| 8807 } | |
| 8808 int f(A a) { | |
| 8809 return a(0); | |
| 8810 }'''); | |
| 8811 computeLibrarySourceErrors(source); | |
| 8812 assertNoErrors(source); | |
| 8813 verify([source]); | |
| 8814 } | |
| 8815 | |
| 8816 void test_class_extends_implements() { | |
| 8817 Source source = addSource(r''' | |
| 8818 class A extends B implements C {} | |
| 8819 class B {} | |
| 8820 class C {}'''); | |
| 8821 computeLibrarySourceErrors(source); | |
| 8822 assertNoErrors(source); | |
| 8823 verify([source]); | |
| 8824 } | |
| 8825 | |
| 8826 void test_commentReference_class() { | |
| 8827 Source source = addSource(r''' | |
| 8828 f() {} | |
| 8829 /** [A] [new A] [A.n] [new A.n] [m] [f] */ | |
| 8830 class A { | |
| 8831 A() {} | |
| 8832 A.n() {} | |
| 8833 m() {} | |
| 8834 }'''); | |
| 8835 computeLibrarySourceErrors(source); | |
| 8836 assertNoErrors(source); | |
| 8837 verify([source]); | |
| 8838 } | |
| 8839 | |
| 8840 void test_commentReference_parameter() { | |
| 8841 Source source = addSource(r''' | |
| 8842 class A { | |
| 8843 A() {} | |
| 8844 A.n() {} | |
| 8845 /** [e] [f] */ | |
| 8846 m(e, f()) {} | |
| 8847 }'''); | |
| 8848 computeLibrarySourceErrors(source); | |
| 8849 assertNoErrors(source); | |
| 8850 verify([source]); | |
| 8851 } | |
| 8852 | |
| 8853 void test_commentReference_singleLine() { | |
| 8854 Source source = addSource(r''' | |
| 8855 /// [A] | |
| 8856 class A {}'''); | |
| 8857 computeLibrarySourceErrors(source); | |
| 8858 assertNoErrors(source); | |
| 8859 verify([source]); | |
| 8860 } | |
| 8861 | |
| 8862 void test_continueTarget_labeled() { | |
| 8863 // Verify that the target of the label is correctly found and is recorded | |
| 8864 // as the unlabeled portion of the statement. | |
| 8865 String text = r''' | |
| 8866 void f() { | |
| 8867 loop1: while (true) { | |
| 8868 loop2: for (int i = 0; i < 10; i++) { | |
| 8869 continue loop1; | |
| 8870 continue loop2; | |
| 8871 } | |
| 8872 } | |
| 8873 } | |
| 8874 '''; | |
| 8875 CompilationUnit unit = resolveSource(text); | |
| 8876 WhileStatement whileStatement = EngineTestCase.findNode( | |
| 8877 unit, text, 'while (true)', (n) => n is WhileStatement); | |
| 8878 ForStatement forStatement = | |
| 8879 EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement); | |
| 8880 ContinueStatement continue1 = EngineTestCase.findNode( | |
| 8881 unit, text, 'continue loop1', (n) => n is ContinueStatement); | |
| 8882 ContinueStatement continue2 = EngineTestCase.findNode( | |
| 8883 unit, text, 'continue loop2', (n) => n is ContinueStatement); | |
| 8884 expect(continue1.target, same(whileStatement)); | |
| 8885 expect(continue2.target, same(forStatement)); | |
| 8886 } | |
| 8887 | |
| 8888 void test_continueTarget_unlabeledContinueFromDo() { | |
| 8889 String text = r''' | |
| 8890 void f() { | |
| 8891 do { | |
| 8892 continue; | |
| 8893 } while (true); | |
| 8894 } | |
| 8895 '''; | |
| 8896 CompilationUnit unit = resolveSource(text); | |
| 8897 DoStatement doStatement = | |
| 8898 EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement); | |
| 8899 ContinueStatement continueStatement = EngineTestCase.findNode( | |
| 8900 unit, text, 'continue', (n) => n is ContinueStatement); | |
| 8901 expect(continueStatement.target, same(doStatement)); | |
| 8902 } | |
| 8903 | |
| 8904 void test_continueTarget_unlabeledContinueFromFor() { | |
| 8905 String text = r''' | |
| 8906 void f() { | |
| 8907 for (int i = 0; i < 10; i++) { | |
| 8908 continue; | |
| 8909 } | |
| 8910 } | |
| 8911 '''; | |
| 8912 CompilationUnit unit = resolveSource(text); | |
| 8913 ForStatement forStatement = | |
| 8914 EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement); | |
| 8915 ContinueStatement continueStatement = EngineTestCase.findNode( | |
| 8916 unit, text, 'continue', (n) => n is ContinueStatement); | |
| 8917 expect(continueStatement.target, same(forStatement)); | |
| 8918 } | |
| 8919 | |
| 8920 void test_continueTarget_unlabeledContinueFromForEach() { | |
| 8921 String text = r''' | |
| 8922 void f() { | |
| 8923 for (x in []) { | |
| 8924 continue; | |
| 8925 } | |
| 8926 } | |
| 8927 '''; | |
| 8928 CompilationUnit unit = resolveSource(text); | |
| 8929 ForEachStatement forStatement = EngineTestCase.findNode( | |
| 8930 unit, text, 'for', (n) => n is ForEachStatement); | |
| 8931 ContinueStatement continueStatement = EngineTestCase.findNode( | |
| 8932 unit, text, 'continue', (n) => n is ContinueStatement); | |
| 8933 expect(continueStatement.target, same(forStatement)); | |
| 8934 } | |
| 8935 | |
| 8936 void test_continueTarget_unlabeledContinueFromWhile() { | |
| 8937 String text = r''' | |
| 8938 void f() { | |
| 8939 while (true) { | |
| 8940 continue; | |
| 8941 } | |
| 8942 } | |
| 8943 '''; | |
| 8944 CompilationUnit unit = resolveSource(text); | |
| 8945 WhileStatement whileStatement = EngineTestCase.findNode( | |
| 8946 unit, text, 'while', (n) => n is WhileStatement); | |
| 8947 ContinueStatement continueStatement = EngineTestCase.findNode( | |
| 8948 unit, text, 'continue', (n) => n is ContinueStatement); | |
| 8949 expect(continueStatement.target, same(whileStatement)); | |
| 8950 } | |
| 8951 | |
| 8952 void test_continueTarget_unlabeledContinueSkipsSwitch() { | |
| 8953 String text = r''' | |
| 8954 void f() { | |
| 8955 while (true) { | |
| 8956 switch (0) { | |
| 8957 case 0: | |
| 8958 continue; | |
| 8959 } | |
| 8960 } | |
| 8961 } | |
| 8962 '''; | |
| 8963 CompilationUnit unit = resolveSource(text); | |
| 8964 WhileStatement whileStatement = EngineTestCase.findNode( | |
| 8965 unit, text, 'while', (n) => n is WhileStatement); | |
| 8966 ContinueStatement continueStatement = EngineTestCase.findNode( | |
| 8967 unit, text, 'continue', (n) => n is ContinueStatement); | |
| 8968 expect(continueStatement.target, same(whileStatement)); | |
| 8969 } | |
| 8970 | |
| 8971 void test_continueTarget_unlabeledContinueToOuterFunction() { | |
| 8972 // Verify that unlabeled continue statements can't resolve to loops in an | |
| 8973 // outer function. | |
| 8974 String text = r''' | |
| 8975 void f() { | |
| 8976 while (true) { | |
| 8977 void g() { | |
| 8978 continue; | |
| 8979 } | |
| 8980 } | |
| 8981 } | |
| 8982 '''; | |
| 8983 CompilationUnit unit = resolveSource(text); | |
| 8984 ContinueStatement continueStatement = EngineTestCase.findNode( | |
| 8985 unit, text, 'continue', (n) => n is ContinueStatement); | |
| 8986 expect(continueStatement.target, isNull); | |
| 8987 } | |
| 8988 | |
| 8989 void test_empty() { | |
| 8990 Source source = addSource(""); | |
| 8991 computeLibrarySourceErrors(source); | |
| 8992 assertNoErrors(source); | |
| 8993 verify([source]); | |
| 8994 } | |
| 8995 | |
| 8996 void test_entryPoint_exported() { | |
| 8997 addNamedSource( | |
| 8998 "/two.dart", | |
| 8999 r''' | |
| 9000 library two; | |
| 9001 main() {}'''); | |
| 9002 Source source = addNamedSource( | |
| 9003 "/one.dart", | |
| 9004 r''' | |
| 9005 library one; | |
| 9006 export 'two.dart';'''); | |
| 9007 LibraryElement library = resolve2(source); | |
| 9008 expect(library, isNotNull); | |
| 9009 FunctionElement main = library.entryPoint; | |
| 9010 expect(main, isNotNull); | |
| 9011 expect(main.library, isNot(same(library))); | |
| 9012 assertNoErrors(source); | |
| 9013 verify([source]); | |
| 9014 } | |
| 9015 | |
| 9016 void test_entryPoint_local() { | |
| 9017 Source source = addNamedSource( | |
| 9018 "/one.dart", | |
| 9019 r''' | |
| 9020 library one; | |
| 9021 main() {}'''); | |
| 9022 LibraryElement library = resolve2(source); | |
| 9023 expect(library, isNotNull); | |
| 9024 FunctionElement main = library.entryPoint; | |
| 9025 expect(main, isNotNull); | |
| 9026 expect(main.library, same(library)); | |
| 9027 assertNoErrors(source); | |
| 9028 verify([source]); | |
| 9029 } | |
| 9030 | |
| 9031 void test_entryPoint_none() { | |
| 9032 Source source = addNamedSource("/one.dart", "library one;"); | |
| 9033 LibraryElement library = resolve2(source); | |
| 9034 expect(library, isNotNull); | |
| 9035 expect(library.entryPoint, isNull); | |
| 9036 assertNoErrors(source); | |
| 9037 verify([source]); | |
| 9038 } | |
| 9039 | |
| 9040 void test_enum_externalLibrary() { | |
| 9041 addNamedSource( | |
| 9042 "/my_lib.dart", | |
| 9043 r''' | |
| 9044 library my_lib; | |
| 9045 enum EEE {A, B, C}'''); | |
| 9046 Source source = addSource(r''' | |
| 9047 import 'my_lib.dart'; | |
| 9048 main() { | |
| 9049 EEE e = null; | |
| 9050 }'''); | |
| 9051 computeLibrarySourceErrors(source); | |
| 9052 assertNoErrors(source); | |
| 9053 verify([source]); | |
| 9054 } | |
| 9055 | |
| 9056 void test_extractedMethodAsConstant() { | |
| 9057 Source source = addSource(r''' | |
| 9058 abstract class Comparable<T> { | |
| 9059 int compareTo(T other); | |
| 9060 static int compare(Comparable a, Comparable b) => a.compareTo(b); | |
| 9061 } | |
| 9062 class A { | |
| 9063 void sort([compare = Comparable.compare]) {} | |
| 9064 }'''); | |
| 9065 computeLibrarySourceErrors(source); | |
| 9066 assertNoErrors(source); | |
| 9067 verify([source]); | |
| 9068 } | |
| 9069 | |
| 9070 void test_fieldFormalParameter() { | |
| 9071 Source source = addSource(r''' | |
| 9072 class A { | |
| 9073 int x; | |
| 9074 A(this.x) {} | |
| 9075 }'''); | |
| 9076 computeLibrarySourceErrors(source); | |
| 9077 assertNoErrors(source); | |
| 9078 verify([source]); | |
| 9079 } | |
| 9080 | |
| 9081 void test_forEachLoops_nonConflicting() { | |
| 9082 Source source = addSource(r''' | |
| 9083 f() { | |
| 9084 List list = [1,2,3]; | |
| 9085 for (int x in list) {} | |
| 9086 for (int x in list) {} | |
| 9087 }'''); | |
| 9088 computeLibrarySourceErrors(source); | |
| 9089 assertNoErrors(source); | |
| 9090 verify([source]); | |
| 9091 } | |
| 9092 | |
| 9093 void test_forLoops_nonConflicting() { | |
| 9094 Source source = addSource(r''' | |
| 9095 f() { | |
| 9096 for (int i = 0; i < 3; i++) { | |
| 9097 } | |
| 9098 for (int i = 0; i < 3; i++) { | |
| 9099 } | |
| 9100 }'''); | |
| 9101 computeLibrarySourceErrors(source); | |
| 9102 assertNoErrors(source); | |
| 9103 verify([source]); | |
| 9104 } | |
| 9105 | |
| 9106 void test_functionTypeAlias() { | |
| 9107 Source source = addSource(r''' | |
| 9108 typedef bool P(e); | |
| 9109 class A { | |
| 9110 P p; | |
| 9111 m(e) { | |
| 9112 if (p(e)) {} | |
| 9113 } | |
| 9114 }'''); | |
| 9115 computeLibrarySourceErrors(source); | |
| 9116 assertNoErrors(source); | |
| 9117 verify([source]); | |
| 9118 } | |
| 9119 | |
| 9120 void test_getter_and_setter_fromMixins_bare_identifier() { | |
| 9121 Source source = addSource(''' | |
| 9122 class B {} | |
| 9123 class M1 { | |
| 9124 get x => null; | |
| 9125 set x(value) {} | |
| 9126 } | |
| 9127 class M2 { | |
| 9128 get x => null; | |
| 9129 set x(value) {} | |
| 9130 } | |
| 9131 class C extends B with M1, M2 { | |
| 9132 void f() { | |
| 9133 x += 1; | |
| 9134 } | |
| 9135 } | |
| 9136 '''); | |
| 9137 LibraryElement library = resolve2(source); | |
| 9138 assertNoErrors(source); | |
| 9139 verify([source]); | |
| 9140 // Verify that both the getter and setter for "x" in C.f() refer to the | |
| 9141 // accessors defined in M2. | |
| 9142 ClassElement classC = library.definingCompilationUnit.types[3]; | |
| 9143 MethodDeclaration f = classC.getMethod('f').computeNode(); | |
| 9144 BlockFunctionBody body = f.body; | |
| 9145 ExpressionStatement stmt = body.block.statements[0]; | |
| 9146 AssignmentExpression assignment = stmt.expression; | |
| 9147 SimpleIdentifier leftHandSide = assignment.leftHandSide; | |
| 9148 expect(leftHandSide.staticElement.enclosingElement.name, 'M2'); | |
| 9149 expect(leftHandSide.auxiliaryElements.staticElement.enclosingElement.name, | |
| 9150 'M2'); | |
| 9151 } | |
| 9152 | |
| 9153 void test_getter_fromMixins_bare_identifier() { | |
| 9154 Source source = addSource(''' | |
| 9155 class B {} | |
| 9156 class M1 { | |
| 9157 get x => null; | |
| 9158 } | |
| 9159 class M2 { | |
| 9160 get x => null; | |
| 9161 } | |
| 9162 class C extends B with M1, M2 { | |
| 9163 f() { | |
| 9164 return x; | |
| 9165 } | |
| 9166 } | |
| 9167 '''); | |
| 9168 LibraryElement library = resolve2(source); | |
| 9169 assertNoErrors(source); | |
| 9170 verify([source]); | |
| 9171 // Verify that the getter for "x" in C.f() refers to the getter defined in | |
| 9172 // M2. | |
| 9173 ClassElement classC = library.definingCompilationUnit.types[3]; | |
| 9174 MethodDeclaration f = classC.getMethod('f').computeNode(); | |
| 9175 BlockFunctionBody body = f.body; | |
| 9176 ReturnStatement stmt = body.block.statements[0]; | |
| 9177 SimpleIdentifier x = stmt.expression; | |
| 9178 expect(x.staticElement.enclosingElement.name, 'M2'); | |
| 9179 } | |
| 9180 | |
| 9181 void test_getter_fromMixins_property_access() { | |
| 9182 Source source = addSource(''' | |
| 9183 class B {} | |
| 9184 class M1 { | |
| 9185 get x => null; | |
| 9186 } | |
| 9187 class M2 { | |
| 9188 get x => null; | |
| 9189 } | |
| 9190 class C extends B with M1, M2 {} | |
| 9191 void main() { | |
| 9192 var y = new C().x; | |
| 9193 } | |
| 9194 '''); | |
| 9195 LibraryElement library = resolve2(source); | |
| 9196 assertNoErrors(source); | |
| 9197 verify([source]); | |
| 9198 // Verify that the getter for "x" in "new C().x" refers to the getter | |
| 9199 // defined in M2. | |
| 9200 FunctionDeclaration main = | |
| 9201 library.definingCompilationUnit.functions[0].computeNode(); | |
| 9202 BlockFunctionBody body = main.functionExpression.body; | |
| 9203 VariableDeclarationStatement stmt = body.block.statements[0]; | |
| 9204 PropertyAccess propertyAccess = stmt.variables.variables[0].initializer; | |
| 9205 expect( | |
| 9206 propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2'); | |
| 9207 } | |
| 9208 | |
| 9209 void test_getterAndSetterWithDifferentTypes() { | |
| 9210 Source source = addSource(r''' | |
| 9211 class A { | |
| 9212 int get f => 0; | |
| 9213 void set f(String s) {} | |
| 9214 } | |
| 9215 g (A a) { | |
| 9216 a.f = a.f.toString(); | |
| 9217 }'''); | |
| 9218 computeLibrarySourceErrors(source); | |
| 9219 assertErrors( | |
| 9220 source, [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]); | |
| 9221 verify([source]); | |
| 9222 } | |
| 9223 | |
| 9224 void test_hasReferenceToSuper() { | |
| 9225 Source source = addSource(r''' | |
| 9226 class A {} | |
| 9227 class B {toString() => super.toString();}'''); | |
| 9228 LibraryElement library = resolve2(source); | |
| 9229 expect(library, isNotNull); | |
| 9230 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9231 expect(unit, isNotNull); | |
| 9232 List<ClassElement> classes = unit.types; | |
| 9233 expect(classes, hasLength(2)); | |
| 9234 expect(classes[0].hasReferenceToSuper, isFalse); | |
| 9235 expect(classes[1].hasReferenceToSuper, isTrue); | |
| 9236 assertNoErrors(source); | |
| 9237 verify([source]); | |
| 9238 } | |
| 9239 | |
| 9240 void test_import_hide() { | |
| 9241 addNamedSource( | |
| 9242 "/lib1.dart", | |
| 9243 r''' | |
| 9244 library lib1; | |
| 9245 set foo(value) {} | |
| 9246 class A {}'''); | |
| 9247 addNamedSource( | |
| 9248 "/lib2.dart", | |
| 9249 r''' | |
| 9250 library lib2; | |
| 9251 set foo(value) {}'''); | |
| 9252 Source source = addNamedSource( | |
| 9253 "/lib3.dart", | |
| 9254 r''' | |
| 9255 import 'lib1.dart' hide foo; | |
| 9256 import 'lib2.dart'; | |
| 9257 | |
| 9258 main() { | |
| 9259 foo = 0; | |
| 9260 } | |
| 9261 A a;'''); | |
| 9262 computeLibrarySourceErrors(source); | |
| 9263 assertNoErrors(source); | |
| 9264 verify([source]); | |
| 9265 } | |
| 9266 | |
| 9267 void test_import_prefix() { | |
| 9268 addNamedSource( | |
| 9269 "/two.dart", | |
| 9270 r''' | |
| 9271 library two; | |
| 9272 f(int x) { | |
| 9273 return x * x; | |
| 9274 }'''); | |
| 9275 Source source = addNamedSource( | |
| 9276 "/one.dart", | |
| 9277 r''' | |
| 9278 library one; | |
| 9279 import 'two.dart' as _two; | |
| 9280 main() { | |
| 9281 _two.f(0); | |
| 9282 }'''); | |
| 9283 computeLibrarySourceErrors(source); | |
| 9284 assertNoErrors(source); | |
| 9285 verify([source]); | |
| 9286 } | |
| 9287 | |
| 9288 void test_import_spaceInUri() { | |
| 9289 addNamedSource( | |
| 9290 "/sub folder/lib.dart", | |
| 9291 r''' | |
| 9292 library lib; | |
| 9293 foo() {}'''); | |
| 9294 Source source = addNamedSource( | |
| 9295 "/app.dart", | |
| 9296 r''' | |
| 9297 import 'sub folder/lib.dart'; | |
| 9298 | |
| 9299 main() { | |
| 9300 foo(); | |
| 9301 }'''); | |
| 9302 computeLibrarySourceErrors(source); | |
| 9303 assertNoErrors(source); | |
| 9304 verify([source]); | |
| 9305 } | |
| 9306 | |
| 9307 void test_indexExpression_typeParameters() { | |
| 9308 Source source = addSource(r''' | |
| 9309 f() { | |
| 9310 List<int> a; | |
| 9311 a[0]; | |
| 9312 List<List<int>> b; | |
| 9313 b[0][0]; | |
| 9314 List<List<List<int>>> c; | |
| 9315 c[0][0][0]; | |
| 9316 }'''); | |
| 9317 computeLibrarySourceErrors(source); | |
| 9318 assertNoErrors(source); | |
| 9319 verify([source]); | |
| 9320 } | |
| 9321 | |
| 9322 void test_indexExpression_typeParameters_invalidAssignmentWarning() { | |
| 9323 Source source = addSource(r''' | |
| 9324 f() { | |
| 9325 List<List<int>> b; | |
| 9326 b[0][0] = 'hi'; | |
| 9327 }'''); | |
| 9328 computeLibrarySourceErrors(source); | |
| 9329 assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]); | |
| 9330 verify([source]); | |
| 9331 } | |
| 9332 | |
| 9333 void test_indirectOperatorThroughCall() { | |
| 9334 Source source = addSource(r''' | |
| 9335 class A { | |
| 9336 B call() { return new B(); } | |
| 9337 } | |
| 9338 | |
| 9339 class B { | |
| 9340 int operator [](int i) { return i; } | |
| 9341 } | |
| 9342 | |
| 9343 A f = new A(); | |
| 9344 | |
| 9345 g(int x) {} | |
| 9346 | |
| 9347 main() { | |
| 9348 g(f()[0]); | |
| 9349 }'''); | |
| 9350 computeLibrarySourceErrors(source); | |
| 9351 assertNoErrors(source); | |
| 9352 verify([source]); | |
| 9353 } | |
| 9354 | |
| 9355 void test_invoke_dynamicThroughGetter() { | |
| 9356 Source source = addSource(r''' | |
| 9357 class A { | |
| 9358 List get X => [() => 0]; | |
| 9359 m(A a) { | |
| 9360 X.last; | |
| 9361 } | |
| 9362 }'''); | |
| 9363 computeLibrarySourceErrors(source); | |
| 9364 assertNoErrors(source); | |
| 9365 verify([source]); | |
| 9366 } | |
| 9367 | |
| 9368 void test_isValidMixin_badSuperclass() { | |
| 9369 Source source = addSource(r''' | |
| 9370 class A extends B {} | |
| 9371 class B {}'''); | |
| 9372 LibraryElement library = resolve2(source); | |
| 9373 expect(library, isNotNull); | |
| 9374 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9375 expect(unit, isNotNull); | |
| 9376 List<ClassElement> classes = unit.types; | |
| 9377 expect(classes, hasLength(2)); | |
| 9378 expect(classes[0].isValidMixin, isFalse); | |
| 9379 assertNoErrors(source); | |
| 9380 verify([source]); | |
| 9381 } | |
| 9382 | |
| 9383 void test_isValidMixin_constructor() { | |
| 9384 Source source = addSource(r''' | |
| 9385 class A { | |
| 9386 A() {} | |
| 9387 }'''); | |
| 9388 LibraryElement library = resolve2(source); | |
| 9389 expect(library, isNotNull); | |
| 9390 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9391 expect(unit, isNotNull); | |
| 9392 List<ClassElement> classes = unit.types; | |
| 9393 expect(classes, hasLength(1)); | |
| 9394 expect(classes[0].isValidMixin, isFalse); | |
| 9395 assertNoErrors(source); | |
| 9396 verify([source]); | |
| 9397 } | |
| 9398 | |
| 9399 void test_isValidMixin_super() { | |
| 9400 Source source = addSource(r''' | |
| 9401 class A { | |
| 9402 toString() { | |
| 9403 return super.toString(); | |
| 9404 } | |
| 9405 }'''); | |
| 9406 LibraryElement library = resolve2(source); | |
| 9407 expect(library, isNotNull); | |
| 9408 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9409 expect(unit, isNotNull); | |
| 9410 List<ClassElement> classes = unit.types; | |
| 9411 expect(classes, hasLength(1)); | |
| 9412 expect(classes[0].isValidMixin, isFalse); | |
| 9413 assertNoErrors(source); | |
| 9414 verify([source]); | |
| 9415 } | |
| 9416 | |
| 9417 void test_isValidMixin_valid() { | |
| 9418 Source source = addSource("class A {}"); | |
| 9419 LibraryElement library = resolve2(source); | |
| 9420 expect(library, isNotNull); | |
| 9421 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9422 expect(unit, isNotNull); | |
| 9423 List<ClassElement> classes = unit.types; | |
| 9424 expect(classes, hasLength(1)); | |
| 9425 expect(classes[0].isValidMixin, isTrue); | |
| 9426 assertNoErrors(source); | |
| 9427 verify([source]); | |
| 9428 } | |
| 9429 | |
| 9430 void test_labels_switch() { | |
| 9431 Source source = addSource(r''' | |
| 9432 void doSwitch(int target) { | |
| 9433 switch (target) { | |
| 9434 l0: case 0: | |
| 9435 continue l1; | |
| 9436 l1: case 1: | |
| 9437 continue l0; | |
| 9438 default: | |
| 9439 continue l1; | |
| 9440 } | |
| 9441 }'''); | |
| 9442 LibraryElement library = resolve2(source); | |
| 9443 expect(library, isNotNull); | |
| 9444 assertNoErrors(source); | |
| 9445 verify([source]); | |
| 9446 } | |
| 9447 | |
| 9448 void test_localVariable_types_invoked() { | |
| 9449 Source source = addSource(r''' | |
| 9450 const A = null; | |
| 9451 main() { | |
| 9452 var myVar = (int p) => 'foo'; | |
| 9453 myVar(42); | |
| 9454 }'''); | |
| 9455 LibraryElement library = resolve2(source); | |
| 9456 expect(library, isNotNull); | |
| 9457 CompilationUnit unit = | |
| 9458 analysisContext.resolveCompilationUnit(source, library); | |
| 9459 expect(unit, isNotNull); | |
| 9460 List<bool> found = [false]; | |
| 9461 List<CaughtException> thrownException = new List<CaughtException>(1); | |
| 9462 unit.accept(new _SimpleResolverTest_localVariable_types_invoked( | |
| 9463 this, found, thrownException)); | |
| 9464 if (thrownException[0] != null) { | |
| 9465 throw new AnalysisException( | |
| 9466 "Exception", new CaughtException(thrownException[0], null)); | |
| 9467 } | |
| 9468 expect(found[0], isTrue); | |
| 9469 } | |
| 9470 | |
| 9471 void test_metadata_class() { | |
| 9472 Source source = addSource(r''' | |
| 9473 const A = null; | |
| 9474 @A class C<A> {}'''); | |
| 9475 LibraryElement library = resolve2(source); | |
| 9476 expect(library, isNotNull); | |
| 9477 CompilationUnitElement unitElement = library.definingCompilationUnit; | |
| 9478 expect(unitElement, isNotNull); | |
| 9479 List<ClassElement> classes = unitElement.types; | |
| 9480 expect(classes, hasLength(1)); | |
| 9481 List<ElementAnnotation> annotations = classes[0].metadata; | |
| 9482 expect(annotations, hasLength(1)); | |
| 9483 assertNoErrors(source); | |
| 9484 verify([source]); | |
| 9485 CompilationUnit unit = resolveCompilationUnit(source, library); | |
| 9486 NodeList<CompilationUnitMember> declarations = unit.declarations; | |
| 9487 expect(declarations, hasLength(2)); | |
| 9488 Element expectedElement = (declarations[0] as TopLevelVariableDeclaration) | |
| 9489 .variables | |
| 9490 .variables[0].name.staticElement; | |
| 9491 EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement, | |
| 9492 PropertyInducingElement, expectedElement); | |
| 9493 expectedElement = (expectedElement as PropertyInducingElement).getter; | |
| 9494 Element actualElement = | |
| 9495 (declarations[1] as ClassDeclaration).metadata[0].name.staticElement; | |
| 9496 expect(actualElement, same(expectedElement)); | |
| 9497 } | |
| 9498 | |
| 9499 void test_metadata_field() { | |
| 9500 Source source = addSource(r''' | |
| 9501 const A = null; | |
| 9502 class C { | |
| 9503 @A int f; | |
| 9504 }'''); | |
| 9505 LibraryElement library = resolve2(source); | |
| 9506 expect(library, isNotNull); | |
| 9507 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9508 expect(unit, isNotNull); | |
| 9509 List<ClassElement> classes = unit.types; | |
| 9510 expect(classes, hasLength(1)); | |
| 9511 FieldElement field = classes[0].fields[0]; | |
| 9512 List<ElementAnnotation> annotations = field.metadata; | |
| 9513 expect(annotations, hasLength(1)); | |
| 9514 assertNoErrors(source); | |
| 9515 verify([source]); | |
| 9516 } | |
| 9517 | |
| 9518 void test_metadata_fieldFormalParameter() { | |
| 9519 Source source = addSource(r''' | |
| 9520 const A = null; | |
| 9521 class C { | |
| 9522 int f; | |
| 9523 C(@A this.f); | |
| 9524 }'''); | |
| 9525 LibraryElement library = resolve2(source); | |
| 9526 expect(library, isNotNull); | |
| 9527 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9528 expect(unit, isNotNull); | |
| 9529 List<ClassElement> classes = unit.types; | |
| 9530 expect(classes, hasLength(1)); | |
| 9531 List<ConstructorElement> constructors = classes[0].constructors; | |
| 9532 expect(constructors, hasLength(1)); | |
| 9533 List<ParameterElement> parameters = constructors[0].parameters; | |
| 9534 expect(parameters, hasLength(1)); | |
| 9535 List<ElementAnnotation> annotations = parameters[0].metadata; | |
| 9536 expect(annotations, hasLength(1)); | |
| 9537 assertNoErrors(source); | |
| 9538 verify([source]); | |
| 9539 } | |
| 9540 | |
| 9541 void test_metadata_function() { | |
| 9542 Source source = addSource(r''' | |
| 9543 const A = null; | |
| 9544 @A f() {}'''); | |
| 9545 LibraryElement library = resolve2(source); | |
| 9546 expect(library, isNotNull); | |
| 9547 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9548 expect(unit, isNotNull); | |
| 9549 List<FunctionElement> functions = unit.functions; | |
| 9550 expect(functions, hasLength(1)); | |
| 9551 List<ElementAnnotation> annotations = functions[0].metadata; | |
| 9552 expect(annotations, hasLength(1)); | |
| 9553 assertNoErrors(source); | |
| 9554 verify([source]); | |
| 9555 } | |
| 9556 | |
| 9557 void test_metadata_functionTypedParameter() { | |
| 9558 Source source = addSource(r''' | |
| 9559 const A = null; | |
| 9560 f(@A int p(int x)) {}'''); | |
| 9561 LibraryElement library = resolve2(source); | |
| 9562 expect(library, isNotNull); | |
| 9563 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9564 expect(unit, isNotNull); | |
| 9565 List<FunctionElement> functions = unit.functions; | |
| 9566 expect(functions, hasLength(1)); | |
| 9567 List<ParameterElement> parameters = functions[0].parameters; | |
| 9568 expect(parameters, hasLength(1)); | |
| 9569 List<ElementAnnotation> annotations1 = parameters[0].metadata; | |
| 9570 expect(annotations1, hasLength(1)); | |
| 9571 assertNoErrors(source); | |
| 9572 verify([source]); | |
| 9573 } | |
| 9574 | |
| 9575 void test_metadata_libraryDirective() { | |
| 9576 Source source = addSource(r''' | |
| 9577 @A library lib; | |
| 9578 const A = null;'''); | |
| 9579 LibraryElement library = resolve2(source); | |
| 9580 expect(library, isNotNull); | |
| 9581 List<ElementAnnotation> annotations = library.metadata; | |
| 9582 expect(annotations, hasLength(1)); | |
| 9583 assertNoErrors(source); | |
| 9584 verify([source]); | |
| 9585 } | |
| 9586 | |
| 9587 void test_metadata_method() { | |
| 9588 Source source = addSource(r''' | |
| 9589 const A = null; | |
| 9590 class C { | |
| 9591 @A void m() {} | |
| 9592 }'''); | |
| 9593 LibraryElement library = resolve2(source); | |
| 9594 expect(library, isNotNull); | |
| 9595 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9596 expect(unit, isNotNull); | |
| 9597 List<ClassElement> classes = unit.types; | |
| 9598 expect(classes, hasLength(1)); | |
| 9599 MethodElement method = classes[0].methods[0]; | |
| 9600 List<ElementAnnotation> annotations = method.metadata; | |
| 9601 expect(annotations, hasLength(1)); | |
| 9602 assertNoErrors(source); | |
| 9603 verify([source]); | |
| 9604 } | |
| 9605 | |
| 9606 void test_metadata_namedParameter() { | |
| 9607 Source source = addSource(r''' | |
| 9608 const A = null; | |
| 9609 f({@A int p : 0}) {}'''); | |
| 9610 LibraryElement library = resolve2(source); | |
| 9611 expect(library, isNotNull); | |
| 9612 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9613 expect(unit, isNotNull); | |
| 9614 List<FunctionElement> functions = unit.functions; | |
| 9615 expect(functions, hasLength(1)); | |
| 9616 List<ParameterElement> parameters = functions[0].parameters; | |
| 9617 expect(parameters, hasLength(1)); | |
| 9618 List<ElementAnnotation> annotations1 = parameters[0].metadata; | |
| 9619 expect(annotations1, hasLength(1)); | |
| 9620 assertNoErrors(source); | |
| 9621 verify([source]); | |
| 9622 } | |
| 9623 | |
| 9624 void test_metadata_positionalParameter() { | |
| 9625 Source source = addSource(r''' | |
| 9626 const A = null; | |
| 9627 f([@A int p = 0]) {}'''); | |
| 9628 LibraryElement library = resolve2(source); | |
| 9629 expect(library, isNotNull); | |
| 9630 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9631 expect(unit, isNotNull); | |
| 9632 List<FunctionElement> functions = unit.functions; | |
| 9633 expect(functions, hasLength(1)); | |
| 9634 List<ParameterElement> parameters = functions[0].parameters; | |
| 9635 expect(parameters, hasLength(1)); | |
| 9636 List<ElementAnnotation> annotations1 = parameters[0].metadata; | |
| 9637 expect(annotations1, hasLength(1)); | |
| 9638 assertNoErrors(source); | |
| 9639 verify([source]); | |
| 9640 } | |
| 9641 | |
| 9642 void test_metadata_simpleParameter() { | |
| 9643 Source source = addSource(r''' | |
| 9644 const A = null; | |
| 9645 f(@A p1, @A int p2) {}'''); | |
| 9646 LibraryElement library = resolve2(source); | |
| 9647 expect(library, isNotNull); | |
| 9648 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9649 expect(unit, isNotNull); | |
| 9650 List<FunctionElement> functions = unit.functions; | |
| 9651 expect(functions, hasLength(1)); | |
| 9652 List<ParameterElement> parameters = functions[0].parameters; | |
| 9653 expect(parameters, hasLength(2)); | |
| 9654 List<ElementAnnotation> annotations1 = parameters[0].metadata; | |
| 9655 expect(annotations1, hasLength(1)); | |
| 9656 List<ElementAnnotation> annotations2 = parameters[1].metadata; | |
| 9657 expect(annotations2, hasLength(1)); | |
| 9658 assertNoErrors(source); | |
| 9659 verify([source]); | |
| 9660 } | |
| 9661 | |
| 9662 void test_metadata_typedef() { | |
| 9663 Source source = addSource(r''' | |
| 9664 const A = null; | |
| 9665 @A typedef F<A>();'''); | |
| 9666 LibraryElement library = resolve2(source); | |
| 9667 expect(library, isNotNull); | |
| 9668 CompilationUnitElement unitElement = library.definingCompilationUnit; | |
| 9669 expect(unitElement, isNotNull); | |
| 9670 List<FunctionTypeAliasElement> aliases = unitElement.functionTypeAliases; | |
| 9671 expect(aliases, hasLength(1)); | |
| 9672 List<ElementAnnotation> annotations = aliases[0].metadata; | |
| 9673 expect(annotations, hasLength(1)); | |
| 9674 assertNoErrors(source); | |
| 9675 verify([source]); | |
| 9676 CompilationUnit unit = resolveCompilationUnit(source, library); | |
| 9677 NodeList<CompilationUnitMember> declarations = unit.declarations; | |
| 9678 expect(declarations, hasLength(2)); | |
| 9679 Element expectedElement = (declarations[0] as TopLevelVariableDeclaration) | |
| 9680 .variables | |
| 9681 .variables[0].name.staticElement; | |
| 9682 EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement, | |
| 9683 PropertyInducingElement, expectedElement); | |
| 9684 expectedElement = (expectedElement as PropertyInducingElement).getter; | |
| 9685 Element actualElement = | |
| 9686 (declarations[1] as FunctionTypeAlias).metadata[0].name.staticElement; | |
| 9687 expect(actualElement, same(expectedElement)); | |
| 9688 } | |
| 9689 | |
| 9690 void test_method_fromMixin() { | |
| 9691 Source source = addSource(r''' | |
| 9692 class B { | |
| 9693 bar() => 1; | |
| 9694 } | |
| 9695 class A { | |
| 9696 foo() => 2; | |
| 9697 } | |
| 9698 | |
| 9699 class C extends B with A { | |
| 9700 bar() => super.bar(); | |
| 9701 foo() => super.foo(); | |
| 9702 }'''); | |
| 9703 computeLibrarySourceErrors(source); | |
| 9704 assertNoErrors(source); | |
| 9705 verify([source]); | |
| 9706 } | |
| 9707 | |
| 9708 void test_method_fromMixins() { | |
| 9709 Source source = addSource(''' | |
| 9710 class B {} | |
| 9711 class M1 { | |
| 9712 void f() {} | |
| 9713 } | |
| 9714 class M2 { | |
| 9715 void f() {} | |
| 9716 } | |
| 9717 class C extends B with M1, M2 {} | |
| 9718 void main() { | |
| 9719 new C().f(); | |
| 9720 } | |
| 9721 '''); | |
| 9722 LibraryElement library = resolve2(source); | |
| 9723 assertNoErrors(source); | |
| 9724 verify([source]); | |
| 9725 // Verify that the "f" in "new C().f()" refers to the "f" defined in M2. | |
| 9726 FunctionDeclaration main = | |
| 9727 library.definingCompilationUnit.functions[0].computeNode(); | |
| 9728 BlockFunctionBody body = main.functionExpression.body; | |
| 9729 ExpressionStatement stmt = body.block.statements[0]; | |
| 9730 MethodInvocation expr = stmt.expression; | |
| 9731 expect(expr.methodName.staticElement.enclosingElement.name, 'M2'); | |
| 9732 } | |
| 9733 | |
| 9734 void test_method_fromMixins_bare_identifier() { | |
| 9735 Source source = addSource(''' | |
| 9736 class B {} | |
| 9737 class M1 { | |
| 9738 void f() {} | |
| 9739 } | |
| 9740 class M2 { | |
| 9741 void f() {} | |
| 9742 } | |
| 9743 class C extends B with M1, M2 { | |
| 9744 void g() { | |
| 9745 f(); | |
| 9746 } | |
| 9747 } | |
| 9748 '''); | |
| 9749 LibraryElement library = resolve2(source); | |
| 9750 assertNoErrors(source); | |
| 9751 verify([source]); | |
| 9752 // Verify that the call to f() in C.g() refers to the method defined in M2. | |
| 9753 ClassElement classC = library.definingCompilationUnit.types[3]; | |
| 9754 MethodDeclaration g = classC.getMethod('g').computeNode(); | |
| 9755 BlockFunctionBody body = g.body; | |
| 9756 ExpressionStatement stmt = body.block.statements[0]; | |
| 9757 MethodInvocation invocation = stmt.expression; | |
| 9758 SimpleIdentifier methodName = invocation.methodName; | |
| 9759 expect(methodName.staticElement.enclosingElement.name, 'M2'); | |
| 9760 } | |
| 9761 | |
| 9762 void test_method_fromMixins_invked_from_outside_class() { | |
| 9763 Source source = addSource(''' | |
| 9764 class B {} | |
| 9765 class M1 { | |
| 9766 void f() {} | |
| 9767 } | |
| 9768 class M2 { | |
| 9769 void f() {} | |
| 9770 } | |
| 9771 class C extends B with M1, M2 {} | |
| 9772 void main() { | |
| 9773 new C().f(); | |
| 9774 } | |
| 9775 '''); | |
| 9776 LibraryElement library = resolve2(source); | |
| 9777 assertNoErrors(source); | |
| 9778 verify([source]); | |
| 9779 // Verify that the call to f() in "new C().f()" refers to the method | |
| 9780 // defined in M2. | |
| 9781 FunctionDeclaration main = | |
| 9782 library.definingCompilationUnit.functions[0].computeNode(); | |
| 9783 BlockFunctionBody body = main.functionExpression.body; | |
| 9784 ExpressionStatement stmt = body.block.statements[0]; | |
| 9785 MethodInvocation invocation = stmt.expression; | |
| 9786 expect(invocation.methodName.staticElement.enclosingElement.name, 'M2'); | |
| 9787 } | |
| 9788 | |
| 9789 void test_method_fromSuperclassMixin() { | |
| 9790 Source source = addSource(r''' | |
| 9791 class A { | |
| 9792 void m1() {} | |
| 9793 } | |
| 9794 class B extends Object with A { | |
| 9795 } | |
| 9796 class C extends B { | |
| 9797 } | |
| 9798 f(C c) { | |
| 9799 c.m1(); | |
| 9800 }'''); | |
| 9801 computeLibrarySourceErrors(source); | |
| 9802 assertNoErrors(source); | |
| 9803 verify([source]); | |
| 9804 } | |
| 9805 | |
| 9806 void test_methodCascades() { | |
| 9807 Source source = addSource(r''' | |
| 9808 class A { | |
| 9809 void m1() {} | |
| 9810 void m2() {} | |
| 9811 void m() { | |
| 9812 A a = new A(); | |
| 9813 a..m1() | |
| 9814 ..m2(); | |
| 9815 } | |
| 9816 }'''); | |
| 9817 computeLibrarySourceErrors(source); | |
| 9818 assertNoErrors(source); | |
| 9819 verify([source]); | |
| 9820 } | |
| 9821 | |
| 9822 void test_methodCascades_withSetter() { | |
| 9823 Source source = addSource(r''' | |
| 9824 class A { | |
| 9825 String name; | |
| 9826 void m1() {} | |
| 9827 void m2() {} | |
| 9828 void m() { | |
| 9829 A a = new A(); | |
| 9830 a..m1() | |
| 9831 ..name = 'name' | |
| 9832 ..m2(); | |
| 9833 } | |
| 9834 }'''); | |
| 9835 computeLibrarySourceErrors(source); | |
| 9836 // failing with error code: INVOCATION_OF_NON_FUNCTION | |
| 9837 assertNoErrors(source); | |
| 9838 verify([source]); | |
| 9839 } | |
| 9840 | |
| 9841 void test_resolveAgainstNull() { | |
| 9842 Source source = addSource(r''' | |
| 9843 f(var p) { | |
| 9844 return null == p; | |
| 9845 }'''); | |
| 9846 computeLibrarySourceErrors(source); | |
| 9847 assertNoErrors(source); | |
| 9848 } | |
| 9849 | |
| 9850 void test_setter_fromMixins_bare_identifier() { | |
| 9851 Source source = addSource(''' | |
| 9852 class B {} | |
| 9853 class M1 { | |
| 9854 set x(value) {} | |
| 9855 } | |
| 9856 class M2 { | |
| 9857 set x(value) {} | |
| 9858 } | |
| 9859 class C extends B with M1, M2 { | |
| 9860 void f() { | |
| 9861 x = 1; | |
| 9862 } | |
| 9863 } | |
| 9864 '''); | |
| 9865 LibraryElement library = resolve2(source); | |
| 9866 assertNoErrors(source); | |
| 9867 verify([source]); | |
| 9868 // Verify that the setter for "x" in C.f() refers to the setter defined in | |
| 9869 // M2. | |
| 9870 ClassElement classC = library.definingCompilationUnit.types[3]; | |
| 9871 MethodDeclaration f = classC.getMethod('f').computeNode(); | |
| 9872 BlockFunctionBody body = f.body; | |
| 9873 ExpressionStatement stmt = body.block.statements[0]; | |
| 9874 AssignmentExpression assignment = stmt.expression; | |
| 9875 SimpleIdentifier leftHandSide = assignment.leftHandSide; | |
| 9876 expect(leftHandSide.staticElement.enclosingElement.name, 'M2'); | |
| 9877 } | |
| 9878 | |
| 9879 void test_setter_fromMixins_property_access() { | |
| 9880 Source source = addSource(''' | |
| 9881 class B {} | |
| 9882 class M1 { | |
| 9883 set x(value) {} | |
| 9884 } | |
| 9885 class M2 { | |
| 9886 set x(value) {} | |
| 9887 } | |
| 9888 class C extends B with M1, M2 {} | |
| 9889 void main() { | |
| 9890 new C().x = 1; | |
| 9891 } | |
| 9892 '''); | |
| 9893 LibraryElement library = resolve2(source); | |
| 9894 assertNoErrors(source); | |
| 9895 verify([source]); | |
| 9896 // Verify that the setter for "x" in "new C().x" refers to the setter | |
| 9897 // defined in M2. | |
| 9898 FunctionDeclaration main = | |
| 9899 library.definingCompilationUnit.functions[0].computeNode(); | |
| 9900 BlockFunctionBody body = main.functionExpression.body; | |
| 9901 ExpressionStatement stmt = body.block.statements[0]; | |
| 9902 AssignmentExpression assignment = stmt.expression; | |
| 9903 PropertyAccess propertyAccess = assignment.leftHandSide; | |
| 9904 expect( | |
| 9905 propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2'); | |
| 9906 } | |
| 9907 | |
| 9908 void test_setter_inherited() { | |
| 9909 Source source = addSource(r''' | |
| 9910 class A { | |
| 9911 int get x => 0; | |
| 9912 set x(int p) {} | |
| 9913 } | |
| 9914 class B extends A { | |
| 9915 int get x => super.x == null ? 0 : super.x; | |
| 9916 int f() => x = 1; | |
| 9917 }'''); | |
| 9918 computeLibrarySourceErrors(source); | |
| 9919 assertNoErrors(source); | |
| 9920 verify([source]); | |
| 9921 } | |
| 9922 | |
| 9923 void test_setter_static() { | |
| 9924 Source source = addSource(r''' | |
| 9925 set s(x) { | |
| 9926 } | |
| 9927 | |
| 9928 main() { | |
| 9929 s = 123; | |
| 9930 }'''); | |
| 9931 computeLibrarySourceErrors(source); | |
| 9932 assertNoErrors(source); | |
| 9933 verify([source]); | |
| 9934 } | |
| 9935 | |
| 9936 /** | |
| 9937 * Resolve the given source and verify that the arguments in a specific method
invocation were | |
| 9938 * correctly resolved. | |
| 9939 * | |
| 9940 * The source is expected to be source for a compilation unit, the first decla
ration is expected | |
| 9941 * to be a class, the first member of which is expected to be a method with a
block body, and the | |
| 9942 * first statement in the body is expected to be an expression statement whose
expression is a | |
| 9943 * method invocation. It is the arguments to that method invocation that are t
ested. The method | |
| 9944 * invocation can contain errors. | |
| 9945 * | |
| 9946 * The arguments were resolved correctly if the number of expressions in the l
ist matches the | |
| 9947 * length of the array of indices and if, for each index in the array of indic
es, the parameter to | |
| 9948 * which the argument expression was resolved is the parameter in the invoked
method's list of | |
| 9949 * parameters at that index. Arguments that should not be resolved to a parame
ter because of an | |
| 9950 * error can be denoted by including a negative index in the array of indices. | |
| 9951 * | |
| 9952 * @param source the source to be resolved | |
| 9953 * @param indices the array of indices used to associate arguments with parame
ters | |
| 9954 * @throws Exception if the source could not be resolved or if the structure o
f the source is not | |
| 9955 * valid | |
| 9956 */ | |
| 9957 void _validateArgumentResolution(Source source, List<int> indices) { | |
| 9958 LibraryElement library = resolve2(source); | |
| 9959 expect(library, isNotNull); | |
| 9960 ClassElement classElement = library.definingCompilationUnit.types[0]; | |
| 9961 List<ParameterElement> parameters = classElement.methods[1].parameters; | |
| 9962 CompilationUnit unit = resolveCompilationUnit(source, library); | |
| 9963 expect(unit, isNotNull); | |
| 9964 ClassDeclaration classDeclaration = | |
| 9965 unit.declarations[0] as ClassDeclaration; | |
| 9966 MethodDeclaration methodDeclaration = | |
| 9967 classDeclaration.members[0] as MethodDeclaration; | |
| 9968 Block block = (methodDeclaration.body as BlockFunctionBody).block; | |
| 9969 ExpressionStatement statement = block.statements[0] as ExpressionStatement; | |
| 9970 MethodInvocation invocation = statement.expression as MethodInvocation; | |
| 9971 NodeList<Expression> arguments = invocation.argumentList.arguments; | |
| 9972 int argumentCount = arguments.length; | |
| 9973 expect(argumentCount, indices.length); | |
| 9974 for (int i = 0; i < argumentCount; i++) { | |
| 9975 Expression argument = arguments[i]; | |
| 9976 ParameterElement element = argument.staticParameterElement; | |
| 9977 int index = indices[i]; | |
| 9978 if (index < 0) { | |
| 9979 expect(element, isNull); | |
| 9980 } else { | |
| 9981 expect(element, same(parameters[index])); | |
| 9982 } | |
| 9983 } | |
| 9984 } | |
| 9985 } | |
| 9986 | |
| 9987 class SourceContainer_ChangeSetTest_test_toString implements SourceContainer { | 391 class SourceContainer_ChangeSetTest_test_toString implements SourceContainer { |
| 9988 @override | 392 @override |
| 9989 bool contains(Source source) => false; | 393 bool contains(Source source) => false; |
| 9990 } | 394 } |
| 9991 | 395 |
| 9992 /** | 396 /** |
| 9993 * Like [StaticTypeAnalyzerTest], but as end-to-end tests. | |
| 9994 */ | |
| 9995 @reflectiveTest | |
| 9996 class StaticTypeAnalyzer2Test extends _StaticTypeAnalyzer2TestShared { | |
| 9997 void test_FunctionExpressionInvocation_block() { | |
| 9998 String code = r''' | |
| 9999 main() { | |
| 10000 var foo = (() { return 1; })(); | |
| 10001 } | |
| 10002 '''; | |
| 10003 _resolveTestUnit(code); | |
| 10004 SimpleIdentifier identifier = _findIdentifier('foo'); | |
| 10005 VariableDeclaration declaration = | |
| 10006 identifier.getAncestor((node) => node is VariableDeclaration); | |
| 10007 expect(declaration.initializer.staticType.isDynamic, isTrue); | |
| 10008 expect(declaration.initializer.propagatedType, isNull); | |
| 10009 } | |
| 10010 | |
| 10011 void test_FunctionExpressionInvocation_curried() { | |
| 10012 String code = r''' | |
| 10013 typedef int F(); | |
| 10014 F f() => null; | |
| 10015 main() { | |
| 10016 var foo = f()(); | |
| 10017 } | |
| 10018 '''; | |
| 10019 _resolveTestUnit(code); | |
| 10020 SimpleIdentifier identifier = _findIdentifier('foo'); | |
| 10021 VariableDeclaration declaration = | |
| 10022 identifier.getAncestor((node) => node is VariableDeclaration); | |
| 10023 expect(declaration.initializer.staticType.name, 'int'); | |
| 10024 expect(declaration.initializer.propagatedType, isNull); | |
| 10025 } | |
| 10026 | |
| 10027 void test_FunctionExpressionInvocation_expression() { | |
| 10028 String code = r''' | |
| 10029 main() { | |
| 10030 var foo = (() => 1)(); | |
| 10031 } | |
| 10032 '''; | |
| 10033 _resolveTestUnit(code); | |
| 10034 SimpleIdentifier identifier = _findIdentifier('foo'); | |
| 10035 VariableDeclaration declaration = | |
| 10036 identifier.getAncestor((node) => node is VariableDeclaration); | |
| 10037 expect(declaration.initializer.staticType.name, 'int'); | |
| 10038 expect(declaration.initializer.propagatedType, isNull); | |
| 10039 } | |
| 10040 | |
| 10041 void test_MethodInvocation_nameType_localVariable() { | |
| 10042 String code = r""" | |
| 10043 typedef Foo(); | |
| 10044 main() { | |
| 10045 Foo foo; | |
| 10046 foo(); | |
| 10047 } | |
| 10048 """; | |
| 10049 _resolveTestUnit(code); | |
| 10050 // "foo" should be resolved to the "Foo" type | |
| 10051 SimpleIdentifier identifier = _findIdentifier("foo();"); | |
| 10052 DartType type = identifier.staticType; | |
| 10053 expect(type, new isInstanceOf<FunctionType>()); | |
| 10054 } | |
| 10055 | |
| 10056 void test_MethodInvocation_nameType_parameter_FunctionTypeAlias() { | |
| 10057 String code = r""" | |
| 10058 typedef Foo(); | |
| 10059 main(Foo foo) { | |
| 10060 foo(); | |
| 10061 } | |
| 10062 """; | |
| 10063 _resolveTestUnit(code); | |
| 10064 // "foo" should be resolved to the "Foo" type | |
| 10065 SimpleIdentifier identifier = _findIdentifier("foo();"); | |
| 10066 DartType type = identifier.staticType; | |
| 10067 expect(type, new isInstanceOf<FunctionType>()); | |
| 10068 } | |
| 10069 | |
| 10070 void test_MethodInvocation_nameType_parameter_propagatedType() { | |
| 10071 String code = r""" | |
| 10072 typedef Foo(); | |
| 10073 main(p) { | |
| 10074 if (p is Foo) { | |
| 10075 p(); | |
| 10076 } | |
| 10077 } | |
| 10078 """; | |
| 10079 _resolveTestUnit(code); | |
| 10080 SimpleIdentifier identifier = _findIdentifier("p()"); | |
| 10081 expect(identifier.staticType, DynamicTypeImpl.instance); | |
| 10082 { | |
| 10083 FunctionType type = identifier.propagatedType; | |
| 10084 expect(type, isNotNull); | |
| 10085 expect(type.name, 'Foo'); | |
| 10086 } | |
| 10087 } | |
| 10088 } | |
| 10089 | |
| 10090 @reflectiveTest | |
| 10091 class StaticTypeAnalyzerTest extends EngineTestCase { | |
| 10092 /** | |
| 10093 * The error listener to which errors will be reported. | |
| 10094 */ | |
| 10095 GatheringErrorListener _listener; | |
| 10096 | |
| 10097 /** | |
| 10098 * The resolver visitor used to create the analyzer. | |
| 10099 */ | |
| 10100 ResolverVisitor _visitor; | |
| 10101 | |
| 10102 /** | |
| 10103 * The analyzer being used to analyze the test cases. | |
| 10104 */ | |
| 10105 StaticTypeAnalyzer _analyzer; | |
| 10106 | |
| 10107 /** | |
| 10108 * The type provider used to access the types. | |
| 10109 */ | |
| 10110 TestTypeProvider _typeProvider; | |
| 10111 | |
| 10112 void fail_visitFunctionExpressionInvocation() { | |
| 10113 fail("Not yet tested"); | |
| 10114 _listener.assertNoErrors(); | |
| 10115 } | |
| 10116 | |
| 10117 void fail_visitMethodInvocation() { | |
| 10118 fail("Not yet tested"); | |
| 10119 _listener.assertNoErrors(); | |
| 10120 } | |
| 10121 | |
| 10122 void fail_visitSimpleIdentifier() { | |
| 10123 fail("Not yet tested"); | |
| 10124 _listener.assertNoErrors(); | |
| 10125 } | |
| 10126 | |
| 10127 @override | |
| 10128 void setUp() { | |
| 10129 _listener = new GatheringErrorListener(); | |
| 10130 _typeProvider = new TestTypeProvider(); | |
| 10131 _analyzer = _createAnalyzer(); | |
| 10132 } | |
| 10133 | |
| 10134 void test_flatten_derived() { | |
| 10135 // class Derived<T> extends Future<T> { ... } | |
| 10136 ClassElementImpl derivedClass = | |
| 10137 ElementFactory.classElement2('Derived', ['T']); | |
| 10138 derivedClass.supertype = _typeProvider.futureType | |
| 10139 .substitute4([derivedClass.typeParameters[0].type]); | |
| 10140 InterfaceType intType = _typeProvider.intType; | |
| 10141 DartType dynamicType = _typeProvider.dynamicType; | |
| 10142 InterfaceType derivedIntType = derivedClass.type.substitute4([intType]); | |
| 10143 // flatten(Derived) = dynamic | |
| 10144 InterfaceType derivedDynamicType = | |
| 10145 derivedClass.type.substitute4([dynamicType]); | |
| 10146 expect(_flatten(derivedDynamicType), dynamicType); | |
| 10147 // flatten(Derived<int>) = int | |
| 10148 expect(_flatten(derivedIntType), intType); | |
| 10149 // flatten(Derived<Derived>) = Derived | |
| 10150 expect(_flatten(derivedClass.type.substitute4([derivedDynamicType])), | |
| 10151 derivedDynamicType); | |
| 10152 // flatten(Derived<Derived<int>>) = Derived<int> | |
| 10153 expect(_flatten(derivedClass.type.substitute4([derivedIntType])), | |
| 10154 derivedIntType); | |
| 10155 } | |
| 10156 | |
| 10157 void test_flatten_inhibit_recursion() { | |
| 10158 // class A extends B | |
| 10159 // class B extends A | |
| 10160 ClassElementImpl classA = ElementFactory.classElement2('A', []); | |
| 10161 ClassElementImpl classB = ElementFactory.classElement2('B', []); | |
| 10162 classA.supertype = classB.type; | |
| 10163 classB.supertype = classA.type; | |
| 10164 // flatten(A) = A and flatten(B) = B, since neither class contains Future | |
| 10165 // in its class hierarchy. Even though there is a loop in the class | |
| 10166 // hierarchy, flatten() should terminate. | |
| 10167 expect(_flatten(classA.type), classA.type); | |
| 10168 expect(_flatten(classB.type), classB.type); | |
| 10169 } | |
| 10170 | |
| 10171 void test_flatten_related_derived_types() { | |
| 10172 InterfaceType intType = _typeProvider.intType; | |
| 10173 InterfaceType numType = _typeProvider.numType; | |
| 10174 // class Derived<T> extends Future<T> | |
| 10175 ClassElementImpl derivedClass = | |
| 10176 ElementFactory.classElement2('Derived', ['T']); | |
| 10177 derivedClass.supertype = _typeProvider.futureType | |
| 10178 .substitute4([derivedClass.typeParameters[0].type]); | |
| 10179 InterfaceType derivedType = derivedClass.type; | |
| 10180 // class A extends Derived<int> implements Derived<num> { ... } | |
| 10181 ClassElementImpl classA = | |
| 10182 ElementFactory.classElement('A', derivedType.substitute4([intType])); | |
| 10183 classA.interfaces = <InterfaceType>[ | |
| 10184 derivedType.substitute4([numType]) | |
| 10185 ]; | |
| 10186 // class B extends Future<num> implements Future<int> { ... } | |
| 10187 ClassElementImpl classB = | |
| 10188 ElementFactory.classElement('B', derivedType.substitute4([numType])); | |
| 10189 classB.interfaces = <InterfaceType>[ | |
| 10190 derivedType.substitute4([intType]) | |
| 10191 ]; | |
| 10192 // flatten(A) = flatten(B) = int, since int is more specific than num. | |
| 10193 // The code in flatten() that inhibits infinite recursion shouldn't be | |
| 10194 // fooled by the fact that Derived appears twice in the type hierarchy. | |
| 10195 expect(_flatten(classA.type), intType); | |
| 10196 expect(_flatten(classB.type), intType); | |
| 10197 } | |
| 10198 | |
| 10199 void test_flatten_related_types() { | |
| 10200 InterfaceType futureType = _typeProvider.futureType; | |
| 10201 InterfaceType intType = _typeProvider.intType; | |
| 10202 InterfaceType numType = _typeProvider.numType; | |
| 10203 // class A extends Future<int> implements Future<num> { ... } | |
| 10204 ClassElementImpl classA = | |
| 10205 ElementFactory.classElement('A', futureType.substitute4([intType])); | |
| 10206 classA.interfaces = <InterfaceType>[ | |
| 10207 futureType.substitute4([numType]) | |
| 10208 ]; | |
| 10209 // class B extends Future<num> implements Future<int> { ... } | |
| 10210 ClassElementImpl classB = | |
| 10211 ElementFactory.classElement('B', futureType.substitute4([numType])); | |
| 10212 classB.interfaces = <InterfaceType>[ | |
| 10213 futureType.substitute4([intType]) | |
| 10214 ]; | |
| 10215 // flatten(A) = flatten(B) = int, since int is more specific than num. | |
| 10216 expect(_flatten(classA.type), intType); | |
| 10217 expect(_flatten(classB.type), intType); | |
| 10218 } | |
| 10219 | |
| 10220 void test_flatten_simple() { | |
| 10221 InterfaceType intType = _typeProvider.intType; | |
| 10222 DartType dynamicType = _typeProvider.dynamicType; | |
| 10223 InterfaceType futureDynamicType = _typeProvider.futureDynamicType; | |
| 10224 InterfaceType futureIntType = | |
| 10225 _typeProvider.futureType.substitute4([intType]); | |
| 10226 InterfaceType futureFutureDynamicType = | |
| 10227 _typeProvider.futureType.substitute4([futureDynamicType]); | |
| 10228 InterfaceType futureFutureIntType = | |
| 10229 _typeProvider.futureType.substitute4([futureIntType]); | |
| 10230 // flatten(int) = int | |
| 10231 expect(_flatten(intType), intType); | |
| 10232 // flatten(dynamic) = dynamic | |
| 10233 expect(_flatten(dynamicType), dynamicType); | |
| 10234 // flatten(Future) = dynamic | |
| 10235 expect(_flatten(futureDynamicType), dynamicType); | |
| 10236 // flatten(Future<int>) = int | |
| 10237 expect(_flatten(futureIntType), intType); | |
| 10238 // flatten(Future<Future>) = dynamic | |
| 10239 expect(_flatten(futureFutureDynamicType), dynamicType); | |
| 10240 // flatten(Future<Future<int>>) = int | |
| 10241 expect(_flatten(futureFutureIntType), intType); | |
| 10242 } | |
| 10243 | |
| 10244 void test_flatten_unrelated_types() { | |
| 10245 InterfaceType futureType = _typeProvider.futureType; | |
| 10246 InterfaceType intType = _typeProvider.intType; | |
| 10247 InterfaceType stringType = _typeProvider.stringType; | |
| 10248 // class A extends Future<int> implements Future<String> { ... } | |
| 10249 ClassElementImpl classA = | |
| 10250 ElementFactory.classElement('A', futureType.substitute4([intType])); | |
| 10251 classA.interfaces = <InterfaceType>[ | |
| 10252 futureType.substitute4([stringType]) | |
| 10253 ]; | |
| 10254 // class B extends Future<String> implements Future<int> { ... } | |
| 10255 ClassElementImpl classB = | |
| 10256 ElementFactory.classElement('B', futureType.substitute4([stringType])); | |
| 10257 classB.interfaces = <InterfaceType>[ | |
| 10258 futureType.substitute4([intType]) | |
| 10259 ]; | |
| 10260 // flatten(A) = A and flatten(B) = B, since neither string nor int is more | |
| 10261 // specific than the other. | |
| 10262 expect(_flatten(classA.type), classA.type); | |
| 10263 expect(_flatten(classB.type), classB.type); | |
| 10264 } | |
| 10265 | |
| 10266 void test_visitAdjacentStrings() { | |
| 10267 // "a" "b" | |
| 10268 Expression node = AstFactory | |
| 10269 .adjacentStrings([_resolvedString("a"), _resolvedString("b")]); | |
| 10270 expect(_analyze(node), same(_typeProvider.stringType)); | |
| 10271 _listener.assertNoErrors(); | |
| 10272 } | |
| 10273 | |
| 10274 void test_visitAsExpression() { | |
| 10275 // class A { ... this as B ... } | |
| 10276 // class B extends A {} | |
| 10277 ClassElement superclass = ElementFactory.classElement2("A"); | |
| 10278 InterfaceType superclassType = superclass.type; | |
| 10279 ClassElement subclass = ElementFactory.classElement("B", superclassType); | |
| 10280 Expression node = AstFactory.asExpression( | |
| 10281 AstFactory.thisExpression(), AstFactory.typeName(subclass)); | |
| 10282 expect(_analyze3(node, superclassType), same(subclass.type)); | |
| 10283 _listener.assertNoErrors(); | |
| 10284 } | |
| 10285 | |
| 10286 void test_visitAssignmentExpression_compound() { | |
| 10287 // i += 1 | |
| 10288 InterfaceType numType = _typeProvider.numType; | |
| 10289 SimpleIdentifier identifier = _resolvedVariable(_typeProvider.intType, "i"); | |
| 10290 AssignmentExpression node = AstFactory.assignmentExpression( | |
| 10291 identifier, TokenType.PLUS_EQ, _resolvedInteger(1)); | |
| 10292 MethodElement plusMethod = getMethod(numType, "+"); | |
| 10293 node.staticElement = plusMethod; | |
| 10294 expect(_analyze(node), same(numType)); | |
| 10295 _listener.assertNoErrors(); | |
| 10296 } | |
| 10297 | |
| 10298 void test_visitAssignmentExpression_compoundIfNull_differentTypes() { | |
| 10299 // double d; d ??= 0 | |
| 10300 Expression node = AstFactory.assignmentExpression( | |
| 10301 _resolvedVariable(_typeProvider.doubleType, 'd'), | |
| 10302 TokenType.QUESTION_QUESTION_EQ, | |
| 10303 _resolvedInteger(0)); | |
| 10304 expect(_analyze(node), same(_typeProvider.numType)); | |
| 10305 _listener.assertNoErrors(); | |
| 10306 } | |
| 10307 | |
| 10308 void test_visitAssignmentExpression_compoundIfNull_sameTypes() { | |
| 10309 // int i; i ??= 0 | |
| 10310 Expression node = AstFactory.assignmentExpression( | |
| 10311 _resolvedVariable(_typeProvider.intType, 'i'), | |
| 10312 TokenType.QUESTION_QUESTION_EQ, | |
| 10313 _resolvedInteger(0)); | |
| 10314 expect(_analyze(node), same(_typeProvider.intType)); | |
| 10315 _listener.assertNoErrors(); | |
| 10316 } | |
| 10317 | |
| 10318 void test_visitAssignmentExpression_simple() { | |
| 10319 // i = 0 | |
| 10320 InterfaceType intType = _typeProvider.intType; | |
| 10321 Expression node = AstFactory.assignmentExpression( | |
| 10322 _resolvedVariable(intType, "i"), TokenType.EQ, _resolvedInteger(0)); | |
| 10323 expect(_analyze(node), same(intType)); | |
| 10324 _listener.assertNoErrors(); | |
| 10325 } | |
| 10326 | |
| 10327 void test_visitAwaitExpression_flattened() { | |
| 10328 // await e, where e has type Future<Future<int>> | |
| 10329 InterfaceType intType = _typeProvider.intType; | |
| 10330 InterfaceType futureIntType = | |
| 10331 _typeProvider.futureType.substitute4(<DartType>[intType]); | |
| 10332 InterfaceType futureFutureIntType = | |
| 10333 _typeProvider.futureType.substitute4(<DartType>[futureIntType]); | |
| 10334 Expression node = | |
| 10335 AstFactory.awaitExpression(_resolvedVariable(futureFutureIntType, 'e')); | |
| 10336 expect(_analyze(node), same(intType)); | |
| 10337 _listener.assertNoErrors(); | |
| 10338 } | |
| 10339 | |
| 10340 void test_visitAwaitExpression_simple() { | |
| 10341 // await e, where e has type Future<int> | |
| 10342 InterfaceType intType = _typeProvider.intType; | |
| 10343 InterfaceType futureIntType = | |
| 10344 _typeProvider.futureType.substitute4(<DartType>[intType]); | |
| 10345 Expression node = | |
| 10346 AstFactory.awaitExpression(_resolvedVariable(futureIntType, 'e')); | |
| 10347 expect(_analyze(node), same(intType)); | |
| 10348 _listener.assertNoErrors(); | |
| 10349 } | |
| 10350 | |
| 10351 void test_visitBinaryExpression_equals() { | |
| 10352 // 2 == 3 | |
| 10353 Expression node = AstFactory.binaryExpression( | |
| 10354 _resolvedInteger(2), TokenType.EQ_EQ, _resolvedInteger(3)); | |
| 10355 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 10356 _listener.assertNoErrors(); | |
| 10357 } | |
| 10358 | |
| 10359 void test_visitBinaryExpression_ifNull() { | |
| 10360 // 1 ?? 1.5 | |
| 10361 Expression node = AstFactory.binaryExpression( | |
| 10362 _resolvedInteger(1), TokenType.QUESTION_QUESTION, _resolvedDouble(1.5)); | |
| 10363 expect(_analyze(node), same(_typeProvider.numType)); | |
| 10364 _listener.assertNoErrors(); | |
| 10365 } | |
| 10366 | |
| 10367 void test_visitBinaryExpression_logicalAnd() { | |
| 10368 // false && true | |
| 10369 Expression node = AstFactory.binaryExpression( | |
| 10370 AstFactory.booleanLiteral(false), | |
| 10371 TokenType.AMPERSAND_AMPERSAND, | |
| 10372 AstFactory.booleanLiteral(true)); | |
| 10373 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 10374 _listener.assertNoErrors(); | |
| 10375 } | |
| 10376 | |
| 10377 void test_visitBinaryExpression_logicalOr() { | |
| 10378 // false || true | |
| 10379 Expression node = AstFactory.binaryExpression( | |
| 10380 AstFactory.booleanLiteral(false), | |
| 10381 TokenType.BAR_BAR, | |
| 10382 AstFactory.booleanLiteral(true)); | |
| 10383 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 10384 _listener.assertNoErrors(); | |
| 10385 } | |
| 10386 | |
| 10387 void test_visitBinaryExpression_minusID_propagated() { | |
| 10388 // a - b | |
| 10389 BinaryExpression node = AstFactory.binaryExpression( | |
| 10390 _propagatedVariable(_typeProvider.intType, 'a'), | |
| 10391 TokenType.MINUS, | |
| 10392 _propagatedVariable(_typeProvider.doubleType, 'b')); | |
| 10393 node.propagatedElement = getMethod(_typeProvider.numType, "+"); | |
| 10394 _analyze(node); | |
| 10395 expect(node.propagatedType, same(_typeProvider.doubleType)); | |
| 10396 _listener.assertNoErrors(); | |
| 10397 } | |
| 10398 | |
| 10399 void test_visitBinaryExpression_notEquals() { | |
| 10400 // 2 != 3 | |
| 10401 Expression node = AstFactory.binaryExpression( | |
| 10402 _resolvedInteger(2), TokenType.BANG_EQ, _resolvedInteger(3)); | |
| 10403 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 10404 _listener.assertNoErrors(); | |
| 10405 } | |
| 10406 | |
| 10407 void test_visitBinaryExpression_plusID() { | |
| 10408 // 1 + 2.0 | |
| 10409 BinaryExpression node = AstFactory.binaryExpression( | |
| 10410 _resolvedInteger(1), TokenType.PLUS, _resolvedDouble(2.0)); | |
| 10411 node.staticElement = getMethod(_typeProvider.numType, "+"); | |
| 10412 expect(_analyze(node), same(_typeProvider.doubleType)); | |
| 10413 _listener.assertNoErrors(); | |
| 10414 } | |
| 10415 | |
| 10416 void test_visitBinaryExpression_plusII() { | |
| 10417 // 1 + 2 | |
| 10418 BinaryExpression node = AstFactory.binaryExpression( | |
| 10419 _resolvedInteger(1), TokenType.PLUS, _resolvedInteger(2)); | |
| 10420 node.staticElement = getMethod(_typeProvider.numType, "+"); | |
| 10421 expect(_analyze(node), same(_typeProvider.intType)); | |
| 10422 _listener.assertNoErrors(); | |
| 10423 } | |
| 10424 | |
| 10425 void test_visitBinaryExpression_plusII_propagated() { | |
| 10426 // a + b | |
| 10427 BinaryExpression node = AstFactory.binaryExpression( | |
| 10428 _propagatedVariable(_typeProvider.intType, 'a'), | |
| 10429 TokenType.PLUS, | |
| 10430 _propagatedVariable(_typeProvider.intType, 'b')); | |
| 10431 node.propagatedElement = getMethod(_typeProvider.numType, "+"); | |
| 10432 _analyze(node); | |
| 10433 expect(node.propagatedType, same(_typeProvider.intType)); | |
| 10434 _listener.assertNoErrors(); | |
| 10435 } | |
| 10436 | |
| 10437 void test_visitBinaryExpression_slash() { | |
| 10438 // 2 / 2 | |
| 10439 BinaryExpression node = AstFactory.binaryExpression( | |
| 10440 _resolvedInteger(2), TokenType.SLASH, _resolvedInteger(2)); | |
| 10441 node.staticElement = getMethod(_typeProvider.numType, "/"); | |
| 10442 expect(_analyze(node), same(_typeProvider.doubleType)); | |
| 10443 _listener.assertNoErrors(); | |
| 10444 } | |
| 10445 | |
| 10446 void test_visitBinaryExpression_star_notSpecial() { | |
| 10447 // class A { | |
| 10448 // A operator *(double value); | |
| 10449 // } | |
| 10450 // (a as A) * 2.0 | |
| 10451 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 10452 InterfaceType typeA = classA.type; | |
| 10453 MethodElement operator = | |
| 10454 ElementFactory.methodElement("*", typeA, [_typeProvider.doubleType]); | |
| 10455 classA.methods = <MethodElement>[operator]; | |
| 10456 BinaryExpression node = AstFactory.binaryExpression( | |
| 10457 AstFactory.asExpression( | |
| 10458 AstFactory.identifier3("a"), AstFactory.typeName(classA)), | |
| 10459 TokenType.PLUS, | |
| 10460 _resolvedDouble(2.0)); | |
| 10461 node.staticElement = operator; | |
| 10462 expect(_analyze(node), same(typeA)); | |
| 10463 _listener.assertNoErrors(); | |
| 10464 } | |
| 10465 | |
| 10466 void test_visitBinaryExpression_starID() { | |
| 10467 // 1 * 2.0 | |
| 10468 BinaryExpression node = AstFactory.binaryExpression( | |
| 10469 _resolvedInteger(1), TokenType.PLUS, _resolvedDouble(2.0)); | |
| 10470 node.staticElement = getMethod(_typeProvider.numType, "*"); | |
| 10471 expect(_analyze(node), same(_typeProvider.doubleType)); | |
| 10472 _listener.assertNoErrors(); | |
| 10473 } | |
| 10474 | |
| 10475 void test_visitBooleanLiteral_false() { | |
| 10476 // false | |
| 10477 Expression node = AstFactory.booleanLiteral(false); | |
| 10478 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 10479 _listener.assertNoErrors(); | |
| 10480 } | |
| 10481 | |
| 10482 void test_visitBooleanLiteral_true() { | |
| 10483 // true | |
| 10484 Expression node = AstFactory.booleanLiteral(true); | |
| 10485 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 10486 _listener.assertNoErrors(); | |
| 10487 } | |
| 10488 | |
| 10489 void test_visitCascadeExpression() { | |
| 10490 // a..length | |
| 10491 Expression node = AstFactory.cascadeExpression( | |
| 10492 _resolvedString("a"), [AstFactory.propertyAccess2(null, "length")]); | |
| 10493 expect(_analyze(node), same(_typeProvider.stringType)); | |
| 10494 _listener.assertNoErrors(); | |
| 10495 } | |
| 10496 | |
| 10497 void test_visitConditionalExpression_differentTypes() { | |
| 10498 // true ? 1.0 : 0 | |
| 10499 Expression node = AstFactory.conditionalExpression( | |
| 10500 AstFactory.booleanLiteral(true), | |
| 10501 _resolvedDouble(1.0), | |
| 10502 _resolvedInteger(0)); | |
| 10503 expect(_analyze(node), same(_typeProvider.numType)); | |
| 10504 _listener.assertNoErrors(); | |
| 10505 } | |
| 10506 | |
| 10507 void test_visitConditionalExpression_sameTypes() { | |
| 10508 // true ? 1 : 0 | |
| 10509 Expression node = AstFactory.conditionalExpression( | |
| 10510 AstFactory.booleanLiteral(true), | |
| 10511 _resolvedInteger(1), | |
| 10512 _resolvedInteger(0)); | |
| 10513 expect(_analyze(node), same(_typeProvider.intType)); | |
| 10514 _listener.assertNoErrors(); | |
| 10515 } | |
| 10516 | |
| 10517 void test_visitDoubleLiteral() { | |
| 10518 // 4.33 | |
| 10519 Expression node = AstFactory.doubleLiteral(4.33); | |
| 10520 expect(_analyze(node), same(_typeProvider.doubleType)); | |
| 10521 _listener.assertNoErrors(); | |
| 10522 } | |
| 10523 | |
| 10524 void test_visitFunctionExpression_async_block() { | |
| 10525 // () async {} | |
| 10526 BlockFunctionBody body = AstFactory.blockFunctionBody2(); | |
| 10527 body.keyword = TokenFactory.tokenFromString('async'); | |
| 10528 FunctionExpression node = | |
| 10529 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body); | |
| 10530 DartType resultType = _analyze(node); | |
| 10531 _assertFunctionType( | |
| 10532 _typeProvider.futureDynamicType, null, null, null, resultType); | |
| 10533 _listener.assertNoErrors(); | |
| 10534 } | |
| 10535 | |
| 10536 void test_visitFunctionExpression_async_expression() { | |
| 10537 // () async => e, where e has type int | |
| 10538 InterfaceType intType = _typeProvider.intType; | |
| 10539 InterfaceType futureIntType = | |
| 10540 _typeProvider.futureType.substitute4(<DartType>[intType]); | |
| 10541 Expression expression = _resolvedVariable(intType, 'e'); | |
| 10542 ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression); | |
| 10543 body.keyword = TokenFactory.tokenFromString('async'); | |
| 10544 FunctionExpression node = | |
| 10545 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body); | |
| 10546 DartType resultType = _analyze(node); | |
| 10547 _assertFunctionType(futureIntType, null, null, null, resultType); | |
| 10548 _listener.assertNoErrors(); | |
| 10549 } | |
| 10550 | |
| 10551 void test_visitFunctionExpression_async_expression_flatten() { | |
| 10552 // () async => e, where e has type Future<int> | |
| 10553 InterfaceType intType = _typeProvider.intType; | |
| 10554 InterfaceType futureIntType = | |
| 10555 _typeProvider.futureType.substitute4(<DartType>[intType]); | |
| 10556 Expression expression = _resolvedVariable(futureIntType, 'e'); | |
| 10557 ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression); | |
| 10558 body.keyword = TokenFactory.tokenFromString('async'); | |
| 10559 FunctionExpression node = | |
| 10560 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body); | |
| 10561 DartType resultType = _analyze(node); | |
| 10562 _assertFunctionType(futureIntType, null, null, null, resultType); | |
| 10563 _listener.assertNoErrors(); | |
| 10564 } | |
| 10565 | |
| 10566 void test_visitFunctionExpression_async_expression_flatten_twice() { | |
| 10567 // () async => e, where e has type Future<Future<int>> | |
| 10568 InterfaceType intType = _typeProvider.intType; | |
| 10569 InterfaceType futureIntType = | |
| 10570 _typeProvider.futureType.substitute4(<DartType>[intType]); | |
| 10571 InterfaceType futureFutureIntType = | |
| 10572 _typeProvider.futureType.substitute4(<DartType>[futureIntType]); | |
| 10573 Expression expression = _resolvedVariable(futureFutureIntType, 'e'); | |
| 10574 ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression); | |
| 10575 body.keyword = TokenFactory.tokenFromString('async'); | |
| 10576 FunctionExpression node = | |
| 10577 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body); | |
| 10578 DartType resultType = _analyze(node); | |
| 10579 _assertFunctionType(futureIntType, null, null, null, resultType); | |
| 10580 _listener.assertNoErrors(); | |
| 10581 } | |
| 10582 | |
| 10583 void test_visitFunctionExpression_generator_async() { | |
| 10584 // () async* {} | |
| 10585 BlockFunctionBody body = AstFactory.blockFunctionBody2(); | |
| 10586 body.keyword = TokenFactory.tokenFromString('async'); | |
| 10587 body.star = TokenFactory.tokenFromType(TokenType.STAR); | |
| 10588 FunctionExpression node = | |
| 10589 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body); | |
| 10590 DartType resultType = _analyze(node); | |
| 10591 _assertFunctionType( | |
| 10592 _typeProvider.streamDynamicType, null, null, null, resultType); | |
| 10593 _listener.assertNoErrors(); | |
| 10594 } | |
| 10595 | |
| 10596 void test_visitFunctionExpression_generator_sync() { | |
| 10597 // () sync* {} | |
| 10598 BlockFunctionBody body = AstFactory.blockFunctionBody2(); | |
| 10599 body.keyword = TokenFactory.tokenFromString('sync'); | |
| 10600 body.star = TokenFactory.tokenFromType(TokenType.STAR); | |
| 10601 FunctionExpression node = | |
| 10602 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body); | |
| 10603 DartType resultType = _analyze(node); | |
| 10604 _assertFunctionType( | |
| 10605 _typeProvider.iterableDynamicType, null, null, null, resultType); | |
| 10606 _listener.assertNoErrors(); | |
| 10607 } | |
| 10608 | |
| 10609 void test_visitFunctionExpression_named_block() { | |
| 10610 // ({p1 : 0, p2 : 0}) {} | |
| 10611 DartType dynamicType = _typeProvider.dynamicType; | |
| 10612 FormalParameter p1 = AstFactory.namedFormalParameter( | |
| 10613 AstFactory.simpleFormalParameter3("p1"), _resolvedInteger(0)); | |
| 10614 _setType(p1, dynamicType); | |
| 10615 FormalParameter p2 = AstFactory.namedFormalParameter( | |
| 10616 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0)); | |
| 10617 _setType(p2, dynamicType); | |
| 10618 FunctionExpression node = _resolvedFunctionExpression( | |
| 10619 AstFactory.formalParameterList([p1, p2]), | |
| 10620 AstFactory.blockFunctionBody2()); | |
| 10621 _analyze5(p1); | |
| 10622 _analyze5(p2); | |
| 10623 DartType resultType = _analyze(node); | |
| 10624 Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>(); | |
| 10625 expectedNamedTypes["p1"] = dynamicType; | |
| 10626 expectedNamedTypes["p2"] = dynamicType; | |
| 10627 _assertFunctionType( | |
| 10628 dynamicType, null, null, expectedNamedTypes, resultType); | |
| 10629 _listener.assertNoErrors(); | |
| 10630 } | |
| 10631 | |
| 10632 void test_visitFunctionExpression_named_expression() { | |
| 10633 // ({p : 0}) -> 0; | |
| 10634 DartType dynamicType = _typeProvider.dynamicType; | |
| 10635 FormalParameter p = AstFactory.namedFormalParameter( | |
| 10636 AstFactory.simpleFormalParameter3("p"), _resolvedInteger(0)); | |
| 10637 _setType(p, dynamicType); | |
| 10638 FunctionExpression node = _resolvedFunctionExpression( | |
| 10639 AstFactory.formalParameterList([p]), | |
| 10640 AstFactory.expressionFunctionBody(_resolvedInteger(0))); | |
| 10641 _analyze5(p); | |
| 10642 DartType resultType = _analyze(node); | |
| 10643 Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>(); | |
| 10644 expectedNamedTypes["p"] = dynamicType; | |
| 10645 _assertFunctionType( | |
| 10646 _typeProvider.intType, null, null, expectedNamedTypes, resultType); | |
| 10647 _listener.assertNoErrors(); | |
| 10648 } | |
| 10649 | |
| 10650 void test_visitFunctionExpression_normal_block() { | |
| 10651 // (p1, p2) {} | |
| 10652 DartType dynamicType = _typeProvider.dynamicType; | |
| 10653 FormalParameter p1 = AstFactory.simpleFormalParameter3("p1"); | |
| 10654 _setType(p1, dynamicType); | |
| 10655 FormalParameter p2 = AstFactory.simpleFormalParameter3("p2"); | |
| 10656 _setType(p2, dynamicType); | |
| 10657 FunctionExpression node = _resolvedFunctionExpression( | |
| 10658 AstFactory.formalParameterList([p1, p2]), | |
| 10659 AstFactory.blockFunctionBody2()); | |
| 10660 _analyze5(p1); | |
| 10661 _analyze5(p2); | |
| 10662 DartType resultType = _analyze(node); | |
| 10663 _assertFunctionType(dynamicType, <DartType>[dynamicType, dynamicType], null, | |
| 10664 null, resultType); | |
| 10665 _listener.assertNoErrors(); | |
| 10666 } | |
| 10667 | |
| 10668 void test_visitFunctionExpression_normal_expression() { | |
| 10669 // (p1, p2) -> 0 | |
| 10670 DartType dynamicType = _typeProvider.dynamicType; | |
| 10671 FormalParameter p = AstFactory.simpleFormalParameter3("p"); | |
| 10672 _setType(p, dynamicType); | |
| 10673 FunctionExpression node = _resolvedFunctionExpression( | |
| 10674 AstFactory.formalParameterList([p]), | |
| 10675 AstFactory.expressionFunctionBody(_resolvedInteger(0))); | |
| 10676 _analyze5(p); | |
| 10677 DartType resultType = _analyze(node); | |
| 10678 _assertFunctionType( | |
| 10679 _typeProvider.intType, <DartType>[dynamicType], null, null, resultType); | |
| 10680 _listener.assertNoErrors(); | |
| 10681 } | |
| 10682 | |
| 10683 void test_visitFunctionExpression_normalAndNamed_block() { | |
| 10684 // (p1, {p2 : 0}) {} | |
| 10685 DartType dynamicType = _typeProvider.dynamicType; | |
| 10686 FormalParameter p1 = AstFactory.simpleFormalParameter3("p1"); | |
| 10687 _setType(p1, dynamicType); | |
| 10688 FormalParameter p2 = AstFactory.namedFormalParameter( | |
| 10689 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0)); | |
| 10690 _setType(p2, dynamicType); | |
| 10691 FunctionExpression node = _resolvedFunctionExpression( | |
| 10692 AstFactory.formalParameterList([p1, p2]), | |
| 10693 AstFactory.blockFunctionBody2()); | |
| 10694 _analyze5(p2); | |
| 10695 DartType resultType = _analyze(node); | |
| 10696 Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>(); | |
| 10697 expectedNamedTypes["p2"] = dynamicType; | |
| 10698 _assertFunctionType(dynamicType, <DartType>[dynamicType], null, | |
| 10699 expectedNamedTypes, resultType); | |
| 10700 _listener.assertNoErrors(); | |
| 10701 } | |
| 10702 | |
| 10703 void test_visitFunctionExpression_normalAndNamed_expression() { | |
| 10704 // (p1, {p2 : 0}) -> 0 | |
| 10705 DartType dynamicType = _typeProvider.dynamicType; | |
| 10706 FormalParameter p1 = AstFactory.simpleFormalParameter3("p1"); | |
| 10707 _setType(p1, dynamicType); | |
| 10708 FormalParameter p2 = AstFactory.namedFormalParameter( | |
| 10709 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0)); | |
| 10710 _setType(p2, dynamicType); | |
| 10711 FunctionExpression node = _resolvedFunctionExpression( | |
| 10712 AstFactory.formalParameterList([p1, p2]), | |
| 10713 AstFactory.expressionFunctionBody(_resolvedInteger(0))); | |
| 10714 _analyze5(p2); | |
| 10715 DartType resultType = _analyze(node); | |
| 10716 Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>(); | |
| 10717 expectedNamedTypes["p2"] = dynamicType; | |
| 10718 _assertFunctionType(_typeProvider.intType, <DartType>[dynamicType], null, | |
| 10719 expectedNamedTypes, resultType); | |
| 10720 _listener.assertNoErrors(); | |
| 10721 } | |
| 10722 | |
| 10723 void test_visitFunctionExpression_normalAndPositional_block() { | |
| 10724 // (p1, [p2 = 0]) {} | |
| 10725 DartType dynamicType = _typeProvider.dynamicType; | |
| 10726 FormalParameter p1 = AstFactory.simpleFormalParameter3("p1"); | |
| 10727 _setType(p1, dynamicType); | |
| 10728 FormalParameter p2 = AstFactory.positionalFormalParameter( | |
| 10729 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0)); | |
| 10730 _setType(p2, dynamicType); | |
| 10731 FunctionExpression node = _resolvedFunctionExpression( | |
| 10732 AstFactory.formalParameterList([p1, p2]), | |
| 10733 AstFactory.blockFunctionBody2()); | |
| 10734 _analyze5(p1); | |
| 10735 _analyze5(p2); | |
| 10736 DartType resultType = _analyze(node); | |
| 10737 _assertFunctionType(dynamicType, <DartType>[dynamicType], | |
| 10738 <DartType>[dynamicType], null, resultType); | |
| 10739 _listener.assertNoErrors(); | |
| 10740 } | |
| 10741 | |
| 10742 void test_visitFunctionExpression_normalAndPositional_expression() { | |
| 10743 // (p1, [p2 = 0]) -> 0 | |
| 10744 DartType dynamicType = _typeProvider.dynamicType; | |
| 10745 FormalParameter p1 = AstFactory.simpleFormalParameter3("p1"); | |
| 10746 _setType(p1, dynamicType); | |
| 10747 FormalParameter p2 = AstFactory.positionalFormalParameter( | |
| 10748 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0)); | |
| 10749 _setType(p2, dynamicType); | |
| 10750 FunctionExpression node = _resolvedFunctionExpression( | |
| 10751 AstFactory.formalParameterList([p1, p2]), | |
| 10752 AstFactory.expressionFunctionBody(_resolvedInteger(0))); | |
| 10753 _analyze5(p1); | |
| 10754 _analyze5(p2); | |
| 10755 DartType resultType = _analyze(node); | |
| 10756 _assertFunctionType(_typeProvider.intType, <DartType>[dynamicType], | |
| 10757 <DartType>[dynamicType], null, resultType); | |
| 10758 _listener.assertNoErrors(); | |
| 10759 } | |
| 10760 | |
| 10761 void test_visitFunctionExpression_positional_block() { | |
| 10762 // ([p1 = 0, p2 = 0]) {} | |
| 10763 DartType dynamicType = _typeProvider.dynamicType; | |
| 10764 FormalParameter p1 = AstFactory.positionalFormalParameter( | |
| 10765 AstFactory.simpleFormalParameter3("p1"), _resolvedInteger(0)); | |
| 10766 _setType(p1, dynamicType); | |
| 10767 FormalParameter p2 = AstFactory.positionalFormalParameter( | |
| 10768 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0)); | |
| 10769 _setType(p2, dynamicType); | |
| 10770 FunctionExpression node = _resolvedFunctionExpression( | |
| 10771 AstFactory.formalParameterList([p1, p2]), | |
| 10772 AstFactory.blockFunctionBody2()); | |
| 10773 _analyze5(p1); | |
| 10774 _analyze5(p2); | |
| 10775 DartType resultType = _analyze(node); | |
| 10776 _assertFunctionType(dynamicType, null, <DartType>[dynamicType, dynamicType], | |
| 10777 null, resultType); | |
| 10778 _listener.assertNoErrors(); | |
| 10779 } | |
| 10780 | |
| 10781 void test_visitFunctionExpression_positional_expression() { | |
| 10782 // ([p1 = 0, p2 = 0]) -> 0 | |
| 10783 DartType dynamicType = _typeProvider.dynamicType; | |
| 10784 FormalParameter p = AstFactory.positionalFormalParameter( | |
| 10785 AstFactory.simpleFormalParameter3("p"), _resolvedInteger(0)); | |
| 10786 _setType(p, dynamicType); | |
| 10787 FunctionExpression node = _resolvedFunctionExpression( | |
| 10788 AstFactory.formalParameterList([p]), | |
| 10789 AstFactory.expressionFunctionBody(_resolvedInteger(0))); | |
| 10790 _analyze5(p); | |
| 10791 DartType resultType = _analyze(node); | |
| 10792 _assertFunctionType( | |
| 10793 _typeProvider.intType, null, <DartType>[dynamicType], null, resultType); | |
| 10794 _listener.assertNoErrors(); | |
| 10795 } | |
| 10796 | |
| 10797 void test_visitIndexExpression_getter() { | |
| 10798 // List a; | |
| 10799 // a[2] | |
| 10800 InterfaceType listType = _typeProvider.listType; | |
| 10801 SimpleIdentifier identifier = _resolvedVariable(listType, "a"); | |
| 10802 IndexExpression node = | |
| 10803 AstFactory.indexExpression(identifier, _resolvedInteger(2)); | |
| 10804 MethodElement indexMethod = listType.element.methods[0]; | |
| 10805 node.staticElement = indexMethod; | |
| 10806 expect(_analyze(node), same(listType.typeArguments[0])); | |
| 10807 _listener.assertNoErrors(); | |
| 10808 } | |
| 10809 | |
| 10810 void test_visitIndexExpression_setter() { | |
| 10811 // List a; | |
| 10812 // a[2] = 0 | |
| 10813 InterfaceType listType = _typeProvider.listType; | |
| 10814 SimpleIdentifier identifier = _resolvedVariable(listType, "a"); | |
| 10815 IndexExpression node = | |
| 10816 AstFactory.indexExpression(identifier, _resolvedInteger(2)); | |
| 10817 MethodElement indexMethod = listType.element.methods[1]; | |
| 10818 node.staticElement = indexMethod; | |
| 10819 AstFactory.assignmentExpression(node, TokenType.EQ, AstFactory.integer(0)); | |
| 10820 expect(_analyze(node), same(listType.typeArguments[0])); | |
| 10821 _listener.assertNoErrors(); | |
| 10822 } | |
| 10823 | |
| 10824 void test_visitIndexExpression_typeParameters() { | |
| 10825 // List<int> list = ... | |
| 10826 // list[0] | |
| 10827 InterfaceType intType = _typeProvider.intType; | |
| 10828 InterfaceType listType = _typeProvider.listType; | |
| 10829 // (int) -> E | |
| 10830 MethodElement methodElement = getMethod(listType, "[]"); | |
| 10831 // "list" has type List<int> | |
| 10832 SimpleIdentifier identifier = AstFactory.identifier3("list"); | |
| 10833 InterfaceType listOfIntType = listType.substitute4(<DartType>[intType]); | |
| 10834 identifier.staticType = listOfIntType; | |
| 10835 // list[0] has MethodElement element (int) -> E | |
| 10836 IndexExpression indexExpression = | |
| 10837 AstFactory.indexExpression(identifier, AstFactory.integer(0)); | |
| 10838 MethodElement indexMethod = MethodMember.from(methodElement, listOfIntType); | |
| 10839 indexExpression.staticElement = indexMethod; | |
| 10840 // analyze and assert result of the index expression | |
| 10841 expect(_analyze(indexExpression), same(intType)); | |
| 10842 _listener.assertNoErrors(); | |
| 10843 } | |
| 10844 | |
| 10845 void test_visitIndexExpression_typeParameters_inSetterContext() { | |
| 10846 // List<int> list = ... | |
| 10847 // list[0] = 0; | |
| 10848 InterfaceType intType = _typeProvider.intType; | |
| 10849 InterfaceType listType = _typeProvider.listType; | |
| 10850 // (int, E) -> void | |
| 10851 MethodElement methodElement = getMethod(listType, "[]="); | |
| 10852 // "list" has type List<int> | |
| 10853 SimpleIdentifier identifier = AstFactory.identifier3("list"); | |
| 10854 InterfaceType listOfIntType = listType.substitute4(<DartType>[intType]); | |
| 10855 identifier.staticType = listOfIntType; | |
| 10856 // list[0] has MethodElement element (int) -> E | |
| 10857 IndexExpression indexExpression = | |
| 10858 AstFactory.indexExpression(identifier, AstFactory.integer(0)); | |
| 10859 MethodElement indexMethod = MethodMember.from(methodElement, listOfIntType); | |
| 10860 indexExpression.staticElement = indexMethod; | |
| 10861 // list[0] should be in a setter context | |
| 10862 AstFactory.assignmentExpression( | |
| 10863 indexExpression, TokenType.EQ, AstFactory.integer(0)); | |
| 10864 // analyze and assert result of the index expression | |
| 10865 expect(_analyze(indexExpression), same(intType)); | |
| 10866 _listener.assertNoErrors(); | |
| 10867 } | |
| 10868 | |
| 10869 void test_visitInstanceCreationExpression_named() { | |
| 10870 // new C.m() | |
| 10871 ClassElementImpl classElement = ElementFactory.classElement2("C"); | |
| 10872 String constructorName = "m"; | |
| 10873 ConstructorElementImpl constructor = | |
| 10874 ElementFactory.constructorElement2(classElement, constructorName); | |
| 10875 constructor.returnType = classElement.type; | |
| 10876 FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor); | |
| 10877 constructor.type = constructorType; | |
| 10878 classElement.constructors = <ConstructorElement>[constructor]; | |
| 10879 InstanceCreationExpression node = AstFactory.instanceCreationExpression2( | |
| 10880 null, | |
| 10881 AstFactory.typeName(classElement), | |
| 10882 [AstFactory.identifier3(constructorName)]); | |
| 10883 node.staticElement = constructor; | |
| 10884 expect(_analyze(node), same(classElement.type)); | |
| 10885 _listener.assertNoErrors(); | |
| 10886 } | |
| 10887 | |
| 10888 void test_visitInstanceCreationExpression_typeParameters() { | |
| 10889 // new C<I>() | |
| 10890 ClassElementImpl elementC = ElementFactory.classElement2("C", ["E"]); | |
| 10891 ClassElementImpl elementI = ElementFactory.classElement2("I"); | |
| 10892 ConstructorElementImpl constructor = | |
| 10893 ElementFactory.constructorElement2(elementC, null); | |
| 10894 elementC.constructors = <ConstructorElement>[constructor]; | |
| 10895 constructor.returnType = elementC.type; | |
| 10896 FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor); | |
| 10897 constructor.type = constructorType; | |
| 10898 TypeName typeName = | |
| 10899 AstFactory.typeName(elementC, [AstFactory.typeName(elementI)]); | |
| 10900 typeName.type = elementC.type.substitute4(<DartType>[elementI.type]); | |
| 10901 InstanceCreationExpression node = | |
| 10902 AstFactory.instanceCreationExpression2(null, typeName); | |
| 10903 node.staticElement = constructor; | |
| 10904 InterfaceType interfaceType = _analyze(node) as InterfaceType; | |
| 10905 List<DartType> typeArgs = interfaceType.typeArguments; | |
| 10906 expect(typeArgs.length, 1); | |
| 10907 expect(typeArgs[0], elementI.type); | |
| 10908 _listener.assertNoErrors(); | |
| 10909 } | |
| 10910 | |
| 10911 void test_visitInstanceCreationExpression_unnamed() { | |
| 10912 // new C() | |
| 10913 ClassElementImpl classElement = ElementFactory.classElement2("C"); | |
| 10914 ConstructorElementImpl constructor = | |
| 10915 ElementFactory.constructorElement2(classElement, null); | |
| 10916 constructor.returnType = classElement.type; | |
| 10917 FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor); | |
| 10918 constructor.type = constructorType; | |
| 10919 classElement.constructors = <ConstructorElement>[constructor]; | |
| 10920 InstanceCreationExpression node = AstFactory.instanceCreationExpression2( | |
| 10921 null, AstFactory.typeName(classElement)); | |
| 10922 node.staticElement = constructor; | |
| 10923 expect(_analyze(node), same(classElement.type)); | |
| 10924 _listener.assertNoErrors(); | |
| 10925 } | |
| 10926 | |
| 10927 void test_visitIntegerLiteral() { | |
| 10928 // 42 | |
| 10929 Expression node = _resolvedInteger(42); | |
| 10930 expect(_analyze(node), same(_typeProvider.intType)); | |
| 10931 _listener.assertNoErrors(); | |
| 10932 } | |
| 10933 | |
| 10934 void test_visitIsExpression_negated() { | |
| 10935 // a is! String | |
| 10936 Expression node = AstFactory.isExpression( | |
| 10937 _resolvedString("a"), true, AstFactory.typeName4("String")); | |
| 10938 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 10939 _listener.assertNoErrors(); | |
| 10940 } | |
| 10941 | |
| 10942 void test_visitIsExpression_notNegated() { | |
| 10943 // a is String | |
| 10944 Expression node = AstFactory.isExpression( | |
| 10945 _resolvedString("a"), false, AstFactory.typeName4("String")); | |
| 10946 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 10947 _listener.assertNoErrors(); | |
| 10948 } | |
| 10949 | |
| 10950 void test_visitListLiteral_empty() { | |
| 10951 // [] | |
| 10952 Expression node = AstFactory.listLiteral(); | |
| 10953 DartType resultType = _analyze(node); | |
| 10954 _assertType2( | |
| 10955 _typeProvider.listType | |
| 10956 .substitute4(<DartType>[_typeProvider.dynamicType]), | |
| 10957 resultType); | |
| 10958 _listener.assertNoErrors(); | |
| 10959 } | |
| 10960 | |
| 10961 void test_visitListLiteral_nonEmpty() { | |
| 10962 // [0] | |
| 10963 Expression node = AstFactory.listLiteral([_resolvedInteger(0)]); | |
| 10964 DartType resultType = _analyze(node); | |
| 10965 _assertType2( | |
| 10966 _typeProvider.listType | |
| 10967 .substitute4(<DartType>[_typeProvider.dynamicType]), | |
| 10968 resultType); | |
| 10969 _listener.assertNoErrors(); | |
| 10970 } | |
| 10971 | |
| 10972 void test_visitMapLiteral_empty() { | |
| 10973 // {} | |
| 10974 Expression node = AstFactory.mapLiteral2(); | |
| 10975 DartType resultType = _analyze(node); | |
| 10976 _assertType2( | |
| 10977 _typeProvider.mapType.substitute4( | |
| 10978 <DartType>[_typeProvider.dynamicType, _typeProvider.dynamicType]), | |
| 10979 resultType); | |
| 10980 _listener.assertNoErrors(); | |
| 10981 } | |
| 10982 | |
| 10983 void test_visitMapLiteral_nonEmpty() { | |
| 10984 // {"k" : 0} | |
| 10985 Expression node = AstFactory | |
| 10986 .mapLiteral2([AstFactory.mapLiteralEntry("k", _resolvedInteger(0))]); | |
| 10987 DartType resultType = _analyze(node); | |
| 10988 _assertType2( | |
| 10989 _typeProvider.mapType.substitute4( | |
| 10990 <DartType>[_typeProvider.dynamicType, _typeProvider.dynamicType]), | |
| 10991 resultType); | |
| 10992 _listener.assertNoErrors(); | |
| 10993 } | |
| 10994 | |
| 10995 void test_visitMethodInvocation_then() { | |
| 10996 // then() | |
| 10997 Expression node = AstFactory.methodInvocation(null, "then"); | |
| 10998 _analyze(node); | |
| 10999 _listener.assertNoErrors(); | |
| 11000 } | |
| 11001 | |
| 11002 void test_visitNamedExpression() { | |
| 11003 // n: a | |
| 11004 Expression node = AstFactory.namedExpression2("n", _resolvedString("a")); | |
| 11005 expect(_analyze(node), same(_typeProvider.stringType)); | |
| 11006 _listener.assertNoErrors(); | |
| 11007 } | |
| 11008 | |
| 11009 void test_visitNullLiteral() { | |
| 11010 // null | |
| 11011 Expression node = AstFactory.nullLiteral(); | |
| 11012 expect(_analyze(node), same(_typeProvider.bottomType)); | |
| 11013 _listener.assertNoErrors(); | |
| 11014 } | |
| 11015 | |
| 11016 void test_visitParenthesizedExpression() { | |
| 11017 // (0) | |
| 11018 Expression node = AstFactory.parenthesizedExpression(_resolvedInteger(0)); | |
| 11019 expect(_analyze(node), same(_typeProvider.intType)); | |
| 11020 _listener.assertNoErrors(); | |
| 11021 } | |
| 11022 | |
| 11023 void test_visitPostfixExpression_minusMinus() { | |
| 11024 // 0-- | |
| 11025 PostfixExpression node = AstFactory.postfixExpression( | |
| 11026 _resolvedInteger(0), TokenType.MINUS_MINUS); | |
| 11027 expect(_analyze(node), same(_typeProvider.intType)); | |
| 11028 _listener.assertNoErrors(); | |
| 11029 } | |
| 11030 | |
| 11031 void test_visitPostfixExpression_plusPlus() { | |
| 11032 // 0++ | |
| 11033 PostfixExpression node = | |
| 11034 AstFactory.postfixExpression(_resolvedInteger(0), TokenType.PLUS_PLUS); | |
| 11035 expect(_analyze(node), same(_typeProvider.intType)); | |
| 11036 _listener.assertNoErrors(); | |
| 11037 } | |
| 11038 | |
| 11039 void test_visitPrefixedIdentifier_getter() { | |
| 11040 DartType boolType = _typeProvider.boolType; | |
| 11041 PropertyAccessorElementImpl getter = | |
| 11042 ElementFactory.getterElement("b", false, boolType); | |
| 11043 PrefixedIdentifier node = AstFactory.identifier5("a", "b"); | |
| 11044 node.identifier.staticElement = getter; | |
| 11045 expect(_analyze(node), same(boolType)); | |
| 11046 _listener.assertNoErrors(); | |
| 11047 } | |
| 11048 | |
| 11049 void test_visitPrefixedIdentifier_setter() { | |
| 11050 DartType boolType = _typeProvider.boolType; | |
| 11051 FieldElementImpl field = | |
| 11052 ElementFactory.fieldElement("b", false, false, false, boolType); | |
| 11053 PropertyAccessorElement setter = field.setter; | |
| 11054 PrefixedIdentifier node = AstFactory.identifier5("a", "b"); | |
| 11055 node.identifier.staticElement = setter; | |
| 11056 expect(_analyze(node), same(boolType)); | |
| 11057 _listener.assertNoErrors(); | |
| 11058 } | |
| 11059 | |
| 11060 void test_visitPrefixedIdentifier_variable() { | |
| 11061 VariableElementImpl variable = ElementFactory.localVariableElement2("b"); | |
| 11062 variable.type = _typeProvider.boolType; | |
| 11063 PrefixedIdentifier node = AstFactory.identifier5("a", "b"); | |
| 11064 node.identifier.staticElement = variable; | |
| 11065 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 11066 _listener.assertNoErrors(); | |
| 11067 } | |
| 11068 | |
| 11069 void test_visitPrefixExpression_bang() { | |
| 11070 // !0 | |
| 11071 PrefixExpression node = | |
| 11072 AstFactory.prefixExpression(TokenType.BANG, _resolvedInteger(0)); | |
| 11073 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 11074 _listener.assertNoErrors(); | |
| 11075 } | |
| 11076 | |
| 11077 void test_visitPrefixExpression_minus() { | |
| 11078 // -0 | |
| 11079 PrefixExpression node = | |
| 11080 AstFactory.prefixExpression(TokenType.MINUS, _resolvedInteger(0)); | |
| 11081 MethodElement minusMethod = getMethod(_typeProvider.numType, "-"); | |
| 11082 node.staticElement = minusMethod; | |
| 11083 expect(_analyze(node), same(_typeProvider.numType)); | |
| 11084 _listener.assertNoErrors(); | |
| 11085 } | |
| 11086 | |
| 11087 void test_visitPrefixExpression_minusMinus() { | |
| 11088 // --0 | |
| 11089 PrefixExpression node = | |
| 11090 AstFactory.prefixExpression(TokenType.MINUS_MINUS, _resolvedInteger(0)); | |
| 11091 MethodElement minusMethod = getMethod(_typeProvider.numType, "-"); | |
| 11092 node.staticElement = minusMethod; | |
| 11093 expect(_analyze(node), same(_typeProvider.intType)); | |
| 11094 _listener.assertNoErrors(); | |
| 11095 } | |
| 11096 | |
| 11097 void test_visitPrefixExpression_not() { | |
| 11098 // !true | |
| 11099 Expression node = AstFactory.prefixExpression( | |
| 11100 TokenType.BANG, AstFactory.booleanLiteral(true)); | |
| 11101 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 11102 _listener.assertNoErrors(); | |
| 11103 } | |
| 11104 | |
| 11105 void test_visitPrefixExpression_plusPlus() { | |
| 11106 // ++0 | |
| 11107 PrefixExpression node = | |
| 11108 AstFactory.prefixExpression(TokenType.PLUS_PLUS, _resolvedInteger(0)); | |
| 11109 MethodElement plusMethod = getMethod(_typeProvider.numType, "+"); | |
| 11110 node.staticElement = plusMethod; | |
| 11111 expect(_analyze(node), same(_typeProvider.intType)); | |
| 11112 _listener.assertNoErrors(); | |
| 11113 } | |
| 11114 | |
| 11115 void test_visitPrefixExpression_tilde() { | |
| 11116 // ~0 | |
| 11117 PrefixExpression node = | |
| 11118 AstFactory.prefixExpression(TokenType.TILDE, _resolvedInteger(0)); | |
| 11119 MethodElement tildeMethod = getMethod(_typeProvider.intType, "~"); | |
| 11120 node.staticElement = tildeMethod; | |
| 11121 expect(_analyze(node), same(_typeProvider.intType)); | |
| 11122 _listener.assertNoErrors(); | |
| 11123 } | |
| 11124 | |
| 11125 void test_visitPropertyAccess_propagated_getter() { | |
| 11126 DartType boolType = _typeProvider.boolType; | |
| 11127 PropertyAccessorElementImpl getter = | |
| 11128 ElementFactory.getterElement("b", false, boolType); | |
| 11129 PropertyAccess node = | |
| 11130 AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b"); | |
| 11131 node.propertyName.propagatedElement = getter; | |
| 11132 expect(_analyze2(node, false), same(boolType)); | |
| 11133 _listener.assertNoErrors(); | |
| 11134 } | |
| 11135 | |
| 11136 void test_visitPropertyAccess_propagated_setter() { | |
| 11137 DartType boolType = _typeProvider.boolType; | |
| 11138 FieldElementImpl field = | |
| 11139 ElementFactory.fieldElement("b", false, false, false, boolType); | |
| 11140 PropertyAccessorElement setter = field.setter; | |
| 11141 PropertyAccess node = | |
| 11142 AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b"); | |
| 11143 node.propertyName.propagatedElement = setter; | |
| 11144 expect(_analyze2(node, false), same(boolType)); | |
| 11145 _listener.assertNoErrors(); | |
| 11146 } | |
| 11147 | |
| 11148 void test_visitPropertyAccess_static_getter() { | |
| 11149 DartType boolType = _typeProvider.boolType; | |
| 11150 PropertyAccessorElementImpl getter = | |
| 11151 ElementFactory.getterElement("b", false, boolType); | |
| 11152 PropertyAccess node = | |
| 11153 AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b"); | |
| 11154 node.propertyName.staticElement = getter; | |
| 11155 expect(_analyze(node), same(boolType)); | |
| 11156 _listener.assertNoErrors(); | |
| 11157 } | |
| 11158 | |
| 11159 void test_visitPropertyAccess_static_setter() { | |
| 11160 DartType boolType = _typeProvider.boolType; | |
| 11161 FieldElementImpl field = | |
| 11162 ElementFactory.fieldElement("b", false, false, false, boolType); | |
| 11163 PropertyAccessorElement setter = field.setter; | |
| 11164 PropertyAccess node = | |
| 11165 AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b"); | |
| 11166 node.propertyName.staticElement = setter; | |
| 11167 expect(_analyze(node), same(boolType)); | |
| 11168 _listener.assertNoErrors(); | |
| 11169 } | |
| 11170 | |
| 11171 void test_visitSimpleIdentifier_dynamic() { | |
| 11172 // "dynamic" | |
| 11173 SimpleIdentifier identifier = AstFactory.identifier3('dynamic'); | |
| 11174 DynamicElementImpl element = DynamicElementImpl.instance; | |
| 11175 identifier.staticElement = element; | |
| 11176 identifier.staticType = _typeProvider.typeType; | |
| 11177 expect(_analyze(identifier), same(_typeProvider.typeType)); | |
| 11178 _listener.assertNoErrors(); | |
| 11179 } | |
| 11180 | |
| 11181 void test_visitSimpleStringLiteral() { | |
| 11182 // "a" | |
| 11183 Expression node = _resolvedString("a"); | |
| 11184 expect(_analyze(node), same(_typeProvider.stringType)); | |
| 11185 _listener.assertNoErrors(); | |
| 11186 } | |
| 11187 | |
| 11188 void test_visitStringInterpolation() { | |
| 11189 // "a${'b'}c" | |
| 11190 Expression node = AstFactory.string([ | |
| 11191 AstFactory.interpolationString("a", "a"), | |
| 11192 AstFactory.interpolationExpression(_resolvedString("b")), | |
| 11193 AstFactory.interpolationString("c", "c") | |
| 11194 ]); | |
| 11195 expect(_analyze(node), same(_typeProvider.stringType)); | |
| 11196 _listener.assertNoErrors(); | |
| 11197 } | |
| 11198 | |
| 11199 void test_visitSuperExpression() { | |
| 11200 // super | |
| 11201 InterfaceType superType = ElementFactory.classElement2("A").type; | |
| 11202 InterfaceType thisType = ElementFactory.classElement("B", superType).type; | |
| 11203 Expression node = AstFactory.superExpression(); | |
| 11204 expect(_analyze3(node, thisType), same(thisType)); | |
| 11205 _listener.assertNoErrors(); | |
| 11206 } | |
| 11207 | |
| 11208 void test_visitSymbolLiteral() { | |
| 11209 expect(_analyze(AstFactory.symbolLiteral(["a"])), | |
| 11210 same(_typeProvider.symbolType)); | |
| 11211 } | |
| 11212 | |
| 11213 void test_visitThisExpression() { | |
| 11214 // this | |
| 11215 InterfaceType thisType = ElementFactory | |
| 11216 .classElement("B", ElementFactory.classElement2("A").type) | |
| 11217 .type; | |
| 11218 Expression node = AstFactory.thisExpression(); | |
| 11219 expect(_analyze3(node, thisType), same(thisType)); | |
| 11220 _listener.assertNoErrors(); | |
| 11221 } | |
| 11222 | |
| 11223 void test_visitThrowExpression_withoutValue() { | |
| 11224 // throw | |
| 11225 Expression node = AstFactory.throwExpression(); | |
| 11226 expect(_analyze(node), same(_typeProvider.bottomType)); | |
| 11227 _listener.assertNoErrors(); | |
| 11228 } | |
| 11229 | |
| 11230 void test_visitThrowExpression_withValue() { | |
| 11231 // throw 0 | |
| 11232 Expression node = AstFactory.throwExpression2(_resolvedInteger(0)); | |
| 11233 expect(_analyze(node), same(_typeProvider.bottomType)); | |
| 11234 _listener.assertNoErrors(); | |
| 11235 } | |
| 11236 | |
| 11237 /** | |
| 11238 * Return the type associated with the given expression after the static type
analyzer has | |
| 11239 * computed a type for it. | |
| 11240 * | |
| 11241 * @param node the expression with which the type is associated | |
| 11242 * @return the type associated with the expression | |
| 11243 */ | |
| 11244 DartType _analyze(Expression node) => _analyze4(node, null, true); | |
| 11245 | |
| 11246 /** | |
| 11247 * Return the type associated with the given expression after the static or pr
opagated type | |
| 11248 * analyzer has computed a type for it. | |
| 11249 * | |
| 11250 * @param node the expression with which the type is associated | |
| 11251 * @param useStaticType `true` if the static type is being requested, and `fal
se` if | |
| 11252 * the propagated type is being requested | |
| 11253 * @return the type associated with the expression | |
| 11254 */ | |
| 11255 DartType _analyze2(Expression node, bool useStaticType) => | |
| 11256 _analyze4(node, null, useStaticType); | |
| 11257 | |
| 11258 /** | |
| 11259 * Return the type associated with the given expression after the static type
analyzer has | |
| 11260 * computed a type for it. | |
| 11261 * | |
| 11262 * @param node the expression with which the type is associated | |
| 11263 * @param thisType the type of 'this' | |
| 11264 * @return the type associated with the expression | |
| 11265 */ | |
| 11266 DartType _analyze3(Expression node, InterfaceType thisType) => | |
| 11267 _analyze4(node, thisType, true); | |
| 11268 | |
| 11269 /** | |
| 11270 * Return the type associated with the given expression after the static type
analyzer has | |
| 11271 * computed a type for it. | |
| 11272 * | |
| 11273 * @param node the expression with which the type is associated | |
| 11274 * @param thisType the type of 'this' | |
| 11275 * @param useStaticType `true` if the static type is being requested, and `fal
se` if | |
| 11276 * the propagated type is being requested | |
| 11277 * @return the type associated with the expression | |
| 11278 */ | |
| 11279 DartType _analyze4( | |
| 11280 Expression node, InterfaceType thisType, bool useStaticType) { | |
| 11281 try { | |
| 11282 _analyzer.thisType = thisType; | |
| 11283 } catch (exception) { | |
| 11284 throw new IllegalArgumentException( | |
| 11285 "Could not set type of 'this'", exception); | |
| 11286 } | |
| 11287 node.accept(_analyzer); | |
| 11288 if (useStaticType) { | |
| 11289 return node.staticType; | |
| 11290 } else { | |
| 11291 return node.propagatedType; | |
| 11292 } | |
| 11293 } | |
| 11294 | |
| 11295 /** | |
| 11296 * Return the type associated with the given parameter after the static type a
nalyzer has computed | |
| 11297 * a type for it. | |
| 11298 * | |
| 11299 * @param node the parameter with which the type is associated | |
| 11300 * @return the type associated with the parameter | |
| 11301 */ | |
| 11302 DartType _analyze5(FormalParameter node) { | |
| 11303 node.accept(_analyzer); | |
| 11304 return (node.identifier.staticElement as ParameterElement).type; | |
| 11305 } | |
| 11306 | |
| 11307 /** | |
| 11308 * Assert that the actual type is a function type with the expected characteri
stics. | |
| 11309 * | |
| 11310 * @param expectedReturnType the expected return type of the function | |
| 11311 * @param expectedNormalTypes the expected types of the normal parameters | |
| 11312 * @param expectedOptionalTypes the expected types of the optional parameters | |
| 11313 * @param expectedNamedTypes the expected types of the named parameters | |
| 11314 * @param actualType the type being tested | |
| 11315 */ | |
| 11316 void _assertFunctionType( | |
| 11317 DartType expectedReturnType, | |
| 11318 List<DartType> expectedNormalTypes, | |
| 11319 List<DartType> expectedOptionalTypes, | |
| 11320 Map<String, DartType> expectedNamedTypes, | |
| 11321 DartType actualType) { | |
| 11322 EngineTestCase.assertInstanceOf( | |
| 11323 (obj) => obj is FunctionType, FunctionType, actualType); | |
| 11324 FunctionType functionType = actualType as FunctionType; | |
| 11325 List<DartType> normalTypes = functionType.normalParameterTypes; | |
| 11326 if (expectedNormalTypes == null) { | |
| 11327 expect(normalTypes, hasLength(0)); | |
| 11328 } else { | |
| 11329 int expectedCount = expectedNormalTypes.length; | |
| 11330 expect(normalTypes, hasLength(expectedCount)); | |
| 11331 for (int i = 0; i < expectedCount; i++) { | |
| 11332 expect(normalTypes[i], same(expectedNormalTypes[i])); | |
| 11333 } | |
| 11334 } | |
| 11335 List<DartType> optionalTypes = functionType.optionalParameterTypes; | |
| 11336 if (expectedOptionalTypes == null) { | |
| 11337 expect(optionalTypes, hasLength(0)); | |
| 11338 } else { | |
| 11339 int expectedCount = expectedOptionalTypes.length; | |
| 11340 expect(optionalTypes, hasLength(expectedCount)); | |
| 11341 for (int i = 0; i < expectedCount; i++) { | |
| 11342 expect(optionalTypes[i], same(expectedOptionalTypes[i])); | |
| 11343 } | |
| 11344 } | |
| 11345 Map<String, DartType> namedTypes = functionType.namedParameterTypes; | |
| 11346 if (expectedNamedTypes == null) { | |
| 11347 expect(namedTypes, hasLength(0)); | |
| 11348 } else { | |
| 11349 expect(namedTypes, hasLength(expectedNamedTypes.length)); | |
| 11350 expectedNamedTypes.forEach((String name, DartType type) { | |
| 11351 expect(namedTypes[name], same(type)); | |
| 11352 }); | |
| 11353 } | |
| 11354 expect(functionType.returnType, equals(expectedReturnType)); | |
| 11355 } | |
| 11356 | |
| 11357 void _assertType( | |
| 11358 InterfaceTypeImpl expectedType, InterfaceTypeImpl actualType) { | |
| 11359 expect(actualType.displayName, expectedType.displayName); | |
| 11360 expect(actualType.element, expectedType.element); | |
| 11361 List<DartType> expectedArguments = expectedType.typeArguments; | |
| 11362 int length = expectedArguments.length; | |
| 11363 List<DartType> actualArguments = actualType.typeArguments; | |
| 11364 expect(actualArguments, hasLength(length)); | |
| 11365 for (int i = 0; i < length; i++) { | |
| 11366 _assertType2(expectedArguments[i], actualArguments[i]); | |
| 11367 } | |
| 11368 } | |
| 11369 | |
| 11370 void _assertType2(DartType expectedType, DartType actualType) { | |
| 11371 if (expectedType is InterfaceTypeImpl) { | |
| 11372 EngineTestCase.assertInstanceOf( | |
| 11373 (obj) => obj is InterfaceTypeImpl, InterfaceTypeImpl, actualType); | |
| 11374 _assertType(expectedType, actualType as InterfaceTypeImpl); | |
| 11375 } | |
| 11376 // TODO(brianwilkerson) Compare other kinds of types then make this a shared | |
| 11377 // utility method. | |
| 11378 } | |
| 11379 | |
| 11380 /** | |
| 11381 * Create the analyzer used by the tests. | |
| 11382 * | |
| 11383 * @return the analyzer to be used by the tests | |
| 11384 */ | |
| 11385 StaticTypeAnalyzer _createAnalyzer() { | |
| 11386 InternalAnalysisContext context = AnalysisContextFactory.contextWithCore(); | |
| 11387 FileBasedSource source = | |
| 11388 new FileBasedSource(FileUtilities2.createFile("/lib.dart")); | |
| 11389 CompilationUnitElementImpl definingCompilationUnit = | |
| 11390 new CompilationUnitElementImpl("lib.dart"); | |
| 11391 definingCompilationUnit.librarySource = | |
| 11392 definingCompilationUnit.source = source; | |
| 11393 LibraryElementImpl definingLibrary = | |
| 11394 new LibraryElementImpl.forNode(context, null); | |
| 11395 definingLibrary.definingCompilationUnit = definingCompilationUnit; | |
| 11396 Library library = new Library(context, _listener, source); | |
| 11397 library.libraryElement = definingLibrary; | |
| 11398 _visitor = new ResolverVisitor( | |
| 11399 library.libraryElement, source, _typeProvider, library.errorListener, | |
| 11400 nameScope: library.libraryScope, | |
| 11401 inheritanceManager: library.inheritanceManager); | |
| 11402 _visitor.overrideManager.enterScope(); | |
| 11403 try { | |
| 11404 return _visitor.typeAnalyzer; | |
| 11405 } catch (exception) { | |
| 11406 throw new IllegalArgumentException( | |
| 11407 "Could not create analyzer", exception); | |
| 11408 } | |
| 11409 } | |
| 11410 | |
| 11411 DartType _flatten(DartType type) => | |
| 11412 StaticTypeAnalyzer.flattenFutures(_typeProvider, type); | |
| 11413 | |
| 11414 /** | |
| 11415 * Return a simple identifier that has been resolved to a variable element wit
h the given type. | |
| 11416 * | |
| 11417 * @param type the type of the variable being represented | |
| 11418 * @param variableName the name of the variable | |
| 11419 * @return a simple identifier that has been resolved to a variable element wi
th the given type | |
| 11420 */ | |
| 11421 SimpleIdentifier _propagatedVariable( | |
| 11422 InterfaceType type, String variableName) { | |
| 11423 SimpleIdentifier identifier = AstFactory.identifier3(variableName); | |
| 11424 VariableElementImpl element = | |
| 11425 ElementFactory.localVariableElement(identifier); | |
| 11426 element.type = type; | |
| 11427 identifier.staticType = _typeProvider.dynamicType; | |
| 11428 identifier.propagatedElement = element; | |
| 11429 identifier.propagatedType = type; | |
| 11430 return identifier; | |
| 11431 } | |
| 11432 | |
| 11433 /** | |
| 11434 * Return an integer literal that has been resolved to the correct type. | |
| 11435 * | |
| 11436 * @param value the value of the literal | |
| 11437 * @return an integer literal that has been resolved to the correct type | |
| 11438 */ | |
| 11439 DoubleLiteral _resolvedDouble(double value) { | |
| 11440 DoubleLiteral literal = AstFactory.doubleLiteral(value); | |
| 11441 literal.staticType = _typeProvider.doubleType; | |
| 11442 return literal; | |
| 11443 } | |
| 11444 | |
| 11445 /** | |
| 11446 * Create a function expression that has an element associated with it, where
the element has an | |
| 11447 * incomplete type associated with it (just like the one | |
| 11448 * [ElementBuilder.visitFunctionExpression] would have built if we had | |
| 11449 * run it). | |
| 11450 * | |
| 11451 * @param parameters the parameters to the function | |
| 11452 * @param body the body of the function | |
| 11453 * @return a resolved function expression | |
| 11454 */ | |
| 11455 FunctionExpression _resolvedFunctionExpression( | |
| 11456 FormalParameterList parameters, FunctionBody body) { | |
| 11457 List<ParameterElement> parameterElements = new List<ParameterElement>(); | |
| 11458 for (FormalParameter parameter in parameters.parameters) { | |
| 11459 ParameterElementImpl element = | |
| 11460 new ParameterElementImpl.forNode(parameter.identifier); | |
| 11461 element.parameterKind = parameter.kind; | |
| 11462 element.type = _typeProvider.dynamicType; | |
| 11463 parameter.identifier.staticElement = element; | |
| 11464 parameterElements.add(element); | |
| 11465 } | |
| 11466 FunctionExpression node = AstFactory.functionExpression2(parameters, body); | |
| 11467 FunctionElementImpl element = new FunctionElementImpl.forNode(null); | |
| 11468 element.parameters = parameterElements; | |
| 11469 element.type = new FunctionTypeImpl(element); | |
| 11470 node.element = element; | |
| 11471 return node; | |
| 11472 } | |
| 11473 | |
| 11474 /** | |
| 11475 * Return an integer literal that has been resolved to the correct type. | |
| 11476 * | |
| 11477 * @param value the value of the literal | |
| 11478 * @return an integer literal that has been resolved to the correct type | |
| 11479 */ | |
| 11480 IntegerLiteral _resolvedInteger(int value) { | |
| 11481 IntegerLiteral literal = AstFactory.integer(value); | |
| 11482 literal.staticType = _typeProvider.intType; | |
| 11483 return literal; | |
| 11484 } | |
| 11485 | |
| 11486 /** | |
| 11487 * Return a string literal that has been resolved to the correct type. | |
| 11488 * | |
| 11489 * @param value the value of the literal | |
| 11490 * @return a string literal that has been resolved to the correct type | |
| 11491 */ | |
| 11492 SimpleStringLiteral _resolvedString(String value) { | |
| 11493 SimpleStringLiteral string = AstFactory.string2(value); | |
| 11494 string.staticType = _typeProvider.stringType; | |
| 11495 return string; | |
| 11496 } | |
| 11497 | |
| 11498 /** | |
| 11499 * Return a simple identifier that has been resolved to a variable element wit
h the given type. | |
| 11500 * | |
| 11501 * @param type the type of the variable being represented | |
| 11502 * @param variableName the name of the variable | |
| 11503 * @return a simple identifier that has been resolved to a variable element wi
th the given type | |
| 11504 */ | |
| 11505 SimpleIdentifier _resolvedVariable(InterfaceType type, String variableName) { | |
| 11506 SimpleIdentifier identifier = AstFactory.identifier3(variableName); | |
| 11507 VariableElementImpl element = | |
| 11508 ElementFactory.localVariableElement(identifier); | |
| 11509 element.type = type; | |
| 11510 identifier.staticElement = element; | |
| 11511 identifier.staticType = type; | |
| 11512 return identifier; | |
| 11513 } | |
| 11514 | |
| 11515 /** | |
| 11516 * Set the type of the given parameter to the given type. | |
| 11517 * | |
| 11518 * @param parameter the parameter whose type is to be set | |
| 11519 * @param type the new type of the given parameter | |
| 11520 */ | |
| 11521 void _setType(FormalParameter parameter, DartType type) { | |
| 11522 SimpleIdentifier identifier = parameter.identifier; | |
| 11523 Element element = identifier.staticElement; | |
| 11524 if (element is! ParameterElement) { | |
| 11525 element = new ParameterElementImpl.forNode(identifier); | |
| 11526 identifier.staticElement = element; | |
| 11527 } | |
| 11528 (element as ParameterElementImpl).type = type; | |
| 11529 } | |
| 11530 } | |
| 11531 | |
| 11532 /** | |
| 11533 * Instances of the class `StaticTypeVerifier` verify that all of the nodes in a
n AST | 397 * Instances of the class `StaticTypeVerifier` verify that all of the nodes in a
n AST |
| 11534 * structure that should have a static type associated with them do have a stati
c type. | 398 * structure that should have a static type associated with them do have a stati
c type. |
| 11535 */ | 399 */ |
| 11536 class StaticTypeVerifier extends GeneralizingAstVisitor<Object> { | 400 class StaticTypeVerifier extends GeneralizingAstVisitor<Object> { |
| 11537 /** | 401 /** |
| 11538 * A list containing all of the AST Expression nodes that were not resolved. | 402 * A list containing all of the AST Expression nodes that were not resolved. |
| 11539 */ | 403 */ |
| 11540 List<Expression> _unresolvedExpressions = new List<Expression>(); | 404 List<Expression> _unresolvedExpressions = new List<Expression>(); |
| 11541 | 405 |
| 11542 /** | 406 /** |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11888 Source source = addSource(r''' | 752 Source source = addSource(r''' |
| 11889 int f() { | 753 int f() { |
| 11890 num n = 1234; | 754 num n = 1234; |
| 11891 return n & 0x0F; | 755 return n & 0x0F; |
| 11892 }'''); | 756 }'''); |
| 11893 computeLibrarySourceErrors(source); | 757 computeLibrarySourceErrors(source); |
| 11894 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]); | 758 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]); |
| 11895 } | 759 } |
| 11896 } | 760 } |
| 11897 | 761 |
| 11898 /** | |
| 11899 * Strong mode static analyzer end to end tests | |
| 11900 */ | |
| 11901 @reflectiveTest | 762 @reflectiveTest |
| 11902 class StrongModeStaticTypeAnalyzer2Test extends _StaticTypeAnalyzer2TestShared { | 763 class SubtypeManagerTest { |
| 11903 void setUp() { | |
| 11904 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); | |
| 11905 options.strongMode = true; | |
| 11906 resetWithOptions(options); | |
| 11907 } | |
| 11908 | |
| 11909 void test_dynamicObjectGetter_hashCode() { | |
| 11910 String code = r''' | |
| 11911 main() { | |
| 11912 dynamic a = null; | |
| 11913 var foo = a.hashCode; | |
| 11914 } | |
| 11915 '''; | |
| 11916 _resolveTestUnit(code); | |
| 11917 | |
| 11918 SimpleIdentifier identifier = _findIdentifier('foo'); | |
| 11919 VariableDeclaration declaration = | |
| 11920 identifier.getAncestor((node) => node is VariableDeclaration); | |
| 11921 expect(declaration.initializer.staticType.name, 'int'); | |
| 11922 expect(declaration.initializer.propagatedType, isNull); | |
| 11923 } | |
| 11924 | |
| 11925 void test_dynamicObjectMethod_toString() { | |
| 11926 String code = r''' | |
| 11927 main() { | |
| 11928 dynamic a = null; | |
| 11929 var foo = a.toString(); | |
| 11930 } | |
| 11931 '''; | |
| 11932 _resolveTestUnit(code); | |
| 11933 | |
| 11934 SimpleIdentifier identifier = _findIdentifier('foo'); | |
| 11935 VariableDeclaration declaration = | |
| 11936 identifier.getAncestor((node) => node is VariableDeclaration); | |
| 11937 expect(declaration.initializer.staticType.name, 'String'); | |
| 11938 expect(declaration.initializer.propagatedType, isNull); | |
| 11939 } | |
| 11940 | |
| 11941 void test_pseudoGeneric_max_doubleDouble() { | |
| 11942 String code = r''' | |
| 11943 import 'dart:math'; | |
| 11944 main() { | |
| 11945 var foo = max(1.0, 2.0); | |
| 11946 } | |
| 11947 '''; | |
| 11948 _resolveTestUnit(code); | |
| 11949 | |
| 11950 SimpleIdentifier identifier = _findIdentifier('foo'); | |
| 11951 VariableDeclaration declaration = | |
| 11952 identifier.getAncestor((node) => node is VariableDeclaration); | |
| 11953 expect(declaration.initializer.staticType.name, 'double'); | |
| 11954 expect(declaration.initializer.propagatedType, isNull); | |
| 11955 } | |
| 11956 | |
| 11957 void test_pseudoGeneric_max_doubleInt() { | |
| 11958 String code = r''' | |
| 11959 import 'dart:math'; | |
| 11960 main() { | |
| 11961 var foo = max(1.0, 2); | |
| 11962 } | |
| 11963 '''; | |
| 11964 _resolveTestUnit(code); | |
| 11965 | |
| 11966 SimpleIdentifier identifier = _findIdentifier('foo'); | |
| 11967 VariableDeclaration declaration = | |
| 11968 identifier.getAncestor((node) => node is VariableDeclaration); | |
| 11969 expect(declaration.initializer.staticType.name, 'num'); | |
| 11970 expect(declaration.initializer.propagatedType, isNull); | |
| 11971 } | |
| 11972 | |
| 11973 void test_pseudoGeneric_max_intDouble() { | |
| 11974 String code = r''' | |
| 11975 import 'dart:math'; | |
| 11976 main() { | |
| 11977 var foo = max(1, 2.0); | |
| 11978 } | |
| 11979 '''; | |
| 11980 _resolveTestUnit(code); | |
| 11981 | |
| 11982 SimpleIdentifier identifier = _findIdentifier('foo'); | |
| 11983 VariableDeclaration declaration = | |
| 11984 identifier.getAncestor((node) => node is VariableDeclaration); | |
| 11985 expect(declaration.initializer.staticType.name, 'num'); | |
| 11986 expect(declaration.initializer.propagatedType, isNull); | |
| 11987 } | |
| 11988 | |
| 11989 void test_pseudoGeneric_max_intInt() { | |
| 11990 String code = r''' | |
| 11991 import 'dart:math'; | |
| 11992 main() { | |
| 11993 var foo = max(1, 2); | |
| 11994 } | |
| 11995 '''; | |
| 11996 _resolveTestUnit(code); | |
| 11997 | |
| 11998 SimpleIdentifier identifier = _findIdentifier('foo'); | |
| 11999 VariableDeclaration declaration = | |
| 12000 identifier.getAncestor((node) => node is VariableDeclaration); | |
| 12001 expect(declaration.initializer.staticType.name, 'int'); | |
| 12002 expect(declaration.initializer.propagatedType, isNull); | |
| 12003 } | |
| 12004 | |
| 12005 void test_pseudoGeneric_then() { | |
| 12006 String code = r''' | |
| 12007 import 'dart:async'; | |
| 12008 String toString(int x) => x.toString(); | |
| 12009 main() { | |
| 12010 Future<int> bar = null; | |
| 12011 var foo = bar.then(toString); | |
| 12012 } | |
| 12013 '''; | |
| 12014 _resolveTestUnit(code); | |
| 12015 | |
| 12016 SimpleIdentifier identifier = _findIdentifier('foo'); | |
| 12017 VariableDeclaration declaration = | |
| 12018 identifier.getAncestor((node) => node is VariableDeclaration); | |
| 12019 | |
| 12020 expect(declaration.initializer.staticType.toString(), "Future<String>"); | |
| 12021 expect(declaration.initializer.propagatedType, isNull); | |
| 12022 } | |
| 12023 | |
| 12024 void test_ternaryOperator_null_left() { | |
| 12025 String code = r''' | |
| 12026 main() { | |
| 12027 var foo = (true) ? null : 3; | |
| 12028 } | |
| 12029 '''; | |
| 12030 _resolveTestUnit(code); | |
| 12031 | |
| 12032 SimpleIdentifier identifier = _findIdentifier('foo'); | |
| 12033 VariableDeclaration declaration = | |
| 12034 identifier.getAncestor((node) => node is VariableDeclaration); | |
| 12035 expect(declaration.initializer.staticType.name, 'int'); | |
| 12036 expect(declaration.initializer.propagatedType, isNull); | |
| 12037 } | |
| 12038 | |
| 12039 void test_ternaryOperator_null_right() { | |
| 12040 String code = r''' | |
| 12041 main() { | |
| 12042 var foo = (true) ? 3 : null; | |
| 12043 } | |
| 12044 '''; | |
| 12045 _resolveTestUnit(code); | |
| 12046 | |
| 12047 SimpleIdentifier identifier = _findIdentifier('foo'); | |
| 12048 VariableDeclaration declaration = | |
| 12049 identifier.getAncestor((node) => node is VariableDeclaration); | |
| 12050 expect(declaration.initializer.staticType.name, 'int'); | |
| 12051 expect(declaration.initializer.propagatedType, isNull); | |
| 12052 } | |
| 12053 } | |
| 12054 | |
| 12055 @reflectiveTest | |
| 12056 class StrongModeTypePropagationTest extends ResolverTestCase { | |
| 12057 @override | |
| 12058 void setUp() { | |
| 12059 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); | |
| 12060 options.strongMode = true; | |
| 12061 resetWithOptions(options); | |
| 12062 } | |
| 12063 | |
| 12064 void test_foreachInference_dynamic_disabled() { | |
| 12065 String code = r''' | |
| 12066 main() { | |
| 12067 var list = <int>[]; | |
| 12068 for (dynamic v in list) { | |
| 12069 v; // marker | |
| 12070 } | |
| 12071 }'''; | |
| 12072 _assertPropagatedIterationType( | |
| 12073 code, typeProvider.dynamicType, typeProvider.intType); | |
| 12074 _assertTypeOfMarkedExpression( | |
| 12075 code, typeProvider.dynamicType, typeProvider.intType); | |
| 12076 } | |
| 12077 | |
| 12078 void test_foreachInference_reusedVar_disabled() { | |
| 12079 String code = r''' | |
| 12080 main() { | |
| 12081 var list = <int>[]; | |
| 12082 var v; | |
| 12083 for (v in list) { | |
| 12084 v; // marker | |
| 12085 } | |
| 12086 }'''; | |
| 12087 _assertPropagatedIterationType( | |
| 12088 code, typeProvider.dynamicType, typeProvider.intType); | |
| 12089 _assertTypeOfMarkedExpression( | |
| 12090 code, typeProvider.dynamicType, typeProvider.intType); | |
| 12091 } | |
| 12092 | |
| 12093 void test_foreachInference_var() { | |
| 12094 String code = r''' | |
| 12095 main() { | |
| 12096 var list = <int>[]; | |
| 12097 for (var v in list) { | |
| 12098 v; // marker | |
| 12099 } | |
| 12100 }'''; | |
| 12101 _assertPropagatedIterationType(code, typeProvider.intType, null); | |
| 12102 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 12103 } | |
| 12104 | |
| 12105 void test_foreachInference_var_iterable() { | |
| 12106 String code = r''' | |
| 12107 main() { | |
| 12108 Iterable<int> list = <int>[]; | |
| 12109 for (var v in list) { | |
| 12110 v; // marker | |
| 12111 } | |
| 12112 }'''; | |
| 12113 _assertPropagatedIterationType(code, typeProvider.intType, null); | |
| 12114 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 12115 } | |
| 12116 | |
| 12117 void test_foreachInference_var_stream() { | |
| 12118 String code = r''' | |
| 12119 import 'dart:async'; | |
| 12120 main() async { | |
| 12121 Stream<int> stream = null; | |
| 12122 await for (var v in stream) { | |
| 12123 v; // marker | |
| 12124 } | |
| 12125 }'''; | |
| 12126 _assertPropagatedIterationType(code, typeProvider.intType, null); | |
| 12127 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 12128 } | |
| 12129 | |
| 12130 void test_localVariableInference_bottom_disabled() { | |
| 12131 String code = r''' | |
| 12132 main() { | |
| 12133 var v = null; | |
| 12134 v; // marker | |
| 12135 }'''; | |
| 12136 _assertPropagatedAssignedType(code, typeProvider.dynamicType, null); | |
| 12137 _assertTypeOfMarkedExpression(code, typeProvider.dynamicType, null); | |
| 12138 } | |
| 12139 | |
| 12140 void test_localVariableInference_constant() { | |
| 12141 String code = r''' | |
| 12142 main() { | |
| 12143 var v = 3; | |
| 12144 v; // marker | |
| 12145 }'''; | |
| 12146 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 12147 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 12148 } | |
| 12149 | |
| 12150 void test_localVariableInference_declaredType_disabled() { | |
| 12151 String code = r''' | |
| 12152 main() { | |
| 12153 dynamic v = 3; | |
| 12154 v; // marker | |
| 12155 }'''; | |
| 12156 _assertPropagatedAssignedType( | |
| 12157 code, typeProvider.dynamicType, typeProvider.intType); | |
| 12158 _assertTypeOfMarkedExpression( | |
| 12159 code, typeProvider.dynamicType, typeProvider.intType); | |
| 12160 } | |
| 12161 | |
| 12162 void test_localVariableInference_noInitializer_disabled() { | |
| 12163 String code = r''' | |
| 12164 main() { | |
| 12165 var v; | |
| 12166 v = 3; | |
| 12167 v; // marker | |
| 12168 }'''; | |
| 12169 _assertPropagatedAssignedType( | |
| 12170 code, typeProvider.dynamicType, typeProvider.intType); | |
| 12171 _assertTypeOfMarkedExpression( | |
| 12172 code, typeProvider.dynamicType, typeProvider.intType); | |
| 12173 } | |
| 12174 | |
| 12175 void test_localVariableInference_transitive_field_inferred_lexical() { | |
| 12176 if (!AnalysisEngine.instance.useTaskModel) { | |
| 12177 return; | |
| 12178 } | |
| 12179 String code = r''' | |
| 12180 class A { | |
| 12181 final x = 3; | |
| 12182 f() { | |
| 12183 var v = x; | |
| 12184 return v; // marker | |
| 12185 } | |
| 12186 } | |
| 12187 main() { | |
| 12188 } | |
| 12189 '''; | |
| 12190 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 12191 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 12192 } | |
| 12193 | |
| 12194 void test_localVariableInference_transitive_field_inferred_reversed() { | |
| 12195 if (!AnalysisEngine.instance.useTaskModel) { | |
| 12196 return; | |
| 12197 } | |
| 12198 String code = r''' | |
| 12199 class A { | |
| 12200 f() { | |
| 12201 var v = x; | |
| 12202 return v; // marker | |
| 12203 } | |
| 12204 final x = 3; | |
| 12205 } | |
| 12206 main() { | |
| 12207 } | |
| 12208 '''; | |
| 12209 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 12210 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 12211 } | |
| 12212 | |
| 12213 void test_localVariableInference_transitive_field_lexical() { | |
| 12214 String code = r''' | |
| 12215 class A { | |
| 12216 int x = 3; | |
| 12217 f() { | |
| 12218 var v = x; | |
| 12219 return v; // marker | |
| 12220 } | |
| 12221 } | |
| 12222 main() { | |
| 12223 } | |
| 12224 '''; | |
| 12225 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 12226 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 12227 } | |
| 12228 | |
| 12229 void test_localVariableInference_transitive_field_reversed() { | |
| 12230 String code = r''' | |
| 12231 class A { | |
| 12232 f() { | |
| 12233 var v = x; | |
| 12234 return v; // marker | |
| 12235 } | |
| 12236 int x = 3; | |
| 12237 } | |
| 12238 main() { | |
| 12239 } | |
| 12240 '''; | |
| 12241 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 12242 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 12243 } | |
| 12244 | |
| 12245 void test_localVariableInference_transitive_list_local() { | |
| 12246 String code = r''' | |
| 12247 main() { | |
| 12248 var x = <int>[3]; | |
| 12249 var v = x[0]; | |
| 12250 v; // marker | |
| 12251 }'''; | |
| 12252 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 12253 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 12254 } | |
| 12255 | |
| 12256 void test_localVariableInference_transitive_local() { | |
| 12257 String code = r''' | |
| 12258 main() { | |
| 12259 var x = 3; | |
| 12260 var v = x; | |
| 12261 v; // marker | |
| 12262 }'''; | |
| 12263 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 12264 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 12265 } | |
| 12266 | |
| 12267 void test_localVariableInference_transitive_toplevel_inferred_lexical() { | |
| 12268 if (!AnalysisEngine.instance.useTaskModel) { | |
| 12269 return; | |
| 12270 } | |
| 12271 String code = r''' | |
| 12272 final x = 3; | |
| 12273 main() { | |
| 12274 var v = x; | |
| 12275 v; // marker | |
| 12276 } | |
| 12277 '''; | |
| 12278 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 12279 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 12280 } | |
| 12281 | |
| 12282 void test_localVariableInference_transitive_toplevel_inferred_reversed() { | |
| 12283 if (!AnalysisEngine.instance.useTaskModel) { | |
| 12284 return; | |
| 12285 } | |
| 12286 String code = r''' | |
| 12287 main() { | |
| 12288 var v = x; | |
| 12289 v; // marker | |
| 12290 } | |
| 12291 final x = 3; | |
| 12292 '''; | |
| 12293 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 12294 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 12295 } | |
| 12296 | |
| 12297 void test_localVariableInference_transitive_toplevel_lexical() { | |
| 12298 String code = r''' | |
| 12299 int x = 3; | |
| 12300 main() { | |
| 12301 var v = x; | |
| 12302 v; // marker | |
| 12303 } | |
| 12304 '''; | |
| 12305 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 12306 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 12307 } | |
| 12308 | |
| 12309 void test_localVariableInference_transitive_toplevel_reversed() { | |
| 12310 String code = r''' | |
| 12311 main() { | |
| 12312 var v = x; | |
| 12313 v; // marker | |
| 12314 } | |
| 12315 int x = 3; | |
| 12316 '''; | |
| 12317 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 12318 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 12319 } | |
| 12320 } | |
| 12321 | |
| 12322 @reflectiveTest | |
| 12323 class SubtypeManagerTest extends EngineTestCase { | |
| 12324 /** | 764 /** |
| 12325 * The inheritance manager being tested. | 765 * The inheritance manager being tested. |
| 12326 */ | 766 */ |
| 12327 SubtypeManager _subtypeManager; | 767 SubtypeManager _subtypeManager; |
| 12328 | 768 |
| 12329 /** | 769 /** |
| 12330 * The compilation unit element containing all of the types setup in each test
. | 770 * The compilation unit element containing all of the types setup in each test
. |
| 12331 */ | 771 */ |
| 12332 CompilationUnitElementImpl _definingCompilationUnit; | 772 CompilationUnitElementImpl _definingCompilationUnit; |
| 12333 | 773 |
| 12334 @override | |
| 12335 void setUp() { | 774 void setUp() { |
| 12336 super.setUp(); | 775 MemoryResourceProvider resourceProvider = new MemoryResourceProvider(); |
| 12337 AnalysisContext context = AnalysisContextFactory.contextWithCore(); | 776 AnalysisContext context = AnalysisContextFactory.contextWithCore( |
| 12338 FileBasedSource source = | 777 resourceProvider: resourceProvider); |
| 12339 new FileBasedSource(FileUtilities2.createFile("/test.dart")); | 778 Source source = new FileSource(resourceProvider.getFile("/test.dart")); |
| 12340 _definingCompilationUnit = new CompilationUnitElementImpl("test.dart"); | 779 _definingCompilationUnit = new CompilationUnitElementImpl("test.dart"); |
| 12341 _definingCompilationUnit.librarySource = | 780 _definingCompilationUnit.librarySource = |
| 12342 _definingCompilationUnit.source = source; | 781 _definingCompilationUnit.source = source; |
| 12343 LibraryElementImpl definingLibrary = | 782 LibraryElementImpl definingLibrary = |
| 12344 ElementFactory.library(context, "test"); | 783 ElementFactory.library(context, "test"); |
| 12345 definingLibrary.definingCompilationUnit = _definingCompilationUnit; | 784 definingLibrary.definingCompilationUnit = _definingCompilationUnit; |
| 12346 _subtypeManager = new SubtypeManager(); | 785 _subtypeManager = new SubtypeManager(); |
| 12347 } | 786 } |
| 12348 | 787 |
| 12349 void test_computeAllSubtypes_infiniteLoop() { | 788 void test_computeAllSubtypes_infiniteLoop() { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12418 List<ClassElement> arraySubtypesOfA = new List.from(subtypesOfA); | 857 List<ClassElement> arraySubtypesOfA = new List.from(subtypesOfA); |
| 12419 expect(subtypesOfA, hasLength(1)); | 858 expect(subtypesOfA, hasLength(1)); |
| 12420 expect(arraySubtypesOfA, unorderedEquals([classB])); | 859 expect(arraySubtypesOfA, unorderedEquals([classB])); |
| 12421 } | 860 } |
| 12422 } | 861 } |
| 12423 | 862 |
| 12424 @reflectiveTest | 863 @reflectiveTest |
| 12425 class TypeOverrideManagerTest extends EngineTestCase { | 864 class TypeOverrideManagerTest extends EngineTestCase { |
| 12426 void test_exitScope_noScopes() { | 865 void test_exitScope_noScopes() { |
| 12427 TypeOverrideManager manager = new TypeOverrideManager(); | 866 TypeOverrideManager manager = new TypeOverrideManager(); |
| 12428 try { | 867 expect(() { |
| 12429 manager.exitScope(); | 868 manager.exitScope(); |
| 12430 fail("Expected IllegalStateException"); | 869 }, throwsStateError); |
| 12431 } on IllegalStateException { | |
| 12432 // Expected | |
| 12433 } | |
| 12434 } | 870 } |
| 12435 | 871 |
| 12436 void test_exitScope_oneScope() { | 872 void test_exitScope_oneScope() { |
| 12437 TypeOverrideManager manager = new TypeOverrideManager(); | 873 TypeOverrideManager manager = new TypeOverrideManager(); |
| 12438 manager.enterScope(); | 874 manager.enterScope(); |
| 12439 manager.exitScope(); | 875 manager.exitScope(); |
| 12440 try { | 876 expect(() { |
| 12441 manager.exitScope(); | 877 manager.exitScope(); |
| 12442 fail("Expected IllegalStateException"); | 878 }, throwsStateError); |
| 12443 } on IllegalStateException { | |
| 12444 // Expected | |
| 12445 } | |
| 12446 } | 879 } |
| 12447 | 880 |
| 12448 void test_exitScope_twoScopes() { | 881 void test_exitScope_twoScopes() { |
| 12449 TypeOverrideManager manager = new TypeOverrideManager(); | 882 TypeOverrideManager manager = new TypeOverrideManager(); |
| 12450 manager.enterScope(); | 883 manager.enterScope(); |
| 12451 manager.exitScope(); | 884 manager.exitScope(); |
| 12452 manager.enterScope(); | 885 manager.enterScope(); |
| 12453 manager.exitScope(); | 886 manager.exitScope(); |
| 12454 try { | 887 expect(() { |
| 12455 manager.exitScope(); | 888 manager.exitScope(); |
| 12456 fail("Expected IllegalStateException"); | 889 }, throwsStateError); |
| 12457 } on IllegalStateException { | |
| 12458 // Expected | |
| 12459 } | |
| 12460 } | 890 } |
| 12461 | 891 |
| 12462 void test_getType_enclosedOverride() { | 892 void test_getType_enclosedOverride() { |
| 12463 TypeOverrideManager manager = new TypeOverrideManager(); | 893 TypeOverrideManager manager = new TypeOverrideManager(); |
| 12464 LocalVariableElementImpl element = | 894 LocalVariableElementImpl element = |
| 12465 ElementFactory.localVariableElement2("v"); | 895 ElementFactory.localVariableElement2("v"); |
| 12466 InterfaceType type = ElementFactory.classElement2("C").type; | 896 InterfaceType type = ElementFactory.classElement2("C").type; |
| 12467 manager.enterScope(); | 897 manager.enterScope(); |
| 12468 manager.setType(element, type); | 898 manager.setType(element, type); |
| 12469 manager.enterScope(); | 899 manager.enterScope(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 12487 } | 917 } |
| 12488 | 918 |
| 12489 void test_getType_noScope() { | 919 void test_getType_noScope() { |
| 12490 TypeOverrideManager manager = new TypeOverrideManager(); | 920 TypeOverrideManager manager = new TypeOverrideManager(); |
| 12491 expect(manager.getType(ElementFactory.localVariableElement2("v")), isNull); | 921 expect(manager.getType(ElementFactory.localVariableElement2("v")), isNull); |
| 12492 } | 922 } |
| 12493 } | 923 } |
| 12494 | 924 |
| 12495 @reflectiveTest | 925 @reflectiveTest |
| 12496 class TypePropagationTest extends ResolverTestCase { | 926 class TypePropagationTest extends ResolverTestCase { |
| 12497 void fail_finalPropertyInducingVariable_classMember_instance() { | |
| 12498 addNamedSource( | |
| 12499 "/lib.dart", | |
| 12500 r''' | |
| 12501 class A { | |
| 12502 final v = 0; | |
| 12503 }'''); | |
| 12504 String code = r''' | |
| 12505 import 'lib.dart'; | |
| 12506 f(A a) { | |
| 12507 return a.v; // marker | |
| 12508 }'''; | |
| 12509 _assertTypeOfMarkedExpression( | |
| 12510 code, typeProvider.dynamicType, typeProvider.intType); | |
| 12511 } | |
| 12512 | |
| 12513 void fail_finalPropertyInducingVariable_classMember_instance_inherited() { | |
| 12514 addNamedSource( | |
| 12515 "/lib.dart", | |
| 12516 r''' | |
| 12517 class A { | |
| 12518 final v = 0; | |
| 12519 }'''); | |
| 12520 String code = r''' | |
| 12521 import 'lib.dart'; | |
| 12522 class B extends A { | |
| 12523 m() { | |
| 12524 return v; // marker | |
| 12525 } | |
| 12526 }'''; | |
| 12527 _assertTypeOfMarkedExpression( | |
| 12528 code, typeProvider.dynamicType, typeProvider.intType); | |
| 12529 } | |
| 12530 | |
| 12531 void fail_finalPropertyInducingVariable_classMember_instance_propagatedTarget(
) { | |
| 12532 addNamedSource( | |
| 12533 "/lib.dart", | |
| 12534 r''' | |
| 12535 class A { | |
| 12536 final v = 0; | |
| 12537 }'''); | |
| 12538 String code = r''' | |
| 12539 import 'lib.dart'; | |
| 12540 f(p) { | |
| 12541 if (p is A) { | |
| 12542 return p.v; // marker | |
| 12543 } | |
| 12544 }'''; | |
| 12545 _assertTypeOfMarkedExpression( | |
| 12546 code, typeProvider.dynamicType, typeProvider.intType); | |
| 12547 } | |
| 12548 | |
| 12549 void fail_finalPropertyInducingVariable_classMember_instance_unprefixed() { | |
| 12550 String code = r''' | |
| 12551 class A { | |
| 12552 final v = 0; | |
| 12553 m() { | |
| 12554 v; // marker | |
| 12555 } | |
| 12556 }'''; | |
| 12557 _assertTypeOfMarkedExpression( | |
| 12558 code, typeProvider.dynamicType, typeProvider.intType); | |
| 12559 } | |
| 12560 | |
| 12561 void fail_finalPropertyInducingVariable_classMember_static() { | |
| 12562 addNamedSource( | |
| 12563 "/lib.dart", | |
| 12564 r''' | |
| 12565 class A { | |
| 12566 static final V = 0; | |
| 12567 }'''); | |
| 12568 String code = r''' | |
| 12569 import 'lib.dart'; | |
| 12570 f() { | |
| 12571 return A.V; // marker | |
| 12572 }'''; | |
| 12573 _assertTypeOfMarkedExpression( | |
| 12574 code, typeProvider.dynamicType, typeProvider.intType); | |
| 12575 } | |
| 12576 | |
| 12577 void fail_finalPropertyInducingVariable_topLevelVaraible_prefixed() { | |
| 12578 addNamedSource("/lib.dart", "final V = 0;"); | |
| 12579 String code = r''' | |
| 12580 import 'lib.dart' as p; | |
| 12581 f() { | |
| 12582 var v2 = p.V; // marker prefixed | |
| 12583 }'''; | |
| 12584 _assertTypeOfMarkedExpression( | |
| 12585 code, typeProvider.dynamicType, typeProvider.intType); | |
| 12586 } | |
| 12587 | |
| 12588 void fail_finalPropertyInducingVariable_topLevelVaraible_simple() { | |
| 12589 addNamedSource("/lib.dart", "final V = 0;"); | |
| 12590 String code = r''' | |
| 12591 import 'lib.dart'; | |
| 12592 f() { | |
| 12593 return V; // marker simple | |
| 12594 }'''; | |
| 12595 _assertTypeOfMarkedExpression( | |
| 12596 code, typeProvider.dynamicType, typeProvider.intType); | |
| 12597 } | |
| 12598 | |
| 12599 void fail_mergePropagatedTypesAtJoinPoint_1() { | 927 void fail_mergePropagatedTypesAtJoinPoint_1() { |
| 12600 // https://code.google.com/p/dart/issues/detail?id=19929 | 928 // https://code.google.com/p/dart/issues/detail?id=19929 |
| 12601 _assertTypeOfMarkedExpression( | 929 assertTypeOfMarkedExpression( |
| 12602 r''' | 930 r''' |
| 12603 f1(x) { | 931 f1(x) { |
| 12604 var y = []; | 932 var y = []; |
| 12605 if (x) { | 933 if (x) { |
| 12606 y = 0; | 934 y = 0; |
| 12607 } else { | 935 } else { |
| 12608 y = ''; | 936 y = ''; |
| 12609 } | 937 } |
| 12610 // Propagated type is [List] here: incorrect. | 938 // Propagated type is [List] here: incorrect. |
| 12611 // Best we can do is [Object]? | 939 // Best we can do is [Object]? |
| 12612 return y; // marker | 940 return y; // marker |
| 12613 }''', | 941 }''', |
| 12614 null, | 942 null, |
| 12615 typeProvider.dynamicType); | 943 typeProvider.dynamicType); |
| 12616 } | 944 } |
| 12617 | 945 |
| 12618 void fail_mergePropagatedTypesAtJoinPoint_2() { | 946 void fail_mergePropagatedTypesAtJoinPoint_2() { |
| 12619 // https://code.google.com/p/dart/issues/detail?id=19929 | 947 // https://code.google.com/p/dart/issues/detail?id=19929 |
| 12620 _assertTypeOfMarkedExpression( | 948 assertTypeOfMarkedExpression( |
| 12621 r''' | 949 r''' |
| 12622 f2(x) { | 950 f2(x) { |
| 12623 var y = []; | 951 var y = []; |
| 12624 if (x) { | 952 if (x) { |
| 12625 y = 0; | 953 y = 0; |
| 12626 } else { | 954 } else { |
| 12627 } | 955 } |
| 12628 // Propagated type is [List] here: incorrect. | 956 // Propagated type is [List] here: incorrect. |
| 12629 // Best we can do is [Object]? | 957 // Best we can do is [Object]? |
| 12630 return y; // marker | 958 return y; // marker |
| 12631 }''', | 959 }''', |
| 12632 null, | 960 null, |
| 12633 typeProvider.dynamicType); | 961 typeProvider.dynamicType); |
| 12634 } | 962 } |
| 12635 | 963 |
| 12636 void fail_mergePropagatedTypesAtJoinPoint_3() { | 964 void fail_mergePropagatedTypesAtJoinPoint_3() { |
| 12637 // https://code.google.com/p/dart/issues/detail?id=19929 | 965 // https://code.google.com/p/dart/issues/detail?id=19929 |
| 12638 _assertTypeOfMarkedExpression( | 966 assertTypeOfMarkedExpression( |
| 12639 r''' | 967 r''' |
| 12640 f4(x) { | 968 f4(x) { |
| 12641 var y = []; | 969 var y = []; |
| 12642 if (x) { | 970 if (x) { |
| 12643 y = 0; | 971 y = 0; |
| 12644 } else { | 972 } else { |
| 12645 y = 1.5; | 973 y = 1.5; |
| 12646 } | 974 } |
| 12647 // Propagated type is [List] here: incorrect. | 975 // Propagated type is [List] here: incorrect. |
| 12648 // A correct answer is the least upper bound of [int] and [double], | 976 // A correct answer is the least upper bound of [int] and [double], |
| 12649 // i.e. [num]. | 977 // i.e. [num]. |
| 12650 return y; // marker | 978 return y; // marker |
| 12651 }''', | 979 }''', |
| 12652 null, | 980 null, |
| 12653 typeProvider.numType); | 981 typeProvider.numType); |
| 12654 } | 982 } |
| 12655 | 983 |
| 12656 void fail_mergePropagatedTypesAtJoinPoint_5() { | 984 void fail_mergePropagatedTypesAtJoinPoint_5() { |
| 12657 // https://code.google.com/p/dart/issues/detail?id=19929 | 985 // https://code.google.com/p/dart/issues/detail?id=19929 |
| 12658 _assertTypeOfMarkedExpression( | 986 assertTypeOfMarkedExpression( |
| 12659 r''' | 987 r''' |
| 12660 f6(x,y) { | 988 f6(x,y) { |
| 12661 var z = []; | 989 var z = []; |
| 12662 if (x || (z = y) < 0) { | 990 if (x || (z = y) < 0) { |
| 12663 } else { | 991 } else { |
| 12664 z = 0; | 992 z = 0; |
| 12665 } | 993 } |
| 12666 // Propagated type is [List] here: incorrect. | 994 // Propagated type is [List] here: incorrect. |
| 12667 // Best we can do is [Object]? | 995 // Best we can do is [Object]? |
| 12668 return z; // marker | 996 return z; // marker |
| (...skipping 19 matching lines...) Expand all Loading... |
| 12688 if (c) { | 1016 if (c) { |
| 12689 d = false; | 1017 d = false; |
| 12690 } else { | 1018 } else { |
| 12691 x = ''; | 1019 x = ''; |
| 12692 c = true; | 1020 c = true; |
| 12693 continue; | 1021 continue; |
| 12694 } | 1022 } |
| 12695 x; // marker | 1023 x; // marker |
| 12696 } | 1024 } |
| 12697 }'''; | 1025 }'''; |
| 12698 DartType t = _findMarkedIdentifier(code, "; // marker").propagatedType; | 1026 DartType t = findMarkedIdentifier(code, "; // marker").propagatedType; |
| 12699 expect(typeProvider.intType.isSubtypeOf(t), isTrue); | 1027 expect(typeProvider.intType.isSubtypeOf(t), isTrue); |
| 12700 expect(typeProvider.stringType.isSubtypeOf(t), isTrue); | 1028 expect(typeProvider.stringType.isSubtypeOf(t), isTrue); |
| 12701 } | 1029 } |
| 12702 | 1030 |
| 12703 void fail_mergePropagatedTypesAtJoinPoint_8() { | 1031 void fail_mergePropagatedTypesAtJoinPoint_8() { |
| 12704 // https://code.google.com/p/dart/issues/detail?id=19929 | 1032 // https://code.google.com/p/dart/issues/detail?id=19929 |
| 12705 // | 1033 // |
| 12706 // In nested loops [breaks]s are unsafe for the purposes of | 1034 // In nested loops [breaks]s are unsafe for the purposes of |
| 12707 // [isAbruptTerminationStatement]. | 1035 // [isAbruptTerminationStatement]. |
| 12708 // | 1036 // |
| (...skipping 11 matching lines...) Expand all Loading... |
| 12720 d = false; | 1048 d = false; |
| 12721 } else { | 1049 } else { |
| 12722 x = ''; | 1050 x = ''; |
| 12723 c = true; | 1051 c = true; |
| 12724 break; | 1052 break; |
| 12725 } | 1053 } |
| 12726 x; // marker | 1054 x; // marker |
| 12727 } | 1055 } |
| 12728 } | 1056 } |
| 12729 }'''; | 1057 }'''; |
| 12730 DartType t = _findMarkedIdentifier(code, "; // marker").propagatedType; | 1058 DartType t = findMarkedIdentifier(code, "; // marker").propagatedType; |
| 12731 expect(typeProvider.intType.isSubtypeOf(t), isTrue); | 1059 expect(typeProvider.intType.isSubtypeOf(t), isTrue); |
| 12732 expect(typeProvider.stringType.isSubtypeOf(t), isTrue); | 1060 expect(typeProvider.stringType.isSubtypeOf(t), isTrue); |
| 12733 } | 1061 } |
| 12734 | 1062 |
| 12735 void fail_propagatedReturnType_functionExpression() { | 1063 void fail_propagatedReturnType_functionExpression() { |
| 12736 // TODO(scheglov) disabled because we don't resolve function expression | 1064 // TODO(scheglov) disabled because we don't resolve function expression |
| 12737 String code = r''' | 1065 String code = r''' |
| 12738 main() { | 1066 main() { |
| 12739 var v = (() {return 42;})(); | 1067 var v = (() {return 42;})(); |
| 12740 }'''; | 1068 }'''; |
| 12741 _assertPropagatedAssignedType( | 1069 assertPropagatedAssignedType( |
| 12742 code, typeProvider.dynamicType, typeProvider.intType); | 1070 code, typeProvider.dynamicType, typeProvider.intType); |
| 12743 } | 1071 } |
| 12744 | 1072 |
| 12745 void test_as() { | 1073 void test_as() { |
| 12746 Source source = addSource(r''' | 1074 Source source = addSource(r''' |
| 12747 class A { | 1075 class A { |
| 12748 bool get g => true; | 1076 bool get g => true; |
| 12749 } | 1077 } |
| 12750 A f(var p) { | 1078 A f(var p) { |
| 12751 if ((p as A).g) { | 1079 if ((p as A).g) { |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12929 expect(identifier.propagatedType, same(stringType)); | 1257 expect(identifier.propagatedType, same(stringType)); |
| 12930 } | 1258 } |
| 12931 // in the loop body | 1259 // in the loop body |
| 12932 { | 1260 { |
| 12933 SimpleIdentifier identifier = EngineTestCase.findNode( | 1261 SimpleIdentifier identifier = EngineTestCase.findNode( |
| 12934 unit, code, "e;", (node) => node is SimpleIdentifier); | 1262 unit, code, "e;", (node) => node is SimpleIdentifier); |
| 12935 expect(identifier.propagatedType, same(stringType)); | 1263 expect(identifier.propagatedType, same(stringType)); |
| 12936 } | 1264 } |
| 12937 } | 1265 } |
| 12938 | 1266 |
| 1267 void test_forEach_async_inheritedStream() { |
| 1268 // From https://github.com/dart-lang/sdk/issues/24191, this ensures that |
| 1269 // `await for` works for types where the generic parameter doesn't |
| 1270 // correspond to the type of the Stream's data. |
| 1271 String code = r''' |
| 1272 import 'dart:async'; |
| 1273 abstract class MyCustomStream<T> implements Stream<List<T>> {} |
| 1274 f(MyCustomStream<String> stream) async { |
| 1275 await for (var e in stream) { |
| 1276 e; |
| 1277 } |
| 1278 }'''; |
| 1279 Source source = addSource(code); |
| 1280 LibraryElement library = resolve2(source); |
| 1281 assertNoErrors(source); |
| 1282 verify([source]); |
| 1283 CompilationUnit unit = resolveCompilationUnit(source, library); |
| 1284 InterfaceType listOfStringType = |
| 1285 typeProvider.listType.instantiate([typeProvider.stringType]); |
| 1286 // in the declaration |
| 1287 { |
| 1288 SimpleIdentifier identifier = EngineTestCase.findNode( |
| 1289 unit, code, "e in", (node) => node is SimpleIdentifier); |
| 1290 expect(identifier.propagatedType, equals(listOfStringType)); |
| 1291 } |
| 1292 // in the loop body |
| 1293 { |
| 1294 SimpleIdentifier identifier = EngineTestCase.findNode( |
| 1295 unit, code, "e;", (node) => node is SimpleIdentifier); |
| 1296 expect(identifier.propagatedType, equals(listOfStringType)); |
| 1297 } |
| 1298 } |
| 1299 |
| 12939 void test_functionExpression_asInvocationArgument() { | 1300 void test_functionExpression_asInvocationArgument() { |
| 12940 String code = r''' | 1301 String code = r''' |
| 12941 class MyMap<K, V> { | 1302 class MyMap<K, V> { |
| 12942 forEach(f(K key, V value)) {} | 1303 forEach(f(K key, V value)) {} |
| 12943 } | 1304 } |
| 12944 f(MyMap<int, String> m) { | 1305 f(MyMap<int, String> m) { |
| 12945 m.forEach((k, v) { | 1306 m.forEach((k, v) { |
| 12946 k; | 1307 k; |
| 12947 v; | 1308 v; |
| 12948 }); | 1309 }); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12991 FormalParameter kParameter = EngineTestCase.findNode( | 1352 FormalParameter kParameter = EngineTestCase.findNode( |
| 12992 unit, code, "k, ", (node) => node is SimpleFormalParameter); | 1353 unit, code, "k, ", (node) => node is SimpleFormalParameter); |
| 12993 expect(kParameter.identifier.propagatedType, same(intType)); | 1354 expect(kParameter.identifier.propagatedType, same(intType)); |
| 12994 // v | 1355 // v |
| 12995 DartType stringType = typeProvider.stringType; | 1356 DartType stringType = typeProvider.stringType; |
| 12996 FormalParameter vParameter = EngineTestCase.findNode( | 1357 FormalParameter vParameter = EngineTestCase.findNode( |
| 12997 unit, code, "v)", (node) => node is SimpleFormalParameter); | 1358 unit, code, "v)", (node) => node is SimpleFormalParameter); |
| 12998 expect(vParameter.identifier.propagatedType, same(stringType)); | 1359 expect(vParameter.identifier.propagatedType, same(stringType)); |
| 12999 } | 1360 } |
| 13000 | 1361 |
| 13001 void test_functionExpression_asInvocationArgument_functionExpressionInvocation
() { | 1362 void |
| 1363 test_functionExpression_asInvocationArgument_functionExpressionInvocation(
) { |
| 13002 String code = r''' | 1364 String code = r''' |
| 13003 main() { | 1365 main() { |
| 13004 (f(String value)) {} ((v) { | 1366 (f(String value)) {} ((v) { |
| 13005 v; | 1367 v; |
| 13006 }); | 1368 }); |
| 13007 }'''; | 1369 }'''; |
| 13008 Source source = addSource(code); | 1370 Source source = addSource(code); |
| 13009 LibraryElement library = resolve2(source); | 1371 LibraryElement library = resolve2(source); |
| 13010 assertNoErrors(source); | 1372 assertNoErrors(source); |
| 13011 verify([source]); | 1373 verify([source]); |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13259 expect(identifier.propagatedType, same(null)); | 1621 expect(identifier.propagatedType, same(null)); |
| 13260 } | 1622 } |
| 13261 { | 1623 { |
| 13262 SimpleIdentifier identifier = EngineTestCase.findNode( | 1624 SimpleIdentifier identifier = EngineTestCase.findNode( |
| 13263 unit, code, "v; // marker", (node) => node is SimpleIdentifier); | 1625 unit, code, "v; // marker", (node) => node is SimpleIdentifier); |
| 13264 expect(identifier.staticType, same(typeProvider.intType)); | 1626 expect(identifier.staticType, same(typeProvider.intType)); |
| 13265 expect(identifier.propagatedType, same(null)); | 1627 expect(identifier.propagatedType, same(null)); |
| 13266 } | 1628 } |
| 13267 } | 1629 } |
| 13268 | 1630 |
| 1631 void test_invocation_target_prefixed() { |
| 1632 addNamedSource( |
| 1633 '/helper.dart', |
| 1634 ''' |
| 1635 library helper; |
| 1636 int max(int x, int y) => 0; |
| 1637 '''); |
| 1638 String code = ''' |
| 1639 import 'helper.dart' as helper; |
| 1640 main() { |
| 1641 helper.max(10, 10); // marker |
| 1642 }'''; |
| 1643 SimpleIdentifier methodName = |
| 1644 findMarkedIdentifier(code, "(10, 10); // marker"); |
| 1645 MethodInvocation methodInvoke = methodName.parent; |
| 1646 expect(methodInvoke.methodName.staticElement, isNotNull); |
| 1647 expect(methodInvoke.methodName.propagatedElement, isNull); |
| 1648 } |
| 1649 |
| 13269 void test_is_conditional() { | 1650 void test_is_conditional() { |
| 13270 Source source = addSource(r''' | 1651 Source source = addSource(r''' |
| 13271 class A {} | 1652 class A {} |
| 13272 A f(var p) { | 1653 A f(var p) { |
| 13273 return (p is A) ? p : null; | 1654 return (p is A) ? p : null; |
| 13274 }'''); | 1655 }'''); |
| 13275 LibraryElement library = resolve2(source); | 1656 LibraryElement library = resolve2(source); |
| 13276 assertNoErrors(source); | 1657 assertNoErrors(source); |
| 13277 verify([source]); | 1658 verify([source]); |
| 13278 CompilationUnit unit = resolveCompilationUnit(source, library); | 1659 CompilationUnit unit = resolveCompilationUnit(source, library); |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13619 class A {} | 2000 class A {} |
| 13620 class B extends A {} | 2001 class B extends A {} |
| 13621 f() { | 2002 f() { |
| 13622 var a = new A(); | 2003 var a = new A(); |
| 13623 var b = new B(); | 2004 var b = new B(); |
| 13624 b; // B | 2005 b; // B |
| 13625 if (a is B) { | 2006 if (a is B) { |
| 13626 return a; // marker | 2007 return a; // marker |
| 13627 } | 2008 } |
| 13628 }'''; | 2009 }'''; |
| 13629 DartType tB = _findMarkedIdentifier(code, "; // B").propagatedType; | 2010 DartType tB = findMarkedIdentifier(code, "; // B").propagatedType; |
| 13630 _assertTypeOfMarkedExpression(code, null, tB); | 2011 assertTypeOfMarkedExpression(code, null, tB); |
| 13631 } | 2012 } |
| 13632 | 2013 |
| 13633 void test_issue20904BuggyTypePromotionAtIfJoin_6() { | 2014 void test_issue20904BuggyTypePromotionAtIfJoin_6() { |
| 13634 // https://code.google.com/p/dart/issues/detail?id=20904 | 2015 // https://code.google.com/p/dart/issues/detail?id=20904 |
| 13635 // | 2016 // |
| 13636 // The other half of the *_5() test. | 2017 // The other half of the *_5() test. |
| 13637 // | 2018 // |
| 13638 // Here the is-check loses precision, so we don't use it. | 2019 // Here the is-check loses precision, so we don't use it. |
| 13639 String code = r''' | 2020 String code = r''' |
| 13640 class A {} | 2021 class A {} |
| 13641 class B extends A {} | 2022 class B extends A {} |
| 13642 f() { | 2023 f() { |
| 13643 var b = new B(); | 2024 var b = new B(); |
| 13644 b; // B | 2025 b; // B |
| 13645 if (b is A) { | 2026 if (b is A) { |
| 13646 return b; // marker | 2027 return b; // marker |
| 13647 } | 2028 } |
| 13648 }'''; | 2029 }'''; |
| 13649 DartType tB = _findMarkedIdentifier(code, "; // B").propagatedType; | 2030 DartType tB = findMarkedIdentifier(code, "; // B").propagatedType; |
| 13650 _assertTypeOfMarkedExpression(code, null, tB); | 2031 assertTypeOfMarkedExpression(code, null, tB); |
| 13651 } | 2032 } |
| 13652 | 2033 |
| 13653 void test_listLiteral_different() { | 2034 void test_listLiteral_different() { |
| 13654 Source source = addSource(r''' | 2035 Source source = addSource(r''' |
| 13655 f() { | 2036 f() { |
| 13656 var v = [0, '1', 2]; | 2037 var v = [0, '1', 2]; |
| 13657 return v[2]; | 2038 return v[2]; |
| 13658 }'''); | 2039 }'''); |
| 13659 LibraryElement library = resolve2(source); | 2040 LibraryElement library = resolve2(source); |
| 13660 assertNoErrors(source); | 2041 assertNoErrors(source); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13741 void test_mergePropagatedTypes_afterIfThen_different() { | 2122 void test_mergePropagatedTypes_afterIfThen_different() { |
| 13742 String code = r''' | 2123 String code = r''' |
| 13743 main() { | 2124 main() { |
| 13744 var v = 0; | 2125 var v = 0; |
| 13745 if (v != null) { | 2126 if (v != null) { |
| 13746 v = ''; | 2127 v = ''; |
| 13747 } | 2128 } |
| 13748 return v; | 2129 return v; |
| 13749 }'''; | 2130 }'''; |
| 13750 { | 2131 { |
| 13751 SimpleIdentifier identifier = _findMarkedIdentifier(code, "v;"); | 2132 SimpleIdentifier identifier = findMarkedIdentifier(code, "v;"); |
| 13752 expect(identifier.propagatedType, null); | 2133 expect(identifier.propagatedType, null); |
| 13753 } | 2134 } |
| 13754 { | 2135 { |
| 13755 SimpleIdentifier identifier = _findMarkedIdentifier(code, "v = '';"); | 2136 SimpleIdentifier identifier = findMarkedIdentifier(code, "v = '';"); |
| 13756 expect(identifier.propagatedType, typeProvider.stringType); | 2137 expect(identifier.propagatedType, typeProvider.stringType); |
| 13757 } | 2138 } |
| 13758 } | 2139 } |
| 13759 | 2140 |
| 13760 void test_mergePropagatedTypes_afterIfThen_same() { | 2141 void test_mergePropagatedTypes_afterIfThen_same() { |
| 13761 _assertTypeOfMarkedExpression( | 2142 assertTypeOfMarkedExpression( |
| 13762 r''' | 2143 r''' |
| 13763 main() { | 2144 main() { |
| 13764 var v = 1; | 2145 var v = 1; |
| 13765 if (v != null) { | 2146 if (v != null) { |
| 13766 v = 2; | 2147 v = 2; |
| 13767 } | 2148 } |
| 13768 return v; // marker | 2149 return v; // marker |
| 13769 }''', | 2150 }''', |
| 13770 null, | 2151 null, |
| 13771 typeProvider.intType); | 2152 typeProvider.intType); |
| 13772 } | 2153 } |
| 13773 | 2154 |
| 13774 void test_mergePropagatedTypes_afterIfThenElse_different() { | 2155 void test_mergePropagatedTypes_afterIfThenElse_different() { |
| 13775 _assertTypeOfMarkedExpression( | 2156 assertTypeOfMarkedExpression( |
| 13776 r''' | 2157 r''' |
| 13777 main() { | 2158 main() { |
| 13778 var v = 1; | 2159 var v = 1; |
| 13779 if (v != null) { | 2160 if (v != null) { |
| 13780 v = 2; | 2161 v = 2; |
| 13781 } else { | 2162 } else { |
| 13782 v = '3'; | 2163 v = '3'; |
| 13783 } | 2164 } |
| 13784 return v; // marker | 2165 return v; // marker |
| 13785 }''', | 2166 }''', |
| 13786 null, | 2167 null, |
| 13787 null); | 2168 null); |
| 13788 } | 2169 } |
| 13789 | 2170 |
| 13790 void test_mergePropagatedTypes_afterIfThenElse_same() { | 2171 void test_mergePropagatedTypes_afterIfThenElse_same() { |
| 13791 _assertTypeOfMarkedExpression( | 2172 assertTypeOfMarkedExpression( |
| 13792 r''' | 2173 r''' |
| 13793 main() { | 2174 main() { |
| 13794 var v = 1; | 2175 var v = 1; |
| 13795 if (v != null) { | 2176 if (v != null) { |
| 13796 v = 2; | 2177 v = 2; |
| 13797 } else { | 2178 } else { |
| 13798 v = 3; | 2179 v = 3; |
| 13799 } | 2180 } |
| 13800 return v; // marker | 2181 return v; // marker |
| 13801 }''', | 2182 }''', |
| 13802 null, | 2183 null, |
| 13803 typeProvider.intType); | 2184 typeProvider.intType); |
| 13804 } | 2185 } |
| 13805 | 2186 |
| 13806 void test_mergePropagatedTypesAtJoinPoint_4() { | 2187 void test_mergePropagatedTypesAtJoinPoint_4() { |
| 13807 // https://code.google.com/p/dart/issues/detail?id=19929 | 2188 // https://code.google.com/p/dart/issues/detail?id=19929 |
| 13808 _assertTypeOfMarkedExpression( | 2189 assertTypeOfMarkedExpression( |
| 13809 r''' | 2190 r''' |
| 13810 f5(x) { | 2191 f5(x) { |
| 13811 var y = []; | 2192 var y = []; |
| 13812 if (x) { | 2193 if (x) { |
| 13813 y = 0; | 2194 y = 0; |
| 13814 } else { | 2195 } else { |
| 13815 return y; | 2196 return y; |
| 13816 } | 2197 } |
| 13817 // Propagated type is [int] here: correct. | 2198 // Propagated type is [int] here: correct. |
| 13818 return y; // marker | 2199 return y; // marker |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13859 ''' | 2240 ''' |
| 13860 library helper; | 2241 library helper; |
| 13861 dynamic get $name => 42; | 2242 dynamic get $name => 42; |
| 13862 '''); | 2243 '''); |
| 13863 String code = ''' | 2244 String code = ''' |
| 13864 import 'helper.dart' as helper; | 2245 import 'helper.dart' as helper; |
| 13865 main() { | 2246 main() { |
| 13866 helper.$name; // marker | 2247 helper.$name; // marker |
| 13867 }'''; | 2248 }'''; |
| 13868 | 2249 |
| 13869 SimpleIdentifier id = _findMarkedIdentifier(code, "; // marker"); | 2250 SimpleIdentifier id = findMarkedIdentifier(code, "; // marker"); |
| 13870 PrefixedIdentifier prefixedId = id.parent; | 2251 PrefixedIdentifier prefixedId = id.parent; |
| 13871 expect(id.staticType, typeProvider.dynamicType); | 2252 expect(id.staticType, typeProvider.dynamicType); |
| 13872 expect(prefixedId.staticType, typeProvider.dynamicType); | 2253 expect(prefixedId.staticType, typeProvider.dynamicType); |
| 13873 } | 2254 } |
| 13874 | 2255 |
| 13875 void test_objectAccessInference_disabled_for_local_getter() { | 2256 void test_objectAccessInference_disabled_for_local_getter() { |
| 13876 String name = 'hashCode'; | 2257 String name = 'hashCode'; |
| 13877 String code = ''' | 2258 String code = ''' |
| 13878 dynamic get $name => null; | 2259 dynamic get $name => null; |
| 13879 main() { | 2260 main() { |
| 13880 $name; // marker | 2261 $name; // marker |
| 13881 }'''; | 2262 }'''; |
| 13882 | 2263 |
| 13883 SimpleIdentifier getter = _findMarkedIdentifier(code, "; // marker"); | 2264 SimpleIdentifier getter = findMarkedIdentifier(code, "; // marker"); |
| 13884 expect(getter.staticType, typeProvider.dynamicType); | 2265 expect(getter.staticType, typeProvider.dynamicType); |
| 13885 } | 2266 } |
| 13886 | 2267 |
| 13887 void test_objectAccessInference_enabled_for_cascades() { | 2268 void test_objectAccessInference_enabled_for_cascades() { |
| 13888 String name = 'hashCode'; | 2269 String name = 'hashCode'; |
| 13889 String code = ''' | 2270 String code = ''' |
| 13890 main() { | 2271 main() { |
| 13891 dynamic obj; | 2272 dynamic obj; |
| 13892 obj..$name..$name; // marker | 2273 obj..$name..$name; // marker |
| 13893 }'''; | 2274 }'''; |
| 13894 PropertyAccess access = _findMarkedIdentifier(code, "; // marker").parent; | 2275 PropertyAccess access = findMarkedIdentifier(code, "; // marker").parent; |
| 13895 expect(access.staticType, typeProvider.dynamicType); | 2276 expect(access.staticType, typeProvider.dynamicType); |
| 13896 expect(access.realTarget.staticType, typeProvider.dynamicType); | 2277 expect(access.realTarget.staticType, typeProvider.dynamicType); |
| 13897 } | 2278 } |
| 13898 | 2279 |
| 13899 void test_objectMethodInference_disabled_for_library_prefix() { | 2280 void test_objectMethodInference_disabled_for_library_prefix() { |
| 13900 String name = 'toString'; | 2281 String name = 'toString'; |
| 13901 addNamedSource( | 2282 addNamedSource( |
| 13902 '/helper.dart', | 2283 '/helper.dart', |
| 13903 ''' | 2284 ''' |
| 13904 library helper; | 2285 library helper; |
| 13905 dynamic $name = (int x) => x + 42'); | 2286 dynamic $name = (int x) => x + 42'); |
| 13906 '''); | 2287 '''); |
| 13907 String code = ''' | 2288 String code = ''' |
| 13908 import 'helper.dart' as helper; | 2289 import 'helper.dart' as helper; |
| 13909 main() { | 2290 main() { |
| 13910 helper.$name(); // marker | 2291 helper.$name(); // marker |
| 13911 }'''; | 2292 }'''; |
| 13912 SimpleIdentifier methodName = _findMarkedIdentifier(code, "(); // marker"); | 2293 SimpleIdentifier methodName = findMarkedIdentifier(code, "(); // marker"); |
| 13913 MethodInvocation methodInvoke = methodName.parent; | 2294 MethodInvocation methodInvoke = methodName.parent; |
| 13914 expect(methodName.staticType, null, reason: 'library prefix has no type'); | 2295 expect(methodName.staticType, typeProvider.dynamicType); |
| 13915 expect(methodInvoke.staticType, typeProvider.dynamicType); | 2296 expect(methodInvoke.staticType, typeProvider.dynamicType); |
| 13916 } | 2297 } |
| 13917 | 2298 |
| 13918 void test_objectMethodInference_disabled_for_local_function() { | 2299 void test_objectMethodInference_disabled_for_local_function() { |
| 13919 String name = 'toString'; | 2300 String name = 'toString'; |
| 13920 String code = ''' | 2301 String code = ''' |
| 13921 main() { | 2302 main() { |
| 13922 dynamic $name = () => null; | 2303 dynamic $name = () => null; |
| 13923 $name(); // marker | 2304 $name(); // marker |
| 13924 }'''; | 2305 }'''; |
| 13925 SimpleIdentifier identifier = _findMarkedIdentifier(code, "$name = "); | 2306 SimpleIdentifier identifier = findMarkedIdentifier(code, "$name = "); |
| 13926 expect(identifier.staticType, typeProvider.dynamicType); | 2307 expect(identifier.staticType, typeProvider.dynamicType); |
| 13927 | 2308 |
| 13928 SimpleIdentifier methodName = _findMarkedIdentifier(code, "(); // marker"); | 2309 SimpleIdentifier methodName = findMarkedIdentifier(code, "(); // marker"); |
| 13929 MethodInvocation methodInvoke = methodName.parent; | 2310 MethodInvocation methodInvoke = methodName.parent; |
| 13930 expect(methodName.staticType, typeProvider.dynamicType); | 2311 expect(methodName.staticType, typeProvider.dynamicType); |
| 13931 expect(methodInvoke.staticType, typeProvider.dynamicType); | 2312 expect(methodInvoke.staticType, typeProvider.dynamicType); |
| 13932 } | 2313 } |
| 13933 | 2314 |
| 13934 void test_objectMethodInference_enabled_for_cascades() { | 2315 void test_objectMethodInference_enabled_for_cascades() { |
| 13935 String name = 'toString'; | 2316 String name = 'toString'; |
| 13936 String code = ''' | 2317 String code = ''' |
| 13937 main() { | 2318 main() { |
| 13938 dynamic obj; | 2319 dynamic obj; |
| 13939 obj..$name()..$name(); // marker | 2320 obj..$name()..$name(); // marker |
| 13940 }'''; | 2321 }'''; |
| 13941 SimpleIdentifier methodName = _findMarkedIdentifier(code, "(); // marker"); | 2322 SimpleIdentifier methodName = findMarkedIdentifier(code, "(); // marker"); |
| 13942 MethodInvocation methodInvoke = methodName.parent; | 2323 MethodInvocation methodInvoke = methodName.parent; |
| 13943 | 2324 |
| 13944 expect(methodInvoke.staticType, typeProvider.dynamicType); | 2325 expect(methodInvoke.staticType, typeProvider.dynamicType); |
| 13945 expect(methodInvoke.realTarget.staticType, typeProvider.dynamicType); | 2326 expect(methodInvoke.realTarget.staticType, typeProvider.dynamicType); |
| 13946 } | 2327 } |
| 13947 | 2328 |
| 13948 void test_objectMethodOnDynamicExpression_doubleEquals() { | 2329 void test_objectMethodOnDynamicExpression_doubleEquals() { |
| 13949 // https://code.google.com/p/dart/issues/detail?id=20342 | 2330 // https://code.google.com/p/dart/issues/detail?id=20342 |
| 13950 // | 2331 // |
| 13951 // This was not actually part of Issue 20342, since the spec specifies a | 2332 // This was not actually part of Issue 20342, since the spec specifies a |
| 13952 // static type of [bool] for [==] comparison and the implementation | 2333 // static type of [bool] for [==] comparison and the implementation |
| 13953 // was already consistent with the spec there. But, it's another | 2334 // was already consistent with the spec there. But, it's another |
| 13954 // [Object] method, so it's included here. | 2335 // [Object] method, so it's included here. |
| 13955 _assertTypeOfMarkedExpression( | 2336 assertTypeOfMarkedExpression( |
| 13956 r''' | 2337 r''' |
| 13957 f1(x) { | 2338 f1(x) { |
| 13958 var v = (x == x); | 2339 var v = (x == x); |
| 13959 return v; // marker | 2340 return v; // marker |
| 13960 }''', | 2341 }''', |
| 13961 null, | 2342 null, |
| 13962 typeProvider.boolType); | 2343 typeProvider.boolType); |
| 13963 } | 2344 } |
| 13964 | 2345 |
| 13965 void test_objectMethodOnDynamicExpression_hashCode() { | 2346 void test_objectMethodOnDynamicExpression_hashCode() { |
| 13966 // https://code.google.com/p/dart/issues/detail?id=20342 | 2347 // https://code.google.com/p/dart/issues/detail?id=20342 |
| 13967 _assertTypeOfMarkedExpression( | 2348 assertTypeOfMarkedExpression( |
| 13968 r''' | 2349 r''' |
| 13969 f1(x) { | 2350 f1(x) { |
| 13970 var v = x.hashCode; | 2351 var v = x.hashCode; |
| 13971 return v; // marker | 2352 return v; // marker |
| 13972 }''', | 2353 }''', |
| 13973 null, | 2354 null, |
| 13974 typeProvider.intType); | 2355 typeProvider.intType); |
| 13975 } | 2356 } |
| 13976 | 2357 |
| 13977 void test_objectMethodOnDynamicExpression_runtimeType() { | 2358 void test_objectMethodOnDynamicExpression_runtimeType() { |
| 13978 // https://code.google.com/p/dart/issues/detail?id=20342 | 2359 // https://code.google.com/p/dart/issues/detail?id=20342 |
| 13979 _assertTypeOfMarkedExpression( | 2360 assertTypeOfMarkedExpression( |
| 13980 r''' | 2361 r''' |
| 13981 f1(x) { | 2362 f1(x) { |
| 13982 var v = x.runtimeType; | 2363 var v = x.runtimeType; |
| 13983 return v; // marker | 2364 return v; // marker |
| 13984 }''', | 2365 }''', |
| 13985 null, | 2366 null, |
| 13986 typeProvider.typeType); | 2367 typeProvider.typeType); |
| 13987 } | 2368 } |
| 13988 | 2369 |
| 13989 void test_objectMethodOnDynamicExpression_toString() { | 2370 void test_objectMethodOnDynamicExpression_toString() { |
| 13990 // https://code.google.com/p/dart/issues/detail?id=20342 | 2371 // https://code.google.com/p/dart/issues/detail?id=20342 |
| 13991 _assertTypeOfMarkedExpression( | 2372 assertTypeOfMarkedExpression( |
| 13992 r''' | 2373 r''' |
| 13993 f1(x) { | 2374 f1(x) { |
| 13994 var v = x.toString(); | 2375 var v = x.toString(); |
| 13995 return v; // marker | 2376 return v; // marker |
| 13996 }''', | 2377 }''', |
| 13997 null, | 2378 null, |
| 13998 typeProvider.stringType); | 2379 typeProvider.stringType); |
| 13999 } | 2380 } |
| 14000 | 2381 |
| 14001 void test_propagatedReturnType_localFunction() { | 2382 void test_propagatedReturnType_localFunction() { |
| 14002 String code = r''' | 2383 String code = r''' |
| 14003 main() { | 2384 main() { |
| 14004 f() => 42; | 2385 f() => 42; |
| 14005 var v = f(); | 2386 var v = f(); |
| 14006 }'''; | 2387 }'''; |
| 14007 _assertPropagatedAssignedType( | 2388 assertPropagatedAssignedType( |
| 14008 code, typeProvider.dynamicType, typeProvider.intType); | 2389 code, typeProvider.dynamicType, typeProvider.intType); |
| 14009 } | 2390 } |
| 14010 | 2391 |
| 14011 void test_query() { | 2392 void test_query() { |
| 14012 Source source = addSource(r''' | 2393 Source source = addSource(r''' |
| 14013 import 'dart:html'; | 2394 import 'dart:html'; |
| 14014 | 2395 |
| 14015 main() { | 2396 main() { |
| 14016 var v1 = query('a'); | 2397 var v1 = query('a'); |
| 14017 var v2 = query('A'); | 2398 var v2 = query('A'); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14110 expect(provider.bottomType, isNotNull); | 2491 expect(provider.bottomType, isNotNull); |
| 14111 expect(provider.doubleType, same(doubleType)); | 2492 expect(provider.doubleType, same(doubleType)); |
| 14112 expect(provider.dynamicType, isNotNull); | 2493 expect(provider.dynamicType, isNotNull); |
| 14113 expect(provider.functionType, same(functionType)); | 2494 expect(provider.functionType, same(functionType)); |
| 14114 expect(provider.futureType, same(futureType)); | 2495 expect(provider.futureType, same(futureType)); |
| 14115 expect(provider.intType, same(intType)); | 2496 expect(provider.intType, same(intType)); |
| 14116 expect(provider.listType, same(listType)); | 2497 expect(provider.listType, same(listType)); |
| 14117 expect(provider.mapType, same(mapType)); | 2498 expect(provider.mapType, same(mapType)); |
| 14118 expect(provider.objectType, same(objectType)); | 2499 expect(provider.objectType, same(objectType)); |
| 14119 expect(provider.stackTraceType, same(stackTraceType)); | 2500 expect(provider.stackTraceType, same(stackTraceType)); |
| 2501 expect(provider.streamType, same(streamType)); |
| 14120 expect(provider.stringType, same(stringType)); | 2502 expect(provider.stringType, same(stringType)); |
| 14121 expect(provider.symbolType, same(symbolType)); | 2503 expect(provider.symbolType, same(symbolType)); |
| 14122 expect(provider.typeType, same(typeType)); | 2504 expect(provider.typeType, same(typeType)); |
| 14123 } | 2505 } |
| 14124 | 2506 |
| 14125 ClassElement _classElement(String typeName, InterfaceType superclassType, | 2507 ClassElement _classElement(String typeName, InterfaceType superclassType, |
| 14126 [List<String> parameterNames]) { | 2508 [List<String> parameterNames]) { |
| 14127 ClassElementImpl element = | 2509 ClassElementImpl element = |
| 14128 new ClassElementImpl.forNode(AstFactory.identifier3(typeName)); | 2510 new ClassElementImpl.forNode(AstFactory.identifier3(typeName)); |
| 14129 element.supertype = superclassType; | 2511 element.supertype = superclassType; |
| 14130 InterfaceTypeImpl type = new InterfaceTypeImpl(element); | |
| 14131 element.type = type; | |
| 14132 if (parameterNames != null) { | 2512 if (parameterNames != null) { |
| 14133 int count = parameterNames.length; | 2513 int count = parameterNames.length; |
| 14134 if (count > 0) { | 2514 if (count > 0) { |
| 14135 List<TypeParameterElementImpl> typeParameters = | 2515 List<TypeParameterElementImpl> typeParameters = |
| 14136 new List<TypeParameterElementImpl>(count); | 2516 new List<TypeParameterElementImpl>(count); |
| 14137 List<TypeParameterTypeImpl> typeArguments = | 2517 List<TypeParameterTypeImpl> typeArguments = |
| 14138 new List<TypeParameterTypeImpl>(count); | 2518 new List<TypeParameterTypeImpl>(count); |
| 14139 for (int i = 0; i < count; i++) { | 2519 for (int i = 0; i < count; i++) { |
| 14140 TypeParameterElementImpl typeParameter = | 2520 TypeParameterElementImpl typeParameter = |
| 14141 new TypeParameterElementImpl.forNode( | 2521 new TypeParameterElementImpl.forNode( |
| 14142 AstFactory.identifier3(parameterNames[i])); | 2522 AstFactory.identifier3(parameterNames[i])); |
| 14143 typeParameters[i] = typeParameter; | 2523 typeParameters[i] = typeParameter; |
| 14144 typeArguments[i] = new TypeParameterTypeImpl(typeParameter); | 2524 typeArguments[i] = new TypeParameterTypeImpl(typeParameter); |
| 14145 typeParameter.type = typeArguments[i]; | 2525 typeParameter.type = typeArguments[i]; |
| 14146 } | 2526 } |
| 14147 element.typeParameters = typeParameters; | 2527 element.typeParameters = typeParameters; |
| 14148 type.typeArguments = typeArguments; | |
| 14149 } | 2528 } |
| 14150 } | 2529 } |
| 14151 return element; | 2530 return element; |
| 14152 } | 2531 } |
| 14153 } | 2532 } |
| 14154 | 2533 |
| 14155 @reflectiveTest | 2534 @reflectiveTest |
| 14156 class TypeResolverVisitorTest extends EngineTestCase { | 2535 class TypeResolverVisitorTest { |
| 14157 /** | 2536 /** |
| 14158 * The error listener to which errors will be reported. | 2537 * The error listener to which errors will be reported. |
| 14159 */ | 2538 */ |
| 14160 GatheringErrorListener _listener; | 2539 GatheringErrorListener _listener; |
| 14161 | 2540 |
| 14162 /** | 2541 /** |
| 14163 * The object representing the information about the library in which the type
s are being | |
| 14164 * resolved. | |
| 14165 */ | |
| 14166 Library _library; | |
| 14167 | |
| 14168 /** | |
| 14169 * The type provider used to access the types. | 2542 * The type provider used to access the types. |
| 14170 */ | 2543 */ |
| 14171 TestTypeProvider _typeProvider; | 2544 TestTypeProvider _typeProvider; |
| 14172 | 2545 |
| 14173 /** | 2546 /** |
| 2547 * The library scope in which types are to be resolved. |
| 2548 */ |
| 2549 LibraryScope libraryScope; |
| 2550 |
| 2551 /** |
| 14174 * The visitor used to resolve types needed to form the type hierarchy. | 2552 * The visitor used to resolve types needed to form the type hierarchy. |
| 14175 */ | 2553 */ |
| 14176 TypeResolverVisitor _visitor; | 2554 TypeResolverVisitor _visitor; |
| 14177 | 2555 |
| 14178 void fail_visitConstructorDeclaration() { | 2556 void fail_visitConstructorDeclaration() { |
| 14179 fail("Not yet tested"); | 2557 fail("Not yet tested"); |
| 14180 _listener.assertNoErrors(); | 2558 _listener.assertNoErrors(); |
| 14181 } | 2559 } |
| 14182 | 2560 |
| 14183 void fail_visitFunctionTypeAlias() { | 2561 void fail_visitFunctionTypeAlias() { |
| 14184 fail("Not yet tested"); | 2562 fail("Not yet tested"); |
| 14185 _listener.assertNoErrors(); | 2563 _listener.assertNoErrors(); |
| 14186 } | 2564 } |
| 14187 | 2565 |
| 14188 void fail_visitVariableDeclaration() { | 2566 void fail_visitVariableDeclaration() { |
| 14189 fail("Not yet tested"); | 2567 fail("Not yet tested"); |
| 14190 ClassElement type = ElementFactory.classElement2("A"); | 2568 ClassElement type = ElementFactory.classElement2("A"); |
| 14191 VariableDeclaration node = AstFactory.variableDeclaration("a"); | 2569 VariableDeclaration node = AstFactory.variableDeclaration("a"); |
| 14192 AstFactory.variableDeclarationList(null, AstFactory.typeName(type), [node]); | 2570 AstFactory.variableDeclarationList(null, AstFactory.typeName(type), [node]); |
| 14193 //resolve(node); | 2571 //resolve(node); |
| 14194 expect(node.name.staticType, same(type.type)); | 2572 expect(node.name.staticType, same(type.type)); |
| 14195 _listener.assertNoErrors(); | 2573 _listener.assertNoErrors(); |
| 14196 } | 2574 } |
| 14197 | 2575 |
| 14198 @override | |
| 14199 void setUp() { | 2576 void setUp() { |
| 14200 _listener = new GatheringErrorListener(); | 2577 _listener = new GatheringErrorListener(); |
| 14201 InternalAnalysisContext context = AnalysisContextFactory.contextWithCore(); | 2578 MemoryResourceProvider resourceProvider = new MemoryResourceProvider(); |
| 2579 InternalAnalysisContext context = AnalysisContextFactory.contextWithCore( |
| 2580 resourceProvider: resourceProvider); |
| 14202 Source librarySource = | 2581 Source librarySource = |
| 14203 new FileBasedSource(FileUtilities2.createFile("/lib.dart")); | 2582 new FileSource(resourceProvider.getFile("/lib.dart")); |
| 14204 _library = new Library(context, _listener, librarySource); | |
| 14205 LibraryElementImpl element = new LibraryElementImpl.forNode( | 2583 LibraryElementImpl element = new LibraryElementImpl.forNode( |
| 14206 context, AstFactory.libraryIdentifier2(["lib"])); | 2584 context, AstFactory.libraryIdentifier2(["lib"])); |
| 14207 element.definingCompilationUnit = | 2585 element.definingCompilationUnit = |
| 14208 new CompilationUnitElementImpl("lib.dart"); | 2586 new CompilationUnitElementImpl("lib.dart"); |
| 14209 _library.libraryElement = element; | |
| 14210 _typeProvider = new TestTypeProvider(); | 2587 _typeProvider = new TestTypeProvider(); |
| 14211 _visitor = new TypeResolverVisitor(_library.libraryElement, librarySource, | 2588 libraryScope = new LibraryScope(element); |
| 14212 _typeProvider, _library.errorListener, | 2589 _visitor = new TypeResolverVisitor( |
| 14213 nameScope: _library.libraryScope); | 2590 element, librarySource, _typeProvider, _listener, |
| 2591 nameScope: libraryScope); |
| 14214 } | 2592 } |
| 14215 | 2593 |
| 14216 void test_visitCatchClause_exception() { | 2594 void test_visitCatchClause_exception() { |
| 14217 // catch (e) | 2595 // catch (e) |
| 14218 CatchClause clause = AstFactory.catchClause("e"); | 2596 CatchClause clause = AstFactory.catchClause("e"); |
| 14219 SimpleIdentifier exceptionParameter = clause.exceptionParameter; | 2597 SimpleIdentifier exceptionParameter = clause.exceptionParameter; |
| 14220 exceptionParameter.staticElement = | 2598 exceptionParameter.staticElement = |
| 14221 new LocalVariableElementImpl.forNode(exceptionParameter); | 2599 new LocalVariableElementImpl.forNode(exceptionParameter); |
| 14222 _resolveCatchClause(clause, _typeProvider.dynamicType, null); | 2600 _resolveCatchClause(clause, _typeProvider.dynamicType, null); |
| 14223 _listener.assertNoErrors(); | 2601 _listener.assertNoErrors(); |
| (...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14675 | 3053 |
| 14676 void test_visitTypeName_noParameters_noArguments() { | 3054 void test_visitTypeName_noParameters_noArguments() { |
| 14677 ClassElement classA = ElementFactory.classElement2("A"); | 3055 ClassElement classA = ElementFactory.classElement2("A"); |
| 14678 TypeName typeName = AstFactory.typeName(classA); | 3056 TypeName typeName = AstFactory.typeName(classA); |
| 14679 typeName.type = null; | 3057 typeName.type = null; |
| 14680 _resolveNode(typeName, [classA]); | 3058 _resolveNode(typeName, [classA]); |
| 14681 expect(typeName.type, same(classA.type)); | 3059 expect(typeName.type, same(classA.type)); |
| 14682 _listener.assertNoErrors(); | 3060 _listener.assertNoErrors(); |
| 14683 } | 3061 } |
| 14684 | 3062 |
| 3063 void test_visitTypeName_noParameters_noArguments_undefined() { |
| 3064 SimpleIdentifier id = AstFactory.identifier3("unknown") |
| 3065 ..staticElement = new _StaleElement(); |
| 3066 TypeName typeName = new TypeName(id, null); |
| 3067 _resolveNode(typeName, []); |
| 3068 expect(typeName.type, UndefinedTypeImpl.instance); |
| 3069 expect(typeName.name.staticElement, null); |
| 3070 _listener.assertErrorsWithCodes([StaticWarningCode.UNDEFINED_CLASS]); |
| 3071 } |
| 3072 |
| 14685 void test_visitTypeName_parameters_arguments() { | 3073 void test_visitTypeName_parameters_arguments() { |
| 14686 ClassElement classA = ElementFactory.classElement2("A", ["E"]); | 3074 ClassElement classA = ElementFactory.classElement2("A", ["E"]); |
| 14687 ClassElement classB = ElementFactory.classElement2("B"); | 3075 ClassElement classB = ElementFactory.classElement2("B"); |
| 14688 TypeName typeName = | 3076 TypeName typeName = |
| 14689 AstFactory.typeName(classA, [AstFactory.typeName(classB)]); | 3077 AstFactory.typeName(classA, [AstFactory.typeName(classB)]); |
| 14690 typeName.type = null; | 3078 typeName.type = null; |
| 14691 _resolveNode(typeName, [classA, classB]); | 3079 _resolveNode(typeName, [classA, classB]); |
| 14692 InterfaceType resultType = typeName.type as InterfaceType; | 3080 InterfaceType resultType = typeName.type as InterfaceType; |
| 14693 expect(resultType.element, same(classA)); | 3081 expect(resultType.element, same(classA)); |
| 14694 List<DartType> resultArguments = resultType.typeArguments; | 3082 List<DartType> resultArguments = resultType.typeArguments; |
| 14695 expect(resultArguments, hasLength(1)); | 3083 expect(resultArguments, hasLength(1)); |
| 14696 expect(resultArguments[0], same(classB.type)); | 3084 expect(resultArguments[0], same(classB.type)); |
| 14697 _listener.assertNoErrors(); | 3085 _listener.assertNoErrors(); |
| 14698 } | 3086 } |
| 14699 | 3087 |
| 14700 void test_visitTypeName_parameters_noArguments() { | 3088 void test_visitTypeName_parameters_noArguments() { |
| 14701 ClassElement classA = ElementFactory.classElement2("A", ["E"]); | 3089 ClassElement classA = ElementFactory.classElement2("A", ["E"]); |
| 14702 TypeName typeName = AstFactory.typeName(classA); | 3090 TypeName typeName = AstFactory.typeName(classA); |
| 14703 typeName.type = null; | 3091 typeName.type = null; |
| 14704 _resolveNode(typeName, [classA]); | 3092 _resolveNode(typeName, [classA]); |
| 14705 InterfaceType resultType = typeName.type as InterfaceType; | 3093 InterfaceType resultType = typeName.type as InterfaceType; |
| 14706 expect(resultType.element, same(classA)); | 3094 expect(resultType.element, same(classA)); |
| 14707 List<DartType> resultArguments = resultType.typeArguments; | 3095 List<DartType> resultArguments = resultType.typeArguments; |
| 14708 expect(resultArguments, hasLength(1)); | 3096 expect(resultArguments, hasLength(1)); |
| 14709 expect(resultArguments[0], same(DynamicTypeImpl.instance)); | 3097 expect(resultArguments[0], same(DynamicTypeImpl.instance)); |
| 14710 _listener.assertNoErrors(); | 3098 _listener.assertNoErrors(); |
| 14711 } | 3099 } |
| 14712 | 3100 |
| 3101 void test_visitTypeName_prefixed_noParameters_noArguments_undefined() { |
| 3102 SimpleIdentifier prefix = AstFactory.identifier3("unknownPrefix") |
| 3103 ..staticElement = new _StaleElement(); |
| 3104 SimpleIdentifier suffix = AstFactory.identifier3("unknownSuffix") |
| 3105 ..staticElement = new _StaleElement(); |
| 3106 TypeName typeName = |
| 3107 new TypeName(AstFactory.identifier(prefix, suffix), null); |
| 3108 _resolveNode(typeName, []); |
| 3109 expect(typeName.type, UndefinedTypeImpl.instance); |
| 3110 expect(prefix.staticElement, null); |
| 3111 expect(suffix.staticElement, null); |
| 3112 _listener.assertErrorsWithCodes([StaticWarningCode.UNDEFINED_CLASS]); |
| 3113 } |
| 3114 |
| 14713 void test_visitTypeName_void() { | 3115 void test_visitTypeName_void() { |
| 14714 ClassElement classA = ElementFactory.classElement2("A"); | 3116 ClassElement classA = ElementFactory.classElement2("A"); |
| 14715 TypeName typeName = AstFactory.typeName4("void"); | 3117 TypeName typeName = AstFactory.typeName4("void"); |
| 14716 _resolveNode(typeName, [classA]); | 3118 _resolveNode(typeName, [classA]); |
| 14717 expect(typeName.type, same(VoidTypeImpl.instance)); | 3119 expect(typeName.type, same(VoidTypeImpl.instance)); |
| 14718 _listener.assertNoErrors(); | 3120 _listener.assertNoErrors(); |
| 14719 } | 3121 } |
| 14720 | 3122 |
| 14721 /** | 3123 /** |
| 14722 * Analyze the given catch clause and assert that the types of the parameters
have been set to the | 3124 * Analyze the given catch clause and assert that the types of the parameters
have been set to the |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14763 * identifier. | 3165 * identifier. |
| 14764 * | 3166 * |
| 14765 * @param node the expression to be resolved | 3167 * @param node the expression to be resolved |
| 14766 * @param definedElements the elements that are to be defined in the scope in
which the element is | 3168 * @param definedElements the elements that are to be defined in the scope in
which the element is |
| 14767 * being resolved | 3169 * being resolved |
| 14768 * @return the element to which the expression was resolved | 3170 * @return the element to which the expression was resolved |
| 14769 */ | 3171 */ |
| 14770 void _resolveNode(AstNode node, [List<Element> definedElements]) { | 3172 void _resolveNode(AstNode node, [List<Element> definedElements]) { |
| 14771 if (definedElements != null) { | 3173 if (definedElements != null) { |
| 14772 for (Element element in definedElements) { | 3174 for (Element element in definedElements) { |
| 14773 _library.libraryScope.define(element); | 3175 libraryScope.define(element); |
| 14774 } | 3176 } |
| 14775 } | 3177 } |
| 14776 node.accept(_visitor); | 3178 node.accept(_visitor); |
| 14777 } | 3179 } |
| 14778 } | 3180 } |
| 14779 | 3181 |
| 14780 class _AnalysisContextFactory_initContextWithCore | 3182 class _RootScope extends Scope { |
| 14781 extends DirectoryBasedDartSdk { | |
| 14782 _AnalysisContextFactory_initContextWithCore(JavaFile arg0) : super(arg0); | |
| 14783 | |
| 14784 @override | 3183 @override |
| 14785 LibraryMap initialLibraryMap(bool useDart2jsPaths) { | 3184 Element internalLookup(Identifier identifier, String name, |
| 14786 LibraryMap map = new LibraryMap(); | 3185 LibraryElement referencingLibrary) => |
| 14787 _addLibrary(map, DartSdk.DART_ASYNC, false, "async.dart"); | 3186 null; |
| 14788 _addLibrary(map, DartSdk.DART_CORE, false, "core.dart"); | |
| 14789 _addLibrary(map, DartSdk.DART_HTML, false, "html_dartium.dart"); | |
| 14790 _addLibrary(map, AnalysisContextFactory._DART_MATH, false, "math.dart"); | |
| 14791 _addLibrary(map, AnalysisContextFactory._DART_INTERCEPTORS, true, | |
| 14792 "_interceptors.dart"); | |
| 14793 _addLibrary( | |
| 14794 map, AnalysisContextFactory._DART_JS_HELPER, true, "_js_helper.dart"); | |
| 14795 return map; | |
| 14796 } | |
| 14797 | |
| 14798 void _addLibrary(LibraryMap map, String uri, bool isInternal, String path) { | |
| 14799 SdkLibraryImpl library = new SdkLibraryImpl(uri); | |
| 14800 if (isInternal) { | |
| 14801 library.category = "Internal"; | |
| 14802 } | |
| 14803 library.path = path; | |
| 14804 map.setLibrary(uri, library); | |
| 14805 } | |
| 14806 } | |
| 14807 | |
| 14808 class _SimpleResolverTest_localVariable_types_invoked | |
| 14809 extends RecursiveAstVisitor<Object> { | |
| 14810 final SimpleResolverTest test; | |
| 14811 | |
| 14812 List<bool> found; | |
| 14813 | |
| 14814 List<CaughtException> thrownException; | |
| 14815 | |
| 14816 _SimpleResolverTest_localVariable_types_invoked( | |
| 14817 this.test, this.found, this.thrownException) | |
| 14818 : super(); | |
| 14819 | |
| 14820 @override | |
| 14821 Object visitSimpleIdentifier(SimpleIdentifier node) { | |
| 14822 if (node.name == "myVar" && node.parent is MethodInvocation) { | |
| 14823 try { | |
| 14824 found[0] = true; | |
| 14825 // check static type | |
| 14826 DartType staticType = node.staticType; | |
| 14827 expect(staticType, same(test.typeProvider.dynamicType)); | |
| 14828 // check propagated type | |
| 14829 FunctionType propagatedType = node.propagatedType as FunctionType; | |
| 14830 expect(propagatedType.returnType, test.typeProvider.stringType); | |
| 14831 } on AnalysisException catch (e, stackTrace) { | |
| 14832 thrownException[0] = new CaughtException(e, stackTrace); | |
| 14833 } | |
| 14834 } | |
| 14835 return null; | |
| 14836 } | |
| 14837 } | 3187 } |
| 14838 | 3188 |
| 14839 /** | 3189 /** |
| 14840 * Shared infrastructure for [StaticTypeAnalyzer2Test] and | 3190 * Represents an element left over from a previous resolver run. |
| 14841 * [StrongModeStaticTypeAnalyzer2Test]. | 3191 * |
| 3192 * A _StaleElement should always be replaced with either null or a new Element. |
| 14842 */ | 3193 */ |
| 14843 class _StaticTypeAnalyzer2TestShared extends ResolverTestCase { | 3194 class _StaleElement extends ElementImpl { |
| 14844 String testCode; | 3195 _StaleElement() : super("_StaleElement", -1); |
| 14845 Source testSource; | |
| 14846 CompilationUnit testUnit; | |
| 14847 | 3196 |
| 14848 SimpleIdentifier _findIdentifier(String search) { | 3197 @override |
| 14849 SimpleIdentifier identifier = EngineTestCase.findNode( | 3198 get kind => throw "_StaleElement's kind shouldn't be accessed"; |
| 14850 testUnit, testCode, search, (node) => node is SimpleIdentifier); | |
| 14851 return identifier; | |
| 14852 } | |
| 14853 | 3199 |
| 14854 void _resolveTestUnit(String code) { | 3200 @override |
| 14855 testCode = code; | 3201 accept(_) => throw "_StaleElement shouldn't be visited"; |
| 14856 testSource = addSource(testCode); | |
| 14857 LibraryElement library = resolve2(testSource); | |
| 14858 assertNoErrors(testSource); | |
| 14859 verify([testSource]); | |
| 14860 testUnit = resolveCompilationUnit(testSource, library); | |
| 14861 } | |
| 14862 } | 3202 } |
| OLD | NEW |