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

Side by Side Diff: lib/src/info.dart

Issue 1172453002: fixes #209, remove tree mutation from CodeChecker (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 6 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
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 /// Defines static information collected by the type checker and used later by 5 /// Defines static information collected by the type checker and used later by
6 /// emitters to generate code. 6 /// emitters to generate code.
7 library dev_compiler.src.info; 7 library dev_compiler.src.info;
8 8
9 import 'dart:mirrors'; 9 import 'dart:mirrors';
10 10
11 import 'package:analyzer/src/generated/ast.dart'; 11 import 'package:analyzer/src/generated/ast.dart';
12 import 'package:analyzer/src/generated/element.dart'; 12 import 'package:analyzer/src/generated/element.dart';
13 import 'package:analyzer/src/generated/error.dart' as analyzer; 13 import 'package:analyzer/src/generated/error.dart' as analyzer;
14 import 'package:analyzer/src/generated/scanner.dart'
15 show Token, TokenType, SyntheticStringToken;
16 import 'package:logging/logging.dart' show Level; 14 import 'package:logging/logging.dart' show Level;
17 15
18 import 'package:dev_compiler/src/checker/rules.dart'; 16 import 'package:dev_compiler/src/checker/rules.dart';
19 import 'package:dev_compiler/src/utils.dart' as utils; 17 import 'package:dev_compiler/src/utils.dart' as utils;
20 18
21 import 'report.dart' show Message; 19 import 'report.dart' show Message;
22 20
23 /// Represents a summary of the results collected by running the program 21 /// Represents a summary of the results collected by running the program
24 /// checker. 22 /// checker.
25 class CheckerResults { 23 class CheckerResults {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 @override 100 @override
103 int get begin => node is AnnotatedNode 101 int get begin => node is AnnotatedNode
104 ? (node as AnnotatedNode).firstTokenAfterCommentAndMetadata.offset 102 ? (node as AnnotatedNode).firstTokenAfterCommentAndMetadata.offset
105 : node.offset; 103 : node.offset;
106 104
107 @override 105 @override
108 int get end => node.end; 106 int get end => node.end;
109 } 107 }
110 108
111 /// Implicitly injected expression conversion. 109 /// Implicitly injected expression conversion.
112 // TODO(jmesserly): rename to have Expression suffix? 110 abstract class CoercionInfo extends StaticInfo {
113 abstract class Conversion extends Expression with StaticInfo {
114 final TypeRules rules; 111 final TypeRules rules;
115 112
116 // TODO(jmesserly): should probably rename this "operand" for consistency with 113 final Expression node;
117 // analyzer's unary expressions (e.g. PrefixExpression).
118 final Expression expression;
119 114
120 AstNode get node => expression; 115 DartType get convertedType;
121 DartType _convertedType;
122 116
123 Conversion(this.rules, this.expression) { 117 CoercionInfo(this.rules, this.node);
124 this._convertedType = _getConvertedType();
125 }
126 118
127 DartType get baseType => rules.getStaticType(expression); 119 DartType get baseType => rules.getStaticType(node);
128 DartType get convertedType => _convertedType; 120 DartType get staticType => convertedType;
129 DartType get staticType => _convertedType;
130
131 DartType _getConvertedType();
132 121
133 // safe iff this cannot throw 122 // safe iff this cannot throw
134 bool get safe => false; 123 bool get safe => false;
135 124
136 Level get level => safe ? Level.CONFIG : Level.INFO; 125 Level get level => safe ? Level.CONFIG : Level.INFO;
137 126
138 String get description => '${this.runtimeType}: $baseType to $convertedType'; 127 String get description => '${this.runtimeType}: $baseType to $convertedType';
139 128
140 Token get beginToken => expression.beginToken; 129 static const String _propertyName = 'dev_compiler.Conversion';
141 Token get endToken => expression.endToken;
142 130
143 @override 131 /// Gets the coercion info associated with this node.
144 void visitChildren(AstVisitor visitor) { 132 static CoercionInfo get(AstNode node) => node.getProperty(_propertyName);
145 expression.accept(visitor); 133
134 /// Sets the coercion info associated with this node.
135 static CoercionInfo set(AstNode node, CoercionInfo info) {
136 node.setProperty(_propertyName, info);
137 return info;
146 } 138 }
147
148 // Use same precedence as MethodInvocation.
149 int get precedence => 15;
150
151 @override
152 Iterable get childEntities => new ChildEntities()..add(expression);
153 } 139 }
154 140
155 // Base class for all casts from base type to sub type. 141 // Base class for all casts from base type to sub type.
156 abstract class DownCast extends Conversion { 142 abstract class DownCast extends CoercionInfo {
157 Cast _cast; 143 Cast _cast;
158 144
159 DownCast._internal(TypeRules rules, Expression expression, this._cast) 145 DownCast._internal(TypeRules rules, Expression expression, this._cast)
160 : super(rules, expression) { 146 : super(rules, expression) {
161 assert(_cast.toType != baseType && 147 assert(_cast.toType != baseType &&
162 _cast.fromType == baseType && 148 _cast.fromType == baseType &&
163 (baseType.isDynamic || 149 (baseType.isDynamic ||
164 // Call methods make the following non-redundant 150 // Call methods make the following non-redundant
165 _cast.toType.isSubtypeOf(baseType) || 151 _cast.toType.isSubtypeOf(baseType) ||
166 baseType.isAssignableTo(_cast.toType))); 152 baseType.isAssignableTo(_cast.toType)));
167 } 153 }
168 154
169 Cast get cast => _cast; 155 Cast get cast => _cast;
170 156
171 DartType _getConvertedType() => _cast.toType; 157 DartType get convertedType => _cast.toType;
172 158
173 String get message => '$expression ($baseType) will need runtime check ' 159 String get message => '$node ($baseType) will need runtime check '
174 'to cast to type $convertedType'; 160 'to cast to type $convertedType';
175 161
176 // Factory to create correct DownCast variant. 162 // Factory to create correct DownCast variant.
177 static StaticInfo create(TypeRules rules, Expression expression, Cast cast, 163 static StaticInfo create(TypeRules rules, Expression expression, Cast cast,
178 {String reason}) { 164 {String reason}) {
179 final fromT = cast.fromType; 165 final fromT = cast.fromType;
180 final toT = cast.toType; 166 final toT = cast.toType;
181 167
182 // toT <:_R fromT => to <: fromT 168 // toT <:_R fromT => to <: fromT
183 // NB: classes with call methods are subtypes of function 169 // NB: classes with call methods are subtypes of function
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 214
229 // Assignment cast 215 // Assignment cast
230 var parent = expression.parent; 216 var parent = expression.parent;
231 if (parent is VariableDeclaration && (parent.initializer == expression)) { 217 if (parent is VariableDeclaration && (parent.initializer == expression)) {
232 return new AssignmentCast(rules, expression, cast); 218 return new AssignmentCast(rules, expression, cast);
233 } 219 }
234 220
235 // Other casts 221 // Other casts
236 return new DownCastImplicit(rules, expression, cast); 222 return new DownCastImplicit(rules, expression, cast);
237 } 223 }
238
239 accept(AstVisitor visitor) {
240 if (visitor is ConversionVisitor) {
241 return visitor.visitDownCast(this);
242 } else {
243 return expression.accept(visitor);
244 }
245 }
246 } 224 }
247 225
248 // 226 //
249 // Standard down casts. These casts are implicitly injected by the compiler. 227 // Standard down casts. These casts are implicitly injected by the compiler.
250 // 228 //
251 229
252 // A down cast from dynamic to T. 230 // A down cast from dynamic to T.
253 class DynamicCast extends DownCast { 231 class DynamicCast extends DownCast {
254 DynamicCast(TypeRules rules, Expression expression, Cast cast) 232 DynamicCast(TypeRules rules, Expression expression, Cast cast)
255 : super._internal(rules, expression, cast); 233 : super._internal(rules, expression, cast);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 // Dart and may be more likely to fail at runtime. 280 // Dart and may be more likely to fail at runtime.
303 class DownCastImplicit extends DownCast { 281 class DownCastImplicit extends DownCast {
304 DownCastImplicit(TypeRules rules, Expression expression, Cast cast) 282 DownCastImplicit(TypeRules rules, Expression expression, Cast cast)
305 : super._internal(rules, expression, cast); 283 : super._internal(rules, expression, cast);
306 284
307 final Level level = Level.WARNING; 285 final Level level = Level.WARNING;
308 } 286 }
309 287
310 // An inferred type for the wrapped expression, which may need to be 288 // An inferred type for the wrapped expression, which may need to be
311 // reified into the term 289 // reified into the term
312 abstract class InferredTypeBase extends Conversion { 290 abstract class InferredTypeBase extends CoercionInfo {
313 DartType _type; 291 final DartType _type;
314 292
315 InferredTypeBase._internal(TypeRules rules, Expression expression, this._type) 293 InferredTypeBase._internal(TypeRules rules, Expression expression, this._type)
316 : super(rules, expression); 294 : super(rules, expression);
317 295
318 DartType get type => _type; 296 DartType get type => _type;
319 297 DartType get convertedType => type;
320 DartType _getConvertedType() => type; 298 String get message => '$node has inferred type $type';
321
322 String get message => '$expression has inferred type $type';
323
324 Level get level => Level.INFO; 299 Level get level => Level.INFO;
325
326 accept(AstVisitor visitor) {
327 if (visitor is ConversionVisitor) {
328 return visitor.visitInferredTypeBase(this);
329 } else {
330 return expression.accept(visitor);
331 }
332 }
333 } 300 }
334 301
335 // Standard / unspecialized inferred type 302 // Standard / unspecialized inferred type
336 class InferredType extends InferredTypeBase { 303 class InferredType extends InferredTypeBase {
337 InferredType(TypeRules rules, Expression expression, DartType type) 304 InferredType(TypeRules rules, Expression expression, DartType type)
338 : super._internal(rules, expression, type); 305 : super._internal(rules, expression, type);
339 306
340 // Factory to create correct InferredType variant. 307 // Factory to create correct InferredType variant.
341 static InferredTypeBase create( 308 static InferredTypeBase create(
342 TypeRules rules, Expression expression, DartType type) { 309 TypeRules rules, Expression expression, DartType type) {
(...skipping 23 matching lines...) Expand all
366 InferredTypeAllocation(TypeRules rules, Expression expression, DartType type) 333 InferredTypeAllocation(TypeRules rules, Expression expression, DartType type)
367 : super._internal(rules, expression, type); 334 : super._internal(rules, expression, type);
368 } 335 }
369 336
370 // An inferred type for a closure expression 337 // An inferred type for a closure expression
371 class InferredTypeClosure extends InferredTypeBase { 338 class InferredTypeClosure extends InferredTypeBase {
372 InferredTypeClosure(TypeRules rules, Expression expression, DartType type) 339 InferredTypeClosure(TypeRules rules, Expression expression, DartType type)
373 : super._internal(rules, expression, type); 340 : super._internal(rules, expression, type);
374 } 341 }
375 342
376 class DynamicInvoke extends Conversion { 343 class DynamicInvoke extends CoercionInfo {
377 DynamicInvoke(TypeRules rules, Expression expression) 344 DynamicInvoke(TypeRules rules, Expression expression)
378 : super(rules, expression); 345 : super(rules, expression);
379 346
380 DartType _getConvertedType() => rules.provider.dynamicType; 347 DartType get convertedType => rules.provider.dynamicType;
381 348 String get message => '$node requires dynamic invoke';
382 String get message => '$expression requires dynamic invoke';
383 Level get level => Level.INFO; 349 Level get level => Level.INFO;
384
385 accept(AstVisitor visitor) {
386 if (visitor is ConversionVisitor) {
387 return visitor.visitDynamicInvoke(this);
388 } else {
389 return expression.accept(visitor);
390 }
391 }
392 } 350 }
393 351
394 abstract class StaticError extends StaticInfo { 352 abstract class StaticError extends StaticInfo {
395 final AstNode node; 353 final AstNode node;
396 354
397 StaticError(this.node); 355 StaticError(this.node);
398 356
399 Level get level => Level.SEVERE; 357 Level get level => Level.SEVERE;
400 } 358 }
401 359
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 /// <http://goo.gl/q1T4BB> 507 /// <http://goo.gl/q1T4BB>
550 /// 508 ///
551 /// For now this is the only pattern we support. 509 /// For now this is the only pattern we support.
552 class InvalidSuperInvocation extends StaticError { 510 class InvalidSuperInvocation extends StaticError {
553 InvalidSuperInvocation(SuperConstructorInvocation node) : super(node); 511 InvalidSuperInvocation(SuperConstructorInvocation node) : super(node);
554 512
555 String get message => "super call must be last in an initializer list " 513 String get message => "super call must be last in an initializer list "
556 "(see http://goo.gl/q1T4BB): $node"; 514 "(see http://goo.gl/q1T4BB): $node";
557 } 515 }
558 516
559 /// A simple generalizing visitor interface for the conversion nodes.
560 /// This can be mixed in to your visitor if the AST can contain these nodes.
561 abstract class ConversionVisitor<R> implements AstVisitor<R> {
562 /// This method must be implemented. It is typically supplied by the base
563 /// GeneralizingAstVisitor<R>.
564 R visitNode(AstNode node);
565
566 /// The catch-all for any kind of conversion
567 R visitConversion(Conversion node) => visitNode(node);
568
569 // Methods for conversion subtypes:
570 R visitDownCast(DownCast node) => visitConversion(node);
571 R visitDynamicInvoke(DynamicInvoke node) => visitConversion(node);
572 R visitInferredTypeBase(InferredTypeBase node) => visitConversion(node);
573 }
574
575 /// Automatically infer list of types by scanning this library using mirrors. 517 /// Automatically infer list of types by scanning this library using mirrors.
576 final List<Type> infoTypes = () { 518 final List<Type> infoTypes = () {
577 var allTypes = new Set(); 519 var allTypes = new Set();
578 var baseTypes = new Set(); 520 var baseTypes = new Set();
579 var infoMirror = reflectClass(StaticInfo); 521 var infoMirror = reflectClass(StaticInfo);
580 var libMirror = infoMirror.owner as LibraryMirror; 522 var libMirror = infoMirror.owner as LibraryMirror;
581 var declarations = libMirror.declarations.values; 523 var declarations = libMirror.declarations.values;
582 for (ClassMirror cls in declarations.where((d) => d is ClassMirror)) { 524 for (ClassMirror cls in declarations.where((d) => d is ClassMirror)) {
583 if (cls.isSubtypeOf(infoMirror)) { 525 if (cls.isSubtypeOf(infoMirror)) {
584 allTypes.add(cls); 526 allTypes.add(cls);
(...skipping 11 matching lines...) Expand all
596 var isError = severity == analyzer.ErrorSeverity.WARNING; 538 var isError = severity == analyzer.ErrorSeverity.WARNING;
597 var level = isError ? Level.SEVERE : Level.WARNING; 539 var level = isError ? Level.SEVERE : Level.WARNING;
598 int begin = error.offset; 540 int begin = error.offset;
599 int end = begin + error.length; 541 int end = begin + error.length;
600 return new AnalyzerError(error.message, level, begin, end); 542 return new AnalyzerError(error.message, level, begin, end);
601 } 543 }
602 544
603 const AnalyzerError(String message, Level level, int begin, int end) 545 const AnalyzerError(String message, Level level, int begin, int end)
604 : super(message, level, begin, end); 546 : super(message, level, begin, end);
605 } 547 }
OLDNEW
« no previous file with comments | « lib/src/codegen/reify_coercions.dart ('k') | lib/src/testing.dart » ('j') | lib/src/testing.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698