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

Side by Side Diff: pkg/analyzer/lib/src/summary/summarize_const_expr.dart

Issue 1674073002: Add UnlinkedConst.isValid and set it during summarizing. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 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) 2016, the Dart project authors. Please see the AUTHORS file 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 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 library serialization.summarize_const_expr; 5 library serialization.summarize_const_expr;
6 6
7 import 'package:analyzer/src/generated/ast.dart'; 7 import 'package:analyzer/src/generated/ast.dart';
8 import 'package:analyzer/src/generated/scanner.dart'; 8 import 'package:analyzer/src/generated/scanner.dart';
9 import 'package:analyzer/src/summary/format.dart'; 9 import 'package:analyzer/src/summary/format.dart';
10 import 'package:analyzer/src/summary/idl.dart'; 10 import 'package:analyzer/src/summary/idl.dart';
(...skipping 22 matching lines...) Expand all
33 * See [UnlinkedConstBuilder.strings]. 33 * See [UnlinkedConstBuilder.strings].
34 */ 34 */
35 final List<String> strings = <String>[]; 35 final List<String> strings = <String>[];
36 36
37 /** 37 /**
38 * See [UnlinkedConstBuilder.references]. 38 * See [UnlinkedConstBuilder.references].
39 */ 39 */
40 final List<EntityRefBuilder> references = <EntityRefBuilder>[]; 40 final List<EntityRefBuilder> references = <EntityRefBuilder>[];
41 41
42 /** 42 /**
43 * Return the [UnlinkedConstBuilder] that corresponds to the given [expr].
44 */
45 UnlinkedConstBuilder serialize(Expression expr) {
46 try {
47 _serialize(expr);
48 return new UnlinkedConstBuilder(
49 isValid: true,
50 operations: operations,
51 ints: ints,
52 doubles: doubles,
53 strings: strings,
54 references: references);
55 } on StateError {
56 return new UnlinkedConstBuilder(isValid: false);
57 }
58 }
59
60 /**
61 * Return [EntityRefBuilder] that corresponds to the given [constructor].
62 */
63 EntityRefBuilder serializeConstructorName(ConstructorName constructor);
64
65 /**
66 * Return [EntityRefBuilder] that corresponds to the given [identifier].
67 */
68 EntityRefBuilder serializeIdentifier(Identifier identifier);
69
70 /**
71 * Return [EntityRefBuilder] that corresponds to the given [access].
72 */
73 EntityRefBuilder serializePropertyAccess(PropertyAccess access);
74
75 /**
76 * Return [EntityRefBuilder] that corresponds to the given [type].
77 */
78 EntityRefBuilder serializeType(TypeName type);
79
80 void _pushInt(int value) {
81 assert(value >= 0);
82 if (value >= (1 << 32)) {
83 int numOfComponents = 0;
84 ints.add(numOfComponents);
85 void pushComponents(int value) {
86 if (value >= (1 << 32)) {
87 pushComponents(value >> 32);
88 }
89 numOfComponents++;
90 ints.add(value & 0xFFFFFFFF);
91 }
92 pushComponents(value);
93 ints[ints.length - 1 - numOfComponents] = numOfComponents;
94 operations.add(UnlinkedConstOperation.pushLongInt);
95 } else {
96 operations.add(UnlinkedConstOperation.pushInt);
97 ints.add(value);
98 }
99 }
100
101 /**
43 * Serialize the given [expr] expression into this serializer state. 102 * Serialize the given [expr] expression into this serializer state.
44 */ 103 */
45 void serialize(Expression expr) { 104 void _serialize(Expression expr) {
46 if (expr is IntegerLiteral) { 105 if (expr is IntegerLiteral) {
47 _pushInt(expr.value); 106 _pushInt(expr.value);
48 } else if (expr is DoubleLiteral) { 107 } else if (expr is DoubleLiteral) {
49 operations.add(UnlinkedConstOperation.pushDouble); 108 operations.add(UnlinkedConstOperation.pushDouble);
50 doubles.add(expr.value); 109 doubles.add(expr.value);
51 } else if (expr is BooleanLiteral) { 110 } else if (expr is BooleanLiteral) {
52 if (expr.value) { 111 if (expr.value) {
53 operations.add(UnlinkedConstOperation.pushTrue); 112 operations.add(UnlinkedConstOperation.pushTrue);
54 } else { 113 } else {
55 operations.add(UnlinkedConstOperation.pushFalse); 114 operations.add(UnlinkedConstOperation.pushFalse);
(...skipping 10 matching lines...) Expand all
66 operations.add(UnlinkedConstOperation.pushReference); 125 operations.add(UnlinkedConstOperation.pushReference);
67 } else if (expr is InstanceCreationExpression) { 126 } else if (expr is InstanceCreationExpression) {
68 _serializeInstanceCreation(expr); 127 _serializeInstanceCreation(expr);
69 } else if (expr is ListLiteral) { 128 } else if (expr is ListLiteral) {
70 _serializeListLiteral(expr); 129 _serializeListLiteral(expr);
71 } else if (expr is MapLiteral) { 130 } else if (expr is MapLiteral) {
72 _serializeMapLiteral(expr); 131 _serializeMapLiteral(expr);
73 } else if (expr is MethodInvocation) { 132 } else if (expr is MethodInvocation) {
74 String name = expr.methodName.name; 133 String name = expr.methodName.name;
75 if (name != 'identical') { 134 if (name != 'identical') {
76 throw new _ConstExprSerializationError( 135 throw new StateError('Only "identity" function invocation is allowed.');
77 'Only "identity" function invocation is allowed.');
78 } 136 }
79 if (expr.argumentList == null || 137 if (expr.argumentList == null ||
80 expr.argumentList.arguments.length != 2) { 138 expr.argumentList.arguments.length != 2) {
81 throw new _ConstExprSerializationError( 139 throw new StateError(
82 'The function "identity" requires exactly 2 arguments.'); 140 'The function "identity" requires exactly 2 arguments.');
83 } 141 }
84 expr.argumentList.arguments.forEach(serialize); 142 expr.argumentList.arguments.forEach(_serialize);
85 operations.add(UnlinkedConstOperation.identical); 143 operations.add(UnlinkedConstOperation.identical);
86 } else if (expr is BinaryExpression) { 144 } else if (expr is BinaryExpression) {
87 _serializeBinaryExpression(expr); 145 _serializeBinaryExpression(expr);
88 } else if (expr is ConditionalExpression) { 146 } else if (expr is ConditionalExpression) {
89 serialize(expr.condition); 147 _serialize(expr.condition);
90 serialize(expr.thenExpression); 148 _serialize(expr.thenExpression);
91 serialize(expr.elseExpression); 149 _serialize(expr.elseExpression);
92 operations.add(UnlinkedConstOperation.conditional); 150 operations.add(UnlinkedConstOperation.conditional);
93 } else if (expr is PrefixExpression) { 151 } else if (expr is PrefixExpression) {
94 _serializePrefixExpression(expr); 152 _serializePrefixExpression(expr);
95 } else if (expr is PropertyAccess) { 153 } else if (expr is PropertyAccess) {
96 if (expr.target is! PrefixedIdentifier && 154 if (expr.target is! PrefixedIdentifier &&
97 expr.propertyName.name == 'length') { 155 expr.propertyName.name == 'length') {
98 serialize(expr.target); 156 _serialize(expr.target);
99 operations.add(UnlinkedConstOperation.length); 157 operations.add(UnlinkedConstOperation.length);
100 } else { 158 } else {
101 references.add(serializePropertyAccess(expr)); 159 references.add(serializePropertyAccess(expr));
102 operations.add(UnlinkedConstOperation.pushReference); 160 operations.add(UnlinkedConstOperation.pushReference);
103 } 161 }
104 } else if (expr is ParenthesizedExpression) { 162 } else if (expr is ParenthesizedExpression) {
105 serialize(expr.expression); 163 _serialize(expr.expression);
106 } else { 164 } else {
107 throw new _ConstExprSerializationError('Unknown expression type: $expr'); 165 throw new StateError('Unknown expression type: $expr');
108 }
109 }
110
111 /**
112 * Return [EntityRefBuilder] that corresponds to the given [constructor].
113 */
114 EntityRefBuilder serializeConstructorName(ConstructorName constructor);
115
116 /**
117 * Return [EntityRefBuilder] that corresponds to the given [identifier].
118 */
119 EntityRefBuilder serializeIdentifier(Identifier identifier);
120
121 /**
122 * Return [EntityRefBuilder] that corresponds to the given [access].
123 */
124 EntityRefBuilder serializePropertyAccess(PropertyAccess access);
125
126 /**
127 * Return [EntityRefBuilder] that corresponds to the given [type].
128 */
129 EntityRefBuilder serializeType(TypeName type);
130
131 /**
132 * Return the [UnlinkedConstBuilder] that corresponds to the state of this
133 * serializer.
134 */
135 UnlinkedConstBuilder toBuilder() {
136 return new UnlinkedConstBuilder(
137 operations: operations,
138 ints: ints,
139 doubles: doubles,
140 strings: strings,
141 references: references);
142 }
143
144 void _pushInt(int value) {
145 assert(value >= 0);
146 if (value >= (1 << 32)) {
147 int numOfComponents = 0;
148 ints.add(numOfComponents);
149 void pushComponents(int value) {
150 if (value >= (1 << 32)) {
151 pushComponents(value >> 32);
152 }
153 numOfComponents++;
154 ints.add(value & 0xFFFFFFFF);
155 }
156 pushComponents(value);
157 ints[ints.length - 1 - numOfComponents] = numOfComponents;
158 operations.add(UnlinkedConstOperation.pushLongInt);
159 } else {
160 operations.add(UnlinkedConstOperation.pushInt);
161 ints.add(value);
162 } 166 }
163 } 167 }
164 168
165 void _serializeBinaryExpression(BinaryExpression expr) { 169 void _serializeBinaryExpression(BinaryExpression expr) {
166 serialize(expr.leftOperand); 170 _serialize(expr.leftOperand);
167 serialize(expr.rightOperand); 171 _serialize(expr.rightOperand);
168 TokenType operator = expr.operator.type; 172 TokenType operator = expr.operator.type;
169 if (operator == TokenType.EQ_EQ) { 173 if (operator == TokenType.EQ_EQ) {
170 operations.add(UnlinkedConstOperation.equal); 174 operations.add(UnlinkedConstOperation.equal);
171 } else if (operator == TokenType.BANG_EQ) { 175 } else if (operator == TokenType.BANG_EQ) {
172 operations.add(UnlinkedConstOperation.notEqual); 176 operations.add(UnlinkedConstOperation.notEqual);
173 } else if (operator == TokenType.AMPERSAND_AMPERSAND) { 177 } else if (operator == TokenType.AMPERSAND_AMPERSAND) {
174 operations.add(UnlinkedConstOperation.and); 178 operations.add(UnlinkedConstOperation.and);
175 } else if (operator == TokenType.BAR_BAR) { 179 } else if (operator == TokenType.BAR_BAR) {
176 operations.add(UnlinkedConstOperation.or); 180 operations.add(UnlinkedConstOperation.or);
177 } else if (operator == TokenType.CARET) { 181 } else if (operator == TokenType.CARET) {
(...skipping 20 matching lines...) Expand all
198 operations.add(UnlinkedConstOperation.greater); 202 operations.add(UnlinkedConstOperation.greater);
199 } else if (operator == TokenType.LT) { 203 } else if (operator == TokenType.LT) {
200 operations.add(UnlinkedConstOperation.less); 204 operations.add(UnlinkedConstOperation.less);
201 } else if (operator == TokenType.GT_EQ) { 205 } else if (operator == TokenType.GT_EQ) {
202 operations.add(UnlinkedConstOperation.greaterEqual); 206 operations.add(UnlinkedConstOperation.greaterEqual);
203 } else if (operator == TokenType.LT_EQ) { 207 } else if (operator == TokenType.LT_EQ) {
204 operations.add(UnlinkedConstOperation.lessEqual); 208 operations.add(UnlinkedConstOperation.lessEqual);
205 } else if (operator == TokenType.PERCENT) { 209 } else if (operator == TokenType.PERCENT) {
206 operations.add(UnlinkedConstOperation.modulo); 210 operations.add(UnlinkedConstOperation.modulo);
207 } else { 211 } else {
208 throw new _ConstExprSerializationError('Unknown operator: $operator'); 212 throw new StateError('Unknown operator: $operator');
209 } 213 }
210 } 214 }
211 215
212 void _serializeInstanceCreation(InstanceCreationExpression expr) { 216 void _serializeInstanceCreation(InstanceCreationExpression expr) {
213 ConstructorName constructor = expr.constructorName; 217 ConstructorName constructor = expr.constructorName;
214 List<Expression> arguments = expr.argumentList.arguments; 218 List<Expression> arguments = expr.argumentList.arguments;
215 // Serialize the arguments. 219 // Serialize the arguments.
216 List<String> argumentNames = <String>[]; 220 List<String> argumentNames = <String>[];
217 arguments.forEach((arg) { 221 arguments.forEach((arg) {
218 if (arg is NamedExpression) { 222 if (arg is NamedExpression) {
219 argumentNames.add(arg.name.label.name); 223 argumentNames.add(arg.name.label.name);
220 serialize(arg.expression); 224 _serialize(arg.expression);
221 } else { 225 } else {
222 serialize(arg); 226 _serialize(arg);
223 } 227 }
224 }); 228 });
225 // Add the op-code and numbers of named and positional arguments. 229 // Add the op-code and numbers of named and positional arguments.
226 operations.add(UnlinkedConstOperation.invokeConstructor); 230 operations.add(UnlinkedConstOperation.invokeConstructor);
227 ints.add(argumentNames.length); 231 ints.add(argumentNames.length);
228 strings.addAll(argumentNames); 232 strings.addAll(argumentNames);
229 ints.add(arguments.length - argumentNames.length); 233 ints.add(arguments.length - argumentNames.length);
230 // Serialize the reference. 234 // Serialize the reference.
231 references.add(serializeConstructorName(constructor)); 235 references.add(serializeConstructorName(constructor));
232 } 236 }
233 237
234 void _serializeListLiteral(ListLiteral expr) { 238 void _serializeListLiteral(ListLiteral expr) {
235 List<Expression> elements = expr.elements; 239 List<Expression> elements = expr.elements;
236 elements.forEach(serialize); 240 elements.forEach(_serialize);
237 ints.add(elements.length); 241 ints.add(elements.length);
238 if (expr.typeArguments != null && 242 if (expr.typeArguments != null &&
239 expr.typeArguments.arguments.length == 1) { 243 expr.typeArguments.arguments.length == 1) {
240 references.add(serializeType(expr.typeArguments.arguments[0])); 244 references.add(serializeType(expr.typeArguments.arguments[0]));
241 operations.add(UnlinkedConstOperation.makeTypedList); 245 operations.add(UnlinkedConstOperation.makeTypedList);
242 } else { 246 } else {
243 operations.add(UnlinkedConstOperation.makeUntypedList); 247 operations.add(UnlinkedConstOperation.makeUntypedList);
244 } 248 }
245 } 249 }
246 250
247 void _serializeMapLiteral(MapLiteral expr) { 251 void _serializeMapLiteral(MapLiteral expr) {
248 for (MapLiteralEntry entry in expr.entries) { 252 for (MapLiteralEntry entry in expr.entries) {
249 serialize(entry.key); 253 _serialize(entry.key);
250 serialize(entry.value); 254 _serialize(entry.value);
251 } 255 }
252 ints.add(expr.entries.length); 256 ints.add(expr.entries.length);
253 if (expr.typeArguments != null && 257 if (expr.typeArguments != null &&
254 expr.typeArguments.arguments.length == 2) { 258 expr.typeArguments.arguments.length == 2) {
255 references.add(serializeType(expr.typeArguments.arguments[0])); 259 references.add(serializeType(expr.typeArguments.arguments[0]));
256 references.add(serializeType(expr.typeArguments.arguments[1])); 260 references.add(serializeType(expr.typeArguments.arguments[1]));
257 operations.add(UnlinkedConstOperation.makeTypedMap); 261 operations.add(UnlinkedConstOperation.makeTypedMap);
258 } else { 262 } else {
259 operations.add(UnlinkedConstOperation.makeUntypedMap); 263 operations.add(UnlinkedConstOperation.makeUntypedMap);
260 } 264 }
261 } 265 }
262 266
263 void _serializePrefixExpression(PrefixExpression expr) { 267 void _serializePrefixExpression(PrefixExpression expr) {
264 serialize(expr.operand); 268 _serialize(expr.operand);
265 TokenType operator = expr.operator.type; 269 TokenType operator = expr.operator.type;
266 if (operator == TokenType.BANG) { 270 if (operator == TokenType.BANG) {
267 operations.add(UnlinkedConstOperation.not); 271 operations.add(UnlinkedConstOperation.not);
268 } else if (operator == TokenType.MINUS) { 272 } else if (operator == TokenType.MINUS) {
269 operations.add(UnlinkedConstOperation.negate); 273 operations.add(UnlinkedConstOperation.negate);
270 } else if (operator == TokenType.TILDE) { 274 } else if (operator == TokenType.TILDE) {
271 operations.add(UnlinkedConstOperation.complement); 275 operations.add(UnlinkedConstOperation.complement);
272 } else { 276 } else {
273 throw new _ConstExprSerializationError('Unknown operator: $operator'); 277 throw new StateError('Unknown operator: $operator');
274 } 278 }
275 } 279 }
276 280
277 void _serializeString(StringLiteral expr) { 281 void _serializeString(StringLiteral expr) {
278 if (expr is AdjacentStrings) { 282 if (expr is AdjacentStrings) {
279 if (expr.strings.every((string) => string is SimpleStringLiteral)) { 283 if (expr.strings.every((string) => string is SimpleStringLiteral)) {
280 operations.add(UnlinkedConstOperation.pushString); 284 operations.add(UnlinkedConstOperation.pushString);
281 strings.add(expr.stringValue); 285 strings.add(expr.stringValue);
282 } else { 286 } else {
283 expr.strings.forEach(_serializeString); 287 expr.strings.forEach(_serializeString);
284 operations.add(UnlinkedConstOperation.concatenate); 288 operations.add(UnlinkedConstOperation.concatenate);
285 ints.add(expr.strings.length); 289 ints.add(expr.strings.length);
286 } 290 }
287 } else if (expr is SimpleStringLiteral) { 291 } else if (expr is SimpleStringLiteral) {
288 operations.add(UnlinkedConstOperation.pushString); 292 operations.add(UnlinkedConstOperation.pushString);
289 strings.add(expr.value); 293 strings.add(expr.value);
290 } else { 294 } else {
291 StringInterpolation interpolation = expr as StringInterpolation; 295 StringInterpolation interpolation = expr as StringInterpolation;
292 for (InterpolationElement element in interpolation.elements) { 296 for (InterpolationElement element in interpolation.elements) {
293 if (element is InterpolationString) { 297 if (element is InterpolationString) {
294 operations.add(UnlinkedConstOperation.pushString); 298 operations.add(UnlinkedConstOperation.pushString);
295 strings.add(element.value); 299 strings.add(element.value);
296 } else { 300 } else {
297 serialize((element as InterpolationExpression).expression); 301 _serialize((element as InterpolationExpression).expression);
298 } 302 }
299 } 303 }
300 operations.add(UnlinkedConstOperation.concatenate); 304 operations.add(UnlinkedConstOperation.concatenate);
301 ints.add(interpolation.elements.length); 305 ints.add(interpolation.elements.length);
302 } 306 }
303 } 307 }
304 } 308 }
305
306 /**
307 * Error that describes a problem during a constant expression serialization.
308 */
309 class _ConstExprSerializationError {
310 final String message;
311
312 _ConstExprSerializationError(this.message);
313
314 @override
315 String toString() => message;
316 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698