| 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 AstElement, |
| 15 ClassElement, |
| 15 CompilationUnitElement, | 16 CompilationUnitElement, |
| 16 ClassElement, | 17 Element, |
| 17 AstElement; | 18 FunctionElement, |
| 19 LibraryElement, |
| 20 MemberElement; |
| 18 import 'package:compiler/src/io/source_file.dart' show SourceFile; | 21 import 'package:compiler/src/io/source_file.dart' show SourceFile; |
| 22 import 'package:compiler/src/io/source_information.dart' |
| 23 show computeElementNameForSourceMaps; |
| 19 | 24 |
| 20 validateSourceMap(Uri targetUri, | 25 validateSourceMap(Uri targetUri, |
| 21 {Uri mainUri, | 26 {Uri mainUri, |
| 22 Position mainPosition, | 27 Position mainPosition, |
| 23 Compiler compiler}) { | 28 Compiler compiler}) { |
| 24 Uri mapUri = getMapUri(targetUri); | 29 Uri mapUri = getMapUri(targetUri); |
| 25 List<String> targetLines = new File.fromUri(targetUri).readAsLinesSync(); | 30 List<String> targetLines = new File.fromUri(targetUri).readAsLinesSync(); |
| 26 SingleMapping sourceMap = getSourceMap(mapUri); | 31 SingleMapping sourceMap = getSourceMap(mapUri); |
| 27 checkFileReferences(targetUri, mapUri, sourceMap); | 32 checkFileReferences(targetUri, mapUri, sourceMap); |
| 28 checkIndexReferences(targetLines, mapUri, sourceMap); | 33 checkIndexReferences(targetLines, mapUri, sourceMap); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 Interval intervalFromElement(AstElement element) { | 141 Interval intervalFromElement(AstElement element) { |
| 137 if (!element.hasNode) return null; | 142 if (!element.hasNode) return null; |
| 138 | 143 |
| 139 var begin = element.node.getBeginToken().charOffset; | 144 var begin = element.node.getBeginToken().charOffset; |
| 140 var end = element.node.getEndToken(); | 145 var end = element.node.getEndToken(); |
| 141 end = end.charOffset + end.charCount; | 146 end = end.charOffset + end.charCount; |
| 142 return new Interval(positionFromOffset(begin), | 147 return new Interval(positionFromOffset(begin), |
| 143 positionFromOffset(end)); | 148 positionFromOffset(end)); |
| 144 } | 149 } |
| 145 | 150 |
| 151 AstElement findInnermost(AstElement element) { |
| 152 bool isInsideElement(FunctionElement closure) { |
| 153 Element enclosing = closure; |
| 154 while (enclosing != null) { |
| 155 if (enclosing == element) return true; |
| 156 enclosing = enclosing.enclosingElement; |
| 157 } |
| 158 return false; |
| 159 } |
| 160 |
| 161 if (element is MemberElement) { |
| 162 MemberElement member = element; |
| 163 member.nestedClosures.forEach((closure) { |
| 164 var localFunction = closure.expression; |
| 165 Interval interval = intervalFromElement(localFunction); |
| 166 if (interval != null && |
| 167 interval.contains(sourcePosition) && |
| 168 isInsideElement(localFunction)) { |
| 169 element = localFunction; |
| 170 } |
| 171 }); |
| 172 } |
| 173 return element; |
| 174 } |
| 175 |
| 146 void match(AstElement element) { | 176 void match(AstElement element) { |
| 147 Interval interval = intervalFromElement(element); | 177 Interval interval = intervalFromElement(element); |
| 148 if (interval != null && interval.contains(sourcePosition)) { | 178 if (interval != null && interval.contains(sourcePosition)) { |
| 149 if (name != 'call') { | 179 AstElement innerElement = findInnermost(element); |
| 150 // TODO(johnniwinther): Check closures. | 180 String expectedName = |
| 151 Expect.equals(element.name, name); | 181 computeElementNameForSourceMaps(innerElement); |
| 152 } else if (name != element.name) { | 182 if (name != expectedName) { |
| 153 print("${targetUri}$targetPosition:\n" | 183 // For the code |
| 154 "Name '$name' does not match element $element in " | 184 // (){}(); |
| 155 "${sourceFile.filename}$sourcePosition."); | 185 // ^ |
| 186 // the indicated position is within the scope of the local |
| 187 // function but it is also the position for the invocation of it. |
| 188 // Allow name to be either from the local or from its calling |
| 189 // context. |
| 190 if (innerElement.isLocal && innerElement.isFunction) { |
| 191 var enclosingElement = innerElement.enclosingElement; |
| 192 String expectedName2 = |
| 193 computeElementNameForSourceMaps(enclosingElement); |
| 194 Expect.isTrue(name == expectedName2, |
| 195 "Unexpected name '${name}', " |
| 196 "expected '${expectedName}' for $innerElement " |
| 197 "or '${expectedName2}' for $enclosingElement."); |
| 198 } else { |
| 199 Expect.equals(expectedName, name, |
| 200 "Unexpected name '${name}', " |
| 201 "expected '${expectedName}' or for $innerElement."); |
| 202 } |
| 156 } | 203 } |
| 157 } | 204 } |
| 158 } | 205 } |
| 159 | 206 |
| 160 compilationUnit.forEachLocalMember((AstElement element) { | 207 compilationUnit.forEachLocalMember((AstElement element) { |
| 161 if (element.isClass) { | 208 if (element.isClass) { |
| 162 ClassElement classElement = element; | 209 ClassElement classElement = element; |
| 163 classElement.forEachLocalMember(match); | 210 classElement.forEachLocalMember(match); |
| 164 } else { | 211 } else { |
| 165 match(element); | 212 match(element); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 final int line; | 306 final int line; |
| 260 final int column; | 307 final int column; |
| 261 | 308 |
| 262 const Position(this.line, this.column); | 309 const Position(this.line, this.column); |
| 263 | 310 |
| 264 bool operator <=(Position other) { | 311 bool operator <=(Position other) { |
| 265 return line < other.line || | 312 return line < other.line || |
| 266 line == other.line && column <= other.column; | 313 line == other.line && column <= other.column; |
| 267 } | 314 } |
| 268 | 315 |
| 269 String toString() => '[$line,$column]'; | 316 String toString() => '[${line + 1},${column + 1}]'; |
| 270 } | 317 } |
| 271 | 318 |
| 272 class Interval { | 319 class Interval { |
| 273 final Position begin; | 320 final Position begin; |
| 274 final Position end; | 321 final Position end; |
| 275 | 322 |
| 276 Interval(this.begin, this.end); | 323 Interval(this.begin, this.end); |
| 277 | 324 |
| 278 bool contains(Position other) { | 325 bool contains(Position other) { |
| 279 return begin <= other && other <= end; | 326 return begin <= other && other <= end; |
| 280 } | 327 } |
| 281 | 328 |
| 282 String toString() => '$begin-$end'; | 329 String toString() => '$begin-$end'; |
| 283 } | 330 } |
| OLD | NEW |