| 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 'dart:io'; | 6 import 'dart:io'; |
| 7 | 7 |
| 8 import 'package:front_end/compiler_options.dart'; | 8 import 'package:front_end/compiler_options.dart'; |
| 9 import 'package:front_end/dependency_grapher.dart'; | 9 import 'package:front_end/dependency_grapher.dart'; |
| 10 import 'package:path/path.dart' as pathos; | 10 import 'package:path/path.dart' as pathos; |
| 11 | 11 |
| 12 main() async { | 12 main() async { |
| 13 exit(await new _SubpackageRelationshipsTest().run()); | 13 exit(await new _SubpackageRelationshipsTest().run()); |
| 14 } | 14 } |
| 15 | 15 |
| 16 /// List of packages that front_end is allowed to directly depend on. | 16 /// List of packages that front_end is allowed to directly depend on. |
| 17 /// | 17 /// |
| 18 /// Note that this script only checks files in pkg/front_end/lib, so this list | 18 /// Note that this script only checks files in pkg/front_end/lib, so this list |
| 19 /// excludes dev dependencies. | 19 /// excludes dev dependencies. |
| 20 /// | |
| 21 /// TODO(paulberry): remove dependencies on analyzer. | |
| 22 final allowedPackageDependencies = [ | 20 final allowedPackageDependencies = [ |
| 23 'analyzer', | |
| 24 'charcode', | 21 'charcode', |
| 25 'convert', | 22 'convert', |
| 26 'crypto', | 23 'crypto', |
| 27 'kernel', | 24 'kernel', |
| 28 'meta', | 25 'meta', |
| 29 'package_config', | 26 'package_config', |
| 30 'path', | 27 'path', |
| 31 'source_span', | 28 'source_span', |
| 32 'testing', | 29 'testing', |
| 33 ]; | 30 ]; |
| 34 | 31 |
| 35 /// Map from subpackage name to the rules for what the subpackage is allowed to | 32 /// Map from subpackage name to the rules for what the subpackage is allowed to |
| 36 /// depend directly on. | 33 /// depend directly on. |
| 37 /// | 34 /// |
| 38 /// Each listed directory is considered a subpackage. Each package contains all | 35 /// Each listed directory is considered a subpackage. Each package contains all |
| 39 /// of its descendant files that are not in a more deeply nested subpackage. | 36 /// of its descendant files that are not in a more deeply nested subpackage. |
| 40 /// | 37 /// |
| 41 /// TODO(paulberry): stuff in lib/src shouldn't depend on lib; lib should just | 38 /// TODO(paulberry): stuff in lib/src shouldn't depend on lib; lib should just |
| 42 /// re-export stuff in lib/src. | 39 /// re-export stuff in lib/src. |
| 43 /// TODO(paulberry): remove dependencies on analyzer. | |
| 44 final subpackageRules = { | 40 final subpackageRules = { |
| 45 'lib': new SubpackageRules(mayImportAnalyzer: true, allowedDependencies: [ | 41 'lib': new SubpackageRules(allowedDependencies: [ |
| 46 'lib/src', | 42 'lib/src', |
| 47 'lib/src/base', | 43 'lib/src/base', |
| 48 'lib/src/fasta', | 44 'lib/src/fasta', |
| 49 'lib/src/fasta/dill', | 45 'lib/src/fasta/dill', |
| 50 'lib/src/fasta/kernel', | 46 'lib/src/fasta/kernel', |
| 51 'lib/src/incremental' | 47 'lib/src/incremental' |
| 52 ]), | 48 ]), |
| 53 'lib/src': new SubpackageRules(mayImportAnalyzer: true, allowedDependencies: [ | 49 'lib/src': new SubpackageRules(allowedDependencies: [ |
| 54 'lib', | 50 'lib', |
| 55 'lib/src/base', | 51 'lib/src/base', |
| 56 'lib/src/fasta', | 52 'lib/src/fasta', |
| 57 "lib/src/fasta/dill", | 53 "lib/src/fasta/dill", |
| 58 "lib/src/fasta/kernel", | 54 "lib/src/fasta/kernel", |
| 59 'lib/src/fasta/source', | 55 'lib/src/fasta/source', |
| 60 'lib/src/incremental', | 56 'lib/src/incremental', |
| 61 ]), | 57 ]), |
| 62 'lib/src/base': new SubpackageRules(allowedDependencies: [ | 58 'lib/src/base': new SubpackageRules(allowedDependencies: [ |
| 63 'lib', | 59 'lib', |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 // fasta scanner produces analyzer scanner tokens | 151 // fasta scanner produces analyzer scanner tokens |
| 156 'lib/src/fasta/scanner', | 152 'lib/src/fasta/scanner', |
| 157 ]), | 153 ]), |
| 158 'lib/src/testing': new SubpackageRules(allowedDependencies: [ | 154 'lib/src/testing': new SubpackageRules(allowedDependencies: [ |
| 159 'lib', | 155 'lib', |
| 160 ]), | 156 ]), |
| 161 }; | 157 }; |
| 162 | 158 |
| 163 /// Rules for what a subpackage may depend directly on. | 159 /// Rules for what a subpackage may depend directly on. |
| 164 class SubpackageRules { | 160 class SubpackageRules { |
| 165 /// Indicates whether the subpackage may directly depend on analyzer. | |
| 166 final bool mayImportAnalyzer; | |
| 167 | |
| 168 /// Indicates whether dart files may exist in subdirectories of this | 161 /// Indicates whether dart files may exist in subdirectories of this |
| 169 /// subpackage. | 162 /// subpackage. |
| 170 /// | 163 /// |
| 171 /// If `false`, any subdirectory of this subpackage must be a separate | 164 /// If `false`, any subdirectory of this subpackage must be a separate |
| 172 /// subpackage. | 165 /// subpackage. |
| 173 final bool allowSubdirs; | 166 final bool allowSubdirs; |
| 174 | 167 |
| 175 /// Indicates which other subpackages a given subpackage may directly depend | 168 /// Indicates which other subpackages a given subpackage may directly depend |
| 176 /// on. | 169 /// on. |
| 177 final List<String> allowedDependencies; | 170 final List<String> allowedDependencies; |
| 178 | 171 |
| 179 var actuallyContainsFiles = false; | 172 var actuallyContainsFiles = false; |
| 180 | 173 |
| 181 var actuallyImportsAnalyzer = false; | |
| 182 | |
| 183 var actuallyHasSubdirs = false; | 174 var actuallyHasSubdirs = false; |
| 184 | 175 |
| 185 var actualDependencies = new Set<String>(); | 176 var actualDependencies = new Set<String>(); |
| 186 | 177 |
| 187 SubpackageRules( | 178 SubpackageRules( |
| 188 {this.mayImportAnalyzer: false, | 179 {this.allowSubdirs: false, this.allowedDependencies: const []}); |
| 189 this.allowSubdirs: false, | |
| 190 this.allowedDependencies: const []}); | |
| 191 } | 180 } |
| 192 | 181 |
| 193 class _SubpackageRelationshipsTest { | 182 class _SubpackageRelationshipsTest { |
| 194 /// File uri of the front_end package's "lib" directory. | 183 /// File uri of the front_end package's "lib" directory. |
| 195 final frontEndLibUri = Platform.script.resolve('../lib/'); | 184 final frontEndLibUri = Platform.script.resolve('../lib/'); |
| 196 | 185 |
| 197 /// Indicates whether any problems have been reported yet. | 186 /// Indicates whether any problems have been reported yet. |
| 198 bool problemsReported = false; | 187 bool problemsReported = false; |
| 199 | 188 |
| 200 /// Package dependencies that were actually discovered | 189 /// Package dependencies that were actually discovered |
| (...skipping 20 matching lines...) Expand all Loading... |
| 221 } | 210 } |
| 222 var srcSubpackage = subpackageForUri(src); | 211 var srcSubpackage = subpackageForUri(src); |
| 223 if (srcSubpackage == null) return; | 212 if (srcSubpackage == null) return; |
| 224 var srcSubpackageRules = subpackageRules[srcSubpackage]; | 213 var srcSubpackageRules = subpackageRules[srcSubpackage]; |
| 225 if (srcSubpackageRules == null) { | 214 if (srcSubpackageRules == null) { |
| 226 problem('$src is in subpackage "$srcSubpackage", which is not found in ' | 215 problem('$src is in subpackage "$srcSubpackage", which is not found in ' |
| 227 'subpackageRules'); | 216 'subpackageRules'); |
| 228 return; | 217 return; |
| 229 } | 218 } |
| 230 srcSubpackageRules.actuallyContainsFiles = true; | 219 srcSubpackageRules.actuallyContainsFiles = true; |
| 231 if (dst.pathSegments[0] == 'analyzer') { | |
| 232 if (srcSubpackageRules.mayImportAnalyzer) { | |
| 233 srcSubpackageRules.actuallyImportsAnalyzer = true; | |
| 234 } else { | |
| 235 problem('$src depends on $dst, but subpackage "$srcSubpackage" may not ' | |
| 236 'import analyzer'); | |
| 237 } | |
| 238 } | |
| 239 var dstSubPackage = subpackageForUri(dst); | 220 var dstSubPackage = subpackageForUri(dst); |
| 240 if (dstSubPackage == null) return; | 221 if (dstSubPackage == null) return; |
| 241 if (dstSubPackage == srcSubpackage) return; | 222 if (dstSubPackage == srcSubpackage) return; |
| 242 if (srcSubpackageRules.allowedDependencies.contains(dstSubPackage)) { | 223 if (srcSubpackageRules.allowedDependencies.contains(dstSubPackage)) { |
| 243 srcSubpackageRules.actualDependencies.add(dstSubPackage); | 224 srcSubpackageRules.actualDependencies.add(dstSubPackage); |
| 244 } else { | 225 } else { |
| 245 problem('$src depends on $dst, but subpackage "$srcSubpackage" is not ' | 226 problem('$src depends on $dst, but subpackage "$srcSubpackage" is not ' |
| 246 'allowed to depend on subpackage "$dstSubPackage"'); | 227 'allowed to depend on subpackage "$dstSubPackage"'); |
| 247 } | 228 } |
| 248 } | 229 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 for (var package in allowedPackageDependencies) { | 270 for (var package in allowedPackageDependencies) { |
| 290 if (!actualPackageDependencies.contains(package)) { | 271 if (!actualPackageDependencies.contains(package)) { |
| 291 problem('$package is listed in allowedPackageDependencies, ' | 272 problem('$package is listed in allowedPackageDependencies, ' |
| 292 'but is not used'); | 273 'but is not used'); |
| 293 } | 274 } |
| 294 } | 275 } |
| 295 subpackageRules.forEach((subpackage, rule) { | 276 subpackageRules.forEach((subpackage, rule) { |
| 296 if (!rule.actuallyContainsFiles) { | 277 if (!rule.actuallyContainsFiles) { |
| 297 problem("$subpackage contains no files"); | 278 problem("$subpackage contains no files"); |
| 298 } | 279 } |
| 299 if (rule.mayImportAnalyzer && !rule.actuallyImportsAnalyzer) { | |
| 300 problem("$subpackage is allowed to import analyzer, but doesn't"); | |
| 301 } | |
| 302 if (rule.allowSubdirs && !rule.actuallyHasSubdirs) { | 280 if (rule.allowSubdirs && !rule.actuallyHasSubdirs) { |
| 303 problem("$subpackage is allowed to have subdirectories, but doesn't"); | 281 problem("$subpackage is allowed to have subdirectories, but doesn't"); |
| 304 } | 282 } |
| 305 for (var dep in rule.allowedDependencies | 283 for (var dep in rule.allowedDependencies |
| 306 .toSet() | 284 .toSet() |
| 307 .difference(rule.actualDependencies)) { | 285 .difference(rule.actualDependencies)) { |
| 308 problem("$subpackage lists $dep as a dependency, but doesn't use it"); | 286 problem("$subpackage lists $dep as a dependency, but doesn't use it"); |
| 309 } | 287 } |
| 310 }); | 288 }); |
| 311 return problemsReported ? 1 : 0; | 289 return problemsReported ? 1 : 0; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 336 if (subpackageRules[subpackage].allowSubdirs) { | 314 if (subpackageRules[subpackage].allowSubdirs) { |
| 337 subpackageRules[subpackage].actuallyHasSubdirs = true; | 315 subpackageRules[subpackage].actuallyHasSubdirs = true; |
| 338 } else { | 316 } else { |
| 339 problem('Uri $src is in a subfolder of $subpackage, but that ' | 317 problem('Uri $src is in a subfolder of $subpackage, but that ' |
| 340 'subpackage does not allow dart files in subdirectories.'); | 318 'subpackage does not allow dart files in subdirectories.'); |
| 341 } | 319 } |
| 342 } | 320 } |
| 343 return subpackage; | 321 return subpackage; |
| 344 } | 322 } |
| 345 } | 323 } |
| OLD | NEW |