Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(212)

Side by Side Diff: tests/compiler/dart2js/sourcemaps/sourcemap_helper.dart

Issue 1678043003: Add Dart code to diff_view (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Cleanup Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 sourcemap.helper; 5 library sourcemap.helper;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:io';
8 import 'package:compiler/compiler_new.dart'; 9 import 'package:compiler/compiler_new.dart';
9 import 'package:compiler/src/apiimpl.dart' as api; 10 import 'package:compiler/src/apiimpl.dart' as api;
10 import 'package:compiler/src/null_compiler_output.dart' show NullSink; 11 import 'package:compiler/src/null_compiler_output.dart' show NullSink;
11 import 'package:compiler/src/elements/elements.dart'; 12 import 'package:compiler/src/elements/elements.dart';
12 import 'package:compiler/src/helpers/helpers.dart'; 13 import 'package:compiler/src/helpers/helpers.dart';
13 import 'package:compiler/src/filenames.dart'; 14 import 'package:compiler/src/filenames.dart';
14 import 'package:compiler/src/io/code_output.dart'; 15 import 'package:compiler/src/io/code_output.dart';
15 import 'package:compiler/src/io/source_file.dart'; 16 import 'package:compiler/src/io/source_file.dart';
16 import 'package:compiler/src/io/source_information.dart'; 17 import 'package:compiler/src/io/source_information.dart';
17 import 'package:compiler/src/io/position_information.dart'; 18 import 'package:compiler/src/io/position_information.dart';
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 297
297 /// Creates a processor for the Dart file [filename]. 298 /// Creates a processor for the Dart file [filename].
298 SourceMapProcessor(String filename, {this.outputToFile: false}) { 299 SourceMapProcessor(String filename, {this.outputToFile: false}) {
299 inputUri = Uri.base.resolve(nativeToUriPath(filename)); 300 inputUri = Uri.base.resolve(nativeToUriPath(filename));
300 jsPath = 'out.js'; 301 jsPath = 'out.js';
301 targetUri = Uri.base.resolve(jsPath); 302 targetUri = Uri.base.resolve(jsPath);
302 sourceMapFileUri = Uri.base.resolve('${jsPath}.map'); 303 sourceMapFileUri = Uri.base.resolve('${jsPath}.map');
303 } 304 }
304 305
305 /// Computes the [SourceMapInfo] for the compiled elements. 306 /// Computes the [SourceMapInfo] for the compiled elements.
306 Future<List<SourceMapInfo>> process( 307 Future<SourceMaps> process(
307 List<String> options, 308 List<String> options,
308 {bool verbose: true, 309 {bool verbose: true,
309 bool perElement: true}) async { 310 bool perElement: true,
311 bool forMain: false}) async {
310 OutputProvider outputProvider = outputToFile 312 OutputProvider outputProvider = outputToFile
311 ? new CloningOutputProvider(targetUri, sourceMapFileUri) 313 ? new CloningOutputProvider(targetUri, sourceMapFileUri)
312 : new OutputProvider(); 314 : new OutputProvider();
313 if (options.contains(USE_NEW_SOURCE_INFO)) { 315 if (options.contains(USE_NEW_SOURCE_INFO)) {
314 if (verbose) print('Using the new source information system.'); 316 if (verbose) print('Using the new source information system.');
315 useNewSourceInfo = true; 317 useNewSourceInfo = true;
316 } 318 }
317 api.CompilerImpl compiler = await compilerFor( 319 api.CompilerImpl compiler = await compilerFor(
318 outputProvider: outputProvider, 320 outputProvider: outputProvider,
319 // TODO(johnniwinther): Use [verbose] to avoid showing diagnostics. 321 // TODO(johnniwinther): Use [verbose] to avoid showing diagnostics.
320 options: ['--out=$targetUri', '--source-map=$sourceMapFileUri'] 322 options: ['--out=$targetUri', '--source-map=$sourceMapFileUri']
321 ..addAll(options)); 323 ..addAll(options));
322 if (options.contains(DISABLE_INLINING)) { 324 if (options.contains(DISABLE_INLINING)) {
323 if (verbose) print('Inlining disabled'); 325 if (verbose) print('Inlining disabled');
324 compiler.disableInlining = true; 326 compiler.disableInlining = true;
325 } 327 }
326 328
327 JavaScriptBackend backend = compiler.backend; 329 JavaScriptBackend backend = compiler.backend;
328 var handler = compiler.handler; 330 var handler = compiler.handler;
329 SourceFileProvider sourceFileProvider = handler.provider; 331 SourceFileProvider sourceFileProvider = handler.provider;
330 sourceFileManager = new ProviderSourceFileManager( 332 sourceFileManager = new ProviderSourceFileManager(
331 sourceFileProvider, 333 sourceFileProvider,
332 outputProvider); 334 outputProvider);
333 RecordingSourceInformationStrategy strategy = 335 RecordingSourceInformationStrategy strategy =
334 new RecordingSourceInformationStrategy(backend.sourceInformationStrategy ); 336 new RecordingSourceInformationStrategy(backend.sourceInformationStrategy );
335 backend.sourceInformationStrategy = strategy; 337 backend.sourceInformationStrategy = strategy;
336 await compiler.run(inputUri); 338 await compiler.run(inputUri);
337 339
338 List<SourceMapInfo> infoList = <SourceMapInfo>[]; 340 SourceMapInfo mainSourceMapInfo;
341 Map<Element, SourceMapInfo> elementSourceMapInfos =
342 <Element, SourceMapInfo>{};
339 if (perElement) { 343 if (perElement) {
340 backend.generatedCode.forEach((Element element, js.Expression node) { 344 backend.generatedCode.forEach((Element element, js.Expression node) {
341 RecordedSourceInformationProcess subProcess = 345 RecordedSourceInformationProcess subProcess =
342 strategy.subProcessForNode(node); 346 strategy.subProcessForNode(node);
343 if (subProcess == null) { 347 if (subProcess == null) {
344 // TODO(johnniwinther): Find out when this is happening and if it 348 // TODO(johnniwinther): Find out when this is happening and if it
345 // is benign. (Known to happen for `bool#fromString`) 349 // is benign. (Known to happen for `bool#fromString`)
346 print('No subProcess found for $element'); 350 print('No subProcess found for $element');
347 return; 351 return;
348 } 352 }
349 LocationMap nodeMap = subProcess.nodeToSourceLocationsMap; 353 LocationMap nodeMap = subProcess.nodeToSourceLocationsMap;
350 String code = subProcess.code; 354 String code = subProcess.code;
351 CodePositionRecorder codePositions = subProcess.codePositions; 355 CodePositionRecorder codePositions = subProcess.codePositions;
352 CodePointComputer visitor = 356 CodePointComputer visitor =
353 new CodePointComputer(sourceFileManager, code, nodeMap); 357 new CodePointComputer(sourceFileManager, code, nodeMap);
354 visitor.apply(node); 358 new JavaScriptTracer(codePositions, [visitor]).apply(node);
355 List<CodePoint> codePoints = visitor.codePoints; 359 List<CodePoint> codePoints = visitor.codePoints;
356 infoList.add(new SourceMapInfo( 360 elementSourceMapInfos[element] = new SourceMapInfo(
357 element, code, node, 361 element,
362 code,
363 node,
358 codePoints, 364 codePoints,
359 codePositions/*strategy.codePositions*/, 365 codePositions,
360 nodeMap)); 366 nodeMap);
361 }); 367 });
362 } else { 368 }
369 if (forMain) {
363 // TODO(johnniwinther): Supported multiple output units. 370 // TODO(johnniwinther): Supported multiple output units.
364 RecordedSourceInformationProcess process = strategy.processMap.keys.first; 371 RecordedSourceInformationProcess process = strategy.processMap.keys.first;
365 js.Node node = strategy.processMap[process]; 372 js.Node node = strategy.processMap[process];
366 String code; 373 String code;
367 LocationMap nodeMap; 374 LocationMap nodeMap;
368 CodePositionRecorder codePositions; 375 CodePositionRecorder codePositions;
369 nodeMap = process.nodeToSourceLocationsMap; 376 nodeMap = process.nodeToSourceLocationsMap;
370 code = process.code; 377 code = process.code;
371 codePositions = process.codePositions; 378 codePositions = process.codePositions;
372 CodePointComputer visitor = 379 CodePointComputer visitor =
373 new CodePointComputer(sourceFileManager, code, nodeMap); 380 new CodePointComputer(sourceFileManager, code, nodeMap);
374 visitor.apply(node); 381 new JavaScriptTracer(codePositions, [visitor]).apply(node);
375 List<CodePoint> codePoints = visitor.codePoints; 382 List<CodePoint> codePoints = visitor.codePoints;
376 infoList.add(new SourceMapInfo( 383 mainSourceMapInfo = new SourceMapInfo(
377 null, code, node, 384 null, code, node,
378 codePoints, 385 codePoints,
379 codePositions, 386 codePositions,
380 nodeMap)); 387 nodeMap);
381 } 388 }
382 389
383 return infoList; 390 return new SourceMaps(
391 sourceFileManager, mainSourceMapInfo, elementSourceMapInfos);
384 } 392 }
385 } 393 }
386 394
395 class SourceMaps {
396 final SourceFileManager sourceFileManager;
397 // TODO(johnniwinther): Supported multiple output units.
398 final SourceMapInfo mainSourceMapInfo;
399 final Map<Element, SourceMapInfo> elementSourceMapInfos;
400
401 SourceMaps(
402 this.sourceFileManager,
403 this.mainSourceMapInfo,
404 this.elementSourceMapInfos);
405 }
406
387 /// Source mapping information for the JavaScript code of an [Element]. 407 /// Source mapping information for the JavaScript code of an [Element].
388 class SourceMapInfo { 408 class SourceMapInfo {
389 final String name; 409 final String name;
390 final Element element; 410 final Element element;
391 final String code; 411 final String code;
392 final js.Node node; 412 final js.Node node;
393 final List<CodePoint> codePoints; 413 final List<CodePoint> codePoints;
394 final CodePositionMap jsCodePositions; 414 final CodePositionMap jsCodePositions;
395 final LocationMap nodeMap; 415 final LocationMap nodeMap;
396 416
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 470
451 Iterable<js.Node> get nodes => map.nodes.where((n) => _nodes.contains(n)); 471 Iterable<js.Node> get nodes => map.nodes.where((n) => _nodes.contains(n));
452 472
453 Map<int, List<SourceLocation>> operator[] (js.Node node) { 473 Map<int, List<SourceLocation>> operator[] (js.Node node) {
454 return map[node]; 474 return map[node];
455 } 475 }
456 } 476 }
457 477
458 478
459 /// Visitor that computes the [CodePoint]s for source mapping locations. 479 /// Visitor that computes the [CodePoint]s for source mapping locations.
460 class CodePointComputer extends js.BaseVisitor { 480 class CodePointComputer extends TraceListener {
461 final SourceFileManager sourceFileManager; 481 final SourceFileManager sourceFileManager;
462 final String code; 482 final String code;
463 final LocationMap nodeMap; 483 final LocationMap nodeMap;
464 List<CodePoint> codePoints = []; 484 List<CodePoint> codePoints = [];
465 485
466 CodePointComputer(this.sourceFileManager, this.code, this.nodeMap); 486 CodePointComputer(this.sourceFileManager, this.code, this.nodeMap);
467 487
468 String nodeToString(js.Node node) { 488 String nodeToString(js.Node node) {
469 js.JavaScriptPrintingOptions options = new js.JavaScriptPrintingOptions( 489 js.JavaScriptPrintingOptions options = new js.JavaScriptPrintingOptions(
470 shouldCompressOutput: true, 490 shouldCompressOutput: true,
471 preferSemicolonToNewlineInMinifiedOutput: true); 491 preferSemicolonToNewlineInMinifiedOutput: true);
472 LenientPrintingContext printingContext = new LenientPrintingContext(); 492 LenientPrintingContext printingContext = new LenientPrintingContext();
473 new js.Printer(options, printingContext).visit(node); 493 new js.Printer(options, printingContext).visit(node);
474 return printingContext.buffer.toString(); 494 return printingContext.buffer.toString();
475 } 495 }
476 496
477 String positionToString(int position) { 497 String positionToString(int position) {
478 String line = code.substring(position); 498 String line = code.substring(position);
479 int nl = line.indexOf('\n'); 499 int nl = line.indexOf('\n');
480 if (nl != -1) { 500 if (nl != -1) {
481 line = line.substring(0, nl); 501 line = line.substring(0, nl);
482 } 502 }
483 return line; 503 return line;
484 } 504 }
485 505
506 /// Called when [node] defines a step of the given [kind] at the given
507 /// [offset] when the generated JavaScript code.
508 void onStep(js.Node node, Offset offset, StepKind kind) {
509 register('$kind', node);
510 }
511
486 void register(String kind, js.Node node, {bool expectInfo: true}) { 512 void register(String kind, js.Node node, {bool expectInfo: true}) {
487 513
488 String dartCodeFromSourceLocation(SourceLocation sourceLocation) { 514 String dartCodeFromSourceLocation(SourceLocation sourceLocation) {
489 SourceFile sourceFile = 515 SourceFile sourceFile =
490 sourceFileManager.getSourceFile(sourceLocation.sourceUri); 516 sourceFileManager.getSourceFile(sourceLocation.sourceUri);
517 if (sourceFile == null) {
518 return sourceLocation.shortText;
519 }
491 return sourceFile.getLineText(sourceLocation.line) 520 return sourceFile.getLineText(sourceLocation.line)
492 .substring(sourceLocation.column).trim(); 521 .substring(sourceLocation.column).trim();
493 } 522 }
494 523
495 void addLocation(SourceLocation sourceLocation, String jsCode) { 524 void addLocation(SourceLocation sourceLocation, String jsCode) {
496 if (sourceLocation == null) { 525 if (sourceLocation == null) {
497 if (expectInfo) { 526 if (expectInfo) {
498 SourceInformation sourceInformation = node.sourceInformation; 527 SourceInformation sourceInformation = node.sourceInformation;
499 SourceLocation sourceLocation; 528 SourceLocation sourceLocation;
500 String dartCode; 529 String dartCode;
(...skipping 15 matching lines...) Expand all
516 addLocation(null, nodeToString(node)); 545 addLocation(null, nodeToString(node));
517 } else { 546 } else {
518 locationMap.forEach((int targetOffset, List<SourceLocation> locations) { 547 locationMap.forEach((int targetOffset, List<SourceLocation> locations) {
519 String jsCode = nodeToString(node); 548 String jsCode = nodeToString(node);
520 for (SourceLocation location in locations) { 549 for (SourceLocation location in locations) {
521 addLocation(location, jsCode); 550 addLocation(location, jsCode);
522 } 551 }
523 }); 552 });
524 } 553 }
525 } 554 }
526
527 void apply(js.Node node) {
528 node.accept(this);
529 }
530
531 void visitNode(js.Node node) {
532 register('${node.runtimeType}', node, expectInfo: false);
533 super.visitNode(node);
534 }
535
536 @override
537 void visitNew(js.New node) {
538 node.arguments.forEach(apply);
539 register('New', node);
540 }
541
542 @override
543 void visitReturn(js.Return node) {
544 if (node.value != null) {
545 apply(node.value);
546 }
547 register('Return', node);
548 }
549
550 @override
551 void visitCall(js.Call node) {
552 apply(node.target);
553 node.arguments.forEach(apply);
554 register('Call (${node.target.runtimeType})', node);
555 }
556
557 @override
558 void visitFun(js.Fun node) {
559 node.visitChildren(this);
560 register('Fun', node);
561 }
562
563 @override
564 visitExpressionStatement(js.ExpressionStatement node) {
565 node.visitChildren(this);
566 }
567
568 @override
569 visitBinary(js.Binary node) {
570 node.visitChildren(this);
571 }
572
573 @override
574 visitAccess(js.PropertyAccess node) {
575 node.visitChildren(this);
576 }
577 } 555 }
578 556
579 /// A JavaScript code point and its mapped dart source location. 557 /// A JavaScript code point and its mapped dart source location.
580 class CodePoint { 558 class CodePoint {
581 final String kind; 559 final String kind;
582 final String jsCode; 560 final String jsCode;
583 final SourceLocation sourceLocation; 561 final SourceLocation sourceLocation;
584 final String dartCode; 562 final String dartCode;
585 final bool isMissing; 563 final bool isMissing;
586 564
587 CodePoint( 565 CodePoint(
588 this.kind, 566 this.kind,
589 this.jsCode, 567 this.jsCode,
590 this.sourceLocation, 568 this.sourceLocation,
591 this.dartCode, 569 this.dartCode,
592 {this.isMissing: false}); 570 {this.isMissing: false});
593 571
594 String toString() { 572 String toString() {
595 return 'CodePoint[kind=$kind,js=$jsCode,dart=$dartCode,' 573 return 'CodePoint[kind=$kind,js=$jsCode,dart=$dartCode,'
596 'location=$sourceLocation]'; 574 'location=$sourceLocation]';
597 } 575 }
598 } 576 }
577
578 class IOSourceFileManager implements SourceFileManager {
579 final Uri base;
580
581 Map<Uri, SourceFile> sourceFiles = <Uri, SourceFile>{};
582
583 IOSourceFileManager(this.base);
584
585 SourceFile getSourceFile(var uri) {
586 Uri absoluteUri;
587 if (uri is Uri) {
588 absoluteUri = base.resolveUri(uri);
589 } else {
590 absoluteUri = base.resolve(uri);
591 }
592 return sourceFiles.putIfAbsent(absoluteUri, () {
593 String text = new File.fromUri(absoluteUri).readAsStringSync();
594 return new StringSourceFile.fromUri(absoluteUri, text);
595 });
596 }
597 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698