| 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 test.services.src.index.store.codec; | 5 library test.services.src.index.store.codec; |
| 6 | 6 |
| 7 import 'package:analysis_server/src/services/index/index.dart'; | 7 import 'package:analysis_server/src/services/index/index.dart'; |
| 8 import 'package:analysis_server/src/services/index/store/codec.dart'; | 8 import 'package:analysis_server/src/services/index/store/codec.dart'; |
| 9 import 'package:analyzer/src/generated/element.dart'; | 9 import 'package:analyzer/src/generated/element.dart'; |
| 10 import 'package:analyzer/src/generated/engine.dart'; | 10 import 'package:analyzer/src/generated/engine.dart'; |
| 11 import 'package:analyzer/src/generated/source.dart'; | |
| 12 import 'package:unittest/unittest.dart'; | 11 import 'package:unittest/unittest.dart'; |
| 13 | 12 |
| 14 import '../../../abstract_single_unit.dart'; | 13 import '../../../abstract_single_unit.dart'; |
| 15 import '../../../mocks.dart'; | 14 import '../../../mocks.dart'; |
| 16 import '../../../reflective_tests.dart'; | 15 import '../../../reflective_tests.dart'; |
| 17 | 16 |
| 18 main() { | 17 main() { |
| 19 groupSep = ' | '; | 18 groupSep = ' | '; |
| 20 runReflectiveTests(_ContextCodecTest); | 19 runReflectiveTests(_ContextCodecTest); |
| 21 runReflectiveTests(_ElementCodecTest); | 20 runReflectiveTests(_ElementCodecTest); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 class _ElementCodecTest extends AbstractSingleUnitTest { | 64 class _ElementCodecTest extends AbstractSingleUnitTest { |
| 66 ElementCodec codec; | 65 ElementCodec codec; |
| 67 AnalysisContext context = new MockAnalysisContext('context'); | 66 AnalysisContext context = new MockAnalysisContext('context'); |
| 68 StringCodec stringCodec = new StringCodec(); | 67 StringCodec stringCodec = new StringCodec(); |
| 69 | 68 |
| 70 void setUp() { | 69 void setUp() { |
| 71 super.setUp(); | 70 super.setUp(); |
| 72 codec = new ElementCodec(stringCodec); | 71 codec = new ElementCodec(stringCodec); |
| 73 } | 72 } |
| 74 | 73 |
| 74 void test_encode_CompilationUnitElement() { |
| 75 addSource('/my_part.dart', ''' |
| 76 part of my_lib; |
| 77 '''); |
| 78 resolveTestUnit(''' |
| 79 library my_lib; |
| 80 part 'my_part.dart'; |
| 81 '''); |
| 82 // defining unit |
| 83 { |
| 84 Element element = testLibraryElement.definingCompilationUnit; |
| 85 expect(element.source.fullName, '/test.dart'); |
| 86 int id1 = codec.encode1(element); |
| 87 int id2 = codec.encode2(element); |
| 88 int id3 = codec.encode3(element); |
| 89 expect(id1, isNonNegative); |
| 90 expect(id2, element.nameOffset); |
| 91 expect(id3, ElementKind.COMPILATION_UNIT.ordinal); |
| 92 // decode |
| 93 Element element2 = codec.decode(context, id1, id2, id3); |
| 94 expect(element2, element); |
| 95 } |
| 96 // part |
| 97 { |
| 98 Element element = testLibraryElement.parts[0]; |
| 99 expect(element.source.fullName, '/my_part.dart'); |
| 100 int id1 = codec.encode1(element); |
| 101 int id2 = codec.encode2(element); |
| 102 int id3 = codec.encode3(element); |
| 103 expect(id1, isNonNegative); |
| 104 expect(id2, element.nameOffset); |
| 105 expect(id3, ElementKind.COMPILATION_UNIT.ordinal); |
| 106 // decode |
| 107 Element element2 = codec.decode(context, id1, id2, id3); |
| 108 expect(element2, element); |
| 109 } |
| 110 } |
| 111 |
| 112 void test_encode_ConstructorElement_default_real() { |
| 113 resolveTestUnit(''' |
| 114 class A { |
| 115 A(); |
| 116 } |
| 117 '''); |
| 118 ClassElement classA = findElement('A'); |
| 119 ConstructorElement element = classA.constructors[0]; |
| 120 int id1 = codec.encode1(element); |
| 121 int id2 = codec.encode2(element); |
| 122 int id3 = codec.encode3(element); |
| 123 expect(id1, isNonNegative); |
| 124 expect(id2, classA.nameOffset); |
| 125 expect(id3, -100); |
| 126 // decode |
| 127 Element element2 = codec.decode(context, id1, id2, id3); |
| 128 expect(element2, element); |
| 129 } |
| 130 |
| 131 void test_encode_ConstructorElement_default_synthetic() { |
| 132 resolveTestUnit(''' |
| 133 class A { |
| 134 } |
| 135 '''); |
| 136 ClassElement classA = findElement('A'); |
| 137 ConstructorElement element = classA.constructors[0]; |
| 138 int id1 = codec.encode1(element); |
| 139 int id2 = codec.encode2(element); |
| 140 int id3 = codec.encode3(element); |
| 141 expect(id1, isNonNegative); |
| 142 expect(id2, classA.nameOffset); |
| 143 expect(id3, -100); |
| 144 // decode |
| 145 Element element2 = codec.decode(context, id1, id2, id3); |
| 146 expect(element2, element); |
| 147 } |
| 148 |
| 149 void test_encode_ConstructorElement_named_real() { |
| 150 resolveTestUnit(''' |
| 151 class A { |
| 152 A.aaa(); |
| 153 A.bbb(); |
| 154 } |
| 155 '''); |
| 156 ClassElement classA = findElement('A'); |
| 157 // A.aaa() |
| 158 { |
| 159 ConstructorElement element = classA.getNamedConstructor('aaa'); |
| 160 int id1 = codec.encode1(element); |
| 161 int id2 = codec.encode2(element); |
| 162 int id3 = codec.encode3(element); |
| 163 expect(id1, isNonNegative); |
| 164 expect(id2, classA.nameOffset); |
| 165 expect(id3, -100); |
| 166 // decode |
| 167 Element element2 = codec.decode(context, id1, id2, id3); |
| 168 expect(element2, element); |
| 169 } |
| 170 // A.bbb() |
| 171 { |
| 172 ConstructorElement element = classA.getNamedConstructor('bbb'); |
| 173 int id1 = codec.encode1(element); |
| 174 int id2 = codec.encode2(element); |
| 175 int id3 = codec.encode3(element); |
| 176 expect(id1, isNonNegative); |
| 177 expect(id2, classA.nameOffset); |
| 178 expect(id3, -101); |
| 179 // decode |
| 180 Element element2 = codec.decode(context, id1, id2, id3); |
| 181 expect(element2, element); |
| 182 } |
| 183 } |
| 184 |
| 185 void test_encode_ConstructorElement_named_synthetic() { |
| 186 resolveTestUnit(''' |
| 187 class A { |
| 188 A.aaa(); |
| 189 A.bbb(); |
| 190 } |
| 191 class M {} |
| 192 class X = A with M; |
| 193 '''); |
| 194 ClassElement classX = findElement('X'); |
| 195 // X.aaa() |
| 196 { |
| 197 ConstructorElement element = classX.getNamedConstructor('aaa'); |
| 198 int id1 = codec.encode1(element); |
| 199 int id2 = codec.encode2(element); |
| 200 int id3 = codec.encode3(element); |
| 201 expect(id1, isNonNegative); |
| 202 expect(id2, classX.nameOffset); |
| 203 expect(id3, -100); |
| 204 // decode |
| 205 Element element2 = codec.decode(context, id1, id2, id3); |
| 206 expect(element2, element); |
| 207 } |
| 208 // X.bbb() |
| 209 { |
| 210 ConstructorElement element = classX.getNamedConstructor('bbb'); |
| 211 int id1 = codec.encode1(element); |
| 212 int id2 = codec.encode2(element); |
| 213 int id3 = codec.encode3(element); |
| 214 expect(id1, isNonNegative); |
| 215 expect(id2, classX.nameOffset); |
| 216 expect(id3, -101); |
| 217 // decode |
| 218 Element element2 = codec.decode(context, id1, id2, id3); |
| 219 expect(element2, element); |
| 220 } |
| 221 } |
| 222 |
| 223 void test_encode_getter_real() { |
| 224 resolveTestUnit(''' |
| 225 class A { |
| 226 int get test => 42; |
| 227 } |
| 228 '''); |
| 229 PropertyAccessorElement element = findElement('test', ElementKind.GETTER); |
| 230 int id1 = codec.encode1(element); |
| 231 int id2 = codec.encode2(element); |
| 232 int id3 = codec.encode3(element); |
| 233 expect(id1, isNonNegative); |
| 234 expect(id2, element.nameOffset); |
| 235 expect(id3, ElementKind.GETTER.ordinal); |
| 236 // decode |
| 237 Element element2 = codec.decode(context, id1, id2, id3); |
| 238 expect(element2, element); |
| 239 } |
| 240 |
| 241 void test_encode_getter_synthetic() { |
| 242 resolveTestUnit(''' |
| 243 class A { |
| 244 int test; |
| 245 } |
| 246 '''); |
| 247 FieldElement field = findElement('test', ElementKind.FIELD); |
| 248 PropertyAccessorElement element = field.getter; |
| 249 int id1 = codec.encode1(element); |
| 250 int id2 = codec.encode2(element); |
| 251 int id3 = codec.encode3(element); |
| 252 expect(id1, isNonNegative); |
| 253 expect(id2, element.nameOffset); |
| 254 expect(id3, ElementKind.GETTER.ordinal); |
| 255 // decode |
| 256 Element element2 = codec.decode(context, id1, id2, id3); |
| 257 expect(element2, element); |
| 258 } |
| 259 |
| 260 void test_encode_LibraryElement() { |
| 261 resolveTestUnit(''' |
| 262 class A { |
| 263 test() {} |
| 264 } |
| 265 '''); |
| 266 Element element = testLibraryElement; |
| 267 int id1 = codec.encode1(element); |
| 268 int id2 = codec.encode2(element); |
| 269 int id3 = codec.encode3(element); |
| 270 expect(id1, isNonNegative); |
| 271 expect(id2, element.nameOffset); |
| 272 expect(id3, ElementKind.LIBRARY.ordinal); |
| 273 // decode |
| 274 Element element2 = codec.decode(context, id1, id2, id3); |
| 275 expect(element2, element); |
| 276 } |
| 277 |
| 278 void test_encode_MethodElement() { |
| 279 resolveTestUnit(''' |
| 280 class A { |
| 281 test() {} |
| 282 } |
| 283 '''); |
| 284 Element element = findElement('test'); |
| 285 int id1 = codec.encode1(element); |
| 286 int id2 = codec.encode2(element); |
| 287 int id3 = codec.encode3(element); |
| 288 expect(id1, isNonNegative); |
| 289 expect(id2, element.nameOffset); |
| 290 expect(id3, ElementKind.METHOD.ordinal); |
| 291 // decode |
| 292 Element element2 = codec.decode(context, id1, id2, id3); |
| 293 expect(element2, element); |
| 294 } |
| 295 |
| 296 void test_encode_NameElement() { |
| 297 Element element = new NameElement('test'); |
| 298 int id1 = codec.encode1(element); |
| 299 int id2 = codec.encode2(element); |
| 300 int id3 = codec.encode3(element); |
| 301 expect(id1, ElementCodec.NAMED_FILE_ID); |
| 302 expect(id2, isNonNegative); |
| 303 expect(id3, ElementCodec.NAMED_KIND_ID); |
| 304 } |
| 305 |
| 306 void test_encode_nullLibraryElement() { |
| 307 resolveTestUnit(''' |
| 308 test() {} |
| 309 '''); |
| 310 Element element = findElement('test'); |
| 311 int id1 = codec.encode1(element); |
| 312 int id2 = codec.encode2(element); |
| 313 int id3 = codec.encode3(element); |
| 314 context.setContents(testSource, ''); |
| 315 // decode |
| 316 Element element2 = codec.decode(context, id1, id2, id3); |
| 317 expect(element2, isNull); |
| 318 } |
| 319 |
| 320 void test_encode_setter_real() { |
| 321 resolveTestUnit(''' |
| 322 class A { |
| 323 void set test(x) {} |
| 324 } |
| 325 '''); |
| 326 PropertyAccessorElement element = findElement('test=', ElementKind.SETTER); |
| 327 int id1 = codec.encode1(element); |
| 328 int id2 = codec.encode2(element); |
| 329 int id3 = codec.encode3(element); |
| 330 expect(id1, isNonNegative); |
| 331 expect(id2, element.nameOffset); |
| 332 expect(id3, ElementKind.SETTER.ordinal); |
| 333 // decode |
| 334 Element element2 = codec.decode(context, id1, id2, id3); |
| 335 expect(element2, element); |
| 336 } |
| 337 |
| 338 void test_encode_setter_synthetic() { |
| 339 resolveTestUnit(''' |
| 340 class A { |
| 341 int test; |
| 342 } |
| 343 '''); |
| 344 FieldElement field = findElement('test', ElementKind.FIELD); |
| 345 PropertyAccessorElement element = field.setter; |
| 346 int id1 = codec.encode1(element); |
| 347 int id2 = codec.encode2(element); |
| 348 int id3 = codec.encode3(element); |
| 349 expect(id1, isNonNegative); |
| 350 expect(id2, element.nameOffset); |
| 351 expect(id3, ElementKind.SETTER.ordinal); |
| 352 // decode |
| 353 Element element2 = codec.decode(context, id1, id2, id3); |
| 354 expect(element2, element); |
| 355 } |
| 356 |
| 75 void test_encodeHash_notLocal() { | 357 void test_encodeHash_notLocal() { |
| 76 resolveTestUnit(''' | 358 resolveTestUnit(''' |
| 77 class A { | 359 class A { |
| 78 void mainA() { | 360 void mainA() { |
| 79 int foo; // A | 361 int foo; // A |
| 80 } | 362 } |
| 81 void mainB() { | 363 void mainB() { |
| 82 int foo; // B | 364 int foo; // B |
| 83 int bar; | 365 int bar; |
| 84 } | 366 } |
| 85 } | 367 } |
| 86 '''); | 368 '''); |
| 87 MethodElement mainA = findElement('mainA'); | 369 MethodElement mainA = findElement('mainA'); |
| 88 MethodElement mainB = findElement('mainB'); | 370 MethodElement mainB = findElement('mainB'); |
| 89 Element fooA = mainA.localVariables[0]; | 371 Element fooA = mainA.localVariables[0]; |
| 90 Element fooB = mainB.localVariables[0]; | 372 Element fooB = mainB.localVariables[0]; |
| 91 Element bar = mainB.localVariables[1]; | 373 Element bar = mainB.localVariables[1]; |
| 92 int id_fooA = codec.encodeHash(fooA); | 374 int id_fooA = codec.encodeHash(fooA); |
| 93 int id_fooB = codec.encodeHash(fooB); | 375 int id_fooB = codec.encodeHash(fooB); |
| 94 int id_bar = codec.encodeHash(bar); | 376 int id_bar = codec.encodeHash(bar); |
| 95 expect(id_fooA == id_fooB, isTrue); | 377 expect(id_fooA == id_fooB, isTrue); |
| 96 expect(id_fooA == id_bar, isFalse); | 378 expect(id_fooA == id_bar, isFalse); |
| 97 } | 379 } |
| 98 | 380 } |
| 99 void test_field() { | 381 |
| 100 resolveTestUnit(''' | |
| 101 class A { | |
| 102 int field; | |
| 103 } | |
| 104 '''); | |
| 105 FieldElement field = findElement('field', ElementKind.FIELD); | |
| 106 PropertyAccessorElement getter = field.getter; | |
| 107 PropertyAccessorElement setter = field.setter; | |
| 108 { | |
| 109 int id = codec.encode(getter, false); | |
| 110 expect(codec.decode(context, id), getter); | |
| 111 } | |
| 112 { | |
| 113 int id = codec.encode(setter, false); | |
| 114 expect(codec.decode(context, id), setter); | |
| 115 } | |
| 116 { | |
| 117 int id = codec.encode(field, false); | |
| 118 expect(codec.decode(context, id), field); | |
| 119 } | |
| 120 } | |
| 121 | |
| 122 void test_filePackage_uriMix() { | |
| 123 MethodElement buildMethodElement(Source source) { | |
| 124 CompilationUnitElementImpl unitElement = | |
| 125 new CompilationUnitElementImpl('file.dart'); | |
| 126 LibraryElementImpl libraryElement = | |
| 127 new LibraryElementImpl(null, 'lib', 0); | |
| 128 ClassElementImpl classElement = new ClassElementImpl('A', 0); | |
| 129 MethodElementImpl methodElement = new MethodElementImpl('m', 0); | |
| 130 unitElement.source = source; | |
| 131 libraryElement.definingCompilationUnit = unitElement; | |
| 132 unitElement.types = [classElement]; | |
| 133 classElement.methods = [methodElement]; | |
| 134 return methodElement; | |
| 135 } | |
| 136 // file: | |
| 137 int fileId; | |
| 138 { | |
| 139 Source source = new _TestSource('/my/file.dart', 'file:///my/file.dart'); | |
| 140 var methodElement = buildMethodElement(source); | |
| 141 fileId = codec.encode(methodElement, true); | |
| 142 } | |
| 143 // package: | |
| 144 int packageId; | |
| 145 { | |
| 146 Source source = | |
| 147 new _TestSource('/my/file.dart', 'package:my_pkg/file.dart'); | |
| 148 var methodElement = buildMethodElement(source); | |
| 149 packageId = codec.encode(methodElement, true); | |
| 150 } | |
| 151 // should be the same | |
| 152 expect(packageId, fileId); | |
| 153 } | |
| 154 | |
| 155 void test_localLocalVariable() { | |
| 156 resolveTestUnit(''' | |
| 157 main() { | |
| 158 { | |
| 159 foo() { | |
| 160 int bar; // A | |
| 161 } | |
| 162 } | |
| 163 { | |
| 164 foo() { | |
| 165 int bar; // B | |
| 166 } | |
| 167 } | |
| 168 } | |
| 169 '''); | |
| 170 { | |
| 171 LocalVariableElement element = findNodeElementAtString('bar; // A', null); | |
| 172 int id = codec.encode(element, false); | |
| 173 expect(codec.decode(context, id), element); | |
| 174 } | |
| 175 { | |
| 176 LocalVariableElement element = findNodeElementAtString('bar; // B', null); | |
| 177 int id = codec.encode(element, false); | |
| 178 expect(codec.decode(context, id), element); | |
| 179 } | |
| 180 // check strings, "foo" as a single string, no "foo@17" or "bar@35" | |
| 181 expect(stringCodec.nameToIndex, hasLength(4)); | |
| 182 expect(stringCodec.nameToIndex, containsPair('file:///test.dart', 0)); | |
| 183 expect(stringCodec.nameToIndex, containsPair('main', 1)); | |
| 184 expect(stringCodec.nameToIndex, containsPair('foo', 2)); | |
| 185 expect(stringCodec.nameToIndex, containsPair('bar', 3)); | |
| 186 } | |
| 187 | |
| 188 void test_localVariable() { | |
| 189 resolveTestUnit(''' | |
| 190 main() { | |
| 191 { | |
| 192 int foo; // A | |
| 193 } | |
| 194 { | |
| 195 int foo; // B | |
| 196 } | |
| 197 } | |
| 198 '''); | |
| 199 { | |
| 200 LocalVariableElement element = findNodeElementAtString('foo; // A', null); | |
| 201 int id = codec.encode(element, false); | |
| 202 expect(codec.decode(context, id), element); | |
| 203 } | |
| 204 { | |
| 205 LocalVariableElement element = findNodeElementAtString('foo; // B', null); | |
| 206 int id = codec.encode(element, false); | |
| 207 expect(codec.decode(context, id), element); | |
| 208 } | |
| 209 // check strings, "foo" as a single string, no "foo@21" or "foo@47" | |
| 210 expect(stringCodec.nameToIndex, hasLength(3)); | |
| 211 expect(stringCodec.nameToIndex, containsPair('file:///test.dart', 0)); | |
| 212 expect(stringCodec.nameToIndex, containsPair('main', 1)); | |
| 213 expect(stringCodec.nameToIndex, containsPair('foo', 2)); | |
| 214 } | |
| 215 | |
| 216 void test_notLocal() { | |
| 217 resolveTestUnit(''' | |
| 218 main() { | |
| 219 int foo; | |
| 220 } | |
| 221 '''); | |
| 222 LocalVariableElement element = findElement('foo'); | |
| 223 int id = codec.encode(element, false); | |
| 224 expect(codec.encode(element, false), id); | |
| 225 expect(codec.decode(context, id), element); | |
| 226 // check strings | |
| 227 expect(stringCodec.nameToIndex, hasLength(3)); | |
| 228 expect(stringCodec.nameToIndex, containsPair('file:///test.dart', 0)); | |
| 229 expect(stringCodec.nameToIndex, containsPair('main', 1)); | |
| 230 expect(stringCodec.nameToIndex, containsPair('foo', 2)); | |
| 231 } | |
| 232 } | |
| 233 | |
| 234 @reflectiveTest | 382 @reflectiveTest |
| 235 class _RelationshipCodecTest { | 383 class _RelationshipCodecTest { |
| 236 StringCodec stringCodec = new StringCodec(); | 384 StringCodec stringCodec = new StringCodec(); |
| 237 RelationshipCodec codec; | 385 RelationshipCodec codec; |
| 238 | 386 |
| 239 void setUp() { | 387 void setUp() { |
| 240 codec = new RelationshipCodec(stringCodec); | 388 codec = new RelationshipCodec(stringCodec); |
| 241 } | 389 } |
| 242 | 390 |
| 243 void test_all() { | 391 void test_all() { |
| 244 Relationship relationship = Relationship.getRelationship('my-relationship'); | 392 Relationship relationship = Relationship.getRelationship('my-relationship'); |
| 245 int id = codec.encode(relationship); | 393 int id = codec.encode(relationship); |
| 246 expect(codec.decode(id), relationship); | 394 expect(codec.decode(id), relationship); |
| 247 } | 395 } |
| 248 } | 396 } |
| 249 | 397 |
| 250 @reflectiveTest | 398 @reflectiveTest |
| 251 class _StringCodecTest { | 399 class _StringCodecTest { |
| 252 StringCodec codec = new StringCodec(); | 400 StringCodec codec = new StringCodec(); |
| 253 | 401 |
| 254 void test_all() { | 402 void test_all() { |
| 255 int idA = codec.encode('aaa'); | 403 int idA = codec.encode('aaa'); |
| 256 int idB = codec.encode('bbb'); | 404 int idB = codec.encode('bbb'); |
| 257 expect(codec.decode(idA), 'aaa'); | 405 expect(codec.decode(idA), 'aaa'); |
| 258 expect(codec.decode(idB), 'bbb'); | 406 expect(codec.decode(idB), 'bbb'); |
| 259 } | 407 } |
| 260 } | 408 } |
| 261 | |
| 262 class _TestSource implements Source { | |
| 263 final String fullName; | |
| 264 final String encoding; | |
| 265 | |
| 266 _TestSource(this.fullName, this.encoding); | |
| 267 | |
| 268 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | |
| 269 } | |
| OLD | NEW |