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

Side by Side Diff: bin/commands/global_compile.dart

Issue 1900813002: Global compile option (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Created 4 years, 8 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
« no previous file with comments | « no previous file | bin/dartdevc.dart » ('j') | bin/dartdevc.dart » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
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.
4
5 import 'dart:io';
6 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
7 import 'package:analyzer/src/generated/source.dart' show Source;
8 import 'package:analyzer/src/summary/package_bundle_reader.dart'
9 show InSummarySource;
10 import 'package:args/command_runner.dart';
11 import 'package:dev_compiler/src/analyzer/context.dart' show
12 createAnalysisContextWithSources;
13 import 'package:dev_compiler/src/compiler/command.dart';
14 import 'package:dev_compiler/src/compiler/compiler.dart'
15 show BuildUnit, CompilerOptions, JSModuleFile, ModuleCompiler, ModuleFormat;
16 import 'package:dev_compiler/src/analyzer/context.dart' show AnalyzerOptions;
17 import 'package:path/path.dart' as path;
18 import 'package:yaml/yaml.dart' show loadYaml;
19
20
21 /// The command for invoking the modular compiler on the whole program.
22 class GlobalCommand extends Command {
Jennifer Messerly 2016/04/18 21:45:45 WholeProgramCompileCommand? or GlobalCompileComman
23 get name => 'global-compile';
Jennifer Messerly 2016/04/18 21:45:45 in the original design this was called "build". Th
24 get description => 'Compile all files reachable from an entry point.';
25
26 GlobalCommand() {
27 argParser.addOption('out', abbr: 'o', help: 'Output file (required)');
28 CompilerOptions.addArguments(argParser);
29 AnalyzerOptions.addArguments(argParser);
30 }
31
32 String canonicalize(String uri, String root) {
Jennifer Messerly 2016/04/18 21:45:45 is this is the exact code we have in ModuleCompile
33 var sourceUri = Uri.parse(uri);
34 if (sourceUri.scheme == '') {
35 sourceUri = path.toUri(path.isAbsolute(uri) ? path.absolute(uri) : path.jo in(root, uri));
Jennifer Messerly 2016/04/18 21:45:45 looks like this needs dartfmt
36 }
37 return sourceUri.toString();
38 }
39
40 void transitiveFiles(Set<String> results, AnalysisContext context, String entr yPoint, String root) {
41 entryPoint = canonicalize(entryPoint, root);
42 if (entryPoint.startsWith('dart:')) return;
43 var entryDir = path.dirname(entryPoint);
44 if (results.add(entryPoint)) {
45 // Process this
46 var source = context.sourceFactory.forUri(entryPoint);
47 if (source == null) {
48 throw new Exception('could not create a source for $entryPoint.'
49 ' The file name is in the wrong format or was not found.');
50 }
51 var library = context.computeLibraryElement(source);
Jennifer Messerly 2016/04/18 21:45:45 I'm curious, why use resolution? You can figure ou
52 for (var entry in library.imports) {
53 if (entry.uri == null) continue;
54 transitiveFiles(results, context, entry.uri, entryDir);
55 }
56 for (var entry in library.exports) {
57 transitiveFiles(results, context, entry.uri, entryDir);
58 }
59 for (var part in library.parts) {
60 results.add(canonicalize(part.uri, entryDir));
61 }
62 }
63 }
64
65 @override
66 void run() {
67 var analyzerOptions = new AnalyzerOptions.fromArguments(argResults);
68
69 var context = createAnalysisContextWithSources(analyzerOptions);
70 var inputSet = new Set<String>();
71 for (var entry in argResults.rest) {
72 transitiveFiles(inputSet, context, entry, Directory.current.path);
73 }
74 compile(
75 new ModuleCompiler.withContext(context),
Jennifer Messerly 2016/04/18 21:45:45 IMO, it would be better to have it use the command
Jennifer Messerly 2016/04/18 21:49:30 addendum -- a lot depends on where we are going wi
76 new CompilerOptions.fromArguments(argResults),
77 argResults['out'],
78 inputSet.toList());
79 }
80
81 void compile(ModuleCompiler compiler, CompilerOptions compilerOptions,
82 String outPath, List<String> extraArgs,
83 {void forEachError(String error): print}) {
84 if (outPath == null) {
85 usageException('Please include the output file location. For example:\n'
86 ' -o PATH/TO/OUTPUT_FILE.js');
87 }
88 if (compilerOptions.sourceMap) {
89 usageException('Source maps are not supported in global mode');
90 }
91 if (compilerOptions.summarizeApi) {
92 usageException('Summaries are not supported in global mode');
93 }
94 if (compilerOptions.moduleFormat != ModuleFormat.legacy) {
95 usageException('Only legacy modules are supported in global mode');
96 }
97 var unit = new BuildUnit(
98 path.basenameWithoutExtension(outPath), extraArgs, _moduleForLibrary);
99
100 JSModuleFile module = compiler.compile(unit, compilerOptions);
101 module.errors.forEach(forEachError);
102
103 if (!module.isValid) throw new CompileErrorException();
104
105 // Write JS file, as well as source map and summary (if requested).
106 var file = new File(outPath);
107 if (file.existsSync()) file.delete();
108 _copyLegacyDartRuntime(file);
109 file.writeAsStringSync(module.code, mode: FileMode.APPEND);
Jennifer Messerly 2016/04/18 21:45:45 I don't think you want .APPEND, won't this break a
110 }
111
112 String _moduleForLibrary(Source source) {
113 if (source is InSummarySource) {
114 return path.basenameWithoutExtension(source.summaryPath);
115 }
116
117 throw usageException(
118 'Imported file "${source.uri}" was not found as a summary or source '
119 'file. Please pass in either the summary or the source file '
120 'for this import.');
121 }
122
123 void _copyLegacyDartRuntime(File outfile) {
124 var runtimeDir = _computeRuntimeDir();
125 if (runtimeDir == null) {
126 usageException('Cannot compute runtime directory for global mode');
127 }
128 for (var runtimeFile in _RUNTIME_FILES) {
129 var inPath = path.join(runtimeDir, runtimeFile);
130 var infile = new File(inPath);
131 var contents = infile.readAsStringSync();
132 outfile.writeAsStringSync(contents, mode: FileMode.APPEND);
133 }
134 }
135 }
136
137 const _ENTRY_POINTS = const [
138 'dartdevc.dart',
139 ];
140
141 const _RUNTIME_FILES = const [
142 'dart_library.js',
143 'dart_sdk.js'
144 ];
145
146 final _ENTRY_POINT_SNAPSHOTS = _ENTRY_POINTS.map((f) => "$f.snapshot");
147
148 /// Tries to find the `lib/runtime/` directory of the dev_compiler package. This
149 /// works when running devc from it's sources or from a snapshot that is
150 /// activated via `pub global activate`.
151 String _computeRuntimeDir() {
Jennifer Messerly 2016/04/18 21:45:45 Vader "NOOOOOOOooooooooooo" meme ... ;) We just g
152 var scriptPath = path.fromUri(Platform.script);
153 var file = path.basename(scriptPath);
154 var dir = path.dirname(scriptPath);
155 var lastdir = path.basename(dir);
156 dir = path.dirname(dir);
157
158 // Both the source dartdevc.dart and the snapshot generated by pub global acti vate
159 // are under a bin folder.
160 if (lastdir != 'bin') return null;
161
162 // And both under a project directory containing a pubspec.lock file.
163 var lockfile = path.join(dir, 'pubspec.lock');
164 if (!new File(lockfile).existsSync()) return null;
165
166 // If running from sources we found it!
167 if (_ENTRY_POINTS.contains(file)) {
168 return path.join(dir, 'lib', 'runtime');
169 }
170
171 // If running from a pub global snapshot, we need to read the lock file to
172 // find where the actual sources are located in the pub cache.
173 if (_ENTRY_POINT_SNAPSHOTS.contains(file)) {
174 // Note: this depends on implementation details of pub.
175 var yaml = loadYaml(new File(lockfile).readAsStringSync());
176 var info = yaml['packages']['dev_compiler'];
177 if (info == null) return null;
178
179 var cacheDir;
180 if (info['source'] == 'hosted') {
181 cacheDir = path.join(
182 'hosted', 'pub.dartlang.org', 'dev_compiler-${info["version"]}');
183 } else if (info['source'] == 'git') {
184 var ref = info['description']['resolved-ref'];
185 cacheDir = path.join('git', 'dev_compiler-${ref}');
186 }
187
188 // We should be under "/path/to/pub-cache/global_packages/dev_compiler".
189 // The pub-cache directory is two levels up, but we verify that the layout
190 // looks correct.
191 if (path.basename(dir) != 'dev_compiler') return null;
192 dir = path.dirname(dir);
193 if (path.basename(dir) != 'global_packages') return null;
194 dir = path.dirname(dir);
195 return path.join(dir, cacheDir, 'lib', 'runtime');
196 }
197 return null;
198 }
OLDNEW
« no previous file with comments | « no previous file | bin/dartdevc.dart » ('j') | bin/dartdevc.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698