Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 import 'dart:async'; | 5 import 'dart:async'; |
| 6 import 'package:compiler/src/commandline_options.dart'; | 6 import 'package:compiler/src/commandline_options.dart'; |
| 7 import 'package:compiler/src/common.dart'; | 7 import 'package:compiler/src/common.dart'; |
| 8 import 'package:compiler/src/common_elements.dart'; | 8 import 'package:compiler/src/common_elements.dart'; |
| 9 import 'package:compiler/src/compiler.dart'; | 9 import 'package:compiler/src/compiler.dart'; |
| 10 import 'package:compiler/src/elements/elements.dart'; | |
| 11 import 'package:compiler/src/elements/entities.dart'; | 10 import 'package:compiler/src/elements/entities.dart'; |
| 12 import 'package:compiler/src/resolution/tree_elements.dart'; | |
| 13 import 'package:compiler/src/tree/nodes.dart' as ast; | |
| 14 import 'package:expect/expect.dart'; | 11 import 'package:expect/expect.dart'; |
| 15 import 'package:kernel/ast.dart' as ir; | |
| 16 | 12 |
| 17 import '../annotated_code_helper.dart'; | 13 import '../annotated_code_helper.dart'; |
| 18 import '../memory_compiler.dart'; | 14 import '../memory_compiler.dart'; |
| 19 import '../equivalence/id_equivalence.dart'; | 15 import '../equivalence/id_equivalence.dart'; |
| 20 import '../kernel/compiler_helper.dart'; | 16 import '../kernel/compiler_helper.dart'; |
| 21 | 17 |
| 22 /// Function that compiles [code] with [options] and returns the [Compiler] obje ct. | 18 /// Function that compiles [code] with [options] and returns the [Compiler] obje ct. |
| 23 typedef Future<Compiler> CompileFunction( | 19 typedef Future<Compiler> CompileFunction( |
| 24 AnnotatedCode code, Uri mainUri, List<String> options); | 20 AnnotatedCode code, Uri mainUri, List<String> options); |
| 25 | 21 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 81 } | 77 } |
| 82 }); | 78 }); |
| 83 }); | 79 }); |
| 84 elementEnvironment.forEachLibraryMember(mainLibrary, (MemberEntity member) { | 80 elementEnvironment.forEachLibraryMember(mainLibrary, (MemberEntity member) { |
| 85 computeMemberData(compiler, member, actualMap, verbose: verbose); | 81 computeMemberData(compiler, member, actualMap, verbose: verbose); |
| 86 }); | 82 }); |
| 87 return new IdData( | 83 return new IdData( |
| 88 code, compiler, elementEnvironment, mainUri, expectedMap, actualMap); | 84 code, compiler, elementEnvironment, mainUri, expectedMap, actualMap); |
| 89 } | 85 } |
| 90 | 86 |
| 91 class ActualData { | |
| 92 final Id id; | |
| 93 final String value; | |
| 94 final SourceSpan sourceSpan; | |
| 95 final Object object; | |
| 96 | |
| 97 ActualData(this.id, this.value, this.sourceSpan, this.object); | |
| 98 } | |
| 99 | |
| 100 /// Data collected by [computeData]. | 87 /// Data collected by [computeData]. |
| 101 class IdData { | 88 class IdData { |
| 102 final AnnotatedCode code; | 89 final AnnotatedCode code; |
| 103 final Compiler compiler; | 90 final Compiler compiler; |
| 104 final ElementEnvironment elementEnvironment; | 91 final ElementEnvironment elementEnvironment; |
| 105 final Uri mainUri; | 92 final Uri mainUri; |
| 106 final Map<Id, String> expectedMap; | 93 final Map<Id, String> expectedMap; |
| 107 final Map<Id, ActualData> actualMap; | 94 final Map<Id, ActualData> actualMap; |
| 108 | 95 |
| 109 IdData(this.code, this.compiler, this.elementEnvironment, this.mainUri, | 96 IdData(this.code, this.compiler, this.elementEnvironment, this.mainUri, |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 148 if (!actualMap.containsKey(id)) { | 135 if (!actualMap.containsKey(id)) { |
| 149 int offset = compiler.reporter | 136 int offset = compiler.reporter |
| 150 .spanFromSpannable( | 137 .spanFromSpannable( |
| 151 computeSpannable(elementEnvironment, mainUri, id)) | 138 computeSpannable(elementEnvironment, mainUri, id)) |
| 152 .begin; | 139 .begin; |
| 153 annotations[offset] = '${expected} | ---'; | 140 annotations[offset] = '${expected} | ---'; |
| 154 } | 141 } |
| 155 }); | 142 }); |
| 156 return withAnnotations(annotations); | 143 return withAnnotations(annotations); |
| 157 } | 144 } |
| 145 | |
| 146 String computeDiffCodeFor(IdData other) { | |
| 147 Map<int, String> annotations = <int, String>{}; | |
| 148 actualMap.forEach((Id id, ActualData data1) { | |
| 149 ActualData data2 = other.actualMap[id]; | |
| 150 if (data1.value != data2?.value) { | |
| 151 annotations[data1.sourceSpan.begin] = | |
| 152 '${data1.value} | ${data2?.value ?? '---'}'; | |
| 153 } | |
| 154 }); | |
| 155 other.actualMap.forEach((Id id, ActualData data2) { | |
| 156 if (!actualMap.containsKey(id)) { | |
| 157 int offset = compiler.reporter | |
| 158 .spanFromSpannable( | |
| 159 computeSpannable(elementEnvironment, mainUri, id)) | |
| 160 .begin; | |
| 161 annotations[offset] = '--- | ${data2.value}'; | |
| 162 } | |
| 163 }); | |
| 164 return withAnnotations(annotations); | |
| 165 } | |
| 158 } | 166 } |
| 159 | 167 |
| 160 /// Compiles the [annotatedCode] with the provided [options] and calls | 168 /// Compiles the [annotatedCode] with the provided [options] and calls |
| 161 /// [computeMemberData] for each member. The result is checked against the | 169 /// [computeMemberData] for each member. The result is checked against the |
| 162 /// expected data derived from [annotatedCode]. | 170 /// expected data derived from [annotatedCode]. |
| 163 Future checkCode( | 171 Future checkCode( |
| 164 String annotatedCode, | 172 String annotatedCode, |
| 165 ComputeMemberDataFunction computeMemberData, | 173 ComputeMemberDataFunction computeMemberData, |
| 166 CompileFunction compileFunction, | 174 CompileFunction compileFunction, |
| 167 {List<String> options: const <String>[], | 175 {List<String> options: const <String>[], |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 241 id = new NodeId(annotation.offset); | 249 id = new NodeId(annotation.offset); |
| 242 expected = text; | 250 expected = text; |
| 243 } else { | 251 } else { |
| 244 id = new ElementId(text.substring(0, colonPos)); | 252 id = new ElementId(text.substring(0, colonPos)); |
| 245 expected = text.substring(colonPos + 1); | 253 expected = text.substring(colonPos + 1); |
| 246 } | 254 } |
| 247 map[id] = expected; | 255 map[id] = expected; |
| 248 } | 256 } |
| 249 return map; | 257 return map; |
| 250 } | 258 } |
| 251 | |
| 252 /// Mixin used for computing [Id] data. | |
| 253 abstract class ComputerMixin { | |
|
Siggi Cherem (dart-lang)
2017/08/18 21:20:21
ha! - I just realized this was a move :(...
comme
Johnni Winther
2017/08/19 09:30:52
Acknowledged.
| |
| 254 Map<Id, ActualData> get actualMap; | |
| 255 | |
| 256 void registerValue( | |
| 257 SourceSpan sourceSpan, Id id, String value, Object object) { | |
| 258 if (id != null && value != null) { | |
| 259 actualMap[id] = new ActualData(id, value, sourceSpan, object); | |
| 260 } | |
| 261 } | |
| 262 } | |
| 263 | |
| 264 /// Abstract AST visitor for computing [Id] data. | |
| 265 abstract class AbstractResolvedAstComputer extends ast.Visitor | |
| 266 with AstEnumeratorMixin, ComputerMixin { | |
| 267 final DiagnosticReporter reporter; | |
| 268 final Map<Id, ActualData> actualMap; | |
| 269 final ResolvedAst resolvedAst; | |
| 270 | |
| 271 AbstractResolvedAstComputer(this.reporter, this.actualMap, this.resolvedAst); | |
| 272 | |
| 273 TreeElements get elements => resolvedAst.elements; | |
| 274 | |
| 275 void computeForElement(AstElement element) { | |
| 276 ElementId id = computeElementId(element); | |
| 277 if (id == null) return; | |
| 278 String value = computeElementValue(element); | |
| 279 registerValue(element.sourcePosition, id, value, element); | |
| 280 } | |
| 281 | |
| 282 void computeForNode(ast.Node node, AstElement element) { | |
| 283 NodeId id = computeNodeId(node, element); | |
| 284 if (id == null) return; | |
| 285 String value = computeNodeValue(node, element); | |
| 286 SourceSpan sourceSpan = new SourceSpan(resolvedAst.sourceUri, | |
| 287 node.getBeginToken().charOffset, node.getEndToken().charEnd); | |
| 288 registerValue(sourceSpan, id, value, element ?? node); | |
| 289 } | |
| 290 | |
| 291 String computeElementValue(AstElement element); | |
| 292 | |
| 293 String computeNodeValue(ast.Node node, AstElement element); | |
| 294 | |
| 295 void run() { | |
| 296 resolvedAst.node.accept(this); | |
| 297 } | |
| 298 | |
| 299 visitNode(ast.Node node) { | |
| 300 node.visitChildren(this); | |
| 301 } | |
| 302 | |
| 303 visitVariableDefinitions(ast.VariableDefinitions node) { | |
| 304 for (ast.Node child in node.definitions) { | |
| 305 AstElement element = elements[child]; | |
| 306 if (element == null) { | |
| 307 reportHere(reporter, child, 'No element for variable.'); | |
| 308 } else if (!element.isLocal) { | |
| 309 computeForElement(element); | |
| 310 } else { | |
| 311 computeForNode(child, element); | |
| 312 } | |
| 313 } | |
| 314 visitNode(node); | |
| 315 } | |
| 316 | |
| 317 visitFunctionExpression(ast.FunctionExpression node) { | |
| 318 AstElement element = elements.getFunctionDefinition(node); | |
| 319 if (!element.isLocal) { | |
| 320 computeForElement(element); | |
| 321 } else { | |
| 322 computeForNode(node, element); | |
| 323 } | |
| 324 visitNode(node); | |
| 325 } | |
| 326 | |
| 327 visitSend(ast.Send node) { | |
| 328 computeForNode(node, null); | |
| 329 visitNode(node); | |
| 330 } | |
| 331 | |
| 332 visitSendSet(ast.SendSet node) { | |
| 333 computeForNode(node, null); | |
| 334 visitNode(node); | |
| 335 } | |
| 336 } | |
| 337 | |
| 338 /// Abstract IR visitor for computing [Id] data. | |
| 339 abstract class AbstractIrComputer extends ir.Visitor | |
| 340 with IrEnumeratorMixin, ComputerMixin { | |
| 341 final Map<Id, ActualData> actualMap; | |
| 342 | |
| 343 AbstractIrComputer(this.actualMap); | |
| 344 | |
| 345 void computeForMember(ir.Member member) { | |
| 346 ElementId id = computeElementId(member); | |
| 347 if (id == null) return; | |
| 348 String value = computeMemberValue(member); | |
| 349 registerValue(computeSpannable(member), id, value, member); | |
| 350 } | |
| 351 | |
| 352 void computeForNode(ir.TreeNode node) { | |
| 353 NodeId id = computeNodeId(node); | |
| 354 if (id == null) return; | |
| 355 String value = computeNodeValue(node); | |
| 356 registerValue(computeSpannable(node), id, value, node); | |
| 357 } | |
| 358 | |
| 359 Spannable computeSpannable(ir.TreeNode node) { | |
| 360 return new SourceSpan( | |
| 361 Uri.parse(node.location.file), node.fileOffset, node.fileOffset + 1); | |
| 362 } | |
| 363 | |
| 364 String computeMemberValue(ir.Member member); | |
| 365 | |
| 366 String computeNodeValue(ir.TreeNode node); | |
| 367 | |
| 368 void run(ir.Node root) { | |
| 369 root.accept(this); | |
| 370 } | |
| 371 | |
| 372 defaultNode(ir.Node node) { | |
| 373 node.visitChildren(this); | |
| 374 } | |
| 375 | |
| 376 defaultMember(ir.Member node) { | |
| 377 computeForMember(node); | |
| 378 super.defaultMember(node); | |
| 379 } | |
| 380 | |
| 381 visitMethodInvocation(ir.MethodInvocation node) { | |
| 382 computeForNode(node); | |
| 383 super.visitMethodInvocation(node); | |
| 384 } | |
| 385 | |
| 386 visitPropertyGet(ir.PropertyGet node) { | |
| 387 computeForNode(node); | |
| 388 super.visitPropertyGet(node); | |
| 389 } | |
| 390 | |
| 391 visitVariableDeclaration(ir.VariableDeclaration node) { | |
| 392 computeForNode(node); | |
| 393 super.visitVariableDeclaration(node); | |
| 394 } | |
| 395 | |
| 396 visitFunctionDeclaration(ir.FunctionDeclaration node) { | |
| 397 computeForNode(node); | |
| 398 super.visitFunctionDeclaration(node); | |
| 399 } | |
| 400 | |
| 401 visitFunctionExpression(ir.FunctionExpression node) { | |
| 402 computeForNode(node); | |
| 403 super.visitFunctionExpression(node); | |
| 404 } | |
| 405 } | |
| OLD | NEW |