| 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 analyzer.test.generated.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/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/token.dart'; | 10 import 'package:analyzer/dart/ast/token.dart'; |
| 11 import 'package:analyzer/dart/ast/visitor.dart'; | 11 import 'package:analyzer/dart/ast/visitor.dart'; |
| 12 import 'package:analyzer/dart/element/element.dart'; | 12 import 'package:analyzer/dart/element/element.dart'; |
| 13 import 'package:analyzer/dart/element/type.dart'; | 13 import 'package:analyzer/dart/element/type.dart'; |
| 14 import 'package:analyzer/src/context/context.dart'; | 14 import 'package:analyzer/src/context/context.dart'; |
| 15 import 'package:analyzer/src/dart/element/element.dart'; | 15 import 'package:analyzer/src/dart/element/element.dart'; |
| 16 import 'package:analyzer/src/dart/element/member.dart'; | |
| 17 import 'package:analyzer/src/dart/element/type.dart'; | 16 import 'package:analyzer/src/dart/element/type.dart'; |
| 18 import 'package:analyzer/src/generated/element_resolver.dart'; | |
| 19 import 'package:analyzer/src/generated/engine.dart'; | 17 import 'package:analyzer/src/generated/engine.dart'; |
| 20 import 'package:analyzer/src/generated/error.dart'; | 18 import 'package:analyzer/src/generated/error.dart'; |
| 21 import 'package:analyzer/src/generated/java_core.dart'; | 19 import 'package:analyzer/src/generated/java_core.dart'; |
| 22 import 'package:analyzer/src/generated/java_engine.dart'; | |
| 23 import 'package:analyzer/src/generated/java_engine_io.dart'; | 20 import 'package:analyzer/src/generated/java_engine_io.dart'; |
| 24 import 'package:analyzer/src/generated/java_io.dart'; | |
| 25 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode; | 21 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode; |
| 26 import 'package:analyzer/src/generated/resolver.dart'; | 22 import 'package:analyzer/src/generated/resolver.dart'; |
| 27 import 'package:analyzer/src/generated/sdk.dart'; | |
| 28 import 'package:analyzer/src/generated/sdk_io.dart' show DirectoryBasedDartSdk; | |
| 29 import 'package:analyzer/src/generated/source_io.dart'; | 23 import 'package:analyzer/src/generated/source_io.dart'; |
| 30 import 'package:analyzer/src/generated/static_type_analyzer.dart'; | |
| 31 import 'package:analyzer/src/generated/testing/ast_factory.dart'; | 24 import 'package:analyzer/src/generated/testing/ast_factory.dart'; |
| 32 import 'package:analyzer/src/generated/testing/element_factory.dart'; | 25 import 'package:analyzer/src/generated/testing/element_factory.dart'; |
| 33 import 'package:analyzer/src/generated/testing/test_type_provider.dart'; | 26 import 'package:analyzer/src/generated/testing/test_type_provider.dart'; |
| 34 import 'package:analyzer/src/generated/testing/token_factory.dart'; | |
| 35 import 'package:analyzer/src/generated/utilities_dart.dart'; | 27 import 'package:analyzer/src/generated/utilities_dart.dart'; |
| 36 import 'package:analyzer/src/string_source.dart'; | |
| 37 import 'package:unittest/unittest.dart'; | 28 import 'package:unittest/unittest.dart'; |
| 38 | 29 |
| 39 import '../reflective_tests.dart'; | 30 import '../reflective_tests.dart'; |
| 40 import '../utils.dart'; | 31 import '../utils.dart'; |
| 32 import 'analysis_context_factory.dart'; |
| 33 import 'resolver_test_case.dart'; |
| 41 import 'test_support.dart'; | 34 import 'test_support.dart'; |
| 42 | 35 |
| 43 main() { | 36 main() { |
| 44 initializeTestEnvironment(); | 37 initializeTestEnvironment(); |
| 45 runReflectiveTests(AnalysisDeltaTest); | 38 runReflectiveTests(AnalysisDeltaTest); |
| 46 runReflectiveTests(ChangeSetTest); | 39 runReflectiveTests(ChangeSetTest); |
| 47 runReflectiveTests(CheckedModeCompileTimeErrorCodeTest); | |
| 48 runReflectiveTests(DisableAsyncTestCase); | 40 runReflectiveTests(DisableAsyncTestCase); |
| 49 runReflectiveTests(ElementResolverTest); | |
| 50 runReflectiveTests(EnclosedScopeTest); | 41 runReflectiveTests(EnclosedScopeTest); |
| 51 runReflectiveTests(ErrorResolverTest); | 42 runReflectiveTests(ErrorResolverTest); |
| 52 runReflectiveTests(HintCodeTest); | |
| 53 runReflectiveTests(InheritanceManagerTest); | |
| 54 runReflectiveTests(LibraryImportScopeTest); | 43 runReflectiveTests(LibraryImportScopeTest); |
| 55 runReflectiveTests(LibraryScopeTest); | 44 runReflectiveTests(LibraryScopeTest); |
| 56 runReflectiveTests(MemberMapTest); | 45 runReflectiveTests(MemberMapTest); |
| 57 runReflectiveTests(NonHintCodeTest); | |
| 58 runReflectiveTests(ScopeTest); | 46 runReflectiveTests(ScopeTest); |
| 59 runReflectiveTests(SimpleResolverTest); | |
| 60 runReflectiveTests(StaticTypeAnalyzerTest); | |
| 61 runReflectiveTests(StaticTypeAnalyzer2Test); | |
| 62 runReflectiveTests(StrictModeTest); | 47 runReflectiveTests(StrictModeTest); |
| 63 runReflectiveTests(StrongModeDownwardsInferenceTest); | |
| 64 runReflectiveTests(StrongModeStaticTypeAnalyzer2Test); | |
| 65 runReflectiveTests(StrongModeTypePropagationTest); | |
| 66 runReflectiveTests(SubtypeManagerTest); | 48 runReflectiveTests(SubtypeManagerTest); |
| 67 runReflectiveTests(TypeOverrideManagerTest); | 49 runReflectiveTests(TypeOverrideManagerTest); |
| 68 runReflectiveTests(TypePropagationTest); | 50 runReflectiveTests(TypePropagationTest); |
| 69 runReflectiveTests(TypeProviderImplTest); | 51 runReflectiveTests(TypeProviderImplTest); |
| 70 runReflectiveTests(TypeResolverVisitorTest); | 52 runReflectiveTests(TypeResolverVisitorTest); |
| 71 } | 53 } |
| 72 | 54 |
| 73 /** | |
| 74 * The class `AnalysisContextFactory` defines utility methods used to create ana
lysis contexts | |
| 75 * for testing purposes. | |
| 76 */ | |
| 77 class AnalysisContextFactory { | |
| 78 static String _DART_MATH = "dart:math"; | |
| 79 | |
| 80 static String _DART_INTERCEPTORS = "dart:_interceptors"; | |
| 81 | |
| 82 static String _DART_JS_HELPER = "dart:_js_helper"; | |
| 83 | |
| 84 /** | |
| 85 * Create an analysis context that has a fake core library already resolved. | |
| 86 * Return the context that was created. | |
| 87 */ | |
| 88 static InternalAnalysisContext contextWithCore() { | |
| 89 AnalysisContextForTests context = new AnalysisContextForTests(); | |
| 90 return initContextWithCore(context); | |
| 91 } | |
| 92 | |
| 93 /** | |
| 94 * Create an analysis context that uses the given [options] and has a fake | |
| 95 * core library already resolved. Return the context that was created. | |
| 96 */ | |
| 97 static InternalAnalysisContext contextWithCoreAndOptions( | |
| 98 AnalysisOptions options) { | |
| 99 AnalysisContextForTests context = new AnalysisContextForTests(); | |
| 100 context._internalSetAnalysisOptions(options); | |
| 101 return initContextWithCore(context); | |
| 102 } | |
| 103 | |
| 104 static InternalAnalysisContext contextWithCoreAndPackages( | |
| 105 Map<String, String> packages) { | |
| 106 AnalysisContextForTests context = new AnalysisContextForTests(); | |
| 107 return initContextWithCore(context, new TestPackageUriResolver(packages)); | |
| 108 } | |
| 109 | |
| 110 /** | |
| 111 * Initialize the given analysis context with a fake core library already reso
lved. | |
| 112 * | |
| 113 * @param context the context to be initialized (not `null`) | |
| 114 * @return the analysis context that was created | |
| 115 */ | |
| 116 static InternalAnalysisContext initContextWithCore( | |
| 117 InternalAnalysisContext context, | |
| 118 [UriResolver contributedResolver]) { | |
| 119 DirectoryBasedDartSdk sdk = new _AnalysisContextFactory_initContextWithCore( | |
| 120 new JavaFile("/fake/sdk"), | |
| 121 enableAsync: context.analysisOptions.enableAsync); | |
| 122 List<UriResolver> resolvers = <UriResolver>[ | |
| 123 new DartUriResolver(sdk), | |
| 124 new FileUriResolver() | |
| 125 ]; | |
| 126 if (contributedResolver != null) { | |
| 127 resolvers.add(contributedResolver); | |
| 128 } | |
| 129 SourceFactory sourceFactory = new SourceFactory(resolvers); | |
| 130 context.sourceFactory = sourceFactory; | |
| 131 AnalysisContext coreContext = sdk.context; | |
| 132 (coreContext.analysisOptions as AnalysisOptionsImpl).strongMode = | |
| 133 context.analysisOptions.strongMode; | |
| 134 // | |
| 135 // dart:core | |
| 136 // | |
| 137 TestTypeProvider provider = new TestTypeProvider(); | |
| 138 CompilationUnitElementImpl coreUnit = | |
| 139 new CompilationUnitElementImpl("core.dart"); | |
| 140 Source coreSource = sourceFactory.forUri(DartSdk.DART_CORE); | |
| 141 coreContext.setContents(coreSource, ""); | |
| 142 coreUnit.librarySource = coreUnit.source = coreSource; | |
| 143 ClassElementImpl proxyClassElement = ElementFactory.classElement2("_Proxy"); | |
| 144 proxyClassElement.constructors = <ConstructorElement>[ | |
| 145 ElementFactory.constructorElement(proxyClassElement, '', true) | |
| 146 ..isCycleFree = true | |
| 147 ..constantInitializers = <ConstructorInitializer>[] | |
| 148 ]; | |
| 149 ClassElement objectClassElement = provider.objectType.element; | |
| 150 coreUnit.types = <ClassElement>[ | |
| 151 provider.boolType.element, | |
| 152 provider.deprecatedType.element, | |
| 153 provider.doubleType.element, | |
| 154 provider.functionType.element, | |
| 155 provider.intType.element, | |
| 156 provider.iterableType.element, | |
| 157 provider.iteratorType.element, | |
| 158 provider.listType.element, | |
| 159 provider.mapType.element, | |
| 160 provider.nullType.element, | |
| 161 provider.numType.element, | |
| 162 objectClassElement, | |
| 163 proxyClassElement, | |
| 164 provider.stackTraceType.element, | |
| 165 provider.stringType.element, | |
| 166 provider.symbolType.element, | |
| 167 provider.typeType.element | |
| 168 ]; | |
| 169 coreUnit.functions = <FunctionElement>[ | |
| 170 ElementFactory.functionElement3("identical", provider.boolType.element, | |
| 171 <ClassElement>[objectClassElement, objectClassElement], null), | |
| 172 ElementFactory.functionElement3("print", VoidTypeImpl.instance.element, | |
| 173 <ClassElement>[objectClassElement], null) | |
| 174 ]; | |
| 175 TopLevelVariableElement proxyTopLevelVariableElt = ElementFactory | |
| 176 .topLevelVariableElement3("proxy", true, false, proxyClassElement.type); | |
| 177 ConstTopLevelVariableElementImpl deprecatedTopLevelVariableElt = | |
| 178 ElementFactory.topLevelVariableElement3( | |
| 179 "deprecated", true, false, provider.deprecatedType); | |
| 180 { | |
| 181 ClassElement deprecatedElement = provider.deprecatedType.element; | |
| 182 InstanceCreationExpression initializer = AstFactory | |
| 183 .instanceCreationExpression2( | |
| 184 Keyword.CONST, | |
| 185 AstFactory.typeName(deprecatedElement), | |
| 186 [AstFactory.string2('next release')]); | |
| 187 ConstructorElement constructor = deprecatedElement.constructors.single; | |
| 188 initializer.staticElement = constructor; | |
| 189 initializer.constructorName.staticElement = constructor; | |
| 190 deprecatedTopLevelVariableElt.constantInitializer = initializer; | |
| 191 } | |
| 192 coreUnit.accessors = <PropertyAccessorElement>[ | |
| 193 proxyTopLevelVariableElt.getter, | |
| 194 deprecatedTopLevelVariableElt.getter | |
| 195 ]; | |
| 196 coreUnit.topLevelVariables = <TopLevelVariableElement>[ | |
| 197 proxyTopLevelVariableElt, | |
| 198 deprecatedTopLevelVariableElt | |
| 199 ]; | |
| 200 LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode( | |
| 201 coreContext, AstFactory.libraryIdentifier2(["dart", "core"])); | |
| 202 coreLibrary.definingCompilationUnit = coreUnit; | |
| 203 // | |
| 204 // dart:async | |
| 205 // | |
| 206 Source asyncSource; | |
| 207 LibraryElementImpl asyncLibrary; | |
| 208 if (context.analysisOptions.enableAsync) { | |
| 209 asyncLibrary = new LibraryElementImpl.forNode( | |
| 210 coreContext, AstFactory.libraryIdentifier2(["dart", "async"])); | |
| 211 CompilationUnitElementImpl asyncUnit = | |
| 212 new CompilationUnitElementImpl("async.dart"); | |
| 213 asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC); | |
| 214 coreContext.setContents(asyncSource, ""); | |
| 215 asyncUnit.librarySource = asyncUnit.source = asyncSource; | |
| 216 asyncLibrary.definingCompilationUnit = asyncUnit; | |
| 217 // Future | |
| 218 ClassElementImpl futureElement = | |
| 219 ElementFactory.classElement2("Future", ["T"]); | |
| 220 futureElement.enclosingElement = asyncUnit; | |
| 221 // factory Future.value([value]) | |
| 222 ConstructorElementImpl futureConstructor = | |
| 223 ElementFactory.constructorElement2(futureElement, "value"); | |
| 224 futureConstructor.parameters = <ParameterElement>[ | |
| 225 ElementFactory.positionalParameter2("value", provider.dynamicType) | |
| 226 ]; | |
| 227 futureConstructor.factory = true; | |
| 228 futureElement.constructors = <ConstructorElement>[futureConstructor]; | |
| 229 // Future then(onValue(T value), { Function onError }); | |
| 230 TypeDefiningElement futureThenR = DynamicElementImpl.instance; | |
| 231 if (context.analysisOptions.strongMode) { | |
| 232 futureThenR = ElementFactory.typeParameterWithType('R'); | |
| 233 } | |
| 234 FunctionElementImpl thenOnValue = ElementFactory.functionElement3( | |
| 235 'onValue', futureThenR, [futureElement.typeParameters[0]], null); | |
| 236 thenOnValue.synthetic = true; | |
| 237 | |
| 238 DartType futureRType = futureElement.type.instantiate([futureThenR.type]); | |
| 239 MethodElementImpl thenMethod = ElementFactory | |
| 240 .methodElementWithParameters(futureElement, "then", futureRType, [ | |
| 241 ElementFactory.requiredParameter2("onValue", thenOnValue.type), | |
| 242 ElementFactory.namedParameter2("onError", provider.functionType) | |
| 243 ]); | |
| 244 if (!futureThenR.type.isDynamic) { | |
| 245 thenMethod.typeParameters = [futureThenR]; | |
| 246 } | |
| 247 thenOnValue.enclosingElement = thenMethod; | |
| 248 thenOnValue.type = new FunctionTypeImpl(thenOnValue); | |
| 249 (thenMethod.parameters[0] as ParameterElementImpl).type = | |
| 250 thenOnValue.type; | |
| 251 thenMethod.type = new FunctionTypeImpl(thenMethod); | |
| 252 | |
| 253 futureElement.methods = <MethodElement>[thenMethod]; | |
| 254 // Completer | |
| 255 ClassElementImpl completerElement = | |
| 256 ElementFactory.classElement2("Completer", ["T"]); | |
| 257 ConstructorElementImpl completerConstructor = | |
| 258 ElementFactory.constructorElement2(completerElement, null); | |
| 259 completerElement.constructors = <ConstructorElement>[ | |
| 260 completerConstructor | |
| 261 ]; | |
| 262 // StreamSubscription | |
| 263 ClassElementImpl streamSubscriptionElement = | |
| 264 ElementFactory.classElement2("StreamSubscription", ["T"]); | |
| 265 // Stream | |
| 266 ClassElementImpl streamElement = | |
| 267 ElementFactory.classElement2("Stream", ["T"]); | |
| 268 streamElement.constructors = <ConstructorElement>[ | |
| 269 ElementFactory.constructorElement2(streamElement, null) | |
| 270 ]; | |
| 271 DartType returnType = streamSubscriptionElement.type | |
| 272 .instantiate(streamElement.type.typeArguments); | |
| 273 FunctionElementImpl listenOnData = ElementFactory.functionElement3( | |
| 274 'onData', | |
| 275 VoidTypeImpl.instance.element, | |
| 276 <TypeDefiningElement>[streamElement.typeParameters[0]], | |
| 277 null); | |
| 278 listenOnData.synthetic = true; | |
| 279 List<DartType> parameterTypes = <DartType>[listenOnData.type,]; | |
| 280 // TODO(brianwilkerson) This is missing the optional parameters. | |
| 281 MethodElementImpl listenMethod = | |
| 282 ElementFactory.methodElement('listen', returnType, parameterTypes); | |
| 283 streamElement.methods = <MethodElement>[listenMethod]; | |
| 284 listenMethod.type = new FunctionTypeImpl(listenMethod); | |
| 285 | |
| 286 FunctionElementImpl listenParamFunction = parameterTypes[0].element; | |
| 287 listenParamFunction.enclosingElement = listenMethod; | |
| 288 listenParamFunction.type = new FunctionTypeImpl(listenParamFunction); | |
| 289 ParameterElementImpl listenParam = listenMethod.parameters[0]; | |
| 290 listenParam.type = listenParamFunction.type; | |
| 291 | |
| 292 asyncUnit.types = <ClassElement>[ | |
| 293 completerElement, | |
| 294 futureElement, | |
| 295 streamElement, | |
| 296 streamSubscriptionElement | |
| 297 ]; | |
| 298 } | |
| 299 // | |
| 300 // dart:html | |
| 301 // | |
| 302 CompilationUnitElementImpl htmlUnit = | |
| 303 new CompilationUnitElementImpl("html_dartium.dart"); | |
| 304 Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML); | |
| 305 coreContext.setContents(htmlSource, ""); | |
| 306 htmlUnit.librarySource = htmlUnit.source = htmlSource; | |
| 307 ClassElementImpl elementElement = ElementFactory.classElement2("Element"); | |
| 308 InterfaceType elementType = elementElement.type; | |
| 309 ClassElementImpl canvasElement = | |
| 310 ElementFactory.classElement("CanvasElement", elementType); | |
| 311 ClassElementImpl contextElement = | |
| 312 ElementFactory.classElement2("CanvasRenderingContext"); | |
| 313 InterfaceType contextElementType = contextElement.type; | |
| 314 ClassElementImpl context2dElement = ElementFactory.classElement( | |
| 315 "CanvasRenderingContext2D", contextElementType); | |
| 316 canvasElement.methods = <MethodElement>[ | |
| 317 ElementFactory.methodElement( | |
| 318 "getContext", contextElementType, [provider.stringType]) | |
| 319 ]; | |
| 320 canvasElement.accessors = <PropertyAccessorElement>[ | |
| 321 ElementFactory.getterElement("context2D", false, context2dElement.type) | |
| 322 ]; | |
| 323 canvasElement.fields = canvasElement.accessors | |
| 324 .map((PropertyAccessorElement accessor) => accessor.variable) | |
| 325 .toList(); | |
| 326 ClassElementImpl documentElement = | |
| 327 ElementFactory.classElement("Document", elementType); | |
| 328 ClassElementImpl htmlDocumentElement = | |
| 329 ElementFactory.classElement("HtmlDocument", documentElement.type); | |
| 330 htmlDocumentElement.methods = <MethodElement>[ | |
| 331 ElementFactory | |
| 332 .methodElement("query", elementType, <DartType>[provider.stringType]) | |
| 333 ]; | |
| 334 htmlUnit.types = <ClassElement>[ | |
| 335 ElementFactory.classElement("AnchorElement", elementType), | |
| 336 ElementFactory.classElement("BodyElement", elementType), | |
| 337 ElementFactory.classElement("ButtonElement", elementType), | |
| 338 canvasElement, | |
| 339 contextElement, | |
| 340 context2dElement, | |
| 341 ElementFactory.classElement("DivElement", elementType), | |
| 342 documentElement, | |
| 343 elementElement, | |
| 344 htmlDocumentElement, | |
| 345 ElementFactory.classElement("InputElement", elementType), | |
| 346 ElementFactory.classElement("SelectElement", elementType) | |
| 347 ]; | |
| 348 htmlUnit.functions = <FunctionElement>[ | |
| 349 ElementFactory.functionElement3("query", elementElement, | |
| 350 <ClassElement>[provider.stringType.element], ClassElement.EMPTY_LIST) | |
| 351 ]; | |
| 352 TopLevelVariableElementImpl document = | |
| 353 ElementFactory.topLevelVariableElement3( | |
| 354 "document", false, true, htmlDocumentElement.type); | |
| 355 htmlUnit.topLevelVariables = <TopLevelVariableElement>[document]; | |
| 356 htmlUnit.accessors = <PropertyAccessorElement>[document.getter]; | |
| 357 LibraryElementImpl htmlLibrary = new LibraryElementImpl.forNode( | |
| 358 coreContext, AstFactory.libraryIdentifier2(["dart", "dom", "html"])); | |
| 359 htmlLibrary.definingCompilationUnit = htmlUnit; | |
| 360 // | |
| 361 // dart:math | |
| 362 // | |
| 363 CompilationUnitElementImpl mathUnit = | |
| 364 new CompilationUnitElementImpl("math.dart"); | |
| 365 Source mathSource = sourceFactory.forUri(_DART_MATH); | |
| 366 coreContext.setContents(mathSource, ""); | |
| 367 mathUnit.librarySource = mathUnit.source = mathSource; | |
| 368 FunctionElement cosElement = ElementFactory.functionElement3( | |
| 369 "cos", | |
| 370 provider.doubleType.element, | |
| 371 <ClassElement>[provider.numType.element], | |
| 372 ClassElement.EMPTY_LIST); | |
| 373 TopLevelVariableElement ln10Element = ElementFactory | |
| 374 .topLevelVariableElement3("LN10", true, false, provider.doubleType); | |
| 375 TypeParameterElement maxT = | |
| 376 ElementFactory.typeParameterWithType('T', provider.numType); | |
| 377 FunctionElementImpl maxElement = ElementFactory.functionElement3( | |
| 378 "max", maxT, [maxT, maxT], ClassElement.EMPTY_LIST); | |
| 379 maxElement.typeParameters = [maxT]; | |
| 380 maxElement.type = new FunctionTypeImpl(maxElement); | |
| 381 TopLevelVariableElement piElement = ElementFactory.topLevelVariableElement3( | |
| 382 "PI", true, false, provider.doubleType); | |
| 383 ClassElementImpl randomElement = ElementFactory.classElement2("Random"); | |
| 384 randomElement.abstract = true; | |
| 385 ConstructorElementImpl randomConstructor = | |
| 386 ElementFactory.constructorElement2(randomElement, null); | |
| 387 randomConstructor.factory = true; | |
| 388 ParameterElementImpl seedParam = new ParameterElementImpl("seed", 0); | |
| 389 seedParam.parameterKind = ParameterKind.POSITIONAL; | |
| 390 seedParam.type = provider.intType; | |
| 391 randomConstructor.parameters = <ParameterElement>[seedParam]; | |
| 392 randomElement.constructors = <ConstructorElement>[randomConstructor]; | |
| 393 FunctionElement sinElement = ElementFactory.functionElement3( | |
| 394 "sin", | |
| 395 provider.doubleType.element, | |
| 396 <ClassElement>[provider.numType.element], | |
| 397 ClassElement.EMPTY_LIST); | |
| 398 FunctionElement sqrtElement = ElementFactory.functionElement3( | |
| 399 "sqrt", | |
| 400 provider.doubleType.element, | |
| 401 <ClassElement>[provider.numType.element], | |
| 402 ClassElement.EMPTY_LIST); | |
| 403 mathUnit.accessors = <PropertyAccessorElement>[ | |
| 404 ln10Element.getter, | |
| 405 piElement.getter | |
| 406 ]; | |
| 407 mathUnit.functions = <FunctionElement>[ | |
| 408 cosElement, | |
| 409 maxElement, | |
| 410 sinElement, | |
| 411 sqrtElement | |
| 412 ]; | |
| 413 mathUnit.topLevelVariables = <TopLevelVariableElement>[ | |
| 414 ln10Element, | |
| 415 piElement | |
| 416 ]; | |
| 417 mathUnit.types = <ClassElement>[randomElement]; | |
| 418 LibraryElementImpl mathLibrary = new LibraryElementImpl.forNode( | |
| 419 coreContext, AstFactory.libraryIdentifier2(["dart", "math"])); | |
| 420 mathLibrary.definingCompilationUnit = mathUnit; | |
| 421 // | |
| 422 // Set empty sources for the rest of the libraries. | |
| 423 // | |
| 424 Source source = sourceFactory.forUri(_DART_INTERCEPTORS); | |
| 425 coreContext.setContents(source, ""); | |
| 426 source = sourceFactory.forUri(_DART_JS_HELPER); | |
| 427 coreContext.setContents(source, ""); | |
| 428 // | |
| 429 // Record the elements. | |
| 430 // | |
| 431 HashMap<Source, LibraryElement> elementMap = | |
| 432 new HashMap<Source, LibraryElement>(); | |
| 433 elementMap[coreSource] = coreLibrary; | |
| 434 if (asyncSource != null) { | |
| 435 elementMap[asyncSource] = asyncLibrary; | |
| 436 } | |
| 437 elementMap[htmlSource] = htmlLibrary; | |
| 438 elementMap[mathSource] = mathLibrary; | |
| 439 // | |
| 440 // Set the public and export namespaces. We don't use exports in the fake | |
| 441 // core library so public and export namespaces are the same. | |
| 442 // | |
| 443 for (LibraryElementImpl library in elementMap.values) { | |
| 444 Namespace namespace = | |
| 445 new NamespaceBuilder().createPublicNamespaceForLibrary(library); | |
| 446 library.exportNamespace = namespace; | |
| 447 library.publicNamespace = namespace; | |
| 448 } | |
| 449 context.recordLibraryElements(elementMap); | |
| 450 // Create the synthetic element for `loadLibrary`. | |
| 451 for (LibraryElementImpl library in elementMap.values) { | |
| 452 library.createLoadLibraryFunction(context.typeProvider); | |
| 453 } | |
| 454 return context; | |
| 455 } | |
| 456 } | |
| 457 | |
| 458 /** | |
| 459 * An analysis context that has a fake SDK that is much smaller and faster for | |
| 460 * testing purposes. | |
| 461 */ | |
| 462 class AnalysisContextForTests extends AnalysisContextImpl { | |
| 463 @override | |
| 464 void set analysisOptions(AnalysisOptions options) { | |
| 465 AnalysisOptions currentOptions = analysisOptions; | |
| 466 bool needsRecompute = currentOptions.analyzeFunctionBodiesPredicate != | |
| 467 options.analyzeFunctionBodiesPredicate || | |
| 468 currentOptions.generateImplicitErrors != | |
| 469 options.generateImplicitErrors || | |
| 470 currentOptions.generateSdkErrors != options.generateSdkErrors || | |
| 471 currentOptions.dart2jsHint != options.dart2jsHint || | |
| 472 (currentOptions.hint && !options.hint) || | |
| 473 currentOptions.preserveComments != options.preserveComments || | |
| 474 currentOptions.enableStrictCallChecks != options.enableStrictCallChecks; | |
| 475 if (needsRecompute) { | |
| 476 fail( | |
| 477 "Cannot set options that cause the sources to be reanalyzed in a test
context"); | |
| 478 } | |
| 479 super.analysisOptions = options; | |
| 480 } | |
| 481 | |
| 482 @override | |
| 483 bool exists(Source source) => | |
| 484 super.exists(source) || sourceFactory.dartSdk.context.exists(source); | |
| 485 | |
| 486 @override | |
| 487 TimestampedData<String> getContents(Source source) { | |
| 488 if (source.isInSystemLibrary) { | |
| 489 return sourceFactory.dartSdk.context.getContents(source); | |
| 490 } | |
| 491 return super.getContents(source); | |
| 492 } | |
| 493 | |
| 494 @override | |
| 495 int getModificationStamp(Source source) { | |
| 496 if (source.isInSystemLibrary) { | |
| 497 return sourceFactory.dartSdk.context.getModificationStamp(source); | |
| 498 } | |
| 499 return super.getModificationStamp(source); | |
| 500 } | |
| 501 | |
| 502 /** | |
| 503 * Set the analysis options, even if they would force re-analysis. This method
should only be | |
| 504 * invoked before the fake SDK is initialized. | |
| 505 * | |
| 506 * @param options the analysis options to be set | |
| 507 */ | |
| 508 void _internalSetAnalysisOptions(AnalysisOptions options) { | |
| 509 super.analysisOptions = options; | |
| 510 } | |
| 511 } | |
| 512 | |
| 513 /** | |
| 514 * Helper for creating and managing single [AnalysisContext]. | |
| 515 */ | |
| 516 class AnalysisContextHelper { | |
| 517 AnalysisContext context; | |
| 518 | |
| 519 /** | |
| 520 * Creates new [AnalysisContext] using [AnalysisContextFactory]. | |
| 521 */ | |
| 522 AnalysisContextHelper([AnalysisOptionsImpl options]) { | |
| 523 if (options == null) { | |
| 524 options = new AnalysisOptionsImpl(); | |
| 525 } | |
| 526 options.cacheSize = 256; | |
| 527 context = AnalysisContextFactory.contextWithCoreAndOptions(options); | |
| 528 } | |
| 529 | |
| 530 Source addSource(String path, String code) { | |
| 531 Source source = new FileBasedSource(FileUtilities2.createFile(path)); | |
| 532 if (path.endsWith(".dart") || path.endsWith(".html")) { | |
| 533 ChangeSet changeSet = new ChangeSet(); | |
| 534 changeSet.addedSource(source); | |
| 535 context.applyChanges(changeSet); | |
| 536 } | |
| 537 context.setContents(source, code); | |
| 538 return source; | |
| 539 } | |
| 540 | |
| 541 CompilationUnitElement getDefiningUnitElement(Source source) => | |
| 542 context.getCompilationUnitElement(source, source); | |
| 543 | |
| 544 CompilationUnit resolveDefiningUnit(Source source) { | |
| 545 LibraryElement libraryElement = context.computeLibraryElement(source); | |
| 546 return context.resolveCompilationUnit(source, libraryElement); | |
| 547 } | |
| 548 | |
| 549 void runTasks() { | |
| 550 AnalysisResult result = context.performAnalysisTask(); | |
| 551 while (result.changeNotices != null) { | |
| 552 result = context.performAnalysisTask(); | |
| 553 } | |
| 554 } | |
| 555 } | |
| 556 | |
| 557 @reflectiveTest | 55 @reflectiveTest |
| 558 class AnalysisDeltaTest extends EngineTestCase { | 56 class AnalysisDeltaTest extends EngineTestCase { |
| 559 TestSource source1 = new TestSource('/1.dart'); | 57 TestSource source1 = new TestSource('/1.dart'); |
| 560 TestSource source2 = new TestSource('/2.dart'); | 58 TestSource source2 = new TestSource('/2.dart'); |
| 561 TestSource source3 = new TestSource('/3.dart'); | 59 TestSource source3 = new TestSource('/3.dart'); |
| 562 | 60 |
| 563 void test_getAddedSources() { | 61 void test_getAddedSources() { |
| 564 AnalysisDelta delta = new AnalysisDelta(); | 62 AnalysisDelta delta = new AnalysisDelta(); |
| 565 delta.setAnalysisLevel(source1, AnalysisLevel.ALL); | 63 delta.setAnalysisLevel(source1, AnalysisLevel.ALL); |
| 566 delta.setAnalysisLevel(source2, AnalysisLevel.ERRORS); | 64 delta.setAnalysisLevel(source2, AnalysisLevel.ERRORS); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 changeSet.changedRange(new TestSource(), "", 0, 0, 0); | 139 changeSet.changedRange(new TestSource(), "", 0, 0, 0); |
| 642 changeSet.deletedSource(new TestSource()); | 140 changeSet.deletedSource(new TestSource()); |
| 643 changeSet.removedSource(new TestSource()); | 141 changeSet.removedSource(new TestSource()); |
| 644 changeSet | 142 changeSet |
| 645 .removedContainer(new SourceContainer_ChangeSetTest_test_toString()); | 143 .removedContainer(new SourceContainer_ChangeSetTest_test_toString()); |
| 646 expect(changeSet.toString(), isNotNull); | 144 expect(changeSet.toString(), isNotNull); |
| 647 } | 145 } |
| 648 } | 146 } |
| 649 | 147 |
| 650 @reflectiveTest | 148 @reflectiveTest |
| 651 class CheckedModeCompileTimeErrorCodeTest extends ResolverTestCase { | |
| 652 void test_fieldFormalParameterAssignableToField_extends() { | |
| 653 // According to checked-mode type checking rules, a value of type B is | |
| 654 // assignable to a field of type A, because B extends A (and hence is a | |
| 655 // subtype of A). | |
| 656 Source source = addSource(r''' | |
| 657 class A { | |
| 658 const A(); | |
| 659 } | |
| 660 class B extends A { | |
| 661 const B(); | |
| 662 } | |
| 663 class C { | |
| 664 final A a; | |
| 665 const C(this.a); | |
| 666 } | |
| 667 var v = const C(const B());'''); | |
| 668 computeLibrarySourceErrors(source); | |
| 669 assertNoErrors(source); | |
| 670 verify([source]); | |
| 671 } | |
| 672 | |
| 673 void test_fieldFormalParameterAssignableToField_fieldType_unresolved_null() { | |
| 674 // Null always passes runtime type checks, even when the type is | |
| 675 // unresolved. | |
| 676 Source source = addSource(r''' | |
| 677 class A { | |
| 678 final Unresolved x; | |
| 679 const A(String this.x); | |
| 680 } | |
| 681 var v = const A(null);'''); | |
| 682 computeLibrarySourceErrors(source); | |
| 683 assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]); | |
| 684 verify([source]); | |
| 685 } | |
| 686 | |
| 687 void test_fieldFormalParameterAssignableToField_implements() { | |
| 688 // According to checked-mode type checking rules, a value of type B is | |
| 689 // assignable to a field of type A, because B implements A (and hence is a | |
| 690 // subtype of A). | |
| 691 Source source = addSource(r''' | |
| 692 class A {} | |
| 693 class B implements A { | |
| 694 const B(); | |
| 695 } | |
| 696 class C { | |
| 697 final A a; | |
| 698 const C(this.a); | |
| 699 } | |
| 700 var v = const C(const B());'''); | |
| 701 computeLibrarySourceErrors(source); | |
| 702 assertNoErrors(source); | |
| 703 verify([source]); | |
| 704 } | |
| 705 | |
| 706 void test_fieldFormalParameterAssignableToField_list_dynamic() { | |
| 707 // [1, 2, 3] has type List<dynamic>, which is a subtype of List<int>. | |
| 708 Source source = addSource(r''' | |
| 709 class A { | |
| 710 const A(List<int> x); | |
| 711 } | |
| 712 var x = const A(const [1, 2, 3]);'''); | |
| 713 computeLibrarySourceErrors(source); | |
| 714 assertNoErrors(source); | |
| 715 verify([source]); | |
| 716 } | |
| 717 | |
| 718 void test_fieldFormalParameterAssignableToField_list_nonDynamic() { | |
| 719 // <int>[1, 2, 3] has type List<int>, which is a subtype of List<num>. | |
| 720 Source source = addSource(r''' | |
| 721 class A { | |
| 722 const A(List<num> x); | |
| 723 } | |
| 724 var x = const A(const <int>[1, 2, 3]);'''); | |
| 725 computeLibrarySourceErrors(source); | |
| 726 assertNoErrors(source); | |
| 727 verify([source]); | |
| 728 } | |
| 729 | |
| 730 void test_fieldFormalParameterAssignableToField_map_dynamic() { | |
| 731 // {1: 2} has type Map<dynamic, dynamic>, which is a subtype of | |
| 732 // Map<int, int>. | |
| 733 Source source = addSource(r''' | |
| 734 class A { | |
| 735 const A(Map<int, int> x); | |
| 736 } | |
| 737 var x = const A(const {1: 2});'''); | |
| 738 computeLibrarySourceErrors(source); | |
| 739 assertNoErrors(source); | |
| 740 verify([source]); | |
| 741 } | |
| 742 | |
| 743 void test_fieldFormalParameterAssignableToField_map_keyDifferent() { | |
| 744 // <int, int>{1: 2} has type Map<int, int>, which is a subtype of | |
| 745 // Map<num, int>. | |
| 746 Source source = addSource(r''' | |
| 747 class A { | |
| 748 const A(Map<num, int> x); | |
| 749 } | |
| 750 var x = const A(const <int, int>{1: 2});'''); | |
| 751 computeLibrarySourceErrors(source); | |
| 752 assertNoErrors(source); | |
| 753 verify([source]); | |
| 754 } | |
| 755 | |
| 756 void test_fieldFormalParameterAssignableToField_map_valueDifferent() { | |
| 757 // <int, int>{1: 2} has type Map<int, int>, which is a subtype of | |
| 758 // Map<int, num>. | |
| 759 Source source = addSource(r''' | |
| 760 class A { | |
| 761 const A(Map<int, num> x); | |
| 762 } | |
| 763 var x = const A(const <int, int>{1: 2});'''); | |
| 764 computeLibrarySourceErrors(source); | |
| 765 assertNoErrors(source); | |
| 766 verify([source]); | |
| 767 } | |
| 768 | |
| 769 void test_fieldFormalParameterAssignableToField_notype() { | |
| 770 // If a field is declared without a type, then any value may be assigned to | |
| 771 // it. | |
| 772 Source source = addSource(r''' | |
| 773 class A { | |
| 774 final x; | |
| 775 const A(this.x); | |
| 776 } | |
| 777 var v = const A(5);'''); | |
| 778 computeLibrarySourceErrors(source); | |
| 779 assertNoErrors(source); | |
| 780 verify([source]); | |
| 781 } | |
| 782 | |
| 783 void test_fieldFormalParameterAssignableToField_null() { | |
| 784 // Null is assignable to anything. | |
| 785 Source source = addSource(r''' | |
| 786 class A { | |
| 787 final int x; | |
| 788 const A(this.x); | |
| 789 } | |
| 790 var v = const A(null);'''); | |
| 791 computeLibrarySourceErrors(source); | |
| 792 assertNoErrors(source); | |
| 793 verify([source]); | |
| 794 } | |
| 795 | |
| 796 void test_fieldFormalParameterAssignableToField_typedef() { | |
| 797 // foo has the runtime type dynamic -> dynamic, so it should be assignable | |
| 798 // to A.f. | |
| 799 Source source = addSource(r''' | |
| 800 typedef String Int2String(int x); | |
| 801 class A { | |
| 802 final Int2String f; | |
| 803 const A(this.f); | |
| 804 } | |
| 805 foo(x) => 1; | |
| 806 var v = const A(foo);'''); | |
| 807 computeLibrarySourceErrors(source); | |
| 808 assertNoErrors(source); | |
| 809 verify([source]); | |
| 810 } | |
| 811 | |
| 812 void test_fieldFormalParameterAssignableToField_typeSubstitution() { | |
| 813 // foo has the runtime type dynamic -> dynamic, so it should be assignable | |
| 814 // to A.f. | |
| 815 Source source = addSource(r''' | |
| 816 class A<T> { | |
| 817 final T x; | |
| 818 const A(this.x); | |
| 819 } | |
| 820 var v = const A<int>(3);'''); | |
| 821 computeLibrarySourceErrors(source); | |
| 822 assertNoErrors(source); | |
| 823 verify([source]); | |
| 824 } | |
| 825 | |
| 826 void test_fieldFormalParameterNotAssignableToField() { | |
| 827 Source source = addSource(r''' | |
| 828 class A { | |
| 829 final int x; | |
| 830 const A(this.x); | |
| 831 } | |
| 832 var v = const A('foo');'''); | |
| 833 computeLibrarySourceErrors(source); | |
| 834 assertErrors(source, [ | |
| 835 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, | |
| 836 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE | |
| 837 ]); | |
| 838 verify([source]); | |
| 839 } | |
| 840 | |
| 841 void test_fieldFormalParameterNotAssignableToField_extends() { | |
| 842 // According to checked-mode type checking rules, a value of type A is not | |
| 843 // assignable to a field of type B, because B extends A (the subtyping | |
| 844 // relationship is in the wrong direction). | |
| 845 Source source = addSource(r''' | |
| 846 class A { | |
| 847 const A(); | |
| 848 } | |
| 849 class B extends A { | |
| 850 const B(); | |
| 851 } | |
| 852 class C { | |
| 853 final B b; | |
| 854 const C(this.b); | |
| 855 } | |
| 856 var v = const C(const A());'''); | |
| 857 computeLibrarySourceErrors(source); | |
| 858 assertErrors(source, [ | |
| 859 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH | |
| 860 ]); | |
| 861 verify([source]); | |
| 862 } | |
| 863 | |
| 864 void test_fieldFormalParameterNotAssignableToField_fieldType() { | |
| 865 Source source = addSource(r''' | |
| 866 class A { | |
| 867 final int x; | |
| 868 const A(String this.x); | |
| 869 } | |
| 870 var v = const A('foo');'''); | |
| 871 computeLibrarySourceErrors(source); | |
| 872 assertErrors(source, [ | |
| 873 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, | |
| 874 StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE | |
| 875 ]); | |
| 876 verify([source]); | |
| 877 } | |
| 878 | |
| 879 void test_fieldFormalParameterNotAssignableToField_fieldType_unresolved() { | |
| 880 Source source = addSource(r''' | |
| 881 class A { | |
| 882 final Unresolved x; | |
| 883 const A(String this.x); | |
| 884 } | |
| 885 var v = const A('foo');'''); | |
| 886 computeLibrarySourceErrors(source); | |
| 887 assertErrors(source, [ | |
| 888 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, | |
| 889 StaticWarningCode.UNDEFINED_CLASS | |
| 890 ]); | |
| 891 verify([source]); | |
| 892 } | |
| 893 | |
| 894 void test_fieldFormalParameterNotAssignableToField_implements() { | |
| 895 // According to checked-mode type checking rules, a value of type A is not | |
| 896 // assignable to a field of type B, because B implements A (the subtyping | |
| 897 // relationship is in the wrong direction). | |
| 898 Source source = addSource(r''' | |
| 899 class A { | |
| 900 const A(); | |
| 901 } | |
| 902 class B implements A {} | |
| 903 class C { | |
| 904 final B b; | |
| 905 const C(this.b); | |
| 906 } | |
| 907 var v = const C(const A());'''); | |
| 908 computeLibrarySourceErrors(source); | |
| 909 assertErrors(source, [ | |
| 910 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH | |
| 911 ]); | |
| 912 verify([source]); | |
| 913 } | |
| 914 | |
| 915 void test_fieldFormalParameterNotAssignableToField_list() { | |
| 916 // <num>[1, 2, 3] has type List<num>, which is not a subtype of List<int>. | |
| 917 Source source = addSource(r''' | |
| 918 class A { | |
| 919 const A(List<int> x); | |
| 920 } | |
| 921 var x = const A(const <num>[1, 2, 3]);'''); | |
| 922 computeLibrarySourceErrors(source); | |
| 923 assertErrors(source, [ | |
| 924 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH | |
| 925 ]); | |
| 926 verify([source]); | |
| 927 } | |
| 928 | |
| 929 void test_fieldFormalParameterNotAssignableToField_map_keyMismatch() { | |
| 930 // <num, int>{1: 2} has type Map<num, int>, which is not a subtype of | |
| 931 // Map<int, int>. | |
| 932 Source source = addSource(r''' | |
| 933 class A { | |
| 934 const A(Map<int, int> x); | |
| 935 } | |
| 936 var x = const A(const <num, int>{1: 2});'''); | |
| 937 computeLibrarySourceErrors(source); | |
| 938 assertErrors(source, [ | |
| 939 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH | |
| 940 ]); | |
| 941 verify([source]); | |
| 942 } | |
| 943 | |
| 944 void test_fieldFormalParameterNotAssignableToField_map_valueMismatch() { | |
| 945 // <int, num>{1: 2} has type Map<int, num>, which is not a subtype of | |
| 946 // Map<int, int>. | |
| 947 Source source = addSource(r''' | |
| 948 class A { | |
| 949 const A(Map<int, int> x); | |
| 950 } | |
| 951 var x = const A(const <int, num>{1: 2});'''); | |
| 952 computeLibrarySourceErrors(source); | |
| 953 assertErrors(source, [ | |
| 954 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH | |
| 955 ]); | |
| 956 verify([source]); | |
| 957 } | |
| 958 | |
| 959 void test_fieldFormalParameterNotAssignableToField_optional() { | |
| 960 Source source = addSource(r''' | |
| 961 class A { | |
| 962 final int x; | |
| 963 const A([this.x = 'foo']); | |
| 964 } | |
| 965 var v = const A();'''); | |
| 966 computeLibrarySourceErrors(source); | |
| 967 assertErrors(source, [ | |
| 968 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, | |
| 969 StaticTypeWarningCode.INVALID_ASSIGNMENT | |
| 970 ]); | |
| 971 verify([source]); | |
| 972 } | |
| 973 | |
| 974 void test_fieldFormalParameterNotAssignableToField_typedef() { | |
| 975 // foo has the runtime type String -> int, so it should not be assignable | |
| 976 // to A.f (A.f requires it to be int -> String). | |
| 977 Source source = addSource(r''' | |
| 978 typedef String Int2String(int x); | |
| 979 class A { | |
| 980 final Int2String f; | |
| 981 const A(this.f); | |
| 982 } | |
| 983 int foo(String x) => 1; | |
| 984 var v = const A(foo);'''); | |
| 985 computeLibrarySourceErrors(source); | |
| 986 assertErrors(source, [ | |
| 987 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, | |
| 988 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE | |
| 989 ]); | |
| 990 verify([source]); | |
| 991 } | |
| 992 | |
| 993 void test_fieldInitializerNotAssignable() { | |
| 994 Source source = addSource(r''' | |
| 995 class A { | |
| 996 final int x; | |
| 997 const A() : x = ''; | |
| 998 }'''); | |
| 999 computeLibrarySourceErrors(source); | |
| 1000 assertErrors(source, [ | |
| 1001 CheckedModeCompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE, | |
| 1002 StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE | |
| 1003 ]); | |
| 1004 verify([source]); | |
| 1005 } | |
| 1006 | |
| 1007 void test_fieldTypeMismatch() { | |
| 1008 Source source = addSource(r''' | |
| 1009 class A { | |
| 1010 const A(x) : y = x; | |
| 1011 final int y; | |
| 1012 } | |
| 1013 var v = const A('foo');'''); | |
| 1014 computeLibrarySourceErrors(source); | |
| 1015 assertErrors(source, [ | |
| 1016 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH | |
| 1017 ]); | |
| 1018 verify([source]); | |
| 1019 } | |
| 1020 | |
| 1021 void test_fieldTypeMismatch_generic() { | |
| 1022 Source source = addSource(r''' | |
| 1023 class C<T> { | |
| 1024 final T x = y; | |
| 1025 const C(); | |
| 1026 } | |
| 1027 const int y = 1; | |
| 1028 var v = const C<String>(); | |
| 1029 '''); | |
| 1030 computeLibrarySourceErrors(source); | |
| 1031 assertErrors(source, [ | |
| 1032 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH, | |
| 1033 StaticTypeWarningCode.INVALID_ASSIGNMENT | |
| 1034 ]); | |
| 1035 verify([source]); | |
| 1036 } | |
| 1037 | |
| 1038 void test_fieldTypeMismatch_unresolved() { | |
| 1039 Source source = addSource(r''' | |
| 1040 class A { | |
| 1041 const A(x) : y = x; | |
| 1042 final Unresolved y; | |
| 1043 } | |
| 1044 var v = const A('foo');'''); | |
| 1045 computeLibrarySourceErrors(source); | |
| 1046 assertErrors(source, [ | |
| 1047 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH, | |
| 1048 StaticWarningCode.UNDEFINED_CLASS | |
| 1049 ]); | |
| 1050 verify([source]); | |
| 1051 } | |
| 1052 | |
| 1053 void test_fieldTypeOk_generic() { | |
| 1054 Source source = addSource(r''' | |
| 1055 class C<T> { | |
| 1056 final T x = y; | |
| 1057 const C(); | |
| 1058 } | |
| 1059 const int y = 1; | |
| 1060 var v = const C<int>(); | |
| 1061 '''); | |
| 1062 computeLibrarySourceErrors(source); | |
| 1063 assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]); | |
| 1064 verify([source]); | |
| 1065 } | |
| 1066 | |
| 1067 void test_fieldTypeOk_null() { | |
| 1068 Source source = addSource(r''' | |
| 1069 class A { | |
| 1070 const A(x) : y = x; | |
| 1071 final int y; | |
| 1072 } | |
| 1073 var v = const A(null);'''); | |
| 1074 computeLibrarySourceErrors(source); | |
| 1075 assertNoErrors(source); | |
| 1076 verify([source]); | |
| 1077 } | |
| 1078 | |
| 1079 void test_fieldTypeOk_unresolved_null() { | |
| 1080 // Null always passes runtime type checks, even when the type is | |
| 1081 // unresolved. | |
| 1082 Source source = addSource(r''' | |
| 1083 class A { | |
| 1084 const A(x) : y = x; | |
| 1085 final Unresolved y; | |
| 1086 } | |
| 1087 var v = const A(null);'''); | |
| 1088 computeLibrarySourceErrors(source); | |
| 1089 assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]); | |
| 1090 verify([source]); | |
| 1091 } | |
| 1092 | |
| 1093 void test_listElementTypeNotAssignable() { | |
| 1094 Source source = addSource("var v = const <String> [42];"); | |
| 1095 computeLibrarySourceErrors(source); | |
| 1096 assertErrors(source, [ | |
| 1097 CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE, | |
| 1098 StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE | |
| 1099 ]); | |
| 1100 verify([source]); | |
| 1101 } | |
| 1102 | |
| 1103 void test_mapKeyTypeNotAssignable() { | |
| 1104 Source source = addSource("var v = const <String, int > {1 : 2};"); | |
| 1105 computeLibrarySourceErrors(source); | |
| 1106 assertErrors(source, [ | |
| 1107 CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE, | |
| 1108 StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE | |
| 1109 ]); | |
| 1110 verify([source]); | |
| 1111 } | |
| 1112 | |
| 1113 void test_mapValueTypeNotAssignable() { | |
| 1114 Source source = addSource("var v = const <String, String> {'a' : 2};"); | |
| 1115 computeLibrarySourceErrors(source); | |
| 1116 assertErrors(source, [ | |
| 1117 CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE, | |
| 1118 StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE | |
| 1119 ]); | |
| 1120 verify([source]); | |
| 1121 } | |
| 1122 | |
| 1123 void test_parameterAssignable_null() { | |
| 1124 // Null is assignable to anything. | |
| 1125 Source source = addSource(r''' | |
| 1126 class A { | |
| 1127 const A(int x); | |
| 1128 } | |
| 1129 var v = const A(null);'''); | |
| 1130 computeLibrarySourceErrors(source); | |
| 1131 assertNoErrors(source); | |
| 1132 verify([source]); | |
| 1133 } | |
| 1134 | |
| 1135 void test_parameterAssignable_typeSubstitution() { | |
| 1136 Source source = addSource(r''' | |
| 1137 class A<T> { | |
| 1138 const A(T x); | |
| 1139 } | |
| 1140 var v = const A<int>(3);'''); | |
| 1141 computeLibrarySourceErrors(source); | |
| 1142 assertNoErrors(source); | |
| 1143 verify([source]); | |
| 1144 } | |
| 1145 | |
| 1146 void test_parameterAssignable_undefined_null() { | |
| 1147 // Null always passes runtime type checks, even when the type is | |
| 1148 // unresolved. | |
| 1149 Source source = addSource(r''' | |
| 1150 class A { | |
| 1151 const A(Unresolved x); | |
| 1152 } | |
| 1153 var v = const A(null);'''); | |
| 1154 computeLibrarySourceErrors(source); | |
| 1155 assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]); | |
| 1156 verify([source]); | |
| 1157 } | |
| 1158 | |
| 1159 void test_parameterNotAssignable() { | |
| 1160 Source source = addSource(r''' | |
| 1161 class A { | |
| 1162 const A(int x); | |
| 1163 } | |
| 1164 var v = const A('foo');'''); | |
| 1165 computeLibrarySourceErrors(source); | |
| 1166 assertErrors(source, [ | |
| 1167 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, | |
| 1168 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE | |
| 1169 ]); | |
| 1170 verify([source]); | |
| 1171 } | |
| 1172 | |
| 1173 void test_parameterNotAssignable_typeSubstitution() { | |
| 1174 Source source = addSource(r''' | |
| 1175 class A<T> { | |
| 1176 const A(T x); | |
| 1177 } | |
| 1178 var v = const A<int>('foo');'''); | |
| 1179 computeLibrarySourceErrors(source); | |
| 1180 assertErrors(source, [ | |
| 1181 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, | |
| 1182 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE | |
| 1183 ]); | |
| 1184 verify([source]); | |
| 1185 } | |
| 1186 | |
| 1187 void test_parameterNotAssignable_undefined() { | |
| 1188 Source source = addSource(r''' | |
| 1189 class A { | |
| 1190 const A(Unresolved x); | |
| 1191 } | |
| 1192 var v = const A('foo');'''); | |
| 1193 computeLibrarySourceErrors(source); | |
| 1194 assertErrors(source, [ | |
| 1195 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, | |
| 1196 StaticWarningCode.UNDEFINED_CLASS | |
| 1197 ]); | |
| 1198 verify([source]); | |
| 1199 } | |
| 1200 | |
| 1201 void test_redirectingConstructor_paramTypeMismatch() { | |
| 1202 Source source = addSource(r''' | |
| 1203 class A { | |
| 1204 const A.a1(x) : this.a2(x); | |
| 1205 const A.a2(String x); | |
| 1206 } | |
| 1207 var v = const A.a1(0);'''); | |
| 1208 computeLibrarySourceErrors(source); | |
| 1209 assertErrors(source, [ | |
| 1210 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH | |
| 1211 ]); | |
| 1212 verify([source]); | |
| 1213 } | |
| 1214 | |
| 1215 void test_topLevelVarAssignable_null() { | |
| 1216 Source source = addSource("const int x = null;"); | |
| 1217 computeLibrarySourceErrors(source); | |
| 1218 assertNoErrors(source); | |
| 1219 verify([source]); | |
| 1220 } | |
| 1221 | |
| 1222 void test_topLevelVarAssignable_undefined_null() { | |
| 1223 // Null always passes runtime type checks, even when the type is | |
| 1224 // unresolved. | |
| 1225 Source source = addSource("const Unresolved x = null;"); | |
| 1226 computeLibrarySourceErrors(source); | |
| 1227 assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]); | |
| 1228 verify([source]); | |
| 1229 } | |
| 1230 | |
| 1231 void test_topLevelVarNotAssignable() { | |
| 1232 Source source = addSource("const int x = 'foo';"); | |
| 1233 computeLibrarySourceErrors(source); | |
| 1234 assertErrors(source, [ | |
| 1235 CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, | |
| 1236 StaticTypeWarningCode.INVALID_ASSIGNMENT | |
| 1237 ]); | |
| 1238 verify([source]); | |
| 1239 } | |
| 1240 | |
| 1241 void test_topLevelVarNotAssignable_undefined() { | |
| 1242 Source source = addSource("const Unresolved x = 'foo';"); | |
| 1243 computeLibrarySourceErrors(source); | |
| 1244 assertErrors(source, [ | |
| 1245 CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, | |
| 1246 StaticWarningCode.UNDEFINED_CLASS | |
| 1247 ]); | |
| 1248 verify([source]); | |
| 1249 } | |
| 1250 } | |
| 1251 | |
| 1252 @reflectiveTest | |
| 1253 class DisableAsyncTestCase extends ResolverTestCase { | 149 class DisableAsyncTestCase extends ResolverTestCase { |
| 1254 @override | 150 @override |
| 1255 void setUp() { | 151 void setUp() { |
| 1256 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); | 152 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); |
| 1257 options.enableAsync = false; | 153 options.enableAsync = false; |
| 1258 resetWithOptions(options); | 154 resetWithOptions(options); |
| 1259 } | 155 } |
| 1260 | 156 |
| 1261 void test_resolve() { | 157 void test_resolve() { |
| 1262 Source source = addSource(r''' | 158 Source source = addSource(r''' |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1288 StaticWarningCode.UNDEFINED_CLASS, | 184 StaticWarningCode.UNDEFINED_CLASS, |
| 1289 StaticWarningCode.UNDEFINED_CLASS, | 185 StaticWarningCode.UNDEFINED_CLASS, |
| 1290 StaticWarningCode.UNDEFINED_CLASS, | 186 StaticWarningCode.UNDEFINED_CLASS, |
| 1291 StaticWarningCode.UNDEFINED_CLASS, | 187 StaticWarningCode.UNDEFINED_CLASS, |
| 1292 ParserErrorCode.ASYNC_NOT_SUPPORTED | 188 ParserErrorCode.ASYNC_NOT_SUPPORTED |
| 1293 ]); | 189 ]); |
| 1294 } | 190 } |
| 1295 } | 191 } |
| 1296 | 192 |
| 1297 @reflectiveTest | 193 @reflectiveTest |
| 1298 class ElementResolverTest extends EngineTestCase { | |
| 1299 /** | |
| 1300 * The error listener to which errors will be reported. | |
| 1301 */ | |
| 1302 GatheringErrorListener _listener; | |
| 1303 | |
| 1304 /** | |
| 1305 * The type provider used to access the types. | |
| 1306 */ | |
| 1307 TestTypeProvider _typeProvider; | |
| 1308 | |
| 1309 /** | |
| 1310 * The library containing the code being resolved. | |
| 1311 */ | |
| 1312 LibraryElementImpl _definingLibrary; | |
| 1313 | |
| 1314 /** | |
| 1315 * The resolver visitor that maintains the state for the resolver. | |
| 1316 */ | |
| 1317 ResolverVisitor _visitor; | |
| 1318 | |
| 1319 /** | |
| 1320 * The resolver being used to resolve the test cases. | |
| 1321 */ | |
| 1322 ElementResolver _resolver; | |
| 1323 | |
| 1324 void fail_visitExportDirective_combinators() { | |
| 1325 fail("Not yet tested"); | |
| 1326 // Need to set up the exported library so that the identifier can be | |
| 1327 // resolved. | |
| 1328 ExportDirective directive = AstFactory.exportDirective2(null, [ | |
| 1329 AstFactory.hideCombinator2(["A"]) | |
| 1330 ]); | |
| 1331 _resolveNode(directive); | |
| 1332 _listener.assertNoErrors(); | |
| 1333 } | |
| 1334 | |
| 1335 void fail_visitFunctionExpressionInvocation() { | |
| 1336 fail("Not yet tested"); | |
| 1337 _listener.assertNoErrors(); | |
| 1338 } | |
| 1339 | |
| 1340 void fail_visitImportDirective_combinators_noPrefix() { | |
| 1341 fail("Not yet tested"); | |
| 1342 // Need to set up the imported library so that the identifier can be | |
| 1343 // resolved. | |
| 1344 ImportDirective directive = AstFactory.importDirective3(null, null, [ | |
| 1345 AstFactory.showCombinator2(["A"]) | |
| 1346 ]); | |
| 1347 _resolveNode(directive); | |
| 1348 _listener.assertNoErrors(); | |
| 1349 } | |
| 1350 | |
| 1351 void fail_visitImportDirective_combinators_prefix() { | |
| 1352 fail("Not yet tested"); | |
| 1353 // Need to set up the imported library so that the identifiers can be | |
| 1354 // resolved. | |
| 1355 String prefixName = "p"; | |
| 1356 _definingLibrary.imports = <ImportElement>[ | |
| 1357 ElementFactory.importFor(null, ElementFactory.prefix(prefixName)) | |
| 1358 ]; | |
| 1359 ImportDirective directive = AstFactory.importDirective3(null, prefixName, [ | |
| 1360 AstFactory.showCombinator2(["A"]), | |
| 1361 AstFactory.hideCombinator2(["B"]) | |
| 1362 ]); | |
| 1363 _resolveNode(directive); | |
| 1364 _listener.assertNoErrors(); | |
| 1365 } | |
| 1366 | |
| 1367 void fail_visitRedirectingConstructorInvocation() { | |
| 1368 fail("Not yet tested"); | |
| 1369 _listener.assertNoErrors(); | |
| 1370 } | |
| 1371 | |
| 1372 @override | |
| 1373 void setUp() { | |
| 1374 super.setUp(); | |
| 1375 _listener = new GatheringErrorListener(); | |
| 1376 _typeProvider = new TestTypeProvider(); | |
| 1377 _resolver = _createResolver(); | |
| 1378 } | |
| 1379 | |
| 1380 void test_lookUpMethodInInterfaces() { | |
| 1381 InterfaceType intType = _typeProvider.intType; | |
| 1382 // | |
| 1383 // abstract class A { int operator[](int index); } | |
| 1384 // | |
| 1385 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1386 MethodElement operator = | |
| 1387 ElementFactory.methodElement("[]", intType, [intType]); | |
| 1388 classA.methods = <MethodElement>[operator]; | |
| 1389 // | |
| 1390 // class B implements A {} | |
| 1391 // | |
| 1392 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 1393 classB.interfaces = <InterfaceType>[classA.type]; | |
| 1394 // | |
| 1395 // class C extends Object with B {} | |
| 1396 // | |
| 1397 ClassElementImpl classC = ElementFactory.classElement2("C"); | |
| 1398 classC.mixins = <InterfaceType>[classB.type]; | |
| 1399 // | |
| 1400 // class D extends C {} | |
| 1401 // | |
| 1402 ClassElementImpl classD = ElementFactory.classElement("D", classC.type); | |
| 1403 // | |
| 1404 // D a; | |
| 1405 // a[i]; | |
| 1406 // | |
| 1407 SimpleIdentifier array = AstFactory.identifier3("a"); | |
| 1408 array.staticType = classD.type; | |
| 1409 IndexExpression expression = | |
| 1410 AstFactory.indexExpression(array, AstFactory.identifier3("i")); | |
| 1411 expect(_resolveIndexExpression(expression), same(operator)); | |
| 1412 _listener.assertNoErrors(); | |
| 1413 } | |
| 1414 | |
| 1415 void test_visitAssignmentExpression_compound() { | |
| 1416 InterfaceType intType = _typeProvider.intType; | |
| 1417 SimpleIdentifier leftHandSide = AstFactory.identifier3("a"); | |
| 1418 leftHandSide.staticType = intType; | |
| 1419 AssignmentExpression assignment = AstFactory.assignmentExpression( | |
| 1420 leftHandSide, TokenType.PLUS_EQ, AstFactory.integer(1)); | |
| 1421 _resolveNode(assignment); | |
| 1422 expect( | |
| 1423 assignment.staticElement, same(getMethod(_typeProvider.numType, "+"))); | |
| 1424 _listener.assertNoErrors(); | |
| 1425 } | |
| 1426 | |
| 1427 void test_visitAssignmentExpression_simple() { | |
| 1428 AssignmentExpression expression = AstFactory.assignmentExpression( | |
| 1429 AstFactory.identifier3("x"), TokenType.EQ, AstFactory.integer(0)); | |
| 1430 _resolveNode(expression); | |
| 1431 expect(expression.staticElement, isNull); | |
| 1432 _listener.assertNoErrors(); | |
| 1433 } | |
| 1434 | |
| 1435 void test_visitBinaryExpression_bangEq() { | |
| 1436 // String i; | |
| 1437 // var j; | |
| 1438 // i == j | |
| 1439 InterfaceType stringType = _typeProvider.stringType; | |
| 1440 SimpleIdentifier left = AstFactory.identifier3("i"); | |
| 1441 left.staticType = stringType; | |
| 1442 BinaryExpression expression = AstFactory.binaryExpression( | |
| 1443 left, TokenType.BANG_EQ, AstFactory.identifier3("j")); | |
| 1444 _resolveNode(expression); | |
| 1445 var stringElement = stringType.element; | |
| 1446 expect(expression.staticElement, isNotNull); | |
| 1447 expect( | |
| 1448 expression.staticElement, | |
| 1449 stringElement.lookUpMethod( | |
| 1450 TokenType.EQ_EQ.lexeme, stringElement.library)); | |
| 1451 expect(expression.propagatedElement, isNull); | |
| 1452 _listener.assertNoErrors(); | |
| 1453 } | |
| 1454 | |
| 1455 void test_visitBinaryExpression_eq() { | |
| 1456 // String i; | |
| 1457 // var j; | |
| 1458 // i == j | |
| 1459 InterfaceType stringType = _typeProvider.stringType; | |
| 1460 SimpleIdentifier left = AstFactory.identifier3("i"); | |
| 1461 left.staticType = stringType; | |
| 1462 BinaryExpression expression = AstFactory.binaryExpression( | |
| 1463 left, TokenType.EQ_EQ, AstFactory.identifier3("j")); | |
| 1464 _resolveNode(expression); | |
| 1465 var stringElement = stringType.element; | |
| 1466 expect( | |
| 1467 expression.staticElement, | |
| 1468 stringElement.lookUpMethod( | |
| 1469 TokenType.EQ_EQ.lexeme, stringElement.library)); | |
| 1470 expect(expression.propagatedElement, isNull); | |
| 1471 _listener.assertNoErrors(); | |
| 1472 } | |
| 1473 | |
| 1474 void test_visitBinaryExpression_plus() { | |
| 1475 // num i; | |
| 1476 // var j; | |
| 1477 // i + j | |
| 1478 InterfaceType numType = _typeProvider.numType; | |
| 1479 SimpleIdentifier left = AstFactory.identifier3("i"); | |
| 1480 left.staticType = numType; | |
| 1481 BinaryExpression expression = AstFactory.binaryExpression( | |
| 1482 left, TokenType.PLUS, AstFactory.identifier3("j")); | |
| 1483 _resolveNode(expression); | |
| 1484 expect(expression.staticElement, getMethod(numType, "+")); | |
| 1485 expect(expression.propagatedElement, isNull); | |
| 1486 _listener.assertNoErrors(); | |
| 1487 } | |
| 1488 | |
| 1489 void test_visitBinaryExpression_plus_propagatedElement() { | |
| 1490 // var i = 1; | |
| 1491 // var j; | |
| 1492 // i + j | |
| 1493 InterfaceType numType = _typeProvider.numType; | |
| 1494 SimpleIdentifier left = AstFactory.identifier3("i"); | |
| 1495 left.propagatedType = numType; | |
| 1496 BinaryExpression expression = AstFactory.binaryExpression( | |
| 1497 left, TokenType.PLUS, AstFactory.identifier3("j")); | |
| 1498 _resolveNode(expression); | |
| 1499 expect(expression.staticElement, isNull); | |
| 1500 expect(expression.propagatedElement, getMethod(numType, "+")); | |
| 1501 _listener.assertNoErrors(); | |
| 1502 } | |
| 1503 | |
| 1504 void test_visitBreakStatement_withLabel() { | |
| 1505 // loop: while (true) { | |
| 1506 // break loop; | |
| 1507 // } | |
| 1508 String label = "loop"; | |
| 1509 LabelElementImpl labelElement = new LabelElementImpl.forNode( | |
| 1510 AstFactory.identifier3(label), false, false); | |
| 1511 BreakStatement breakStatement = AstFactory.breakStatement2(label); | |
| 1512 Expression condition = AstFactory.booleanLiteral(true); | |
| 1513 WhileStatement whileStatement = | |
| 1514 AstFactory.whileStatement(condition, breakStatement); | |
| 1515 expect(_resolveBreak(breakStatement, labelElement, whileStatement), | |
| 1516 same(labelElement)); | |
| 1517 expect(breakStatement.target, same(whileStatement)); | |
| 1518 _listener.assertNoErrors(); | |
| 1519 } | |
| 1520 | |
| 1521 void test_visitBreakStatement_withoutLabel() { | |
| 1522 BreakStatement statement = AstFactory.breakStatement(); | |
| 1523 _resolveStatement(statement, null, null); | |
| 1524 _listener.assertNoErrors(); | |
| 1525 } | |
| 1526 | |
| 1527 void test_visitCommentReference_prefixedIdentifier_class_getter() { | |
| 1528 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1529 // set accessors | |
| 1530 String propName = "p"; | |
| 1531 PropertyAccessorElement getter = | |
| 1532 ElementFactory.getterElement(propName, false, _typeProvider.intType); | |
| 1533 PropertyAccessorElement setter = | |
| 1534 ElementFactory.setterElement(propName, false, _typeProvider.intType); | |
| 1535 classA.accessors = <PropertyAccessorElement>[getter, setter]; | |
| 1536 // set name scope | |
| 1537 _visitor.nameScope = new EnclosedScope(null) | |
| 1538 ..defineNameWithoutChecking('A', classA); | |
| 1539 // prepare "A.p" | |
| 1540 PrefixedIdentifier prefixed = AstFactory.identifier5('A', 'p'); | |
| 1541 CommentReference commentReference = new CommentReference(null, prefixed); | |
| 1542 // resolve | |
| 1543 _resolveNode(commentReference); | |
| 1544 expect(prefixed.prefix.staticElement, classA); | |
| 1545 expect(prefixed.identifier.staticElement, getter); | |
| 1546 _listener.assertNoErrors(); | |
| 1547 } | |
| 1548 | |
| 1549 void test_visitCommentReference_prefixedIdentifier_class_method() { | |
| 1550 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1551 // set method | |
| 1552 MethodElement method = | |
| 1553 ElementFactory.methodElement("m", _typeProvider.intType); | |
| 1554 classA.methods = <MethodElement>[method]; | |
| 1555 // set name scope | |
| 1556 _visitor.nameScope = new EnclosedScope(null) | |
| 1557 ..defineNameWithoutChecking('A', classA); | |
| 1558 // prepare "A.m" | |
| 1559 PrefixedIdentifier prefixed = AstFactory.identifier5('A', 'm'); | |
| 1560 CommentReference commentReference = new CommentReference(null, prefixed); | |
| 1561 // resolve | |
| 1562 _resolveNode(commentReference); | |
| 1563 expect(prefixed.prefix.staticElement, classA); | |
| 1564 expect(prefixed.identifier.staticElement, method); | |
| 1565 _listener.assertNoErrors(); | |
| 1566 } | |
| 1567 | |
| 1568 void test_visitConstructorName_named() { | |
| 1569 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1570 String constructorName = "a"; | |
| 1571 ConstructorElement constructor = | |
| 1572 ElementFactory.constructorElement2(classA, constructorName); | |
| 1573 classA.constructors = <ConstructorElement>[constructor]; | |
| 1574 ConstructorName name = AstFactory.constructorName( | |
| 1575 AstFactory.typeName(classA), constructorName); | |
| 1576 _resolveNode(name); | |
| 1577 expect(name.staticElement, same(constructor)); | |
| 1578 _listener.assertNoErrors(); | |
| 1579 } | |
| 1580 | |
| 1581 void test_visitConstructorName_unnamed() { | |
| 1582 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1583 String constructorName = null; | |
| 1584 ConstructorElement constructor = | |
| 1585 ElementFactory.constructorElement2(classA, constructorName); | |
| 1586 classA.constructors = <ConstructorElement>[constructor]; | |
| 1587 ConstructorName name = AstFactory.constructorName( | |
| 1588 AstFactory.typeName(classA), constructorName); | |
| 1589 _resolveNode(name); | |
| 1590 expect(name.staticElement, same(constructor)); | |
| 1591 _listener.assertNoErrors(); | |
| 1592 } | |
| 1593 | |
| 1594 void test_visitContinueStatement_withLabel() { | |
| 1595 // loop: while (true) { | |
| 1596 // continue loop; | |
| 1597 // } | |
| 1598 String label = "loop"; | |
| 1599 LabelElementImpl labelElement = new LabelElementImpl.forNode( | |
| 1600 AstFactory.identifier3(label), false, false); | |
| 1601 ContinueStatement continueStatement = AstFactory.continueStatement(label); | |
| 1602 Expression condition = AstFactory.booleanLiteral(true); | |
| 1603 WhileStatement whileStatement = | |
| 1604 AstFactory.whileStatement(condition, continueStatement); | |
| 1605 expect(_resolveContinue(continueStatement, labelElement, whileStatement), | |
| 1606 same(labelElement)); | |
| 1607 expect(continueStatement.target, same(whileStatement)); | |
| 1608 _listener.assertNoErrors(); | |
| 1609 } | |
| 1610 | |
| 1611 void test_visitContinueStatement_withoutLabel() { | |
| 1612 ContinueStatement statement = AstFactory.continueStatement(); | |
| 1613 _resolveStatement(statement, null, null); | |
| 1614 _listener.assertNoErrors(); | |
| 1615 } | |
| 1616 | |
| 1617 void test_visitEnumDeclaration() { | |
| 1618 CompilationUnitElementImpl compilationUnitElement = | |
| 1619 ElementFactory.compilationUnit('foo.dart'); | |
| 1620 ClassElementImpl enumElement = | |
| 1621 ElementFactory.enumElement(_typeProvider, ('E')); | |
| 1622 compilationUnitElement.enums = <ClassElement>[enumElement]; | |
| 1623 EnumDeclaration enumNode = AstFactory.enumDeclaration2('E', []); | |
| 1624 Annotation annotationNode = | |
| 1625 AstFactory.annotation(AstFactory.identifier3('a')); | |
| 1626 annotationNode.element = ElementFactory.classElement2('A'); | |
| 1627 annotationNode.elementAnnotation = | |
| 1628 new ElementAnnotationImpl(compilationUnitElement); | |
| 1629 enumNode.metadata.add(annotationNode); | |
| 1630 enumNode.name.staticElement = enumElement; | |
| 1631 List<ElementAnnotation> metadata = <ElementAnnotation>[ | |
| 1632 annotationNode.elementAnnotation | |
| 1633 ]; | |
| 1634 _resolveNode(enumNode); | |
| 1635 expect(metadata[0].element, annotationNode.element); | |
| 1636 } | |
| 1637 | |
| 1638 void test_visitExportDirective_noCombinators() { | |
| 1639 ExportDirective directive = AstFactory.exportDirective2(null); | |
| 1640 directive.element = ElementFactory | |
| 1641 .exportFor(ElementFactory.library(_definingLibrary.context, "lib")); | |
| 1642 _resolveNode(directive); | |
| 1643 _listener.assertNoErrors(); | |
| 1644 } | |
| 1645 | |
| 1646 void test_visitFieldFormalParameter() { | |
| 1647 String fieldName = "f"; | |
| 1648 InterfaceType intType = _typeProvider.intType; | |
| 1649 FieldElementImpl fieldElement = | |
| 1650 ElementFactory.fieldElement(fieldName, false, false, false, intType); | |
| 1651 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1652 classA.fields = <FieldElement>[fieldElement]; | |
| 1653 FieldFormalParameter parameter = | |
| 1654 AstFactory.fieldFormalParameter2(fieldName); | |
| 1655 FieldFormalParameterElementImpl parameterElement = | |
| 1656 ElementFactory.fieldFormalParameter(parameter.identifier); | |
| 1657 parameterElement.field = fieldElement; | |
| 1658 parameterElement.type = intType; | |
| 1659 parameter.identifier.staticElement = parameterElement; | |
| 1660 _resolveInClass(parameter, classA); | |
| 1661 expect(parameter.element.type, same(intType)); | |
| 1662 } | |
| 1663 | |
| 1664 void test_visitImportDirective_noCombinators_noPrefix() { | |
| 1665 ImportDirective directive = AstFactory.importDirective3(null, null); | |
| 1666 directive.element = ElementFactory.importFor( | |
| 1667 ElementFactory.library(_definingLibrary.context, "lib"), null); | |
| 1668 _resolveNode(directive); | |
| 1669 _listener.assertNoErrors(); | |
| 1670 } | |
| 1671 | |
| 1672 void test_visitImportDirective_noCombinators_prefix() { | |
| 1673 String prefixName = "p"; | |
| 1674 ImportElement importElement = ElementFactory.importFor( | |
| 1675 ElementFactory.library(_definingLibrary.context, "lib"), | |
| 1676 ElementFactory.prefix(prefixName)); | |
| 1677 _definingLibrary.imports = <ImportElement>[importElement]; | |
| 1678 ImportDirective directive = AstFactory.importDirective3(null, prefixName); | |
| 1679 directive.element = importElement; | |
| 1680 _resolveNode(directive); | |
| 1681 _listener.assertNoErrors(); | |
| 1682 } | |
| 1683 | |
| 1684 void test_visitImportDirective_withCombinators() { | |
| 1685 ShowCombinator combinator = AstFactory.showCombinator2(["A", "B", "C"]); | |
| 1686 ImportDirective directive = | |
| 1687 AstFactory.importDirective3(null, null, [combinator]); | |
| 1688 LibraryElementImpl library = | |
| 1689 ElementFactory.library(_definingLibrary.context, "lib"); | |
| 1690 TopLevelVariableElementImpl varA = | |
| 1691 ElementFactory.topLevelVariableElement2("A"); | |
| 1692 TopLevelVariableElementImpl varB = | |
| 1693 ElementFactory.topLevelVariableElement2("B"); | |
| 1694 TopLevelVariableElementImpl varC = | |
| 1695 ElementFactory.topLevelVariableElement2("C"); | |
| 1696 CompilationUnitElementImpl unit = | |
| 1697 library.definingCompilationUnit as CompilationUnitElementImpl; | |
| 1698 unit.accessors = <PropertyAccessorElement>[ | |
| 1699 varA.getter, | |
| 1700 varA.setter, | |
| 1701 varB.getter, | |
| 1702 varC.setter | |
| 1703 ]; | |
| 1704 unit.topLevelVariables = <TopLevelVariableElement>[varA, varB, varC]; | |
| 1705 directive.element = ElementFactory.importFor(library, null); | |
| 1706 _resolveNode(directive); | |
| 1707 expect(combinator.shownNames[0].staticElement, same(varA)); | |
| 1708 expect(combinator.shownNames[1].staticElement, same(varB)); | |
| 1709 expect(combinator.shownNames[2].staticElement, same(varC)); | |
| 1710 _listener.assertNoErrors(); | |
| 1711 } | |
| 1712 | |
| 1713 void test_visitIndexExpression_get() { | |
| 1714 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1715 InterfaceType intType = _typeProvider.intType; | |
| 1716 MethodElement getter = | |
| 1717 ElementFactory.methodElement("[]", intType, [intType]); | |
| 1718 classA.methods = <MethodElement>[getter]; | |
| 1719 SimpleIdentifier array = AstFactory.identifier3("a"); | |
| 1720 array.staticType = classA.type; | |
| 1721 IndexExpression expression = | |
| 1722 AstFactory.indexExpression(array, AstFactory.identifier3("i")); | |
| 1723 expect(_resolveIndexExpression(expression), same(getter)); | |
| 1724 _listener.assertNoErrors(); | |
| 1725 } | |
| 1726 | |
| 1727 void test_visitIndexExpression_set() { | |
| 1728 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1729 InterfaceType intType = _typeProvider.intType; | |
| 1730 MethodElement setter = | |
| 1731 ElementFactory.methodElement("[]=", intType, [intType]); | |
| 1732 classA.methods = <MethodElement>[setter]; | |
| 1733 SimpleIdentifier array = AstFactory.identifier3("a"); | |
| 1734 array.staticType = classA.type; | |
| 1735 IndexExpression expression = | |
| 1736 AstFactory.indexExpression(array, AstFactory.identifier3("i")); | |
| 1737 AstFactory.assignmentExpression( | |
| 1738 expression, TokenType.EQ, AstFactory.integer(0)); | |
| 1739 expect(_resolveIndexExpression(expression), same(setter)); | |
| 1740 _listener.assertNoErrors(); | |
| 1741 } | |
| 1742 | |
| 1743 void test_visitInstanceCreationExpression_named() { | |
| 1744 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1745 String constructorName = "a"; | |
| 1746 ConstructorElement constructor = | |
| 1747 ElementFactory.constructorElement2(classA, constructorName); | |
| 1748 classA.constructors = <ConstructorElement>[constructor]; | |
| 1749 ConstructorName name = AstFactory.constructorName( | |
| 1750 AstFactory.typeName(classA), constructorName); | |
| 1751 name.staticElement = constructor; | |
| 1752 InstanceCreationExpression creation = | |
| 1753 AstFactory.instanceCreationExpression(Keyword.NEW, name); | |
| 1754 _resolveNode(creation); | |
| 1755 expect(creation.staticElement, same(constructor)); | |
| 1756 _listener.assertNoErrors(); | |
| 1757 } | |
| 1758 | |
| 1759 void test_visitInstanceCreationExpression_unnamed() { | |
| 1760 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1761 String constructorName = null; | |
| 1762 ConstructorElement constructor = | |
| 1763 ElementFactory.constructorElement2(classA, constructorName); | |
| 1764 classA.constructors = <ConstructorElement>[constructor]; | |
| 1765 ConstructorName name = AstFactory.constructorName( | |
| 1766 AstFactory.typeName(classA), constructorName); | |
| 1767 name.staticElement = constructor; | |
| 1768 InstanceCreationExpression creation = | |
| 1769 AstFactory.instanceCreationExpression(Keyword.NEW, name); | |
| 1770 _resolveNode(creation); | |
| 1771 expect(creation.staticElement, same(constructor)); | |
| 1772 _listener.assertNoErrors(); | |
| 1773 } | |
| 1774 | |
| 1775 void test_visitInstanceCreationExpression_unnamed_namedParameter() { | |
| 1776 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1777 String constructorName = null; | |
| 1778 ConstructorElementImpl constructor = | |
| 1779 ElementFactory.constructorElement2(classA, constructorName); | |
| 1780 String parameterName = "a"; | |
| 1781 ParameterElement parameter = ElementFactory.namedParameter(parameterName); | |
| 1782 constructor.parameters = <ParameterElement>[parameter]; | |
| 1783 classA.constructors = <ConstructorElement>[constructor]; | |
| 1784 ConstructorName name = AstFactory.constructorName( | |
| 1785 AstFactory.typeName(classA), constructorName); | |
| 1786 name.staticElement = constructor; | |
| 1787 InstanceCreationExpression creation = AstFactory.instanceCreationExpression( | |
| 1788 Keyword.NEW, | |
| 1789 name, | |
| 1790 [AstFactory.namedExpression2(parameterName, AstFactory.integer(0))]); | |
| 1791 _resolveNode(creation); | |
| 1792 expect(creation.staticElement, same(constructor)); | |
| 1793 expect( | |
| 1794 (creation.argumentList.arguments[0] as NamedExpression) | |
| 1795 .name | |
| 1796 .label | |
| 1797 .staticElement, | |
| 1798 same(parameter)); | |
| 1799 _listener.assertNoErrors(); | |
| 1800 } | |
| 1801 | |
| 1802 void test_visitMethodInvocation() { | |
| 1803 InterfaceType numType = _typeProvider.numType; | |
| 1804 SimpleIdentifier left = AstFactory.identifier3("i"); | |
| 1805 left.staticType = numType; | |
| 1806 String methodName = "abs"; | |
| 1807 MethodInvocation invocation = AstFactory.methodInvocation(left, methodName); | |
| 1808 _resolveNode(invocation); | |
| 1809 expect(invocation.methodName.staticElement, | |
| 1810 same(getMethod(numType, methodName))); | |
| 1811 _listener.assertNoErrors(); | |
| 1812 } | |
| 1813 | |
| 1814 void test_visitMethodInvocation_namedParameter() { | |
| 1815 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1816 String methodName = "m"; | |
| 1817 String parameterName = "p"; | |
| 1818 MethodElementImpl method = ElementFactory.methodElement(methodName, null); | |
| 1819 ParameterElement parameter = ElementFactory.namedParameter(parameterName); | |
| 1820 method.parameters = <ParameterElement>[parameter]; | |
| 1821 classA.methods = <MethodElement>[method]; | |
| 1822 SimpleIdentifier left = AstFactory.identifier3("i"); | |
| 1823 left.staticType = classA.type; | |
| 1824 MethodInvocation invocation = AstFactory.methodInvocation(left, methodName, | |
| 1825 [AstFactory.namedExpression2(parameterName, AstFactory.integer(0))]); | |
| 1826 _resolveNode(invocation); | |
| 1827 expect(invocation.methodName.staticElement, same(method)); | |
| 1828 expect( | |
| 1829 (invocation.argumentList.arguments[0] as NamedExpression) | |
| 1830 .name | |
| 1831 .label | |
| 1832 .staticElement, | |
| 1833 same(parameter)); | |
| 1834 _listener.assertNoErrors(); | |
| 1835 } | |
| 1836 | |
| 1837 void test_visitPostfixExpression() { | |
| 1838 InterfaceType numType = _typeProvider.numType; | |
| 1839 SimpleIdentifier operand = AstFactory.identifier3("i"); | |
| 1840 operand.staticType = numType; | |
| 1841 PostfixExpression expression = | |
| 1842 AstFactory.postfixExpression(operand, TokenType.PLUS_PLUS); | |
| 1843 _resolveNode(expression); | |
| 1844 expect(expression.staticElement, getMethod(numType, "+")); | |
| 1845 _listener.assertNoErrors(); | |
| 1846 } | |
| 1847 | |
| 1848 void test_visitPrefixedIdentifier_dynamic() { | |
| 1849 DartType dynamicType = _typeProvider.dynamicType; | |
| 1850 SimpleIdentifier target = AstFactory.identifier3("a"); | |
| 1851 VariableElementImpl variable = ElementFactory.localVariableElement(target); | |
| 1852 variable.type = dynamicType; | |
| 1853 target.staticElement = variable; | |
| 1854 target.staticType = dynamicType; | |
| 1855 PrefixedIdentifier identifier = | |
| 1856 AstFactory.identifier(target, AstFactory.identifier3("b")); | |
| 1857 _resolveNode(identifier); | |
| 1858 expect(identifier.staticElement, isNull); | |
| 1859 expect(identifier.identifier.staticElement, isNull); | |
| 1860 _listener.assertNoErrors(); | |
| 1861 } | |
| 1862 | |
| 1863 void test_visitPrefixedIdentifier_nonDynamic() { | |
| 1864 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1865 String getterName = "b"; | |
| 1866 PropertyAccessorElement getter = | |
| 1867 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 1868 classA.accessors = <PropertyAccessorElement>[getter]; | |
| 1869 SimpleIdentifier target = AstFactory.identifier3("a"); | |
| 1870 VariableElementImpl variable = ElementFactory.localVariableElement(target); | |
| 1871 variable.type = classA.type; | |
| 1872 target.staticElement = variable; | |
| 1873 target.staticType = classA.type; | |
| 1874 PrefixedIdentifier identifier = | |
| 1875 AstFactory.identifier(target, AstFactory.identifier3(getterName)); | |
| 1876 _resolveNode(identifier); | |
| 1877 expect(identifier.staticElement, same(getter)); | |
| 1878 expect(identifier.identifier.staticElement, same(getter)); | |
| 1879 _listener.assertNoErrors(); | |
| 1880 } | |
| 1881 | |
| 1882 void test_visitPrefixedIdentifier_staticClassMember_getter() { | |
| 1883 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1884 // set accessors | |
| 1885 String propName = "b"; | |
| 1886 PropertyAccessorElement getter = | |
| 1887 ElementFactory.getterElement(propName, false, _typeProvider.intType); | |
| 1888 PropertyAccessorElement setter = | |
| 1889 ElementFactory.setterElement(propName, false, _typeProvider.intType); | |
| 1890 classA.accessors = <PropertyAccessorElement>[getter, setter]; | |
| 1891 // prepare "A.m" | |
| 1892 SimpleIdentifier target = AstFactory.identifier3("A"); | |
| 1893 target.staticElement = classA; | |
| 1894 target.staticType = classA.type; | |
| 1895 PrefixedIdentifier identifier = | |
| 1896 AstFactory.identifier(target, AstFactory.identifier3(propName)); | |
| 1897 // resolve | |
| 1898 _resolveNode(identifier); | |
| 1899 expect(identifier.staticElement, same(getter)); | |
| 1900 expect(identifier.identifier.staticElement, same(getter)); | |
| 1901 _listener.assertNoErrors(); | |
| 1902 } | |
| 1903 | |
| 1904 void test_visitPrefixedIdentifier_staticClassMember_method() { | |
| 1905 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1906 // set methods | |
| 1907 String propName = "m"; | |
| 1908 MethodElement method = | |
| 1909 ElementFactory.methodElement("m", _typeProvider.intType); | |
| 1910 classA.methods = <MethodElement>[method]; | |
| 1911 // prepare "A.m" | |
| 1912 SimpleIdentifier target = AstFactory.identifier3("A"); | |
| 1913 target.staticElement = classA; | |
| 1914 target.staticType = classA.type; | |
| 1915 PrefixedIdentifier identifier = | |
| 1916 AstFactory.identifier(target, AstFactory.identifier3(propName)); | |
| 1917 AstFactory.assignmentExpression( | |
| 1918 identifier, TokenType.EQ, AstFactory.nullLiteral()); | |
| 1919 // resolve | |
| 1920 _resolveNode(identifier); | |
| 1921 expect(identifier.staticElement, same(method)); | |
| 1922 expect(identifier.identifier.staticElement, same(method)); | |
| 1923 _listener.assertNoErrors(); | |
| 1924 } | |
| 1925 | |
| 1926 void test_visitPrefixedIdentifier_staticClassMember_setter() { | |
| 1927 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1928 // set accessors | |
| 1929 String propName = "b"; | |
| 1930 PropertyAccessorElement getter = | |
| 1931 ElementFactory.getterElement(propName, false, _typeProvider.intType); | |
| 1932 PropertyAccessorElement setter = | |
| 1933 ElementFactory.setterElement(propName, false, _typeProvider.intType); | |
| 1934 classA.accessors = <PropertyAccessorElement>[getter, setter]; | |
| 1935 // prepare "A.b = null" | |
| 1936 SimpleIdentifier target = AstFactory.identifier3("A"); | |
| 1937 target.staticElement = classA; | |
| 1938 target.staticType = classA.type; | |
| 1939 PrefixedIdentifier identifier = | |
| 1940 AstFactory.identifier(target, AstFactory.identifier3(propName)); | |
| 1941 AstFactory.assignmentExpression( | |
| 1942 identifier, TokenType.EQ, AstFactory.nullLiteral()); | |
| 1943 // resolve | |
| 1944 _resolveNode(identifier); | |
| 1945 expect(identifier.staticElement, same(setter)); | |
| 1946 expect(identifier.identifier.staticElement, same(setter)); | |
| 1947 _listener.assertNoErrors(); | |
| 1948 } | |
| 1949 | |
| 1950 void test_visitPrefixExpression() { | |
| 1951 InterfaceType numType = _typeProvider.numType; | |
| 1952 SimpleIdentifier operand = AstFactory.identifier3("i"); | |
| 1953 operand.staticType = numType; | |
| 1954 PrefixExpression expression = | |
| 1955 AstFactory.prefixExpression(TokenType.PLUS_PLUS, operand); | |
| 1956 _resolveNode(expression); | |
| 1957 expect(expression.staticElement, getMethod(numType, "+")); | |
| 1958 _listener.assertNoErrors(); | |
| 1959 } | |
| 1960 | |
| 1961 void test_visitPropertyAccess_getter_identifier() { | |
| 1962 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1963 String getterName = "b"; | |
| 1964 PropertyAccessorElement getter = | |
| 1965 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 1966 classA.accessors = <PropertyAccessorElement>[getter]; | |
| 1967 SimpleIdentifier target = AstFactory.identifier3("a"); | |
| 1968 target.staticType = classA.type; | |
| 1969 PropertyAccess access = AstFactory.propertyAccess2(target, getterName); | |
| 1970 _resolveNode(access); | |
| 1971 expect(access.propertyName.staticElement, same(getter)); | |
| 1972 _listener.assertNoErrors(); | |
| 1973 } | |
| 1974 | |
| 1975 void test_visitPropertyAccess_getter_super() { | |
| 1976 // | |
| 1977 // class A { | |
| 1978 // int get b; | |
| 1979 // } | |
| 1980 // class B { | |
| 1981 // ... super.m ... | |
| 1982 // } | |
| 1983 // | |
| 1984 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 1985 String getterName = "b"; | |
| 1986 PropertyAccessorElement getter = | |
| 1987 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 1988 classA.accessors = <PropertyAccessorElement>[getter]; | |
| 1989 SuperExpression target = AstFactory.superExpression(); | |
| 1990 target.staticType = ElementFactory.classElement("B", classA.type).type; | |
| 1991 PropertyAccess access = AstFactory.propertyAccess2(target, getterName); | |
| 1992 AstFactory.methodDeclaration2( | |
| 1993 null, | |
| 1994 null, | |
| 1995 null, | |
| 1996 null, | |
| 1997 AstFactory.identifier3("m"), | |
| 1998 AstFactory.formalParameterList(), | |
| 1999 AstFactory.expressionFunctionBody(access)); | |
| 2000 _resolveNode(access); | |
| 2001 expect(access.propertyName.staticElement, same(getter)); | |
| 2002 _listener.assertNoErrors(); | |
| 2003 } | |
| 2004 | |
| 2005 void test_visitPropertyAccess_setter_this() { | |
| 2006 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 2007 String setterName = "b"; | |
| 2008 PropertyAccessorElement setter = | |
| 2009 ElementFactory.setterElement(setterName, false, _typeProvider.intType); | |
| 2010 classA.accessors = <PropertyAccessorElement>[setter]; | |
| 2011 ThisExpression target = AstFactory.thisExpression(); | |
| 2012 target.staticType = classA.type; | |
| 2013 PropertyAccess access = AstFactory.propertyAccess2(target, setterName); | |
| 2014 AstFactory.assignmentExpression( | |
| 2015 access, TokenType.EQ, AstFactory.integer(0)); | |
| 2016 _resolveNode(access); | |
| 2017 expect(access.propertyName.staticElement, same(setter)); | |
| 2018 _listener.assertNoErrors(); | |
| 2019 } | |
| 2020 | |
| 2021 void test_visitSimpleIdentifier_classScope() { | |
| 2022 InterfaceType doubleType = _typeProvider.doubleType; | |
| 2023 String fieldName = "NAN"; | |
| 2024 SimpleIdentifier node = AstFactory.identifier3(fieldName); | |
| 2025 _resolveInClass(node, doubleType.element); | |
| 2026 expect(node.staticElement, getGetter(doubleType, fieldName)); | |
| 2027 _listener.assertNoErrors(); | |
| 2028 } | |
| 2029 | |
| 2030 void test_visitSimpleIdentifier_dynamic() { | |
| 2031 SimpleIdentifier node = AstFactory.identifier3("dynamic"); | |
| 2032 _resolveIdentifier(node); | |
| 2033 expect(node.staticElement, same(_typeProvider.dynamicType.element)); | |
| 2034 expect(node.staticType, same(_typeProvider.typeType)); | |
| 2035 _listener.assertNoErrors(); | |
| 2036 } | |
| 2037 | |
| 2038 void test_visitSimpleIdentifier_lexicalScope() { | |
| 2039 SimpleIdentifier node = AstFactory.identifier3("i"); | |
| 2040 VariableElementImpl element = ElementFactory.localVariableElement(node); | |
| 2041 expect(_resolveIdentifier(node, [element]), same(element)); | |
| 2042 _listener.assertNoErrors(); | |
| 2043 } | |
| 2044 | |
| 2045 void test_visitSimpleIdentifier_lexicalScope_field_setter() { | |
| 2046 InterfaceType intType = _typeProvider.intType; | |
| 2047 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 2048 String fieldName = "a"; | |
| 2049 FieldElement field = | |
| 2050 ElementFactory.fieldElement(fieldName, false, false, false, intType); | |
| 2051 classA.fields = <FieldElement>[field]; | |
| 2052 classA.accessors = <PropertyAccessorElement>[field.getter, field.setter]; | |
| 2053 SimpleIdentifier node = AstFactory.identifier3(fieldName); | |
| 2054 AstFactory.assignmentExpression(node, TokenType.EQ, AstFactory.integer(0)); | |
| 2055 _resolveInClass(node, classA); | |
| 2056 Element element = node.staticElement; | |
| 2057 EngineTestCase.assertInstanceOf((obj) => obj is PropertyAccessorElement, | |
| 2058 PropertyAccessorElement, element); | |
| 2059 expect((element as PropertyAccessorElement).isSetter, isTrue); | |
| 2060 _listener.assertNoErrors(); | |
| 2061 } | |
| 2062 | |
| 2063 void test_visitSuperConstructorInvocation() { | |
| 2064 ClassElementImpl superclass = ElementFactory.classElement2("A"); | |
| 2065 ConstructorElementImpl superConstructor = | |
| 2066 ElementFactory.constructorElement2(superclass, null); | |
| 2067 superclass.constructors = <ConstructorElement>[superConstructor]; | |
| 2068 ClassElementImpl subclass = | |
| 2069 ElementFactory.classElement("B", superclass.type); | |
| 2070 ConstructorElementImpl subConstructor = | |
| 2071 ElementFactory.constructorElement2(subclass, null); | |
| 2072 subclass.constructors = <ConstructorElement>[subConstructor]; | |
| 2073 SuperConstructorInvocation invocation = | |
| 2074 AstFactory.superConstructorInvocation(); | |
| 2075 _resolveInClass(invocation, subclass); | |
| 2076 expect(invocation.staticElement, superConstructor); | |
| 2077 _listener.assertNoErrors(); | |
| 2078 } | |
| 2079 | |
| 2080 void test_visitSuperConstructorInvocation_namedParameter() { | |
| 2081 ClassElementImpl superclass = ElementFactory.classElement2("A"); | |
| 2082 ConstructorElementImpl superConstructor = | |
| 2083 ElementFactory.constructorElement2(superclass, null); | |
| 2084 String parameterName = "p"; | |
| 2085 ParameterElement parameter = ElementFactory.namedParameter(parameterName); | |
| 2086 superConstructor.parameters = <ParameterElement>[parameter]; | |
| 2087 superclass.constructors = <ConstructorElement>[superConstructor]; | |
| 2088 ClassElementImpl subclass = | |
| 2089 ElementFactory.classElement("B", superclass.type); | |
| 2090 ConstructorElementImpl subConstructor = | |
| 2091 ElementFactory.constructorElement2(subclass, null); | |
| 2092 subclass.constructors = <ConstructorElement>[subConstructor]; | |
| 2093 SuperConstructorInvocation invocation = AstFactory | |
| 2094 .superConstructorInvocation([ | |
| 2095 AstFactory.namedExpression2(parameterName, AstFactory.integer(0)) | |
| 2096 ]); | |
| 2097 _resolveInClass(invocation, subclass); | |
| 2098 expect(invocation.staticElement, superConstructor); | |
| 2099 expect( | |
| 2100 (invocation.argumentList.arguments[0] as NamedExpression) | |
| 2101 .name | |
| 2102 .label | |
| 2103 .staticElement, | |
| 2104 same(parameter)); | |
| 2105 _listener.assertNoErrors(); | |
| 2106 } | |
| 2107 | |
| 2108 /** | |
| 2109 * Create the resolver used by the tests. | |
| 2110 * | |
| 2111 * @return the resolver that was created | |
| 2112 */ | |
| 2113 ElementResolver _createResolver() { | |
| 2114 InternalAnalysisContext context = AnalysisContextFactory.contextWithCore(); | |
| 2115 FileBasedSource source = | |
| 2116 new FileBasedSource(FileUtilities2.createFile("/test.dart")); | |
| 2117 CompilationUnitElementImpl definingCompilationUnit = | |
| 2118 new CompilationUnitElementImpl("test.dart"); | |
| 2119 definingCompilationUnit.librarySource = | |
| 2120 definingCompilationUnit.source = source; | |
| 2121 _definingLibrary = ElementFactory.library(context, "test"); | |
| 2122 _definingLibrary.definingCompilationUnit = definingCompilationUnit; | |
| 2123 _visitor = new ResolverVisitor( | |
| 2124 _definingLibrary, source, _typeProvider, _listener, | |
| 2125 nameScope: new LibraryScope(_definingLibrary, _listener)); | |
| 2126 try { | |
| 2127 return _visitor.elementResolver; | |
| 2128 } catch (exception) { | |
| 2129 throw new IllegalArgumentException( | |
| 2130 "Could not create resolver", exception); | |
| 2131 } | |
| 2132 } | |
| 2133 | |
| 2134 /** | |
| 2135 * Return the element associated with the label of [statement] after the | |
| 2136 * resolver has resolved it. [labelElement] is the label element to be | |
| 2137 * defined in the statement's label scope, and [labelTarget] is the statement | |
| 2138 * the label resolves to. | |
| 2139 */ | |
| 2140 Element _resolveBreak(BreakStatement statement, LabelElementImpl labelElement, | |
| 2141 Statement labelTarget) { | |
| 2142 _resolveStatement(statement, labelElement, labelTarget); | |
| 2143 return statement.label.staticElement; | |
| 2144 } | |
| 2145 | |
| 2146 /** | |
| 2147 * Return the element associated with the label [statement] after the | |
| 2148 * resolver has resolved it. [labelElement] is the label element to be | |
| 2149 * defined in the statement's label scope, and [labelTarget] is the AST node | |
| 2150 * the label resolves to. | |
| 2151 * | |
| 2152 * @param statement the statement to be resolved | |
| 2153 * @param labelElement the label element to be defined in the statement's labe
l scope | |
| 2154 * @return the element to which the statement's label was resolved | |
| 2155 */ | |
| 2156 Element _resolveContinue(ContinueStatement statement, | |
| 2157 LabelElementImpl labelElement, AstNode labelTarget) { | |
| 2158 _resolveStatement(statement, labelElement, labelTarget); | |
| 2159 return statement.label.staticElement; | |
| 2160 } | |
| 2161 | |
| 2162 /** | |
| 2163 * Return the element associated with the given identifier after the resolver
has resolved the | |
| 2164 * identifier. | |
| 2165 * | |
| 2166 * @param node the expression to be resolved | |
| 2167 * @param definedElements the elements that are to be defined in the scope in
which the element is | |
| 2168 * being resolved | |
| 2169 * @return the element to which the expression was resolved | |
| 2170 */ | |
| 2171 Element _resolveIdentifier(Identifier node, [List<Element> definedElements]) { | |
| 2172 _resolveNode(node, definedElements); | |
| 2173 return node.staticElement; | |
| 2174 } | |
| 2175 | |
| 2176 /** | |
| 2177 * Return the element associated with the given identifier after the resolver
has resolved the | |
| 2178 * identifier. | |
| 2179 * | |
| 2180 * @param node the expression to be resolved | |
| 2181 * @param enclosingClass the element representing the class enclosing the iden
tifier | |
| 2182 * @return the element to which the expression was resolved | |
| 2183 */ | |
| 2184 void _resolveInClass(AstNode node, ClassElement enclosingClass) { | |
| 2185 try { | |
| 2186 Scope outerScope = _visitor.nameScope; | |
| 2187 try { | |
| 2188 _visitor.enclosingClass = enclosingClass; | |
| 2189 EnclosedScope innerScope = new ClassScope( | |
| 2190 new TypeParameterScope(outerScope, enclosingClass), enclosingClass); | |
| 2191 _visitor.nameScope = innerScope; | |
| 2192 node.accept(_resolver); | |
| 2193 } finally { | |
| 2194 _visitor.enclosingClass = null; | |
| 2195 _visitor.nameScope = outerScope; | |
| 2196 } | |
| 2197 } catch (exception) { | |
| 2198 throw new IllegalArgumentException("Could not resolve node", exception); | |
| 2199 } | |
| 2200 } | |
| 2201 | |
| 2202 /** | |
| 2203 * Return the element associated with the given expression after the resolver
has resolved the | |
| 2204 * expression. | |
| 2205 * | |
| 2206 * @param node the expression to be resolved | |
| 2207 * @param definedElements the elements that are to be defined in the scope in
which the element is | |
| 2208 * being resolved | |
| 2209 * @return the element to which the expression was resolved | |
| 2210 */ | |
| 2211 Element _resolveIndexExpression(IndexExpression node, | |
| 2212 [List<Element> definedElements]) { | |
| 2213 _resolveNode(node, definedElements); | |
| 2214 return node.staticElement; | |
| 2215 } | |
| 2216 | |
| 2217 /** | |
| 2218 * Return the element associated with the given identifier after the resolver
has resolved the | |
| 2219 * identifier. | |
| 2220 * | |
| 2221 * @param node the expression to be resolved | |
| 2222 * @param definedElements the elements that are to be defined in the scope in
which the element is | |
| 2223 * being resolved | |
| 2224 * @return the element to which the expression was resolved | |
| 2225 */ | |
| 2226 void _resolveNode(AstNode node, [List<Element> definedElements]) { | |
| 2227 try { | |
| 2228 Scope outerScope = _visitor.nameScope; | |
| 2229 try { | |
| 2230 EnclosedScope innerScope = new EnclosedScope(outerScope); | |
| 2231 if (definedElements != null) { | |
| 2232 for (Element element in definedElements) { | |
| 2233 innerScope.define(element); | |
| 2234 } | |
| 2235 } | |
| 2236 _visitor.nameScope = innerScope; | |
| 2237 node.accept(_resolver); | |
| 2238 } finally { | |
| 2239 _visitor.nameScope = outerScope; | |
| 2240 } | |
| 2241 } catch (exception) { | |
| 2242 throw new IllegalArgumentException("Could not resolve node", exception); | |
| 2243 } | |
| 2244 } | |
| 2245 | |
| 2246 /** | |
| 2247 * Return the element associated with the label of the given statement after t
he resolver has | |
| 2248 * resolved the statement. | |
| 2249 * | |
| 2250 * @param statement the statement to be resolved | |
| 2251 * @param labelElement the label element to be defined in the statement's labe
l scope | |
| 2252 * @return the element to which the statement's label was resolved | |
| 2253 */ | |
| 2254 void _resolveStatement( | |
| 2255 Statement statement, LabelElementImpl labelElement, AstNode labelTarget) { | |
| 2256 try { | |
| 2257 LabelScope outerScope = _visitor.labelScope; | |
| 2258 try { | |
| 2259 LabelScope innerScope; | |
| 2260 if (labelElement == null) { | |
| 2261 innerScope = outerScope; | |
| 2262 } else { | |
| 2263 innerScope = new LabelScope( | |
| 2264 outerScope, labelElement.name, labelTarget, labelElement); | |
| 2265 } | |
| 2266 _visitor.labelScope = innerScope; | |
| 2267 statement.accept(_resolver); | |
| 2268 } finally { | |
| 2269 _visitor.labelScope = outerScope; | |
| 2270 } | |
| 2271 } catch (exception) { | |
| 2272 throw new IllegalArgumentException("Could not resolve node", exception); | |
| 2273 } | |
| 2274 } | |
| 2275 } | |
| 2276 | |
| 2277 @reflectiveTest | |
| 2278 class EnclosedScopeTest extends ResolverTestCase { | 194 class EnclosedScopeTest extends ResolverTestCase { |
| 2279 void test_define_duplicate() { | 195 void test_define_duplicate() { |
| 2280 GatheringErrorListener listener = new GatheringErrorListener(); | 196 GatheringErrorListener listener = new GatheringErrorListener(); |
| 2281 Scope rootScope = | 197 Scope rootScope = |
| 2282 new Scope_EnclosedScopeTest_test_define_duplicate(listener); | 198 new Scope_EnclosedScopeTest_test_define_duplicate(listener); |
| 2283 EnclosedScope scope = new EnclosedScope(rootScope); | 199 EnclosedScope scope = new EnclosedScope(rootScope); |
| 2284 VariableElement element1 = | 200 VariableElement element1 = |
| 2285 ElementFactory.localVariableElement(AstFactory.identifier3("v1")); | 201 ElementFactory.localVariableElement(AstFactory.identifier3("v1")); |
| 2286 VariableElement element2 = | 202 VariableElement element2 = |
| 2287 ElementFactory.localVariableElement(AstFactory.identifier3("v1")); | 203 ElementFactory.localVariableElement(AstFactory.identifier3("v1")); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2365 expect(functions, hasLength(1)); | 281 expect(functions, hasLength(1)); |
| 2366 expect(functions[0].enclosingElement, constructor); | 282 expect(functions[0].enclosingElement, constructor); |
| 2367 assertErrors(source, [ParserErrorCode.GETTER_IN_FUNCTION]); | 283 assertErrors(source, [ParserErrorCode.GETTER_IN_FUNCTION]); |
| 2368 } | 284 } |
| 2369 } | 285 } |
| 2370 | 286 |
| 2371 /** | 287 /** |
| 2372 * Tests for generic method and function resolution that do not use strong mode. | 288 * Tests for generic method and function resolution that do not use strong mode. |
| 2373 */ | 289 */ |
| 2374 @reflectiveTest | 290 @reflectiveTest |
| 2375 class GenericMethodResolverTest extends _StaticTypeAnalyzer2TestShared { | 291 class GenericMethodResolverTest extends StaticTypeAnalyzer2TestShared { |
| 2376 void setUp() { | 292 void setUp() { |
| 2377 super.setUp(); | 293 super.setUp(); |
| 2378 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); | 294 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); |
| 2379 options.enableGenericMethods = true; | 295 options.enableGenericMethods = true; |
| 2380 resetWithOptions(options); | 296 resetWithOptions(options); |
| 2381 } | 297 } |
| 2382 | 298 |
| 2383 void test_genericMethod_propagatedType_promotion() { | 299 void test_genericMethod_propagatedType_promotion() { |
| 2384 // Regression test for: | 300 // Regression test for: |
| 2385 // https://github.com/dart-lang/sdk/issues/25340 | 301 // https://github.com/dart-lang/sdk/issues/25340 |
| 2386 // | 302 // |
| 2387 // Note, after https://github.com/dart-lang/sdk/issues/25486 the original | 303 // Note, after https://github.com/dart-lang/sdk/issues/25486 the original |
| 2388 // strong mode example won't work, as we now compute a static type and | 304 // strong mode example won't work, as we now compute a static type and |
| 2389 // therefore discard the propagated type. | 305 // therefore discard the propagated type. |
| 2390 // | 306 // |
| 2391 // So this test does not use strong mode. | 307 // So this test does not use strong mode. |
| 2392 _resolveTestUnit(r''' | 308 resolveTestUnit(r''' |
| 2393 abstract class Iter { | 309 abstract class Iter { |
| 2394 List<S> map<S>(S f(x)); | 310 List<S> map<S>(S f(x)); |
| 2395 } | 311 } |
| 2396 class C {} | 312 class C {} |
| 2397 C toSpan(dynamic element) { | 313 C toSpan(dynamic element) { |
| 2398 if (element is Iter) { | 314 if (element is Iter) { |
| 2399 var y = element.map(toSpan); | 315 var y = element.map(toSpan); |
| 2400 } | 316 } |
| 2401 return null; | 317 return null; |
| 2402 }'''); | 318 }'''); |
| 2403 _expectIdentifierType('y = ', 'dynamic', 'List<dynamic>'); | 319 expectIdentifierType('y = ', 'dynamic', 'List<dynamic>'); |
| 2404 } | |
| 2405 } | |
| 2406 | |
| 2407 @reflectiveTest | |
| 2408 class HintCodeTest extends ResolverTestCase { | |
| 2409 void fail_deadCode_statementAfterRehrow() { | |
| 2410 Source source = addSource(r''' | |
| 2411 f() { | |
| 2412 try { | |
| 2413 var one = 1; | |
| 2414 } catch (e) { | |
| 2415 rethrow; | |
| 2416 var two = 2; | |
| 2417 } | |
| 2418 }'''); | |
| 2419 computeLibrarySourceErrors(source); | |
| 2420 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2421 verify([source]); | |
| 2422 } | |
| 2423 | |
| 2424 void fail_deadCode_statementAfterThrow() { | |
| 2425 Source source = addSource(r''' | |
| 2426 f() { | |
| 2427 var one = 1; | |
| 2428 throw 'Stop here'; | |
| 2429 var two = 2; | |
| 2430 }'''); | |
| 2431 computeLibrarySourceErrors(source); | |
| 2432 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2433 verify([source]); | |
| 2434 } | |
| 2435 | |
| 2436 void fail_isInt() { | |
| 2437 Source source = addSource("var v = 1 is int;"); | |
| 2438 computeLibrarySourceErrors(source); | |
| 2439 assertErrors(source, [HintCode.IS_INT]); | |
| 2440 verify([source]); | |
| 2441 } | |
| 2442 | |
| 2443 void fail_isNotInt() { | |
| 2444 Source source = addSource("var v = 1 is! int;"); | |
| 2445 computeLibrarySourceErrors(source); | |
| 2446 assertErrors(source, [HintCode.IS_NOT_INT]); | |
| 2447 verify([source]); | |
| 2448 } | |
| 2449 | |
| 2450 void fail_overrideEqualsButNotHashCode() { | |
| 2451 Source source = addSource(r''' | |
| 2452 class A { | |
| 2453 bool operator ==(x) {} | |
| 2454 }'''); | |
| 2455 computeLibrarySourceErrors(source); | |
| 2456 assertErrors(source, [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE]); | |
| 2457 verify([source]); | |
| 2458 } | |
| 2459 | |
| 2460 void fail_unusedImport_as_equalPrefixes() { | |
| 2461 // See todo at ImportsVerifier.prefixElementMap. | |
| 2462 Source source = addSource(r''' | |
| 2463 library L; | |
| 2464 import 'lib1.dart' as one; | |
| 2465 import 'lib2.dart' as one; | |
| 2466 one.A a;'''); | |
| 2467 Source source2 = addNamedSource( | |
| 2468 "/lib1.dart", | |
| 2469 r''' | |
| 2470 library lib1; | |
| 2471 class A {}'''); | |
| 2472 Source source3 = addNamedSource( | |
| 2473 "/lib2.dart", | |
| 2474 r''' | |
| 2475 library lib2; | |
| 2476 class B {}'''); | |
| 2477 computeLibrarySourceErrors(source); | |
| 2478 assertErrors(source, [HintCode.UNUSED_IMPORT]); | |
| 2479 assertNoErrors(source2); | |
| 2480 assertNoErrors(source3); | |
| 2481 verify([source, source2, source3]); | |
| 2482 } | |
| 2483 | |
| 2484 @override | |
| 2485 void reset() { | |
| 2486 analysisContext2 = AnalysisContextFactory.contextWithCoreAndPackages({ | |
| 2487 'package:meta/meta.dart': r''' | |
| 2488 library meta; | |
| 2489 | |
| 2490 const _Factory factory = const _Factory(); | |
| 2491 const _Literal literal = const _Literal(); | |
| 2492 const _MustCallSuper mustCallSuper = const _MustCallSuper(); | |
| 2493 const _Override override = const _Override(); | |
| 2494 const _Protected protected = const _Protected(); | |
| 2495 const _Required required = const _Required(); | |
| 2496 | |
| 2497 class _Factory { | |
| 2498 const _Factory(); | |
| 2499 } | |
| 2500 class _Literal { | |
| 2501 const _Literal(); | |
| 2502 } | |
| 2503 class _MustCallSuper { | |
| 2504 const _MustCallSuper(); | |
| 2505 } | |
| 2506 class _Override { | |
| 2507 const _Override(); | |
| 2508 } | |
| 2509 class _Protected { | |
| 2510 const _Protected(); | |
| 2511 } | |
| 2512 class _Required { | |
| 2513 final String reason; | |
| 2514 const _Required([this.reason])); | |
| 2515 } | |
| 2516 ''' | |
| 2517 }); | |
| 2518 } | |
| 2519 | |
| 2520 void test_argumentTypeNotAssignable_functionType() { | |
| 2521 Source source = addSource(r''' | |
| 2522 m() { | |
| 2523 var a = new A(); | |
| 2524 a.n(() => 0); | |
| 2525 } | |
| 2526 class A { | |
| 2527 n(void f(int i)) {} | |
| 2528 }'''); | |
| 2529 computeLibrarySourceErrors(source); | |
| 2530 assertErrors(source, [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]); | |
| 2531 verify([source]); | |
| 2532 } | |
| 2533 | |
| 2534 void test_argumentTypeNotAssignable_message() { | |
| 2535 // The implementation of HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE assumes that | |
| 2536 // StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE has the same message. | |
| 2537 expect(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE.message, | |
| 2538 HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE.message); | |
| 2539 } | |
| 2540 | |
| 2541 void test_argumentTypeNotAssignable_type() { | |
| 2542 Source source = addSource(r''' | |
| 2543 m() { | |
| 2544 var i = ''; | |
| 2545 n(i); | |
| 2546 } | |
| 2547 n(int i) {}'''); | |
| 2548 computeLibrarySourceErrors(source); | |
| 2549 assertErrors(source, [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]); | |
| 2550 verify([source]); | |
| 2551 } | |
| 2552 | |
| 2553 void test_canBeNullAfterNullAware_false_methodInvocation() { | |
| 2554 Source source = addSource(r''' | |
| 2555 m(x) { | |
| 2556 x?.a()?.b(); | |
| 2557 } | |
| 2558 '''); | |
| 2559 computeLibrarySourceErrors(source); | |
| 2560 assertNoErrors(source); | |
| 2561 verify([source]); | |
| 2562 } | |
| 2563 | |
| 2564 void test_canBeNullAfterNullAware_false_propertyAccess() { | |
| 2565 Source source = addSource(r''' | |
| 2566 m(x) { | |
| 2567 x?.a?.b; | |
| 2568 } | |
| 2569 '''); | |
| 2570 computeLibrarySourceErrors(source); | |
| 2571 assertNoErrors(source); | |
| 2572 verify([source]); | |
| 2573 } | |
| 2574 | |
| 2575 void test_canBeNullAfterNullAware_methodInvocation() { | |
| 2576 Source source = addSource(r''' | |
| 2577 m(x) { | |
| 2578 x?.a.b(); | |
| 2579 } | |
| 2580 '''); | |
| 2581 computeLibrarySourceErrors(source); | |
| 2582 assertErrors(source, [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]); | |
| 2583 verify([source]); | |
| 2584 } | |
| 2585 | |
| 2586 void test_canBeNullAfterNullAware_parenthesized() { | |
| 2587 Source source = addSource(r''' | |
| 2588 m(x) { | |
| 2589 (x?.a).b; | |
| 2590 } | |
| 2591 '''); | |
| 2592 computeLibrarySourceErrors(source); | |
| 2593 assertErrors(source, [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]); | |
| 2594 verify([source]); | |
| 2595 } | |
| 2596 | |
| 2597 void test_canBeNullAfterNullAware_propertyAccess() { | |
| 2598 Source source = addSource(r''' | |
| 2599 m(x) { | |
| 2600 x?.a.b; | |
| 2601 } | |
| 2602 '''); | |
| 2603 computeLibrarySourceErrors(source); | |
| 2604 assertErrors(source, [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]); | |
| 2605 verify([source]); | |
| 2606 } | |
| 2607 | |
| 2608 void test_deadCode_deadBlock_conditionalElse() { | |
| 2609 Source source = addSource(r''' | |
| 2610 f() { | |
| 2611 true ? 1 : 2; | |
| 2612 }'''); | |
| 2613 computeLibrarySourceErrors(source); | |
| 2614 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2615 verify([source]); | |
| 2616 } | |
| 2617 | |
| 2618 void test_deadCode_deadBlock_conditionalElse_nested() { | |
| 2619 // test that a dead else-statement can't generate additional violations | |
| 2620 Source source = addSource(r''' | |
| 2621 f() { | |
| 2622 true ? true : false && false; | |
| 2623 }'''); | |
| 2624 computeLibrarySourceErrors(source); | |
| 2625 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2626 verify([source]); | |
| 2627 } | |
| 2628 | |
| 2629 void test_deadCode_deadBlock_conditionalIf() { | |
| 2630 Source source = addSource(r''' | |
| 2631 f() { | |
| 2632 false ? 1 : 2; | |
| 2633 }'''); | |
| 2634 computeLibrarySourceErrors(source); | |
| 2635 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2636 verify([source]); | |
| 2637 } | |
| 2638 | |
| 2639 void test_deadCode_deadBlock_conditionalIf_nested() { | |
| 2640 // test that a dead then-statement can't generate additional violations | |
| 2641 Source source = addSource(r''' | |
| 2642 f() { | |
| 2643 false ? false && false : true; | |
| 2644 }'''); | |
| 2645 computeLibrarySourceErrors(source); | |
| 2646 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2647 verify([source]); | |
| 2648 } | |
| 2649 | |
| 2650 void test_deadCode_deadBlock_else() { | |
| 2651 Source source = addSource(r''' | |
| 2652 f() { | |
| 2653 if(true) {} else {} | |
| 2654 }'''); | |
| 2655 computeLibrarySourceErrors(source); | |
| 2656 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2657 verify([source]); | |
| 2658 } | |
| 2659 | |
| 2660 void test_deadCode_deadBlock_else_nested() { | |
| 2661 // test that a dead else-statement can't generate additional violations | |
| 2662 Source source = addSource(r''' | |
| 2663 f() { | |
| 2664 if(true) {} else {if (false) {}} | |
| 2665 }'''); | |
| 2666 computeLibrarySourceErrors(source); | |
| 2667 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2668 verify([source]); | |
| 2669 } | |
| 2670 | |
| 2671 void test_deadCode_deadBlock_if() { | |
| 2672 Source source = addSource(r''' | |
| 2673 f() { | |
| 2674 if(false) {} | |
| 2675 }'''); | |
| 2676 computeLibrarySourceErrors(source); | |
| 2677 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2678 verify([source]); | |
| 2679 } | |
| 2680 | |
| 2681 void test_deadCode_deadBlock_if_nested() { | |
| 2682 // test that a dead then-statement can't generate additional violations | |
| 2683 Source source = addSource(r''' | |
| 2684 f() { | |
| 2685 if(false) {if(false) {}} | |
| 2686 }'''); | |
| 2687 computeLibrarySourceErrors(source); | |
| 2688 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2689 verify([source]); | |
| 2690 } | |
| 2691 | |
| 2692 void test_deadCode_deadBlock_while() { | |
| 2693 Source source = addSource(r''' | |
| 2694 f() { | |
| 2695 while(false) {} | |
| 2696 }'''); | |
| 2697 computeLibrarySourceErrors(source); | |
| 2698 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2699 verify([source]); | |
| 2700 } | |
| 2701 | |
| 2702 void test_deadCode_deadBlock_while_nested() { | |
| 2703 // test that a dead while body can't generate additional violations | |
| 2704 Source source = addSource(r''' | |
| 2705 f() { | |
| 2706 while(false) {if(false) {}} | |
| 2707 }'''); | |
| 2708 computeLibrarySourceErrors(source); | |
| 2709 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2710 verify([source]); | |
| 2711 } | |
| 2712 | |
| 2713 void test_deadCode_deadCatch_catchFollowingCatch() { | |
| 2714 Source source = addSource(r''' | |
| 2715 class A {} | |
| 2716 f() { | |
| 2717 try {} catch (e) {} catch (e) {} | |
| 2718 }'''); | |
| 2719 computeLibrarySourceErrors(source); | |
| 2720 assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]); | |
| 2721 verify([source]); | |
| 2722 } | |
| 2723 | |
| 2724 void test_deadCode_deadCatch_catchFollowingCatch_nested() { | |
| 2725 // test that a dead catch clause can't generate additional violations | |
| 2726 Source source = addSource(r''' | |
| 2727 class A {} | |
| 2728 f() { | |
| 2729 try {} catch (e) {} catch (e) {if(false) {}} | |
| 2730 }'''); | |
| 2731 computeLibrarySourceErrors(source); | |
| 2732 assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]); | |
| 2733 verify([source]); | |
| 2734 } | |
| 2735 | |
| 2736 void test_deadCode_deadCatch_catchFollowingCatch_object() { | |
| 2737 Source source = addSource(r''' | |
| 2738 f() { | |
| 2739 try {} on Object catch (e) {} catch (e) {} | |
| 2740 }'''); | |
| 2741 computeLibrarySourceErrors(source); | |
| 2742 assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]); | |
| 2743 verify([source]); | |
| 2744 } | |
| 2745 | |
| 2746 void test_deadCode_deadCatch_catchFollowingCatch_object_nested() { | |
| 2747 // test that a dead catch clause can't generate additional violations | |
| 2748 Source source = addSource(r''' | |
| 2749 f() { | |
| 2750 try {} on Object catch (e) {} catch (e) {if(false) {}} | |
| 2751 }'''); | |
| 2752 computeLibrarySourceErrors(source); | |
| 2753 assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]); | |
| 2754 verify([source]); | |
| 2755 } | |
| 2756 | |
| 2757 void test_deadCode_deadCatch_onCatchSubtype() { | |
| 2758 Source source = addSource(r''' | |
| 2759 class A {} | |
| 2760 class B extends A {} | |
| 2761 f() { | |
| 2762 try {} on A catch (e) {} on B catch (e) {} | |
| 2763 }'''); | |
| 2764 computeLibrarySourceErrors(source); | |
| 2765 assertErrors(source, [HintCode.DEAD_CODE_ON_CATCH_SUBTYPE]); | |
| 2766 verify([source]); | |
| 2767 } | |
| 2768 | |
| 2769 void test_deadCode_deadCatch_onCatchSubtype_nested() { | |
| 2770 // test that a dead catch clause can't generate additional violations | |
| 2771 Source source = addSource(r''' | |
| 2772 class A {} | |
| 2773 class B extends A {} | |
| 2774 f() { | |
| 2775 try {} on A catch (e) {} on B catch (e) {if(false) {}} | |
| 2776 }'''); | |
| 2777 computeLibrarySourceErrors(source); | |
| 2778 assertErrors(source, [HintCode.DEAD_CODE_ON_CATCH_SUBTYPE]); | |
| 2779 verify([source]); | |
| 2780 } | |
| 2781 | |
| 2782 void test_deadCode_deadOperandLHS_and() { | |
| 2783 Source source = addSource(r''' | |
| 2784 f() { | |
| 2785 bool b = false && false; | |
| 2786 }'''); | |
| 2787 computeLibrarySourceErrors(source); | |
| 2788 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2789 verify([source]); | |
| 2790 } | |
| 2791 | |
| 2792 void test_deadCode_deadOperandLHS_and_nested() { | |
| 2793 Source source = addSource(r''' | |
| 2794 f() { | |
| 2795 bool b = false && (false && false); | |
| 2796 }'''); | |
| 2797 computeLibrarySourceErrors(source); | |
| 2798 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2799 verify([source]); | |
| 2800 } | |
| 2801 | |
| 2802 void test_deadCode_deadOperandLHS_or() { | |
| 2803 Source source = addSource(r''' | |
| 2804 f() { | |
| 2805 bool b = true || true; | |
| 2806 }'''); | |
| 2807 computeLibrarySourceErrors(source); | |
| 2808 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2809 verify([source]); | |
| 2810 } | |
| 2811 | |
| 2812 void test_deadCode_deadOperandLHS_or_nested() { | |
| 2813 Source source = addSource(r''' | |
| 2814 f() { | |
| 2815 bool b = true || (false && false); | |
| 2816 }'''); | |
| 2817 computeLibrarySourceErrors(source); | |
| 2818 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2819 verify([source]); | |
| 2820 } | |
| 2821 | |
| 2822 void test_deadCode_statementAfterBreak_inDefaultCase() { | |
| 2823 Source source = addSource(r''' | |
| 2824 f(v) { | |
| 2825 switch(v) { | |
| 2826 case 1: | |
| 2827 default: | |
| 2828 break; | |
| 2829 var a; | |
| 2830 } | |
| 2831 }'''); | |
| 2832 computeLibrarySourceErrors(source); | |
| 2833 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2834 verify([source]); | |
| 2835 } | |
| 2836 | |
| 2837 void test_deadCode_statementAfterBreak_inForEachStatement() { | |
| 2838 Source source = addSource(r''' | |
| 2839 f() { | |
| 2840 var list; | |
| 2841 for(var l in list) { | |
| 2842 break; | |
| 2843 var a; | |
| 2844 } | |
| 2845 }'''); | |
| 2846 computeLibrarySourceErrors(source); | |
| 2847 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2848 verify([source]); | |
| 2849 } | |
| 2850 | |
| 2851 void test_deadCode_statementAfterBreak_inForStatement() { | |
| 2852 Source source = addSource(r''' | |
| 2853 f() { | |
| 2854 for(;;) { | |
| 2855 break; | |
| 2856 var a; | |
| 2857 } | |
| 2858 }'''); | |
| 2859 computeLibrarySourceErrors(source); | |
| 2860 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2861 verify([source]); | |
| 2862 } | |
| 2863 | |
| 2864 void test_deadCode_statementAfterBreak_inSwitchCase() { | |
| 2865 Source source = addSource(r''' | |
| 2866 f(v) { | |
| 2867 switch(v) { | |
| 2868 case 1: | |
| 2869 break; | |
| 2870 var a; | |
| 2871 } | |
| 2872 }'''); | |
| 2873 computeLibrarySourceErrors(source); | |
| 2874 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2875 verify([source]); | |
| 2876 } | |
| 2877 | |
| 2878 void test_deadCode_statementAfterBreak_inWhileStatement() { | |
| 2879 Source source = addSource(r''' | |
| 2880 f(v) { | |
| 2881 while(v) { | |
| 2882 break; | |
| 2883 var a; | |
| 2884 } | |
| 2885 }'''); | |
| 2886 computeLibrarySourceErrors(source); | |
| 2887 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2888 verify([source]); | |
| 2889 } | |
| 2890 | |
| 2891 void test_deadCode_statementAfterContinue_inForEachStatement() { | |
| 2892 Source source = addSource(r''' | |
| 2893 f() { | |
| 2894 var list; | |
| 2895 for(var l in list) { | |
| 2896 continue; | |
| 2897 var a; | |
| 2898 } | |
| 2899 }'''); | |
| 2900 computeLibrarySourceErrors(source); | |
| 2901 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2902 verify([source]); | |
| 2903 } | |
| 2904 | |
| 2905 void test_deadCode_statementAfterContinue_inForStatement() { | |
| 2906 Source source = addSource(r''' | |
| 2907 f() { | |
| 2908 for(;;) { | |
| 2909 continue; | |
| 2910 var a; | |
| 2911 } | |
| 2912 }'''); | |
| 2913 computeLibrarySourceErrors(source); | |
| 2914 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2915 verify([source]); | |
| 2916 } | |
| 2917 | |
| 2918 void test_deadCode_statementAfterContinue_inWhileStatement() { | |
| 2919 Source source = addSource(r''' | |
| 2920 f(v) { | |
| 2921 while(v) { | |
| 2922 continue; | |
| 2923 var a; | |
| 2924 } | |
| 2925 }'''); | |
| 2926 computeLibrarySourceErrors(source); | |
| 2927 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2928 verify([source]); | |
| 2929 } | |
| 2930 | |
| 2931 void test_deadCode_statementAfterReturn_function() { | |
| 2932 Source source = addSource(r''' | |
| 2933 f() { | |
| 2934 var one = 1; | |
| 2935 return; | |
| 2936 var two = 2; | |
| 2937 }'''); | |
| 2938 computeLibrarySourceErrors(source); | |
| 2939 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2940 verify([source]); | |
| 2941 } | |
| 2942 | |
| 2943 void test_deadCode_statementAfterReturn_ifStatement() { | |
| 2944 Source source = addSource(r''' | |
| 2945 f(bool b) { | |
| 2946 if(b) { | |
| 2947 var one = 1; | |
| 2948 return; | |
| 2949 var two = 2; | |
| 2950 } | |
| 2951 }'''); | |
| 2952 computeLibrarySourceErrors(source); | |
| 2953 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2954 verify([source]); | |
| 2955 } | |
| 2956 | |
| 2957 void test_deadCode_statementAfterReturn_method() { | |
| 2958 Source source = addSource(r''' | |
| 2959 class A { | |
| 2960 m() { | |
| 2961 var one = 1; | |
| 2962 return; | |
| 2963 var two = 2; | |
| 2964 } | |
| 2965 }'''); | |
| 2966 computeLibrarySourceErrors(source); | |
| 2967 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2968 verify([source]); | |
| 2969 } | |
| 2970 | |
| 2971 void test_deadCode_statementAfterReturn_nested() { | |
| 2972 Source source = addSource(r''' | |
| 2973 f() { | |
| 2974 var one = 1; | |
| 2975 return; | |
| 2976 if(false) {} | |
| 2977 }'''); | |
| 2978 computeLibrarySourceErrors(source); | |
| 2979 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2980 verify([source]); | |
| 2981 } | |
| 2982 | |
| 2983 void test_deadCode_statementAfterReturn_twoReturns() { | |
| 2984 Source source = addSource(r''' | |
| 2985 f() { | |
| 2986 var one = 1; | |
| 2987 return; | |
| 2988 var two = 2; | |
| 2989 return; | |
| 2990 var three = 3; | |
| 2991 }'''); | |
| 2992 computeLibrarySourceErrors(source); | |
| 2993 assertErrors(source, [HintCode.DEAD_CODE]); | |
| 2994 verify([source]); | |
| 2995 } | |
| 2996 | |
| 2997 void test_deprecatedAnnotationUse_assignment() { | |
| 2998 Source source = addSource(r''' | |
| 2999 class A { | |
| 3000 @deprecated | |
| 3001 A operator+(A a) { return a; } | |
| 3002 } | |
| 3003 f(A a) { | |
| 3004 A b; | |
| 3005 a += b; | |
| 3006 }'''); | |
| 3007 computeLibrarySourceErrors(source); | |
| 3008 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 3009 verify([source]); | |
| 3010 } | |
| 3011 | |
| 3012 void test_deprecatedAnnotationUse_Deprecated() { | |
| 3013 Source source = addSource(r''' | |
| 3014 class A { | |
| 3015 @Deprecated('0.9') | |
| 3016 m() {} | |
| 3017 n() {m();} | |
| 3018 }'''); | |
| 3019 computeLibrarySourceErrors(source); | |
| 3020 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 3021 verify([source]); | |
| 3022 } | |
| 3023 | |
| 3024 void test_deprecatedAnnotationUse_deprecated() { | |
| 3025 Source source = addSource(r''' | |
| 3026 class A { | |
| 3027 @deprecated | |
| 3028 m() {} | |
| 3029 n() {m();} | |
| 3030 }'''); | |
| 3031 computeLibrarySourceErrors(source); | |
| 3032 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 3033 verify([source]); | |
| 3034 } | |
| 3035 | |
| 3036 void test_deprecatedAnnotationUse_export() { | |
| 3037 Source source = addSource("export 'deprecated_library.dart';"); | |
| 3038 addNamedSource( | |
| 3039 "/deprecated_library.dart", | |
| 3040 r''' | |
| 3041 @deprecated | |
| 3042 library deprecated_library; | |
| 3043 class A {}'''); | |
| 3044 computeLibrarySourceErrors(source); | |
| 3045 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 3046 verify([source]); | |
| 3047 } | |
| 3048 | |
| 3049 void test_deprecatedAnnotationUse_getter() { | |
| 3050 Source source = addSource(r''' | |
| 3051 class A { | |
| 3052 @deprecated | |
| 3053 get m => 1; | |
| 3054 } | |
| 3055 f(A a) { | |
| 3056 return a.m; | |
| 3057 }'''); | |
| 3058 computeLibrarySourceErrors(source); | |
| 3059 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 3060 verify([source]); | |
| 3061 } | |
| 3062 | |
| 3063 void test_deprecatedAnnotationUse_import() { | |
| 3064 Source source = addSource(r''' | |
| 3065 import 'deprecated_library.dart'; | |
| 3066 f(A a) {}'''); | |
| 3067 addNamedSource( | |
| 3068 "/deprecated_library.dart", | |
| 3069 r''' | |
| 3070 @deprecated | |
| 3071 library deprecated_library; | |
| 3072 class A {}'''); | |
| 3073 computeLibrarySourceErrors(source); | |
| 3074 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 3075 verify([source]); | |
| 3076 } | |
| 3077 | |
| 3078 void test_deprecatedAnnotationUse_indexExpression() { | |
| 3079 Source source = addSource(r''' | |
| 3080 class A { | |
| 3081 @deprecated | |
| 3082 operator[](int i) {} | |
| 3083 } | |
| 3084 f(A a) { | |
| 3085 return a[1]; | |
| 3086 }'''); | |
| 3087 computeLibrarySourceErrors(source); | |
| 3088 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 3089 verify([source]); | |
| 3090 } | |
| 3091 | |
| 3092 void test_deprecatedAnnotationUse_instanceCreation() { | |
| 3093 Source source = addSource(r''' | |
| 3094 class A { | |
| 3095 @deprecated | |
| 3096 A(int i) {} | |
| 3097 } | |
| 3098 f() { | |
| 3099 A a = new A(1); | |
| 3100 }'''); | |
| 3101 computeLibrarySourceErrors(source); | |
| 3102 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 3103 verify([source]); | |
| 3104 } | |
| 3105 | |
| 3106 void test_deprecatedAnnotationUse_instanceCreation_namedConstructor() { | |
| 3107 Source source = addSource(r''' | |
| 3108 class A { | |
| 3109 @deprecated | |
| 3110 A.named(int i) {} | |
| 3111 } | |
| 3112 f() { | |
| 3113 A a = new A.named(1); | |
| 3114 }'''); | |
| 3115 computeLibrarySourceErrors(source); | |
| 3116 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 3117 verify([source]); | |
| 3118 } | |
| 3119 | |
| 3120 void test_deprecatedAnnotationUse_operator() { | |
| 3121 Source source = addSource(r''' | |
| 3122 class A { | |
| 3123 @deprecated | |
| 3124 operator+(A a) {} | |
| 3125 } | |
| 3126 f(A a) { | |
| 3127 A b; | |
| 3128 return a + b; | |
| 3129 }'''); | |
| 3130 computeLibrarySourceErrors(source); | |
| 3131 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 3132 verify([source]); | |
| 3133 } | |
| 3134 | |
| 3135 void test_deprecatedAnnotationUse_setter() { | |
| 3136 Source source = addSource(r''' | |
| 3137 class A { | |
| 3138 @deprecated | |
| 3139 set s(v) {} | |
| 3140 } | |
| 3141 f(A a) { | |
| 3142 return a.s = 1; | |
| 3143 }'''); | |
| 3144 computeLibrarySourceErrors(source); | |
| 3145 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 3146 verify([source]); | |
| 3147 } | |
| 3148 | |
| 3149 void test_deprecatedAnnotationUse_superConstructor() { | |
| 3150 Source source = addSource(r''' | |
| 3151 class A { | |
| 3152 @deprecated | |
| 3153 A() {} | |
| 3154 } | |
| 3155 class B extends A { | |
| 3156 B() : super() {} | |
| 3157 }'''); | |
| 3158 computeLibrarySourceErrors(source); | |
| 3159 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 3160 verify([source]); | |
| 3161 } | |
| 3162 | |
| 3163 void test_deprecatedAnnotationUse_superConstructor_namedConstructor() { | |
| 3164 Source source = addSource(r''' | |
| 3165 class A { | |
| 3166 @deprecated | |
| 3167 A.named() {} | |
| 3168 } | |
| 3169 class B extends A { | |
| 3170 B() : super.named() {} | |
| 3171 }'''); | |
| 3172 computeLibrarySourceErrors(source); | |
| 3173 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]); | |
| 3174 verify([source]); | |
| 3175 } | |
| 3176 | |
| 3177 void test_divisionOptimization_double() { | |
| 3178 Source source = addSource(r''' | |
| 3179 f(double x, double y) { | |
| 3180 var v = (x / y).toInt(); | |
| 3181 }'''); | |
| 3182 computeLibrarySourceErrors(source); | |
| 3183 assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]); | |
| 3184 verify([source]); | |
| 3185 } | |
| 3186 | |
| 3187 void test_divisionOptimization_int() { | |
| 3188 Source source = addSource(r''' | |
| 3189 f(int x, int y) { | |
| 3190 var v = (x / y).toInt(); | |
| 3191 }'''); | |
| 3192 computeLibrarySourceErrors(source); | |
| 3193 assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]); | |
| 3194 verify([source]); | |
| 3195 } | |
| 3196 | |
| 3197 void test_divisionOptimization_propagatedType() { | |
| 3198 // Tests the propagated type information of the '/' method | |
| 3199 Source source = addSource(r''' | |
| 3200 f(x, y) { | |
| 3201 x = 1; | |
| 3202 y = 1; | |
| 3203 var v = (x / y).toInt(); | |
| 3204 }'''); | |
| 3205 computeLibrarySourceErrors(source); | |
| 3206 assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]); | |
| 3207 verify([source]); | |
| 3208 } | |
| 3209 | |
| 3210 void test_divisionOptimization_wrappedBinaryExpression() { | |
| 3211 Source source = addSource(r''' | |
| 3212 f(int x, int y) { | |
| 3213 var v = (((x / y))).toInt(); | |
| 3214 }'''); | |
| 3215 computeLibrarySourceErrors(source); | |
| 3216 assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]); | |
| 3217 verify([source]); | |
| 3218 } | |
| 3219 | |
| 3220 void test_duplicateImport() { | |
| 3221 Source source = addSource(r''' | |
| 3222 library L; | |
| 3223 import 'lib1.dart'; | |
| 3224 import 'lib1.dart'; | |
| 3225 A a;'''); | |
| 3226 addNamedSource( | |
| 3227 "/lib1.dart", | |
| 3228 r''' | |
| 3229 library lib1; | |
| 3230 class A {}'''); | |
| 3231 computeLibrarySourceErrors(source); | |
| 3232 assertErrors(source, [HintCode.DUPLICATE_IMPORT]); | |
| 3233 verify([source]); | |
| 3234 } | |
| 3235 | |
| 3236 void test_duplicateImport2() { | |
| 3237 Source source = addSource(r''' | |
| 3238 library L; | |
| 3239 import 'lib1.dart'; | |
| 3240 import 'lib1.dart'; | |
| 3241 import 'lib1.dart'; | |
| 3242 A a;'''); | |
| 3243 addNamedSource( | |
| 3244 "/lib1.dart", | |
| 3245 r''' | |
| 3246 library lib1; | |
| 3247 class A {}'''); | |
| 3248 computeLibrarySourceErrors(source); | |
| 3249 assertErrors( | |
| 3250 source, [HintCode.DUPLICATE_IMPORT, HintCode.DUPLICATE_IMPORT]); | |
| 3251 verify([source]); | |
| 3252 } | |
| 3253 | |
| 3254 void test_duplicateImport3() { | |
| 3255 Source source = addSource(r''' | |
| 3256 library L; | |
| 3257 import 'lib1.dart' as M show A hide B; | |
| 3258 import 'lib1.dart' as M show A hide B; | |
| 3259 M.A a;'''); | |
| 3260 addNamedSource( | |
| 3261 "/lib1.dart", | |
| 3262 r''' | |
| 3263 library lib1; | |
| 3264 class A {} | |
| 3265 class B {}'''); | |
| 3266 computeLibrarySourceErrors(source); | |
| 3267 assertErrors(source, [HintCode.DUPLICATE_IMPORT]); | |
| 3268 verify([source]); | |
| 3269 } | |
| 3270 | |
| 3271 void test_importDeferredLibraryWithLoadFunction() { | |
| 3272 resolveWithErrors(<String>[ | |
| 3273 r''' | |
| 3274 library lib1; | |
| 3275 loadLibrary() {} | |
| 3276 f() {}''', | |
| 3277 r''' | |
| 3278 library root; | |
| 3279 import 'lib1.dart' deferred as lib1; | |
| 3280 main() { lib1.f(); }''' | |
| 3281 ], <ErrorCode>[ | |
| 3282 HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION | |
| 3283 ]); | |
| 3284 } | |
| 3285 | |
| 3286 void test_invalidAssignment_instanceVariable() { | |
| 3287 Source source = addSource(r''' | |
| 3288 class A { | |
| 3289 int x; | |
| 3290 } | |
| 3291 f(var y) { | |
| 3292 A a; | |
| 3293 if(y is String) { | |
| 3294 a.x = y; | |
| 3295 } | |
| 3296 }'''); | |
| 3297 computeLibrarySourceErrors(source); | |
| 3298 assertErrors(source, [HintCode.INVALID_ASSIGNMENT]); | |
| 3299 verify([source]); | |
| 3300 } | |
| 3301 | |
| 3302 void test_invalidAssignment_localVariable() { | |
| 3303 Source source = addSource(r''' | |
| 3304 f(var y) { | |
| 3305 if(y is String) { | |
| 3306 int x = y; | |
| 3307 } | |
| 3308 }'''); | |
| 3309 computeLibrarySourceErrors(source); | |
| 3310 assertErrors(source, [HintCode.INVALID_ASSIGNMENT]); | |
| 3311 verify([source]); | |
| 3312 } | |
| 3313 | |
| 3314 void test_invalidAssignment_message() { | |
| 3315 // The implementation of HintCode.INVALID_ASSIGNMENT assumes that | |
| 3316 // StaticTypeWarningCode.INVALID_ASSIGNMENT has the same message. | |
| 3317 expect(StaticTypeWarningCode.INVALID_ASSIGNMENT.message, | |
| 3318 HintCode.INVALID_ASSIGNMENT.message); | |
| 3319 } | |
| 3320 | |
| 3321 void test_invalidAssignment_staticVariable() { | |
| 3322 Source source = addSource(r''' | |
| 3323 class A { | |
| 3324 static int x; | |
| 3325 } | |
| 3326 f(var y) { | |
| 3327 if(y is String) { | |
| 3328 A.x = y; | |
| 3329 } | |
| 3330 }'''); | |
| 3331 computeLibrarySourceErrors(source); | |
| 3332 assertErrors(source, [HintCode.INVALID_ASSIGNMENT]); | |
| 3333 verify([source]); | |
| 3334 } | |
| 3335 | |
| 3336 void test_invalidAssignment_variableDeclaration() { | |
| 3337 // 17971 | |
| 3338 Source source = addSource(r''' | |
| 3339 class Point { | |
| 3340 final num x, y; | |
| 3341 Point(this.x, this.y); | |
| 3342 Point operator +(Point other) { | |
| 3343 return new Point(x+other.x, y+other.y); | |
| 3344 } | |
| 3345 } | |
| 3346 main() { | |
| 3347 var p1 = new Point(0, 0); | |
| 3348 var p2 = new Point(10, 10); | |
| 3349 int n = p1 + p2; | |
| 3350 }'''); | |
| 3351 computeLibrarySourceErrors(source); | |
| 3352 assertErrors(source, [HintCode.INVALID_ASSIGNMENT]); | |
| 3353 verify([source]); | |
| 3354 } | |
| 3355 | |
| 3356 void test_invalidUseOfProtectedMember_field() { | |
| 3357 Source source = addSource(r''' | |
| 3358 import 'package:meta/meta.dart'; | |
| 3359 class A { | |
| 3360 @protected | |
| 3361 int a; | |
| 3362 } | |
| 3363 abstract class B implements A { | |
| 3364 int b() => a; | |
| 3365 }'''); | |
| 3366 computeLibrarySourceErrors(source); | |
| 3367 assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]); | |
| 3368 verify([source]); | |
| 3369 } | |
| 3370 | |
| 3371 void test_invalidUseOfProtectedMember_function() { | |
| 3372 Source source = addSource(r''' | |
| 3373 import 'package:meta/meta.dart'; | |
| 3374 class A { | |
| 3375 @protected | |
| 3376 void a(){ } | |
| 3377 } | |
| 3378 main() { | |
| 3379 new A().a(); | |
| 3380 }'''); | |
| 3381 computeLibrarySourceErrors(source); | |
| 3382 assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]); | |
| 3383 verify([source]); | |
| 3384 } | |
| 3385 | |
| 3386 void test_invalidUseOfProtectedMember_getter() { | |
| 3387 Source source = addSource(r''' | |
| 3388 import 'package:meta/meta.dart'; | |
| 3389 class A { | |
| 3390 @protected | |
| 3391 int get a => 42; | |
| 3392 } | |
| 3393 abstract class B implements A { | |
| 3394 int b() => a; | |
| 3395 }'''); | |
| 3396 computeLibrarySourceErrors(source); | |
| 3397 assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]); | |
| 3398 verify([source]); | |
| 3399 } | |
| 3400 | |
| 3401 void test_invalidUseOfProtectedMember_message() { | |
| 3402 Source source = addSource(r''' | |
| 3403 import 'package:meta/meta.dart'; | |
| 3404 class A { | |
| 3405 @protected | |
| 3406 void a(){ } | |
| 3407 } | |
| 3408 class B { | |
| 3409 void b() => new A().a(); | |
| 3410 }'''); | |
| 3411 List<AnalysisError> errors = analysisContext2.computeErrors(source); | |
| 3412 expect(errors, hasLength(1)); | |
| 3413 expect(errors[0].message, | |
| 3414 "The member 'a' can only be used within instance members of subclasses o
f 'A'"); | |
| 3415 } | |
| 3416 | |
| 3417 void test_invalidUseOfProtectedMember_method_1() { | |
| 3418 Source source = addSource(r''' | |
| 3419 import 'package:meta/meta.dart'; | |
| 3420 class A { | |
| 3421 @protected | |
| 3422 void a(){ } | |
| 3423 } | |
| 3424 class B { | |
| 3425 void b() => new A().a(); | |
| 3426 }'''); | |
| 3427 computeLibrarySourceErrors(source); | |
| 3428 assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]); | |
| 3429 verify([source]); | |
| 3430 } | |
| 3431 | |
| 3432 void test_invalidUseOfProtectedMember_method_2() { | |
| 3433 Source source = addSource(r''' | |
| 3434 import 'package:meta/meta.dart'; | |
| 3435 class A { | |
| 3436 @protected | |
| 3437 void a(){ } | |
| 3438 } | |
| 3439 abstract class B implements A { | |
| 3440 void b() => a(); | |
| 3441 }'''); | |
| 3442 computeLibrarySourceErrors(source); | |
| 3443 assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]); | |
| 3444 verify([source]); | |
| 3445 } | |
| 3446 | |
| 3447 void test_invalidUseOfProtectedMember_OK_1() { | |
| 3448 Source source = addSource(r''' | |
| 3449 import 'package:meta/meta.dart'; | |
| 3450 class A { | |
| 3451 @protected | |
| 3452 void a(){ } | |
| 3453 } | |
| 3454 class B extends A { | |
| 3455 void b() => a(); | |
| 3456 }'''); | |
| 3457 computeLibrarySourceErrors(source); | |
| 3458 assertErrors(source, []); | |
| 3459 verify([source]); | |
| 3460 } | |
| 3461 | |
| 3462 void test_invalidUseOfProtectedMember_OK_2() { | |
| 3463 Source source = addSource(r''' | |
| 3464 import 'package:meta/meta.dart'; | |
| 3465 class A { | |
| 3466 @protected | |
| 3467 void a(){ } | |
| 3468 } | |
| 3469 class B extends Object with A { | |
| 3470 void b() => a(); | |
| 3471 }'''); | |
| 3472 computeLibrarySourceErrors(source); | |
| 3473 assertErrors(source, []); | |
| 3474 verify([source]); | |
| 3475 } | |
| 3476 | |
| 3477 void test_invalidUseOfProtectedMember_OK_3() { | |
| 3478 Source source = addSource(r''' | |
| 3479 import 'package:meta/meta.dart'; | |
| 3480 class A { | |
| 3481 @protected m1() {} | |
| 3482 } | |
| 3483 class B extends A { | |
| 3484 static m2(A a) => a.m1(); | |
| 3485 }'''); | |
| 3486 computeLibrarySourceErrors(source); | |
| 3487 assertErrors(source, []); | |
| 3488 verify([source]); | |
| 3489 } | |
| 3490 | |
| 3491 void test_invalidUseOfProtectedMember_OK_4() { | |
| 3492 Source source = addSource(r''' | |
| 3493 import 'package:meta/meta.dart'; | |
| 3494 class A { | |
| 3495 @protected | |
| 3496 void a(){ } | |
| 3497 } | |
| 3498 class B extends A { | |
| 3499 void a() => a(); | |
| 3500 } | |
| 3501 main() { | |
| 3502 new B().a(); | |
| 3503 }'''); | |
| 3504 computeLibrarySourceErrors(source); | |
| 3505 assertErrors(source, []); | |
| 3506 verify([source]); | |
| 3507 } | |
| 3508 | |
| 3509 void test_invalidUseOfProtectedMember_OK_field() { | |
| 3510 Source source = addSource(r''' | |
| 3511 import 'package:meta/meta.dart'; | |
| 3512 class A { | |
| 3513 @protected | |
| 3514 int a = 42; | |
| 3515 } | |
| 3516 class B extends A { | |
| 3517 int b() => a; | |
| 3518 } | |
| 3519 '''); | |
| 3520 computeLibrarySourceErrors(source); | |
| 3521 assertErrors(source, []); | |
| 3522 verify([source]); | |
| 3523 } | |
| 3524 | |
| 3525 void test_invalidUseOfProtectedMember_OK_getter() { | |
| 3526 Source source = addSource(r''' | |
| 3527 import 'package:meta/meta.dart'; | |
| 3528 class A { | |
| 3529 @protected | |
| 3530 int get a => 42; | |
| 3531 } | |
| 3532 class B extends A { | |
| 3533 int b() => a; | |
| 3534 } | |
| 3535 '''); | |
| 3536 computeLibrarySourceErrors(source); | |
| 3537 assertErrors(source, []); | |
| 3538 verify([source]); | |
| 3539 } | |
| 3540 | |
| 3541 void test_invalidUseOfProtectedMember_OK_setter() { | |
| 3542 Source source = addSource(r''' | |
| 3543 import 'package:meta/meta.dart'; | |
| 3544 class A { | |
| 3545 @protected | |
| 3546 void set a(int i) { } | |
| 3547 } | |
| 3548 class B extends A { | |
| 3549 void b(int i) { | |
| 3550 a = i; | |
| 3551 } | |
| 3552 } | |
| 3553 '''); | |
| 3554 computeLibrarySourceErrors(source); | |
| 3555 assertErrors(source, []); | |
| 3556 verify([source]); | |
| 3557 } | |
| 3558 | |
| 3559 void test_invalidUseOfProtectedMember_setter() { | |
| 3560 Source source = addSource(r''' | |
| 3561 import 'package:meta/meta.dart'; | |
| 3562 class A { | |
| 3563 @protected | |
| 3564 void set a(int i) { } | |
| 3565 } | |
| 3566 abstract class B implements A { | |
| 3567 b(int i) { | |
| 3568 a = i; | |
| 3569 } | |
| 3570 }'''); | |
| 3571 computeLibrarySourceErrors(source); | |
| 3572 assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]); | |
| 3573 verify([source]); | |
| 3574 } | |
| 3575 | |
| 3576 void test_invalidUseOfProtectedMember_topLevelVariable() { | |
| 3577 Source source = addSource(r''' | |
| 3578 import 'package:meta/meta.dart'; | |
| 3579 @protected | |
| 3580 int x = 0; | |
| 3581 main() { | |
| 3582 print(x); | |
| 3583 }'''); | |
| 3584 computeLibrarySourceErrors(source); | |
| 3585 // TODO(brianwilkerson) This should produce a hint because the annotation is | |
| 3586 // being applied to the wrong kind of declaration. | |
| 3587 assertNoErrors(source); | |
| 3588 verify([source]); | |
| 3589 } | |
| 3590 | |
| 3591 void test_isDouble() { | |
| 3592 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); | |
| 3593 options.dart2jsHint = true; | |
| 3594 resetWithOptions(options); | |
| 3595 Source source = addSource("var v = 1 is double;"); | |
| 3596 computeLibrarySourceErrors(source); | |
| 3597 assertErrors(source, [HintCode.IS_DOUBLE]); | |
| 3598 verify([source]); | |
| 3599 } | |
| 3600 | |
| 3601 void test_isNotDouble() { | |
| 3602 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); | |
| 3603 options.dart2jsHint = true; | |
| 3604 resetWithOptions(options); | |
| 3605 Source source = addSource("var v = 1 is! double;"); | |
| 3606 computeLibrarySourceErrors(source); | |
| 3607 assertErrors(source, [HintCode.IS_NOT_DOUBLE]); | |
| 3608 verify([source]); | |
| 3609 } | |
| 3610 | |
| 3611 void test_missingReturn_async() { | |
| 3612 Source source = addSource(''' | |
| 3613 import 'dart:async'; | |
| 3614 Future<int> f() async {} | |
| 3615 '''); | |
| 3616 computeLibrarySourceErrors(source); | |
| 3617 assertErrors(source, [HintCode.MISSING_RETURN]); | |
| 3618 verify([source]); | |
| 3619 } | |
| 3620 | |
| 3621 void test_missingReturn_function() { | |
| 3622 Source source = addSource("int f() {}"); | |
| 3623 computeLibrarySourceErrors(source); | |
| 3624 assertErrors(source, [HintCode.MISSING_RETURN]); | |
| 3625 verify([source]); | |
| 3626 } | |
| 3627 | |
| 3628 void test_missingReturn_method() { | |
| 3629 Source source = addSource(r''' | |
| 3630 class A { | |
| 3631 int m() {} | |
| 3632 }'''); | |
| 3633 computeLibrarySourceErrors(source); | |
| 3634 assertErrors(source, [HintCode.MISSING_RETURN]); | |
| 3635 verify([source]); | |
| 3636 } | |
| 3637 | |
| 3638 void test_mustCallSuper() { | |
| 3639 Source source = addSource(r''' | |
| 3640 import 'package:meta/meta.dart'; | |
| 3641 class A { | |
| 3642 @mustCallSuper | |
| 3643 void a() {} | |
| 3644 } | |
| 3645 class B extends A { | |
| 3646 @override | |
| 3647 void a() | |
| 3648 {} | |
| 3649 } | |
| 3650 '''); | |
| 3651 computeLibrarySourceErrors(source); | |
| 3652 assertErrors(source, [HintCode.MUST_CALL_SUPER]); | |
| 3653 verify([source]); | |
| 3654 } | |
| 3655 | |
| 3656 void test_mustCallSuper_indirect() { | |
| 3657 Source source = addSource(r''' | |
| 3658 import 'package:meta/meta.dart'; | |
| 3659 class A { | |
| 3660 @mustCallSuper | |
| 3661 void a() {} | |
| 3662 } | |
| 3663 class C extends A { | |
| 3664 @override | |
| 3665 void a() { | |
| 3666 super.a(); | |
| 3667 } | |
| 3668 } | |
| 3669 class D extends C { | |
| 3670 @override | |
| 3671 void a() {} | |
| 3672 } | |
| 3673 '''); | |
| 3674 computeLibrarySourceErrors(source); | |
| 3675 assertErrors(source, [HintCode.MUST_CALL_SUPER]); | |
| 3676 verify([source]); | |
| 3677 } | |
| 3678 | |
| 3679 void test_mustCallSuper_OK() { | |
| 3680 Source source = addSource(r''' | |
| 3681 import 'package:meta/meta.dart'; | |
| 3682 class A { | |
| 3683 @mustCallSuper | |
| 3684 void a() {} | |
| 3685 } | |
| 3686 class C extends A { | |
| 3687 @override | |
| 3688 void a() { | |
| 3689 super.a(); //OK | |
| 3690 } | |
| 3691 } | |
| 3692 '''); | |
| 3693 computeLibrarySourceErrors(source); | |
| 3694 assertErrors(source, []); | |
| 3695 verify([source]); | |
| 3696 } | |
| 3697 | |
| 3698 @override | |
| 3699 void test_nullAwareInCondition_assert() { | |
| 3700 Source source = addSource(r''' | |
| 3701 m(x) { | |
| 3702 assert (x?.a); | |
| 3703 } | |
| 3704 '''); | |
| 3705 computeLibrarySourceErrors(source); | |
| 3706 assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]); | |
| 3707 verify([source]); | |
| 3708 } | |
| 3709 | |
| 3710 void test_nullAwareInCondition_conditionalExpression() { | |
| 3711 Source source = addSource(r''' | |
| 3712 m(x) { | |
| 3713 return x?.a ? 0 : 1; | |
| 3714 } | |
| 3715 '''); | |
| 3716 computeLibrarySourceErrors(source); | |
| 3717 assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]); | |
| 3718 verify([source]); | |
| 3719 } | |
| 3720 | |
| 3721 void test_nullAwareInCondition_do() { | |
| 3722 Source source = addSource(r''' | |
| 3723 m(x) { | |
| 3724 do {} while (x?.a); | |
| 3725 } | |
| 3726 '''); | |
| 3727 computeLibrarySourceErrors(source); | |
| 3728 assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]); | |
| 3729 verify([source]); | |
| 3730 } | |
| 3731 | |
| 3732 void test_nullAwareInCondition_for() { | |
| 3733 Source source = addSource(r''' | |
| 3734 m(x) { | |
| 3735 for (var v = x; v?.a; v = v.next) {} | |
| 3736 } | |
| 3737 '''); | |
| 3738 computeLibrarySourceErrors(source); | |
| 3739 assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]); | |
| 3740 verify([source]); | |
| 3741 } | |
| 3742 | |
| 3743 void test_nullAwareInCondition_if() { | |
| 3744 Source source = addSource(r''' | |
| 3745 m(x) { | |
| 3746 if (x?.a) {} | |
| 3747 } | |
| 3748 '''); | |
| 3749 computeLibrarySourceErrors(source); | |
| 3750 assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]); | |
| 3751 verify([source]); | |
| 3752 } | |
| 3753 | |
| 3754 void test_nullAwareInCondition_if_conditionalAnd_first() { | |
| 3755 Source source = addSource(r''' | |
| 3756 m(x) { | |
| 3757 if (x?.a && x.b) {} | |
| 3758 } | |
| 3759 '''); | |
| 3760 computeLibrarySourceErrors(source); | |
| 3761 assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]); | |
| 3762 verify([source]); | |
| 3763 } | |
| 3764 | |
| 3765 void test_nullAwareInCondition_if_conditionalAnd_second() { | |
| 3766 Source source = addSource(r''' | |
| 3767 m(x) { | |
| 3768 if (x.a && x?.b) {} | |
| 3769 } | |
| 3770 '''); | |
| 3771 computeLibrarySourceErrors(source); | |
| 3772 assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]); | |
| 3773 verify([source]); | |
| 3774 } | |
| 3775 | |
| 3776 void test_nullAwareInCondition_if_conditionalAnd_third() { | |
| 3777 Source source = addSource(r''' | |
| 3778 m(x) { | |
| 3779 if (x.a && x.b && x?.c) {} | |
| 3780 } | |
| 3781 '''); | |
| 3782 computeLibrarySourceErrors(source); | |
| 3783 assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]); | |
| 3784 verify([source]); | |
| 3785 } | |
| 3786 | |
| 3787 void test_nullAwareInCondition_if_conditionalOr_first() { | |
| 3788 Source source = addSource(r''' | |
| 3789 m(x) { | |
| 3790 if (x?.a || x.b) {} | |
| 3791 } | |
| 3792 '''); | |
| 3793 computeLibrarySourceErrors(source); | |
| 3794 assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]); | |
| 3795 verify([source]); | |
| 3796 } | |
| 3797 | |
| 3798 void test_nullAwareInCondition_if_conditionalOr_second() { | |
| 3799 Source source = addSource(r''' | |
| 3800 m(x) { | |
| 3801 if (x.a || x?.b) {} | |
| 3802 } | |
| 3803 '''); | |
| 3804 computeLibrarySourceErrors(source); | |
| 3805 assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]); | |
| 3806 verify([source]); | |
| 3807 } | |
| 3808 | |
| 3809 void test_nullAwareInCondition_if_conditionalOr_third() { | |
| 3810 Source source = addSource(r''' | |
| 3811 m(x) { | |
| 3812 if (x.a || x.b || x?.c) {} | |
| 3813 } | |
| 3814 '''); | |
| 3815 computeLibrarySourceErrors(source); | |
| 3816 assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]); | |
| 3817 verify([source]); | |
| 3818 } | |
| 3819 | |
| 3820 void test_nullAwareInCondition_if_not() { | |
| 3821 Source source = addSource(r''' | |
| 3822 m(x) { | |
| 3823 if (!x?.a) {} | |
| 3824 } | |
| 3825 '''); | |
| 3826 computeLibrarySourceErrors(source); | |
| 3827 assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]); | |
| 3828 verify([source]); | |
| 3829 } | |
| 3830 | |
| 3831 void test_nullAwareInCondition_if_parenthesized() { | |
| 3832 Source source = addSource(r''' | |
| 3833 m(x) { | |
| 3834 if ((x?.a)) {} | |
| 3835 } | |
| 3836 '''); | |
| 3837 computeLibrarySourceErrors(source); | |
| 3838 assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]); | |
| 3839 verify([source]); | |
| 3840 } | |
| 3841 | |
| 3842 void test_nullAwareInCondition_while() { | |
| 3843 Source source = addSource(r''' | |
| 3844 m(x) { | |
| 3845 while (x?.a) {} | |
| 3846 } | |
| 3847 '''); | |
| 3848 computeLibrarySourceErrors(source); | |
| 3849 assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]); | |
| 3850 verify([source]); | |
| 3851 } | |
| 3852 | |
| 3853 void test_overrideOnNonOverridingGetter_invalid() { | |
| 3854 Source source = addSource(r''' | |
| 3855 library dart.core; | |
| 3856 const override = null; | |
| 3857 class A { | |
| 3858 } | |
| 3859 class B extends A { | |
| 3860 @override | |
| 3861 int get m => 1; | |
| 3862 }'''); | |
| 3863 computeLibrarySourceErrors(source); | |
| 3864 assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER]); | |
| 3865 verify([source]); | |
| 3866 } | |
| 3867 | |
| 3868 void test_overrideOnNonOverridingMethod_invalid() { | |
| 3869 Source source = addSource(r''' | |
| 3870 library dart.core; | |
| 3871 const override = null; | |
| 3872 class A { | |
| 3873 } | |
| 3874 class B extends A { | |
| 3875 @override | |
| 3876 int m() => 1; | |
| 3877 }'''); | |
| 3878 computeLibrarySourceErrors(source); | |
| 3879 assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD]); | |
| 3880 verify([source]); | |
| 3881 } | |
| 3882 | |
| 3883 void test_overrideOnNonOverridingSetter_invalid() { | |
| 3884 Source source = addSource(r''' | |
| 3885 library dart.core; | |
| 3886 const override = null; | |
| 3887 class A { | |
| 3888 } | |
| 3889 class B extends A { | |
| 3890 @override | |
| 3891 set m(int x) {} | |
| 3892 }'''); | |
| 3893 computeLibrarySourceErrors(source); | |
| 3894 assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER]); | |
| 3895 verify([source]); | |
| 3896 } | |
| 3897 | |
| 3898 void test_typeCheck_type_is_Null() { | |
| 3899 Source source = addSource(r''' | |
| 3900 m(i) { | |
| 3901 bool b = i is Null; | |
| 3902 }'''); | |
| 3903 computeLibrarySourceErrors(source); | |
| 3904 assertErrors(source, [HintCode.TYPE_CHECK_IS_NULL]); | |
| 3905 verify([source]); | |
| 3906 } | |
| 3907 | |
| 3908 void test_typeCheck_type_not_Null() { | |
| 3909 Source source = addSource(r''' | |
| 3910 m(i) { | |
| 3911 bool b = i is! Null; | |
| 3912 }'''); | |
| 3913 computeLibrarySourceErrors(source); | |
| 3914 assertErrors(source, [HintCode.TYPE_CHECK_IS_NOT_NULL]); | |
| 3915 verify([source]); | |
| 3916 } | |
| 3917 | |
| 3918 void test_undefinedGetter() { | |
| 3919 Source source = addSource(r''' | |
| 3920 class A {} | |
| 3921 f(var a) { | |
| 3922 if(a is A) { | |
| 3923 return a.m; | |
| 3924 } | |
| 3925 }'''); | |
| 3926 computeLibrarySourceErrors(source); | |
| 3927 assertErrors(source, [HintCode.UNDEFINED_GETTER]); | |
| 3928 } | |
| 3929 | |
| 3930 void test_undefinedGetter_message() { | |
| 3931 // The implementation of HintCode.UNDEFINED_SETTER assumes that | |
| 3932 // UNDEFINED_SETTER in StaticTypeWarningCode and StaticWarningCode are the | |
| 3933 // same, this verifies that assumption. | |
| 3934 expect(StaticWarningCode.UNDEFINED_GETTER.message, | |
| 3935 StaticTypeWarningCode.UNDEFINED_GETTER.message); | |
| 3936 } | |
| 3937 | |
| 3938 void test_undefinedMethod() { | |
| 3939 Source source = addSource(r''' | |
| 3940 f() { | |
| 3941 var a = 'str'; | |
| 3942 a.notAMethodOnString(); | |
| 3943 }'''); | |
| 3944 computeLibrarySourceErrors(source); | |
| 3945 assertErrors(source, [HintCode.UNDEFINED_METHOD]); | |
| 3946 } | |
| 3947 | |
| 3948 void test_undefinedMethod_assignmentExpression() { | |
| 3949 Source source = addSource(r''' | |
| 3950 class A {} | |
| 3951 class B { | |
| 3952 f(var a, var a2) { | |
| 3953 a = new A(); | |
| 3954 a2 = new A(); | |
| 3955 a += a2; | |
| 3956 } | |
| 3957 }'''); | |
| 3958 computeLibrarySourceErrors(source); | |
| 3959 assertErrors(source, [HintCode.UNDEFINED_METHOD]); | |
| 3960 } | |
| 3961 | |
| 3962 void test_undefinedOperator_binaryExpression() { | |
| 3963 Source source = addSource(r''' | |
| 3964 class A {} | |
| 3965 f(var a) { | |
| 3966 if(a is A) { | |
| 3967 a + 1; | |
| 3968 } | |
| 3969 }'''); | |
| 3970 computeLibrarySourceErrors(source); | |
| 3971 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]); | |
| 3972 } | |
| 3973 | |
| 3974 void test_undefinedOperator_indexBoth() { | |
| 3975 Source source = addSource(r''' | |
| 3976 class A {} | |
| 3977 f(var a) { | |
| 3978 if(a is A) { | |
| 3979 a[0]++; | |
| 3980 } | |
| 3981 }'''); | |
| 3982 computeLibrarySourceErrors(source); | |
| 3983 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]); | |
| 3984 } | |
| 3985 | |
| 3986 void test_undefinedOperator_indexGetter() { | |
| 3987 Source source = addSource(r''' | |
| 3988 class A {} | |
| 3989 f(var a) { | |
| 3990 if(a is A) { | |
| 3991 a[0]; | |
| 3992 } | |
| 3993 }'''); | |
| 3994 computeLibrarySourceErrors(source); | |
| 3995 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]); | |
| 3996 } | |
| 3997 | |
| 3998 void test_undefinedOperator_indexSetter() { | |
| 3999 Source source = addSource(r''' | |
| 4000 class A {} | |
| 4001 f(var a) { | |
| 4002 if(a is A) { | |
| 4003 a[0] = 1; | |
| 4004 } | |
| 4005 }'''); | |
| 4006 computeLibrarySourceErrors(source); | |
| 4007 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]); | |
| 4008 } | |
| 4009 | |
| 4010 void test_undefinedOperator_postfixExpression() { | |
| 4011 Source source = addSource(r''' | |
| 4012 class A {} | |
| 4013 f(var a) { | |
| 4014 if(a is A) { | |
| 4015 a++; | |
| 4016 } | |
| 4017 }'''); | |
| 4018 computeLibrarySourceErrors(source); | |
| 4019 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]); | |
| 4020 } | |
| 4021 | |
| 4022 void test_undefinedOperator_prefixExpression() { | |
| 4023 Source source = addSource(r''' | |
| 4024 class A {} | |
| 4025 f(var a) { | |
| 4026 if(a is A) { | |
| 4027 ++a; | |
| 4028 } | |
| 4029 }'''); | |
| 4030 computeLibrarySourceErrors(source); | |
| 4031 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]); | |
| 4032 } | |
| 4033 | |
| 4034 void test_undefinedSetter() { | |
| 4035 Source source = addSource(r''' | |
| 4036 class A {} | |
| 4037 f(var a) { | |
| 4038 if(a is A) { | |
| 4039 a.m = 0; | |
| 4040 } | |
| 4041 }'''); | |
| 4042 computeLibrarySourceErrors(source); | |
| 4043 assertErrors(source, [HintCode.UNDEFINED_SETTER]); | |
| 4044 } | |
| 4045 | |
| 4046 void test_undefinedSetter_message() { | |
| 4047 // The implementation of HintCode.UNDEFINED_SETTER assumes that | |
| 4048 // UNDEFINED_SETTER in StaticTypeWarningCode and StaticWarningCode are the | |
| 4049 // same, this verifies that assumption. | |
| 4050 expect(StaticWarningCode.UNDEFINED_SETTER.message, | |
| 4051 StaticTypeWarningCode.UNDEFINED_SETTER.message); | |
| 4052 } | |
| 4053 | |
| 4054 void test_unnecessaryCast_type_supertype() { | |
| 4055 Source source = addSource(r''' | |
| 4056 m(int i) { | |
| 4057 var b = i as Object; | |
| 4058 }'''); | |
| 4059 computeLibrarySourceErrors(source); | |
| 4060 assertErrors(source, [HintCode.UNNECESSARY_CAST]); | |
| 4061 verify([source]); | |
| 4062 } | |
| 4063 | |
| 4064 void test_unnecessaryCast_type_type() { | |
| 4065 Source source = addSource(r''' | |
| 4066 m(num i) { | |
| 4067 var b = i as num; | |
| 4068 }'''); | |
| 4069 computeLibrarySourceErrors(source); | |
| 4070 assertErrors(source, [HintCode.UNNECESSARY_CAST]); | |
| 4071 verify([source]); | |
| 4072 } | |
| 4073 | |
| 4074 void test_unnecessaryNoSuchMethod_blockBody() { | |
| 4075 Source source = addSource(r''' | |
| 4076 class A { | |
| 4077 noSuchMethod(x) => super.noSuchMethod(x); | |
| 4078 } | |
| 4079 class B extends A { | |
| 4080 mmm(); | |
| 4081 noSuchMethod(y) { | |
| 4082 return super.noSuchMethod(y); | |
| 4083 } | |
| 4084 }'''); | |
| 4085 computeLibrarySourceErrors(source); | |
| 4086 assertErrors(source, [HintCode.UNNECESSARY_NO_SUCH_METHOD]); | |
| 4087 verify([source]); | |
| 4088 } | |
| 4089 | |
| 4090 void test_unnecessaryNoSuchMethod_expressionBody() { | |
| 4091 Source source = addSource(r''' | |
| 4092 class A { | |
| 4093 noSuchMethod(x) => super.noSuchMethod(x); | |
| 4094 } | |
| 4095 class B extends A { | |
| 4096 mmm(); | |
| 4097 noSuchMethod(y) => super.noSuchMethod(y); | |
| 4098 }'''); | |
| 4099 computeLibrarySourceErrors(source); | |
| 4100 assertErrors(source, [HintCode.UNNECESSARY_NO_SUCH_METHOD]); | |
| 4101 verify([source]); | |
| 4102 } | |
| 4103 | |
| 4104 void test_unnecessaryTypeCheck_null_is_Null() { | |
| 4105 Source source = addSource("bool b = null is Null;"); | |
| 4106 computeLibrarySourceErrors(source); | |
| 4107 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]); | |
| 4108 verify([source]); | |
| 4109 } | |
| 4110 | |
| 4111 void test_unnecessaryTypeCheck_null_not_Null() { | |
| 4112 Source source = addSource("bool b = null is! Null;"); | |
| 4113 computeLibrarySourceErrors(source); | |
| 4114 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]); | |
| 4115 verify([source]); | |
| 4116 } | |
| 4117 | |
| 4118 void test_unnecessaryTypeCheck_type_is_dynamic() { | |
| 4119 Source source = addSource(r''' | |
| 4120 m(i) { | |
| 4121 bool b = i is dynamic; | |
| 4122 }'''); | |
| 4123 computeLibrarySourceErrors(source); | |
| 4124 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]); | |
| 4125 verify([source]); | |
| 4126 } | |
| 4127 | |
| 4128 void test_unnecessaryTypeCheck_type_is_object() { | |
| 4129 Source source = addSource(r''' | |
| 4130 m(i) { | |
| 4131 bool b = i is Object; | |
| 4132 }'''); | |
| 4133 computeLibrarySourceErrors(source); | |
| 4134 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]); | |
| 4135 verify([source]); | |
| 4136 } | |
| 4137 | |
| 4138 void test_unnecessaryTypeCheck_type_not_dynamic() { | |
| 4139 Source source = addSource(r''' | |
| 4140 m(i) { | |
| 4141 bool b = i is! dynamic; | |
| 4142 }'''); | |
| 4143 computeLibrarySourceErrors(source); | |
| 4144 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]); | |
| 4145 verify([source]); | |
| 4146 } | |
| 4147 | |
| 4148 void test_unnecessaryTypeCheck_type_not_object() { | |
| 4149 Source source = addSource(r''' | |
| 4150 m(i) { | |
| 4151 bool b = i is! Object; | |
| 4152 }'''); | |
| 4153 computeLibrarySourceErrors(source); | |
| 4154 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]); | |
| 4155 verify([source]); | |
| 4156 } | |
| 4157 | |
| 4158 void test_unusedElement_class_isUsed_extends() { | |
| 4159 enableUnusedElement = true; | |
| 4160 Source source = addSource(r''' | |
| 4161 class _A {} | |
| 4162 class B extends _A {} | |
| 4163 '''); | |
| 4164 computeLibrarySourceErrors(source); | |
| 4165 assertNoErrors(source); | |
| 4166 verify([source]); | |
| 4167 } | |
| 4168 | |
| 4169 void test_unusedElement_class_isUsed_fieldDeclaration() { | |
| 4170 enableUnusedElement = true; | |
| 4171 var src = r''' | |
| 4172 class Foo { | |
| 4173 _Bar x; | |
| 4174 } | |
| 4175 | |
| 4176 class _Bar { | |
| 4177 } | |
| 4178 '''; | |
| 4179 Source source = addSource(src); | |
| 4180 computeLibrarySourceErrors(source); | |
| 4181 assertNoErrors(source); | |
| 4182 verify([source]); | |
| 4183 } | |
| 4184 | |
| 4185 void test_unusedElement_class_isUsed_implements() { | |
| 4186 enableUnusedElement = true; | |
| 4187 Source source = addSource(r''' | |
| 4188 class _A {} | |
| 4189 class B implements _A {} | |
| 4190 '''); | |
| 4191 computeLibrarySourceErrors(source); | |
| 4192 assertNoErrors(source); | |
| 4193 verify([source]); | |
| 4194 } | |
| 4195 | |
| 4196 void test_unusedElement_class_isUsed_instanceCreation() { | |
| 4197 enableUnusedElement = true; | |
| 4198 Source source = addSource(r''' | |
| 4199 class _A {} | |
| 4200 main() { | |
| 4201 new _A(); | |
| 4202 }'''); | |
| 4203 computeLibrarySourceErrors(source); | |
| 4204 assertNoErrors(source); | |
| 4205 verify([source]); | |
| 4206 } | |
| 4207 | |
| 4208 void test_unusedElement_class_isUsed_staticFieldAccess() { | |
| 4209 enableUnusedElement = true; | |
| 4210 Source source = addSource(r''' | |
| 4211 class _A { | |
| 4212 static const F = 42; | |
| 4213 } | |
| 4214 main() { | |
| 4215 _A.F; | |
| 4216 }'''); | |
| 4217 computeLibrarySourceErrors(source); | |
| 4218 assertNoErrors(source); | |
| 4219 verify([source]); | |
| 4220 } | |
| 4221 | |
| 4222 void test_unusedElement_class_isUsed_staticMethodInvocation() { | |
| 4223 enableUnusedElement = true; | |
| 4224 Source source = addSource(r''' | |
| 4225 class _A { | |
| 4226 static m() {} | |
| 4227 } | |
| 4228 main() { | |
| 4229 _A.m(); | |
| 4230 }'''); | |
| 4231 computeLibrarySourceErrors(source); | |
| 4232 assertNoErrors(source); | |
| 4233 verify([source]); | |
| 4234 } | |
| 4235 | |
| 4236 void test_unusedElement_class_isUsed_typeArgument() { | |
| 4237 enableUnusedElement = true; | |
| 4238 Source source = addSource(r''' | |
| 4239 class _A {} | |
| 4240 main() { | |
| 4241 var v = new List<_A>(); | |
| 4242 print(v); | |
| 4243 }'''); | |
| 4244 computeLibrarySourceErrors(source); | |
| 4245 assertNoErrors(source); | |
| 4246 verify([source]); | |
| 4247 } | |
| 4248 | |
| 4249 void test_unusedElement_class_notUsed_inClassMember() { | |
| 4250 enableUnusedElement = true; | |
| 4251 Source source = addSource(r''' | |
| 4252 class _A { | |
| 4253 static staticMethod() { | |
| 4254 new _A(); | |
| 4255 } | |
| 4256 instanceMethod() { | |
| 4257 new _A(); | |
| 4258 } | |
| 4259 } | |
| 4260 '''); | |
| 4261 computeLibrarySourceErrors(source); | |
| 4262 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 4263 verify([source]); | |
| 4264 } | |
| 4265 | |
| 4266 void test_unusedElement_class_notUsed_inConstructorName() { | |
| 4267 enableUnusedElement = true; | |
| 4268 Source source = addSource(r''' | |
| 4269 class _A { | |
| 4270 _A() {} | |
| 4271 _A.named() {} | |
| 4272 } | |
| 4273 '''); | |
| 4274 computeLibrarySourceErrors(source); | |
| 4275 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 4276 verify([source]); | |
| 4277 } | |
| 4278 | |
| 4279 void test_unusedElement_class_notUsed_isExpression() { | |
| 4280 enableUnusedElement = true; | |
| 4281 Source source = addSource(r''' | |
| 4282 class _A {} | |
| 4283 main(p) { | |
| 4284 if (p is _A) { | |
| 4285 } | |
| 4286 } | |
| 4287 '''); | |
| 4288 computeLibrarySourceErrors(source); | |
| 4289 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 4290 verify([source]); | |
| 4291 } | |
| 4292 | |
| 4293 void test_unusedElement_class_notUsed_noReference() { | |
| 4294 enableUnusedElement = true; | |
| 4295 Source source = addSource(r''' | |
| 4296 class _A {} | |
| 4297 main() { | |
| 4298 }'''); | |
| 4299 computeLibrarySourceErrors(source); | |
| 4300 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 4301 verify([source]); | |
| 4302 } | |
| 4303 | |
| 4304 void test_unusedElement_class_notUsed_variableDeclaration() { | |
| 4305 enableUnusedElement = true; | |
| 4306 Source source = addSource(r''' | |
| 4307 class _A {} | |
| 4308 main() { | |
| 4309 _A v; | |
| 4310 print(v); | |
| 4311 } | |
| 4312 print(x) {} | |
| 4313 '''); | |
| 4314 computeLibrarySourceErrors(source); | |
| 4315 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 4316 verify([source]); | |
| 4317 } | |
| 4318 | |
| 4319 void test_unusedElement_enum_isUsed_fieldReference() { | |
| 4320 enableUnusedElement = true; | |
| 4321 Source source = addSource(r''' | |
| 4322 enum _MyEnum {A, B, C} | |
| 4323 main() { | |
| 4324 print(_MyEnum.B); | |
| 4325 }'''); | |
| 4326 computeLibrarySourceErrors(source); | |
| 4327 assertNoErrors(source); | |
| 4328 verify([source]); | |
| 4329 } | |
| 4330 | |
| 4331 void test_unusedElement_enum_notUsed_noReference() { | |
| 4332 enableUnusedElement = true; | |
| 4333 Source source = addSource(r''' | |
| 4334 enum _MyEnum {A, B, C} | |
| 4335 main() { | |
| 4336 }'''); | |
| 4337 computeLibrarySourceErrors(source); | |
| 4338 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 4339 verify([source]); | |
| 4340 } | |
| 4341 | |
| 4342 void test_unusedElement_functionLocal_isUsed_closure() { | |
| 4343 enableUnusedElement = true; | |
| 4344 Source source = addSource(r''' | |
| 4345 main() { | |
| 4346 print(() {}); | |
| 4347 } | |
| 4348 print(x) {} | |
| 4349 '''); | |
| 4350 computeLibrarySourceErrors(source); | |
| 4351 assertNoErrors(source); | |
| 4352 verify([source]); | |
| 4353 } | |
| 4354 | |
| 4355 void test_unusedElement_functionLocal_isUsed_invocation() { | |
| 4356 enableUnusedElement = true; | |
| 4357 Source source = addSource(r''' | |
| 4358 main() { | |
| 4359 f() {} | |
| 4360 f(); | |
| 4361 }'''); | |
| 4362 computeLibrarySourceErrors(source); | |
| 4363 assertNoErrors(source); | |
| 4364 verify([source]); | |
| 4365 } | |
| 4366 | |
| 4367 void test_unusedElement_functionLocal_isUsed_reference() { | |
| 4368 enableUnusedElement = true; | |
| 4369 Source source = addSource(r''' | |
| 4370 main() { | |
| 4371 f() {} | |
| 4372 print(f); | |
| 4373 } | |
| 4374 print(x) {} | |
| 4375 '''); | |
| 4376 computeLibrarySourceErrors(source); | |
| 4377 assertNoErrors(source); | |
| 4378 verify([source]); | |
| 4379 } | |
| 4380 | |
| 4381 void test_unusedElement_functionLocal_notUsed_noReference() { | |
| 4382 enableUnusedElement = true; | |
| 4383 Source source = addSource(r''' | |
| 4384 main() { | |
| 4385 f() {} | |
| 4386 }'''); | |
| 4387 computeLibrarySourceErrors(source); | |
| 4388 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 4389 verify([source]); | |
| 4390 } | |
| 4391 | |
| 4392 void test_unusedElement_functionLocal_notUsed_referenceFromItself() { | |
| 4393 enableUnusedElement = true; | |
| 4394 Source source = addSource(r''' | |
| 4395 main() { | |
| 4396 _f(int p) { | |
| 4397 _f(p - 1); | |
| 4398 } | |
| 4399 }'''); | |
| 4400 computeLibrarySourceErrors(source); | |
| 4401 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 4402 verify([source]); | |
| 4403 } | |
| 4404 | |
| 4405 void test_unusedElement_functionTop_isUsed_invocation() { | |
| 4406 enableUnusedElement = true; | |
| 4407 Source source = addSource(r''' | |
| 4408 _f() {} | |
| 4409 main() { | |
| 4410 _f(); | |
| 4411 }'''); | |
| 4412 computeLibrarySourceErrors(source); | |
| 4413 assertNoErrors(source); | |
| 4414 verify([source]); | |
| 4415 } | |
| 4416 | |
| 4417 void test_unusedElement_functionTop_isUsed_reference() { | |
| 4418 enableUnusedElement = true; | |
| 4419 Source source = addSource(r''' | |
| 4420 _f() {} | |
| 4421 main() { | |
| 4422 print(_f); | |
| 4423 } | |
| 4424 print(x) {} | |
| 4425 '''); | |
| 4426 computeLibrarySourceErrors(source); | |
| 4427 assertNoErrors(source); | |
| 4428 verify([source]); | |
| 4429 } | |
| 4430 | |
| 4431 void test_unusedElement_functionTop_notUsed_noReference() { | |
| 4432 enableUnusedElement = true; | |
| 4433 Source source = addSource(r''' | |
| 4434 _f() {} | |
| 4435 main() { | |
| 4436 }'''); | |
| 4437 computeLibrarySourceErrors(source); | |
| 4438 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 4439 verify([source]); | |
| 4440 } | |
| 4441 | |
| 4442 void test_unusedElement_functionTop_notUsed_referenceFromItself() { | |
| 4443 enableUnusedElement = true; | |
| 4444 Source source = addSource(r''' | |
| 4445 _f(int p) { | |
| 4446 _f(p - 1); | |
| 4447 } | |
| 4448 main() { | |
| 4449 }'''); | |
| 4450 computeLibrarySourceErrors(source); | |
| 4451 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 4452 verify([source]); | |
| 4453 } | |
| 4454 | |
| 4455 void test_unusedElement_functionTypeAlias_isUsed_isExpression() { | |
| 4456 enableUnusedElement = true; | |
| 4457 Source source = addSource(r''' | |
| 4458 typedef _F(a, b); | |
| 4459 main(f) { | |
| 4460 if (f is _F) { | |
| 4461 print('F'); | |
| 4462 } | |
| 4463 }'''); | |
| 4464 computeLibrarySourceErrors(source); | |
| 4465 assertNoErrors(source); | |
| 4466 verify([source]); | |
| 4467 } | |
| 4468 | |
| 4469 void test_unusedElement_functionTypeAlias_isUsed_reference() { | |
| 4470 enableUnusedElement = true; | |
| 4471 Source source = addSource(r''' | |
| 4472 typedef _F(a, b); | |
| 4473 main(_F f) { | |
| 4474 }'''); | |
| 4475 computeLibrarySourceErrors(source); | |
| 4476 assertNoErrors(source); | |
| 4477 verify([source]); | |
| 4478 } | |
| 4479 | |
| 4480 void test_unusedElement_functionTypeAlias_isUsed_typeArgument() { | |
| 4481 enableUnusedElement = true; | |
| 4482 Source source = addSource(r''' | |
| 4483 typedef _F(a, b); | |
| 4484 main() { | |
| 4485 var v = new List<_F>(); | |
| 4486 print(v); | |
| 4487 }'''); | |
| 4488 computeLibrarySourceErrors(source); | |
| 4489 assertNoErrors(source); | |
| 4490 verify([source]); | |
| 4491 } | |
| 4492 | |
| 4493 void test_unusedElement_functionTypeAlias_isUsed_variableDeclaration() { | |
| 4494 enableUnusedElement = true; | |
| 4495 Source source = addSource(r''' | |
| 4496 typedef _F(a, b); | |
| 4497 class A { | |
| 4498 _F f; | |
| 4499 }'''); | |
| 4500 computeLibrarySourceErrors(source); | |
| 4501 assertNoErrors(source); | |
| 4502 verify([source]); | |
| 4503 } | |
| 4504 | |
| 4505 void test_unusedElement_functionTypeAlias_notUsed_noReference() { | |
| 4506 enableUnusedElement = true; | |
| 4507 Source source = addSource(r''' | |
| 4508 typedef _F(a, b); | |
| 4509 main() { | |
| 4510 }'''); | |
| 4511 computeLibrarySourceErrors(source); | |
| 4512 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 4513 verify([source]); | |
| 4514 } | |
| 4515 | |
| 4516 void test_unusedElement_getter_isUsed_invocation_implicitThis() { | |
| 4517 enableUnusedElement = true; | |
| 4518 Source source = addSource(r''' | |
| 4519 class A { | |
| 4520 get _g => null; | |
| 4521 useGetter() { | |
| 4522 var v = _g; | |
| 4523 } | |
| 4524 }'''); | |
| 4525 computeLibrarySourceErrors(source); | |
| 4526 assertNoErrors(source); | |
| 4527 verify([source]); | |
| 4528 } | |
| 4529 | |
| 4530 void test_unusedElement_getter_isUsed_invocation_PrefixedIdentifier() { | |
| 4531 enableUnusedElement = true; | |
| 4532 Source source = addSource(r''' | |
| 4533 class A { | |
| 4534 get _g => null; | |
| 4535 } | |
| 4536 main(A a) { | |
| 4537 var v = a._g; | |
| 4538 } | |
| 4539 '''); | |
| 4540 computeLibrarySourceErrors(source); | |
| 4541 assertNoErrors(source); | |
| 4542 verify([source]); | |
| 4543 } | |
| 4544 | |
| 4545 void test_unusedElement_getter_isUsed_invocation_PropertyAccess() { | |
| 4546 enableUnusedElement = true; | |
| 4547 Source source = addSource(r''' | |
| 4548 class A { | |
| 4549 get _g => null; | |
| 4550 } | |
| 4551 main() { | |
| 4552 var v = new A()._g; | |
| 4553 } | |
| 4554 '''); | |
| 4555 computeLibrarySourceErrors(source); | |
| 4556 assertNoErrors(source); | |
| 4557 verify([source]); | |
| 4558 } | |
| 4559 | |
| 4560 void test_unusedElement_getter_notUsed_noReference() { | |
| 4561 enableUnusedElement = true; | |
| 4562 Source source = addSource(r''' | |
| 4563 class A { | |
| 4564 get _g => null; | |
| 4565 }'''); | |
| 4566 computeLibrarySourceErrors(source); | |
| 4567 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 4568 verify([source]); | |
| 4569 } | |
| 4570 | |
| 4571 void test_unusedElement_getter_notUsed_referenceFromItself() { | |
| 4572 enableUnusedElement = true; | |
| 4573 Source source = addSource(r''' | |
| 4574 class A { | |
| 4575 get _g { | |
| 4576 return _g; | |
| 4577 } | |
| 4578 }'''); | |
| 4579 computeLibrarySourceErrors(source); | |
| 4580 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 4581 verify([source]); | |
| 4582 } | |
| 4583 | |
| 4584 void test_unusedElement_method_isUsed_hasReference_implicitThis() { | |
| 4585 enableUnusedElement = true; | |
| 4586 Source source = addSource(r''' | |
| 4587 class A { | |
| 4588 _m() {} | |
| 4589 useMethod() { | |
| 4590 print(_m); | |
| 4591 } | |
| 4592 } | |
| 4593 print(x) {} | |
| 4594 '''); | |
| 4595 computeLibrarySourceErrors(source); | |
| 4596 assertNoErrors(source); | |
| 4597 verify([source]); | |
| 4598 } | |
| 4599 | |
| 4600 void test_unusedElement_method_isUsed_hasReference_implicitThis_subclass() { | |
| 4601 enableUnusedElement = true; | |
| 4602 Source source = addSource(r''' | |
| 4603 class A { | |
| 4604 _m() {} | |
| 4605 useMethod() { | |
| 4606 print(_m); | |
| 4607 } | |
| 4608 } | |
| 4609 class B extends A { | |
| 4610 _m() {} | |
| 4611 } | |
| 4612 print(x) {} | |
| 4613 '''); | |
| 4614 computeLibrarySourceErrors(source); | |
| 4615 assertNoErrors(source); | |
| 4616 verify([source]); | |
| 4617 } | |
| 4618 | |
| 4619 void test_unusedElement_method_isUsed_hasReference_PrefixedIdentifier() { | |
| 4620 enableUnusedElement = true; | |
| 4621 Source source = addSource(r''' | |
| 4622 class A { | |
| 4623 _m() {} | |
| 4624 } | |
| 4625 main(A a) { | |
| 4626 a._m; | |
| 4627 }'''); | |
| 4628 computeLibrarySourceErrors(source); | |
| 4629 assertNoErrors(source); | |
| 4630 verify([source]); | |
| 4631 } | |
| 4632 | |
| 4633 void test_unusedElement_method_isUsed_hasReference_PropertyAccess() { | |
| 4634 enableUnusedElement = true; | |
| 4635 Source source = addSource(r''' | |
| 4636 class A { | |
| 4637 _m() {} | |
| 4638 } | |
| 4639 main() { | |
| 4640 new A()._m; | |
| 4641 }'''); | |
| 4642 computeLibrarySourceErrors(source); | |
| 4643 assertNoErrors(source); | |
| 4644 verify([source]); | |
| 4645 } | |
| 4646 | |
| 4647 void test_unusedElement_method_isUsed_invocation_implicitThis() { | |
| 4648 enableUnusedElement = true; | |
| 4649 Source source = addSource(r''' | |
| 4650 class A { | |
| 4651 _m() {} | |
| 4652 useMethod() { | |
| 4653 _m(); | |
| 4654 } | |
| 4655 }'''); | |
| 4656 computeLibrarySourceErrors(source); | |
| 4657 assertNoErrors(source); | |
| 4658 verify([source]); | |
| 4659 } | |
| 4660 | |
| 4661 void test_unusedElement_method_isUsed_invocation_implicitThis_subclass() { | |
| 4662 enableUnusedElement = true; | |
| 4663 Source source = addSource(r''' | |
| 4664 class A { | |
| 4665 _m() {} | |
| 4666 useMethod() { | |
| 4667 _m(); | |
| 4668 } | |
| 4669 } | |
| 4670 class B extends A { | |
| 4671 _m() {} | |
| 4672 }'''); | |
| 4673 computeLibrarySourceErrors(source); | |
| 4674 assertNoErrors(source); | |
| 4675 verify([source]); | |
| 4676 } | |
| 4677 | |
| 4678 void test_unusedElement_method_isUsed_invocation_MemberElement() { | |
| 4679 enableUnusedElement = true; | |
| 4680 Source source = addSource(r''' | |
| 4681 class A<T> { | |
| 4682 _m(T t) {} | |
| 4683 } | |
| 4684 main(A<int> a) { | |
| 4685 a._m(0); | |
| 4686 }'''); | |
| 4687 computeLibrarySourceErrors(source); | |
| 4688 assertNoErrors(source); | |
| 4689 verify([source]); | |
| 4690 } | |
| 4691 | |
| 4692 void test_unusedElement_method_isUsed_invocation_propagated() { | |
| 4693 enableUnusedElement = true; | |
| 4694 Source source = addSource(r''' | |
| 4695 class A { | |
| 4696 _m() {} | |
| 4697 } | |
| 4698 main() { | |
| 4699 var a = new A(); | |
| 4700 a._m(); | |
| 4701 }'''); | |
| 4702 computeLibrarySourceErrors(source); | |
| 4703 assertNoErrors(source); | |
| 4704 verify([source]); | |
| 4705 } | |
| 4706 | |
| 4707 void test_unusedElement_method_isUsed_invocation_static() { | |
| 4708 enableUnusedElement = true; | |
| 4709 Source source = addSource(r''' | |
| 4710 class A { | |
| 4711 _m() {} | |
| 4712 } | |
| 4713 main() { | |
| 4714 A a = new A(); | |
| 4715 a._m(); | |
| 4716 }'''); | |
| 4717 computeLibrarySourceErrors(source); | |
| 4718 assertNoErrors(source); | |
| 4719 verify([source]); | |
| 4720 } | |
| 4721 | |
| 4722 void test_unusedElement_method_isUsed_invocation_subclass() { | |
| 4723 enableUnusedElement = true; | |
| 4724 Source source = addSource(r''' | |
| 4725 class A { | |
| 4726 _m() {} | |
| 4727 } | |
| 4728 class B extends A { | |
| 4729 _m() {} | |
| 4730 } | |
| 4731 main(A a) { | |
| 4732 a._m(); | |
| 4733 }'''); | |
| 4734 computeLibrarySourceErrors(source); | |
| 4735 assertNoErrors(source); | |
| 4736 verify([source]); | |
| 4737 } | |
| 4738 | |
| 4739 void test_unusedElement_method_isUsed_notPrivate() { | |
| 4740 enableUnusedElement = true; | |
| 4741 Source source = addSource(r''' | |
| 4742 class A { | |
| 4743 m() {} | |
| 4744 } | |
| 4745 main() { | |
| 4746 }'''); | |
| 4747 computeLibrarySourceErrors(source); | |
| 4748 assertNoErrors(source); | |
| 4749 verify([source]); | |
| 4750 } | |
| 4751 | |
| 4752 void test_unusedElement_method_isUsed_staticInvocation() { | |
| 4753 enableUnusedElement = true; | |
| 4754 Source source = addSource(r''' | |
| 4755 class A { | |
| 4756 static _m() {} | |
| 4757 } | |
| 4758 main() { | |
| 4759 A._m(); | |
| 4760 }'''); | |
| 4761 computeLibrarySourceErrors(source); | |
| 4762 assertNoErrors(source); | |
| 4763 verify([source]); | |
| 4764 } | |
| 4765 | |
| 4766 void test_unusedElement_method_notUsed_noReference() { | |
| 4767 enableUnusedElement = true; | |
| 4768 Source source = addSource(r''' | |
| 4769 class A { | |
| 4770 static _m() {} | |
| 4771 }'''); | |
| 4772 computeLibrarySourceErrors(source); | |
| 4773 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 4774 verify([source]); | |
| 4775 } | |
| 4776 | |
| 4777 void test_unusedElement_method_notUsed_referenceFromItself() { | |
| 4778 enableUnusedElement = true; | |
| 4779 Source source = addSource(r''' | |
| 4780 class A { | |
| 4781 static _m(int p) { | |
| 4782 _m(p - 1); | |
| 4783 } | |
| 4784 }'''); | |
| 4785 computeLibrarySourceErrors(source); | |
| 4786 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 4787 verify([source]); | |
| 4788 } | |
| 4789 | |
| 4790 void test_unusedElement_setter_isUsed_invocation_implicitThis() { | |
| 4791 enableUnusedElement = true; | |
| 4792 Source source = addSource(r''' | |
| 4793 class A { | |
| 4794 set _s(x) {} | |
| 4795 useSetter() { | |
| 4796 _s = 42; | |
| 4797 } | |
| 4798 }'''); | |
| 4799 computeLibrarySourceErrors(source); | |
| 4800 assertNoErrors(source); | |
| 4801 verify([source]); | |
| 4802 } | |
| 4803 | |
| 4804 void test_unusedElement_setter_isUsed_invocation_PrefixedIdentifier() { | |
| 4805 enableUnusedElement = true; | |
| 4806 Source source = addSource(r''' | |
| 4807 class A { | |
| 4808 set _s(x) {} | |
| 4809 } | |
| 4810 main(A a) { | |
| 4811 a._s = 42; | |
| 4812 } | |
| 4813 '''); | |
| 4814 computeLibrarySourceErrors(source); | |
| 4815 assertNoErrors(source); | |
| 4816 verify([source]); | |
| 4817 } | |
| 4818 | |
| 4819 void test_unusedElement_setter_isUsed_invocation_PropertyAccess() { | |
| 4820 enableUnusedElement = true; | |
| 4821 Source source = addSource(r''' | |
| 4822 class A { | |
| 4823 set _s(x) {} | |
| 4824 } | |
| 4825 main() { | |
| 4826 new A()._s = 42; | |
| 4827 } | |
| 4828 '''); | |
| 4829 computeLibrarySourceErrors(source); | |
| 4830 assertNoErrors(source); | |
| 4831 verify([source]); | |
| 4832 } | |
| 4833 | |
| 4834 void test_unusedElement_setter_notUsed_noReference() { | |
| 4835 enableUnusedElement = true; | |
| 4836 Source source = addSource(r''' | |
| 4837 class A { | |
| 4838 set _s(x) {} | |
| 4839 }'''); | |
| 4840 computeLibrarySourceErrors(source); | |
| 4841 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 4842 verify([source]); | |
| 4843 } | |
| 4844 | |
| 4845 void test_unusedElement_setter_notUsed_referenceFromItself() { | |
| 4846 enableUnusedElement = true; | |
| 4847 Source source = addSource(r''' | |
| 4848 class A { | |
| 4849 set _s(int x) { | |
| 4850 if (x > 5) { | |
| 4851 _s = x - 1; | |
| 4852 } | |
| 4853 } | |
| 4854 }'''); | |
| 4855 computeLibrarySourceErrors(source); | |
| 4856 assertErrors(source, [HintCode.UNUSED_ELEMENT]); | |
| 4857 verify([source]); | |
| 4858 } | |
| 4859 | |
| 4860 void test_unusedField_isUsed_argument() { | |
| 4861 enableUnusedElement = true; | |
| 4862 Source source = addSource(r''' | |
| 4863 class A { | |
| 4864 int _f = 0; | |
| 4865 main() { | |
| 4866 print(++_f); | |
| 4867 } | |
| 4868 } | |
| 4869 print(x) {}'''); | |
| 4870 computeLibrarySourceErrors(source); | |
| 4871 assertErrors(source); | |
| 4872 verify([source]); | |
| 4873 } | |
| 4874 | |
| 4875 void test_unusedField_isUsed_reference_implicitThis() { | |
| 4876 enableUnusedElement = true; | |
| 4877 Source source = addSource(r''' | |
| 4878 class A { | |
| 4879 int _f; | |
| 4880 main() { | |
| 4881 print(_f); | |
| 4882 } | |
| 4883 } | |
| 4884 print(x) {}'''); | |
| 4885 computeLibrarySourceErrors(source); | |
| 4886 assertErrors(source); | |
| 4887 verify([source]); | |
| 4888 } | |
| 4889 | |
| 4890 void test_unusedField_isUsed_reference_implicitThis_expressionFunctionBody() { | |
| 4891 enableUnusedElement = true; | |
| 4892 Source source = addSource(r''' | |
| 4893 class A { | |
| 4894 int _f; | |
| 4895 m() => _f; | |
| 4896 }'''); | |
| 4897 computeLibrarySourceErrors(source); | |
| 4898 assertErrors(source); | |
| 4899 verify([source]); | |
| 4900 } | |
| 4901 | |
| 4902 void test_unusedField_isUsed_reference_implicitThis_subclass() { | |
| 4903 enableUnusedElement = true; | |
| 4904 Source source = addSource(r''' | |
| 4905 class A { | |
| 4906 int _f; | |
| 4907 main() { | |
| 4908 print(_f); | |
| 4909 } | |
| 4910 } | |
| 4911 class B extends A { | |
| 4912 int _f; | |
| 4913 } | |
| 4914 print(x) {}'''); | |
| 4915 computeLibrarySourceErrors(source); | |
| 4916 assertErrors(source); | |
| 4917 verify([source]); | |
| 4918 } | |
| 4919 | |
| 4920 void test_unusedField_isUsed_reference_qualified_propagatedElement() { | |
| 4921 enableUnusedElement = true; | |
| 4922 Source source = addSource(r''' | |
| 4923 class A { | |
| 4924 int _f; | |
| 4925 } | |
| 4926 main() { | |
| 4927 var a = new A(); | |
| 4928 print(a._f); | |
| 4929 } | |
| 4930 print(x) {}'''); | |
| 4931 computeLibrarySourceErrors(source); | |
| 4932 assertErrors(source); | |
| 4933 verify([source]); | |
| 4934 } | |
| 4935 | |
| 4936 void test_unusedField_isUsed_reference_qualified_staticElement() { | |
| 4937 enableUnusedElement = true; | |
| 4938 Source source = addSource(r''' | |
| 4939 class A { | |
| 4940 int _f; | |
| 4941 } | |
| 4942 main() { | |
| 4943 A a = new A(); | |
| 4944 print(a._f); | |
| 4945 } | |
| 4946 print(x) {}'''); | |
| 4947 computeLibrarySourceErrors(source); | |
| 4948 assertErrors(source); | |
| 4949 verify([source]); | |
| 4950 } | |
| 4951 | |
| 4952 void test_unusedField_isUsed_reference_qualified_unresolved() { | |
| 4953 enableUnusedElement = true; | |
| 4954 Source source = addSource(r''' | |
| 4955 class A { | |
| 4956 int _f; | |
| 4957 } | |
| 4958 main(a) { | |
| 4959 print(a._f); | |
| 4960 } | |
| 4961 print(x) {}'''); | |
| 4962 computeLibrarySourceErrors(source); | |
| 4963 assertErrors(source); | |
| 4964 verify([source]); | |
| 4965 } | |
| 4966 | |
| 4967 void test_unusedField_notUsed_compoundAssign() { | |
| 4968 enableUnusedElement = true; | |
| 4969 Source source = addSource(r''' | |
| 4970 class A { | |
| 4971 int _f; | |
| 4972 main() { | |
| 4973 _f += 2; | |
| 4974 } | |
| 4975 }'''); | |
| 4976 computeLibrarySourceErrors(source); | |
| 4977 assertErrors(source, [HintCode.UNUSED_FIELD]); | |
| 4978 verify([source]); | |
| 4979 } | |
| 4980 | |
| 4981 void test_unusedField_notUsed_noReference() { | |
| 4982 enableUnusedElement = true; | |
| 4983 Source source = addSource(r''' | |
| 4984 class A { | |
| 4985 int _f; | |
| 4986 } | |
| 4987 '''); | |
| 4988 computeLibrarySourceErrors(source); | |
| 4989 assertErrors(source, [HintCode.UNUSED_FIELD]); | |
| 4990 verify([source]); | |
| 4991 } | |
| 4992 | |
| 4993 void test_unusedField_notUsed_postfixExpr() { | |
| 4994 enableUnusedElement = true; | |
| 4995 Source source = addSource(r''' | |
| 4996 class A { | |
| 4997 int _f = 0; | |
| 4998 main() { | |
| 4999 _f++; | |
| 5000 } | |
| 5001 }'''); | |
| 5002 computeLibrarySourceErrors(source); | |
| 5003 assertErrors(source, [HintCode.UNUSED_FIELD]); | |
| 5004 verify([source]); | |
| 5005 } | |
| 5006 | |
| 5007 void test_unusedField_notUsed_prefixExpr() { | |
| 5008 enableUnusedElement = true; | |
| 5009 Source source = addSource(r''' | |
| 5010 class A { | |
| 5011 int _f = 0; | |
| 5012 main() { | |
| 5013 ++_f; | |
| 5014 } | |
| 5015 }'''); | |
| 5016 computeLibrarySourceErrors(source); | |
| 5017 assertErrors(source, [HintCode.UNUSED_FIELD]); | |
| 5018 verify([source]); | |
| 5019 } | |
| 5020 | |
| 5021 void test_unusedField_notUsed_simpleAssignment() { | |
| 5022 enableUnusedElement = true; | |
| 5023 Source source = addSource(r''' | |
| 5024 class A { | |
| 5025 int _f; | |
| 5026 m() { | |
| 5027 _f = 1; | |
| 5028 } | |
| 5029 } | |
| 5030 main(A a) { | |
| 5031 a._f = 2; | |
| 5032 } | |
| 5033 '''); | |
| 5034 computeLibrarySourceErrors(source); | |
| 5035 assertErrors(source, [HintCode.UNUSED_FIELD]); | |
| 5036 verify([source]); | |
| 5037 } | |
| 5038 | |
| 5039 void test_unusedImport() { | |
| 5040 Source source = addSource(r''' | |
| 5041 library L; | |
| 5042 import 'lib1.dart';'''); | |
| 5043 Source source2 = addNamedSource("/lib1.dart", "library lib1;"); | |
| 5044 computeLibrarySourceErrors(source); | |
| 5045 assertErrors(source, [HintCode.UNUSED_IMPORT]); | |
| 5046 assertNoErrors(source2); | |
| 5047 verify([source, source2]); | |
| 5048 } | |
| 5049 | |
| 5050 void test_unusedImport_as() { | |
| 5051 Source source = addSource(r''' | |
| 5052 library L; | |
| 5053 import 'lib1.dart'; | |
| 5054 import 'lib1.dart' as one; | |
| 5055 one.A a;'''); | |
| 5056 Source source2 = addNamedSource( | |
| 5057 "/lib1.dart", | |
| 5058 r''' | |
| 5059 library lib1; | |
| 5060 class A {}'''); | |
| 5061 computeLibrarySourceErrors(source); | |
| 5062 assertErrors(source, [HintCode.UNUSED_IMPORT]); | |
| 5063 assertNoErrors(source2); | |
| 5064 verify([source, source2]); | |
| 5065 } | |
| 5066 | |
| 5067 void test_unusedImport_hide() { | |
| 5068 Source source = addSource(r''' | |
| 5069 library L; | |
| 5070 import 'lib1.dart'; | |
| 5071 import 'lib1.dart' hide A; | |
| 5072 A a;'''); | |
| 5073 Source source2 = addNamedSource( | |
| 5074 "/lib1.dart", | |
| 5075 r''' | |
| 5076 library lib1; | |
| 5077 class A {}'''); | |
| 5078 computeLibrarySourceErrors(source); | |
| 5079 assertErrors(source, [HintCode.UNUSED_IMPORT]); | |
| 5080 assertNoErrors(source2); | |
| 5081 verify([source, source2]); | |
| 5082 } | |
| 5083 | |
| 5084 void test_unusedImport_show() { | |
| 5085 Source source = addSource(r''' | |
| 5086 library L; | |
| 5087 import 'lib1.dart' show A; | |
| 5088 import 'lib1.dart' show B; | |
| 5089 A a;'''); | |
| 5090 Source source2 = addNamedSource( | |
| 5091 "/lib1.dart", | |
| 5092 r''' | |
| 5093 library lib1; | |
| 5094 class A {} | |
| 5095 class B {}'''); | |
| 5096 computeLibrarySourceErrors(source); | |
| 5097 assertErrors(source, [HintCode.UNUSED_IMPORT]); | |
| 5098 assertNoErrors(source2); | |
| 5099 verify([source, source2]); | |
| 5100 } | |
| 5101 | |
| 5102 void test_unusedLocalVariable_inCatch_exception() { | |
| 5103 enableUnusedLocalVariable = true; | |
| 5104 Source source = addSource(r''' | |
| 5105 main() { | |
| 5106 try { | |
| 5107 } on String catch (exception) { | |
| 5108 } | |
| 5109 }'''); | |
| 5110 computeLibrarySourceErrors(source); | |
| 5111 assertErrors(source, [HintCode.UNUSED_CATCH_CLAUSE]); | |
| 5112 verify([source]); | |
| 5113 } | |
| 5114 | |
| 5115 void test_unusedLocalVariable_inCatch_exception_hasStack() { | |
| 5116 enableUnusedLocalVariable = true; | |
| 5117 Source source = addSource(r''' | |
| 5118 main() { | |
| 5119 try { | |
| 5120 } catch (exception, stack) { | |
| 5121 print(stack); | |
| 5122 } | |
| 5123 }'''); | |
| 5124 computeLibrarySourceErrors(source); | |
| 5125 assertNoErrors(source); | |
| 5126 verify([source]); | |
| 5127 } | |
| 5128 | |
| 5129 void test_unusedLocalVariable_inCatch_exception_noOnClause() { | |
| 5130 enableUnusedLocalVariable = true; | |
| 5131 Source source = addSource(r''' | |
| 5132 main() { | |
| 5133 try { | |
| 5134 } catch (exception) { | |
| 5135 } | |
| 5136 }'''); | |
| 5137 computeLibrarySourceErrors(source); | |
| 5138 assertNoErrors(source); | |
| 5139 verify([source]); | |
| 5140 } | |
| 5141 | |
| 5142 void test_unusedLocalVariable_inCatch_stackTrace() { | |
| 5143 enableUnusedLocalVariable = true; | |
| 5144 Source source = addSource(r''' | |
| 5145 main() { | |
| 5146 try { | |
| 5147 } catch (exception, stackTrace) { | |
| 5148 } | |
| 5149 }'''); | |
| 5150 computeLibrarySourceErrors(source); | |
| 5151 assertErrors(source, [HintCode.UNUSED_CATCH_STACK]); | |
| 5152 verify([source]); | |
| 5153 } | |
| 5154 | |
| 5155 void test_unusedLocalVariable_inCatch_stackTrace_used() { | |
| 5156 enableUnusedLocalVariable = true; | |
| 5157 Source source = addSource(r''' | |
| 5158 main() { | |
| 5159 try { | |
| 5160 } catch (exception, stackTrace) { | |
| 5161 print('exception at $stackTrace'); | |
| 5162 } | |
| 5163 } | |
| 5164 print(x) {}'''); | |
| 5165 computeLibrarySourceErrors(source); | |
| 5166 assertErrors(source); | |
| 5167 verify([source]); | |
| 5168 } | |
| 5169 | |
| 5170 void test_unusedLocalVariable_inFor_underscore_ignored() { | |
| 5171 enableUnusedLocalVariable = true; | |
| 5172 Source source = addSource(r''' | |
| 5173 main() { | |
| 5174 for (var _ in [1,2,3]) { | |
| 5175 for (var __ in [4,5,6]) { | |
| 5176 // do something | |
| 5177 } | |
| 5178 } | |
| 5179 }'''); | |
| 5180 computeLibrarySourceErrors(source); | |
| 5181 assertErrors(source); | |
| 5182 verify([source]); | |
| 5183 } | |
| 5184 | |
| 5185 void test_unusedLocalVariable_inFunction() { | |
| 5186 enableUnusedLocalVariable = true; | |
| 5187 Source source = addSource(r''' | |
| 5188 main() { | |
| 5189 var v = 1; | |
| 5190 v = 2; | |
| 5191 }'''); | |
| 5192 computeLibrarySourceErrors(source); | |
| 5193 assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]); | |
| 5194 verify([source]); | |
| 5195 } | |
| 5196 | |
| 5197 void test_unusedLocalVariable_inMethod() { | |
| 5198 enableUnusedLocalVariable = true; | |
| 5199 Source source = addSource(r''' | |
| 5200 class A { | |
| 5201 foo() { | |
| 5202 var v = 1; | |
| 5203 v = 2; | |
| 5204 } | |
| 5205 }'''); | |
| 5206 computeLibrarySourceErrors(source); | |
| 5207 assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]); | |
| 5208 verify([source]); | |
| 5209 } | |
| 5210 | |
| 5211 void test_unusedLocalVariable_isInvoked() { | |
| 5212 enableUnusedLocalVariable = true; | |
| 5213 Source source = addSource(r''' | |
| 5214 typedef Foo(); | |
| 5215 main() { | |
| 5216 Foo foo; | |
| 5217 foo(); | |
| 5218 }'''); | |
| 5219 computeLibrarySourceErrors(source); | |
| 5220 assertErrors(source); | |
| 5221 verify([source]); | |
| 5222 } | |
| 5223 | |
| 5224 void test_unusedLocalVariable_isRead_notUsed_compoundAssign() { | |
| 5225 enableUnusedLocalVariable = true; | |
| 5226 Source source = addSource(r''' | |
| 5227 main() { | |
| 5228 var v = 1; | |
| 5229 v += 2; | |
| 5230 }'''); | |
| 5231 computeLibrarySourceErrors(source); | |
| 5232 assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]); | |
| 5233 verify([source]); | |
| 5234 } | |
| 5235 | |
| 5236 void test_unusedLocalVariable_isRead_notUsed_postfixExpr() { | |
| 5237 enableUnusedLocalVariable = true; | |
| 5238 Source source = addSource(r''' | |
| 5239 main() { | |
| 5240 var v = 1; | |
| 5241 v++; | |
| 5242 }'''); | |
| 5243 computeLibrarySourceErrors(source); | |
| 5244 assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]); | |
| 5245 verify([source]); | |
| 5246 } | |
| 5247 | |
| 5248 void test_unusedLocalVariable_isRead_notUsed_prefixExpr() { | |
| 5249 enableUnusedLocalVariable = true; | |
| 5250 Source source = addSource(r''' | |
| 5251 main() { | |
| 5252 var v = 1; | |
| 5253 ++v; | |
| 5254 }'''); | |
| 5255 computeLibrarySourceErrors(source); | |
| 5256 assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]); | |
| 5257 verify([source]); | |
| 5258 } | |
| 5259 | |
| 5260 void test_unusedLocalVariable_isRead_usedArgument() { | |
| 5261 enableUnusedLocalVariable = true; | |
| 5262 Source source = addSource(r''' | |
| 5263 main() { | |
| 5264 var v = 1; | |
| 5265 print(++v); | |
| 5266 } | |
| 5267 print(x) {}'''); | |
| 5268 computeLibrarySourceErrors(source); | |
| 5269 assertErrors(source); | |
| 5270 verify([source]); | |
| 5271 } | |
| 5272 | |
| 5273 void test_unusedLocalVariable_isRead_usedInvocationTarget() { | |
| 5274 enableUnusedLocalVariable = true; | |
| 5275 Source source = addSource(r''' | |
| 5276 class A { | |
| 5277 foo() {} | |
| 5278 } | |
| 5279 main() { | |
| 5280 var a = new A(); | |
| 5281 a.foo(); | |
| 5282 } | |
| 5283 '''); | |
| 5284 computeLibrarySourceErrors(source); | |
| 5285 assertErrors(source); | |
| 5286 verify([source]); | |
| 5287 } | |
| 5288 | |
| 5289 void test_useOfVoidResult_assignmentExpression_function() { | |
| 5290 Source source = addSource(r''' | |
| 5291 void f() {} | |
| 5292 class A { | |
| 5293 n() { | |
| 5294 var a; | |
| 5295 a = f(); | |
| 5296 } | |
| 5297 }'''); | |
| 5298 computeLibrarySourceErrors(source); | |
| 5299 assertErrors(source, [HintCode.USE_OF_VOID_RESULT]); | |
| 5300 verify([source]); | |
| 5301 } | |
| 5302 | |
| 5303 void test_useOfVoidResult_assignmentExpression_method() { | |
| 5304 Source source = addSource(r''' | |
| 5305 class A { | |
| 5306 void m() {} | |
| 5307 n() { | |
| 5308 var a; | |
| 5309 a = m(); | |
| 5310 } | |
| 5311 }'''); | |
| 5312 computeLibrarySourceErrors(source); | |
| 5313 assertErrors(source, [HintCode.USE_OF_VOID_RESULT]); | |
| 5314 verify([source]); | |
| 5315 } | |
| 5316 | |
| 5317 void test_useOfVoidResult_inForLoop() { | |
| 5318 Source source = addSource(r''' | |
| 5319 class A { | |
| 5320 void m() {} | |
| 5321 n() { | |
| 5322 for(var a = m();;) {} | |
| 5323 } | |
| 5324 }'''); | |
| 5325 computeLibrarySourceErrors(source); | |
| 5326 assertErrors(source, [HintCode.USE_OF_VOID_RESULT]); | |
| 5327 verify([source]); | |
| 5328 } | |
| 5329 | |
| 5330 void test_useOfVoidResult_variableDeclaration_function() { | |
| 5331 Source source = addSource(r''' | |
| 5332 void f() {} | |
| 5333 class A { | |
| 5334 n() { | |
| 5335 var a = f(); | |
| 5336 } | |
| 5337 }'''); | |
| 5338 computeLibrarySourceErrors(source); | |
| 5339 assertErrors(source, [HintCode.USE_OF_VOID_RESULT]); | |
| 5340 verify([source]); | |
| 5341 } | |
| 5342 | |
| 5343 void test_useOfVoidResult_variableDeclaration_method() { | |
| 5344 Source source = addSource(r''' | |
| 5345 class A { | |
| 5346 void m() {} | |
| 5347 n() { | |
| 5348 var a = m(); | |
| 5349 } | |
| 5350 }'''); | |
| 5351 computeLibrarySourceErrors(source); | |
| 5352 assertErrors(source, [HintCode.USE_OF_VOID_RESULT]); | |
| 5353 verify([source]); | |
| 5354 } | |
| 5355 | |
| 5356 void test_useOfVoidResult_variableDeclaration_method2() { | |
| 5357 Source source = addSource(r''' | |
| 5358 class A { | |
| 5359 void m() {} | |
| 5360 n() { | |
| 5361 var a = m(), b = m(); | |
| 5362 } | |
| 5363 }'''); | |
| 5364 computeLibrarySourceErrors(source); | |
| 5365 assertErrors( | |
| 5366 source, [HintCode.USE_OF_VOID_RESULT, HintCode.USE_OF_VOID_RESULT]); | |
| 5367 verify([source]); | |
| 5368 } | |
| 5369 } | |
| 5370 | |
| 5371 @reflectiveTest | |
| 5372 class InheritanceManagerTest { | |
| 5373 /** | |
| 5374 * The type provider used to access the types. | |
| 5375 */ | |
| 5376 TestTypeProvider _typeProvider; | |
| 5377 | |
| 5378 /** | |
| 5379 * The library containing the code being resolved. | |
| 5380 */ | |
| 5381 LibraryElementImpl _definingLibrary; | |
| 5382 | |
| 5383 /** | |
| 5384 * The inheritance manager being tested. | |
| 5385 */ | |
| 5386 InheritanceManager _inheritanceManager; | |
| 5387 | |
| 5388 /** | |
| 5389 * The number of members that Object implements (as determined by [TestTypePro
vider]). | |
| 5390 */ | |
| 5391 int _numOfMembersInObject = 0; | |
| 5392 | |
| 5393 void setUp() { | |
| 5394 _typeProvider = new TestTypeProvider(); | |
| 5395 _inheritanceManager = _createInheritanceManager(); | |
| 5396 InterfaceType objectType = _typeProvider.objectType; | |
| 5397 _numOfMembersInObject = | |
| 5398 objectType.methods.length + objectType.accessors.length; | |
| 5399 } | |
| 5400 | |
| 5401 void test_getMapOfMembersInheritedFromClasses_accessor_extends() { | |
| 5402 // class A { int get g; } | |
| 5403 // class B extends A {} | |
| 5404 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5405 String getterName = "g"; | |
| 5406 PropertyAccessorElement getterG = | |
| 5407 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 5408 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 5409 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 5410 MemberMap mapB = | |
| 5411 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB); | |
| 5412 MemberMap mapA = | |
| 5413 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA); | |
| 5414 expect(mapA.size, _numOfMembersInObject); | |
| 5415 expect(mapB.size, _numOfMembersInObject + 1); | |
| 5416 expect(mapB.get(getterName), same(getterG)); | |
| 5417 _assertNoErrors(classA); | |
| 5418 _assertNoErrors(classB); | |
| 5419 } | |
| 5420 | |
| 5421 void test_getMapOfMembersInheritedFromClasses_accessor_implements() { | |
| 5422 // class A { int get g; } | |
| 5423 // class B implements A {} | |
| 5424 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5425 String getterName = "g"; | |
| 5426 PropertyAccessorElement getterG = | |
| 5427 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 5428 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 5429 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5430 classB.interfaces = <InterfaceType>[classA.type]; | |
| 5431 MemberMap mapB = | |
| 5432 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB); | |
| 5433 MemberMap mapA = | |
| 5434 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA); | |
| 5435 expect(mapA.size, _numOfMembersInObject); | |
| 5436 expect(mapB.size, _numOfMembersInObject); | |
| 5437 expect(mapB.get(getterName), isNull); | |
| 5438 _assertNoErrors(classA); | |
| 5439 _assertNoErrors(classB); | |
| 5440 } | |
| 5441 | |
| 5442 void test_getMapOfMembersInheritedFromClasses_accessor_with() { | |
| 5443 // class A { int get g; } | |
| 5444 // class B extends Object with A {} | |
| 5445 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5446 String getterName = "g"; | |
| 5447 PropertyAccessorElement getterG = | |
| 5448 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 5449 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 5450 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5451 classB.mixins = <InterfaceType>[classA.type]; | |
| 5452 MemberMap mapB = | |
| 5453 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB); | |
| 5454 MemberMap mapA = | |
| 5455 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA); | |
| 5456 expect(mapA.size, _numOfMembersInObject); | |
| 5457 expect(mapB.size, _numOfMembersInObject + 1); | |
| 5458 expect(mapB.get(getterName), same(getterG)); | |
| 5459 _assertNoErrors(classA); | |
| 5460 _assertNoErrors(classB); | |
| 5461 } | |
| 5462 | |
| 5463 void test_getMapOfMembersInheritedFromClasses_implicitExtends() { | |
| 5464 // class A {} | |
| 5465 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5466 MemberMap mapA = | |
| 5467 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA); | |
| 5468 expect(mapA.size, _numOfMembersInObject); | |
| 5469 _assertNoErrors(classA); | |
| 5470 } | |
| 5471 | |
| 5472 void test_getMapOfMembersInheritedFromClasses_method_extends() { | |
| 5473 // class A { int g(); } | |
| 5474 // class B extends A {} | |
| 5475 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5476 String methodName = "m"; | |
| 5477 MethodElement methodM = | |
| 5478 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5479 classA.methods = <MethodElement>[methodM]; | |
| 5480 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5481 classB.supertype = classA.type; | |
| 5482 MemberMap mapB = | |
| 5483 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB); | |
| 5484 MemberMap mapA = | |
| 5485 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA); | |
| 5486 expect(mapA.size, _numOfMembersInObject); | |
| 5487 expect(mapB.size, _numOfMembersInObject + 1); | |
| 5488 expect(mapB.get(methodName), same(methodM)); | |
| 5489 _assertNoErrors(classA); | |
| 5490 _assertNoErrors(classB); | |
| 5491 } | |
| 5492 | |
| 5493 void test_getMapOfMembersInheritedFromClasses_method_implements() { | |
| 5494 // class A { int g(); } | |
| 5495 // class B implements A {} | |
| 5496 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5497 String methodName = "m"; | |
| 5498 MethodElement methodM = | |
| 5499 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5500 classA.methods = <MethodElement>[methodM]; | |
| 5501 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5502 classB.interfaces = <InterfaceType>[classA.type]; | |
| 5503 MemberMap mapB = | |
| 5504 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB); | |
| 5505 MemberMap mapA = | |
| 5506 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA); | |
| 5507 expect(mapA.size, _numOfMembersInObject); | |
| 5508 expect(mapB.size, _numOfMembersInObject); | |
| 5509 expect(mapB.get(methodName), isNull); | |
| 5510 _assertNoErrors(classA); | |
| 5511 _assertNoErrors(classB); | |
| 5512 } | |
| 5513 | |
| 5514 void test_getMapOfMembersInheritedFromClasses_method_with() { | |
| 5515 // class A { int g(); } | |
| 5516 // class B extends Object with A {} | |
| 5517 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5518 String methodName = "m"; | |
| 5519 MethodElement methodM = | |
| 5520 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5521 classA.methods = <MethodElement>[methodM]; | |
| 5522 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5523 classB.mixins = <InterfaceType>[classA.type]; | |
| 5524 MemberMap mapB = | |
| 5525 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB); | |
| 5526 MemberMap mapA = | |
| 5527 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA); | |
| 5528 expect(mapA.size, _numOfMembersInObject); | |
| 5529 expect(mapB.size, _numOfMembersInObject + 1); | |
| 5530 expect(mapB.get(methodName), same(methodM)); | |
| 5531 _assertNoErrors(classA); | |
| 5532 _assertNoErrors(classB); | |
| 5533 } | |
| 5534 | |
| 5535 void test_getMapOfMembersInheritedFromClasses_method_with_two_mixins() { | |
| 5536 // class A1 { int m(); } | |
| 5537 // class A2 { int m(); } | |
| 5538 // class B extends Object with A1, A2 {} | |
| 5539 ClassElementImpl classA1 = ElementFactory.classElement2("A1"); | |
| 5540 String methodName = "m"; | |
| 5541 MethodElement methodA1M = | |
| 5542 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5543 classA1.methods = <MethodElement>[methodA1M]; | |
| 5544 ClassElementImpl classA2 = ElementFactory.classElement2("A2"); | |
| 5545 MethodElement methodA2M = | |
| 5546 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5547 classA2.methods = <MethodElement>[methodA2M]; | |
| 5548 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5549 classB.mixins = <InterfaceType>[classA1.type, classA2.type]; | |
| 5550 MemberMap mapB = | |
| 5551 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB); | |
| 5552 expect(mapB.get(methodName), same(methodA2M)); | |
| 5553 _assertNoErrors(classA1); | |
| 5554 _assertNoErrors(classA2); | |
| 5555 _assertNoErrors(classB); | |
| 5556 } | |
| 5557 | |
| 5558 void test_getMapOfMembersInheritedFromInterfaces_accessor_extends() { | |
| 5559 // class A { int get g; } | |
| 5560 // class B extends A {} | |
| 5561 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5562 String getterName = "g"; | |
| 5563 PropertyAccessorElement getterG = | |
| 5564 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 5565 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 5566 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 5567 MemberMap mapB = | |
| 5568 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB); | |
| 5569 MemberMap mapA = | |
| 5570 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5571 expect(mapA.size, _numOfMembersInObject); | |
| 5572 expect(mapB.size, _numOfMembersInObject + 1); | |
| 5573 expect(mapB.get(getterName), same(getterG)); | |
| 5574 _assertNoErrors(classA); | |
| 5575 _assertNoErrors(classB); | |
| 5576 } | |
| 5577 | |
| 5578 void test_getMapOfMembersInheritedFromInterfaces_accessor_implements() { | |
| 5579 // class A { int get g; } | |
| 5580 // class B implements A {} | |
| 5581 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5582 String getterName = "g"; | |
| 5583 PropertyAccessorElement getterG = | |
| 5584 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 5585 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 5586 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5587 classB.interfaces = <InterfaceType>[classA.type]; | |
| 5588 MemberMap mapB = | |
| 5589 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB); | |
| 5590 MemberMap mapA = | |
| 5591 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5592 expect(mapA.size, _numOfMembersInObject); | |
| 5593 expect(mapB.size, _numOfMembersInObject + 1); | |
| 5594 expect(mapB.get(getterName), same(getterG)); | |
| 5595 _assertNoErrors(classA); | |
| 5596 _assertNoErrors(classB); | |
| 5597 } | |
| 5598 | |
| 5599 void test_getMapOfMembersInheritedFromInterfaces_accessor_with() { | |
| 5600 // class A { int get g; } | |
| 5601 // class B extends Object with A {} | |
| 5602 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5603 String getterName = "g"; | |
| 5604 PropertyAccessorElement getterG = | |
| 5605 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 5606 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 5607 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5608 classB.mixins = <InterfaceType>[classA.type]; | |
| 5609 MemberMap mapB = | |
| 5610 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB); | |
| 5611 MemberMap mapA = | |
| 5612 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5613 expect(mapA.size, _numOfMembersInObject); | |
| 5614 expect(mapB.size, _numOfMembersInObject + 1); | |
| 5615 expect(mapB.get(getterName), same(getterG)); | |
| 5616 _assertNoErrors(classA); | |
| 5617 _assertNoErrors(classB); | |
| 5618 } | |
| 5619 | |
| 5620 void test_getMapOfMembersInheritedFromInterfaces_implicitExtends() { | |
| 5621 // class A {} | |
| 5622 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5623 MemberMap mapA = | |
| 5624 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5625 expect(mapA.size, _numOfMembersInObject); | |
| 5626 _assertNoErrors(classA); | |
| 5627 } | |
| 5628 | |
| 5629 void | |
| 5630 test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_
getter_method() { | |
| 5631 // class I1 { int m(); } | |
| 5632 // class I2 { int get m; } | |
| 5633 // class A implements I2, I1 {} | |
| 5634 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5635 String methodName = "m"; | |
| 5636 MethodElement methodM = | |
| 5637 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5638 classI1.methods = <MethodElement>[methodM]; | |
| 5639 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5640 PropertyAccessorElement getter = | |
| 5641 ElementFactory.getterElement(methodName, false, _typeProvider.intType); | |
| 5642 classI2.accessors = <PropertyAccessorElement>[getter]; | |
| 5643 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5644 classA.interfaces = <InterfaceType>[classI2.type, classI1.type]; | |
| 5645 MemberMap mapA = | |
| 5646 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5647 expect(mapA.size, _numOfMembersInObject); | |
| 5648 expect(mapA.get(methodName), isNull); | |
| 5649 _assertErrors(classA, | |
| 5650 [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]); | |
| 5651 } | |
| 5652 | |
| 5653 void | |
| 5654 test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_
int_str() { | |
| 5655 // class I1 { int m(); } | |
| 5656 // class I2 { String m(); } | |
| 5657 // class A implements I1, I2 {} | |
| 5658 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5659 String methodName = "m"; | |
| 5660 MethodElement methodM1 = | |
| 5661 ElementFactory.methodElement(methodName, null, [_typeProvider.intType]); | |
| 5662 classI1.methods = <MethodElement>[methodM1]; | |
| 5663 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5664 MethodElement methodM2 = ElementFactory | |
| 5665 .methodElement(methodName, null, [_typeProvider.stringType]); | |
| 5666 classI2.methods = <MethodElement>[methodM2]; | |
| 5667 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5668 classA.interfaces = <InterfaceType>[classI1.type, classI2.type]; | |
| 5669 MemberMap mapA = | |
| 5670 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5671 expect(mapA.size, _numOfMembersInObject); | |
| 5672 expect(mapA.get(methodName), isNull); | |
| 5673 _assertErrors( | |
| 5674 classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]); | |
| 5675 } | |
| 5676 | |
| 5677 void | |
| 5678 test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_
method_getter() { | |
| 5679 // class I1 { int m(); } | |
| 5680 // class I2 { int get m; } | |
| 5681 // class A implements I1, I2 {} | |
| 5682 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5683 String methodName = "m"; | |
| 5684 MethodElement methodM = | |
| 5685 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5686 classI1.methods = <MethodElement>[methodM]; | |
| 5687 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5688 PropertyAccessorElement getter = | |
| 5689 ElementFactory.getterElement(methodName, false, _typeProvider.intType); | |
| 5690 classI2.accessors = <PropertyAccessorElement>[getter]; | |
| 5691 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5692 classA.interfaces = <InterfaceType>[classI1.type, classI2.type]; | |
| 5693 MemberMap mapA = | |
| 5694 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5695 expect(mapA.size, _numOfMembersInObject); | |
| 5696 expect(mapA.get(methodName), isNull); | |
| 5697 _assertErrors(classA, | |
| 5698 [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]); | |
| 5699 } | |
| 5700 | |
| 5701 void | |
| 5702 test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_
numOfRequiredParams() { | |
| 5703 // class I1 { dynamic m(int, [int]); } | |
| 5704 // class I2 { dynamic m(int, int, int); } | |
| 5705 // class A implements I1, I2 {} | |
| 5706 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5707 String methodName = "m"; | |
| 5708 MethodElementImpl methodM1 = | |
| 5709 ElementFactory.methodElement(methodName, _typeProvider.dynamicType); | |
| 5710 ParameterElementImpl parameter1 = | |
| 5711 new ParameterElementImpl.forNode(AstFactory.identifier3("a1")); | |
| 5712 parameter1.type = _typeProvider.intType; | |
| 5713 parameter1.parameterKind = ParameterKind.REQUIRED; | |
| 5714 ParameterElementImpl parameter2 = | |
| 5715 new ParameterElementImpl.forNode(AstFactory.identifier3("a2")); | |
| 5716 parameter2.type = _typeProvider.intType; | |
| 5717 parameter2.parameterKind = ParameterKind.POSITIONAL; | |
| 5718 methodM1.parameters = <ParameterElement>[parameter1, parameter2]; | |
| 5719 classI1.methods = <MethodElement>[methodM1]; | |
| 5720 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5721 MethodElementImpl methodM2 = | |
| 5722 ElementFactory.methodElement(methodName, _typeProvider.dynamicType); | |
| 5723 ParameterElementImpl parameter3 = | |
| 5724 new ParameterElementImpl.forNode(AstFactory.identifier3("a3")); | |
| 5725 parameter3.type = _typeProvider.intType; | |
| 5726 parameter3.parameterKind = ParameterKind.REQUIRED; | |
| 5727 ParameterElementImpl parameter4 = | |
| 5728 new ParameterElementImpl.forNode(AstFactory.identifier3("a4")); | |
| 5729 parameter4.type = _typeProvider.intType; | |
| 5730 parameter4.parameterKind = ParameterKind.REQUIRED; | |
| 5731 ParameterElementImpl parameter5 = | |
| 5732 new ParameterElementImpl.forNode(AstFactory.identifier3("a5")); | |
| 5733 parameter5.type = _typeProvider.intType; | |
| 5734 parameter5.parameterKind = ParameterKind.REQUIRED; | |
| 5735 methodM2.parameters = <ParameterElement>[ | |
| 5736 parameter3, | |
| 5737 parameter4, | |
| 5738 parameter5 | |
| 5739 ]; | |
| 5740 classI2.methods = <MethodElement>[methodM2]; | |
| 5741 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5742 classA.interfaces = <InterfaceType>[classI1.type, classI2.type]; | |
| 5743 MemberMap mapA = | |
| 5744 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5745 expect(mapA.size, _numOfMembersInObject); | |
| 5746 expect(mapA.get(methodName), isNull); | |
| 5747 _assertErrors( | |
| 5748 classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]); | |
| 5749 } | |
| 5750 | |
| 5751 void | |
| 5752 test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_
str_int() { | |
| 5753 // class I1 { int m(); } | |
| 5754 // class I2 { String m(); } | |
| 5755 // class A implements I2, I1 {} | |
| 5756 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5757 String methodName = "m"; | |
| 5758 MethodElement methodM1 = ElementFactory | |
| 5759 .methodElement(methodName, null, [_typeProvider.stringType]); | |
| 5760 classI1.methods = <MethodElement>[methodM1]; | |
| 5761 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5762 MethodElement methodM2 = | |
| 5763 ElementFactory.methodElement(methodName, null, [_typeProvider.intType]); | |
| 5764 classI2.methods = <MethodElement>[methodM2]; | |
| 5765 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5766 classA.interfaces = <InterfaceType>[classI2.type, classI1.type]; | |
| 5767 MemberMap mapA = | |
| 5768 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5769 expect(mapA.size, _numOfMembersInObject); | |
| 5770 expect(mapA.get(methodName), isNull); | |
| 5771 _assertErrors( | |
| 5772 classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]); | |
| 5773 } | |
| 5774 | |
| 5775 void test_getMapOfMembersInheritedFromInterfaces_method_extends() { | |
| 5776 // class A { int g(); } | |
| 5777 // class B extends A {} | |
| 5778 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5779 String methodName = "m"; | |
| 5780 MethodElement methodM = | |
| 5781 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5782 classA.methods = <MethodElement>[methodM]; | |
| 5783 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 5784 MemberMap mapB = | |
| 5785 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB); | |
| 5786 MemberMap mapA = | |
| 5787 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5788 expect(mapA.size, _numOfMembersInObject); | |
| 5789 expect(mapB.size, _numOfMembersInObject + 1); | |
| 5790 expect(mapB.get(methodName), same(methodM)); | |
| 5791 _assertNoErrors(classA); | |
| 5792 _assertNoErrors(classB); | |
| 5793 } | |
| 5794 | |
| 5795 void test_getMapOfMembersInheritedFromInterfaces_method_implements() { | |
| 5796 // class A { int g(); } | |
| 5797 // class B implements A {} | |
| 5798 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5799 String methodName = "m"; | |
| 5800 MethodElement methodM = | |
| 5801 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5802 classA.methods = <MethodElement>[methodM]; | |
| 5803 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5804 classB.interfaces = <InterfaceType>[classA.type]; | |
| 5805 MemberMap mapB = | |
| 5806 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB); | |
| 5807 MemberMap mapA = | |
| 5808 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5809 expect(mapA.size, _numOfMembersInObject); | |
| 5810 expect(mapB.size, _numOfMembersInObject + 1); | |
| 5811 expect(mapB.get(methodName), same(methodM)); | |
| 5812 _assertNoErrors(classA); | |
| 5813 _assertNoErrors(classB); | |
| 5814 } | |
| 5815 | |
| 5816 void test_getMapOfMembersInheritedFromInterfaces_method_with() { | |
| 5817 // class A { int g(); } | |
| 5818 // class B extends Object with A {} | |
| 5819 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5820 String methodName = "m"; | |
| 5821 MethodElement methodM = | |
| 5822 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 5823 classA.methods = <MethodElement>[methodM]; | |
| 5824 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 5825 classB.mixins = <InterfaceType>[classA.type]; | |
| 5826 MemberMap mapB = | |
| 5827 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB); | |
| 5828 MemberMap mapA = | |
| 5829 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5830 expect(mapA.size, _numOfMembersInObject); | |
| 5831 expect(mapB.size, _numOfMembersInObject + 1); | |
| 5832 expect(mapB.get(methodName), same(methodM)); | |
| 5833 _assertNoErrors(classA); | |
| 5834 _assertNoErrors(classB); | |
| 5835 } | |
| 5836 | |
| 5837 void test_getMapOfMembersInheritedFromInterfaces_union_differentNames() { | |
| 5838 // class I1 { int m1(); } | |
| 5839 // class I2 { int m2(); } | |
| 5840 // class A implements I1, I2 {} | |
| 5841 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5842 String methodName1 = "m1"; | |
| 5843 MethodElement methodM1 = | |
| 5844 ElementFactory.methodElement(methodName1, _typeProvider.intType); | |
| 5845 classI1.methods = <MethodElement>[methodM1]; | |
| 5846 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5847 String methodName2 = "m2"; | |
| 5848 MethodElement methodM2 = | |
| 5849 ElementFactory.methodElement(methodName2, _typeProvider.intType); | |
| 5850 classI2.methods = <MethodElement>[methodM2]; | |
| 5851 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5852 classA.interfaces = <InterfaceType>[classI1.type, classI2.type]; | |
| 5853 MemberMap mapA = | |
| 5854 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5855 expect(mapA.size, _numOfMembersInObject + 2); | |
| 5856 expect(mapA.get(methodName1), same(methodM1)); | |
| 5857 expect(mapA.get(methodName2), same(methodM2)); | |
| 5858 _assertNoErrors(classA); | |
| 5859 } | |
| 5860 | |
| 5861 void | |
| 5862 test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_gette
rs() { | |
| 5863 // class I1 { int get g; } | |
| 5864 // class I2 { num get g; } | |
| 5865 // class A implements I1, I2 {} | |
| 5866 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5867 String accessorName = "g"; | |
| 5868 PropertyAccessorElement getter1 = ElementFactory.getterElement( | |
| 5869 accessorName, false, _typeProvider.intType); | |
| 5870 classI1.accessors = <PropertyAccessorElement>[getter1]; | |
| 5871 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5872 PropertyAccessorElement getter2 = ElementFactory.getterElement( | |
| 5873 accessorName, false, _typeProvider.numType); | |
| 5874 classI2.accessors = <PropertyAccessorElement>[getter2]; | |
| 5875 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5876 classA.interfaces = <InterfaceType>[classI1.type, classI2.type]; | |
| 5877 MemberMap mapA = | |
| 5878 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5879 expect(mapA.size, _numOfMembersInObject + 1); | |
| 5880 PropertyAccessorElement syntheticAccessor = ElementFactory.getterElement( | |
| 5881 accessorName, false, _typeProvider.dynamicType); | |
| 5882 expect(mapA.get(accessorName).type, syntheticAccessor.type); | |
| 5883 _assertNoErrors(classA); | |
| 5884 } | |
| 5885 | |
| 5886 void | |
| 5887 test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_metho
ds() { | |
| 5888 // class I1 { dynamic m(int); } | |
| 5889 // class I2 { dynamic m(num); } | |
| 5890 // class A implements I1, I2 {} | |
| 5891 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5892 String methodName = "m"; | |
| 5893 MethodElementImpl methodM1 = | |
| 5894 ElementFactory.methodElement(methodName, _typeProvider.dynamicType); | |
| 5895 ParameterElementImpl parameter1 = | |
| 5896 new ParameterElementImpl.forNode(AstFactory.identifier3("a0")); | |
| 5897 parameter1.type = _typeProvider.intType; | |
| 5898 parameter1.parameterKind = ParameterKind.REQUIRED; | |
| 5899 methodM1.parameters = <ParameterElement>[parameter1]; | |
| 5900 classI1.methods = <MethodElement>[methodM1]; | |
| 5901 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5902 MethodElementImpl methodM2 = | |
| 5903 ElementFactory.methodElement(methodName, _typeProvider.dynamicType); | |
| 5904 ParameterElementImpl parameter2 = | |
| 5905 new ParameterElementImpl.forNode(AstFactory.identifier3("a0")); | |
| 5906 parameter2.type = _typeProvider.numType; | |
| 5907 parameter2.parameterKind = ParameterKind.REQUIRED; | |
| 5908 methodM2.parameters = <ParameterElement>[parameter2]; | |
| 5909 classI2.methods = <MethodElement>[methodM2]; | |
| 5910 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5911 classA.interfaces = <InterfaceType>[classI1.type, classI2.type]; | |
| 5912 MemberMap mapA = | |
| 5913 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5914 expect(mapA.size, _numOfMembersInObject + 1); | |
| 5915 MethodElement syntheticMethod = ElementFactory.methodElement( | |
| 5916 methodName, _typeProvider.dynamicType, [_typeProvider.dynamicType]); | |
| 5917 expect(mapA.get(methodName).type, syntheticMethod.type); | |
| 5918 _assertNoErrors(classA); | |
| 5919 } | |
| 5920 | |
| 5921 void | |
| 5922 test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_sette
rs() { | |
| 5923 // class I1 { set s(int); } | |
| 5924 // class I2 { set s(num); } | |
| 5925 // class A implements I1, I2 {} | |
| 5926 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5927 String accessorName = "s"; | |
| 5928 PropertyAccessorElement setter1 = ElementFactory.setterElement( | |
| 5929 accessorName, false, _typeProvider.intType); | |
| 5930 classI1.accessors = <PropertyAccessorElement>[setter1]; | |
| 5931 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5932 PropertyAccessorElement setter2 = ElementFactory.setterElement( | |
| 5933 accessorName, false, _typeProvider.numType); | |
| 5934 classI2.accessors = <PropertyAccessorElement>[setter2]; | |
| 5935 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5936 classA.interfaces = <InterfaceType>[classI1.type, classI2.type]; | |
| 5937 MemberMap mapA = | |
| 5938 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 5939 expect(mapA.size, _numOfMembersInObject + 1); | |
| 5940 PropertyAccessorElementImpl syntheticAccessor = ElementFactory | |
| 5941 .setterElement(accessorName, false, _typeProvider.dynamicType); | |
| 5942 syntheticAccessor.returnType = _typeProvider.dynamicType; | |
| 5943 expect(mapA.get("$accessorName=").type, syntheticAccessor.type); | |
| 5944 _assertNoErrors(classA); | |
| 5945 } | |
| 5946 | |
| 5947 void | |
| 5948 test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_gette
rs() { | |
| 5949 // class A {} | |
| 5950 // class B extends A {} | |
| 5951 // class C extends B {} | |
| 5952 // class I1 { A get g; } | |
| 5953 // class I2 { B get g; } | |
| 5954 // class I3 { C get g; } | |
| 5955 // class D implements I1, I2, I3 {} | |
| 5956 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5957 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 5958 ClassElementImpl classC = ElementFactory.classElement("C", classB.type); | |
| 5959 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 5960 String accessorName = "g"; | |
| 5961 PropertyAccessorElement getter1 = | |
| 5962 ElementFactory.getterElement(accessorName, false, classA.type); | |
| 5963 classI1.accessors = <PropertyAccessorElement>[getter1]; | |
| 5964 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 5965 PropertyAccessorElement getter2 = | |
| 5966 ElementFactory.getterElement(accessorName, false, classB.type); | |
| 5967 classI2.accessors = <PropertyAccessorElement>[getter2]; | |
| 5968 ClassElementImpl classI3 = ElementFactory.classElement2("I3"); | |
| 5969 PropertyAccessorElement getter3 = | |
| 5970 ElementFactory.getterElement(accessorName, false, classC.type); | |
| 5971 classI3.accessors = <PropertyAccessorElement>[getter3]; | |
| 5972 ClassElementImpl classD = ElementFactory.classElement2("D"); | |
| 5973 classD.interfaces = <InterfaceType>[ | |
| 5974 classI1.type, | |
| 5975 classI2.type, | |
| 5976 classI3.type | |
| 5977 ]; | |
| 5978 MemberMap mapD = | |
| 5979 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD); | |
| 5980 expect(mapD.size, _numOfMembersInObject + 1); | |
| 5981 PropertyAccessorElement syntheticAccessor = ElementFactory.getterElement( | |
| 5982 accessorName, false, _typeProvider.dynamicType); | |
| 5983 expect(mapD.get(accessorName).type, syntheticAccessor.type); | |
| 5984 _assertNoErrors(classD); | |
| 5985 } | |
| 5986 | |
| 5987 void | |
| 5988 test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_metho
ds() { | |
| 5989 // class A {} | |
| 5990 // class B extends A {} | |
| 5991 // class C extends B {} | |
| 5992 // class I1 { dynamic m(A a); } | |
| 5993 // class I2 { dynamic m(B b); } | |
| 5994 // class I3 { dynamic m(C c); } | |
| 5995 // class D implements I1, I2, I3 {} | |
| 5996 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 5997 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 5998 ClassElementImpl classC = ElementFactory.classElement("C", classB.type); | |
| 5999 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 6000 String methodName = "m"; | |
| 6001 MethodElementImpl methodM1 = | |
| 6002 ElementFactory.methodElement(methodName, _typeProvider.dynamicType); | |
| 6003 ParameterElementImpl parameter1 = | |
| 6004 new ParameterElementImpl.forNode(AstFactory.identifier3("a0")); | |
| 6005 parameter1.type = classA.type; | |
| 6006 parameter1.parameterKind = ParameterKind.REQUIRED; | |
| 6007 methodM1.parameters = <ParameterElement>[parameter1]; | |
| 6008 classI1.methods = <MethodElement>[methodM1]; | |
| 6009 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 6010 MethodElementImpl methodM2 = | |
| 6011 ElementFactory.methodElement(methodName, _typeProvider.dynamicType); | |
| 6012 ParameterElementImpl parameter2 = | |
| 6013 new ParameterElementImpl.forNode(AstFactory.identifier3("a0")); | |
| 6014 parameter2.type = classB.type; | |
| 6015 parameter2.parameterKind = ParameterKind.REQUIRED; | |
| 6016 methodM2.parameters = <ParameterElement>[parameter2]; | |
| 6017 classI2.methods = <MethodElement>[methodM2]; | |
| 6018 ClassElementImpl classI3 = ElementFactory.classElement2("I3"); | |
| 6019 MethodElementImpl methodM3 = | |
| 6020 ElementFactory.methodElement(methodName, _typeProvider.dynamicType); | |
| 6021 ParameterElementImpl parameter3 = | |
| 6022 new ParameterElementImpl.forNode(AstFactory.identifier3("a0")); | |
| 6023 parameter3.type = classC.type; | |
| 6024 parameter3.parameterKind = ParameterKind.REQUIRED; | |
| 6025 methodM3.parameters = <ParameterElement>[parameter3]; | |
| 6026 classI3.methods = <MethodElement>[methodM3]; | |
| 6027 ClassElementImpl classD = ElementFactory.classElement2("D"); | |
| 6028 classD.interfaces = <InterfaceType>[ | |
| 6029 classI1.type, | |
| 6030 classI2.type, | |
| 6031 classI3.type | |
| 6032 ]; | |
| 6033 MemberMap mapD = | |
| 6034 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD); | |
| 6035 expect(mapD.size, _numOfMembersInObject + 1); | |
| 6036 MethodElement syntheticMethod = ElementFactory.methodElement( | |
| 6037 methodName, _typeProvider.dynamicType, [_typeProvider.dynamicType]); | |
| 6038 expect(mapD.get(methodName).type, syntheticMethod.type); | |
| 6039 _assertNoErrors(classD); | |
| 6040 } | |
| 6041 | |
| 6042 void | |
| 6043 test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_sette
rs() { | |
| 6044 // class A {} | |
| 6045 // class B extends A {} | |
| 6046 // class C extends B {} | |
| 6047 // class I1 { set s(A); } | |
| 6048 // class I2 { set s(B); } | |
| 6049 // class I3 { set s(C); } | |
| 6050 // class D implements I1, I2, I3 {} | |
| 6051 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6052 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 6053 ClassElementImpl classC = ElementFactory.classElement("C", classB.type); | |
| 6054 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 6055 String accessorName = "s"; | |
| 6056 PropertyAccessorElement setter1 = | |
| 6057 ElementFactory.setterElement(accessorName, false, classA.type); | |
| 6058 classI1.accessors = <PropertyAccessorElement>[setter1]; | |
| 6059 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 6060 PropertyAccessorElement setter2 = | |
| 6061 ElementFactory.setterElement(accessorName, false, classB.type); | |
| 6062 classI2.accessors = <PropertyAccessorElement>[setter2]; | |
| 6063 ClassElementImpl classI3 = ElementFactory.classElement2("I3"); | |
| 6064 PropertyAccessorElement setter3 = | |
| 6065 ElementFactory.setterElement(accessorName, false, classC.type); | |
| 6066 classI3.accessors = <PropertyAccessorElement>[setter3]; | |
| 6067 ClassElementImpl classD = ElementFactory.classElement2("D"); | |
| 6068 classD.interfaces = <InterfaceType>[ | |
| 6069 classI1.type, | |
| 6070 classI2.type, | |
| 6071 classI3.type | |
| 6072 ]; | |
| 6073 MemberMap mapD = | |
| 6074 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD); | |
| 6075 expect(mapD.size, _numOfMembersInObject + 1); | |
| 6076 PropertyAccessorElementImpl syntheticAccessor = ElementFactory | |
| 6077 .setterElement(accessorName, false, _typeProvider.dynamicType); | |
| 6078 syntheticAccessor.returnType = _typeProvider.dynamicType; | |
| 6079 expect(mapD.get("$accessorName=").type, syntheticAccessor.type); | |
| 6080 _assertNoErrors(classD); | |
| 6081 } | |
| 6082 | |
| 6083 void | |
| 6084 test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_2_methods() { | |
| 6085 // class I1 { int m(); } | |
| 6086 // class I2 { int m([int]); } | |
| 6087 // class A implements I1, I2 {} | |
| 6088 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 6089 String methodName = "m"; | |
| 6090 MethodElement methodM1 = | |
| 6091 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6092 classI1.methods = <MethodElement>[methodM1]; | |
| 6093 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 6094 MethodElementImpl methodM2 = | |
| 6095 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6096 ParameterElementImpl parameter1 = | |
| 6097 new ParameterElementImpl.forNode(AstFactory.identifier3("a1")); | |
| 6098 parameter1.type = _typeProvider.intType; | |
| 6099 parameter1.parameterKind = ParameterKind.POSITIONAL; | |
| 6100 methodM2.parameters = <ParameterElement>[parameter1]; | |
| 6101 classI2.methods = <MethodElement>[methodM2]; | |
| 6102 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6103 classA.interfaces = <InterfaceType>[classI1.type, classI2.type]; | |
| 6104 MemberMap mapA = | |
| 6105 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 6106 expect(mapA.size, _numOfMembersInObject + 1); | |
| 6107 expect(mapA.get(methodName), same(methodM2)); | |
| 6108 _assertNoErrors(classA); | |
| 6109 } | |
| 6110 | |
| 6111 void | |
| 6112 test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_3_methods() { | |
| 6113 // class I1 { int m(); } | |
| 6114 // class I2 { int m([int]); } | |
| 6115 // class I3 { int m([int, int]); } | |
| 6116 // class A implements I1, I2, I3 {} | |
| 6117 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 6118 String methodName = "m"; | |
| 6119 MethodElementImpl methodM1 = | |
| 6120 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6121 classI1.methods = <MethodElement>[methodM1]; | |
| 6122 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 6123 MethodElementImpl methodM2 = | |
| 6124 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6125 ParameterElementImpl parameter1 = | |
| 6126 new ParameterElementImpl.forNode(AstFactory.identifier3("a1")); | |
| 6127 parameter1.type = _typeProvider.intType; | |
| 6128 parameter1.parameterKind = ParameterKind.POSITIONAL; | |
| 6129 methodM1.parameters = <ParameterElement>[parameter1]; | |
| 6130 classI2.methods = <MethodElement>[methodM2]; | |
| 6131 ClassElementImpl classI3 = ElementFactory.classElement2("I3"); | |
| 6132 MethodElementImpl methodM3 = | |
| 6133 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6134 ParameterElementImpl parameter2 = | |
| 6135 new ParameterElementImpl.forNode(AstFactory.identifier3("a2")); | |
| 6136 parameter2.type = _typeProvider.intType; | |
| 6137 parameter2.parameterKind = ParameterKind.POSITIONAL; | |
| 6138 ParameterElementImpl parameter3 = | |
| 6139 new ParameterElementImpl.forNode(AstFactory.identifier3("a3")); | |
| 6140 parameter3.type = _typeProvider.intType; | |
| 6141 parameter3.parameterKind = ParameterKind.POSITIONAL; | |
| 6142 methodM3.parameters = <ParameterElement>[parameter2, parameter3]; | |
| 6143 classI3.methods = <MethodElement>[methodM3]; | |
| 6144 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6145 classA.interfaces = <InterfaceType>[ | |
| 6146 classI1.type, | |
| 6147 classI2.type, | |
| 6148 classI3.type | |
| 6149 ]; | |
| 6150 MemberMap mapA = | |
| 6151 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 6152 expect(mapA.size, _numOfMembersInObject + 1); | |
| 6153 expect(mapA.get(methodName), same(methodM3)); | |
| 6154 _assertNoErrors(classA); | |
| 6155 } | |
| 6156 | |
| 6157 void | |
| 6158 test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_4_methods() { | |
| 6159 // class I1 { int m(); } | |
| 6160 // class I2 { int m(); } | |
| 6161 // class I3 { int m([int]); } | |
| 6162 // class I4 { int m([int, int]); } | |
| 6163 // class A implements I1, I2, I3, I4 {} | |
| 6164 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 6165 String methodName = "m"; | |
| 6166 MethodElement methodM1 = | |
| 6167 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6168 classI1.methods = <MethodElement>[methodM1]; | |
| 6169 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 6170 MethodElement methodM2 = | |
| 6171 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6172 classI2.methods = <MethodElement>[methodM2]; | |
| 6173 ClassElementImpl classI3 = ElementFactory.classElement2("I3"); | |
| 6174 MethodElementImpl methodM3 = | |
| 6175 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6176 ParameterElementImpl parameter1 = | |
| 6177 new ParameterElementImpl.forNode(AstFactory.identifier3("a1")); | |
| 6178 parameter1.type = _typeProvider.intType; | |
| 6179 parameter1.parameterKind = ParameterKind.POSITIONAL; | |
| 6180 methodM3.parameters = <ParameterElement>[parameter1]; | |
| 6181 classI3.methods = <MethodElement>[methodM3]; | |
| 6182 ClassElementImpl classI4 = ElementFactory.classElement2("I4"); | |
| 6183 MethodElementImpl methodM4 = | |
| 6184 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6185 ParameterElementImpl parameter2 = | |
| 6186 new ParameterElementImpl.forNode(AstFactory.identifier3("a2")); | |
| 6187 parameter2.type = _typeProvider.intType; | |
| 6188 parameter2.parameterKind = ParameterKind.POSITIONAL; | |
| 6189 ParameterElementImpl parameter3 = | |
| 6190 new ParameterElementImpl.forNode(AstFactory.identifier3("a3")); | |
| 6191 parameter3.type = _typeProvider.intType; | |
| 6192 parameter3.parameterKind = ParameterKind.POSITIONAL; | |
| 6193 methodM4.parameters = <ParameterElement>[parameter2, parameter3]; | |
| 6194 classI4.methods = <MethodElement>[methodM4]; | |
| 6195 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6196 classA.interfaces = <InterfaceType>[ | |
| 6197 classI1.type, | |
| 6198 classI2.type, | |
| 6199 classI3.type, | |
| 6200 classI4.type | |
| 6201 ]; | |
| 6202 MemberMap mapA = | |
| 6203 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); | |
| 6204 expect(mapA.size, _numOfMembersInObject + 1); | |
| 6205 expect(mapA.get(methodName), same(methodM4)); | |
| 6206 _assertNoErrors(classA); | |
| 6207 } | |
| 6208 | |
| 6209 void test_lookupInheritance_interface_getter() { | |
| 6210 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6211 String getterName = "g"; | |
| 6212 PropertyAccessorElement getterG = | |
| 6213 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 6214 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 6215 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 6216 classB.interfaces = <InterfaceType>[classA.type]; | |
| 6217 expect(_inheritanceManager.lookupInheritance(classB, getterName), | |
| 6218 same(getterG)); | |
| 6219 _assertNoErrors(classA); | |
| 6220 _assertNoErrors(classB); | |
| 6221 } | |
| 6222 | |
| 6223 void test_lookupInheritance_interface_method() { | |
| 6224 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6225 String methodName = "m"; | |
| 6226 MethodElement methodM = | |
| 6227 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6228 classA.methods = <MethodElement>[methodM]; | |
| 6229 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 6230 classB.interfaces = <InterfaceType>[classA.type]; | |
| 6231 expect(_inheritanceManager.lookupInheritance(classB, methodName), | |
| 6232 same(methodM)); | |
| 6233 _assertNoErrors(classA); | |
| 6234 _assertNoErrors(classB); | |
| 6235 } | |
| 6236 | |
| 6237 void test_lookupInheritance_interface_setter() { | |
| 6238 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6239 String setterName = "s"; | |
| 6240 PropertyAccessorElement setterS = | |
| 6241 ElementFactory.setterElement(setterName, false, _typeProvider.intType); | |
| 6242 classA.accessors = <PropertyAccessorElement>[setterS]; | |
| 6243 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 6244 classB.interfaces = <InterfaceType>[classA.type]; | |
| 6245 expect(_inheritanceManager.lookupInheritance(classB, "$setterName="), | |
| 6246 same(setterS)); | |
| 6247 _assertNoErrors(classA); | |
| 6248 _assertNoErrors(classB); | |
| 6249 } | |
| 6250 | |
| 6251 void test_lookupInheritance_interface_staticMember() { | |
| 6252 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6253 String methodName = "m"; | |
| 6254 MethodElement methodM = | |
| 6255 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6256 (methodM as MethodElementImpl).static = true; | |
| 6257 classA.methods = <MethodElement>[methodM]; | |
| 6258 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 6259 classB.interfaces = <InterfaceType>[classA.type]; | |
| 6260 expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull); | |
| 6261 _assertNoErrors(classA); | |
| 6262 _assertNoErrors(classB); | |
| 6263 } | |
| 6264 | |
| 6265 void test_lookupInheritance_interfaces_infiniteLoop() { | |
| 6266 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6267 classA.interfaces = <InterfaceType>[classA.type]; | |
| 6268 expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull); | |
| 6269 _assertNoErrors(classA); | |
| 6270 } | |
| 6271 | |
| 6272 void test_lookupInheritance_interfaces_infiniteLoop2() { | |
| 6273 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6274 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 6275 classA.interfaces = <InterfaceType>[classB.type]; | |
| 6276 classB.interfaces = <InterfaceType>[classA.type]; | |
| 6277 expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull); | |
| 6278 _assertNoErrors(classA); | |
| 6279 _assertNoErrors(classB); | |
| 6280 } | |
| 6281 | |
| 6282 void test_lookupInheritance_interfaces_union2() { | |
| 6283 ClassElementImpl classI1 = ElementFactory.classElement2("I1"); | |
| 6284 String methodName1 = "m1"; | |
| 6285 MethodElement methodM1 = | |
| 6286 ElementFactory.methodElement(methodName1, _typeProvider.intType); | |
| 6287 classI1.methods = <MethodElement>[methodM1]; | |
| 6288 ClassElementImpl classI2 = ElementFactory.classElement2("I2"); | |
| 6289 String methodName2 = "m2"; | |
| 6290 MethodElement methodM2 = | |
| 6291 ElementFactory.methodElement(methodName2, _typeProvider.intType); | |
| 6292 classI2.methods = <MethodElement>[methodM2]; | |
| 6293 classI2.interfaces = <InterfaceType>[classI1.type]; | |
| 6294 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6295 classA.interfaces = <InterfaceType>[classI2.type]; | |
| 6296 expect(_inheritanceManager.lookupInheritance(classA, methodName1), | |
| 6297 same(methodM1)); | |
| 6298 expect(_inheritanceManager.lookupInheritance(classA, methodName2), | |
| 6299 same(methodM2)); | |
| 6300 _assertNoErrors(classI1); | |
| 6301 _assertNoErrors(classI2); | |
| 6302 _assertNoErrors(classA); | |
| 6303 } | |
| 6304 | |
| 6305 void test_lookupInheritance_mixin_getter() { | |
| 6306 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6307 String getterName = "g"; | |
| 6308 PropertyAccessorElement getterG = | |
| 6309 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 6310 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 6311 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 6312 classB.mixins = <InterfaceType>[classA.type]; | |
| 6313 expect(_inheritanceManager.lookupInheritance(classB, getterName), | |
| 6314 same(getterG)); | |
| 6315 _assertNoErrors(classA); | |
| 6316 _assertNoErrors(classB); | |
| 6317 } | |
| 6318 | |
| 6319 void test_lookupInheritance_mixin_method() { | |
| 6320 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6321 String methodName = "m"; | |
| 6322 MethodElement methodM = | |
| 6323 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6324 classA.methods = <MethodElement>[methodM]; | |
| 6325 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 6326 classB.mixins = <InterfaceType>[classA.type]; | |
| 6327 expect(_inheritanceManager.lookupInheritance(classB, methodName), | |
| 6328 same(methodM)); | |
| 6329 _assertNoErrors(classA); | |
| 6330 _assertNoErrors(classB); | |
| 6331 } | |
| 6332 | |
| 6333 void test_lookupInheritance_mixin_setter() { | |
| 6334 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6335 String setterName = "s"; | |
| 6336 PropertyAccessorElement setterS = | |
| 6337 ElementFactory.setterElement(setterName, false, _typeProvider.intType); | |
| 6338 classA.accessors = <PropertyAccessorElement>[setterS]; | |
| 6339 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 6340 classB.mixins = <InterfaceType>[classA.type]; | |
| 6341 expect(_inheritanceManager.lookupInheritance(classB, "$setterName="), | |
| 6342 same(setterS)); | |
| 6343 _assertNoErrors(classA); | |
| 6344 _assertNoErrors(classB); | |
| 6345 } | |
| 6346 | |
| 6347 void test_lookupInheritance_mixin_staticMember() { | |
| 6348 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6349 String methodName = "m"; | |
| 6350 MethodElement methodM = | |
| 6351 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6352 (methodM as MethodElementImpl).static = true; | |
| 6353 classA.methods = <MethodElement>[methodM]; | |
| 6354 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 6355 classB.mixins = <InterfaceType>[classA.type]; | |
| 6356 expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull); | |
| 6357 _assertNoErrors(classA); | |
| 6358 _assertNoErrors(classB); | |
| 6359 } | |
| 6360 | |
| 6361 void test_lookupInheritance_noMember() { | |
| 6362 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6363 expect(_inheritanceManager.lookupInheritance(classA, "a"), isNull); | |
| 6364 _assertNoErrors(classA); | |
| 6365 } | |
| 6366 | |
| 6367 void test_lookupInheritance_superclass_getter() { | |
| 6368 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6369 String getterName = "g"; | |
| 6370 PropertyAccessorElement getterG = | |
| 6371 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 6372 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 6373 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 6374 expect(_inheritanceManager.lookupInheritance(classB, getterName), | |
| 6375 same(getterG)); | |
| 6376 _assertNoErrors(classA); | |
| 6377 _assertNoErrors(classB); | |
| 6378 } | |
| 6379 | |
| 6380 void test_lookupInheritance_superclass_infiniteLoop() { | |
| 6381 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6382 classA.supertype = classA.type; | |
| 6383 expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull); | |
| 6384 _assertNoErrors(classA); | |
| 6385 } | |
| 6386 | |
| 6387 void test_lookupInheritance_superclass_infiniteLoop2() { | |
| 6388 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6389 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 6390 classA.supertype = classB.type; | |
| 6391 classB.supertype = classA.type; | |
| 6392 expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull); | |
| 6393 _assertNoErrors(classA); | |
| 6394 _assertNoErrors(classB); | |
| 6395 } | |
| 6396 | |
| 6397 void test_lookupInheritance_superclass_method() { | |
| 6398 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6399 String methodName = "m"; | |
| 6400 MethodElement methodM = | |
| 6401 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6402 classA.methods = <MethodElement>[methodM]; | |
| 6403 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 6404 expect(_inheritanceManager.lookupInheritance(classB, methodName), | |
| 6405 same(methodM)); | |
| 6406 _assertNoErrors(classA); | |
| 6407 _assertNoErrors(classB); | |
| 6408 } | |
| 6409 | |
| 6410 void test_lookupInheritance_superclass_setter() { | |
| 6411 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6412 String setterName = "s"; | |
| 6413 PropertyAccessorElement setterS = | |
| 6414 ElementFactory.setterElement(setterName, false, _typeProvider.intType); | |
| 6415 classA.accessors = <PropertyAccessorElement>[setterS]; | |
| 6416 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 6417 expect(_inheritanceManager.lookupInheritance(classB, "$setterName="), | |
| 6418 same(setterS)); | |
| 6419 _assertNoErrors(classA); | |
| 6420 _assertNoErrors(classB); | |
| 6421 } | |
| 6422 | |
| 6423 void test_lookupInheritance_superclass_staticMember() { | |
| 6424 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6425 String methodName = "m"; | |
| 6426 MethodElement methodM = | |
| 6427 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6428 (methodM as MethodElementImpl).static = true; | |
| 6429 classA.methods = <MethodElement>[methodM]; | |
| 6430 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 6431 expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull); | |
| 6432 _assertNoErrors(classA); | |
| 6433 _assertNoErrors(classB); | |
| 6434 } | |
| 6435 | |
| 6436 void test_lookupMember_getter() { | |
| 6437 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6438 String getterName = "g"; | |
| 6439 PropertyAccessorElement getterG = | |
| 6440 ElementFactory.getterElement(getterName, false, _typeProvider.intType); | |
| 6441 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 6442 expect(_inheritanceManager.lookupMember(classA, getterName), same(getterG)); | |
| 6443 _assertNoErrors(classA); | |
| 6444 } | |
| 6445 | |
| 6446 void test_lookupMember_getter_static() { | |
| 6447 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6448 String getterName = "g"; | |
| 6449 PropertyAccessorElement getterG = | |
| 6450 ElementFactory.getterElement(getterName, true, _typeProvider.intType); | |
| 6451 classA.accessors = <PropertyAccessorElement>[getterG]; | |
| 6452 expect(_inheritanceManager.lookupMember(classA, getterName), isNull); | |
| 6453 _assertNoErrors(classA); | |
| 6454 } | |
| 6455 | |
| 6456 void test_lookupMember_method() { | |
| 6457 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6458 String methodName = "m"; | |
| 6459 MethodElement methodM = | |
| 6460 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6461 classA.methods = <MethodElement>[methodM]; | |
| 6462 expect(_inheritanceManager.lookupMember(classA, methodName), same(methodM)); | |
| 6463 _assertNoErrors(classA); | |
| 6464 } | |
| 6465 | |
| 6466 void test_lookupMember_method_static() { | |
| 6467 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6468 String methodName = "m"; | |
| 6469 MethodElement methodM = | |
| 6470 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6471 (methodM as MethodElementImpl).static = true; | |
| 6472 classA.methods = <MethodElement>[methodM]; | |
| 6473 expect(_inheritanceManager.lookupMember(classA, methodName), isNull); | |
| 6474 _assertNoErrors(classA); | |
| 6475 } | |
| 6476 | |
| 6477 void test_lookupMember_noMember() { | |
| 6478 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6479 expect(_inheritanceManager.lookupMember(classA, "a"), isNull); | |
| 6480 _assertNoErrors(classA); | |
| 6481 } | |
| 6482 | |
| 6483 void test_lookupMember_setter() { | |
| 6484 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6485 String setterName = "s"; | |
| 6486 PropertyAccessorElement setterS = | |
| 6487 ElementFactory.setterElement(setterName, false, _typeProvider.intType); | |
| 6488 classA.accessors = <PropertyAccessorElement>[setterS]; | |
| 6489 expect(_inheritanceManager.lookupMember(classA, "$setterName="), | |
| 6490 same(setterS)); | |
| 6491 _assertNoErrors(classA); | |
| 6492 } | |
| 6493 | |
| 6494 void test_lookupMember_setter_static() { | |
| 6495 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6496 String setterName = "s"; | |
| 6497 PropertyAccessorElement setterS = | |
| 6498 ElementFactory.setterElement(setterName, true, _typeProvider.intType); | |
| 6499 classA.accessors = <PropertyAccessorElement>[setterS]; | |
| 6500 expect(_inheritanceManager.lookupMember(classA, setterName), isNull); | |
| 6501 _assertNoErrors(classA); | |
| 6502 } | |
| 6503 | |
| 6504 void test_lookupOverrides_noParentClasses() { | |
| 6505 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6506 String methodName = "m"; | |
| 6507 MethodElementImpl methodM = | |
| 6508 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6509 classA.methods = <MethodElement>[methodM]; | |
| 6510 expect( | |
| 6511 _inheritanceManager.lookupOverrides(classA, methodName), hasLength(0)); | |
| 6512 _assertNoErrors(classA); | |
| 6513 } | |
| 6514 | |
| 6515 void test_lookupOverrides_overrideBaseClass() { | |
| 6516 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6517 String methodName = "m"; | |
| 6518 MethodElementImpl methodMinA = | |
| 6519 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6520 classA.methods = <MethodElement>[methodMinA]; | |
| 6521 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
| 6522 MethodElementImpl methodMinB = | |
| 6523 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6524 classB.methods = <MethodElement>[methodMinB]; | |
| 6525 List<ExecutableElement> overrides = | |
| 6526 _inheritanceManager.lookupOverrides(classB, methodName); | |
| 6527 expect(overrides, unorderedEquals([methodMinA])); | |
| 6528 _assertNoErrors(classA); | |
| 6529 _assertNoErrors(classB); | |
| 6530 } | |
| 6531 | |
| 6532 void test_lookupOverrides_overrideInterface() { | |
| 6533 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6534 String methodName = "m"; | |
| 6535 MethodElementImpl methodMinA = | |
| 6536 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6537 classA.methods = <MethodElement>[methodMinA]; | |
| 6538 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 6539 classB.interfaces = <InterfaceType>[classA.type]; | |
| 6540 MethodElementImpl methodMinB = | |
| 6541 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6542 classB.methods = <MethodElement>[methodMinB]; | |
| 6543 List<ExecutableElement> overrides = | |
| 6544 _inheritanceManager.lookupOverrides(classB, methodName); | |
| 6545 expect(overrides, unorderedEquals([methodMinA])); | |
| 6546 _assertNoErrors(classA); | |
| 6547 _assertNoErrors(classB); | |
| 6548 } | |
| 6549 | |
| 6550 void test_lookupOverrides_overrideTwoInterfaces() { | |
| 6551 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 6552 String methodName = "m"; | |
| 6553 MethodElementImpl methodMinA = | |
| 6554 ElementFactory.methodElement(methodName, _typeProvider.intType); | |
| 6555 classA.methods = <MethodElement>[methodMinA]; | |
| 6556 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
| 6557 MethodElementImpl methodMinB = | |
| 6558 ElementFactory.methodElement(methodName, _typeProvider.doubleType); | |
| 6559 classB.methods = <MethodElement>[methodMinB]; | |
| 6560 ClassElementImpl classC = ElementFactory.classElement2("C"); | |
| 6561 classC.interfaces = <InterfaceType>[classA.type, classB.type]; | |
| 6562 MethodElementImpl methodMinC = | |
| 6563 ElementFactory.methodElement(methodName, _typeProvider.numType); | |
| 6564 classC.methods = <MethodElement>[methodMinC]; | |
| 6565 List<ExecutableElement> overrides = | |
| 6566 _inheritanceManager.lookupOverrides(classC, methodName); | |
| 6567 expect(overrides, unorderedEquals([methodMinA, methodMinB])); | |
| 6568 _assertNoErrors(classA); | |
| 6569 _assertNoErrors(classB); | |
| 6570 _assertNoErrors(classC); | |
| 6571 } | |
| 6572 | |
| 6573 void _assertErrors(ClassElement classElt, | |
| 6574 [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) { | |
| 6575 GatheringErrorListener errorListener = new GatheringErrorListener(); | |
| 6576 HashSet<AnalysisError> actualErrors = | |
| 6577 _inheritanceManager.getErrors(classElt); | |
| 6578 if (actualErrors != null) { | |
| 6579 for (AnalysisError error in actualErrors) { | |
| 6580 errorListener.onError(error); | |
| 6581 } | |
| 6582 } | |
| 6583 errorListener.assertErrorsWithCodes(expectedErrorCodes); | |
| 6584 } | |
| 6585 | |
| 6586 void _assertNoErrors(ClassElement classElt) { | |
| 6587 _assertErrors(classElt); | |
| 6588 } | |
| 6589 | |
| 6590 /** | |
| 6591 * Create the inheritance manager used by the tests. | |
| 6592 * | |
| 6593 * @return the inheritance manager that was created | |
| 6594 */ | |
| 6595 InheritanceManager _createInheritanceManager() { | |
| 6596 AnalysisContext context = AnalysisContextFactory.contextWithCore(); | |
| 6597 FileBasedSource source = | |
| 6598 new FileBasedSource(FileUtilities2.createFile("/test.dart")); | |
| 6599 CompilationUnitElementImpl definingCompilationUnit = | |
| 6600 new CompilationUnitElementImpl("test.dart"); | |
| 6601 definingCompilationUnit.librarySource = | |
| 6602 definingCompilationUnit.source = source; | |
| 6603 _definingLibrary = ElementFactory.library(context, "test"); | |
| 6604 _definingLibrary.definingCompilationUnit = definingCompilationUnit; | |
| 6605 return new InheritanceManager(_definingLibrary); | |
| 6606 } | 320 } |
| 6607 } | 321 } |
| 6608 | 322 |
| 6609 @reflectiveTest | 323 @reflectiveTest |
| 6610 class LibraryImportScopeTest extends ResolverTestCase { | 324 class LibraryImportScopeTest extends ResolverTestCase { |
| 6611 void test_conflictingImports() { | 325 void test_conflictingImports() { |
| 6612 AnalysisContext context = AnalysisContextFactory.contextWithCore(); | 326 AnalysisContext context = AnalysisContextFactory.contextWithCore(); |
| 6613 String typeNameA = "A"; | 327 String typeNameA = "A"; |
| 6614 String typeNameB = "B"; | 328 String typeNameB = "B"; |
| 6615 String typeNameC = "C"; | 329 String typeNameC = "C"; |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6861 void test_MemberMap_put() { | 575 void test_MemberMap_put() { |
| 6862 MethodElement m1 = ElementFactory.methodElement("m1", _nullType); | 576 MethodElement m1 = ElementFactory.methodElement("m1", _nullType); |
| 6863 MemberMap map = new MemberMap(); | 577 MemberMap map = new MemberMap(); |
| 6864 expect(map.size, 0); | 578 expect(map.size, 0); |
| 6865 map.put(m1.name, m1); | 579 map.put(m1.name, m1); |
| 6866 expect(map.size, 1); | 580 expect(map.size, 1); |
| 6867 expect(map.get("m1"), m1); | 581 expect(map.get("m1"), m1); |
| 6868 } | 582 } |
| 6869 } | 583 } |
| 6870 | 584 |
| 6871 @reflectiveTest | |
| 6872 class NonHintCodeTest extends ResolverTestCase { | |
| 6873 void test_deadCode_deadBlock_conditionalElse_debugConst() { | |
| 6874 Source source = addSource(r''' | |
| 6875 const bool DEBUG = true; | |
| 6876 f() { | |
| 6877 DEBUG ? 1 : 2; | |
| 6878 }'''); | |
| 6879 computeLibrarySourceErrors(source); | |
| 6880 assertNoErrors(source); | |
| 6881 verify([source]); | |
| 6882 } | |
| 6883 | |
| 6884 void test_deadCode_deadBlock_conditionalIf_debugConst() { | |
| 6885 Source source = addSource(r''' | |
| 6886 const bool DEBUG = false; | |
| 6887 f() { | |
| 6888 DEBUG ? 1 : 2; | |
| 6889 }'''); | |
| 6890 computeLibrarySourceErrors(source); | |
| 6891 assertNoErrors(source); | |
| 6892 verify([source]); | |
| 6893 } | |
| 6894 | |
| 6895 void test_deadCode_deadBlock_else() { | |
| 6896 Source source = addSource(r''' | |
| 6897 const bool DEBUG = true; | |
| 6898 f() { | |
| 6899 if(DEBUG) {} else {} | |
| 6900 }'''); | |
| 6901 computeLibrarySourceErrors(source); | |
| 6902 assertNoErrors(source); | |
| 6903 verify([source]); | |
| 6904 } | |
| 6905 | |
| 6906 void test_deadCode_deadBlock_if_debugConst_prefixedIdentifier() { | |
| 6907 Source source = addSource(r''' | |
| 6908 class A { | |
| 6909 static const bool DEBUG = false; | |
| 6910 } | |
| 6911 f() { | |
| 6912 if(A.DEBUG) {} | |
| 6913 }'''); | |
| 6914 computeLibrarySourceErrors(source); | |
| 6915 assertNoErrors(source); | |
| 6916 verify([source]); | |
| 6917 } | |
| 6918 | |
| 6919 void test_deadCode_deadBlock_if_debugConst_prefixedIdentifier2() { | |
| 6920 Source source = addSource(r''' | |
| 6921 library L; | |
| 6922 import 'lib2.dart'; | |
| 6923 f() { | |
| 6924 if(A.DEBUG) {} | |
| 6925 }'''); | |
| 6926 addNamedSource( | |
| 6927 "/lib2.dart", | |
| 6928 r''' | |
| 6929 library lib2; | |
| 6930 class A { | |
| 6931 static const bool DEBUG = false; | |
| 6932 }'''); | |
| 6933 computeLibrarySourceErrors(source); | |
| 6934 assertNoErrors(source); | |
| 6935 verify([source]); | |
| 6936 } | |
| 6937 | |
| 6938 void test_deadCode_deadBlock_if_debugConst_propertyAccessor() { | |
| 6939 Source source = addSource(r''' | |
| 6940 library L; | |
| 6941 import 'lib2.dart' as LIB; | |
| 6942 f() { | |
| 6943 if(LIB.A.DEBUG) {} | |
| 6944 }'''); | |
| 6945 addNamedSource( | |
| 6946 "/lib2.dart", | |
| 6947 r''' | |
| 6948 library lib2; | |
| 6949 class A { | |
| 6950 static const bool DEBUG = false; | |
| 6951 }'''); | |
| 6952 computeLibrarySourceErrors(source); | |
| 6953 assertNoErrors(source); | |
| 6954 verify([source]); | |
| 6955 } | |
| 6956 | |
| 6957 void test_deadCode_deadBlock_if_debugConst_simpleIdentifier() { | |
| 6958 Source source = addSource(r''' | |
| 6959 const bool DEBUG = false; | |
| 6960 f() { | |
| 6961 if(DEBUG) {} | |
| 6962 }'''); | |
| 6963 computeLibrarySourceErrors(source); | |
| 6964 assertNoErrors(source); | |
| 6965 verify([source]); | |
| 6966 } | |
| 6967 | |
| 6968 void test_deadCode_deadBlock_while_debugConst() { | |
| 6969 Source source = addSource(r''' | |
| 6970 const bool DEBUG = false; | |
| 6971 f() { | |
| 6972 while(DEBUG) {} | |
| 6973 }'''); | |
| 6974 computeLibrarySourceErrors(source); | |
| 6975 assertNoErrors(source); | |
| 6976 verify([source]); | |
| 6977 } | |
| 6978 | |
| 6979 void test_deadCode_deadCatch_onCatchSubtype() { | |
| 6980 Source source = addSource(r''' | |
| 6981 class A {} | |
| 6982 class B extends A {} | |
| 6983 f() { | |
| 6984 try {} on B catch (e) {} on A catch (e) {} catch (e) {} | |
| 6985 }'''); | |
| 6986 computeLibrarySourceErrors(source); | |
| 6987 assertNoErrors(source); | |
| 6988 verify([source]); | |
| 6989 } | |
| 6990 | |
| 6991 void test_deadCode_deadOperandLHS_and_debugConst() { | |
| 6992 Source source = addSource(r''' | |
| 6993 const bool DEBUG = false; | |
| 6994 f() { | |
| 6995 bool b = DEBUG && false; | |
| 6996 }'''); | |
| 6997 computeLibrarySourceErrors(source); | |
| 6998 assertNoErrors(source); | |
| 6999 verify([source]); | |
| 7000 } | |
| 7001 | |
| 7002 void test_deadCode_deadOperandLHS_or_debugConst() { | |
| 7003 Source source = addSource(r''' | |
| 7004 const bool DEBUG = true; | |
| 7005 f() { | |
| 7006 bool b = DEBUG || true; | |
| 7007 }'''); | |
| 7008 computeLibrarySourceErrors(source); | |
| 7009 assertNoErrors(source); | |
| 7010 verify([source]); | |
| 7011 } | |
| 7012 | |
| 7013 void test_deprecatedAnnotationUse_classWithConstructor() { | |
| 7014 Source source = addSource(r''' | |
| 7015 @deprecated | |
| 7016 class C { | |
| 7017 C(); | |
| 7018 } | |
| 7019 '''); | |
| 7020 computeLibrarySourceErrors(source); | |
| 7021 assertNoErrors(source); | |
| 7022 verify([source]); | |
| 7023 } | |
| 7024 | |
| 7025 void test_divisionOptimization() { | |
| 7026 Source source = addSource(r''' | |
| 7027 f(int x, int y) { | |
| 7028 var v = x / y.toInt(); | |
| 7029 }'''); | |
| 7030 computeLibrarySourceErrors(source); | |
| 7031 assertNoErrors(source); | |
| 7032 verify([source]); | |
| 7033 } | |
| 7034 | |
| 7035 void test_divisionOptimization_supressIfDivisionNotDefinedInCore() { | |
| 7036 Source source = addSource(r''' | |
| 7037 f(x, y) { | |
| 7038 var v = (x / y).toInt(); | |
| 7039 }'''); | |
| 7040 computeLibrarySourceErrors(source); | |
| 7041 assertNoErrors(source); | |
| 7042 verify([source]); | |
| 7043 } | |
| 7044 | |
| 7045 void test_divisionOptimization_supressIfDivisionOverridden() { | |
| 7046 Source source = addSource(r''' | |
| 7047 class A { | |
| 7048 num operator /(x) { return x; } | |
| 7049 } | |
| 7050 f(A x, A y) { | |
| 7051 var v = (x / y).toInt(); | |
| 7052 }'''); | |
| 7053 computeLibrarySourceErrors(source); | |
| 7054 assertNoErrors(source); | |
| 7055 verify([source]); | |
| 7056 } | |
| 7057 | |
| 7058 void test_duplicateImport_as() { | |
| 7059 Source source = addSource(r''' | |
| 7060 library L; | |
| 7061 import 'lib1.dart'; | |
| 7062 import 'lib1.dart' as one; | |
| 7063 A a; | |
| 7064 one.A a2;'''); | |
| 7065 addNamedSource( | |
| 7066 "/lib1.dart", | |
| 7067 r''' | |
| 7068 library lib1; | |
| 7069 class A {}'''); | |
| 7070 computeLibrarySourceErrors(source); | |
| 7071 assertNoErrors(source); | |
| 7072 verify([source]); | |
| 7073 } | |
| 7074 | |
| 7075 void test_duplicateImport_hide() { | |
| 7076 Source source = addSource(r''' | |
| 7077 library L; | |
| 7078 import 'lib1.dart'; | |
| 7079 import 'lib1.dart' hide A; | |
| 7080 A a; | |
| 7081 B b;'''); | |
| 7082 addNamedSource( | |
| 7083 "/lib1.dart", | |
| 7084 r''' | |
| 7085 library lib1; | |
| 7086 class A {} | |
| 7087 class B {}'''); | |
| 7088 computeLibrarySourceErrors(source); | |
| 7089 assertNoErrors(source); | |
| 7090 verify([source]); | |
| 7091 } | |
| 7092 | |
| 7093 void test_duplicateImport_show() { | |
| 7094 Source source = addSource(r''' | |
| 7095 library L; | |
| 7096 import 'lib1.dart'; | |
| 7097 import 'lib1.dart' show A; | |
| 7098 A a; | |
| 7099 B b;'''); | |
| 7100 addNamedSource( | |
| 7101 "/lib1.dart", | |
| 7102 r''' | |
| 7103 library lib1; | |
| 7104 class A {} | |
| 7105 class B {}'''); | |
| 7106 computeLibrarySourceErrors(source); | |
| 7107 assertNoErrors(source); | |
| 7108 verify([source]); | |
| 7109 } | |
| 7110 | |
| 7111 void test_importDeferredLibraryWithLoadFunction() { | |
| 7112 resolveWithErrors(<String>[ | |
| 7113 r''' | |
| 7114 library lib1; | |
| 7115 f() {}''', | |
| 7116 r''' | |
| 7117 library root; | |
| 7118 import 'lib1.dart' deferred as lib1; | |
| 7119 main() { lib1.f(); }''' | |
| 7120 ], ErrorCode.EMPTY_LIST); | |
| 7121 } | |
| 7122 | |
| 7123 void test_issue20904BuggyTypePromotionAtIfJoin_1() { | |
| 7124 // https://code.google.com/p/dart/issues/detail?id=20904 | |
| 7125 Source source = addSource(r''' | |
| 7126 f(var message, var dynamic_) { | |
| 7127 if (message is Function) { | |
| 7128 message = dynamic_; | |
| 7129 } | |
| 7130 int s = message; | |
| 7131 }'''); | |
| 7132 computeLibrarySourceErrors(source); | |
| 7133 assertNoErrors(source); | |
| 7134 verify([source]); | |
| 7135 } | |
| 7136 | |
| 7137 void test_issue20904BuggyTypePromotionAtIfJoin_3() { | |
| 7138 // https://code.google.com/p/dart/issues/detail?id=20904 | |
| 7139 Source source = addSource(r''' | |
| 7140 f(var message) { | |
| 7141 var dynamic_; | |
| 7142 if (message is Function) { | |
| 7143 message = dynamic_; | |
| 7144 } else { | |
| 7145 return; | |
| 7146 } | |
| 7147 int s = message; | |
| 7148 }'''); | |
| 7149 computeLibrarySourceErrors(source); | |
| 7150 assertNoErrors(source); | |
| 7151 verify([source]); | |
| 7152 } | |
| 7153 | |
| 7154 void test_issue20904BuggyTypePromotionAtIfJoin_4() { | |
| 7155 // https://code.google.com/p/dart/issues/detail?id=20904 | |
| 7156 Source source = addSource(r''' | |
| 7157 f(var message) { | |
| 7158 if (message is Function) { | |
| 7159 message = ''; | |
| 7160 } else { | |
| 7161 return; | |
| 7162 } | |
| 7163 String s = message; | |
| 7164 }'''); | |
| 7165 computeLibrarySourceErrors(source); | |
| 7166 assertNoErrors(source); | |
| 7167 verify([source]); | |
| 7168 } | |
| 7169 | |
| 7170 void test_missingReturn_emptyFunctionBody() { | |
| 7171 Source source = addSource(r''' | |
| 7172 abstract class A { | |
| 7173 int m(); | |
| 7174 }'''); | |
| 7175 computeLibrarySourceErrors(source); | |
| 7176 assertNoErrors(source); | |
| 7177 verify([source]); | |
| 7178 } | |
| 7179 | |
| 7180 void test_missingReturn_expressionFunctionBody() { | |
| 7181 Source source = addSource("int f() => 0;"); | |
| 7182 computeLibrarySourceErrors(source); | |
| 7183 assertNoErrors(source); | |
| 7184 verify([source]); | |
| 7185 } | |
| 7186 | |
| 7187 void test_missingReturn_noReturnType() { | |
| 7188 Source source = addSource("f() {}"); | |
| 7189 computeLibrarySourceErrors(source); | |
| 7190 assertNoErrors(source); | |
| 7191 verify([source]); | |
| 7192 } | |
| 7193 | |
| 7194 void test_missingReturn_voidReturnType() { | |
| 7195 Source source = addSource("void f() {}"); | |
| 7196 computeLibrarySourceErrors(source); | |
| 7197 assertNoErrors(source); | |
| 7198 verify([source]); | |
| 7199 } | |
| 7200 | |
| 7201 void test_nullAwareInCondition_for_noCondition() { | |
| 7202 Source source = addSource(r''' | |
| 7203 m(x) { | |
| 7204 for (var v = x; ; v++) {} | |
| 7205 } | |
| 7206 '''); | |
| 7207 computeLibrarySourceErrors(source); | |
| 7208 assertNoErrors(source); | |
| 7209 verify([source]); | |
| 7210 } | |
| 7211 | |
| 7212 void test_nullAwareInCondition_if_notTopLevel() { | |
| 7213 Source source = addSource(r''' | |
| 7214 m(x) { | |
| 7215 if (x?.y == null) {} | |
| 7216 } | |
| 7217 '''); | |
| 7218 computeLibrarySourceErrors(source); | |
| 7219 assertNoErrors(source); | |
| 7220 verify([source]); | |
| 7221 } | |
| 7222 | |
| 7223 void test_overrideEqualsButNotHashCode() { | |
| 7224 Source source = addSource(r''' | |
| 7225 class A { | |
| 7226 bool operator ==(x) { return x; } | |
| 7227 get hashCode => 0; | |
| 7228 }'''); | |
| 7229 computeLibrarySourceErrors(source); | |
| 7230 assertNoErrors(source); | |
| 7231 verify([source]); | |
| 7232 } | |
| 7233 | |
| 7234 void test_overrideOnNonOverridingGetter_inInterface() { | |
| 7235 Source source = addSource(r''' | |
| 7236 library dart.core; | |
| 7237 const override = null; | |
| 7238 class A { | |
| 7239 int get m => 0; | |
| 7240 } | |
| 7241 class B implements A { | |
| 7242 @override | |
| 7243 int get m => 1; | |
| 7244 }'''); | |
| 7245 computeLibrarySourceErrors(source); | |
| 7246 assertNoErrors(source); | |
| 7247 verify([source]); | |
| 7248 } | |
| 7249 | |
| 7250 void test_overrideOnNonOverridingGetter_inSuperclass() { | |
| 7251 Source source = addSource(r''' | |
| 7252 library dart.core; | |
| 7253 const override = null; | |
| 7254 class A { | |
| 7255 int get m => 0; | |
| 7256 } | |
| 7257 class B extends A { | |
| 7258 @override | |
| 7259 int get m => 1; | |
| 7260 }'''); | |
| 7261 computeLibrarySourceErrors(source); | |
| 7262 assertNoErrors(source); | |
| 7263 verify([source]); | |
| 7264 } | |
| 7265 | |
| 7266 void test_overrideOnNonOverridingMethod_inInterface() { | |
| 7267 Source source = addSource(r''' | |
| 7268 library dart.core; | |
| 7269 const override = null; | |
| 7270 class A { | |
| 7271 int m() => 0; | |
| 7272 } | |
| 7273 class B implements A { | |
| 7274 @override | |
| 7275 int m() => 1; | |
| 7276 }'''); | |
| 7277 computeLibrarySourceErrors(source); | |
| 7278 assertNoErrors(source); | |
| 7279 verify([source]); | |
| 7280 } | |
| 7281 | |
| 7282 void test_overrideOnNonOverridingMethod_inSuperclass() { | |
| 7283 Source source = addSource(r''' | |
| 7284 library dart.core; | |
| 7285 const override = null; | |
| 7286 class A { | |
| 7287 int m() => 0; | |
| 7288 } | |
| 7289 class B extends A { | |
| 7290 @override | |
| 7291 int m() => 1; | |
| 7292 }'''); | |
| 7293 computeLibrarySourceErrors(source); | |
| 7294 assertNoErrors(source); | |
| 7295 verify([source]); | |
| 7296 } | |
| 7297 | |
| 7298 void test_overrideOnNonOverridingSetter_inInterface() { | |
| 7299 Source source = addSource(r''' | |
| 7300 library dart.core; | |
| 7301 const override = null; | |
| 7302 class A { | |
| 7303 set m(int x) {} | |
| 7304 } | |
| 7305 class B implements A { | |
| 7306 @override | |
| 7307 set m(int x) {} | |
| 7308 }'''); | |
| 7309 computeLibrarySourceErrors(source); | |
| 7310 assertNoErrors(source); | |
| 7311 verify([source]); | |
| 7312 } | |
| 7313 | |
| 7314 void test_overrideOnNonOverridingSetter_inSuperclass() { | |
| 7315 Source source = addSource(r''' | |
| 7316 library dart.core; | |
| 7317 const override = null; | |
| 7318 class A { | |
| 7319 set m(int x) {} | |
| 7320 } | |
| 7321 class B extends A { | |
| 7322 @override | |
| 7323 set m(int x) {} | |
| 7324 }'''); | |
| 7325 computeLibrarySourceErrors(source); | |
| 7326 assertNoErrors(source); | |
| 7327 verify([source]); | |
| 7328 } | |
| 7329 | |
| 7330 void test_propagatedFieldType() { | |
| 7331 Source source = addSource(r''' | |
| 7332 class A { } | |
| 7333 class X<T> { | |
| 7334 final x = new List<T>(); | |
| 7335 } | |
| 7336 class Z { | |
| 7337 final X<A> y = new X<A>(); | |
| 7338 foo() { | |
| 7339 y.x.add(new A()); | |
| 7340 } | |
| 7341 }'''); | |
| 7342 computeLibrarySourceErrors(source); | |
| 7343 assertNoErrors(source); | |
| 7344 verify([source]); | |
| 7345 } | |
| 7346 | |
| 7347 void test_proxy_annotation_prefixed() { | |
| 7348 Source source = addSource(r''' | |
| 7349 library L; | |
| 7350 @proxy | |
| 7351 class A {} | |
| 7352 f(var a) { | |
| 7353 a = new A(); | |
| 7354 a.m(); | |
| 7355 var x = a.g; | |
| 7356 a.s = 1; | |
| 7357 var y = a + a; | |
| 7358 a++; | |
| 7359 ++a; | |
| 7360 }'''); | |
| 7361 computeLibrarySourceErrors(source); | |
| 7362 assertNoErrors(source); | |
| 7363 } | |
| 7364 | |
| 7365 void test_proxy_annotation_prefixed2() { | |
| 7366 Source source = addSource(r''' | |
| 7367 library L; | |
| 7368 @proxy | |
| 7369 class A {} | |
| 7370 class B { | |
| 7371 f(var a) { | |
| 7372 a = new A(); | |
| 7373 a.m(); | |
| 7374 var x = a.g; | |
| 7375 a.s = 1; | |
| 7376 var y = a + a; | |
| 7377 a++; | |
| 7378 ++a; | |
| 7379 } | |
| 7380 }'''); | |
| 7381 computeLibrarySourceErrors(source); | |
| 7382 assertNoErrors(source); | |
| 7383 } | |
| 7384 | |
| 7385 void test_proxy_annotation_prefixed3() { | |
| 7386 Source source = addSource(r''' | |
| 7387 library L; | |
| 7388 class B { | |
| 7389 f(var a) { | |
| 7390 a = new A(); | |
| 7391 a.m(); | |
| 7392 var x = a.g; | |
| 7393 a.s = 1; | |
| 7394 var y = a + a; | |
| 7395 a++; | |
| 7396 ++a; | |
| 7397 } | |
| 7398 } | |
| 7399 @proxy | |
| 7400 class A {}'''); | |
| 7401 computeLibrarySourceErrors(source); | |
| 7402 assertNoErrors(source); | |
| 7403 } | |
| 7404 | |
| 7405 void test_undefinedGetter_inSubtype() { | |
| 7406 Source source = addSource(r''' | |
| 7407 class A {} | |
| 7408 class B extends A { | |
| 7409 get b => 0; | |
| 7410 } | |
| 7411 f(var a) { | |
| 7412 if(a is A) { | |
| 7413 return a.b; | |
| 7414 } | |
| 7415 }'''); | |
| 7416 computeLibrarySourceErrors(source); | |
| 7417 assertNoErrors(source); | |
| 7418 } | |
| 7419 | |
| 7420 void test_undefinedMethod_assignmentExpression_inSubtype() { | |
| 7421 Source source = addSource(r''' | |
| 7422 class A {} | |
| 7423 class B extends A { | |
| 7424 operator +(B b) {return new B();} | |
| 7425 } | |
| 7426 f(var a, var a2) { | |
| 7427 a = new A(); | |
| 7428 a2 = new A(); | |
| 7429 a += a2; | |
| 7430 }'''); | |
| 7431 computeLibrarySourceErrors(source); | |
| 7432 assertNoErrors(source); | |
| 7433 } | |
| 7434 | |
| 7435 void test_undefinedMethod_dynamic() { | |
| 7436 Source source = addSource(r''' | |
| 7437 class D<T extends dynamic> { | |
| 7438 fieldAccess(T t) => t.abc; | |
| 7439 methodAccess(T t) => t.xyz(1, 2, 'three'); | |
| 7440 }'''); | |
| 7441 computeLibrarySourceErrors(source); | |
| 7442 assertNoErrors(source); | |
| 7443 } | |
| 7444 | |
| 7445 void test_undefinedMethod_inSubtype() { | |
| 7446 Source source = addSource(r''' | |
| 7447 class A {} | |
| 7448 class B extends A { | |
| 7449 b() {} | |
| 7450 } | |
| 7451 f() { | |
| 7452 var a = new A(); | |
| 7453 a.b(); | |
| 7454 }'''); | |
| 7455 computeLibrarySourceErrors(source); | |
| 7456 assertNoErrors(source); | |
| 7457 } | |
| 7458 | |
| 7459 void test_undefinedMethod_unionType_all() { | |
| 7460 Source source = addSource(r''' | |
| 7461 class A { | |
| 7462 int m(int x) => 0; | |
| 7463 } | |
| 7464 class B { | |
| 7465 String m() => '0'; | |
| 7466 } | |
| 7467 f(A a, B b) { | |
| 7468 var ab; | |
| 7469 if (0 < 1) { | |
| 7470 ab = a; | |
| 7471 } else { | |
| 7472 ab = b; | |
| 7473 } | |
| 7474 ab.m(); | |
| 7475 }'''); | |
| 7476 computeLibrarySourceErrors(source); | |
| 7477 assertNoErrors(source); | |
| 7478 } | |
| 7479 | |
| 7480 void test_undefinedMethod_unionType_some() { | |
| 7481 Source source = addSource(r''' | |
| 7482 class A { | |
| 7483 int m(int x) => 0; | |
| 7484 } | |
| 7485 class B {} | |
| 7486 f(A a, B b) { | |
| 7487 var ab; | |
| 7488 if (0 < 1) { | |
| 7489 ab = a; | |
| 7490 } else { | |
| 7491 ab = b; | |
| 7492 } | |
| 7493 ab.m(0); | |
| 7494 }'''); | |
| 7495 computeLibrarySourceErrors(source); | |
| 7496 assertNoErrors(source); | |
| 7497 } | |
| 7498 | |
| 7499 void test_undefinedOperator_binaryExpression_inSubtype() { | |
| 7500 Source source = addSource(r''' | |
| 7501 class A {} | |
| 7502 class B extends A { | |
| 7503 operator +(B b) {} | |
| 7504 } | |
| 7505 f(var a) { | |
| 7506 if(a is A) { | |
| 7507 a + 1; | |
| 7508 } | |
| 7509 }'''); | |
| 7510 computeLibrarySourceErrors(source); | |
| 7511 assertNoErrors(source); | |
| 7512 } | |
| 7513 | |
| 7514 void test_undefinedOperator_indexBoth_inSubtype() { | |
| 7515 Source source = addSource(r''' | |
| 7516 class A {} | |
| 7517 class B extends A { | |
| 7518 operator [](int index) {} | |
| 7519 } | |
| 7520 f(var a) { | |
| 7521 if(a is A) { | |
| 7522 a[0]++; | |
| 7523 } | |
| 7524 }'''); | |
| 7525 computeLibrarySourceErrors(source); | |
| 7526 assertNoErrors(source); | |
| 7527 } | |
| 7528 | |
| 7529 void test_undefinedOperator_indexGetter_inSubtype() { | |
| 7530 Source source = addSource(r''' | |
| 7531 class A {} | |
| 7532 class B extends A { | |
| 7533 operator [](int index) {} | |
| 7534 } | |
| 7535 f(var a) { | |
| 7536 if(a is A) { | |
| 7537 a[0]; | |
| 7538 } | |
| 7539 }'''); | |
| 7540 computeLibrarySourceErrors(source); | |
| 7541 assertNoErrors(source); | |
| 7542 } | |
| 7543 | |
| 7544 void test_undefinedOperator_indexSetter_inSubtype() { | |
| 7545 Source source = addSource(r''' | |
| 7546 class A {} | |
| 7547 class B extends A { | |
| 7548 operator []=(i, v) {} | |
| 7549 } | |
| 7550 f(var a) { | |
| 7551 if(a is A) { | |
| 7552 a[0] = 1; | |
| 7553 } | |
| 7554 }'''); | |
| 7555 computeLibrarySourceErrors(source); | |
| 7556 assertNoErrors(source); | |
| 7557 } | |
| 7558 | |
| 7559 void test_undefinedOperator_postfixExpression() { | |
| 7560 Source source = addSource(r''' | |
| 7561 class A {} | |
| 7562 class B extends A { | |
| 7563 operator +(B b) {return new B();} | |
| 7564 } | |
| 7565 f(var a) { | |
| 7566 if(a is A) { | |
| 7567 a++; | |
| 7568 } | |
| 7569 }'''); | |
| 7570 computeLibrarySourceErrors(source); | |
| 7571 assertNoErrors(source); | |
| 7572 } | |
| 7573 | |
| 7574 void test_undefinedOperator_prefixExpression() { | |
| 7575 Source source = addSource(r''' | |
| 7576 class A {} | |
| 7577 class B extends A { | |
| 7578 operator +(B b) {return new B();} | |
| 7579 } | |
| 7580 f(var a) { | |
| 7581 if(a is A) { | |
| 7582 ++a; | |
| 7583 } | |
| 7584 }'''); | |
| 7585 computeLibrarySourceErrors(source); | |
| 7586 assertNoErrors(source); | |
| 7587 } | |
| 7588 | |
| 7589 void test_undefinedSetter_inSubtype() { | |
| 7590 Source source = addSource(r''' | |
| 7591 class A {} | |
| 7592 class B extends A { | |
| 7593 set b(x) {} | |
| 7594 } | |
| 7595 f(var a) { | |
| 7596 if(a is A) { | |
| 7597 a.b = 0; | |
| 7598 } | |
| 7599 }'''); | |
| 7600 computeLibrarySourceErrors(source); | |
| 7601 assertNoErrors(source); | |
| 7602 } | |
| 7603 | |
| 7604 void test_unnecessaryCast_13855_parameter_A() { | |
| 7605 // dartbug.com/13855, dartbug.com/13732 | |
| 7606 Source source = addSource(r''' | |
| 7607 class A{ | |
| 7608 a() {} | |
| 7609 } | |
| 7610 class B<E> { | |
| 7611 E e; | |
| 7612 m() { | |
| 7613 (e as A).a(); | |
| 7614 } | |
| 7615 }'''); | |
| 7616 computeLibrarySourceErrors(source); | |
| 7617 assertNoErrors(source); | |
| 7618 verify([source]); | |
| 7619 } | |
| 7620 | |
| 7621 void test_unnecessaryCast_conditionalExpression() { | |
| 7622 Source source = addSource(r''' | |
| 7623 abstract class I {} | |
| 7624 class A implements I {} | |
| 7625 class B implements I {} | |
| 7626 I m(A a, B b) { | |
| 7627 return a == null ? b as I : a as I; | |
| 7628 }'''); | |
| 7629 computeLibrarySourceErrors(source); | |
| 7630 assertNoErrors(source); | |
| 7631 verify([source]); | |
| 7632 } | |
| 7633 | |
| 7634 void test_unnecessaryCast_dynamic_type() { | |
| 7635 Source source = addSource(r''' | |
| 7636 m(v) { | |
| 7637 var b = v as Object; | |
| 7638 }'''); | |
| 7639 computeLibrarySourceErrors(source); | |
| 7640 assertNoErrors(source); | |
| 7641 verify([source]); | |
| 7642 } | |
| 7643 | |
| 7644 void test_unnecessaryCast_generics() { | |
| 7645 // dartbug.com/18953 | |
| 7646 Source source = addSource(r''' | |
| 7647 import 'dart:async'; | |
| 7648 Future<int> f() => new Future.value(0); | |
| 7649 void g(bool c) { | |
| 7650 (c ? f(): new Future.value(0) as Future<int>).then((int value) {}); | |
| 7651 }'''); | |
| 7652 computeLibrarySourceErrors(source); | |
| 7653 assertNoErrors(source); | |
| 7654 verify([source]); | |
| 7655 } | |
| 7656 | |
| 7657 void test_unnecessaryCast_type_dynamic() { | |
| 7658 Source source = addSource(r''' | |
| 7659 m(v) { | |
| 7660 var b = Object as dynamic; | |
| 7661 }'''); | |
| 7662 computeLibrarySourceErrors(source); | |
| 7663 assertNoErrors(source); | |
| 7664 verify([source]); | |
| 7665 } | |
| 7666 | |
| 7667 void test_unnecessaryNoSuchMethod_blockBody_notReturnStatement() { | |
| 7668 Source source = addSource(r''' | |
| 7669 class A { | |
| 7670 noSuchMethod(x) => super.noSuchMethod(x); | |
| 7671 } | |
| 7672 class B extends A { | |
| 7673 mmm(); | |
| 7674 noSuchMethod(y) { | |
| 7675 print(y); | |
| 7676 } | |
| 7677 }'''); | |
| 7678 computeLibrarySourceErrors(source); | |
| 7679 assertNoErrors(source); | |
| 7680 verify([source]); | |
| 7681 } | |
| 7682 | |
| 7683 void test_unnecessaryNoSuchMethod_blockBody_notSingleStatement() { | |
| 7684 Source source = addSource(r''' | |
| 7685 class A { | |
| 7686 noSuchMethod(x) => super.noSuchMethod(x); | |
| 7687 } | |
| 7688 class B extends A { | |
| 7689 mmm(); | |
| 7690 noSuchMethod(y) { | |
| 7691 print(y); | |
| 7692 return super.noSuchMethod(y); | |
| 7693 } | |
| 7694 }'''); | |
| 7695 computeLibrarySourceErrors(source); | |
| 7696 assertNoErrors(source); | |
| 7697 verify([source]); | |
| 7698 } | |
| 7699 | |
| 7700 void test_unnecessaryNoSuchMethod_expressionBody_notNoSuchMethod() { | |
| 7701 Source source = addSource(r''' | |
| 7702 class A { | |
| 7703 noSuchMethod(x) => super.noSuchMethod(x); | |
| 7704 } | |
| 7705 class B extends A { | |
| 7706 mmm(); | |
| 7707 noSuchMethod(y) => super.hashCode; | |
| 7708 }'''); | |
| 7709 computeLibrarySourceErrors(source); | |
| 7710 assertNoErrors(source); | |
| 7711 verify([source]); | |
| 7712 } | |
| 7713 | |
| 7714 void test_unnecessaryNoSuchMethod_expressionBody_notSuper() { | |
| 7715 Source source = addSource(r''' | |
| 7716 class A { | |
| 7717 noSuchMethod(x) => super.noSuchMethod(x); | |
| 7718 } | |
| 7719 class B extends A { | |
| 7720 mmm(); | |
| 7721 noSuchMethod(y) => 42; | |
| 7722 }'''); | |
| 7723 computeLibrarySourceErrors(source); | |
| 7724 assertNoErrors(source); | |
| 7725 verify([source]); | |
| 7726 } | |
| 7727 | |
| 7728 void test_unusedImport_annotationOnDirective() { | |
| 7729 Source source = addSource(r''' | |
| 7730 library L; | |
| 7731 @A() | |
| 7732 import 'lib1.dart';'''); | |
| 7733 Source source2 = addNamedSource( | |
| 7734 "/lib1.dart", | |
| 7735 r''' | |
| 7736 library lib1; | |
| 7737 class A { | |
| 7738 const A() {} | |
| 7739 }'''); | |
| 7740 computeLibrarySourceErrors(source); | |
| 7741 assertErrors(source); | |
| 7742 verify([source, source2]); | |
| 7743 } | |
| 7744 | |
| 7745 void test_unusedImport_as_equalPrefixes() { | |
| 7746 // 18818 | |
| 7747 Source source = addSource(r''' | |
| 7748 library L; | |
| 7749 import 'lib1.dart' as one; | |
| 7750 import 'lib2.dart' as one; | |
| 7751 one.A a; | |
| 7752 one.B b;'''); | |
| 7753 Source source2 = addNamedSource( | |
| 7754 "/lib1.dart", | |
| 7755 r''' | |
| 7756 library lib1; | |
| 7757 class A {}'''); | |
| 7758 Source source3 = addNamedSource( | |
| 7759 "/lib2.dart", | |
| 7760 r''' | |
| 7761 library lib2; | |
| 7762 class B {}'''); | |
| 7763 computeLibrarySourceErrors(source); | |
| 7764 assertErrors(source); | |
| 7765 assertNoErrors(source2); | |
| 7766 assertNoErrors(source3); | |
| 7767 verify([source, source2, source3]); | |
| 7768 } | |
| 7769 | |
| 7770 void test_unusedImport_core_library() { | |
| 7771 Source source = addSource(r''' | |
| 7772 library L; | |
| 7773 import 'dart:core';'''); | |
| 7774 computeLibrarySourceErrors(source); | |
| 7775 assertNoErrors(source); | |
| 7776 verify([source]); | |
| 7777 } | |
| 7778 | |
| 7779 void test_unusedImport_export() { | |
| 7780 Source source = addSource(r''' | |
| 7781 library L; | |
| 7782 import 'lib1.dart'; | |
| 7783 Two two;'''); | |
| 7784 addNamedSource( | |
| 7785 "/lib1.dart", | |
| 7786 r''' | |
| 7787 library lib1; | |
| 7788 export 'lib2.dart'; | |
| 7789 class One {}'''); | |
| 7790 addNamedSource( | |
| 7791 "/lib2.dart", | |
| 7792 r''' | |
| 7793 library lib2; | |
| 7794 class Two {}'''); | |
| 7795 computeLibrarySourceErrors(source); | |
| 7796 assertNoErrors(source); | |
| 7797 verify([source]); | |
| 7798 } | |
| 7799 | |
| 7800 void test_unusedImport_export2() { | |
| 7801 Source source = addSource(r''' | |
| 7802 library L; | |
| 7803 import 'lib1.dart'; | |
| 7804 Three three;'''); | |
| 7805 addNamedSource( | |
| 7806 "/lib1.dart", | |
| 7807 r''' | |
| 7808 library lib1; | |
| 7809 export 'lib2.dart'; | |
| 7810 class One {}'''); | |
| 7811 addNamedSource( | |
| 7812 "/lib2.dart", | |
| 7813 r''' | |
| 7814 library lib2; | |
| 7815 export 'lib3.dart'; | |
| 7816 class Two {}'''); | |
| 7817 addNamedSource( | |
| 7818 "/lib3.dart", | |
| 7819 r''' | |
| 7820 library lib3; | |
| 7821 class Three {}'''); | |
| 7822 computeLibrarySourceErrors(source); | |
| 7823 assertNoErrors(source); | |
| 7824 verify([source]); | |
| 7825 } | |
| 7826 | |
| 7827 void test_unusedImport_export_infiniteLoop() { | |
| 7828 Source source = addSource(r''' | |
| 7829 library L; | |
| 7830 import 'lib1.dart'; | |
| 7831 Two two;'''); | |
| 7832 addNamedSource( | |
| 7833 "/lib1.dart", | |
| 7834 r''' | |
| 7835 library lib1; | |
| 7836 export 'lib2.dart'; | |
| 7837 class One {}'''); | |
| 7838 addNamedSource( | |
| 7839 "/lib2.dart", | |
| 7840 r''' | |
| 7841 library lib2; | |
| 7842 export 'lib3.dart'; | |
| 7843 class Two {}'''); | |
| 7844 addNamedSource( | |
| 7845 "/lib3.dart", | |
| 7846 r''' | |
| 7847 library lib3; | |
| 7848 export 'lib2.dart'; | |
| 7849 class Three {}'''); | |
| 7850 computeLibrarySourceErrors(source); | |
| 7851 assertNoErrors(source); | |
| 7852 verify([source]); | |
| 7853 } | |
| 7854 | |
| 7855 void test_unusedImport_metadata() { | |
| 7856 Source source = addSource(r''' | |
| 7857 library L; | |
| 7858 @A(x) | |
| 7859 import 'lib1.dart'; | |
| 7860 class A { | |
| 7861 final int value; | |
| 7862 const A(this.value); | |
| 7863 }'''); | |
| 7864 addNamedSource( | |
| 7865 "/lib1.dart", | |
| 7866 r''' | |
| 7867 library lib1; | |
| 7868 const x = 0;'''); | |
| 7869 computeLibrarySourceErrors(source); | |
| 7870 assertNoErrors(source); | |
| 7871 verify([source]); | |
| 7872 } | |
| 7873 | |
| 7874 void test_unusedImport_prefix_topLevelFunction() { | |
| 7875 Source source = addSource(r''' | |
| 7876 library L; | |
| 7877 import 'lib1.dart' hide topLevelFunction; | |
| 7878 import 'lib1.dart' as one show topLevelFunction; | |
| 7879 class A { | |
| 7880 static void x() { | |
| 7881 One o; | |
| 7882 one.topLevelFunction(); | |
| 7883 } | |
| 7884 }'''); | |
| 7885 addNamedSource( | |
| 7886 "/lib1.dart", | |
| 7887 r''' | |
| 7888 library lib1; | |
| 7889 class One {} | |
| 7890 topLevelFunction() {}'''); | |
| 7891 computeLibrarySourceErrors(source); | |
| 7892 assertNoErrors(source); | |
| 7893 verify([source]); | |
| 7894 } | |
| 7895 | |
| 7896 void test_useOfVoidResult_implicitReturnValue() { | |
| 7897 Source source = addSource(r''' | |
| 7898 f() {} | |
| 7899 class A { | |
| 7900 n() { | |
| 7901 var a = f(); | |
| 7902 } | |
| 7903 }'''); | |
| 7904 computeLibrarySourceErrors(source); | |
| 7905 assertNoErrors(source); | |
| 7906 verify([source]); | |
| 7907 } | |
| 7908 | |
| 7909 void test_useOfVoidResult_nonVoidReturnValue() { | |
| 7910 Source source = addSource(r''' | |
| 7911 int f() => 1; | |
| 7912 g() { | |
| 7913 var a = f(); | |
| 7914 }'''); | |
| 7915 computeLibrarySourceErrors(source); | |
| 7916 assertNoErrors(source); | |
| 7917 verify([source]); | |
| 7918 } | |
| 7919 } | |
| 7920 | |
| 7921 class PubSuggestionCodeTest extends ResolverTestCase { | |
| 7922 void test_import_package() { | |
| 7923 Source source = addSource("import 'package:somepackage/other.dart';"); | |
| 7924 computeLibrarySourceErrors(source); | |
| 7925 assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]); | |
| 7926 } | |
| 7927 | |
| 7928 void test_import_packageWithDotDot() { | |
| 7929 Source source = addSource("import 'package:somepackage/../other.dart';"); | |
| 7930 computeLibrarySourceErrors(source); | |
| 7931 assertErrors(source, [ | |
| 7932 CompileTimeErrorCode.URI_DOES_NOT_EXIST, | |
| 7933 HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT | |
| 7934 ]); | |
| 7935 } | |
| 7936 | |
| 7937 void test_import_packageWithLeadingDotDot() { | |
| 7938 Source source = addSource("import 'package:../other.dart';"); | |
| 7939 computeLibrarySourceErrors(source); | |
| 7940 assertErrors(source, [ | |
| 7941 CompileTimeErrorCode.URI_DOES_NOT_EXIST, | |
| 7942 HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT | |
| 7943 ]); | |
| 7944 } | |
| 7945 | |
| 7946 void test_import_referenceIntoLibDirectory() { | |
| 7947 cacheSource("/myproj/pubspec.yaml", ""); | |
| 7948 cacheSource("/myproj/lib/other.dart", ""); | |
| 7949 Source source = | |
| 7950 addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';"); | |
| 7951 computeLibrarySourceErrors(source); | |
| 7952 assertErrors( | |
| 7953 source, [HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE]); | |
| 7954 } | |
| 7955 | |
| 7956 void test_import_referenceIntoLibDirectory_no_pubspec() { | |
| 7957 cacheSource("/myproj/lib/other.dart", ""); | |
| 7958 Source source = | |
| 7959 addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';"); | |
| 7960 computeLibrarySourceErrors(source); | |
| 7961 assertNoErrors(source); | |
| 7962 } | |
| 7963 | |
| 7964 void test_import_referenceOutOfLibDirectory() { | |
| 7965 cacheSource("/myproj/pubspec.yaml", ""); | |
| 7966 cacheSource("/myproj/web/other.dart", ""); | |
| 7967 Source source = | |
| 7968 addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';"); | |
| 7969 computeLibrarySourceErrors(source); | |
| 7970 assertErrors( | |
| 7971 source, [HintCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE]); | |
| 7972 } | |
| 7973 | |
| 7974 void test_import_referenceOutOfLibDirectory_no_pubspec() { | |
| 7975 cacheSource("/myproj/web/other.dart", ""); | |
| 7976 Source source = | |
| 7977 addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';"); | |
| 7978 computeLibrarySourceErrors(source); | |
| 7979 assertNoErrors(source); | |
| 7980 } | |
| 7981 | |
| 7982 void test_import_valid_inside_lib1() { | |
| 7983 cacheSource("/myproj/pubspec.yaml", ""); | |
| 7984 cacheSource("/myproj/lib/other.dart", ""); | |
| 7985 Source source = | |
| 7986 addNamedSource("/myproj/lib/test.dart", "import 'other.dart';"); | |
| 7987 computeLibrarySourceErrors(source); | |
| 7988 assertNoErrors(source); | |
| 7989 } | |
| 7990 | |
| 7991 void test_import_valid_inside_lib2() { | |
| 7992 cacheSource("/myproj/pubspec.yaml", ""); | |
| 7993 cacheSource("/myproj/lib/bar/other.dart", ""); | |
| 7994 Source source = addNamedSource( | |
| 7995 "/myproj/lib/foo/test.dart", "import '../bar/other.dart';"); | |
| 7996 computeLibrarySourceErrors(source); | |
| 7997 assertNoErrors(source); | |
| 7998 } | |
| 7999 | |
| 8000 void test_import_valid_outside_lib() { | |
| 8001 cacheSource("/myproj/pubspec.yaml", ""); | |
| 8002 cacheSource("/myproj/web/other.dart", ""); | |
| 8003 Source source = | |
| 8004 addNamedSource("/myproj/lib2/test.dart", "import '../web/other.dart';"); | |
| 8005 computeLibrarySourceErrors(source); | |
| 8006 assertNoErrors(source); | |
| 8007 } | |
| 8008 } | |
| 8009 | |
| 8010 /** | |
| 8011 * An AST visitor used to verify that all of the nodes in an AST structure that | |
| 8012 * should have been resolved were resolved. | |
| 8013 */ | |
| 8014 class ResolutionVerifier extends RecursiveAstVisitor<Object> { | |
| 8015 /** | |
| 8016 * A set containing nodes that are known to not be resolvable and should | |
| 8017 * therefore not cause the test to fail. | |
| 8018 */ | |
| 8019 final Set<AstNode> _knownExceptions; | |
| 8020 | |
| 8021 /** | |
| 8022 * A list containing all of the AST nodes that were not resolved. | |
| 8023 */ | |
| 8024 List<AstNode> _unresolvedNodes = new List<AstNode>(); | |
| 8025 | |
| 8026 /** | |
| 8027 * A list containing all of the AST nodes that were resolved to an element of | |
| 8028 * the wrong type. | |
| 8029 */ | |
| 8030 List<AstNode> _wrongTypedNodes = new List<AstNode>(); | |
| 8031 | |
| 8032 /** | |
| 8033 * Initialize a newly created verifier to verify that all of the identifiers | |
| 8034 * in the visited AST structures that are expected to have been resolved have | |
| 8035 * an element associated with them. Nodes in the set of [_knownExceptions] are | |
| 8036 * not expected to have been resolved, even if they normally would have been | |
| 8037 * expected to have been resolved. | |
| 8038 */ | |
| 8039 ResolutionVerifier([this._knownExceptions]); | |
| 8040 | |
| 8041 /** | |
| 8042 * Assert that all of the visited identifiers were resolved. | |
| 8043 */ | |
| 8044 void assertResolved() { | |
| 8045 if (!_unresolvedNodes.isEmpty || !_wrongTypedNodes.isEmpty) { | |
| 8046 StringBuffer buffer = new StringBuffer(); | |
| 8047 if (!_unresolvedNodes.isEmpty) { | |
| 8048 buffer.write("Failed to resolve "); | |
| 8049 buffer.write(_unresolvedNodes.length); | |
| 8050 buffer.writeln(" nodes:"); | |
| 8051 _printNodes(buffer, _unresolvedNodes); | |
| 8052 } | |
| 8053 if (!_wrongTypedNodes.isEmpty) { | |
| 8054 buffer.write("Resolved "); | |
| 8055 buffer.write(_wrongTypedNodes.length); | |
| 8056 buffer.writeln(" to the wrong type of element:"); | |
| 8057 _printNodes(buffer, _wrongTypedNodes); | |
| 8058 } | |
| 8059 fail(buffer.toString()); | |
| 8060 } | |
| 8061 } | |
| 8062 | |
| 8063 @override | |
| 8064 Object visitAnnotation(Annotation node) { | |
| 8065 node.visitChildren(this); | |
| 8066 ElementAnnotation elementAnnotation = node.elementAnnotation; | |
| 8067 if (elementAnnotation == null) { | |
| 8068 if (_knownExceptions == null || !_knownExceptions.contains(node)) { | |
| 8069 _unresolvedNodes.add(node); | |
| 8070 } | |
| 8071 } else if (elementAnnotation is! ElementAnnotation) { | |
| 8072 _wrongTypedNodes.add(node); | |
| 8073 } | |
| 8074 return null; | |
| 8075 } | |
| 8076 | |
| 8077 @override | |
| 8078 Object visitBinaryExpression(BinaryExpression node) { | |
| 8079 node.visitChildren(this); | |
| 8080 if (!node.operator.isUserDefinableOperator) { | |
| 8081 return null; | |
| 8082 } | |
| 8083 DartType operandType = node.leftOperand.staticType; | |
| 8084 if (operandType == null || operandType.isDynamic) { | |
| 8085 return null; | |
| 8086 } | |
| 8087 return _checkResolved( | |
| 8088 node, node.staticElement, (node) => node is MethodElement); | |
| 8089 } | |
| 8090 | |
| 8091 @override | |
| 8092 Object visitCommentReference(CommentReference node) => null; | |
| 8093 | |
| 8094 @override | |
| 8095 Object visitCompilationUnit(CompilationUnit node) { | |
| 8096 node.visitChildren(this); | |
| 8097 return _checkResolved( | |
| 8098 node, node.element, (node) => node is CompilationUnitElement); | |
| 8099 } | |
| 8100 | |
| 8101 @override | |
| 8102 Object visitExportDirective(ExportDirective node) => | |
| 8103 _checkResolved(node, node.element, (node) => node is ExportElement); | |
| 8104 | |
| 8105 @override | |
| 8106 Object visitFunctionDeclaration(FunctionDeclaration node) { | |
| 8107 node.visitChildren(this); | |
| 8108 if (node.element is LibraryElement) { | |
| 8109 _wrongTypedNodes.add(node); | |
| 8110 } | |
| 8111 return null; | |
| 8112 } | |
| 8113 | |
| 8114 @override | |
| 8115 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { | |
| 8116 node.visitChildren(this); | |
| 8117 // TODO(brianwilkerson) If we start resolving function expressions, then | |
| 8118 // conditionally check to see whether the node was resolved correctly. | |
| 8119 return null; | |
| 8120 //checkResolved(node, node.getElement(), FunctionElement.class); | |
| 8121 } | |
| 8122 | |
| 8123 @override | |
| 8124 Object visitImportDirective(ImportDirective node) { | |
| 8125 // Not sure how to test the combinators given that it isn't an error if the | |
| 8126 // names are not defined. | |
| 8127 _checkResolved(node, node.element, (node) => node is ImportElement); | |
| 8128 SimpleIdentifier prefix = node.prefix; | |
| 8129 if (prefix == null) { | |
| 8130 return null; | |
| 8131 } | |
| 8132 return _checkResolved( | |
| 8133 prefix, prefix.staticElement, (node) => node is PrefixElement); | |
| 8134 } | |
| 8135 | |
| 8136 @override | |
| 8137 Object visitIndexExpression(IndexExpression node) { | |
| 8138 node.visitChildren(this); | |
| 8139 DartType targetType = node.realTarget.staticType; | |
| 8140 if (targetType == null || targetType.isDynamic) { | |
| 8141 return null; | |
| 8142 } | |
| 8143 return _checkResolved( | |
| 8144 node, node.staticElement, (node) => node is MethodElement); | |
| 8145 } | |
| 8146 | |
| 8147 @override | |
| 8148 Object visitLibraryDirective(LibraryDirective node) => | |
| 8149 _checkResolved(node, node.element, (node) => node is LibraryElement); | |
| 8150 | |
| 8151 @override | |
| 8152 Object visitNamedExpression(NamedExpression node) => | |
| 8153 node.expression.accept(this); | |
| 8154 | |
| 8155 @override | |
| 8156 Object visitPartDirective(PartDirective node) => _checkResolved( | |
| 8157 node, node.element, (node) => node is CompilationUnitElement); | |
| 8158 | |
| 8159 @override | |
| 8160 Object visitPartOfDirective(PartOfDirective node) => | |
| 8161 _checkResolved(node, node.element, (node) => node is LibraryElement); | |
| 8162 | |
| 8163 @override | |
| 8164 Object visitPostfixExpression(PostfixExpression node) { | |
| 8165 node.visitChildren(this); | |
| 8166 if (!node.operator.isUserDefinableOperator) { | |
| 8167 return null; | |
| 8168 } | |
| 8169 DartType operandType = node.operand.staticType; | |
| 8170 if (operandType == null || operandType.isDynamic) { | |
| 8171 return null; | |
| 8172 } | |
| 8173 return _checkResolved( | |
| 8174 node, node.staticElement, (node) => node is MethodElement); | |
| 8175 } | |
| 8176 | |
| 8177 @override | |
| 8178 Object visitPrefixedIdentifier(PrefixedIdentifier node) { | |
| 8179 SimpleIdentifier prefix = node.prefix; | |
| 8180 prefix.accept(this); | |
| 8181 DartType prefixType = prefix.staticType; | |
| 8182 if (prefixType == null || prefixType.isDynamic) { | |
| 8183 return null; | |
| 8184 } | |
| 8185 return _checkResolved(node, node.staticElement, null); | |
| 8186 } | |
| 8187 | |
| 8188 @override | |
| 8189 Object visitPrefixExpression(PrefixExpression node) { | |
| 8190 node.visitChildren(this); | |
| 8191 if (!node.operator.isUserDefinableOperator) { | |
| 8192 return null; | |
| 8193 } | |
| 8194 DartType operandType = node.operand.staticType; | |
| 8195 if (operandType == null || operandType.isDynamic) { | |
| 8196 return null; | |
| 8197 } | |
| 8198 return _checkResolved( | |
| 8199 node, node.staticElement, (node) => node is MethodElement); | |
| 8200 } | |
| 8201 | |
| 8202 @override | |
| 8203 Object visitPropertyAccess(PropertyAccess node) { | |
| 8204 Expression target = node.realTarget; | |
| 8205 target.accept(this); | |
| 8206 DartType targetType = target.staticType; | |
| 8207 if (targetType == null || targetType.isDynamic) { | |
| 8208 return null; | |
| 8209 } | |
| 8210 return node.propertyName.accept(this); | |
| 8211 } | |
| 8212 | |
| 8213 @override | |
| 8214 Object visitSimpleIdentifier(SimpleIdentifier node) { | |
| 8215 if (node.name == "void") { | |
| 8216 return null; | |
| 8217 } | |
| 8218 if (node.staticType != null && | |
| 8219 node.staticType.isDynamic && | |
| 8220 node.staticElement == null) { | |
| 8221 return null; | |
| 8222 } | |
| 8223 AstNode parent = node.parent; | |
| 8224 if (parent is MethodInvocation) { | |
| 8225 MethodInvocation invocation = parent; | |
| 8226 if (identical(invocation.methodName, node)) { | |
| 8227 Expression target = invocation.realTarget; | |
| 8228 DartType targetType = target == null ? null : target.staticType; | |
| 8229 if (targetType == null || targetType.isDynamic) { | |
| 8230 return null; | |
| 8231 } | |
| 8232 } | |
| 8233 } | |
| 8234 return _checkResolved(node, node.staticElement, null); | |
| 8235 } | |
| 8236 | |
| 8237 Object _checkResolved( | |
| 8238 AstNode node, Element element, Predicate<Element> predicate) { | |
| 8239 if (element == null) { | |
| 8240 if (_knownExceptions == null || !_knownExceptions.contains(node)) { | |
| 8241 _unresolvedNodes.add(node); | |
| 8242 } | |
| 8243 } else if (predicate != null) { | |
| 8244 if (!predicate(element)) { | |
| 8245 _wrongTypedNodes.add(node); | |
| 8246 } | |
| 8247 } | |
| 8248 return null; | |
| 8249 } | |
| 8250 | |
| 8251 String _getFileName(AstNode node) { | |
| 8252 // TODO (jwren) there are two copies of this method, one here and one in | |
| 8253 // StaticTypeVerifier, they should be resolved into a single method | |
| 8254 if (node != null) { | |
| 8255 AstNode root = node.root; | |
| 8256 if (root is CompilationUnit) { | |
| 8257 CompilationUnit rootCU = root; | |
| 8258 if (rootCU.element != null) { | |
| 8259 return rootCU.element.source.fullName; | |
| 8260 } else { | |
| 8261 return "<unknown file- CompilationUnit.getElement() returned null>"; | |
| 8262 } | |
| 8263 } else { | |
| 8264 return "<unknown file- CompilationUnit.getRoot() is not a CompilationUni
t>"; | |
| 8265 } | |
| 8266 } | |
| 8267 return "<unknown file- ASTNode is null>"; | |
| 8268 } | |
| 8269 | |
| 8270 void _printNodes(StringBuffer buffer, List<AstNode> nodes) { | |
| 8271 for (AstNode identifier in nodes) { | |
| 8272 buffer.write(" "); | |
| 8273 buffer.write(identifier.toString()); | |
| 8274 buffer.write(" ("); | |
| 8275 buffer.write(_getFileName(identifier)); | |
| 8276 buffer.write(" : "); | |
| 8277 buffer.write(identifier.offset); | |
| 8278 buffer.writeln(")"); | |
| 8279 } | |
| 8280 } | |
| 8281 } | |
| 8282 | |
| 8283 class ResolverTestCase extends EngineTestCase { | |
| 8284 /** | |
| 8285 * The analysis context used to parse the compilation units being resolved. | |
| 8286 */ | |
| 8287 InternalAnalysisContext analysisContext2; | |
| 8288 | |
| 8289 /** | |
| 8290 * Specifies if [assertErrors] should check for [HintCode.UNUSED_ELEMENT] and | |
| 8291 * [HintCode.UNUSED_FIELD]. | |
| 8292 */ | |
| 8293 bool enableUnusedElement = false; | |
| 8294 | |
| 8295 /** | |
| 8296 * Specifies if [assertErrors] should check for [HintCode.UNUSED_LOCAL_VARIABL
E]. | |
| 8297 */ | |
| 8298 bool enableUnusedLocalVariable = false; | |
| 8299 | |
| 8300 AnalysisContext get analysisContext => analysisContext2; | |
| 8301 | |
| 8302 /** | |
| 8303 * Return a type provider that can be used to test the results of resolution. | |
| 8304 * | |
| 8305 * @return a type provider | |
| 8306 * @throws AnalysisException if dart:core cannot be resolved | |
| 8307 */ | |
| 8308 TypeProvider get typeProvider => analysisContext2.typeProvider; | |
| 8309 | |
| 8310 /** | |
| 8311 * Return a type system that can be used to test the results of resolution. | |
| 8312 * | |
| 8313 * @return a type system | |
| 8314 */ | |
| 8315 TypeSystem get typeSystem => analysisContext2.typeSystem; | |
| 8316 | |
| 8317 /** | |
| 8318 * Add a source file to the content provider. The file path should be absolute
. | |
| 8319 * | |
| 8320 * @param filePath the path of the file being added | |
| 8321 * @param contents the contents to be returned by the content provider for the
specified file | |
| 8322 * @return the source object representing the added file | |
| 8323 */ | |
| 8324 Source addNamedSource(String filePath, String contents) { | |
| 8325 Source source = cacheSource(filePath, contents); | |
| 8326 ChangeSet changeSet = new ChangeSet(); | |
| 8327 changeSet.addedSource(source); | |
| 8328 analysisContext2.applyChanges(changeSet); | |
| 8329 return source; | |
| 8330 } | |
| 8331 | |
| 8332 /** | |
| 8333 * Add a source file to the content provider. | |
| 8334 * | |
| 8335 * @param contents the contents to be returned by the content provider for the
specified file | |
| 8336 * @return the source object representing the added file | |
| 8337 */ | |
| 8338 Source addSource(String contents) => addNamedSource("/test.dart", contents); | |
| 8339 | |
| 8340 /** | |
| 8341 * Assert that the number of errors reported against the given source matches
the number of errors | |
| 8342 * that are given and that they have the expected error codes. The order in wh
ich the errors were | |
| 8343 * gathered is ignored. | |
| 8344 * | |
| 8345 * @param source the source against which the errors should have been reported | |
| 8346 * @param expectedErrorCodes the error codes of the errors that should have be
en reported | |
| 8347 * @throws AnalysisException if the reported errors could not be computed | |
| 8348 * @throws AssertionFailedError if a different number of errors have been repo
rted than were | |
| 8349 * expected | |
| 8350 */ | |
| 8351 void assertErrors(Source source, | |
| 8352 [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) { | |
| 8353 GatheringErrorListener errorListener = new GatheringErrorListener(); | |
| 8354 for (AnalysisError error in analysisContext2.computeErrors(source)) { | |
| 8355 expect(error.source, source); | |
| 8356 ErrorCode errorCode = error.errorCode; | |
| 8357 if (!enableUnusedElement && | |
| 8358 (errorCode == HintCode.UNUSED_ELEMENT || | |
| 8359 errorCode == HintCode.UNUSED_FIELD)) { | |
| 8360 continue; | |
| 8361 } | |
| 8362 if (!enableUnusedLocalVariable && | |
| 8363 (errorCode == HintCode.UNUSED_CATCH_CLAUSE || | |
| 8364 errorCode == HintCode.UNUSED_CATCH_STACK || | |
| 8365 errorCode == HintCode.UNUSED_LOCAL_VARIABLE)) { | |
| 8366 continue; | |
| 8367 } | |
| 8368 errorListener.onError(error); | |
| 8369 } | |
| 8370 errorListener.assertErrorsWithCodes(expectedErrorCodes); | |
| 8371 } | |
| 8372 | |
| 8373 /** | |
| 8374 * Asserts that [code] verifies, but has errors with the given error codes. | |
| 8375 * | |
| 8376 * Like [assertErrors], but takes a string of source code. | |
| 8377 */ | |
| 8378 // TODO(rnystrom): Use this in more tests that have the same structure. | |
| 8379 void assertErrorsInCode(String code, List<ErrorCode> errors) { | |
| 8380 Source source = addSource(code); | |
| 8381 computeLibrarySourceErrors(source); | |
| 8382 assertErrors(source, errors); | |
| 8383 verify([source]); | |
| 8384 } | |
| 8385 | |
| 8386 /** | |
| 8387 * Asserts that [code] has errors with the given error codes. | |
| 8388 * | |
| 8389 * Like [assertErrors], but takes a string of source code. | |
| 8390 */ | |
| 8391 void assertErrorsInUnverifiedCode(String code, List<ErrorCode> errors) { | |
| 8392 Source source = addSource(code); | |
| 8393 computeLibrarySourceErrors(source); | |
| 8394 assertErrors(source, errors); | |
| 8395 } | |
| 8396 | |
| 8397 /** | |
| 8398 * Assert that no errors have been reported against the given source. | |
| 8399 * | |
| 8400 * @param source the source against which no errors should have been reported | |
| 8401 * @throws AnalysisException if the reported errors could not be computed | |
| 8402 * @throws AssertionFailedError if any errors have been reported | |
| 8403 */ | |
| 8404 void assertNoErrors(Source source) { | |
| 8405 assertErrors(source); | |
| 8406 } | |
| 8407 | |
| 8408 /** | |
| 8409 * Asserts that [code] has no errors or warnings. | |
| 8410 */ | |
| 8411 // TODO(rnystrom): Use this in more tests that have the same structure. | |
| 8412 void assertNoErrorsInCode(String code) { | |
| 8413 Source source = addSource(code); | |
| 8414 computeLibrarySourceErrors(source); | |
| 8415 assertNoErrors(source); | |
| 8416 verify([source]); | |
| 8417 } | |
| 8418 | |
| 8419 /** | |
| 8420 * Cache the source file content in the source factory but don't add the sourc
e to the analysis | |
| 8421 * context. The file path should be absolute. | |
| 8422 * | |
| 8423 * @param filePath the path of the file being cached | |
| 8424 * @param contents the contents to be returned by the content provider for the
specified file | |
| 8425 * @return the source object representing the cached file | |
| 8426 */ | |
| 8427 Source cacheSource(String filePath, String contents) { | |
| 8428 Source source = new FileBasedSource(FileUtilities2.createFile(filePath)); | |
| 8429 analysisContext2.setContents(source, contents); | |
| 8430 return source; | |
| 8431 } | |
| 8432 | |
| 8433 /** | |
| 8434 * Change the contents of the given [source] to the given [contents]. | |
| 8435 */ | |
| 8436 void changeSource(Source source, String contents) { | |
| 8437 analysisContext2.setContents(source, contents); | |
| 8438 ChangeSet changeSet = new ChangeSet(); | |
| 8439 changeSet.changedSource(source); | |
| 8440 analysisContext2.applyChanges(changeSet); | |
| 8441 } | |
| 8442 | |
| 8443 /** | |
| 8444 * Computes errors for the given [librarySource]. | |
| 8445 * This assumes that the given [librarySource] and its parts have already | |
| 8446 * been added to the content provider using the method [addNamedSource]. | |
| 8447 */ | |
| 8448 void computeLibrarySourceErrors(Source librarySource) { | |
| 8449 analysisContext.computeErrors(librarySource); | |
| 8450 } | |
| 8451 | |
| 8452 /** | |
| 8453 * Create a library element that represents a library named `"test"` containin
g a single | |
| 8454 * empty compilation unit. | |
| 8455 * | |
| 8456 * @return the library element that was created | |
| 8457 */ | |
| 8458 LibraryElementImpl createDefaultTestLibrary() => | |
| 8459 createTestLibrary(AnalysisContextFactory.contextWithCore(), "test"); | |
| 8460 | |
| 8461 /** | |
| 8462 * Create a library element that represents a library with the given name cont
aining a single | |
| 8463 * empty compilation unit. | |
| 8464 * | |
| 8465 * @param libraryName the name of the library to be created | |
| 8466 * @return the library element that was created | |
| 8467 */ | |
| 8468 LibraryElementImpl createTestLibrary( | |
| 8469 AnalysisContext context, String libraryName, | |
| 8470 [List<String> typeNames]) { | |
| 8471 String fileName = "$libraryName.dart"; | |
| 8472 FileBasedSource definingCompilationUnitSource = | |
| 8473 _createNamedSource(fileName); | |
| 8474 List<CompilationUnitElement> sourcedCompilationUnits; | |
| 8475 if (typeNames == null) { | |
| 8476 sourcedCompilationUnits = CompilationUnitElement.EMPTY_LIST; | |
| 8477 } else { | |
| 8478 int count = typeNames.length; | |
| 8479 sourcedCompilationUnits = new List<CompilationUnitElement>(count); | |
| 8480 for (int i = 0; i < count; i++) { | |
| 8481 String typeName = typeNames[i]; | |
| 8482 ClassElementImpl type = | |
| 8483 new ClassElementImpl.forNode(AstFactory.identifier3(typeName)); | |
| 8484 String fileName = "$typeName.dart"; | |
| 8485 CompilationUnitElementImpl compilationUnit = | |
| 8486 new CompilationUnitElementImpl(fileName); | |
| 8487 compilationUnit.source = _createNamedSource(fileName); | |
| 8488 compilationUnit.librarySource = definingCompilationUnitSource; | |
| 8489 compilationUnit.types = <ClassElement>[type]; | |
| 8490 sourcedCompilationUnits[i] = compilationUnit; | |
| 8491 } | |
| 8492 } | |
| 8493 CompilationUnitElementImpl compilationUnit = | |
| 8494 new CompilationUnitElementImpl(fileName); | |
| 8495 compilationUnit.librarySource = | |
| 8496 compilationUnit.source = definingCompilationUnitSource; | |
| 8497 LibraryElementImpl library = new LibraryElementImpl.forNode( | |
| 8498 context, AstFactory.libraryIdentifier2([libraryName])); | |
| 8499 library.definingCompilationUnit = compilationUnit; | |
| 8500 library.parts = sourcedCompilationUnits; | |
| 8501 return library; | |
| 8502 } | |
| 8503 | |
| 8504 Expression findTopLevelConstantExpression( | |
| 8505 CompilationUnit compilationUnit, String name) => | |
| 8506 findTopLevelDeclaration(compilationUnit, name).initializer; | |
| 8507 | |
| 8508 VariableDeclaration findTopLevelDeclaration( | |
| 8509 CompilationUnit compilationUnit, String name) { | |
| 8510 for (CompilationUnitMember member in compilationUnit.declarations) { | |
| 8511 if (member is TopLevelVariableDeclaration) { | |
| 8512 for (VariableDeclaration variable in member.variables.variables) { | |
| 8513 if (variable.name.name == name) { | |
| 8514 return variable; | |
| 8515 } | |
| 8516 } | |
| 8517 } | |
| 8518 } | |
| 8519 return null; | |
| 8520 // Not found | |
| 8521 } | |
| 8522 | |
| 8523 /** | |
| 8524 * In the rare cases we want to group several tests into single "test_" method
, so need a way to | |
| 8525 * reset test instance to reuse it. | |
| 8526 */ | |
| 8527 void reset() { | |
| 8528 analysisContext2 = AnalysisContextFactory.contextWithCore(); | |
| 8529 } | |
| 8530 | |
| 8531 /** | |
| 8532 * Reset the analysis context to have the given options applied. | |
| 8533 * | |
| 8534 * @param options the analysis options to be applied to the context | |
| 8535 */ | |
| 8536 void resetWithOptions(AnalysisOptions options) { | |
| 8537 analysisContext2 = | |
| 8538 AnalysisContextFactory.contextWithCoreAndOptions(options); | |
| 8539 } | |
| 8540 | |
| 8541 /** | |
| 8542 * Given a library and all of its parts, resolve the contents of the library a
nd the contents of | |
| 8543 * the parts. This assumes that the sources for the library and its parts have
already been added | |
| 8544 * to the content provider using the method [addNamedSource]. | |
| 8545 * | |
| 8546 * @param librarySource the source for the compilation unit that defines the l
ibrary | |
| 8547 * @return the element representing the resolved library | |
| 8548 * @throws AnalysisException if the analysis could not be performed | |
| 8549 */ | |
| 8550 LibraryElement resolve2(Source librarySource) => | |
| 8551 analysisContext2.computeLibraryElement(librarySource); | |
| 8552 | |
| 8553 /** | |
| 8554 * Return the resolved compilation unit corresponding to the given source in t
he given library. | |
| 8555 * | |
| 8556 * @param source the source of the compilation unit to be returned | |
| 8557 * @param library the library in which the compilation unit is to be resolved | |
| 8558 * @return the resolved compilation unit | |
| 8559 * @throws Exception if the compilation unit could not be resolved | |
| 8560 */ | |
| 8561 CompilationUnit resolveCompilationUnit( | |
| 8562 Source source, LibraryElement library) => | |
| 8563 analysisContext2.resolveCompilationUnit(source, library); | |
| 8564 | |
| 8565 CompilationUnit resolveSource(String sourceText) => | |
| 8566 resolveSource2("/test.dart", sourceText); | |
| 8567 | |
| 8568 CompilationUnit resolveSource2(String fileName, String sourceText) { | |
| 8569 Source source = addNamedSource(fileName, sourceText); | |
| 8570 LibraryElement library = analysisContext.computeLibraryElement(source); | |
| 8571 return analysisContext.resolveCompilationUnit(source, library); | |
| 8572 } | |
| 8573 | |
| 8574 Source resolveSources(List<String> sourceTexts) { | |
| 8575 for (int i = 0; i < sourceTexts.length; i++) { | |
| 8576 CompilationUnit unit = | |
| 8577 resolveSource2("/lib${i + 1}.dart", sourceTexts[i]); | |
| 8578 // reference the source if this is the last source | |
| 8579 if (i + 1 == sourceTexts.length) { | |
| 8580 return unit.element.source; | |
| 8581 } | |
| 8582 } | |
| 8583 return null; | |
| 8584 } | |
| 8585 | |
| 8586 void resolveWithAndWithoutExperimental( | |
| 8587 List<String> strSources, | |
| 8588 List<ErrorCode> codesWithoutExperimental, | |
| 8589 List<ErrorCode> codesWithExperimental) { | |
| 8590 // Setup analysis context as non-experimental | |
| 8591 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); | |
| 8592 // options.enableDeferredLoading = false; | |
| 8593 resetWithOptions(options); | |
| 8594 // Analysis and assertions | |
| 8595 Source source = resolveSources(strSources); | |
| 8596 assertErrors(source, codesWithoutExperimental); | |
| 8597 verify([source]); | |
| 8598 // Setup analysis context as experimental | |
| 8599 reset(); | |
| 8600 // Analysis and assertions | |
| 8601 source = resolveSources(strSources); | |
| 8602 assertErrors(source, codesWithExperimental); | |
| 8603 verify([source]); | |
| 8604 } | |
| 8605 | |
| 8606 void resolveWithErrors(List<String> strSources, List<ErrorCode> codes) { | |
| 8607 // Analysis and assertions | |
| 8608 Source source = resolveSources(strSources); | |
| 8609 assertErrors(source, codes); | |
| 8610 verify([source]); | |
| 8611 } | |
| 8612 | |
| 8613 @override | |
| 8614 void setUp() { | |
| 8615 ElementFactory.flushStaticState(); | |
| 8616 super.setUp(); | |
| 8617 reset(); | |
| 8618 } | |
| 8619 | |
| 8620 @override | |
| 8621 void tearDown() { | |
| 8622 analysisContext2 = null; | |
| 8623 super.tearDown(); | |
| 8624 } | |
| 8625 | |
| 8626 /** | |
| 8627 * Verify that all of the identifiers in the compilation units associated with | |
| 8628 * the given [sources] have been resolved. | |
| 8629 */ | |
| 8630 void verify(List<Source> sources) { | |
| 8631 ResolutionVerifier verifier = new ResolutionVerifier(); | |
| 8632 for (Source source in sources) { | |
| 8633 List<Source> libraries = analysisContext2.getLibrariesContaining(source); | |
| 8634 for (Source library in libraries) { | |
| 8635 analysisContext2 | |
| 8636 .resolveCompilationUnit2(source, library) | |
| 8637 .accept(verifier); | |
| 8638 } | |
| 8639 } | |
| 8640 verifier.assertResolved(); | |
| 8641 } | |
| 8642 | |
| 8643 /** | |
| 8644 * @param code the code that assigns the value to the variable "v", no matter
how. We check that | |
| 8645 * "v" has expected static and propagated type. | |
| 8646 */ | |
| 8647 void _assertPropagatedAssignedType(String code, DartType expectedStaticType, | |
| 8648 DartType expectedPropagatedType) { | |
| 8649 SimpleIdentifier identifier = _findMarkedIdentifier(code, "v = "); | |
| 8650 expect(identifier.staticType, same(expectedStaticType)); | |
| 8651 expect(identifier.propagatedType, same(expectedPropagatedType)); | |
| 8652 } | |
| 8653 | |
| 8654 /** | |
| 8655 * @param code the code that iterates using variable "v". We check that | |
| 8656 * "v" has expected static and propagated type. | |
| 8657 */ | |
| 8658 void _assertPropagatedIterationType(String code, DartType expectedStaticType, | |
| 8659 DartType expectedPropagatedType) { | |
| 8660 SimpleIdentifier identifier = _findMarkedIdentifier(code, "v in "); | |
| 8661 expect(identifier.staticType, same(expectedStaticType)); | |
| 8662 expect(identifier.propagatedType, same(expectedPropagatedType)); | |
| 8663 } | |
| 8664 | |
| 8665 /** | |
| 8666 * Check the static and propagated types of the expression marked with "; // m
arker" comment. | |
| 8667 * | |
| 8668 * @param code source code to analyze, with the expression to check marked wit
h "// marker". | |
| 8669 * @param expectedStaticType if non-null, check actual static type is equal to
this. | |
| 8670 * @param expectedPropagatedType if non-null, check actual static type is equa
l to this. | |
| 8671 * @throws Exception | |
| 8672 */ | |
| 8673 void _assertTypeOfMarkedExpression(String code, DartType expectedStaticType, | |
| 8674 DartType expectedPropagatedType) { | |
| 8675 SimpleIdentifier identifier = _findMarkedIdentifier(code, "; // marker"); | |
| 8676 if (expectedStaticType != null) { | |
| 8677 expect(identifier.staticType, expectedStaticType); | |
| 8678 } | |
| 8679 expect(identifier.propagatedType, expectedPropagatedType); | |
| 8680 } | |
| 8681 | |
| 8682 /** | |
| 8683 * Create a source object representing a file with the given [fileName] and | |
| 8684 * give it an empty content. Return the source that was created. | |
| 8685 */ | |
| 8686 FileBasedSource _createNamedSource(String fileName) { | |
| 8687 FileBasedSource source = | |
| 8688 new FileBasedSource(FileUtilities2.createFile(fileName)); | |
| 8689 analysisContext2.setContents(source, ""); | |
| 8690 return source; | |
| 8691 } | |
| 8692 | |
| 8693 /** | |
| 8694 * Return the `SimpleIdentifier` marked by `marker`. The source code must have
no | |
| 8695 * errors and be verifiable. | |
| 8696 * | |
| 8697 * @param code source code to analyze. | |
| 8698 * @param marker marker identifying sought after expression in source code. | |
| 8699 * @return expression marked by the marker. | |
| 8700 * @throws Exception | |
| 8701 */ | |
| 8702 SimpleIdentifier _findMarkedIdentifier(String code, String marker) { | |
| 8703 try { | |
| 8704 Source source = addSource(code); | |
| 8705 LibraryElement library = resolve2(source); | |
| 8706 assertNoErrors(source); | |
| 8707 verify([source]); | |
| 8708 CompilationUnit unit = resolveCompilationUnit(source, library); | |
| 8709 // Could generalize this further by making [SimpleIdentifier.class] a | |
| 8710 // parameter. | |
| 8711 return EngineTestCase.findNode( | |
| 8712 unit, code, marker, (node) => node is SimpleIdentifier); | |
| 8713 } catch (exception) { | |
| 8714 // Is there a better exception to throw here? The point is that an | |
| 8715 // assertion failure here should be a failure, in both "test_*" and | |
| 8716 // "fail_*" tests. However, an assertion failure is success for the | |
| 8717 // purpose of "fail_*" tests, so without catching them here "fail_*" tests | |
| 8718 // can succeed by failing for the wrong reason. | |
| 8719 throw new JavaException("Unexexpected assertion failure: $exception"); | |
| 8720 } | |
| 8721 } | |
| 8722 } | |
| 8723 | |
| 8724 class Scope_EnclosedScopeTest_test_define_duplicate extends Scope { | 585 class Scope_EnclosedScopeTest_test_define_duplicate extends Scope { |
| 8725 GatheringErrorListener listener; | 586 GatheringErrorListener listener; |
| 8726 | 587 |
| 8727 Scope_EnclosedScopeTest_test_define_duplicate(this.listener) : super(); | 588 Scope_EnclosedScopeTest_test_define_duplicate(this.listener) : super(); |
| 8728 | 589 |
| 8729 @override | 590 @override |
| 8730 AnalysisErrorListener get errorListener => listener; | 591 AnalysisErrorListener get errorListener => listener; |
| 8731 | 592 |
| 8732 @override | 593 @override |
| 8733 Element internalLookup(Identifier identifier, String name, | 594 Element internalLookup(Identifier identifier, String name, |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8800 final AnalysisErrorListener errorListener; | 661 final AnalysisErrorListener errorListener; |
| 8801 | 662 |
| 8802 ScopeTest_TestScope(this.errorListener); | 663 ScopeTest_TestScope(this.errorListener); |
| 8803 | 664 |
| 8804 @override | 665 @override |
| 8805 Element internalLookup(Identifier identifier, String name, | 666 Element internalLookup(Identifier identifier, String name, |
| 8806 LibraryElement referencingLibrary) => | 667 LibraryElement referencingLibrary) => |
| 8807 localLookup(name, referencingLibrary); | 668 localLookup(name, referencingLibrary); |
| 8808 } | 669 } |
| 8809 | 670 |
| 8810 @reflectiveTest | |
| 8811 class SimpleResolverTest extends ResolverTestCase { | |
| 8812 void fail_getter_and_setter_fromMixins_property_access() { | |
| 8813 // TODO(paulberry): it appears that auxiliaryElements isn't properly set on | |
| 8814 // a SimpleIdentifier that's inside a property access. This bug should be | |
| 8815 // fixed. | |
| 8816 Source source = addSource(''' | |
| 8817 class B {} | |
| 8818 class M1 { | |
| 8819 get x => null; | |
| 8820 set x(value) {} | |
| 8821 } | |
| 8822 class M2 { | |
| 8823 get x => null; | |
| 8824 set x(value) {} | |
| 8825 } | |
| 8826 class C extends B with M1, M2 {} | |
| 8827 void main() { | |
| 8828 new C().x += 1; | |
| 8829 } | |
| 8830 '''); | |
| 8831 LibraryElement library = resolve2(source); | |
| 8832 assertNoErrors(source); | |
| 8833 verify([source]); | |
| 8834 // Verify that both the getter and setter for "x" in "new C().x" refer to | |
| 8835 // the accessors defined in M2. | |
| 8836 FunctionDeclaration main = | |
| 8837 library.definingCompilationUnit.functions[0].computeNode(); | |
| 8838 BlockFunctionBody body = main.functionExpression.body; | |
| 8839 ExpressionStatement stmt = body.block.statements[0]; | |
| 8840 AssignmentExpression assignment = stmt.expression; | |
| 8841 PropertyAccess propertyAccess = assignment.leftHandSide; | |
| 8842 expect( | |
| 8843 propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2'); | |
| 8844 expect( | |
| 8845 propertyAccess | |
| 8846 .propertyName.auxiliaryElements.staticElement.enclosingElement.name, | |
| 8847 'M2'); | |
| 8848 } | |
| 8849 | |
| 8850 void fail_staticInvocation() { | |
| 8851 Source source = addSource(r''' | |
| 8852 class A { | |
| 8853 static int get g => (a,b) => 0; | |
| 8854 } | |
| 8855 class B { | |
| 8856 f() { | |
| 8857 A.g(1,0); | |
| 8858 } | |
| 8859 }'''); | |
| 8860 computeLibrarySourceErrors(source); | |
| 8861 assertNoErrors(source); | |
| 8862 verify([source]); | |
| 8863 } | |
| 8864 | |
| 8865 void test_argumentResolution_required_matching() { | |
| 8866 Source source = addSource(r''' | |
| 8867 class A { | |
| 8868 void f() { | |
| 8869 g(1, 2, 3); | |
| 8870 } | |
| 8871 void g(a, b, c) {} | |
| 8872 }'''); | |
| 8873 _validateArgumentResolution(source, [0, 1, 2]); | |
| 8874 } | |
| 8875 | |
| 8876 void test_argumentResolution_required_tooFew() { | |
| 8877 Source source = addSource(r''' | |
| 8878 class A { | |
| 8879 void f() { | |
| 8880 g(1, 2); | |
| 8881 } | |
| 8882 void g(a, b, c) {} | |
| 8883 }'''); | |
| 8884 _validateArgumentResolution(source, [0, 1]); | |
| 8885 } | |
| 8886 | |
| 8887 void test_argumentResolution_required_tooMany() { | |
| 8888 Source source = addSource(r''' | |
| 8889 class A { | |
| 8890 void f() { | |
| 8891 g(1, 2, 3); | |
| 8892 } | |
| 8893 void g(a, b) {} | |
| 8894 }'''); | |
| 8895 _validateArgumentResolution(source, [0, 1, -1]); | |
| 8896 } | |
| 8897 | |
| 8898 void test_argumentResolution_requiredAndNamed_extra() { | |
| 8899 Source source = addSource(r''' | |
| 8900 class A { | |
| 8901 void f() { | |
| 8902 g(1, 2, c: 3, d: 4); | |
| 8903 } | |
| 8904 void g(a, b, {c}) {} | |
| 8905 }'''); | |
| 8906 _validateArgumentResolution(source, [0, 1, 2, -1]); | |
| 8907 } | |
| 8908 | |
| 8909 void test_argumentResolution_requiredAndNamed_matching() { | |
| 8910 Source source = addSource(r''' | |
| 8911 class A { | |
| 8912 void f() { | |
| 8913 g(1, 2, c: 3); | |
| 8914 } | |
| 8915 void g(a, b, {c}) {} | |
| 8916 }'''); | |
| 8917 _validateArgumentResolution(source, [0, 1, 2]); | |
| 8918 } | |
| 8919 | |
| 8920 void test_argumentResolution_requiredAndNamed_missing() { | |
| 8921 Source source = addSource(r''' | |
| 8922 class A { | |
| 8923 void f() { | |
| 8924 g(1, 2, d: 3); | |
| 8925 } | |
| 8926 void g(a, b, {c, d}) {} | |
| 8927 }'''); | |
| 8928 _validateArgumentResolution(source, [0, 1, 3]); | |
| 8929 } | |
| 8930 | |
| 8931 void test_argumentResolution_requiredAndPositional_fewer() { | |
| 8932 Source source = addSource(r''' | |
| 8933 class A { | |
| 8934 void f() { | |
| 8935 g(1, 2, 3); | |
| 8936 } | |
| 8937 void g(a, b, [c, d]) {} | |
| 8938 }'''); | |
| 8939 _validateArgumentResolution(source, [0, 1, 2]); | |
| 8940 } | |
| 8941 | |
| 8942 void test_argumentResolution_requiredAndPositional_matching() { | |
| 8943 Source source = addSource(r''' | |
| 8944 class A { | |
| 8945 void f() { | |
| 8946 g(1, 2, 3, 4); | |
| 8947 } | |
| 8948 void g(a, b, [c, d]) {} | |
| 8949 }'''); | |
| 8950 _validateArgumentResolution(source, [0, 1, 2, 3]); | |
| 8951 } | |
| 8952 | |
| 8953 void test_argumentResolution_requiredAndPositional_more() { | |
| 8954 Source source = addSource(r''' | |
| 8955 class A { | |
| 8956 void f() { | |
| 8957 g(1, 2, 3, 4); | |
| 8958 } | |
| 8959 void g(a, b, [c]) {} | |
| 8960 }'''); | |
| 8961 _validateArgumentResolution(source, [0, 1, 2, -1]); | |
| 8962 } | |
| 8963 | |
| 8964 void test_argumentResolution_setter_propagated() { | |
| 8965 Source source = addSource(r''' | |
| 8966 main() { | |
| 8967 var a = new A(); | |
| 8968 a.sss = 0; | |
| 8969 } | |
| 8970 class A { | |
| 8971 set sss(x) {} | |
| 8972 }'''); | |
| 8973 LibraryElement library = resolve2(source); | |
| 8974 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 8975 // find "a.sss = 0" | |
| 8976 AssignmentExpression assignment; | |
| 8977 { | |
| 8978 FunctionElement mainElement = unit.functions[0]; | |
| 8979 FunctionBody mainBody = mainElement.computeNode().functionExpression.body; | |
| 8980 Statement statement = (mainBody as BlockFunctionBody).block.statements[1]; | |
| 8981 ExpressionStatement expressionStatement = | |
| 8982 statement as ExpressionStatement; | |
| 8983 assignment = expressionStatement.expression as AssignmentExpression; | |
| 8984 } | |
| 8985 // get parameter | |
| 8986 Expression rhs = assignment.rightHandSide; | |
| 8987 expect(rhs.staticParameterElement, isNull); | |
| 8988 ParameterElement parameter = rhs.propagatedParameterElement; | |
| 8989 expect(parameter, isNotNull); | |
| 8990 expect(parameter.displayName, "x"); | |
| 8991 // validate | |
| 8992 ClassElement classA = unit.types[0]; | |
| 8993 PropertyAccessorElement setter = classA.accessors[0]; | |
| 8994 expect(setter.parameters[0], same(parameter)); | |
| 8995 } | |
| 8996 | |
| 8997 void test_argumentResolution_setter_propagated_propertyAccess() { | |
| 8998 Source source = addSource(r''' | |
| 8999 main() { | |
| 9000 var a = new A(); | |
| 9001 a.b.sss = 0; | |
| 9002 } | |
| 9003 class A { | |
| 9004 B b = new B(); | |
| 9005 } | |
| 9006 class B { | |
| 9007 set sss(x) {} | |
| 9008 }'''); | |
| 9009 LibraryElement library = resolve2(source); | |
| 9010 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9011 // find "a.b.sss = 0" | |
| 9012 AssignmentExpression assignment; | |
| 9013 { | |
| 9014 FunctionElement mainElement = unit.functions[0]; | |
| 9015 FunctionBody mainBody = mainElement.computeNode().functionExpression.body; | |
| 9016 Statement statement = (mainBody as BlockFunctionBody).block.statements[1]; | |
| 9017 ExpressionStatement expressionStatement = | |
| 9018 statement as ExpressionStatement; | |
| 9019 assignment = expressionStatement.expression as AssignmentExpression; | |
| 9020 } | |
| 9021 // get parameter | |
| 9022 Expression rhs = assignment.rightHandSide; | |
| 9023 expect(rhs.staticParameterElement, isNull); | |
| 9024 ParameterElement parameter = rhs.propagatedParameterElement; | |
| 9025 expect(parameter, isNotNull); | |
| 9026 expect(parameter.displayName, "x"); | |
| 9027 // validate | |
| 9028 ClassElement classB = unit.types[1]; | |
| 9029 PropertyAccessorElement setter = classB.accessors[0]; | |
| 9030 expect(setter.parameters[0], same(parameter)); | |
| 9031 } | |
| 9032 | |
| 9033 void test_argumentResolution_setter_static() { | |
| 9034 Source source = addSource(r''' | |
| 9035 main() { | |
| 9036 A a = new A(); | |
| 9037 a.sss = 0; | |
| 9038 } | |
| 9039 class A { | |
| 9040 set sss(x) {} | |
| 9041 }'''); | |
| 9042 LibraryElement library = resolve2(source); | |
| 9043 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9044 // find "a.sss = 0" | |
| 9045 AssignmentExpression assignment; | |
| 9046 { | |
| 9047 FunctionElement mainElement = unit.functions[0]; | |
| 9048 FunctionBody mainBody = mainElement.computeNode().functionExpression.body; | |
| 9049 Statement statement = (mainBody as BlockFunctionBody).block.statements[1]; | |
| 9050 ExpressionStatement expressionStatement = | |
| 9051 statement as ExpressionStatement; | |
| 9052 assignment = expressionStatement.expression as AssignmentExpression; | |
| 9053 } | |
| 9054 // get parameter | |
| 9055 Expression rhs = assignment.rightHandSide; | |
| 9056 ParameterElement parameter = rhs.staticParameterElement; | |
| 9057 expect(parameter, isNotNull); | |
| 9058 expect(parameter.displayName, "x"); | |
| 9059 // validate | |
| 9060 ClassElement classA = unit.types[0]; | |
| 9061 PropertyAccessorElement setter = classA.accessors[0]; | |
| 9062 expect(setter.parameters[0], same(parameter)); | |
| 9063 } | |
| 9064 | |
| 9065 void test_argumentResolution_setter_static_propertyAccess() { | |
| 9066 Source source = addSource(r''' | |
| 9067 main() { | |
| 9068 A a = new A(); | |
| 9069 a.b.sss = 0; | |
| 9070 } | |
| 9071 class A { | |
| 9072 B b = new B(); | |
| 9073 } | |
| 9074 class B { | |
| 9075 set sss(x) {} | |
| 9076 }'''); | |
| 9077 LibraryElement library = resolve2(source); | |
| 9078 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9079 // find "a.b.sss = 0" | |
| 9080 AssignmentExpression assignment; | |
| 9081 { | |
| 9082 FunctionElement mainElement = unit.functions[0]; | |
| 9083 FunctionBody mainBody = mainElement.computeNode().functionExpression.body; | |
| 9084 Statement statement = (mainBody as BlockFunctionBody).block.statements[1]; | |
| 9085 ExpressionStatement expressionStatement = | |
| 9086 statement as ExpressionStatement; | |
| 9087 assignment = expressionStatement.expression as AssignmentExpression; | |
| 9088 } | |
| 9089 // get parameter | |
| 9090 Expression rhs = assignment.rightHandSide; | |
| 9091 ParameterElement parameter = rhs.staticParameterElement; | |
| 9092 expect(parameter, isNotNull); | |
| 9093 expect(parameter.displayName, "x"); | |
| 9094 // validate | |
| 9095 ClassElement classB = unit.types[1]; | |
| 9096 PropertyAccessorElement setter = classB.accessors[0]; | |
| 9097 expect(setter.parameters[0], same(parameter)); | |
| 9098 } | |
| 9099 | |
| 9100 void test_breakTarget_labeled() { | |
| 9101 // Verify that the target of the label is correctly found and is recorded | |
| 9102 // as the unlabeled portion of the statement. | |
| 9103 String text = r''' | |
| 9104 void f() { | |
| 9105 loop1: while (true) { | |
| 9106 loop2: for (int i = 0; i < 10; i++) { | |
| 9107 break loop1; | |
| 9108 break loop2; | |
| 9109 } | |
| 9110 } | |
| 9111 } | |
| 9112 '''; | |
| 9113 CompilationUnit unit = resolveSource(text); | |
| 9114 WhileStatement whileStatement = EngineTestCase.findNode( | |
| 9115 unit, text, 'while (true)', (n) => n is WhileStatement); | |
| 9116 ForStatement forStatement = | |
| 9117 EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement); | |
| 9118 BreakStatement break1 = EngineTestCase.findNode( | |
| 9119 unit, text, 'break loop1', (n) => n is BreakStatement); | |
| 9120 BreakStatement break2 = EngineTestCase.findNode( | |
| 9121 unit, text, 'break loop2', (n) => n is BreakStatement); | |
| 9122 expect(break1.target, same(whileStatement)); | |
| 9123 expect(break2.target, same(forStatement)); | |
| 9124 } | |
| 9125 | |
| 9126 void test_breakTarget_unlabeledBreakFromDo() { | |
| 9127 String text = r''' | |
| 9128 void f() { | |
| 9129 do { | |
| 9130 break; | |
| 9131 } while (true); | |
| 9132 } | |
| 9133 '''; | |
| 9134 CompilationUnit unit = resolveSource(text); | |
| 9135 DoStatement doStatement = | |
| 9136 EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement); | |
| 9137 BreakStatement breakStatement = EngineTestCase.findNode( | |
| 9138 unit, text, 'break', (n) => n is BreakStatement); | |
| 9139 expect(breakStatement.target, same(doStatement)); | |
| 9140 } | |
| 9141 | |
| 9142 void test_breakTarget_unlabeledBreakFromFor() { | |
| 9143 String text = r''' | |
| 9144 void f() { | |
| 9145 for (int i = 0; i < 10; i++) { | |
| 9146 break; | |
| 9147 } | |
| 9148 } | |
| 9149 '''; | |
| 9150 CompilationUnit unit = resolveSource(text); | |
| 9151 ForStatement forStatement = | |
| 9152 EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement); | |
| 9153 BreakStatement breakStatement = EngineTestCase.findNode( | |
| 9154 unit, text, 'break', (n) => n is BreakStatement); | |
| 9155 expect(breakStatement.target, same(forStatement)); | |
| 9156 } | |
| 9157 | |
| 9158 void test_breakTarget_unlabeledBreakFromForEach() { | |
| 9159 String text = r''' | |
| 9160 void f() { | |
| 9161 for (x in []) { | |
| 9162 break; | |
| 9163 } | |
| 9164 } | |
| 9165 '''; | |
| 9166 CompilationUnit unit = resolveSource(text); | |
| 9167 ForEachStatement forStatement = EngineTestCase.findNode( | |
| 9168 unit, text, 'for', (n) => n is ForEachStatement); | |
| 9169 BreakStatement breakStatement = EngineTestCase.findNode( | |
| 9170 unit, text, 'break', (n) => n is BreakStatement); | |
| 9171 expect(breakStatement.target, same(forStatement)); | |
| 9172 } | |
| 9173 | |
| 9174 void test_breakTarget_unlabeledBreakFromSwitch() { | |
| 9175 String text = r''' | |
| 9176 void f() { | |
| 9177 while (true) { | |
| 9178 switch (0) { | |
| 9179 case 0: | |
| 9180 break; | |
| 9181 } | |
| 9182 } | |
| 9183 } | |
| 9184 '''; | |
| 9185 CompilationUnit unit = resolveSource(text); | |
| 9186 SwitchStatement switchStatement = EngineTestCase.findNode( | |
| 9187 unit, text, 'switch', (n) => n is SwitchStatement); | |
| 9188 BreakStatement breakStatement = EngineTestCase.findNode( | |
| 9189 unit, text, 'break', (n) => n is BreakStatement); | |
| 9190 expect(breakStatement.target, same(switchStatement)); | |
| 9191 } | |
| 9192 | |
| 9193 void test_breakTarget_unlabeledBreakFromWhile() { | |
| 9194 String text = r''' | |
| 9195 void f() { | |
| 9196 while (true) { | |
| 9197 break; | |
| 9198 } | |
| 9199 } | |
| 9200 '''; | |
| 9201 CompilationUnit unit = resolveSource(text); | |
| 9202 WhileStatement whileStatement = EngineTestCase.findNode( | |
| 9203 unit, text, 'while', (n) => n is WhileStatement); | |
| 9204 BreakStatement breakStatement = EngineTestCase.findNode( | |
| 9205 unit, text, 'break', (n) => n is BreakStatement); | |
| 9206 expect(breakStatement.target, same(whileStatement)); | |
| 9207 } | |
| 9208 | |
| 9209 void test_breakTarget_unlabeledBreakToOuterFunction() { | |
| 9210 // Verify that unlabeled break statements can't resolve to loops in an | |
| 9211 // outer function. | |
| 9212 String text = r''' | |
| 9213 void f() { | |
| 9214 while (true) { | |
| 9215 void g() { | |
| 9216 break; | |
| 9217 } | |
| 9218 } | |
| 9219 } | |
| 9220 '''; | |
| 9221 CompilationUnit unit = resolveSource(text); | |
| 9222 BreakStatement breakStatement = EngineTestCase.findNode( | |
| 9223 unit, text, 'break', (n) => n is BreakStatement); | |
| 9224 expect(breakStatement.target, isNull); | |
| 9225 } | |
| 9226 | |
| 9227 void test_class_definesCall() { | |
| 9228 Source source = addSource(r''' | |
| 9229 class A { | |
| 9230 int call(int x) { return x; } | |
| 9231 } | |
| 9232 int f(A a) { | |
| 9233 return a(0); | |
| 9234 }'''); | |
| 9235 computeLibrarySourceErrors(source); | |
| 9236 assertNoErrors(source); | |
| 9237 verify([source]); | |
| 9238 } | |
| 9239 | |
| 9240 void test_class_extends_implements() { | |
| 9241 Source source = addSource(r''' | |
| 9242 class A extends B implements C {} | |
| 9243 class B {} | |
| 9244 class C {}'''); | |
| 9245 computeLibrarySourceErrors(source); | |
| 9246 assertNoErrors(source); | |
| 9247 verify([source]); | |
| 9248 } | |
| 9249 | |
| 9250 void test_commentReference_class() { | |
| 9251 Source source = addSource(r''' | |
| 9252 f() {} | |
| 9253 /** [A] [new A] [A.n] [new A.n] [m] [f] */ | |
| 9254 class A { | |
| 9255 A() {} | |
| 9256 A.n() {} | |
| 9257 m() {} | |
| 9258 }'''); | |
| 9259 computeLibrarySourceErrors(source); | |
| 9260 assertNoErrors(source); | |
| 9261 verify([source]); | |
| 9262 } | |
| 9263 | |
| 9264 void test_commentReference_parameter() { | |
| 9265 Source source = addSource(r''' | |
| 9266 class A { | |
| 9267 A() {} | |
| 9268 A.n() {} | |
| 9269 /** [e] [f] */ | |
| 9270 m(e, f()) {} | |
| 9271 }'''); | |
| 9272 computeLibrarySourceErrors(source); | |
| 9273 assertNoErrors(source); | |
| 9274 verify([source]); | |
| 9275 } | |
| 9276 | |
| 9277 void test_commentReference_singleLine() { | |
| 9278 Source source = addSource(r''' | |
| 9279 /// [A] | |
| 9280 class A {}'''); | |
| 9281 computeLibrarySourceErrors(source); | |
| 9282 assertNoErrors(source); | |
| 9283 verify([source]); | |
| 9284 } | |
| 9285 | |
| 9286 void test_continueTarget_labeled() { | |
| 9287 // Verify that the target of the label is correctly found and is recorded | |
| 9288 // as the unlabeled portion of the statement. | |
| 9289 String text = r''' | |
| 9290 void f() { | |
| 9291 loop1: while (true) { | |
| 9292 loop2: for (int i = 0; i < 10; i++) { | |
| 9293 continue loop1; | |
| 9294 continue loop2; | |
| 9295 } | |
| 9296 } | |
| 9297 } | |
| 9298 '''; | |
| 9299 CompilationUnit unit = resolveSource(text); | |
| 9300 WhileStatement whileStatement = EngineTestCase.findNode( | |
| 9301 unit, text, 'while (true)', (n) => n is WhileStatement); | |
| 9302 ForStatement forStatement = | |
| 9303 EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement); | |
| 9304 ContinueStatement continue1 = EngineTestCase.findNode( | |
| 9305 unit, text, 'continue loop1', (n) => n is ContinueStatement); | |
| 9306 ContinueStatement continue2 = EngineTestCase.findNode( | |
| 9307 unit, text, 'continue loop2', (n) => n is ContinueStatement); | |
| 9308 expect(continue1.target, same(whileStatement)); | |
| 9309 expect(continue2.target, same(forStatement)); | |
| 9310 } | |
| 9311 | |
| 9312 void test_continueTarget_unlabeledContinueFromDo() { | |
| 9313 String text = r''' | |
| 9314 void f() { | |
| 9315 do { | |
| 9316 continue; | |
| 9317 } while (true); | |
| 9318 } | |
| 9319 '''; | |
| 9320 CompilationUnit unit = resolveSource(text); | |
| 9321 DoStatement doStatement = | |
| 9322 EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement); | |
| 9323 ContinueStatement continueStatement = EngineTestCase.findNode( | |
| 9324 unit, text, 'continue', (n) => n is ContinueStatement); | |
| 9325 expect(continueStatement.target, same(doStatement)); | |
| 9326 } | |
| 9327 | |
| 9328 void test_continueTarget_unlabeledContinueFromFor() { | |
| 9329 String text = r''' | |
| 9330 void f() { | |
| 9331 for (int i = 0; i < 10; i++) { | |
| 9332 continue; | |
| 9333 } | |
| 9334 } | |
| 9335 '''; | |
| 9336 CompilationUnit unit = resolveSource(text); | |
| 9337 ForStatement forStatement = | |
| 9338 EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement); | |
| 9339 ContinueStatement continueStatement = EngineTestCase.findNode( | |
| 9340 unit, text, 'continue', (n) => n is ContinueStatement); | |
| 9341 expect(continueStatement.target, same(forStatement)); | |
| 9342 } | |
| 9343 | |
| 9344 void test_continueTarget_unlabeledContinueFromForEach() { | |
| 9345 String text = r''' | |
| 9346 void f() { | |
| 9347 for (x in []) { | |
| 9348 continue; | |
| 9349 } | |
| 9350 } | |
| 9351 '''; | |
| 9352 CompilationUnit unit = resolveSource(text); | |
| 9353 ForEachStatement forStatement = EngineTestCase.findNode( | |
| 9354 unit, text, 'for', (n) => n is ForEachStatement); | |
| 9355 ContinueStatement continueStatement = EngineTestCase.findNode( | |
| 9356 unit, text, 'continue', (n) => n is ContinueStatement); | |
| 9357 expect(continueStatement.target, same(forStatement)); | |
| 9358 } | |
| 9359 | |
| 9360 void test_continueTarget_unlabeledContinueFromWhile() { | |
| 9361 String text = r''' | |
| 9362 void f() { | |
| 9363 while (true) { | |
| 9364 continue; | |
| 9365 } | |
| 9366 } | |
| 9367 '''; | |
| 9368 CompilationUnit unit = resolveSource(text); | |
| 9369 WhileStatement whileStatement = EngineTestCase.findNode( | |
| 9370 unit, text, 'while', (n) => n is WhileStatement); | |
| 9371 ContinueStatement continueStatement = EngineTestCase.findNode( | |
| 9372 unit, text, 'continue', (n) => n is ContinueStatement); | |
| 9373 expect(continueStatement.target, same(whileStatement)); | |
| 9374 } | |
| 9375 | |
| 9376 void test_continueTarget_unlabeledContinueSkipsSwitch() { | |
| 9377 String text = r''' | |
| 9378 void f() { | |
| 9379 while (true) { | |
| 9380 switch (0) { | |
| 9381 case 0: | |
| 9382 continue; | |
| 9383 } | |
| 9384 } | |
| 9385 } | |
| 9386 '''; | |
| 9387 CompilationUnit unit = resolveSource(text); | |
| 9388 WhileStatement whileStatement = EngineTestCase.findNode( | |
| 9389 unit, text, 'while', (n) => n is WhileStatement); | |
| 9390 ContinueStatement continueStatement = EngineTestCase.findNode( | |
| 9391 unit, text, 'continue', (n) => n is ContinueStatement); | |
| 9392 expect(continueStatement.target, same(whileStatement)); | |
| 9393 } | |
| 9394 | |
| 9395 void test_continueTarget_unlabeledContinueToOuterFunction() { | |
| 9396 // Verify that unlabeled continue statements can't resolve to loops in an | |
| 9397 // outer function. | |
| 9398 String text = r''' | |
| 9399 void f() { | |
| 9400 while (true) { | |
| 9401 void g() { | |
| 9402 continue; | |
| 9403 } | |
| 9404 } | |
| 9405 } | |
| 9406 '''; | |
| 9407 CompilationUnit unit = resolveSource(text); | |
| 9408 ContinueStatement continueStatement = EngineTestCase.findNode( | |
| 9409 unit, text, 'continue', (n) => n is ContinueStatement); | |
| 9410 expect(continueStatement.target, isNull); | |
| 9411 } | |
| 9412 | |
| 9413 void test_empty() { | |
| 9414 Source source = addSource(""); | |
| 9415 computeLibrarySourceErrors(source); | |
| 9416 assertNoErrors(source); | |
| 9417 verify([source]); | |
| 9418 } | |
| 9419 | |
| 9420 void test_entryPoint_exported() { | |
| 9421 addNamedSource( | |
| 9422 "/two.dart", | |
| 9423 r''' | |
| 9424 library two; | |
| 9425 main() {}'''); | |
| 9426 Source source = addNamedSource( | |
| 9427 "/one.dart", | |
| 9428 r''' | |
| 9429 library one; | |
| 9430 export 'two.dart';'''); | |
| 9431 LibraryElement library = resolve2(source); | |
| 9432 expect(library, isNotNull); | |
| 9433 FunctionElement main = library.entryPoint; | |
| 9434 expect(main, isNotNull); | |
| 9435 expect(main.library, isNot(same(library))); | |
| 9436 assertNoErrors(source); | |
| 9437 verify([source]); | |
| 9438 } | |
| 9439 | |
| 9440 void test_entryPoint_local() { | |
| 9441 Source source = addNamedSource( | |
| 9442 "/one.dart", | |
| 9443 r''' | |
| 9444 library one; | |
| 9445 main() {}'''); | |
| 9446 LibraryElement library = resolve2(source); | |
| 9447 expect(library, isNotNull); | |
| 9448 FunctionElement main = library.entryPoint; | |
| 9449 expect(main, isNotNull); | |
| 9450 expect(main.library, same(library)); | |
| 9451 assertNoErrors(source); | |
| 9452 verify([source]); | |
| 9453 } | |
| 9454 | |
| 9455 void test_entryPoint_none() { | |
| 9456 Source source = addNamedSource("/one.dart", "library one;"); | |
| 9457 LibraryElement library = resolve2(source); | |
| 9458 expect(library, isNotNull); | |
| 9459 expect(library.entryPoint, isNull); | |
| 9460 assertNoErrors(source); | |
| 9461 verify([source]); | |
| 9462 } | |
| 9463 | |
| 9464 void test_enum_externalLibrary() { | |
| 9465 addNamedSource( | |
| 9466 "/my_lib.dart", | |
| 9467 r''' | |
| 9468 library my_lib; | |
| 9469 enum EEE {A, B, C}'''); | |
| 9470 Source source = addSource(r''' | |
| 9471 import 'my_lib.dart'; | |
| 9472 main() { | |
| 9473 EEE e = null; | |
| 9474 }'''); | |
| 9475 computeLibrarySourceErrors(source); | |
| 9476 assertNoErrors(source); | |
| 9477 verify([source]); | |
| 9478 } | |
| 9479 | |
| 9480 void test_extractedMethodAsConstant() { | |
| 9481 Source source = addSource(r''' | |
| 9482 abstract class Comparable<T> { | |
| 9483 int compareTo(T other); | |
| 9484 static int compare(Comparable a, Comparable b) => a.compareTo(b); | |
| 9485 } | |
| 9486 class A { | |
| 9487 void sort([compare = Comparable.compare]) {} | |
| 9488 }'''); | |
| 9489 computeLibrarySourceErrors(source); | |
| 9490 assertNoErrors(source); | |
| 9491 verify([source]); | |
| 9492 } | |
| 9493 | |
| 9494 void test_fieldFormalParameter() { | |
| 9495 Source source = addSource(r''' | |
| 9496 class A { | |
| 9497 int x; | |
| 9498 A(this.x) {} | |
| 9499 }'''); | |
| 9500 computeLibrarySourceErrors(source); | |
| 9501 assertNoErrors(source); | |
| 9502 verify([source]); | |
| 9503 } | |
| 9504 | |
| 9505 void test_forEachLoops_nonConflicting() { | |
| 9506 Source source = addSource(r''' | |
| 9507 f() { | |
| 9508 List list = [1,2,3]; | |
| 9509 for (int x in list) {} | |
| 9510 for (int x in list) {} | |
| 9511 }'''); | |
| 9512 computeLibrarySourceErrors(source); | |
| 9513 assertNoErrors(source); | |
| 9514 verify([source]); | |
| 9515 } | |
| 9516 | |
| 9517 void test_forLoops_nonConflicting() { | |
| 9518 Source source = addSource(r''' | |
| 9519 f() { | |
| 9520 for (int i = 0; i < 3; i++) { | |
| 9521 } | |
| 9522 for (int i = 0; i < 3; i++) { | |
| 9523 } | |
| 9524 }'''); | |
| 9525 computeLibrarySourceErrors(source); | |
| 9526 assertNoErrors(source); | |
| 9527 verify([source]); | |
| 9528 } | |
| 9529 | |
| 9530 void test_functionTypeAlias() { | |
| 9531 Source source = addSource(r''' | |
| 9532 typedef bool P(e); | |
| 9533 class A { | |
| 9534 P p; | |
| 9535 m(e) { | |
| 9536 if (p(e)) {} | |
| 9537 } | |
| 9538 }'''); | |
| 9539 computeLibrarySourceErrors(source); | |
| 9540 assertNoErrors(source); | |
| 9541 verify([source]); | |
| 9542 } | |
| 9543 | |
| 9544 void test_getter_and_setter_fromMixins_bare_identifier() { | |
| 9545 Source source = addSource(''' | |
| 9546 class B {} | |
| 9547 class M1 { | |
| 9548 get x => null; | |
| 9549 set x(value) {} | |
| 9550 } | |
| 9551 class M2 { | |
| 9552 get x => null; | |
| 9553 set x(value) {} | |
| 9554 } | |
| 9555 class C extends B with M1, M2 { | |
| 9556 void f() { | |
| 9557 x += 1; | |
| 9558 } | |
| 9559 } | |
| 9560 '''); | |
| 9561 LibraryElement library = resolve2(source); | |
| 9562 assertNoErrors(source); | |
| 9563 verify([source]); | |
| 9564 // Verify that both the getter and setter for "x" in C.f() refer to the | |
| 9565 // accessors defined in M2. | |
| 9566 ClassElement classC = library.definingCompilationUnit.types[3]; | |
| 9567 MethodDeclaration f = classC.getMethod('f').computeNode(); | |
| 9568 BlockFunctionBody body = f.body; | |
| 9569 ExpressionStatement stmt = body.block.statements[0]; | |
| 9570 AssignmentExpression assignment = stmt.expression; | |
| 9571 SimpleIdentifier leftHandSide = assignment.leftHandSide; | |
| 9572 expect(leftHandSide.staticElement.enclosingElement.name, 'M2'); | |
| 9573 expect(leftHandSide.auxiliaryElements.staticElement.enclosingElement.name, | |
| 9574 'M2'); | |
| 9575 } | |
| 9576 | |
| 9577 void test_getter_fromMixins_bare_identifier() { | |
| 9578 Source source = addSource(''' | |
| 9579 class B {} | |
| 9580 class M1 { | |
| 9581 get x => null; | |
| 9582 } | |
| 9583 class M2 { | |
| 9584 get x => null; | |
| 9585 } | |
| 9586 class C extends B with M1, M2 { | |
| 9587 f() { | |
| 9588 return x; | |
| 9589 } | |
| 9590 } | |
| 9591 '''); | |
| 9592 LibraryElement library = resolve2(source); | |
| 9593 assertNoErrors(source); | |
| 9594 verify([source]); | |
| 9595 // Verify that the getter for "x" in C.f() refers to the getter defined in | |
| 9596 // M2. | |
| 9597 ClassElement classC = library.definingCompilationUnit.types[3]; | |
| 9598 MethodDeclaration f = classC.getMethod('f').computeNode(); | |
| 9599 BlockFunctionBody body = f.body; | |
| 9600 ReturnStatement stmt = body.block.statements[0]; | |
| 9601 SimpleIdentifier x = stmt.expression; | |
| 9602 expect(x.staticElement.enclosingElement.name, 'M2'); | |
| 9603 } | |
| 9604 | |
| 9605 void test_getter_fromMixins_property_access() { | |
| 9606 Source source = addSource(''' | |
| 9607 class B {} | |
| 9608 class M1 { | |
| 9609 get x => null; | |
| 9610 } | |
| 9611 class M2 { | |
| 9612 get x => null; | |
| 9613 } | |
| 9614 class C extends B with M1, M2 {} | |
| 9615 void main() { | |
| 9616 var y = new C().x; | |
| 9617 } | |
| 9618 '''); | |
| 9619 LibraryElement library = resolve2(source); | |
| 9620 assertNoErrors(source); | |
| 9621 verify([source]); | |
| 9622 // Verify that the getter for "x" in "new C().x" refers to the getter | |
| 9623 // defined in M2. | |
| 9624 FunctionDeclaration main = | |
| 9625 library.definingCompilationUnit.functions[0].computeNode(); | |
| 9626 BlockFunctionBody body = main.functionExpression.body; | |
| 9627 VariableDeclarationStatement stmt = body.block.statements[0]; | |
| 9628 PropertyAccess propertyAccess = stmt.variables.variables[0].initializer; | |
| 9629 expect( | |
| 9630 propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2'); | |
| 9631 } | |
| 9632 | |
| 9633 void test_getterAndSetterWithDifferentTypes() { | |
| 9634 Source source = addSource(r''' | |
| 9635 class A { | |
| 9636 int get f => 0; | |
| 9637 void set f(String s) {} | |
| 9638 } | |
| 9639 g (A a) { | |
| 9640 a.f = a.f.toString(); | |
| 9641 }'''); | |
| 9642 computeLibrarySourceErrors(source); | |
| 9643 assertErrors( | |
| 9644 source, [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]); | |
| 9645 verify([source]); | |
| 9646 } | |
| 9647 | |
| 9648 void test_hasReferenceToSuper() { | |
| 9649 Source source = addSource(r''' | |
| 9650 class A {} | |
| 9651 class B {toString() => super.toString();}'''); | |
| 9652 LibraryElement library = resolve2(source); | |
| 9653 expect(library, isNotNull); | |
| 9654 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9655 expect(unit, isNotNull); | |
| 9656 List<ClassElement> classes = unit.types; | |
| 9657 expect(classes, hasLength(2)); | |
| 9658 expect(classes[0].hasReferenceToSuper, isFalse); | |
| 9659 expect(classes[1].hasReferenceToSuper, isTrue); | |
| 9660 assertNoErrors(source); | |
| 9661 verify([source]); | |
| 9662 } | |
| 9663 | |
| 9664 void test_import_hide() { | |
| 9665 addNamedSource( | |
| 9666 "/lib1.dart", | |
| 9667 r''' | |
| 9668 library lib1; | |
| 9669 set foo(value) {} | |
| 9670 class A {}'''); | |
| 9671 addNamedSource( | |
| 9672 "/lib2.dart", | |
| 9673 r''' | |
| 9674 library lib2; | |
| 9675 set foo(value) {}'''); | |
| 9676 Source source = addNamedSource( | |
| 9677 "/lib3.dart", | |
| 9678 r''' | |
| 9679 import 'lib1.dart' hide foo; | |
| 9680 import 'lib2.dart'; | |
| 9681 | |
| 9682 main() { | |
| 9683 foo = 0; | |
| 9684 } | |
| 9685 A a;'''); | |
| 9686 computeLibrarySourceErrors(source); | |
| 9687 assertNoErrors(source); | |
| 9688 verify([source]); | |
| 9689 } | |
| 9690 | |
| 9691 void test_import_prefix() { | |
| 9692 addNamedSource( | |
| 9693 "/two.dart", | |
| 9694 r''' | |
| 9695 library two; | |
| 9696 f(int x) { | |
| 9697 return x * x; | |
| 9698 }'''); | |
| 9699 Source source = addNamedSource( | |
| 9700 "/one.dart", | |
| 9701 r''' | |
| 9702 library one; | |
| 9703 import 'two.dart' as _two; | |
| 9704 main() { | |
| 9705 _two.f(0); | |
| 9706 }'''); | |
| 9707 computeLibrarySourceErrors(source); | |
| 9708 assertNoErrors(source); | |
| 9709 verify([source]); | |
| 9710 } | |
| 9711 | |
| 9712 void test_import_spaceInUri() { | |
| 9713 addNamedSource( | |
| 9714 "/sub folder/lib.dart", | |
| 9715 r''' | |
| 9716 library lib; | |
| 9717 foo() {}'''); | |
| 9718 Source source = addNamedSource( | |
| 9719 "/app.dart", | |
| 9720 r''' | |
| 9721 import 'sub folder/lib.dart'; | |
| 9722 | |
| 9723 main() { | |
| 9724 foo(); | |
| 9725 }'''); | |
| 9726 computeLibrarySourceErrors(source); | |
| 9727 assertNoErrors(source); | |
| 9728 verify([source]); | |
| 9729 } | |
| 9730 | |
| 9731 void test_indexExpression_typeParameters() { | |
| 9732 Source source = addSource(r''' | |
| 9733 f() { | |
| 9734 List<int> a; | |
| 9735 a[0]; | |
| 9736 List<List<int>> b; | |
| 9737 b[0][0]; | |
| 9738 List<List<List<int>>> c; | |
| 9739 c[0][0][0]; | |
| 9740 }'''); | |
| 9741 computeLibrarySourceErrors(source); | |
| 9742 assertNoErrors(source); | |
| 9743 verify([source]); | |
| 9744 } | |
| 9745 | |
| 9746 void test_indexExpression_typeParameters_invalidAssignmentWarning() { | |
| 9747 Source source = addSource(r''' | |
| 9748 f() { | |
| 9749 List<List<int>> b; | |
| 9750 b[0][0] = 'hi'; | |
| 9751 }'''); | |
| 9752 computeLibrarySourceErrors(source); | |
| 9753 assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]); | |
| 9754 verify([source]); | |
| 9755 } | |
| 9756 | |
| 9757 void test_indirectOperatorThroughCall() { | |
| 9758 Source source = addSource(r''' | |
| 9759 class A { | |
| 9760 B call() { return new B(); } | |
| 9761 } | |
| 9762 | |
| 9763 class B { | |
| 9764 int operator [](int i) { return i; } | |
| 9765 } | |
| 9766 | |
| 9767 A f = new A(); | |
| 9768 | |
| 9769 g(int x) {} | |
| 9770 | |
| 9771 main() { | |
| 9772 g(f()[0]); | |
| 9773 }'''); | |
| 9774 computeLibrarySourceErrors(source); | |
| 9775 assertNoErrors(source); | |
| 9776 verify([source]); | |
| 9777 } | |
| 9778 | |
| 9779 void test_invoke_dynamicThroughGetter() { | |
| 9780 Source source = addSource(r''' | |
| 9781 class A { | |
| 9782 List get X => [() => 0]; | |
| 9783 m(A a) { | |
| 9784 X.last; | |
| 9785 } | |
| 9786 }'''); | |
| 9787 computeLibrarySourceErrors(source); | |
| 9788 assertNoErrors(source); | |
| 9789 verify([source]); | |
| 9790 } | |
| 9791 | |
| 9792 void test_isValidMixin_badSuperclass() { | |
| 9793 Source source = addSource(r''' | |
| 9794 class A extends B {} | |
| 9795 class B {} | |
| 9796 class C = Object with A;'''); | |
| 9797 LibraryElement library = resolve2(source); | |
| 9798 expect(library, isNotNull); | |
| 9799 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9800 expect(unit, isNotNull); | |
| 9801 ClassElement a = unit.getType('A'); | |
| 9802 expect(a.isValidMixin, isFalse); | |
| 9803 assertErrors(source, [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]); | |
| 9804 verify([source]); | |
| 9805 } | |
| 9806 | |
| 9807 void test_isValidMixin_badSuperclass_withSuperMixins() { | |
| 9808 resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true); | |
| 9809 Source source = addSource(r''' | |
| 9810 class A extends B {} | |
| 9811 class B {} | |
| 9812 class C = Object with A;'''); | |
| 9813 LibraryElement library = resolve2(source); | |
| 9814 expect(library, isNotNull); | |
| 9815 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9816 expect(unit, isNotNull); | |
| 9817 ClassElement a = unit.getType('A'); | |
| 9818 expect(a.isValidMixin, isTrue); | |
| 9819 assertNoErrors(source); | |
| 9820 verify([source]); | |
| 9821 } | |
| 9822 | |
| 9823 void test_isValidMixin_constructor() { | |
| 9824 Source source = addSource(r''' | |
| 9825 class A { | |
| 9826 A() {} | |
| 9827 } | |
| 9828 class C = Object with A;'''); | |
| 9829 LibraryElement library = resolve2(source); | |
| 9830 expect(library, isNotNull); | |
| 9831 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9832 expect(unit, isNotNull); | |
| 9833 ClassElement a = unit.getType('A'); | |
| 9834 expect(a.isValidMixin, isFalse); | |
| 9835 assertErrors(source, [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]); | |
| 9836 verify([source]); | |
| 9837 } | |
| 9838 | |
| 9839 void test_isValidMixin_constructor_withSuperMixins() { | |
| 9840 resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true); | |
| 9841 Source source = addSource(r''' | |
| 9842 class A { | |
| 9843 A() {} | |
| 9844 } | |
| 9845 class C = Object with A;'''); | |
| 9846 LibraryElement library = resolve2(source); | |
| 9847 expect(library, isNotNull); | |
| 9848 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9849 expect(unit, isNotNull); | |
| 9850 ClassElement a = unit.getType('A'); | |
| 9851 expect(a.isValidMixin, isFalse); | |
| 9852 assertErrors(source, [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]); | |
| 9853 verify([source]); | |
| 9854 } | |
| 9855 | |
| 9856 void test_isValidMixin_factoryConstructor() { | |
| 9857 Source source = addSource(r''' | |
| 9858 class A { | |
| 9859 factory A() => null; | |
| 9860 } | |
| 9861 class C = Object with A;'''); | |
| 9862 LibraryElement library = resolve2(source); | |
| 9863 expect(library, isNotNull); | |
| 9864 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9865 expect(unit, isNotNull); | |
| 9866 ClassElement a = unit.getType('A'); | |
| 9867 expect(a.isValidMixin, isTrue); | |
| 9868 assertNoErrors(source); | |
| 9869 verify([source]); | |
| 9870 } | |
| 9871 | |
| 9872 void test_isValidMixin_factoryConstructor_withSuperMixins() { | |
| 9873 resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true); | |
| 9874 Source source = addSource(r''' | |
| 9875 class A { | |
| 9876 factory A() => null; | |
| 9877 } | |
| 9878 class C = Object with A;'''); | |
| 9879 LibraryElement library = resolve2(source); | |
| 9880 expect(library, isNotNull); | |
| 9881 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9882 expect(unit, isNotNull); | |
| 9883 ClassElement a = unit.getType('A'); | |
| 9884 expect(a.isValidMixin, isTrue); | |
| 9885 assertNoErrors(source); | |
| 9886 verify([source]); | |
| 9887 } | |
| 9888 | |
| 9889 void test_isValidMixin_super() { | |
| 9890 Source source = addSource(r''' | |
| 9891 class A { | |
| 9892 toString() { | |
| 9893 return super.toString(); | |
| 9894 } | |
| 9895 } | |
| 9896 class C = Object with A;'''); | |
| 9897 LibraryElement library = resolve2(source); | |
| 9898 expect(library, isNotNull); | |
| 9899 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9900 expect(unit, isNotNull); | |
| 9901 ClassElement a = unit.getType('A'); | |
| 9902 expect(a.isValidMixin, isFalse); | |
| 9903 assertErrors(source, [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]); | |
| 9904 verify([source]); | |
| 9905 } | |
| 9906 | |
| 9907 void test_isValidMixin_super_withSuperMixins() { | |
| 9908 resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true); | |
| 9909 Source source = addSource(r''' | |
| 9910 class A { | |
| 9911 toString() { | |
| 9912 return super.toString(); | |
| 9913 } | |
| 9914 } | |
| 9915 class C = Object with A;'''); | |
| 9916 LibraryElement library = resolve2(source); | |
| 9917 expect(library, isNotNull); | |
| 9918 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9919 expect(unit, isNotNull); | |
| 9920 ClassElement a = unit.getType('A'); | |
| 9921 expect(a.isValidMixin, isTrue); | |
| 9922 assertNoErrors(source); | |
| 9923 verify([source]); | |
| 9924 } | |
| 9925 | |
| 9926 void test_isValidMixin_valid() { | |
| 9927 Source source = addSource(''' | |
| 9928 class A {} | |
| 9929 class C = Object with A;'''); | |
| 9930 LibraryElement library = resolve2(source); | |
| 9931 expect(library, isNotNull); | |
| 9932 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9933 expect(unit, isNotNull); | |
| 9934 ClassElement a = unit.getType('A'); | |
| 9935 expect(a.isValidMixin, isTrue); | |
| 9936 assertNoErrors(source); | |
| 9937 verify([source]); | |
| 9938 } | |
| 9939 | |
| 9940 void test_isValidMixin_valid_withSuperMixins() { | |
| 9941 resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true); | |
| 9942 Source source = addSource(''' | |
| 9943 class A {} | |
| 9944 class C = Object with A;'''); | |
| 9945 LibraryElement library = resolve2(source); | |
| 9946 expect(library, isNotNull); | |
| 9947 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 9948 expect(unit, isNotNull); | |
| 9949 ClassElement a = unit.getType('A'); | |
| 9950 expect(a.isValidMixin, isTrue); | |
| 9951 assertNoErrors(source); | |
| 9952 verify([source]); | |
| 9953 } | |
| 9954 | |
| 9955 void test_labels_switch() { | |
| 9956 Source source = addSource(r''' | |
| 9957 void doSwitch(int target) { | |
| 9958 switch (target) { | |
| 9959 l0: case 0: | |
| 9960 continue l1; | |
| 9961 l1: case 1: | |
| 9962 continue l0; | |
| 9963 default: | |
| 9964 continue l1; | |
| 9965 } | |
| 9966 }'''); | |
| 9967 LibraryElement library = resolve2(source); | |
| 9968 expect(library, isNotNull); | |
| 9969 assertNoErrors(source); | |
| 9970 verify([source]); | |
| 9971 } | |
| 9972 | |
| 9973 void test_localVariable_types_invoked() { | |
| 9974 Source source = addSource(r''' | |
| 9975 const A = null; | |
| 9976 main() { | |
| 9977 var myVar = (int p) => 'foo'; | |
| 9978 myVar(42); | |
| 9979 }'''); | |
| 9980 LibraryElement library = resolve2(source); | |
| 9981 expect(library, isNotNull); | |
| 9982 CompilationUnit unit = | |
| 9983 analysisContext.resolveCompilationUnit(source, library); | |
| 9984 expect(unit, isNotNull); | |
| 9985 List<bool> found = [false]; | |
| 9986 List<CaughtException> thrownException = new List<CaughtException>(1); | |
| 9987 unit.accept(new _SimpleResolverTest_localVariable_types_invoked( | |
| 9988 this, found, thrownException)); | |
| 9989 if (thrownException[0] != null) { | |
| 9990 throw new AnalysisException( | |
| 9991 "Exception", new CaughtException(thrownException[0], null)); | |
| 9992 } | |
| 9993 expect(found[0], isTrue); | |
| 9994 } | |
| 9995 | |
| 9996 void test_metadata_class() { | |
| 9997 Source source = addSource(r''' | |
| 9998 const A = null; | |
| 9999 @A class C<A> {}'''); | |
| 10000 LibraryElement library = resolve2(source); | |
| 10001 expect(library, isNotNull); | |
| 10002 CompilationUnitElement unitElement = library.definingCompilationUnit; | |
| 10003 expect(unitElement, isNotNull); | |
| 10004 List<ClassElement> classes = unitElement.types; | |
| 10005 expect(classes, hasLength(1)); | |
| 10006 List<ElementAnnotation> annotations = classes[0].metadata; | |
| 10007 expect(annotations, hasLength(1)); | |
| 10008 assertNoErrors(source); | |
| 10009 verify([source]); | |
| 10010 CompilationUnit unit = resolveCompilationUnit(source, library); | |
| 10011 NodeList<CompilationUnitMember> declarations = unit.declarations; | |
| 10012 expect(declarations, hasLength(2)); | |
| 10013 Element expectedElement = (declarations[0] as TopLevelVariableDeclaration) | |
| 10014 .variables | |
| 10015 .variables[0] | |
| 10016 .name | |
| 10017 .staticElement; | |
| 10018 EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement, | |
| 10019 PropertyInducingElement, expectedElement); | |
| 10020 expectedElement = (expectedElement as PropertyInducingElement).getter; | |
| 10021 Element actualElement = | |
| 10022 (declarations[1] as ClassDeclaration).metadata[0].name.staticElement; | |
| 10023 expect(actualElement, same(expectedElement)); | |
| 10024 } | |
| 10025 | |
| 10026 void test_metadata_field() { | |
| 10027 Source source = addSource(r''' | |
| 10028 const A = null; | |
| 10029 class C { | |
| 10030 @A int f; | |
| 10031 }'''); | |
| 10032 LibraryElement library = resolve2(source); | |
| 10033 expect(library, isNotNull); | |
| 10034 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 10035 expect(unit, isNotNull); | |
| 10036 List<ClassElement> classes = unit.types; | |
| 10037 expect(classes, hasLength(1)); | |
| 10038 FieldElement field = classes[0].fields[0]; | |
| 10039 List<ElementAnnotation> annotations = field.metadata; | |
| 10040 expect(annotations, hasLength(1)); | |
| 10041 assertNoErrors(source); | |
| 10042 verify([source]); | |
| 10043 } | |
| 10044 | |
| 10045 void test_metadata_fieldFormalParameter() { | |
| 10046 Source source = addSource(r''' | |
| 10047 const A = null; | |
| 10048 class C { | |
| 10049 int f; | |
| 10050 C(@A this.f); | |
| 10051 }'''); | |
| 10052 LibraryElement library = resolve2(source); | |
| 10053 expect(library, isNotNull); | |
| 10054 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 10055 expect(unit, isNotNull); | |
| 10056 List<ClassElement> classes = unit.types; | |
| 10057 expect(classes, hasLength(1)); | |
| 10058 List<ConstructorElement> constructors = classes[0].constructors; | |
| 10059 expect(constructors, hasLength(1)); | |
| 10060 List<ParameterElement> parameters = constructors[0].parameters; | |
| 10061 expect(parameters, hasLength(1)); | |
| 10062 List<ElementAnnotation> annotations = parameters[0].metadata; | |
| 10063 expect(annotations, hasLength(1)); | |
| 10064 assertNoErrors(source); | |
| 10065 verify([source]); | |
| 10066 } | |
| 10067 | |
| 10068 void test_metadata_function() { | |
| 10069 Source source = addSource(r''' | |
| 10070 const A = null; | |
| 10071 @A f() {}'''); | |
| 10072 LibraryElement library = resolve2(source); | |
| 10073 expect(library, isNotNull); | |
| 10074 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 10075 expect(unit, isNotNull); | |
| 10076 List<FunctionElement> functions = unit.functions; | |
| 10077 expect(functions, hasLength(1)); | |
| 10078 List<ElementAnnotation> annotations = functions[0].metadata; | |
| 10079 expect(annotations, hasLength(1)); | |
| 10080 assertNoErrors(source); | |
| 10081 verify([source]); | |
| 10082 } | |
| 10083 | |
| 10084 void test_metadata_functionTypedParameter() { | |
| 10085 Source source = addSource(r''' | |
| 10086 const A = null; | |
| 10087 f(@A int p(int x)) {}'''); | |
| 10088 LibraryElement library = resolve2(source); | |
| 10089 expect(library, isNotNull); | |
| 10090 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 10091 expect(unit, isNotNull); | |
| 10092 List<FunctionElement> functions = unit.functions; | |
| 10093 expect(functions, hasLength(1)); | |
| 10094 List<ParameterElement> parameters = functions[0].parameters; | |
| 10095 expect(parameters, hasLength(1)); | |
| 10096 List<ElementAnnotation> annotations1 = parameters[0].metadata; | |
| 10097 expect(annotations1, hasLength(1)); | |
| 10098 assertNoErrors(source); | |
| 10099 verify([source]); | |
| 10100 } | |
| 10101 | |
| 10102 void test_metadata_libraryDirective() { | |
| 10103 Source source = addSource(r''' | |
| 10104 @A library lib; | |
| 10105 const A = null;'''); | |
| 10106 LibraryElement library = resolve2(source); | |
| 10107 expect(library, isNotNull); | |
| 10108 List<ElementAnnotation> annotations = library.metadata; | |
| 10109 expect(annotations, hasLength(1)); | |
| 10110 assertNoErrors(source); | |
| 10111 verify([source]); | |
| 10112 } | |
| 10113 | |
| 10114 void test_metadata_method() { | |
| 10115 Source source = addSource(r''' | |
| 10116 const A = null; | |
| 10117 class C { | |
| 10118 @A void m() {} | |
| 10119 }'''); | |
| 10120 LibraryElement library = resolve2(source); | |
| 10121 expect(library, isNotNull); | |
| 10122 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 10123 expect(unit, isNotNull); | |
| 10124 List<ClassElement> classes = unit.types; | |
| 10125 expect(classes, hasLength(1)); | |
| 10126 MethodElement method = classes[0].methods[0]; | |
| 10127 List<ElementAnnotation> annotations = method.metadata; | |
| 10128 expect(annotations, hasLength(1)); | |
| 10129 assertNoErrors(source); | |
| 10130 verify([source]); | |
| 10131 } | |
| 10132 | |
| 10133 void test_metadata_namedParameter() { | |
| 10134 Source source = addSource(r''' | |
| 10135 const A = null; | |
| 10136 f({@A int p : 0}) {}'''); | |
| 10137 LibraryElement library = resolve2(source); | |
| 10138 expect(library, isNotNull); | |
| 10139 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 10140 expect(unit, isNotNull); | |
| 10141 List<FunctionElement> functions = unit.functions; | |
| 10142 expect(functions, hasLength(1)); | |
| 10143 List<ParameterElement> parameters = functions[0].parameters; | |
| 10144 expect(parameters, hasLength(1)); | |
| 10145 List<ElementAnnotation> annotations1 = parameters[0].metadata; | |
| 10146 expect(annotations1, hasLength(1)); | |
| 10147 assertNoErrors(source); | |
| 10148 verify([source]); | |
| 10149 } | |
| 10150 | |
| 10151 void test_metadata_positionalParameter() { | |
| 10152 Source source = addSource(r''' | |
| 10153 const A = null; | |
| 10154 f([@A int p = 0]) {}'''); | |
| 10155 LibraryElement library = resolve2(source); | |
| 10156 expect(library, isNotNull); | |
| 10157 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 10158 expect(unit, isNotNull); | |
| 10159 List<FunctionElement> functions = unit.functions; | |
| 10160 expect(functions, hasLength(1)); | |
| 10161 List<ParameterElement> parameters = functions[0].parameters; | |
| 10162 expect(parameters, hasLength(1)); | |
| 10163 List<ElementAnnotation> annotations1 = parameters[0].metadata; | |
| 10164 expect(annotations1, hasLength(1)); | |
| 10165 assertNoErrors(source); | |
| 10166 verify([source]); | |
| 10167 } | |
| 10168 | |
| 10169 void test_metadata_simpleParameter() { | |
| 10170 Source source = addSource(r''' | |
| 10171 const A = null; | |
| 10172 f(@A p1, @A int p2) {}'''); | |
| 10173 LibraryElement library = resolve2(source); | |
| 10174 expect(library, isNotNull); | |
| 10175 CompilationUnitElement unit = library.definingCompilationUnit; | |
| 10176 expect(unit, isNotNull); | |
| 10177 List<FunctionElement> functions = unit.functions; | |
| 10178 expect(functions, hasLength(1)); | |
| 10179 List<ParameterElement> parameters = functions[0].parameters; | |
| 10180 expect(parameters, hasLength(2)); | |
| 10181 List<ElementAnnotation> annotations1 = parameters[0].metadata; | |
| 10182 expect(annotations1, hasLength(1)); | |
| 10183 List<ElementAnnotation> annotations2 = parameters[1].metadata; | |
| 10184 expect(annotations2, hasLength(1)); | |
| 10185 assertNoErrors(source); | |
| 10186 verify([source]); | |
| 10187 } | |
| 10188 | |
| 10189 void test_metadata_typedef() { | |
| 10190 Source source = addSource(r''' | |
| 10191 const A = null; | |
| 10192 @A typedef F<A>();'''); | |
| 10193 LibraryElement library = resolve2(source); | |
| 10194 expect(library, isNotNull); | |
| 10195 CompilationUnitElement unitElement = library.definingCompilationUnit; | |
| 10196 expect(unitElement, isNotNull); | |
| 10197 List<FunctionTypeAliasElement> aliases = unitElement.functionTypeAliases; | |
| 10198 expect(aliases, hasLength(1)); | |
| 10199 List<ElementAnnotation> annotations = aliases[0].metadata; | |
| 10200 expect(annotations, hasLength(1)); | |
| 10201 assertNoErrors(source); | |
| 10202 verify([source]); | |
| 10203 CompilationUnit unit = resolveCompilationUnit(source, library); | |
| 10204 NodeList<CompilationUnitMember> declarations = unit.declarations; | |
| 10205 expect(declarations, hasLength(2)); | |
| 10206 Element expectedElement = (declarations[0] as TopLevelVariableDeclaration) | |
| 10207 .variables | |
| 10208 .variables[0] | |
| 10209 .name | |
| 10210 .staticElement; | |
| 10211 EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement, | |
| 10212 PropertyInducingElement, expectedElement); | |
| 10213 expectedElement = (expectedElement as PropertyInducingElement).getter; | |
| 10214 Element actualElement = | |
| 10215 (declarations[1] as FunctionTypeAlias).metadata[0].name.staticElement; | |
| 10216 expect(actualElement, same(expectedElement)); | |
| 10217 } | |
| 10218 | |
| 10219 void test_method_fromMixin() { | |
| 10220 Source source = addSource(r''' | |
| 10221 class B { | |
| 10222 bar() => 1; | |
| 10223 } | |
| 10224 class A { | |
| 10225 foo() => 2; | |
| 10226 } | |
| 10227 | |
| 10228 class C extends B with A { | |
| 10229 bar() => super.bar(); | |
| 10230 foo() => super.foo(); | |
| 10231 }'''); | |
| 10232 computeLibrarySourceErrors(source); | |
| 10233 assertNoErrors(source); | |
| 10234 verify([source]); | |
| 10235 } | |
| 10236 | |
| 10237 void test_method_fromMixins() { | |
| 10238 Source source = addSource(''' | |
| 10239 class B {} | |
| 10240 class M1 { | |
| 10241 void f() {} | |
| 10242 } | |
| 10243 class M2 { | |
| 10244 void f() {} | |
| 10245 } | |
| 10246 class C extends B with M1, M2 {} | |
| 10247 void main() { | |
| 10248 new C().f(); | |
| 10249 } | |
| 10250 '''); | |
| 10251 LibraryElement library = resolve2(source); | |
| 10252 assertNoErrors(source); | |
| 10253 verify([source]); | |
| 10254 // Verify that the "f" in "new C().f()" refers to the "f" defined in M2. | |
| 10255 FunctionDeclaration main = | |
| 10256 library.definingCompilationUnit.functions[0].computeNode(); | |
| 10257 BlockFunctionBody body = main.functionExpression.body; | |
| 10258 ExpressionStatement stmt = body.block.statements[0]; | |
| 10259 MethodInvocation expr = stmt.expression; | |
| 10260 expect(expr.methodName.staticElement.enclosingElement.name, 'M2'); | |
| 10261 } | |
| 10262 | |
| 10263 void test_method_fromMixins_bare_identifier() { | |
| 10264 Source source = addSource(''' | |
| 10265 class B {} | |
| 10266 class M1 { | |
| 10267 void f() {} | |
| 10268 } | |
| 10269 class M2 { | |
| 10270 void f() {} | |
| 10271 } | |
| 10272 class C extends B with M1, M2 { | |
| 10273 void g() { | |
| 10274 f(); | |
| 10275 } | |
| 10276 } | |
| 10277 '''); | |
| 10278 LibraryElement library = resolve2(source); | |
| 10279 assertNoErrors(source); | |
| 10280 verify([source]); | |
| 10281 // Verify that the call to f() in C.g() refers to the method defined in M2. | |
| 10282 ClassElement classC = library.definingCompilationUnit.types[3]; | |
| 10283 MethodDeclaration g = classC.getMethod('g').computeNode(); | |
| 10284 BlockFunctionBody body = g.body; | |
| 10285 ExpressionStatement stmt = body.block.statements[0]; | |
| 10286 MethodInvocation invocation = stmt.expression; | |
| 10287 SimpleIdentifier methodName = invocation.methodName; | |
| 10288 expect(methodName.staticElement.enclosingElement.name, 'M2'); | |
| 10289 } | |
| 10290 | |
| 10291 void test_method_fromMixins_invked_from_outside_class() { | |
| 10292 Source source = addSource(''' | |
| 10293 class B {} | |
| 10294 class M1 { | |
| 10295 void f() {} | |
| 10296 } | |
| 10297 class M2 { | |
| 10298 void f() {} | |
| 10299 } | |
| 10300 class C extends B with M1, M2 {} | |
| 10301 void main() { | |
| 10302 new C().f(); | |
| 10303 } | |
| 10304 '''); | |
| 10305 LibraryElement library = resolve2(source); | |
| 10306 assertNoErrors(source); | |
| 10307 verify([source]); | |
| 10308 // Verify that the call to f() in "new C().f()" refers to the method | |
| 10309 // defined in M2. | |
| 10310 FunctionDeclaration main = | |
| 10311 library.definingCompilationUnit.functions[0].computeNode(); | |
| 10312 BlockFunctionBody body = main.functionExpression.body; | |
| 10313 ExpressionStatement stmt = body.block.statements[0]; | |
| 10314 MethodInvocation invocation = stmt.expression; | |
| 10315 expect(invocation.methodName.staticElement.enclosingElement.name, 'M2'); | |
| 10316 } | |
| 10317 | |
| 10318 void test_method_fromSuperclassMixin() { | |
| 10319 Source source = addSource(r''' | |
| 10320 class A { | |
| 10321 void m1() {} | |
| 10322 } | |
| 10323 class B extends Object with A { | |
| 10324 } | |
| 10325 class C extends B { | |
| 10326 } | |
| 10327 f(C c) { | |
| 10328 c.m1(); | |
| 10329 }'''); | |
| 10330 computeLibrarySourceErrors(source); | |
| 10331 assertNoErrors(source); | |
| 10332 verify([source]); | |
| 10333 } | |
| 10334 | |
| 10335 void test_methodCascades() { | |
| 10336 Source source = addSource(r''' | |
| 10337 class A { | |
| 10338 void m1() {} | |
| 10339 void m2() {} | |
| 10340 void m() { | |
| 10341 A a = new A(); | |
| 10342 a..m1() | |
| 10343 ..m2(); | |
| 10344 } | |
| 10345 }'''); | |
| 10346 computeLibrarySourceErrors(source); | |
| 10347 assertNoErrors(source); | |
| 10348 verify([source]); | |
| 10349 } | |
| 10350 | |
| 10351 void test_methodCascades_withSetter() { | |
| 10352 Source source = addSource(r''' | |
| 10353 class A { | |
| 10354 String name; | |
| 10355 void m1() {} | |
| 10356 void m2() {} | |
| 10357 void m() { | |
| 10358 A a = new A(); | |
| 10359 a..m1() | |
| 10360 ..name = 'name' | |
| 10361 ..m2(); | |
| 10362 } | |
| 10363 }'''); | |
| 10364 computeLibrarySourceErrors(source); | |
| 10365 // failing with error code: INVOCATION_OF_NON_FUNCTION | |
| 10366 assertNoErrors(source); | |
| 10367 verify([source]); | |
| 10368 } | |
| 10369 | |
| 10370 void test_resolveAgainstNull() { | |
| 10371 Source source = addSource(r''' | |
| 10372 f(var p) { | |
| 10373 return null == p; | |
| 10374 }'''); | |
| 10375 computeLibrarySourceErrors(source); | |
| 10376 assertNoErrors(source); | |
| 10377 } | |
| 10378 | |
| 10379 void test_setter_fromMixins_bare_identifier() { | |
| 10380 Source source = addSource(''' | |
| 10381 class B {} | |
| 10382 class M1 { | |
| 10383 set x(value) {} | |
| 10384 } | |
| 10385 class M2 { | |
| 10386 set x(value) {} | |
| 10387 } | |
| 10388 class C extends B with M1, M2 { | |
| 10389 void f() { | |
| 10390 x = 1; | |
| 10391 } | |
| 10392 } | |
| 10393 '''); | |
| 10394 LibraryElement library = resolve2(source); | |
| 10395 assertNoErrors(source); | |
| 10396 verify([source]); | |
| 10397 // Verify that the setter for "x" in C.f() refers to the setter defined in | |
| 10398 // M2. | |
| 10399 ClassElement classC = library.definingCompilationUnit.types[3]; | |
| 10400 MethodDeclaration f = classC.getMethod('f').computeNode(); | |
| 10401 BlockFunctionBody body = f.body; | |
| 10402 ExpressionStatement stmt = body.block.statements[0]; | |
| 10403 AssignmentExpression assignment = stmt.expression; | |
| 10404 SimpleIdentifier leftHandSide = assignment.leftHandSide; | |
| 10405 expect(leftHandSide.staticElement.enclosingElement.name, 'M2'); | |
| 10406 } | |
| 10407 | |
| 10408 void test_setter_fromMixins_property_access() { | |
| 10409 Source source = addSource(''' | |
| 10410 class B {} | |
| 10411 class M1 { | |
| 10412 set x(value) {} | |
| 10413 } | |
| 10414 class M2 { | |
| 10415 set x(value) {} | |
| 10416 } | |
| 10417 class C extends B with M1, M2 {} | |
| 10418 void main() { | |
| 10419 new C().x = 1; | |
| 10420 } | |
| 10421 '''); | |
| 10422 LibraryElement library = resolve2(source); | |
| 10423 assertNoErrors(source); | |
| 10424 verify([source]); | |
| 10425 // Verify that the setter for "x" in "new C().x" refers to the setter | |
| 10426 // defined in M2. | |
| 10427 FunctionDeclaration main = | |
| 10428 library.definingCompilationUnit.functions[0].computeNode(); | |
| 10429 BlockFunctionBody body = main.functionExpression.body; | |
| 10430 ExpressionStatement stmt = body.block.statements[0]; | |
| 10431 AssignmentExpression assignment = stmt.expression; | |
| 10432 PropertyAccess propertyAccess = assignment.leftHandSide; | |
| 10433 expect( | |
| 10434 propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2'); | |
| 10435 } | |
| 10436 | |
| 10437 void test_setter_inherited() { | |
| 10438 Source source = addSource(r''' | |
| 10439 class A { | |
| 10440 int get x => 0; | |
| 10441 set x(int p) {} | |
| 10442 } | |
| 10443 class B extends A { | |
| 10444 int get x => super.x == null ? 0 : super.x; | |
| 10445 int f() => x = 1; | |
| 10446 }'''); | |
| 10447 computeLibrarySourceErrors(source); | |
| 10448 assertNoErrors(source); | |
| 10449 verify([source]); | |
| 10450 } | |
| 10451 | |
| 10452 void test_setter_static() { | |
| 10453 Source source = addSource(r''' | |
| 10454 set s(x) { | |
| 10455 } | |
| 10456 | |
| 10457 main() { | |
| 10458 s = 123; | |
| 10459 }'''); | |
| 10460 computeLibrarySourceErrors(source); | |
| 10461 assertNoErrors(source); | |
| 10462 verify([source]); | |
| 10463 } | |
| 10464 | |
| 10465 /** | |
| 10466 * Resolve the given source and verify that the arguments in a specific method
invocation were | |
| 10467 * correctly resolved. | |
| 10468 * | |
| 10469 * The source is expected to be source for a compilation unit, the first decla
ration is expected | |
| 10470 * to be a class, the first member of which is expected to be a method with a
block body, and the | |
| 10471 * first statement in the body is expected to be an expression statement whose
expression is a | |
| 10472 * method invocation. It is the arguments to that method invocation that are t
ested. The method | |
| 10473 * invocation can contain errors. | |
| 10474 * | |
| 10475 * The arguments were resolved correctly if the number of expressions in the l
ist matches the | |
| 10476 * length of the array of indices and if, for each index in the array of indic
es, the parameter to | |
| 10477 * which the argument expression was resolved is the parameter in the invoked
method's list of | |
| 10478 * parameters at that index. Arguments that should not be resolved to a parame
ter because of an | |
| 10479 * error can be denoted by including a negative index in the array of indices. | |
| 10480 * | |
| 10481 * @param source the source to be resolved | |
| 10482 * @param indices the array of indices used to associate arguments with parame
ters | |
| 10483 * @throws Exception if the source could not be resolved or if the structure o
f the source is not | |
| 10484 * valid | |
| 10485 */ | |
| 10486 void _validateArgumentResolution(Source source, List<int> indices) { | |
| 10487 LibraryElement library = resolve2(source); | |
| 10488 expect(library, isNotNull); | |
| 10489 ClassElement classElement = library.definingCompilationUnit.types[0]; | |
| 10490 List<ParameterElement> parameters = classElement.methods[1].parameters; | |
| 10491 CompilationUnit unit = resolveCompilationUnit(source, library); | |
| 10492 expect(unit, isNotNull); | |
| 10493 ClassDeclaration classDeclaration = | |
| 10494 unit.declarations[0] as ClassDeclaration; | |
| 10495 MethodDeclaration methodDeclaration = | |
| 10496 classDeclaration.members[0] as MethodDeclaration; | |
| 10497 Block block = (methodDeclaration.body as BlockFunctionBody).block; | |
| 10498 ExpressionStatement statement = block.statements[0] as ExpressionStatement; | |
| 10499 MethodInvocation invocation = statement.expression as MethodInvocation; | |
| 10500 NodeList<Expression> arguments = invocation.argumentList.arguments; | |
| 10501 int argumentCount = arguments.length; | |
| 10502 expect(argumentCount, indices.length); | |
| 10503 for (int i = 0; i < argumentCount; i++) { | |
| 10504 Expression argument = arguments[i]; | |
| 10505 ParameterElement element = argument.staticParameterElement; | |
| 10506 int index = indices[i]; | |
| 10507 if (index < 0) { | |
| 10508 expect(element, isNull); | |
| 10509 } else { | |
| 10510 expect(element, same(parameters[index])); | |
| 10511 } | |
| 10512 } | |
| 10513 } | |
| 10514 } | |
| 10515 | |
| 10516 class SourceContainer_ChangeSetTest_test_toString implements SourceContainer { | 671 class SourceContainer_ChangeSetTest_test_toString implements SourceContainer { |
| 10517 @override | 672 @override |
| 10518 bool contains(Source source) => false; | 673 bool contains(Source source) => false; |
| 10519 } | 674 } |
| 10520 | 675 |
| 10521 /** | 676 /** |
| 10522 * Like [StaticTypeAnalyzerTest], but as end-to-end tests. | |
| 10523 */ | |
| 10524 @reflectiveTest | |
| 10525 class StaticTypeAnalyzer2Test extends _StaticTypeAnalyzer2TestShared { | |
| 10526 void test_FunctionExpressionInvocation_block() { | |
| 10527 String code = r''' | |
| 10528 main() { | |
| 10529 var foo = (() { return 1; })(); | |
| 10530 } | |
| 10531 '''; | |
| 10532 _resolveTestUnit(code); | |
| 10533 _expectInitializerType('foo', 'dynamic', isNull); | |
| 10534 } | |
| 10535 | |
| 10536 void test_FunctionExpressionInvocation_curried() { | |
| 10537 String code = r''' | |
| 10538 typedef int F(); | |
| 10539 F f() => null; | |
| 10540 main() { | |
| 10541 var foo = f()(); | |
| 10542 } | |
| 10543 '''; | |
| 10544 _resolveTestUnit(code); | |
| 10545 _expectInitializerType('foo', 'int', isNull); | |
| 10546 } | |
| 10547 | |
| 10548 void test_FunctionExpressionInvocation_expression() { | |
| 10549 String code = r''' | |
| 10550 main() { | |
| 10551 var foo = (() => 1)(); | |
| 10552 } | |
| 10553 '''; | |
| 10554 _resolveTestUnit(code); | |
| 10555 _expectInitializerType('foo', 'int', isNull); | |
| 10556 } | |
| 10557 | |
| 10558 void test_MethodInvocation_nameType_localVariable() { | |
| 10559 String code = r""" | |
| 10560 typedef Foo(); | |
| 10561 main() { | |
| 10562 Foo foo; | |
| 10563 foo(); | |
| 10564 } | |
| 10565 """; | |
| 10566 _resolveTestUnit(code); | |
| 10567 // "foo" should be resolved to the "Foo" type | |
| 10568 _expectIdentifierType("foo();", new isInstanceOf<FunctionType>()); | |
| 10569 } | |
| 10570 | |
| 10571 void test_MethodInvocation_nameType_parameter_FunctionTypeAlias() { | |
| 10572 String code = r""" | |
| 10573 typedef Foo(); | |
| 10574 main(Foo foo) { | |
| 10575 foo(); | |
| 10576 } | |
| 10577 """; | |
| 10578 _resolveTestUnit(code); | |
| 10579 // "foo" should be resolved to the "Foo" type | |
| 10580 _expectIdentifierType("foo();", new isInstanceOf<FunctionType>()); | |
| 10581 } | |
| 10582 | |
| 10583 void test_MethodInvocation_nameType_parameter_propagatedType() { | |
| 10584 String code = r""" | |
| 10585 typedef Foo(); | |
| 10586 main(p) { | |
| 10587 if (p is Foo) { | |
| 10588 p(); | |
| 10589 } | |
| 10590 } | |
| 10591 """; | |
| 10592 _resolveTestUnit(code); | |
| 10593 _expectIdentifierType("p()", DynamicTypeImpl.instance, | |
| 10594 predicate((type) => type.name == 'Foo')); | |
| 10595 } | |
| 10596 | |
| 10597 void test_staticMethods_classTypeParameters() { | |
| 10598 String code = r''' | |
| 10599 class C<T> { | |
| 10600 static void m() => null; | |
| 10601 } | |
| 10602 main() { | |
| 10603 print(C.m); | |
| 10604 } | |
| 10605 '''; | |
| 10606 _resolveTestUnit(code); | |
| 10607 _expectFunctionType('m);', '() → void'); | |
| 10608 } | |
| 10609 | |
| 10610 void test_staticMethods_classTypeParameters_genericMethod() { | |
| 10611 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); | |
| 10612 options.enableGenericMethods = true; | |
| 10613 resetWithOptions(options); | |
| 10614 String code = r''' | |
| 10615 class C<T> { | |
| 10616 static void m<S>(S s) { | |
| 10617 void f<U>(S s, U u) {} | |
| 10618 print(f); | |
| 10619 } | |
| 10620 } | |
| 10621 main() { | |
| 10622 print(C.m); | |
| 10623 } | |
| 10624 '''; | |
| 10625 _resolveTestUnit(code); | |
| 10626 // C - m | |
| 10627 TypeParameterType typeS; | |
| 10628 { | |
| 10629 _expectFunctionType('m);', '<S>(S) → void', | |
| 10630 elementTypeParams: '[S]', typeFormals: '[S]'); | |
| 10631 | |
| 10632 FunctionTypeImpl type = _findIdentifier('m);').staticType; | |
| 10633 typeS = type.typeFormals[0].type; | |
| 10634 type = type.instantiate([DynamicTypeImpl.instance]); | |
| 10635 expect(type.toString(), '(dynamic) → void'); | |
| 10636 expect(type.typeParameters.toString(), '[S]'); | |
| 10637 expect(type.typeArguments, [DynamicTypeImpl.instance]); | |
| 10638 expect(type.typeFormals, isEmpty); | |
| 10639 } | |
| 10640 // C - m - f | |
| 10641 { | |
| 10642 _expectFunctionType('f);', '<U>(S, U) → void', | |
| 10643 elementTypeParams: '[U]', | |
| 10644 typeParams: '[S]', | |
| 10645 typeArgs: '[S]', | |
| 10646 typeFormals: '[U]'); | |
| 10647 | |
| 10648 FunctionTypeImpl type = _findIdentifier('f);').staticType; | |
| 10649 type = type.instantiate([DynamicTypeImpl.instance]); | |
| 10650 expect(type.toString(), '(S, dynamic) → void'); | |
| 10651 expect(type.typeParameters.toString(), '[S, U]'); | |
| 10652 expect(type.typeArguments, [typeS, DynamicTypeImpl.instance]); | |
| 10653 expect(type.typeFormals, isEmpty); | |
| 10654 } | |
| 10655 } | |
| 10656 } | |
| 10657 | |
| 10658 @reflectiveTest | |
| 10659 class StaticTypeAnalyzerTest extends EngineTestCase { | |
| 10660 /** | |
| 10661 * The error listener to which errors will be reported. | |
| 10662 */ | |
| 10663 GatheringErrorListener _listener; | |
| 10664 | |
| 10665 /** | |
| 10666 * The resolver visitor used to create the analyzer. | |
| 10667 */ | |
| 10668 ResolverVisitor _visitor; | |
| 10669 | |
| 10670 /** | |
| 10671 * The analyzer being used to analyze the test cases. | |
| 10672 */ | |
| 10673 StaticTypeAnalyzer _analyzer; | |
| 10674 | |
| 10675 /** | |
| 10676 * The type provider used to access the types. | |
| 10677 */ | |
| 10678 TestTypeProvider _typeProvider; | |
| 10679 | |
| 10680 /** | |
| 10681 * The type system used to analyze the test cases. | |
| 10682 */ | |
| 10683 TypeSystem get _typeSystem => _visitor.typeSystem; | |
| 10684 | |
| 10685 void fail_visitFunctionExpressionInvocation() { | |
| 10686 fail("Not yet tested"); | |
| 10687 _listener.assertNoErrors(); | |
| 10688 } | |
| 10689 | |
| 10690 void fail_visitMethodInvocation() { | |
| 10691 fail("Not yet tested"); | |
| 10692 _listener.assertNoErrors(); | |
| 10693 } | |
| 10694 | |
| 10695 void fail_visitSimpleIdentifier() { | |
| 10696 fail("Not yet tested"); | |
| 10697 _listener.assertNoErrors(); | |
| 10698 } | |
| 10699 | |
| 10700 @override | |
| 10701 void setUp() { | |
| 10702 super.setUp(); | |
| 10703 _listener = new GatheringErrorListener(); | |
| 10704 _analyzer = _createAnalyzer(); | |
| 10705 } | |
| 10706 | |
| 10707 void test_flatten_derived() { | |
| 10708 // class Derived<T> extends Future<T> { ... } | |
| 10709 ClassElementImpl derivedClass = | |
| 10710 ElementFactory.classElement2('Derived', ['T']); | |
| 10711 derivedClass.supertype = _typeProvider.futureType | |
| 10712 .instantiate([derivedClass.typeParameters[0].type]); | |
| 10713 InterfaceType intType = _typeProvider.intType; | |
| 10714 DartType dynamicType = _typeProvider.dynamicType; | |
| 10715 InterfaceType derivedIntType = derivedClass.type.instantiate([intType]); | |
| 10716 // flatten(Derived) = dynamic | |
| 10717 InterfaceType derivedDynamicType = | |
| 10718 derivedClass.type.instantiate([dynamicType]); | |
| 10719 expect(_flatten(derivedDynamicType), dynamicType); | |
| 10720 // flatten(Derived<int>) = int | |
| 10721 expect(_flatten(derivedIntType), intType); | |
| 10722 // flatten(Derived<Derived>) = Derived | |
| 10723 expect(_flatten(derivedClass.type.instantiate([derivedDynamicType])), | |
| 10724 derivedDynamicType); | |
| 10725 // flatten(Derived<Derived<int>>) = Derived<int> | |
| 10726 expect(_flatten(derivedClass.type.instantiate([derivedIntType])), | |
| 10727 derivedIntType); | |
| 10728 } | |
| 10729 | |
| 10730 void test_flatten_inhibit_recursion() { | |
| 10731 // class A extends B | |
| 10732 // class B extends A | |
| 10733 ClassElementImpl classA = ElementFactory.classElement2('A', []); | |
| 10734 ClassElementImpl classB = ElementFactory.classElement2('B', []); | |
| 10735 classA.supertype = classB.type; | |
| 10736 classB.supertype = classA.type; | |
| 10737 // flatten(A) = A and flatten(B) = B, since neither class contains Future | |
| 10738 // in its class hierarchy. Even though there is a loop in the class | |
| 10739 // hierarchy, flatten() should terminate. | |
| 10740 expect(_flatten(classA.type), classA.type); | |
| 10741 expect(_flatten(classB.type), classB.type); | |
| 10742 } | |
| 10743 | |
| 10744 void test_flatten_related_derived_types() { | |
| 10745 InterfaceType intType = _typeProvider.intType; | |
| 10746 InterfaceType numType = _typeProvider.numType; | |
| 10747 // class Derived<T> extends Future<T> | |
| 10748 ClassElementImpl derivedClass = | |
| 10749 ElementFactory.classElement2('Derived', ['T']); | |
| 10750 derivedClass.supertype = _typeProvider.futureType | |
| 10751 .instantiate([derivedClass.typeParameters[0].type]); | |
| 10752 InterfaceType derivedType = derivedClass.type; | |
| 10753 // class A extends Derived<int> implements Derived<num> { ... } | |
| 10754 ClassElementImpl classA = | |
| 10755 ElementFactory.classElement('A', derivedType.instantiate([intType])); | |
| 10756 classA.interfaces = <InterfaceType>[ | |
| 10757 derivedType.instantiate([numType]) | |
| 10758 ]; | |
| 10759 // class B extends Future<num> implements Future<int> { ... } | |
| 10760 ClassElementImpl classB = | |
| 10761 ElementFactory.classElement('B', derivedType.instantiate([numType])); | |
| 10762 classB.interfaces = <InterfaceType>[ | |
| 10763 derivedType.instantiate([intType]) | |
| 10764 ]; | |
| 10765 // flatten(A) = flatten(B) = int, since int is more specific than num. | |
| 10766 // The code in flatten() that inhibits infinite recursion shouldn't be | |
| 10767 // fooled by the fact that Derived appears twice in the type hierarchy. | |
| 10768 expect(_flatten(classA.type), intType); | |
| 10769 expect(_flatten(classB.type), intType); | |
| 10770 } | |
| 10771 | |
| 10772 void test_flatten_related_types() { | |
| 10773 InterfaceType futureType = _typeProvider.futureType; | |
| 10774 InterfaceType intType = _typeProvider.intType; | |
| 10775 InterfaceType numType = _typeProvider.numType; | |
| 10776 // class A extends Future<int> implements Future<num> { ... } | |
| 10777 ClassElementImpl classA = | |
| 10778 ElementFactory.classElement('A', futureType.instantiate([intType])); | |
| 10779 classA.interfaces = <InterfaceType>[ | |
| 10780 futureType.instantiate([numType]) | |
| 10781 ]; | |
| 10782 // class B extends Future<num> implements Future<int> { ... } | |
| 10783 ClassElementImpl classB = | |
| 10784 ElementFactory.classElement('B', futureType.instantiate([numType])); | |
| 10785 classB.interfaces = <InterfaceType>[ | |
| 10786 futureType.instantiate([intType]) | |
| 10787 ]; | |
| 10788 // flatten(A) = flatten(B) = int, since int is more specific than num. | |
| 10789 expect(_flatten(classA.type), intType); | |
| 10790 expect(_flatten(classB.type), intType); | |
| 10791 } | |
| 10792 | |
| 10793 void test_flatten_simple() { | |
| 10794 InterfaceType intType = _typeProvider.intType; | |
| 10795 DartType dynamicType = _typeProvider.dynamicType; | |
| 10796 InterfaceType futureDynamicType = _typeProvider.futureDynamicType; | |
| 10797 InterfaceType futureIntType = | |
| 10798 _typeProvider.futureType.instantiate([intType]); | |
| 10799 InterfaceType futureFutureDynamicType = | |
| 10800 _typeProvider.futureType.instantiate([futureDynamicType]); | |
| 10801 InterfaceType futureFutureIntType = | |
| 10802 _typeProvider.futureType.instantiate([futureIntType]); | |
| 10803 // flatten(int) = int | |
| 10804 expect(_flatten(intType), intType); | |
| 10805 // flatten(dynamic) = dynamic | |
| 10806 expect(_flatten(dynamicType), dynamicType); | |
| 10807 // flatten(Future) = dynamic | |
| 10808 expect(_flatten(futureDynamicType), dynamicType); | |
| 10809 // flatten(Future<int>) = int | |
| 10810 expect(_flatten(futureIntType), intType); | |
| 10811 // flatten(Future<Future>) = dynamic | |
| 10812 expect(_flatten(futureFutureDynamicType), dynamicType); | |
| 10813 // flatten(Future<Future<int>>) = int | |
| 10814 expect(_flatten(futureFutureIntType), intType); | |
| 10815 } | |
| 10816 | |
| 10817 void test_flatten_unrelated_types() { | |
| 10818 InterfaceType futureType = _typeProvider.futureType; | |
| 10819 InterfaceType intType = _typeProvider.intType; | |
| 10820 InterfaceType stringType = _typeProvider.stringType; | |
| 10821 // class A extends Future<int> implements Future<String> { ... } | |
| 10822 ClassElementImpl classA = | |
| 10823 ElementFactory.classElement('A', futureType.instantiate([intType])); | |
| 10824 classA.interfaces = <InterfaceType>[ | |
| 10825 futureType.instantiate([stringType]) | |
| 10826 ]; | |
| 10827 // class B extends Future<String> implements Future<int> { ... } | |
| 10828 ClassElementImpl classB = | |
| 10829 ElementFactory.classElement('B', futureType.instantiate([stringType])); | |
| 10830 classB.interfaces = <InterfaceType>[ | |
| 10831 futureType.instantiate([intType]) | |
| 10832 ]; | |
| 10833 // flatten(A) = A and flatten(B) = B, since neither string nor int is more | |
| 10834 // specific than the other. | |
| 10835 expect(_flatten(classA.type), classA.type); | |
| 10836 expect(_flatten(classB.type), classB.type); | |
| 10837 } | |
| 10838 | |
| 10839 void test_visitAdjacentStrings() { | |
| 10840 // "a" "b" | |
| 10841 Expression node = AstFactory | |
| 10842 .adjacentStrings([_resolvedString("a"), _resolvedString("b")]); | |
| 10843 expect(_analyze(node), same(_typeProvider.stringType)); | |
| 10844 _listener.assertNoErrors(); | |
| 10845 } | |
| 10846 | |
| 10847 void test_visitAsExpression() { | |
| 10848 // class A { ... this as B ... } | |
| 10849 // class B extends A {} | |
| 10850 ClassElement superclass = ElementFactory.classElement2("A"); | |
| 10851 InterfaceType superclassType = superclass.type; | |
| 10852 ClassElement subclass = ElementFactory.classElement("B", superclassType); | |
| 10853 Expression node = AstFactory.asExpression( | |
| 10854 AstFactory.thisExpression(), AstFactory.typeName(subclass)); | |
| 10855 expect(_analyze3(node, superclassType), same(subclass.type)); | |
| 10856 _listener.assertNoErrors(); | |
| 10857 } | |
| 10858 | |
| 10859 void test_visitAssignmentExpression_compound() { | |
| 10860 // i += 1 | |
| 10861 InterfaceType numType = _typeProvider.numType; | |
| 10862 SimpleIdentifier identifier = _resolvedVariable(_typeProvider.intType, "i"); | |
| 10863 AssignmentExpression node = AstFactory.assignmentExpression( | |
| 10864 identifier, TokenType.PLUS_EQ, _resolvedInteger(1)); | |
| 10865 MethodElement plusMethod = getMethod(numType, "+"); | |
| 10866 node.staticElement = plusMethod; | |
| 10867 expect(_analyze(node), same(numType)); | |
| 10868 _listener.assertNoErrors(); | |
| 10869 } | |
| 10870 | |
| 10871 void test_visitAssignmentExpression_compoundIfNull_differentTypes() { | |
| 10872 // double d; d ??= 0 | |
| 10873 Expression node = AstFactory.assignmentExpression( | |
| 10874 _resolvedVariable(_typeProvider.doubleType, 'd'), | |
| 10875 TokenType.QUESTION_QUESTION_EQ, | |
| 10876 _resolvedInteger(0)); | |
| 10877 expect(_analyze(node), same(_typeProvider.numType)); | |
| 10878 _listener.assertNoErrors(); | |
| 10879 } | |
| 10880 | |
| 10881 void test_visitAssignmentExpression_compoundIfNull_sameTypes() { | |
| 10882 // int i; i ??= 0 | |
| 10883 Expression node = AstFactory.assignmentExpression( | |
| 10884 _resolvedVariable(_typeProvider.intType, 'i'), | |
| 10885 TokenType.QUESTION_QUESTION_EQ, | |
| 10886 _resolvedInteger(0)); | |
| 10887 expect(_analyze(node), same(_typeProvider.intType)); | |
| 10888 _listener.assertNoErrors(); | |
| 10889 } | |
| 10890 | |
| 10891 void test_visitAssignmentExpression_simple() { | |
| 10892 // i = 0 | |
| 10893 InterfaceType intType = _typeProvider.intType; | |
| 10894 Expression node = AstFactory.assignmentExpression( | |
| 10895 _resolvedVariable(intType, "i"), TokenType.EQ, _resolvedInteger(0)); | |
| 10896 expect(_analyze(node), same(intType)); | |
| 10897 _listener.assertNoErrors(); | |
| 10898 } | |
| 10899 | |
| 10900 void test_visitAwaitExpression_flattened() { | |
| 10901 // await e, where e has type Future<Future<int>> | |
| 10902 InterfaceType intType = _typeProvider.intType; | |
| 10903 InterfaceType futureIntType = | |
| 10904 _typeProvider.futureType.instantiate(<DartType>[intType]); | |
| 10905 InterfaceType futureFutureIntType = | |
| 10906 _typeProvider.futureType.instantiate(<DartType>[futureIntType]); | |
| 10907 Expression node = | |
| 10908 AstFactory.awaitExpression(_resolvedVariable(futureFutureIntType, 'e')); | |
| 10909 expect(_analyze(node), same(intType)); | |
| 10910 _listener.assertNoErrors(); | |
| 10911 } | |
| 10912 | |
| 10913 void test_visitAwaitExpression_simple() { | |
| 10914 // await e, where e has type Future<int> | |
| 10915 InterfaceType intType = _typeProvider.intType; | |
| 10916 InterfaceType futureIntType = | |
| 10917 _typeProvider.futureType.instantiate(<DartType>[intType]); | |
| 10918 Expression node = | |
| 10919 AstFactory.awaitExpression(_resolvedVariable(futureIntType, 'e')); | |
| 10920 expect(_analyze(node), same(intType)); | |
| 10921 _listener.assertNoErrors(); | |
| 10922 } | |
| 10923 | |
| 10924 void test_visitBinaryExpression_equals() { | |
| 10925 // 2 == 3 | |
| 10926 Expression node = AstFactory.binaryExpression( | |
| 10927 _resolvedInteger(2), TokenType.EQ_EQ, _resolvedInteger(3)); | |
| 10928 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 10929 _listener.assertNoErrors(); | |
| 10930 } | |
| 10931 | |
| 10932 void test_visitBinaryExpression_ifNull() { | |
| 10933 // 1 ?? 1.5 | |
| 10934 Expression node = AstFactory.binaryExpression( | |
| 10935 _resolvedInteger(1), TokenType.QUESTION_QUESTION, _resolvedDouble(1.5)); | |
| 10936 expect(_analyze(node), same(_typeProvider.numType)); | |
| 10937 _listener.assertNoErrors(); | |
| 10938 } | |
| 10939 | |
| 10940 void test_visitBinaryExpression_logicalAnd() { | |
| 10941 // false && true | |
| 10942 Expression node = AstFactory.binaryExpression( | |
| 10943 AstFactory.booleanLiteral(false), | |
| 10944 TokenType.AMPERSAND_AMPERSAND, | |
| 10945 AstFactory.booleanLiteral(true)); | |
| 10946 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 10947 _listener.assertNoErrors(); | |
| 10948 } | |
| 10949 | |
| 10950 void test_visitBinaryExpression_logicalOr() { | |
| 10951 // false || true | |
| 10952 Expression node = AstFactory.binaryExpression( | |
| 10953 AstFactory.booleanLiteral(false), | |
| 10954 TokenType.BAR_BAR, | |
| 10955 AstFactory.booleanLiteral(true)); | |
| 10956 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 10957 _listener.assertNoErrors(); | |
| 10958 } | |
| 10959 | |
| 10960 void test_visitBinaryExpression_minusID_propagated() { | |
| 10961 // a - b | |
| 10962 BinaryExpression node = AstFactory.binaryExpression( | |
| 10963 _propagatedVariable(_typeProvider.intType, 'a'), | |
| 10964 TokenType.MINUS, | |
| 10965 _propagatedVariable(_typeProvider.doubleType, 'b')); | |
| 10966 node.propagatedElement = getMethod(_typeProvider.numType, "+"); | |
| 10967 _analyze(node); | |
| 10968 expect(node.propagatedType, same(_typeProvider.doubleType)); | |
| 10969 _listener.assertNoErrors(); | |
| 10970 } | |
| 10971 | |
| 10972 void test_visitBinaryExpression_notEquals() { | |
| 10973 // 2 != 3 | |
| 10974 Expression node = AstFactory.binaryExpression( | |
| 10975 _resolvedInteger(2), TokenType.BANG_EQ, _resolvedInteger(3)); | |
| 10976 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 10977 _listener.assertNoErrors(); | |
| 10978 } | |
| 10979 | |
| 10980 void test_visitBinaryExpression_plusID() { | |
| 10981 // 1 + 2.0 | |
| 10982 BinaryExpression node = AstFactory.binaryExpression( | |
| 10983 _resolvedInteger(1), TokenType.PLUS, _resolvedDouble(2.0)); | |
| 10984 node.staticElement = getMethod(_typeProvider.numType, "+"); | |
| 10985 expect(_analyze(node), same(_typeProvider.doubleType)); | |
| 10986 _listener.assertNoErrors(); | |
| 10987 } | |
| 10988 | |
| 10989 void test_visitBinaryExpression_plusII() { | |
| 10990 // 1 + 2 | |
| 10991 BinaryExpression node = AstFactory.binaryExpression( | |
| 10992 _resolvedInteger(1), TokenType.PLUS, _resolvedInteger(2)); | |
| 10993 node.staticElement = getMethod(_typeProvider.numType, "+"); | |
| 10994 expect(_analyze(node), same(_typeProvider.intType)); | |
| 10995 _listener.assertNoErrors(); | |
| 10996 } | |
| 10997 | |
| 10998 void test_visitBinaryExpression_plusII_propagated() { | |
| 10999 // a + b | |
| 11000 BinaryExpression node = AstFactory.binaryExpression( | |
| 11001 _propagatedVariable(_typeProvider.intType, 'a'), | |
| 11002 TokenType.PLUS, | |
| 11003 _propagatedVariable(_typeProvider.intType, 'b')); | |
| 11004 node.propagatedElement = getMethod(_typeProvider.numType, "+"); | |
| 11005 _analyze(node); | |
| 11006 expect(node.propagatedType, same(_typeProvider.intType)); | |
| 11007 _listener.assertNoErrors(); | |
| 11008 } | |
| 11009 | |
| 11010 void test_visitBinaryExpression_slash() { | |
| 11011 // 2 / 2 | |
| 11012 BinaryExpression node = AstFactory.binaryExpression( | |
| 11013 _resolvedInteger(2), TokenType.SLASH, _resolvedInteger(2)); | |
| 11014 node.staticElement = getMethod(_typeProvider.numType, "/"); | |
| 11015 expect(_analyze(node), same(_typeProvider.doubleType)); | |
| 11016 _listener.assertNoErrors(); | |
| 11017 } | |
| 11018 | |
| 11019 void test_visitBinaryExpression_star_notSpecial() { | |
| 11020 // class A { | |
| 11021 // A operator *(double value); | |
| 11022 // } | |
| 11023 // (a as A) * 2.0 | |
| 11024 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
| 11025 InterfaceType typeA = classA.type; | |
| 11026 MethodElement operator = | |
| 11027 ElementFactory.methodElement("*", typeA, [_typeProvider.doubleType]); | |
| 11028 classA.methods = <MethodElement>[operator]; | |
| 11029 BinaryExpression node = AstFactory.binaryExpression( | |
| 11030 AstFactory.asExpression( | |
| 11031 AstFactory.identifier3("a"), AstFactory.typeName(classA)), | |
| 11032 TokenType.PLUS, | |
| 11033 _resolvedDouble(2.0)); | |
| 11034 node.staticElement = operator; | |
| 11035 expect(_analyze(node), same(typeA)); | |
| 11036 _listener.assertNoErrors(); | |
| 11037 } | |
| 11038 | |
| 11039 void test_visitBinaryExpression_starID() { | |
| 11040 // 1 * 2.0 | |
| 11041 BinaryExpression node = AstFactory.binaryExpression( | |
| 11042 _resolvedInteger(1), TokenType.PLUS, _resolvedDouble(2.0)); | |
| 11043 node.staticElement = getMethod(_typeProvider.numType, "*"); | |
| 11044 expect(_analyze(node), same(_typeProvider.doubleType)); | |
| 11045 _listener.assertNoErrors(); | |
| 11046 } | |
| 11047 | |
| 11048 void test_visitBooleanLiteral_false() { | |
| 11049 // false | |
| 11050 Expression node = AstFactory.booleanLiteral(false); | |
| 11051 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 11052 _listener.assertNoErrors(); | |
| 11053 } | |
| 11054 | |
| 11055 void test_visitBooleanLiteral_true() { | |
| 11056 // true | |
| 11057 Expression node = AstFactory.booleanLiteral(true); | |
| 11058 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 11059 _listener.assertNoErrors(); | |
| 11060 } | |
| 11061 | |
| 11062 void test_visitCascadeExpression() { | |
| 11063 // a..length | |
| 11064 Expression node = AstFactory.cascadeExpression( | |
| 11065 _resolvedString("a"), [AstFactory.propertyAccess2(null, "length")]); | |
| 11066 expect(_analyze(node), same(_typeProvider.stringType)); | |
| 11067 _listener.assertNoErrors(); | |
| 11068 } | |
| 11069 | |
| 11070 void test_visitConditionalExpression_differentTypes() { | |
| 11071 // true ? 1.0 : 0 | |
| 11072 Expression node = AstFactory.conditionalExpression( | |
| 11073 AstFactory.booleanLiteral(true), | |
| 11074 _resolvedDouble(1.0), | |
| 11075 _resolvedInteger(0)); | |
| 11076 expect(_analyze(node), same(_typeProvider.numType)); | |
| 11077 _listener.assertNoErrors(); | |
| 11078 } | |
| 11079 | |
| 11080 void test_visitConditionalExpression_sameTypes() { | |
| 11081 // true ? 1 : 0 | |
| 11082 Expression node = AstFactory.conditionalExpression( | |
| 11083 AstFactory.booleanLiteral(true), | |
| 11084 _resolvedInteger(1), | |
| 11085 _resolvedInteger(0)); | |
| 11086 expect(_analyze(node), same(_typeProvider.intType)); | |
| 11087 _listener.assertNoErrors(); | |
| 11088 } | |
| 11089 | |
| 11090 void test_visitDoubleLiteral() { | |
| 11091 // 4.33 | |
| 11092 Expression node = AstFactory.doubleLiteral(4.33); | |
| 11093 expect(_analyze(node), same(_typeProvider.doubleType)); | |
| 11094 _listener.assertNoErrors(); | |
| 11095 } | |
| 11096 | |
| 11097 void test_visitFunctionExpression_async_block() { | |
| 11098 // () async {} | |
| 11099 BlockFunctionBody body = AstFactory.blockFunctionBody2(); | |
| 11100 body.keyword = TokenFactory.tokenFromString('async'); | |
| 11101 FunctionExpression node = | |
| 11102 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body); | |
| 11103 DartType resultType = _analyze(node); | |
| 11104 _assertFunctionType( | |
| 11105 _typeProvider.futureDynamicType, null, null, null, resultType); | |
| 11106 _listener.assertNoErrors(); | |
| 11107 } | |
| 11108 | |
| 11109 void test_visitFunctionExpression_async_expression() { | |
| 11110 // () async => e, where e has type int | |
| 11111 InterfaceType intType = _typeProvider.intType; | |
| 11112 InterfaceType futureIntType = | |
| 11113 _typeProvider.futureType.instantiate(<DartType>[intType]); | |
| 11114 Expression expression = _resolvedVariable(intType, 'e'); | |
| 11115 ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression); | |
| 11116 body.keyword = TokenFactory.tokenFromString('async'); | |
| 11117 FunctionExpression node = | |
| 11118 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body); | |
| 11119 DartType resultType = _analyze(node); | |
| 11120 _assertFunctionType(futureIntType, null, null, null, resultType); | |
| 11121 _listener.assertNoErrors(); | |
| 11122 } | |
| 11123 | |
| 11124 void test_visitFunctionExpression_async_expression_flatten() { | |
| 11125 // () async => e, where e has type Future<int> | |
| 11126 InterfaceType intType = _typeProvider.intType; | |
| 11127 InterfaceType futureIntType = | |
| 11128 _typeProvider.futureType.instantiate(<DartType>[intType]); | |
| 11129 Expression expression = _resolvedVariable(futureIntType, 'e'); | |
| 11130 ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression); | |
| 11131 body.keyword = TokenFactory.tokenFromString('async'); | |
| 11132 FunctionExpression node = | |
| 11133 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body); | |
| 11134 DartType resultType = _analyze(node); | |
| 11135 _assertFunctionType(futureIntType, null, null, null, resultType); | |
| 11136 _listener.assertNoErrors(); | |
| 11137 } | |
| 11138 | |
| 11139 void test_visitFunctionExpression_async_expression_flatten_twice() { | |
| 11140 // () async => e, where e has type Future<Future<int>> | |
| 11141 InterfaceType intType = _typeProvider.intType; | |
| 11142 InterfaceType futureIntType = | |
| 11143 _typeProvider.futureType.instantiate(<DartType>[intType]); | |
| 11144 InterfaceType futureFutureIntType = | |
| 11145 _typeProvider.futureType.instantiate(<DartType>[futureIntType]); | |
| 11146 Expression expression = _resolvedVariable(futureFutureIntType, 'e'); | |
| 11147 ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression); | |
| 11148 body.keyword = TokenFactory.tokenFromString('async'); | |
| 11149 FunctionExpression node = | |
| 11150 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body); | |
| 11151 DartType resultType = _analyze(node); | |
| 11152 _assertFunctionType(futureIntType, null, null, null, resultType); | |
| 11153 _listener.assertNoErrors(); | |
| 11154 } | |
| 11155 | |
| 11156 void test_visitFunctionExpression_generator_async() { | |
| 11157 // () async* {} | |
| 11158 BlockFunctionBody body = AstFactory.blockFunctionBody2(); | |
| 11159 body.keyword = TokenFactory.tokenFromString('async'); | |
| 11160 body.star = TokenFactory.tokenFromType(TokenType.STAR); | |
| 11161 FunctionExpression node = | |
| 11162 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body); | |
| 11163 DartType resultType = _analyze(node); | |
| 11164 _assertFunctionType( | |
| 11165 _typeProvider.streamDynamicType, null, null, null, resultType); | |
| 11166 _listener.assertNoErrors(); | |
| 11167 } | |
| 11168 | |
| 11169 void test_visitFunctionExpression_generator_sync() { | |
| 11170 // () sync* {} | |
| 11171 BlockFunctionBody body = AstFactory.blockFunctionBody2(); | |
| 11172 body.keyword = TokenFactory.tokenFromString('sync'); | |
| 11173 body.star = TokenFactory.tokenFromType(TokenType.STAR); | |
| 11174 FunctionExpression node = | |
| 11175 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body); | |
| 11176 DartType resultType = _analyze(node); | |
| 11177 _assertFunctionType( | |
| 11178 _typeProvider.iterableDynamicType, null, null, null, resultType); | |
| 11179 _listener.assertNoErrors(); | |
| 11180 } | |
| 11181 | |
| 11182 void test_visitFunctionExpression_named_block() { | |
| 11183 // ({p1 : 0, p2 : 0}) {} | |
| 11184 DartType dynamicType = _typeProvider.dynamicType; | |
| 11185 FormalParameter p1 = AstFactory.namedFormalParameter( | |
| 11186 AstFactory.simpleFormalParameter3("p1"), _resolvedInteger(0)); | |
| 11187 _setType(p1, dynamicType); | |
| 11188 FormalParameter p2 = AstFactory.namedFormalParameter( | |
| 11189 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0)); | |
| 11190 _setType(p2, dynamicType); | |
| 11191 FunctionExpression node = _resolvedFunctionExpression( | |
| 11192 AstFactory.formalParameterList([p1, p2]), | |
| 11193 AstFactory.blockFunctionBody2()); | |
| 11194 _analyze5(p1); | |
| 11195 _analyze5(p2); | |
| 11196 DartType resultType = _analyze(node); | |
| 11197 Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>(); | |
| 11198 expectedNamedTypes["p1"] = dynamicType; | |
| 11199 expectedNamedTypes["p2"] = dynamicType; | |
| 11200 _assertFunctionType( | |
| 11201 dynamicType, null, null, expectedNamedTypes, resultType); | |
| 11202 _listener.assertNoErrors(); | |
| 11203 } | |
| 11204 | |
| 11205 void test_visitFunctionExpression_named_expression() { | |
| 11206 // ({p : 0}) -> 0; | |
| 11207 DartType dynamicType = _typeProvider.dynamicType; | |
| 11208 FormalParameter p = AstFactory.namedFormalParameter( | |
| 11209 AstFactory.simpleFormalParameter3("p"), _resolvedInteger(0)); | |
| 11210 _setType(p, dynamicType); | |
| 11211 FunctionExpression node = _resolvedFunctionExpression( | |
| 11212 AstFactory.formalParameterList([p]), | |
| 11213 AstFactory.expressionFunctionBody(_resolvedInteger(0))); | |
| 11214 _analyze5(p); | |
| 11215 DartType resultType = _analyze(node); | |
| 11216 Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>(); | |
| 11217 expectedNamedTypes["p"] = dynamicType; | |
| 11218 _assertFunctionType( | |
| 11219 _typeProvider.intType, null, null, expectedNamedTypes, resultType); | |
| 11220 _listener.assertNoErrors(); | |
| 11221 } | |
| 11222 | |
| 11223 void test_visitFunctionExpression_normal_block() { | |
| 11224 // (p1, p2) {} | |
| 11225 DartType dynamicType = _typeProvider.dynamicType; | |
| 11226 FormalParameter p1 = AstFactory.simpleFormalParameter3("p1"); | |
| 11227 _setType(p1, dynamicType); | |
| 11228 FormalParameter p2 = AstFactory.simpleFormalParameter3("p2"); | |
| 11229 _setType(p2, dynamicType); | |
| 11230 FunctionExpression node = _resolvedFunctionExpression( | |
| 11231 AstFactory.formalParameterList([p1, p2]), | |
| 11232 AstFactory.blockFunctionBody2()); | |
| 11233 _analyze5(p1); | |
| 11234 _analyze5(p2); | |
| 11235 DartType resultType = _analyze(node); | |
| 11236 _assertFunctionType(dynamicType, <DartType>[dynamicType, dynamicType], null, | |
| 11237 null, resultType); | |
| 11238 _listener.assertNoErrors(); | |
| 11239 } | |
| 11240 | |
| 11241 void test_visitFunctionExpression_normal_expression() { | |
| 11242 // (p1, p2) -> 0 | |
| 11243 DartType dynamicType = _typeProvider.dynamicType; | |
| 11244 FormalParameter p = AstFactory.simpleFormalParameter3("p"); | |
| 11245 _setType(p, dynamicType); | |
| 11246 FunctionExpression node = _resolvedFunctionExpression( | |
| 11247 AstFactory.formalParameterList([p]), | |
| 11248 AstFactory.expressionFunctionBody(_resolvedInteger(0))); | |
| 11249 _analyze5(p); | |
| 11250 DartType resultType = _analyze(node); | |
| 11251 _assertFunctionType( | |
| 11252 _typeProvider.intType, <DartType>[dynamicType], null, null, resultType); | |
| 11253 _listener.assertNoErrors(); | |
| 11254 } | |
| 11255 | |
| 11256 void test_visitFunctionExpression_normalAndNamed_block() { | |
| 11257 // (p1, {p2 : 0}) {} | |
| 11258 DartType dynamicType = _typeProvider.dynamicType; | |
| 11259 FormalParameter p1 = AstFactory.simpleFormalParameter3("p1"); | |
| 11260 _setType(p1, dynamicType); | |
| 11261 FormalParameter p2 = AstFactory.namedFormalParameter( | |
| 11262 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0)); | |
| 11263 _setType(p2, dynamicType); | |
| 11264 FunctionExpression node = _resolvedFunctionExpression( | |
| 11265 AstFactory.formalParameterList([p1, p2]), | |
| 11266 AstFactory.blockFunctionBody2()); | |
| 11267 _analyze5(p2); | |
| 11268 DartType resultType = _analyze(node); | |
| 11269 Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>(); | |
| 11270 expectedNamedTypes["p2"] = dynamicType; | |
| 11271 _assertFunctionType(dynamicType, <DartType>[dynamicType], null, | |
| 11272 expectedNamedTypes, resultType); | |
| 11273 _listener.assertNoErrors(); | |
| 11274 } | |
| 11275 | |
| 11276 void test_visitFunctionExpression_normalAndNamed_expression() { | |
| 11277 // (p1, {p2 : 0}) -> 0 | |
| 11278 DartType dynamicType = _typeProvider.dynamicType; | |
| 11279 FormalParameter p1 = AstFactory.simpleFormalParameter3("p1"); | |
| 11280 _setType(p1, dynamicType); | |
| 11281 FormalParameter p2 = AstFactory.namedFormalParameter( | |
| 11282 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0)); | |
| 11283 _setType(p2, dynamicType); | |
| 11284 FunctionExpression node = _resolvedFunctionExpression( | |
| 11285 AstFactory.formalParameterList([p1, p2]), | |
| 11286 AstFactory.expressionFunctionBody(_resolvedInteger(0))); | |
| 11287 _analyze5(p2); | |
| 11288 DartType resultType = _analyze(node); | |
| 11289 Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>(); | |
| 11290 expectedNamedTypes["p2"] = dynamicType; | |
| 11291 _assertFunctionType(_typeProvider.intType, <DartType>[dynamicType], null, | |
| 11292 expectedNamedTypes, resultType); | |
| 11293 _listener.assertNoErrors(); | |
| 11294 } | |
| 11295 | |
| 11296 void test_visitFunctionExpression_normalAndPositional_block() { | |
| 11297 // (p1, [p2 = 0]) {} | |
| 11298 DartType dynamicType = _typeProvider.dynamicType; | |
| 11299 FormalParameter p1 = AstFactory.simpleFormalParameter3("p1"); | |
| 11300 _setType(p1, dynamicType); | |
| 11301 FormalParameter p2 = AstFactory.positionalFormalParameter( | |
| 11302 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0)); | |
| 11303 _setType(p2, dynamicType); | |
| 11304 FunctionExpression node = _resolvedFunctionExpression( | |
| 11305 AstFactory.formalParameterList([p1, p2]), | |
| 11306 AstFactory.blockFunctionBody2()); | |
| 11307 _analyze5(p1); | |
| 11308 _analyze5(p2); | |
| 11309 DartType resultType = _analyze(node); | |
| 11310 _assertFunctionType(dynamicType, <DartType>[dynamicType], | |
| 11311 <DartType>[dynamicType], null, resultType); | |
| 11312 _listener.assertNoErrors(); | |
| 11313 } | |
| 11314 | |
| 11315 void test_visitFunctionExpression_normalAndPositional_expression() { | |
| 11316 // (p1, [p2 = 0]) -> 0 | |
| 11317 DartType dynamicType = _typeProvider.dynamicType; | |
| 11318 FormalParameter p1 = AstFactory.simpleFormalParameter3("p1"); | |
| 11319 _setType(p1, dynamicType); | |
| 11320 FormalParameter p2 = AstFactory.positionalFormalParameter( | |
| 11321 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0)); | |
| 11322 _setType(p2, dynamicType); | |
| 11323 FunctionExpression node = _resolvedFunctionExpression( | |
| 11324 AstFactory.formalParameterList([p1, p2]), | |
| 11325 AstFactory.expressionFunctionBody(_resolvedInteger(0))); | |
| 11326 _analyze5(p1); | |
| 11327 _analyze5(p2); | |
| 11328 DartType resultType = _analyze(node); | |
| 11329 _assertFunctionType(_typeProvider.intType, <DartType>[dynamicType], | |
| 11330 <DartType>[dynamicType], null, resultType); | |
| 11331 _listener.assertNoErrors(); | |
| 11332 } | |
| 11333 | |
| 11334 void test_visitFunctionExpression_positional_block() { | |
| 11335 // ([p1 = 0, p2 = 0]) {} | |
| 11336 DartType dynamicType = _typeProvider.dynamicType; | |
| 11337 FormalParameter p1 = AstFactory.positionalFormalParameter( | |
| 11338 AstFactory.simpleFormalParameter3("p1"), _resolvedInteger(0)); | |
| 11339 _setType(p1, dynamicType); | |
| 11340 FormalParameter p2 = AstFactory.positionalFormalParameter( | |
| 11341 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0)); | |
| 11342 _setType(p2, dynamicType); | |
| 11343 FunctionExpression node = _resolvedFunctionExpression( | |
| 11344 AstFactory.formalParameterList([p1, p2]), | |
| 11345 AstFactory.blockFunctionBody2()); | |
| 11346 _analyze5(p1); | |
| 11347 _analyze5(p2); | |
| 11348 DartType resultType = _analyze(node); | |
| 11349 _assertFunctionType(dynamicType, null, <DartType>[dynamicType, dynamicType], | |
| 11350 null, resultType); | |
| 11351 _listener.assertNoErrors(); | |
| 11352 } | |
| 11353 | |
| 11354 void test_visitFunctionExpression_positional_expression() { | |
| 11355 // ([p1 = 0, p2 = 0]) -> 0 | |
| 11356 DartType dynamicType = _typeProvider.dynamicType; | |
| 11357 FormalParameter p = AstFactory.positionalFormalParameter( | |
| 11358 AstFactory.simpleFormalParameter3("p"), _resolvedInteger(0)); | |
| 11359 _setType(p, dynamicType); | |
| 11360 FunctionExpression node = _resolvedFunctionExpression( | |
| 11361 AstFactory.formalParameterList([p]), | |
| 11362 AstFactory.expressionFunctionBody(_resolvedInteger(0))); | |
| 11363 _analyze5(p); | |
| 11364 DartType resultType = _analyze(node); | |
| 11365 _assertFunctionType( | |
| 11366 _typeProvider.intType, null, <DartType>[dynamicType], null, resultType); | |
| 11367 _listener.assertNoErrors(); | |
| 11368 } | |
| 11369 | |
| 11370 void test_visitIndexExpression_getter() { | |
| 11371 // List a; | |
| 11372 // a[2] | |
| 11373 InterfaceType listType = _typeProvider.listType; | |
| 11374 SimpleIdentifier identifier = _resolvedVariable(listType, "a"); | |
| 11375 IndexExpression node = | |
| 11376 AstFactory.indexExpression(identifier, _resolvedInteger(2)); | |
| 11377 MethodElement indexMethod = listType.element.methods[0]; | |
| 11378 node.staticElement = indexMethod; | |
| 11379 expect(_analyze(node), same(listType.typeArguments[0])); | |
| 11380 _listener.assertNoErrors(); | |
| 11381 } | |
| 11382 | |
| 11383 void test_visitIndexExpression_setter() { | |
| 11384 // List a; | |
| 11385 // a[2] = 0 | |
| 11386 InterfaceType listType = _typeProvider.listType; | |
| 11387 SimpleIdentifier identifier = _resolvedVariable(listType, "a"); | |
| 11388 IndexExpression node = | |
| 11389 AstFactory.indexExpression(identifier, _resolvedInteger(2)); | |
| 11390 MethodElement indexMethod = listType.element.methods[1]; | |
| 11391 node.staticElement = indexMethod; | |
| 11392 AstFactory.assignmentExpression(node, TokenType.EQ, AstFactory.integer(0)); | |
| 11393 expect(_analyze(node), same(listType.typeArguments[0])); | |
| 11394 _listener.assertNoErrors(); | |
| 11395 } | |
| 11396 | |
| 11397 void test_visitIndexExpression_typeParameters() { | |
| 11398 // List<int> list = ... | |
| 11399 // list[0] | |
| 11400 InterfaceType intType = _typeProvider.intType; | |
| 11401 InterfaceType listType = _typeProvider.listType; | |
| 11402 // (int) -> E | |
| 11403 MethodElement methodElement = getMethod(listType, "[]"); | |
| 11404 // "list" has type List<int> | |
| 11405 SimpleIdentifier identifier = AstFactory.identifier3("list"); | |
| 11406 InterfaceType listOfIntType = listType.instantiate(<DartType>[intType]); | |
| 11407 identifier.staticType = listOfIntType; | |
| 11408 // list[0] has MethodElement element (int) -> E | |
| 11409 IndexExpression indexExpression = | |
| 11410 AstFactory.indexExpression(identifier, AstFactory.integer(0)); | |
| 11411 MethodElement indexMethod = MethodMember.from(methodElement, listOfIntType); | |
| 11412 indexExpression.staticElement = indexMethod; | |
| 11413 // analyze and assert result of the index expression | |
| 11414 expect(_analyze(indexExpression), same(intType)); | |
| 11415 _listener.assertNoErrors(); | |
| 11416 } | |
| 11417 | |
| 11418 void test_visitIndexExpression_typeParameters_inSetterContext() { | |
| 11419 // List<int> list = ... | |
| 11420 // list[0] = 0; | |
| 11421 InterfaceType intType = _typeProvider.intType; | |
| 11422 InterfaceType listType = _typeProvider.listType; | |
| 11423 // (int, E) -> void | |
| 11424 MethodElement methodElement = getMethod(listType, "[]="); | |
| 11425 // "list" has type List<int> | |
| 11426 SimpleIdentifier identifier = AstFactory.identifier3("list"); | |
| 11427 InterfaceType listOfIntType = listType.instantiate(<DartType>[intType]); | |
| 11428 identifier.staticType = listOfIntType; | |
| 11429 // list[0] has MethodElement element (int) -> E | |
| 11430 IndexExpression indexExpression = | |
| 11431 AstFactory.indexExpression(identifier, AstFactory.integer(0)); | |
| 11432 MethodElement indexMethod = MethodMember.from(methodElement, listOfIntType); | |
| 11433 indexExpression.staticElement = indexMethod; | |
| 11434 // list[0] should be in a setter context | |
| 11435 AstFactory.assignmentExpression( | |
| 11436 indexExpression, TokenType.EQ, AstFactory.integer(0)); | |
| 11437 // analyze and assert result of the index expression | |
| 11438 expect(_analyze(indexExpression), same(intType)); | |
| 11439 _listener.assertNoErrors(); | |
| 11440 } | |
| 11441 | |
| 11442 void test_visitInstanceCreationExpression_named() { | |
| 11443 // new C.m() | |
| 11444 ClassElementImpl classElement = ElementFactory.classElement2("C"); | |
| 11445 String constructorName = "m"; | |
| 11446 ConstructorElementImpl constructor = | |
| 11447 ElementFactory.constructorElement2(classElement, constructorName); | |
| 11448 constructor.returnType = classElement.type; | |
| 11449 FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor); | |
| 11450 constructor.type = constructorType; | |
| 11451 classElement.constructors = <ConstructorElement>[constructor]; | |
| 11452 InstanceCreationExpression node = AstFactory.instanceCreationExpression2( | |
| 11453 null, | |
| 11454 AstFactory.typeName(classElement), | |
| 11455 [AstFactory.identifier3(constructorName)]); | |
| 11456 node.staticElement = constructor; | |
| 11457 expect(_analyze(node), same(classElement.type)); | |
| 11458 _listener.assertNoErrors(); | |
| 11459 } | |
| 11460 | |
| 11461 void test_visitInstanceCreationExpression_typeParameters() { | |
| 11462 // new C<I>() | |
| 11463 ClassElementImpl elementC = ElementFactory.classElement2("C", ["E"]); | |
| 11464 ClassElementImpl elementI = ElementFactory.classElement2("I"); | |
| 11465 ConstructorElementImpl constructor = | |
| 11466 ElementFactory.constructorElement2(elementC, null); | |
| 11467 elementC.constructors = <ConstructorElement>[constructor]; | |
| 11468 constructor.returnType = elementC.type; | |
| 11469 FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor); | |
| 11470 constructor.type = constructorType; | |
| 11471 TypeName typeName = | |
| 11472 AstFactory.typeName(elementC, [AstFactory.typeName(elementI)]); | |
| 11473 typeName.type = elementC.type.instantiate(<DartType>[elementI.type]); | |
| 11474 InstanceCreationExpression node = | |
| 11475 AstFactory.instanceCreationExpression2(null, typeName); | |
| 11476 node.staticElement = constructor; | |
| 11477 InterfaceType interfaceType = _analyze(node) as InterfaceType; | |
| 11478 List<DartType> typeArgs = interfaceType.typeArguments; | |
| 11479 expect(typeArgs.length, 1); | |
| 11480 expect(typeArgs[0], elementI.type); | |
| 11481 _listener.assertNoErrors(); | |
| 11482 } | |
| 11483 | |
| 11484 void test_visitInstanceCreationExpression_unnamed() { | |
| 11485 // new C() | |
| 11486 ClassElementImpl classElement = ElementFactory.classElement2("C"); | |
| 11487 ConstructorElementImpl constructor = | |
| 11488 ElementFactory.constructorElement2(classElement, null); | |
| 11489 constructor.returnType = classElement.type; | |
| 11490 FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor); | |
| 11491 constructor.type = constructorType; | |
| 11492 classElement.constructors = <ConstructorElement>[constructor]; | |
| 11493 InstanceCreationExpression node = AstFactory.instanceCreationExpression2( | |
| 11494 null, AstFactory.typeName(classElement)); | |
| 11495 node.staticElement = constructor; | |
| 11496 expect(_analyze(node), same(classElement.type)); | |
| 11497 _listener.assertNoErrors(); | |
| 11498 } | |
| 11499 | |
| 11500 void test_visitIntegerLiteral() { | |
| 11501 // 42 | |
| 11502 Expression node = _resolvedInteger(42); | |
| 11503 expect(_analyze(node), same(_typeProvider.intType)); | |
| 11504 _listener.assertNoErrors(); | |
| 11505 } | |
| 11506 | |
| 11507 void test_visitIsExpression_negated() { | |
| 11508 // a is! String | |
| 11509 Expression node = AstFactory.isExpression( | |
| 11510 _resolvedString("a"), true, AstFactory.typeName4("String")); | |
| 11511 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 11512 _listener.assertNoErrors(); | |
| 11513 } | |
| 11514 | |
| 11515 void test_visitIsExpression_notNegated() { | |
| 11516 // a is String | |
| 11517 Expression node = AstFactory.isExpression( | |
| 11518 _resolvedString("a"), false, AstFactory.typeName4("String")); | |
| 11519 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 11520 _listener.assertNoErrors(); | |
| 11521 } | |
| 11522 | |
| 11523 void test_visitListLiteral_empty() { | |
| 11524 // [] | |
| 11525 Expression node = AstFactory.listLiteral(); | |
| 11526 DartType resultType = _analyze(node); | |
| 11527 _assertType2( | |
| 11528 _typeProvider.listType | |
| 11529 .instantiate(<DartType>[_typeProvider.dynamicType]), | |
| 11530 resultType); | |
| 11531 _listener.assertNoErrors(); | |
| 11532 } | |
| 11533 | |
| 11534 void test_visitListLiteral_nonEmpty() { | |
| 11535 // [0] | |
| 11536 Expression node = AstFactory.listLiteral([_resolvedInteger(0)]); | |
| 11537 DartType resultType = _analyze(node); | |
| 11538 _assertType2( | |
| 11539 _typeProvider.listType | |
| 11540 .instantiate(<DartType>[_typeProvider.dynamicType]), | |
| 11541 resultType); | |
| 11542 _listener.assertNoErrors(); | |
| 11543 } | |
| 11544 | |
| 11545 void test_visitMapLiteral_empty() { | |
| 11546 // {} | |
| 11547 Expression node = AstFactory.mapLiteral2(); | |
| 11548 DartType resultType = _analyze(node); | |
| 11549 _assertType2( | |
| 11550 _typeProvider.mapType.instantiate( | |
| 11551 <DartType>[_typeProvider.dynamicType, _typeProvider.dynamicType]), | |
| 11552 resultType); | |
| 11553 _listener.assertNoErrors(); | |
| 11554 } | |
| 11555 | |
| 11556 void test_visitMapLiteral_nonEmpty() { | |
| 11557 // {"k" : 0} | |
| 11558 Expression node = AstFactory | |
| 11559 .mapLiteral2([AstFactory.mapLiteralEntry("k", _resolvedInteger(0))]); | |
| 11560 DartType resultType = _analyze(node); | |
| 11561 _assertType2( | |
| 11562 _typeProvider.mapType.instantiate( | |
| 11563 <DartType>[_typeProvider.dynamicType, _typeProvider.dynamicType]), | |
| 11564 resultType); | |
| 11565 _listener.assertNoErrors(); | |
| 11566 } | |
| 11567 | |
| 11568 void test_visitMethodInvocation_then() { | |
| 11569 // then() | |
| 11570 Expression node = AstFactory.methodInvocation(null, "then"); | |
| 11571 _analyze(node); | |
| 11572 _listener.assertNoErrors(); | |
| 11573 } | |
| 11574 | |
| 11575 void test_visitNamedExpression() { | |
| 11576 // n: a | |
| 11577 Expression node = AstFactory.namedExpression2("n", _resolvedString("a")); | |
| 11578 expect(_analyze(node), same(_typeProvider.stringType)); | |
| 11579 _listener.assertNoErrors(); | |
| 11580 } | |
| 11581 | |
| 11582 void test_visitNullLiteral() { | |
| 11583 // null | |
| 11584 Expression node = AstFactory.nullLiteral(); | |
| 11585 expect(_analyze(node), same(_typeProvider.bottomType)); | |
| 11586 _listener.assertNoErrors(); | |
| 11587 } | |
| 11588 | |
| 11589 void test_visitParenthesizedExpression() { | |
| 11590 // (0) | |
| 11591 Expression node = AstFactory.parenthesizedExpression(_resolvedInteger(0)); | |
| 11592 expect(_analyze(node), same(_typeProvider.intType)); | |
| 11593 _listener.assertNoErrors(); | |
| 11594 } | |
| 11595 | |
| 11596 void test_visitPostfixExpression_minusMinus() { | |
| 11597 // 0-- | |
| 11598 PostfixExpression node = AstFactory.postfixExpression( | |
| 11599 _resolvedInteger(0), TokenType.MINUS_MINUS); | |
| 11600 expect(_analyze(node), same(_typeProvider.intType)); | |
| 11601 _listener.assertNoErrors(); | |
| 11602 } | |
| 11603 | |
| 11604 void test_visitPostfixExpression_plusPlus() { | |
| 11605 // 0++ | |
| 11606 PostfixExpression node = | |
| 11607 AstFactory.postfixExpression(_resolvedInteger(0), TokenType.PLUS_PLUS); | |
| 11608 expect(_analyze(node), same(_typeProvider.intType)); | |
| 11609 _listener.assertNoErrors(); | |
| 11610 } | |
| 11611 | |
| 11612 void test_visitPrefixedIdentifier_getter() { | |
| 11613 DartType boolType = _typeProvider.boolType; | |
| 11614 PropertyAccessorElementImpl getter = | |
| 11615 ElementFactory.getterElement("b", false, boolType); | |
| 11616 PrefixedIdentifier node = AstFactory.identifier5("a", "b"); | |
| 11617 node.identifier.staticElement = getter; | |
| 11618 expect(_analyze(node), same(boolType)); | |
| 11619 _listener.assertNoErrors(); | |
| 11620 } | |
| 11621 | |
| 11622 void test_visitPrefixedIdentifier_setter() { | |
| 11623 DartType boolType = _typeProvider.boolType; | |
| 11624 FieldElementImpl field = | |
| 11625 ElementFactory.fieldElement("b", false, false, false, boolType); | |
| 11626 PropertyAccessorElement setter = field.setter; | |
| 11627 PrefixedIdentifier node = AstFactory.identifier5("a", "b"); | |
| 11628 node.identifier.staticElement = setter; | |
| 11629 expect(_analyze(node), same(boolType)); | |
| 11630 _listener.assertNoErrors(); | |
| 11631 } | |
| 11632 | |
| 11633 void test_visitPrefixedIdentifier_variable() { | |
| 11634 VariableElementImpl variable = ElementFactory.localVariableElement2("b"); | |
| 11635 variable.type = _typeProvider.boolType; | |
| 11636 PrefixedIdentifier node = AstFactory.identifier5("a", "b"); | |
| 11637 node.identifier.staticElement = variable; | |
| 11638 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 11639 _listener.assertNoErrors(); | |
| 11640 } | |
| 11641 | |
| 11642 void test_visitPrefixExpression_bang() { | |
| 11643 // !0 | |
| 11644 PrefixExpression node = | |
| 11645 AstFactory.prefixExpression(TokenType.BANG, _resolvedInteger(0)); | |
| 11646 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 11647 _listener.assertNoErrors(); | |
| 11648 } | |
| 11649 | |
| 11650 void test_visitPrefixExpression_minus() { | |
| 11651 // -0 | |
| 11652 PrefixExpression node = | |
| 11653 AstFactory.prefixExpression(TokenType.MINUS, _resolvedInteger(0)); | |
| 11654 MethodElement minusMethod = getMethod(_typeProvider.numType, "-"); | |
| 11655 node.staticElement = minusMethod; | |
| 11656 expect(_analyze(node), same(_typeProvider.numType)); | |
| 11657 _listener.assertNoErrors(); | |
| 11658 } | |
| 11659 | |
| 11660 void test_visitPrefixExpression_minusMinus() { | |
| 11661 // --0 | |
| 11662 PrefixExpression node = | |
| 11663 AstFactory.prefixExpression(TokenType.MINUS_MINUS, _resolvedInteger(0)); | |
| 11664 MethodElement minusMethod = getMethod(_typeProvider.numType, "-"); | |
| 11665 node.staticElement = minusMethod; | |
| 11666 expect(_analyze(node), same(_typeProvider.intType)); | |
| 11667 _listener.assertNoErrors(); | |
| 11668 } | |
| 11669 | |
| 11670 void test_visitPrefixExpression_not() { | |
| 11671 // !true | |
| 11672 Expression node = AstFactory.prefixExpression( | |
| 11673 TokenType.BANG, AstFactory.booleanLiteral(true)); | |
| 11674 expect(_analyze(node), same(_typeProvider.boolType)); | |
| 11675 _listener.assertNoErrors(); | |
| 11676 } | |
| 11677 | |
| 11678 void test_visitPrefixExpression_plusPlus() { | |
| 11679 // ++0 | |
| 11680 PrefixExpression node = | |
| 11681 AstFactory.prefixExpression(TokenType.PLUS_PLUS, _resolvedInteger(0)); | |
| 11682 MethodElement plusMethod = getMethod(_typeProvider.numType, "+"); | |
| 11683 node.staticElement = plusMethod; | |
| 11684 expect(_analyze(node), same(_typeProvider.intType)); | |
| 11685 _listener.assertNoErrors(); | |
| 11686 } | |
| 11687 | |
| 11688 void test_visitPrefixExpression_tilde() { | |
| 11689 // ~0 | |
| 11690 PrefixExpression node = | |
| 11691 AstFactory.prefixExpression(TokenType.TILDE, _resolvedInteger(0)); | |
| 11692 MethodElement tildeMethod = getMethod(_typeProvider.intType, "~"); | |
| 11693 node.staticElement = tildeMethod; | |
| 11694 expect(_analyze(node), same(_typeProvider.intType)); | |
| 11695 _listener.assertNoErrors(); | |
| 11696 } | |
| 11697 | |
| 11698 void test_visitPropertyAccess_propagated_getter() { | |
| 11699 DartType boolType = _typeProvider.boolType; | |
| 11700 PropertyAccessorElementImpl getter = | |
| 11701 ElementFactory.getterElement("b", false, boolType); | |
| 11702 PropertyAccess node = | |
| 11703 AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b"); | |
| 11704 node.propertyName.propagatedElement = getter; | |
| 11705 expect(_analyze2(node, false), same(boolType)); | |
| 11706 _listener.assertNoErrors(); | |
| 11707 } | |
| 11708 | |
| 11709 void test_visitPropertyAccess_propagated_setter() { | |
| 11710 DartType boolType = _typeProvider.boolType; | |
| 11711 FieldElementImpl field = | |
| 11712 ElementFactory.fieldElement("b", false, false, false, boolType); | |
| 11713 PropertyAccessorElement setter = field.setter; | |
| 11714 PropertyAccess node = | |
| 11715 AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b"); | |
| 11716 node.propertyName.propagatedElement = setter; | |
| 11717 expect(_analyze2(node, false), same(boolType)); | |
| 11718 _listener.assertNoErrors(); | |
| 11719 } | |
| 11720 | |
| 11721 void test_visitPropertyAccess_static_getter() { | |
| 11722 DartType boolType = _typeProvider.boolType; | |
| 11723 PropertyAccessorElementImpl getter = | |
| 11724 ElementFactory.getterElement("b", false, boolType); | |
| 11725 PropertyAccess node = | |
| 11726 AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b"); | |
| 11727 node.propertyName.staticElement = getter; | |
| 11728 expect(_analyze(node), same(boolType)); | |
| 11729 _listener.assertNoErrors(); | |
| 11730 } | |
| 11731 | |
| 11732 void test_visitPropertyAccess_static_setter() { | |
| 11733 DartType boolType = _typeProvider.boolType; | |
| 11734 FieldElementImpl field = | |
| 11735 ElementFactory.fieldElement("b", false, false, false, boolType); | |
| 11736 PropertyAccessorElement setter = field.setter; | |
| 11737 PropertyAccess node = | |
| 11738 AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b"); | |
| 11739 node.propertyName.staticElement = setter; | |
| 11740 expect(_analyze(node), same(boolType)); | |
| 11741 _listener.assertNoErrors(); | |
| 11742 } | |
| 11743 | |
| 11744 void test_visitSimpleIdentifier_dynamic() { | |
| 11745 // "dynamic" | |
| 11746 SimpleIdentifier identifier = AstFactory.identifier3('dynamic'); | |
| 11747 DynamicElementImpl element = DynamicElementImpl.instance; | |
| 11748 identifier.staticElement = element; | |
| 11749 identifier.staticType = _typeProvider.typeType; | |
| 11750 expect(_analyze(identifier), same(_typeProvider.typeType)); | |
| 11751 _listener.assertNoErrors(); | |
| 11752 } | |
| 11753 | |
| 11754 void test_visitSimpleStringLiteral() { | |
| 11755 // "a" | |
| 11756 Expression node = _resolvedString("a"); | |
| 11757 expect(_analyze(node), same(_typeProvider.stringType)); | |
| 11758 _listener.assertNoErrors(); | |
| 11759 } | |
| 11760 | |
| 11761 void test_visitStringInterpolation() { | |
| 11762 // "a${'b'}c" | |
| 11763 Expression node = AstFactory.string([ | |
| 11764 AstFactory.interpolationString("a", "a"), | |
| 11765 AstFactory.interpolationExpression(_resolvedString("b")), | |
| 11766 AstFactory.interpolationString("c", "c") | |
| 11767 ]); | |
| 11768 expect(_analyze(node), same(_typeProvider.stringType)); | |
| 11769 _listener.assertNoErrors(); | |
| 11770 } | |
| 11771 | |
| 11772 void test_visitSuperExpression() { | |
| 11773 // super | |
| 11774 InterfaceType superType = ElementFactory.classElement2("A").type; | |
| 11775 InterfaceType thisType = ElementFactory.classElement("B", superType).type; | |
| 11776 Expression node = AstFactory.superExpression(); | |
| 11777 expect(_analyze3(node, thisType), same(thisType)); | |
| 11778 _listener.assertNoErrors(); | |
| 11779 } | |
| 11780 | |
| 11781 void test_visitSymbolLiteral() { | |
| 11782 expect(_analyze(AstFactory.symbolLiteral(["a"])), | |
| 11783 same(_typeProvider.symbolType)); | |
| 11784 } | |
| 11785 | |
| 11786 void test_visitThisExpression() { | |
| 11787 // this | |
| 11788 InterfaceType thisType = ElementFactory | |
| 11789 .classElement("B", ElementFactory.classElement2("A").type) | |
| 11790 .type; | |
| 11791 Expression node = AstFactory.thisExpression(); | |
| 11792 expect(_analyze3(node, thisType), same(thisType)); | |
| 11793 _listener.assertNoErrors(); | |
| 11794 } | |
| 11795 | |
| 11796 void test_visitThrowExpression_withoutValue() { | |
| 11797 // throw | |
| 11798 Expression node = AstFactory.throwExpression(); | |
| 11799 expect(_analyze(node), same(_typeProvider.bottomType)); | |
| 11800 _listener.assertNoErrors(); | |
| 11801 } | |
| 11802 | |
| 11803 void test_visitThrowExpression_withValue() { | |
| 11804 // throw 0 | |
| 11805 Expression node = AstFactory.throwExpression2(_resolvedInteger(0)); | |
| 11806 expect(_analyze(node), same(_typeProvider.bottomType)); | |
| 11807 _listener.assertNoErrors(); | |
| 11808 } | |
| 11809 | |
| 11810 /** | |
| 11811 * Return the type associated with the given expression after the static type
analyzer has | |
| 11812 * computed a type for it. | |
| 11813 * | |
| 11814 * @param node the expression with which the type is associated | |
| 11815 * @return the type associated with the expression | |
| 11816 */ | |
| 11817 DartType _analyze(Expression node) => _analyze4(node, null, true); | |
| 11818 | |
| 11819 /** | |
| 11820 * Return the type associated with the given expression after the static or pr
opagated type | |
| 11821 * analyzer has computed a type for it. | |
| 11822 * | |
| 11823 * @param node the expression with which the type is associated | |
| 11824 * @param useStaticType `true` if the static type is being requested, and `fal
se` if | |
| 11825 * the propagated type is being requested | |
| 11826 * @return the type associated with the expression | |
| 11827 */ | |
| 11828 DartType _analyze2(Expression node, bool useStaticType) => | |
| 11829 _analyze4(node, null, useStaticType); | |
| 11830 | |
| 11831 /** | |
| 11832 * Return the type associated with the given expression after the static type
analyzer has | |
| 11833 * computed a type for it. | |
| 11834 * | |
| 11835 * @param node the expression with which the type is associated | |
| 11836 * @param thisType the type of 'this' | |
| 11837 * @return the type associated with the expression | |
| 11838 */ | |
| 11839 DartType _analyze3(Expression node, InterfaceType thisType) => | |
| 11840 _analyze4(node, thisType, true); | |
| 11841 | |
| 11842 /** | |
| 11843 * Return the type associated with the given expression after the static type
analyzer has | |
| 11844 * computed a type for it. | |
| 11845 * | |
| 11846 * @param node the expression with which the type is associated | |
| 11847 * @param thisType the type of 'this' | |
| 11848 * @param useStaticType `true` if the static type is being requested, and `fal
se` if | |
| 11849 * the propagated type is being requested | |
| 11850 * @return the type associated with the expression | |
| 11851 */ | |
| 11852 DartType _analyze4( | |
| 11853 Expression node, InterfaceType thisType, bool useStaticType) { | |
| 11854 try { | |
| 11855 _analyzer.thisType = thisType; | |
| 11856 } catch (exception) { | |
| 11857 throw new IllegalArgumentException( | |
| 11858 "Could not set type of 'this'", exception); | |
| 11859 } | |
| 11860 node.accept(_analyzer); | |
| 11861 if (useStaticType) { | |
| 11862 return node.staticType; | |
| 11863 } else { | |
| 11864 return node.propagatedType; | |
| 11865 } | |
| 11866 } | |
| 11867 | |
| 11868 /** | |
| 11869 * Return the type associated with the given parameter after the static type a
nalyzer has computed | |
| 11870 * a type for it. | |
| 11871 * | |
| 11872 * @param node the parameter with which the type is associated | |
| 11873 * @return the type associated with the parameter | |
| 11874 */ | |
| 11875 DartType _analyze5(FormalParameter node) { | |
| 11876 node.accept(_analyzer); | |
| 11877 return (node.identifier.staticElement as ParameterElement).type; | |
| 11878 } | |
| 11879 | |
| 11880 /** | |
| 11881 * Assert that the actual type is a function type with the expected characteri
stics. | |
| 11882 * | |
| 11883 * @param expectedReturnType the expected return type of the function | |
| 11884 * @param expectedNormalTypes the expected types of the normal parameters | |
| 11885 * @param expectedOptionalTypes the expected types of the optional parameters | |
| 11886 * @param expectedNamedTypes the expected types of the named parameters | |
| 11887 * @param actualType the type being tested | |
| 11888 */ | |
| 11889 void _assertFunctionType( | |
| 11890 DartType expectedReturnType, | |
| 11891 List<DartType> expectedNormalTypes, | |
| 11892 List<DartType> expectedOptionalTypes, | |
| 11893 Map<String, DartType> expectedNamedTypes, | |
| 11894 DartType actualType) { | |
| 11895 EngineTestCase.assertInstanceOf( | |
| 11896 (obj) => obj is FunctionType, FunctionType, actualType); | |
| 11897 FunctionType functionType = actualType as FunctionType; | |
| 11898 List<DartType> normalTypes = functionType.normalParameterTypes; | |
| 11899 if (expectedNormalTypes == null) { | |
| 11900 expect(normalTypes, hasLength(0)); | |
| 11901 } else { | |
| 11902 int expectedCount = expectedNormalTypes.length; | |
| 11903 expect(normalTypes, hasLength(expectedCount)); | |
| 11904 for (int i = 0; i < expectedCount; i++) { | |
| 11905 expect(normalTypes[i], same(expectedNormalTypes[i])); | |
| 11906 } | |
| 11907 } | |
| 11908 List<DartType> optionalTypes = functionType.optionalParameterTypes; | |
| 11909 if (expectedOptionalTypes == null) { | |
| 11910 expect(optionalTypes, hasLength(0)); | |
| 11911 } else { | |
| 11912 int expectedCount = expectedOptionalTypes.length; | |
| 11913 expect(optionalTypes, hasLength(expectedCount)); | |
| 11914 for (int i = 0; i < expectedCount; i++) { | |
| 11915 expect(optionalTypes[i], same(expectedOptionalTypes[i])); | |
| 11916 } | |
| 11917 } | |
| 11918 Map<String, DartType> namedTypes = functionType.namedParameterTypes; | |
| 11919 if (expectedNamedTypes == null) { | |
| 11920 expect(namedTypes, hasLength(0)); | |
| 11921 } else { | |
| 11922 expect(namedTypes, hasLength(expectedNamedTypes.length)); | |
| 11923 expectedNamedTypes.forEach((String name, DartType type) { | |
| 11924 expect(namedTypes[name], same(type)); | |
| 11925 }); | |
| 11926 } | |
| 11927 expect(functionType.returnType, equals(expectedReturnType)); | |
| 11928 } | |
| 11929 | |
| 11930 void _assertType( | |
| 11931 InterfaceTypeImpl expectedType, InterfaceTypeImpl actualType) { | |
| 11932 expect(actualType.displayName, expectedType.displayName); | |
| 11933 expect(actualType.element, expectedType.element); | |
| 11934 List<DartType> expectedArguments = expectedType.typeArguments; | |
| 11935 int length = expectedArguments.length; | |
| 11936 List<DartType> actualArguments = actualType.typeArguments; | |
| 11937 expect(actualArguments, hasLength(length)); | |
| 11938 for (int i = 0; i < length; i++) { | |
| 11939 _assertType2(expectedArguments[i], actualArguments[i]); | |
| 11940 } | |
| 11941 } | |
| 11942 | |
| 11943 void _assertType2(DartType expectedType, DartType actualType) { | |
| 11944 if (expectedType is InterfaceTypeImpl) { | |
| 11945 EngineTestCase.assertInstanceOf( | |
| 11946 (obj) => obj is InterfaceTypeImpl, InterfaceTypeImpl, actualType); | |
| 11947 _assertType(expectedType, actualType as InterfaceTypeImpl); | |
| 11948 } | |
| 11949 // TODO(brianwilkerson) Compare other kinds of types then make this a shared | |
| 11950 // utility method. | |
| 11951 } | |
| 11952 | |
| 11953 /** | |
| 11954 * Create the analyzer used by the tests. | |
| 11955 * | |
| 11956 * @return the analyzer to be used by the tests | |
| 11957 */ | |
| 11958 StaticTypeAnalyzer _createAnalyzer() { | |
| 11959 InternalAnalysisContext context = AnalysisContextFactory.contextWithCore(); | |
| 11960 FileBasedSource source = | |
| 11961 new FileBasedSource(FileUtilities2.createFile("/lib.dart")); | |
| 11962 CompilationUnitElementImpl definingCompilationUnit = | |
| 11963 new CompilationUnitElementImpl("lib.dart"); | |
| 11964 definingCompilationUnit.librarySource = | |
| 11965 definingCompilationUnit.source = source; | |
| 11966 LibraryElementImpl definingLibrary = | |
| 11967 new LibraryElementImpl.forNode(context, null); | |
| 11968 definingLibrary.definingCompilationUnit = definingCompilationUnit; | |
| 11969 _typeProvider = new TestTypeProvider(context); | |
| 11970 _visitor = new ResolverVisitor( | |
| 11971 definingLibrary, source, _typeProvider, _listener, | |
| 11972 nameScope: new LibraryScope(definingLibrary, _listener)); | |
| 11973 _visitor.overrideManager.enterScope(); | |
| 11974 try { | |
| 11975 return _visitor.typeAnalyzer; | |
| 11976 } catch (exception) { | |
| 11977 throw new IllegalArgumentException( | |
| 11978 "Could not create analyzer", exception); | |
| 11979 } | |
| 11980 } | |
| 11981 | |
| 11982 DartType _flatten(DartType type) => type.flattenFutures(_typeSystem); | |
| 11983 | |
| 11984 /** | |
| 11985 * Return a simple identifier that has been resolved to a variable element wit
h the given type. | |
| 11986 * | |
| 11987 * @param type the type of the variable being represented | |
| 11988 * @param variableName the name of the variable | |
| 11989 * @return a simple identifier that has been resolved to a variable element wi
th the given type | |
| 11990 */ | |
| 11991 SimpleIdentifier _propagatedVariable( | |
| 11992 InterfaceType type, String variableName) { | |
| 11993 SimpleIdentifier identifier = AstFactory.identifier3(variableName); | |
| 11994 VariableElementImpl element = | |
| 11995 ElementFactory.localVariableElement(identifier); | |
| 11996 element.type = type; | |
| 11997 identifier.staticType = _typeProvider.dynamicType; | |
| 11998 identifier.propagatedElement = element; | |
| 11999 identifier.propagatedType = type; | |
| 12000 return identifier; | |
| 12001 } | |
| 12002 | |
| 12003 /** | |
| 12004 * Return an integer literal that has been resolved to the correct type. | |
| 12005 * | |
| 12006 * @param value the value of the literal | |
| 12007 * @return an integer literal that has been resolved to the correct type | |
| 12008 */ | |
| 12009 DoubleLiteral _resolvedDouble(double value) { | |
| 12010 DoubleLiteral literal = AstFactory.doubleLiteral(value); | |
| 12011 literal.staticType = _typeProvider.doubleType; | |
| 12012 return literal; | |
| 12013 } | |
| 12014 | |
| 12015 /** | |
| 12016 * Create a function expression that has an element associated with it, where
the element has an | |
| 12017 * incomplete type associated with it (just like the one | |
| 12018 * [ElementBuilder.visitFunctionExpression] would have built if we had | |
| 12019 * run it). | |
| 12020 * | |
| 12021 * @param parameters the parameters to the function | |
| 12022 * @param body the body of the function | |
| 12023 * @return a resolved function expression | |
| 12024 */ | |
| 12025 FunctionExpression _resolvedFunctionExpression( | |
| 12026 FormalParameterList parameters, FunctionBody body) { | |
| 12027 List<ParameterElement> parameterElements = new List<ParameterElement>(); | |
| 12028 for (FormalParameter parameter in parameters.parameters) { | |
| 12029 ParameterElementImpl element = | |
| 12030 new ParameterElementImpl.forNode(parameter.identifier); | |
| 12031 element.parameterKind = parameter.kind; | |
| 12032 element.type = _typeProvider.dynamicType; | |
| 12033 parameter.identifier.staticElement = element; | |
| 12034 parameterElements.add(element); | |
| 12035 } | |
| 12036 FunctionExpression node = AstFactory.functionExpression2(parameters, body); | |
| 12037 FunctionElementImpl element = new FunctionElementImpl.forNode(null); | |
| 12038 element.parameters = parameterElements; | |
| 12039 element.type = new FunctionTypeImpl(element); | |
| 12040 node.element = element; | |
| 12041 return node; | |
| 12042 } | |
| 12043 | |
| 12044 /** | |
| 12045 * Return an integer literal that has been resolved to the correct type. | |
| 12046 * | |
| 12047 * @param value the value of the literal | |
| 12048 * @return an integer literal that has been resolved to the correct type | |
| 12049 */ | |
| 12050 IntegerLiteral _resolvedInteger(int value) { | |
| 12051 IntegerLiteral literal = AstFactory.integer(value); | |
| 12052 literal.staticType = _typeProvider.intType; | |
| 12053 return literal; | |
| 12054 } | |
| 12055 | |
| 12056 /** | |
| 12057 * Return a string literal that has been resolved to the correct type. | |
| 12058 * | |
| 12059 * @param value the value of the literal | |
| 12060 * @return a string literal that has been resolved to the correct type | |
| 12061 */ | |
| 12062 SimpleStringLiteral _resolvedString(String value) { | |
| 12063 SimpleStringLiteral string = AstFactory.string2(value); | |
| 12064 string.staticType = _typeProvider.stringType; | |
| 12065 return string; | |
| 12066 } | |
| 12067 | |
| 12068 /** | |
| 12069 * Return a simple identifier that has been resolved to a variable element wit
h the given type. | |
| 12070 * | |
| 12071 * @param type the type of the variable being represented | |
| 12072 * @param variableName the name of the variable | |
| 12073 * @return a simple identifier that has been resolved to a variable element wi
th the given type | |
| 12074 */ | |
| 12075 SimpleIdentifier _resolvedVariable(InterfaceType type, String variableName) { | |
| 12076 SimpleIdentifier identifier = AstFactory.identifier3(variableName); | |
| 12077 VariableElementImpl element = | |
| 12078 ElementFactory.localVariableElement(identifier); | |
| 12079 element.type = type; | |
| 12080 identifier.staticElement = element; | |
| 12081 identifier.staticType = type; | |
| 12082 return identifier; | |
| 12083 } | |
| 12084 | |
| 12085 /** | |
| 12086 * Set the type of the given parameter to the given type. | |
| 12087 * | |
| 12088 * @param parameter the parameter whose type is to be set | |
| 12089 * @param type the new type of the given parameter | |
| 12090 */ | |
| 12091 void _setType(FormalParameter parameter, DartType type) { | |
| 12092 SimpleIdentifier identifier = parameter.identifier; | |
| 12093 Element element = identifier.staticElement; | |
| 12094 if (element is! ParameterElement) { | |
| 12095 element = new ParameterElementImpl.forNode(identifier); | |
| 12096 identifier.staticElement = element; | |
| 12097 } | |
| 12098 (element as ParameterElementImpl).type = type; | |
| 12099 } | |
| 12100 } | |
| 12101 | |
| 12102 /** | |
| 12103 * Instances of the class `StaticTypeVerifier` verify that all of the nodes in a
n AST | 677 * Instances of the class `StaticTypeVerifier` verify that all of the nodes in a
n AST |
| 12104 * structure that should have a static type associated with them do have a stati
c type. | 678 * structure that should have a static type associated with them do have a stati
c type. |
| 12105 */ | 679 */ |
| 12106 class StaticTypeVerifier extends GeneralizingAstVisitor<Object> { | 680 class StaticTypeVerifier extends GeneralizingAstVisitor<Object> { |
| 12107 /** | 681 /** |
| 12108 * A list containing all of the AST Expression nodes that were not resolved. | 682 * A list containing all of the AST Expression nodes that were not resolved. |
| 12109 */ | 683 */ |
| 12110 List<Expression> _unresolvedExpressions = new List<Expression>(); | 684 List<Expression> _unresolvedExpressions = new List<Expression>(); |
| 12111 | 685 |
| 12112 /** | 686 /** |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12458 Source source = addSource(r''' | 1032 Source source = addSource(r''' |
| 12459 int f() { | 1033 int f() { |
| 12460 num n = 1234; | 1034 num n = 1234; |
| 12461 return n & 0x0F; | 1035 return n & 0x0F; |
| 12462 }'''); | 1036 }'''); |
| 12463 computeLibrarySourceErrors(source); | 1037 computeLibrarySourceErrors(source); |
| 12464 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]); | 1038 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]); |
| 12465 } | 1039 } |
| 12466 } | 1040 } |
| 12467 | 1041 |
| 12468 /** | |
| 12469 * Strong mode static analyzer downwards inference tests | |
| 12470 */ | |
| 12471 @reflectiveTest | |
| 12472 class StrongModeDownwardsInferenceTest extends ResolverTestCase { | |
| 12473 TypeAssertions _assertions; | |
| 12474 | |
| 12475 Asserter<DartType> _isDynamic; | |
| 12476 Asserter<InterfaceType> _isFutureOfDynamic; | |
| 12477 Asserter<InterfaceType> _isFutureOfInt; | |
| 12478 Asserter<DartType> _isInt; | |
| 12479 Asserter<DartType> _isNum; | |
| 12480 Asserter<DartType> _isString; | |
| 12481 | |
| 12482 AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, DartType> | |
| 12483 _isFunction2Of; | |
| 12484 AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isFutureOf; | |
| 12485 AsserterBuilderBuilder<Asserter<DartType>, List<Asserter<DartType>>, DartType> | |
| 12486 _isInstantiationOf; | |
| 12487 AsserterBuilder<Asserter<DartType>, InterfaceType> _isListOf; | |
| 12488 AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, InterfaceType> | |
| 12489 _isMapOf; | |
| 12490 AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isStreamOf; | |
| 12491 AsserterBuilder<DartType, DartType> _isType; | |
| 12492 | |
| 12493 AsserterBuilder<Element, DartType> _hasElement; | |
| 12494 AsserterBuilder<DartType, DartType> _sameElement; | |
| 12495 | |
| 12496 @override | |
| 12497 void setUp() { | |
| 12498 super.setUp(); | |
| 12499 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); | |
| 12500 options.strongMode = true; | |
| 12501 resetWithOptions(options); | |
| 12502 _assertions = new TypeAssertions(typeProvider); | |
| 12503 _isType = _assertions.isType; | |
| 12504 _hasElement = _assertions.hasElement; | |
| 12505 _isInstantiationOf = _assertions.isInstantiationOf; | |
| 12506 _isInt = _assertions.isInt; | |
| 12507 _isNum = _assertions.isNum; | |
| 12508 _isString = _assertions.isString; | |
| 12509 _isDynamic = _assertions.isDynamic; | |
| 12510 _isListOf = _assertions.isListOf; | |
| 12511 _isMapOf = _assertions.isMapOf; | |
| 12512 _isFunction2Of = _assertions.isFunction2Of; | |
| 12513 _sameElement = _assertions.sameElement; | |
| 12514 _isFutureOf = _isInstantiationOf(_sameElement(typeProvider.futureType)); | |
| 12515 _isFutureOfDynamic = _isFutureOf([_isDynamic]); | |
| 12516 _isFutureOfInt = _isFutureOf([_isInt]); | |
| 12517 _isStreamOf = _isInstantiationOf(_sameElement(typeProvider.streamType)); | |
| 12518 } | |
| 12519 | |
| 12520 void test_async_method_propagation() { | |
| 12521 String code = r''' | |
| 12522 import "dart:async"; | |
| 12523 class A { | |
| 12524 Future f0() => new Future.value(3); | |
| 12525 Future f1() async => new Future.value(3); | |
| 12526 Future f2() async => await new Future.value(3); | |
| 12527 | |
| 12528 Future<int> f3() => new Future.value(3); | |
| 12529 Future<int> f4() async => new Future.value(3); | |
| 12530 Future<int> f5() async => await new Future.value(3); | |
| 12531 | |
| 12532 Future g0() { return new Future.value(3); } | |
| 12533 Future g1() async { return new Future.value(3); } | |
| 12534 Future g2() async { return await new Future.value(3); } | |
| 12535 | |
| 12536 Future<int> g3() { return new Future.value(3); } | |
| 12537 Future<int> g4() async { return new Future.value(3); } | |
| 12538 Future<int> g5() async { return await new Future.value(3); } | |
| 12539 } | |
| 12540 '''; | |
| 12541 CompilationUnit unit = resolveSource(code); | |
| 12542 | |
| 12543 void check(String name, Asserter<InterfaceType> typeTest) { | |
| 12544 MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name); | |
| 12545 FunctionBody body = test.body; | |
| 12546 Expression returnExp; | |
| 12547 if (body is ExpressionFunctionBody) { | |
| 12548 returnExp = body.expression; | |
| 12549 } else { | |
| 12550 ReturnStatement stmt = (body as BlockFunctionBody).block.statements[0]; | |
| 12551 returnExp = stmt.expression; | |
| 12552 } | |
| 12553 DartType type = returnExp.staticType; | |
| 12554 if (returnExp is AwaitExpression) { | |
| 12555 type = returnExp.expression.staticType; | |
| 12556 } | |
| 12557 typeTest(type); | |
| 12558 } | |
| 12559 | |
| 12560 check("f0", _isFutureOfDynamic); | |
| 12561 check("f1", _isFutureOfDynamic); | |
| 12562 check("f2", _isFutureOfDynamic); | |
| 12563 | |
| 12564 check("f3", _isFutureOfInt); | |
| 12565 // This should be int when we handle the implicit Future<T> | T union | |
| 12566 // https://github.com/dart-lang/sdk/issues/25322 | |
| 12567 check("f4", _isFutureOfDynamic); | |
| 12568 check("f5", _isFutureOfInt); | |
| 12569 | |
| 12570 check("g0", _isFutureOfDynamic); | |
| 12571 check("g1", _isFutureOfDynamic); | |
| 12572 check("g2", _isFutureOfDynamic); | |
| 12573 | |
| 12574 check("g3", _isFutureOfInt); | |
| 12575 // This should be int when we handle the implicit Future<T> | T union | |
| 12576 // https://github.com/dart-lang/sdk/issues/25322 | |
| 12577 check("g4", _isFutureOfDynamic); | |
| 12578 check("g5", _isFutureOfInt); | |
| 12579 } | |
| 12580 | |
| 12581 void test_async_propagation() { | |
| 12582 String code = r''' | |
| 12583 import "dart:async"; | |
| 12584 | |
| 12585 Future f0() => new Future.value(3); | |
| 12586 Future f1() async => new Future.value(3); | |
| 12587 Future f2() async => await new Future.value(3); | |
| 12588 | |
| 12589 Future<int> f3() => new Future.value(3); | |
| 12590 Future<int> f4() async => new Future.value(3); | |
| 12591 Future<int> f5() async => await new Future.value(3); | |
| 12592 | |
| 12593 Future g0() { return new Future.value(3); } | |
| 12594 Future g1() async { return new Future.value(3); } | |
| 12595 Future g2() async { return await new Future.value(3); } | |
| 12596 | |
| 12597 Future<int> g3() { return new Future.value(3); } | |
| 12598 Future<int> g4() async { return new Future.value(3); } | |
| 12599 Future<int> g5() async { return await new Future.value(3); } | |
| 12600 '''; | |
| 12601 CompilationUnit unit = resolveSource(code); | |
| 12602 | |
| 12603 void check(String name, Asserter<InterfaceType> typeTest) { | |
| 12604 FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name); | |
| 12605 FunctionBody body = test.functionExpression.body; | |
| 12606 Expression returnExp; | |
| 12607 if (body is ExpressionFunctionBody) { | |
| 12608 returnExp = body.expression; | |
| 12609 } else { | |
| 12610 ReturnStatement stmt = (body as BlockFunctionBody).block.statements[0]; | |
| 12611 returnExp = stmt.expression; | |
| 12612 } | |
| 12613 DartType type = returnExp.staticType; | |
| 12614 if (returnExp is AwaitExpression) { | |
| 12615 type = returnExp.expression.staticType; | |
| 12616 } | |
| 12617 typeTest(type); | |
| 12618 } | |
| 12619 | |
| 12620 check("f0", _isFutureOfDynamic); | |
| 12621 check("f1", _isFutureOfDynamic); | |
| 12622 check("f2", _isFutureOfDynamic); | |
| 12623 | |
| 12624 check("f3", _isFutureOfInt); | |
| 12625 // This should be int when we handle the implicit Future<T> | T union | |
| 12626 // https://github.com/dart-lang/sdk/issues/25322 | |
| 12627 check("f4", _isFutureOfDynamic); | |
| 12628 check("f5", _isFutureOfInt); | |
| 12629 | |
| 12630 check("g0", _isFutureOfDynamic); | |
| 12631 check("g1", _isFutureOfDynamic); | |
| 12632 check("g2", _isFutureOfDynamic); | |
| 12633 | |
| 12634 check("g3", _isFutureOfInt); | |
| 12635 // This should be int when we handle the implicit Future<T> | T union | |
| 12636 // https://github.com/dart-lang/sdk/issues/25322 | |
| 12637 check("g4", _isFutureOfDynamic); | |
| 12638 check("g5", _isFutureOfInt); | |
| 12639 } | |
| 12640 | |
| 12641 void test_async_star_method_propagation() { | |
| 12642 String code = r''' | |
| 12643 import "dart:async"; | |
| 12644 class A { | |
| 12645 Stream g0() async* { yield []; } | |
| 12646 Stream g1() async* { yield* new Stream(); } | |
| 12647 | |
| 12648 Stream<List<int>> g2() async* { yield []; } | |
| 12649 Stream<List<int>> g3() async* { yield* new Stream(); } | |
| 12650 } | |
| 12651 '''; | |
| 12652 CompilationUnit unit = resolveSource(code); | |
| 12653 | |
| 12654 void check(String name, Asserter<InterfaceType> typeTest) { | |
| 12655 MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name); | |
| 12656 BlockFunctionBody body = test.body; | |
| 12657 YieldStatement stmt = body.block.statements[0]; | |
| 12658 Expression exp = stmt.expression; | |
| 12659 typeTest(exp.staticType); | |
| 12660 } | |
| 12661 | |
| 12662 check("g0", _isListOf(_isDynamic)); | |
| 12663 check("g1", _isStreamOf([_isDynamic])); | |
| 12664 | |
| 12665 check("g2", _isListOf(_isInt)); | |
| 12666 check("g3", _isStreamOf([_isListOf(_isInt)])); | |
| 12667 } | |
| 12668 | |
| 12669 void test_async_star_propagation() { | |
| 12670 String code = r''' | |
| 12671 import "dart:async"; | |
| 12672 | |
| 12673 Stream g0() async* { yield []; } | |
| 12674 Stream g1() async* { yield* new Stream(); } | |
| 12675 | |
| 12676 Stream<List<int>> g2() async* { yield []; } | |
| 12677 Stream<List<int>> g3() async* { yield* new Stream(); } | |
| 12678 '''; | |
| 12679 CompilationUnit unit = resolveSource(code); | |
| 12680 | |
| 12681 void check(String name, Asserter<InterfaceType> typeTest) { | |
| 12682 FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name); | |
| 12683 BlockFunctionBody body = test.functionExpression.body; | |
| 12684 YieldStatement stmt = body.block.statements[0]; | |
| 12685 Expression exp = stmt.expression; | |
| 12686 typeTest(exp.staticType); | |
| 12687 } | |
| 12688 | |
| 12689 check("g0", _isListOf(_isDynamic)); | |
| 12690 check("g1", _isStreamOf([_isDynamic])); | |
| 12691 | |
| 12692 check("g2", _isListOf(_isInt)); | |
| 12693 check("g3", _isStreamOf([_isListOf(_isInt)])); | |
| 12694 } | |
| 12695 | |
| 12696 void test_cascadeExpression() { | |
| 12697 String code = r''' | |
| 12698 class A<T> { | |
| 12699 List<T> map(T a, List<T> mapper(T x)) => mapper(a); | |
| 12700 } | |
| 12701 | |
| 12702 void main () { | |
| 12703 A<int> a = new A()..map(0, (x) => [x]); | |
| 12704 } | |
| 12705 '''; | |
| 12706 CompilationUnit unit = resolveSource(code); | |
| 12707 List<Statement> statements = | |
| 12708 AstFinder.getStatementsInTopLevelFunction(unit, "main"); | |
| 12709 CascadeExpression fetch(int i) { | |
| 12710 VariableDeclarationStatement stmt = statements[i]; | |
| 12711 VariableDeclaration decl = stmt.variables.variables[0]; | |
| 12712 CascadeExpression exp = decl.initializer; | |
| 12713 return exp; | |
| 12714 } | |
| 12715 Element elementA = AstFinder.getClass(unit, "A").element; | |
| 12716 | |
| 12717 CascadeExpression cascade = fetch(0); | |
| 12718 _isInstantiationOf(_hasElement(elementA))([_isInt])(cascade.staticType); | |
| 12719 MethodInvocation invoke = cascade.cascadeSections[0]; | |
| 12720 FunctionExpression function = invoke.argumentList.arguments[1]; | |
| 12721 ExecutableElement f0 = function.element; | |
| 12722 _isListOf(_isInt)(f0.type.returnType); | |
| 12723 expect(f0.type.normalParameterTypes[0], typeProvider.intType); | |
| 12724 } | |
| 12725 | |
| 12726 void test_constructorInitializer_propagation() { | |
| 12727 String code = r''' | |
| 12728 class A { | |
| 12729 List<String> x; | |
| 12730 A() : this.x = []; | |
| 12731 } | |
| 12732 '''; | |
| 12733 CompilationUnit unit = resolveSource(code); | |
| 12734 ConstructorDeclaration constructor = | |
| 12735 AstFinder.getConstructorInClass(unit, "A", null); | |
| 12736 ConstructorFieldInitializer assignment = constructor.initializers[0]; | |
| 12737 Expression exp = assignment.expression; | |
| 12738 _isListOf(_isString)(exp.staticType); | |
| 12739 } | |
| 12740 | |
| 12741 void test_factoryConstructor_propagation() { | |
| 12742 String code = r''' | |
| 12743 class A<T> { | |
| 12744 factory A() { return new B(); } | |
| 12745 } | |
| 12746 class B<S> extends A<S> {} | |
| 12747 '''; | |
| 12748 CompilationUnit unit = resolveSource(code); | |
| 12749 | |
| 12750 ConstructorDeclaration constructor = | |
| 12751 AstFinder.getConstructorInClass(unit, "A", null); | |
| 12752 BlockFunctionBody body = constructor.body; | |
| 12753 ReturnStatement stmt = body.block.statements[0]; | |
| 12754 InstanceCreationExpression exp = stmt.expression; | |
| 12755 ClassElement elementB = AstFinder.getClass(unit, "B").element; | |
| 12756 ClassElement elementA = AstFinder.getClass(unit, "A").element; | |
| 12757 expect(exp.constructorName.type.type.element, elementB); | |
| 12758 _isInstantiationOf(_hasElement(elementB))( | |
| 12759 [_isType(elementA.typeParameters[0].type)])(exp.staticType); | |
| 12760 } | |
| 12761 | |
| 12762 void test_fieldDeclaration_propagation() { | |
| 12763 String code = r''' | |
| 12764 class A { | |
| 12765 List<String> f0 = ["hello"]; | |
| 12766 } | |
| 12767 '''; | |
| 12768 CompilationUnit unit = resolveSource(code); | |
| 12769 | |
| 12770 VariableDeclaration field = AstFinder.getFieldInClass(unit, "A", "f0"); | |
| 12771 | |
| 12772 _isListOf(_isString)(field.initializer.staticType); | |
| 12773 } | |
| 12774 | |
| 12775 void test_functionDeclaration_body_propagation() { | |
| 12776 String code = r''' | |
| 12777 typedef T Function2<S, T>(S x); | |
| 12778 | |
| 12779 List<int> test1() => []; | |
| 12780 | |
| 12781 Function2<int, int> test2 (int x) { | |
| 12782 Function2<String, int> inner() { | |
| 12783 return (x) => x.length; | |
| 12784 } | |
| 12785 return (x) => x; | |
| 12786 } | |
| 12787 '''; | |
| 12788 CompilationUnit unit = resolveSource(code); | |
| 12789 | |
| 12790 Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt); | |
| 12791 | |
| 12792 FunctionDeclaration test1 = AstFinder.getTopLevelFunction(unit, "test1"); | |
| 12793 ExpressionFunctionBody body = test1.functionExpression.body; | |
| 12794 assertListOfInt(body.expression.staticType); | |
| 12795 | |
| 12796 List<Statement> statements = | |
| 12797 AstFinder.getStatementsInTopLevelFunction(unit, "test2"); | |
| 12798 | |
| 12799 FunctionDeclaration inner = | |
| 12800 (statements[0] as FunctionDeclarationStatement).functionDeclaration; | |
| 12801 BlockFunctionBody body0 = inner.functionExpression.body; | |
| 12802 ReturnStatement return0 = body0.block.statements[0]; | |
| 12803 Expression anon0 = return0.expression; | |
| 12804 FunctionType type0 = anon0.staticType; | |
| 12805 expect(type0.returnType, typeProvider.intType); | |
| 12806 expect(type0.normalParameterTypes[0], typeProvider.stringType); | |
| 12807 | |
| 12808 FunctionExpression anon1 = (statements[1] as ReturnStatement).expression; | |
| 12809 FunctionType type1 = anon1.element.type; | |
| 12810 expect(type1.returnType, typeProvider.intType); | |
| 12811 expect(type1.normalParameterTypes[0], typeProvider.intType); | |
| 12812 } | |
| 12813 | |
| 12814 void test_functionLiteral_assignment_typedArguments() { | |
| 12815 String code = r''' | |
| 12816 typedef T Function2<S, T>(S x); | |
| 12817 | |
| 12818 void main () { | |
| 12819 Function2<int, String> l0 = (int x) => null; | |
| 12820 Function2<int, String> l1 = (int x) => "hello"; | |
| 12821 Function2<int, String> l2 = (String x) => "hello"; | |
| 12822 Function2<int, String> l3 = (int x) => 3; | |
| 12823 Function2<int, String> l4 = (int x) {return 3;}; | |
| 12824 } | |
| 12825 '''; | |
| 12826 CompilationUnit unit = resolveSource(code); | |
| 12827 List<Statement> statements = | |
| 12828 AstFinder.getStatementsInTopLevelFunction(unit, "main"); | |
| 12829 DartType literal(int i) { | |
| 12830 VariableDeclarationStatement stmt = statements[i]; | |
| 12831 VariableDeclaration decl = stmt.variables.variables[0]; | |
| 12832 FunctionExpression exp = decl.initializer; | |
| 12833 return exp.element.type; | |
| 12834 } | |
| 12835 _isFunction2Of(_isInt, _isString)(literal(0)); | |
| 12836 _isFunction2Of(_isInt, _isString)(literal(1)); | |
| 12837 _isFunction2Of(_isString, _isString)(literal(2)); | |
| 12838 _isFunction2Of(_isInt, _isInt)(literal(3)); | |
| 12839 _isFunction2Of(_isInt, _isString)(literal(4)); | |
| 12840 } | |
| 12841 | |
| 12842 void test_functionLiteral_assignment_unTypedArguments() { | |
| 12843 String code = r''' | |
| 12844 typedef T Function2<S, T>(S x); | |
| 12845 | |
| 12846 void main () { | |
| 12847 Function2<int, String> l0 = (x) => null; | |
| 12848 Function2<int, String> l1 = (x) => "hello"; | |
| 12849 Function2<int, String> l2 = (x) => "hello"; | |
| 12850 Function2<int, String> l3 = (x) => 3; | |
| 12851 Function2<int, String> l4 = (x) {return 3;}; | |
| 12852 } | |
| 12853 '''; | |
| 12854 CompilationUnit unit = resolveSource(code); | |
| 12855 List<Statement> statements = | |
| 12856 AstFinder.getStatementsInTopLevelFunction(unit, "main"); | |
| 12857 DartType literal(int i) { | |
| 12858 VariableDeclarationStatement stmt = statements[i]; | |
| 12859 VariableDeclaration decl = stmt.variables.variables[0]; | |
| 12860 FunctionExpression exp = decl.initializer; | |
| 12861 return exp.element.type; | |
| 12862 } | |
| 12863 _isFunction2Of(_isInt, _isString)(literal(0)); | |
| 12864 _isFunction2Of(_isInt, _isString)(literal(1)); | |
| 12865 _isFunction2Of(_isInt, _isString)(literal(2)); | |
| 12866 _isFunction2Of(_isInt, _isInt)(literal(3)); | |
| 12867 _isFunction2Of(_isInt, _isString)(literal(4)); | |
| 12868 } | |
| 12869 | |
| 12870 void test_functionLiteral_body_propagation() { | |
| 12871 String code = r''' | |
| 12872 typedef T Function2<S, T>(S x); | |
| 12873 | |
| 12874 void main () { | |
| 12875 Function2<int, List<String>> l0 = (int x) => ["hello"]; | |
| 12876 Function2<int, List<String>> l1 = (String x) => ["hello"]; | |
| 12877 Function2<int, List<String>> l2 = (int x) => [3]; | |
| 12878 Function2<int, List<String>> l3 = (int x) {return [3];}; | |
| 12879 } | |
| 12880 '''; | |
| 12881 CompilationUnit unit = resolveSource(code); | |
| 12882 List<Statement> statements = | |
| 12883 AstFinder.getStatementsInTopLevelFunction(unit, "main"); | |
| 12884 Expression functionReturnValue(int i) { | |
| 12885 VariableDeclarationStatement stmt = statements[i]; | |
| 12886 VariableDeclaration decl = stmt.variables.variables[0]; | |
| 12887 FunctionExpression exp = decl.initializer; | |
| 12888 FunctionBody body = exp.body; | |
| 12889 if (body is ExpressionFunctionBody) { | |
| 12890 return body.expression; | |
| 12891 } else { | |
| 12892 Statement stmt = (body as BlockFunctionBody).block.statements[0]; | |
| 12893 return (stmt as ReturnStatement).expression; | |
| 12894 } | |
| 12895 } | |
| 12896 Asserter<InterfaceType> assertListOfString = _isListOf(_isString); | |
| 12897 assertListOfString(functionReturnValue(0).staticType); | |
| 12898 assertListOfString(functionReturnValue(1).staticType); | |
| 12899 assertListOfString(functionReturnValue(2).staticType); | |
| 12900 assertListOfString(functionReturnValue(3).staticType); | |
| 12901 } | |
| 12902 | |
| 12903 void test_functionLiteral_functionExpressionInvocation_typedArguments() { | |
| 12904 String code = r''' | |
| 12905 class Mapper<F, T> { | |
| 12906 T map(T mapper(F x)) => mapper(null); | |
| 12907 } | |
| 12908 | |
| 12909 void main () { | |
| 12910 (new Mapper<int, String>().map)((int x) => null); | |
| 12911 (new Mapper<int, String>().map)((int x) => "hello"); | |
| 12912 (new Mapper<int, String>().map)((String x) => "hello"); | |
| 12913 (new Mapper<int, String>().map)((int x) => 3); | |
| 12914 (new Mapper<int, String>().map)((int x) {return 3;}); | |
| 12915 } | |
| 12916 '''; | |
| 12917 CompilationUnit unit = resolveSource(code); | |
| 12918 List<Statement> statements = | |
| 12919 AstFinder.getStatementsInTopLevelFunction(unit, "main"); | |
| 12920 DartType literal(int i) { | |
| 12921 ExpressionStatement stmt = statements[i]; | |
| 12922 FunctionExpressionInvocation invk = stmt.expression; | |
| 12923 FunctionExpression exp = invk.argumentList.arguments[0]; | |
| 12924 return exp.element.type; | |
| 12925 } | |
| 12926 _isFunction2Of(_isInt, _isString)(literal(0)); | |
| 12927 _isFunction2Of(_isInt, _isString)(literal(1)); | |
| 12928 _isFunction2Of(_isString, _isString)(literal(2)); | |
| 12929 _isFunction2Of(_isInt, _isInt)(literal(3)); | |
| 12930 _isFunction2Of(_isInt, _isString)(literal(4)); | |
| 12931 } | |
| 12932 | |
| 12933 void test_functionLiteral_functionExpressionInvocation_unTypedArguments() { | |
| 12934 String code = r''' | |
| 12935 class Mapper<F, T> { | |
| 12936 T map(T mapper(F x)) => mapper(null); | |
| 12937 } | |
| 12938 | |
| 12939 void main () { | |
| 12940 (new Mapper<int, String>().map)((x) => null); | |
| 12941 (new Mapper<int, String>().map)((x) => "hello"); | |
| 12942 (new Mapper<int, String>().map)((x) => "hello"); | |
| 12943 (new Mapper<int, String>().map)((x) => 3); | |
| 12944 (new Mapper<int, String>().map)((x) {return 3;}); | |
| 12945 } | |
| 12946 '''; | |
| 12947 CompilationUnit unit = resolveSource(code); | |
| 12948 List<Statement> statements = | |
| 12949 AstFinder.getStatementsInTopLevelFunction(unit, "main"); | |
| 12950 DartType literal(int i) { | |
| 12951 ExpressionStatement stmt = statements[i]; | |
| 12952 FunctionExpressionInvocation invk = stmt.expression; | |
| 12953 FunctionExpression exp = invk.argumentList.arguments[0]; | |
| 12954 return exp.element.type; | |
| 12955 } | |
| 12956 _isFunction2Of(_isInt, _isString)(literal(0)); | |
| 12957 _isFunction2Of(_isInt, _isString)(literal(1)); | |
| 12958 _isFunction2Of(_isInt, _isString)(literal(2)); | |
| 12959 _isFunction2Of(_isInt, _isInt)(literal(3)); | |
| 12960 _isFunction2Of(_isInt, _isString)(literal(4)); | |
| 12961 } | |
| 12962 | |
| 12963 void test_functionLiteral_functionInvocation_typedArguments() { | |
| 12964 String code = r''' | |
| 12965 String map(String mapper(int x)) => mapper(null); | |
| 12966 | |
| 12967 void main () { | |
| 12968 map((int x) => null); | |
| 12969 map((int x) => "hello"); | |
| 12970 map((String x) => "hello"); | |
| 12971 map((int x) => 3); | |
| 12972 map((int x) {return 3;}); | |
| 12973 } | |
| 12974 '''; | |
| 12975 CompilationUnit unit = resolveSource(code); | |
| 12976 List<Statement> statements = | |
| 12977 AstFinder.getStatementsInTopLevelFunction(unit, "main"); | |
| 12978 DartType literal(int i) { | |
| 12979 ExpressionStatement stmt = statements[i]; | |
| 12980 MethodInvocation invk = stmt.expression; | |
| 12981 FunctionExpression exp = invk.argumentList.arguments[0]; | |
| 12982 return exp.element.type; | |
| 12983 } | |
| 12984 _isFunction2Of(_isInt, _isString)(literal(0)); | |
| 12985 _isFunction2Of(_isInt, _isString)(literal(1)); | |
| 12986 _isFunction2Of(_isString, _isString)(literal(2)); | |
| 12987 _isFunction2Of(_isInt, _isInt)(literal(3)); | |
| 12988 _isFunction2Of(_isInt, _isString)(literal(4)); | |
| 12989 } | |
| 12990 | |
| 12991 void test_functionLiteral_functionInvocation_unTypedArguments() { | |
| 12992 String code = r''' | |
| 12993 String map(String mapper(int x)) => mapper(null); | |
| 12994 | |
| 12995 void main () { | |
| 12996 map((x) => null); | |
| 12997 map((x) => "hello"); | |
| 12998 map((x) => "hello"); | |
| 12999 map((x) => 3); | |
| 13000 map((x) {return 3;}); | |
| 13001 } | |
| 13002 '''; | |
| 13003 CompilationUnit unit = resolveSource(code); | |
| 13004 List<Statement> statements = | |
| 13005 AstFinder.getStatementsInTopLevelFunction(unit, "main"); | |
| 13006 DartType literal(int i) { | |
| 13007 ExpressionStatement stmt = statements[i]; | |
| 13008 MethodInvocation invk = stmt.expression; | |
| 13009 FunctionExpression exp = invk.argumentList.arguments[0]; | |
| 13010 return exp.element.type; | |
| 13011 } | |
| 13012 _isFunction2Of(_isInt, _isString)(literal(0)); | |
| 13013 _isFunction2Of(_isInt, _isString)(literal(1)); | |
| 13014 _isFunction2Of(_isInt, _isString)(literal(2)); | |
| 13015 _isFunction2Of(_isInt, _isInt)(literal(3)); | |
| 13016 _isFunction2Of(_isInt, _isString)(literal(4)); | |
| 13017 } | |
| 13018 | |
| 13019 void test_functionLiteral_methodInvocation_typedArguments() { | |
| 13020 String code = r''' | |
| 13021 class Mapper<F, T> { | |
| 13022 T map(T mapper(F x)) => mapper(null); | |
| 13023 } | |
| 13024 | |
| 13025 void main () { | |
| 13026 new Mapper<int, String>().map((int x) => null); | |
| 13027 new Mapper<int, String>().map((int x) => "hello"); | |
| 13028 new Mapper<int, String>().map((String x) => "hello"); | |
| 13029 new Mapper<int, String>().map((int x) => 3); | |
| 13030 new Mapper<int, String>().map((int x) {return 3;}); | |
| 13031 } | |
| 13032 '''; | |
| 13033 CompilationUnit unit = resolveSource(code); | |
| 13034 List<Statement> statements = | |
| 13035 AstFinder.getStatementsInTopLevelFunction(unit, "main"); | |
| 13036 DartType literal(int i) { | |
| 13037 ExpressionStatement stmt = statements[i]; | |
| 13038 MethodInvocation invk = stmt.expression; | |
| 13039 FunctionExpression exp = invk.argumentList.arguments[0]; | |
| 13040 return exp.element.type; | |
| 13041 } | |
| 13042 _isFunction2Of(_isInt, _isString)(literal(0)); | |
| 13043 _isFunction2Of(_isInt, _isString)(literal(1)); | |
| 13044 _isFunction2Of(_isString, _isString)(literal(2)); | |
| 13045 _isFunction2Of(_isInt, _isInt)(literal(3)); | |
| 13046 _isFunction2Of(_isInt, _isString)(literal(4)); | |
| 13047 } | |
| 13048 | |
| 13049 void test_functionLiteral_methodInvocation_unTypedArguments() { | |
| 13050 String code = r''' | |
| 13051 class Mapper<F, T> { | |
| 13052 T map(T mapper(F x)) => mapper(null); | |
| 13053 } | |
| 13054 | |
| 13055 void main () { | |
| 13056 new Mapper<int, String>().map((x) => null); | |
| 13057 new Mapper<int, String>().map((x) => "hello"); | |
| 13058 new Mapper<int, String>().map((x) => "hello"); | |
| 13059 new Mapper<int, String>().map((x) => 3); | |
| 13060 new Mapper<int, String>().map((x) {return 3;}); | |
| 13061 } | |
| 13062 '''; | |
| 13063 CompilationUnit unit = resolveSource(code); | |
| 13064 List<Statement> statements = | |
| 13065 AstFinder.getStatementsInTopLevelFunction(unit, "main"); | |
| 13066 DartType literal(int i) { | |
| 13067 ExpressionStatement stmt = statements[i]; | |
| 13068 MethodInvocation invk = stmt.expression; | |
| 13069 FunctionExpression exp = invk.argumentList.arguments[0]; | |
| 13070 return exp.element.type; | |
| 13071 } | |
| 13072 _isFunction2Of(_isInt, _isString)(literal(0)); | |
| 13073 _isFunction2Of(_isInt, _isString)(literal(1)); | |
| 13074 _isFunction2Of(_isInt, _isString)(literal(2)); | |
| 13075 _isFunction2Of(_isInt, _isInt)(literal(3)); | |
| 13076 _isFunction2Of(_isInt, _isString)(literal(4)); | |
| 13077 } | |
| 13078 | |
| 13079 void test_functionLiteral_unTypedArgument_propagation() { | |
| 13080 String code = r''' | |
| 13081 typedef T Function2<S, T>(S x); | |
| 13082 | |
| 13083 void main () { | |
| 13084 Function2<int, int> l0 = (x) => x; | |
| 13085 Function2<int, int> l1 = (x) => x+1; | |
| 13086 Function2<int, String> l2 = (x) => x; | |
| 13087 Function2<int, String> l3 = (x) => x.toLowerCase(); | |
| 13088 Function2<String, String> l4 = (x) => x.toLowerCase(); | |
| 13089 } | |
| 13090 '''; | |
| 13091 CompilationUnit unit = resolveSource(code); | |
| 13092 List<Statement> statements = | |
| 13093 AstFinder.getStatementsInTopLevelFunction(unit, "main"); | |
| 13094 Expression functionReturnValue(int i) { | |
| 13095 VariableDeclarationStatement stmt = statements[i]; | |
| 13096 VariableDeclaration decl = stmt.variables.variables[0]; | |
| 13097 FunctionExpression exp = decl.initializer; | |
| 13098 FunctionBody body = exp.body; | |
| 13099 if (body is ExpressionFunctionBody) { | |
| 13100 return body.expression; | |
| 13101 } else { | |
| 13102 Statement stmt = (body as BlockFunctionBody).block.statements[0]; | |
| 13103 return (stmt as ReturnStatement).expression; | |
| 13104 } | |
| 13105 } | |
| 13106 expect(functionReturnValue(0).staticType, typeProvider.intType); | |
| 13107 expect(functionReturnValue(1).staticType, typeProvider.intType); | |
| 13108 expect(functionReturnValue(2).staticType, typeProvider.intType); | |
| 13109 expect(functionReturnValue(3).staticType, typeProvider.dynamicType); | |
| 13110 expect(functionReturnValue(4).staticType, typeProvider.stringType); | |
| 13111 } | |
| 13112 | |
| 13113 void test_inference_hints() { | |
| 13114 Source source = addSource(r''' | |
| 13115 void main () { | |
| 13116 var x = 3; | |
| 13117 List<int> l0 = []; | |
| 13118 } | |
| 13119 '''); | |
| 13120 resolve2(source); | |
| 13121 assertNoErrors(source); | |
| 13122 verify([source]); | |
| 13123 } | |
| 13124 | |
| 13125 void test_instanceCreation() { | |
| 13126 String code = r''' | |
| 13127 class A<S, T> { | |
| 13128 S x; | |
| 13129 T y; | |
| 13130 A(this.x, this.y); | |
| 13131 A.named(this.x, this.y); | |
| 13132 } | |
| 13133 | |
| 13134 class B<S, T> extends A<T, S> { | |
| 13135 B(S y, T x) : super(x, y); | |
| 13136 B.named(S y, T x) : super.named(x, y); | |
| 13137 } | |
| 13138 | |
| 13139 class C<S> extends B<S, S> { | |
| 13140 C(S a) : super(a, a); | |
| 13141 C.named(S a) : super.named(a, a); | |
| 13142 } | |
| 13143 | |
| 13144 class D<S, T> extends B<T, int> { | |
| 13145 D(T a) : super(a, 3); | |
| 13146 D.named(T a) : super.named(a, 3); | |
| 13147 } | |
| 13148 | |
| 13149 class E<S, T> extends A<C<S>, T> { | |
| 13150 E(T a) : super(null, a); | |
| 13151 } | |
| 13152 | |
| 13153 class F<S, T> extends A<S, T> { | |
| 13154 F(S x, T y, {List<S> a, List<T> b}) : super(x, y); | |
| 13155 F.named(S x, T y, [S a, T b]) : super(a, b); | |
| 13156 } | |
| 13157 | |
| 13158 void test0() { | |
| 13159 A<int, String> a0 = new A(3, "hello"); | |
| 13160 A<int, String> a1 = new A.named(3, "hello"); | |
| 13161 A<int, String> a2 = new A<int, String>(3, "hello"); | |
| 13162 A<int, String> a3 = new A<int, String>.named(3, "hello"); | |
| 13163 A<int, String> a4 = new A<int, dynamic>(3, "hello"); | |
| 13164 A<int, String> a5 = new A<dynamic, dynamic>.named(3, "hello"); | |
| 13165 } | |
| 13166 void test1() { | |
| 13167 A<int, String> a0 = new A("hello", 3); | |
| 13168 A<int, String> a1 = new A.named("hello", 3); | |
| 13169 } | |
| 13170 void test2() { | |
| 13171 A<int, String> a0 = new B("hello", 3); | |
| 13172 A<int, String> a1 = new B.named("hello", 3); | |
| 13173 A<int, String> a2 = new B<String, int>("hello", 3); | |
| 13174 A<int, String> a3 = new B<String, int>.named("hello", 3); | |
| 13175 A<int, String> a4 = new B<String, dynamic>("hello", 3); | |
| 13176 A<int, String> a5 = new B<dynamic, dynamic>.named("hello", 3); | |
| 13177 } | |
| 13178 void test3() { | |
| 13179 A<int, String> a0 = new B(3, "hello"); | |
| 13180 A<int, String> a1 = new B.named(3, "hello"); | |
| 13181 } | |
| 13182 void test4() { | |
| 13183 A<int, int> a0 = new C(3); | |
| 13184 A<int, int> a1 = new C.named(3); | |
| 13185 A<int, int> a2 = new C<int>(3); | |
| 13186 A<int, int> a3 = new C<int>.named(3); | |
| 13187 A<int, int> a4 = new C<dynamic>(3); | |
| 13188 A<int, int> a5 = new C<dynamic>.named(3); | |
| 13189 } | |
| 13190 void test5() { | |
| 13191 A<int, int> a0 = new C("hello"); | |
| 13192 A<int, int> a1 = new C.named("hello"); | |
| 13193 } | |
| 13194 void test6() { | |
| 13195 A<int, String> a0 = new D("hello"); | |
| 13196 A<int, String> a1 = new D.named("hello"); | |
| 13197 A<int, String> a2 = new D<int, String>("hello"); | |
| 13198 A<int, String> a3 = new D<String, String>.named("hello"); | |
| 13199 A<int, String> a4 = new D<num, dynamic>("hello"); | |
| 13200 A<int, String> a5 = new D<dynamic, dynamic>.named("hello"); | |
| 13201 } | |
| 13202 void test7() { | |
| 13203 A<int, String> a0 = new D(3); | |
| 13204 A<int, String> a1 = new D.named(3); | |
| 13205 } | |
| 13206 void test8() { | |
| 13207 // Currently we only allow variable constraints. Test that we reject. | |
| 13208 A<C<int>, String> a0 = new E("hello"); | |
| 13209 } | |
| 13210 void test9() { // Check named and optional arguments | |
| 13211 A<int, String> a0 = new F(3, "hello", a: [3], b: ["hello"]); | |
| 13212 A<int, String> a1 = new F(3, "hello", a: ["hello"], b:[3]); | |
| 13213 A<int, String> a2 = new F.named(3, "hello", 3, "hello"); | |
| 13214 A<int, String> a3 = new F.named(3, "hello"); | |
| 13215 A<int, String> a4 = new F.named(3, "hello", "hello", 3); | |
| 13216 A<int, String> a5 = new F.named(3, "hello", "hello"); | |
| 13217 } | |
| 13218 }'''; | |
| 13219 CompilationUnit unit = resolveSource(code); | |
| 13220 | |
| 13221 Expression rhs(VariableDeclarationStatement stmt) { | |
| 13222 VariableDeclaration decl = stmt.variables.variables[0]; | |
| 13223 Expression exp = decl.initializer; | |
| 13224 return exp; | |
| 13225 } | |
| 13226 | |
| 13227 void hasType(Asserter<DartType> assertion, Expression exp) => | |
| 13228 assertion(exp.staticType); | |
| 13229 | |
| 13230 Element elementA = AstFinder.getClass(unit, "A").element; | |
| 13231 Element elementB = AstFinder.getClass(unit, "B").element; | |
| 13232 Element elementC = AstFinder.getClass(unit, "C").element; | |
| 13233 Element elementD = AstFinder.getClass(unit, "D").element; | |
| 13234 Element elementE = AstFinder.getClass(unit, "E").element; | |
| 13235 Element elementF = AstFinder.getClass(unit, "F").element; | |
| 13236 | |
| 13237 AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf = | |
| 13238 _isInstantiationOf(_hasElement(elementA)); | |
| 13239 AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf = | |
| 13240 _isInstantiationOf(_hasElement(elementB)); | |
| 13241 AsserterBuilder<List<Asserter<DartType>>, DartType> assertCOf = | |
| 13242 _isInstantiationOf(_hasElement(elementC)); | |
| 13243 AsserterBuilder<List<Asserter<DartType>>, DartType> assertDOf = | |
| 13244 _isInstantiationOf(_hasElement(elementD)); | |
| 13245 AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf = | |
| 13246 _isInstantiationOf(_hasElement(elementE)); | |
| 13247 AsserterBuilder<List<Asserter<DartType>>, DartType> assertFOf = | |
| 13248 _isInstantiationOf(_hasElement(elementF)); | |
| 13249 | |
| 13250 { | |
| 13251 List<Statement> statements = | |
| 13252 AstFinder.getStatementsInTopLevelFunction(unit, "test0"); | |
| 13253 | |
| 13254 hasType(assertAOf([_isInt, _isString]), rhs(statements[0])); | |
| 13255 hasType(assertAOf([_isInt, _isString]), rhs(statements[0])); | |
| 13256 hasType(assertAOf([_isInt, _isString]), rhs(statements[1])); | |
| 13257 hasType(assertAOf([_isInt, _isString]), rhs(statements[2])); | |
| 13258 hasType(assertAOf([_isInt, _isString]), rhs(statements[3])); | |
| 13259 hasType(assertAOf([_isInt, _isDynamic]), rhs(statements[4])); | |
| 13260 hasType(assertAOf([_isDynamic, _isDynamic]), rhs(statements[5])); | |
| 13261 } | |
| 13262 | |
| 13263 { | |
| 13264 List<Statement> statements = | |
| 13265 AstFinder.getStatementsInTopLevelFunction(unit, "test1"); | |
| 13266 hasType(assertAOf([_isInt, _isString]), rhs(statements[0])); | |
| 13267 hasType(assertAOf([_isInt, _isString]), rhs(statements[1])); | |
| 13268 } | |
| 13269 | |
| 13270 { | |
| 13271 List<Statement> statements = | |
| 13272 AstFinder.getStatementsInTopLevelFunction(unit, "test2"); | |
| 13273 hasType(assertBOf([_isString, _isInt]), rhs(statements[0])); | |
| 13274 hasType(assertBOf([_isString, _isInt]), rhs(statements[1])); | |
| 13275 hasType(assertBOf([_isString, _isInt]), rhs(statements[2])); | |
| 13276 hasType(assertBOf([_isString, _isInt]), rhs(statements[3])); | |
| 13277 hasType(assertBOf([_isString, _isDynamic]), rhs(statements[4])); | |
| 13278 hasType(assertBOf([_isDynamic, _isDynamic]), rhs(statements[5])); | |
| 13279 } | |
| 13280 | |
| 13281 { | |
| 13282 List<Statement> statements = | |
| 13283 AstFinder.getStatementsInTopLevelFunction(unit, "test3"); | |
| 13284 hasType(assertBOf([_isString, _isInt]), rhs(statements[0])); | |
| 13285 hasType(assertBOf([_isString, _isInt]), rhs(statements[1])); | |
| 13286 } | |
| 13287 | |
| 13288 { | |
| 13289 List<Statement> statements = | |
| 13290 AstFinder.getStatementsInTopLevelFunction(unit, "test4"); | |
| 13291 hasType(assertCOf([_isInt]), rhs(statements[0])); | |
| 13292 hasType(assertCOf([_isInt]), rhs(statements[1])); | |
| 13293 hasType(assertCOf([_isInt]), rhs(statements[2])); | |
| 13294 hasType(assertCOf([_isInt]), rhs(statements[3])); | |
| 13295 hasType(assertCOf([_isDynamic]), rhs(statements[4])); | |
| 13296 hasType(assertCOf([_isDynamic]), rhs(statements[5])); | |
| 13297 } | |
| 13298 | |
| 13299 { | |
| 13300 List<Statement> statements = | |
| 13301 AstFinder.getStatementsInTopLevelFunction(unit, "test5"); | |
| 13302 hasType(assertCOf([_isInt]), rhs(statements[0])); | |
| 13303 hasType(assertCOf([_isInt]), rhs(statements[1])); | |
| 13304 } | |
| 13305 | |
| 13306 { | |
| 13307 // The first type parameter is not constrained by the | |
| 13308 // context. We could choose a tighter type, but currently | |
| 13309 // we just use dynamic. | |
| 13310 List<Statement> statements = | |
| 13311 AstFinder.getStatementsInTopLevelFunction(unit, "test6"); | |
| 13312 hasType(assertDOf([_isDynamic, _isString]), rhs(statements[0])); | |
| 13313 hasType(assertDOf([_isDynamic, _isString]), rhs(statements[1])); | |
| 13314 hasType(assertDOf([_isInt, _isString]), rhs(statements[2])); | |
| 13315 hasType(assertDOf([_isString, _isString]), rhs(statements[3])); | |
| 13316 hasType(assertDOf([_isNum, _isDynamic]), rhs(statements[4])); | |
| 13317 hasType(assertDOf([_isDynamic, _isDynamic]), rhs(statements[5])); | |
| 13318 } | |
| 13319 | |
| 13320 { | |
| 13321 List<Statement> statements = | |
| 13322 AstFinder.getStatementsInTopLevelFunction(unit, "test7"); | |
| 13323 hasType(assertDOf([_isDynamic, _isString]), rhs(statements[0])); | |
| 13324 hasType(assertDOf([_isDynamic, _isString]), rhs(statements[1])); | |
| 13325 } | |
| 13326 | |
| 13327 { | |
| 13328 List<Statement> statements = | |
| 13329 AstFinder.getStatementsInTopLevelFunction(unit, "test8"); | |
| 13330 hasType(assertEOf([_isDynamic, _isDynamic]), rhs(statements[0])); | |
| 13331 } | |
| 13332 | |
| 13333 { | |
| 13334 List<Statement> statements = | |
| 13335 AstFinder.getStatementsInTopLevelFunction(unit, "test9"); | |
| 13336 hasType(assertFOf([_isInt, _isString]), rhs(statements[0])); | |
| 13337 hasType(assertFOf([_isInt, _isString]), rhs(statements[1])); | |
| 13338 hasType(assertFOf([_isInt, _isString]), rhs(statements[2])); | |
| 13339 hasType(assertFOf([_isInt, _isString]), rhs(statements[3])); | |
| 13340 hasType(assertFOf([_isInt, _isString]), rhs(statements[4])); | |
| 13341 hasType(assertFOf([_isInt, _isString]), rhs(statements[5])); | |
| 13342 } | |
| 13343 } | |
| 13344 | |
| 13345 void test_listLiteral_nested() { | |
| 13346 String code = r''' | |
| 13347 void main () { | |
| 13348 List<List<int>> l0 = [[]]; | |
| 13349 Iterable<List<int>> l1 = [[3]]; | |
| 13350 Iterable<List<int>> l2 = [[3], [4]]; | |
| 13351 List<List<int>> l3 = [["hello", 3], []]; | |
| 13352 } | |
| 13353 '''; | |
| 13354 CompilationUnit unit = resolveSource(code); | |
| 13355 List<Statement> statements = | |
| 13356 AstFinder.getStatementsInTopLevelFunction(unit, "main"); | |
| 13357 ListLiteral literal(int i) { | |
| 13358 VariableDeclarationStatement stmt = statements[i]; | |
| 13359 VariableDeclaration decl = stmt.variables.variables[0]; | |
| 13360 ListLiteral exp = decl.initializer; | |
| 13361 return exp; | |
| 13362 } | |
| 13363 | |
| 13364 Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt); | |
| 13365 Asserter<InterfaceType> assertListOfListOfInt = _isListOf(assertListOfInt); | |
| 13366 | |
| 13367 assertListOfListOfInt(literal(0).staticType); | |
| 13368 assertListOfListOfInt(literal(1).staticType); | |
| 13369 assertListOfListOfInt(literal(2).staticType); | |
| 13370 assertListOfListOfInt(literal(3).staticType); | |
| 13371 | |
| 13372 assertListOfInt(literal(1).elements[0].staticType); | |
| 13373 assertListOfInt(literal(2).elements[0].staticType); | |
| 13374 assertListOfInt(literal(3).elements[0].staticType); | |
| 13375 } | |
| 13376 | |
| 13377 void test_listLiteral_simple() { | |
| 13378 String code = r''' | |
| 13379 void main () { | |
| 13380 List<int> l0 = []; | |
| 13381 List<int> l1 = [3]; | |
| 13382 List<int> l2 = ["hello"]; | |
| 13383 List<int> l3 = ["hello", 3]; | |
| 13384 } | |
| 13385 '''; | |
| 13386 CompilationUnit unit = resolveSource(code); | |
| 13387 List<Statement> statements = | |
| 13388 AstFinder.getStatementsInTopLevelFunction(unit, "main"); | |
| 13389 DartType literal(int i) { | |
| 13390 VariableDeclarationStatement stmt = statements[i]; | |
| 13391 VariableDeclaration decl = stmt.variables.variables[0]; | |
| 13392 ListLiteral exp = decl.initializer; | |
| 13393 return exp.staticType; | |
| 13394 } | |
| 13395 | |
| 13396 Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt); | |
| 13397 | |
| 13398 assertListOfInt(literal(0)); | |
| 13399 assertListOfInt(literal(1)); | |
| 13400 assertListOfInt(literal(2)); | |
| 13401 assertListOfInt(literal(3)); | |
| 13402 } | |
| 13403 | |
| 13404 void test_listLiteral_simple_const() { | |
| 13405 String code = r''' | |
| 13406 void main () { | |
| 13407 const List<int> c0 = const []; | |
| 13408 const List<int> c1 = const [3]; | |
| 13409 const List<int> c2 = const ["hello"]; | |
| 13410 const List<int> c3 = const ["hello", 3]; | |
| 13411 } | |
| 13412 '''; | |
| 13413 CompilationUnit unit = resolveSource(code); | |
| 13414 List<Statement> statements = | |
| 13415 AstFinder.getStatementsInTopLevelFunction(unit, "main"); | |
| 13416 DartType literal(int i) { | |
| 13417 VariableDeclarationStatement stmt = statements[i]; | |
| 13418 VariableDeclaration decl = stmt.variables.variables[0]; | |
| 13419 ListLiteral exp = decl.initializer; | |
| 13420 return exp.staticType; | |
| 13421 } | |
| 13422 | |
| 13423 Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt); | |
| 13424 | |
| 13425 assertListOfInt(literal(0)); | |
| 13426 assertListOfInt(literal(1)); | |
| 13427 assertListOfInt(literal(2)); | |
| 13428 assertListOfInt(literal(3)); | |
| 13429 } | |
| 13430 | |
| 13431 void test_listLiteral_simple_disabled() { | |
| 13432 String code = r''' | |
| 13433 void main () { | |
| 13434 List<int> l0 = <num>[]; | |
| 13435 List<int> l1 = <num>[3]; | |
| 13436 List<int> l2 = <String>["hello"]; | |
| 13437 List<int> l3 = <dynamic>["hello", 3]; | |
| 13438 } | |
| 13439 '''; | |
| 13440 CompilationUnit unit = resolveSource(code); | |
| 13441 List<Statement> statements = | |
| 13442 AstFinder.getStatementsInTopLevelFunction(unit, "main"); | |
| 13443 DartType literal(int i) { | |
| 13444 VariableDeclarationStatement stmt = statements[i]; | |
| 13445 VariableDeclaration decl = stmt.variables.variables[0]; | |
| 13446 ListLiteral exp = decl.initializer; | |
| 13447 return exp.staticType; | |
| 13448 } | |
| 13449 | |
| 13450 _isListOf(_isNum)(literal(0)); | |
| 13451 _isListOf(_isNum)(literal(1)); | |
| 13452 _isListOf(_isString)(literal(2)); | |
| 13453 _isListOf(_isDynamic)(literal(3)); | |
| 13454 } | |
| 13455 | |
| 13456 void test_listLiteral_simple_subtype() { | |
| 13457 String code = r''' | |
| 13458 void main () { | |
| 13459 Iterable<int> l0 = []; | |
| 13460 Iterable<int> l1 = [3]; | |
| 13461 Iterable<int> l2 = ["hello"]; | |
| 13462 Iterable<int> l3 = ["hello", 3]; | |
| 13463 } | |
| 13464 '''; | |
| 13465 CompilationUnit unit = resolveSource(code); | |
| 13466 List<Statement> statements = | |
| 13467 AstFinder.getStatementsInTopLevelFunction(unit, "main"); | |
| 13468 DartType literal(int i) { | |
| 13469 VariableDeclarationStatement stmt = statements[i]; | |
| 13470 VariableDeclaration decl = stmt.variables.variables[0]; | |
| 13471 ListLiteral exp = decl.initializer; | |
| 13472 return exp.staticType; | |
| 13473 } | |
| 13474 | |
| 13475 Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt); | |
| 13476 | |
| 13477 assertListOfInt(literal(0)); | |
| 13478 assertListOfInt(literal(1)); | |
| 13479 assertListOfInt(literal(2)); | |
| 13480 assertListOfInt(literal(3)); | |
| 13481 } | |
| 13482 | |
| 13483 void test_mapLiteral_nested() { | |
| 13484 String code = r''' | |
| 13485 void main () { | |
| 13486 Map<int, List<String>> l0 = {}; | |
| 13487 Map<int, List<String>> l1 = {3: ["hello"]}; | |
| 13488 Map<int, List<String>> l2 = {"hello": ["hello"]}; | |
| 13489 Map<int, List<String>> l3 = {3: [3]}; | |
| 13490 Map<int, List<String>> l4 = {3:["hello"], "hello": [3]}; | |
| 13491 } | |
| 13492 '''; | |
| 13493 CompilationUnit unit = resolveSource(code); | |
| 13494 List<Statement> statements = | |
| 13495 AstFinder.getStatementsInTopLevelFunction(unit, "main"); | |
| 13496 MapLiteral literal(int i) { | |
| 13497 VariableDeclarationStatement stmt = statements[i]; | |
| 13498 VariableDeclaration decl = stmt.variables.variables[0]; | |
| 13499 MapLiteral exp = decl.initializer; | |
| 13500 return exp; | |
| 13501 } | |
| 13502 | |
| 13503 Asserter<InterfaceType> assertListOfString = _isListOf(_isString); | |
| 13504 Asserter<InterfaceType> assertMapOfIntToListOfString = | |
| 13505 _isMapOf(_isInt, assertListOfString); | |
| 13506 | |
| 13507 assertMapOfIntToListOfString(literal(0).staticType); | |
| 13508 assertMapOfIntToListOfString(literal(1).staticType); | |
| 13509 assertMapOfIntToListOfString(literal(2).staticType); | |
| 13510 assertMapOfIntToListOfString(literal(3).staticType); | |
| 13511 assertMapOfIntToListOfString(literal(4).staticType); | |
| 13512 | |
| 13513 assertListOfString(literal(1).entries[0].value.staticType); | |
| 13514 assertListOfString(literal(2).entries[0].value.staticType); | |
| 13515 assertListOfString(literal(3).entries[0].value.staticType); | |
| 13516 assertListOfString(literal(4).entries[0].value.staticType); | |
| 13517 } | |
| 13518 | |
| 13519 void test_mapLiteral_simple() { | |
| 13520 String code = r''' | |
| 13521 void main () { | |
| 13522 Map<int, String> l0 = {}; | |
| 13523 Map<int, String> l1 = {3: "hello"}; | |
| 13524 Map<int, String> l2 = {"hello": "hello"}; | |
| 13525 Map<int, String> l3 = {3: 3}; | |
| 13526 Map<int, String> l4 = {3:"hello", "hello": 3}; | |
| 13527 } | |
| 13528 '''; | |
| 13529 CompilationUnit unit = resolveSource(code); | |
| 13530 List<Statement> statements = | |
| 13531 AstFinder.getStatementsInTopLevelFunction(unit, "main"); | |
| 13532 DartType literal(int i) { | |
| 13533 VariableDeclarationStatement stmt = statements[i]; | |
| 13534 VariableDeclaration decl = stmt.variables.variables[0]; | |
| 13535 MapLiteral exp = decl.initializer; | |
| 13536 return exp.staticType; | |
| 13537 } | |
| 13538 | |
| 13539 Asserter<InterfaceType> assertMapOfIntToString = | |
| 13540 _isMapOf(_isInt, _isString); | |
| 13541 | |
| 13542 assertMapOfIntToString(literal(0)); | |
| 13543 assertMapOfIntToString(literal(1)); | |
| 13544 assertMapOfIntToString(literal(2)); | |
| 13545 assertMapOfIntToString(literal(3)); | |
| 13546 } | |
| 13547 | |
| 13548 void test_mapLiteral_simple_disabled() { | |
| 13549 String code = r''' | |
| 13550 void main () { | |
| 13551 Map<int, String> l0 = <int, dynamic>{}; | |
| 13552 Map<int, String> l1 = <int, dynamic>{3: "hello"}; | |
| 13553 Map<int, String> l2 = <int, dynamic>{"hello": "hello"}; | |
| 13554 Map<int, String> l3 = <int, dynamic>{3: 3}; | |
| 13555 } | |
| 13556 '''; | |
| 13557 CompilationUnit unit = resolveSource(code); | |
| 13558 List<Statement> statements = | |
| 13559 AstFinder.getStatementsInTopLevelFunction(unit, "main"); | |
| 13560 DartType literal(int i) { | |
| 13561 VariableDeclarationStatement stmt = statements[i]; | |
| 13562 VariableDeclaration decl = stmt.variables.variables[0]; | |
| 13563 MapLiteral exp = decl.initializer; | |
| 13564 return exp.staticType; | |
| 13565 } | |
| 13566 | |
| 13567 Asserter<InterfaceType> assertMapOfIntToDynamic = | |
| 13568 _isMapOf(_isInt, _isDynamic); | |
| 13569 | |
| 13570 assertMapOfIntToDynamic(literal(0)); | |
| 13571 assertMapOfIntToDynamic(literal(1)); | |
| 13572 assertMapOfIntToDynamic(literal(2)); | |
| 13573 assertMapOfIntToDynamic(literal(3)); | |
| 13574 } | |
| 13575 | |
| 13576 void test_methodDeclaration_body_propagation() { | |
| 13577 String code = r''' | |
| 13578 class A { | |
| 13579 List<String> m0(int x) => ["hello"]; | |
| 13580 List<String> m1(int x) {return [3];}; | |
| 13581 } | |
| 13582 '''; | |
| 13583 CompilationUnit unit = resolveSource(code); | |
| 13584 Expression methodReturnValue(String methodName) { | |
| 13585 MethodDeclaration method = | |
| 13586 AstFinder.getMethodInClass(unit, "A", methodName); | |
| 13587 FunctionBody body = method.body; | |
| 13588 if (body is ExpressionFunctionBody) { | |
| 13589 return body.expression; | |
| 13590 } else { | |
| 13591 Statement stmt = (body as BlockFunctionBody).block.statements[0]; | |
| 13592 return (stmt as ReturnStatement).expression; | |
| 13593 } | |
| 13594 } | |
| 13595 Asserter<InterfaceType> assertListOfString = _isListOf(_isString); | |
| 13596 assertListOfString(methodReturnValue("m0").staticType); | |
| 13597 assertListOfString(methodReturnValue("m1").staticType); | |
| 13598 } | |
| 13599 | |
| 13600 void test_redirectingConstructor_propagation() { | |
| 13601 String code = r''' | |
| 13602 class A { | |
| 13603 A() : this.named([]); | |
| 13604 A.named(List<String> x); | |
| 13605 } | |
| 13606 '''; | |
| 13607 CompilationUnit unit = resolveSource(code); | |
| 13608 | |
| 13609 ConstructorDeclaration constructor = | |
| 13610 AstFinder.getConstructorInClass(unit, "A", null); | |
| 13611 RedirectingConstructorInvocation invocation = constructor.initializers[0]; | |
| 13612 Expression exp = invocation.argumentList.arguments[0]; | |
| 13613 _isListOf(_isString)(exp.staticType); | |
| 13614 } | |
| 13615 | |
| 13616 void test_superConstructorInvocation_propagation() { | |
| 13617 String code = r''' | |
| 13618 class B { | |
| 13619 B(List<String>); | |
| 13620 } | |
| 13621 class A extends B { | |
| 13622 A() : super([]); | |
| 13623 } | |
| 13624 '''; | |
| 13625 CompilationUnit unit = resolveSource(code); | |
| 13626 | |
| 13627 ConstructorDeclaration constructor = | |
| 13628 AstFinder.getConstructorInClass(unit, "A", null); | |
| 13629 SuperConstructorInvocation invocation = constructor.initializers[0]; | |
| 13630 Expression exp = invocation.argumentList.arguments[0]; | |
| 13631 _isListOf(_isString)(exp.staticType); | |
| 13632 } | |
| 13633 | |
| 13634 void test_sync_star_method_propagation() { | |
| 13635 String code = r''' | |
| 13636 import "dart:async"; | |
| 13637 class A { | |
| 13638 Iterable f0() sync* { yield []; } | |
| 13639 Iterable f1() sync* { yield* new List(); } | |
| 13640 | |
| 13641 Iterable<List<int>> f2() sync* { yield []; } | |
| 13642 Iterable<List<int>> f3() sync* { yield* new List(); } | |
| 13643 } | |
| 13644 '''; | |
| 13645 CompilationUnit unit = resolveSource(code); | |
| 13646 | |
| 13647 void check(String name, Asserter<InterfaceType> typeTest) { | |
| 13648 MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name); | |
| 13649 BlockFunctionBody body = test.body; | |
| 13650 YieldStatement stmt = body.block.statements[0]; | |
| 13651 Expression exp = stmt.expression; | |
| 13652 typeTest(exp.staticType); | |
| 13653 } | |
| 13654 | |
| 13655 check("f0", _isListOf(_isDynamic)); | |
| 13656 check("f1", _isListOf(_isDynamic)); | |
| 13657 | |
| 13658 check("f2", _isListOf(_isInt)); | |
| 13659 check("f3", _isListOf(_isListOf(_isInt))); | |
| 13660 } | |
| 13661 | |
| 13662 void test_sync_star_propagation() { | |
| 13663 String code = r''' | |
| 13664 import "dart:async"; | |
| 13665 | |
| 13666 Iterable f0() sync* { yield []; } | |
| 13667 Iterable f1() sync* { yield* new List(); } | |
| 13668 | |
| 13669 Iterable<List<int>> f2() sync* { yield []; } | |
| 13670 Iterable<List<int>> f3() sync* { yield* new List(); } | |
| 13671 '''; | |
| 13672 CompilationUnit unit = resolveSource(code); | |
| 13673 | |
| 13674 void check(String name, Asserter<InterfaceType> typeTest) { | |
| 13675 FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name); | |
| 13676 BlockFunctionBody body = test.functionExpression.body; | |
| 13677 YieldStatement stmt = body.block.statements[0]; | |
| 13678 Expression exp = stmt.expression; | |
| 13679 typeTest(exp.staticType); | |
| 13680 } | |
| 13681 | |
| 13682 check("f0", _isListOf(_isDynamic)); | |
| 13683 check("f1", _isListOf(_isDynamic)); | |
| 13684 | |
| 13685 check("f2", _isListOf(_isInt)); | |
| 13686 check("f3", _isListOf(_isListOf(_isInt))); | |
| 13687 } | |
| 13688 } | |
| 13689 | |
| 13690 /** | |
| 13691 * Strong mode static analyzer end to end tests | |
| 13692 */ | |
| 13693 @reflectiveTest | |
| 13694 class StrongModeStaticTypeAnalyzer2Test extends _StaticTypeAnalyzer2TestShared { | |
| 13695 void fail_genericMethod_tearoff_instantiated() { | |
| 13696 _resolveTestUnit(r''' | |
| 13697 class C<E> { | |
| 13698 /*=T*/ f/*<T>*/(E e) => null; | |
| 13699 static /*=T*/ g/*<T>*/(/*=T*/ e) => null; | |
| 13700 static final h = g; | |
| 13701 } | |
| 13702 | |
| 13703 /*=T*/ topF/*<T>*/(/*=T*/ e) => null; | |
| 13704 var topG = topF; | |
| 13705 void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) { | |
| 13706 var c = new C<int>(); | |
| 13707 /*=T*/ lf/*<T>*/(/*=T*/ e) => null; | |
| 13708 var methodTearOffInst = c.f/*<int>*/; | |
| 13709 var staticTearOffInst = C.g/*<int>*/; | |
| 13710 var staticFieldTearOffInst = C.h/*<int>*/; | |
| 13711 var topFunTearOffInst = topF/*<int>*/; | |
| 13712 var topFieldTearOffInst = topG/*<int>*/; | |
| 13713 var localTearOffInst = lf/*<int>*/; | |
| 13714 var paramTearOffInst = pf/*<int>*/; | |
| 13715 } | |
| 13716 '''); | |
| 13717 _expectIdentifierType('methodTearOffInst', "(int) → int"); | |
| 13718 _expectIdentifierType('staticTearOffInst', "(int) → int"); | |
| 13719 _expectIdentifierType('staticFieldTearOffInst', "(int) → int"); | |
| 13720 _expectIdentifierType('topFunTearOffInst', "(int) → int"); | |
| 13721 _expectIdentifierType('topFieldTearOffInst', "(int) → int"); | |
| 13722 _expectIdentifierType('localTearOffInst', "(int) → int"); | |
| 13723 _expectIdentifierType('paramTearOffInst', "(int) → int"); | |
| 13724 } | |
| 13725 | |
| 13726 void setUp() { | |
| 13727 super.setUp(); | |
| 13728 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); | |
| 13729 options.strongMode = true; | |
| 13730 resetWithOptions(options); | |
| 13731 } | |
| 13732 | |
| 13733 void test_dynamicObjectGetter_hashCode() { | |
| 13734 String code = r''' | |
| 13735 main() { | |
| 13736 dynamic a = null; | |
| 13737 var foo = a.hashCode; | |
| 13738 } | |
| 13739 '''; | |
| 13740 _resolveTestUnit(code); | |
| 13741 _expectInitializerType('foo', 'int', isNull); | |
| 13742 } | |
| 13743 | |
| 13744 void test_dynamicObjectMethod_toString() { | |
| 13745 String code = r''' | |
| 13746 main() { | |
| 13747 dynamic a = null; | |
| 13748 var foo = a.toString(); | |
| 13749 } | |
| 13750 '''; | |
| 13751 _resolveTestUnit(code); | |
| 13752 _expectInitializerType('foo', 'String', isNull); | |
| 13753 } | |
| 13754 | |
| 13755 void test_genericFunction() { | |
| 13756 _resolveTestUnit(r'/*=T*/ f/*<T>*/(/*=T*/ x) => null;'); | |
| 13757 _expectFunctionType('f', '<T>(T) → T', | |
| 13758 elementTypeParams: '[T]', typeFormals: '[T]'); | |
| 13759 SimpleIdentifier f = _findIdentifier('f'); | |
| 13760 FunctionElementImpl e = f.staticElement; | |
| 13761 FunctionType ft = e.type.instantiate([typeProvider.stringType]); | |
| 13762 expect(ft.toString(), '(String) → String'); | |
| 13763 } | |
| 13764 | |
| 13765 void test_genericFunction_bounds() { | |
| 13766 _resolveTestUnit(r'/*=T*/ f/*<T extends num>*/(/*=T*/ x) => null;'); | |
| 13767 _expectFunctionType('f', '<T extends num>(T) → T', | |
| 13768 elementTypeParams: '[T extends num]', typeFormals: '[T extends num]'); | |
| 13769 } | |
| 13770 | |
| 13771 void test_genericFunction_parameter() { | |
| 13772 _resolveTestUnit(r''' | |
| 13773 void g(/*=T*/ f/*<T>*/(/*=T*/ x)) {} | |
| 13774 '''); | |
| 13775 _expectFunctionType('f', '<T>(T) → T', | |
| 13776 elementTypeParams: '[T]', typeFormals: '[T]'); | |
| 13777 SimpleIdentifier f = _findIdentifier('f'); | |
| 13778 ParameterElementImpl e = f.staticElement; | |
| 13779 FunctionType type = e.type; | |
| 13780 FunctionType ft = type.instantiate([typeProvider.stringType]); | |
| 13781 expect(ft.toString(), '(String) → String'); | |
| 13782 } | |
| 13783 | |
| 13784 void test_genericFunction_static() { | |
| 13785 _resolveTestUnit(r''' | |
| 13786 class C<E> { | |
| 13787 static /*=T*/ f/*<T>*/(/*=T*/ x) => null; | |
| 13788 } | |
| 13789 '''); | |
| 13790 _expectFunctionType('f', '<T>(T) → T', | |
| 13791 elementTypeParams: '[T]', typeFormals: '[T]'); | |
| 13792 SimpleIdentifier f = _findIdentifier('f'); | |
| 13793 MethodElementImpl e = f.staticElement; | |
| 13794 FunctionType ft = e.type.instantiate([typeProvider.stringType]); | |
| 13795 expect(ft.toString(), '(String) → String'); | |
| 13796 } | |
| 13797 | |
| 13798 void test_genericFunction_typedef() { | |
| 13799 String code = r''' | |
| 13800 typedef T F<T>(T x); | |
| 13801 F f0; | |
| 13802 | |
| 13803 class C { | |
| 13804 static F f1; | |
| 13805 F f2; | |
| 13806 void g(F f3) { | |
| 13807 F f4; | |
| 13808 f0(3); | |
| 13809 f1(3); | |
| 13810 f2(3); | |
| 13811 f3(3); | |
| 13812 f4(3); | |
| 13813 } | |
| 13814 } | |
| 13815 | |
| 13816 class D<S> { | |
| 13817 static F f1; | |
| 13818 F f2; | |
| 13819 void g(F f3) { | |
| 13820 F f4; | |
| 13821 f0(3); | |
| 13822 f1(3); | |
| 13823 f2(3); | |
| 13824 f3(3); | |
| 13825 f4(3); | |
| 13826 } | |
| 13827 } | |
| 13828 '''; | |
| 13829 _resolveTestUnit(code); | |
| 13830 | |
| 13831 checkBody(String className) { | |
| 13832 List<Statement> statements = | |
| 13833 AstFinder.getStatementsInMethod(testUnit, className, "g"); | |
| 13834 | |
| 13835 for (int i = 1; i <= 5; i++) { | |
| 13836 Expression exp = (statements[i] as ExpressionStatement).expression; | |
| 13837 expect(exp.staticType, typeProvider.dynamicType); | |
| 13838 } | |
| 13839 } | |
| 13840 | |
| 13841 checkBody("C"); | |
| 13842 checkBody("D"); | |
| 13843 } | |
| 13844 | |
| 13845 void test_genericMethod() { | |
| 13846 _resolveTestUnit(r''' | |
| 13847 class C<E> { | |
| 13848 List/*<T>*/ f/*<T>*/(E e) => null; | |
| 13849 } | |
| 13850 main() { | |
| 13851 C<String> cOfString; | |
| 13852 } | |
| 13853 '''); | |
| 13854 _expectFunctionType('f', '<T>(E) → List<T>', | |
| 13855 elementTypeParams: '[T]', | |
| 13856 typeParams: '[E]', | |
| 13857 typeArgs: '[E]', | |
| 13858 typeFormals: '[T]'); | |
| 13859 SimpleIdentifier c = _findIdentifier('cOfString'); | |
| 13860 FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type; | |
| 13861 expect(ft.toString(), '<T>(String) → List<T>'); | |
| 13862 ft = ft.instantiate([typeProvider.intType]); | |
| 13863 expect(ft.toString(), '(String) → List<int>'); | |
| 13864 expect('${ft.typeArguments}/${ft.typeParameters}', '[String, int]/[E, T]'); | |
| 13865 } | |
| 13866 | |
| 13867 void test_genericMethod_explicitTypeParams() { | |
| 13868 _resolveTestUnit(r''' | |
| 13869 class C<E> { | |
| 13870 List/*<T>*/ f/*<T>*/(E e) => null; | |
| 13871 } | |
| 13872 main() { | |
| 13873 C<String> cOfString; | |
| 13874 var x = cOfString.f/*<int>*/('hi'); | |
| 13875 } | |
| 13876 '''); | |
| 13877 MethodInvocation f = _findIdentifier('f/*<int>*/').parent; | |
| 13878 FunctionType ft = f.staticInvokeType; | |
| 13879 expect(ft.toString(), '(String) → List<int>'); | |
| 13880 expect('${ft.typeArguments}/${ft.typeParameters}', '[String, int]/[E, T]'); | |
| 13881 | |
| 13882 SimpleIdentifier x = _findIdentifier('x'); | |
| 13883 expect(x.staticType, | |
| 13884 typeProvider.listType.instantiate([typeProvider.intType])); | |
| 13885 } | |
| 13886 | |
| 13887 void test_genericMethod_functionExpressionInvocation_explicit() { | |
| 13888 _resolveTestUnit(r''' | |
| 13889 class C<E> { | |
| 13890 /*=T*/ f/*<T>*/(/*=T*/ e) => null; | |
| 13891 static /*=T*/ g/*<T>*/(/*=T*/ e) => null; | |
| 13892 static final h = g; | |
| 13893 } | |
| 13894 | |
| 13895 /*=T*/ topF/*<T>*/(/*=T*/ e) => null; | |
| 13896 var topG = topF; | |
| 13897 void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) { | |
| 13898 var c = new C<int>(); | |
| 13899 /*=T*/ lf/*<T>*/(/*=T*/ e) => null; | |
| 13900 | |
| 13901 var lambdaCall = (/*<E>*/(/*=E*/ e) => e)/*<int>*/(3); | |
| 13902 var methodCall = (c.f)/*<int>*/(3); | |
| 13903 var staticCall = (C.g)/*<int>*/(3); | |
| 13904 var staticFieldCall = (C.h)/*<int>*/(3); | |
| 13905 var topFunCall = (topF)/*<int>*/(3); | |
| 13906 var topFieldCall = (topG)/*<int>*/(3); | |
| 13907 var localCall = (lf)/*<int>*/(3); | |
| 13908 var paramCall = (pf)/*<int>*/(3); | |
| 13909 } | |
| 13910 '''); | |
| 13911 _expectIdentifierType('methodCall', "int"); | |
| 13912 _expectIdentifierType('staticCall', "int"); | |
| 13913 _expectIdentifierType('staticFieldCall', "int"); | |
| 13914 _expectIdentifierType('topFunCall', "int"); | |
| 13915 _expectIdentifierType('topFieldCall', "int"); | |
| 13916 _expectIdentifierType('localCall', "int"); | |
| 13917 _expectIdentifierType('paramCall', "int"); | |
| 13918 _expectIdentifierType('lambdaCall', "int"); | |
| 13919 } | |
| 13920 | |
| 13921 void test_genericMethod_functionExpressionInvocation_inferred() { | |
| 13922 _resolveTestUnit(r''' | |
| 13923 class C<E> { | |
| 13924 /*=T*/ f/*<T>*/(/*=T*/ e) => null; | |
| 13925 static /*=T*/ g/*<T>*/(/*=T*/ e) => null; | |
| 13926 static final h = g; | |
| 13927 } | |
| 13928 | |
| 13929 /*=T*/ topF/*<T>*/(/*=T*/ e) => null; | |
| 13930 var topG = topF; | |
| 13931 void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) { | |
| 13932 var c = new C<int>(); | |
| 13933 /*=T*/ lf/*<T>*/(/*=T*/ e) => null; | |
| 13934 | |
| 13935 var lambdaCall = (/*<E>*/(/*=E*/ e) => e)(3); | |
| 13936 var methodCall = (c.f)(3); | |
| 13937 var staticCall = (C.g)(3); | |
| 13938 var staticFieldCall = (C.h)(3); | |
| 13939 var topFunCall = (topF)(3); | |
| 13940 var topFieldCall = (topG)(3); | |
| 13941 var localCall = (lf)(3); | |
| 13942 var paramCall = (pf)(3); | |
| 13943 } | |
| 13944 '''); | |
| 13945 _expectIdentifierType('methodCall', "int"); | |
| 13946 _expectIdentifierType('staticCall', "int"); | |
| 13947 _expectIdentifierType('staticFieldCall', "int"); | |
| 13948 _expectIdentifierType('topFunCall', "int"); | |
| 13949 _expectIdentifierType('topFieldCall', "int"); | |
| 13950 _expectIdentifierType('localCall', "int"); | |
| 13951 _expectIdentifierType('paramCall', "int"); | |
| 13952 _expectIdentifierType('lambdaCall', "int"); | |
| 13953 } | |
| 13954 | |
| 13955 void test_genericMethod_functionInvocation_explicit() { | |
| 13956 _resolveTestUnit(r''' | |
| 13957 class C<E> { | |
| 13958 /*=T*/ f/*<T>*/(/*=T*/ e) => null; | |
| 13959 static /*=T*/ g/*<T>*/(/*=T*/ e) => null; | |
| 13960 static final h = g; | |
| 13961 } | |
| 13962 | |
| 13963 /*=T*/ topF/*<T>*/(/*=T*/ e) => null; | |
| 13964 var topG = topF; | |
| 13965 void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) { | |
| 13966 var c = new C<int>(); | |
| 13967 /*=T*/ lf/*<T>*/(/*=T*/ e) => null; | |
| 13968 var methodCall = c.f/*<int>*/(3); | |
| 13969 var staticCall = C.g/*<int>*/(3); | |
| 13970 var staticFieldCall = C.h/*<int>*/(3); | |
| 13971 var topFunCall = topF/*<int>*/(3); | |
| 13972 var topFieldCall = topG/*<int>*/(3); | |
| 13973 var localCall = lf/*<int>*/(3); | |
| 13974 var paramCall = pf/*<int>*/(3); | |
| 13975 } | |
| 13976 '''); | |
| 13977 _expectIdentifierType('methodCall', "int"); | |
| 13978 _expectIdentifierType('staticCall', "int"); | |
| 13979 _expectIdentifierType('staticFieldCall', "int"); | |
| 13980 _expectIdentifierType('topFunCall', "int"); | |
| 13981 _expectIdentifierType('topFieldCall', "int"); | |
| 13982 _expectIdentifierType('localCall', "int"); | |
| 13983 _expectIdentifierType('paramCall', "int"); | |
| 13984 } | |
| 13985 | |
| 13986 void test_genericMethod_functionInvocation_inferred() { | |
| 13987 _resolveTestUnit(r''' | |
| 13988 class C<E> { | |
| 13989 /*=T*/ f/*<T>*/(/*=T*/ e) => null; | |
| 13990 static /*=T*/ g/*<T>*/(/*=T*/ e) => null; | |
| 13991 static final h = g; | |
| 13992 } | |
| 13993 | |
| 13994 /*=T*/ topF/*<T>*/(/*=T*/ e) => null; | |
| 13995 var topG = topF; | |
| 13996 void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) { | |
| 13997 var c = new C<int>(); | |
| 13998 /*=T*/ lf/*<T>*/(/*=T*/ e) => null; | |
| 13999 var methodCall = c.f(3); | |
| 14000 var staticCall = C.g(3); | |
| 14001 var staticFieldCall = C.h(3); | |
| 14002 var topFunCall = topF(3); | |
| 14003 var topFieldCall = topG(3); | |
| 14004 var localCall = lf(3); | |
| 14005 var paramCall = pf(3); | |
| 14006 } | |
| 14007 '''); | |
| 14008 _expectIdentifierType('methodCall', "int"); | |
| 14009 _expectIdentifierType('staticCall', "int"); | |
| 14010 _expectIdentifierType('staticFieldCall', "int"); | |
| 14011 _expectIdentifierType('topFunCall', "int"); | |
| 14012 _expectIdentifierType('topFieldCall', "int"); | |
| 14013 _expectIdentifierType('localCall', "int"); | |
| 14014 _expectIdentifierType('paramCall', "int"); | |
| 14015 } | |
| 14016 | |
| 14017 void test_genericMethod_functionTypedParameter() { | |
| 14018 _resolveTestUnit(r''' | |
| 14019 class C<E> { | |
| 14020 List/*<T>*/ f/*<T>*/(/*=T*/ f(E e)) => null; | |
| 14021 } | |
| 14022 main() { | |
| 14023 C<String> cOfString; | |
| 14024 } | |
| 14025 '''); | |
| 14026 _expectFunctionType('f', '<T>((E) → T) → List<T>', | |
| 14027 elementTypeParams: '[T]', | |
| 14028 typeParams: '[E]', | |
| 14029 typeArgs: '[E]', | |
| 14030 typeFormals: '[T]'); | |
| 14031 | |
| 14032 SimpleIdentifier c = _findIdentifier('cOfString'); | |
| 14033 FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type; | |
| 14034 expect(ft.toString(), '<T>((String) → T) → List<T>'); | |
| 14035 ft = ft.instantiate([typeProvider.intType]); | |
| 14036 expect(ft.toString(), '((String) → int) → List<int>'); | |
| 14037 } | |
| 14038 | |
| 14039 void test_genericMethod_implicitDynamic() { | |
| 14040 // Regression test for: | |
| 14041 // https://github.com/dart-lang/sdk/issues/25100#issuecomment-162047588 | |
| 14042 // These should not cause any hints or warnings. | |
| 14043 _resolveTestUnit(r''' | |
| 14044 class List<E> { | |
| 14045 /*=T*/ map/*<T>*/(/*=T*/ f(E e)) => null; | |
| 14046 } | |
| 14047 void foo() { | |
| 14048 List list = null; | |
| 14049 list.map((e) => e); | |
| 14050 list.map((e) => 3); | |
| 14051 }'''); | |
| 14052 _expectIdentifierType('map((e) => e);', '<T>((dynamic) → T) → T', isNull); | |
| 14053 _expectIdentifierType('map((e) => 3);', '<T>((dynamic) → T) → T', isNull); | |
| 14054 | |
| 14055 MethodInvocation m1 = _findIdentifier('map((e) => e);').parent; | |
| 14056 expect(m1.staticInvokeType.toString(), '((dynamic) → dynamic) → dynamic'); | |
| 14057 MethodInvocation m2 = _findIdentifier('map((e) => 3);').parent; | |
| 14058 expect(m2.staticInvokeType.toString(), '((dynamic) → int) → int'); | |
| 14059 } | |
| 14060 | |
| 14061 void test_genericMethod_max_doubleDouble() { | |
| 14062 String code = r''' | |
| 14063 import 'dart:math'; | |
| 14064 main() { | |
| 14065 var foo = max(1.0, 2.0); | |
| 14066 } | |
| 14067 '''; | |
| 14068 _resolveTestUnit(code); | |
| 14069 _expectInitializerType('foo', 'double', isNull); | |
| 14070 } | |
| 14071 | |
| 14072 void test_genericMethod_max_doubleDouble_prefixed() { | |
| 14073 String code = r''' | |
| 14074 import 'dart:math' as math; | |
| 14075 main() { | |
| 14076 var foo = math.max(1.0, 2.0); | |
| 14077 } | |
| 14078 '''; | |
| 14079 _resolveTestUnit(code); | |
| 14080 _expectInitializerType('foo', 'double', isNull); | |
| 14081 } | |
| 14082 | |
| 14083 void test_genericMethod_max_doubleInt() { | |
| 14084 String code = r''' | |
| 14085 import 'dart:math'; | |
| 14086 main() { | |
| 14087 var foo = max(1.0, 2); | |
| 14088 } | |
| 14089 '''; | |
| 14090 _resolveTestUnit(code); | |
| 14091 _expectInitializerType('foo', 'num', isNull); | |
| 14092 } | |
| 14093 | |
| 14094 void test_genericMethod_max_intDouble() { | |
| 14095 String code = r''' | |
| 14096 import 'dart:math'; | |
| 14097 main() { | |
| 14098 var foo = max(1, 2.0); | |
| 14099 } | |
| 14100 '''; | |
| 14101 _resolveTestUnit(code); | |
| 14102 _expectInitializerType('foo', 'num', isNull); | |
| 14103 } | |
| 14104 | |
| 14105 void test_genericMethod_max_intInt() { | |
| 14106 String code = r''' | |
| 14107 import 'dart:math'; | |
| 14108 main() { | |
| 14109 var foo = max(1, 2); | |
| 14110 } | |
| 14111 '''; | |
| 14112 _resolveTestUnit(code); | |
| 14113 _expectInitializerType('foo', 'int', isNull); | |
| 14114 } | |
| 14115 | |
| 14116 void test_genericMethod_nestedBound() { | |
| 14117 String code = r''' | |
| 14118 class Foo<T extends num> { | |
| 14119 void method/*<U extends T>*/(dynamic/*=U*/ u) { | |
| 14120 u.abs(); | |
| 14121 } | |
| 14122 } | |
| 14123 '''; | |
| 14124 // Just validate that there is no warning on the call to `.abs()`. | |
| 14125 _resolveTestUnit(code); | |
| 14126 } | |
| 14127 | |
| 14128 void test_genericMethod_nestedCapture() { | |
| 14129 _resolveTestUnit(r''' | |
| 14130 class C<T> { | |
| 14131 /*=T*/ f/*<S>*/(/*=S*/ x) { | |
| 14132 new C<S>().f/*<int>*/(3); | |
| 14133 new C<S>().f; // tear-off | |
| 14134 return null; | |
| 14135 } | |
| 14136 } | |
| 14137 '''); | |
| 14138 MethodInvocation f = _findIdentifier('f/*<int>*/(3);').parent; | |
| 14139 expect(f.staticInvokeType.toString(), '(int) → S'); | |
| 14140 FunctionType ft = f.staticInvokeType; | |
| 14141 expect('${ft.typeArguments}/${ft.typeParameters}', '[S, int]/[T, S]'); | |
| 14142 | |
| 14143 _expectIdentifierType('f;', '<S₀>(S₀) → S'); | |
| 14144 } | |
| 14145 | |
| 14146 void test_genericMethod_nestedFunctions() { | |
| 14147 _resolveTestUnit(r''' | |
| 14148 /*=S*/ f/*<S>*/(/*=S*/ x) { | |
| 14149 g/*<S>*/(/*=S*/ x) => f; | |
| 14150 return null; | |
| 14151 } | |
| 14152 '''); | |
| 14153 _expectIdentifierType('f', '<S>(S) → S'); | |
| 14154 _expectIdentifierType('g', '<S>(S) → dynamic'); | |
| 14155 } | |
| 14156 | |
| 14157 void test_genericMethod_override() { | |
| 14158 _resolveTestUnit(r''' | |
| 14159 class C { | |
| 14160 /*=T*/ f/*<T>*/(/*=T*/ x) => null; | |
| 14161 } | |
| 14162 class D extends C { | |
| 14163 /*=T*/ f/*<T>*/(/*=T*/ x) => null; // from D | |
| 14164 } | |
| 14165 '''); | |
| 14166 _expectFunctionType('f/*<T>*/(/*=T*/ x) => null; // from D', '<T>(T) → T', | |
| 14167 elementTypeParams: '[T]', typeFormals: '[T]'); | |
| 14168 SimpleIdentifier f = | |
| 14169 _findIdentifier('f/*<T>*/(/*=T*/ x) => null; // from D'); | |
| 14170 MethodElementImpl e = f.staticElement; | |
| 14171 FunctionType ft = e.type.instantiate([typeProvider.stringType]); | |
| 14172 expect(ft.toString(), '(String) → String'); | |
| 14173 } | |
| 14174 | |
| 14175 void test_genericMethod_override_bounds() { | |
| 14176 _resolveTestUnit(r''' | |
| 14177 class A {} | |
| 14178 class B extends A {} | |
| 14179 class C { | |
| 14180 /*=T*/ f/*<T extends B>*/(/*=T*/ x) => null; | |
| 14181 } | |
| 14182 class D extends C { | |
| 14183 /*=T*/ f/*<T extends A>*/(/*=T*/ x) => null; | |
| 14184 } | |
| 14185 '''); | |
| 14186 } | |
| 14187 | |
| 14188 void test_genericMethod_override_invalidReturnType() { | |
| 14189 Source source = addSource(r''' | |
| 14190 class C { | |
| 14191 Iterable/*<T>*/ f/*<T>*/(/*=T*/ x) => null; | |
| 14192 } | |
| 14193 class D extends C { | |
| 14194 String f/*<S>*/(/*=S*/ x) => null; | |
| 14195 }'''); | |
| 14196 // TODO(jmesserly): we can't use assertErrors because STRONG_MODE_* errors | |
| 14197 // from CodeChecker don't have working equality. | |
| 14198 List<AnalysisError> errors = analysisContext2.computeErrors(source); | |
| 14199 | |
| 14200 // Sort errors by name. | |
| 14201 errors.sort((AnalysisError e1, AnalysisError e2) => | |
| 14202 e1.errorCode.name.compareTo(e2.errorCode.name)); | |
| 14203 | |
| 14204 expect(errors.map((e) => e.errorCode.name), [ | |
| 14205 'INVALID_METHOD_OVERRIDE_RETURN_TYPE', | |
| 14206 'STRONG_MODE_INVALID_METHOD_OVERRIDE' | |
| 14207 ]); | |
| 14208 expect(errors[0].message, contains('Iterable<S>'), | |
| 14209 reason: 'errors should be in terms of the type parameters ' | |
| 14210 'at the error location'); | |
| 14211 verify([source]); | |
| 14212 } | |
| 14213 | |
| 14214 void test_genericMethod_override_invalidTypeParamBounds() { | |
| 14215 Source source = addSource(r''' | |
| 14216 class A {} | |
| 14217 class B extends A {} | |
| 14218 class C { | |
| 14219 /*=T*/ f/*<T extends A>*/(/*=T*/ x) => null; | |
| 14220 } | |
| 14221 class D extends C { | |
| 14222 /*=T*/ f/*<T extends B>*/(/*=T*/ x) => null; | |
| 14223 }'''); | |
| 14224 // TODO(jmesserly): this is modified code from assertErrors, which we can't | |
| 14225 // use directly because STRONG_MODE_* errors don't have working equality. | |
| 14226 List<AnalysisError> errors = analysisContext2.computeErrors(source); | |
| 14227 List errorNames = errors.map((e) => e.errorCode.name).toList(); | |
| 14228 expect(errorNames, hasLength(2)); | |
| 14229 expect(errorNames, contains('STRONG_MODE_INVALID_METHOD_OVERRIDE')); | |
| 14230 expect( | |
| 14231 errorNames, contains('INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND')); | |
| 14232 verify([source]); | |
| 14233 } | |
| 14234 | |
| 14235 void test_genericMethod_override_invalidTypeParamCount() { | |
| 14236 Source source = addSource(r''' | |
| 14237 class C { | |
| 14238 /*=T*/ f/*<T>*/(/*=T*/ x) => null; | |
| 14239 } | |
| 14240 class D extends C { | |
| 14241 /*=S*/ f/*<T, S>*/(/*=T*/ x) => null; | |
| 14242 }'''); | |
| 14243 // TODO(jmesserly): we can't use assertErrors because STRONG_MODE_* errors | |
| 14244 // from CodeChecker don't have working equality. | |
| 14245 List<AnalysisError> errors = analysisContext2.computeErrors(source); | |
| 14246 expect(errors.map((e) => e.errorCode.name), [ | |
| 14247 'STRONG_MODE_INVALID_METHOD_OVERRIDE', | |
| 14248 'INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS' | |
| 14249 ]); | |
| 14250 verify([source]); | |
| 14251 } | |
| 14252 | |
| 14253 void test_genericMethod_propagatedType_promotion() { | |
| 14254 // Regression test for: | |
| 14255 // https://github.com/dart-lang/sdk/issues/25340 | |
| 14256 | |
| 14257 // Note, after https://github.com/dart-lang/sdk/issues/25486 the original | |
| 14258 // example won't work, as we now compute a static type and therefore discard | |
| 14259 // the propagated type. So a new test was created that doesn't run under | |
| 14260 // strong mode. | |
| 14261 _resolveTestUnit(r''' | |
| 14262 abstract class Iter { | |
| 14263 List/*<S>*/ map/*<S>*/(/*=S*/ f(x)); | |
| 14264 } | |
| 14265 class C {} | |
| 14266 C toSpan(dynamic element) { | |
| 14267 if (element is Iter) { | |
| 14268 var y = element.map(toSpan); | |
| 14269 } | |
| 14270 return null; | |
| 14271 }'''); | |
| 14272 _expectIdentifierType('y = ', 'List<C>', isNull); | |
| 14273 } | |
| 14274 | |
| 14275 void test_genericMethod_tearoff() { | |
| 14276 _resolveTestUnit(r''' | |
| 14277 class C<E> { | |
| 14278 /*=T*/ f/*<T>*/(E e) => null; | |
| 14279 static /*=T*/ g/*<T>*/(/*=T*/ e) => null; | |
| 14280 static final h = g; | |
| 14281 } | |
| 14282 | |
| 14283 /*=T*/ topF/*<T>*/(/*=T*/ e) => null; | |
| 14284 var topG = topF; | |
| 14285 void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) { | |
| 14286 var c = new C<int>(); | |
| 14287 /*=T*/ lf/*<T>*/(/*=T*/ e) => null; | |
| 14288 var methodTearOff = c.f; | |
| 14289 var staticTearOff = C.g; | |
| 14290 var staticFieldTearOff = C.h; | |
| 14291 var topFunTearOff = topF; | |
| 14292 var topFieldTearOff = topG; | |
| 14293 var localTearOff = lf; | |
| 14294 var paramTearOff = pf; | |
| 14295 } | |
| 14296 '''); | |
| 14297 _expectIdentifierType('methodTearOff', "<T>(int) → T"); | |
| 14298 _expectIdentifierType('staticTearOff', "<T>(T) → T"); | |
| 14299 _expectIdentifierType('staticFieldTearOff', "<T>(T) → T"); | |
| 14300 _expectIdentifierType('topFunTearOff', "<T>(T) → T"); | |
| 14301 _expectIdentifierType('topFieldTearOff', "<T>(T) → T"); | |
| 14302 _expectIdentifierType('localTearOff', "<T>(T) → T"); | |
| 14303 _expectIdentifierType('paramTearOff', "<T>(T) → T"); | |
| 14304 } | |
| 14305 | |
| 14306 void test_genericMethod_then() { | |
| 14307 String code = r''' | |
| 14308 import 'dart:async'; | |
| 14309 String toString(int x) => x.toString(); | |
| 14310 main() { | |
| 14311 Future<int> bar = null; | |
| 14312 var foo = bar.then(toString); | |
| 14313 } | |
| 14314 '''; | |
| 14315 _resolveTestUnit(code); | |
| 14316 _expectInitializerType('foo', 'Future<String>', isNull); | |
| 14317 } | |
| 14318 | |
| 14319 void test_genericMethod_then_prefixed() { | |
| 14320 String code = r''' | |
| 14321 import 'dart:async' as async; | |
| 14322 String toString(int x) => x.toString(); | |
| 14323 main() { | |
| 14324 async.Future<int> bar = null; | |
| 14325 var foo = bar.then(toString); | |
| 14326 } | |
| 14327 '''; | |
| 14328 _resolveTestUnit(code); | |
| 14329 _expectInitializerType('foo', 'Future<String>', isNull); | |
| 14330 } | |
| 14331 | |
| 14332 void test_genericMethod_then_propagatedType() { | |
| 14333 // Regression test for https://github.com/dart-lang/sdk/issues/25482. | |
| 14334 String code = r''' | |
| 14335 import 'dart:async'; | |
| 14336 void main() { | |
| 14337 Future<String> p; | |
| 14338 var foo = p.then((r) => new Future<String>.value(3)); | |
| 14339 } | |
| 14340 '''; | |
| 14341 // This should produce no hints or warnings. | |
| 14342 _resolveTestUnit(code); | |
| 14343 _expectInitializerType('foo', 'Future<String>', isNull); | |
| 14344 } | |
| 14345 | |
| 14346 void test_implicitBounds() { | |
| 14347 String code = r''' | |
| 14348 class A<T> {} | |
| 14349 | |
| 14350 class B<T extends num> {} | |
| 14351 | |
| 14352 class C<S extends int, T extends B<S>, U extends B> {} | |
| 14353 | |
| 14354 void test() { | |
| 14355 // | |
| 14356 A ai; | |
| 14357 B bi; | |
| 14358 C ci; | |
| 14359 var aa = new A(); | |
| 14360 var bb = new B(); | |
| 14361 var cc = new C(); | |
| 14362 } | |
| 14363 '''; | |
| 14364 _resolveTestUnit(code); | |
| 14365 _expectIdentifierType('ai', "A<dynamic>"); | |
| 14366 _expectIdentifierType('bi', "B<num>"); | |
| 14367 _expectIdentifierType('ci', "C<int, B<int>, B<num>>"); | |
| 14368 _expectIdentifierType('aa', "A<dynamic>"); | |
| 14369 _expectIdentifierType('bb', "B<num>"); | |
| 14370 _expectIdentifierType('cc', "C<int, B<int>, B<num>>"); | |
| 14371 } | |
| 14372 | |
| 14373 void test_setterWithDynamicTypeIsError() { | |
| 14374 Source source = addSource(r''' | |
| 14375 class A { | |
| 14376 dynamic set f(String s) => null; | |
| 14377 } | |
| 14378 dynamic set g(int x) => null; | |
| 14379 '''); | |
| 14380 computeLibrarySourceErrors(source); | |
| 14381 assertErrors(source, [ | |
| 14382 StaticWarningCode.NON_VOID_RETURN_FOR_SETTER, | |
| 14383 StaticWarningCode.NON_VOID_RETURN_FOR_SETTER | |
| 14384 ]); | |
| 14385 verify([source]); | |
| 14386 } | |
| 14387 | |
| 14388 void test_setterWithExplicitVoidType_returningVoid() { | |
| 14389 Source source = addSource(r''' | |
| 14390 void returnsVoid() {} | |
| 14391 class A { | |
| 14392 void set f(String s) => returnsVoid(); | |
| 14393 } | |
| 14394 void set g(int x) => returnsVoid(); | |
| 14395 '''); | |
| 14396 computeLibrarySourceErrors(source); | |
| 14397 assertNoErrors(source); | |
| 14398 verify([source]); | |
| 14399 } | |
| 14400 | |
| 14401 void test_setterWithNoVoidType() { | |
| 14402 Source source = addSource(r''' | |
| 14403 class A { | |
| 14404 set f(String s) { | |
| 14405 return '42'; | |
| 14406 } | |
| 14407 } | |
| 14408 set g(int x) => 42; | |
| 14409 '''); | |
| 14410 computeLibrarySourceErrors(source); | |
| 14411 assertErrors(source, [ | |
| 14412 StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, | |
| 14413 StaticTypeWarningCode.RETURN_OF_INVALID_TYPE | |
| 14414 ]); | |
| 14415 verify([source]); | |
| 14416 } | |
| 14417 | |
| 14418 void test_setterWithNoVoidType_returningVoid() { | |
| 14419 Source source = addSource(r''' | |
| 14420 void returnsVoid() {} | |
| 14421 class A { | |
| 14422 set f(String s) => returnsVoid(); | |
| 14423 } | |
| 14424 set g(int x) => returnsVoid(); | |
| 14425 '''); | |
| 14426 computeLibrarySourceErrors(source); | |
| 14427 assertNoErrors(source); | |
| 14428 verify([source]); | |
| 14429 } | |
| 14430 | |
| 14431 void test_setterWithOtherTypeIsError() { | |
| 14432 Source source = addSource(r''' | |
| 14433 class A { | |
| 14434 String set f(String s) => null; | |
| 14435 } | |
| 14436 Object set g(x) => null; | |
| 14437 '''); | |
| 14438 computeLibrarySourceErrors(source); | |
| 14439 assertErrors(source, [ | |
| 14440 StaticWarningCode.NON_VOID_RETURN_FOR_SETTER, | |
| 14441 StaticWarningCode.NON_VOID_RETURN_FOR_SETTER | |
| 14442 ]); | |
| 14443 verify([source]); | |
| 14444 } | |
| 14445 | |
| 14446 void test_ternaryOperator_null_left() { | |
| 14447 String code = r''' | |
| 14448 main() { | |
| 14449 var foo = (true) ? null : 3; | |
| 14450 } | |
| 14451 '''; | |
| 14452 _resolveTestUnit(code); | |
| 14453 _expectInitializerType('foo', 'int', isNull); | |
| 14454 } | |
| 14455 | |
| 14456 void test_ternaryOperator_null_right() { | |
| 14457 String code = r''' | |
| 14458 main() { | |
| 14459 var foo = (true) ? 3 : null; | |
| 14460 } | |
| 14461 '''; | |
| 14462 _resolveTestUnit(code); | |
| 14463 _expectInitializerType('foo', 'int', isNull); | |
| 14464 } | |
| 14465 } | |
| 14466 | |
| 14467 @reflectiveTest | |
| 14468 class StrongModeTypePropagationTest extends ResolverTestCase { | |
| 14469 @override | |
| 14470 void setUp() { | |
| 14471 super.setUp(); | |
| 14472 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); | |
| 14473 options.strongMode = true; | |
| 14474 resetWithOptions(options); | |
| 14475 } | |
| 14476 | |
| 14477 void test_foreachInference_dynamic_disabled() { | |
| 14478 String code = r''' | |
| 14479 main() { | |
| 14480 var list = <int>[]; | |
| 14481 for (dynamic v in list) { | |
| 14482 v; // marker | |
| 14483 } | |
| 14484 }'''; | |
| 14485 _assertPropagatedIterationType( | |
| 14486 code, typeProvider.dynamicType, typeProvider.intType); | |
| 14487 _assertTypeOfMarkedExpression( | |
| 14488 code, typeProvider.dynamicType, typeProvider.intType); | |
| 14489 } | |
| 14490 | |
| 14491 void test_foreachInference_reusedVar_disabled() { | |
| 14492 String code = r''' | |
| 14493 main() { | |
| 14494 var list = <int>[]; | |
| 14495 var v; | |
| 14496 for (v in list) { | |
| 14497 v; // marker | |
| 14498 } | |
| 14499 }'''; | |
| 14500 _assertPropagatedIterationType( | |
| 14501 code, typeProvider.dynamicType, typeProvider.intType); | |
| 14502 _assertTypeOfMarkedExpression( | |
| 14503 code, typeProvider.dynamicType, typeProvider.intType); | |
| 14504 } | |
| 14505 | |
| 14506 void test_foreachInference_var() { | |
| 14507 String code = r''' | |
| 14508 main() { | |
| 14509 var list = <int>[]; | |
| 14510 for (var v in list) { | |
| 14511 v; // marker | |
| 14512 } | |
| 14513 }'''; | |
| 14514 _assertPropagatedIterationType(code, typeProvider.intType, null); | |
| 14515 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 14516 } | |
| 14517 | |
| 14518 void test_foreachInference_var_iterable() { | |
| 14519 String code = r''' | |
| 14520 main() { | |
| 14521 Iterable<int> list = <int>[]; | |
| 14522 for (var v in list) { | |
| 14523 v; // marker | |
| 14524 } | |
| 14525 }'''; | |
| 14526 _assertPropagatedIterationType(code, typeProvider.intType, null); | |
| 14527 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 14528 } | |
| 14529 | |
| 14530 void test_foreachInference_var_stream() { | |
| 14531 String code = r''' | |
| 14532 import 'dart:async'; | |
| 14533 main() async { | |
| 14534 Stream<int> stream = null; | |
| 14535 await for (var v in stream) { | |
| 14536 v; // marker | |
| 14537 } | |
| 14538 }'''; | |
| 14539 _assertPropagatedIterationType(code, typeProvider.intType, null); | |
| 14540 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 14541 } | |
| 14542 | |
| 14543 void test_localVariableInference_bottom_disabled() { | |
| 14544 String code = r''' | |
| 14545 main() { | |
| 14546 var v = null; | |
| 14547 v; // marker | |
| 14548 }'''; | |
| 14549 _assertPropagatedAssignedType(code, typeProvider.dynamicType, null); | |
| 14550 _assertTypeOfMarkedExpression(code, typeProvider.dynamicType, null); | |
| 14551 } | |
| 14552 | |
| 14553 void test_localVariableInference_constant() { | |
| 14554 String code = r''' | |
| 14555 main() { | |
| 14556 var v = 3; | |
| 14557 v; // marker | |
| 14558 }'''; | |
| 14559 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 14560 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 14561 } | |
| 14562 | |
| 14563 void test_localVariableInference_declaredType_disabled() { | |
| 14564 String code = r''' | |
| 14565 main() { | |
| 14566 dynamic v = 3; | |
| 14567 v; // marker | |
| 14568 }'''; | |
| 14569 _assertPropagatedAssignedType( | |
| 14570 code, typeProvider.dynamicType, typeProvider.intType); | |
| 14571 _assertTypeOfMarkedExpression( | |
| 14572 code, typeProvider.dynamicType, typeProvider.intType); | |
| 14573 } | |
| 14574 | |
| 14575 void test_localVariableInference_noInitializer_disabled() { | |
| 14576 String code = r''' | |
| 14577 main() { | |
| 14578 var v; | |
| 14579 v = 3; | |
| 14580 v; // marker | |
| 14581 }'''; | |
| 14582 _assertPropagatedAssignedType( | |
| 14583 code, typeProvider.dynamicType, typeProvider.intType); | |
| 14584 _assertTypeOfMarkedExpression( | |
| 14585 code, typeProvider.dynamicType, typeProvider.intType); | |
| 14586 } | |
| 14587 | |
| 14588 void test_localVariableInference_transitive_field_inferred_lexical() { | |
| 14589 String code = r''' | |
| 14590 class A { | |
| 14591 final x = 3; | |
| 14592 f() { | |
| 14593 var v = x; | |
| 14594 return v; // marker | |
| 14595 } | |
| 14596 } | |
| 14597 main() { | |
| 14598 } | |
| 14599 '''; | |
| 14600 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 14601 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 14602 } | |
| 14603 | |
| 14604 void test_localVariableInference_transitive_field_inferred_reversed() { | |
| 14605 String code = r''' | |
| 14606 class A { | |
| 14607 f() { | |
| 14608 var v = x; | |
| 14609 return v; // marker | |
| 14610 } | |
| 14611 final x = 3; | |
| 14612 } | |
| 14613 main() { | |
| 14614 } | |
| 14615 '''; | |
| 14616 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 14617 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 14618 } | |
| 14619 | |
| 14620 void test_localVariableInference_transitive_field_lexical() { | |
| 14621 String code = r''' | |
| 14622 class A { | |
| 14623 int x = 3; | |
| 14624 f() { | |
| 14625 var v = x; | |
| 14626 return v; // marker | |
| 14627 } | |
| 14628 } | |
| 14629 main() { | |
| 14630 } | |
| 14631 '''; | |
| 14632 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 14633 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 14634 } | |
| 14635 | |
| 14636 void test_localVariableInference_transitive_field_reversed() { | |
| 14637 String code = r''' | |
| 14638 class A { | |
| 14639 f() { | |
| 14640 var v = x; | |
| 14641 return v; // marker | |
| 14642 } | |
| 14643 int x = 3; | |
| 14644 } | |
| 14645 main() { | |
| 14646 } | |
| 14647 '''; | |
| 14648 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 14649 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 14650 } | |
| 14651 | |
| 14652 void test_localVariableInference_transitive_list_local() { | |
| 14653 String code = r''' | |
| 14654 main() { | |
| 14655 var x = <int>[3]; | |
| 14656 var v = x[0]; | |
| 14657 v; // marker | |
| 14658 }'''; | |
| 14659 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 14660 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 14661 } | |
| 14662 | |
| 14663 void test_localVariableInference_transitive_local() { | |
| 14664 String code = r''' | |
| 14665 main() { | |
| 14666 var x = 3; | |
| 14667 var v = x; | |
| 14668 v; // marker | |
| 14669 }'''; | |
| 14670 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 14671 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 14672 } | |
| 14673 | |
| 14674 void test_localVariableInference_transitive_toplevel_inferred_lexical() { | |
| 14675 String code = r''' | |
| 14676 final x = 3; | |
| 14677 main() { | |
| 14678 var v = x; | |
| 14679 v; // marker | |
| 14680 } | |
| 14681 '''; | |
| 14682 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 14683 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 14684 } | |
| 14685 | |
| 14686 void test_localVariableInference_transitive_toplevel_inferred_reversed() { | |
| 14687 String code = r''' | |
| 14688 main() { | |
| 14689 var v = x; | |
| 14690 v; // marker | |
| 14691 } | |
| 14692 final x = 3; | |
| 14693 '''; | |
| 14694 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 14695 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 14696 } | |
| 14697 | |
| 14698 void test_localVariableInference_transitive_toplevel_lexical() { | |
| 14699 String code = r''' | |
| 14700 int x = 3; | |
| 14701 main() { | |
| 14702 var v = x; | |
| 14703 v; // marker | |
| 14704 } | |
| 14705 '''; | |
| 14706 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 14707 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 14708 } | |
| 14709 | |
| 14710 void test_localVariableInference_transitive_toplevel_reversed() { | |
| 14711 String code = r''' | |
| 14712 main() { | |
| 14713 var v = x; | |
| 14714 v; // marker | |
| 14715 } | |
| 14716 int x = 3; | |
| 14717 '''; | |
| 14718 _assertPropagatedAssignedType(code, typeProvider.intType, null); | |
| 14719 _assertTypeOfMarkedExpression(code, typeProvider.intType, null); | |
| 14720 } | |
| 14721 } | |
| 14722 | |
| 14723 @reflectiveTest | 1042 @reflectiveTest |
| 14724 class SubtypeManagerTest { | 1043 class SubtypeManagerTest { |
| 14725 /** | 1044 /** |
| 14726 * The inheritance manager being tested. | 1045 * The inheritance manager being tested. |
| 14727 */ | 1046 */ |
| 14728 SubtypeManager _subtypeManager; | 1047 SubtypeManager _subtypeManager; |
| 14729 | 1048 |
| 14730 /** | 1049 /** |
| 14731 * The compilation unit element containing all of the types setup in each test
. | 1050 * The compilation unit element containing all of the types setup in each test
. |
| 14732 */ | 1051 */ |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14813 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | 1132 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); |
| 14814 _definingCompilationUnit.types = <ClassElement>[classA, classB]; | 1133 _definingCompilationUnit.types = <ClassElement>[classA, classB]; |
| 14815 HashSet<ClassElement> subtypesOfA = | 1134 HashSet<ClassElement> subtypesOfA = |
| 14816 _subtypeManager.computeAllSubtypes(classA); | 1135 _subtypeManager.computeAllSubtypes(classA); |
| 14817 List<ClassElement> arraySubtypesOfA = new List.from(subtypesOfA); | 1136 List<ClassElement> arraySubtypesOfA = new List.from(subtypesOfA); |
| 14818 expect(subtypesOfA, hasLength(1)); | 1137 expect(subtypesOfA, hasLength(1)); |
| 14819 expect(arraySubtypesOfA, unorderedEquals([classB])); | 1138 expect(arraySubtypesOfA, unorderedEquals([classB])); |
| 14820 } | 1139 } |
| 14821 } | 1140 } |
| 14822 | 1141 |
| 14823 class TestPackageUriResolver extends UriResolver { | |
| 14824 Map<Uri, Source> sourceMap = new HashMap<Uri, Source>(); | |
| 14825 | |
| 14826 TestPackageUriResolver(Map<String, String> map) { | |
| 14827 map.forEach((String uri, String contents) { | |
| 14828 sourceMap[Uri.parse(uri)] = | |
| 14829 new StringSource(contents, '/test_pkg_source.dart'); | |
| 14830 }); | |
| 14831 } | |
| 14832 | |
| 14833 @override | |
| 14834 Source resolveAbsolute(Uri uri, [Uri actualUri]) => sourceMap[uri]; | |
| 14835 | |
| 14836 @override | |
| 14837 Uri restoreAbsolute(Source source) => throw new UnimplementedError(); | |
| 14838 } | |
| 14839 | |
| 14840 @reflectiveTest | 1142 @reflectiveTest |
| 14841 class TypeOverrideManagerTest extends EngineTestCase { | 1143 class TypeOverrideManagerTest extends EngineTestCase { |
| 14842 void test_exitScope_noScopes() { | 1144 void test_exitScope_noScopes() { |
| 14843 TypeOverrideManager manager = new TypeOverrideManager(); | 1145 TypeOverrideManager manager = new TypeOverrideManager(); |
| 14844 try { | 1146 try { |
| 14845 manager.exitScope(); | 1147 manager.exitScope(); |
| 14846 fail("Expected IllegalStateException"); | 1148 fail("Expected IllegalStateException"); |
| 14847 } on IllegalStateException { | 1149 } on IllegalStateException { |
| 14848 // Expected | 1150 // Expected |
| 14849 } | 1151 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14905 void test_getType_noScope() { | 1207 void test_getType_noScope() { |
| 14906 TypeOverrideManager manager = new TypeOverrideManager(); | 1208 TypeOverrideManager manager = new TypeOverrideManager(); |
| 14907 expect(manager.getType(ElementFactory.localVariableElement2("v")), isNull); | 1209 expect(manager.getType(ElementFactory.localVariableElement2("v")), isNull); |
| 14908 } | 1210 } |
| 14909 } | 1211 } |
| 14910 | 1212 |
| 14911 @reflectiveTest | 1213 @reflectiveTest |
| 14912 class TypePropagationTest extends ResolverTestCase { | 1214 class TypePropagationTest extends ResolverTestCase { |
| 14913 void fail_mergePropagatedTypesAtJoinPoint_1() { | 1215 void fail_mergePropagatedTypesAtJoinPoint_1() { |
| 14914 // https://code.google.com/p/dart/issues/detail?id=19929 | 1216 // https://code.google.com/p/dart/issues/detail?id=19929 |
| 14915 _assertTypeOfMarkedExpression( | 1217 assertTypeOfMarkedExpression( |
| 14916 r''' | 1218 r''' |
| 14917 f1(x) { | 1219 f1(x) { |
| 14918 var y = []; | 1220 var y = []; |
| 14919 if (x) { | 1221 if (x) { |
| 14920 y = 0; | 1222 y = 0; |
| 14921 } else { | 1223 } else { |
| 14922 y = ''; | 1224 y = ''; |
| 14923 } | 1225 } |
| 14924 // Propagated type is [List] here: incorrect. | 1226 // Propagated type is [List] here: incorrect. |
| 14925 // Best we can do is [Object]? | 1227 // Best we can do is [Object]? |
| 14926 return y; // marker | 1228 return y; // marker |
| 14927 }''', | 1229 }''', |
| 14928 null, | 1230 null, |
| 14929 typeProvider.dynamicType); | 1231 typeProvider.dynamicType); |
| 14930 } | 1232 } |
| 14931 | 1233 |
| 14932 void fail_mergePropagatedTypesAtJoinPoint_2() { | 1234 void fail_mergePropagatedTypesAtJoinPoint_2() { |
| 14933 // https://code.google.com/p/dart/issues/detail?id=19929 | 1235 // https://code.google.com/p/dart/issues/detail?id=19929 |
| 14934 _assertTypeOfMarkedExpression( | 1236 assertTypeOfMarkedExpression( |
| 14935 r''' | 1237 r''' |
| 14936 f2(x) { | 1238 f2(x) { |
| 14937 var y = []; | 1239 var y = []; |
| 14938 if (x) { | 1240 if (x) { |
| 14939 y = 0; | 1241 y = 0; |
| 14940 } else { | 1242 } else { |
| 14941 } | 1243 } |
| 14942 // Propagated type is [List] here: incorrect. | 1244 // Propagated type is [List] here: incorrect. |
| 14943 // Best we can do is [Object]? | 1245 // Best we can do is [Object]? |
| 14944 return y; // marker | 1246 return y; // marker |
| 14945 }''', | 1247 }''', |
| 14946 null, | 1248 null, |
| 14947 typeProvider.dynamicType); | 1249 typeProvider.dynamicType); |
| 14948 } | 1250 } |
| 14949 | 1251 |
| 14950 void fail_mergePropagatedTypesAtJoinPoint_3() { | 1252 void fail_mergePropagatedTypesAtJoinPoint_3() { |
| 14951 // https://code.google.com/p/dart/issues/detail?id=19929 | 1253 // https://code.google.com/p/dart/issues/detail?id=19929 |
| 14952 _assertTypeOfMarkedExpression( | 1254 assertTypeOfMarkedExpression( |
| 14953 r''' | 1255 r''' |
| 14954 f4(x) { | 1256 f4(x) { |
| 14955 var y = []; | 1257 var y = []; |
| 14956 if (x) { | 1258 if (x) { |
| 14957 y = 0; | 1259 y = 0; |
| 14958 } else { | 1260 } else { |
| 14959 y = 1.5; | 1261 y = 1.5; |
| 14960 } | 1262 } |
| 14961 // Propagated type is [List] here: incorrect. | 1263 // Propagated type is [List] here: incorrect. |
| 14962 // A correct answer is the least upper bound of [int] and [double], | 1264 // A correct answer is the least upper bound of [int] and [double], |
| 14963 // i.e. [num]. | 1265 // i.e. [num]. |
| 14964 return y; // marker | 1266 return y; // marker |
| 14965 }''', | 1267 }''', |
| 14966 null, | 1268 null, |
| 14967 typeProvider.numType); | 1269 typeProvider.numType); |
| 14968 } | 1270 } |
| 14969 | 1271 |
| 14970 void fail_mergePropagatedTypesAtJoinPoint_5() { | 1272 void fail_mergePropagatedTypesAtJoinPoint_5() { |
| 14971 // https://code.google.com/p/dart/issues/detail?id=19929 | 1273 // https://code.google.com/p/dart/issues/detail?id=19929 |
| 14972 _assertTypeOfMarkedExpression( | 1274 assertTypeOfMarkedExpression( |
| 14973 r''' | 1275 r''' |
| 14974 f6(x,y) { | 1276 f6(x,y) { |
| 14975 var z = []; | 1277 var z = []; |
| 14976 if (x || (z = y) < 0) { | 1278 if (x || (z = y) < 0) { |
| 14977 } else { | 1279 } else { |
| 14978 z = 0; | 1280 z = 0; |
| 14979 } | 1281 } |
| 14980 // Propagated type is [List] here: incorrect. | 1282 // Propagated type is [List] here: incorrect. |
| 14981 // Best we can do is [Object]? | 1283 // Best we can do is [Object]? |
| 14982 return z; // marker | 1284 return z; // marker |
| (...skipping 19 matching lines...) Expand all Loading... |
| 15002 if (c) { | 1304 if (c) { |
| 15003 d = false; | 1305 d = false; |
| 15004 } else { | 1306 } else { |
| 15005 x = ''; | 1307 x = ''; |
| 15006 c = true; | 1308 c = true; |
| 15007 continue; | 1309 continue; |
| 15008 } | 1310 } |
| 15009 x; // marker | 1311 x; // marker |
| 15010 } | 1312 } |
| 15011 }'''; | 1313 }'''; |
| 15012 DartType t = _findMarkedIdentifier(code, "; // marker").propagatedType; | 1314 DartType t = findMarkedIdentifier(code, "; // marker").propagatedType; |
| 15013 expect(typeProvider.intType.isSubtypeOf(t), isTrue); | 1315 expect(typeProvider.intType.isSubtypeOf(t), isTrue); |
| 15014 expect(typeProvider.stringType.isSubtypeOf(t), isTrue); | 1316 expect(typeProvider.stringType.isSubtypeOf(t), isTrue); |
| 15015 } | 1317 } |
| 15016 | 1318 |
| 15017 void fail_mergePropagatedTypesAtJoinPoint_8() { | 1319 void fail_mergePropagatedTypesAtJoinPoint_8() { |
| 15018 // https://code.google.com/p/dart/issues/detail?id=19929 | 1320 // https://code.google.com/p/dart/issues/detail?id=19929 |
| 15019 // | 1321 // |
| 15020 // In nested loops [breaks]s are unsafe for the purposes of | 1322 // In nested loops [breaks]s are unsafe for the purposes of |
| 15021 // [isAbruptTerminationStatement]. | 1323 // [isAbruptTerminationStatement]. |
| 15022 // | 1324 // |
| (...skipping 11 matching lines...) Expand all Loading... |
| 15034 d = false; | 1336 d = false; |
| 15035 } else { | 1337 } else { |
| 15036 x = ''; | 1338 x = ''; |
| 15037 c = true; | 1339 c = true; |
| 15038 break; | 1340 break; |
| 15039 } | 1341 } |
| 15040 x; // marker | 1342 x; // marker |
| 15041 } | 1343 } |
| 15042 } | 1344 } |
| 15043 }'''; | 1345 }'''; |
| 15044 DartType t = _findMarkedIdentifier(code, "; // marker").propagatedType; | 1346 DartType t = findMarkedIdentifier(code, "; // marker").propagatedType; |
| 15045 expect(typeProvider.intType.isSubtypeOf(t), isTrue); | 1347 expect(typeProvider.intType.isSubtypeOf(t), isTrue); |
| 15046 expect(typeProvider.stringType.isSubtypeOf(t), isTrue); | 1348 expect(typeProvider.stringType.isSubtypeOf(t), isTrue); |
| 15047 } | 1349 } |
| 15048 | 1350 |
| 15049 void fail_propagatedReturnType_functionExpression() { | 1351 void fail_propagatedReturnType_functionExpression() { |
| 15050 // TODO(scheglov) disabled because we don't resolve function expression | 1352 // TODO(scheglov) disabled because we don't resolve function expression |
| 15051 String code = r''' | 1353 String code = r''' |
| 15052 main() { | 1354 main() { |
| 15053 var v = (() {return 42;})(); | 1355 var v = (() {return 42;})(); |
| 15054 }'''; | 1356 }'''; |
| 15055 _assertPropagatedAssignedType( | 1357 assertPropagatedAssignedType( |
| 15056 code, typeProvider.dynamicType, typeProvider.intType); | 1358 code, typeProvider.dynamicType, typeProvider.intType); |
| 15057 } | 1359 } |
| 15058 | 1360 |
| 15059 void test_as() { | 1361 void test_as() { |
| 15060 Source source = addSource(r''' | 1362 Source source = addSource(r''' |
| 15061 class A { | 1363 class A { |
| 15062 bool get g => true; | 1364 bool get g => true; |
| 15063 } | 1365 } |
| 15064 A f(var p) { | 1366 A f(var p) { |
| 15065 if ((p as A).g) { | 1367 if ((p as A).g) { |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15199 "/lib.dart", | 1501 "/lib.dart", |
| 15200 r''' | 1502 r''' |
| 15201 class A { | 1503 class A { |
| 15202 final v = 0; | 1504 final v = 0; |
| 15203 }'''); | 1505 }'''); |
| 15204 String code = r''' | 1506 String code = r''' |
| 15205 import 'lib.dart'; | 1507 import 'lib.dart'; |
| 15206 f(A a) { | 1508 f(A a) { |
| 15207 return a.v; // marker | 1509 return a.v; // marker |
| 15208 }'''; | 1510 }'''; |
| 15209 _assertTypeOfMarkedExpression( | 1511 assertTypeOfMarkedExpression( |
| 15210 code, typeProvider.dynamicType, typeProvider.intType); | 1512 code, typeProvider.dynamicType, typeProvider.intType); |
| 15211 } | 1513 } |
| 15212 | 1514 |
| 15213 void test_finalPropertyInducingVariable_classMember_instance_inherited() { | 1515 void test_finalPropertyInducingVariable_classMember_instance_inherited() { |
| 15214 addNamedSource( | 1516 addNamedSource( |
| 15215 "/lib.dart", | 1517 "/lib.dart", |
| 15216 r''' | 1518 r''' |
| 15217 class A { | 1519 class A { |
| 15218 final v = 0; | 1520 final v = 0; |
| 15219 }'''); | 1521 }'''); |
| 15220 String code = r''' | 1522 String code = r''' |
| 15221 import 'lib.dart'; | 1523 import 'lib.dart'; |
| 15222 class B extends A { | 1524 class B extends A { |
| 15223 m() { | 1525 m() { |
| 15224 return v; // marker | 1526 return v; // marker |
| 15225 } | 1527 } |
| 15226 }'''; | 1528 }'''; |
| 15227 _assertTypeOfMarkedExpression( | 1529 assertTypeOfMarkedExpression( |
| 15228 code, typeProvider.dynamicType, typeProvider.intType); | 1530 code, typeProvider.dynamicType, typeProvider.intType); |
| 15229 } | 1531 } |
| 15230 | 1532 |
| 15231 void | 1533 void |
| 15232 test_finalPropertyInducingVariable_classMember_instance_propagatedTarget()
{ | 1534 test_finalPropertyInducingVariable_classMember_instance_propagatedTarget()
{ |
| 15233 addNamedSource( | 1535 addNamedSource( |
| 15234 "/lib.dart", | 1536 "/lib.dart", |
| 15235 r''' | 1537 r''' |
| 15236 class A { | 1538 class A { |
| 15237 final v = 0; | 1539 final v = 0; |
| 15238 }'''); | 1540 }'''); |
| 15239 String code = r''' | 1541 String code = r''' |
| 15240 import 'lib.dart'; | 1542 import 'lib.dart'; |
| 15241 f(p) { | 1543 f(p) { |
| 15242 if (p is A) { | 1544 if (p is A) { |
| 15243 return p.v; // marker | 1545 return p.v; // marker |
| 15244 } | 1546 } |
| 15245 }'''; | 1547 }'''; |
| 15246 _assertTypeOfMarkedExpression( | 1548 assertTypeOfMarkedExpression( |
| 15247 code, typeProvider.dynamicType, typeProvider.intType); | 1549 code, typeProvider.dynamicType, typeProvider.intType); |
| 15248 } | 1550 } |
| 15249 | 1551 |
| 15250 void test_finalPropertyInducingVariable_classMember_instance_unprefixed() { | 1552 void test_finalPropertyInducingVariable_classMember_instance_unprefixed() { |
| 15251 String code = r''' | 1553 String code = r''' |
| 15252 class A { | 1554 class A { |
| 15253 final v = 0; | 1555 final v = 0; |
| 15254 m() { | 1556 m() { |
| 15255 v; // marker | 1557 v; // marker |
| 15256 } | 1558 } |
| 15257 }'''; | 1559 }'''; |
| 15258 _assertTypeOfMarkedExpression( | 1560 assertTypeOfMarkedExpression( |
| 15259 code, typeProvider.dynamicType, typeProvider.intType); | 1561 code, typeProvider.dynamicType, typeProvider.intType); |
| 15260 } | 1562 } |
| 15261 | 1563 |
| 15262 void test_finalPropertyInducingVariable_classMember_static() { | 1564 void test_finalPropertyInducingVariable_classMember_static() { |
| 15263 addNamedSource( | 1565 addNamedSource( |
| 15264 "/lib.dart", | 1566 "/lib.dart", |
| 15265 r''' | 1567 r''' |
| 15266 class A { | 1568 class A { |
| 15267 static final V = 0; | 1569 static final V = 0; |
| 15268 }'''); | 1570 }'''); |
| 15269 String code = r''' | 1571 String code = r''' |
| 15270 import 'lib.dart'; | 1572 import 'lib.dart'; |
| 15271 f() { | 1573 f() { |
| 15272 return A.V; // marker | 1574 return A.V; // marker |
| 15273 }'''; | 1575 }'''; |
| 15274 _assertTypeOfMarkedExpression( | 1576 assertTypeOfMarkedExpression( |
| 15275 code, typeProvider.dynamicType, typeProvider.intType); | 1577 code, typeProvider.dynamicType, typeProvider.intType); |
| 15276 } | 1578 } |
| 15277 | 1579 |
| 15278 void test_finalPropertyInducingVariable_topLevelVariable_prefixed() { | 1580 void test_finalPropertyInducingVariable_topLevelVariable_prefixed() { |
| 15279 addNamedSource("/lib.dart", "final V = 0;"); | 1581 addNamedSource("/lib.dart", "final V = 0;"); |
| 15280 String code = r''' | 1582 String code = r''' |
| 15281 import 'lib.dart' as p; | 1583 import 'lib.dart' as p; |
| 15282 f() { | 1584 f() { |
| 15283 var v2 = p.V; // marker prefixed | 1585 var v2 = p.V; // marker prefixed |
| 15284 }'''; | 1586 }'''; |
| 15285 _assertTypeOfMarkedExpression( | 1587 assertTypeOfMarkedExpression( |
| 15286 code, typeProvider.dynamicType, typeProvider.intType); | 1588 code, typeProvider.dynamicType, typeProvider.intType); |
| 15287 } | 1589 } |
| 15288 | 1590 |
| 15289 void test_finalPropertyInducingVariable_topLevelVariable_simple() { | 1591 void test_finalPropertyInducingVariable_topLevelVariable_simple() { |
| 15290 addNamedSource("/lib.dart", "final V = 0;"); | 1592 addNamedSource("/lib.dart", "final V = 0;"); |
| 15291 String code = r''' | 1593 String code = r''' |
| 15292 import 'lib.dart'; | 1594 import 'lib.dart'; |
| 15293 f() { | 1595 f() { |
| 15294 return V; // marker simple | 1596 return V; // marker simple |
| 15295 }'''; | 1597 }'''; |
| 15296 _assertTypeOfMarkedExpression( | 1598 assertTypeOfMarkedExpression( |
| 15297 code, typeProvider.dynamicType, typeProvider.intType); | 1599 code, typeProvider.dynamicType, typeProvider.intType); |
| 15298 } | 1600 } |
| 15299 | 1601 |
| 15300 void test_forEach() { | 1602 void test_forEach() { |
| 15301 String code = r''' | 1603 String code = r''' |
| 15302 main() { | 1604 main() { |
| 15303 var list = <String> []; | 1605 var list = <String> []; |
| 15304 for (var e in list) { | 1606 for (var e in list) { |
| 15305 e; | 1607 e; |
| 15306 } | 1608 } |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15723 ''' | 2025 ''' |
| 15724 library helper; | 2026 library helper; |
| 15725 int max(int x, int y) => 0; | 2027 int max(int x, int y) => 0; |
| 15726 '''); | 2028 '''); |
| 15727 String code = ''' | 2029 String code = ''' |
| 15728 import 'helper.dart' as helper; | 2030 import 'helper.dart' as helper; |
| 15729 main() { | 2031 main() { |
| 15730 helper.max(10, 10); // marker | 2032 helper.max(10, 10); // marker |
| 15731 }'''; | 2033 }'''; |
| 15732 SimpleIdentifier methodName = | 2034 SimpleIdentifier methodName = |
| 15733 _findMarkedIdentifier(code, "(10, 10); // marker"); | 2035 findMarkedIdentifier(code, "(10, 10); // marker"); |
| 15734 MethodInvocation methodInvoke = methodName.parent; | 2036 MethodInvocation methodInvoke = methodName.parent; |
| 15735 expect(methodInvoke.methodName.staticElement, isNotNull); | 2037 expect(methodInvoke.methodName.staticElement, isNotNull); |
| 15736 expect(methodInvoke.methodName.propagatedElement, isNull); | 2038 expect(methodInvoke.methodName.propagatedElement, isNull); |
| 15737 } | 2039 } |
| 15738 | 2040 |
| 15739 void test_is_conditional() { | 2041 void test_is_conditional() { |
| 15740 Source source = addSource(r''' | 2042 Source source = addSource(r''' |
| 15741 class A {} | 2043 class A {} |
| 15742 A f(var p) { | 2044 A f(var p) { |
| 15743 return (p is A) ? p : null; | 2045 return (p is A) ? p : null; |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16089 class A {} | 2391 class A {} |
| 16090 class B extends A {} | 2392 class B extends A {} |
| 16091 f() { | 2393 f() { |
| 16092 var a = new A(); | 2394 var a = new A(); |
| 16093 var b = new B(); | 2395 var b = new B(); |
| 16094 b; // B | 2396 b; // B |
| 16095 if (a is B) { | 2397 if (a is B) { |
| 16096 return a; // marker | 2398 return a; // marker |
| 16097 } | 2399 } |
| 16098 }'''; | 2400 }'''; |
| 16099 DartType tB = _findMarkedIdentifier(code, "; // B").propagatedType; | 2401 DartType tB = findMarkedIdentifier(code, "; // B").propagatedType; |
| 16100 _assertTypeOfMarkedExpression(code, null, tB); | 2402 assertTypeOfMarkedExpression(code, null, tB); |
| 16101 } | 2403 } |
| 16102 | 2404 |
| 16103 void test_issue20904BuggyTypePromotionAtIfJoin_6() { | 2405 void test_issue20904BuggyTypePromotionAtIfJoin_6() { |
| 16104 // https://code.google.com/p/dart/issues/detail?id=20904 | 2406 // https://code.google.com/p/dart/issues/detail?id=20904 |
| 16105 // | 2407 // |
| 16106 // The other half of the *_5() test. | 2408 // The other half of the *_5() test. |
| 16107 // | 2409 // |
| 16108 // Here the is-check loses precision, so we don't use it. | 2410 // Here the is-check loses precision, so we don't use it. |
| 16109 String code = r''' | 2411 String code = r''' |
| 16110 class A {} | 2412 class A {} |
| 16111 class B extends A {} | 2413 class B extends A {} |
| 16112 f() { | 2414 f() { |
| 16113 var b = new B(); | 2415 var b = new B(); |
| 16114 b; // B | 2416 b; // B |
| 16115 if (b is A) { | 2417 if (b is A) { |
| 16116 return b; // marker | 2418 return b; // marker |
| 16117 } | 2419 } |
| 16118 }'''; | 2420 }'''; |
| 16119 DartType tB = _findMarkedIdentifier(code, "; // B").propagatedType; | 2421 DartType tB = findMarkedIdentifier(code, "; // B").propagatedType; |
| 16120 _assertTypeOfMarkedExpression(code, null, tB); | 2422 assertTypeOfMarkedExpression(code, null, tB); |
| 16121 } | 2423 } |
| 16122 | 2424 |
| 16123 void test_listLiteral_different() { | 2425 void test_listLiteral_different() { |
| 16124 Source source = addSource(r''' | 2426 Source source = addSource(r''' |
| 16125 f() { | 2427 f() { |
| 16126 var v = [0, '1', 2]; | 2428 var v = [0, '1', 2]; |
| 16127 return v[2]; | 2429 return v[2]; |
| 16128 }'''); | 2430 }'''); |
| 16129 LibraryElement library = resolve2(source); | 2431 LibraryElement library = resolve2(source); |
| 16130 assertNoErrors(source); | 2432 assertNoErrors(source); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16211 void test_mergePropagatedTypes_afterIfThen_different() { | 2513 void test_mergePropagatedTypes_afterIfThen_different() { |
| 16212 String code = r''' | 2514 String code = r''' |
| 16213 main() { | 2515 main() { |
| 16214 var v = 0; | 2516 var v = 0; |
| 16215 if (v != null) { | 2517 if (v != null) { |
| 16216 v = ''; | 2518 v = ''; |
| 16217 } | 2519 } |
| 16218 return v; | 2520 return v; |
| 16219 }'''; | 2521 }'''; |
| 16220 { | 2522 { |
| 16221 SimpleIdentifier identifier = _findMarkedIdentifier(code, "v;"); | 2523 SimpleIdentifier identifier = findMarkedIdentifier(code, "v;"); |
| 16222 expect(identifier.propagatedType, null); | 2524 expect(identifier.propagatedType, null); |
| 16223 } | 2525 } |
| 16224 { | 2526 { |
| 16225 SimpleIdentifier identifier = _findMarkedIdentifier(code, "v = '';"); | 2527 SimpleIdentifier identifier = findMarkedIdentifier(code, "v = '';"); |
| 16226 expect(identifier.propagatedType, typeProvider.stringType); | 2528 expect(identifier.propagatedType, typeProvider.stringType); |
| 16227 } | 2529 } |
| 16228 } | 2530 } |
| 16229 | 2531 |
| 16230 void test_mergePropagatedTypes_afterIfThen_same() { | 2532 void test_mergePropagatedTypes_afterIfThen_same() { |
| 16231 _assertTypeOfMarkedExpression( | 2533 assertTypeOfMarkedExpression( |
| 16232 r''' | 2534 r''' |
| 16233 main() { | 2535 main() { |
| 16234 var v = 1; | 2536 var v = 1; |
| 16235 if (v != null) { | 2537 if (v != null) { |
| 16236 v = 2; | 2538 v = 2; |
| 16237 } | 2539 } |
| 16238 return v; // marker | 2540 return v; // marker |
| 16239 }''', | 2541 }''', |
| 16240 null, | 2542 null, |
| 16241 typeProvider.intType); | 2543 typeProvider.intType); |
| 16242 } | 2544 } |
| 16243 | 2545 |
| 16244 void test_mergePropagatedTypes_afterIfThenElse_different() { | 2546 void test_mergePropagatedTypes_afterIfThenElse_different() { |
| 16245 _assertTypeOfMarkedExpression( | 2547 assertTypeOfMarkedExpression( |
| 16246 r''' | 2548 r''' |
| 16247 main() { | 2549 main() { |
| 16248 var v = 1; | 2550 var v = 1; |
| 16249 if (v != null) { | 2551 if (v != null) { |
| 16250 v = 2; | 2552 v = 2; |
| 16251 } else { | 2553 } else { |
| 16252 v = '3'; | 2554 v = '3'; |
| 16253 } | 2555 } |
| 16254 return v; // marker | 2556 return v; // marker |
| 16255 }''', | 2557 }''', |
| 16256 null, | 2558 null, |
| 16257 null); | 2559 null); |
| 16258 } | 2560 } |
| 16259 | 2561 |
| 16260 void test_mergePropagatedTypes_afterIfThenElse_same() { | 2562 void test_mergePropagatedTypes_afterIfThenElse_same() { |
| 16261 _assertTypeOfMarkedExpression( | 2563 assertTypeOfMarkedExpression( |
| 16262 r''' | 2564 r''' |
| 16263 main() { | 2565 main() { |
| 16264 var v = 1; | 2566 var v = 1; |
| 16265 if (v != null) { | 2567 if (v != null) { |
| 16266 v = 2; | 2568 v = 2; |
| 16267 } else { | 2569 } else { |
| 16268 v = 3; | 2570 v = 3; |
| 16269 } | 2571 } |
| 16270 return v; // marker | 2572 return v; // marker |
| 16271 }''', | 2573 }''', |
| 16272 null, | 2574 null, |
| 16273 typeProvider.intType); | 2575 typeProvider.intType); |
| 16274 } | 2576 } |
| 16275 | 2577 |
| 16276 void test_mergePropagatedTypesAtJoinPoint_4() { | 2578 void test_mergePropagatedTypesAtJoinPoint_4() { |
| 16277 // https://code.google.com/p/dart/issues/detail?id=19929 | 2579 // https://code.google.com/p/dart/issues/detail?id=19929 |
| 16278 _assertTypeOfMarkedExpression( | 2580 assertTypeOfMarkedExpression( |
| 16279 r''' | 2581 r''' |
| 16280 f5(x) { | 2582 f5(x) { |
| 16281 var y = []; | 2583 var y = []; |
| 16282 if (x) { | 2584 if (x) { |
| 16283 y = 0; | 2585 y = 0; |
| 16284 } else { | 2586 } else { |
| 16285 return y; | 2587 return y; |
| 16286 } | 2588 } |
| 16287 // Propagated type is [int] here: correct. | 2589 // Propagated type is [int] here: correct. |
| 16288 return y; // marker | 2590 return y; // marker |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16329 ''' | 2631 ''' |
| 16330 library helper; | 2632 library helper; |
| 16331 dynamic get $name => 42; | 2633 dynamic get $name => 42; |
| 16332 '''); | 2634 '''); |
| 16333 String code = ''' | 2635 String code = ''' |
| 16334 import 'helper.dart' as helper; | 2636 import 'helper.dart' as helper; |
| 16335 main() { | 2637 main() { |
| 16336 helper.$name; // marker | 2638 helper.$name; // marker |
| 16337 }'''; | 2639 }'''; |
| 16338 | 2640 |
| 16339 SimpleIdentifier id = _findMarkedIdentifier(code, "; // marker"); | 2641 SimpleIdentifier id = findMarkedIdentifier(code, "; // marker"); |
| 16340 PrefixedIdentifier prefixedId = id.parent; | 2642 PrefixedIdentifier prefixedId = id.parent; |
| 16341 expect(id.staticType, typeProvider.dynamicType); | 2643 expect(id.staticType, typeProvider.dynamicType); |
| 16342 expect(prefixedId.staticType, typeProvider.dynamicType); | 2644 expect(prefixedId.staticType, typeProvider.dynamicType); |
| 16343 } | 2645 } |
| 16344 | 2646 |
| 16345 void test_objectAccessInference_disabled_for_local_getter() { | 2647 void test_objectAccessInference_disabled_for_local_getter() { |
| 16346 String name = 'hashCode'; | 2648 String name = 'hashCode'; |
| 16347 String code = ''' | 2649 String code = ''' |
| 16348 dynamic get $name => null; | 2650 dynamic get $name => null; |
| 16349 main() { | 2651 main() { |
| 16350 $name; // marker | 2652 $name; // marker |
| 16351 }'''; | 2653 }'''; |
| 16352 | 2654 |
| 16353 SimpleIdentifier getter = _findMarkedIdentifier(code, "; // marker"); | 2655 SimpleIdentifier getter = findMarkedIdentifier(code, "; // marker"); |
| 16354 expect(getter.staticType, typeProvider.dynamicType); | 2656 expect(getter.staticType, typeProvider.dynamicType); |
| 16355 } | 2657 } |
| 16356 | 2658 |
| 16357 void test_objectAccessInference_enabled_for_cascades() { | 2659 void test_objectAccessInference_enabled_for_cascades() { |
| 16358 String name = 'hashCode'; | 2660 String name = 'hashCode'; |
| 16359 String code = ''' | 2661 String code = ''' |
| 16360 main() { | 2662 main() { |
| 16361 dynamic obj; | 2663 dynamic obj; |
| 16362 obj..$name..$name; // marker | 2664 obj..$name..$name; // marker |
| 16363 }'''; | 2665 }'''; |
| 16364 PropertyAccess access = _findMarkedIdentifier(code, "; // marker").parent; | 2666 PropertyAccess access = findMarkedIdentifier(code, "; // marker").parent; |
| 16365 expect(access.staticType, typeProvider.dynamicType); | 2667 expect(access.staticType, typeProvider.dynamicType); |
| 16366 expect(access.realTarget.staticType, typeProvider.dynamicType); | 2668 expect(access.realTarget.staticType, typeProvider.dynamicType); |
| 16367 } | 2669 } |
| 16368 | 2670 |
| 16369 void test_objectMethodInference_disabled_for_library_prefix() { | 2671 void test_objectMethodInference_disabled_for_library_prefix() { |
| 16370 String name = 'toString'; | 2672 String name = 'toString'; |
| 16371 addNamedSource( | 2673 addNamedSource( |
| 16372 '/helper.dart', | 2674 '/helper.dart', |
| 16373 ''' | 2675 ''' |
| 16374 library helper; | 2676 library helper; |
| 16375 dynamic $name = (int x) => x + 42'); | 2677 dynamic $name = (int x) => x + 42'); |
| 16376 '''); | 2678 '''); |
| 16377 String code = ''' | 2679 String code = ''' |
| 16378 import 'helper.dart' as helper; | 2680 import 'helper.dart' as helper; |
| 16379 main() { | 2681 main() { |
| 16380 helper.$name(); // marker | 2682 helper.$name(); // marker |
| 16381 }'''; | 2683 }'''; |
| 16382 SimpleIdentifier methodName = _findMarkedIdentifier(code, "(); // marker"); | 2684 SimpleIdentifier methodName = findMarkedIdentifier(code, "(); // marker"); |
| 16383 MethodInvocation methodInvoke = methodName.parent; | 2685 MethodInvocation methodInvoke = methodName.parent; |
| 16384 expect(methodName.staticType, typeProvider.dynamicType); | 2686 expect(methodName.staticType, typeProvider.dynamicType); |
| 16385 expect(methodInvoke.staticType, typeProvider.dynamicType); | 2687 expect(methodInvoke.staticType, typeProvider.dynamicType); |
| 16386 } | 2688 } |
| 16387 | 2689 |
| 16388 void test_objectMethodInference_disabled_for_local_function() { | 2690 void test_objectMethodInference_disabled_for_local_function() { |
| 16389 String name = 'toString'; | 2691 String name = 'toString'; |
| 16390 String code = ''' | 2692 String code = ''' |
| 16391 main() { | 2693 main() { |
| 16392 dynamic $name = () => null; | 2694 dynamic $name = () => null; |
| 16393 $name(); // marker | 2695 $name(); // marker |
| 16394 }'''; | 2696 }'''; |
| 16395 SimpleIdentifier identifier = _findMarkedIdentifier(code, "$name = "); | 2697 SimpleIdentifier identifier = findMarkedIdentifier(code, "$name = "); |
| 16396 expect(identifier.staticType, typeProvider.dynamicType); | 2698 expect(identifier.staticType, typeProvider.dynamicType); |
| 16397 | 2699 |
| 16398 SimpleIdentifier methodName = _findMarkedIdentifier(code, "(); // marker"); | 2700 SimpleIdentifier methodName = findMarkedIdentifier(code, "(); // marker"); |
| 16399 MethodInvocation methodInvoke = methodName.parent; | 2701 MethodInvocation methodInvoke = methodName.parent; |
| 16400 expect(methodName.staticType, typeProvider.dynamicType); | 2702 expect(methodName.staticType, typeProvider.dynamicType); |
| 16401 expect(methodInvoke.staticType, typeProvider.dynamicType); | 2703 expect(methodInvoke.staticType, typeProvider.dynamicType); |
| 16402 } | 2704 } |
| 16403 | 2705 |
| 16404 void test_objectMethodInference_enabled_for_cascades() { | 2706 void test_objectMethodInference_enabled_for_cascades() { |
| 16405 String name = 'toString'; | 2707 String name = 'toString'; |
| 16406 String code = ''' | 2708 String code = ''' |
| 16407 main() { | 2709 main() { |
| 16408 dynamic obj; | 2710 dynamic obj; |
| 16409 obj..$name()..$name(); // marker | 2711 obj..$name()..$name(); // marker |
| 16410 }'''; | 2712 }'''; |
| 16411 SimpleIdentifier methodName = _findMarkedIdentifier(code, "(); // marker"); | 2713 SimpleIdentifier methodName = findMarkedIdentifier(code, "(); // marker"); |
| 16412 MethodInvocation methodInvoke = methodName.parent; | 2714 MethodInvocation methodInvoke = methodName.parent; |
| 16413 | 2715 |
| 16414 expect(methodInvoke.staticType, typeProvider.dynamicType); | 2716 expect(methodInvoke.staticType, typeProvider.dynamicType); |
| 16415 expect(methodInvoke.realTarget.staticType, typeProvider.dynamicType); | 2717 expect(methodInvoke.realTarget.staticType, typeProvider.dynamicType); |
| 16416 } | 2718 } |
| 16417 | 2719 |
| 16418 void test_objectMethodOnDynamicExpression_doubleEquals() { | 2720 void test_objectMethodOnDynamicExpression_doubleEquals() { |
| 16419 // https://code.google.com/p/dart/issues/detail?id=20342 | 2721 // https://code.google.com/p/dart/issues/detail?id=20342 |
| 16420 // | 2722 // |
| 16421 // This was not actually part of Issue 20342, since the spec specifies a | 2723 // This was not actually part of Issue 20342, since the spec specifies a |
| 16422 // static type of [bool] for [==] comparison and the implementation | 2724 // static type of [bool] for [==] comparison and the implementation |
| 16423 // was already consistent with the spec there. But, it's another | 2725 // was already consistent with the spec there. But, it's another |
| 16424 // [Object] method, so it's included here. | 2726 // [Object] method, so it's included here. |
| 16425 _assertTypeOfMarkedExpression( | 2727 assertTypeOfMarkedExpression( |
| 16426 r''' | 2728 r''' |
| 16427 f1(x) { | 2729 f1(x) { |
| 16428 var v = (x == x); | 2730 var v = (x == x); |
| 16429 return v; // marker | 2731 return v; // marker |
| 16430 }''', | 2732 }''', |
| 16431 null, | 2733 null, |
| 16432 typeProvider.boolType); | 2734 typeProvider.boolType); |
| 16433 } | 2735 } |
| 16434 | 2736 |
| 16435 void test_objectMethodOnDynamicExpression_hashCode() { | 2737 void test_objectMethodOnDynamicExpression_hashCode() { |
| 16436 // https://code.google.com/p/dart/issues/detail?id=20342 | 2738 // https://code.google.com/p/dart/issues/detail?id=20342 |
| 16437 _assertTypeOfMarkedExpression( | 2739 assertTypeOfMarkedExpression( |
| 16438 r''' | 2740 r''' |
| 16439 f1(x) { | 2741 f1(x) { |
| 16440 var v = x.hashCode; | 2742 var v = x.hashCode; |
| 16441 return v; // marker | 2743 return v; // marker |
| 16442 }''', | 2744 }''', |
| 16443 null, | 2745 null, |
| 16444 typeProvider.intType); | 2746 typeProvider.intType); |
| 16445 } | 2747 } |
| 16446 | 2748 |
| 16447 void test_objectMethodOnDynamicExpression_runtimeType() { | 2749 void test_objectMethodOnDynamicExpression_runtimeType() { |
| 16448 // https://code.google.com/p/dart/issues/detail?id=20342 | 2750 // https://code.google.com/p/dart/issues/detail?id=20342 |
| 16449 _assertTypeOfMarkedExpression( | 2751 assertTypeOfMarkedExpression( |
| 16450 r''' | 2752 r''' |
| 16451 f1(x) { | 2753 f1(x) { |
| 16452 var v = x.runtimeType; | 2754 var v = x.runtimeType; |
| 16453 return v; // marker | 2755 return v; // marker |
| 16454 }''', | 2756 }''', |
| 16455 null, | 2757 null, |
| 16456 typeProvider.typeType); | 2758 typeProvider.typeType); |
| 16457 } | 2759 } |
| 16458 | 2760 |
| 16459 void test_objectMethodOnDynamicExpression_toString() { | 2761 void test_objectMethodOnDynamicExpression_toString() { |
| 16460 // https://code.google.com/p/dart/issues/detail?id=20342 | 2762 // https://code.google.com/p/dart/issues/detail?id=20342 |
| 16461 _assertTypeOfMarkedExpression( | 2763 assertTypeOfMarkedExpression( |
| 16462 r''' | 2764 r''' |
| 16463 f1(x) { | 2765 f1(x) { |
| 16464 var v = x.toString(); | 2766 var v = x.toString(); |
| 16465 return v; // marker | 2767 return v; // marker |
| 16466 }''', | 2768 }''', |
| 16467 null, | 2769 null, |
| 16468 typeProvider.stringType); | 2770 typeProvider.stringType); |
| 16469 } | 2771 } |
| 16470 | 2772 |
| 16471 void test_propagatedReturnType_localFunction() { | 2773 void test_propagatedReturnType_localFunction() { |
| 16472 String code = r''' | 2774 String code = r''' |
| 16473 main() { | 2775 main() { |
| 16474 f() => 42; | 2776 f() => 42; |
| 16475 var v = f(); | 2777 var v = f(); |
| 16476 }'''; | 2778 }'''; |
| 16477 _assertPropagatedAssignedType( | 2779 assertPropagatedAssignedType( |
| 16478 code, typeProvider.dynamicType, typeProvider.intType); | 2780 code, typeProvider.dynamicType, typeProvider.intType); |
| 16479 } | 2781 } |
| 16480 | 2782 |
| 16481 void test_query() { | 2783 void test_query() { |
| 16482 Source source = addSource(r''' | 2784 Source source = addSource(r''' |
| 16483 import 'dart:html'; | 2785 import 'dart:html'; |
| 16484 | 2786 |
| 16485 main() { | 2787 main() { |
| 16486 var v1 = query('a'); | 2788 var v1 = query('a'); |
| 16487 var v2 = query('A'); | 2789 var v2 = query('A'); |
| (...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17331 void _resolveNode(AstNode node, [List<Element> definedElements]) { | 3633 void _resolveNode(AstNode node, [List<Element> definedElements]) { |
| 17332 if (definedElements != null) { | 3634 if (definedElements != null) { |
| 17333 for (Element element in definedElements) { | 3635 for (Element element in definedElements) { |
| 17334 libraryScope.define(element); | 3636 libraryScope.define(element); |
| 17335 } | 3637 } |
| 17336 } | 3638 } |
| 17337 node.accept(_visitor); | 3639 node.accept(_visitor); |
| 17338 } | 3640 } |
| 17339 } | 3641 } |
| 17340 | 3642 |
| 17341 class _AnalysisContextFactory_initContextWithCore | |
| 17342 extends DirectoryBasedDartSdk { | |
| 17343 final bool enableAsync; | |
| 17344 _AnalysisContextFactory_initContextWithCore(JavaFile arg0, | |
| 17345 {this.enableAsync: true}) | |
| 17346 : super(arg0); | |
| 17347 | |
| 17348 @override | |
| 17349 LibraryMap initialLibraryMap(bool useDart2jsPaths) { | |
| 17350 LibraryMap map = new LibraryMap(); | |
| 17351 if (enableAsync) { | |
| 17352 _addLibrary(map, DartSdk.DART_ASYNC, false, "async.dart"); | |
| 17353 } | |
| 17354 _addLibrary(map, DartSdk.DART_CORE, false, "core.dart"); | |
| 17355 _addLibrary(map, DartSdk.DART_HTML, false, "html_dartium.dart"); | |
| 17356 _addLibrary(map, AnalysisContextFactory._DART_MATH, false, "math.dart"); | |
| 17357 _addLibrary(map, AnalysisContextFactory._DART_INTERCEPTORS, true, | |
| 17358 "_interceptors.dart"); | |
| 17359 _addLibrary( | |
| 17360 map, AnalysisContextFactory._DART_JS_HELPER, true, "_js_helper.dart"); | |
| 17361 return map; | |
| 17362 } | |
| 17363 | |
| 17364 void _addLibrary(LibraryMap map, String uri, bool isInternal, String path) { | |
| 17365 SdkLibraryImpl library = new SdkLibraryImpl(uri); | |
| 17366 if (isInternal) { | |
| 17367 library.category = "Internal"; | |
| 17368 } | |
| 17369 library.path = path; | |
| 17370 map.setLibrary(uri, library); | |
| 17371 } | |
| 17372 } | |
| 17373 | |
| 17374 class _SimpleResolverTest_localVariable_types_invoked | |
| 17375 extends RecursiveAstVisitor<Object> { | |
| 17376 final SimpleResolverTest test; | |
| 17377 | |
| 17378 List<bool> found; | |
| 17379 | |
| 17380 List<CaughtException> thrownException; | |
| 17381 | |
| 17382 _SimpleResolverTest_localVariable_types_invoked( | |
| 17383 this.test, this.found, this.thrownException) | |
| 17384 : super(); | |
| 17385 | |
| 17386 @override | |
| 17387 Object visitSimpleIdentifier(SimpleIdentifier node) { | |
| 17388 if (node.name == "myVar" && node.parent is MethodInvocation) { | |
| 17389 try { | |
| 17390 found[0] = true; | |
| 17391 // check static type | |
| 17392 DartType staticType = node.staticType; | |
| 17393 expect(staticType, same(test.typeProvider.dynamicType)); | |
| 17394 // check propagated type | |
| 17395 FunctionType propagatedType = node.propagatedType as FunctionType; | |
| 17396 expect(propagatedType.returnType, test.typeProvider.stringType); | |
| 17397 } on AnalysisException catch (e, stackTrace) { | |
| 17398 thrownException[0] = new CaughtException(e, stackTrace); | |
| 17399 } | |
| 17400 } | |
| 17401 return null; | |
| 17402 } | |
| 17403 } | |
| 17404 | |
| 17405 /** | 3643 /** |
| 17406 * Represents an element left over from a previous resolver run. | 3644 * Represents an element left over from a previous resolver run. |
| 17407 * | 3645 * |
| 17408 * A _StaleElement should always be replaced with either null or a new Element. | 3646 * A _StaleElement should always be replaced with either null or a new Element. |
| 17409 */ | 3647 */ |
| 17410 class _StaleElement extends ElementImpl { | 3648 class _StaleElement extends ElementImpl { |
| 17411 _StaleElement() : super("_StaleElement", -1); | 3649 _StaleElement() : super("_StaleElement", -1); |
| 17412 | 3650 |
| 17413 @override | 3651 @override |
| 17414 get kind => throw "_StaleElement's kind shouldn't be accessed"; | 3652 get kind => throw "_StaleElement's kind shouldn't be accessed"; |
| 17415 | 3653 |
| 17416 @override | 3654 @override |
| 17417 accept(_) => throw "_StaleElement shouldn't be visited"; | 3655 accept(_) => throw "_StaleElement shouldn't be visited"; |
| 17418 } | 3656 } |
| 17419 | |
| 17420 /** | |
| 17421 * Shared infrastructure for [StaticTypeAnalyzer2Test] and | |
| 17422 * [StrongModeStaticTypeAnalyzer2Test]. | |
| 17423 */ | |
| 17424 class _StaticTypeAnalyzer2TestShared extends ResolverTestCase { | |
| 17425 String testCode; | |
| 17426 Source testSource; | |
| 17427 CompilationUnit testUnit; | |
| 17428 | |
| 17429 /** | |
| 17430 * Looks up the identifier with [name] and validates that its type type | |
| 17431 * stringifies to [type] and that its generics match the given stringified | |
| 17432 * output. | |
| 17433 */ | |
| 17434 _expectFunctionType(String name, String type, | |
| 17435 {String elementTypeParams: '[]', | |
| 17436 String typeParams: '[]', | |
| 17437 String typeArgs: '[]', | |
| 17438 String typeFormals: '[]'}) { | |
| 17439 SimpleIdentifier identifier = _findIdentifier(name); | |
| 17440 // Element is either ExecutableElement or ParameterElement. | |
| 17441 var element = identifier.staticElement; | |
| 17442 FunctionTypeImpl functionType = identifier.staticType; | |
| 17443 expect(functionType.toString(), type); | |
| 17444 expect(element.typeParameters.toString(), elementTypeParams); | |
| 17445 expect(functionType.typeParameters.toString(), typeParams); | |
| 17446 expect(functionType.typeArguments.toString(), typeArgs); | |
| 17447 expect(functionType.typeFormals.toString(), typeFormals); | |
| 17448 } | |
| 17449 | |
| 17450 /** | |
| 17451 * Looks up the identifier with [name] and validates its static [type]. | |
| 17452 * | |
| 17453 * If [type] is a string, validates that the identifier's static type | |
| 17454 * stringifies to that text. Otherwise, [type] is used directly a [Matcher] | |
| 17455 * to match the type. | |
| 17456 * | |
| 17457 * If [propagatedType] is given, also validate's the identifier's propagated | |
| 17458 * type. | |
| 17459 */ | |
| 17460 void _expectIdentifierType(String name, type, [propagatedType]) { | |
| 17461 SimpleIdentifier identifier = _findIdentifier(name); | |
| 17462 _expectType(identifier.staticType, type); | |
| 17463 if (propagatedType != null) { | |
| 17464 _expectType(identifier.propagatedType, propagatedType); | |
| 17465 } | |
| 17466 } | |
| 17467 | |
| 17468 /** | |
| 17469 * Looks up the initializer for the declaration containing [identifier] and | |
| 17470 * validates its static [type]. | |
| 17471 * | |
| 17472 * If [type] is a string, validates that the identifier's static type | |
| 17473 * stringifies to that text. Otherwise, [type] is used directly a [Matcher] | |
| 17474 * to match the type. | |
| 17475 * | |
| 17476 * If [propagatedType] is given, also validate's the identifier's propagated | |
| 17477 * type. | |
| 17478 */ | |
| 17479 void _expectInitializerType(String name, type, [propagatedType]) { | |
| 17480 SimpleIdentifier identifier = _findIdentifier(name); | |
| 17481 VariableDeclaration declaration = | |
| 17482 identifier.getAncestor((node) => node is VariableDeclaration); | |
| 17483 Expression initializer = declaration.initializer; | |
| 17484 _expectType(initializer.staticType, type); | |
| 17485 if (propagatedType != null) { | |
| 17486 _expectType(initializer.propagatedType, propagatedType); | |
| 17487 } | |
| 17488 } | |
| 17489 | |
| 17490 /** | |
| 17491 * Validates that [type] matches [expected]. | |
| 17492 * | |
| 17493 * If [expected] is a string, validates that the type stringifies to that | |
| 17494 * text. Otherwise, [expected] is used directly a [Matcher] to match the type. | |
| 17495 */ | |
| 17496 _expectType(DartType type, expected) { | |
| 17497 if (expected is String) { | |
| 17498 expect(type.toString(), expected); | |
| 17499 } else { | |
| 17500 expect(type, expected); | |
| 17501 } | |
| 17502 } | |
| 17503 | |
| 17504 SimpleIdentifier _findIdentifier(String search) { | |
| 17505 SimpleIdentifier identifier = EngineTestCase.findNode( | |
| 17506 testUnit, testCode, search, (node) => node is SimpleIdentifier); | |
| 17507 return identifier; | |
| 17508 } | |
| 17509 | |
| 17510 void _resolveTestUnit(String code) { | |
| 17511 testCode = code; | |
| 17512 testSource = addSource(testCode); | |
| 17513 LibraryElement library = resolve2(testSource); | |
| 17514 assertNoErrors(testSource); | |
| 17515 verify([testSource]); | |
| 17516 testUnit = resolveCompilationUnit(testSource, library); | |
| 17517 } | |
| 17518 } | |
| OLD | NEW |