| 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 import 'dart:io'; | 5 import 'dart:io'; |
| 6 import 'dart:convert'; | 6 import 'dart:convert'; |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:path/path.dart' as path; | 9 import 'package:path/path.dart' as path; |
| 10 import 'package:expect/expect.dart'; | 10 import 'package:expect/expect.dart'; |
| 11 import 'package:source_maps/source_maps.dart' hide SourceFile; | 11 import 'package:source_maps/source_maps.dart' hide SourceFile; |
| 12 import 'package:compiler/src/apiimpl.dart'; | 12 import 'package:compiler/src/apiimpl.dart'; |
| 13 import 'package:compiler/src/elements/elements.dart' | 13 import 'package:compiler/src/elements/elements.dart' |
| 14 show LibraryElement, | 14 show LibraryElement, |
| 15 CompilationUnitElement, | 15 CompilationUnitElement, |
| 16 ClassElement, | 16 ClassElement, |
| 17 AstElement; | 17 AstElement; |
| 18 import 'package:compiler/src/io/source_file.dart' show SourceFile; | 18 import 'package:compiler/src/io/source_file.dart' show SourceFile; |
| 19 | 19 |
| 20 validateSourceMap(Uri targetUri, [Compiler compiler]) { | 20 validateSourceMap(Uri targetUri, |
| 21 {Uri mainUri, |
| 22 Position mainPosition, |
| 23 Compiler compiler}) { |
| 21 Uri mapUri = getMapUri(targetUri); | 24 Uri mapUri = getMapUri(targetUri); |
| 25 List<String> targetLines = new File.fromUri(targetUri).readAsLinesSync(); |
| 22 SingleMapping sourceMap = getSourceMap(mapUri); | 26 SingleMapping sourceMap = getSourceMap(mapUri); |
| 23 checkFileReferences(targetUri, mapUri, sourceMap); | 27 checkFileReferences(targetUri, mapUri, sourceMap); |
| 24 checkIndexReferences(targetUri, mapUri, sourceMap); | 28 checkIndexReferences(targetLines, mapUri, sourceMap); |
| 25 checkRedundancy(sourceMap); | 29 checkRedundancy(sourceMap); |
| 26 if (compiler != null) { | 30 if (compiler != null) { |
| 27 checkNames(targetUri, mapUri, sourceMap, compiler); | 31 checkNames(targetUri, mapUri, sourceMap, compiler); |
| 28 } | 32 } |
| 33 if (mainUri != null && mainPosition != null) { |
| 34 checkMainPosition(targetUri, targetLines ,sourceMap, mainUri, mainPosition); |
| 35 } |
| 29 } | 36 } |
| 30 | 37 |
| 31 checkIndexReferences(Uri targetUri, Uri mapUri, SingleMapping sourceMap) { | 38 checkIndexReferences(List<String> targetLines, |
| 32 List<String> target = | 39 Uri mapUri, |
| 33 new File.fromUri(targetUri).readAsStringSync().split('\n'); | 40 SingleMapping sourceMap) { |
| 34 int urlsLength = sourceMap.urls.length; | 41 int urlsLength = sourceMap.urls.length; |
| 35 List<List<String>> sources = new List(urlsLength); | 42 List<List<String>> sources = new List(urlsLength); |
| 36 print('Reading sources'); | 43 print('Reading sources'); |
| 37 for (int i = 0; i < urlsLength; i++) { | 44 for (int i = 0; i < urlsLength; i++) { |
| 38 sources[i] = new File.fromUri(mapUri.resolve(sourceMap.urls[i])). | 45 sources[i] = new File.fromUri(mapUri.resolve(sourceMap.urls[i])). |
| 39 readAsStringSync().split('\n'); | 46 readAsStringSync().split('\n'); |
| 40 } | 47 } |
| 41 | 48 |
| 42 sourceMap.lines.forEach((TargetLineEntry line) { | 49 sourceMap.lines.forEach((TargetLineEntry line) { |
| 43 Expect.isTrue(line.line >= 0); | 50 Expect.isTrue(line.line >= 0); |
| 44 Expect.isTrue(line.line < target.length); | 51 Expect.isTrue(line.line < targetLines.length); |
| 45 for (TargetEntry entry in line.entries) { | 52 for (TargetEntry entry in line.entries) { |
| 46 int urlIndex = entry.sourceUrlId; | 53 int urlIndex = entry.sourceUrlId; |
| 47 | 54 |
| 48 // TODO(zarah): Entry columns sometimes point one or more characters too | 55 // TODO(zarah): Entry columns sometimes point one or more characters too |
| 49 // far. Incomment this check when this is fixed. | 56 // far. Incomment this check when this is fixed. |
| 50 // | 57 // |
| 51 // Expect.isTrue(entry.column < target[line.line].length); | 58 // Expect.isTrue(entry.column < target[line.line].length); |
| 52 Expect.isTrue(entry.column >= 0); | 59 Expect.isTrue(entry.column >= 0); |
| 53 Expect.isTrue(urlIndex == null || | 60 Expect.isTrue(urlIndex == null || |
| 54 (urlIndex >= 0 && urlIndex < urlsLength)); | 61 (urlIndex >= 0 && urlIndex < urlsLength)); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 classElement.forEachLocalMember(match); | 163 classElement.forEachLocalMember(match); |
| 157 } else { | 164 } else { |
| 158 match(element); | 165 match(element); |
| 159 } | 166 } |
| 160 }); | 167 }); |
| 161 } | 168 } |
| 162 } | 169 } |
| 163 }); | 170 }); |
| 164 } | 171 } |
| 165 | 172 |
| 173 RegExp mainSignaturePrefix = new RegExp(r'main: \[?function\('); |
| 174 |
| 175 // Check that the line pointing to by [mainPosition] in [mainUri] contains |
| 176 // the main function signature. |
| 177 checkMainPosition(Uri targetUri, |
| 178 List<String> targetLines, |
| 179 SingleMapping sourceMap, |
| 180 Uri mainUri, |
| 181 Position mainPosition) { |
| 182 bool mainPositionFound = false; |
| 183 sourceMap.lines.forEach((TargetLineEntry lineEntry) { |
| 184 lineEntry.entries.forEach((TargetEntry entry) { |
| 185 if (entry.sourceLine == null || entry.sourceUrlId == null) return; |
| 186 Uri sourceUri = targetUri.resolve(sourceMap.urls[entry.sourceUrlId]); |
| 187 if (sourceUri != mainUri) return; |
| 188 if (entry.sourceLine + 1 == mainPosition.line && |
| 189 entry.sourceColumn + 1 == mainPosition.column) { |
| 190 Expect.isNotNull(entry.sourceNameId, |
| 191 "Main position has no name."); |
| 192 String name = sourceMap.names[entry.sourceNameId]; |
| 193 Expect.equals('main', name, |
| 194 "Main position name is not '$name', not 'main'."); |
| 195 String line = targetLines[lineEntry.line]; |
| 196 Expect.isTrue(line.contains(mainSignaturePrefix), |
| 197 "Line mapped to main position " |
| 198 "([${lineEntry.line + 1},${entry.column + 1}]) " |
| 199 "expected to contain '${mainSignaturePrefix.pattern}':\n$line\n"); |
| 200 mainPositionFound = true; |
| 201 } |
| 202 }); |
| 203 }); |
| 204 Expect.isTrue(mainPositionFound, |
| 205 'No main position $mainPosition found in $mainUri'); |
| 206 } |
| 207 |
| 208 |
| 166 sameSourcePoint(TargetEntry entry, TargetEntry otherEntry) { | 209 sameSourcePoint(TargetEntry entry, TargetEntry otherEntry) { |
| 167 return | 210 return |
| 168 (entry.sourceUrlId == otherEntry.sourceUrlId) && | 211 (entry.sourceUrlId == otherEntry.sourceUrlId) && |
| 169 (entry.sourceLine == otherEntry.sourceLine) && | 212 (entry.sourceLine == otherEntry.sourceLine) && |
| 170 (entry.sourceColumn == otherEntry.sourceColumn) && | 213 (entry.sourceColumn == otherEntry.sourceColumn) && |
| 171 (entry.sourceNameId == otherEntry.sourceNameId); | 214 (entry.sourceNameId == otherEntry.sourceNameId); |
| 172 } | 215 } |
| 173 | 216 |
| 174 Uri getMapUri(Uri targetUri) { | 217 Uri getMapUri(Uri targetUri) { |
| 175 print('Accessing $targetUri'); | 218 print('Accessing $targetUri'); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 .createTemp('sourceMap_test-') | 252 .createTemp('sourceMap_test-') |
| 210 .then((Directory dir) { | 253 .then((Directory dir) { |
| 211 return dir; | 254 return dir; |
| 212 }); | 255 }); |
| 213 } | 256 } |
| 214 | 257 |
| 215 class Position { | 258 class Position { |
| 216 final int line; | 259 final int line; |
| 217 final int column; | 260 final int column; |
| 218 | 261 |
| 219 Position(this.line, this.column); | 262 const Position(this.line, this.column); |
| 220 | 263 |
| 221 bool operator <=(Position other) { | 264 bool operator <=(Position other) { |
| 222 return line < other.line || | 265 return line < other.line || |
| 223 line == other.line && column <= other.column; | 266 line == other.line && column <= other.column; |
| 224 } | 267 } |
| 225 | 268 |
| 226 String toString() => '[$line,$column]'; | 269 String toString() => '[$line,$column]'; |
| 227 } | 270 } |
| 228 | 271 |
| 229 class Interval { | 272 class Interval { |
| 230 final Position begin; | 273 final Position begin; |
| 231 final Position end; | 274 final Position end; |
| 232 | 275 |
| 233 Interval(this.begin, this.end); | 276 Interval(this.begin, this.end); |
| 234 | 277 |
| 235 bool contains(Position other) { | 278 bool contains(Position other) { |
| 236 return begin <= other && other <= end; | 279 return begin <= other && other <= end; |
| 237 } | 280 } |
| 238 | 281 |
| 239 String toString() => '$begin-$end'; | 282 String toString() => '$begin-$end'; |
| 240 } | 283 } |
| OLD | NEW |