Skip to content

Commit 8f4db8f

Browse files
author
John Messerly
committed
expose strong checker API, for use by analyzer_cli
most of the changes here are around making options sane(r), which fixes #204 [email protected] Review URL: https://codereview.chromium.org/1174643003.
1 parent b62fdb5 commit 8f4db8f

24 files changed

+507
-468
lines changed

pkg/dev_compiler/bin/devc.dart

+3-2
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@ void main(List<String> args) {
2323
var options = parseOptions(args);
2424
if (options.help) _showUsageAndExit();
2525

26-
if (!options.useMockSdk && options.dartSdkPath == null) {
26+
var srcOpts = options.sourceOptions;
27+
if (!srcOpts.useMockSdk && srcOpts.dartSdkPath == null) {
2728
print('Could not automatically find dart sdk path.');
2829
print('Please pass in explicitly: --dart-sdk <path>');
2930
exit(1);
3031
}
3132

32-
if (options.entryPointFile == null) {
33+
if (srcOpts.entryPointFile == null) {
3334
print('Expected filename.');
3435
_showUsageAndExit();
3536
}

pkg/dev_compiler/bin/edit_files.dart

+3-2
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ void main(List<String> argv) {
135135
}
136136

137137
var filename = args.rest.first;
138-
var options = new CompilerOptions(
138+
var options = new SourceResolverOptions(
139139
dartSdkPath: sdkDir.path,
140140
useMultiPackage: args['use-multi-package'],
141141
packageRoot: args['package-root'],
@@ -150,7 +150,8 @@ void main(List<String> argv) {
150150
? new RegExp(args['include-pattern'])
151151
: null;
152152

153-
var context = createAnalysisContext(options);
153+
var context =
154+
createAnalysisContextWithSources(new StrongModeOptions(), options);
154155
var visitor = new EditFileSummaryVisitor(context, args['level'],
155156
args['checkout-files-executable'], args['checkout-files-arg'],
156157
includePattern, excludePattern);

pkg/dev_compiler/lib/config.dart

-26
This file was deleted.

pkg/dev_compiler/lib/devc.dart

+28-21
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ abstract class AbstractCompiler {
5353
class Compiler implements AbstractCompiler {
5454
final CompilerOptions options;
5555
final AnalysisContext context;
56-
final CheckerReporter _reporter;
56+
final CompilerReporter _reporter;
5757
final TypeRules rules;
5858
final CodeChecker _checker;
5959
final SourceNode _entryNode;
@@ -63,24 +63,29 @@ class Compiler implements AbstractCompiler {
6363
bool _failure = false;
6464

6565
factory Compiler(CompilerOptions options,
66-
{AnalysisContext context, CheckerReporter reporter}) {
67-
if (context == null) context = createAnalysisContext(options);
66+
{AnalysisContext context, CompilerReporter reporter}) {
67+
var strongOpts = options.strongOptions;
68+
var sourceOpts = options.sourceOptions;
69+
if (context == null) {
70+
context = createAnalysisContextWithSources(strongOpts, sourceOpts);
71+
}
6872

6973
if (reporter == null) {
7074
reporter = options.dumpInfo
7175
? new SummaryReporter(context, options.logLevel)
7276
: new LogReporter(context, useColors: options.useColors);
7377
}
7478
var graph = new SourceGraph(context, reporter, options);
75-
var rules = new RestrictedRules(context.typeProvider, options: options);
76-
var checker = new CodeChecker(rules, reporter, options);
79+
var rules = new RestrictedRules(context.typeProvider,
80+
options: options.strongOptions);
81+
var checker = new CodeChecker(rules, reporter, strongOpts);
7782

78-
var inputFile = options.entryPointFile;
83+
var inputFile = sourceOpts.entryPointFile;
7984
var inputUri = inputFile.startsWith('dart:') ||
8085
inputFile.startsWith('package:')
8186
? Uri.parse(inputFile)
82-
: new Uri.file(path.absolute(options.useImplicitHtml
83-
? ResolverOptions.implicitHtmlFile
87+
: new Uri.file(path.absolute(sourceOpts.useImplicitHtml
88+
? SourceResolverOptions.implicitHtmlFile
8489
: inputFile));
8590
var entryNode = graph.nodeFromUri(inputUri);
8691

@@ -90,14 +95,15 @@ class Compiler implements AbstractCompiler {
9095

9196
Compiler._(this.options, this.context, this._reporter, this.rules,
9297
this._checker, this._entryNode) {
93-
if (options.outputDir != null) {
98+
if (outputDir != null) {
9499
_generators.add(new JSGenerator(this));
95100
}
96101
// TODO(sigmund): refactor to support hashing of the dart output?
97102
_hashing = options.enableHashing && _generators.length == 1;
98103
}
99104

100105
Uri get entryPointUri => _entryNode.uri;
106+
String get outputDir => options.codegenOptions.outputDir;
101107

102108
bool _buildSource(SourceNode node) {
103109
if (node is HtmlSourceNode) {
@@ -116,7 +122,7 @@ class Compiler implements AbstractCompiler {
116122
}
117123

118124
void _buildHtmlFile(HtmlSourceNode node) {
119-
if (options.outputDir == null) return;
125+
if (outputDir == null) return;
120126
var uri = node.source.uri;
121127
_reporter.enterHtml(uri);
122128
var output = generateEntryHtml(node, options);
@@ -126,18 +132,18 @@ class Compiler implements AbstractCompiler {
126132
}
127133
_reporter.leaveHtml();
128134
var filename = path.basename(node.uri.path);
129-
String outputFile = path.join(options.outputDir, filename);
135+
String outputFile = path.join(outputDir, filename);
130136
new File(outputFile).writeAsStringSync(output);
131137
}
132138

133139
void _buildResourceFile(ResourceSourceNode node) {
134140
// ResourceSourceNodes files that just need to be copied over to the output
135141
// location. These can be external dependencies or pieces of the
136142
// dev_compiler runtime.
137-
if (options.outputDir == null) return;
143+
if (outputDir == null) return;
138144
var filepath = resourceOutputPath(node.uri, _entryNode.uri);
139145
assert(filepath != null);
140-
filepath = path.join(options.outputDir, filepath);
146+
filepath = path.join(outputDir, filepath);
141147
var dir = path.dirname(filepath);
142148
new Directory(dir).createSync(recursive: true);
143149
new File.fromUri(node.source.uri).copySync(filepath);
@@ -182,7 +188,7 @@ class Compiler implements AbstractCompiler {
182188
}
183189
if (failureInLib) {
184190
_failure = true;
185-
if (!options.forceCompile) return;
191+
if (!options.codegenOptions.forceCompile) return;
186192
}
187193

188194
for (var cg in _generators) {
@@ -221,7 +227,7 @@ class Compiler implements AbstractCompiler {
221227
var time = (clock.elapsedMilliseconds / 1000).toStringAsFixed(2);
222228
_log.fine('Compiled ${_libraries.length} libraries in ${time} s\n');
223229
return new CheckerResults(
224-
_libraries, rules, _failure || options.forceCompile);
230+
_libraries, rules, _failure || options.codegenOptions.forceCompile);
225231
}
226232

227233
void _runAgain() {
@@ -245,7 +251,7 @@ class Compiler implements AbstractCompiler {
245251
var result = (_reporter as SummaryReporter).result;
246252
if (!options.serverMode) print(summaryToString(result));
247253
var filepath = options.serverMode
248-
? path.join(options.outputDir, 'messages.json')
254+
? path.join(outputDir, 'messages.json')
249255
: options.dumpInfoFile;
250256
if (filepath == null) return;
251257
new File(filepath).writeAsStringSync(JSON.encode(result.toJsonMap()));
@@ -260,15 +266,15 @@ class CompilerServer {
260266
final String _entryPath;
261267

262268
factory CompilerServer(CompilerOptions options) {
263-
var entryPath = path.basename(options.entryPointFile);
269+
var entryPath = path.basename(options.sourceOptions.entryPointFile);
264270
var extension = path.extension(entryPath);
265-
if (extension != '.html' && !options.useImplicitHtml) {
271+
if (extension != '.html' && !options.sourceOptions.useImplicitHtml) {
266272
print('error: devc in server mode requires an HTML or Dart entry point.');
267273
exit(1);
268274
}
269275

270276
// TODO(sigmund): allow running without a dir, but keep output in memory?
271-
var outDir = options.outputDir;
277+
var outDir = options.codegenOptions.outputDir;
272278
if (outDir == null) {
273279
print('error: devc in server mode also requires specifying and '
274280
'output location for generated code.');
@@ -283,8 +289,9 @@ class CompilerServer {
283289
CompilerServer._(
284290
Compiler compiler, this.outDir, this.host, this.port, String entryPath)
285291
: this.compiler = compiler,
286-
this._entryPath = compiler.options.useImplicitHtml
287-
? ResolverOptions.implicitHtmlFile
292+
// TODO(jmesserly): this logic is duplicated in a few places
293+
this._entryPath = compiler.options.sourceOptions.useImplicitHtml
294+
? SourceResolverOptions.implicitHtmlFile
288295
: entryPath;
289296

290297
Future start() async {

pkg/dev_compiler/lib/src/analysis_context.dart

+25-19
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,40 @@ import 'package:analyzer/src/generated/source.dart' show DartUriResolver;
1313
import 'package:analyzer/src/generated/source_io.dart';
1414
import 'package:path/path.dart' as path;
1515

16+
import 'package:dev_compiler/strong_mode.dart' show StrongModeOptions;
17+
1618
import 'checker/resolver.dart';
1719
import 'dart_sdk.dart';
1820
import 'multi_package_resolver.dart';
1921
import 'options.dart';
2022

21-
/// Creates an AnalysisContext with dev_compiler type rules and inference.
23+
/// Creates an [AnalysisContext] with dev_compiler type rules and inference,
24+
/// using [createSourceFactory] to set up its [SourceFactory].
25+
AnalysisContext createAnalysisContextWithSources(
26+
StrongModeOptions strongOptions, SourceResolverOptions srcOptions,
27+
{DartUriResolver sdkResolver, List fileResolvers}) {
28+
var srcFactory = createSourceFactory(srcOptions,
29+
sdkResolver: sdkResolver, fileResolvers: fileResolvers);
30+
return createAnalysisContext(strongOptions)..sourceFactory = srcFactory;
31+
}
32+
33+
/// Creates an analysis context that contains our restricted typing rules.
34+
AnalysisContext createAnalysisContext(StrongModeOptions options) {
35+
AnalysisContextImpl res = AnalysisEngine.instance.createAnalysisContext();
36+
res.libraryResolverFactory =
37+
(context) => new LibraryResolverWithInference(context, options);
38+
return res;
39+
}
40+
41+
/// Creates a SourceFactory configured by the [options].
2242
///
2343
/// Use [options.useMockSdk] to specify the SDK mode, or use [sdkResolver]
2444
/// to entirely override the DartUriResolver.
2545
///
2646
/// If supplied, [fileResolvers] will override the default `file:` and
2747
/// `package:` URI resolvers.
28-
///
29-
AnalysisContext createAnalysisContext(CompilerOptions options,
48+
SourceFactory createSourceFactory(SourceResolverOptions options,
3049
{DartUriResolver sdkResolver, List fileResolvers}) {
31-
var context = _initContext(options);
32-
3350
var sdkResolver = options.useMockSdk
3451
? createMockSdkResolver(mockSdkSources)
3552
: createSdkPathResolver(options.dartSdkPath);
@@ -49,8 +66,7 @@ AnalysisContext createAnalysisContext(CompilerOptions options,
4966
: new PackageUriResolver([new JavaFile(options.packageRoot)]));
5067
}
5168
resolvers.addAll(fileResolvers);
52-
context.sourceFactory = new SourceFactory(resolvers);
53-
return context;
69+
return new SourceFactory(resolvers);
5470
}
5571

5672
/// Creates a [DartUriResolver] that uses a mock 'dart:' library contents.
@@ -61,8 +77,8 @@ DartUriResolver createMockSdkResolver(Map<String, String> mockSources) =>
6177
DartUriResolver createSdkPathResolver(String sdkPath) =>
6278
new DartUriResolver(new DirectoryBasedDartSdk(new JavaFile(sdkPath)));
6379

64-
UriResolver _createImplicitEntryResolver(ResolverOptions options) {
65-
var entry = path.absolute(ResolverOptions.implicitHtmlFile);
80+
UriResolver _createImplicitEntryResolver(SourceResolverOptions options) {
81+
var entry = path.absolute(SourceResolverOptions.implicitHtmlFile);
6682
var src = path.absolute(options.entryPointFile);
6783
var provider = new MemoryResourceProvider();
6884
provider.newFile(
@@ -83,13 +99,3 @@ class ExistingSourceUriResolver implements UriResolver {
8399
}
84100
Uri restoreAbsolute(Source source) => resolver.restoreAbsolute(source);
85101
}
86-
87-
/// Creates an analysis context that contains our restricted typing rules.
88-
AnalysisContext _initContext(ResolverOptions options) {
89-
var analysisOptions = new AnalysisOptionsImpl()..cacheSize = 512;
90-
AnalysisContextImpl res = AnalysisEngine.instance.createAnalysisContext();
91-
res.analysisOptions = analysisOptions;
92-
res.libraryResolverFactory =
93-
(context) => new LibraryResolverWithInference(context, options);
94-
return res;
95-
}

pkg/dev_compiler/lib/src/checker/checker.dart

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import 'package:analyzer/src/generated/scanner.dart' show Token, TokenType;
1111
import 'package:logging/logging.dart' as logger;
1212

1313
import 'package:dev_compiler/src/info.dart';
14-
import 'package:dev_compiler/src/options.dart';
1514
import 'package:dev_compiler/src/report.dart' show CheckerReporter;
1615
import 'package:dev_compiler/src/utils.dart' show getMemberType;
16+
import 'package:dev_compiler/strong_mode.dart' show StrongModeOptions;
1717
import 'rules.dart';
1818

1919
/// Checks for overriding declarations of fields and methods. This is used to
@@ -24,7 +24,7 @@ class _OverrideChecker {
2424
final TypeRules _rules;
2525
final CheckerReporter _reporter;
2626
final bool _inferFromOverrides;
27-
_OverrideChecker(this._rules, this._reporter, CompilerOptions options)
27+
_OverrideChecker(this._rules, this._reporter, StrongModeOptions options)
2828
: _inferFromOverrides = options.inferFromOverrides;
2929

3030
void check(ClassDeclaration node) {
@@ -342,7 +342,7 @@ class CodeChecker extends RecursiveAstVisitor {
342342
bool get failure => _failure || _overrideChecker._failure;
343343

344344
CodeChecker(
345-
TypeRules rules, CheckerReporter reporter, CompilerOptions options)
345+
TypeRules rules, CheckerReporter reporter, StrongModeOptions options)
346346
: _rules = rules,
347347
_reporter = reporter,
348348
_overrideChecker = new _OverrideChecker(rules, reporter, options);

pkg/dev_compiler/lib/src/checker/resolver.dart

+4-4
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@ import 'package:analyzer/src/generated/utilities_collection.dart'
1717
show DirectedGraph;
1818
import 'package:logging/logging.dart' as logger;
1919

20-
import 'package:dev_compiler/src/options.dart';
2120
import 'package:dev_compiler/src/utils.dart';
21+
import 'package:dev_compiler/strong_mode.dart' show StrongModeOptions;
2222

2323
final _log = new logger.Logger('dev_compiler.src.resolver');
2424

2525
/// A [LibraryResolver] that performs inference on top-levels and fields based
2626
/// on the value of the initializer, and on fields and methods based on
2727
/// overridden members in super classes.
2828
class LibraryResolverWithInference extends LibraryResolver {
29-
final ResolverOptions _options;
29+
final StrongModeOptions _options;
3030

3131
LibraryResolverWithInference(context, this._options) : super(context);
3232

@@ -213,7 +213,7 @@ class LibraryResolverWithInference extends LibraryResolver {
213213
continue;
214214
}
215215

216-
// When field is final and overriden getter is dynamic, we can infer from
216+
// When field is final and overridden getter is dynamic, we can infer from
217217
// the RHS without breaking subtyping rules (return type is covariant).
218218
if (type.returnType.isDynamic) {
219219
if (variables.isFinal && variable.initializer != null) {
@@ -356,7 +356,7 @@ class RestrictedResolverVisitor extends ResolverVisitor {
356356
final _visitedInitializers = new Set<VariableDeclaration>();
357357

358358
RestrictedResolverVisitor(Library library, Source source,
359-
TypeProvider typeProvider, ResolverOptions options)
359+
TypeProvider typeProvider, StrongModeOptions options)
360360
: _typeProvider = typeProvider,
361361
super.con1(library, source, typeProvider,
362362
typeAnalyzerFactory: RestrictedStaticTypeAnalyzer.constructor);

pkg/dev_compiler/lib/src/checker/rules.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import 'package:analyzer/src/generated/element.dart';
99
import 'package:analyzer/src/generated/resolver.dart';
1010

1111
import 'package:dev_compiler/src/info.dart';
12-
import 'package:dev_compiler/src/options.dart';
1312
import 'package:dev_compiler/src/utils.dart' as utils;
13+
import 'package:dev_compiler/strong_mode.dart' show StrongModeOptions;
1414

1515
abstract class TypeRules {
1616
final TypeProvider provider;
@@ -116,7 +116,7 @@ typedef void MissingTypeReporter(Expression expr);
116116

117117
class RestrictedRules extends TypeRules {
118118
MissingTypeReporter reportMissingType = null;
119-
final RulesOptions options;
119+
final StrongModeOptions options;
120120
final List<DartType> _nonnullableTypes;
121121
DownwardsInference inferrer;
122122

0 commit comments

Comments
 (0)